Esempio n. 1
0
static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
{
	u32 walign;

	if (!rvin_format_from_pixel(pix->pixelformat) ||
	    (vin->info->model == RCAR_M1 &&
	     pix->pixelformat == V4L2_PIX_FMT_XBGR32))
		pix->pixelformat = RVIN_DEFAULT_FORMAT;

	switch (pix->field) {
	case V4L2_FIELD_TOP:
	case V4L2_FIELD_BOTTOM:
	case V4L2_FIELD_NONE:
	case V4L2_FIELD_INTERLACED_TB:
	case V4L2_FIELD_INTERLACED_BT:
	case V4L2_FIELD_INTERLACED:
		break;
	case V4L2_FIELD_ALTERNATE:
		/*
		 * Driver does not (yet) support outputting ALTERNATE to a
		 * userspace. It does support outputting INTERLACED so use
		 * the VIN hardware to combine the two fields.
		 */
		pix->field = V4L2_FIELD_INTERLACED;
		pix->height *= 2;
		break;
	default:
		pix->field = RVIN_DEFAULT_FIELD;
		break;
	}

	/* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
	walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;

	/* Limit to VIN capabilities */
	v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
			      &pix->height, 4, vin->info->max_height, 2, 0);

	pix->bytesperline = rvin_format_bytesperline(pix);
	pix->sizeimage = rvin_format_sizeimage(pix);

	vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n",
		pix->width, pix->height, pix->bytesperline, pix->sizeimage);
}
Esempio n. 2
0
static int __rvin_try_format(struct rvin_dev *vin,
			     u32 which,
			     struct v4l2_pix_format *pix,
			     struct rvin_source_fmt *source)
{
	const struct rvin_video_format *info;
	u32 rwidth, rheight, walign;

	/* Requested */
	rwidth = pix->width;
	rheight = pix->height;

	/* Keep current field if no specific one is asked for */
	if (pix->field == V4L2_FIELD_ANY)
		pix->field = vin->format.field;

	/*
	 * Retrieve format information and select the current format if the
	 * requested format isn't supported.
	 */
	info = rvin_format_from_pixel(pix->pixelformat);
	if (!info) {
		vin_dbg(vin, "Format %x not found, keeping %x\n",
			pix->pixelformat, vin->format.pixelformat);
		*pix = vin->format;
		pix->width = rwidth;
		pix->height = rheight;
	}

	/* Always recalculate */
	pix->bytesperline = 0;
	pix->sizeimage = 0;

	/* Limit to source capabilities */
	__rvin_try_format_source(vin, which, pix, source);

	switch (pix->field) {
	case V4L2_FIELD_TOP:
	case V4L2_FIELD_BOTTOM:
	case V4L2_FIELD_ALTERNATE:
		pix->height /= 2;
		source->height /= 2;
		break;
	case V4L2_FIELD_NONE:
	case V4L2_FIELD_INTERLACED_TB:
	case V4L2_FIELD_INTERLACED_BT:
	case V4L2_FIELD_INTERLACED:
		break;
	default:
		pix->field = V4L2_FIELD_NONE;
		break;
	}

	/* If source can't match format try if VIN can scale */
	if (source->width != rwidth || source->height != rheight)
		rvin_scale_try(vin, pix, rwidth, rheight);

	/* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
	walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;

	/* Limit to VIN capabilities */
	v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign,
			      &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);

	pix->bytesperline = max_t(u32, pix->bytesperline,
				  rvin_format_bytesperline(pix));
	pix->sizeimage = max_t(u32, pix->sizeimage,
			       rvin_format_sizeimage(pix));

	if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
		vin_err(vin, "pixel format XBGR32 not supported on M1\n");
		return -EINVAL;
	}

	vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n",
		rwidth, rheight, pix->width, pix->height,
		pix->bytesperline, pix->sizeimage);

	return 0;
}