[FFmpeg-devel] [PATCH] HWAccel infrastructure (take 3)
Gwenole Beauchesne
gbeauchesne
Wed Feb 18 16:23:22 CET 2009
On Wed, 18 Feb 2009, Michael Niedermayer wrote:
>>>> + int (*start_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_offset);
>>>
>>> hmm this seems poorly designed
>>> first, it needs a buf_size or you will segfault
>>> second buf / buf_offset can be replaced by buf or why not?
>>
>> Actually, the correct sequence order was meant to be start_slice(),
>> decode_slice(), end_slice() so that to follow natural processing of the
>> bitstream in the codec implementation. Otherwise, we can end up
>> duplicating code to advance to the next slice and/or add other variables
>> to record the previous position then compute size. i.e. IMO, uglification
>> in some locations (in h263dec.c in particular).
>>
>> If it's OK with you to slightly uglify h263dec but make it possible to
>> merge all 3 into a single decode_slice() call, then that'd be fine with me
>> too.
>
> start&decode as in your patch can be merged without any other changes
> i cant speak about if i would accept some uglification without really seeing
> it
> also considering the special casing in mpeg1/2 it does not seem the split in
> 3 really avoids uglification
OK, I probably could do something like the following in
h263dec.c::decode_slice():
if (s->avctx->hwaccel) {
/* FIXME: we only handle "normal" H.263 / MPEG-4 bitstreams */
assert(!s->msmpeg4_version);
int current_pos = get_bits_count(&s->gb) / 8;
int end_pos, resync_marker_pos = -1;
if ((resync_marker_pos = ff_h263_resync(s)) < 0)
end_pos = (s->gb.size_in_bits+7)/8;
else
end_pos = resync_marker_pos;
if (s->avctx->hwaccel->start_slice(s->avctx, s->gb.buffer + current_pos, end_pos - current_pos) < 0)
return -1;
return s->avctx->hwaccel->end_slice(s->avctx);
}
then, don't perform the second ff_h263_resync() in the
while(s->mb_y<s->mb_height) block from ff_h263_decode_frame() i.e.
if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits)
break;
- }else{
+ }else if(!s->avctx->hwaccel){
if ((resync_marker_pos = ff_h263_resync(s)) < 0)
break;
}
That should be enough. Would that be OK with you (stylistically speaking)?
>> Concerning buf / buf_offset, this was meant for optimization purposes in
>> the HWAccel implementation. That way we can reduce control blocks and/or
>> (it depends on the HWAccel) copy only one buffer in the end.
>
> if you have buf + buf_size and the buffers overlap you can do that too,
> besides if you have a buf/buf_size from start_frame you could check if
> the slices buffer is within that.
It depends, if the hardware accelerator wants the unescaped data (e.g. for
H.264 and VC-1), then the check wouldn't be valid since the passed args
would be from another (temporary) buffer. On the other hand, VA API and
VDPAU are working fine with the escaped (raw bitstream) data.
buf/buf_size from start_frame would be the buf/buf_size from
AVCodec::decode_frame()? I really want start_frame() to be at a location
where we are assured that frame info is parsed.
For h264.c, that'd be a little problematic. I could use the same mpeg12.c
trick to use s->first_slice and:
NAL_SLICE: [...]
if((err = decode_slice_header(hx, h)))
break;
if(s->avctx->hwaccel && s->first_slice){
s->first_slice=0;
s->avctx->hwaccel->start_frame(s->avctx, buf, buf_size);
}
but I might not get the whole frame buffer. Or I could place the
start_frame() call where ff_vdpau_h264_set_reference_frames(s); currently
is. But in that case, I might have the following AVHWAccel hooks calling
sequence: [?start_slice() ]+, end_slice(), start_frame(), end_frame(),
which is not really desirable.
IMO, this complicates a little the code for no real gain. I don't actually
need buf/buf_size in neither VA API nor VDPAU.
>>>> @@ -950,7 +950,8 @@ void MPV_frame_end(MpegEncContext *s)
>>>> //just to make sure that all data is rendered.
>>>> if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
>>>
>>>> ff_xvmc_field_end(s);
>>>> - }else if(!(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
>>>> + }else if(!s->avctx->hwaccel
>>>> + && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
>>>> && s->unrestricted_mv
>>>
>>> }else if(!(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
>>> + !s->avctx->hwaccel
>>> && s->unrestricted_mv
>>
>> Order does not really matter here since the next patch will remove the
>> HWACCEL_VDPAU thing. So, currently it's 1-/2+ then 1-, and with your
>> suggestion that will be 1+ then 2-/1+ -- do you prefer keeping some more
>> work for next time? ;-)
>
> you can do it as 1+ and then 1-/1+
Sorry, I don't see how. Could you please show it off to me?
Thanks,
Gwenole.
More information about the ffmpeg-devel
mailing list