我已成功地使用ffmpeg实现了一个视频播放器。现在,我正在尝试使用硬件解码,但我遇到了一些问题。 我找到了一篇文章作为起点,链接在这里:https://ffmpeg.org/pipermail/libav-user/2014-August/007323.html
我更新了设置解码所需内容的代码。更新后的代码可在此处获得:https://drive.google.com/file/d/0B5ufHdoDzA4ieVk5UVpxcDNzRHc/view?usp=sharing
以下是我用来初始化解码器的方式:
// Prepare the decoding context
AVCodec *codec = nullptr;
_codecContext = _avFormatContext->streams[_streamIndex]->codec;
if ((codec = avcodec_find_decoder(_codecContext->codec_id)) == 0)
{
std::cout << "Unsupported video codec!" << std::endl;
return false;
}
_codecContext->thread_count = 1; // Multithreading is apparently not compatible with hardware decoding
InputStream *ist = new InputStream();
ist->hwaccel_id = HWACCEL_AUTO;
ist->hwaccel_device = "dxva2";
ist->dec = codec;
ist->dec_ctx = _codecContext;
_codecContext->coded_width = _width;
_codecContext->coded_height = _height;
_codecContext->opaque = ist;
dxva2_init(_codecContext);
_codecContext->get_buffer2 = ist->hwaccel_get_buffer;
_codecContext->get_format = GetHwFormat;
_codecContext->thread_safe_callbacks = 1;
if (avcodec_open2(_codecContext, codec, nullptr) < 0)
{
std::cout << "Video codec open error" << std::endl;
return false;
}
这里是上面提到的GetHwFormat的定义:
AVPixelFormat GetHwFormat(AVCodecContext *s, const AVPixelFormat *pix_fmts)
{
InputStream* ist = (InputStream*)s->opaque;
ist->active_hwaccel_id = HWACCEL_DXVA2;
ist->hwaccel_pix_fmt = AV_PIX_FMT_DXVA2_VLD;
return ist->hwaccel_pix_fmt;
}
当我打开一个h264编码的mp4视频,它的分辨率是高清或更低时,一切似乎都正常。但是,当我尝试更高分辨率的视频,比如3840x2160时,我会不断遇到以下错误:
Failed to execute: 0x80070057
Hardware accelerator failed to decode picture
几秒钟后,我还会开始收到以下错误:
co located POCs unavailable
视频无法正常显示:视频上出现了很多伪像,而且视频卡顿。我检查了ffmpeg源代码中的第一个错误,发现是因为无效参数引起的IDirectXVideoDecoder_Execute失败。由于这是在ffmpeg内发生的,一定有些我没有注意到的东西,但我无法弄清楚是什么。我找到的唯一与此错误相关的帖子是因为多线程,但在打开编解码器之前,我已将线程数设置为1。
我的主计算机遇到了这个问题,它的规格如下:
- i7-4790 CPU @ 3.6GHz
- RAM 16 GB
- Intel HD Graphics 4600
- Windows 8.1
我的第二台计算机规格如下,没有出现同样的问题:
- i7 4510U @ 2GHz
- RAM 8 GB
- NVIDIA GeForce GTX 750Ti
- Windows 10
如果我在主计算机上使用DXVAChecker,它会说我的显卡支持DXVA2进行H264_VLD_*的硬件加速,并且我可以看到视频播放时调用了Microsoft API(DXVA2_DecodeDeviceCreated、DXVA2_DecodeDeviceBeginFrame、DXVA2_DecodeDeviceGetBuffer、DXVA2_DecodeDeviceExecute、DXVA2_DecodeDeviceEndFrame)。
我在两台计算机上都没有看到GPU使用率的增加(无论是有硬件解码的版本还是没有硬件解码的版本),但是CPU使用率有所下降(虽然下降得不够明显)。这也非常奇怪。
请注意,我已尝试过FFmpeg网站上提供的Windows版本和编译时使用--enable-dxva2选项的版本。我已经搜索了很多,但无法找到自己做错了什么。
希望有人能帮助我,或者指向一个更好的示例?