只是一个测试
时间戳的感觉有问题 毕竟在RTMP里只是一个24位的整型,如果超过了怎么办呢??
还有 感觉明明是发布上去了 用VLC通过RTSP也可以看到视频了
但是用FLASH看视频就是看不到 很奇怪
如果转载的话建议注明来源
http://blog.csdn.net/zblue78
// demo.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "librtmp/rtmp_sys.h" #include "librtmp/log.h" #include "librtmp/amf.h" int InitSockets() { #ifdef WIN32 WORD version; WSADATA wsaData; version = MAKEWORD(1, 1); return (WSAStartup(version, &wsaData) == 0); #else return TRUE; #endif } inline void CleanupSockets() { #ifdef WIN32 WSACleanup(); #endif } #define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf)) int hex2bin(char *str, char **hex) { char *ptr; int i, l = strlen(str); if (l & 1) return 0; *hex = (char *)malloc(l/2); ptr = *hex; if (!ptr) return 0; for (i=0; i<l; i+=2) *ptr++ = (HEX2BIN(str[i]) << 4) | HEX2BIN(str[i+1]); return l/2; } char * put_byte( char *output, uint8_t nVal ) { output[0] = nVal; return output+1; } char * put_be16(char *output, uint16_t nVal ) { output[1] = nVal & 0xff; output[0] = nVal >> 8; return output+2; } char * put_be24(char *output,uint32_t nVal ) { output[2] = nVal & 0xff; output[1] = nVal >> 8; output[0] = nVal >> 16; return output+3; } char * put_be32(char *output, uint32_t nVal ) { output[3] = nVal & 0xff; output[2] = nVal >> 8; output[1] = nVal >> 16; output[0] = nVal >> 24; return output+4; } char * put_be64( char *output, uint64_t nVal ) { output=put_be32( output, nVal >> 32 ); output=put_be32( output, nVal ); return output; } char * put_amf_string( char *c, const char *str ) { uint16_t len = strlen( str ); c=put_be16( c, len ); memcpy(c,str,len); return c+len; } char * put_amf_double( char *c, double d ) { *c++ = AMF_NUMBER; /* type: Number */ { unsigned char *ci, *co; ci = (unsigned char *)&d; co = (unsigned char *)c; co[0] = ci[7]; co[1] = ci[6]; co[2] = ci[5]; co[3] = ci[4]; co[4] = ci[3]; co[5] = ci[2]; co[6] = ci[1]; co[7] = ci[0]; } return c+8; } int main(int argc, _TCHAR* argv[]) { RTMP_LogPrintf("InitSockets!/n"); if (!InitSockets()) return -1; RTMP_debuglevel = RTMP_LOGINFO; RTMP *r; //char uri[]="rtmp://127.0.0.1/live/mp4:test"; char uri[]="rtmp://192.199.15.223/live/mp4:test"; //char uri[]="rtmp://192.199.15.223/oflaDemo/mp4:test"; //char uri[]="rtmp://192.199.15.151/live/test"; //char uri[]="rtmp://221.9.244.4/live/test"; r= RTMP_Alloc(); RTMP_Init(r); RTMP_SetupURL(r, (char*)uri); RTMP_EnableWrite(r); RTMP_Connect(r, NULL); RTMP_ConnectStream(r,0); FILE *yuv=fopen("c://video-qcif.yuv","rb"); FILE *dbg=fopen("C://video-qcif.h264","wb"); unsigned char szNalBuffer[1024*32]; //unsigned char szTempBuffer[1024*32]; unsigned char szBodyBuffer[1024*32]; x264_nal_t *p264Nal; int i264Nal; x264_param_t * p264Param; x264_picture_t * p264Pic; x264_t *p264Handle; p264Param = new x264_param_t(); p264Pic = new x264_picture_t(); memset(p264Pic,0,sizeof(x264_picture_t)); x264_param_default(p264Param); //set default param p264Param->i_width = 176; //set frame width p264Param->i_height = 144; //set frame height /*baseline level 1.1*/ p264Param->b_cabac =0; p264Param->i_bframe =0; p264Param->b_interlaced=0; p264Param->rc.i_rc_method=X264_RC_ABR;//X264_RC_CQP p264Param->i_level_idc=21; p264Param->rc.i_bitrate=64; p264Param->i_keyint_max=20; p264Param->i_fps_num=15; // p264Param->rc.i_qp_constant=22; if((p264Handle = x264_encoder_open(p264Param)) == NULL) { fprintf( stderr, "x264_encoder_open failed/n" ); return -2; } bs_t bs={0}; //fwrite(szNalBuffer,sizeof(char),bs.p-bs.p_start,dbg); x264_picture_alloc(p264Pic, X264_CSP_I420, p264Param->i_width, p264Param->i_height); p264Pic->i_type = X264_TYPE_AUTO; x264_picture_t pic_out; RTMPPacket packet={0}; memset(&packet,0,sizeof(RTMPPacket)); packet.m_nChannel = 0x04; packet.m_headerType = RTMP_PACKET_SIZE_LARGE; packet.m_nTimeStamp = 0; packet.m_nInfoField2 = r->m_stream_id; packet.m_hasAbsTimestamp = 0; packet.m_body =(char *) szBodyBuffer; char * szTmp=(char *)szBodyBuffer; packet.m_packetType = RTMP_PACKET_TYPE_INFO; szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string(szTmp, "@setDataFrame" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string(szTmp, "onMetaData" ); szTmp=put_byte(szTmp, AMF_OBJECT ); szTmp=put_amf_string( szTmp, "author" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_amf_string( szTmp, "copyright" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_amf_string( szTmp, "description" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_amf_string( szTmp, "keywords" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_amf_string( szTmp, "rating" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_amf_string( szTmp, "presetname" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "Custom" ); szTmp=put_amf_string( szTmp, "width" ); szTmp=put_amf_double( szTmp, p264Param->i_width ); szTmp=put_amf_string( szTmp, "width" ); szTmp=put_amf_double( szTmp, p264Param->i_width ); szTmp=put_amf_string( szTmp, "height" ); szTmp=put_amf_double( szTmp, p264Param->i_height ); szTmp=put_amf_string( szTmp, "framerate" ); szTmp=put_amf_double( szTmp, (double)p264Param->i_fps_num / p264Param->i_fps_den ); szTmp=put_amf_string( szTmp, "videocodecid" ); szTmp=put_byte(szTmp, AMF_STRING ); szTmp=put_amf_string( szTmp, "avc1" ); szTmp=put_amf_string( szTmp, "videodatarate" ); szTmp=put_amf_double( szTmp, p264Param->rc.i_bitrate ); szTmp=put_amf_string( szTmp, "avclevel" ); szTmp=put_amf_double( szTmp, p264Param->i_level_idc ); szTmp=put_amf_string( szTmp, "avcprofile" ); szTmp=put_amf_double( szTmp, 66 ); szTmp=put_amf_string( szTmp, "videokeyframe_frequency" ); szTmp=put_amf_double( szTmp, 10 ); szTmp=put_amf_string( szTmp, "" ); szTmp=put_byte( szTmp, AMF_OBJECT_END ); packet.m_nBodySize=szTmp-(char *)szBodyBuffer; RTMP_SendPacket(r,&packet,1); packet.m_packetType = RTMP_PACKET_TYPE_VIDEO; /* VIDEO */ szBodyBuffer[ 0]=0x17; szBodyBuffer[ 1]=0x00; szBodyBuffer[ 2]=0x00; szBodyBuffer[ 3]=0x00; szBodyBuffer[ 4]=0x00; szBodyBuffer[ 5]=0x01; szBodyBuffer[ 6]=0x42; szBodyBuffer[ 7]=0xC0; szBodyBuffer[ 8]=0x15; szBodyBuffer[ 9]=0x03; szBodyBuffer[10]=0x01; szTmp=(char *)szBodyBuffer+11; short slen=0; bs_init(&bs,szNalBuffer,16);//初始话bsW x264_sps_write(&bs, p264Handle->sps);//读取编码器的SPS slen=bs.p-bs.p_start+1;//spslen(short) slen=htons(slen); memcpy(szTmp,&slen,sizeof(short)); szTmp+=sizeof(short); *szTmp=0x67; szTmp+=1; memcpy(szTmp,bs.p_start,bs.p-bs.p_start); szTmp+=bs.p-bs.p_start; *szTmp=0x01; szTmp+=1; bs_init(&bs,szNalBuffer,16);//初始话bs x264_pps_write(&bs, p264Handle->pps);//读取编码器的PPS slen=bs.p-bs.p_start+1;//spslen(short) slen=htons(slen); memcpy(szTmp,&slen,sizeof(short)); szTmp+=sizeof(short); *szTmp=0x68; szTmp+=1; memcpy(szTmp,bs.p_start,bs.p-bs.p_start); szTmp+=bs.p-bs.p_start; packet.m_nBodySize=szTmp-(char *)szBodyBuffer; RTMP_SendPacket(r,&packet,0); //packet.m_nTimeStamp=0xFFFFFF; unsigned int nTimes=0; //unsigned int old=GetTickCount(); packet.m_nTimeStamp=0; while(dbg) { szBodyBuffer[ 0]=0x17; szBodyBuffer[ 1]=0x01; szBodyBuffer[ 2]=0x00; szBodyBuffer[ 3]=0x00; szBodyBuffer[ 4]=0x00; unsigned char * szTmp=szBodyBuffer+5; unsigned char * pNal=szNalBuffer; //if (nTimes%5==0) //{ // p264Pic->i_type=X264_TYPE_IDR; //} //else //{ // p264Pic->i_type=X264_TYPE_P; //} nTimes++; int nFramsInPack=0; while(true) { nFramsInPack++; int nCount; nCount=fread(p264Pic->img.plane[0],1,176*144,yuv); if (nCount<176*144) { fseek(yuv,SEEK_SET,0); continue; } nCount=fread(p264Pic->img.plane[1],1,176*144/4,yuv); if (nCount<176*144/4) { fseek(yuv,SEEK_SET,0); continue; } nCount=fread(p264Pic->img.plane[2],1,176*144/4,yuv); if (nCount<176*144/4) { fseek(yuv,SEEK_SET,0); continue; } if( x264_encoder_encode( p264Handle, &p264Nal, &i264Nal, p264Pic ,&pic_out) < 0 ) { fprintf( stderr, "x264_encoder_encode failed/n" ); } for( int i = 0; i < i264Nal; i++ ) { int i_size; int i_data; i_data = 1024*32; if( ( i_size = x264_nal_encode( pNal, &i_data, 1, &p264Nal[i] ) ) > 0 ) { if ((pNal[4]&0x60)==0) { continue; } fwrite(pNal,sizeof(char),i_size,dbg); fflush(dbg); if (pNal[4]==0x67) { continue; } if (pNal[4]==0x68) { continue; } //unsigned long *len=(unsigned long *)szNalBuffer; //int nlen=htonl(i_size-4); //memcpy(szTmp,szNalBuffer,i_size); //memcpy(szTmp,&nlen,sizeof(unsigned long)); memmove(pNal,pNal+4,i_size-4); fprintf( stderr, "Info x264_nal_encode[%d] Type:0x%x size: %d/n",i,*pNal, i_size); pNal+=i_size-4; } else if( i_size < 0 ) { fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size ); } } Sleep(67); unsigned int nSize=pNal-szNalBuffer; packet.m_nBodySize=nSize+9; if (i264Nal>1) { szBodyBuffer[ 0]=0x17; //packet.m_nTimeStamp=65; // packet.m_nTimeStamp=0; // packet.m_headerType = RTMP_PACKET_SIZE_LARGE; } else { szBodyBuffer[ 0]=0x27; // packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; // packet.m_packetType = RTMP_PACKET_TYPE_VIDEO; /* VIDEO */ } //nSize=htonl(nSize); //memcpy(szTmp,&nSize,sizeof(unsigned int)); //szTmp+=sizeof(unsigned int); //nSize=pNal-szNalBuffer; put_be32((char *)szBodyBuffer+5,nSize); memcpy(szBodyBuffer+9,szNalBuffer,pNal-szNalBuffer); RTMP_SendPacket(r,&packet,0); packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet.m_nTimeStamp+=67; //old=GetTickCount(); //fprintf( stderr, "Info RTMP_SendPacket[%d] /n",nFramsInPack); break; } } return 0; }