ffmpeg扩展支持H265视频流的flv封装

ffmpeg扩展支持H265视频流的flv封装

由于Adobe暂停了对RTMP/FLV标准的更新,所以目前标准中没有支持HEVC视频编码格式。为避免各终端和服务器间的兼容性问题,FFmpeg也没有在RTMP/FLV的协议实现中进行HEVC的相关扩展。CDN联盟制定了相关的协议扩展规范,并在FFmpeg中完成了相关代码实现,本文主要介绍如何让ffmpeg扩展支持HEVC视频编码格式的HTTP-FLV流媒体协议。

flv协议扩展支持HEVC

有关FLV协议介绍参照文章:HTTP FLV交互流程及实例解析
有关ffmpeg介绍参照文章:音视频领域强大的辅助工具-ffmpeg常用操作介绍

为推进HEVC视频编码格式在直播方案中的落地,CDN联盟规范了HEVC在RTMP/FLV中的扩展,在支持HEVC的VideoTagHeader

FLV协议扩展支持HEVC

  1. 支持HEVC的VideoTagHeader扩展,扩展后的格式如下图所示:
    1

其中修改了如下部分:

  • CodecID :定义HEVC格式的值为12
  • HEVCPacketType :当CodecID=12时,AVCPacketType改为HEVCPacketType;其中HEVCPacketType=0,表示HEVCVIDEOPACKET中存放的是HEVC sequence header;HEVCPacketType=1,表示HEVCVIDEOPACKET中存放的是HEVC NALU;HEVCPacketType=2,表示HEVCVIDEPACKET中存放的是HEVC end of sequence,即HEVCDecoderConfigurationRecord
  • CompositionTime:当CodecID=12时,也需要CompositionTime
  1. 支持HEVC的VideoTagBody扩展,扩展后的格式如下:
    2
    当CodecID为12时,VideoTagBody中存放的就是HEVC视频帧内容

ffmpeg扩展支持HEVC flv封装源码修改

FLV的解复用和复用功能代码分别在libavformt/flvdec.c和libavformat/flvenc.c中,扩展后的修改也都集中在这两个文件。

  1. 编码类型的枚举扩展

修改文件libavformat/flv.h,修改如下,CodecId增加FLV_CODECID_HEVC:

enum {
    FLV_CODECID_H263    = 2,
    FLV_CODECID_SCREEN  = 3,
    FLV_CODECID_VP6     = 4,
    FLV_CODECID_VP6A    = 5,
    FLV_CODECID_SCREEN2 = 6,
    FLV_CODECID_H264    = 7,
    FLV_CODECID_REALH263= 8,
    FLV_CODECID_MPEG4   = 9,
    FLV_CODECID_HEVC   = 12,
};
  1. flv解复用修改

HEVCPacketType=0时,表示HEVCVIDEOPACKET中存放的是HEVC sequence header,也就是HEVCDecoderConfigurationRecord,解码时需设置HEVCDecoderConfigurationRecord方能正确解码,在读取Video Tag的地方增加AV_CODEC_ID_HEVC的判断条件。

修改文件libavformt/flvdec.c,修改内容如下,

if (st->codecpar->codec_id == AV_CODEC_ID_AAC ||
     st->codecpar->codec_id == AV_CODEC_ID_H264 ||
     st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
    st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
    int type = avio_r8(s->pb);
    size--;
    if (st->codecpar->codec_id == AV_CODEC_ID_H264 || 
         st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
         st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
         // sign extension
         int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
         pts = dts + cts;
         if (cts< 0) { // dts might be wrong
             if (!flv->wrong_dts)
                 av_log(s, AV_LOG_WARNING,
                        "Negative cts, previous timestamps might be wrong.\n");
            flv->wrong_dts = 1;
        } else if (FFABS(dts - pts) > 1000*60*15) {
                av_log(s, AV_LOG_WARNING,
                       "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts);
                dts = pts = AV_NOPTS_VALUE;
        }
   }
   
   if (type == 0 &&(!st->codecpar->extradata ||
       st->codecpar->codec_id == AV_CODEC_ID_AAC ||
       st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
       st->codecpar->codec_id == AV_CODEC_ID_H264)) {
       AVDictionaryEntry *t;
       if (st->codecpar->extradata) {
           if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0)
               return ret;
           ret = FFERROR_REDO;
           goto leave;
       }
       if ((ret = flv_get_extradata(s, st, size)) < 0)
           return ret;
       ……
   }
}

3.flv复用修改

主要修改header、packet、trailer,修改文件libavformat/flvenc.c,改动就多,需改后文件直接从如下连接获取:
https://github.com/ksvc/FFmpeg

本文也是基于他们整理的资料进行编译打包。

ffmpeg扩展修改后编译安装步骤

测试环境为:centos 7 x86-64

  1. 下载x265并编译:
wget http://ftp.videolan.org/pub/videolan/x265/x265_3.2.tar.gz
tar -zxvf x265_3.2.tar.gz
./make-Makefiles.bash
make
make install
pkg-config --list-all #查看x265是否安装成功
  1. 编译修改后的ffmpeg

从上面的github中下在源码,编译过程如下:

#下载修改后的ffmpeg,解压,https://github.com/ksvc/FFmpeg/archive/refs/tags/n3.3.2.tar.gz
# 编译步骤如下:
./configure --enable-shared --enable-libx264 --enable-gpl --enable-libx265
make&make install
ffmpeg version # 查看是否编译成功
  1. 测试验证
    通过如下命令测试,看是否能够成功,参照文章《使用nginx搭建HTTP FLV流媒体服务器》搭建http-flv服务器。
    找到一个HEVC的rtsp视频连接,输入如下命令,看是否能够正常打包flv。
    ffmpeg -i rtsp://admin:@******@10.45.13.236/h265/ch1/main/av_stream -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:1935/live/test
    (备注,nginx的rtmp扩展模块开源版本并不支持H265的HTTP-FLV协议,需要花钱向开源的作者购买补丁才行,如需要测试,可安装SRS流媒体服务器,这个已经支持了,后续文章会介绍)

后话

今天早上(2023-11-11)看到ffmpeg发布最新的版本6.1,已经增加了对flv h265的支持,有兴趣的可以直接下载官方最新的版本,试试是否已经支持flv h265格式,ffmpeg6.1版本安装包也可用过关注公众号:零**仓,发送消息:软件工具 获取。
安装步骤如下:

tar -jxvf ffmpeg-6.1.tar.gz
./configure --enable-shared --prefix=/usr/ffmpeg
make & make install
vi /etc/profile
# 增加ffmpeg执行路径的环境变量:
PATH=$PATH:/usr/ffmpeg/bin
export PATH
# 使环境变量生效:
source /etc/profile

vi /etc/ld.so.conf
# 增加系统连接库路径:/usr/ffmpeg/lib/
# 生效
ldconfig
ffmpeg version

最新版本更新说明如下:


增加了 libaribcaption 解码器
增加 Playdate 视频 Decoder 和 Demuxer
增加了 afireqsrc 音频源滤镜
增加了 arls 音频滤镜
增加了 zoneplate 视频源滤镜
在 Windows 上扩展对 libva-win32 的 VAAPI 支持
在 setpts 和 asetpts 滤镜中支持命令
完善 Vulkan 解码硬件加速,支持 H264、HEVC 和 AV1
增加了 color_vulkan 滤镜
增加了 bwdif_vulkan 滤镜
增加了 nlmeans_vulkan 滤镜
增加了 RivaTuner 视频解码器
增加了 xfade_vulkan 滤镜
增加了 vMix 视频解码器
增加了 Essential Video Coding parser、muxer 和 demuxer
增加了 Essential Video Coding 帧合并 bsf
增加了 bwdif_cuda 滤镜
实现了 apsnr 和 asisdr 音频滤镜
增加了 Microsoft RLE 视频编码器
Raw AC-4 Muxer 和 Demuxer
Raw VVC bitstream parser、Muxer 和 Demuxer
增加了 用于编辑 VVC 流中metadata的bsf
将 VVC 从 MP4 转换为 Annex B 的 bitstream 滤镜
实现了 apsnr 和 asisdr 音频滤镜
实现了 videotoolbox 的 scale_vt 滤镜
实现了 videotoolbox 的 transpose_vt 滤镜
支持 P_SKIP 提示以加速 libx264 编码
在增强的 flv 格式中支持 HEVC、VP9、AV1 编解码器
实现了 OSQ复用器和解码器
在增强的rtmp协议中支持HEVC、VP9、AV1编解码器的fourcclist
实现了 CRI USM复用器
ffmpeg CLI的'-top'选项已弃用,推荐使用setfield过滤器
ffmpeg CLI选项:-readrate_initial_burst
完善了 VAAPI AV1编码器
ffprobe XML 输出模式已更改,以适应同一父元素内的多个可变字段元素
添加了ffprobe -output_format 选项,作为 -of 的别名

关注,发送:flv,获取更多flv文章。

猜你喜欢

转载自blog.csdn.net/water1209/article/details/134390339