如何在RTMP推送端和RTMP播放端支持Enhanced RTMP H.265(HEVC)

​技术背景

时隔多年,在Enhancing RTMP, FLV With Additional Video Codecs And HDR Support(2023年7月31号正式发布)官方规范出来之前,如果RTMP要支持H.265,大家约定俗成的做法是扩展flv协议,CDN厂商携手给出的解决方案是给flv的videotag CodecID增加一个新类型(12)来表示h265(hevc),和h264不同的地方是要解析HEVCDecoderConfigurationRecord,从HEVCDecoderConfigurationRecord中解析出vps, sps, pps. 有了vps, sps, pps, 就可以解码。

遗憾的是,尽管CodecID可以自定义,但CodecID只有4个bits,增加H.265尚可,如果后续再新增VP8、VP9、 AV1甚至H.266就很尴尬,这种尴尬持续了数年,直到官方发布了 Enhancing RTMP新的规范。值得欣慰的是,SRS等开源组织在服务侧第一时间进行了适配兼容。

技术实现

本文以大牛直播SDK的Windows平台RTMP直播推送和RTMP直播播放模块为例,考虑到老的扩展CodecID 12的场景依然使用,我们添加了个设置接口:

RTMP推送端,对应文件为SmartPublisherSDK\nt_smart_publisher_sdk.h:

scss 复制代码
       /*
		* disable enhanced RTMP, SDK默认是开启enhanced RTMP的
		* value: 1:disable, 0:enable
		*/
		NT_UINT32(NT_API *DisableEnhancedRTMP)(NT_HANDLE handle, NT_INT32 value);

RTMP播放端,对应文件为SmartPlayerSDK\smart_player_sdk.h:

scss 复制代码
		/*
		* disable enhanced RTMP, SDK默认是开启enhanced RTMP的
		* value: 1:disable, 0:enable
		*/
		NT_UINT32(NT_API *DisableEnhancedRTMP)(NT_HANDLE handle, NT_INT32 value);

Enhanced RTMP针对flv原有VideoTagHeader中FrameType(4bits)做了如下调整:

| IsExHeader(1bit)FrameType(3bits) |

VideoTagHeader的第一个字节的第0位来判断是否是Enhanced RTMP格式,如果这一位是1,那就是扩展头,Enhanced-Rtmp格式。

RTMP推送端生成HEVC的FLV VideoTagHeader,对应的sample判断代码如下:

less 复制代码
/*
* Author:daniusdk.com
*/
*p = 0x80;
if (key)
	*p |= (1<<4);
else
	*p |= (2 << 4);
 
if (pts != dts)
	*p |= 1;
else
	*p |= 3;
 
p++;
 
*p++ = 'h';
*p++ = 'v';
*p++ = 'c';
*p++ = '1';
 
//....

RTMP播放端,对应的sample判断代码如下:

ini 复制代码
/*
 * Author:daniusdk.com 
 */
bool is_ex_header;

if (p[0]&0x80)
    is_ex_header = true;
else
    is_ex_header = false;
 
if (is_ex_header) {
	auto video_fourcc = (p[1] << 24)|(p[2] << 16)|(p[3] << 8)|p[4];
	if (HEVC == video_fourcc) {
	   // hevc处理
	}else if (VP9 == video_fourcc) {
	   // vp9处理
	}else if (AV1 == video_fourcc ) {
	   // AV1处理
	}
}

启动Windows平台窗体采集,设置H.265硬编码,输入RTMP推流URL,实现Enhanced RTMP推送,播放端拉流播放,整体延迟如下:

可以看到,尽管开启了Enhanced RTMP,整体延迟还在毫秒级。

技术总结

鉴于目前RTMP扩展265这块,大多还是用的老的CodecID设置为12的模式,如果需要支持新的Enhanced RTMP,除了推送端和播放端外,RTMP服务端也需要做响应的调整,来适配这种情况,好在SRS等一线开源组织已经做了适配,我们也自己调整了nginx的代码,做了简单的测试,整体延迟满足预期,感兴趣的开发者可以单独跟我交流。

相关推荐
LittroInno1 天前
边缘AI模组选型:把视频带宽、压缩和推理吞吐分别算清
人工智能·音视频·边缘计算·视频编码·模组选型·视频带宽·tofu6
屏什么录2 天前
录屏超过两小时就卡顿崩盘?从参数调优到代码实现,一文彻底搞定长时间录屏
前端·音视频开发
字节跳动视频云技术团队3 天前
720P 直升 8K,解密 2026 抖音美好奇妙夜巨幕超分黑科技
人工智能·音视频开发
the3clipse5 天前
AV1编码优化实战:CDEF、LR与Film Grain合成技术调优指南
视频编码·restoration·av1编码·cdef·film grain·svt-av1·画质优化
Industio_触觉智能5 天前
瑞芯微RK平台视频硬解排障指南-下|板端实测记录
音视频·视频编码·视频编解码·零拷贝·gstreamer·视频解码·rk3576
the3clipse6 天前
VVC并行处理架构详解:Tile、WPP与Subpicture工程实战指南
视频编码·tile·vvenc·vvc并行处理·wpp·subpicture·多线程编码
VimorphTech6 天前
文件名是 MP4 就能处理?用 ffprobe 检查视频流、音轨和时长
java·音视频开发
冬奇Lab9 天前
开源项目第242期:HyperFrames —— 写 HTML 就能渲染视频,专为 AI Agent 设计的确定性视频框架
人工智能·开源·音视频开发
Industio_触觉智能11 天前
瑞芯微RK平台视频硬解排障指南-上|编解码、GStreamer与零拷贝全解析
视频编码·视频编解码·零拷贝·gstreamer·视频解码·rk3576
Hello_Pyhx13 天前
Bilirec 配置入门:录制哔哩哔哩直播间
直播·视频录制·哔哩哔哩·直播工具