Adjust capture format to the Exynos4x12 device limitations, according to the subsampling value parsed from the source JPEG image header. If the capture format was set to YUV with subsampling lower than the one of the source JPEG image the decoding process would not succeed. Signed-off-by: Jacek Anaszewski <j.anaszewski@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 78 +++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index e09b03a..15b2dea 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -941,6 +941,7 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); + struct v4l2_pix_format *pix = &f->fmt.pix; struct s5p_jpeg_fmt *fmt; fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat, @@ -952,6 +953,83 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; } + /* + * The exynos4x12 device requires resulting YUV image + * subsampling not to be lower than the input jpeg subsampling. + * If this requirement is not met then downgrade the requested + * output format to the one with subsampling equal to the input jpeg. + */ + if ((ctx->jpeg->variant->version != SJPEG_S5P) && + (ctx->mode == S5P_JPEG_DECODE) && + (fmt->flags & SJPEG_FMT_NON_RGB) && + (fmt->subsampling < ctx->subsampling)) { + switch (fmt->fourcc) { + case V4L2_PIX_FMT_NV24: + switch (ctx->subsampling) { + case V4L2_JPEG_CHROMA_SUBSAMPLING_422: + pix->pixelformat = V4L2_PIX_FMT_NV16; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_420: + pix->pixelformat = V4L2_PIX_FMT_NV12; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: + pix->pixelformat = V4L2_PIX_FMT_GREY; + break; + default: + return -EINVAL; + } + break; + case V4L2_PIX_FMT_NV42: + switch (ctx->subsampling) { + case V4L2_JPEG_CHROMA_SUBSAMPLING_422: + pix->pixelformat = V4L2_PIX_FMT_NV61; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_420: + pix->pixelformat = V4L2_PIX_FMT_NV21; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: + pix->pixelformat = V4L2_PIX_FMT_GREY; + break; + default: + return -EINVAL; + } + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_YUV420: + switch (ctx->subsampling) { + case V4L2_JPEG_CHROMA_SUBSAMPLING_420: + pix->pixelformat = V4L2_PIX_FMT_NV12; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: + pix->pixelformat = V4L2_PIX_FMT_GREY; + break; + default: + return -EINVAL; + } + break; + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_NV61: + switch (ctx->subsampling) { + case V4L2_JPEG_CHROMA_SUBSAMPLING_420: + pix->pixelformat = V4L2_PIX_FMT_NV21; + break; + case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: + pix->pixelformat = V4L2_PIX_FMT_GREY; + break; + default: + return -EINVAL; + } + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + pix->pixelformat = V4L2_PIX_FMT_GREY; + break; + default: + return -EINVAL; + } + } + return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html