Commit 19c2813c authored by John Sheu's avatar John Sheu Committed by Mauro Carvalho Chehab

[media] s5p-mfc: Fix input/output format reporting

The video encode/decode paths have duplicated logic between
VIDIOC_TRY_FMT and VIDIOC_S_FMT that should be de-duped.  Also, video
decode reports V4L2_PIX_FMT_NV12MT_16X16 output format, regardless of
what the actual output has been set at.  Fix this.
Signed-off-by: default avatarJohn Sheu <sheu@google.com>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
Cc: stable@vger.kernel.org
parent 26a20eb0
...@@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
pix_mp->num_planes = 2; pix_mp->num_planes = 2;
/* Set pixelformat to the format in which MFC /* Set pixelformat to the format in which MFC
outputs the decoded frame */ outputs the decoded frame */
pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT; pix_mp->pixelformat = ctx->dst_fmt->fourcc;
pix_mp->plane_fmt[0].bytesperline = ctx->buf_width; pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
pix_mp->plane_fmt[0].sizeimage = ctx->luma_size; pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
pix_mp->plane_fmt[1].bytesperline = ctx->buf_width; pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
...@@ -382,10 +382,20 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -382,10 +382,20 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
mfc_err("Unsupported format for source.\n"); mfc_err("Unsupported format for source.\n");
return -EINVAL; return -EINVAL;
} }
if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
mfc_err("Unknown codec\n");
return -EINVAL;
}
if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
mfc_err("Not supported format.\n"); mfc_err("Not supported format.\n");
return -EINVAL; return -EINVAL;
} }
if (!IS_MFCV6_PLUS(dev)) {
if (fmt->fourcc == V4L2_PIX_FMT_VP8) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
}
} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
fmt = find_format(f, MFC_FMT_RAW); fmt = find_format(f, MFC_FMT_RAW);
if (!fmt) { if (!fmt) {
...@@ -412,7 +422,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -412,7 +422,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct s5p_mfc_dev *dev = video_drvdata(file); struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret = 0; int ret = 0;
struct s5p_mfc_fmt *fmt;
struct v4l2_pix_format_mplane *pix_mp; struct v4l2_pix_format_mplane *pix_mp;
mfc_debug_enter(); mfc_debug_enter();
...@@ -426,45 +435,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -426,45 +435,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
goto out; goto out;
} }
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
fmt = find_format(f, MFC_FMT_RAW); /* dst_fmt is validated by call to vidioc_try_fmt */
if (!fmt) { ctx->dst_fmt = find_format(f, MFC_FMT_RAW);
mfc_err("Unsupported format for source.\n"); ret = 0;
return -EINVAL;
}
if (!IS_MFCV6_PLUS(dev) &&
(fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
mfc_err("Not supported format.\n");
return -EINVAL;
} else if (IS_MFCV6_PLUS(dev) &&
(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
ctx->dst_fmt = fmt;
mfc_debug_leave();
return ret;
} else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
mfc_err("Wrong type error for S_FMT : %d", f->type);
return -EINVAL;
}
fmt = find_format(f, MFC_FMT_DEC);
if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
mfc_err("Unknown codec\n");
ret = -EINVAL;
goto out; goto out;
} } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
if (fmt->type != MFC_FMT_DEC) { /* src_fmt is validated by call to vidioc_try_fmt */
mfc_err("Wrong format selected, you should choose " ctx->src_fmt = find_format(f, MFC_FMT_DEC);
"format for decoding\n"); ctx->codec_mode = ctx->src_fmt->codec_mode;
ret = -EINVAL;
goto out;
}
if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
ctx->src_fmt = fmt;
ctx->codec_mode = fmt->codec_mode;
mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
pix_mp->height = 0; pix_mp->height = 0;
pix_mp->width = 0; pix_mp->width = 0;
...@@ -475,6 +453,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -475,6 +453,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
DEF_CPB_SIZE; DEF_CPB_SIZE;
pix_mp->plane_fmt[0].bytesperline = 0; pix_mp->plane_fmt[0].bytesperline = 0;
ctx->state = MFCINST_INIT; ctx->state = MFCINST_INIT;
ret = 0;
goto out;
} else {
mfc_err("Wrong type error for S_FMT : %d", f->type);
ret = -EINVAL;
goto out;
}
out: out:
mfc_debug_leave(); mfc_debug_leave();
return ret; return ret;
......
...@@ -967,6 +967,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -967,6 +967,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{ {
struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_fmt *fmt; struct s5p_mfc_fmt *fmt;
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
...@@ -977,6 +978,11 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -977,6 +978,11 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
return -EINVAL; return -EINVAL;
} }
if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
mfc_err("VP8 is supported only in MFC v7\n");
return -EINVAL;
}
if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
mfc_err("must be set encoding output size\n"); mfc_err("must be set encoding output size\n");
return -EINVAL; return -EINVAL;
...@@ -991,6 +997,18 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -991,6 +997,18 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
return -EINVAL; return -EINVAL;
} }
if (!IS_MFCV6_PLUS(dev)) {
if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
} else if (IS_MFCV6_PLUS(dev)) {
if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
}
if (fmt->num_planes != pix_fmt_mp->num_planes) { if (fmt->num_planes != pix_fmt_mp->num_planes) {
mfc_err("failed to try output format\n"); mfc_err("failed to try output format\n");
return -EINVAL; return -EINVAL;
...@@ -1008,7 +1026,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -1008,7 +1026,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{ {
struct s5p_mfc_dev *dev = video_drvdata(file); struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
struct s5p_mfc_fmt *fmt;
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
int ret = 0; int ret = 0;
...@@ -1021,17 +1038,9 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -1021,17 +1038,9 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
goto out; goto out;
} }
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
fmt = find_format(f, MFC_FMT_ENC); /* dst_fmt is validated by call to vidioc_try_fmt */
if (!fmt) { ctx->dst_fmt = find_format(f, MFC_FMT_ENC);
mfc_err("failed to set capture format\n");
return -EINVAL;
}
if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
mfc_err("VP8 is supported only in MFC v7\n");
return -EINVAL;
}
ctx->state = MFCINST_INIT; ctx->state = MFCINST_INIT;
ctx->dst_fmt = fmt;
ctx->codec_mode = ctx->dst_fmt->codec_mode; ctx->codec_mode = ctx->dst_fmt->codec_mode;
ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
pix_fmt_mp->plane_fmt[0].bytesperline = 0; pix_fmt_mp->plane_fmt[0].bytesperline = 0;
...@@ -1052,28 +1061,8 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -1052,28 +1061,8 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
} }
mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
fmt = find_format(f, MFC_FMT_RAW); /* src_fmt is validated by call to vidioc_try_fmt */
if (!fmt) { ctx->src_fmt = find_format(f, MFC_FMT_RAW);
mfc_err("failed to set output format\n");
return -EINVAL;
}
if (!IS_MFCV6_PLUS(dev) &&
(fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
mfc_err("Not supported format.\n");
return -EINVAL;
} else if (IS_MFCV6_PLUS(dev) &&
(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
mfc_err("Not supported format.\n");
return -EINVAL;
}
if (fmt->num_planes != pix_fmt_mp->num_planes) {
mfc_err("failed to set output format\n");
ret = -EINVAL;
goto out;
}
ctx->src_fmt = fmt;
ctx->img_width = pix_fmt_mp->width; ctx->img_width = pix_fmt_mp->width;
ctx->img_height = pix_fmt_mp->height; ctx->img_height = pix_fmt_mp->height;
mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);
......
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