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