rtp基本封包格式

rtp包易于过大,一般每个包不要超过1400,这里设置为1380,即DEFAULT_MTU=1380

这里介绍的媒体格式有视频:H264/H265,音频:AAC

1、如果媒体包小于DEFAULT_MTU时可直接写入rtp包中,示例代码:

    unsigned char *pNAL;    //媒体数据包
    int nalsize;            //媒体数据包长度
    uint32_t timestamp;     //时间戳
    // RTPSession rtp_session;
    /* H264、H265 */
    // 以jrtplib以为发送H264/H265视频数据的rtp包,成功时返回值是0
    rtp_session.SendPacket(PacketData,PacketDataSize,96,true,(uint32_t)timestamp);

    /* AAC */
    uint8 aacHeader[4]={0x00,0x10,0x04,0xb8};
    aacHeader[2] = nalsize >> 5;
    aacHeader[3] = (nalsize & 0x1F) << 3;
    memcpy(PacketData,aacHeader,sizeof(aacHeader));
    memcpy(PacketData+sizeof(aacHeader),pNAL,nalsize);
    PacketDataSize = nalsize+sizeof(aacHeader);
    // 以jrtplib以为发送AAC音频数据的rtp包,成功时返回值是0
    rtp_session.SendPacket(PacketData,PacketDataSize,97,true,(uint32_t)timestamp);

2、当媒体数据的包长度超过DEFAULT_MTU时需要采用分片封包模式(FUs),示例代码:

    unsigned char *pNAL;    //媒体数据包
    int nalsize;            //媒体数据包长度
    uint32_t timestamp;     //时间戳
    unsigned char PacketData[DEFAULT_MTU];  //rtp数据包
    uint32_t PacketDataSize = 0;            //rtp数据包长度
    int rtp_head_size = 0;

    //计算rtp包头需要的信息
    #if H264 || AAC
        const uint8_t fu_indicator = (pNAL[0] & 0xe0) | 28;
        const uint8_t fu_header = pNAL[0] & 0x1f;
        pNAL++;
        nalsize--;
        rtp_head_size = 2;
    #else if H265
        const uint8_t payloadhdr[2]={(pNAL[0]&0x81)|(49<<1),pNAL[1]};
        const uint8_t fu_header = (pNAL[0] & 0x7E)>>1; 
        pNAL+=2;
        nalsize-=2;
        rtp_head_size = 3;
    #endif

    //计算需要拆分的片数
    uint32_t FU_size = 0;
    if((nalsize % (DEFAULT_MTU-rtp_head_size))!=0)
        FU_size=nalsize / (DEFAULT_MTU-rtp_head_size) +1;
    else
        FU_size=nalsize / (DEFAULT_MTU-rtp_head_size);

    int start = true;           //第一个分片标记
    bool end_mask = false;      //最后一个分片标志
    while(nalsize>0){
        const uint32_t fraglen = MIN(DEFAULT_MTU-rtp_head_size, nalsize);
        PacketDataSize = fraglen+rtp_head_size;

        #if H264 || AAC
            PacketData[0]=fu_indicator;     //rtp包第一个字节
            PacketData[1]=fu_header;        //rtp包第二个字节
        #else if H265
            PacketData[0]=payloadhdr[0];    //rtp包第一个字节
            PacketData[1]=payloadhdr[1];    //rtp包第二个字节
            PacketData[2]=fu_header;        //rtp包第三个字节
        #endif

        if (start) {                    //第一个分片需要在最高位需要至1
            PacketData[rtp_head_size-1] |= (1<<7);
            start = false;
        }
        if (fraglen == nalsize) {       //最后一个分片需要在第2高位需要至1
            PacketData[rtp_head_size-1] |= (1<<6);
            end_mask=true;
        }
        memcpy(PacketData+rtp_head_size, pNAL, fraglen);    //剩下的数据接在后面
        // RTPSession rtp_session;
        // 以jrtplib以为发送H264/H265视频数据的rtp包,成功时返回值是0
        rtp_session.SendPacket(PacketData,PacketDataSize,96,end_mask,(uint32_t)timestamp);
        // 以jrtplib以为发送AAC音频数据的rtp包,成功时返回值是0
        rtp_session.SendPacket(PacketData,PacketDataSize,97,true,(uint32_t)timestamp);

        //媒体数据包去掉已经发送的部分
        nalsize -= fraglen;     
        pNAL += fraglen;
    }
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值