织梦CMS - 轻松建站从此开始!

罗索实验室

当前位置: 主页 > 流媒体开发 > 流媒体开发 >

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

jackyhwei 发布于 2011-08-16 11:05 点击:次 
直接上代码 //demo.cpp:定义控制台应用程序的入口点。 // #includestdafx.h #includeMqOaI.h extern C { #include../../common/common.h #include../../common/cpu.h #include../../x264.h #include../../encoder/set.h } #includelibrtmp/rtmp_sys.h #includelibrtmp/
TAG:

直接上代码

  1. // demo.cpp : 定义控制台应用程序的入口点。 
  2. // 
  3. #include "stdafx.h" 
  4. #include <MqOaI.h> 
  5. extern "C"  
  6. #include "../../common/common.h" 
  7. #include "../../common/cpu.h"" 
  8. #include "../../x264.h" 
  9. #include "../../encoder/set.h" 
  10. #include "librtmp/rtmp_sys.h" 
  11. #include "librtmp/log.h" 
  12. #include "librtmp/amf.h" 
  13. #include "CameraDS.h" 
  14. void ConvertYCbCr2BGR(unsigned char *pYUV,unsigned char *pBGR
  15. ,int iWidth,int iHeight); 
  16. void ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned char *yuv); 
  17. int InitSockets() 
  18. #ifdef WIN32 
  19.     WORD version; 
  20.     WSADATA wsaData; 
  21.     version = MAKEWORD(1, 1); 
  22.     return (WSAStartup(version, &wsaData) == 0); 
  23. #else 
  24.     return TRUE; 
  25. #endif 
  26. inline void CleanupSockets() 
  27. #ifdef WIN32 
  28.     WSACleanup(); 
  29. #endif 
  30. #define HEX2BIN(a)      (((a)&0x40)?((a)&0xf)+9:((a)&0xf)) 
  31. int hex2bin(char *str, char **hex) 
  32.     char *ptr; 
  33.     int i, l = strlen(str); 
  34.     if (l & 1) 
  35.         return 0; 
  36.     *hex = (char *)malloc(l/2); 
  37.     ptr = *hex; 
  38.     if (!ptr) 
  39.         return 0; 
  40.     for (i=0; i<l; i+=2) 
  41.         *ptr++ = (HEX2BIN(str[i]) << 4) | HEX2BIN(str[i+1]); 
  42.     return l/2; 
  43. char * put_byte( char *output, uint8_t nVal ) 
  44.     output[0] = nVal; 
  45.     return output+1; 
  46. char * put_be16(char *output, uint16_t nVal ) 
  47.     output[1] = nVal & 0xff; 
  48.     output[0] = nVal >> 8; 
  49.     return output+2; 
  50. char * put_be24(char *output,uint32_t nVal ) 
  51.     output[2] = nVal & 0xff; 
  52.     output[1] = nVal >> 8; 
  53.     output[0] = nVal >> 16; 
  54.     return output+3; 
  55. char * put_be32(char *output, uint32_t nVal ) 
  56.     output[3] = nVal & 0xff; 
  57.     output[2] = nVal >> 8; 
  58.     output[1] = nVal >> 16; 
  59.     output[0] = nVal >> 24; 
  60.     return output+4; 
  61. char *  put_be64( char *output, uint64_t nVal ) 
  62.     output=put_be32( output, nVal >> 32 ); 
  63.     output=put_be32( output, nVal ); 
  64.     return output; 
  65. char * put_amf_string( char *c, const char *str ) 
  66.     uint16_t len = strlen( str ); 
  67.     c=put_be16( c, len ); 
  68.     memcpy(c,str,len); 
  69.     return c+len; 
  70. char * put_amf_double( char *c, double d ) 
  71.     *c++ = AMF_NUMBER;  /* type: Number */ 
  72.     { 
  73.         unsigned char *ci, *co; 
  74.         ci = (unsigned char *)&d; 
  75.         co = (unsigned char *)c; 
  76.         co[0] = ci[7]; 
  77.         co[1] = ci[6]; 
  78.         co[2] = ci[5]; 
  79.         co[3] = ci[4]; 
  80.         co[4] = ci[3]; 
  81.         co[5] = ci[2]; 
  82.         co[6] = ci[1]; 
  83.         co[7] = ci[0]; 
  84.     } 
  85.     return c+8; 
  86. int main(int argc, char * argv[]) 
  87.     if (argc<2)  
  88.     { 
  89.         RTMP_LogPrintf("RTMP_URL IS NULL!!!/n"); 
  90.         //return -1; 
  91.     } 
  92.     if (!InitSockets()) 
  93.     { 
  94.         RTMP_LogPrintf("InitSockets Error!/n"); 
  95.         return -1; 
  96.     } 
  97.     RTMP_LogPrintf("InitSockets!/n"); 
  98.     CoInitialize(NULL); 
  99.     CCameraDS camera; 
  100.     if (!camera.OpenCamera(0,320,240,false)) 
  101.     { 
  102.         RTMP_LogPrintf("Open Camera Error/n"); 
  103.         return -1; 
  104.     } 
  105.     int nHeight=camera.GetHeight(); 
  106.     int nWidth=camera.GetWidth(); 
  107.     unsigned char * szRGBBuffer=new unsigned char[nHeight*nWidth * 3]; 
  108.     RTMP_LogPrintf("Camera Open Scuess,Picture Size[%2dx%d]/n",nWidth,nHeight); 
  109.     RTMP_debuglevel = RTMP_LOGINFO; 
  110.     RTMP *r; 
  111.     //char uri[]="rtmp://127.0.0.1/live/test"; 
  112.     //char uri[]="rtmp://192.199.15.223/live/test"; 
  113.     //char uri[]="rtmp://221.9.244.4/live/jltv"; 
  114.     //char uri[]="rtmp://192.199.15.223/oflaDemo/red5StreamDemo"; 
  115.     //char uri[]="rtmp://192.199.15.151/live/test"; 
  116.     char uri[]="rtmp://127.0.0.1/live/zzj"
  117.     r= RTMP_Alloc(); 
  118.     RTMP_Init(r); 
  119.     RTMP_SetupURL(r, (char*)uri); 
  120.     RTMP_EnableWrite(r); 
  121.     RTMP_Connect(r, NULL); 
  122.     RTMP_ConnectStream(r,0); 
  123.     unsigned char szNalBuffer[1024*32]; 
  124.     unsigned char szBodyBuffer[1024*32]; 
  125.     x264_nal_t  *p264Nal; 
  126.     int         i264Nal; 
  127.     x264_param_t * p264Param; 
  128.     x264_picture_t * p264Pic; 
  129.     x264_t *p264Handle;  
  130.     p264Param = new x264_param_t(); 
  131.     p264Pic  = new x264_picture_t(); 
  132.     memset(p264Pic,0,sizeof(x264_picture_t)); 
  133.     x264_param_default(p264Param);  //set default param 
  134.     p264Param->i_threads=2; 
  135.     p264Param->i_width  = nWidth;   //set frame width 
  136.     p264Param->i_height = nHeight;  //set frame height 
  137.     /*baseline level 1.1*/ 
  138.     p264Param->b_cabac =0;  
  139.     p264Param->i_bframe =0; 
  140.     p264Param->b_interlaced=0; 
  141.     p264Param->rc.i_rc_method=X264_RC_ABR;//X264_RC_CQP 
  142.     p264Param->i_level_idc=21; 
  143.     p264Param->rc.i_bitrate=200; 
  144.     p264Param->i_fps_num=30; 
  145.     p264Param->i_keyint_max=p264Param->i_fps_num*3; 
  146.     if((p264Handle = x264_encoder_open(p264Param)) == NULL) 
  147.     { 
  148.         fprintf( stderr, "x264_encoder_open failed/n" ); 
  149.         return -2; 
  150.     } 
  151.     bs_t bs={0}; 
  152.     x264_picture_alloc(p264Pic, X264_CSP_YV12, p264Param->i_width
  153. , p264Param->i_height); 
  154.     p264Pic->i_type = X264_TYPE_AUTO; 
  155.     x264_picture_t pic_out; 
  156.     RTMPPacket packet={0}; 
  157.     memset(&packet,0,sizeof(RTMPPacket)); 
  158.     packet.m_nChannel = 0x04; 
  159.     packet.m_headerType = RTMP_PACKET_SIZE_LARGE; 
  160.     packet.m_nTimeStamp = 0; 
  161.     packet.m_nInfoField2 = r->m_stream_id; 
  162.     packet.m_hasAbsTimestamp = 0; 
  163.     packet.m_body =(char *) szBodyBuffer; 
  164.     char * szTmp=(char *)szBodyBuffer; 
  165.     packet.m_packetType = RTMP_PACKET_TYPE_INFO; 
  166.     szTmp=put_byte(szTmp, AMF_STRING ); 
  167.     szTmp=put_amf_string(szTmp, "@setDataFrame" ); 
  168.     szTmp=put_byte(szTmp, AMF_STRING ); 
  169.     szTmp=put_amf_string(szTmp, "onMetaData" ); 
  170.     szTmp=put_byte(szTmp, AMF_OBJECT ); 
  171.     szTmp=put_amf_string( szTmp, "author" ); 
  172.     szTmp=put_byte(szTmp, AMF_STRING ); 
  173.     szTmp=put_amf_string( szTmp, "" ); 
  174.     szTmp=put_amf_string( szTmp, "copyright" ); 
  175.     szTmp=put_byte(szTmp, AMF_STRING ); 
  176.     szTmp=put_amf_string( szTmp, "" ); 
  177.     szTmp=put_amf_string( szTmp, "description" ); 
  178.     szTmp=put_byte(szTmp, AMF_STRING ); 
  179.     szTmp=put_amf_string( szTmp, "" ); 
  180.     szTmp=put_amf_string( szTmp, "keywords" ); 
  181.     szTmp=put_byte(szTmp, AMF_STRING ); 
  182.     szTmp=put_amf_string( szTmp, "" ); 
  183.     szTmp=put_amf_string( szTmp, "rating" ); 
  184.     szTmp=put_byte(szTmp, AMF_STRING ); 
  185.     szTmp=put_amf_string( szTmp, "" ); 
  186.     szTmp=put_amf_string( szTmp, "presetname" ); 
  187.     szTmp=put_byte(szTmp, AMF_STRING ); 
  188.     szTmp=put_amf_string( szTmp, "Custom" ); 
  189.     szTmp=put_amf_string( szTmp, "width" ); 
  190.     szTmp=put_amf_double( szTmp, p264Param->i_width ); 
  191.     szTmp=put_amf_string( szTmp, "width" ); 
  192.     szTmp=put_amf_double( szTmp, p264Param->i_width ); 
  193.     szTmp=put_amf_string( szTmp, "height" ); 
  194.     szTmp=put_amf_double( szTmp, p264Param->i_height ); 
  195.     szTmp=put_amf_string( szTmp, "framerate" ); 
  196.     szTmp=put_amf_double( szTmp,
  197.  (double)p264Param->i_fps_num / p264Param->i_fps_den ); 
  198.     szTmp=put_amf_string( szTmp, "videocodecid" ); 
  199.     szTmp=put_byte(szTmp, AMF_STRING ); 
  200.     szTmp=put_amf_string( szTmp, "avc1" ); 
  201.     szTmp=put_amf_string( szTmp, "videodatarate" ); 
  202.     szTmp=put_amf_double( szTmp, p264Param->rc.i_bitrate );  
  203.     szTmp=put_amf_string( szTmp, "avclevel" ); 
  204.     szTmp=put_amf_double( szTmp, p264Param->i_level_idc );  
  205.     szTmp=put_amf_string( szTmp, "avcprofile" ); 
  206.     szTmp=put_amf_double( szTmp, 0x42 );  
  207.     szTmp=put_amf_string( szTmp, "videokeyframe_frequency" ); 
  208.     szTmp=put_amf_double( szTmp, 3 );  
  209.     szTmp=put_amf_string( szTmp, "" ); 
  210.     szTmp=put_byte( szTmp, AMF_OBJECT_END ); 
  211.     packet.m_nBodySize=szTmp-(char *)szBodyBuffer; 
  212.     RTMP_SendPacket(r,&packet,1); 
  213.     packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;   /* VIDEO */ 
  214.     szBodyBuffer[ 0]=0x17; 
  215.     szBodyBuffer[ 1]=0x00; 
  216.     szBodyBuffer[ 2]=0x00; 
  217.     szBodyBuffer[ 3]=0x00; 
  218.     szBodyBuffer[ 4]=0x00; 
  219.     szBodyBuffer[ 5]=0x01; 
  220.     szBodyBuffer[ 6]=0x42; 
  221.     szBodyBuffer[ 7]=0xC0; 
  222.     szBodyBuffer[ 8]=0x15; 
  223.     szBodyBuffer[ 9]=0x03; 
  224.     szBodyBuffer[10]=0x01; 
  225.     szTmp=(char *)szBodyBuffer+11; 
  226.     short slen=0; 
  227.     bs_init(&bs,szNalBuffer,16);//初始话bs 
  228.     x264_sps_write(&bs, p264Handle->sps);//读取编码器的SPS 
  229.     slen=bs.p-bs.p_start+1;//spslen(short) 
  230.     slen=htons(slen); 
  231.     memcpy(szTmp,&slen,sizeof(short)); 
  232.     szTmp+=sizeof(short); 
  233.     *szTmp=0x67; 
  234.     szTmp+=1; 
  235.     memcpy(szTmp,bs.p_start,bs.p-bs.p_start); 
  236.     szTmp+=bs.p-bs.p_start; 
  237.     *szTmp=0x01; 
  238.     szTmp+=1; 
  239.     bs_init(&bs,szNalBuffer,16);//初始话bs 
  240.     x264_pps_write(&bs, p264Handle->pps);//读取编码器的PPS 
  241.     slen=bs.p-bs.p_start+1;//spslen(short) 
  242.     slen=htons(slen); 
  243.     memcpy(szTmp,&slen,sizeof(short)); 
  244.     szTmp+=sizeof(short); 
  245.     *szTmp=0x68; 
  246.     szTmp+=1; 
  247.     memcpy(szTmp,bs.p_start,bs.p-bs.p_start); 
  248.     szTmp+=bs.p-bs.p_start; 
  249.     packet.m_nBodySize=szTmp-(char *)szBodyBuffer; 
  250.     RTMP_SendPacket(r,&packet,0); 
  251.     unsigned int nTimes=0; 
  252.     unsigned int oldTick=GetTickCount(); 
  253.     unsigned int newTick=0; 
  254.     packet.m_nTimeStamp=0; 
  255.      
  256.     while(true
  257.     { 
  258.         szBodyBuffer[ 0]=0x17; 
  259.         szBodyBuffer[ 1]=0x01; 
  260.         szBodyBuffer[ 2]=0x00; 
  261.         szBodyBuffer[ 3]=0x00; 
  262.         szBodyBuffer[ 4]=0x42; 
  263.         unsigned char * szTmp=szBodyBuffer+5; 
  264.         unsigned  char * pNal=szNalBuffer; 
  265.         nTimes++; 
  266.         int nFramsInPack=0; 
  267.         while(true
  268.         { 
  269.             nFramsInPack++; 
  270.             unsigned char * pCameraBuf = camera.QueryFrame(); 
  271.             if (!pCameraBuf) 
  272.             { 
  273.                 return -1; 
  274.             } 
  275.             for(int ii=0;ii<nHeight;ii++) 
  276.             { 
  277. memcpy(szRGBBuffer+(nWidth*3)*(nHeight-ii-1),pCameraBuf+(nWidth*3)*ii,nWidth*3); 
  278. //memcpy(pCameraBuf+nWidth*(nHeight-ii-1),pCameraBuf+nWidth*ii,nWidth*3); 
  279. //memcpy(szLineBuffer,pCameraBuf+nWidth*(nHeight-ii-1),nWidth*3); 
  280.             } 
  281.             ConvertRGB2YUV(nWidth,nHeight,szRGBBuffer,p264Pic->img.plane[0]); 
  282. //memcpy(p264Pic->img.plane[0],szNalBuffer,nWidth*nHeight); 
  283. //memcpy(p264Pic->img.plane[1],szNalBuffer+nWidth*nHeight,nWidth*nHeight/4); 
  284. //memcpy(p264Pic->img.plane[2],szNalBuffer+nWidth*nHeight*5/4,nWidth*nHeight/4); 
  285.             /* 
  286.             int nCount; 
  287.             nCount=fread(p264Pic->img.plane[0],1,176*144,yuv); 
  288.             if (nCount<176*144) 
  289.             { 
  290.             fseek(yuv,SEEK_SET,0); 
  291.             continue; 
  292.             } 
  293.             nCount=fread(p264Pic->img.plane[1],1,176*144/4,yuv); 
  294.             if (nCount<176*144/4) 
  295.             { 
  296.             fseek(yuv,SEEK_SET,0); 
  297.             continue; 
  298.             } 
  299.             nCount=fread(p264Pic->img.plane[2],1,176*144/4,yuv); 
  300.             if (nCount<176*144/4) 
  301.             { 
  302.             fseek(yuv,SEEK_SET,0); 
  303.             continue; 
  304.             } 
  305.             */ 
  306. if( x264_encoder_encode( p264Handle, &p264Nal, &i264Nal, p264Pic ,&pic_out) < 0 ) 
  307.             { 
  308.                 fprintf( stderr, "x264_encoder_encode failed/n" ); 
  309.             } 
  310.             forint i = 0; i < i264Nal; i++ ) 
  311.             { 
  312.                 int i_size; 
  313.                 int i_data; 
  314.                 i_data = 1024*32; 
  315. if( ( i_size = x264_nal_encode( pNal, &i_data, 1, &p264Nal[i] ) ) > 0 ) 
  316.                 { 
  317.                     if ((pNal[4]&0x60)==0) 
  318.                     { 
  319.                         continue
  320.                     } 
  321.                     if (pNal[4]==0x67) 
  322.                     { 
  323.                         continue
  324.                     } 
  325.                     if (pNal[4]==0x68) 
  326.                     { 
  327.                         continue
  328.                     } 
  329.                     memmove(pNal,pNal+4,i_size-4); 
  330.                     pNal+=i_size-4; 
  331.                 } 
  332.                 else if( i_size < 0 ) 
  333.                 { 
  334. fprintf( stderr,"need to increase buffer size (size=%d)/n", -i_size ); 
  335.                 } 
  336.             } 
  337.             unsigned int nSize=pNal-szNalBuffer; 
  338.             packet.m_nBodySize=nSize+9; 
  339.             if (i264Nal>1) 
  340.             { 
  341.                 szBodyBuffer[ 0]=0x17; 
  342.             } 
  343.             else 
  344.             { 
  345.                 szBodyBuffer[ 0]=0x27; 
  346.             } 
  347.             put_be32((char *)szBodyBuffer+5,nSize); 
  348.             memcpy(szBodyBuffer+9,szNalBuffer,pNal-szNalBuffer); 
  349.             RTMP_SendPacket(r,&packet,0); 
  350.             Sleep(20); 
  351.             newTick=GetTickCount(); 
  352. //RTMP_LogStatus("/rInfo NAUL Type:0x%02x size: %5d Tick:%03d %03d",szNalBuffer[0]
  353. , nSize,33-nSleep,GetTickCount()-oldTick+nSleep); 
  354.             packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; 
  355.             packet.m_nTimeStamp+=newTick-oldTick; 
  356.             oldTick=newTick; 
  357.             break
  358.         } 
  359.     } 
  360.     return 0; 

 

(zblue78)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www1.rosoo.net/a/201105/12417.html]
本文出处:CSDN博客 作者:zblue78
顶一下
(7)
63.6%
踩一下
(4)
36.4%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容