[FFmpeg-devel] [PATCH 2/2] avutil: make AVFrameSideData buffers ref-counted.
wm4
nfxjfg at googlemail.com
Mon Mar 23 17:16:46 CET 2015
On Mon, 23 Mar 2015 11:11:19 -0400
"Ronald S. Bultje" <rsbultje at gmail.com> wrote:
> ---
> libavutil/frame.c | 53 ++++++++++++++++++++++++++++++++++++++---------------
> libavutil/frame.h | 1 +
> 2 files changed, 39 insertions(+), 15 deletions(-)
>
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 85f5637..4596927 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -115,7 +115,7 @@ static void free_side_data(AVFrameSideData **ptr_sd)
> {
> AVFrameSideData *sd = *ptr_sd;
>
> - av_freep(&sd->data);
> + av_buffer_unref(&sd->buf);
> av_dict_free(&sd->metadata);
> av_freep(ptr_sd);
> }
> @@ -275,7 +275,7 @@ int av_frame_get_buffer(AVFrame *frame, int align)
> return AVERROR(EINVAL);
> }
>
> -int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
> +static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
> {
> int i;
>
> @@ -320,13 +320,28 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
> if ( sd_src->type == AV_FRAME_DATA_PANSCAN
> && (src->width != dst->width || src->height != dst->height))
> continue;
> - sd_dst = av_frame_new_side_data(dst, sd_src->type,
> - sd_src->size);
> - if (!sd_dst) {
> - wipe_side_data(dst);
> - return AVERROR(ENOMEM);
> + if (force_copy) {
> + sd_dst = av_frame_new_side_data(dst, sd_src->type,
> + sd_src->size);
> + if (!sd_dst) {
> + wipe_side_data(dst);
> + return AVERROR(ENOMEM);
> + }
> + memcpy(sd_dst->data, sd_src->data, sd_src->size);
> + } else {
> + sd_dst = av_frame_new_side_data(dst, sd_src->type, 0);
> + if (!sd_dst) {
> + wipe_side_data(dst);
> + return AVERROR(ENOMEM);
> + }
> + sd_dst->buf = av_buffer_ref(sd_src->buf);
> + if (!sd_dst->buf) {
> + wipe_side_data(dst);
> + return AVERROR(ENOMEM);
> + }
> + sd_dst->data = sd_dst->buf->data;
> + sd_dst->size = sd_dst->buf->size;
> }
> - memcpy(sd_dst->data, sd_src->data, sd_src->size);
> av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
> }
>
> @@ -356,7 +371,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
> dst->channel_layout = src->channel_layout;
> dst->nb_samples = src->nb_samples;
>
> - ret = av_frame_copy_props(dst, src);
> + ret = frame_copy_props(dst, src, 0);
> if (ret < 0)
> return ret;
>
> @@ -530,6 +545,11 @@ int av_frame_make_writable(AVFrame *frame)
> return 0;
> }
>
> +int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
> +{
> + return frame_copy_props(dst, src, 1);
> +}
> +
> AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane)
> {
> uint8_t *data;
> @@ -580,13 +600,16 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
> if (!ret)
> return NULL;
>
> - ret->data = av_malloc(size);
> - if (!ret->data) {
> - av_freep(&ret);
> - return NULL;
> - }
> + if (size > 0) {
> + ret->buf = av_buffer_alloc(size);
> + if (!ret->buf) {
> + av_freep(&ret);
> + return NULL;
> + }
>
> - ret->size = size;
> + ret->data = ret->buf->data;
> + ret->size = size;
> + }
> ret->type = type;
>
> frame->side_data[frame->nb_side_data++] = ret;
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 6b9ac6a..e65ad79 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -129,6 +129,7 @@ typedef struct AVFrameSideData {
> uint8_t *data;
> int size;
> AVDictionary *metadata;
> + AVBufferRef *buf;
> } AVFrameSideData;
>
> /**
What if someone wants to do write-accesses to the side-data? I don't
think this patch handles this case. av_frame_make_writable() should be
extended.
More information about the ffmpeg-devel
mailing list