Hi, On Mon, Mar 23, 2015 at 12:16 PM, wm4 <nfx...@googlemail.com> wrote:
> On Mon, 23 Mar 2015 11:11:19 -0400 > "Ronald S. Bultje" <rsbul...@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. av_frame_make_writable() copies (as opposed to refcounts) the side-data, so that works fine. The refcount-increment code is only invoked for av_frame_ref(). Ronald _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel