How to open a GStreamer pipeline from OpenCV with VideoWriter

前端 未结 1 1734
长情又很酷
长情又很酷 2020-11-30 02:53

I am capturing video frames with OpenCV VideoCapture. The capturing works fine as I am able to use the frames like this:

cv::VideoCapture cap(\"v4l2src devic         


        
相关标签:
1条回答
  • 2020-11-30 03:22

    Before using OpenCV's Gstreamer API, we need a working pipeline using the Gstreamer command line tool.

    Sender: The OP is using JPEG encoding, so this pipeline will be using the same encoding.

    gst-launch-1.0 -v v4l2src \
    ! video/x-raw,format=YUY2,width=640,height=480 \
    ! jpegenc \
    ! rtpjpegpay \
    ! udpsink host=127.0.0.1 port=5000
    

    Receiver: The sink caps for rtpjpegdepay need to match the src caps of the rtpjpegpay of sender pipeline.

    gst-launch-1.0 -v udpsrc port=5000 \
    ! application/x-rtp, media=video, clock-rate=90000, encoding-name=JPEG, payload=26 \
    ! rtpjpegdepay \
    ! jpegdec \
    ! xvimagesink sync=0
    

    Now that we have working pipelines for sender and receiver, we can port them to OpenCV.

    Sender:

    void sender()
    {
        // VideoCapture: Getting frames using 'v4l2src' plugin, format is 'BGR' because
        // the VideoWriter class expects a 3 channel image since we are sending colored images.
        // Both 'YUY2' and 'I420' are single channel images. 
        VideoCapture cap("v4l2src ! video/x-raw,format=BGR,width=640,height=480,framerate=30/1 ! appsink",CAP_GSTREAMER);
    
        // VideoWriter: 'videoconvert' converts the 'BGR' images into 'YUY2' raw frames to be fed to
        // 'jpegenc' encoder since 'jpegenc' does not accept 'BGR' images. The 'videoconvert' is not
        // in the original pipeline, because in there we are reading frames in 'YUY2' format from 'v4l2src'
        VideoWriter out("appsrc ! videoconvert ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! jpegenc ! rtpjpegpay ! udpsink host=127.0.0.1 port=5000",CAP_GSTREAMER,0,30,Size(640,480),true);
    
        if(!cap.isOpened() || !out.isOpened())
        {
            cout<<"VideoCapture or VideoWriter not opened"<<endl;
            exit(-1);
        }
    
        Mat frame;
    
        while(true) {
    
            cap.read(frame);
    
            if(frame.empty())
                break;
    
            out.write(frame);
    
            imshow("Sender", frame);
            if(waitKey(1) == 's')
                break;
        }
        destroyWindow("Sender");
    }
    

    Receiver:

    void receiver()
    {    
        // The sink caps for the 'rtpjpegdepay' need to match the src caps of the 'rtpjpegpay' of the sender pipeline
        // Added 'videoconvert' at the end to convert the images into proper format for appsink, without
        // 'videoconvert' the receiver will not read the frames, even though 'videoconvert' is not present
        // in the original working pipeline
        VideoCapture cap("udpsrc port=5000 ! application/x-rtp,media=video,payload=26,clock-rate=90000,encoding-name=JPEG,framerate=30/1 ! rtpjpegdepay ! jpegdec ! videoconvert ! appsink",CAP_GSTREAMER);
    
        if(!cap.isOpened())
        {
            cout<<"VideoCapture not opened"<<endl;
            exit(-1);
        }
    
        Mat frame;
    
        while(true) {
    
            cap.read(frame);
    
            if(frame.empty())
                break;
    
            imshow("Receiver", frame);
            if(waitKey(1) == 'r')
                break;
        }
        destroyWindow("Receiver");
    }
    
    0 讨论(0)
提交回复
热议问题