Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp2875189rwb; Mon, 15 Aug 2022 13:05:53 -0700 (PDT) X-Google-Smtp-Source: AA6agR63Hy4xGIeIJK9LrDpdVUL7ZM9ClQRy/Pk8/gIlb49Nlg38htDeQQ3QvrjFm1EoPW/uMNXx X-Received: by 2002:a17:90b:4b4c:b0:1f4:da77:3f80 with SMTP id mi12-20020a17090b4b4c00b001f4da773f80mr19593781pjb.55.1660593953064; Mon, 15 Aug 2022 13:05:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660593953; cv=none; d=google.com; s=arc-20160816; b=UlJ4KeS+pi3W9zHp8A+7yd6mX66HCOA9J9lAb4XVZjiPHzsB6a+OCRhBmMTAO5ZP0P G0oX8Jc9Q7Xy5EpdRNtMZkJj/LzCj2fErmpfdPNGmtPZB1LA004qDjpaHtqhVb5h2bMQ pirNjTh82T0AQ+oM40uxpKD9w4VJ6FYxY2y2L8eFpNYLYo30nuZGWhi1il0UzRvXS5YD Gb4Zg8dTL5t10TCgTrFbGRclrCGjqwHyxgtYrYFRZoc66NmNPPS9/AwDG5Js32GcKk41 5rNg/tm0eckT+bc2KYoXGN+w9JfgaKTpwiG1HExlwQ7q5nFBqatAGpstUPlpGAxcJOJm 30FA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=i7krQODMKuLO//7KwoYY8AHuhnBdPrwFi0p+krwZAFk=; b=zFpQCa3clmFEJX5qGsNHavctztB0jijWmzFujkaoAB8OQXtb9KK6hrc93P0wZbAGjS QM3Ku+NllVRpSUK1uG12o3jcDfMUzDH7Zjh0kHfqzoVq/bZ+YfhrTzN5rx/fIi7EQFxn ZwZsXYNDBL0d/5zwXBd2p8AKruq8c2rbVECf3ZEVzOzKmghupy5199aoEuDeyrQvB1rK fYiWKxICbMfVsJCjniDrQi5XiJp8TEkYgjumk/hoJqkhl9FPFXQinTwlVurFqx7vbOBw NuF3awIkzQV7Ll0XZ9uToBZHdgDMjM0CdP6XiJX/26tDdg+kTXhOtkOmE7kaeye8hPCp VPTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="KRMH/QD0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j7-20020a17090276c700b0017086b1c40dsi10692009plt.400.2022.08.15.13.05.41; Mon, 15 Aug 2022 13:05:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="KRMH/QD0"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233778AbiHOStu (ORCPT + 99 others); Mon, 15 Aug 2022 14:49:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38138 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243526AbiHOSon (ORCPT ); Mon, 15 Aug 2022 14:44:43 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48E0F2FFEB; Mon, 15 Aug 2022 11:27:22 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9CCCC60691; Mon, 15 Aug 2022 18:27:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 91671C433D7; Mon, 15 Aug 2022 18:27:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660588041; bh=fiSO3jBXEXqACFFwooF7XCH3mk6KVEXM0hjIHuOLFAY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KRMH/QD0757lpsEF8wifgF8lUFhkQ+5nSv1Zo3QFrDrvNa2NQkzWP/yAhQhWpNO2A gA+DOwnMw7S2jpocRnuMN+prDQaCwFlIzTmRTdBKGiICdxeiBrG2n5LIqNuikHoIgP jcpPPas2kGThICUf0z7cbS7Mmr5PkihvfrK1ucrI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ming Qian , Mirela Rabulea , Hans Verkuil , Mauro Carvalho Chehab , Sasha Levin Subject: [PATCH 5.15 276/779] media: imx-jpeg: Support dynamic resolution change Date: Mon, 15 Aug 2022 19:58:40 +0200 Message-Id: <20220815180349.102600750@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180337.130757997@linuxfoundation.org> References: <20220815180337.130757997@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ming Qian [ Upstream commit b4e1fb8643daabba850e97df532191acffc23e6a ] To support dynamic resolution change, driver should meet the following conditions: 1. the previous pictures are all decoded before source change event. 2. prevent decoding new resolution pictures with incorrect capture buffer, until user handle source change event and setup capture. 3. report correct fmt and resolution during source change. Signed-off-by: Ming Qian Reviewed-by: Mirela Rabulea Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 69 +++++++++++++++++----- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 2 + 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c index 6289fec6e2a0..52732fbb2664 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c @@ -919,13 +919,14 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, { struct device *dev = ctx->mxc_jpeg->dev; struct mxc_jpeg_q_data *q_data_cap; - bool src_chg = false; if (!jpeg_src_buf->fmt) - return src_chg; + return false; q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) { + if (q_data_cap->fmt != jpeg_src_buf->fmt || + q_data_cap->w != jpeg_src_buf->w || + q_data_cap->h != jpeg_src_buf->h) { dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", q_data_cap->w, q_data_cap->h, jpeg_src_buf->w, jpeg_src_buf->h, @@ -962,9 +963,16 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision); mxc_jpeg_sizeimage(q_data_cap); notify_src_chg(ctx); - src_chg = true; + ctx->source_change = 1; } - return src_chg; + return ctx->source_change ? true : false; +} + +static int mxc_jpeg_job_ready(void *priv) +{ + struct mxc_jpeg_ctx *ctx = priv; + + return ctx->source_change ? 0 : 1; } static void mxc_jpeg_device_run(void *priv) @@ -1014,6 +1022,13 @@ static void mxc_jpeg_device_run(void *priv) return; } + if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) { + if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) { + spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + return; + } + } /* * TODO: this reset should be removed, once we figure out @@ -1065,6 +1080,7 @@ static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx) q->last_buffer_dequeued = true; wake_up(&q->done_wq); ctx->stopped = 0; + ctx->header_parsed = false; } static int mxc_jpeg_decoder_cmd(struct file *file, void *priv, @@ -1158,6 +1174,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); int ret; + if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) + ctx->source_change = 0; dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); q_data->sequence = 0; @@ -1336,16 +1354,15 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) dev_warn(dev, "Invalid user resolution 0x0"); dev_warn(dev, "Keeping resolution from JPEG: %dx%d", header.frame.width, header.frame.height); - q_data_out->w = header.frame.width; - q_data_out->h = header.frame.height; } else if (header.frame.width != q_data_out->w || header.frame.height != q_data_out->h) { dev_err(dev, "Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)", header.frame.width, header.frame.height, q_data_out->w, q_data_out->h); - return -EINVAL; } + q_data_out->w = header.frame.width; + q_data_out->h = header.frame.height; if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) { dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n", header.frame.width, header.frame.height); @@ -1381,8 +1398,10 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) jpeg_src_buf->fmt = mxc_jpeg_find_format(ctx, fourcc); jpeg_src_buf->w = header.frame.width; jpeg_src_buf->h = header.frame.height; + ctx->header_parsed = true; - mxc_jpeg_source_change(ctx, jpeg_src_buf); + if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx)) + mxc_jpeg_source_change(ctx, jpeg_src_buf); return 0; } @@ -1459,6 +1478,7 @@ static void mxc_jpeg_buf_finish(struct vb2_buffer *vb) if (list_empty(&q->done_list)) { vbuf->flags |= V4L2_BUF_FLAG_LAST; ctx->stopped = 0; + ctx->header_parsed = false; } } @@ -1604,26 +1624,42 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); + struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type); - if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) + if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) { return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, MXC_JPEG_FMT_TYPE_ENC); - else + } else if (!ctx->header_parsed) { return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, MXC_JPEG_FMT_TYPE_RAW); + } else { + /* For the decoder CAPTURE queue, only enumerate the raw formats + * supported for the format currently active on OUTPUT + * (more precisely what was propagated on capture queue + * after jpeg parse on the output buffer) + */ + if (f->index) + return -EINVAL; + f->pixelformat = q_data->fmt->fourcc; + strscpy(f->description, q_data->fmt->name, sizeof(f->description)); + return 0; + } } static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); + u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC : + MXC_JPEG_FMT_TYPE_RAW; + int ret; + ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type); + if (ret) + return ret; if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) - return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, - MXC_JPEG_FMT_TYPE_ENC); - else - return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, - MXC_JPEG_FMT_TYPE_RAW); + f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION; + return 0; } static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt, @@ -1981,6 +2017,7 @@ static const struct v4l2_file_operations mxc_jpeg_fops = { }; static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = { + .job_ready = mxc_jpeg_job_ready, .device_run = mxc_jpeg_device_run, }; diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h index 2b4b30d01e51..6913ae087e44 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h @@ -95,6 +95,8 @@ struct mxc_jpeg_ctx { unsigned int stopping; unsigned int stopped; unsigned int slot; + unsigned int source_change; + bool header_parsed; }; struct mxc_jpeg_slot_data { -- 2.35.1