Commit 2f5d0aef authored by Xiaoyong Lu's avatar Xiaoyong Lu Committed by Mauro Carvalho Chehab

media: mediatek: vcodec: support stateless AV1 decoder

Add mediatek av1 decoder linux driver which use the stateless API in
MT8195.

Signed-off-by: Xiaoyong Lu<xiaoyong.lu@mediatek.com>
Tested-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: default avatarNicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 80c7373a
......@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
vdec/vdec_vp8_req_if.o \
vdec/vdec_vp9_if.o \
vdec/vdec_vp9_req_lat_if.o \
vdec/vdec_av1_req_lat_if.o \
vdec/vdec_h264_req_if.o \
vdec/vdec_h264_req_common.o \
vdec/vdec_h264_req_multi_if.o \
......
......@@ -159,11 +159,51 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
},
.codec_type = V4L2_PIX_FMT_HEVC_SLICE,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_AV1_SEQUENCE,
},
.codec_type = V4L2_PIX_FMT_AV1_FRAME,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_AV1_FRAME,
},
.codec_type = V4L2_PIX_FMT_AV1_FRAME,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY,
.dims = { V4L2_AV1_MAX_TILE_COUNT },
},
.codec_type = V4L2_PIX_FMT_AV1_FRAME,
},
{
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_AV1_PROFILE,
.min = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN,
.def = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN,
.max = V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN,
},
.codec_type = V4L2_PIX_FMT_AV1_FRAME,
},
{
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_AV1_LEVEL,
.min = V4L2_MPEG_VIDEO_AV1_LEVEL_2_0,
.def = V4L2_MPEG_VIDEO_AV1_LEVEL_4_0,
.max = V4L2_MPEG_VIDEO_AV1_LEVEL_5_1,
},
.codec_type = V4L2_PIX_FMT_AV1_FRAME,
},
};
#define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
static struct mtk_video_fmt mtk_video_formats[6];
static struct mtk_video_fmt mtk_video_formats[7];
static struct mtk_video_fmt default_out_format;
static struct mtk_video_fmt default_cap_format;
......@@ -409,6 +449,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_VP9_FRAME:
case V4L2_PIX_FMT_HEVC_SLICE:
case V4L2_PIX_FMT_AV1_FRAME:
mtk_video_formats[count_formats].fourcc = fourcc;
mtk_video_formats[count_formats].type = MTK_FMT_DEC;
mtk_video_formats[count_formats].num_planes = 1;
......@@ -469,6 +510,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
mtk_vcodec_add_formats(V4L2_PIX_FMT_HEVC_SLICE, ctx);
out_format_count++;
}
if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_AV1_FRAME) {
mtk_vcodec_add_formats(V4L2_PIX_FMT_AV1_FRAME, ctx);
out_format_count++;
}
if (cap_format_count)
default_cap_format = mtk_video_formats[cap_format_count - 1];
......
......@@ -347,6 +347,7 @@ enum mtk_vdec_format_types {
MTK_VDEC_FORMAT_H264_SLICE = 0x100,
MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
MTK_VDEC_FORMAT_AV1_FRAME = 0x800,
MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000,
MTK_VCODEC_INNER_RACING = 0x20000,
};
......
......@@ -53,6 +53,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
ctx->dec_if = &vdec_hevc_slice_multi_if;
ctx->hw_id = MTK_VDEC_LAT0;
break;
case V4L2_PIX_FMT_AV1_FRAME:
ctx->dec_if = &vdec_av1_slice_lat_if;
ctx->hw_id = MTK_VDEC_LAT0;
break;
default:
return -EINVAL;
}
......
......@@ -62,6 +62,7 @@ extern const struct vdec_common_if vdec_vp8_slice_if;
extern const struct vdec_common_if vdec_vp9_if;
extern const struct vdec_common_if vdec_vp9_slice_lat_if;
extern const struct vdec_common_if vdec_hevc_slice_multi_if;
extern const struct vdec_common_if vdec_av1_slice_lat_if;
/**
* vdec_if_init() - initialize decode driver
......
......@@ -20,6 +20,9 @@
/* the size used to store avc error information */
#define VDEC_ERR_MAP_SZ_AVC (17 * SZ_1K)
#define VDEC_RD_MV_BUFFER_SZ (((SZ_4K * 2304 >> 4) + SZ_1K) << 1)
#define VDEC_LAT_TILE_SZ (64 * V4L2_AV1_MAX_TILE_COUNT)
/* core will read the trans buffer which decoded by lat to decode again.
* The trans buffer size of FHD and 4K bitstreams are different.
*/
......@@ -219,6 +222,14 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
if (mem->va)
mtk_vcodec_mem_free(ctx, mem);
mem = &lat_buf->rd_mv_addr;
if (mem->va)
mtk_vcodec_mem_free(ctx, mem);
mem = &lat_buf->tile_addr;
if (mem->va)
mtk_vcodec_mem_free(ctx, mem);
kfree(lat_buf->private_data);
}
......@@ -321,6 +332,22 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
goto mem_alloc_err;
}
if (ctx->current_codec == V4L2_PIX_FMT_AV1_FRAME) {
lat_buf->rd_mv_addr.size = VDEC_RD_MV_BUFFER_SZ;
err = mtk_vcodec_mem_alloc(ctx, &lat_buf->rd_mv_addr);
if (err) {
mtk_v4l2_err("failed to allocate rd_mv_addr buf[%d]", i);
return -ENOMEM;
}
lat_buf->tile_addr.size = VDEC_LAT_TILE_SZ;
err = mtk_vcodec_mem_alloc(ctx, &lat_buf->tile_addr);
if (err) {
mtk_v4l2_err("failed to allocate tile_addr buf[%d]", i);
return -ENOMEM;
}
}
lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
if (!lat_buf->private_data) {
err = -ENOMEM;
......
......@@ -54,6 +54,8 @@ struct vdec_msg_queue_ctx {
* struct vdec_lat_buf - lat buffer message used to store lat info for core decode
* @wdma_err_addr: wdma error address used for lat hardware
* @slice_bc_addr: slice bc address used for lat hardware
* @rd_mv_addr: mv addr for av1 lat hardware output, core hardware input
* @tile_addr: tile buffer for av1 core input
* @ts_info: need to set timestamp from output to capture
* @src_buf_req: output buffer media request object
*
......@@ -68,6 +70,8 @@ struct vdec_msg_queue_ctx {
struct vdec_lat_buf {
struct mtk_vcodec_mem wdma_err_addr;
struct mtk_vcodec_mem slice_bc_addr;
struct mtk_vcodec_mem rd_mv_addr;
struct mtk_vcodec_mem tile_addr;
struct vb2_v4l2_buffer ts_info;
struct media_request *src_buf_req;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment