diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-11-17 08:26:01 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-12-02 08:18:09 -0500 |
commit | 3e8a78d13997bc559aad626dfa0fb26e50a99676 (patch) | |
tree | 8376ff8ee90192a4f3b89347972e1598d29a678c | |
parent | cd8adbe7013f4a0c82c29f549161588eeec13696 (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.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-ctrls.c | 86 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-cap.c | 18 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-common.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-out.c | 25 |
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 | ||
712 | static 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 | |||
725 | static 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 | |||
734 | static const char * const vivid_ctrl_quantization_strings[] = { | ||
735 | "Default", | ||
736 | "Full Range", | ||
737 | "Limited Range", | ||
738 | NULL, | ||
739 | }; | ||
740 | |||
741 | static 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 | |||
696 | static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = { | 750 | static 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 | ||
501 | static 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 | |||
508 | static 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 | |||
501 | int vivid_g_fmt_vid_cap(struct file *file, void *priv, | 515 | int 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 | ||
523 | set_colorspace: | 534 | set_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); |