#include "CommonCode.h"
#define RingPoolSize (2*1024*1024)
CRtpDecoder::CRtpDecoder()
{
int i;
pRingPool = new char[RingPoolSize];
nRingGet = 0; nRingPut = 0;
nTimeCnt = -1; nRecUdpCnt = 0;
for (i = 0; i < 128; i++)
{
udpbuf[i] = new char[1500];
memset(udpbuf[i], 0xff, sizeof(RTP_FIXED_HEADER));
}
}
CRtpDecoder::~CRtpDecoder()
{
delete pRingPool;
for (int i = 0; i < 128; i++) delete udpbuf[i];
}
void CRtpDecoder::FillRing(char *pdata, int len)
{
int tmpGet, tmpPut;
tmpGet = (nRingPut >= nRingGet) ? nRingGet + RingPoolSize : nRingGet;
tmpPut = nRingPut + 4 + len;
if(tmpPut<tmpGet)
{
//有足够的存储空间
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x01; if (nRingPut >= RingPoolSize) nRingPut = 0;
if (nRingPut + len >= RingPoolSize)
{
memcpy(pRingPool + nRingPut, pdata, RingPoolSize - nRingPut);
memcpy(pRingPool, pdata + RingPoolSize - nRingPut, len - (RingPoolSize - nRingPut));
}
else memcpy(pRingPool + nRingPut, pdata, len);
nRingPut = (nRingPut + len) % RingPoolSize;
}
}
bool CRtpDecoder::FillRing(int cnt)
{
RTP_FIXED_HEADER *pRtpTmp;
int beginIndex = -1, endIndex = -1,i,len,tmp;
unsigned short int seqbegin, seqend,sum;
if (cnt < 2) return false;
for (i = 0; i < cnt; i++)
{
if ((udpbuf[i][13+4] & 0xE0) == 0x80) beginIndex = i;
else if ((udpbuf[i][13+4] & 0xE0) == 0x40) endIndex = i;
}
if (beginIndex == -1 || endIndex == -1) return false;
pRtpTmp = (RTP_FIXED_HEADER *)(udpbuf[beginIndex] + 4);
seqbegin = htons(pRtpTmp->seq_no);
pRtpTmp = (RTP_FIXED_HEADER *)(udpbuf[endIndex] + 4);
seqend = htons(pRtpTmp->seq_no);
sum = seqend - seqbegin+1;
if (sum == cnt)
{
int tmpGet, tmpPut;
printf("rebuild a nal %d\r\n", nTimeCnt);
//计算总长度,len
len = 4 + 1;
for (i = 0; i < cnt; i++)
{
memcpy(&tmp, udpbuf[i], 4);
len += tmp - 14;
}
tmpGet = (nRingPut >= nRingGet) ? nRingGet + RingPoolSize : nRingGet;
tmpPut = nRingPut + len;
if (tmpPut < tmpGet)
{
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x00; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = 0x01; if (nRingPut >= RingPoolSize) nRingPut = 0;
pRingPool[nRingPut++] = (udpbuf[beginIndex][12 + 4] & 0xE0) | (udpbuf[beginIndex][13 + 4] & 0x1F); if (nRingPut >= RingPoolSize) nRingPut = 0;
for (i = 0; i < cnt; i++)
{
int iSeq;
char *pdata;
for (iSeq = 0; iSeq < cnt; iSeq++)
{
pRtpTmp = (RTP_FIXED_HEADER *)(udpbuf[iSeq] + 4);
seqend = htons(pRtpTmp->seq_no);
if (seqbegin == seqend) break;
}
memcpy(&len, udpbuf[iSeq], 4); len -= 14;
pdata = udpbuf[iSeq] + 14+4;
if (nRingPut + len >= RingPoolSize)
{
memcpy(pRingPool + nRingPut, pdata, RingPoolSize - nRingPut);
memcpy(pRingPool, pdata + RingPoolSize - nRingPut, len - (RingPoolSize - nRingPut));
}
else memcpy(pRingPool + nRingPut, pdata, len);
nRingPut = (nRingPut + len) % RingPoolSize;
++seqbegin;
}
}
else printf("no space\r\n");
return true;
}
return false;
}
void CRtpDecoder::FillUdpData(char *pdata,int len)
{
unsigned char type;
RTP_FIXED_HEADER *pRtpHeader;
int timecnt,seqcnt;
pRtpHeader = (RTP_FIXED_HEADER *)pdata;
timecnt = htonl(pRtpHeader->timestamp);
seqcnt = htons(pRtpHeader->seq_no);
type = pdata[sizeof(RTP_FIXED_HEADER)] & 0x1F;
//printf("rec:%d\r\n", type);
if (type <23)
{
//不是组合包,或者分片包
FillRing(pdata + sizeof(RTP_FIXED_HEADER), len - sizeof(RTP_FIXED_HEADER));
return;
}
if (type == 0x1C)
{
//分片包
if (timecnt != nTimeCnt)
{
//if (nRecUdpCnt) printf("err frame\r\n");
nRecUdpCnt = 0;
nTimeCnt = timecnt;
}
memcpy(udpbuf[nRecUdpCnt], &len, 4); //记录包长度
memcpy(udpbuf[nRecUdpCnt] + 4, pdata, len); //记录包内容
if (++nRecUdpCnt >= 128) nRecUdpCnt = 0;
if (FillRing(nRecUdpCnt)) nRecUdpCnt = 0;
}
}
int CRtpDecoder::GetH264Buf(char *pdst, int max)
{
int len;
if (nRingGet == nRingPut) return 0;
len = ((nRingPut + RingPoolSize) - nRingGet) % RingPoolSize;
if (len > max) len = max;
if (nRingGet + len > RingPoolSize)
{
memcpy(pdst, pRingPool + nRingGet, RingPoolSize - nRingGet);
memcpy(pdst + RingPoolSize - nRingGet, pRingPool, len - (RingPoolSize - nRingGet));
}
else memcpy(pdst, pRingPool + nRingGet, len);
nRingGet = (nRingGet + len) % RingPoolSize;
return len;
}
下载 vc 下的工程