RTP解析音视频帧

RTP解析H264、AAC负载

RTSP中音视频是通过RTP传输的,本文记录从RTP解析出H264、AAC的过程。
协议介绍可参考 https://blog.youkuaiyun.com/lostyears/article/details/51374997
拿到RTP数据后,先去除12字节RTP头部,然后进行下面处理。

解析H264

数据较大的H264包,需要进行RTP分片发送。
实现代码:

  /*
     * @par        pBufIn   待解析RTP(不包含12字节头)
     *             nLenIn   载荷长度
     *             pBufOut  装载H264的buf(外部传入,分配空间不小于nLenIn)
     *             nLenOut  一帧H264数据长度,函数返回true时有效
     *
     * @return    true     一帧结束
     *            false    分片未结束
     */
bool UnpackRtpH264(const UInt8 *pBufIn, const Int32 nLenIn, UInt8 *pBufOut, Int32& nLenOut)
{
   
   
    bool bFinished = true;
    do
    {
   
   
        nLenOut = 0;
        const Int32 eFrameType = pBufIn[0] & 0x1F;
        if (eFrameType >= 1 && eFrameType <= 23) //单一NAL单元
        {
   
   
            pBufOut[0] = 0x00;//添加H264四字节头部
            pBufOut[1] = 0x00;
            pBufOut[2] = 0x00;
            pBufOut[3] = 0x01;
            memcpy(pBufOut + 4, pBufIn, nLenIn);
            nLenOut = nLenIn + 4;
        }
        else //分片NAL单元,由多个RTP包拼接成完整的NAL单元
        {
   
   
            bFinished = false;
            if (pBufIn[1] & 0x80) // 分片Nal单元开始位
            {
   
   
                m_nH264FrmeSize = 0;
                pBufOut[0] = 0x00;
                pBufOut[1] = 0x00;
                pBufOut[2] = 0x00;
                pBufOut[3] = 0x01;
                pBufOut[4] = ((pBufIn[0] & 0xe0)|(pBufIn[1] & 0x1f));//取pBufIn[0]的前3位 与 pBufIn[1]的后5位
                memcpy(pBufOut + 5, pBufIn + 2, nLenIn - 2); //跳过分片RTP的前两字节
                m_nH264FrmeSize = nLenIn + 5 - 2;
            }
            else //后续的Nal单元载荷
            {
   
   
                Assert(m_nH264FrmeSize + nLenIn - 2 <= MAX_FRAME_SISE);
                memcpy(pBufOut + m_nH264FrmeSize, pBufIn + 2, nLenIn -2);//跳过分片RTP的前两字节
                m_nH264FrmeSize += nLenIn -2;
                if (pBufIn[1] & 0x40) // 分片Nal单元结束位
                {
   
   
                    nLenOut = m_nH264FrmeSize;
                    m_nH264FrmeSize = 0;
                    bFinished = true;
                }
            }
        }
    }while (0);

    return bFinished;
}

解析AAC

这里要注意,可能是一个RTP包含多个AAC帧,之前按网上找的RTP后直接负载1帧AAC,大部分场景没问题,后面有个输入源解析AAC后没声音,最后发现是一个RTP包含了多个AAC负载。解析协议规范最好还是花时间研读协议规范文档,网上找的博客介绍可能不够全面,导致部分场景失效。
实现代码如下:

  
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值