2016-01-05 14 views
7

ffmpegを使用してビデオプレーヤーを正常に実装しました。ハードウェアデコードを使用しようとしていますが、私はいくつかの問題に直面しています。 私がここに出発点として投稿した記事を見つけました。http://comments.gmane.org/gmane.comp.video.ffmpeg.libav.user/13523実行に失敗しました:0x80070057、dxva2でffmpeg経由でビデオをデコードするとき

デコーダに必要なものをセットアップするコードを更新しました。 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; 
} 

をHD解像度以下の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ギガバイト
  • インテルHDグラフィックス4600
  • のWindows 8.1

次の仕様の2台目のコンピュータで同じ問題は起こりません。

GHzの
  • RAM 8ギガバイト
  • NVIDIAのGeForce GTX 750Ti
  • のWindows 10
  • @

    • i7プロセッサー4510U私は私のメインのコンピュータ上DXVACheckerを使用している場合、それは私のグラフィックカードがDXVA2をサポートしていることを言います私のビデオが再生されている間、Microsoft APIの呼び出しが行われていることがわかります(DXVA2_DecodeDeviceCreated、DXVA2_DecodeDeviceBeginFrame、DXVA2_DecodeDeviceGetBuffer、DXVA2_DecodeDeviceExecute、DXVA2_DecodeDeviceEndFrame)。

      また、ハードウェアのデコードを行っているバージョンと、バージョンがないバージョンの間でGPU使用率(どちらのコンピュータでも)が増加することはありません。しかし、私はCPU使用量の減少を見ています(私が思っていたほどではありません)。これはまた非常に奇妙です。

      FFmpegのWebサイトで入手できるWindowsリリースと、--enable-dxva2でコンパイルしたバージョンの両方を試しました。私はすでに多くを検索しましたが、私が間違っていることを見つけることができませんでした。

      うまくいけば、誰かが私を助けることができますか、より良い例を教えてくれるでしょうか?

    +0

    i5 4300U @ 1.9GHz(4 CPU)、8 GB RAM、インテルHDグラフィックス4400、Windows 10、ビデオはよく見える。エラーメッセージはありません.CPUの使用率は、前述の2台目のコンピュータのようなハードウェアデコードなしの場合よりも40%少なくなります.GPUは、3840x2160で同じビデオをテストすると、1%または多分2%以上(上記の他の2台のコンピュータと同じです) 。 – CD83

    答えて

    5

    私は最終的に私の問題が何かを知った。

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

    さて、映像が正しく復号化され、私はもう何の成果物を持っていない:avcodec_decode_video2呼び出した後、私はこのようなパケットのサイズとデータポインタを更新していませんでした。

    また、遅れに関しては、これはエラーメッセージに関連しない別個の問題であり、イメージをCPUのメモリにコピーするのに時間がかかるためだと思います。これを行う必要がある場合は、上記の質問で投稿したコードのようにav_image_copy_planeを使用する代わりに、VLCの機能やこのリンクhttps://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffersを調べることができます。私はマシン上で簡単なテストを行い、時間を7分の1または8分の1に短縮しました。