diff options
Diffstat (limited to 'isp')
-rw-r--r-- | isp/omap3isp-priv.h | 2 | ||||
-rw-r--r-- | isp/omap3isp.c | 118 |
2 files changed, 61 insertions, 59 deletions
diff --git a/isp/omap3isp-priv.h b/isp/omap3isp-priv.h index 9706ba8..b143b13 100644 --- a/isp/omap3isp-priv.h +++ b/isp/omap3isp-priv.h @@ -51,6 +51,7 @@ enum omap3_isp_entity_type { * @entity: Media entity information * @sink: Sink pad * @source: Sink pad + * @last: Indicates whether this is the last entity in the pipeline */ struct omap3_isp_entity { struct list_entry list; @@ -58,6 +59,7 @@ struct omap3_isp_entity { struct media_entity *entity; struct omap3_isp_pad sink; struct omap3_isp_pad source; + bool last; }; /* diff --git a/isp/omap3isp.c b/isp/omap3isp.c index 7ab90c4..24d956c 100644 --- a/isp/omap3isp.c +++ b/isp/omap3isp.c @@ -88,6 +88,26 @@ static __u32 mbus_to_pix(enum v4l2_mbus_pixelcode code) } } +static enum v4l2_mbus_pixelcode pix_to_mbus(__u32 pixelformat) +{ + switch (pixelformat) { + case V4L2_PIX_FMT_SBGGR10: + return V4L2_MBUS_FMT_SBGGR10_1X10; + case V4L2_PIX_FMT_SGBRG10: + return V4L2_MBUS_FMT_SGBRG10_1X10; + case V4L2_PIX_FMT_SGRBG10: + return V4L2_MBUS_FMT_SGRBG10_1X10; + case V4L2_PIX_FMT_SRGGB10: + return V4L2_MBUS_FMT_SRGGB10_1X10; + case V4L2_PIX_FMT_UYVY: + return V4L2_MBUS_FMT_UYVY8_1X16; + case V4L2_PIX_FMT_YUYV: + return V4L2_MBUS_FMT_YUYV8_1X16; + default: + return 0; + } +} + static const char *entity_name(struct omap3_isp_entity *entity) { if (entity == NULL) @@ -316,6 +336,7 @@ static int omap3_isp_pipeline_build(struct omap3_isp_device *isp, } pipe->output = to_omap3_isp_video(source); + source->last = true; va_end(ap); ret = 0; @@ -333,9 +354,10 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp, enum omap3_isp_scaler scaler) { struct v4l2_mbus_framefmt format; + struct v4l2_pix_format v4l2_fmt; struct omap3_isp_entity *source = NULL; struct omap3_isp_entity *sink; - struct omap3_isp_entity *last = NULL; + struct omap3_isp_video *video; struct media_entity_pad *pad; int ret; @@ -376,7 +398,11 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp, return ret; } - format.code = ofmt->code; + if (sink->last) + format = *ofmt; + else + format.code = ofmt->code; + ret = v4l2_subdev_set_format(pad->entity, &format, pad->index, V4L2_SUBDEV_FORMAT_TRY); if (ret < 0) { @@ -386,6 +412,8 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp, } source->source.format = format; + if (sink->last) + *ofmt = format; } if (sink->type == OMAP3_ISP_ENTITY_ENTITY) { @@ -401,24 +429,34 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp, } sink->sink.format = format; - last = sink; - } - - source = sink; - } + } else if (sink->type == OMAP3_ISP_ENTITY_VIDEO) { + video = to_omap3_isp_video(sink); + + /* Set the capture format on the capture or output video + * node. If the connected source is a pool, v4l2_fmt + * already contains the format that has been setup on + * the associated capture video node. + */ + if (source->type != OMAP3_ISP_ENTITY_POOL) { + memset(&v4l2_fmt, 0, sizeof v4l2_fmt); + v4l2_fmt.pixelformat = mbus_to_pix(format.code); + v4l2_fmt.width = format.width; + v4l2_fmt.height = format.height; + } - if (last != NULL) { - pad = last->source.link->source; + ret = v4l2_set_format(video->video, &v4l2_fmt); + if (ret < 0) { + printf("error: set format failed on %s.\n", + sink->entity->info.name); + return ret; + } - ret = v4l2_subdev_set_format(pad->entity, ofmt, pad->index, - V4L2_SUBDEV_FORMAT_TRY); - if (ret < 0) { - printf("error: set format failed on %s:%u.\n", - pad->entity->info.name, pad->index); - return ret; + video->format.code = pix_to_mbus(v4l2_fmt.pixelformat); + video->format.width = v4l2_fmt.width; + video->format.height = v4l2_fmt.height; } - last->source.format = *ofmt; + source = sink; } return 0; @@ -430,7 +468,6 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp, struct v4l2_mbus_framefmt format; struct omap3_isp_entity *source = NULL; struct omap3_isp_entity *sink; - struct omap3_isp_entity *last = NULL; struct media_entity_pad *pad; int ret; @@ -475,7 +512,11 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp, return ret; } - format.code = source->source.format.code; + if (sink->last) + format = source->source.format; + else + format.code = source->source.format.code; + ret = v4l2_subdev_set_format(pad->entity, &format, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE); if (ret < 0) { @@ -496,26 +537,11 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp, pad->entity->info.name, pad->index); return ret; } - - last = sink; } source = sink; } - if (last != NULL) { - pad = last->source.link->source; - format = last->source.format; - - 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; - } - } - return 0; } @@ -627,7 +653,6 @@ static int omap3_isp_viewfinder_setup_pipeline(struct omap3_isp_device *isp) int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp, struct v4l2_mbus_framefmt *ofmt) { - struct v4l2_pix_format format; int ret; ret = omap3_isp_pipeline_build(isp, &isp->viewfinder, ENTITY_SENSOR, @@ -651,18 +676,6 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp, if (ret < 0) return ret; - /* Set the capture format on the output video node. */ - memset(&format, 0, sizeof format); - format.pixelformat = mbus_to_pix(ofmt->code); - format.width = ofmt->width; - format.height = ofmt->height; - - ret = v4l2_set_format(isp->viewfinder.output->video, &format); - if (ret < 0) - return ret; - - isp->viewfinder.output->format = *ofmt; - return 0; } @@ -822,7 +835,6 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp, struct v4l2_mbus_framefmt *ofmt) { struct v4l2_video_buffer buffer; - struct v4l2_pix_format format; struct media_entity *entity; unsigned int i; int ret; @@ -858,18 +870,6 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp, if (ret < 0) return ret; - isp->snapshot.output->format = *ofmt; - - /* Set the capture format on the output video node. */ - memset(&format, 0, sizeof format); - format.pixelformat = mbus_to_pix(ofmt->code); - format.width = ofmt->width; - format.height = ofmt->height; - - ret = v4l2_set_format(isp->snapshot.output->video, &format); - if (ret < 0) - return ret; - /* Pre-allocate capture buffers. */ isp->snapshot.output->pool = v4l2_buffers_pool_new(2); if (isp->snapshot.output->pool == NULL) { |