有没有办法强制 FFMPEG 从使用 libvpx-vp9 编码的 WebM 视频解码带有 alpha 的视频流?

问题描述

我有一个 WebM 文件,其中包含一个使用 VP9 (libvpx-vp9) 编码的视频流。

我编写了一个 C++ 程序来从视频流中提取帧并将它们保存为 PNG。这工作正常,只是生成的 PNG 缺少 alpha。

如果我使用 FFMPEG 从同一个 WebM 文件提取帧,则生成的 PNG 确实包含 alpha。这是 FFMPEG 的输出

$ ffmpeg -c:v libvpx-vp9 -i temp/anim.webm temp/output-%3d.png

[libvpx-vp9 @ 0000024732b106c0] v1.10.0-rc1-11-gcb0d8ce31
    Last message repeated 1 times
Input #0,matroska,webm,from 'temp/anim.webm':
  Metadata:
    ENCODER         : Lavf58.45.100
  Duration: 00:00:04.04,start: 0.000000,bitrate: 112 kb/s
  Stream #0:0: Video: vp9 (Profile 0),yuva420p(tv),640x480,SAR 1:1 DAR 4:3,25 fps,25 tbr,1k tbn,1k tbc (default)
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc58.91.100 libvpx-vp9
      DURATION        : 00:00:04.040000000

FFMPEG 将流格式识别为 yuva420p。

这是调用 av_dump_format 时我的程序的输出

Input #0,yuv420p(tv),1k tbc (default)
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc58.91.100 libvpx-vp9
      DURATION        : 00:00:04.040000000

注意检测到的流格式是 yuv420p(缺少 alpha)。

有人知道如何强制流格式使用 alpha 吗?

我的设置代码如下(省略了错误处理)

auto result = avformat_open_input(&formatContext,fileName.c_str(),nullptr,nullptr);
auto result = avformat_find_stream_info(formatContext,nullptr);
streamIndex = av_find_best_stream(formatContext,mediaType,-1,0);
auto stream = formatContext->streams[streamIndex];
const auto codecIdentifier{ AV_CODEC_ID_VP9 };
auto decoder = avcodec_find_decoder(codecIdentifier);
pCodecContext = avcodec_alloc_context3(decoder);
auto result = avcodec_open2(pCodecContext,decoder,&options);
// AV_PIX_FMT_YUV420P - missing alpha
auto pixelFormat = pCodecContext->pix_fmt;

Gyan 指出了问题所在。这是更正后的代码

In case anybody else runs into this issue in the future here is the code (error handling omitted):

auto formatContext = avformat_alloc_context();
formatContext->video_codec_id = AV_CODEC_ID_VP9;
const auto decoder = avcodec_find_decoder_by_name("libvpx-vp9");
formatContext->video_codec = decoder;
avformat_open_input(&formatContext,nullptr);
avformat_find_stream_info(formatContext.get(),nullptr);
for (unsigned int streamIndex = 0; streamIndex < formatContext->nb_streams; ++streamIndex) {
    // displayed the stream format as yuva420p (contains alpha)
    av_dump_format(formatContext,static_cast<int>(streamIndex),fileName.toStdString().c_str(),0);
}
```

Thanks,

解决方法

就像您的 ffmpeg 命令一样,您必须强制使用 vpx 解码器。

使用

auto decoder = avcodec_find_decoder_by_name("libvpx-vp9");

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...