Output buffer alignment might be different to ZIMG_ALIGNMENT or it may not be aligned at all if a downstream filter (e.g. vf_pad) intentionally misaligns it. Or maybe we should unconditionally always allocate output with av_frame_get_buffer() instead of ff_get_video_buffer()?
Unified · Split
| @@ -632,7 +632,7 @@ static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *des · 631 unmodified lines | ||
| 632 | 632 | return 0; |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | −static int realign_frame(const AVPixFmtDescriptor *desc, AVFrame **frame) | |
| 635 | +static int realign_frame(const AVPixFmtDescriptor *desc, AVFrame **frame, int needs_copy) | |
| 636 | 636 | { |
| 637 | 637 | AVFrame *aligned = NULL; |
| 638 | 638 | int ret = 0, plane, planes; |
| @@ -654,10 +654,10 @@ static int realign_frame(const AVPixFmtDescriptor *desc, AVFrame **frame) · 15 unmodified lines | ||
| 654 | 654 | if ((ret = av_frame_get_buffer(aligned, ZIMG_ALIGNMENT)) < 0) |
| 655 | 655 | goto fail; |
| 656 | 656 | |
| 657 | − if ((ret = av_frame_copy(aligned, *frame)) < 0) | |
| 657 | + if (needs_copy && (ret = av_frame_copy(aligned, *frame)) < 0) | |
| 658 | 658 | goto fail; |
| 659 | 659 | |
| 660 | − if ((ret = av_frame_copy_props(aligned, *frame)) < 0) | |
| 660 | + if (needs_copy && (ret = av_frame_copy_props(aligned, *frame)) < 0) | |
| 661 | 661 | goto fail; |
| 662 | 662 | |
| 663 | 663 | av_frame_free(frame); |
| @@ -786,9 +786,12 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) · 122 unmodified lines | ||
| 786 | 786 | goto fail; |
| 787 | 787 | } |
| 788 | 788 | |
| 789 | + if ((ret = realign_frame(odesc, &out, 0)) < 0) | |
| 790 | + goto fail; | |
| 791 | + | |
| 789 | 792 | av_frame_copy_props(out, in); |
| 790 | 793 | |
| 791 | − if ((ret = realign_frame(desc, &in)) < 0) | |
| 794 | + if ((ret = realign_frame(desc, &in, 1)) < 0) | |
| 792 | 795 | goto fail; |
| 793 | 796 | |
| 794 | 797 | snprintf(buf, sizeof(buf)-1, "%d", outlink->w); |