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: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
parent
80c7373a45
commit
2f5d0aef37
@ -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,
|
||||
};
|
||||
|
2207
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c
Normal file
2207
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user