Commit 02aa769d authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] vivid: add support for 8-bit Bayer formats

Add support for: PIX_FMT_SBGGR8, SGBRG8, SGRBG8 and SRGGB8.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 87c674e2
...@@ -181,6 +181,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -181,6 +181,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->planes = 1; tpg->planes = 1;
tpg->buffers = 1; tpg->buffers = 1;
tpg->recalc_colors = true; tpg->recalc_colors = true;
tpg->interleaved = false;
tpg->vdownsampling[0] = 1; tpg->vdownsampling[0] = 1;
tpg->hdownsampling[0] = 1; tpg->hdownsampling[0] = 1;
tpg->hmask[0] = ~0; tpg->hmask[0] = ~0;
...@@ -188,6 +189,15 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -188,6 +189,15 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->hmask[2] = ~0; tpg->hmask[2] = ~0;
switch (fourcc) { switch (fourcc) {
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
tpg->interleaved = true;
tpg->vdownsampling[1] = 1;
tpg->hdownsampling[1] = 1;
tpg->planes = 2;
/* fall through */
case V4L2_PIX_FMT_RGB332: case V4L2_PIX_FMT_RGB332:
case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565:
case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_RGB565X:
...@@ -326,13 +336,14 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -326,13 +336,14 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV21:
case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV12M:
case V4L2_PIX_FMT_NV21M: case V4L2_PIX_FMT_NV21M:
tpg->twopixelsize[0] = 2;
tpg->twopixelsize[1] = 2;
break;
case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61: case V4L2_PIX_FMT_NV61:
case V4L2_PIX_FMT_NV16M: case V4L2_PIX_FMT_NV16M:
case V4L2_PIX_FMT_NV61M: case V4L2_PIX_FMT_NV61M:
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
tpg->twopixelsize[0] = 2; tpg->twopixelsize[0] = 2;
tpg->twopixelsize[1] = 2; tpg->twopixelsize[1] = 2;
break; break;
...@@ -1011,6 +1022,35 @@ static void gen_twopix(struct tpg_data *tpg, ...@@ -1011,6 +1022,35 @@ static void gen_twopix(struct tpg_data *tpg,
buf[0][offset + 2] = r_y; buf[0][offset + 2] = r_y;
buf[0][offset + 3] = alpha; buf[0][offset + 3] = alpha;
break; break;
case V4L2_PIX_FMT_SBGGR8:
buf[0][offset] = odd ? g_u : b_v;
buf[1][offset] = odd ? r_y : g_u;
break;
case V4L2_PIX_FMT_SGBRG8:
buf[0][offset] = odd ? b_v : g_u;
buf[1][offset] = odd ? g_u : r_y;
break;
case V4L2_PIX_FMT_SGRBG8:
buf[0][offset] = odd ? r_y : g_u;
buf[1][offset] = odd ? g_u : b_v;
break;
case V4L2_PIX_FMT_SRGGB8:
buf[0][offset] = odd ? g_u : r_y;
buf[1][offset] = odd ? b_v : g_u;
break;
}
}
unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
{
switch (tpg->fourcc) {
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
return buf_line & 1;
default:
return 0;
} }
} }
...@@ -1614,6 +1654,8 @@ void tpg_calc_text_basep(struct tpg_data *tpg, ...@@ -1614,6 +1654,8 @@ void tpg_calc_text_basep(struct tpg_data *tpg,
basep[p][1] += h * stride / 2; basep[p][1] += h * stride / 2;
else if (tpg->field == V4L2_FIELD_SEQ_BT) else if (tpg->field == V4L2_FIELD_SEQ_BT)
basep[p][0] += h * stride / 2; basep[p][0] += h * stride / 2;
if (p == 0 && tpg->interleaved)
tpg_calc_text_basep(tpg, basep, 1, vbuf);
} }
static int tpg_pattern_avg(const struct tpg_data *tpg, static int tpg_pattern_avg(const struct tpg_data *tpg,
...@@ -1990,6 +2032,13 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, ...@@ -1990,6 +2032,13 @@ void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
src_y++; src_y++;
} }
/*
* For line-interleaved formats determine the 'plane'
* based on the buffer line.
*/
if (tpg_g_interleaved(tpg))
p = tpg_g_interleaved_plane(tpg, buf_line);
if (tpg->vdownsampling[p] > 1) { if (tpg->vdownsampling[p] > 1) {
/* /*
* When doing vertical downsampling the field setting * When doing vertical downsampling the field setting
...@@ -2036,7 +2085,7 @@ void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf) ...@@ -2036,7 +2085,7 @@ void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
return; return;
} }
for (i = 0; i < tpg->planes; i++) { for (i = 0; i < tpg_g_planes(tpg); i++) {
tpg_fill_plane_buffer(tpg, std, i, vbuf + offset); tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
offset += tpg_calc_plane_size(tpg, i); offset += tpg_calc_plane_size(tpg, i);
} }
......
...@@ -140,6 +140,7 @@ struct tpg_data { ...@@ -140,6 +140,7 @@ struct tpg_data {
unsigned real_rgb_range; unsigned real_rgb_range;
unsigned buffers; unsigned buffers;
unsigned planes; unsigned planes;
bool interleaved;
u8 vdownsampling[TPG_MAX_PLANES]; u8 vdownsampling[TPG_MAX_PLANES];
u8 hdownsampling[TPG_MAX_PLANES]; u8 hdownsampling[TPG_MAX_PLANES];
/* /*
...@@ -197,6 +198,7 @@ void tpg_gen_text(const struct tpg_data *tpg, ...@@ -197,6 +198,7 @@ void tpg_gen_text(const struct tpg_data *tpg,
u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text);
void tpg_calc_text_basep(struct tpg_data *tpg, void tpg_calc_text_basep(struct tpg_data *tpg,
u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
unsigned p, u8 *vbuf); unsigned p, u8 *vbuf);
void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
...@@ -346,7 +348,12 @@ static inline unsigned tpg_g_buffers(const struct tpg_data *tpg) ...@@ -346,7 +348,12 @@ static inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
static inline unsigned tpg_g_planes(const struct tpg_data *tpg) static inline unsigned tpg_g_planes(const struct tpg_data *tpg)
{ {
return tpg->planes; return tpg->interleaved ? 1 : tpg->planes;
}
static inline bool tpg_g_interleaved(const struct tpg_data *tpg)
{
return tpg->interleaved;
} }
static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
...@@ -386,7 +393,7 @@ static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsi ...@@ -386,7 +393,7 @@ static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsi
return; return;
} }
for (p = 0; p < tpg->planes; p++) { for (p = 0; p < tpg_g_planes(tpg); p++) {
unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p]; tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
...@@ -401,7 +408,7 @@ static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned pla ...@@ -401,7 +408,7 @@ static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned pla
if (tpg->buffers > 1) if (tpg->buffers > 1)
return tpg_g_bytesperline(tpg, plane); return tpg_g_bytesperline(tpg, plane);
for (p = 0; p < tpg->planes; p++) { for (p = 0; p < tpg_g_planes(tpg); p++) {
unsigned plane_w = tpg_g_bytesperline(tpg, p); unsigned plane_w = tpg_g_bytesperline(tpg, p);
w += plane_w / tpg->vdownsampling[p]; w += plane_w / tpg->vdownsampling[p];
...@@ -417,7 +424,7 @@ static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, ...@@ -417,7 +424,7 @@ static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
if (tpg->buffers > 1) if (tpg->buffers > 1)
return bpl; return bpl;
for (p = 0; p < tpg->planes; p++) { for (p = 0; p < tpg_g_planes(tpg); p++) {
unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
plane_w /= tpg->hdownsampling[p]; plane_w /= tpg->hdownsampling[p];
...@@ -428,7 +435,7 @@ static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, ...@@ -428,7 +435,7 @@ static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane) static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
{ {
if (plane >= tpg->planes) if (plane >= tpg_g_planes(tpg))
return 0; return 0;
return tpg_g_bytesperline(tpg, plane) * tpg->buf_height / return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
......
...@@ -383,6 +383,38 @@ struct vivid_fmt vivid_formats[] = { ...@@ -383,6 +383,38 @@ struct vivid_fmt vivid_formats[] = {
.buffers = 1, .buffers = 1,
.alpha_mask = 0xff000000, .alpha_mask = 0xff000000,
}, },
{
.name = "Bayer BG/GR",
.fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
.vdownsampling = { 1 },
.bit_depth = { 8 },
.planes = 1,
.buffers = 1,
},
{
.name = "Bayer GB/RG",
.fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
.vdownsampling = { 1 },
.bit_depth = { 8 },
.planes = 1,
.buffers = 1,
},
{
.name = "Bayer GR/BG",
.fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
.vdownsampling = { 1 },
.bit_depth = { 8 },
.planes = 1,
.buffers = 1,
},
{
.name = "Bayer RG/GB",
.fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
.vdownsampling = { 1 },
.bit_depth = { 8 },
.planes = 1,
.buffers = 1,
},
{ {
.name = "4:2:2, biplanar, YUV", .name = "4:2:2, biplanar, YUV",
.fourcc = V4L2_PIX_FMT_NV16M, .fourcc = V4L2_PIX_FMT_NV16M,
......
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