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

[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
...@@ -793,6 +793,21 @@ static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv, ...@@ -793,6 +793,21 @@ static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
return 0; 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 * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
* elements * elements
...@@ -808,19 +823,23 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, ...@@ -808,19 +823,23 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
{ {
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR]; 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_subdev_format sfmt;
struct v4l2_mbus_framefmt *mf = &sfmt.format; struct v4l2_mbus_framefmt *mf = &sfmt.format;
struct fimc_fmt *ffmt = NULL; struct media_entity *me;
int ret, i = 0; struct fimc_fmt *ffmt;
struct media_pad *pad;
int ret, i = 1;
u32 fcc;
if (WARN_ON(!sd || !tfmt)) if (WARN_ON(!sd || !tfmt))
return -EINVAL; return -EINVAL;
memset(&sfmt, 0, sizeof(sfmt)); memset(&sfmt, 0, sizeof(sfmt));
sfmt.format = *tfmt; sfmt.format = *tfmt;
sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY; sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
me = fimc_pipeline_get_head(&sd->entity);
while (1) { while (1) {
ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL, ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
FMT_FLAGS_CAM, i++); FMT_FLAGS_CAM, i++);
...@@ -833,32 +852,45 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, ...@@ -833,32 +852,45 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
} }
mf->code = tfmt->code = ffmt->mbus_code; 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); ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
if (ret) if (ret)
return ret; return ret;
if (mf->code != tfmt->code) {
mf->code = 0; if (me->pads[0].flags & MEDIA_PAD_FL_SINK) {
continue; 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->width = mf->width;
tfmt->height = mf->height; tfmt->height = mf->height;
ffmt = fimc_capture_try_format(ctx, ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
&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); NULL, &fcc, FIMC_SD_PAD_SOURCE);
if (ffmt && ffmt->mbus_code) if (ffmt && ffmt->mbus_code)
mf->code = ffmt->mbus_code; mf->code = ffmt->mbus_code;
if (mf->width != tfmt->width || if (mf->width != tfmt->width || mf->height != tfmt->height)
mf->height != tfmt->height)
continue; continue;
tfmt->code = mf->code; 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; break;
} }
...@@ -866,7 +898,6 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, ...@@ -866,7 +898,6 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
*fmt_id = ffmt; *fmt_id = ffmt;
*tfmt = *mf; *tfmt = *mf;
dbg("code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment