首页 文章

MJPEG流媒体和解码

提问于
浏览
16

我想从IP摄像头(通过RTSP)接收JPEG图像 . 为此,我在OpenCV中尝试了 cvCreateFileCapture_FFMPEG . 但是ffmpeg似乎对流媒体的MJPEG格式有一些问题(因为它会自动尝试检测流媒体信息)并且我最终得到以下错误

mjpeg: unsupported coding type

然后,我决定使用live555进行流媒体播放 . 到目前为止,我可以通过openRTSP成功 Build 流媒体和捕获(非解码)图像 .

问题是如何在我的应用程序中执行此操作,例如在OpenCV中 . 如何在OpenCV中使用openRTSP获取图像并以JPEG格式保存?

我听说openRTSP中的数据可以发送到缓冲区(或命名管道),然后在OpenCV的 IplImage 中读取 . 但我不知道该怎么做 .

我将非常感谢有关此问题的任何帮助/建议 . 我需要以下任一问题的答案:

  • 如何禁用ffmpeg的自动流信息检测并指定我自己的格式(mjpeg),或者

  • 如何在OpenCV中使用openRTSP?

问候,

1 回答

  • 18

    这是Axis IP摄像头吗?无论哪种方式,大多数提供 MPEG4 RTSP流的IP摄像机都可以使用 cvCreateFileCapture_FFMPEG 使用OpenCV进行解码 . 但是,ffmpeg decoder的 MJPEG 编解码器有一个众所周知的未解决的问题 . 我相信你会收到类似的 error

    [ingenient @ 0x97d20c0]Could not find codec parameters (Video: mjpeg)
    

    Option1 : Using opencv, libcurl and libjpeg

    要在opencv中查看mjpeg流,请查看以下实现

    http://www.eecs.ucf.edu/~rpatrick/code/onelinksys.chttp://cse.unl.edu/~rpatrick/code/onelinksys.c

    Option2: Using gstreamer (no opencv)

    如果您的目标是查看或保存jpeg图像,我建议您查看gstreamer

    对于 view MJPEG流,可以如下执行媒体管道串

    gst-launch -v souphttpsrc location="http://[ip]:[port]/[dir]/xxx.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec ! ffmpegcolorspace ! autovideosink
    

    对于RTSP

    gst-launch -v rtspsrc location="rtsp://[user]:[pass]@[ip]:[port]/[dir]/xxx.amp" debug=1 ! rtpmp4vdepay ! mpeg4videoparse ! ffdec_mpeg4 ! ffmpegcolorspace! autovideosink
    

    要使用C API,请参阅

    http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Multimedia_Components/Camera_API_Usage

    有关一个简单示例,请查看我在rtsp上的其他帖子,以构建gstreamer C API媒体管道(这与gst-launch字符串相同,但实现为C API)

    Playing RTSP with python-gstreamer

    save MJPEG流作为管道的多个图像(让我们放一个垂直翻转 BIN 并将 PADS 连接到前一个和下一个 BINS 以使其更加漂亮)

    gst-launch souphttpsrc location="http://[ip]:[port]/[dir]/xxx.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec !  videoflip method=vertical-flip ! jpegenc !  multifilesink location=image-out-%05d.jpg
    

    也许值得一看 gst-opencv

    UPDATE:

    Option3: Using gstreamer, Named Pipe and opencv

    在Linux上,可以获取mjpeg流并将其转换为mpeg4并将其提供给命名管道 . 然后在opencv中读取命名管道中的数据

    步骤1.创建命名管道

    mkfifo stream_fifo
    

    步骤2.创建opencvvideo_test.c

    // compile with gcc -ggdb `pkg-config --cflags --libs opencv` opencvvideo_test.c -o opencvvideo_test
    #include <stdio.h>
    #include "highgui.h"
    #include "cv.h"
    
    
    int main( int argc, char** argv){
    
    IplImage  *frame;
        int       key;
    
        /* supply the AVI file to play */
        assert( argc == 2 );
    
        /* load the AVI file */
        CvCapture *capture = cvCreateFileCapture(argv[1]) ;//cvCaptureFromAVI( argv[1] );
    
        /* always check */
        if( !capture ) return 1;    
    
        /* get fps, needed to set the delay */
        int fps = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FPS );
    
        int frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
        int frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
    
        /* display video */
        cvNamedWindow( "video", CV_WINDOW_AUTOSIZE );
    
        while( key != 'q' ) {
    
        double t1=(double)cvGetTickCount();
        /* get a frame */
        frame = cvQueryFrame( capture );
        double t2=(double)cvGetTickCount();
        printf("time: %gms  fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
    
        /* always check */
        if( !frame ) break;
    
        /* display frame */
        cvShowImage( "video", frame );
    
        /* quit if user press 'q' */
        key = cvWaitKey( 1000 / fps );
        }
    
        /* free memory */
        cvReleaseCapture( &capture );
        cvDestroyWindow( "video" );
    
        return 0;
    }
    

    步骤3.准备使用gstreamer从MJPEG转换为MPEG4(传入帧的速率至关重要)

    gst-launch -v souphttpsrc location="http://<ip>/cgi_bin/<mjpeg>.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec ! queue ! videoscale ! 'video/x-raw-yuv, width=640, height=480'! queue ! videorate ! 'video/x-raw-yuv,framerate=30/1' ! queue ! ffmpegcolorspace ! 'video/x-raw-yuv,format=(fourcc)I420' ! ffenc_mpeg4 ! queue ! filesink location=stream_fifo
    

    步骤4.在OpenCV中显示流

    ./opencvvideo_test stream_fifo
    

相关问题