The colorimetry parameters need to be tested at both sink and source
pads. Specifically, for prpencvf, the IC only supports RGB full-range
quantization at input and output.

Fix this by cleaning up imx_media_fill_default_mbus_fields(), renaming
to imx_media_try_colorimetry(), and call it at both sink and source
pad try_fmt's. The unrelated check for uninitialized field value is
moved out to appropriate places in each subdev try_fmt.

Signed-off-by: Steve Longerbeam <slongerb...@gmail.com>
---
 drivers/staging/media/imx/imx-ic-prp.c      |  6 +-
 drivers/staging/media/imx/imx-ic-prpencvf.c |  8 +--
 drivers/staging/media/imx/imx-media-csi.c   | 19 +++---
 drivers/staging/media/imx/imx-media-utils.c | 68 +++++++++++----------
 drivers/staging/media/imx/imx-media-vdic.c  |  5 +-
 drivers/staging/media/imx/imx-media.h       |  5 +-
 drivers/staging/media/imx/imx7-media-csi.c  |  8 +--
 7 files changed, 62 insertions(+), 57 deletions(-)

diff --git a/drivers/staging/media/imx/imx-ic-prp.c 
b/drivers/staging/media/imx/imx-ic-prp.c
index 3d43cdcb4bb9..8010ee706164 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -197,8 +197,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
                        sdformat->format.code = cc->codes[0];
                }
 
-               imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
-                                                  true);
+               if (sdformat->format.field == V4L2_FIELD_ANY)
+                       sdformat->format.field = V4L2_FIELD_NONE;
                break;
        case PRP_SRC_PAD_PRPENC:
        case PRP_SRC_PAD_PRPVF:
@@ -207,6 +207,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
                break;
        }
 
+       imx_media_try_colorimetry(&sdformat->format, true);
+
        fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
        *fmt = sdformat->format;
 out:
diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
b/drivers/staging/media/imx/imx-ic-prpencvf.c
index 10f2c7684727..b1886a4e362e 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -899,8 +899,6 @@ static void prp_try_fmt(struct prp_priv *priv,
                /* propagate colorimetry from sink */
                sdformat->format.colorspace = infmt->colorspace;
                sdformat->format.xfer_func = infmt->xfer_func;
-               sdformat->format.quantization = infmt->quantization;
-               sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
        } else {
                v4l_bound_align_image(&sdformat->format.width,
                                      MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK,
@@ -908,9 +906,11 @@ static void prp_try_fmt(struct prp_priv *priv,
                                      MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK,
                                      S_ALIGN);
 
-               imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
-                                                  true);
+               if (sdformat->format.field == V4L2_FIELD_ANY)
+                       sdformat->format.field = V4L2_FIELD_NONE;
        }
+
+       imx_media_try_colorimetry(&sdformat->format, true);
 }
 
 static int prp_set_fmt(struct v4l2_subdev *sd,
diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 3b7517348666..cc3e0086b08a 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1369,9 +1369,15 @@ static void csi_try_field(struct csi_priv *priv,
        struct v4l2_mbus_framefmt *infmt =
                __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which);
 
-       /* no restrictions on sink pad field type */
-       if (sdformat->pad == CSI_SINK_PAD)
+       /*
+        * no restrictions on sink pad field type except must
+        * be initialized.
+        */
+       if (sdformat->pad == CSI_SINK_PAD) {
+               if (sdformat->format.field == V4L2_FIELD_ANY)
+                       sdformat->format.field = V4L2_FIELD_NONE;
                return;
+       }
 
        switch (infmt->field) {
        case V4L2_FIELD_SEQ_TB:
@@ -1449,8 +1455,6 @@ static void csi_try_fmt(struct csi_priv *priv,
                /* propagate colorimetry from sink */
                sdformat->format.colorspace = infmt->colorspace;
                sdformat->format.xfer_func = infmt->xfer_func;
-               sdformat->format.quantization = infmt->quantization;
-               sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
 
                break;
        case CSI_SINK_PAD:
@@ -1470,10 +1474,6 @@ static void csi_try_fmt(struct csi_priv *priv,
 
                csi_try_field(priv, cfg, sdformat);
 
-               imx_media_fill_default_mbus_fields(
-                       &sdformat->format, infmt,
-                       priv->active_output_pad == CSI_SRC_PAD_DIRECT);
-
                /* Reset crop and compose rectangles */
                crop->left = 0;
                crop->top = 0;
@@ -1489,6 +1489,9 @@ static void csi_try_fmt(struct csi_priv *priv,
 
                break;
        }
+
+       imx_media_try_colorimetry(&sdformat->format,
+                       priv->active_output_pad == CSI_SRC_PAD_DIRECT);
 }
 
 static int csi_set_fmt(struct v4l2_subdev *sd,
diff --git a/drivers/staging/media/imx/imx-media-utils.c 
b/drivers/staging/media/imx/imx-media-utils.c
index 1c63a2765a81..aa7d4be77a7e 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -515,21 +515,19 @@ int imx_media_init_cfg(struct v4l2_subdev *sd,
 EXPORT_SYMBOL_GPL(imx_media_init_cfg);
 
 /*
- * Check whether the field and colorimetry parameters in tryfmt are
- * uninitialized, and if so fill them with the values from fmt,
- * or if tryfmt->colorspace has been initialized, all the default
- * colorimetry params can be derived from tryfmt->colorspace.
+ * Default the colorspace in tryfmt to SRGB if set to an unsupported
+ * colorspace or not initialized. Then set the remaining colorimetry
+ * parameters based on the colorspace if they are uninitialized.
  *
  * tryfmt->code must be set on entry.
  *
  * If this format is destined to be routed through the Image Converter,
- * quantization and Y`CbCr encoding must be fixed. The IC expects and
- * produces fixed quantization and Y`CbCr encoding at its input and output
- * (full range for RGB, limited range for YUV, and V4L2_YCBCR_ENC_601).
+ * quantization and Y`CbCr encoding must be fixed. The IC supports only
+ * full-range quantization for RGB at its input and output, and only
+ * BT.601 Y`CbCr encoding.
  */
-void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt,
-                                       struct v4l2_mbus_framefmt *fmt,
-                                       bool ic_route)
+void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
+                              bool ic_route)
 {
        const struct imx_media_pixfmt *cc;
        bool is_rgb = false;
@@ -537,28 +535,41 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
        cc = imx_media_find_mbus_format(tryfmt->code, CS_SEL_ANY, true);
        if (!cc)
                cc = imx_media_find_ipu_format(tryfmt->code, CS_SEL_ANY);
-       if (cc && cc->cs != IPUV3_COLORSPACE_YUV)
+       if (cc && cc->cs == IPUV3_COLORSPACE_RGB)
                is_rgb = true;
 
-       /* fill field if necessary */
-       if (tryfmt->field == V4L2_FIELD_ANY)
-               tryfmt->field = fmt->field;
+       switch (tryfmt->colorspace) {
+       case V4L2_COLORSPACE_SMPTE170M:
+       case V4L2_COLORSPACE_REC709:
+       case V4L2_COLORSPACE_JPEG:
+       case V4L2_COLORSPACE_SRGB:
+       case V4L2_COLORSPACE_BT2020:
+       case V4L2_COLORSPACE_OPRGB:
+       case V4L2_COLORSPACE_DCI_P3:
+       case V4L2_COLORSPACE_RAW:
+               break;
+       default:
+               tryfmt->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       }
+
+       if (tryfmt->xfer_func == V4L2_XFER_FUNC_DEFAULT) {
+               tryfmt->xfer_func =
+                       V4L2_MAP_XFER_FUNC_DEFAULT(tryfmt->colorspace);
+       }
+
+       if (ic_route) {
+               if (is_rgb ||
+                   tryfmt->quantization == V4L2_QUANTIZATION_DEFAULT)
+                       tryfmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
 
-       /* fill colorimetry if necessary */
-       if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT) {
-               tryfmt->colorspace = fmt->colorspace;
-               tryfmt->xfer_func = fmt->xfer_func;
-               tryfmt->ycbcr_enc = fmt->ycbcr_enc;
-               tryfmt->quantization = fmt->quantization;
+               tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
        } else {
-               if (tryfmt->xfer_func == V4L2_XFER_FUNC_DEFAULT) {
-                       tryfmt->xfer_func =
-                               V4L2_MAP_XFER_FUNC_DEFAULT(tryfmt->colorspace);
-               }
                if (tryfmt->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) {
                        tryfmt->ycbcr_enc =
                                V4L2_MAP_YCBCR_ENC_DEFAULT(tryfmt->colorspace);
                }
+
                if (tryfmt->quantization == V4L2_QUANTIZATION_DEFAULT) {
                        tryfmt->quantization =
                                V4L2_MAP_QUANTIZATION_DEFAULT(
@@ -566,15 +577,8 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
                                        tryfmt->ycbcr_enc);
                }
        }
-
-       if (ic_route) {
-               tryfmt->quantization = is_rgb ?
-                       V4L2_QUANTIZATION_FULL_RANGE :
-                       V4L2_QUANTIZATION_LIM_RANGE;
-               tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
-       }
 }
-EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields);
+EXPORT_SYMBOL_GPL(imx_media_try_colorimetry);
 
 int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
                                  struct v4l2_rect *compose,
diff --git a/drivers/staging/media/imx/imx-media-vdic.c 
b/drivers/staging/media/imx/imx-media-vdic.c
index 2808662e2597..a285619afa0f 100644
--- a/drivers/staging/media/imx/imx-media-vdic.c
+++ b/drivers/staging/media/imx/imx-media-vdic.c
@@ -615,14 +615,13 @@ static void vdic_try_fmt(struct vdic_priv *priv,
                                      &sdformat->format.height,
                                      MIN_H, MAX_H_VDIC, H_ALIGN, S_ALIGN);
 
-               imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
-                                                  true);
-
                /* input must be interlaced! Choose SEQ_TB if not */
                if (!V4L2_FIELD_HAS_BOTH(sdformat->format.field))
                        sdformat->format.field = V4L2_FIELD_SEQ_TB;
                break;
        }
+
+       imx_media_try_colorimetry(&sdformat->format, true);
 }
 
 static int vdic_set_fmt(struct v4l2_subdev *sd,
diff --git a/drivers/staging/media/imx/imx-media.h 
b/drivers/staging/media/imx/imx-media.h
index ae964c8d5be1..48c8996d394c 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -176,9 +176,8 @@ int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
                            const struct imx_media_pixfmt **cc);
 int imx_media_init_cfg(struct v4l2_subdev *sd,
                       struct v4l2_subdev_pad_config *cfg);
-void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt,
-                                       struct v4l2_mbus_framefmt *fmt,
-                                       bool ic_route);
+void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
+                              bool ic_route);
 int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
                                  struct v4l2_rect *compose,
                                  const struct v4l2_mbus_framefmt *mbus,
diff --git a/drivers/staging/media/imx/imx7-media-csi.c 
b/drivers/staging/media/imx/imx7-media-csi.c
index 3fba7c27c0ec..6e626c10a5f1 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1003,8 +1003,6 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi,
 
                sdformat->format.colorspace = in_fmt->colorspace;
                sdformat->format.xfer_func = in_fmt->xfer_func;
-               sdformat->format.quantization = in_fmt->quantization;
-               sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc;
                break;
        case IMX7_CSI_PAD_SINK:
                *cc = imx_media_find_mbus_format(sdformat->format.code,
@@ -1015,14 +1013,14 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi,
                                                         false);
                        sdformat->format.code = (*cc)->codes[0];
                }
-
-               imx_media_fill_default_mbus_fields(&sdformat->format, in_fmt,
-                                                  false);
                break;
        default:
                return -EINVAL;
                break;
        }
+
+       imx_media_try_colorimetry(&sdformat->format, false);
+
        return 0;
 }
 
-- 
2.17.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to