2013-03-12 113 views
0

我想使用mongoose轻量级web服务器实现MJPEG流。有人能给我一些关于我如何有效地做到这一点的指示吗?我已经有了需要流式处理的jpeg文件,并且我理解MJPEG概念。我只需要知道如何从协议级别实现MJPEG流。需要实现mjpeg流

回答

1

几乎所有ip摄像头实现的http上的mjpeg是multipart mime消息的子类型。 http://en.wikipedia.org/wiki/MIME#Mixed-Replace

你必须用你的实现来替换cvloop()来填充jbuf。

#include <vector> 
#include "mongoose.h" 

#ifdef _WIN32 
#include <windows.h> 
#define SLEEP(ms) Sleep(ms) 
#endif 
#ifdef __linux__ 
#define SLEEP(ms) usleep(ms*1000) 
#endif 

std::vector<unsigned char> jbuf;//fill this with a single jpeg image data 

#include "opencv2/highgui/highgui.hpp" 
void cvloop() 
{ 
    cv::VideoCapture cap("c:/toprocess/frame_%004d.jpg"); 
    cv::Mat frame; 
    for(;;) 
    { 
     cap>>frame; 
     std::vector<unsigned char> buffer; 
     std::vector<int> param(2); 
     param[0]=CV_IMWRITE_JPEG_QUALITY; 
     param[1]=40; 
     imencode(".jpg",frame,buffer,param); 
     jbuf.swap(buffer); 
     SLEEP(50); 
    } 
} 

// This function will be called by mongoose on every new request. 
static int begin_request_handler(struct mg_connection *conn) { 
    mg_printf(conn, 
     "HTTP/1.1 200 OK\r\n" 
     "Content-Type: multipart/x-mixed-replace;boundary=b\r\n" 
     "Cache-Control: no-store\r\n" 
     "Pragma: no-cache\r\n" 
     "Connection: close\r\n" 
     "\r\n"); 
    for(;;) 
    { 
     if(jbuf.size()<4 || 
      (jbuf[0]!=0xff && jbuf[0]!=0xd8) || 
      (jbuf[jbuf.size()-2]!=0xff && jbuf[jbuf.size()-1]!=0xd9)) 
     { 
      SLEEP(10); 
      continue; 
     } 
     mg_printf(conn, 
      "--b\r\n" 
      "Content-Type: image/jpeg\r\n" 
      "Content-length: %d\r\n" 
      "\r\n",jbuf.size()); 
     int ret=mg_write(conn,&jbuf[0], jbuf.size()); 
     if(ret==0||ret==-1) return 1; 
     SLEEP(50); 
    } 
    return 1; 
} 

int main(void) { 
    struct mg_context *ctx; 
    struct mg_callbacks callbacks; 

    // List of options. Last element must be NULL. 
    const char *options[] = {"listening_ports", "8080",NULL}; 

    // Prepare callbacks structure. We have only one callback, the rest are NULL. 
    memset(&callbacks, 0, sizeof(callbacks)); 
    callbacks.begin_request = begin_request_handler; 

    // Start the web server. 
    ctx = mg_start(&callbacks, NULL, options); 
    cvloop(); 

    // Wait until user hits "enter". Server is running in separate thread. 
    // Navigating to http://localhost:8080 will invoke begin_request_handler(). 
    getchar(); 

    // Stop the server. 
    mg_stop(ctx); 

    return 0; 
}