--- libavutil/frame.c | 171 +++++++++++++++++++++++++++++++----------------------- libavutil/frame.h | 1 + 2 files changed, 98 insertions(+), 74 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c index 12fe0a6..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,6 +275,91 @@ int av_frame_get_buffer(AVFrame *frame, int align) return AVERROR(EINVAL); } +static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) +{ + int i; + + dst->key_frame = src->key_frame; + dst->pict_type = src->pict_type; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->pts = src->pts; + dst->repeat_pict = src->repeat_pict; + dst->interlaced_frame = src->interlaced_frame; + dst->top_field_first = src->top_field_first; + dst->palette_has_changed = src->palette_has_changed; + dst->sample_rate = src->sample_rate; + dst->opaque = src->opaque; +#if FF_API_AVFRAME_LAVC + dst->type = src->type; +#endif + dst->pkt_pts = src->pkt_pts; + dst->pkt_dts = src->pkt_dts; + dst->pkt_pos = src->pkt_pos; + dst->pkt_size = src->pkt_size; + dst->pkt_duration = src->pkt_duration; + dst->reordered_opaque = src->reordered_opaque; + dst->quality = src->quality; + dst->best_effort_timestamp = src->best_effort_timestamp; + dst->coded_picture_number = src->coded_picture_number; + dst->display_picture_number = src->display_picture_number; + dst->flags = src->flags; + dst->decode_error_flags = src->decode_error_flags; + dst->color_primaries = src->color_primaries; + dst->color_trc = src->color_trc; + dst->colorspace = src->colorspace; + dst->color_range = src->color_range; + dst->chroma_location = src->chroma_location; + + av_dict_copy(&dst->metadata, src->metadata, 0); + + memcpy(dst->error, src->error, sizeof(dst->error)); + + for (i = 0; i < src->nb_side_data; i++) { + const AVFrameSideData *sd_src = src->side_data[i]; + AVFrameSideData *sd_dst; + if ( sd_src->type == AV_FRAME_DATA_PANSCAN + && (src->width != dst->width || src->height != dst->height)) + continue; + 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; + } + av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); + } + + dst->qscale_table = NULL; + dst->qstride = 0; + dst->qscale_type = 0; + if (src->qp_table_buf) { + dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); + if (dst->qp_table_buf) { + dst->qscale_table = dst->qp_table_buf->data; + dst->qstride = src->qstride; + dst->qscale_type = src->qscale_type; + } + } + + return 0; +} + int av_frame_ref(AVFrame *dst, const AVFrame *src) { int i, ret = 0; @@ -286,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; @@ -462,72 +547,7 @@ int av_frame_make_writable(AVFrame *frame) int av_frame_copy_props(AVFrame *dst, const AVFrame *src) { - int i; - - dst->key_frame = src->key_frame; - dst->pict_type = src->pict_type; - dst->sample_aspect_ratio = src->sample_aspect_ratio; - dst->pts = src->pts; - dst->repeat_pict = src->repeat_pict; - dst->interlaced_frame = src->interlaced_frame; - dst->top_field_first = src->top_field_first; - dst->palette_has_changed = src->palette_has_changed; - dst->sample_rate = src->sample_rate; - dst->opaque = src->opaque; -#if FF_API_AVFRAME_LAVC - dst->type = src->type; -#endif - dst->pkt_pts = src->pkt_pts; - dst->pkt_dts = src->pkt_dts; - dst->pkt_pos = src->pkt_pos; - dst->pkt_size = src->pkt_size; - dst->pkt_duration = src->pkt_duration; - dst->reordered_opaque = src->reordered_opaque; - dst->quality = src->quality; - dst->best_effort_timestamp = src->best_effort_timestamp; - dst->coded_picture_number = src->coded_picture_number; - dst->display_picture_number = src->display_picture_number; - dst->flags = src->flags; - dst->decode_error_flags = src->decode_error_flags; - dst->color_primaries = src->color_primaries; - dst->color_trc = src->color_trc; - dst->colorspace = src->colorspace; - dst->color_range = src->color_range; - dst->chroma_location = src->chroma_location; - - av_dict_copy(&dst->metadata, src->metadata, 0); - - memcpy(dst->error, src->error, sizeof(dst->error)); - - for (i = 0; i < src->nb_side_data; i++) { - const AVFrameSideData *sd_src = src->side_data[i]; - AVFrameSideData *sd_dst; - 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); - } - memcpy(sd_dst->data, sd_src->data, sd_src->size); - av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); - } - - dst->qscale_table = NULL; - dst->qstride = 0; - dst->qscale_type = 0; - if (src->qp_table_buf) { - dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); - if (dst->qp_table_buf) { - dst->qscale_table = dst->qp_table_buf->data; - dst->qstride = src->qstride; - dst->qscale_type = src->qscale_type; - } - } - - return 0; + return frame_copy_props(dst, src, 1); } AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) @@ -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; /** -- 2.1.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel