【问题标题】:Display multiple OpenCv IplImages over VLC Video Output在 VLC 视频输出上显示多个 OpenCv IplImage
【发布时间】:2013-04-26 19:41:28
【问题描述】:

我正在尝试通过套接字 (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 不显示任何内容。

非常感谢!

【问题讨论】:

    标签: c++ opencv vlc serversocket


    【解决方案1】:

    首先

    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++?

    【讨论】:

    • 本来我也是这样的,但效果不太好... :(
    • 我怎样才能拥有那个流协议?
    • 您可以通过 HTTP 流式传输 MJPEG。基本上你只需要等待GET 请求并发送一个HTTP 响应,其中包含你所有的JPEG 图像一个接一个地发送未压缩。
    猜你喜欢
    • 2020-05-11
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2011-12-17
    • 2010-11-14
    • 2017-05-29
    • 1970-01-01
    • 2017-10-23
    相关资源
    最近更新 更多