<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>10000)</p>
<p>{</p>
<p>m_MAXRTPPACKSIZE=10000;</p>
<p>}</p>
<p>if(m_MAXRTPPACKSIZE<50)</p>
<p>{</p>
<p>m_MAXRTPPACKSIZE=50;</p>
<p>}</p>
<p></p>
<p>memset(&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]&0x1f;</p>
<p>if(type<1||type>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)>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>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&&!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*)&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>>8)&0xff;</p>
<p>cp[3]=m_RTP_Info.rtp_hdr.seq&0xff;</p>
<p></p>
<p>cp[4]=(m_RTP_Info.rtp_hdr.ts>>24)&0xff;</p>
<p>cp[5]=(m_RTP_Info.rtp_hdr.ts>>16)&0xff;</p>
<p>cp[6]=(m_RTP_Info.rtp_hdr.ts>>8)&0xff;</p>
<p>cp[7]=m_RTP_Info.rtp_hdr.ts&0xff;</p>
<p></p>
<p>cp[8]=(m_RTP_Info.rtp_hdr.ssrc>>24)&0xff;</p>
<p>cp[9]=(m_RTP_Info.rtp_hdr.ssrc>>16)&0xff;</p>
<p>cp[10]=(m_RTP_Info.rtp_hdr.ssrc>>8)&0xff;</p>
<p>cp[11]=m_RTP_Info.rtp_hdr.ssrc&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&0xe0)|28;//Typeis28forFU_A</p>
<p>//FUheaderS|E|R|Type</p>
<p>cp[13]=(m_RTP_Info.s_bit<<7)</p>
<p>|(m_RTP_Info.e_bit<<6)|(m_RTP_Info.nal.type&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=&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<<=8;</p>
<p>d32|=cp[2];</p>
<p>d32<<=8;</p>
<p>d32|=cp[1];</p>
<p>d32<<=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(&wLen))</p>
<p>{</p>
<p>//rtppacketprocess</p>
<p>//...</p>
<p>}</p>
<p></p>
<p></p>
</wbr>
RTP_h264打包源码
最新推荐文章于 2021-02-16 02:59:25 发布