From 9f0f82fe95718938042163e469da045011e68ce6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 25 Jul 2011 01:37:20 +0200 Subject: Configure formats in omap3_isp_pipeline_activate() And remove the omap3_isp_pipeline_set_format() function. Signed-off-by: Laurent Pinchart --- isp/omap3isp.c | 163 +++++++++++++++++---------------------------------------- 1 file changed, 49 insertions(+), 114 deletions(-) (limited to 'isp/omap3isp.c') 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; -- cgit v1.2.3