H265打包成RTP

原文链接:https://blog.csdn.net/hiwubihe/article/details/84704046

本篇介绍一下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的类型字段。

             

H265类型定义如下


/*********************************************************************************
* 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,
};

附上一段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 */
		//去掉H265头类型长度
		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类型分析

扫描二维码关注公众号,回复: 6205953 查看本文章

猜你喜欢

转载自blog.csdn.net/u011425939/article/details/90137221
今日推荐