diff options
| -rw-r--r-- | zmq-camera.c | 66 | 
1 files changed, 59 insertions, 7 deletions
diff --git a/zmq-camera.c b/zmq-camera.c index 3c0a5a7..c3e59c7 100644 --- a/zmq-camera.c +++ b/zmq-camera.c @@ -20,8 +20,10 @@  #include <arpa/inet.h>  #include <assert.h>  #include <pthread.h> +#include <signal.h>  #include <stdlib.h>  #include <stdio.h> +#include <sys/time.h>  #include <sys/types.h>  #include <unicap.h> @@ -60,8 +62,16 @@ void *sender_thread (void *arg)      unicap_data_buffer_t src_buffer;      unicap_data_buffer_t dest_buffer;      unicap_data_buffer_t *returned_buffer; +    sigset_t block_set;      sender_args = (struct sender_args_t *)arg; +         +    /* Block SIGALRM in the sender thread since it's used for timers in the +       main thread */ +    sigemptyset (&block_set); +    sigaddset (&block_set, SIGALRM); +    pthread_sigmask (SIG_BLOCK, &block_set, NULL); +      /* Create a ZMQ_PUB socket for sending video data and connect it to both         an inproc endpoint for the local loopback view and bind to the endpoint @@ -230,6 +240,13 @@ void err_usage(void)   *  Main thread   */ +volatile int alarm_expired = 0; + +void alarm_handler (int signo) +{ +    alarm_expired = 1; +} +  int main (int argc, char *argv [])  {      void *ctx, *s; @@ -241,6 +258,11 @@ int main (int argc, char *argv [])      uint32_t image_width, image_height;      int sdl_initialised = 0;      int quit = 0; +    struct sigaction alarm_action; +    struct itimerval alarm_timer; +    uint64_t received_fps = 0; +    uint64_t received_bps = 0; +    char window_title[80];      /* Parse command line. */      if (argc != 3) @@ -270,7 +292,7 @@ int main (int argc, char *argv [])                  zmq_strerror (errno));              exit (1);          } - +              /* Start the sender thread after binding to the inproc: endpoint             since this must exist for it to connect. */          struct sender_args_t sender_args = {endpoint, ctx}; @@ -291,11 +313,28 @@ int main (int argc, char *argv [])      /* Subscribe to all messages on socket. */      rc = zmq_setsockopt (s, ZMQ_SUBSCRIBE, "", 0);      assert (rc == 0); +     +    /* Set up an interval timer to fire SIGALRM once a second so that +       we can update bandwidth and fps statistics */ +    alarm_action.sa_flags = 0; +    alarm_action.sa_handler = alarm_handler; +    rc = sigaction (SIGALRM, &alarm_action, NULL); +    assert (rc == 0); +    alarm_timer.it_interval.tv_sec = 1; +    alarm_timer.it_interval.tv_usec = 0; +    alarm_timer.it_value.tv_sec = 1; +    alarm_timer.it_value.tv_usec = 0; +    rc = setitimer (ITIMER_REAL, &alarm_timer, NULL); +    assert (rc == 0); + +    /* Intial window title is the endpoint we are receiving from */ +    snprintf (window_title, 80, "%s", is_sender ? local_camera : endpoint);      /* Display video until user asks to quit. */      while (!quit) {          zmq_msg_t msg; +        size_t msg_size;          unsigned char *data;          SDL_Event event; @@ -309,7 +348,8 @@ int main (int argc, char *argv [])          data = (unsigned char*) zmq_msg_data (&msg);          /* Sanity check that we have at least the width, height in              the message data */ -        assert (zmq_msg_size (&msg) >= sizeof (uint32_t) + sizeof (uint32_t)); +        msg_size = zmq_msg_size (&msg); +        assert (msg_size >= sizeof (uint32_t) + sizeof (uint32_t));          /* Get image width in pixels. */          memcpy (&image_width, data, sizeof (uint32_t)); @@ -321,6 +361,9 @@ int main (int argc, char *argv [])          image_height = ntohl (image_height);          data += sizeof (uint32_t); +        /* Sanity check message size again */ +        assert (msg_size >= image_width * image_height * 3); +          /* data now points to RGB24 pixel data. */          if (!sdl_initialised) { @@ -342,11 +385,6 @@ int main (int argc, char *argv [])                 SDL_Quit ();                 exit (1);              } -            /* Set window title to endpoint we are receiving from */ -            if (is_sender) -                SDL_WM_SetCaption (local_camera, local_camera); -            else -                SDL_WM_SetCaption (endpoint, endpoint);              sdl_initialised = 1;          } @@ -367,6 +405,20 @@ int main (int argc, char *argv [])          /* Free zmq_msg we received */          zmq_msg_close (&msg); +         +        /* Update statistics */ +        received_fps += 1; +        received_bps += msg_size; +        /* If the timer fired, recalculate bandwidth and update window title */ +        if (alarm_expired) { +            double received_mbps = (double)received_bps * 8 / (1<<20); +            snprintf (window_title, 80, "%s (%lu fps, %.2lf Mbps)",  +                is_sender ? local_camera : endpoint, +                received_fps, received_mbps); +            SDL_WM_SetCaption (window_title, window_title); +            received_fps = received_bps = 0; +            alarm_expired = 0; +        }          /* Check if user asked to quit. */          while (SDL_PollEvent (&event))  | 
