1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include "channel_layout.h" 20cabdff1aSopenharmony_ci#include "avassert.h" 21cabdff1aSopenharmony_ci#include "buffer.h" 22cabdff1aSopenharmony_ci#include "common.h" 23cabdff1aSopenharmony_ci#include "cpu.h" 24cabdff1aSopenharmony_ci#include "dict.h" 25cabdff1aSopenharmony_ci#include "frame.h" 26cabdff1aSopenharmony_ci#include "imgutils.h" 27cabdff1aSopenharmony_ci#include "mem.h" 28cabdff1aSopenharmony_ci#include "samplefmt.h" 29cabdff1aSopenharmony_ci#include "hwcontext.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 32cabdff1aSopenharmony_ci#define CHECK_CHANNELS_CONSISTENCY(frame) \ 33cabdff1aSopenharmony_ci av_assert2(!(frame)->channel_layout || \ 34cabdff1aSopenharmony_ci (frame)->channels == \ 35cabdff1aSopenharmony_ci av_get_channel_layout_nb_channels((frame)->channel_layout)) 36cabdff1aSopenharmony_ci#endif 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci#if FF_API_COLORSPACE_NAME 39cabdff1aSopenharmony_ciconst char *av_get_colorspace_name(enum AVColorSpace val) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci static const char * const name[] = { 42cabdff1aSopenharmony_ci [AVCOL_SPC_RGB] = "GBR", 43cabdff1aSopenharmony_ci [AVCOL_SPC_BT709] = "bt709", 44cabdff1aSopenharmony_ci [AVCOL_SPC_FCC] = "fcc", 45cabdff1aSopenharmony_ci [AVCOL_SPC_BT470BG] = "bt470bg", 46cabdff1aSopenharmony_ci [AVCOL_SPC_SMPTE170M] = "smpte170m", 47cabdff1aSopenharmony_ci [AVCOL_SPC_SMPTE240M] = "smpte240m", 48cabdff1aSopenharmony_ci [AVCOL_SPC_YCOCG] = "YCgCo", 49cabdff1aSopenharmony_ci }; 50cabdff1aSopenharmony_ci if ((unsigned)val >= FF_ARRAY_ELEMS(name)) 51cabdff1aSopenharmony_ci return NULL; 52cabdff1aSopenharmony_ci return name[val]; 53cabdff1aSopenharmony_ci} 54cabdff1aSopenharmony_ci#endif 55cabdff1aSopenharmony_cistatic void get_frame_defaults(AVFrame *frame) 56cabdff1aSopenharmony_ci{ 57cabdff1aSopenharmony_ci memset(frame, 0, sizeof(*frame)); 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci frame->pts = 60cabdff1aSopenharmony_ci frame->pkt_dts = AV_NOPTS_VALUE; 61cabdff1aSopenharmony_ci frame->best_effort_timestamp = AV_NOPTS_VALUE; 62cabdff1aSopenharmony_ci frame->pkt_duration = 0; 63cabdff1aSopenharmony_ci frame->pkt_pos = -1; 64cabdff1aSopenharmony_ci frame->pkt_size = -1; 65cabdff1aSopenharmony_ci frame->time_base = (AVRational){ 0, 1 }; 66cabdff1aSopenharmony_ci frame->key_frame = 1; 67cabdff1aSopenharmony_ci frame->sample_aspect_ratio = (AVRational){ 0, 1 }; 68cabdff1aSopenharmony_ci frame->format = -1; /* unknown */ 69cabdff1aSopenharmony_ci frame->extended_data = frame->data; 70cabdff1aSopenharmony_ci frame->color_primaries = AVCOL_PRI_UNSPECIFIED; 71cabdff1aSopenharmony_ci frame->color_trc = AVCOL_TRC_UNSPECIFIED; 72cabdff1aSopenharmony_ci frame->colorspace = AVCOL_SPC_UNSPECIFIED; 73cabdff1aSopenharmony_ci frame->color_range = AVCOL_RANGE_UNSPECIFIED; 74cabdff1aSopenharmony_ci frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED; 75cabdff1aSopenharmony_ci frame->flags = 0; 76cabdff1aSopenharmony_ci} 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_cistatic void free_side_data(AVFrameSideData **ptr_sd) 79cabdff1aSopenharmony_ci{ 80cabdff1aSopenharmony_ci AVFrameSideData *sd = *ptr_sd; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci av_buffer_unref(&sd->buf); 83cabdff1aSopenharmony_ci av_dict_free(&sd->metadata); 84cabdff1aSopenharmony_ci av_freep(ptr_sd); 85cabdff1aSopenharmony_ci} 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_cistatic void wipe_side_data(AVFrame *frame) 88cabdff1aSopenharmony_ci{ 89cabdff1aSopenharmony_ci int i; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci for (i = 0; i < frame->nb_side_data; i++) { 92cabdff1aSopenharmony_ci free_side_data(&frame->side_data[i]); 93cabdff1aSopenharmony_ci } 94cabdff1aSopenharmony_ci frame->nb_side_data = 0; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci av_freep(&frame->side_data); 97cabdff1aSopenharmony_ci} 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ciAVFrame *av_frame_alloc(void) 100cabdff1aSopenharmony_ci{ 101cabdff1aSopenharmony_ci AVFrame *frame = av_malloc(sizeof(*frame)); 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci if (!frame) 104cabdff1aSopenharmony_ci return NULL; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci get_frame_defaults(frame); 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci return frame; 109cabdff1aSopenharmony_ci} 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_civoid av_frame_free(AVFrame **frame) 112cabdff1aSopenharmony_ci{ 113cabdff1aSopenharmony_ci if (!frame || !*frame) 114cabdff1aSopenharmony_ci return; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci av_frame_unref(*frame); 117cabdff1aSopenharmony_ci av_freep(frame); 118cabdff1aSopenharmony_ci} 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_cistatic int get_video_buffer(AVFrame *frame, int align) 121cabdff1aSopenharmony_ci{ 122cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); 123cabdff1aSopenharmony_ci int ret, i, padded_height, total_size; 124cabdff1aSopenharmony_ci int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); 125cabdff1aSopenharmony_ci ptrdiff_t linesizes[4]; 126cabdff1aSopenharmony_ci size_t sizes[4]; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci if (!desc) 129cabdff1aSopenharmony_ci return AVERROR(EINVAL); 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) 132cabdff1aSopenharmony_ci return ret; 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci if (!frame->linesize[0]) { 135cabdff1aSopenharmony_ci if (align <= 0) 136cabdff1aSopenharmony_ci align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */ 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci for(i=1; i<=align; i+=i) { 139cabdff1aSopenharmony_ci ret = av_image_fill_linesizes(frame->linesize, frame->format, 140cabdff1aSopenharmony_ci FFALIGN(frame->width, i)); 141cabdff1aSopenharmony_ci if (ret < 0) 142cabdff1aSopenharmony_ci return ret; 143cabdff1aSopenharmony_ci if (!(frame->linesize[0] & (align-1))) 144cabdff1aSopenharmony_ci break; 145cabdff1aSopenharmony_ci } 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci for (i = 0; i < 4 && frame->linesize[i]; i++) 148cabdff1aSopenharmony_ci frame->linesize[i] = FFALIGN(frame->linesize[i], align); 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 152cabdff1aSopenharmony_ci linesizes[i] = frame->linesize[i]; 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci padded_height = FFALIGN(frame->height, 32); 155cabdff1aSopenharmony_ci if ((ret = av_image_fill_plane_sizes(sizes, frame->format, 156cabdff1aSopenharmony_ci padded_height, linesizes)) < 0) 157cabdff1aSopenharmony_ci return ret; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci total_size = 4*plane_padding; 160cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 161cabdff1aSopenharmony_ci if (sizes[i] > INT_MAX - total_size) 162cabdff1aSopenharmony_ci return AVERROR(EINVAL); 163cabdff1aSopenharmony_ci total_size += sizes[i]; 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci frame->buf[0] = av_buffer_alloc(total_size); 167cabdff1aSopenharmony_ci if (!frame->buf[0]) { 168cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 169cabdff1aSopenharmony_ci goto fail; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, 173cabdff1aSopenharmony_ci frame->buf[0]->data, frame->linesize)) < 0) 174cabdff1aSopenharmony_ci goto fail; 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci for (i = 1; i < 4; i++) { 177cabdff1aSopenharmony_ci if (frame->data[i]) 178cabdff1aSopenharmony_ci frame->data[i] += i * plane_padding; 179cabdff1aSopenharmony_ci } 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci frame->extended_data = frame->data; 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci return 0; 184cabdff1aSopenharmony_cifail: 185cabdff1aSopenharmony_ci av_frame_unref(frame); 186cabdff1aSopenharmony_ci return ret; 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic int get_audio_buffer(AVFrame *frame, int align) 190cabdff1aSopenharmony_ci{ 191cabdff1aSopenharmony_ci int planar = av_sample_fmt_is_planar(frame->format); 192cabdff1aSopenharmony_ci int channels, planes; 193cabdff1aSopenharmony_ci int ret, i; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 196cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 197cabdff1aSopenharmony_ci if (!frame->ch_layout.nb_channels) { 198cabdff1aSopenharmony_ci if (frame->channel_layout) { 199cabdff1aSopenharmony_ci av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout); 200cabdff1aSopenharmony_ci } else { 201cabdff1aSopenharmony_ci frame->ch_layout.nb_channels = frame->channels; 202cabdff1aSopenharmony_ci frame->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci } 205cabdff1aSopenharmony_ci frame->channels = frame->ch_layout.nb_channels; 206cabdff1aSopenharmony_ci frame->channel_layout = frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ? 207cabdff1aSopenharmony_ci frame->ch_layout.u.mask : 0; 208cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 209cabdff1aSopenharmony_ci#endif 210cabdff1aSopenharmony_ci channels = frame->ch_layout.nb_channels; 211cabdff1aSopenharmony_ci planes = planar ? channels : 1; 212cabdff1aSopenharmony_ci if (!frame->linesize[0]) { 213cabdff1aSopenharmony_ci ret = av_samples_get_buffer_size(&frame->linesize[0], channels, 214cabdff1aSopenharmony_ci frame->nb_samples, frame->format, 215cabdff1aSopenharmony_ci align); 216cabdff1aSopenharmony_ci if (ret < 0) 217cabdff1aSopenharmony_ci return ret; 218cabdff1aSopenharmony_ci } 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci if (planes > AV_NUM_DATA_POINTERS) { 221cabdff1aSopenharmony_ci frame->extended_data = av_calloc(planes, 222cabdff1aSopenharmony_ci sizeof(*frame->extended_data)); 223cabdff1aSopenharmony_ci frame->extended_buf = av_calloc(planes - AV_NUM_DATA_POINTERS, 224cabdff1aSopenharmony_ci sizeof(*frame->extended_buf)); 225cabdff1aSopenharmony_ci if (!frame->extended_data || !frame->extended_buf) { 226cabdff1aSopenharmony_ci av_freep(&frame->extended_data); 227cabdff1aSopenharmony_ci av_freep(&frame->extended_buf); 228cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 229cabdff1aSopenharmony_ci } 230cabdff1aSopenharmony_ci frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; 231cabdff1aSopenharmony_ci } else 232cabdff1aSopenharmony_ci frame->extended_data = frame->data; 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { 235cabdff1aSopenharmony_ci frame->buf[i] = av_buffer_alloc(frame->linesize[0]); 236cabdff1aSopenharmony_ci if (!frame->buf[i]) { 237cabdff1aSopenharmony_ci av_frame_unref(frame); 238cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 239cabdff1aSopenharmony_ci } 240cabdff1aSopenharmony_ci frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) { 243cabdff1aSopenharmony_ci frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]); 244cabdff1aSopenharmony_ci if (!frame->extended_buf[i]) { 245cabdff1aSopenharmony_ci av_frame_unref(frame); 246cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 247cabdff1aSopenharmony_ci } 248cabdff1aSopenharmony_ci frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci return 0; 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci} 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ciint av_frame_get_buffer(AVFrame *frame, int align) 255cabdff1aSopenharmony_ci{ 256cabdff1aSopenharmony_ci if (frame->format < 0) 257cabdff1aSopenharmony_ci return AVERROR(EINVAL); 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 260cabdff1aSopenharmony_ci if (frame->width > 0 && frame->height > 0) 261cabdff1aSopenharmony_ci return get_video_buffer(frame, align); 262cabdff1aSopenharmony_ci else if (frame->nb_samples > 0 && 263cabdff1aSopenharmony_ci (av_channel_layout_check(&frame->ch_layout) 264cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 265cabdff1aSopenharmony_ci || frame->channel_layout || frame->channels > 0 266cabdff1aSopenharmony_ci#endif 267cabdff1aSopenharmony_ci )) 268cabdff1aSopenharmony_ci return get_audio_buffer(frame, align); 269cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci return AVERROR(EINVAL); 272cabdff1aSopenharmony_ci} 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_cistatic int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) 275cabdff1aSopenharmony_ci{ 276cabdff1aSopenharmony_ci int ret, i; 277cabdff1aSopenharmony_ci 278cabdff1aSopenharmony_ci dst->key_frame = src->key_frame; 279cabdff1aSopenharmony_ci dst->pict_type = src->pict_type; 280cabdff1aSopenharmony_ci dst->sample_aspect_ratio = src->sample_aspect_ratio; 281cabdff1aSopenharmony_ci dst->crop_top = src->crop_top; 282cabdff1aSopenharmony_ci dst->crop_bottom = src->crop_bottom; 283cabdff1aSopenharmony_ci dst->crop_left = src->crop_left; 284cabdff1aSopenharmony_ci dst->crop_right = src->crop_right; 285cabdff1aSopenharmony_ci dst->pts = src->pts; 286cabdff1aSopenharmony_ci dst->repeat_pict = src->repeat_pict; 287cabdff1aSopenharmony_ci dst->interlaced_frame = src->interlaced_frame; 288cabdff1aSopenharmony_ci dst->top_field_first = src->top_field_first; 289cabdff1aSopenharmony_ci dst->palette_has_changed = src->palette_has_changed; 290cabdff1aSopenharmony_ci dst->sample_rate = src->sample_rate; 291cabdff1aSopenharmony_ci dst->opaque = src->opaque; 292cabdff1aSopenharmony_ci dst->pkt_dts = src->pkt_dts; 293cabdff1aSopenharmony_ci dst->pkt_pos = src->pkt_pos; 294cabdff1aSopenharmony_ci dst->pkt_size = src->pkt_size; 295cabdff1aSopenharmony_ci dst->pkt_duration = src->pkt_duration; 296cabdff1aSopenharmony_ci dst->time_base = src->time_base; 297cabdff1aSopenharmony_ci dst->reordered_opaque = src->reordered_opaque; 298cabdff1aSopenharmony_ci dst->quality = src->quality; 299cabdff1aSopenharmony_ci dst->best_effort_timestamp = src->best_effort_timestamp; 300cabdff1aSopenharmony_ci dst->coded_picture_number = src->coded_picture_number; 301cabdff1aSopenharmony_ci dst->display_picture_number = src->display_picture_number; 302cabdff1aSopenharmony_ci dst->flags = src->flags; 303cabdff1aSopenharmony_ci dst->decode_error_flags = src->decode_error_flags; 304cabdff1aSopenharmony_ci dst->color_primaries = src->color_primaries; 305cabdff1aSopenharmony_ci dst->color_trc = src->color_trc; 306cabdff1aSopenharmony_ci dst->colorspace = src->colorspace; 307cabdff1aSopenharmony_ci dst->color_range = src->color_range; 308cabdff1aSopenharmony_ci dst->chroma_location = src->chroma_location; 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci av_dict_copy(&dst->metadata, src->metadata, 0); 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_ci for (i = 0; i < src->nb_side_data; i++) { 313cabdff1aSopenharmony_ci const AVFrameSideData *sd_src = src->side_data[i]; 314cabdff1aSopenharmony_ci AVFrameSideData *sd_dst; 315cabdff1aSopenharmony_ci if ( sd_src->type == AV_FRAME_DATA_PANSCAN 316cabdff1aSopenharmony_ci && (src->width != dst->width || src->height != dst->height)) 317cabdff1aSopenharmony_ci continue; 318cabdff1aSopenharmony_ci if (force_copy) { 319cabdff1aSopenharmony_ci sd_dst = av_frame_new_side_data(dst, sd_src->type, 320cabdff1aSopenharmony_ci sd_src->size); 321cabdff1aSopenharmony_ci if (!sd_dst) { 322cabdff1aSopenharmony_ci wipe_side_data(dst); 323cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 324cabdff1aSopenharmony_ci } 325cabdff1aSopenharmony_ci memcpy(sd_dst->data, sd_src->data, sd_src->size); 326cabdff1aSopenharmony_ci } else { 327cabdff1aSopenharmony_ci AVBufferRef *ref = av_buffer_ref(sd_src->buf); 328cabdff1aSopenharmony_ci sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); 329cabdff1aSopenharmony_ci if (!sd_dst) { 330cabdff1aSopenharmony_ci av_buffer_unref(&ref); 331cabdff1aSopenharmony_ci wipe_side_data(dst); 332cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 333cabdff1aSopenharmony_ci } 334cabdff1aSopenharmony_ci } 335cabdff1aSopenharmony_ci av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); 336cabdff1aSopenharmony_ci } 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); 339cabdff1aSopenharmony_ci ret |= av_buffer_replace(&dst->private_ref, src->private_ref); 340cabdff1aSopenharmony_ci return ret; 341cabdff1aSopenharmony_ci} 342cabdff1aSopenharmony_ci 343cabdff1aSopenharmony_ciint av_frame_ref(AVFrame *dst, const AVFrame *src) 344cabdff1aSopenharmony_ci{ 345cabdff1aSopenharmony_ci int i, ret = 0; 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci av_assert1(dst->width == 0 && dst->height == 0); 348cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 349cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 350cabdff1aSopenharmony_ci av_assert1(dst->channels == 0); 351cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 352cabdff1aSopenharmony_ci#endif 353cabdff1aSopenharmony_ci av_assert1(dst->ch_layout.nb_channels == 0 && 354cabdff1aSopenharmony_ci dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC); 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_ci dst->format = src->format; 357cabdff1aSopenharmony_ci dst->width = src->width; 358cabdff1aSopenharmony_ci dst->height = src->height; 359cabdff1aSopenharmony_ci dst->nb_samples = src->nb_samples; 360cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 361cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 362cabdff1aSopenharmony_ci dst->channels = src->channels; 363cabdff1aSopenharmony_ci dst->channel_layout = src->channel_layout; 364cabdff1aSopenharmony_ci if (!av_channel_layout_check(&src->ch_layout)) { 365cabdff1aSopenharmony_ci if (src->channel_layout) 366cabdff1aSopenharmony_ci av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout); 367cabdff1aSopenharmony_ci else { 368cabdff1aSopenharmony_ci dst->ch_layout.nb_channels = src->channels; 369cabdff1aSopenharmony_ci dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 370cabdff1aSopenharmony_ci } 371cabdff1aSopenharmony_ci } 372cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 373cabdff1aSopenharmony_ci#endif 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci ret = frame_copy_props(dst, src, 0); 376cabdff1aSopenharmony_ci if (ret < 0) 377cabdff1aSopenharmony_ci goto fail; 378cabdff1aSopenharmony_ci 379cabdff1aSopenharmony_ci // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out 380cabdff1aSopenharmony_ci if (av_channel_layout_check(&src->ch_layout)) { 381cabdff1aSopenharmony_ci ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); 382cabdff1aSopenharmony_ci if (ret < 0) 383cabdff1aSopenharmony_ci goto fail; 384cabdff1aSopenharmony_ci } 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_ci /* duplicate the frame data if it's not refcounted */ 387cabdff1aSopenharmony_ci if (!src->buf[0]) { 388cabdff1aSopenharmony_ci ret = av_frame_get_buffer(dst, 0); 389cabdff1aSopenharmony_ci if (ret < 0) 390cabdff1aSopenharmony_ci goto fail; 391cabdff1aSopenharmony_ci 392cabdff1aSopenharmony_ci ret = av_frame_copy(dst, src); 393cabdff1aSopenharmony_ci if (ret < 0) 394cabdff1aSopenharmony_ci goto fail; 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci return 0; 397cabdff1aSopenharmony_ci } 398cabdff1aSopenharmony_ci 399cabdff1aSopenharmony_ci /* ref the buffers */ 400cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { 401cabdff1aSopenharmony_ci if (!src->buf[i]) 402cabdff1aSopenharmony_ci continue; 403cabdff1aSopenharmony_ci dst->buf[i] = av_buffer_ref(src->buf[i]); 404cabdff1aSopenharmony_ci if (!dst->buf[i]) { 405cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 406cabdff1aSopenharmony_ci goto fail; 407cabdff1aSopenharmony_ci } 408cabdff1aSopenharmony_ci } 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci if (src->extended_buf) { 411cabdff1aSopenharmony_ci dst->extended_buf = av_calloc(src->nb_extended_buf, 412cabdff1aSopenharmony_ci sizeof(*dst->extended_buf)); 413cabdff1aSopenharmony_ci if (!dst->extended_buf) { 414cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 415cabdff1aSopenharmony_ci goto fail; 416cabdff1aSopenharmony_ci } 417cabdff1aSopenharmony_ci dst->nb_extended_buf = src->nb_extended_buf; 418cabdff1aSopenharmony_ci 419cabdff1aSopenharmony_ci for (i = 0; i < src->nb_extended_buf; i++) { 420cabdff1aSopenharmony_ci dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]); 421cabdff1aSopenharmony_ci if (!dst->extended_buf[i]) { 422cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 423cabdff1aSopenharmony_ci goto fail; 424cabdff1aSopenharmony_ci } 425cabdff1aSopenharmony_ci } 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci if (src->hw_frames_ctx) { 429cabdff1aSopenharmony_ci dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); 430cabdff1aSopenharmony_ci if (!dst->hw_frames_ctx) { 431cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 432cabdff1aSopenharmony_ci goto fail; 433cabdff1aSopenharmony_ci } 434cabdff1aSopenharmony_ci } 435cabdff1aSopenharmony_ci 436cabdff1aSopenharmony_ci /* duplicate extended data */ 437cabdff1aSopenharmony_ci if (src->extended_data != src->data) { 438cabdff1aSopenharmony_ci int ch = dst->ch_layout.nb_channels; 439cabdff1aSopenharmony_ci 440cabdff1aSopenharmony_ci if (!ch) { 441cabdff1aSopenharmony_ci ret = AVERROR(EINVAL); 442cabdff1aSopenharmony_ci goto fail; 443cabdff1aSopenharmony_ci } 444cabdff1aSopenharmony_ci 445cabdff1aSopenharmony_ci dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); 446cabdff1aSopenharmony_ci if (!dst->extended_data) { 447cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 448cabdff1aSopenharmony_ci goto fail; 449cabdff1aSopenharmony_ci } 450cabdff1aSopenharmony_ci memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch); 451cabdff1aSopenharmony_ci } else 452cabdff1aSopenharmony_ci dst->extended_data = dst->data; 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_ci memcpy(dst->data, src->data, sizeof(src->data)); 455cabdff1aSopenharmony_ci memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); 456cabdff1aSopenharmony_ci 457cabdff1aSopenharmony_ci return 0; 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_cifail: 460cabdff1aSopenharmony_ci av_frame_unref(dst); 461cabdff1aSopenharmony_ci return ret; 462cabdff1aSopenharmony_ci} 463cabdff1aSopenharmony_ci 464cabdff1aSopenharmony_ciAVFrame *av_frame_clone(const AVFrame *src) 465cabdff1aSopenharmony_ci{ 466cabdff1aSopenharmony_ci AVFrame *ret = av_frame_alloc(); 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci if (!ret) 469cabdff1aSopenharmony_ci return NULL; 470cabdff1aSopenharmony_ci 471cabdff1aSopenharmony_ci if (av_frame_ref(ret, src) < 0) 472cabdff1aSopenharmony_ci av_frame_free(&ret); 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci return ret; 475cabdff1aSopenharmony_ci} 476cabdff1aSopenharmony_ci 477cabdff1aSopenharmony_civoid av_frame_unref(AVFrame *frame) 478cabdff1aSopenharmony_ci{ 479cabdff1aSopenharmony_ci int i; 480cabdff1aSopenharmony_ci 481cabdff1aSopenharmony_ci if (!frame) 482cabdff1aSopenharmony_ci return; 483cabdff1aSopenharmony_ci 484cabdff1aSopenharmony_ci wipe_side_data(frame); 485cabdff1aSopenharmony_ci 486cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) 487cabdff1aSopenharmony_ci av_buffer_unref(&frame->buf[i]); 488cabdff1aSopenharmony_ci for (i = 0; i < frame->nb_extended_buf; i++) 489cabdff1aSopenharmony_ci av_buffer_unref(&frame->extended_buf[i]); 490cabdff1aSopenharmony_ci av_freep(&frame->extended_buf); 491cabdff1aSopenharmony_ci av_dict_free(&frame->metadata); 492cabdff1aSopenharmony_ci 493cabdff1aSopenharmony_ci av_buffer_unref(&frame->hw_frames_ctx); 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci av_buffer_unref(&frame->opaque_ref); 496cabdff1aSopenharmony_ci av_buffer_unref(&frame->private_ref); 497cabdff1aSopenharmony_ci 498cabdff1aSopenharmony_ci if (frame->extended_data != frame->data) 499cabdff1aSopenharmony_ci av_freep(&frame->extended_data); 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_ci av_channel_layout_uninit(&frame->ch_layout); 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_ci get_frame_defaults(frame); 504cabdff1aSopenharmony_ci} 505cabdff1aSopenharmony_ci 506cabdff1aSopenharmony_civoid av_frame_move_ref(AVFrame *dst, AVFrame *src) 507cabdff1aSopenharmony_ci{ 508cabdff1aSopenharmony_ci av_assert1(dst->width == 0 && dst->height == 0); 509cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 510cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 511cabdff1aSopenharmony_ci av_assert1(dst->channels == 0); 512cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 513cabdff1aSopenharmony_ci#endif 514cabdff1aSopenharmony_ci av_assert1(dst->ch_layout.nb_channels == 0 && 515cabdff1aSopenharmony_ci dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC); 516cabdff1aSopenharmony_ci 517cabdff1aSopenharmony_ci *dst = *src; 518cabdff1aSopenharmony_ci if (src->extended_data == src->data) 519cabdff1aSopenharmony_ci dst->extended_data = dst->data; 520cabdff1aSopenharmony_ci get_frame_defaults(src); 521cabdff1aSopenharmony_ci} 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_ciint av_frame_is_writable(AVFrame *frame) 524cabdff1aSopenharmony_ci{ 525cabdff1aSopenharmony_ci int i, ret = 1; 526cabdff1aSopenharmony_ci 527cabdff1aSopenharmony_ci /* assume non-refcounted frames are not writable */ 528cabdff1aSopenharmony_ci if (!frame->buf[0]) 529cabdff1aSopenharmony_ci return 0; 530cabdff1aSopenharmony_ci 531cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) 532cabdff1aSopenharmony_ci if (frame->buf[i]) 533cabdff1aSopenharmony_ci ret &= !!av_buffer_is_writable(frame->buf[i]); 534cabdff1aSopenharmony_ci for (i = 0; i < frame->nb_extended_buf; i++) 535cabdff1aSopenharmony_ci ret &= !!av_buffer_is_writable(frame->extended_buf[i]); 536cabdff1aSopenharmony_ci 537cabdff1aSopenharmony_ci return ret; 538cabdff1aSopenharmony_ci} 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_ciint av_frame_make_writable(AVFrame *frame) 541cabdff1aSopenharmony_ci{ 542cabdff1aSopenharmony_ci AVFrame tmp; 543cabdff1aSopenharmony_ci int ret; 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_ci if (!frame->buf[0]) 546cabdff1aSopenharmony_ci return AVERROR(EINVAL); 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_ci if (av_frame_is_writable(frame)) 549cabdff1aSopenharmony_ci return 0; 550cabdff1aSopenharmony_ci 551cabdff1aSopenharmony_ci memset(&tmp, 0, sizeof(tmp)); 552cabdff1aSopenharmony_ci tmp.format = frame->format; 553cabdff1aSopenharmony_ci tmp.width = frame->width; 554cabdff1aSopenharmony_ci tmp.height = frame->height; 555cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 556cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 557cabdff1aSopenharmony_ci tmp.channels = frame->channels; 558cabdff1aSopenharmony_ci tmp.channel_layout = frame->channel_layout; 559cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 560cabdff1aSopenharmony_ci#endif 561cabdff1aSopenharmony_ci tmp.nb_samples = frame->nb_samples; 562cabdff1aSopenharmony_ci ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout); 563cabdff1aSopenharmony_ci if (ret < 0) { 564cabdff1aSopenharmony_ci av_frame_unref(&tmp); 565cabdff1aSopenharmony_ci return ret; 566cabdff1aSopenharmony_ci } 567cabdff1aSopenharmony_ci 568cabdff1aSopenharmony_ci if (frame->hw_frames_ctx) 569cabdff1aSopenharmony_ci ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); 570cabdff1aSopenharmony_ci else 571cabdff1aSopenharmony_ci ret = av_frame_get_buffer(&tmp, 0); 572cabdff1aSopenharmony_ci if (ret < 0) 573cabdff1aSopenharmony_ci return ret; 574cabdff1aSopenharmony_ci 575cabdff1aSopenharmony_ci ret = av_frame_copy(&tmp, frame); 576cabdff1aSopenharmony_ci if (ret < 0) { 577cabdff1aSopenharmony_ci av_frame_unref(&tmp); 578cabdff1aSopenharmony_ci return ret; 579cabdff1aSopenharmony_ci } 580cabdff1aSopenharmony_ci 581cabdff1aSopenharmony_ci ret = av_frame_copy_props(&tmp, frame); 582cabdff1aSopenharmony_ci if (ret < 0) { 583cabdff1aSopenharmony_ci av_frame_unref(&tmp); 584cabdff1aSopenharmony_ci return ret; 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci 587cabdff1aSopenharmony_ci av_frame_unref(frame); 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ci *frame = tmp; 590cabdff1aSopenharmony_ci if (tmp.data == tmp.extended_data) 591cabdff1aSopenharmony_ci frame->extended_data = frame->data; 592cabdff1aSopenharmony_ci 593cabdff1aSopenharmony_ci return 0; 594cabdff1aSopenharmony_ci} 595cabdff1aSopenharmony_ci 596cabdff1aSopenharmony_ciint av_frame_copy_props(AVFrame *dst, const AVFrame *src) 597cabdff1aSopenharmony_ci{ 598cabdff1aSopenharmony_ci return frame_copy_props(dst, src, 1); 599cabdff1aSopenharmony_ci} 600cabdff1aSopenharmony_ci 601cabdff1aSopenharmony_ciAVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) 602cabdff1aSopenharmony_ci{ 603cabdff1aSopenharmony_ci uint8_t *data; 604cabdff1aSopenharmony_ci int planes, i; 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_ci if (frame->nb_samples) { 607cabdff1aSopenharmony_ci int channels = frame->ch_layout.nb_channels; 608cabdff1aSopenharmony_ci 609cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 610cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 611cabdff1aSopenharmony_ci if (!channels) { 612cabdff1aSopenharmony_ci channels = frame->channels; 613cabdff1aSopenharmony_ci CHECK_CHANNELS_CONSISTENCY(frame); 614cabdff1aSopenharmony_ci } 615cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 616cabdff1aSopenharmony_ci#endif 617cabdff1aSopenharmony_ci if (!channels) 618cabdff1aSopenharmony_ci return NULL; 619cabdff1aSopenharmony_ci planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; 620cabdff1aSopenharmony_ci } else 621cabdff1aSopenharmony_ci planes = 4; 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci if (plane < 0 || plane >= planes || !frame->extended_data[plane]) 624cabdff1aSopenharmony_ci return NULL; 625cabdff1aSopenharmony_ci data = frame->extended_data[plane]; 626cabdff1aSopenharmony_ci 627cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) { 628cabdff1aSopenharmony_ci AVBufferRef *buf = frame->buf[i]; 629cabdff1aSopenharmony_ci if (data >= buf->data && data < buf->data + buf->size) 630cabdff1aSopenharmony_ci return buf; 631cabdff1aSopenharmony_ci } 632cabdff1aSopenharmony_ci for (i = 0; i < frame->nb_extended_buf; i++) { 633cabdff1aSopenharmony_ci AVBufferRef *buf = frame->extended_buf[i]; 634cabdff1aSopenharmony_ci if (data >= buf->data && data < buf->data + buf->size) 635cabdff1aSopenharmony_ci return buf; 636cabdff1aSopenharmony_ci } 637cabdff1aSopenharmony_ci return NULL; 638cabdff1aSopenharmony_ci} 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_ciAVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, 641cabdff1aSopenharmony_ci enum AVFrameSideDataType type, 642cabdff1aSopenharmony_ci AVBufferRef *buf) 643cabdff1aSopenharmony_ci{ 644cabdff1aSopenharmony_ci AVFrameSideData *ret, **tmp; 645cabdff1aSopenharmony_ci 646cabdff1aSopenharmony_ci if (!buf) 647cabdff1aSopenharmony_ci return NULL; 648cabdff1aSopenharmony_ci 649cabdff1aSopenharmony_ci if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1) 650cabdff1aSopenharmony_ci return NULL; 651cabdff1aSopenharmony_ci 652cabdff1aSopenharmony_ci tmp = av_realloc(frame->side_data, 653cabdff1aSopenharmony_ci (frame->nb_side_data + 1) * sizeof(*frame->side_data)); 654cabdff1aSopenharmony_ci if (!tmp) 655cabdff1aSopenharmony_ci return NULL; 656cabdff1aSopenharmony_ci frame->side_data = tmp; 657cabdff1aSopenharmony_ci 658cabdff1aSopenharmony_ci ret = av_mallocz(sizeof(*ret)); 659cabdff1aSopenharmony_ci if (!ret) 660cabdff1aSopenharmony_ci return NULL; 661cabdff1aSopenharmony_ci 662cabdff1aSopenharmony_ci ret->buf = buf; 663cabdff1aSopenharmony_ci ret->data = ret->buf->data; 664cabdff1aSopenharmony_ci ret->size = buf->size; 665cabdff1aSopenharmony_ci ret->type = type; 666cabdff1aSopenharmony_ci 667cabdff1aSopenharmony_ci frame->side_data[frame->nb_side_data++] = ret; 668cabdff1aSopenharmony_ci 669cabdff1aSopenharmony_ci return ret; 670cabdff1aSopenharmony_ci} 671cabdff1aSopenharmony_ci 672cabdff1aSopenharmony_ciAVFrameSideData *av_frame_new_side_data(AVFrame *frame, 673cabdff1aSopenharmony_ci enum AVFrameSideDataType type, 674cabdff1aSopenharmony_ci size_t size) 675cabdff1aSopenharmony_ci{ 676cabdff1aSopenharmony_ci AVFrameSideData *ret; 677cabdff1aSopenharmony_ci AVBufferRef *buf = av_buffer_alloc(size); 678cabdff1aSopenharmony_ci ret = av_frame_new_side_data_from_buf(frame, type, buf); 679cabdff1aSopenharmony_ci if (!ret) 680cabdff1aSopenharmony_ci av_buffer_unref(&buf); 681cabdff1aSopenharmony_ci return ret; 682cabdff1aSopenharmony_ci} 683cabdff1aSopenharmony_ci 684cabdff1aSopenharmony_ciAVFrameSideData *av_frame_get_side_data(const AVFrame *frame, 685cabdff1aSopenharmony_ci enum AVFrameSideDataType type) 686cabdff1aSopenharmony_ci{ 687cabdff1aSopenharmony_ci int i; 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci for (i = 0; i < frame->nb_side_data; i++) { 690cabdff1aSopenharmony_ci if (frame->side_data[i]->type == type) 691cabdff1aSopenharmony_ci return frame->side_data[i]; 692cabdff1aSopenharmony_ci } 693cabdff1aSopenharmony_ci return NULL; 694cabdff1aSopenharmony_ci} 695cabdff1aSopenharmony_ci 696cabdff1aSopenharmony_cistatic int frame_copy_video(AVFrame *dst, const AVFrame *src) 697cabdff1aSopenharmony_ci{ 698cabdff1aSopenharmony_ci const uint8_t *src_data[4]; 699cabdff1aSopenharmony_ci int i, planes; 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci if (dst->width < src->width || 702cabdff1aSopenharmony_ci dst->height < src->height) 703cabdff1aSopenharmony_ci return AVERROR(EINVAL); 704cabdff1aSopenharmony_ci 705cabdff1aSopenharmony_ci if (src->hw_frames_ctx || dst->hw_frames_ctx) 706cabdff1aSopenharmony_ci return av_hwframe_transfer_data(dst, src, 0); 707cabdff1aSopenharmony_ci 708cabdff1aSopenharmony_ci planes = av_pix_fmt_count_planes(dst->format); 709cabdff1aSopenharmony_ci for (i = 0; i < planes; i++) 710cabdff1aSopenharmony_ci if (!dst->data[i] || !src->data[i]) 711cabdff1aSopenharmony_ci return AVERROR(EINVAL); 712cabdff1aSopenharmony_ci 713cabdff1aSopenharmony_ci memcpy(src_data, src->data, sizeof(src_data)); 714cabdff1aSopenharmony_ci av_image_copy(dst->data, dst->linesize, 715cabdff1aSopenharmony_ci src_data, src->linesize, 716cabdff1aSopenharmony_ci dst->format, src->width, src->height); 717cabdff1aSopenharmony_ci 718cabdff1aSopenharmony_ci return 0; 719cabdff1aSopenharmony_ci} 720cabdff1aSopenharmony_ci 721cabdff1aSopenharmony_cistatic int frame_copy_audio(AVFrame *dst, const AVFrame *src) 722cabdff1aSopenharmony_ci{ 723cabdff1aSopenharmony_ci int planar = av_sample_fmt_is_planar(dst->format); 724cabdff1aSopenharmony_ci int channels = dst->ch_layout.nb_channels; 725cabdff1aSopenharmony_ci int planes = planar ? channels : 1; 726cabdff1aSopenharmony_ci int i; 727cabdff1aSopenharmony_ci 728cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 729cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 730cabdff1aSopenharmony_ci if (!channels || !src->ch_layout.nb_channels) { 731cabdff1aSopenharmony_ci if (dst->channels != src->channels || 732cabdff1aSopenharmony_ci dst->channel_layout != src->channel_layout) 733cabdff1aSopenharmony_ci return AVERROR(EINVAL); 734cabdff1aSopenharmony_ci CHECK_CHANNELS_CONSISTENCY(src); 735cabdff1aSopenharmony_ci } 736cabdff1aSopenharmony_ci if (!channels) { 737cabdff1aSopenharmony_ci channels = dst->channels; 738cabdff1aSopenharmony_ci planes = planar ? channels : 1; 739cabdff1aSopenharmony_ci } 740cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 741cabdff1aSopenharmony_ci#endif 742cabdff1aSopenharmony_ci 743cabdff1aSopenharmony_ci if (dst->nb_samples != src->nb_samples || 744cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 745cabdff1aSopenharmony_ci (av_channel_layout_check(&dst->ch_layout) && 746cabdff1aSopenharmony_ci av_channel_layout_check(&src->ch_layout) && 747cabdff1aSopenharmony_ci#endif 748cabdff1aSopenharmony_ci av_channel_layout_compare(&dst->ch_layout, &src->ch_layout)) 749cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 750cabdff1aSopenharmony_ci ) 751cabdff1aSopenharmony_ci#endif 752cabdff1aSopenharmony_ci return AVERROR(EINVAL); 753cabdff1aSopenharmony_ci 754cabdff1aSopenharmony_ci for (i = 0; i < planes; i++) 755cabdff1aSopenharmony_ci if (!dst->extended_data[i] || !src->extended_data[i]) 756cabdff1aSopenharmony_ci return AVERROR(EINVAL); 757cabdff1aSopenharmony_ci 758cabdff1aSopenharmony_ci av_samples_copy(dst->extended_data, src->extended_data, 0, 0, 759cabdff1aSopenharmony_ci dst->nb_samples, channels, dst->format); 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ci return 0; 762cabdff1aSopenharmony_ci} 763cabdff1aSopenharmony_ci 764cabdff1aSopenharmony_ciint av_frame_copy(AVFrame *dst, const AVFrame *src) 765cabdff1aSopenharmony_ci{ 766cabdff1aSopenharmony_ci if (dst->format != src->format || dst->format < 0) 767cabdff1aSopenharmony_ci return AVERROR(EINVAL); 768cabdff1aSopenharmony_ci 769cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 770cabdff1aSopenharmony_ci if (dst->width > 0 && dst->height > 0) 771cabdff1aSopenharmony_ci return frame_copy_video(dst, src); 772cabdff1aSopenharmony_ci else if (dst->nb_samples > 0 && 773cabdff1aSopenharmony_ci (av_channel_layout_check(&dst->ch_layout) 774cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 775cabdff1aSopenharmony_ci || dst->channels > 0 776cabdff1aSopenharmony_ci#endif 777cabdff1aSopenharmony_ci )) 778cabdff1aSopenharmony_ci return frame_copy_audio(dst, src); 779cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 780cabdff1aSopenharmony_ci 781cabdff1aSopenharmony_ci return AVERROR(EINVAL); 782cabdff1aSopenharmony_ci} 783cabdff1aSopenharmony_ci 784cabdff1aSopenharmony_civoid av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) 785cabdff1aSopenharmony_ci{ 786cabdff1aSopenharmony_ci int i; 787cabdff1aSopenharmony_ci 788cabdff1aSopenharmony_ci for (i = frame->nb_side_data - 1; i >= 0; i--) { 789cabdff1aSopenharmony_ci AVFrameSideData *sd = frame->side_data[i]; 790cabdff1aSopenharmony_ci if (sd->type == type) { 791cabdff1aSopenharmony_ci free_side_data(&frame->side_data[i]); 792cabdff1aSopenharmony_ci frame->side_data[i] = frame->side_data[frame->nb_side_data - 1]; 793cabdff1aSopenharmony_ci frame->nb_side_data--; 794cabdff1aSopenharmony_ci } 795cabdff1aSopenharmony_ci } 796cabdff1aSopenharmony_ci} 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_ciconst char *av_frame_side_data_name(enum AVFrameSideDataType type) 799cabdff1aSopenharmony_ci{ 800cabdff1aSopenharmony_ci switch(type) { 801cabdff1aSopenharmony_ci case AV_FRAME_DATA_PANSCAN: return "AVPanScan"; 802cabdff1aSopenharmony_ci case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions"; 803cabdff1aSopenharmony_ci case AV_FRAME_DATA_STEREO3D: return "Stereo 3D"; 804cabdff1aSopenharmony_ci case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding"; 805cabdff1aSopenharmony_ci case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure"; 806cabdff1aSopenharmony_ci case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain"; 807cabdff1aSopenharmony_ci case AV_FRAME_DATA_DISPLAYMATRIX: return "3x3 displaymatrix"; 808cabdff1aSopenharmony_ci case AV_FRAME_DATA_AFD: return "Active format description"; 809cabdff1aSopenharmony_ci case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors"; 810cabdff1aSopenharmony_ci case AV_FRAME_DATA_SKIP_SAMPLES: return "Skip samples"; 811cabdff1aSopenharmony_ci case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio service type"; 812cabdff1aSopenharmony_ci case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; 813cabdff1aSopenharmony_ci case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; 814cabdff1aSopenharmony_ci case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; 815cabdff1aSopenharmony_ci case AV_FRAME_DATA_S12M_TIMECODE: return "SMPTE 12-1 timecode"; 816cabdff1aSopenharmony_ci case AV_FRAME_DATA_SPHERICAL: return "Spherical Mapping"; 817cabdff1aSopenharmony_ci case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; 818cabdff1aSopenharmony_ci case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; 819cabdff1aSopenharmony_ci case AV_FRAME_DATA_DYNAMIC_HDR_VIVID: return "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)"; 820cabdff1aSopenharmony_ci case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; 821cabdff1aSopenharmony_ci case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters"; 822cabdff1aSopenharmony_ci case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message"; 823cabdff1aSopenharmony_ci case AV_FRAME_DATA_FILM_GRAIN_PARAMS: return "Film grain parameters"; 824cabdff1aSopenharmony_ci case AV_FRAME_DATA_DETECTION_BBOXES: return "Bounding boxes for object detection and classification"; 825cabdff1aSopenharmony_ci case AV_FRAME_DATA_DOVI_RPU_BUFFER: return "Dolby Vision RPU Data"; 826cabdff1aSopenharmony_ci case AV_FRAME_DATA_DOVI_METADATA: return "Dolby Vision Metadata"; 827cabdff1aSopenharmony_ci } 828cabdff1aSopenharmony_ci return NULL; 829cabdff1aSopenharmony_ci} 830cabdff1aSopenharmony_ci 831cabdff1aSopenharmony_cistatic int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, 832cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc) 833cabdff1aSopenharmony_ci{ 834cabdff1aSopenharmony_ci int i, j; 835cabdff1aSopenharmony_ci 836cabdff1aSopenharmony_ci for (i = 0; frame->data[i]; i++) { 837cabdff1aSopenharmony_ci const AVComponentDescriptor *comp = NULL; 838cabdff1aSopenharmony_ci int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; 839cabdff1aSopenharmony_ci int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; 840cabdff1aSopenharmony_ci 841cabdff1aSopenharmony_ci if (desc->flags & AV_PIX_FMT_FLAG_PAL && i == 1) { 842cabdff1aSopenharmony_ci offsets[i] = 0; 843cabdff1aSopenharmony_ci break; 844cabdff1aSopenharmony_ci } 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_ci /* find any component descriptor for this plane */ 847cabdff1aSopenharmony_ci for (j = 0; j < desc->nb_components; j++) { 848cabdff1aSopenharmony_ci if (desc->comp[j].plane == i) { 849cabdff1aSopenharmony_ci comp = &desc->comp[j]; 850cabdff1aSopenharmony_ci break; 851cabdff1aSopenharmony_ci } 852cabdff1aSopenharmony_ci } 853cabdff1aSopenharmony_ci if (!comp) 854cabdff1aSopenharmony_ci return AVERROR_BUG; 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_ci offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + 857cabdff1aSopenharmony_ci (frame->crop_left >> shift_x) * comp->step; 858cabdff1aSopenharmony_ci } 859cabdff1aSopenharmony_ci 860cabdff1aSopenharmony_ci return 0; 861cabdff1aSopenharmony_ci} 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ciint av_frame_apply_cropping(AVFrame *frame, int flags) 864cabdff1aSopenharmony_ci{ 865cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc; 866cabdff1aSopenharmony_ci size_t offsets[4]; 867cabdff1aSopenharmony_ci int i; 868cabdff1aSopenharmony_ci 869cabdff1aSopenharmony_ci if (!(frame->width > 0 && frame->height > 0)) 870cabdff1aSopenharmony_ci return AVERROR(EINVAL); 871cabdff1aSopenharmony_ci 872cabdff1aSopenharmony_ci if (frame->crop_left >= INT_MAX - frame->crop_right || 873cabdff1aSopenharmony_ci frame->crop_top >= INT_MAX - frame->crop_bottom || 874cabdff1aSopenharmony_ci (frame->crop_left + frame->crop_right) >= frame->width || 875cabdff1aSopenharmony_ci (frame->crop_top + frame->crop_bottom) >= frame->height) 876cabdff1aSopenharmony_ci return AVERROR(ERANGE); 877cabdff1aSopenharmony_ci 878cabdff1aSopenharmony_ci desc = av_pix_fmt_desc_get(frame->format); 879cabdff1aSopenharmony_ci if (!desc) 880cabdff1aSopenharmony_ci return AVERROR_BUG; 881cabdff1aSopenharmony_ci 882cabdff1aSopenharmony_ci /* Apply just the right/bottom cropping for hwaccel formats. Bitstream 883cabdff1aSopenharmony_ci * formats cannot be easily handled here either (and corresponding decoders 884cabdff1aSopenharmony_ci * should not export any cropping anyway), so do the same for those as well. 885cabdff1aSopenharmony_ci * */ 886cabdff1aSopenharmony_ci if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { 887cabdff1aSopenharmony_ci frame->width -= frame->crop_right; 888cabdff1aSopenharmony_ci frame->height -= frame->crop_bottom; 889cabdff1aSopenharmony_ci frame->crop_right = 0; 890cabdff1aSopenharmony_ci frame->crop_bottom = 0; 891cabdff1aSopenharmony_ci return 0; 892cabdff1aSopenharmony_ci } 893cabdff1aSopenharmony_ci 894cabdff1aSopenharmony_ci /* calculate the offsets for each plane */ 895cabdff1aSopenharmony_ci calc_cropping_offsets(offsets, frame, desc); 896cabdff1aSopenharmony_ci 897cabdff1aSopenharmony_ci /* adjust the offsets to avoid breaking alignment */ 898cabdff1aSopenharmony_ci if (!(flags & AV_FRAME_CROP_UNALIGNED)) { 899cabdff1aSopenharmony_ci int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; 900cabdff1aSopenharmony_ci int min_log2_align = INT_MAX; 901cabdff1aSopenharmony_ci 902cabdff1aSopenharmony_ci for (i = 0; frame->data[i]; i++) { 903cabdff1aSopenharmony_ci int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX; 904cabdff1aSopenharmony_ci min_log2_align = FFMIN(log2_align, min_log2_align); 905cabdff1aSopenharmony_ci } 906cabdff1aSopenharmony_ci 907cabdff1aSopenharmony_ci /* we assume, and it should always be true, that the data alignment is 908cabdff1aSopenharmony_ci * related to the cropping alignment by a constant power-of-2 factor */ 909cabdff1aSopenharmony_ci if (log2_crop_align < min_log2_align) 910cabdff1aSopenharmony_ci return AVERROR_BUG; 911cabdff1aSopenharmony_ci 912cabdff1aSopenharmony_ci if (min_log2_align < 5 && log2_crop_align != INT_MAX) { 913cabdff1aSopenharmony_ci frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); 914cabdff1aSopenharmony_ci calc_cropping_offsets(offsets, frame, desc); 915cabdff1aSopenharmony_ci } 916cabdff1aSopenharmony_ci } 917cabdff1aSopenharmony_ci 918cabdff1aSopenharmony_ci for (i = 0; frame->data[i]; i++) 919cabdff1aSopenharmony_ci frame->data[i] += offsets[i]; 920cabdff1aSopenharmony_ci 921cabdff1aSopenharmony_ci frame->width -= (frame->crop_left + frame->crop_right); 922cabdff1aSopenharmony_ci frame->height -= (frame->crop_top + frame->crop_bottom); 923cabdff1aSopenharmony_ci frame->crop_left = 0; 924cabdff1aSopenharmony_ci frame->crop_right = 0; 925cabdff1aSopenharmony_ci frame->crop_top = 0; 926cabdff1aSopenharmony_ci frame->crop_bottom = 0; 927cabdff1aSopenharmony_ci 928cabdff1aSopenharmony_ci return 0; 929cabdff1aSopenharmony_ci} 930