Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47800bc4 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-fimc: Improved pipeline try format routine



Make the pipeline try format routine more generic to support any
number of subdevs in the pipeline, rather than hard coding it for
only a sensor, MIPI-CSIS and FIMC subdevs and the FIMC video node.

Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2bffebc1
Loading
Loading
Loading
Loading
+61 −30
Original line number Diff line number Diff line
@@ -793,6 +793,21 @@ static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
	return 0;
}

static struct media_entity *fimc_pipeline_get_head(struct media_entity *me)
{
	struct media_pad *pad = &me->pads[0];

	while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
		pad = media_entity_remote_source(pad);
		if (!pad)
			break;
		me = pad->entity;
		pad = &me->pads[0];
	}

	return me;
}

/**
 * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
 *                            elements
@@ -808,19 +823,23 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
{
	struct fimc_dev *fimc = ctx->fimc_dev;
	struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
	struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
	struct v4l2_subdev_format sfmt;
	struct v4l2_mbus_framefmt *mf = &sfmt.format;
	struct fimc_fmt *ffmt = NULL;
	int ret, i = 0;
	struct media_entity *me;
	struct fimc_fmt *ffmt;
	struct media_pad *pad;
	int ret, i = 1;
	u32 fcc;

	if (WARN_ON(!sd || !tfmt))
		return -EINVAL;

	memset(&sfmt, 0, sizeof(sfmt));
	sfmt.format = *tfmt;

	sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;

	me = fimc_pipeline_get_head(&sd->entity);

	while (1) {
		ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
					FMT_FLAGS_CAM, i++);
@@ -833,32 +852,45 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
		}
		mf->code = tfmt->code = ffmt->mbus_code;

		/* set format on all pipeline subdevs */
		while (me != &fimc->vid_cap.subdev.entity) {
			sd = media_entity_to_v4l2_subdev(me);

			sfmt.pad = 0;
			ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
			if (ret)
				return ret;
		if (mf->code != tfmt->code) {
			mf->code = 0;
			continue;

			if (me->pads[0].flags & MEDIA_PAD_FL_SINK) {
				sfmt.pad = me->num_pads - 1;
				mf->code = tfmt->code;
				ret = v4l2_subdev_call(sd, pad, set_fmt, NULL,
									&sfmt);
				if (ret)
					return ret;
			}

			pad = media_entity_remote_source(&me->pads[sfmt.pad]);
			if (!pad)
				return -EINVAL;
			me = pad->entity;
		}
		if (mf->width != tfmt->width || mf->height != tfmt->height) {
			u32 fcc = ffmt->fourcc;

		if (mf->code != tfmt->code)
			continue;

		fcc = ffmt->fourcc;
		tfmt->width  = mf->width;
		tfmt->height = mf->height;
			ffmt = fimc_capture_try_format(ctx,
					       &tfmt->width, &tfmt->height,
		ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
					NULL, &fcc, FIMC_SD_PAD_SINK);
		ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
					NULL, &fcc, FIMC_SD_PAD_SOURCE);
		if (ffmt && ffmt->mbus_code)
			mf->code = ffmt->mbus_code;
			if (mf->width != tfmt->width ||
			    mf->height != tfmt->height)
		if (mf->width != tfmt->width || mf->height != tfmt->height)
			continue;
		tfmt->code = mf->code;
		}
		if (csis)
			ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt);

		if (mf->code == tfmt->code &&
		    mf->width == tfmt->width && mf->height == tfmt->height)
		break;
	}

@@ -866,7 +898,6 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
		*fmt_id = ffmt;
	*tfmt = *mf;

	dbg("code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
	return 0;
}