[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <967409e7-5565-4616-95ce-780650609567@kwiboo.se>
Date: Wed, 22 Oct 2025 23:44:48 +0200
From: Jonas Karlman <jonas@...boo.se>
To: Detlev Casanova <detlev.casanova@...labora.com>
Cc: Mauro Carvalho Chehab <mchehab@...nel.org>,
Ezequiel Garcia <ezequiel@...guardiasur.com.ar>,
Heiko Stuebner <heiko@...ech.de>, Ricardo Ribalda <ribalda@...omium.org>,
Hans Verkuil <hverkuil@...nel.org>, Hans de Goede <hansg@...nel.org>,
Yunke Cao <yunkec@...gle.com>, Jonathan Corbet <corbet@....net>,
Laurent Pinchart <laurent.pinchart@...asonboard.com>,
Sakari Ailus <sakari.ailus@...ux.intel.com>,
James Cowgill <james.cowgill@...ize.com>, linux-media@...r.kernel.org,
linux-rockchip@...ts.infradead.org, linux-arm-kernel@...ts.infradead.org,
kernel@...labora.com, Nicolas Dufresne <nicolas.dufresne@...labora.com>,
Diederik de Haas <didi.debian@...ow.org>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v4 07/15] media: rkvdec: Move hevc functions to common
file
Hi Detlev,
On 10/22/2025 7:44 PM, Detlev Casanova wrote:
> This is a preparation commit to add support for new variants of the
> decoder.
>
> The functions will later be shared with vdpu381 (rk3588) and vdpu383
> (rk3576).
>
> Tested-by: Diederik de Haas <didi.debian@...ow.org> # Rock 5B
> Signed-off-by: Detlev Casanova <detlev.casanova@...labora.com>
> ---
> .../media/platform/rockchip/rkvdec/Makefile | 1 +
> .../rockchip/rkvdec/rkvdec-hevc-common.c | 233 +++++++++++++++++
> .../rockchip/rkvdec/rkvdec-hevc-common.h | 51 ++++
> .../platform/rockchip/rkvdec/rkvdec-hevc.c | 243 +-----------------
> 4 files changed, 291 insertions(+), 237 deletions(-)
> create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
> create mode 100644 drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
>
> diff --git a/drivers/media/platform/rockchip/rkvdec/Makefile b/drivers/media/platform/rockchip/rkvdec/Makefile
> index d2ba7a7c15e5..1b4bc44be23e 100644
> --- a/drivers/media/platform/rockchip/rkvdec/Makefile
> +++ b/drivers/media/platform/rockchip/rkvdec/Makefile
> @@ -6,4 +6,5 @@ rockchip-vdec-y += \
> rkvdec-h264.o \
> rkvdec-h264-common.o \
> rkvdec-hevc.o \
> + rkvdec-hevc-common.o \
> rkvdec-vp9.o
> diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
> new file mode 100644
> index 000000000000..d571107f2242
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
> @@ -0,0 +1,233 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip video decoder hevc common functions
> + *
> + * Copyright (C) 2025 Collabora, Ltd.
> + * Detlev Casanova <detlev.casanova@...labora.com>
> + *
> + * Copyright (C) 2023 Collabora, Ltd.
> + * Sebastian Fricke <sebastian.fricke@...labora.com>
> + *
> + * Copyright (C) 2019 Collabora, Ltd.
> + * Boris Brezillon <boris.brezillon@...labora.com>
> + *
> + * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
> + * Jeffy Chen <jeffy.chen@...k-chips.com>
> + */
> +
> +#include <linux/v4l2-common.h>
> +#include <media/v4l2-mem2mem.h>
> +
> +#include "rkvdec.h"
> +#include "rkvdec-hevc-common.h"
> +
> +/*
> + * Flip one or more matrices along their main diagonal and flatten them
> + * before writing it to the memory.
> + * Convert:
> + * ABCD AEIM
> + * EFGH => BFJN => AEIMBFJNCGKODHLP
> + * IJKL CGKO
> + * MNOP DHLP
> + */
> +static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
> + int matrices, int row_length)
> +{
> + int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
> +
> + matrix_size = row_length * row_length;
> + for (i = 0; i < matrices; i++) {
> + row = 0;
> + x_offset = 0;
> + matrix_offset = i * matrix_size;
> + for (j = 0; j < matrix_size; j++) {
> + y_offset = j - (row * row_length);
> + rot_index = y_offset * row_length + x_offset;
> + new_value = *(input + i * matrix_size + j);
> + output[matrix_offset + rot_index] = new_value;
> + if ((j + 1) % row_length == 0) {
> + row += 1;
> + x_offset += 1;
> + }
> + }
> + }
> +}
> +
> +static void assemble_scalingfactor0(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
> +{
> + int offset = 0;
> +
> + transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
> + offset = 6 * 16 * sizeof(u8);
> + transpose_and_flatten_matrices(output + offset, (const u8 *)input->scaling_list_8x8, 6, 8);
> + offset += 6 * 64 * sizeof(u8);
> + transpose_and_flatten_matrices(output + offset,
> + (const u8 *)input->scaling_list_16x16, 6, 8);
> + offset += 6 * 64 * sizeof(u8);
> + /* Add a 128 byte padding with 0s between the two 32x32 matrices */
> + transpose_and_flatten_matrices(output + offset,
> + (const u8 *)input->scaling_list_32x32, 1, 8);
> + offset += 64 * sizeof(u8);
> + memset(output + offset, 0, 128);
> + offset += 128 * sizeof(u8);
> + transpose_and_flatten_matrices(output + offset,
> + (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)),
> + 1, 8);
> + offset += 64 * sizeof(u8);
> + memset(output + offset, 0, 128);
> +}
> +
> +/*
> + * Required layout:
> + * A = scaling_list_dc_coef_16x16
> + * B = scaling_list_dc_coef_32x32
> + * 0 = Padding
> + *
> + * A, A, A, A, A, A, B, 0, 0, B, 0, 0
> + */
> +static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
> +{
> + u8 list_32x32[6] = {0};
> +
> + memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8));
> + list_32x32[0] = input->scaling_list_dc_coef_32x32[0];
> + list_32x32[3] = input->scaling_list_dc_coef_32x32[1];
> + memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8));
> +}
> +
> +static void translate_scaling_list(struct scaling_factor *output,
> + const struct v4l2_ctrl_hevc_scaling_matrix *input)
> +{
> + assemble_scalingfactor0(output->scalingfactor0, input);
> + memcpy(output->scalingfactor1, (const u8 *)input->scaling_list_4x4, 96);
> + assemble_scalingdc(output->scalingdc, input);
> + memset(output->reserved, 0, 4 * sizeof(u8));
> +}
> +
> +void rkvdec_hevc_assemble_hw_scaling_list(struct rkvdec_hevc_run *run,
> + struct scaling_factor *scaling_factor,
> + struct v4l2_ctrl_hevc_scaling_matrix *cache)
> +{
> + const struct v4l2_ctrl_hevc_scaling_matrix *scaling = run->scaling_matrix;
> +
> + if (!memcmp(cache, scaling,
> + sizeof(struct v4l2_ctrl_hevc_scaling_matrix)))
> + return;
> +
> + translate_scaling_list(scaling_factor, scaling);
> +
> + memcpy(cache, scaling,
> + sizeof(struct v4l2_ctrl_hevc_scaling_matrix));
> +}
> +
> +struct vb2_buffer *
> +get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run,
> + unsigned int dpb_idx)
> +{
> + struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
> + const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
> + const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
> + struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
> + struct vb2_buffer *buf = NULL;
> +
> + if (dpb_idx < decode_params->num_active_dpb_entries)
> + buf = vb2_find_buffer(cap_q, dpb[dpb_idx].timestamp);
> +
> + /*
> + * If a DPB entry is unused or invalid, the address of current destination
> + * buffer is returned.
> + */
> + if (!buf)
> + return &run->base.bufs.dst->vb2_buf;
> +
> + return buf;
> +}
> +
> +#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES 2
> +
> +int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f)
> +{
> + struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
> +
> + fmt->num_planes = 1;
> + if (!fmt->plane_fmt[0].sizeimage)
> + fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
> + RKVDEC_HEVC_MAX_DEPTH_IN_BYTES;
> + return 0;
> +}
> +
> +enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx,
> + struct v4l2_ctrl *ctrl)
> +{
> + const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
> +
> + if (ctrl->id != V4L2_CID_STATELESS_HEVC_SPS)
> + return RKVDEC_IMG_FMT_ANY;
> +
> + if (sps->bit_depth_luma_minus8 == 0) {
> + if (sps->chroma_format_idc == 2)
> + return RKVDEC_IMG_FMT_422_8BIT;
> + else
> + return RKVDEC_IMG_FMT_420_8BIT;
> + } else if (sps->bit_depth_luma_minus8 == 2) {
> + if (sps->chroma_format_idc == 2)
> + return RKVDEC_IMG_FMT_422_10BIT;
> + else
> + return RKVDEC_IMG_FMT_420_10BIT;
> + }
> +
> + return RKVDEC_IMG_FMT_ANY;
> +}
This function is moved here in this patch, and then later rewritten and
moved once more in a later patch. Please move the functions to final
position in this patch and do not rewrite the function in a later patch.
Regards,
Jonas
[snip]
Powered by blists - more mailing lists