[FFmpeg-devel] [PATCH][7/8] Add VA API accelerated H.264 decoding (take 4)

Gwenole Beauchesne gbeauchesne
Mon Feb 9 10:25:49 CET 2009


Hi Michael,

On Fri, 6 Feb 2009, Michael Niedermayer wrote:

> Please factorize the code somehow.
> I dont want to have all codecs salted with 2 dozen video acceleration APIs

This looks a little unfair to me. I posted the VA API patches at the very 
same time as VDPAU and the only complains at that time were indentation & 
cosmetics so I thought the approach was right. Now, you say the current 
implementation is somewhat crap. I am sorry, it's pretty demotivating.

I believe the current VA API implement should get in as is (with the usual 
cosmetics changes) and have a third party couple of eyes leveraging, which 
generally works better that way. VA API and VDPAU needs different things, 
at different places, and it seems hazardous to try to factor them all at 
once.

I'd pretty would like VA API support integrated for the next FFmpeg 
release as it's the *only* means to have all 3 major vendors HW video 
decode (VLD level) acceleration working through a single API. It turns out 
the current implementation now even outperforms commercial and proprietary 
implementations (Helix, and other GStreamer-based implementation). So 
having this integrated for the upcoming release is a good step forward to 
get broader adoption by other players.

> B. a AVHWAccel struct is added similar to AVCodec and that codecs are
> only allowed to call its members like start_frame() start_slice() end_frame()
> and such

Where would that struct be initialized? Having each codec calling an 
ff_API_CODEC_decode_init() function or have avcodec_get_context_defaults() 
call an ff_API_get_defaults() to initialize the vtable? Though, 
avctx->codec wouldn't be set at this time.

Suggested struct:

typedef struct AVHWAccel {
     void *avctx;
     unsigned int flags; ///< Hardware decode pipeline configuration flags
     int (*start_frame)(AVCodecContext *avctx);
     int (*start_slice)(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size);
     int (*decode_slice)(AVCodecContext *avctx);
     int (*end_slice)(AVCodecContext *avctx);
     int (*end_frame)(AVCodecContext *avctx);
} AVHWAccel;

But there is a problem with this approach. Sometimes, the size of the 
slice can't be known beforehand. e.g. MPEG-4. Unless you accept to 
duplicate code to move to the next resync marker or end of buffer, I don't 
see how to elegantly handle this code.

Probably make start_slice() take a buffer base + offset into this buffer 
(for internal optimisation => use a single whole buffer to emit) and have 
end_slice() take the buffer_end (or size wrt. the previous call to 
start_slice())?

AVHWAccel::flags could be any of:

enum {
   FF_HWACCEL_CAP_DECODE_PICTURE = 1 << 1, ///< HW decoder accepts full picture buffers offloadd. Otherwise, it's on a per-slice basis
   FF_HWACCEL_CAP_DECODE_ESCAPED = 1 << 2, ///< HW decoder accepts raw (escaped) bitstreams. Otherwise, the decoder needs unescaped buffers
};

Regards,
Gwenole.




More information about the ffmpeg-devel mailing list