有没有一种方法可以强制FFMPEG使用libvpx-vp9编码的WebM视频解码带有Alpha通道的视频流?

4
我有一个包含VP9编码(libvpx-vp9)的WebM文件,其中只有一个视频流。
我写了一个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, 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), yuv420p(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

请注意,检测到的流格式为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, -1, nullptr, 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;

吉安指出了问题所在。这是已经更正的代码:
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, fileName.c_str(), nullptr, 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,
1个回答

4
像您的ffmpeg命令一样,您需要强制使用vpx解码器。
使用:
auto decoder = avcodec_find_decoder_by_name("libvpx-vp9");

谢谢您的建议。我尝试了,但不幸的是,AVCodecContext pix_fmt 仍然缺少 alpha 组件(仍为 AV_PIX_FMT_YUV420P)。 - David
1
在打开格式并查找流信息之前,应在格式上下文中分配视频编解码器。 - Gyan
是的 - 这解决了我的问题!再次感谢。非常感激。 - David
还需要执行'avcodec_find_decoder_by_name("libvpx-vp9");'吗?还是在打开格式之前分配视频编解码器就可以了?我收到一个错误,说没有这个名称的编解码器。但是vp9的解码是有效的。 - avl_sweden
是的,默认解码器是本地的,它不解码alpha通道。你可能没有链接libvpx库。 - Gyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接