当前位置:  开发笔记 > 编程语言 > 正文

执行失败:0x80070057,使用dxva2通过ffmpeg解码视频时

如何解决《执行失败:0x80070057,使用dxva2通过ffmpeg解码视频时》经验,为你挑选了1个好方法。

我已经使用ffmpeg成功实现了一个视频播放器.我现在正在尝试使用硬件解码,但我面临一些问题.我发现了一篇帖子,我将其作为起点:http://comments.gmane.org/gmane.comp.video.ffmpeg.libav.user/13523

我已经更新了为解码器设置必要内容的代码.更新后的代码可以在这里找到: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;
}

当我打开一个高清分辨率或更低分辨率的mp4(h264编码)视频时,一切似乎都运行正常.但是,只要我尝试像3840x2160这样的高分辨率视频,我就会反复出现以下错误:

Failed to execute: 0x80070057
Hardware accelerator failed to decode picture

几秒钟后我也开始收到以下错误:

co located POCs unavailable

并且视频显示不正确:我在整个视频中收到了很多文物,而且它是滞后的.我检查了ffmpeg源代码中的第一个错误.由于参数无效,似乎IDirectXVideoDecoder_Execute失败.由于ffmpeg正在发生这种情况,因此必定会有一些我缺少的东西,但我无法弄清楚是什么.我发现此错误的唯一相关帖子是因为多线程,但我在打开编解码器之前将thread_count设置为1.

这个问题发生在我的主计算机上,它有以下规格:

i7-4790 CPU @ 3.6GHz

RAM 16 GB

英特尔高清显卡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编译的版本.我已经搜索了很多,但我无法找到我做错了什么.

希望有人可以帮助我,或者指点一个更好的例子?



1> CD83..:

我终于找到了我的问题.在调用avcodec_decode_video2之后,我没有像这样更新数据包的大小和数据指针:

int r = avcodec_decode_video2(_codecContext, frame, &frameDecoded, &pkt);
pkt.size -= r;
pkt.data += r;

现在,视频已正确解码,我不再有任何工件.

此外,关于滞后,我认为这是一个单独的问题,与错误消息无关,并且由于将图像复制回CPU的内存所花费的时间.如果您需要这样做,而不是像我在上面的问题中发布的代码中那样使用av_image_copy_plane,您可能需要查看VLC的功能,或者在此链接https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers.我在我的机器上进行了快速测试,它将时间缩短了7或8倍.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有