RTP_h264解包源码

//// classCH264_RTP_UNPACK

classCH264_RTP_UNPACK

{

#defineRTP_VERSION2

#defineBUF_SIZE(1024*500)

typedefstruct

{

//LITTLE_ENDIAN

unsignedshortcc:4;/*CSRCcount*/

unsignedshortx:1;/*headerextensionflag*/

unsignedshortp:1;/*paddingflag*/

unsignedshortv:2;/*packettype*/

unsignedshortpt:7;/*payloadtype*/

unsignedshortm:1;/*markerbit*/

unsignedshortseq;/*sequencenumber*/

unsignedlongts;/*timestamp*/

unsignedlongssrc;/*synchronizationsource*/

}rtp_hdr_t;

public:

CH264_RTP_UNPACK(HRESULT&hr,unsignedcharH264PAYLOADTYPE=96)

:m_bSPSFound(false)

,m_bWaitKeyFrame(true)

,m_bPrevFrameEnd(false)

,m_bAssemblingFrame(false)

,m_wSeq(1234)

,m_ssrc(0)

{

m_pBuf=newBYTE[BUF_SIZE];

if(m_pBuf==NULL)

{

hr=E_OUTOFMEMORY;

return;

}

m_H264PAYLOADTYPE=H264PAYLOADTYPE;

m_pEnd=m_pBuf+BUF_SIZE;

m_pStart=m_pBuf;

m_dwSize=0;

hr=S_OK;

}

~CH264_RTP_UNPACK(void)

{

delete[]m_pBuf;

}

//pBuf为H264RTP视频数据包,nSize为RTP视频数据包字节长度,outSize为输出视频数据帧字节长度。

//返回值为指向视频数据帧的指针。输入数据可能被破坏。

BYTE*Parse_RTP_Packet(BYTE*pBuf,unsignedshortnSize,int*outSize)

{

if(nSize<=12)

{

returnNULL;

}

BYTE*cp=(BYTE*)&m_RTP_Header;

cp[0]=pBuf[0];

cp[1]=pBuf[1];

m_RTP_Header.seq=pBuf[2];

m_RTP_Header.seq<<=8;

m_RTP_Header.seq|=pBuf[3];

m_RTP_Header.ts=pBuf[4];

m_RTP_Header.ts<<=8;

m_RTP_Header.ts|=pBuf[5];

m_RTP_Header.ts<<=8;

m_RTP_Header.ts|=pBuf[6];

m_RTP_Header.ts<<=8;

m_RTP_Header.ts|=pBuf[7];

m_RTP_Header.ssrc=pBuf[8];

m_RTP_Header.ssrc<<=8;

m_RTP_Header.ssrc|=pBuf[9];

m_RTP_Header.ssrc<<=8;

m_RTP_Header.ssrc|=pBuf[10];

m_RTP_Header.ssrc<<=8;

m_RTP_Header.ssrc|=pBuf[11];

BYTE*pPayload=pBuf+12;

DWORDPayloadSize=nSize-12;

//ChecktheRTPversionnumber(itshouldbe2):

if(m_RTP_Header.v!=RTP_VERSION)

{

returnNULL;

}

/*

//SkipoveranyCSRCidentifiersintheheader:

if(m_RTP_Header.cc)

{

longcc=m_RTP_Header.cc*4;

if(Size<cc)

{

returnNULL;

}

Size-=cc;

p+=cc;

}

//Checkfor(&ignore)anyRTPheaderextension

if(m_RTP_Header.x)

{

if(Size<4)

{

returnNULL;

}

Size-=4;

p+=2;

longl=p[0];

l<<=8;

l|=p[1];

p+=2;

l*=4;

if(Size<l);

{

returnNULL;

}

Size-=l;

p+=l;

}

//Discardanypaddingbytes:

if(m_RTP_Header.p)

{

if(Size==0)

{

returnNULL;

}

longPadding=p[Size-1];

if(Size<Padding)

{

returnNULL;

}

Size-=Padding;

}*/

//CheckthePayloadType.

if(m_RTP_Header.pt!=m_H264PAYLOADTYPE)

{

returnNULL;

}

intPayloadType=pPayload[0]&0x1f;

intNALType=PayloadType;

if(NALType==28)//FU_A

{

if(PayloadSize<2)

{

returnNULL;

}

NALType=pPayload[1]&0x1f;

}

if(m_ssrc!=m_RTP_Header.ssrc)

{

m_ssrc=m_RTP_Header.ssrc;

SetLostPacket();

}

if(NALType==0x07)//SPS

{

m_bSPSFound=true;

}

if(!m_bSPSFound)

{

returnNULL;

}

if(NALType==0x07||NALType==0x08)//SPSPPS

{

m_wSeq=m_RTP_Header.seq;

m_bPrevFrameEnd=true;

pPayload-=4;

*((DWORD*)(pPayload))=0x01000000;

*outSize=PayloadSize+4;

returnpPayload;

}

if(m_bWaitKeyFrame)

{

if(m_RTP_Header.m)//frameend

{

m_bPrevFrameEnd=true;

if(!m_bAssemblingFrame)

{

m_wSeq=m_RTP_Header.seq;

returnNULL;

}

}

if(!m_bPrevFrameEnd)

{

m_wSeq=m_RTP_Header.seq;

returnNULL;

}

else

{

if(NALType!=0x05)//KEYFRAME

{

m_wSeq=m_RTP_Header.seq;

m_bPrevFrameEnd=false;

returnNULL;

}

}

}

if(m_RTP_Header.seq!=(WORD)(m_wSeq+1))//lostpacket

{

m_wSeq=m_RTP_Header.seq;

SetLostPacket();

returnNULL;

}

else

{

//码流正常

m_wSeq=m_RTP_Header.seq;

m_bAssemblingFrame=true;

if(PayloadType!=28)//wholeNAL

{

*((DWORD*)(m_pStart))=0x01000000;

m_pStart+=4;

m_dwSize+=4;

}

else//FU_A

{

if(pPayload[1]&0x80)//FU_Astart

{

*((DWORD*)(m_pStart))=0x01000000;

m_pStart+=4;

m_dwSize+=4;

pPayload[1]=(pPayload[0]&0xE0)|NALType;

pPayload+=1;

PayloadSize-=1;

}

else

{

pPayload+=2;

PayloadSize-=2;

}

}

if(m_pStart+PayloadSize<m_pEnd)

{

CopyMemory(m_pStart,pPayload,PayloadSize);

m_dwSize+=PayloadSize;

m_pStart+=PayloadSize;

}

else//memoryoverflow

{

SetLostPacket();

returnNULL;

}

if(m_RTP_Header.m)//frameend

{

*outSize=m_dwSize;

m_pStart=m_pBuf;

m_dwSize=0;

if(NALType==0x05)//KEYFRAME

{

m_bWaitKeyFrame=false;

}

returnm_pBuf;

}

else

{

returnNULL;

}

}

}

voidSetLostPacket()

{

m_bSPSFound=false;

m_bWaitKeyFrame=true;

m_bPrevFrameEnd=false;

m_bAssemblingFrame=false;

m_pStart=m_pBuf;

m_dwSize=0;

}

private:

rtp_hdr_tm_RTP_Header;

BYTE*m_pBuf;

boolm_bSPSFound;

boolm_bWaitKeyFrame;

boolm_bAssemblingFrame;

boolm_bPrevFrameEnd;

BYTE*m_pStart;

BYTE*m_pEnd;

DWORDm_dwSize;

WORDm_wSeq;

BYTEm_H264PAYLOADTYPE;

DWORDm_ssrc;

};

//classCH264_RTP_UNPACKend

//使用范例

HRESULThr;

CH264_RTP_UNPACKunpack(hr);

BYTE*pRtpData;

WORDinSize;

intoutSize;

BYTE*pFrame=unpack.Parse_RTP_Packet(pRtpData,inSize,&outSize);

if(pFrame!=NULL)

{

//frameprocess

//...

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值