X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fframe.c;h=d69dd38dc47cea70ade1eda9d64778571a4dd85e;hb=3b56fa85e8f50db83b54518ae31ebdb3f6b0cc39;hp=6c2c28f18fc799ec2ce7a46b390ecf3a7128d140;hpb=f4cf6ba8c9646814af842a99335c6ee312ded299;p=ffmpeg diff --git a/libavutil/frame.c b/libavutil/frame.c index 6c2c28f18fc..d69dd38dc47 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -25,6 +25,7 @@ #include "imgutils.h" #include "mem.h" #include "samplefmt.h" +#include "hwcontext.h" #if FF_API_FRAME_GET_SET MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp) @@ -45,80 +46,7 @@ MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range) (frame)->channels == \ av_get_channel_layout_nb_channels((frame)->channel_layout)) -#if FF_API_FRAME_QP -struct qp_properties { - int stride; - int type; -}; - -int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) -{ - struct qp_properties *p; - AVFrameSideData *sd; - AVBufferRef *ref; - -FF_DISABLE_DEPRECATION_WARNINGS - av_buffer_unref(&f->qp_table_buf); - - f->qp_table_buf = buf; - f->qscale_table = buf->data; - f->qstride = stride; - f->qscale_type = qp_type; -FF_ENABLE_DEPRECATION_WARNINGS - - av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); - av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); - - ref = av_buffer_ref(buf); - if (!av_frame_new_side_data_from_buf(f, AV_FRAME_DATA_QP_TABLE_DATA, ref)) { - av_buffer_unref(&ref); - return AVERROR(ENOMEM); - } - - sd = av_frame_new_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES, - sizeof(struct qp_properties)); - if (!sd) - return AVERROR(ENOMEM); - - p = (struct qp_properties *)sd->data; - p->stride = stride; - p->type = qp_type; - - return 0; -} - -int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) -{ - AVBufferRef *buf = NULL; - - *stride = 0; - *type = 0; - -FF_DISABLE_DEPRECATION_WARNINGS - if (f->qp_table_buf) { - *stride = f->qstride; - *type = f->qscale_type; - buf = f->qp_table_buf; -FF_ENABLE_DEPRECATION_WARNINGS - } else { - AVFrameSideData *sd; - struct qp_properties *p; - sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); - if (!sd) - return NULL; - p = (struct qp_properties *)sd->data; - sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); - if (!sd) - return NULL; - *stride = p->stride; - *type = p->type; - buf = sd->buf; - } - - return buf ? buf->data : NULL; -} -#endif - +#if FF_API_COLORSPACE_NAME const char *av_get_colorspace_name(enum AVColorSpace val) { static const char * const name[] = { @@ -134,7 +62,7 @@ const char *av_get_colorspace_name(enum AVColorSpace val) return NULL; return name[val]; } - +#endif static void get_frame_defaults(AVFrame *frame) { if (frame->extended_data != frame->data) @@ -211,8 +139,10 @@ void av_frame_free(AVFrame **frame) static int get_video_buffer(AVFrame *frame, int align) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - int ret, i, padded_height; + int ret, i, padded_height, total_size; int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); + ptrdiff_t linesizes[4]; + size_t sizes[4]; if (!desc) return AVERROR(EINVAL); @@ -237,17 +167,29 @@ static int get_video_buffer(AVFrame *frame, int align) frame->linesize[i] = FFALIGN(frame->linesize[i], align); } + for (i = 0; i < 4; i++) + linesizes[i] = frame->linesize[i]; + padded_height = FFALIGN(frame->height, 32); - if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, - NULL, frame->linesize)) < 0) + if ((ret = av_image_fill_plane_sizes(sizes, frame->format, + padded_height, linesizes)) < 0) return ret; - frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding); - if (!frame->buf[0]) + total_size = 4*plane_padding; + for (i = 0; i < 4; i++) { + if (sizes[i] > INT_MAX - total_size) + return AVERROR(EINVAL); + total_size += sizes[i]; + } + + frame->buf[0] = av_buffer_alloc(total_size); + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); goto fail; + } - if (av_image_fill_pointers(frame->data, frame->format, padded_height, - frame->buf[0]->data, frame->linesize) < 0) + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + frame->buf[0]->data, frame->linesize)) < 0) goto fail; for (i = 1; i < 4; i++) { @@ -260,7 +202,7 @@ static int get_video_buffer(AVFrame *frame, int align) return 0; fail: av_frame_unref(frame); - return AVERROR(ENOMEM); + return ret; } static int get_audio_buffer(AVFrame *frame, int align) @@ -334,7 +276,7 @@ int av_frame_get_buffer(AVFrame *frame, int align) static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) { - int i; + int ret, i; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; @@ -374,12 +316,6 @@ FF_ENABLE_DEPRECATION_WARNINGS av_dict_copy(&dst->metadata, src->metadata, 0); -#if FF_API_ERROR_FRAME -FF_DISABLE_DEPRECATION_WARNINGS - memcpy(dst->error, src->error, sizeof(dst->error)); -FF_ENABLE_DEPRECATION_WARNINGS -#endif - for (i = 0; i < src->nb_side_data; i++) { const AVFrameSideData *sd_src = src->side_data[i]; AVFrameSideData *sd_dst; @@ -406,36 +342,9 @@ FF_ENABLE_DEPRECATION_WARNINGS av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } -#if FF_API_FRAME_QP -FF_DISABLE_DEPRECATION_WARNINGS - dst->qscale_table = NULL; - dst->qstride = 0; - dst->qscale_type = 0; - av_buffer_unref(&dst->qp_table_buf); - 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; - } - } -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - av_buffer_unref(&dst->opaque_ref); - av_buffer_unref(&dst->private_ref); - if (src->opaque_ref) { - dst->opaque_ref = av_buffer_ref(src->opaque_ref); - if (!dst->opaque_ref) - return AVERROR(ENOMEM); - } - if (src->private_ref) { - dst->private_ref = av_buffer_ref(src->private_ref); - if (!dst->private_ref) - return AVERROR(ENOMEM); - } - return 0; + ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); + ret |= av_buffer_replace(&dst->private_ref, src->private_ref); + return ret; } int av_frame_ref(AVFrame *dst, const AVFrame *src) @@ -454,19 +363,19 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) ret = frame_copy_props(dst, src, 0); if (ret < 0) - return ret; + goto fail; /* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) { - ret = av_frame_get_buffer(dst, 32); + ret = av_frame_get_buffer(dst, 0); if (ret < 0) - return ret; + goto fail; ret = av_frame_copy(dst, src); if (ret < 0) - av_frame_unref(dst); + goto fail; - return ret; + return 0; } /* ref the buffers */ @@ -563,11 +472,6 @@ void av_frame_unref(AVFrame *frame) av_buffer_unref(&frame->extended_buf[i]); av_freep(&frame->extended_buf); av_dict_free(&frame->metadata); -#if FF_API_FRAME_QP -FF_DISABLE_DEPRECATION_WARNINGS - av_buffer_unref(&frame->qp_table_buf); -FF_ENABLE_DEPRECATION_WARNINGS -#endif av_buffer_unref(&frame->hw_frames_ctx); @@ -624,7 +528,11 @@ int av_frame_make_writable(AVFrame *frame) tmp.channels = frame->channels; tmp.channel_layout = frame->channel_layout; tmp.nb_samples = frame->nb_samples; - ret = av_frame_get_buffer(&tmp, 32); + + if (frame->hw_frames_ctx) + ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); + else + ret = av_frame_get_buffer(&tmp, 0); if (ret < 0) return ret; @@ -719,7 +627,7 @@ AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, AVFrameSideData *av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, - int size) + buffer_size_t size) { AVFrameSideData *ret; AVBufferRef *buf = av_buffer_alloc(size); @@ -750,6 +658,9 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src) dst->height < src->height) return AVERROR(EINVAL); + if (src->hw_frames_ctx || dst->hw_frames_ctx) + return av_hwframe_transfer_data(dst, src, 0); + planes = av_pix_fmt_count_planes(dst->format); for (i = 0; i < planes; i++) if (!dst->data[i] || !src->data[i]) @@ -804,7 +715,7 @@ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) { int i; - for (i = 0; i < frame->nb_side_data; i++) { + for (i = frame->nb_side_data - 1; i >= 0; i--) { AVFrameSideData *sd = frame->side_data[i]; if (sd->type == type) { free_side_data(&frame->side_data[i]); @@ -831,9 +742,15 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; + case AV_FRAME_DATA_S12M_TIMECODE: return "SMPTE 12-1 timecode"; + case AV_FRAME_DATA_SPHERICAL: return "Spherical Mapping"; case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; - case AV_FRAME_DATA_QP_TABLE_PROPERTIES: return "QP table properties"; - case AV_FRAME_DATA_QP_TABLE_DATA: return "QP table data"; + case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; + case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; + case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters"; + case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message"; + case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters"; + case AV_FRAME_DATA_DETECTION_BBOXES: return "Bounding boxes for object detection and classification"; } return NULL; }