aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-11-17 08:26:01 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-12-02 08:18:09 -0500
commit3e8a78d13997bc559aad626dfa0fb26e50a99676 (patch)
tree8376ff8ee90192a4f3b89347972e1598d29a678c
parentcd8adbe7013f4a0c82c29f549161588eeec13696 (diff)
[media] vivid: add support for YCbCr encoding and quantization
Implement controls to set the YCbCr encoding and the quantization range for the colorspace. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/platform/vivid/vivid-core.h2
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.c86
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c18
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c4
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c25
5 files changed, 116 insertions, 19 deletions
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 9e41cbe23006..4b497df4b6a4 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -329,6 +329,8 @@ struct vivid_dev {
329 v4l2_std_id std_out; 329 v4l2_std_id std_out;
330 struct v4l2_dv_timings dv_timings_out; 330 struct v4l2_dv_timings dv_timings_out;
331 u32 colorspace_out; 331 u32 colorspace_out;
332 u32 ycbcr_enc_out;
333 u32 quantization_out;
332 u32 service_set_out; 334 u32 service_set_out;
333 u32 bytesperline_out[2]; 335 u32 bytesperline_out[2];
334 unsigned tv_field_out; 336 unsigned tv_field_out;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index dcb912d6e4ba..857e7866e8bc 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -62,19 +62,21 @@
62#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23) 62#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
63#define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24) 63#define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
64#define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25) 64#define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
65#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 26) 65#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 26)
66#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 27) 66#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 27)
67#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 28) 67#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 28)
68#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 29) 68#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 29)
69#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 30) 69#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 30)
70#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 31) 70#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 31)
71#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 32) 71#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 32)
72#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 33) 72#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 33)
73#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 34) 73#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 34)
74#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 35) 74#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 35)
75#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 36) 75#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 36)
76#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 37) 76#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 37)
77#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 38) 77#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 38)
78#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 39)
79#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 40)
78 80
79#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) 81#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
80#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) 82#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
@@ -358,6 +360,20 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
358 vivid_send_source_change(dev, HDMI); 360 vivid_send_source_change(dev, HDMI);
359 vivid_send_source_change(dev, WEBCAM); 361 vivid_send_source_change(dev, WEBCAM);
360 break; 362 break;
363 case VIVID_CID_YCBCR_ENC:
364 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
365 vivid_send_source_change(dev, TV);
366 vivid_send_source_change(dev, SVID);
367 vivid_send_source_change(dev, HDMI);
368 vivid_send_source_change(dev, WEBCAM);
369 break;
370 case VIVID_CID_QUANTIZATION:
371 tpg_s_quantization(&dev->tpg, ctrl->val);
372 vivid_send_source_change(dev, TV);
373 vivid_send_source_change(dev, SVID);
374 vivid_send_source_change(dev, HDMI);
375 vivid_send_source_change(dev, WEBCAM);
376 break;
361 case V4L2_CID_DV_RX_RGB_RANGE: 377 case V4L2_CID_DV_RX_RGB_RANGE:
362 if (!vivid_is_hdmi_cap(dev)) 378 if (!vivid_is_hdmi_cap(dev))
363 break; 379 break;
@@ -693,6 +709,44 @@ static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
693 .qmenu = vivid_ctrl_colorspace_strings, 709 .qmenu = vivid_ctrl_colorspace_strings,
694}; 710};
695 711
712static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
713 "Default",
714 "ITU-R 601",
715 "Rec. 709",
716 "xvYCC 601",
717 "xvYCC 709",
718 "sYCC",
719 "BT.2020 Non-Constant Luminance",
720 "BT.2020 Constant Luminance",
721 "SMPTE 240M",
722 NULL,
723};
724
725static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
726 .ops = &vivid_vid_cap_ctrl_ops,
727 .id = VIVID_CID_YCBCR_ENC,
728 .name = "Y'CbCr Encoding",
729 .type = V4L2_CTRL_TYPE_MENU,
730 .max = 8,
731 .qmenu = vivid_ctrl_ycbcr_enc_strings,
732};
733
734static const char * const vivid_ctrl_quantization_strings[] = {
735 "Default",
736 "Full Range",
737 "Limited Range",
738 NULL,
739};
740
741static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
742 .ops = &vivid_vid_cap_ctrl_ops,
743 .id = VIVID_CID_QUANTIZATION,
744 .name = "Quantization",
745 .type = V4L2_CTRL_TYPE_MENU,
746 .max = 2,
747 .qmenu = vivid_ctrl_quantization_strings,
748};
749
696static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = { 750static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
697 .ops = &vivid_vid_cap_ctrl_ops, 751 .ops = &vivid_vid_cap_ctrl_ops,
698 .id = VIVID_CID_ALPHA_MODE, 752 .id = VIVID_CID_ALPHA_MODE,
@@ -769,8 +823,12 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
769 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 823 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
770 else 824 else
771 dev->colorspace_out = V4L2_COLORSPACE_REC709; 825 dev->colorspace_out = V4L2_COLORSPACE_REC709;
826 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
772 } else { 827 } else {
773 dev->colorspace_out = V4L2_COLORSPACE_SRGB; 828 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
829 dev->quantization_out = dev->dvi_d_out ?
830 V4L2_QUANTIZATION_LIM_RANGE :
831 V4L2_QUANTIZATION_DEFAULT;
774 } 832 }
775 if (dev->loop_video) 833 if (dev->loop_video)
776 vivid_send_source_change(dev, HDMI); 834 vivid_send_source_change(dev, HDMI);
@@ -1307,6 +1365,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1307 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL); 1365 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1308 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap, 1366 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1309 &vivid_ctrl_colorspace, NULL); 1367 &vivid_ctrl_colorspace, NULL);
1368 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1369 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1310 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); 1370 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1311 } 1371 }
1312 1372
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index 923a4f854eba..867a29a6d18f 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -498,6 +498,20 @@ static unsigned vivid_colorspace_cap(struct vivid_dev *dev)
498 return dev->colorspace_out; 498 return dev->colorspace_out;
499} 499}
500 500
501static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev)
502{
503 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
504 return tpg_g_ycbcr_enc(&dev->tpg);
505 return dev->ycbcr_enc_out;
506}
507
508static unsigned vivid_quantization_cap(struct vivid_dev *dev)
509{
510 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev))
511 return tpg_g_quantization(&dev->tpg);
512 return dev->quantization_out;
513}
514
501int vivid_g_fmt_vid_cap(struct file *file, void *priv, 515int vivid_g_fmt_vid_cap(struct file *file, void *priv,
502 struct v4l2_format *f) 516 struct v4l2_format *f)
503{ 517{
@@ -510,6 +524,8 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv,
510 mp->field = dev->field_cap; 524 mp->field = dev->field_cap;
511 mp->pixelformat = dev->fmt_cap->fourcc; 525 mp->pixelformat = dev->fmt_cap->fourcc;
512 mp->colorspace = vivid_colorspace_cap(dev); 526 mp->colorspace = vivid_colorspace_cap(dev);
527 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
528 mp->quantization = vivid_quantization_cap(dev);
513 mp->num_planes = dev->fmt_cap->planes; 529 mp->num_planes = dev->fmt_cap->planes;
514 for (p = 0; p < mp->num_planes; p++) { 530 for (p = 0; p < mp->num_planes; p++) {
515 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); 531 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);
@@ -595,6 +611,8 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
595 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 611 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
596 } 612 }
597 mp->colorspace = vivid_colorspace_cap(dev); 613 mp->colorspace = vivid_colorspace_cap(dev);
614 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
615 mp->quantization = vivid_quantization_cap(dev);
598 memset(mp->reserved, 0, sizeof(mp->reserved)); 616 memset(mp->reserved, 0, sizeof(mp->reserved));
599 return 0; 617 return 0;
600} 618}
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index 16cd6d2d2ed6..6bef1e6d6788 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -259,6 +259,8 @@ void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
259 mp->pixelformat = pix->pixelformat; 259 mp->pixelformat = pix->pixelformat;
260 mp->field = pix->field; 260 mp->field = pix->field;
261 mp->colorspace = pix->colorspace; 261 mp->colorspace = pix->colorspace;
262 mp->ycbcr_enc = pix->ycbcr_enc;
263 mp->quantization = pix->quantization;
262 mp->num_planes = 1; 264 mp->num_planes = 1;
263 mp->flags = pix->flags; 265 mp->flags = pix->flags;
264 ppix->sizeimage = pix->sizeimage; 266 ppix->sizeimage = pix->sizeimage;
@@ -285,6 +287,8 @@ int fmt_sp2mp_func(struct file *file, void *priv,
285 pix->pixelformat = mp->pixelformat; 287 pix->pixelformat = mp->pixelformat;
286 pix->field = mp->field; 288 pix->field = mp->field;
287 pix->colorspace = mp->colorspace; 289 pix->colorspace = mp->colorspace;
290 pix->ycbcr_enc = mp->ycbcr_enc;
291 pix->quantization = mp->quantization;
288 pix->sizeimage = ppix->sizeimage; 292 pix->sizeimage = ppix->sizeimage;
289 pix->bytesperline = ppix->bytesperline; 293 pix->bytesperline = ppix->bytesperline;
290 pix->flags = mp->flags; 294 pix->flags = mp->flags;
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
index 078bc35571b4..ee5c3992b276 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -259,6 +259,8 @@ void vivid_update_format_out(struct vivid_dev *dev)
259 } 259 }
260 break; 260 break;
261 } 261 }
262 dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT;
263 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
262 dev->compose_out = dev->sink_rect; 264 dev->compose_out = dev->sink_rect;
263 dev->compose_bounds_out = dev->sink_rect; 265 dev->compose_bounds_out = dev->sink_rect;
264 dev->crop_out = dev->compose_out; 266 dev->crop_out = dev->compose_out;
@@ -318,6 +320,8 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv,
318 mp->field = dev->field_out; 320 mp->field = dev->field_out;
319 mp->pixelformat = dev->fmt_out->fourcc; 321 mp->pixelformat = dev->fmt_out->fourcc;
320 mp->colorspace = dev->colorspace_out; 322 mp->colorspace = dev->colorspace_out;
323 mp->ycbcr_enc = dev->ycbcr_enc_out;
324 mp->quantization = dev->quantization_out;
321 mp->num_planes = dev->fmt_out->planes; 325 mp->num_planes = dev->fmt_out->planes;
322 for (p = 0; p < mp->num_planes; p++) { 326 for (p = 0; p < mp->num_planes; p++) {
323 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; 327 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
@@ -394,16 +398,23 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
394 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; 398 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height;
395 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 399 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
396 } 400 }
397 if (vivid_is_svid_out(dev)) 401 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
402 mp->quantization = V4L2_QUANTIZATION_DEFAULT;
403 if (vivid_is_svid_out(dev)) {
398 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 404 mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
399 else if (dev->dvi_d_out || !(bt->standards & V4L2_DV_BT_STD_CEA861)) 405 } else if (dev->dvi_d_out || !(bt->standards & V4L2_DV_BT_STD_CEA861)) {
400 mp->colorspace = V4L2_COLORSPACE_SRGB; 406 mp->colorspace = V4L2_COLORSPACE_SRGB;
401 else if (bt->width == 720 && bt->height <= 576) 407 if (dev->dvi_d_out)
408 mp->quantization = V4L2_QUANTIZATION_LIM_RANGE;
409 } else if (bt->width == 720 && bt->height <= 576) {
402 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 410 mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
403 else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M && 411 } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
404 mp->colorspace != V4L2_COLORSPACE_REC709 && 412 mp->colorspace != V4L2_COLORSPACE_REC709 &&
405 mp->colorspace != V4L2_COLORSPACE_SRGB) 413 mp->colorspace != V4L2_COLORSPACE_ADOBERGB &&
414 mp->colorspace != V4L2_COLORSPACE_BT2020 &&
415 mp->colorspace != V4L2_COLORSPACE_SRGB) {
406 mp->colorspace = V4L2_COLORSPACE_REC709; 416 mp->colorspace = V4L2_COLORSPACE_REC709;
417 }
407 memset(mp->reserved, 0, sizeof(mp->reserved)); 418 memset(mp->reserved, 0, sizeof(mp->reserved));
408 return 0; 419 return 0;
409} 420}
@@ -522,6 +533,8 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv,
522 533
523set_colorspace: 534set_colorspace:
524 dev->colorspace_out = mp->colorspace; 535 dev->colorspace_out = mp->colorspace;
536 dev->ycbcr_enc_out = mp->ycbcr_enc;
537 dev->quantization_out = mp->quantization;
525 if (dev->loop_video) { 538 if (dev->loop_video) {
526 vivid_send_source_change(dev, SVID); 539 vivid_send_source_change(dev, SVID);
527 vivid_send_source_change(dev, HDMI); 540 vivid_send_source_change(dev, HDMI);