RTMP推送扩展支持HEVC(H265)

不久前刚实现SkeyeRTMP Pusher扩展支持h265推送,当时在网上也查找了很多资料,发现都不尽详细,而官方也没有更新对HEVC(H265,后文统称HEVC)tag的支持,反正是走了不少弯路,当然,在广大网友以及ffmpeg代码的帮助下我最终实现了通过SkeyeRTMPPusher推送HEVC视频帧数据到SkeyeSMS,这里我将把实现过程详细的记录下来,供广大网友参考。
首先, RTMP头部信息封装并没有定义HEVC,我们采用CDN联盟的HEVC扩展标准,将HEVC的VideoTagHeader定义为12,详见下图:
在这里插入图片描述
然后,我们在H264封装的基础上进行改进,以支持HEVC头部的封装,而HEVC头有
SPS PPS VPS,我们参考ffmpeg的HEVCDecoderConfigurationRecord结构对metadata进行封装,该结构体代码如下:

typedef struct HVCCNALUnitArray {
	uint8_t  array_completeness;
	uint8_t  NAL_unit_type;
	uint16_t numNalus;
	uint16_t *nalUnitLength;
	uint8_t  **nalUnit;
} HVCCNALUnitArray;

typedef struct HEVCDecoderConfigurationRecord {
	uint8_t  configurationVersion;
	uint8_t  general_profile_space;
	uint8_t  general_tier_flag;
	uint8_t  general_profile_idc;
	uint32_t general_profile_compatibility_flags;
	uint64_t general_constraint_indicator_flags;
	uint8_t  general_level_idc;
	uint16_t min_spatial_segmentation_idc;
	uint8_t  parallelismType;
	uint8_t  chromaFormat;
	uint8_t  bitDepthLumaMinus8;
	uint8_t  bitDepthChromaMinus8;
	uint16_t avgFrameRate;
	uint8_t  constantFrameRate;
	uint8_t  numTemporalLayers;
	uint8_t  temporalIdNested;
	uint8_t  lengthSizeMinusOne;
	uint8_t  numOfArrays;
	HVCCNALUnitArray *array;
} HEVCDecoderConfigurationRecord;

参考ffmeg对该结构进行初始化如下:


static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc)
{
    memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord));
    hvcc->configurationVersion = 1;
    hvcc->lengthSizeMinusOne   = 3; // 4 bytes

    /*
     * The following fields have all their valid bits set by default,
     * the ProfileTierLevel parsing code will unset them when needed.
     */
    hvcc->general_profile_compatibility_flags = 0xffffffff;
    hvcc->general_constraint_indicator_flags  = 0xffffffffffff;

    /*
     * Initialize this field with an invalid value which can be used to detect
     * whether we didn't see any VUI (in which case it should be reset to zero).
     */
    hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1;
}

需要注意的是,该结构其他参数我们其实可以不特别关心,我们只需要在HVCCNALUnitArray数组中把HEVC的VPS,SPS和PPS信息填入即可。

最后,填写好Metadata信息后,我们还需要在发送帧数据的时候做一下修改,将I帧的tag头改成12,P帧tag不变,设置成1即可,如下代码所示:

	int i = 0;
	if(bIsKeyFrame)
	{
		//body[i++] = 0x17;// 2:Pframe  7:AVC
		body[i++] = 	 (m_metadata.nVideoCodec  == FLV_CODECID_HEVC) ? 0x1C:0x17;// 1:Iframe  7:AVC 12:HEVC

		if (m_bWaitingKeyFrame)
		{
			m_bWaitingKeyFrame = false;
		}
	}
	else
	{
		//body[i++] = 0x27;// 2:Pframe  7:AVC
		body[i++] = 	 (m_metadata.nVideoCodec  == FLV_CODECID_HEVC) ? 0x2C:0x27;// 1:Iframe  7:AVC 12:HEVC
	}
	body[i++] = 0x01;// AVC NALU
	body[i++] = 0x00;
	body[i++] = 0x00;
	body[i++] = 0x00;

	// NALU size
	body[i++] = size>>24;
	body[i++] = size>>16;
	body[i++] = size>>8;
	body[i++] = size&0xff;

有相关的技术问题,欢迎大家和我进行技术交流:
295222688@qq.com
大家也可以加入SkeyeRTMP直播推流技术 QQ群进行讨论:
102644504

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用FFmpeg推送H.265HEVC)视频流,你可以按照以下步骤进行操作: 1. 确保你已经安装了FFmpeg。如果没有安装,可以通过FFmpeg官方网站(https://ffmpeg.org/)或软件包管理器来安装它。 2. 准备要推送的H.265视频文件或视频流。确保你的视频源是H.265编码格式,可以使用FFmpeg命令行工具进行检查。 3. 使用以下命令行语法将H.265视频推送到特定的目标,例如RTMP服务器: ```bash ffmpeg -re -i input_file.mp4 -c:v libx265 -f flv rtmp://server/live/stream_key ``` - `-re` 标志将FFmpeg设置为以实时速率推送视频,如果你的输入文件不是实时生成的,可以忽略该标志。 - `-i input_file.mp4` 指定要推送的H.265视频文件的路径和文件名。 - `-c:v libx265` 设置视频编码器为libx265,以进行H.265编码。 - `-f flv` 设置输出格式为FLV,这是用于RTMP流的常见格式。如果你要推送到其他目标,可以选择适当的输出格式。 - `rtmp://server/live/stream_key` 指定目标推送地址,这里使用RTMP服务器的地址和流密钥。根据你的实际情况,可以更改为其他协议(例如RTSP,HLS等)和目标地址。 4. 运行命令并等待FFmpeg开始推送H.265视频。你可以在输出日志中查看进度和状态信息。 请注意,FFmpeg的命令行选项和参数可以根据需要进行更改,例如调整视频质量,帧率,码率等。确保在推送之前仔细检查文档并了解每个选项的用途和影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SwordTwelve

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值