mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
media: rkvdec: Implement capability filtering
Add filtering of coded formats and controls depending on a variant capabilities. Signed-off-by: Alex Bee <knaerzche@gmail.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Tested-by: Diederik de Haas <didi.debian@cknow.org> # Rock64, RockPro64, Quartz64-B, NanoPi R5S Tested-by: Detlev Casanova <detlev.casanova@collabora.com> # RK3399 Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
parent
603bf462ad
commit
b26d95f9c6
|
|
@ -365,13 +365,36 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static bool rkvdec_is_capable(struct rkvdec_ctx *ctx, unsigned int capability)
|
||||
{
|
||||
return (ctx->dev->variant->capabilities & capability) == capability;
|
||||
}
|
||||
|
||||
static const struct rkvdec_coded_fmt_desc *
|
||||
rkvdec_find_coded_fmt_desc(u32 fourcc)
|
||||
rkvdec_enum_coded_fmt_desc(struct rkvdec_ctx *ctx, int index)
|
||||
{
|
||||
int fmt_idx = -1;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
|
||||
if (!rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability))
|
||||
continue;
|
||||
fmt_idx++;
|
||||
if (index == fmt_idx)
|
||||
return &rkvdec_coded_fmts[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct rkvdec_coded_fmt_desc *
|
||||
rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
|
||||
if (rkvdec_coded_fmts[i].fourcc == fourcc)
|
||||
if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability) &&
|
||||
rkvdec_coded_fmts[i].fourcc == fourcc)
|
||||
return &rkvdec_coded_fmts[i];
|
||||
}
|
||||
|
||||
|
|
@ -382,7 +405,7 @@ static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
|
|||
{
|
||||
struct v4l2_format *f = &ctx->coded_fmt;
|
||||
|
||||
ctx->coded_fmt_desc = &rkvdec_coded_fmts[0];
|
||||
ctx->coded_fmt_desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
|
||||
rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc);
|
||||
|
||||
f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
|
|
@ -396,21 +419,22 @@ static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
|
|||
static int rkvdec_enum_framesizes(struct file *file, void *priv,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
const struct rkvdec_coded_fmt_desc *fmt;
|
||||
struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
|
||||
const struct rkvdec_coded_fmt_desc *desc;
|
||||
|
||||
if (fsize->index != 0)
|
||||
return -EINVAL;
|
||||
|
||||
fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format);
|
||||
if (!fmt)
|
||||
desc = rkvdec_find_coded_fmt_desc(ctx, fsize->pixel_format);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
|
||||
fsize->stepwise.min_width = 1;
|
||||
fsize->stepwise.max_width = fmt->frmsize.max_width;
|
||||
fsize->stepwise.max_width = desc->frmsize.max_width;
|
||||
fsize->stepwise.step_width = 1;
|
||||
fsize->stepwise.min_height = 1;
|
||||
fsize->stepwise.max_height = fmt->frmsize.max_height;
|
||||
fsize->stepwise.max_height = desc->frmsize.max_height;
|
||||
fsize->stepwise.step_height = 1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -470,10 +494,10 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
|
|||
struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
|
||||
const struct rkvdec_coded_fmt_desc *desc;
|
||||
|
||||
desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat);
|
||||
desc = rkvdec_find_coded_fmt_desc(ctx, pix_mp->pixelformat);
|
||||
if (!desc) {
|
||||
pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc;
|
||||
desc = &rkvdec_coded_fmts[0];
|
||||
desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
|
||||
pix_mp->pixelformat = desc->fourcc;
|
||||
}
|
||||
|
||||
v4l2_apply_frmsize_constraints(&pix_mp->width,
|
||||
|
|
@ -550,7 +574,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat);
|
||||
desc = rkvdec_find_coded_fmt_desc(ctx, f->fmt.pix_mp.pixelformat);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
ctx->coded_fmt_desc = desc;
|
||||
|
|
@ -602,10 +626,14 @@ static int rkvdec_g_capture_fmt(struct file *file, void *priv,
|
|||
static int rkvdec_enum_output_fmt(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts))
|
||||
struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
|
||||
const struct rkvdec_coded_fmt_desc *desc;
|
||||
|
||||
desc = rkvdec_enum_coded_fmt_desc(ctx, f->index);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
f->pixelformat = rkvdec_coded_fmts[f->index].fourcc;
|
||||
f->pixelformat = desc->fourcc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -969,14 +997,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
|
|||
int ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
|
||||
nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
|
||||
if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability))
|
||||
nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
|
||||
|
||||
v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
|
||||
ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
|
||||
if (ret)
|
||||
goto err_free_handler;
|
||||
if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability)) {
|
||||
ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
|
||||
if (ret)
|
||||
goto err_free_handler;
|
||||
}
|
||||
}
|
||||
|
||||
ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user