[Libav-user] get_buffer vs get_buffer2, how do I manage/release buffers?

Antoine Martin antoine at nagafix.co.uk
Thu Nov 14 15:51:36 CET 2013


On 12/11/13 15:25, Hendrik Leppkes wrote:
> On Tue, Nov 12, 2013 at 9:15 AM, Antoine Martin <antoine at nagafix.co.uk> wrote:
>> Hi,
>>
>> Our app uses ffmpeg1.2's "get_buffer" API to manage the lifecycle of the
>> video buffers (decoding vpx and x264):
>> * it overrides "get_buffer" and "release_buffer"
>> * it calls "avcodec_get_buffer" and does its own reference counting
>> * it only calls "avcodec_release_buffer" when it is safe to do so (when
>> both ffmpeg and our code have finished using the buffer)
>>
>> I've looked at porting to ffmpeg2's "get_buffer2" API but I do not
>> understand how we can achieve the same results.
>> How/when do the frames get released? (since "avcodec_release_buffer" is
>> no more)
>> It seems that "refcounted_frames" and "av_frame_unref" have something to
>> do with it, but how?
>>
> You need to fill AVFrame->buf[] using av_buffer_create when you
> allocate a frame, and that function takes a release callback which
> will be called once the buffer is unused and should be released.
> AVCodecContext->release_buffer is unused in this model.
>
> If all you want is reference counting, you don't need to worry about
> implementing your own get_buffer(2) anymore.
> You can simply set AVCodecContext->refcounted_frames to 1, and all
> frames you get from the decoder are yours to keep, until you call
> av_frame_unref or av_frame_free to release it (which you MUST do, or
> you leak memory)
Thanks. I thought I would try this approach first because it would
reduce the amount of code.
But if I not mistaken, all the buffers get copied which is why we are
free to manage them as we please, and I would rather avoid the copy
overhead as we can deal with a lot of large frames per second (1080p
32-bit RGB at 30fps is already ~240MB/s).
Also, I quickly hit a snag:
"av_frame_unref" crashes trying to access "side_data", which is unset
(NULL deref)
Judging from the "av_freep(&frame->side_data)", this side_data is
mandatory, but I just cannot figure out who is supposed to set it and
what with!

The downside of the "av_buffer_create" approach is that I am going to
have to duplicate the code which figures out how big the buffer needs to
be. When previously I didn't have to do any of that.
Unless... Would it be dangerous (or even possible), to use
"avcodec_default_get_buffer2" from my own "get_buffer2" callback and
just save+replace the free callback that is set with my own one so that
I can defer the free call until we are also done with the buffer?
(this would be much closer to the code we currently have - only changing
where we override the release call, but none of the logic)

Thanks
Antoine
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20131114/85e65f1c/attachment.html>


More information about the Libav-user mailing list