Commit 429175e4 authored by Ricardo Ribalda's avatar Ricardo Ribalda Committed by Mauro Carvalho Chehab
Browse files

[media] vivid: Add support for HSV encoding



Support HSV encoding. Most of the logic is replicated from ycbcr_enc.

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 5f3d32ec
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -504,6 +504,7 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
	int max_rgb, min_rgb, diff_rgb;
	int aux;
	int third;
	int third_size;

	r >>= 4;
	g >>= 4;
@@ -530,30 +531,36 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
		return;
	}

	third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;

	/* Hue */
	if (max_rgb == r) {
		aux =  g - b;
		third = 0;
	} else if (max_rgb == g) {
		aux =  b - r;
		third = 60;
		third = third_size;
	} else {
		aux =  r - g;
		third = 120;
		third = third_size * 2;
	}

	aux *= 30;
	aux *= third_size / 2;
	aux += diff_rgb / 2;
	aux /= diff_rgb;
	aux += third;

	/* Clamp Hue */
	if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
		if (aux < 0)
			aux += 180;
		else if (aux > 180)
			aux -= 180;
	*h = aux;
	} else {
		aux = aux & 0xff;
	}

	*h = aux;
}

static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
@@ -1928,6 +1935,7 @@ static void tpg_recalc(struct tpg_data *tpg)
		tpg->recalc_lines = true;
		tpg->real_xfer_func = tpg->xfer_func;
		tpg->real_ycbcr_enc = tpg->ycbcr_enc;
		tpg->real_hsv_enc = tpg->hsv_enc;
		tpg->real_quantization = tpg->quantization;

		if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
@@ -2018,6 +2026,7 @@ void tpg_log_status(struct tpg_data *tpg)
	pr_info("tpg colorspace: %d\n", tpg->colorspace);
	pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
	pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
	pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc);
	pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
	pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
}
+1 −0
Original line number Diff line number Diff line
@@ -346,6 +346,7 @@ struct vivid_dev {
	struct v4l2_dv_timings		dv_timings_out;
	u32				colorspace_out;
	u32				ycbcr_enc_out;
	u32				hsv_enc_out;
	u32				quantization_out;
	u32				xfer_func_out;
	u32				service_set_out;
+25 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@
#define VIVID_CID_MAX_EDID_BLOCKS	(VIVID_CID_VIVID_BASE + 40)
#define VIVID_CID_PERCENTAGE_FILL	(VIVID_CID_VIVID_BASE + 41)
#define VIVID_CID_REDUCED_FPS		(VIVID_CID_VIVID_BASE + 42)
#define VIVID_CID_HSV_ENC		(VIVID_CID_VIVID_BASE + 43)

#define VIVID_CID_STD_SIGNAL_MODE	(VIVID_CID_VIVID_BASE + 60)
#define VIVID_CID_STANDARD		(VIVID_CID_VIVID_BASE + 61)
@@ -378,6 +379,14 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
		vivid_send_source_change(dev, HDMI);
		vivid_send_source_change(dev, WEBCAM);
		break;
	case VIVID_CID_HSV_ENC:
		tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
						     V4L2_HSV_ENC_180);
		vivid_send_source_change(dev, TV);
		vivid_send_source_change(dev, SVID);
		vivid_send_source_change(dev, HDMI);
		vivid_send_source_change(dev, WEBCAM);
		break;
	case VIVID_CID_QUANTIZATION:
		tpg_s_quantization(&dev->tpg, ctrl->val);
		vivid_send_source_change(dev, TV);
@@ -778,6 +787,21 @@ static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
	.qmenu = vivid_ctrl_ycbcr_enc_strings,
};

static const char * const vivid_ctrl_hsv_enc_strings[] = {
	"Hue 0-179",
	"Hue 0-256",
	NULL,
};

static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
	.ops = &vivid_vid_cap_ctrl_ops,
	.id = VIVID_CID_HSV_ENC,
	.name = "HSV Encoding",
	.type = V4L2_CTRL_TYPE_MENU,
	.max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
	.qmenu = vivid_ctrl_hsv_enc_strings,
};

static const char * const vivid_ctrl_quantization_strings[] = {
	"Default",
	"Full Range",
@@ -1454,6 +1478,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
			&vivid_ctrl_colorspace, NULL);
		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
		v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
	}
+15 −2
Original line number Diff line number Diff line
@@ -510,6 +510,13 @@ static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev)
	return dev->ycbcr_enc_out;
}

static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev)
{
	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
		return tpg_g_hsv_enc(&dev->tpg);
	return dev->hsv_enc_out;
}

static unsigned vivid_quantization_cap(struct vivid_dev *dev)
{
	if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
@@ -530,6 +537,9 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv,
	mp->pixelformat  = dev->fmt_cap->fourcc;
	mp->colorspace   = vivid_colorspace_cap(dev);
	mp->xfer_func    = vivid_xfer_func_cap(dev);
	if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV)
		mp->hsv_enc    = vivid_hsv_enc_cap(dev);
	else
		mp->ycbcr_enc    = vivid_ycbcr_enc_cap(dev);
	mp->quantization = vivid_quantization_cap(dev);
	mp->num_planes = dev->fmt_cap->buffers;
@@ -618,6 +628,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
		memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
	}
	mp->colorspace = vivid_colorspace_cap(dev);
	if (fmt->color_enc == TGP_COLOR_ENC_HSV)
		mp->hsv_enc = vivid_hsv_enc_cap(dev);
	else
		mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
	mp->xfer_func = vivid_xfer_func_cap(dev);
	mp->quantization = vivid_quantization_cap(dev);
+2 −0
Original line number Diff line number Diff line
@@ -630,6 +630,7 @@ void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
	mp->field = pix->field;
	mp->colorspace = pix->colorspace;
	mp->xfer_func = pix->xfer_func;
	/* Also copies hsv_enc */
	mp->ycbcr_enc = pix->ycbcr_enc;
	mp->quantization = pix->quantization;
	mp->num_planes = 1;
@@ -659,6 +660,7 @@ int fmt_sp2mp_func(struct file *file, void *priv,
	pix->field = mp->field;
	pix->colorspace = mp->colorspace;
	pix->xfer_func = mp->xfer_func;
	/* Also copies hsv_enc */
	pix->ycbcr_enc = mp->ycbcr_enc;
	pix->quantization = mp->quantization;
	pix->sizeimage = ppix->sizeimage;
Loading