1

I'm writing a RPi based surveillance solution that, among other things, starts video feeds on demand. In my very first attempt I wrote a pretty simple TCP server that listen for a connection collect the command from the client then if the command require a video feeds it forks the process and spawn a video streaming using this command line:

raspivid -n -ih -t 0 -rot 90 -w 640 -h 480 -fps 25 -b 2000000 -l -o - | nc -l -p 5000

Such command is spawned trough the following function:

void spawn_child(const char* script)
{
  child = true;
  setpgid(0, 0);
  openlog (process_name, LOG_PID | LOG_ODELAY, LOG_LOCAL0);
  syslog(LOG_INFO, "spawned: %s", script);        
  system(script);
  exit_cond = TERMINATE; 
}

where script parameter is set as the command line above...

Now I would like to have a little more control over the script running for this reason I tought to use popen() instead netcat.

This's the new spawn_child function:

void spawn_child(const char* script)
{
  child = true;
  setpgid(0, 0);
  openlog (process_name, LOG_PID | LOG_ODELAY, LOG_LOCAL0);
  syslog(LOG_INFO, "spawned : %s", script);     
  
  syslog(LOG_INFO,"CREATING SOCKET");
  accept_socket = create_socket(video_port);
  
  video_socket = accept(accept_socket, 0, 0);
  
  syslog(LOG_INFO,"CLIENT CONNECTED");
  
  streamVideo = popen(script,"r");
      
  while(!feof(streamVideo) && !terminate)
  {
    int bytes;

    bytes = fread(video_buff, BUF_SIZE, 1, streamVideo);
        
    if(bytes > 0)
      write(video_socket,video_buff,bytes);
  }

  close(video_socket);
  pclose(streamVideo);
  
  exit_cond = TERMINATE; 
}

Of course in this case the script parameter become:

raspivid -n -ih -t 0 -rot 90 -w 640 -h 480 -fps 25 -b 2000000 -l -o -

I don't think is the correct solution since both reading and writing calls should be managed with a different approach (threading?) but what I observe right now is a much slower output rate (of the streaming) compared with the netcat solution. Is this performance degradation due to my code structure, delays between read() and write() calls, or there's something more I forgot?

What's a better approach to fix this? Threading? read() and write() non blocking?

3
+50

I bet it has to do with buffering you're doing on streams. man popen has this line

Note that output popen() streams are block buffered by default.

You'll have to increase the buffer size to something more respectable than the default block size (which can be as small as 256 bytes) using setvbuf. AFAIK nc increases the buffer size to 8K.

  • thnx I'll give this a try. – weirdgyn Jul 20 '20 at 13:09
  • 1
    It works better. Not the perfect solution but a step forward has been done. – weirdgyn Jul 29 '20 at 7:50
  • @weirdgyn Good to hear that. Which buffer sizes have you tried? – Dmitry Grigoryev Jul 29 '20 at 10:35
  • 8K right now because I would like to keep it as small as possiible. – weirdgyn Jul 29 '20 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.