From 5f86113fe3dbbe48a88b59f52d88d3058b93a533 Mon Sep 17 00:00:00 2001 From: Damiano Galassi Date: Fri, 18 Jul 2025 06:17:58 +0200 Subject: [PATCH] libhb: fix high depth plane copy When the src and dst stride differs.Fix #7033. --- libhb/chroma_smooth.c | 19 +------------------ libhb/detelecine.c | 23 +++-------------------- libhb/fifo.c | 34 +++++++--------------------------- libhb/handbrake/internal.h | 22 ++++++++++++++++++++++ libhb/hbffmpeg.c | 16 +++------------- libhb/unsharp.c | 19 +------------------ 6 files changed, 37 insertions(+), 96 deletions(-) diff --git a/libhb/chroma_smooth.c b/libhb/chroma_smooth.c index d9248684c..4726b52a0 100644 --- a/libhb/chroma_smooth.c +++ b/libhb/chroma_smooth.c @@ -111,24 +111,7 @@ static void name##_##nbits(const uint8_t *frame_src, \ if (!amount) \ { \ - if (src != dst) \ - { \ - if (stride_src == stride_dst) \ - { \ - memcpy(dst, src, stride_dst * height); \ - } \ - else \ - { \ - const int size = stride_src < stride_dst ? ABS(stride_src) : stride_dst; \ - for (int yy = 0; yy < height; yy++) \ - { \ - memcpy(dst, src, size); \ - dst += stride_dst; \ - src += stride_src; \ - } \ - } \ - } \ - \ + hb_image_copy_plane(frame_dst, frame_src, stride_dst, stride_src, height); \ return; \ } \ \ diff --git a/libhb/detelecine.c b/libhb/detelecine.c index a935562d0..b548b182b 100644 --- a/libhb/detelecine.c +++ b/libhb/detelecine.c @@ -1153,26 +1153,9 @@ static int hb_detelecine_work( hb_filter_object_t * filter, /* Copy input buffer into pullup buffer */ for (int pp = 0; pp < 3; pp++) { - if (in->plane[pp].stride == ctx->stride[pp]) - { - memcpy(buf->planes[pp], in->plane[pp].data, buf->size[pp]); - } - else - { - const int stride_src = in->plane[pp].stride; - const int stride_dst = ctx->stride[pp]; - const int height = in->plane[pp].height; - const int size = stride_src < stride_dst ? ABS(stride_src) : stride_dst; - uint8_t *dst = buf->planes[pp]; - uint8_t *src = in->plane[pp].data; - - for (int yy = 0; yy < height; yy++) - { - memcpy(dst, src, size); - dst += stride_dst; - src += stride_src; - } - } + hb_image_copy_plane(buf->planes[pp], in->plane[pp].data, + ctx->stride[pp], in->plane[pp].stride, + in->plane[pp].height); } /* Submit buffer fields based on buffer flags. diff --git a/libhb/fifo.c b/libhb/fifo.c index f26321b47..bf21f2dcc 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -665,32 +665,6 @@ static int copy_hwframe_to_video_buffer(const AVFrame *frame, hb_buffer_t *buf) return ret; } -static void copy_avframe_to_video_buffer(const AVFrame *frame, hb_buffer_t *buf) -{ - for (int pp = 0; pp <= buf->f.max_plane; pp++) - { - if (buf->plane[pp].stride == frame->linesize[pp]) - { - memcpy(buf->plane[pp].data, frame->data[pp], frame->linesize[pp] * buf->plane[pp].height); - } - else - { - const int stride = buf->plane[pp].stride; - const int height = buf->plane[pp].height; - const int linesize = frame->linesize[pp]; - const int size = linesize < stride ? ABS(linesize) : stride; - uint8_t *dst = buf->plane[pp].data; - uint8_t *src = frame->data[pp]; - for (int yy = 0; yy < height; yy++) - { - memcpy(dst, src, size); - dst += stride; - src += linesize; - } - } - } -} - hb_buffer_t * hb_buffer_shallow_dup(const hb_buffer_t *src) { hb_buffer_t *buf = NULL; @@ -806,7 +780,13 @@ hb_buffer_t * hb_buffer_dup(const hb_buffer_t *src) { buf->f = src->f; hb_buffer_copy_props(buf, src); - copy_avframe_to_video_buffer(frame, buf); + + for (int pp = 0; pp <= buf->f.max_plane; pp++) + { + hb_image_copy_plane(buf->plane[pp].data, frame->data[pp], + buf->plane[pp].stride, frame->linesize[pp], + buf->plane[pp].height); + } } } } diff --git a/libhb/handbrake/internal.h b/libhb/handbrake/internal.h index f8dc78aae..15a4e5df1 100644 --- a/libhb/handbrake/internal.h +++ b/libhb/handbrake/internal.h @@ -251,6 +251,28 @@ static inline int hb_image_height(int pix_fmt, int height, int plane) return height; } +static inline void hb_image_copy_plane(uint8_t *restrict dst, const uint8_t *restrict src, + const int stride_dst, const int stride_src, const int height) +{ + if (src != dst) + { + if (stride_src == stride_dst) + { + memcpy(dst, src, stride_dst * height); + } + else + { + const int size = stride_src < stride_dst ? ABS(stride_src) : stride_dst; + for (int yy = 0; yy < height; yy++) + { + memcpy(dst, src, size); + dst += stride_dst; + src += stride_src; + } + } + } +} + /*********************************************************************** * Threads: scan.c, work.c, reader.c, muxcommon.c **********************************************************************/ diff --git a/libhb/hbffmpeg.c b/libhb/hbffmpeg.c index 713d003a6..1216b4209 100644 --- a/libhb/hbffmpeg.c +++ b/libhb/hbffmpeg.c @@ -251,19 +251,9 @@ hb_buffer_t * hb_avframe_to_video_buffer(AVFrame *frame, AVRational time_base) int pp; for (pp = 0; pp <= buf->f.max_plane; pp++) { - int yy; - int stride = buf->plane[pp].stride; - int height = buf->plane[pp].height; - int linesize = frame->linesize[pp]; - int size = linesize < stride ? ABS(linesize) : stride; - uint8_t * dst = buf->plane[pp].data; - uint8_t * src = frame->data[pp]; - for (yy = 0; yy < height; yy++) - { - memcpy(dst, src, size); - dst += stride; - src += linesize; - } + hb_image_copy_plane(buf->plane[pp].data, frame->data[pp], + buf->plane[pp].stride, frame->linesize[pp], + buf->plane[pp].height); } for (int i = 0; i < frame->nb_side_data; i++) { diff --git a/libhb/unsharp.c b/libhb/unsharp.c index 4db51d76a..7db410bc5 100644 --- a/libhb/unsharp.c +++ b/libhb/unsharp.c @@ -112,24 +112,7 @@ static void name##_##nbits(const uint8_t *frame_src, \ if (!amount) \ { \ - if (src != dst) \ - { \ - if (stride_src == stride_dst) \ - { \ - memcpy(dst, src, stride_dst * height); \ - } \ - else \ - { \ - const int size = stride_src < stride_dst ? ABS(stride_src) : stride_dst; \ - for (int yy = 0; yy < height; yy++) \ - { \ - memcpy(dst, src, size); \ - dst += stride_dst; \ - src += stride_src; \ - } \ - } \ - } \ - \ + hb_image_copy_plane(frame_dst, frame_src, stride_dst, stride_src, height); \ return; \ } \ \