fmt = &formats[f->index];
f->pixelformat = fmt->fourcc;
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return 0;
+
+ /* allow changing the quantization and xfer func for YUV formats */
+ if (v4l2_is_format_yuv(v4l2_format_info(f->pixelformat)))
+ f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION |
+ V4L2_FMT_FLAG_CSC_YCBCR_ENC;
+
return 0;
}
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct rga_fmt *fmt;
+ if (V4L2_TYPE_IS_CAPTURE(f->type)) {
+ const struct rga_frame *frm;
+
+ frm = rga_get_frame(ctx, f->type);
+ if (IS_ERR(frm))
+ return PTR_ERR(frm);
+
+ if (!(pix_fmt->flags & V4L2_PIX_FMT_FLAG_SET_CSC)) {
+ pix_fmt->quantization = frm->pix.quantization;
+ pix_fmt->ycbcr_enc = frm->pix.ycbcr_enc;
+ }
+ /* disallow values not announced in vidioc_enum_fmt */
+ pix_fmt->colorspace = frm->pix.colorspace;
+ pix_fmt->xfer_func = frm->pix.xfer_func;
+ }
+
fmt = rga_fmt_find(pix_fmt->pixelformat);
if (!fmt)
fmt = &formats[0];
frm->fmt = rga_fmt_find(pix_fmt->pixelformat);
frm->stride = pix_fmt->plane_fmt[0].bytesperline;
+ /*
+ * Copy colorimetry from output to capture as required by the
+ * v4l2-compliance tests
+ */
+ if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+ ctx->out.pix.colorspace = pix_fmt->colorspace;
+ ctx->out.pix.ycbcr_enc = pix_fmt->ycbcr_enc;
+ ctx->out.pix.quantization = pix_fmt->quantization;
+ ctx->out.pix.xfer_func = pix_fmt->xfer_func;
+ }
+
/* Reset crop settings */
frm->crop.left = 0;
frm->crop.top = 0;