Hi i am trying to simulate a client-server program.Both are independent processes.The client listens for image data(mat.data) written on a named fifo by the server (which reads image frames from a webcam and writes them one by one on the namedfifo) My server and client sides work perfectly, if I create a simple mat object on the client side ,write it on the fifo,read it on the server and recreate it on the server side.However, when I try to write a continuous stream of frames from webcam, the server gives core-dump, segmentation fault.
The server side code is shown below.
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
int check;
int fd;
int totalbytes;
int buflen;
fd = open("/home/vidfifo",O_WRONLY|O_NONBLOCK);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
int totalbytes = frame.total()*frame.elemSize();
int buflen = frame.cols*3;
check = writefifo(frame.data,totalbytes,buflen,fd);
if (check == 1)
{
cout<<"write successful"<<endl;
imshow("frames1", frame);
if(waitKey(30) >= 0) break;
}
else
{
break;
}
}
close(fd);
return 0;
}
the writefifo function is as follows
int writefifo(uchar *framepointer,int totalbytes,int buflen,int fd)
{
uchar* buf;
buf = framepointer;
int num = totalbytes/buflen;
for(int i = 1;i<=num;i++)
{
write(fd,buf,buflen);
buf = buf + buflen;
}
return 1;
}
the client side is
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main( int argc, char** argv )
{
//I found these by running the server program beforehand
int rows = 480;
int cols = 640;
int nchan = 3;
int totalbytes = 921600;//rows*cols*nchan
int buflen = 1920;//cols*nchan
while(1)
{
Mat img(rows,cols,CV_8UC3);
uchar buf[buflen];
uchar datarray[totalbytes];
int fd1 = open("/home/vidfifo",O_RDONLY);
int j;
int k = 0;
int num = totalbytes/buflen;//=num of rows
for(int i = 1;i<=num;i++)
{
read(fd1,buf,buflen);
for ( j = 0 ; j<= (buflen-1);j++ ) //originally wrote this as j<= (buflen-1+k)--see update1 at the end of post
{
datarray[j+k] = buf[j];
}
k = k+buflen;
}
img.data = datarray;
imshow("framesrec", img);
if(waitKey(30) >= 0) break;
}
return 0;
}
I know there's something wrong with a pointer in the server program.But I can't figure out what. Please tell me if there is some pointer related issue or something else in the code that does not allow the client to receive a continuous stream of frames. Thanks.
update1 after posting this question, I realized I should have written the limit of the read loop( in server) as j<=(buflen -1) instead of j<=(buflen-1+k).This removed the segmentation error, but all I get is a corrupted frozen frame instead of a continuous stream and the window stops responding after some time.So, now my question is How do I get a continuous stream?
update2 after putting the close system call outside loop in the server code, i now get a continuous stream but it is blurred and frames appear squashed.Still not a perfect stream.