H265视频封装成RTP

本篇介绍一下H265怎么打包RTP,在H265中,每一个前缀码00000001后面跟随的前两个字节为NALU的语法元素,总体结构如下

这两个字节字段分布如下,F(forbidden_zero_bit)通常为0,LayId(nuh_layer_id)通常为0,Tid(nuh_temporal_id_plus1)通常为1,所以对一段码流来说第二字节通常都是1。

 

1. 当收到NALU单元长度小于MTU时,直接把00000001/000001前缀去掉,加上RTPHead即可 

2.当收到NALU单元长度大于MTU时,需要做FU分包处理,先把00000001前缀+2B类型去掉,然后对剩下的数据分包处理。分包的每一段数据前加上FUHead,FUHead长度是3字节。FUHead[0],FUHead[1]的结构和H265NULU类型2B结构相同,只是Type取值49即可。FUHead[2]结构如下,S置1表示分包开始,E置1分包结束,中间包都不置1,后面6bit就是H265的类型字段。

  

 

附上一段FFMPEG代码理解


static void nal_send(AVFormatContext *ctx, const uint8_t *buf, int len, int last_packet_of_frame)
 {
        RTPMuxContext *rtp_ctx = ctx->priv_data;
        int rtp_payload_size   = rtp_ctx->max_payload_size - RTP_HEVC_HEADERS_SIZE;
        int nal_type           = (buf[0] >> 1) & 0x3F;
    
        //长度<MTU直接打包RTP发送
        /* send it as one single NAL unit? */
        if (len <= rtp_ctx->max_payload_size) {
            /* use the original NAL unit buffer and transmit it as RTP payload */
            ff_rtp_send_data(ctx, buf, len, last_packet_of_frame);
        } else {
            /*
              create the HEVC payload header and transmit the buffer as fragmentation units (FU)
    
                 0                   1
                 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |F|   Type    |  LayerId  | TID |
                +-------------+-----------------+
    
                   F       = 0
                   Type    = 49 (fragmentation unit (FU))
                   LayerId = 0
                   TID     = 1
             */
            //分包先赋值RTP头三个字节
            //类型49表示该包是FU分包
            rtp_ctx->buf[0] = 49 << 1;
            //保持原来H265类型字段第二个字段 一般都是1
            rtp_ctx->buf[1] = 1;
    
            /*
                  create the FU header
    
                  0 1 2 3 4 5 6 7
                 +-+-+-+-+-+-+-+-+
                 |S|E|  FuType   |
                 +---------------+
    
                    S       = variable
                    E       = variable
                    FuType  = NAL unit type
             */
            //保持原来H265类型字段类型字段 
            rtp_ctx->buf[2]  = nal_type;
            /* set the S bit: mark as start fragment */
            //设置开始标志
            rtp_ctx->buf[2] |= 1 << 7;
    
            /* pass the original NAL header */
            //去掉H264头类型长度
            buf += 2;
            len -= 2;
    
            while (len > rtp_payload_size) {
                /* complete and send current RTP packet */
                memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, rtp_payload_size);
                ff_rtp_send_data(ctx, rtp_ctx->buf, rtp_ctx->max_payload_size, 0);
    
                buf += rtp_payload_size;
                len -= rtp_payload_size;
    
                /* reset the S bit */
                //去掉开始结束标志
                rtp_ctx->buf[2] &= ~(1 << 7);
            }
    
            /* set the E bit: mark as last fragment */
            //设置结束标志
            rtp_ctx->buf[2] |= 1 << 6;
    
            /* complete and send last RTP packet */
            memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, len);
            ff_rtp_send_data(ctx, rtp_ctx->buf, len + 2, last_packet_of_frame);
        }

}

 

H265类型定义如下


/**
 * Table 7-1: NAL unit type codes
 */
 
enum HEVCNALUnitType {
 
    HEVC_NAL_TRAIL_N    = 0,
 
    HEVC_NAL_TRAIL_R    = 1,
 
    HEVC_NAL_TSA_N      = 2,
 
    HEVC_NAL_TSA_R      = 3,
 
    HEVC_NAL_STSA_N     = 4,
 
    HEVC_NAL_STSA_R     = 5,
 
    HEVC_NAL_RADL_N     = 6,
 
    HEVC_NAL_RADL_R     = 7,
 
    HEVC_NAL_RASL_N     = 8,
 
    HEVC_NAL_RASL_R     = 9,
 
    HEVC_NAL_VCL_N10    = 10,
 
    HEVC_NAL_VCL_R11    = 11,
 
    HEVC_NAL_VCL_N12    = 12,
 
    HEVC_NAL_VCL_R13    = 13,
 
    HEVC_NAL_VCL_N14    = 14,
 
    HEVC_NAL_VCL_R15    = 15,
 
    HEVC_NAL_BLA_W_LP   = 16,
 
    HEVC_NAL_BLA_W_RADL = 17,
 
    HEVC_NAL_BLA_N_LP   = 18,
 
    HEVC_NAL_IDR_W_RADL = 19,
 
    HEVC_NAL_IDR_N_LP   = 20,
 
    HEVC_NAL_CRA_NUT    = 21,
 
    HEVC_NAL_IRAP_VCL22 = 22,
 
    HEVC_NAL_IRAP_VCL23 = 23,
 
    HEVC_NAL_RSV_VCL24  = 24,
 
    HEVC_NAL_RSV_VCL25  = 25,
 
    HEVC_NAL_RSV_VCL26  = 26,
 
    HEVC_NAL_RSV_VCL27  = 27,
 
    HEVC_NAL_RSV_VCL28  = 28,
 
    HEVC_NAL_RSV_VCL29  = 29,
 
    HEVC_NAL_RSV_VCL30  = 30,
 
    HEVC_NAL_RSV_VCL31  = 31,
 
    HEVC_NAL_VPS        = 32,
 
    HEVC_NAL_SPS        = 33,
 
    HEVC_NAL_PPS        = 34,
 
    HEVC_NAL_AUD        = 35,
 
    HEVC_NAL_EOS_NUT    = 36,
 
    HEVC_NAL_EOB_NUT    = 37,
 
    HEVC_NAL_FD_NUT     = 38,
 
    HEVC_NAL_SEI_PREFIX = 39,
 
    HEVC_NAL_SEI_SUFFIX = 40,
 
};


H265类型分析

 

 



--------------------- 
作者:hiwubihe 
来源:CSDN 
原文:https://blog.csdn.net/hiwubihe/article/details/84704046 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值