summaryrefslogtreecommitdiff
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
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>
-rw-r--r--isp/omap3isp-priv.h2
-rw-r--r--isp/omap3isp.c248
-rw-r--r--isp/omap3isp.h22
3 files changed, 100 insertions, 172 deletions
diff --git a/isp/omap3isp-priv.h b/isp/omap3isp-priv.h
index c9f73a1..4e24d31 100644
--- a/isp/omap3isp-priv.h
+++ b/isp/omap3isp-priv.h
@@ -75,7 +75,6 @@ struct omap3_isp_entity {
* @video: V4L2 capture device
* @format: Current video format
* @pool: Buffers pool
- * @dequeued: Bitmask of dequeued buffers that belong to the application
* @queued: Number of buffers queued to the driver
* @running: Whether video capture is running on the device
*/
@@ -85,7 +84,6 @@ struct omap3_isp_video {
struct v4l2_device *video;
struct v4l2_mbus_framefmt format;
struct v4l2_buffers_pool *pool;
- unsigned int dequeued;
unsigned int queued;
bool running;
};
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)
{
diff --git a/isp/omap3isp.h b/isp/omap3isp.h
index 16c96bd..93ddfff 100644
--- a/isp/omap3isp.h
+++ b/isp/omap3isp.h
@@ -48,7 +48,7 @@ struct omap3_isp_operations {
void (*prepare_streamon)(struct omap3_isp_device *isp);
void (*viewfinder_ready)(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer);
- bool (*snapshot_ready)(struct omap3_isp_device *isp,
+ void (*snapshot_ready)(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer);
void (*aewb_ready)(struct omap3_isp_device *isp,
const struct omap3_isp_aewb_stats *stats);
@@ -61,33 +61,30 @@ struct omap3_isp_device *omap3_isp_open(const char *devname,
const struct omap3_isp_operations *ops);
void omap3_isp_close(struct omap3_isp_device *isp);
+/* Viewfinder */
int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,
struct v4l2_mbus_framefmt *ofmt);
int omap3_isp_viewfinder_set_pool(struct omap3_isp_device *isp,
struct v4l2_buffers_pool *pool);
int omap3_isp_viewfinder_set_scaler(struct omap3_isp_device *isp,
enum omap3_isp_scaler scaler);
-int omap3_isp_viewfinder_start(struct omap3_isp_device *isp);
+int omap3_isp_viewfinder_start(struct omap3_isp_device *isp, unsigned int bufs);
int omap3_isp_viewfinder_stop(struct omap3_isp_device *isp);
int omap3_isp_viewfinder_put_buffer(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer);
int omap3_isp_viewfinder_pan_zoom(struct omap3_isp_device *isp,
float x, float y, float zoom);
+/* Snapshot */
int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,
struct v4l2_rect *crop,
struct v4l2_mbus_framefmt *ofmt);
int omap3_isp_snapshot_capture(struct omap3_isp_device *isp);
+int omap3_isp_snapshot_done(struct omap3_isp_device *isp);
int omap3_isp_snapshot_put_buffer(struct omap3_isp_device *isp,
struct v4l2_video_buffer *buffer);
-int omap3_isp_ccdc_set_black_level(struct omap3_isp_device *isp, unsigned int value);
-
-int omap3_isp_preview_set_contrast(struct omap3_isp_device *isp, unsigned int value);
-int omap3_isp_preview_set_saturation(struct omap3_isp_device *isp, float value);
-int omap3_isp_preview_set_gain(struct omap3_isp_device *isp, float gain);
-int omap3_isp_preview_set_white_balance(struct omap3_isp_device *isp, float gains[4]);
-
+/* Processing parameters */
#define OMAP3_ISP_SENSOR_GAIN_KEEP -1
int omap3_isp_sensor_get_exposure(struct omap3_isp_device *isp,
@@ -98,4 +95,11 @@ int omap3_isp_sensor_set_gain(struct omap3_isp_device *isp, unsigned int gain);
int omap3_isp_sensor_set_gains(struct omap3_isp_device *isp,
int red, int green, int blue);
+int omap3_isp_ccdc_set_black_level(struct omap3_isp_device *isp, unsigned int value);
+
+int omap3_isp_preview_set_contrast(struct omap3_isp_device *isp, unsigned int value);
+int omap3_isp_preview_set_saturation(struct omap3_isp_device *isp, float value);
+int omap3_isp_preview_set_gain(struct omap3_isp_device *isp, float gain);
+int omap3_isp_preview_set_white_balance(struct omap3_isp_device *isp, float gains[4]);
+
#endif