Commit 54fb1534 authored by Ricardo Ribalda Delgado's avatar Ricardo Ribalda Delgado Committed by Mauro Carvalho Chehab

[media] vivid: Add support for HSV formats

This patch adds support for V4L2_PIX_FMT_HSV24 and V4L2_PIX_FMT_HSV32.
Signed-off-by: default avatarRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 646895e9
...@@ -318,6 +318,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -318,6 +318,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->hmask[0] = ~1; tpg->hmask[0] = ~1;
tpg->color_enc = TGP_COLOR_ENC_YCBCR; tpg->color_enc = TGP_COLOR_ENC_YCBCR;
break; break;
case V4L2_PIX_FMT_HSV24:
case V4L2_PIX_FMT_HSV32:
tpg->color_enc = TGP_COLOR_ENC_HSV;
break;
default: default:
return false; return false;
} }
...@@ -351,6 +355,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -351,6 +355,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
break; break;
case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24: case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_HSV24:
tpg->twopixelsize[0] = 2 * 3; tpg->twopixelsize[0] = 2 * 3;
break; break;
case V4L2_PIX_FMT_BGR666: case V4L2_PIX_FMT_BGR666:
...@@ -361,6 +366,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) ...@@ -361,6 +366,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
case V4L2_PIX_FMT_ARGB32: case V4L2_PIX_FMT_ARGB32:
case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_ABGR32:
case V4L2_PIX_FMT_YUV32: case V4L2_PIX_FMT_YUV32:
case V4L2_PIX_FMT_HSV32:
tpg->twopixelsize[0] = 2 * 4; tpg->twopixelsize[0] = 2 * 4;
break; break;
case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV12:
...@@ -490,6 +496,64 @@ static inline int linear_to_rec709(int v) ...@@ -490,6 +496,64 @@ static inline int linear_to_rec709(int v)
return tpg_linear_to_rec709[v]; return tpg_linear_to_rec709[v];
} }
static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
int *h, int *s, int *v)
{
int max_rgb, min_rgb, diff_rgb;
int aux;
int third;
r >>= 4;
g >>= 4;
b >>= 4;
/* Value */
max_rgb = max3(r, g, b);
*v = max_rgb;
if (!max_rgb) {
*h = 0;
*s = 0;
return;
}
/* Saturation */
min_rgb = min3(r, g, b);
diff_rgb = max_rgb - min_rgb;
aux = 255 * diff_rgb;
aux += max_rgb / 2;
aux /= max_rgb;
*s = aux;
if (!aux) {
*h = 0;
return;
}
/* Hue */
if (max_rgb == r) {
aux = g - b;
third = 0;
} else if (max_rgb == g) {
aux = b - r;
third = 60;
} else {
aux = r - g;
third = 120;
}
aux *= 30;
aux += diff_rgb / 2;
aux /= diff_rgb;
aux += third;
/* Clamp Hue */
if (aux < 0)
aux += 180;
else if (aux > 180)
aux -= 180;
*h = aux;
}
static void rgb2ycbcr(const int m[3][3], int r, int g, int b, static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
int y_offset, int *y, int *cb, int *cr) int y_offset, int *y, int *cb, int *cr)
{ {
...@@ -830,7 +894,19 @@ static void precalculate_color(struct tpg_data *tpg, int k) ...@@ -830,7 +894,19 @@ static void precalculate_color(struct tpg_data *tpg, int k)
ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b); ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
} }
if (tpg->color_enc == TGP_COLOR_ENC_YCBCR) { switch (tpg->color_enc) {
case TGP_COLOR_ENC_HSV:
{
int h, s, v;
color_to_hsv(tpg, r, g, b, &h, &s, &v);
tpg->colors[k][0] = h;
tpg->colors[k][1] = s;
tpg->colors[k][2] = v;
break;
}
case TGP_COLOR_ENC_YCBCR:
{
/* Convert to YCbCr */ /* Convert to YCbCr */
int y, cb, cr; int y, cb, cr;
...@@ -864,7 +940,10 @@ static void precalculate_color(struct tpg_data *tpg, int k) ...@@ -864,7 +940,10 @@ static void precalculate_color(struct tpg_data *tpg, int k)
tpg->colors[k][0] = y; tpg->colors[k][0] = y;
tpg->colors[k][1] = cb; tpg->colors[k][1] = cb;
tpg->colors[k][2] = cr; tpg->colors[k][2] = cr;
} else { break;
}
case TGP_COLOR_ENC_RGB:
{
if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
r = (r * 219) / 255 + (16 << 4); r = (r * 219) / 255 + (16 << 4);
g = (g * 219) / 255 + (16 << 4); g = (g * 219) / 255 + (16 << 4);
...@@ -914,6 +993,8 @@ static void precalculate_color(struct tpg_data *tpg, int k) ...@@ -914,6 +993,8 @@ static void precalculate_color(struct tpg_data *tpg, int k)
tpg->colors[k][0] = r; tpg->colors[k][0] = r;
tpg->colors[k][1] = g; tpg->colors[k][1] = g;
tpg->colors[k][2] = b; tpg->colors[k][2] = b;
break;
}
} }
} }
...@@ -939,8 +1020,8 @@ static void gen_twopix(struct tpg_data *tpg, ...@@ -939,8 +1020,8 @@ static void gen_twopix(struct tpg_data *tpg,
alpha = 0; alpha = 0;
if (color == TPG_COLOR_RANDOM) if (color == TPG_COLOR_RANDOM)
precalculate_color(tpg, color); precalculate_color(tpg, color);
r_y = tpg->colors[color][0]; /* R or precalculated Y */ r_y = tpg->colors[color][0]; /* R or precalculated Y, H */
g_u = tpg->colors[color][1]; /* G or precalculated U */ g_u = tpg->colors[color][1]; /* G or precalculated U, V */
b_v = tpg->colors[color][2]; /* B or precalculated V */ b_v = tpg->colors[color][2]; /* B or precalculated V */
switch (tpg->fourcc) { switch (tpg->fourcc) {
...@@ -1122,6 +1203,7 @@ static void gen_twopix(struct tpg_data *tpg, ...@@ -1122,6 +1203,7 @@ static void gen_twopix(struct tpg_data *tpg,
buf[0][offset + 1] = (g_u << 5) | b_v; buf[0][offset + 1] = (g_u << 5) | b_v;
break; break;
case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_HSV24:
buf[0][offset] = r_y; buf[0][offset] = r_y;
buf[0][offset + 1] = g_u; buf[0][offset + 1] = g_u;
buf[0][offset + 2] = b_v; buf[0][offset + 2] = b_v;
...@@ -1139,6 +1221,7 @@ static void gen_twopix(struct tpg_data *tpg, ...@@ -1139,6 +1221,7 @@ static void gen_twopix(struct tpg_data *tpg,
break; break;
case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_XRGB32: case V4L2_PIX_FMT_XRGB32:
case V4L2_PIX_FMT_HSV32:
alpha = 0; alpha = 0;
/* fall through */ /* fall through */
case V4L2_PIX_FMT_YUV32: case V4L2_PIX_FMT_YUV32:
...@@ -1895,6 +1978,8 @@ static const char *tpg_color_enc_str(enum tgp_color_enc ...@@ -1895,6 +1978,8 @@ static const char *tpg_color_enc_str(enum tgp_color_enc
color_enc) color_enc)
{ {
switch (color_enc) { switch (color_enc) {
case TGP_COLOR_ENC_HSV:
return "HSV";
case TGP_COLOR_ENC_YCBCR: case TGP_COLOR_ENC_YCBCR:
return "Y'CbCr"; return "Y'CbCr";
case TGP_COLOR_ENC_RGB: case TGP_COLOR_ENC_RGB:
......
...@@ -445,6 +445,20 @@ struct vivid_fmt vivid_formats[] = { ...@@ -445,6 +445,20 @@ struct vivid_fmt vivid_formats[] = {
.planes = 1, .planes = 1,
.buffers = 1, .buffers = 1,
}, },
{
.fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
.vdownsampling = { 1 },
.bit_depth = { 24 },
.planes = 1,
.buffers = 1,
},
{
.fourcc = V4L2_PIX_FMT_HSV32, /* HSV 32bits */
.vdownsampling = { 1 },
.bit_depth = { 32 },
.planes = 1,
.buffers = 1,
},
/* Multiplanar formats */ /* Multiplanar formats */
......
...@@ -90,6 +90,7 @@ enum tpg_move_mode { ...@@ -90,6 +90,7 @@ enum tpg_move_mode {
enum tgp_color_enc { enum tgp_color_enc {
TGP_COLOR_ENC_RGB, TGP_COLOR_ENC_RGB,
TGP_COLOR_ENC_YCBCR, TGP_COLOR_ENC_YCBCR,
TGP_COLOR_ENC_HSV,
}; };
extern const char * const tpg_aspect_strings[]; extern const char * const tpg_aspect_strings[];
......
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