summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
diff options
context:
space:
mode:
authorYunfei Dong <yunfei.dong@mediatek.com>2022-05-12 04:19:39 +0200
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-05-13 14:44:06 +0200
commit7b182b8d9c852343fb34923a2d1b4e61421b37c7 (patch)
tree8e477d38cc309d7e3e85f53e57cf24c07362f441 /drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
parentf8c52711530b8d99d9612f26b4d0648e62589c8a (diff)
downloadlinux-stable-7b182b8d9c852343fb34923a2d1b4e61421b37c7.tar.gz
linux-stable-7b182b8d9c852343fb34923a2d1b4e61421b37c7.tar.bz2
linux-stable-7b182b8d9c852343fb34923a2d1b4e61421b37c7.zip
media: mediatek: vcodec: Refactor get and put capture buffer flow
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 <yunfei.dong@mediatek.com> Tested-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c')
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c88
1 files changed, 63 insertions, 25 deletions
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
index 4df7b158ec5e..c61df1f51185 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_framesizes[] = {
#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-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 =
- container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
- struct vdec_fb *pfb = &framebuf->frame_buffer;
- struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+ struct vb2_v4l2_buffer *vb2_dst;
+ enum vb2_buffer_state state;
- pfb->base_y.va = NULL;
+ if (error)
+ state = VB2_BUF_STATE_ERROR;
+ else
+ state = VB2_BUF_STATE_DONE;
+
+ vb2_dst = 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 = 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 = &vb2_v4l2->vb2_buf;
+ framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+
+ pfb = &framebuf->frame_buffer;
+ pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
- pfb->base_c.va = NULL;
+ pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
pfb->base_c.dma_addr =
vb2_dma_contig_plane_dma_addr(dst_buf, 1);
pfb->base_c.size = 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 =
container_of(work, struct mtk_vcodec_ctx, decode_work);
struct mtk_vcodec_dev *dev = 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 = false;
int ret;
@@ -161,13 +191,6 @@ static void mtk_vdec_worker(struct work_struct *work)
return;
}
- vb2_v4l2_dst = 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 = &vb2_v4l2_src->vb2_buf;
dec_buf_src = 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=%d, vb=%p", ctx->id,
vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
- bs_src->va = NULL;
+ bs_src->va = vb2_plane_vaddr(vb2_src, 0);
bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
bs_src->size = (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=%d source buffer is NULL", ctx->id,
+ vb2_src->index);
+ return;
+ }
mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%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");
- dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
- v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
- ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+ ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
if (ret) {
mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
ctx->id, vb2_src->index, bs_src->size,
@@ -203,10 +230,17 @@ static void mtk_vdec_worker(struct work_struct *work)
}
}
- 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 = ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE;
+ if (!IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch) ||
+ ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME || ret) {
+ 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);
+ }
}
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 = {
.uses_stateless_api = true,
.worker = mtk_vdec_worker,
.flush_decoder = mtk_vdec_flush_decoder,
+ .cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+ .get_cap_buffer = vdec_get_cap_buffer,
.is_subdev_supported = false,
.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
};
@@ -354,6 +390,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
.uses_stateless_api = true,
.worker = mtk_vdec_worker,
.flush_decoder = mtk_vdec_flush_decoder,
+ .cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+ .get_cap_buffer = vdec_get_cap_buffer,
.is_subdev_supported = true,
.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
};