[FFmpeg-devel] [PATCH] lavfi/zscale: Fix unaligned data ptr issues in realign_frame

James Almer jamrial at gmail.com
Sat Nov 9 04:29:33 EET 2024


On 11/8/2024 10:51 PM, Pavel Koshevoy wrote:
> I ran into segfaults in zimg when I attempted to use zscale
> to convert a 512x538 at yuv444p16le(tv) image from HLG to Bt.709
> with this filter chain:
> 
> buffer=width=512:height=538:pix_fmt=yuv444p16le:time_base=1/1:sar=1/1,zscale=min=2020_ncl:rin=limited:pin=2020:tin=arib-std-b67:cin=left:t=linear,format=gbrpf32le,tonemap=gamma:desat=0,zscale=tin=linear:npl=100:p=709:m=709:r=limited:t=709,format=pix_fmts=yuv444p16le,buffersink
> 
> I found several issues:
> - realign_frame called av_pix_fmt_count_planes with incorrect parameter.
> - av_frame_get_buffer did not align data pointers to specified alignment.

Because it's not supposed to. The align parameter doxy states "buffer 
size alignment", which is the result of aligning the stride/linesizes, 
not the data pointers.

You may want to use ff_default_get_video_buffer2(), which will add align 
amount of bytes to the allocated buffers (On top of aligning the 
linesizes to it), and then align the pointers with FFALIGN().

> - s->tmp[job_nr] pointer was also unaligned.

Please split this into one patch per issue fixed, to simplify future 
bisecting.

> 
> https://github.com/sekrit-twc/zimg/issues/212
> ---
>   libavfilter/vf_zscale.c | 17 ++++++++++++-----
>   libavutil/frame.c       |  8 +++++++-
>   2 files changed, 19 insertions(+), 6 deletions(-)
> 
> diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c
> index 4ba059064b..a74a3da8d9 100644
> --- a/libavfilter/vf_zscale.c
> +++ b/libavfilter/vf_zscale.c
> @@ -112,6 +112,7 @@ typedef struct ZScaleContext {
>       int force_original_aspect_ratio;
>   
>       void *tmp[MAX_THREADS]; //separate for each thread;
> +    void *tmp_aligned[MAX_THREADS];
>       int nb_threads;
>       int jobs_ret[MAX_THREADS];
>       double in_slice_start[MAX_THREADS];
> @@ -594,6 +595,7 @@ static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *des
>   {
>       ZScaleContext *s = ctx->priv;
>       int ret;
> +    int misaligned_tmp;
>       size_t size;
>       zimg_image_format src_format;
>       zimg_image_format dst_format;
> @@ -628,11 +630,15 @@ static int graphs_build(AVFrame *in, AVFrame *out, const AVPixFmtDescriptor *des
>       if (ret)
>           return print_zimg_error(ctx);
>   
> -    if (s->tmp[job_nr])
> +    if (s->tmp[job_nr]) {
>           av_freep(&s->tmp[job_nr]);
> -    s->tmp[job_nr] = av_calloc(size, 1);
> +        s->tmp_aligned[job_nr] = NULL;
> +    }
> +    s->tmp[job_nr] = av_calloc(size + ZIMG_ALIGNMENT - 1, 1);
>       if (!s->tmp[job_nr])
>           return AVERROR(ENOMEM);
> +    misaligned_tmp = ((uintptr_t)(s->tmp[job_nr])) % ZIMG_ALIGNMENT;

Use FFALIGN() instead.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20241108/0499073d/attachment.sig>


More information about the ffmpeg-devel mailing list