接收rtp數據保存爲h264

#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 下的工程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章