Search code examples
c++clinuxopencvsystems-programming

Webcam stream from parent process to child process


I want to send a stream of video frames using a webcam from a parent process to child process through a named pipe.The parent displays the sent frames while the child displays the received frames.I am using openCV 2.4.12 for accessing and displaying video frames on UBuntu 14.04.However, it only sends one frame and freezes.I cannot figure out what's causing the problem.This code works perfectly fine if I send a single image but freezes on the first frame when I try to send a stream.

Here's the code:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
using namespace cv;
using namespace std;


void  ChildProcess(void);                /* child process prototype  */
void  ParentProcess(void);               /* parent process prototype */

int  main()
 {

 pid_t  pid;

 pid = fork();
 if (pid == 0)
      ChildProcess();
 else
    ParentProcess();

 }

void  ChildProcess(void)
{

int fd2 = open("/home/eelab/vidpipe",O_RDONLY);

for(;;)
{
int rows = 480;
int cols = 640;
int nchan = 3;
int totalbytes = rows*cols*nchan;
int buflen = cols*nchan;
int ret;
//int fd1 = open("/dev/xillybus_read_32",O_RDONLY);

uchar buf[buflen];
uchar datarray[totalbytes];
Mat img(rows,cols,CV_8UC3);

int j;
int k = 0;
int num = totalbytes/buflen;
int bread = 0;
while(bread<totalbytes)
{

    ret=read(fd2,buf,buflen);
    for ( j = 0 ; j<= (ret-1);j++ )
    {
        datarray[j+k] = buf[j];

    }
        k = k+ret;
    bread = bread+ret;
}

img.data = datarray;

namedWindow( "Received image", WINDOW_AUTOSIZE );
imshow( "Received image", img );
waitKey(0);
}
close(fd2);
}

void  ParentProcess(void)
{

int check;
int fd;
int totalbytes;
int buflen;
int count = 0;
fd = open("/home/eelab/vidpipe",O_WRONLY);
if (fd < 1)
{
    perror("open error");
}

VideoCapture cap(0);

for(;;)
{
    Mat frame;
    cap >> frame;


totalbytes = frame.total()*frame.elemSize();
buflen = (frame.cols*3);

uchar *framepointer = frame.data;



 int bwritten = 0;
 int ret;
 uchar* buf;
 buf = framepointer;
 int num = totalbytes/buflen;
 while(bwritten<totalbytes)
 {
   ret = write(fd,buf,buflen);
   write(fd,NULL,0);
   buf = buf + ret;
   bwritten = bwritten+ret;
  }



    namedWindow( "Sent image", WINDOW_AUTOSIZE );
    imshow( "Sent image", frame );
    waitKey(0);

  }

  close(fd);

  }    

Please help, how can I get a continuous stream?


Solution

  • waitKey(0); will block the process until a key is pressed. If you change to waitKey(1); it will proceed automatically after >= 1 ms. If that's not fast enough (e.g. your fps is very high) you should switch to a different GUI library (Qt for example).