mirror of
https://github.com/torvalds/linux.git
synced 2026-05-21 05:18:45 +02:00
media: rkvdec: h264: Support High 10 and 4:2:2 profiles
Add support and enable decoding of H264 High 10 and 4:2:2 profiles. Decoded CAPTURE buffer width is aligned to 64 pixels to accommodate HW requirement of 10-bit format buffers, fixes decoding of all the 4:2:2 and 10bit 4:2:2 flusters tests except two stream that present some visual artifacts. - Hi422FREXT17_SONY_A - Hi422FREXT19_SONY_A The get_image_fmt() ops is implemented to select an image format required for the provided SPS control, and returns RKVDEC_IMG_FMT_ANY for other controls. Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Tested-by: Christopher Obbard <chris.obbard@collabora.com> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
parent
d35c64eccf
commit
5e1ff23147
|
|
@ -1027,24 +1027,42 @@ static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx,
|
||||
struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
|
||||
|
||||
if (ctrl->id != V4L2_CID_STATELESS_H264_SPS)
|
||||
return RKVDEC_IMG_FMT_ANY;
|
||||
|
||||
if (sps->bit_depth_luma_minus8 == 0) {
|
||||
if (sps->chroma_format_idc == 2)
|
||||
return RKVDEC_IMG_FMT_422_8BIT;
|
||||
else
|
||||
return RKVDEC_IMG_FMT_420_8BIT;
|
||||
} else if (sps->bit_depth_luma_minus8 == 2) {
|
||||
if (sps->chroma_format_idc == 2)
|
||||
return RKVDEC_IMG_FMT_422_10BIT;
|
||||
else
|
||||
return RKVDEC_IMG_FMT_420_10BIT;
|
||||
}
|
||||
|
||||
return RKVDEC_IMG_FMT_ANY;
|
||||
}
|
||||
|
||||
static int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx,
|
||||
const struct v4l2_ctrl_h264_sps *sps)
|
||||
{
|
||||
unsigned int width, height;
|
||||
|
||||
/*
|
||||
* TODO: The hardware supports 10-bit and 4:2:2 profiles,
|
||||
* but it's currently broken in the driver.
|
||||
* Reject them for now, until it's fixed.
|
||||
*/
|
||||
if (sps->chroma_format_idc > 1)
|
||||
/* Only 4:0:0 and 4:2:0 are supported */
|
||||
if (sps->chroma_format_idc > 2)
|
||||
/* Only 4:0:0, 4:2:0 and 4:2:2 are supported */
|
||||
return -EINVAL;
|
||||
if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
|
||||
/* Luma and chroma bit depth mismatch */
|
||||
return -EINVAL;
|
||||
if (sps->bit_depth_luma_minus8 != 0)
|
||||
/* Only 8-bit is supported */
|
||||
if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
|
||||
/* Only 8-bit and 10-bit is supported */
|
||||
return -EINVAL;
|
||||
|
||||
width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
|
||||
|
|
@ -1190,4 +1208,5 @@ const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = {
|
|||
.stop = rkvdec_h264_stop,
|
||||
.run = rkvdec_h264_run,
|
||||
.try_ctrl = rkvdec_h264_try_ctrl,
|
||||
.get_image_fmt = rkvdec_h264_get_image_fmt,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -186,9 +186,10 @@ static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = {
|
|||
{
|
||||
.cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
|
||||
.cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE,
|
||||
.cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
|
||||
.cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA,
|
||||
.cfg.menu_skip_mask =
|
||||
BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
|
||||
BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
|
||||
BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE),
|
||||
.cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
|
||||
},
|
||||
{
|
||||
|
|
@ -203,11 +204,23 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
|
|||
.num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
|
||||
};
|
||||
|
||||
static const struct rkvdec_decoded_fmt_desc rkvdec_h264_vp9_decoded_fmts[] = {
|
||||
static const struct rkvdec_decoded_fmt_desc rkvdec_h264_decoded_fmts[] = {
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_NV12,
|
||||
.image_fmt = RKVDEC_IMG_FMT_420_8BIT,
|
||||
},
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_NV15,
|
||||
.image_fmt = RKVDEC_IMG_FMT_420_10BIT,
|
||||
},
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_NV16,
|
||||
.image_fmt = RKVDEC_IMG_FMT_422_8BIT,
|
||||
},
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_NV20,
|
||||
.image_fmt = RKVDEC_IMG_FMT_422_10BIT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
|
||||
|
|
@ -230,21 +243,28 @@ static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
|
|||
.num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
|
||||
};
|
||||
|
||||
static const struct rkvdec_decoded_fmt_desc rkvdec_vp9_decoded_fmts[] = {
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_NV12,
|
||||
.image_fmt = RKVDEC_IMG_FMT_420_8BIT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_H264_SLICE,
|
||||
.frmsize = {
|
||||
.min_width = 48,
|
||||
.min_width = 64,
|
||||
.max_width = 4096,
|
||||
.step_width = 16,
|
||||
.step_width = 64,
|
||||
.min_height = 48,
|
||||
.max_height = 2560,
|
||||
.step_height = 16,
|
||||
},
|
||||
.ctrls = &rkvdec_h264_ctrls,
|
||||
.ops = &rkvdec_h264_fmt_ops,
|
||||
.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
|
||||
.decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
|
||||
.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
|
||||
.decoded_fmts = rkvdec_h264_decoded_fmts,
|
||||
.subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
|
||||
},
|
||||
{
|
||||
|
|
@ -259,8 +279,8 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
|
|||
},
|
||||
.ctrls = &rkvdec_vp9_ctrls,
|
||||
.ops = &rkvdec_vp9_fmt_ops,
|
||||
.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
|
||||
.decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
|
||||
.num_decoded_fmts = ARRAY_SIZE(rkvdec_vp9_decoded_fmts),
|
||||
.decoded_fmts = rkvdec_vp9_decoded_fmts,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ struct rkvdec_coded_fmt_ops {
|
|||
enum rkvdec_image_fmt {
|
||||
RKVDEC_IMG_FMT_ANY = 0,
|
||||
RKVDEC_IMG_FMT_420_8BIT,
|
||||
RKVDEC_IMG_FMT_420_10BIT,
|
||||
RKVDEC_IMG_FMT_422_8BIT,
|
||||
RKVDEC_IMG_FMT_422_10BIT,
|
||||
};
|
||||
|
||||
struct rkvdec_decoded_fmt_desc {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user