X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fframe.c;h=df826fbfb738e541d1f77d16ac3e77fe915dd96c;hb=b8accd1175d20ab308de69dbd06bda06a02183e3;hp=61c45f0f53247540b139b2a28eae3d3d6a3bed71;hpb=9a15af48284b951701b7e6b9dcc81b4212c6ca95;p=ffmpeg diff --git a/libavutil/frame.c b/libavutil/frame.c index 61c45f0f532..df826fbfb73 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,36 +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 -int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) -{ - av_buffer_unref(&f->qp_table_buf); - - f->qp_table_buf = buf; - -FF_DISABLE_DEPRECATION_WARNINGS - f->qscale_table = buf->data; - f->qstride = stride; - f->qscale_type = qp_type; -FF_ENABLE_DEPRECATION_WARNINGS - - return 0; -} - -int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) -{ -FF_DISABLE_DEPRECATION_WARNINGS - *stride = f->qstride; - *type = f->qscale_type; -FF_ENABLE_DEPRECATION_WARNINGS - - if (!f->qp_table_buf) - return NULL; - - return f->qp_table_buf->data; -} -#endif - +#if FF_API_COLORSPACE_NAME const char *av_get_colorspace_name(enum AVColorSpace val) { static const char * const name[] = { @@ -90,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) @@ -167,7 +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; + 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); @@ -192,23 +167,34 @@ static int get_video_buffer(AVFrame *frame, int align) frame->linesize[i] = FFALIGN(frame->linesize[i], align); } - for (i = 0; i < 4 && frame->linesize[i]; i++) { - int h = FFALIGN(frame->height, 32); - if (i == 1 || i == 2) - h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h); + for (i = 0; i < 4; i++) + linesizes[i] = frame->linesize[i]; - frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16 + 16/*STRIDE_ALIGN*/ - 1); - if (!frame->buf[i]) - goto fail; + padded_height = FFALIGN(frame->height, 32); + if ((ret = av_image_fill_plane_sizes(sizes, frame->format, + padded_height, linesizes)) < 0) + return ret; + + 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->data[i] = frame->buf[i]->data; + frame->buf[0] = av_buffer_alloc(total_size); + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; } - if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { - av_buffer_unref(&frame->buf[1]); - frame->buf[1] = av_buffer_alloc(AVPALETTE_SIZE); - if (!frame->buf[1]) - goto fail; - frame->data[1] = frame->buf[1]->data; + + 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++) { + if (frame->data[i]) + frame->data[i] += i * plane_padding; } frame->extended_data = frame->data; @@ -216,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) @@ -290,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; @@ -362,36 +348,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) @@ -410,19 +369,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 */ @@ -519,9 +478,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 - av_buffer_unref(&frame->qp_table_buf); -#endif av_buffer_unref(&frame->hw_frames_ctx); @@ -578,7 +534,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; @@ -673,7 +633,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); @@ -704,6 +664,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]) @@ -758,7 +721,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]); @@ -773,7 +736,7 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) switch(type) { case AV_FRAME_DATA_PANSCAN: return "AVPanScan"; case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions"; - case AV_FRAME_DATA_STEREO3D: return "Stereoscopic 3d metadata"; + case AV_FRAME_DATA_STEREO3D: return "Stereo 3D"; case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding"; case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure"; case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain"; @@ -785,7 +748,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_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; } @@ -800,7 +771,7 @@ static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL) && i == 1) { + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | FF_PSEUDOPAL) && i == 1) { offsets[i] = 0; break; }