From patchwork Wed Apr 6 08:51:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philipp Zabel X-Patchwork-Id: 12803339 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7B31C433F5 for ; Wed, 6 Apr 2022 12:46:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230027AbiDFMsS (ORCPT ); Wed, 6 Apr 2022 08:48:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231772AbiDFMrd (ORCPT ); Wed, 6 Apr 2022 08:47:33 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2D934C38CE for ; Wed, 6 Apr 2022 01:51:49 -0700 (PDT) Received: from dude03.red.stw.pengutronix.de ([2a0a:edc0:0:1101:1d::39]) by metis.ext.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1nc1OG-0008Pe-6q; Wed, 06 Apr 2022 10:51:48 +0200 From: Philipp Zabel To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , kernel@pengutronix.de Subject: [PATCH] media: coda: add JPEG downscale support Date: Wed, 6 Apr 2022 10:51:45 +0200 Message-Id: <20220406085145.2365446-1-p.zabel@pengutronix.de> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:1101:1d::39 X-SA-Exim-Mail-From: p.zabel@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The JPEG decoder in the CODA960 VPU can downscale images while decoding, with a factor of 1/2, 1/4, or 1/8. Signed-off-by: Philipp Zabel --- .../media/platform/chips-media/coda-common.c | 30 ++++++++++++++----- .../media/platform/chips-media/coda-jpeg.c | 10 ++++++- drivers/media/platform/chips-media/coda.h | 7 +++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/chips-media/coda-common.c b/drivers/media/platform/chips-media/coda-common.c index a57822b05070..37360cb6ddb0 100644 --- a/drivers/media/platform/chips-media/coda-common.c +++ b/drivers/media/platform/chips-media/coda-common.c @@ -657,6 +657,8 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv, const struct coda_q_data *q_data_src; const struct coda_codec *codec; struct vb2_queue *src_vq; + int hscale = 0; + int vscale = 0; int ret; bool use_vdoa; @@ -673,8 +675,13 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv, */ src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); if (vb2_is_streaming(src_vq)) { - f->fmt.pix.width = q_data_src->width; - f->fmt.pix.height = q_data_src->height; + if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && + ctx->dev->devtype->product == CODA_960) { + hscale = coda_jpeg_scale(q_data_src->width, f->fmt.pix.width); + vscale = coda_jpeg_scale(q_data_src->height, f->fmt.pix.height); + } + f->fmt.pix.width = q_data_src->width >> hscale; + f->fmt.pix.height = q_data_src->height >> vscale; if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG) { if (ctx->params.jpeg_chroma_subsampling == @@ -704,8 +711,8 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv, /* The decoders always write complete macroblocks or MCUs */ if (ctx->inst_type == CODA_INST_DECODER) { - f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); - f->fmt.pix.height = round_up(f->fmt.pix.height, 16); + f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16 >> hscale); + f->fmt.pix.height = round_up(f->fmt.pix.height, 16 >> vscale); if (codec->src_fourcc == V4L2_PIX_FMT_JPEG && f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) { f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * @@ -850,17 +857,26 @@ static int coda_s_fmt_vid_cap(struct file *file, void *priv, struct coda_q_data *q_data_src; const struct coda_codec *codec; struct v4l2_rect r; + int hscale = 0; + int vscale = 0; int ret; + q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + + if (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && + ctx->dev->devtype->product == CODA_960) { + hscale = coda_jpeg_scale(q_data_src->width, f->fmt.pix.width); + vscale = coda_jpeg_scale(q_data_src->height, f->fmt.pix.height); + } + ret = coda_try_fmt_vid_cap(file, priv, f); if (ret) return ret; - q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); r.left = 0; r.top = 0; - r.width = q_data_src->width; - r.height = q_data_src->height; + r.width = q_data_src->width >> hscale; + r.height = q_data_src->height >> vscale; ret = coda_s_fmt(ctx, f, &r); if (ret) diff --git a/drivers/media/platform/chips-media/coda-jpeg.c b/drivers/media/platform/chips-media/coda-jpeg.c index a72f4655e5ad..5948ada75d43 100644 --- a/drivers/media/platform/chips-media/coda-jpeg.c +++ b/drivers/media/platform/chips-media/coda-jpeg.c @@ -1328,6 +1328,7 @@ static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx) struct coda_q_data *q_data_src, *q_data_dst; struct vb2_v4l2_buffer *src_buf, *dst_buf; int chroma_interleave; + int scl_hor_mode, scl_ver_mode; src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); @@ -1335,6 +1336,9 @@ static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx) q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); dst_fourcc = q_data_dst->fourcc; + scl_hor_mode = coda_jpeg_scale(q_data_src->width, q_data_dst->width); + scl_ver_mode = coda_jpeg_scale(q_data_src->height, q_data_dst->height); + if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0) vb2_set_plane_payload(&src_buf->vb2_buf, 0, vb2_plane_size(&src_buf->vb2_buf, 0)); @@ -1386,7 +1390,11 @@ static int coda9_jpeg_prepare_decode(struct coda_ctx *ctx) coda_write(dev, 0, CODA9_REG_JPEG_ROT_INFO); coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO); coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO); - coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO); + if (scl_hor_mode || scl_ver_mode) + val = CODA9_JPEG_SCL_ENABLE | (scl_hor_mode << 2) | scl_ver_mode; + else + val = 0; + coda_write(dev, val, CODA9_REG_JPEG_SCL_INFO); coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG); coda_write(dev, ctx->params.jpeg_restart_interval, CODA9_REG_JPEG_RST_INTVAL); diff --git a/drivers/media/platform/chips-media/coda.h b/drivers/media/platform/chips-media/coda.h index dcf35641c603..ddfd0a32c653 100644 --- a/drivers/media/platform/chips-media/coda.h +++ b/drivers/media/platform/chips-media/coda.h @@ -380,6 +380,13 @@ u32 coda_mpeg4_parse_headers(struct coda_ctx *ctx, u8 *buf, u32 size); void coda_update_profile_level_ctrls(struct coda_ctx *ctx, u8 profile_idc, u8 level_idc); +static inline int coda_jpeg_scale(int src, int dst) +{ + return (dst <= src / 8) ? 3 : + (dst <= src / 4) ? 2 : + (dst <= src / 2) ? 1 : 0; +} + bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb); int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb); int coda_jpeg_write_tables(struct coda_ctx *ctx);