Commit e7a1494a authored by Ming Qian's avatar Ming Qian Committed by Mauro Carvalho Chehab

media: imx-jpeg: Decoder add support for 12bit jpeg

enable decoding 12-bit extended jpeg
Signed-off-by: default avatarMing Qian <ming.qian@nxp.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent a14e14ba
...@@ -87,6 +87,20 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -87,6 +87,20 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.precision = 8, .precision = 8,
.is_rgb = 1, .is_rgb = 1,
}, },
{
.name = "BGR 12bit", /*12-bit BGR packed format*/
.fourcc = V4L2_PIX_FMT_BGR48_12,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
.nc = 3,
.depth = 36,
.mem_planes = 1,
.comp_planes = 1,
.h_align = 3,
.v_align = 3,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
.is_rgb = 1,
},
{ {
.name = "ABGR", /* ABGR packed format */ .name = "ABGR", /* ABGR packed format */
.fourcc = V4L2_PIX_FMT_ABGR32, .fourcc = V4L2_PIX_FMT_ABGR32,
...@@ -101,6 +115,20 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -101,6 +115,20 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.precision = 8, .precision = 8,
.is_rgb = 1, .is_rgb = 1,
}, },
{
.name = "ABGR 12bit", /* 12-bit ABGR packed format */
.fourcc = V4L2_PIX_FMT_ABGR64_12,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
.nc = 4,
.depth = 48,
.mem_planes = 1,
.comp_planes = 1,
.h_align = 3,
.v_align = 3,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
.is_rgb = 1,
},
{ {
.name = "YUV420", /* 1st plane = Y, 2nd plane = UV */ .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
.fourcc = V4L2_PIX_FMT_NV12M, .fourcc = V4L2_PIX_FMT_NV12M,
...@@ -127,6 +155,32 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -127,6 +155,32 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.flags = MXC_JPEG_FMT_TYPE_RAW, .flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 8, .precision = 8,
}, },
{
.name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */
.fourcc = V4L2_PIX_FMT_P012M,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
.nc = 3,
.depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */
.mem_planes = 2,
.comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
.h_align = 4,
.v_align = 4,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
},
{
.name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */
.fourcc = V4L2_PIX_FMT_P012,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
.nc = 3,
.depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */
.mem_planes = 1,
.comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
.h_align = 4,
.v_align = 4,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
},
{ {
.name = "YUV422", /* YUYV */ .name = "YUV422", /* YUYV */
.fourcc = V4L2_PIX_FMT_YUYV, .fourcc = V4L2_PIX_FMT_YUYV,
...@@ -140,6 +194,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -140,6 +194,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.flags = MXC_JPEG_FMT_TYPE_RAW, .flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 8, .precision = 8,
}, },
{
.name = "YUV422 12bit", /* YUYV */
.fourcc = V4L2_PIX_FMT_Y212,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
.nc = 3,
.depth = 24,
.mem_planes = 1,
.comp_planes = 1,
.h_align = 4,
.v_align = 3,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
},
{ {
.name = "YUV444", /* YUVYUV */ .name = "YUV444", /* YUVYUV */
.fourcc = V4L2_PIX_FMT_YUV24, .fourcc = V4L2_PIX_FMT_YUV24,
...@@ -153,6 +220,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -153,6 +220,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.flags = MXC_JPEG_FMT_TYPE_RAW, .flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 8, .precision = 8,
}, },
{
.name = "YUV444 12bit", /* YUVYUV */
.fourcc = V4L2_PIX_FMT_YUV48_12,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
.nc = 3,
.depth = 36,
.mem_planes = 1,
.comp_planes = 1,
.h_align = 3,
.v_align = 3,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
},
{ {
.name = "Gray", /* Gray (Y8/Y12) or Single Comp */ .name = "Gray", /* Gray (Y8/Y12) or Single Comp */
.fourcc = V4L2_PIX_FMT_GREY, .fourcc = V4L2_PIX_FMT_GREY,
...@@ -166,6 +246,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = { ...@@ -166,6 +246,19 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
.flags = MXC_JPEG_FMT_TYPE_RAW, .flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 8, .precision = 8,
}, },
{
.name = "Gray 12bit", /* Gray (Y8/Y12) or Single Comp */
.fourcc = V4L2_PIX_FMT_Y012,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
.nc = 1,
.depth = 12,
.mem_planes = 1,
.comp_planes = 1,
.h_align = 3,
.v_align = 3,
.flags = MXC_JPEG_FMT_TYPE_RAW,
.precision = 12,
},
}; };
#define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats) #define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats)
...@@ -437,17 +530,24 @@ static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc) ...@@ -437,17 +530,24 @@ static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)
{ {
switch (fourcc) { switch (fourcc) {
case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y012:
return MXC_JPEG_GRAY; return MXC_JPEG_GRAY;
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_Y212:
return MXC_JPEG_YUV422; return MXC_JPEG_YUV422;
case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_P012:
case V4L2_PIX_FMT_P012M:
return MXC_JPEG_YUV420; return MXC_JPEG_YUV420;
case V4L2_PIX_FMT_YUV24: case V4L2_PIX_FMT_YUV24:
case V4L2_PIX_FMT_YUV48_12:
return MXC_JPEG_YUV444; return MXC_JPEG_YUV444;
case V4L2_PIX_FMT_BGR24: case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_BGR48_12:
return MXC_JPEG_BGR; return MXC_JPEG_BGR;
case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_ABGR32:
case V4L2_PIX_FMT_ABGR64_12:
return MXC_JPEG_ABGR; return MXC_JPEG_ABGR;
default: default:
return MXC_JPEG_INVALID; return MXC_JPEG_INVALID;
...@@ -483,6 +583,17 @@ static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, ...@@ -483,6 +583,17 @@ static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc,
offset; offset;
} }
static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt)
{
if (!fmt || !(fmt->flags & MXC_JPEG_FMT_TYPE_RAW))
return false;
if (fmt->precision > 8)
return true;
return false;
}
static void notify_eos(struct mxc_jpeg_ctx *ctx) static void notify_eos(struct mxc_jpeg_ctx *ctx)
{ {
const struct v4l2_event ev = { const struct v4l2_event ev = {
...@@ -771,24 +882,31 @@ static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof, ...@@ -771,24 +882,31 @@ static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
switch (fourcc) { switch (fourcc) {
case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_P012:
case V4L2_PIX_FMT_P012M:
sof->components_no = 3; sof->components_no = 3;
sof->comp[0].v = 0x2; sof->comp[0].v = 0x2;
sof->comp[0].h = 0x2; sof->comp[0].h = 0x2;
break; break;
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_Y212:
sof->components_no = 3; sof->components_no = 3;
sof->comp[0].v = 0x1; sof->comp[0].v = 0x1;
sof->comp[0].h = 0x2; sof->comp[0].h = 0x2;
break; break;
case V4L2_PIX_FMT_YUV24: case V4L2_PIX_FMT_YUV24:
case V4L2_PIX_FMT_YUV48_12:
case V4L2_PIX_FMT_BGR24: case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_BGR48_12:
default: default:
sof->components_no = 3; sof->components_no = 3;
break; break;
case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_ABGR32:
case V4L2_PIX_FMT_ABGR64_12:
sof->components_no = 4; sof->components_no = 4;
break; break;
case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y012:
sof->components_no = 1; sof->components_no = 1;
break; break;
} }
...@@ -808,20 +926,27 @@ static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos, ...@@ -808,20 +926,27 @@ static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
switch (fourcc) { switch (fourcc) {
case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_P012:
case V4L2_PIX_FMT_P012M:
sos->components_no = 3; sos->components_no = 3;
break; break;
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_Y212:
sos->components_no = 3; sos->components_no = 3;
break; break;
case V4L2_PIX_FMT_YUV24: case V4L2_PIX_FMT_YUV24:
case V4L2_PIX_FMT_YUV48_12:
case V4L2_PIX_FMT_BGR24: case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_BGR48_12:
default: default:
sos->components_no = 3; sos->components_no = 3;
break; break;
case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_ABGR32:
case V4L2_PIX_FMT_ABGR64_12:
sos->components_no = 4; sos->components_no = 4;
break; break;
case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y012:
sos->components_no = 1; sos->components_no = 1;
break; break;
} }
...@@ -851,12 +976,15 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr, ...@@ -851,12 +976,15 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
u8 *cfg = (u8 *)cfg_stream_vaddr; u8 *cfg = (u8 *)cfg_stream_vaddr;
struct mxc_jpeg_sof *sof; struct mxc_jpeg_sof *sof;
struct mxc_jpeg_sos *sos; struct mxc_jpeg_sos *sos;
const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc);
if (!fmt)
return 0;
memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi)); memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi));
offset += ARRAY_SIZE(jpeg_soi); offset += ARRAY_SIZE(jpeg_soi);
if (fourcc == V4L2_PIX_FMT_BGR24 || if (fmt->is_rgb) {
fourcc == V4L2_PIX_FMT_ABGR32) {
memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14)); memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14));
offset += sizeof(jpeg_app14); offset += sizeof(jpeg_app14);
} else { } else {
...@@ -922,6 +1050,10 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf, ...@@ -922,6 +1050,10 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */ desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */
desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt); desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1); desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt))
desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION;
else
desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION;
desc->line_pitch = q_data_cap->bytesperline[0]; desc->line_pitch = q_data_cap->bytesperline[0];
mxc_jpeg_addrs(desc, dst_buf, src_buf, 0); mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024)); mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024));
......
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