[FFmpeg-devel] [PATCH][VAAPI][2/6] Add common data structures and helpers (take 12)
Gwenole Beauchesne
gbeauchesne
Thu Mar 19 00:44:06 CET 2009
Le 19 mars 09 ? 00:01, Michael Niedermayer a ?crit :
>>> [...]
>>>> +void *ff_vaapi_alloc_slice(AVCodecContext *avctx, const uint8_t
>>>> *buffer, uint32_t size)
>>>> +{
>>>> + MpegEncContext * const s = avctx->priv_data;
>>>> + struct vaapi_picture_private *pp = s->current_picture_ptr-
>>>>> hwaccel_data_private;
>>>> + uint8_t *slice_params;
>>>> + VASliceParameterBufferBase *slice_param;
>>>> +
>>>> + if (!pp->slice_data)
>>>> + pp->slice_data = buffer;
>>>> + if (pp->slice_data + pp->slice_data_size != buffer) {
>>>> + if (commit_slices(avctx, s->current_picture_ptr) < 0)
>>>> + return NULL;
>>>> + pp->slice_data = buffer;
>>>> + }
>>>
>>> can commit_slices() here be called with slice_count=0 ?
>>> if so does that work?
>>
>> If slice_count==0, commit_slices() can't be called because pp-
>>> slice_data==buffer && pp->slice_data_size==0.
>> But yes, if slice_count==0, commit_slices() now returns 0
>> immediately,
>> which wasn't the case before.
>> So, the first if (!pp->slice_data) check could probably be dropped,
>> is
>> this what you meant? (unless buffer can be allocated from 0, or size
>> be very large, which is very unlikely).
>
> i didnt mean anything beyond what i said, that is that it looks odd, i
> did not investigate what exactly would be the best solution
Hey, I'd rather keep the code as is because removing that check would
require another pill for me. ;-)
(mainly because of the unlikely case I exposed -- unlikely does not
mean risk-free to happen).
>>>> + dprintf(avctx, "ff_vaapi_common_end_frame()\n");
>>>> +
>>>> + if (commit_slices(avctx, s->current_picture_ptr) < 0)
>>>> + return -1;
>>>> + if (pp->n_slice_buf_ids > 0) {
>>>> + if (render_picture(avctx, s->current_picture_ptr) < 0)
>>>> + return -1;
>>>> + ff_draw_horiz_band(s, 0, s->avctx->height);
>>>> + }
>>>> +
>>>> + destroy_buffers(va_context->display, &pp->pic_param_buf_id,
>>>> 1);
>>>> + destroy_buffers(va_context->display, &pp->iq_matrix_buf_id,
>>>> 1);
>>>> + destroy_buffers(va_context->display, &pp->bitplane_buf_id, 1);
>>>> + destroy_buffers(va_context->display, pp->slice_buf_ids, pp-
>>>>> n_slice_buf_ids);
>>>> + av_freep(&pp->bitplane_buffer);
>>>> + av_freep(&pp->slice_buf_ids);
>>>> + av_freep(&pp->slice_params);
>>>
>>> do the return -1 above lead to memleaks?
>>
>> ff_vaapi_common_end_frame() is always called, but yes, I had an
>> alternative with a temporary result var but it did not look
>> particularly beautiful to me:
>>
>> int r;
>> if ((r = commit_slices(avctx, s->current_picture_ptr)) >= 0) {
>> if (pp->n_slice_buf_ids > 0 && ((r = render_picture(avctx, s-
>>> current_picture_ptr)) >= 0)
>> ff_draw_horiz_band(s, 0, s->avctx->height);
>> }
>> [...]
>> return r;
>>
>> would be OK with you?
>
> no but a goto would
int r = -1;
if (commit_slices(...) < 0)
goto done;
[...]
r = 0;
done:
[... free stuff ...]
return r;
?
I don't really see how to do that without a temp var. If you know,
please tell.
>>>> +struct vaapi_picture_private {
>>>> + VABufferID pic_param_buf_id; ///<
>>>> VAPictureParameterBuffer ID
>>>> + VABufferID iq_matrix_buf_id; ///<
>>>> VAIQMatrixBuffer ID
>>>> + VABufferID bitplane_buf_id; ///< VABitPlaneBuffer
>>>> ID (for VC-1 decoding)
>>>> + VABufferID *slice_buf_ids; ///< Slice parameter/
>>>> data buffer IDs
>>>> + unsigned int n_slice_buf_ids; ///< Number of
>>>> effective slice buffer IDs to send to the HW
>>>> + unsigned int slice_buf_ids_alloc; ///< Size of pre-
>>>> allocated slice_buf_ids
>>>> + union {
>>>> + VAPictureParameterBufferMPEG2 mpeg2;
>>>> + VAPictureParameterBufferMPEG4 mpeg4;
>>>> + VAPictureParameterBufferH264 h264;
>>>> + VAPictureParameterBufferVC1 vc1;
>>>> + } pic_param; ///< Picture parameter
>>>> buffer
>>>> + unsigned int pic_param_size; ///< Size of a
>>>> VAPictureParameterBuffer element
>>>> + union {
>>>> + VAIQMatrixBufferMPEG2 mpeg2;
>>>> + VAIQMatrixBufferMPEG4 mpeg4;
>>>> + VAIQMatrixBufferH264 h264;
>>>> + } iq_matrix; ///< Inverse
>>>> quantization matrix buffer
>>>> + unsigned int iq_matrix_size; ///< Size of a
>>>> VAIQMatrixBuffer element
>>>> + uint8_t iq_matrix_present; ///< Flag: is
>>>> quantization matrix present?
>>>
>>>> + uint8_t *bitplane_buffer; ///< VC-1 bitplane
>>>> buffer
>>>> + unsigned int bitplane_buffer_size; ///< Size of VC-1
>>>> bitplane buffer
>>>
>>> the way i understand it, is that this stuff is filled in and then
>>> decoded by the hardware before filling the next in, and it isnt used
>>> otherwise, if so it is like a local context and does not really need
>>> to
>>> be allocated and stored per picture
>>
>> How/where would you allocate it? The fields are progressively filled
>> in by either start_frame(), or decode_slice() or end_frame(). So,
>> storage somehow needs to be persistent between those calls. What
>> mechanism can guarantee this without memory allocation? If memory
>> allocation is a performance problem, we could very well write a pool
>> based memory allocator with bins of specific sizes (ranges).
>
> i felt it would fit better in AVCodecContext.hwaccel_context
I'd prefer keep hwaccel_context (for VA API case) read-only from an
FFmpeg POV, wasn't that what you intended too? I mean, having bits of
a struct filled in by either the user app or by lavc (as temp data)
could be confusing. The goal was also to not expose internal data to
the user, even though it's somewhat short-lived, and user normally has
zero chance to disturb this process.
I don't mind though I finally found the current separation/approach
quite elegant.
Besides, if the temporary bits that are lazily-allocated (e.g.
slice_params) are moved to hwaccel_context, we'd need another
AVCodecContext member function to clean that up. i.e. no, I don't want
the user clean up things allocated and only used by lavc internally.
The rest are very minor things, and IMHO it's also better to keep data
for the decoding task in a single location. i.e. if pic_param needs to
be there anyway, just keep his friends with him in the same struct.
More information about the ffmpeg-devel
mailing list