2016-01-05 21 views
7

Tôi đã triển khai thành công trình phát video bằng ffmpeg. Tôi hiện đang cố gắng sử dụng giải mã phần cứng nhưng tôi đang đối mặt với một số vấn đề. Tôi đã tìm thấy bài đăng mà tôi đã theo dõi dưới dạng điểm xuất phát tại đây: http://comments.gmane.org/gmane.comp.video.ffmpeg.libav.user/13523Không thực thi được: 0x80070057, khi giải mã video qua ffmpeg với dxva2

Tôi đã cập nhật mã thiết lập nội dung cần thiết cho bộ giải mã. Các mã được cập nhật có sẵn ở đây: https://drive.google.com/file/d/0B5ufHdoDzA4ieVk5UVpxcDNzRHc/view?usp=sharing

Và đây là cách tôi đang sử dụng nó để khởi tạo các bộ giải mã:

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

Và đây là định nghĩa của GetHwFormat tham chiếu ở trên:

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

Khi tôi mở một video mp4 (được mã hóa trong h264) có độ phân giải HD trở xuống, mọi thứ có vẻ hoạt động tốt. Tuy nhiên, ngay sau khi tôi thử video độ phân giải cao như 3840x2160, tôi nhận được các lỗi sau đây liên tục:

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

Tôi cũng bắt đầu nhận được các lỗi sau đây sau một vài giây:

co located POCs unavailable 

Và video được không được hiển thị đúng cách: Tôi nhận được rất nhiều đồ tạo tác trên tất cả video và nó bị trễ. Tôi đã kiểm tra lỗi đầu tiên trong mã nguồn ffmpeg. Dường như IDirectXVideoDecoder_Execute không thành công do tham số không hợp lệ. Kể từ khi điều này xảy ra với ffmpeg, phải có một cái gì đó mà tôi đang thiếu nhưng tôi không thể tìm ra những gì. Bài viết liên quan duy nhất mà tôi tìm thấy với lỗi này là do đa luồng nhưng tôi đặt thread_count thành 1 trước khi mở codec.

Vấn đề này đang xảy ra trên máy tính chính của tôi trong đó có các thông số kỹ thuật sau:

  • i7-4790 CPU @ 3.6GHz
  • RAM 16 GB
  • Intel HD Graphics 4600
  • Windows 8.1

Vấn đề tương tự không xảy ra trên máy tính thứ hai của tôi có thông số kỹ thuật sau:

  • i7 4510U @ 2GHz
  • RAM 8 GB
  • NVIDIA GeForce GTX 750Ti
  • của Windows 10

Nếu tôi sử dụng DXVAChecker trên máy tính chính của tôi, nó nói rằng card đồ họa của tôi hỗ trợ DXVA2 cho H264_VLD_ *, và tôi có thể thấy rằng các cuộc gọi đến Microsoft API đang được thực hiện (DXVA2_DecodeDeviceCreated, DXVA2_DecodeDeviceBeginFrame, DXVA2_DecodeDeviceGetBuffer, DXVA2_DecodeDeviceExecute, DXVA2_DecodeDeviceEndFrame) trong khi video của tôi đang phát.

Tôi cũng không thấy bất kỳ sự gia tăng sử dụng GPU nào (trên cả hai máy tính) giữa phiên bản với giải mã phần cứng và phiên bản không có; Tuy nhiên, tôi thấy việc giảm sử dụng CPU (không nhiều như tôi mong đợi). Điều này cũng rất lạ.

Lưu ý rằng tôi đã thử cả bản phát hành Windows có sẵn trên trang web FFmpeg và phiên bản mà tôi đã biên dịch bằng --enable-dxva2. Tôi đã tìm kiếm rất nhiều nhưng tôi không thể tìm thấy những gì tôi đang làm sai.

Hy vọng rằng, ai đó có thể giúp tôi hoặc có thể chỉ cho tôi một ví dụ tốt hơn?

+0

Tôi cũng chỉ thử nghiệm trên Surface Pro 3 với i5 4300U @ 1.9GHz (4 CPU), 8 GB RAM, Intel HD Graphics 4400, Windows 10 và video có vẻ tốt. Không có thông báo lỗi.CPU sử dụng ít hơn 40% mà không cần giải mã phần cứng như máy tính thứ hai được đề cập ở trên.GPU chỉ có 1% hoặc có thể thêm 2% (giống như 2 máy tính khác được đề cập ở trên) thử nghiệm cùng một video ở 3840x2160 . – CD83

Trả lời

5

Cuối cùng tôi đã tìm ra vấn đề của mình là gì. Sau khi gọi avcodec_decode_video2, tôi đã không cập nhật kích thước và dữ liệu con trỏ của gói như thế này:

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

Bây giờ, video được giải mã đúng và tôi không có hiện vật nữa.

Ngoài ra, liên quan đến độ trễ, tôi tin rằng đây là một vấn đề riêng biệt, không liên quan đến thông báo lỗi và do thời gian cần để sao chép ảnh trở lại bộ nhớ của CPU. Nếu bạn cần làm điều này, thay vì sử dụng av_image_copy_plane như trong mã mà tôi đã đăng với câu hỏi của tôi ở trên, bạn có thể muốn xem những gì VLC thực hiện, hoặc tại liên kết này https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers. Tôi đã thực hiện một bài kiểm tra nhanh trên máy của mình và giảm thời gian theo hệ số 7 hoặc 8.

Các vấn đề liên quan