通过VLC视频输出显示多个OpenCv IplImages

时间:2013-05-02 14:59:08

标签: c++ opencv vlc serversocket

我正在尝试通过套接字(C ++)发送多个帧(预先从实际视频文件中获取)然后使用VLC播放。

我搜索了很多,但没有找到解决方案。希望你能帮帮我。

所以,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string.h>
#include <time.h>
#include <errno.h>
//#include <fstream>

#include <opencv2/core/core.hpp>        // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/highgui/highgui.hpp>  // OpenCV window I/O

using namespace std;

#define PORT 6666
#define GROUP "127.0.0.1"
//#define INADDR_ANY

int serversock, clientsock;
int is_data_ready = 0;
struct sockaddr_in server, client;
int bytes = 0;
int count = 0;

int addrlen = sizeof(server);
int clielen = sizeof(client);

int opt = 1;

//methods
void quit(char* msg, int retval);

void quit(char* msg, int retval)
{
    if (retval == 0) {
        fprintf(stdout, (msg == NULL ? "" : msg));
        fprintf(stdout, "\n");
    } else {
        fprintf(stderr, (msg == NULL ? "" : msg));
        fprintf(stderr, "\n");
    }

    if (clientsock) closesocket(clientsock);

    if (serversock) closesocket(serversock);

    exit(retval);
}

int main()
{
    // Initialize Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %ld\n", iResult);
        return 1;
    }

    //char *imgname; //path e nome das imagens
    int i=0;
    char filename[50];
    IplImage *img = cvLoadImage(<path\\imgname.jpg); //1ª imagem como referência
    //IplImage *img2;
    CvSize size;
    size.width = img->width;
    size.height = img->height;

    /* setup server's IP and port */
    memset(&server,0,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(6666/*PORT*/);
    server.sin_addr.s_addr = inet_addr("127.0.0.1"/*GROUP*/);
    //server.sin_addr.s_addr = INADDR_ANY;

    SOCKET serversock = socket(AF_INET, SOCK_STREAM, 0);
    //SOCKET t;
    //t = socket(AF_INET, SOCK_STREAM,NULL);

    if (serversock < 0) { // or == -1
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        //quit("socket() failed", 1);
    }     

    /* bind the socket */
    int b = bind(serversock, (const sockaddr*)&server, sizeof(server));
    if (b < 0) {
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        quit("bind() failed", 1);
    }

    /* wait for connection */
    int l = listen(serversock, 5);
    if(l < 0) {
        quit("listen() failed.", 1);
    }   

    setsockopt(serversock, SOL_SOCKET, SO_KEEPALIVE, (const char*) &opt, sizeof(int));

    while(img != NULL) 
    {
        sprintf(filename, "filter\\frame_%d.jpg", i);

        img = cvLoadImage(filename);

        if (img) {
            int imgSize = (int) &size;
            sendto(serversock, img->imageData, imgSize, 0, (const struct sockaddr*)&server, addrlen);
            if(bytes < 0) { //error
                wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
                WSACleanup();
                quit("sendto FAILED", 1);
            }

            //end socket stuff

            cout << "Image sent!" << endl;   
        }
        i++;
    } 
    cvReleaseImage(&img);
}

Ant然后我打开VLC并将其设置为接收下一个地址的网络流:rtp://127.0.0.1:6666

应用程序结束,VLC没有显示任何内容。

非常感谢!

1 个答案:

答案 0 :(得分:0)

第一

int sendto(
  _In_  SOCKET s,
  _In_  const char *buf,
  _In_  int len,
  _In_  int flags,
  _In_  const struct sockaddr *to,
  _In_  int tolen
);

sendto第三个参数是« The length, in bytes, of the data pointed to by the buf parameter »,而不是某个OpenCV大小对象的地址。如果您的程序崩溃,那就不足为奇了。 imgSize应为img.imageSize

其次,我真的怀疑VLC能够解码由几个原始图像数据组成的流,我很确定它需要一些流协议。

首先,您需要将传输协议用作流媒体协议(HTTP,RTP等)。 然后你需要建立一个实际的视频流(MJPEG,MPEG4等)

您的服务器可以通过HTTP相对轻松地传输MJPEG,对于任何其他协议,您应该使用外部库。

您应该搜索如何在C ++中实现视频流服务器,请参阅此主题:How to get started implementing a video streaming server in c/c++?