2013-05-02 1 views
0

Я пытаюсь отправить несколько кадров (ранее взятых из фактического видеофайла) через сокет (C++), чтобы затем играть с VLC.Отображать несколько OpenClv IplImages через VLC Video Output

Я много искал и не нашел решения. Надеюсь, ты поможешь мне.

Итак, это мой код:

#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 ничего не показывает.

Большое спасибо!

ответ

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 и т. Д.)

Ваш сервер может относительно легко передавать MJPEG через HTTP, для любого другого протокола вы должны использовать внешнюю библиотеку.

Вы должны искать о как реализация потокового видео сервер в C++ см эту тему: How to get started implementing a video streaming server in c/c++?

+0

изначально у меня было именно так, но это не работает, как хорошо ... :( – xatz

+0

Как я могу был ли этот потоковый протокол? – xatz

+0

Shoul Я пытаюсь что-то вроде отправки в формате TS? – xatz

 Смежные вопросы

  • Нет связанных вопросов^_^