OpenCV从命名管道ffplay(fifo)

时间:2016-11-06 20:12:39

标签: c++ opencv ffmpeg vlc

我一直在用C ++编写来自OpenCV的管道视频。我尝试在从OpenCV处理到命名管道之后管理图像,最终目标是使用带有VLC或NodeJS服务器的Web服务器重新发布流。

我遇到的问题是OpenCV的输出似乎没有正确处理。视频总是有伪影,即使它应该是原始视频。

enter image description here

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);
}

2 个答案:

答案 0 :(得分:3)

如果您从O_NONBLOCK电话中移除open(),它在我的网站上运行良好。

此外,而不是使用:

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

你可以简单地使用:

ffplay ... -i /tmp/myfifo

答案 1 :(得分:0)

#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 -
相关问题