简体   繁体   中英

OpenCV to ffplay from named pipe (fifo)

I've been working on piping video from OpenCV in C++. I've tried to pipe the image after processing from OpenCV to a named pipe with the end goal of republishing the stream using a webserver either with VLC or a NodeJS server.

Where I'm stuck is that the output from OpenCV doesn't seem to be processing correctly. The video always has artifacts even though it should be the raw video.

在此处输入图片说明

int main(int argc, char** argv)
{

    VideoCapture camera(argv[1]);

    float fps = 15;

    // VLC raw video
    printf("Run command:\n\ncat /tmp/myfifo | cvlc --demux=rawvideo --rawvid-fps=%4.2f --rawvid-width=%.0f --rawvid-height=%.0f  --rawvid-chroma=RV24 - --sout \"#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}\""
        ,fps
        ,camera.get(CV_CAP_PROP_FRAME_WIDTH)
        ,camera.get(CV_CAP_PROP_FRAME_HEIGHT)
        );


    // ffplay raw video
    printf("Run command:\n\ncat /tmp/myfifo | ffplay -f rawvideo -pixel_format bgr24 -video_size %.0fx%.0f -framerate %4.2f -i pipe:"
        ,camera.get(CV_CAP_PROP_FRAME_WIDTH)
        ,camera.get(CV_CAP_PROP_FRAME_HEIGHT)
        ,fps
        );

    int fd;
    int status;

    char const * myFIFO = "/tmp/myfifo";

    if ((status = mkfifo(myFIFO, 0666)) < 0) { 
        // printf("Fifo mkfifo error: %s\n", strerror(errno)); 
        // exit(EXIT_FAILURE);
    } else {
        cout << "Made a named pipe at: " << myFIFO << endl;
    }

    cout << "\n\nHit any key to continue after running one of the previously listed commands..." << endl;
    cin.get();

    if ((fd = open(myFIFO,O_WRONLY|O_NONBLOCK)) < 0) {
        printf("Fifo open error: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }   

    while (true)
    {
        if (waitKey(1) > 0)
        {
            break;    
        }

        Mat colorImage;
        camera >> colorImage; 

        // method: named pipe as matrix writes data to the named pipe, but image has glitch
        size_t bytes = colorImage.total() * colorImage.elemSize();

        if (write(fd, colorImage.data, bytes) < 0) {
            printf("Error in write: %s \n", strerror(errno)); 
        }            
    }

    close(fd);

    exit(EXIT_SUCCESS);
}

It works fine on mine... if you remove O_NONBLOCK from the open() call.

Also, rather than use:

cat /tmp/myfifo | ffplay .... -i pipe:

you can simply use:

ffplay ... -i /tmp/myfifo
#include <io.h>
#include <fcntl.h>
.....
 _setmode(_fileno(stdout), _O_BINARY);

.....
 cv::cvtColor(frame, frame, CV_BGR2RGBA);
            for (int i = 0; i < frame.rows; ++i) {
                uchar* ptr = frame.data + i * 4 * frame.cols;

                for (int j = 0; j < frame.cols * 4; ++j) {
                     std::cout.write((const char*)(ptr + j), 1);

                }
            }


your.exe | ffplay  -an -f rawvideo -vcodec rawvideo -pixel_format bgr32 -video_size 640x480 -i -

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM