| @@ -271,16 +271,11 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) · 270 unmodified lines |
| 271 | 271 | if (ret < 0) |
| 272 | 272 | return ret; |
| 273 | 273 | |
| 274 | | − if (src->nb_samples) { |
| 275 | | − int ch = src->channels; |
| 276 | | − CHECK_CHANNELS_CONSISTENCY(src); |
| 277 | | − av_samples_copy(dst->extended_data, src->extended_data, 0, 0, |
| 278 | | − dst->nb_samples, ch, dst->format); |
| 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; |
| 274 | + ret = av_frame_copy(dst, src); |
| 275 | + if (ret < 0) |
| 276 | + av_frame_unref(dst); |
| 277 | + |
| 278 | + return ret; |
| 284 | 279 | } |
| 285 | 280 | |
| 286 | 281 | /* ref the buffers */ |
| @@ -424,14 +419,10 @@ int av_frame_make_writable(AVFrame *frame) · 137 unmodified lines |
| 424 | 419 | if (ret < 0) |
| 425 | 420 | return ret; |
| 426 | 421 | |
| 427 | | − if (tmp.nb_samples) { |
| 428 | | − int ch = tmp.channels; |
| 429 | | − CHECK_CHANNELS_CONSISTENCY(&tmp); |
| 430 | | − av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0, |
| 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); |
| 422 | + ret = av_frame_copy(&tmp, frame); |
| 423 | + if (ret < 0) { |
| 424 | + av_frame_unref(&tmp); |
| 425 | + return ret; |
| 435 | 426 | } |
| 436 | 427 | |
| 437 | 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 | 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 | +} |