¿Cómo transferir cv :: marcos de VideoCapture a través del socket en el modelo cliente-servidor (OpenCV C ++)?

Traduzco video a través del socket y veo transmisión de video en el otro lado, pero no puedo recibir video. Mi archivo de video está vacío. Estoy pensando que el problema puede ser un formato de video de conversión incorrecto en el lado de recepción. ¿Cómo debo codificar el video en el lado del servidor y cómo debo decodificar el video en el lado del cliente?

Yo uso Linux Ubuntu Mate, OpenCV 2.4.13.

Servidor:

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fstream>
#include <cstring>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <pthread.h>
#include <SerialStream.h>
#include <unistd.h>
#include <ctime>
#include <iomanip>
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/types_c.h>
#include <vector>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;
using namespace cv;

char answer[] = "Y";
int main()
{
int sock, listener;
struct sockaddr_in addr;
char buf[1024];
int bytes_read;


if( (listener = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
    perror("socket() failed");
    exit(1);
}

addr.sin_family = AF_INET;
addr.sin_port = htons(3425);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    perror("bind");
    exit(2);
}

listen(listener, 1);
ofstream of("readFile.txt");
vector<int> param;
param.push_back(CV_IMWRITE_JPEG_QUALITY);


Mat frame = Mat::zeros(480, 640, CV_8UC3);
Mat receive;
int imgSize = frame.total()*frame.elemSize();

if(! frame.isContinuous() ){
    frame = frame.clone();
}

namedWindow("CV Video Client", 1);

uchar *iptr = frame.data;

int key;

uchar sockData[imgSize];
int count_of_receive_frame = 0;
int num_of_recv_bytes;
VideoWriter outputVideo;
Size S = Size((int) 480,(int) 640);
outputVideo.open("receive.avi", CV_FOURCC('X','V','I','D'), 30, S, true);
int i = 0;

char name_of_photo[20];
while(1)
{
    sock = accept(listener, NULL, NULL);
    if(sock < 0)
    {
        perror("accept");
        exit(3);
    }

    while(key != 'q'){



        if( num_of_recv_bytes = recv(sock, iptr, imgSize, MSG_WAITALL) == -1 ){
            cerr << "recv failed, received bytes = " << num_of_recv_bytes << endl;
        }

        imshow("CV Video Client", frame);

        outputVideo.write(frame);


        if (key = waitKey(10) >= 0) break;


    }
    outputVideo.release();
    close(sock);
    break;
}


return 0;
}

Cliente:

#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fstream>
#include <cstring>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include <iomanip>
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/types_c.h>
#include <vector>
#include <arpa/inet.h>
#include <unistd.h>



using namespace std;
using namespace cv;

size_t get_file_size( const char * filename );
void file_to_buf( char *buf, size_t _len, std::string filename );
void take_photo(char *name);

char answer[] = "N";

char message[] = "Hello there!\n";
int count_send_img = 0;
int main()
{


 string filename = "img.jpg";

    int sock;
    struct sockaddr_in addr;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425); // или любой другой порт...
    addr.sin_addr.s_addr = /*net_addr*/htonl(/*"192.168.1.71"*/INADDR_LOOPBACK);
    if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(2);
    }

 int bbytee;
    cout << "before open the cam" << endl;

 VideoCapture cap(0);

    if(!cap.isOpened()){
      cout<< "Could not open the camera" <<  endl;
    }
    cout << "cam opened" << endl;

    Mat frame, frameGray;

    frame = Mat::zeros(480, 640, CV_8UC3);

    if(! frame.isContinuous() ){
        frame = frame.clone();
    }

    int imgSize = frame.total()*frame.elemSize();



 while(1){ 



  cap >> frame;



        cvtColor(frame, frameGray, CV_BGR2GRAY);

  if( (bbytee = send(sock, frameGray.data, imgSize, 0)) < 0 ){
            cerr<< "bytes = " << bbytee << endl;
            break;
  }


 }
    close(sock);

    return 0;
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta