| @@ -271,16 +271,11 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) · 270 unmodified lines |
| 271 | if (ret < 0) | 271 | if (ret < 0) |
| 272 | return ret; | 272 | return ret; |
| 273 | | 273 | |
| 274 | if (src->nb_samples) { | 274 | ret = av_frame_copy(dst, src); |
| 275 | int ch = src->channels; | 275 | if (ret < 0) |
| 276 | CHECK_CHANNELS_CONSISTENCY(src); | 276 | av_frame_unref(dst); |
| 277 | av_samples_copy(dst->extended_data, src->extended_data, 0, 0, | 277 | |
| 278 | dst->nb_samples, ch, dst->format); | 278 | return ret; |
| 279 | } else { | | |
| 280 | av_image_copy(dst->data, dst->linesize, src->data, src->linesize, | | |
| 281 | dst->format, dst->width, dst->height); | | |
| 282 | } | | |
| 283 | return 0; | | |
| 284 | } | 279 | } |
| 285 | | 280 | |
| 286 | /* ref the buffers */ | 281 | /* ref the buffers */ |
| @@ -424,14 +419,10 @@ int av_frame_make_writable(AVFrame *frame) · 137 unmodified lines |
| 424 | if (ret < 0) | 419 | if (ret < 0) |
| 425 | return ret; | 420 | return ret; |
| 426 | | 421 | |
| 427 | if (tmp.nb_samples) { | 422 | ret = av_frame_copy(&tmp, frame); |
| 428 | int ch = tmp.channels; | 423 | if (ret < 0) { |
| 429 | CHECK_CHANNELS_CONSISTENCY(&tmp); | 424 | av_frame_unref(&tmp); |
| 430 | av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0, | 425 | return ret; |
| 431 | frame->nb_samples, ch, frame->format); | | |
| 432 | } else { | | |
| 433 | av_image_copy(tmp.data, tmp.linesize, frame->data, frame->linesize, | | |
| 434 | frame->format, frame->width, frame->height); | | |
| 435 | } | 426 | } |
| 436 | | 427 | |
| 437 | ret = av_frame_copy_props(&tmp, frame); | 428 | ret = av_frame_copy_props(&tmp, frame); |
| @@ -592,3 +583,61 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, · 154 unmodified lines |
| 592 | } | 583 | } |
| 593 | return NULL; | 584 | return NULL; |
| 594 | } | 585 | } |
| | 586 | |
| | 587 | static int frame_copy_video(AVFrame *dst, const AVFrame *src) |
| | 588 | { |
| | 589 | const uint8_t *src_data[4]; |
| | 590 | int i, planes; |
| | 591 | |
| | 592 | if (dst->width != src->width || |
| | 593 | dst->height != src->height) |
| | 594 | return AVERROR(EINVAL); |
| | 595 | |
| | 596 | planes = av_pix_fmt_count_planes(dst->format); |
| | 597 | for (i = 0; i < planes; i++) |
| | 598 | if (!dst->data[i] || !src->data[i]) |
| | 599 | return AVERROR(EINVAL); |
| | 600 | |
| | 601 | memcpy(src_data, src->data, sizeof(src_data)); |
| | 602 | av_image_copy(dst->data, dst->linesize, |
| | 603 | src_data, src->linesize, |
| | 604 | dst->format, dst->width, dst->height); |
| | 605 | |
| | 606 | return 0; |
| | 607 | } |
| | 608 | |
| | 609 | static int frame_copy_audio(AVFrame *dst, const AVFrame *src) |
| | 610 | { |
| | 611 | int planar = av_sample_fmt_is_planar(dst->format); |
| | 612 | int channels = dst->channels; |
| | 613 | int planes = planar ? channels : 1; |
| | 614 | int i; |
| | 615 | |
| | 616 | if (dst->nb_samples != src->nb_samples || |
| | 617 | dst->channel_layout != src->channel_layout) |
| | 618 | return AVERROR(EINVAL); |
| | 619 | |
| | 620 | CHECK_CHANNELS_CONSISTENCY(src); |
| | 621 | |
| | 622 | for (i = 0; i < planes; i++) |
| | 623 | if (!dst->extended_data[i] || !src->extended_data[i]) |
| | 624 | return AVERROR(EINVAL); |
| | 625 | |
| | 626 | av_samples_copy(dst->extended_data, src->extended_data, 0, 0, |
| | 627 | dst->nb_samples, channels, dst->format); |
| | 628 | |
| | 629 | return 0; |
| | 630 | } |
| | 631 | |
| | 632 | int av_frame_copy(AVFrame *dst, const AVFrame *src) |
| | 633 | { |
| | 634 | if (dst->format != src->format || dst->format < 0) |
| | 635 | return AVERROR(EINVAL); |
| | 636 | |
| | 637 | if (dst->width > 0 && dst->height > 0) |
| | 638 | return frame_copy_video(dst, src); |
| | 639 | else if (dst->nb_samples > 0 && dst->channel_layout) |
| | 640 | return frame_copy_audio(dst, src); |
| | 641 | |
| | 642 | return AVERROR(EINVAL); |
| | 643 | } |