H264通过RTMP发布 V2.0 (Red5 Wowza 测试通过)

 

 

直接上代码

 

// demo.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <MqOaI.h> extern "C" { #include "../../common/common.h" #include "../../common/cpu.h"" #include "../../x264.h" #include "../../encoder/set.h" } #include "librtmp/rtmp_sys.h" #include "librtmp/log.h" #include "librtmp/amf.h" #include "CameraDS.h" void ConvertYCbCr2BGR(unsigned char *pYUV,unsigned char *pBGR,int iWidth,int iHeight); void ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned char *yuv); 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, char * argv[]) { if (argc<2) { RTMP_LogPrintf("RTMP_URL IS NULL!!!/n"); //return -1; } if (!InitSockets()) { RTMP_LogPrintf("InitSockets Error!/n"); return -1; } RTMP_LogPrintf("InitSockets!/n"); CoInitialize(NULL); CCameraDS camera; if (!camera.OpenCamera(0,320,240,false)) { RTMP_LogPrintf("Open Camera Error/n"); return -1; } int nHeight=camera.GetHeight(); int nWidth=camera.GetWidth(); unsigned char * szRGBBuffer=new unsigned char[nHeight*nWidth * 3]; RTMP_LogPrintf("Camera Open Scuess! Picture Size[%2dx%d]/n",nWidth,nHeight); RTMP_debuglevel = RTMP_LOGINFO; RTMP *r; //char uri[]="rtmp://127.0.0.1/live/test"; //char uri[]="rtmp://192.199.15.223/live/test"; //char uri[]="rtmp://221.9.244.4/live/jltv"; //char uri[]="rtmp://192.199.15.223/oflaDemo/red5StreamDemo"; //char uri[]="rtmp://192.199.15.151/live/test"; char uri[]="rtmp://127.0.0.1/live/zzj"; r= RTMP_Alloc(); RTMP_Init(r); RTMP_SetupURL(r, (char*)uri); RTMP_EnableWrite(r); RTMP_Connect(r, NULL); RTMP_ConnectStream(r,0); unsigned char szNalBuffer[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_threads=2; p264Param->i_width = nWidth; //set frame width p264Param->i_height = nHeight; //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=200; p264Param->i_fps_num=30; p264Param->i_keyint_max=p264Param->i_fps_num*3; if((p264Handle = x264_encoder_open(p264Param)) == NULL) { fprintf( stderr, "x264_encoder_open failed/n" ); return -2; } bs_t bs={0}; x264_picture_alloc(p264Pic, X264_CSP_YV12, 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, 0x42 ); szTmp=put_amf_string( szTmp, "videokeyframe_frequency" ); szTmp=put_amf_double( szTmp, 3 ); 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);//初始话bs 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); unsigned int nTimes=0; unsigned int oldTick=GetTickCount(); unsigned int newTick=0; packet.m_nTimeStamp=0; while(true) { szBodyBuffer[ 0]=0x17; szBodyBuffer[ 1]=0x01; szBodyBuffer[ 2]=0x00; szBodyBuffer[ 3]=0x00; szBodyBuffer[ 4]=0x42; unsigned char * szTmp=szBodyBuffer+5; unsigned char * pNal=szNalBuffer; nTimes++; int nFramsInPack=0; while(true) { nFramsInPack++; unsigned char * pCameraBuf = camera.QueryFrame(); if (!pCameraBuf) { return -1; } for(int ii=0;ii<nHeight;ii++) { memcpy(szRGBBuffer+(nWidth*3)*(nHeight-ii-1),pCameraBuf+(nWidth*3)*ii,nWidth*3); //memcpy(pCameraBuf+nWidth*(nHeight-ii-1),pCameraBuf+nWidth*ii,nWidth*3); //memcpy(szLineBuffer,pCameraBuf+nWidth*(nHeight-ii-1),nWidth*3); } ConvertRGB2YUV(nWidth,nHeight,szRGBBuffer,p264Pic->img.plane[0]); //memcpy(p264Pic->img.plane[0],szNalBuffer,nWidth*nHeight); //memcpy(p264Pic->img.plane[1],szNalBuffer+nWidth*nHeight,nWidth*nHeight/4); //memcpy(p264Pic->img.plane[2],szNalBuffer+nWidth*nHeight*5/4,nWidth*nHeight/4); /* 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; } if (pNal[4]==0x67) { continue; } if (pNal[4]==0x68) { continue; } memmove(pNal,pNal+4,i_size-4); pNal+=i_size-4; } else if( i_size < 0 ) { fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size ); } } unsigned int nSize=pNal-szNalBuffer; packet.m_nBodySize=nSize+9; if (i264Nal>1) { szBodyBuffer[ 0]=0x17; } else { szBodyBuffer[ 0]=0x27; } put_be32((char *)szBodyBuffer+5,nSize); memcpy(szBodyBuffer+9,szNalBuffer,pNal-szNalBuffer); RTMP_SendPacket(r,&packet,0); Sleep(20); newTick=GetTickCount(); //RTMP_LogStatus("/rInfo NAUL Type:0x%02x size: %5d Tick:%03d %03d",szNalBuffer[0], nSize,33-nSleep,GetTickCount()-oldTick+nSleep); packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet.m_nTimeStamp+=newTick-oldTick; oldTick=newTick; break; } } return 0; }  

 

H264通过RTMP发布 V2.0 (Red5 Wowza 测试通过)_第1张图片

你可能感兴趣的:(String,测试,null,byte,hex,output)