I am experimenting with OpenCV to process frames from a video stream. The goal is to fetch a frame from a stream, process it and then put the processed frame to a new / fresh stream.
I have been able to successfully read streams using OpenCV video capture functionality. But do not know how I can create an output stream with the processed frames.
In order to do some basic tests, I created a stream from a local video file using ffmpeg like so:
ffmpeg -i sample.mp4 -v 0 -vcodec mpeg4 -f mpegts \
"udp://@127.0.0.1:23000?overrun_nonfatal=1&fifo_size=50000000"
And in my C++ code using the VideoCapture functionality of the OpenCV library, I am able to capture the above created stream. A basic layout of what I am trying to achieve is attached below:
cv::VideoCapture capture("udp://@127.0.0.1:23000?overrun_nonfatal=1&fifo_size=50000000", cv::CAP_FFMPEG);
cv::Mat frame;
while (true)
{
// use the above stream to capture a frame
capture >> frame;
// process the frame (not relevant here)
...
// finally, after all the processing is done I
// want to put this frame on a new stream say at
// udp://@127.0.0.1:25000, I don't know how to do
// this, ideally would like to use Video4Linux but
// solutions with ffmpeg are appreciated as well
}
As you can see from comment in above code, I don't have any idea how I should even begin handling this, I tried searching for similar questions but all I could find was how to do VideoCapture using streams, nothing related to outputting to a stream.
I am relatively new to this and this might seem like a very basic question to many of you, please do excuse me.
We may use the same technique as in my following Python code sample.
Execute FFmpeg as sub-process, open stdin pipe for writing
Write
frame.datato stdin pipe of FFmpeg sub-process (in a loop)Close the pipe at the end (it is going to close the sub-process)
The following sample is a generic example - building numbered frames, and writing the encoded video to an MKV output file.
The example uses the following equivalent command line:
ffmpeg -y -f rawvideo -r 10 -video_size 320x240 -pixel_format bgr24 -i pipe: -vcodec libx264 -crf 24 -pix_fmt yuv420p output.mkvYou may adjust the arguments for your specific requirements (replace
output.mkvwithudp://@127.0.0.1:25000).Replace the numbered frame with
capture >> frame, and adjust the size and framerate.Code sample: