[FFmpeg-devel] [RFC][PATCH] Convert XvMC to hwaccel

Ivan Kalvachev ikalvachev at gmail.com
Tue Dec 17 03:06:47 CET 2013

There is a patch merged from libav that removes XvMC on next major api bump.
Their reasons are: lack of maintainer, xvmc not provided by video card
drivers and xvmc not using hwaccel.
I've always been the maintainer of XvMC.
XvMC is provided by ATI Catalyst binary drivers. The last 13.4 release
contains a working version (but doesn't work with xorg 1.14+).
The recent merge of UVD support in the open source mesa3d/gallium also
provides fully working XvMC support (for all recent and a number of
old cards). I actually used that one for this development.

So, the remaining problem was converting XvMC to hwaccel and
maintaining (some) API compatibility with libav. (I have no illusions
that they would port my changes, but ffmpeg still tries to be able to
work as drop-in replacement for libav.)

What have I done in the patch:

1. I'm using the change to get rid of both
(AV_)PIX_FMT_XVMC_MPEG2_IDCT/MOCO and use a single PIX_FMT for XVMC.
I've noticed that similar change is scheduled for VDPAU.
For compatibility the new PIX_FMT is just define of the IDCT one,
after the API change it would be into the ffmpeg specific format

2. Create AVHWAccel structures for XvMC.

3. Convert frame_start/end to hwaccel. Remove the duplicate calls from
mpegvideo.c (They were supposed to be used for other mpeg like
formats, like mjpeg or dv, that was never implemented).

4. Change the definition of (*decode_slice)(), since XvMC need ffmpeg
macroblock decoding routines. Even dummy decode_slice function would
bypass decoding stages needed by xvmc.

5. Added a new callback function (*decode_mb)() in AVHWAccel. I did
this because it is used in a common code
mpegvideo.c::ff_MPV_decode_mb*(). It might need some version bump, but
IMHO AVHWAccel should be entirely internal to libavcodec.

6. Replace avctx->xvmc_acceleration. That variable was never meant to
be used outside of the codec. I have no idea why it even have parsed
options. It was just meant as a quick way to detect hwaccel mode.
At first I replaced it with (avctx->pix_fmt == AV_PIX_FMT_XVMC), but
then I decided that using (avctx->hwaccel->decode_mb) is much more
explicit and flexible. I know it is not likely that there will be
another hwaccel that uses it... Still, there are places (like
error_resilience) where seeing hwaccel->decode_mb is self explanatory
- why decode_mb() functions could be used, while direct image access
could not.

7. Add .pack_pblocks var to MpegEncCtx. In the past xvmc_acceleration
had two values 1 and 2, for two different modes. In the first one dc
and ac DCT coefficients are decoded in codec own buffers and then
memcpy-ed into an array provided by the video driver. The second one
used packing, this way letting dc/ac decoding to be done directly into
the provided array (it also provided significant speedup).
The second mode uses 2 additional functions. init_block() sets the
buffer to be in the driver array. pack_pblock() makes so all coded
blocks are one after the other.
At first I though that I should add both of these function to
AVHWAccel, but decided against it.
First, because xvmc can work without them. Second, because I found
that vdpau also calls its own functions directly. Third, pack_pblock()
isn't actually a xvmc specific function. I could actually move it to
mpeg12dec.c and even use it during software decoding (I don't expect
any speedup;)).

8. Moved exchange_uv() to mpegvideo_xvmc. It was logical to be
together with pack_pblock. However there is actually a duplicate of it
in mpegvideo.c . It is used for software VCR decoding.

9. Cleaned up a bit of the mpeg12 initialization code, now that
hwaccel is used. (It could be cleaned further, also it kind of assumes
hwaccel never fails, even for vdpau).

10. Removed FF_API_XVMC, from code that is now used for the hwaccel XvMC.
The thing that are going to be removed on the api change are:
- The old (AV)_PIX_FMT_MPEG2_* and their description.
- IMGFMT_XVMC from vf_mp. no filter have ever supported XvMC.
- avctx->xvmc_acceleration and "xvmc_acceleration" from options_table
- AV_CODEC_ID_MPEG2VIDEO_XVMC and "mpeg12_xvmc" codec. These haven't
actually been used for quite some time.

11. I've kept CODEC_CAP_HWACCEL, but I've written an description how
it is supposed to be used. Unfortunately some applications have used
it for XvMC detection in the past.

12. I've added some code to configure to extend the existing detection
and generate the definitions needed for hwaccel. Also enabled xvmc by
Maybe I should not.

I've tested my changes, everything seems to work just like before.

So, I'll repeat the main questions.
- Is it OK to add decode_mb() in AVHWAccel and should I bump some
minor/patch version to do it. Should I add the function at the end of
the struct? Are there really external HWAccels?
- Should I add init_block() to AVHWAccel.
- Should I move pack_pblock() to mpeg12dec.c . Should I make
ff_exchange_uv() and use it.

While I was writing this, I realized that the code uses
The decoder will be removed, so this define should not be used.
My next patch would be to replace it with CONFIG_XVMC, my changes to
configure seem to create that define.

Best Regards
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Convert-XvMC-to-hwaccel.patch
Type: text/x-patch
Size: 24674 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131217/e54ebb3d/attachment.bin>

More information about the ffmpeg-devel mailing list