RTP_h264打包源码

<wbr><p>classCH264_RTP_PACK</p> <p>{</p> <p>#defineRTP_VERSION2</p> <p>typedefstructNAL_msg_s</p> <p>{</p> <p>booleoFrame;</p> <p>unsignedchartype;//NALtype</p> <p>unsignedchar*start;//pointertofirstlocationinthesendbuffer</p> <p>unsignedchar*end;//pointertolastlocationinsendbuffer</p> <p>unsignedlongsize;</p> <p>}NAL_MSG_t;</p> <p>typedefstruct</p> <p>{</p> <p>//LITTLE_ENDIAN</p> <p>unsignedshortcc:4;/*CSRCcount*/</p> <p>unsignedshortx:1;/*headerextensionflag*/</p> <p>unsignedshortp:1;/*paddingflag*/</p> <p>unsignedshortv:2;/*packettype*/</p> <p>unsignedshortpt:7;/*payloadtype*/</p> <p>unsignedshortm:1;/*markerbit*/</p> <p></p> <p>unsignedshortseq;/*sequencenumber*/</p> <p>unsignedlongts;/*timestamp*/</p> <p>unsignedlongssrc;/*synchronizationsource*/</p> <p>}rtp_hdr_t;</p> <p></p> <p>typedefstructtagRTP_INFO</p> <p>{</p> <p>NAL_MSG_tnal;//NALinformation</p> <p>rtp_hdr_trtp_hdr;//RTPheaderisassembledhere</p> <p>inthdr_len;//lengthofRTPheader</p> <p></p> <p>unsignedchar*pRTP;//pointertowhereRTPpackethasbeemassembled</p> <p>unsignedchar*start;//pointertostartofpayload</p> <p>unsignedchar*end;//pointertoendofpayload</p> <p></p> <p>unsignedints_bit;//bitintheFUheader</p> <p>unsignedinte_bit;//bitintheFUheader</p> <p>boolFU_flag;//fragmentedNALUnitflag</p> <p>}RTP_INFO;</p> <p></p> <p>public:</p> <p>CH264_RTP_PACK(unsignedlongH264SSRC,unsignedcharH264PAYLOADTYPE=96</p> <p>,unsignedshortMAXRTPPACKSIZE=1472)</p> <p>{</p> <p>m_MAXRTPPACKSIZE=MAXRTPPACKSIZE;</p> <p>if(m_MAXRTPPACKSIZE&gt;10000)</p> <p>{</p> <p>m_MAXRTPPACKSIZE=10000;</p> <p>}</p> <p>if(m_MAXRTPPACKSIZE&lt;50)</p> <p>{</p> <p>m_MAXRTPPACKSIZE=50;</p> <p>}</p> <p></p> <p>memset(&amp;m_RTP_Info,0,sizeof(m_RTP_Info));</p> <p></p> <p>m_RTP_Info.rtp_hdr.pt=H264PAYLOADTYPE;</p> <p>m_RTP_Info.rtp_hdr.ssrc=H264SSRC;</p> <p>m_RTP_Info.rtp_hdr.v=RTP_VERSION;</p> <p></p> <p>m_RTP_Info.rtp_hdr.seq=0;</p> <p>}</p> <p></p> <p>~CH264_RTP_PACK(void)</p> <p>{</p> <p>}</p> <p></p> <p>//传入Set的数据必须是一个完整的NAL,起始码为0x00000001。</p> <p>//起始码之前至少预留10个字节,以避免内存COPY操作。</p> <p>//打包完成后,原缓冲区内的数据被破坏。</p> <p>boolSet(unsignedchar*NAL_Buf,unsignedlongNAL_Size</p> <p>,unsignedlongTime_Stamp,boolEnd_Of_Frame)</p> <p>{</p> <p>unsignedlongstartcode=StartCode(NAL_Buf);</p> <p></p> <p>if(startcode!=0x01000000)</p> <p>{</p> <p>returnfalse;</p> <p>}</p> <p></p> <p>inttype=NAL_Buf[4]&amp;0x1f;</p> <p>if(type&lt;1||type&gt;12)</p> <p>{</p> <p>returnfalse;</p> <p>}</p> <p></p> <p>m_RTP_Info.nal.start=NAL_Buf;</p> <p>m_RTP_Info.nal.size=NAL_Size;</p> <p>m_RTP_Info.nal.eoFrame=End_Of_Frame;</p> <p>m_RTP_Info.nal.type=m_RTP_Info.nal.start[4];</p> <p>m_RTP_Info.nal.end=m_RTP_Info.nal.start+m_RTP_Info.nal.size;</p> <p></p> <p>m_RTP_Info.rtp_hdr.ts=Time_Stamp;</p> <p></p> <p>m_RTP_Info.nal.start+=4;//skipthesyncword</p> <p></p> <p>if((m_RTP_Info.nal.size+7)&gt;m_MAXRTPPACKSIZE)</p> <p>{</p> <p>m_RTP_Info.FU_flag=true;</p> <p>m_RTP_Info.s_bit=1;</p> <p>m_RTP_Info.e_bit=0;</p> <p></p> <p>m_RTP_Info.nal.start+=1;//skipNALheader</p> <p>}</p> <p>else</p> <p>{</p> <p>m_RTP_Info.FU_flag=false;</p> <p>m_RTP_Info.s_bit=m_RTP_Info.e_bit=0;</p> <p>}</p> <p></p> <p>m_RTP_Info.start=m_RTP_Info.end=m_RTP_Info.nal.start;</p> <p>m_bBeginNAL=true;</p> <p></p> <p>returntrue;</p> <p>}</p> <p></p> <p>//循环调用Get获取RTP包,直到返回值为NULL</p> <p>unsignedchar*Get(unsignedshort*pPacketSize)</p> <p>{</p> <p>if(m_RTP_Info.end==m_RTP_Info.nal.end)</p> <p>{</p> <p>*pPacketSize=0;</p> <p>returnNULL;</p> <p>}</p> <p></p> <p>if(m_bBeginNAL)</p> <p>{</p> <p>m_bBeginNAL=false;</p> <p>}</p> <p>else</p> <p>{</p> <p>m_RTP_Info.start=m_RTP_Info.end;//continuewiththenextRTP-FUpacket</p> <p>}</p> <p></p> <p>intbytesLeft=m_RTP_Info.nal.end-m_RTP_Info.start;</p> <p>intmaxSize=m_MAXRTPPACKSIZE-12;//sizeof(basicrtpheader)==12bytes</p> <p>if(m_RTP_Info.FU_flag)</p> <p>maxSize-=2;</p> <p></p> <p>if(bytesLeft&gt;maxSize)</p> <p>{</p> <p>//limit RTP packetsize to 1472 bytes</p> <p>m_RTP_Info.end=m_RTP_Info.start+maxSize;</p> <p>}</p> <p>else</p> <p>{</p> <p>m_RTP_Info.end=m_RTP_Info.start+bytesLeft;</p> <p>}</p> <p></p> <p>if(m_RTP_Info.FU_flag)</p> <p>{//multiplepacketNALslice</p> <p>if(m_RTP_Info.end==m_RTP_Info.nal.end)</p> <p>{</p> <p>m_RTP_Info.e_bit=1;</p> <p>}</p> <p>}</p> <p>//should be set at EofFrame</p> <p>m_RTP_Info.rtp_hdr.m=m_RTP_Info.nal.eoFrame?1:0;</p> <p>if(m_RTP_Info.FU_flag&amp;&amp;!m_RTP_Info.e_bit)</p> <p>{</p> <p>m_RTP_Info.rtp_hdr.m=0;</p> <p>}</p> <p></p> <p>m_RTP_Info.rtp_hdr.seq++;</p> <p>unsignedchar*cp=m_RTP_Info.start;</p> <p>cp-=(m_RTP_Info.FU_flag?14:12);</p> <p>m_RTP_Info.pRTP=cp;</p> <p></p> <p>unsignedchar*cp2=(unsignedchar*)&amp;m_RTP_Info.rtp_hdr;</p> <p>cp[0]=cp2[0];</p> <p>cp[1]=cp2[1];</p> <p></p> <p>cp[2]=(m_RTP_Info.rtp_hdr.seq&gt;&gt;8)&amp;0xff;</p> <p>cp[3]=m_RTP_Info.rtp_hdr.seq&amp;0xff;</p> <p></p> <p>cp[4]=(m_RTP_Info.rtp_hdr.ts&gt;&gt;24)&amp;0xff;</p> <p>cp[5]=(m_RTP_Info.rtp_hdr.ts&gt;&gt;16)&amp;0xff;</p> <p>cp[6]=(m_RTP_Info.rtp_hdr.ts&gt;&gt;8)&amp;0xff;</p> <p>cp[7]=m_RTP_Info.rtp_hdr.ts&amp;0xff;</p> <p></p> <p>cp[8]=(m_RTP_Info.rtp_hdr.ssrc&gt;&gt;24)&amp;0xff;</p> <p>cp[9]=(m_RTP_Info.rtp_hdr.ssrc&gt;&gt;16)&amp;0xff;</p> <p>cp[10]=(m_RTP_Info.rtp_hdr.ssrc&gt;&gt;8)&amp;0xff;</p> <p>cp[11]=m_RTP_Info.rtp_hdr.ssrc&amp;0xff;</p> <p>m_RTP_Info.hdr_len=12;</p> <p>/*!</p> <p>*\nTheFUindicatoroctethasthefollowingformat:</p> <p>*\n</p> <p>*\n+---------------+</p> <p>*\nMSB|0|1|2|3|4|5|6|7|LSB</p> <p>*\n+-+-+-+-+-+-+-+-+</p> <p>*\n|F|NRI|Type|</p> <p>*\n+---------------+</p> <p>*\n</p> <p>*\nTheFUheaderhasthefollowingformat:</p> <p>*\n</p> <p>*\n+---------------+</p> <p>*\n|0|1|2|3|4|5|6|7|</p> <p>*\n+-+-+-+-+-+-+-+-+</p> <p>*\n|S|E|R|Type|</p> <p>*\n+---------------+</p> <p>*/</p> <p>if(m_RTP_Info.FU_flag)</p> <p>{</p> <p>//FUindicatorF|NRI|Type</p> <p>cp[12]=(m_RTP_Info.nal.type&amp;0xe0)|28;//Typeis28forFU_A</p> <p>//FUheaderS|E|R|Type</p> <p>cp[13]=(m_RTP_Info.s_bit&lt;&lt;7)</p> <p>|(m_RTP_Info.e_bit&lt;&lt;6)|(m_RTP_Info.nal.type&amp;0x1f);</p> <p>//R=0,mustbeignoredbyreceiver</p> <p></p> <p>m_RTP_Info.s_bit=m_RTP_Info.e_bit=0;</p> <p>m_RTP_Info.hdr_len=14;</p> <p>}</p> <p>m_RTP_Info.start=&amp;cp[m_RTP_Info.hdr_len];//newstartofpayload</p> <p></p> <p>*pPacketSize=m_RTP_Info.hdr_len+(m_RTP_Info.end-m_RTP_Info.start);</p> <p>returnm_RTP_Info.pRTP;</p> <p>}</p> <p></p> <p>private:</p> <p>unsignedintStartCode(unsignedchar*cp)</p> <p>{</p> <p>unsignedintd32;</p> <p>d32=cp[3];</p> <p>d32&lt;&lt;=8;</p> <p>d32|=cp[2];</p> <p>d32&lt;&lt;=8;</p> <p>d32|=cp[1];</p> <p>d32&lt;&lt;=8;</p> <p>d32|=cp[0];</p> <p>returnd32;</p> <p>}</p> <p></p> <p>private:</p> <p>RTP_INFOm_RTP_Info;</p> <p>boolm_bBeginNAL;</p> <p>unsignedshortm_MAXRTPPACKSIZE;</p> <p>};</p> <p>//END</p> <p>//使用代码:</p> <p>DWORDH264SSRC;</p> <p>CH264_RTP_PACKpack(H264SSRC);</p> <p>BYTE*pVideoData;</p> <p>DWORDSize,ts;</p> <p>boolIsEndOfFrame;</p> <p>WORDwLen;</p> <p>pack.Set(pVideoData,Size,ts,IsEndOfFrame);</p> <p>BYTE*pPacket;</p> <p>while(pPacket=pack.Get(&amp;wLen))</p> <p>{</p> <p>//rtppacketprocess</p> <p>//...</p> <p>}</p> <p></p> <p></p> </wbr>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值