diff options
| -rwxr-xr-x | build.sh | 2 | ||||
| -rw-r--r-- | src/audio.c | 43 | ||||
| -rw-r--r-- | src/audio.h | 4 | ||||
| -rw-r--r-- | src/camera.c | 5 | ||||
| -rw-r--r-- | src/camera.h | 2 | ||||
| -rw-r--r-- | src/common_v4l2.h | 9 | ||||
| -rw-r--r-- | src/display.c | 2 | ||||
| -rw-r--r-- | src/listener.c | 19 | ||||
| -rw-r--r-- | src/socket.c | 36 | ||||
| -rw-r--r-- | src/talker.c | 16 | ||||
| -rw-r--r-- | src/typedef.h | 2 | 
11 files changed, 98 insertions, 42 deletions
| @@ -42,3 +42,5 @@ gcc -o $BIN/talker       $SRC/talker.c   $OBJ/socket.o $OBJ/camera.o  $OBJ/audio  # if ! { [[ $RUN -eq 0 ]]; } 2> /dev/null  # then  # fi + +# bin/listener diff --git a/src/audio.c b/src/audio.c index 0c40f9f..f7a51a5 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1,3 +1,5 @@ +// TODO: Rewrite with alsa, fuck pulseaudio +  #include <stdio.h>  #include <unistd.h>  #include <string.h> @@ -10,19 +12,20 @@  #include "typedef.h"  static const pa_sample_spec ss = { -    .format = PA_SAMPLE_S16LE, +    .format = PA_SAMPLE_S16BE,      .rate = 44100, -    .channels = 1 +    .channels = 2  };  static pa_simple *play = NULL; +static pa_simple *rec  = NULL; -int audip_play(char *buf) +int audio_play(char *buf)  {      int ret = 1;      int error; -    if(!play) { +    if(play == NULL) {          if (!(play = pa_simple_new(NULL, __FILE__, PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {              fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));              goto finish; @@ -43,38 +46,34 @@ int audip_play(char *buf)  finish: -    if (play) -        pa_simple_free(play); +    // if (play) +        // pa_simple_free(play);      return ret;  } -int audio_record(int fd) +int audio_record(char *buf)  { -    pa_simple *rec = NULL;      int ret = 1;      int error; -    if (!(rec = pa_simple_new(NULL, __FILE__, PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { -        fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); -        goto finish; -    } - -    for(;;) -    { -        char buf[REC_CAP]; - -        if (pa_simple_read(rec, buf, sizeof(buf), &error) < 0) { -            fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); +    if(!rec) { +        if (!(rec = pa_simple_new(NULL, __FILE__, PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) { +            fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));              goto finish;          } +    } -        write(fd, buf, sizeof(buf)); +    if (pa_simple_read(rec, buf, REC_CAP, &error) < 0) { +        fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); +        goto finish;      } +    ret = 0; +  finish: -    if(rec) -        pa_simple_free(rec); +    // if(rec) +        // pa_simple_free(rec);      return ret;  } diff --git a/src/audio.h b/src/audio.h index f7f4ae4..2ca554d 100644 --- a/src/audio.h +++ b/src/audio.h @@ -1,8 +1,8 @@  #ifndef AUDIO_H  #define AUDIO_H -int audip_play(char *buf); +int audio_play(char *buf); -int audio_record(int fd); +int audio_record(char *buf);  #endif diff --git a/src/camera.c b/src/camera.c index fcd0606..6842a12 100644 --- a/src/camera.c +++ b/src/camera.c @@ -18,8 +18,3 @@ void camera_deinit()  {      CommonV4l2_deinit(&common_v4l2);  } - -int camera_get_image_size() -{ -    return (int)CommonV4l2_get_image_size(&common_v4l2); -} diff --git a/src/camera.h b/src/camera.h index 6a3db62..aaf690c 100644 --- a/src/camera.h +++ b/src/camera.h @@ -7,6 +7,4 @@ char *camera_get_image();  void camera_deinit(); -int camera_get_image_size(); -  #endif diff --git a/src/common_v4l2.h b/src/common_v4l2.h index c3762b5..301deb6 100644 --- a/src/common_v4l2.h +++ b/src/common_v4l2.h @@ -44,6 +44,7 @@ void CommonV4l2_init(CommonV4l2 *this, char *dev_name, unsigned int x_res, unsig      enum v4l2_buf_type type;      struct v4l2_format fmt;      struct v4l2_requestbuffers req; +    struct v4l2_streamparm parm;      unsigned int i;      this->fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0); @@ -61,12 +62,20 @@ void CommonV4l2_init(CommonV4l2 *this, char *dev_name, unsigned int x_res, unsig      if ((fmt.fmt.pix.width != x_res) || (fmt.fmt.pix.height != y_res))          printf("Warning: driver is sending image at %dx%d\n",              fmt.fmt.pix.width, fmt.fmt.pix.height); +      COMMON_V4L2_CLEAR(req);      req.count = 2;      req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;      req.memory = V4L2_MEMORY_MMAP;      CommonV4l2_xioctl(this->fd, VIDIOC_REQBUFS, &req);      this->buffers = calloc(req.count, sizeof(*this->buffers)); + +    COMMON_V4L2_CLEAR(parm); +    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +    parm.parm.capture.timeperframe.numerator = 1; +    parm.parm.capture.timeperframe.denominator = 30; +    CommonV4l2_xioctl(this->fd, VIDIOC_S_PARM, &parm); +      for (this->n_buffers = 0; this->n_buffers < req.count; ++this->n_buffers) {          COMMON_V4L2_CLEAR(this->buf);          this->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/src/display.c b/src/display.c index 33131ef..2fb1d78 100644 --- a/src/display.c +++ b/src/display.c @@ -50,4 +50,6 @@ void display(int *argc, char **argv, int readfd)  	glutDisplayFunc(render);  	glutMainLoop(); + +    puts("DISPLAY EXIT");  } diff --git a/src/listener.c b/src/listener.c index 0a5df2d..7e9a839 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1,9 +1,11 @@  #include <stdio.h> -#include <fcntl.h> +#include <stdlib.h>  #include <unistd.h> +#include <fcntl.h>  #include "socket.h"  #include "display.h" +#include "audio.h"  #include "typedef.h"  static int fd; @@ -11,7 +13,20 @@ static int fd;  void on_recv(char *buf, int numbytes)  {      // read and play audio -    write(fd, buf, numbytes); +    pid_t p = fork(); +    if(p < 0) { +        fputs("fork: failed", stderr); +        exit(1); +    } else if(p > 0) { +        write(fd, &(buf[REC_CAP]), numbytes-REC_CAP); +    } else { +        audio_play(buf); +        exit(0); +    } + +    // audio_play(buf); +    // write(fd, &(buf[REC_CAP]), numbytes-REC_CAP); +  }  int main(int argc, char **argv) diff --git a/src/socket.c b/src/socket.c index e388e45..f435812 100644 --- a/src/socket.c +++ b/src/socket.c @@ -5,9 +5,15 @@  #include <string.h>  #include <arpa/inet.h>  #include <netdb.h> +#include <signal.h> +#include <wait.h> +#include <time.h> +  #include "socket.h"  #include "typedef.h" +// #define LOG_INFO_STDOUT +  void *get_in_addr(struct sockaddr *sa)  {  	if (sa->sa_family == AF_INET) { @@ -17,6 +23,16 @@ void *get_in_addr(struct sockaddr *sa)  	return &(((struct sockaddr_in6*)sa)->sin6_addr);  } +void sigchld_handler(int s) +{ +    // waitpid() might overwrite errno, so we save and restore it: +    int saved_errno = errno; + +    while(waitpid(-1, NULL, WNOHANG) > 0); + +    errno = saved_errno; +} +  int listener(char *port, void (*on_recv)(char *, int))  {      int sockfd; @@ -59,7 +75,6 @@ int listener(char *port, void (*on_recv)(char *, int))      freeaddrinfo(servinfo); -    #include <time.h>      int i = 0;      time_t now = 0;      while(1) @@ -68,6 +83,15 @@ int listener(char *port, void (*on_recv)(char *, int))              now = time(NULL);              printf("FPS: %d\n", i);              i = 0; + +            struct sigaction sa; +            sa.sa_handler = sigchld_handler; // reap all dead processes +            sigemptyset(&sa.sa_mask); +            sa.sa_flags = SA_RESTART; +            if (sigaction(SIGCHLD, &sa, NULL) == -1) { +                perror("sigaction"); +                return 1; +            }          }          char buf[BUF_CAP] = {0}; @@ -129,8 +153,16 @@ int talker(char *port, char *address, void (*on_send)(char *, int *))  		return 2;  	} +    int i = 0; +    time_t now = 0;      while(1)      { +        if(now < time(NULL)) { +            now = time(NULL); +            printf("FPS %d\n", i); +            i = 0; +        } +          char buf[BUF_CAP] = {0};          int bytes;          on_send(buf, &bytes); @@ -144,6 +176,8 @@ int talker(char *port, char *address, void (*on_send)(char *, int *))      #ifdef LOG_INFO_STDOUT          printf("talker: sent %d bytes to %s\n", numbytes, address);      #endif + +        i++;      }      freeaddrinfo(servinfo); diff --git a/src/talker.c b/src/talker.c index 8b09274..027d0e6 100644 --- a/src/talker.c +++ b/src/talker.c @@ -1,29 +1,31 @@  #include <stdio.h> +#include <stdlib.h>  #include <string.h>  #include <unistd.h>  #include <fcntl.h>  #include "socket.h"  #include "camera.h" +#include "audio.h"  #include "typedef.h"  #define CAM "/dev/video0"  #define X_RES 160  #define Y_RES 120 +  void on_send(char *buf, int *bytes)  { -    // write here audio +    audio_record(buf); -    int cisz = camera_get_image_size(); -    buf[0] = (unsigned char)X_RES; -    buf[1] = (unsigned char)Y_RES; +    int image_sz = X_RES*Y_RES*3; +    buf[REC_CAP+0] = (unsigned char)X_RES; +    buf[REC_CAP+1] = (unsigned char)Y_RES; -    *bytes = cisz + 2; +    *bytes = REC_CAP + 2 + image_sz; -    memcpy(&(buf[2]), camera_get_image(), cisz); +    memcpy(&(buf[REC_CAP+2]), camera_get_image(), image_sz); -    printf("%d\n", *bytes);  }  int main(void) diff --git a/src/typedef.h b/src/typedef.h index a8871fd..a875116 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -2,6 +2,6 @@  #define TYPEDEF_H  #define BUF_CAP 65536 -#define REC_CAP 2940 // second of audio +#define REC_CAP 5880 // 30th of a second of audio  #endif | 
