summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/iris/iris_vdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/iris/iris_vdec.c')
-rw-r--r--drivers/media/platform/qcom/iris/iris_vdec.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index ae13c3e1b426..69ffe52590d3 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -67,7 +67,7 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
kfree(inst->fmt_src);
}
-static const struct iris_fmt iris_vdec_formats[] = {
+static const struct iris_fmt iris_vdec_formats_out[] = {
[IRIS_FMT_H264] = {
.pixfmt = V4L2_PIX_FMT_H264,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
@@ -82,12 +82,35 @@ static const struct iris_fmt iris_vdec_formats[] = {
},
};
+static const struct iris_fmt iris_vdec_formats_cap[] = {
+ [IRIS_FMT_NV12] = {
+ .pixfmt = V4L2_PIX_FMT_NV12,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ },
+ [IRIS_FMT_QC08C] = {
+ .pixfmt = V4L2_PIX_FMT_QC08C,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ },
+};
+
static const struct iris_fmt *
find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
{
- unsigned int size = ARRAY_SIZE(iris_vdec_formats);
- const struct iris_fmt *fmt = iris_vdec_formats;
+ const struct iris_fmt *fmt = NULL;
+ unsigned int size = 0;
unsigned int i;
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ fmt = iris_vdec_formats_out;
+ size = ARRAY_SIZE(iris_vdec_formats_out);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ fmt = iris_vdec_formats_cap;
+ size = ARRAY_SIZE(iris_vdec_formats_cap);
+ break;
+ default:
+ return NULL;
+ }
for (i = 0; i < size; i++) {
if (fmt[i].pixfmt == pixfmt)
@@ -103,8 +126,21 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
static const struct iris_fmt *
find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
{
- const struct iris_fmt *fmt = iris_vdec_formats;
- unsigned int size = ARRAY_SIZE(iris_vdec_formats);
+ const struct iris_fmt *fmt = NULL;
+ unsigned int size = 0;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ fmt = iris_vdec_formats_out;
+ size = ARRAY_SIZE(iris_vdec_formats_out);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ fmt = iris_vdec_formats_cap;
+ size = ARRAY_SIZE(iris_vdec_formats_cap);
+ break;
+ default:
+ return NULL;
+ }
if (index >= size || fmt[index].type != type)
return NULL;
@@ -126,9 +162,10 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (f->index)
+ fmt = find_format_by_index(inst, f->index, f->type);
+ if (!fmt)
return -EINVAL;
- f->pixelformat = V4L2_PIX_FMT_NV12;
+ f->pixelformat = fmt->pixfmt;
break;
default:
return -EINVAL;
@@ -157,7 +194,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
+ if (!fmt) {
f_inst = inst->fmt_dst;
f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
@@ -190,8 +227,6 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
u32 codec_align;
q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
- if (!q)
- return -EINVAL;
if (vb2_is_busy(q))
return -EBUSY;
@@ -238,10 +273,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
inst->crop.height = f->fmt.pix_mp.height;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
+ return -EINVAL;
+
fmt = inst->fmt_dst;
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12)
- return -EINVAL;
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
@@ -268,7 +304,8 @@ int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat)
{
const struct iris_fmt *fmt = NULL;
- if (pixelformat != V4L2_PIX_FMT_NV12) {
+ fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (!fmt) {
fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (!fmt)
return -EINVAL;