From nobody Sun Sep 22 08:49:59 2024 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 D6261C433EF for ; Thu, 31 Mar 2022 04:13:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229641AbiCaEOq (ORCPT ); Thu, 31 Mar 2022 00:14:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230228AbiCaEOW (ORCPT ); Thu, 31 Mar 2022 00:14:22 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 610AC27AD64; Wed, 30 Mar 2022 20:46:22 -0700 (PDT) X-UUID: 0be1dc210c80407199f822f61748f7fb-20220331 X-UUID: 0be1dc210c80407199f822f61748f7fb-20220331 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1762808605; Thu, 31 Mar 2022 10:48:39 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs10n1.mediatek.inc (172.21.101.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.792.15; Thu, 31 Mar 2022 10:48:37 +0800 Received: from localhost.localdomain (10.17.3.154) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 31 Mar 2022 10:48:34 +0800 From: Yunfei Dong To: Yunfei Dong , Alexandre Courbot , Nicolas Dufresne , "Hans Verkuil" , AngeloGioacchino Del Regno , Benjamin Gaignard , Tiffany Lin , Andrew-CT Chen , Mauro Carvalho Chehab , Rob Herring , Matthias Brugger , Tomasz Figa CC: George Sun , Xiaoyong Lu , Hsin-Yi Wang , Fritz Koenig , Dafna Hirschfeld , Daniel Vetter , dri-devel , Irui Wang , Steve Cho , , , , , , , Subject: [PATCH v8, 06/17] media: mediatek: vcodec: Refactor get and put capture buffer flow Date: Thu, 31 Mar 2022 10:47:50 +0800 Message-ID: <20220331024801.29229-7-yunfei.dong@mediatek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220331024801.29229-1-yunfei.dong@mediatek.com> References: <20220331024801.29229-1-yunfei.dong@mediatek.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" For lat and core decode in parallel, need to get capture buffer when core start to decode and put capture buffer to display list when core decode done. Signed-off-by: Yunfei Dong --- changed compare with v7: In order to adjust GStreamer, need to separate src buffer done with v4l2_ctrl_request_complete. --- .../vcodec/mtk_vcodec_dec_stateless.c | 88 +++++++++++++------ .../platform/mediatek/vcodec/mtk_vcodec_drv.h | 6 +- .../mediatek/vcodec/vdec/vdec_h264_req_if.c | 11 ++- .../platform/mediatek/vcodec/vdec_msg_queue.h | 2 + 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateles= s.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c index 4df7b158ec5e..727a128de18b 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c @@ -108,20 +108,50 @@ static const struct mtk_codec_framesizes mtk_vdec_fra= mesizes[] =3D { =20 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes) =20 -static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx, - struct vb2_v4l2_buffer *vb2_v4l2) +static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int= error, + struct media_request *src_buf_req) { - struct mtk_video_dec_buf *framebuf =3D - container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb); - struct vdec_fb *pfb =3D &framebuf->frame_buffer; - struct vb2_buffer *dst_buf =3D &vb2_v4l2->vb2_buf; + struct vb2_v4l2_buffer *vb2_dst; + enum vb2_buffer_state state; =20 - pfb->base_y.va =3D NULL; + if (error) + state =3D VB2_BUF_STATE_ERROR; + else + state =3D VB2_BUF_STATE_DONE; + + vb2_dst =3D v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(vb2_dst, state); + + mtk_v4l2_debug(2, "free frame buffer id:%d to done list", + vb2_dst->vb2_buf.index); + + if (src_buf_req) + v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl); +} + +static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx) +{ + struct mtk_video_dec_buf *framebuf; + struct vb2_v4l2_buffer *vb2_v4l2; + struct vb2_buffer *dst_buf; + struct vdec_fb *pfb; + + vb2_v4l2 =3D v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + if (!vb2_v4l2) { + mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id); + return NULL; + } + + dst_buf =3D &vb2_v4l2->vb2_buf; + framebuf =3D container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb); + + pfb =3D &framebuf->frame_buffer; + pfb->base_y.va =3D vb2_plane_vaddr(dst_buf, 0); pfb->base_y.dma_addr =3D vb2_dma_contig_plane_dma_addr(dst_buf, 0); pfb->base_y.size =3D ctx->q_data[MTK_Q_DATA_DST].sizeimage[0]; =20 if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes =3D=3D 2) { - pfb->base_c.va =3D NULL; + pfb->base_c.va =3D vb2_plane_vaddr(dst_buf, 1); pfb->base_c.dma_addr =3D vb2_dma_contig_plane_dma_addr(dst_buf, 1); pfb->base_c.size =3D ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]; @@ -145,12 +175,12 @@ static void mtk_vdec_worker(struct work_struct *work) struct mtk_vcodec_ctx *ctx =3D container_of(work, struct mtk_vcodec_ctx, decode_work); struct mtk_vcodec_dev *dev =3D ctx->dev; - struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst; + struct vb2_v4l2_buffer *vb2_v4l2_src; struct vb2_buffer *vb2_src; struct mtk_vcodec_mem *bs_src; struct mtk_video_dec_buf *dec_buf_src; struct media_request *src_buf_req; - struct vdec_fb *dst_buf; + enum vb2_buffer_state state; bool res_chg =3D false; int ret; =20 @@ -161,13 +191,6 @@ static void mtk_vdec_worker(struct work_struct *work) return; } =20 - vb2_v4l2_dst =3D v4l2_m2m_next_dst_buf(ctx->m2m_ctx); - if (!vb2_v4l2_dst) { - v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); - mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id); - return; - } - vb2_src =3D &vb2_v4l2_src->vb2_buf; dec_buf_src =3D container_of(vb2_v4l2_src, struct mtk_video_dec_buf, m2m_buf.vb); @@ -176,9 +199,15 @@ static void mtk_vdec_worker(struct work_struct *work) mtk_v4l2_debug(3, "[%d] (%d) id=3D%d, vb=3D%p", ctx->id, vb2_src->vb2_queue->type, vb2_src->index, vb2_src); =20 - bs_src->va =3D NULL; + bs_src->va =3D vb2_plane_vaddr(vb2_src, 0); bs_src->dma_addr =3D vb2_dma_contig_plane_dma_addr(vb2_src, 0); bs_src->size =3D (size_t)vb2_src->planes[0].bytesused; + if (!bs_src->va) { + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + mtk_v4l2_err("[%d] id=3D%d source buffer is NULL", ctx->id, + vb2_src->index); + return; + } =20 mtk_v4l2_debug(3, "[%d] Bitstream VA=3D%p DMA=3D%pad Size=3D%zx vb=3D%p", ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src); @@ -189,9 +218,7 @@ static void mtk_vdec_worker(struct work_struct *work) else mtk_v4l2_err("vb2 buffer media request is NULL"); =20 - dst_buf =3D vdec_get_cap_buffer(ctx, vb2_v4l2_dst); - v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true); - ret =3D vdec_if_decode(ctx, bs_src, dst_buf, &res_chg); + ret =3D vdec_if_decode(ctx, bs_src, NULL, &res_chg); if (ret) { mtk_v4l2_err(" <=3D=3D=3D[%d], src_buf[%d] sz=3D0x%zx pts=3D%llu vdec_if= _decode() ret=3D%d res_chg=3D%d=3D=3D=3D>", ctx->id, vb2_src->index, bs_src->size, @@ -203,10 +230,17 @@ static void mtk_vdec_worker(struct work_struct *work) } } =20 - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, - ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); - - v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl); + state =3D ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE; + if (!IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch) || + ctx->current_codec =3D=3D V4L2_PIX_FMT_VP8_FRAME) { + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, state); + if (src_buf_req) + v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl); + } else { + v4l2_m2m_src_buf_remove(ctx->m2m_ctx); + v4l2_m2m_buf_done(vb2_v4l2_src, state); + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); + } } =20 static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb) @@ -336,6 +370,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = =3D { .uses_stateless_api =3D true, .worker =3D mtk_vdec_worker, .flush_decoder =3D mtk_vdec_flush_decoder, + .cap_to_disp =3D mtk_vdec_stateless_cap_to_disp, + .get_cap_buffer =3D vdec_get_cap_buffer, .is_subdev_supported =3D false, .hw_arch =3D MTK_VDEC_PURE_SINGLE_CORE, }; @@ -354,6 +390,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdat= a =3D { .uses_stateless_api =3D true, .worker =3D mtk_vdec_worker, .flush_decoder =3D mtk_vdec_flush_decoder, + .cap_to_disp =3D mtk_vdec_stateless_cap_to_disp, + .get_cap_buffer =3D vdec_get_cap_buffer, .is_subdev_supported =3D true, .hw_arch =3D MTK_VDEC_LAT_SINGLE_CORE, }; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/driv= ers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h index 6d27e4d41ede..c06463142182 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h @@ -350,7 +350,8 @@ enum mtk_vdec_hw_arch { * @ctrls_setup: init vcodec dec ctrls * @worker: worker to start a decode job * @flush_decoder: function that flushes the decoder - * + * @get_cap_buffer: get capture buffer from capture queue + * @cap_to_disp: put capture buffer to disp list for lat and core arch * @vdec_vb2_ops: struct vb2_ops * * @vdec_formats: supported video decoder formats @@ -372,6 +373,9 @@ struct mtk_vcodec_dec_pdata { int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx); void (*worker)(struct work_struct *work); int (*flush_decoder)(struct mtk_vcodec_ctx *ctx); + struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx); + void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, int error, + struct media_request *src_buf_req); =20 struct vb2_ops *vdec_vb2_ops; =20 diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c= b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c index 43542de11e9c..27119aa31dd9 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c @@ -670,12 +670,15 @@ static void vdec_h264_slice_deinit(void *h_vdec) } =20 static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, - struct vdec_fb *fb, bool *res_chg) + struct vdec_fb *unused, bool *res_chg) { struct vdec_h264_slice_inst *inst =3D h_vdec; const struct v4l2_ctrl_h264_decode_params *dec_params =3D get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); struct vdec_vpu_inst *vpu =3D &inst->vpu; + struct mtk_video_dec_buf *src_buf_info; + struct mtk_video_dec_buf *dst_buf_info; + struct vdec_fb *fb; u32 data[2]; u64 y_fb_dma; u64 c_fb_dma; @@ -685,6 +688,10 @@ static int vdec_h264_slice_decode(void *h_vdec, struct= mtk_vcodec_mem *bs, if (!bs) return vpu_dec_reset(vpu); =20 + fb =3D inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); + src_buf_info =3D container_of(bs, struct mtk_video_dec_buf, bs_buffer); + dst_buf_info =3D container_of(fb, struct mtk_video_dec_buf, frame_buffer); + y_fb_dma =3D fb ? (u64)fb->base_y.dma_addr : 0; c_fb_dma =3D fb ? (u64)fb->base_c.dma_addr : 0; =20 @@ -696,6 +703,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct = mtk_vcodec_mem *bs, inst->vsi_ctx.dec.c_fb_dma =3D c_fb_dma; inst->vsi_ctx.dec.vdec_fb_va =3D (u64)(uintptr_t)fb; =20 + v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, + &dst_buf_info->m2m_buf.vb, true); get_vdec_decode_parameters(inst); data[0] =3D bs->size; /* diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h b/driv= ers/media/platform/mediatek/vcodec/vdec_msg_queue.h index b6ba66d3e026..c43d427f5f54 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h @@ -43,6 +43,7 @@ struct vdec_msg_queue_ctx { * @wdma_err_addr: wdma error address used for lat hardware * @slice_bc_addr: slice bc address used for lat hardware * @ts_info: need to set timestamp from output to capture + * @src_buf_req: output buffer media request object * * @private_data: shared information used to lat and core hardware * @ctx: mtk vcodec context information @@ -54,6 +55,7 @@ struct vdec_lat_buf { struct mtk_vcodec_mem wdma_err_addr; struct mtk_vcodec_mem slice_bc_addr; struct vb2_v4l2_buffer ts_info; + struct media_request *src_buf_req; =20 void *private_data; struct mtk_vcodec_ctx *ctx; --=20 2.18.0