2016-01-05 36 views
7

Ffmpeg kullanarak bir video oynatıcıyı başarıyla uygulayabildim. Şimdi donanım kod çözme kullanmaya çalışıyorum ama birkaç sorunla karşı karşıyayım. Burada bir başlangıç ​​noktası olarak izlediğim bir gönderi buldum: http://comments.gmane.org/gmane.comp.video.ffmpeg.libav.user/13523Yürütülemedi: 0x80070057, dxva2 ile ffmpeg yoluyla video çözme sırasında

Kod çözücü için gerekli olan öğeleri ayarlayan kodu güncelledim. https://drive.google.com/file/d/0B5ufHdoDzA4ieVk5UVpxcDNzRHc/view?usp=sharing

Ve bu dekoder başlatmak için kullanıyorum nasıl: güncellenen kod burada mevcuttur

// 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; 
} 

Ve burada yukarıda referans GetHwFormat tanımıdır:

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 çözünürlüğü veya daha az olan bir mp4 (h264'te kodlanmış) video açtığımda, her şey iyi çalışıyor gibi görünüyor.

Failed to execute: 0x80070057 
Hardware accelerator failed to decode picture 
şunlarla birkaç saniye sonra hata almaya başlamak

:

co located POCs unavailable 

Ve videodan oluşur Ancak, en kısa zamanda 3840x2160 çözünürlükte gibi yüksek çözünürlüklü videoları, defalarca aşağıdaki hatalar olsun deneyin düzgün görüntülenmiyor: Videonun her yerinde çok fazla yapaylık var ve bu gecikme oluyor. Ffmpeg kaynak kodundaki ilk hatayı kontrol ettim. IDirectXVideoDecoder_Execute geçersiz bir parametre nedeniyle başarısız görünüyor. Bu ffmpeg ile uğraştığından beri, eksik olduğum bir şey olmalı ama ne olduğunu anlayamıyorum. Bu hatayla bulduğum tek ilgili gönderi, çoklu iş parçacığından kaynaklanıyordu, ancak codec'i açmadan önce thread_count değerini 1 olarak ayarladım.

  • i7-4790 işlemci @ 3.6GHz
  • RAM 16 GB
  • Intel HD Grafik 4600
  • Windows 8.1
  • :

    Bu sorun aşağıdaki özeliklere sahip benim ana bilgisayarda oluyor

Aşağıdaki özelliklerdeki ikinci bilgisayarımda da aynı sorun görülmüyor:

GHz @
  • i7 4510U
  • RAM 8 GB
  • NVIDIA GeForce GTX 750Ti
  • , Windows 10

benim ana bilgisayarda DXVAChecker kullanırsanız, benim ekran kartı DXVA2 desteklediğini söylüyor H264_VLD_ * için ve video oynatırken Microsoft API çağrılarının yapıldığını görebiliyorum (DXVA2_DecodeDeviceCreated, DXVA2_DecodeDeviceBeginFrame, DXVA2_DecodeDeviceGetBuffer, DXVA2_DecodeDeviceExecute, DXVA2_DecodeDeviceEndFrame).

Ayrıca, donanım kod çözme sürümü ve sürümü olmayan sürüm arasında herhangi bir GPU kullanımı (bilgisayarlarda) artışı görmüyorum; Ancak, CPU kullanımında bir düşüş görüyorum (beklediğim kadar değil). Bu da çok garip.

FFmpeg web sitesinde bulunan Windows sürümlerini ve --enable-dxva2 ile derlediğim bir sürümü denediğimi unutmayın. Çok fazla arama yaptım ama yanlış yaptığım şeyi bulamadım.

Umarım birileri bana yardımcı olabilir veya belki daha iyi bir örneğe işaret edebilir mi?

+0

Sadece bir i5 4300U @ 1.9GHz (4 CPU), 8 GB RAM ile bir Surface Pro 3 üzerinde test ettim Intel HD Graphics 4400, Windows 10 ve video iyi görünüyor. Hata mesajı yoktur.PU kullanımı yukarıda bahsedilen ikinci bilgisayar gibi donanım kod çözme olmaksızın% 40 daha azdır.GPU sadece% 1 veya belki% 2 daha fazladır (yukarıda bahsedilen diğer 2 bilgisayarla aynıdır) 3840x2160'da aynı videoyu test eder . – CD83

cevap

5

Sonunda sorunumun ne olduğunu öğrendim.

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

Şimdi, video düzgün deşifre edilir ve artık hiçbir eserler vardır: avcodec_decode_video2 çağırdıktan sonra böyle paketinin büyüklüğü ve veri işaretçisi güncellenmesi değildi. Ayrıca, gecikme ile ilgili olarak, bunun hata mesajları ile ilgili olmayan ve görüntüyü CPU belleğine geri kopyalamak için gereken süreden dolayı ayrı bir sorun olduğuna inanıyorum. Bunu yapmam gerekiyorsa, yukarıdaki sorgumla yazdığım kodda olduğu gibi av_image_copy_plane kullanmak yerine, VLC'nin ne yaptığına veya bu bağlantıda https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers'a bakmak isteyebilirsiniz. Makinemde hızlı bir test yaptım ve zamanı 7 veya 8'lik bir faktörle düşürdüm.