[FFmpeg-user] How do I use the HW accerlator?
Wayne Kelly
w.kelly at qut.edu.au
Tue May 22 01:55:34 CEST 2012
Hi nrson,
I've similarly been battling to get DXVA2 to work for H264 decoding. The following is what I've learned:
libavcodec does include some support for DXVA2, but it doesn't do all the work necessary to be able to automatically use DXVA2.
The "Player" (i.e. the program that you write to use libavcodec) needs to do half of the work. ffmpeg.exe and ffplay.exe have not been written to use DXVA2.
Everyone points to the VLC open source player as the best (only) example of how to use DXVA2 with libavcodec. Unfortunately VLC is very complex
and hard to even recompile on Windows. It would be great to have a simple/minimal player example that could demonstrate how to do it.
>From what I understand the basic steps are to:
1) get ffmpeg libraries to compile with DXVA2 support enabled.
2) Create a DirectXVideoDecoderService (http://msdn.microsoft.com/en-us/library/windows/desktop/aa965245(v=vs.85).aspx#Decoding)
3) Choose a Decoder configuration and create an array of Direct3DSurfaces
3) Create a dxva_context structure and initialize it's fields with the above objects
4) Get the AVCodecContext for your video stream, e.g: pCodecCtx = pFormatCtx->streams[videoStream]->codec
5) Before you open the decoder, override the get_format, get_buffer, release_buffer functions of this context, eg: pCodecCtx->get_format = MyGetFormat
6) Set the hwaccel_context of this context to the dxva_context structure created earlier.
7) Your get_format function needs to select the PIX_FMT_DXVA2_VLD pixel format.
8) Your get_buffer function needs to return one of your unused Direct3DSurfaces
9) Your release_buffer function needs to note that your Direct3DSurface is now available to be reused.
I've followed these steps and got it to run. It definitely does use the DXVA accelerator and it doesn't crash, but the output frames are garbled rubbish, which by the was is the same output that I get when I turn on DXVA2 decoding in VLC. I suspect the problem is that I haven't set all of the corrrect parameter values when configuring my DirectX objects to match the video format that I'm trying to play. I know that DVXA2 does definitely work on my machine because I can see Windows Media Player using it successfully.
BTW, a useful tool for diagnosing DXVA2 is DXVAChecker (http://bluesky23.yu-nagi.com/en/#DXVAChecker)
Please let me know if you have any success.
Cheers, Wayne.
________________________________
From: ffmpeg-user-bounces at ffmpeg.org [ffmpeg-user-bounces at ffmpeg.org] On Behalf Of nrson [nrson at win4net.com]
Sent: Monday, 21 May 2012 6:00 PM
To: FFmpeg user questions and RTFMs
Subject: Re: [FFmpeg-user] How do I use the HW accerlator?
Hi ffmpeg experts!
I was writer previous sending e-mail(title:how do I use the HW
acclerator?).
But anybody was not reply e-mail.
I am very confused sataus.
Anyway,
I thought if config.h file was done as following, My graphic
board(Intel i5, Nvida Gefoarce) was recognized.
#define CONFIG_HWACCELS 1
#define CONFIG_H264_DXVA2_HWACCEL 1
But My graphic board did't it.
I have found ff_h264_decoder in h264.c changed to #if
CONFIG_H264_DXVA2_HWACCEL ~ #endif
during searching in internet.
Before: AVCodec ff_h264_decoder = {
.name = "h264",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_H264,
.priv_data_size = sizeof(H264Context),
.init = ff_h264_decode_init,
.close = ff_h264_decode_end,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1 |CODEC_CAP_DELAY |
CODEC_CAP_SLICE_THREADS |CODEC_CAP_FRAME_THREADS,
.flush = flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4
AVC / MPEG-4 part 10"),
.init_thread_copy =
ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(profiles),
.priv_class = &h264_class,
};
After:
#if CONFIG_H264_DXVA2_HWACCEL
#include "dxva2_h264.c"
AVCodec ff_h264_dxva_decoder = {
.name = "h264_dxva2",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_H264,
.priv_data_size = sizeof(H264Context),
.init = ff_h264_decode_init,
.close = ff_h264_decode_end,
.decode = decode_slice,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY |
CODEC_CAP_SLICE_THREADS |
CODEC_CAP_FRAME_THREADS,
CODEC_CAP_HWACCEL,
.flush = flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4
AVC / MPEG-4 part 10"),
.init_thread_copy =
ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(profiles),
.priv_class = &h264_class,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P,
PIX_FMT_NONE},
};
#endif
There is errors after compiling as following
libavcodec/dxva2_h264.c:396:12: error: conflicting types for
'decode_slice'
libavcodec/h264.c:3972:12: note: previous definition of 'decode_slice'
was here
libavcodec/h264.c:1299:12: warning: 'decode_init_thread_copy' defined
but not used [-Wunused-function]
libavcodec/h264.c:1315:12: warning: 'decode_update_thread_context'
defined but not used [-Wunused-function]
libavcodec/h264.c:4491:12: warning: 'decode_frame' defined but not
used [-Wunused-function]
I thought that my works have been wrongly.
How can I use dxva2_h264?
I am really big ffmpeg user, please help me...!!!
Best regards in advances
-nrson-
On 2012-05-18 16:55, nrson wrote:
> Hi Carl!
>
> Thank you for your response quickly.
>
> I did it according to your advices and the config.h file created as
> following:
>
> #define CONFIG_HWACCELS 1
> #define CONFIG_H264_DXVA2_HWACCEL 1
>
> I want to recognize dxva2_h264 in my source but I can't use it.
> Please you think I am big ffmpeg beginner.
> My source is next following and what do I do?
>
> AVHWAccel h264_dxva2_hwaccel = NULL;
>
> av_register_all();
> avcodec_register_all();
>
> pGBCodec = avcodec_find_decoder(CODEC_ID_H264);
>
> if(pGBCodec)
> {
> pGBContext = avcodec_alloc_context();
> avcodec_get_context_defaults(pGBContext);
>
> if(!h264_dxva2_hwaccel)
> {
> AVHWAccel* hwaccel = NULL;
> while(hwaccel = av_hwaccel_next(hwaccel))
> {
> if(hwaccel->pix_fmt == PIX_FMT_DXVA2_VLD && hwaccel->id ==
> CODEC_ID_H264)
> {
> h264_dxva2_hwaccel = hwaccel;
> printf("dxva2_hwaccel = %s",h264_dxva2_hwaccel->name);
> break;
> }
> }
> }
> if(!h264_dxva2_hwaccel)
> {
> printf("dxv2 not supported by ffmpeg");
> exit(0);
> }
> if(avcodec_open(pGBContext, pGBCodec) < 0)
> {
> avcodec_close(pGBContext);
> av_free(pGBContext);
>
> pGBContext = NULL;
> }
> }
>
> Best regards,
> nrson
>
> On 2012-05-17 19:27, Carl Eugen Hoyos wrote:
>> nrson <nrson <at> win4net.com> writes:
>>
>>> My configure and version on WinGW are as follows:
>>>
>>> ffmpeg version 0.9.1.git
>>
>> Always use current git head if you are not distributing FFmpeg
>>
>>> built on Apr 20 2012 11:14:30 with gcc 4.6.2
>>> configuration: --enable-gpl --enable-shared
>>
>>> --enable-swscale
>>> --enable-hwaccel=h264_dxva2 --enable-decoder=h264
>>> --enable-w32threads --enable-memalign-hack --disable-libvorbis
>>> --disable-libx264
>>
>> These options look all unneeded, they are the default iirc.
>>
>>> --disable-yasm
>>
>> This is not advisable if you care about performance.
>>
>>> When I reviewd the config.h after compiling, the results was as
>>> following
>>>
>>> #define CONFIG_HWACCELS 0
>>> #define CONFIG_H264_DXVA2_HWACCEL 0
>>>
>>> How do I solves the problem?
>>
>> Look at config.log, search for dxva, it will tell you that
>> you have to install additional headers.
>>
>> Carl Eugen
>>
>> _______________________________________________
>> ffmpeg-user mailing list
>> ffmpeg-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-user
_______________________________________________
ffmpeg-user mailing list
ffmpeg-user at ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-user
More information about the ffmpeg-user
mailing list