summaryrefslogtreecommitdiff
path: root/live.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-02-22 23:27:15 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-16 23:40:56 +0200
commit211507d598b67e6e274275ab472d5e81ec1afcec (patch)
tree47d4ba219c740b85dd563e312083f2787016d0ec /live.c
parent4dd4dcb4f594c872df222390031975d06adc7e71 (diff)
Factor event handling code out into events.c
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'live.c')
-rw-r--r--live.c154
1 files changed, 17 insertions, 137 deletions
diff --git a/live.c b/live.c
index 70e4db5..c4d5ffd 100644
--- a/live.c
+++ b/live.c
@@ -37,7 +37,6 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
-#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -51,11 +50,11 @@
#include "isp/v4l2.h"
#include "isp/v4l2-pool.h"
+#include "events.h"
#include "videoout.h"
#define MEDIA_DEVICE "/dev/media0"
#define VIDEOOUT_DEVICE "/dev/video0"
-#define SELECT_TIMEOUT 2000 /* in milliseconds */
static struct timespec fps_ts = { 0, 0 };
static unsigned int fps_last = 0;
@@ -67,99 +66,21 @@ static unsigned int frame_skip = 0;
static struct omap3_isp_device *isp = NULL;
static struct videoout *vo = NULL;
-static bool done = false;
+static struct events events;
/* -----------------------------------------------------------------------------
* Events
*/
-struct event_fd {
- struct list_entry list;
-
- int fd;
- bool write;
- void (*callback)(void *priv);
- void *priv;
-};
-
-static struct {
- struct list_entry events;
-
- int maxfd;
- fd_set rfds;
- fd_set wfds;
-} events;
-
-static void events_watch_fd(int fd, bool write, void(*callback)(void *), void *priv)
-{
- struct event_fd *event;
-
- event = malloc(sizeof *event);
- if (event == NULL)
- return;
-
- event->fd = fd;
- event->write = write;
- event->callback = callback;
- event->priv = priv;
-
- if (write)
- FD_SET(fd, &events.wfds);
- else
- FD_SET(fd, &events.rfds);
-
- events.maxfd = max(events.maxfd, fd);
-
- list_append(&event->list, &events.events);
-}
-
-static void events_unwatch_fd(int fd)
-{
- struct event_fd *event = NULL;
- struct event_fd *entry;
- int maxfd = 0;
-
- list_for_each_entry(entry, &events.events, list) {
- if (entry->fd == fd)
- event = entry;
- else
- maxfd = max(maxfd, entry->fd);
- }
-
- if (event == NULL)
- return;
-
- if (event->write)
- FD_CLR(fd, &events.wfds);
- else
- FD_CLR(fd, &events.rfds);
-
- events.maxfd = maxfd;
-
- list_remove(&event->list);
- free(event);
-}
-
-static void events_init(void)
+static void __events_watch_fd(int fd, enum omap3_isp_event_type type,
+ void(*callback)(void *), void *priv)
{
- memset(&events, 0, sizeof events);
-
- FD_ZERO(&events.rfds);
- FD_ZERO(&events.wfds);
- events.maxfd = 0;
- list_init(&events.events);
+ events_watch_fd(&events, fd, type, callback, priv);
}
-static void events_dispatch(const fd_set *rfds, const fd_set *wfds)
+static void __events_unwatch_fd(int fd)
{
- struct event_fd *event;
-
- list_for_each_entry(event, &events.events, list) {
- if (!event->write && FD_ISSET(event->fd, rfds))
- event->callback(event->priv);
- if (event->write && FD_ISSET(event->fd, wfds))
- event->callback(event->priv);
- }
+ events_unwatch_fd(&events, fd);
}
/* -----------------------------------------------------------------------------
@@ -210,17 +131,10 @@ static void viewfinder_process(struct omap3_isp_device *isp __attribute__((__unu
strerror(-ret), ret);
}
-
-static void events_watch_fd_isp(int fd, enum omap3_isp_event_type type,
- void (*callback)(void *priv), void *priv)
-{
- events_watch_fd(fd, type == OMAP3_ISP_EVENT_WRITE, callback, priv);
-}
-
static struct omap3_isp_operations isp_ops = {
.viewfinder_ready = viewfinder_process,
- .watch_fd = events_watch_fd_isp,
- .unwatch_fd = events_unwatch_fd,
+ .watch_fd = __events_watch_fd,
+ .unwatch_fd = __events_unwatch_fd,
};
/* -----------------------------------------------------------------------------
@@ -247,12 +161,12 @@ static void video_out_process(void *priv __attribute__((__unused__)))
static void events_watch_fd_vo(int fd)
{
- events_watch_fd(fd, true, video_out_process, NULL);
+ events_watch_fd(&events, fd, OMAP3_ISP_EVENT_WRITE, video_out_process, NULL);
}
static struct video_out_operations vo_ops = {
.watch_fd = events_watch_fd_vo,
- .unwatch_fd = events_unwatch_fd,
+ .unwatch_fd = __events_unwatch_fd,
};
static const char *video_out_find(void)
@@ -386,10 +300,8 @@ done:
static void sigint_handler(int signal __attribute__((__unused__)))
{
- /* Set the done flag to true when the user presses CTRL-C to interrupt
- * the main loop.
- */
- done = true;
+ /* Stop the main loop when the user presses CTRL-C. */
+ events_stop(&events);
}
static void usage(const char *argv0)
@@ -439,7 +351,7 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu
}
}
- events_init();
+ events_init(&events);
memset(&rect, 0, sizeof rect);
ret = fb_init(&rect);
@@ -514,41 +426,9 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu
clock_gettime(CLOCK_MONOTONIC, &start);
- /* Main capture loop. Wait for a video buffer using select() and process
- * it.
- */
- while (!done) {
- struct timeval timeout;
- fd_set rfds;
- fd_set wfds;
-
- timeout.tv_sec = SELECT_TIMEOUT / 1000;
- timeout.tv_usec = (SELECT_TIMEOUT % 1000) * 1000;
- rfds = events.rfds;
- wfds = events.wfds;
-
- ret = select(events.maxfd + 1, &rfds, &wfds, NULL, &timeout);
- if (ret < 0) {
- /* EINTR means that a signal has been received, continue
- * to the next iteration in that case.
- */
- if (errno == EINTR)
- continue;
-
- printf("error: select failed with %d\n", errno);
- goto cleanup;
- }
- if (ret == 0) {
- /* select() should never time out as the ISP is supposed
- * to capture images continuously. A timeout is thus
- * considered as a fatal error.
- */
- printf("error: select timeout\n");
- goto cleanup;
- }
-
- events_dispatch(&rfds, &wfds);
- }
+ /* Main capture loop. */
+ if (events_loop(&events))
+ goto cleanup;
clock_gettime(CLOCK_MONOTONIC, &end);