为什么 ffmpeg 在将 FLV 转换为 h264 时会删除 SEI 消息?

Why does ffmpeg remove SEI messages when converting FLV to h264?

我有一个带有 h264 视频标签的 FLV 文件。每个包含 h264 IDR NAL 单元的视频标签还包含显示方向 SEI,即我的 IDR 关键帧的 NAL 访问单元是 [SEI, IDR]。

出于某种原因,在没有流复制选项的情况下将此 FLV 文件转换为 h264 会从所有 IDR 帧中删除所有 SEI 消息。取而代之的是,在 SPS 和 PPS NAL 单元之后,有一个用户未注册数据 SEI。

即使用

ffmpeg -i in.flv out.264

给出 [SPS, PPS, SEI, IDR, ...] 其中 SEI 是:

x264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=11 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00

但是

ffmpeg -i in.flv -c:v copy out.264

保留我的 SEI 消息,并且几乎解码为我放入 FLV 多路复用器以首先生成 FLV 文件的原始 h264。为什么会这样?是否有执行编码但保留 SEI 消息的标志?

使用 -c:copy,ffmpeg 不解码 h264,它只是将 NALU 从源复制到目标,甚至不查看它们。因此每个NALU都被保留了。

使用转码,ffmpeg 会在解码时丢失元数据。它需要获取 SEI,将其设置为 AVFrame 的元数据,然后在重新编码时将 SEI 写入新帧。但是 SEI 是每个 AU 对象。这意味着如果您更改帧速率,ffmpeg 将需要知道如何将 SEI 拆分或合并到新的帧速率中。那是很多代码,还没有人写过。可以在不更改帧速率的情况下复制 SEI,为所有已知的 SEI 类型编写 merge/split 处理程序。但是需要有人赞助这项工作。

ffmpeg 是开源的,如果你开发那个代码,他们很可能会接受补丁。