我们正在尝试将 ffmpeg4 与 Pyglet 结合起来。
一切进展顺利,但我们有一个问题:
如果使用 ffmpeg4 从带有 alpha 的 png 文件创建 VP9(或 VP8)文件,我们将获得内部带有 alpha 的视频文件(webm)。
ffmpeg -i image_seq%03d.png -qmin 0 -qmax 50 -crf 5 -b:v 1M output.webm
带有 alpha 的 webm 视频示例可在此页面找到:https://simpl.info/videoalpha/
然而,在播放时,除非我们将编解码器覆盖为 libvpx,否则我们无法获得 alpha。(可以在 CLI 版本的 ffplay 中演示相同的行为)。我们正在包装 avutil, avcodec, etc
。
问题:在代码中,正确识别 VP8 或 VP9 流是否具有 alpha 分量的方法是什么?(这样我们就可以加载它并通过AVFrame()
RGBA 纹理访问它。)
进一步来说:
我们从文件中获取 FormatContext ,并从该 FormatContext 中AVFormatContext
获取流。AVStream
然后我们从中AVStream
得到‘codecpar’参数。
从中AVCodecParameters
我们可以检查codec_id(167是VP9)和其他有用的参数,例如bits_per_coded_sample
。
有趣的是,这些值对于 24 位的 H264 (codec_id=27) 等流似乎是正确的,但对于 VP9 编解码器则标记为 0。这让我认为这不是找到正确值的正确位置。
答案1
好的,原生编解码器不如 Webm 用户提供的 libvpx 编解码器好。因此,如果您想要此 alpha 信息,则应在加载时使用 libvpx 编解码器覆盖编解码器。
如何做到这一点 - 请参阅此处:https://stackoverflow.com/questions/35340437/how-can-i-use-avformat-open-input-function-ffmpeg
基本上,第三个参数avformat_open_input()
需要是av_find_input_format("libvpx")
类型AVInputFormat
如果您不确定文件上下文中是否为 VP8,9 编解码器,则需要先探测文件,发现编解码器,然后在实际加载中覆盖它。请参阅此处了解如何执行此操作: https://stackoverflow.com/questions/14134589/what-does-the-avformat-open-input-do
最后 - 如果您想使用本机而不是 webm 编解码器,除非它具有 alpha(但您为什么要这样做)那么您可以通过检查 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL 侧数据来检查它的 alpha 标志是否设置。
检查 AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,如果 side_data 以 (uint64_t) 1 开头,则存在透明层。
但普遍的共识似乎是始终使用 libvpx 解码器。
编辑:更多详细信息 google VP8 编解码器的 ID 为 139。167 是 Google VP9 编解码器。要替换 libvpx 版本,您需要使用例如 avcodec_find_decoder_by_name("libvpx-vp9") 查找“libvpx-vp8”和“libvpx-vp9”