summaryrefslogtreecommitdiff
path: root/isp/omap3isp.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2011-07-25 01:37:20 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2011-09-04 15:37:55 +0200
commit9f0f82fe95718938042163e469da045011e68ce6 (patch)
treecf57cd5e27d727b97543403bb848c1aea3444318 /isp/omap3isp.c
parenta6204cac1cbccd03307626782c93c34242c5ee2a (diff)
Configure formats in omap3_isp_pipeline_activate()
And remove the omap3_isp_pipeline_set_format() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'isp/omap3isp.c')
-rw-r--r--isp/omap3isp.c163
1 files changed, 49 insertions, 114 deletions
diff --git a/isp/omap3isp.c b/isp/omap3isp.c
index c41e514..2ee87c5 100644
--- a/isp/omap3isp.c
+++ b/isp/omap3isp.c
@@ -68,19 +68,6 @@ static int setup_link(struct omap3_isp_device *isp, struct media_entity *source,
return ret;
}
-static struct media_entity_link *entity_output_link(struct media_entity *entity)
-{
- unsigned int i;
-
- for (i = 0; i < entity->num_links; ++i) {
- if (entity->links[i].source->entity == entity &&
- entity->links[i].flags & MEDIA_LNK_FL_ENABLED)
- return &entity->links[i];
- }
-
- return NULL;
-}
-
static struct media_entity *entity_output_node(struct media_entity *entity)
{
struct media_entity *node;
@@ -297,104 +284,87 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,
return ret;
}
- source->source.format = format;
+ source->source.format = *ofmt;
return 0;
}
static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp,
struct omap3_isp_pipeline *pipe)
{
- struct omap3_isp_entity *entity;
+ struct v4l2_mbus_framefmt format;
+ struct omap3_isp_entity *source = NULL;
+ struct omap3_isp_entity *sink;
+ struct media_entity_pad *pad;
int ret;
ret = media_reset_links(isp->mdev);
if (ret < 0)
return ret;
- list_for_each_entry(entity, &pipe->entities, list) {
- if (entity->source.link == NULL)
- break;
+ list_for_each_entry(sink, &pipe->entities, list) {
+ if (source == NULL) {
+ format = sink->source.format;
+ source = sink;
+ continue;
+ }
- ret = setup_link(isp, entity->source.link->source->entity,
- entity->source.link->sink->entity,
+ /* Enable the link. */
+ ret = setup_link(isp, source->entity, sink->entity,
MEDIA_LNK_FL_ENABLED);
if (ret < 0)
return ret;
- }
-
- return 0;
-}
-
-static int omap3_isp_pipeline_set_format(struct omap3_isp_device *isp,
- struct v4l2_mbus_framefmt *ofmt,
- enum omap3_isp_scaler scaler,
- enum v4l2_subdev_format_whence which)
-{
- struct v4l2_mbus_framefmt format;
- struct media_entity_link *link;
- struct media_entity_pad *pad;
- struct media_entity *entity;
- int ret;
-
- /* Configure formats. Start from the sensor output and propagate the
- * format through the pipeline.
- */
-
- /* When scaling on the ISP, select the sensor default output format.
- * Otherwise scale as much as possible on the sensor.
- */
- if (scaler == OMAP3_ISP_SCALER_ISP)
- format = isp->sensor_format;
- else
- format = *ofmt;
- ret = v4l2_subdev_set_format(isp->sensor, &format, 0, which);
- if (ret < 0) {
- printf("error: get format on sensor output failed.\n");
- return ret;
- }
-
- for (entity = isp->sensor; ; ) {
-
- link = entity_output_link(entity);
- if (link == NULL)
+ if (media_entity_type(sink->entity) == MEDIA_ENT_T_DEVNODE)
break;
- entity = link->sink->entity;
- if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
- break;
+ /* Configure formats.
+ *
+ * HACK: The number of columns cropped by the preview engine for
+ * its internal operations requirements depend on whether the
+ * CCDC to preview engine link is enabled or not. This can lead
+ * to inconsistent results if the link state is changed between
+ * trying formats on the pipeline and applying them. For this
+ * reason, instead of blindly applying formats that have been
+ * tried earlier, repropagate them through the pipeline.
+ */
+ pad = source->source.link->source;
- pad = link->source;
- ret = v4l2_subdev_get_format(pad->entity, &format, pad->index, which);
+ ret = v4l2_subdev_get_format(pad->entity, &format, pad->index,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret < 0) {
printf("error: get format failed on %s:%u.\n",
pad->entity->info.name, pad->index);
return ret;
}
- /* Try to force the output format code onto the output pad. */
- format.code = ofmt->code;
- ret = v4l2_subdev_set_format(pad->entity, &format, pad->index, which);
+ format.code = source->source.format.code;
+ ret = v4l2_subdev_set_format(pad->entity, &format, pad->index,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret < 0) {
printf("error: set format failed on %s:%u.\n",
pad->entity->info.name, pad->index);
return ret;
}
- pad = link->sink;
- ret = v4l2_subdev_set_format(pad->entity, &format, pad->index, which);
+ /* Propagate the format to the link target. */
+ pad = sink->sink.link->sink;
+
+ ret = v4l2_subdev_set_format(pad->entity, &format, pad->index,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret < 0) {
printf("error: set format failed on %s:%u.\n",
pad->entity->info.name, pad->index);
return ret;
}
+
+ source = sink;
}
- if (ofmt == NULL)
- return 0;
+ pad = source->source.link->source;
+ format = source->source.format;
- pad = link->source;
- ret = v4l2_subdev_set_format(pad->entity, ofmt, pad->index, which);
+ ret = v4l2_subdev_set_format(pad->entity, &format, pad->index,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret < 0) {
printf("error: set format failed on %s:%u.\n",
pad->entity->info.name, pad->index);
@@ -510,24 +480,9 @@ void omap3_isp_close(struct omap3_isp_device *isp)
* Viewfinder
*/
-static int omap3_isp_viewfinder_setup_pipeline(struct omap3_isp_device *isp,
- struct v4l2_mbus_framefmt *ofmt)
+static int omap3_isp_viewfinder_setup_pipeline(struct omap3_isp_device *isp)
{
- int ret;
-
- ret = omap3_isp_pipeline_activate(isp, &isp->viewfinder);
- if (ret < 0)
- return ret;
-
- /* Configure the formats on the pipeline. */
- ret = omap3_isp_pipeline_set_format(isp, ofmt, isp->viewfinder.output.scaler,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- if (ret < 0) {
- printf("error: unable to configure formats on pipeline.\n");
- return ret;
- }
-
- return 0;
+ return omap3_isp_pipeline_activate(isp, &isp->viewfinder);
}
int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
@@ -551,7 +506,7 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
return ret;
/* Setup the pipeline. */
- ret = omap3_isp_viewfinder_setup_pipeline(isp, ofmt);
+ ret = omap3_isp_viewfinder_setup_pipeline(isp);
if (ret < 0)
return ret;
@@ -675,7 +630,7 @@ int omap3_isp_viewfinder_start(struct omap3_isp_device *isp)
ret = v4l2_stream_on(isp->viewfinder.output.video);
if (ret < 0) {
- printf("error: streamon failed for viewfinder\n");
+ printf("error: streamon failed for viewfinder (%d)\n", ret);
return ret;
}
@@ -725,25 +680,9 @@ int omap3_isp_viewfinder_put_buffer(struct omap3_isp_device *isp,
* omap3_isp_snapshot_setup() before starting the viewfinder.
*/
-static int omap3_isp_snapshot_setup_pipeline(struct omap3_isp_device *isp,
- struct v4l2_mbus_framefmt *ofmt)
+static int omap3_isp_snapshot_setup_pipeline(struct omap3_isp_device *isp)
{
- int ret;
-
- /* Setup the links. */
- ret = omap3_isp_pipeline_activate(isp, &isp->snapshot);
- if (ret < 0)
- return ret;
-
- /* Configure the formats on the pipeline. */
- ret = omap3_isp_pipeline_set_format(isp, ofmt, isp->snapshot.output.scaler,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- if (ret < 0) {
- printf("error: unable to configure formats on pipeline.\n");
- return ret;
- }
-
- return 0;
+ return omap3_isp_pipeline_activate(isp, &isp->snapshot);
}
int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
@@ -841,7 +780,6 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
static void omap3_isp_snapshot_event(void *priv)
{
struct omap3_isp_device *isp = priv;
- struct v4l2_mbus_framefmt format;
struct v4l2_video_buffer buffer;
unsigned int i;
int ret;
@@ -866,8 +804,7 @@ static void omap3_isp_snapshot_event(void *priv)
isp->ops->snapshot_ready(isp, &buffer);
/* Resume the viewfinder. */
- format = isp->viewfinder.output.format;
- ret = omap3_isp_viewfinder_setup_pipeline(isp, &format);
+ ret = omap3_isp_viewfinder_setup_pipeline(isp);
if (ret < 0)
return;
@@ -891,7 +828,6 @@ static void omap3_isp_snapshot_event(void *priv)
int omap3_isp_snapshot_capture(struct omap3_isp_device *isp)
{
- struct v4l2_mbus_framefmt format;
int ret;
/* Suspend the viewfinder. */
@@ -902,8 +838,7 @@ int omap3_isp_snapshot_capture(struct omap3_isp_device *isp)
}
/* Configure the pipeline. */
- format = isp->snapshot.output.format;
- ret = omap3_isp_snapshot_setup_pipeline(isp, &format);
+ ret = omap3_isp_snapshot_setup_pipeline(isp);
if (ret < 0) {
printf("error: unable to setup snapshot pipeline.\n");
return ret;