[Libav-user] HW Accelerator in Windows: DXVA2 with new API

Hector Alonso hector.alonso.aparicio at gmail.com
Mon Aug 25 15:23:20 CEST 2014

I've rebuilt ffmpeg using these instructions
https://trac.ffmpeg.org/wiki/CompilationGuide/MSVC from the Visual Studio
Console, installing MinGW directly from the link with the flags --enable-dxva2
and --enable-hwaccel=h264_dxva2 and is almost working but I get a lot
of errors:
-1094995529 "Invalid data found when processing input"
from avcodec_decode_video2 a lot of artifacts and a very poor and
inconsistent image quality.
This is my dxva initialization code:

_pCodecCtx->flags|= CODEC_CAP_DR1;
_pCodecCtx->flags|= CODEC_CAP_HWACCEL;

InputStream *ist = new InputStream ();
ist->hwaccel_id = HWACCEL_AUTO;
ist->hwaccel_device = "dxva2";
ist->dec = _pCodec;
ist->dec_ctx = _pCodecCtx;
_pCodecCtx->coded_width  = 1280;
_pCodecCtx->coded_height = 720;
_pCodecCtx->opaque = ist;
_pCodecCtx->opaque  = ist;
_pCodecCtx->get_buffer2 = ist->hwaccel_get_buffer;
_pCodecCtx->get_format = get_format;
_pCodecCtx->thread_safe_callbacks = 0;

before  calling

 if (avcodec_open2(_pCodecCtx , _pCodec, 0) < 0)  ...

Where get_format is:

static enum AVPixelFormat get_format(AVCodecContext *s, const enum
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;

Find attached my modified ffmpeg_dxva2.cpp and ffmpeg_dxva2.h files from
the original ffmpeg_dxva2.c and the InputStream declaration from ffmpeg.h

For getting the decoded frame I call: dxva2_retrieve_data_call, and then I
convert it to YUV420p (I make the final conversion via pixel shader with
OpenGL texture).

Also, with my old CPU decoder I had 3-6% CPU usage and 5-10% GPU usage (as
I said, I'm converting and painting with OpenGL) and now with the "GPU
Accelerated" one I have 5-13% CPU and 6-12% GPU.

Any thoughts?

Thank you!

2014-08-19 11:25 GMT+02:00 Hector Alonso <hector.alonso.aparicio at gmail.com>:

> Hi,
> I'm developing a H264 decoder in Windows and I want to use the hardware
> acceleration capabilities: DXVA2
> I've already built FFMPEG from git (lastest version: N-65404-gd34ec64;
> libavcodec 55.73.101 ...) using Mingw64 for 32bits this way:
> echo 'export PATH=.:/local/bin:/bin:/mingw64/bin' > .profile
> source .profile
> git config --global core.autocrlf false
>   git clone git://git.videolan.org/x264.git x264 cd x264 ./configure
> --host=x86_64-w64-mingw32 --enable-static --enable-shared && make && make
> install cd ..   git clone git://github.com/mstorsjo/fdk-aac.git fdk-aac cd
> fdk-aac ./autogen.sh ./configure --host=x86_64-w64-mingw32 --enable-static
> --enable-shared && make && make install cd ..
> git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg cd ffmpeg
> ./configure --enable-gpl --enable-nonfree --enable-libx264
> --enable-libfdk_aac --enable-memalign-hack --enable-runtime-cpudetect
> --enable-dxva2 --enable-decoder?h264_dxva2 --disable-hwaccels
> --enable-hwaccel=h264_dxva2 --enable-static --enable-shared
> --extra-cflags=-I/local/include --extra-ldflags='-L/local/lib -static' &&
> make && make install
> I've adapted the newest version of ffmpeg_dxva2.c to C++ (with a header
> file including InputStream, HWAccelID and dxva2_init declarations), now
> it builds with VisualStudio 2012 and everything is running correctly with
> my current decoder (not HW accelerated).
> I found an old post of this list (
> https://lists.ffmpeg.org/pipermail/ffmpeg-user/2012-May/006600.html)
> describing the steps for running it, but now te API has changed...
> I've also studied the VLC method, but it is also working with the older
> API (get_buffer instead of get_buffer2, and so).
> In the newest ffmpeg.c they actually use the hwaccel including DXVA2, but
> in quite a complicated way... could you please give an example or a piece
> of advice  on how to do it?
> 1.- Create a InputStream instance, populate it and address it to
> AVCodecContext->opaque. Which are the needed attributes? It requires width
> and height of the input before opening it!
> 2.- call dxva_init() with the decoder AVCodecContext allocated using
> avcodec_alloc_context3 from CODEC_ID_H264 codec before
> calling avcodec_open2 ?
> 3.- Call dxva2_retrieve_data() with the decoder AVCodecContext  and a AV_PIX_FMT_NV12
> frame when avcodec_decode_video2 returns a complete frame (got_output) ?
> 4.- Copy (convert) the resulting frame to a YUV420P OpenGL texture, apply
> a pixelformat conversion shader and show it! <- This step is working fine
> (I did it for a separated decoder using Intel Media SDK last week).
> (Future step. - use directly the DX surface using OpenGL extensions.)
> Now I'm stuck in the first and second steps, when avcodec_decode_video2
> is called it crashes. I've debugged step by step the dxva initialization
> and the DX surfaces are being created correctly. What am I missing?
> Thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20140825/d6aba134/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ffmpeg_dxva2.cpp
Type: text/x-c++src
Size: 21815 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20140825/d6aba134/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ffmpeg_dxva2.h
Type: text/x-chdr
Size: 3525 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20140825/d6aba134/attachment-0001.bin>

More information about the Libav-user mailing list