summaryrefslogtreecommitdiff
path: root/isp/omap3isp.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-07-04 12:46:53 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-10-20 21:28:24 +0200
commitb2f773c5c53c2efe108e44e176a604bca79a6d4b (patch)
tree616717c68848449d76d6007e14e8c88570199fa2 /isp/omap3isp.c
parent51e34d1d5a4a18b8f918eaf9a6e9adf6ea1dcc76 (diff)
isp: Split the viewfinder and snapshot API
Don't suspend and resume the viewfinder implicitly when taking a snapshot, but let the application stop the viewfinder before taking the snapshot, and restart it afterwards. Applications are now responsible for keeping track of the viewfinder output buffers state and pass of bitmask of output buffers indices to be queued when starting the viewfinder. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'isp/omap3isp.c')
-rw-r--r--isp/omap3isp.c248
1 files changed, 87 insertions, 161 deletions
diff --git a/isp/omap3isp.c b/isp/omap3isp.c
index 8b87b10..0c677b4 100644
--- a/isp/omap3isp.c
+++ b/isp/omap3isp.c
@@ -933,8 +933,6 @@ static int omap3_isp_pipeline_put_buffer(struct omap3_isp_device *isp,
void(*callback)(void*),
struct v4l2_video_buffer *buffer)
{
- pipe->output->dequeued &= ~(1 << buffer->index);
-
if (!pipe->output->running)
return 0;
@@ -1106,81 +1104,12 @@ static void omap3_isp_viewfinder_event(void *priv)
return;
}
- isp->viewfinder.output->dequeued |= 1 << buffer.index;
-
if (isp->viewfinder.output->queued == 0)
isp->ops->unwatch_fd(isp->viewfinder.output->video->fd);
isp->ops->viewfinder_ready(isp, &buffer);
}
-static int __omap3_isp_viewfinder_start(struct omap3_isp_device *isp)
-{
- struct v4l2_video_buffer buffer;
- struct omap3_isp_pool *pool;
- unsigned int i;
- int ret;
-
- /* Queue all buffers for video capture. */
- for (i = 0; i < isp->viewfinder.output->video->nbufs; ++i) {
- if (isp->viewfinder.output->dequeued & (1 << i))
- continue;
-
- buffer.index = i;
-
- ret = omap3_isp_video_queue_buffer(isp->viewfinder.output, &buffer);
- if (ret < 0) {
- printf("error: unable to queue buffer %u (%d)\n", i, ret);
- return ret;
- }
- }
-
- if (isp->ops->prepare_streamon)
- isp->ops->prepare_streamon(isp);
-
- /* Start the pools. */
- list_for_each_entry(pool, &isp->viewfinder.pools, list)
- omap3_isp_pool_start(pool);
-
- /* Watch the viewfinder file descriptor. */
- isp->ops->watch_fd(isp->viewfinder.output->video->fd,
- OMAP3_ISP_EVENT_READ, omap3_isp_viewfinder_event,
- isp);
-
- /* Start the statistics engine. */
- omap3_isp_stats_start(isp);
-
- ret = omap3_isp_video_start(isp->viewfinder.output);
- if (ret < 0) {
- printf("error: streamon failed for viewfinder (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __omap3_isp_viewfinder_stop(struct omap3_isp_device *isp)
-{
- struct omap3_isp_pool *pool;
- int ret;
-
- isp->ops->unwatch_fd(isp->viewfinder.output->video->fd);
-
- omap3_isp_stats_stop(isp);
-
- ret = omap3_isp_video_stop(isp->viewfinder.output);
- if (ret < 0) {
- printf("error: streamoff failed for viewfinder\n");
- return ret;
- }
-
- /* Stop the pools. */
- list_for_each_entry(pool, &isp->viewfinder.pools, list)
- omap3_isp_pool_stop(pool);
-
- return 0;
-}
-
static int omap3_isp_viewfinder_setup_pipeline(struct omap3_isp_device *isp)
{
return omap3_isp_pipeline_activate(isp, &isp->viewfinder);
@@ -1208,11 +1137,6 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
if (ret < 0)
return ret;
- /* Setup the pipeline. */
- ret = omap3_isp_viewfinder_setup_pipeline(isp);
- if (ret < 0)
- return ret;
-
/* Allocate buffers for intermediate pools. */
list_for_each_entry(pool, &isp->viewfinder.pools, list)
omap3_isp_pool_alloc_buffers(pool);
@@ -1225,6 +1149,8 @@ int omap3_isp_viewfinder_set_pool(struct omap3_isp_device *isp,
{
int ret;
+ isp->viewfinder.output->pool = pool;
+
/* Allocate video buffers. */
ret = v4l2_alloc_buffers(isp->viewfinder.output->video, pool, V4L2_MEMORY_USERPTR);
if (ret < 0) {
@@ -1232,7 +1158,6 @@ int omap3_isp_viewfinder_set_pool(struct omap3_isp_device *isp,
return ret;
}
- isp->viewfinder.output->dequeued = 0;
isp->viewfinder.output->queued = 0;
return 0;
}
@@ -1285,61 +1210,79 @@ int omap3_isp_viewfinder_put_buffer(struct omap3_isp_device *isp,
buffer);
}
-int omap3_isp_viewfinder_start(struct omap3_isp_device *isp)
+int omap3_isp_viewfinder_start(struct omap3_isp_device *isp, unsigned int bufs)
{
+ struct v4l2_video_buffer buffer;
+ struct omap3_isp_pool *pool;
+ unsigned int i;
int ret;
- ret = __omap3_isp_viewfinder_start(isp);
+ /* Setup the pipeline. */
+ ret = omap3_isp_viewfinder_setup_pipeline(isp);
if (ret < 0)
return ret;
- isp->viewfinder.state = OMAP3_ISP_PIPELINE_RUNNING;
- return 0;
-}
+ /* Queue buffers for video capture. */
+ for (i = 0; i < isp->viewfinder.output->video->nbufs; ++i) {
+ /* Don't queue buffer that are under control of the application. */
+ if (!(bufs & (1 << i)))
+ continue;
-int omap3_isp_viewfinder_stop(struct omap3_isp_device *isp)
-{
- int ret;
+ buffer.index = i;
- ret = __omap3_isp_viewfinder_stop(isp);
- if (ret < 0)
- return ret;
+ ret = omap3_isp_video_queue_buffer(isp->viewfinder.output, &buffer);
+ if (ret < 0) {
+ printf("error: unable to queue buffer %u (%d)\n", i, ret);
+ return ret;
+ }
+ }
- isp->viewfinder.state = OMAP3_ISP_PIPELINE_STOPPED;
- return 0;
-}
+ if (isp->ops->prepare_streamon)
+ isp->ops->prepare_streamon(isp);
-static int omap3_isp_viewfinder_suspend(struct omap3_isp_device *isp)
-{
- int ret;
+ /* Start the pools. */
+ list_for_each_entry(pool, &isp->viewfinder.pools, list)
+ omap3_isp_pool_start(pool);
- if (isp->viewfinder.state != OMAP3_ISP_PIPELINE_RUNNING)
- return 0;
+ /* Watch the viewfinder file descriptor. */
+ if (isp->viewfinder.output->queued)
+ isp->ops->watch_fd(isp->viewfinder.output->video->fd,
+ OMAP3_ISP_EVENT_READ,
+ omap3_isp_viewfinder_event, isp);
- ret = __omap3_isp_viewfinder_stop(isp);
- if (ret < 0)
+ /* Start the statistics engine. */
+ omap3_isp_stats_start(isp);
+
+ ret = omap3_isp_video_start(isp->viewfinder.output);
+ if (ret < 0) {
+ printf("error: streamon failed for viewfinder (%d)\n", ret);
return ret;
+ }
- isp->viewfinder.state = OMAP3_ISP_PIPELINE_SUSPENDED;
+ isp->viewfinder.state = OMAP3_ISP_PIPELINE_RUNNING;
return 0;
}
-static int omap3_isp_viewfinder_resume(struct omap3_isp_device *isp)
+int omap3_isp_viewfinder_stop(struct omap3_isp_device *isp)
{
+ struct omap3_isp_pool *pool;
int ret;
- if (isp->viewfinder.state != OMAP3_ISP_PIPELINE_SUSPENDED)
- return 0;
+ isp->ops->unwatch_fd(isp->viewfinder.output->video->fd);
- ret = omap3_isp_viewfinder_setup_pipeline(isp);
- if (ret < 0)
- return ret;
+ omap3_isp_stats_stop(isp);
- ret = omap3_isp_viewfinder_start(isp);
- if (ret < 0)
+ ret = omap3_isp_video_stop(isp->viewfinder.output);
+ if (ret < 0) {
+ printf("error: streamoff failed for viewfinder\n");
return ret;
+ }
- isp->viewfinder.state = OMAP3_ISP_PIPELINE_RUNNING;
+ /* Stop the pools. */
+ list_for_each_entry(pool, &isp->viewfinder.pools, list)
+ omap3_isp_pool_stop(pool);
+
+ isp->viewfinder.state = OMAP3_ISP_PIPELINE_STOPPED;
return 0;
}
@@ -1356,11 +1299,6 @@ int omap3_isp_viewfinder_pan_zoom(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)
-{
- return omap3_isp_pipeline_activate(isp, &isp->snapshot);
-}
-
int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
struct v4l2_rect *crop,
struct v4l2_mbus_framefmt *ofmt)
@@ -1430,70 +1368,27 @@ static void omap3_isp_snapshot_event(void *priv)
{
struct omap3_isp_device *isp = priv;
struct v4l2_video_buffer buffer;
- unsigned int i;
- bool again;
int ret;
- /* Dequeue a buffer, stop the stream and fire the snapshot event. */
+ /* Dequeue a buffer and fire the snapshot event. */
ret = omap3_isp_video_dequeue_buffer(isp->snapshot.output, &buffer);
if (ret < 0) {
printf("error: unable to dequeue snapshot buffer.\n");
return;
}
- again = isp->ops->snapshot_ready(isp, &buffer);
-
- if (again) {
- isp->snapshot.output->dequeued |= 1 << buffer.index;
-
- if (isp->snapshot.output->queued == 0)
- isp->ops->unwatch_fd(isp->snapshot.output->video->fd);
-
- return;
- }
-
- /* We're done, stop the stream and resume the viewfinder. */
- isp->ops->unwatch_fd(isp->snapshot.output->video->fd);
-
- omap3_isp_stats_stop(isp);
-
- ret = omap3_isp_video_stop(isp->snapshot.output);
- if (ret < 0) {
- printf("error: streamoff failed for snapshot\n");
- return;
- }
-
- ret = omap3_isp_viewfinder_resume(isp);
- if (ret < 0) {
- printf("error: unable to resume viewfinder.\n");
- return;
- }
+ if (isp->snapshot.output->queued == 0)
+ isp->ops->unwatch_fd(isp->snapshot.output->video->fd);
- /* Queue all buffers for the next snapshot. */
- for (i = 0; i < isp->snapshot.output->video->nbufs; ++i) {
- buffer.index = i;
-
- ret = omap3_isp_video_queue_buffer(isp->snapshot.output, &buffer);
- if (ret < 0) {
- printf("error: unable to queue buffer %u\n", i);
- return;
- }
- }
+ isp->ops->snapshot_ready(isp, &buffer);
}
int omap3_isp_snapshot_capture(struct omap3_isp_device *isp)
{
int ret;
- /* Suspend the viewfinder. */
- ret = omap3_isp_viewfinder_suspend(isp);
- if (ret < 0) {
- printf("error: unable to suspend viewfinder.\n");
- return ret;
- }
-
/* Configure the pipeline. */
- ret = omap3_isp_snapshot_setup_pipeline(isp);
+ ret = omap3_isp_pipeline_activate(isp, &isp->snapshot);
if (ret < 0) {
printf("error: unable to setup snapshot pipeline.\n");
return ret;
@@ -1518,6 +1413,37 @@ int omap3_isp_snapshot_capture(struct omap3_isp_device *isp)
return 0;
}
+int omap3_isp_snapshot_done(struct omap3_isp_device *isp)
+{
+ struct v4l2_video_buffer buffer;
+ unsigned int i;
+ int ret;
+
+ /* We're done, stop the snapshot stream. */
+ isp->ops->unwatch_fd(isp->snapshot.output->video->fd);
+
+ omap3_isp_stats_stop(isp);
+
+ ret = omap3_isp_video_stop(isp->snapshot.output);
+ if (ret < 0) {
+ printf("error: streamoff failed for snapshot\n");
+ return ret;
+ }
+
+ /* Queue all buffers for the next snapshot. */
+ for (i = 0; i < isp->snapshot.output->video->nbufs; ++i) {
+ buffer.index = i;
+
+ ret = omap3_isp_video_queue_buffer(isp->snapshot.output, &buffer);
+ if (ret < 0) {
+ printf("error: unable to queue buffer %u\n", i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
int omap3_isp_snapshot_put_buffer(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer)
{