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 \ ...@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
vdec/vdec_vp8_req_if.o \ vdec/vdec_vp8_req_if.o \
vdec/vdec_vp9_if.o \ vdec/vdec_vp9_if.o \
vdec/vdec_vp9_req_lat_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_if.o \
vdec/vdec_h264_req_common.o \ vdec/vdec_h264_req_common.o \
vdec/vdec_h264_req_multi_if.o \ vdec/vdec_h264_req_multi_if.o \
......
...@@ -159,11 +159,51 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = { ...@@ -159,11 +159,51 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
}, },
.codec_type = V4L2_PIX_FMT_HEVC_SLICE, .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) #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_out_format;
static struct mtk_video_fmt default_cap_format; static struct mtk_video_fmt default_cap_format;
...@@ -409,6 +449,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc, ...@@ -409,6 +449,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
case V4L2_PIX_FMT_VP8_FRAME: case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_VP9_FRAME: case V4L2_PIX_FMT_VP9_FRAME:
case V4L2_PIX_FMT_HEVC_SLICE: case V4L2_PIX_FMT_HEVC_SLICE:
case V4L2_PIX_FMT_AV1_FRAME:
mtk_video_formats[count_formats].fourcc = fourcc; mtk_video_formats[count_formats].fourcc = fourcc;
mtk_video_formats[count_formats].type = MTK_FMT_DEC; mtk_video_formats[count_formats].type = MTK_FMT_DEC;
mtk_video_formats[count_formats].num_planes = 1; mtk_video_formats[count_formats].num_planes = 1;
...@@ -469,6 +510,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx) ...@@ -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); mtk_vcodec_add_formats(V4L2_PIX_FMT_HEVC_SLICE, ctx);
out_format_count++; 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) if (cap_format_count)
default_cap_format = mtk_video_formats[cap_format_count - 1]; default_cap_format = mtk_video_formats[cap_format_count - 1];
......
...@@ -347,6 +347,7 @@ enum mtk_vdec_format_types { ...@@ -347,6 +347,7 @@ enum mtk_vdec_format_types {
MTK_VDEC_FORMAT_H264_SLICE = 0x100, MTK_VDEC_FORMAT_H264_SLICE = 0x100,
MTK_VDEC_FORMAT_VP8_FRAME = 0x200, MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
MTK_VDEC_FORMAT_VP9_FRAME = 0x400, MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
MTK_VDEC_FORMAT_AV1_FRAME = 0x800,
MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000, MTK_VDEC_FORMAT_HEVC_FRAME = 0x1000,
MTK_VCODEC_INNER_RACING = 0x20000, MTK_VCODEC_INNER_RACING = 0x20000,
}; };
......
...@@ -53,6 +53,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) ...@@ -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->dec_if = &vdec_hevc_slice_multi_if;
ctx->hw_id = MTK_VDEC_LAT0; ctx->hw_id = MTK_VDEC_LAT0;
break; break;
case V4L2_PIX_FMT_AV1_FRAME:
ctx->dec_if = &vdec_av1_slice_lat_if;
ctx->hw_id = MTK_VDEC_LAT0;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -62,6 +62,7 @@ extern const struct vdec_common_if vdec_vp8_slice_if; ...@@ -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_if;
extern const struct vdec_common_if vdec_vp9_slice_lat_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_hevc_slice_multi_if;
extern const struct vdec_common_if vdec_av1_slice_lat_if;
/** /**
* vdec_if_init() - initialize decode driver * vdec_if_init() - initialize decode driver
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
/* the size used to store avc error information */ /* the size used to store avc error information */
#define VDEC_ERR_MAP_SZ_AVC (17 * SZ_1K) #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. /* core will read the trans buffer which decoded by lat to decode again.
* The trans buffer size of FHD and 4K bitstreams are different. * 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, ...@@ -219,6 +222,14 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
if (mem->va) if (mem->va)
mtk_vcodec_mem_free(ctx, mem); 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); kfree(lat_buf->private_data);
} }
...@@ -321,6 +332,22 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, ...@@ -321,6 +332,22 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
goto mem_alloc_err; 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); lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
if (!lat_buf->private_data) { if (!lat_buf->private_data) {
err = -ENOMEM; err = -ENOMEM;
......
...@@ -54,6 +54,8 @@ struct vdec_msg_queue_ctx { ...@@ -54,6 +54,8 @@ struct vdec_msg_queue_ctx {
* struct vdec_lat_buf - lat buffer message used to store lat info for core decode * 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 * @wdma_err_addr: wdma error address used for lat hardware
* @slice_bc_addr: slice bc 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 * @ts_info: need to set timestamp from output to capture
* @src_buf_req: output buffer media request object * @src_buf_req: output buffer media request object
* *
...@@ -68,6 +70,8 @@ struct vdec_msg_queue_ctx { ...@@ -68,6 +70,8 @@ struct vdec_msg_queue_ctx {
struct vdec_lat_buf { struct vdec_lat_buf {
struct mtk_vcodec_mem wdma_err_addr; struct mtk_vcodec_mem wdma_err_addr;
struct mtk_vcodec_mem slice_bc_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 vb2_v4l2_buffer ts_info;
struct media_request *src_buf_req; 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