2013-05-02 54 views
0

我試圖通過套接字(C++)發送多個幀(預先取自實際視頻文件),然後與VLC一起播放。通過VLC視頻輸出顯示多個OpenCv IplImages

我搜索了很多並沒有找到解決方案。希望您能夠幫助我。

所以,這是我的代碼:

#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); 
} 

螞蟻然後我打開VLC,並將其設置到下一個地址接收網絡數據流:rtp://127.0.0.1:6666

應用程序結束,VLC不顯示任何內容。

非常感謝!

回答

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

+0

的淵源我有這樣的說法,但它不工作,以及... :( – xatz 2013-05-02 15:11:51

+0

我怎麼能有這樣的流協議嗎? – xatz 2013-05-02 15:13:49

+0

首先我嘗試像發送TS格式的東西? – xatz 2013-05-02 15:16:06