diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2015-03-23 11:11:19 -0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-03-25 12:04:00 +0100 |
commit | 589a6042ea80a76c1c936d768a80eb66abd86a2f (patch) | |
tree | edc49a7cf741ea743864fdb7c02ce4c69fbdd52e | |
parent | b8e36690e8d9d60c36c4c9fa470073d58e96646f (diff) | |
download | ffmpeg-589a6042ea80a76c1c936d768a80eb66abd86a2f.tar.gz |
avutil: make AVFrameSideData buffers ref-counted.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavutil/frame.c | 53 | ||||
-rw-r--r-- | libavutil/frame.h | 1 |
2 files changed, 39 insertions, 15 deletions
diff --git a/libavutil/frame.c b/libavutil/frame.c index 85f56373a1..4596927f97 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 2fab79e58b..1e6d9cda00 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -136,6 +136,7 @@ typedef struct AVFrameSideData { uint8_t *data; int size; AVDictionary *metadata; + AVBufferRef *buf; } AVFrameSideData; /** |