How to write YUV 420 video frames from RGB data us

2020-07-22 17:34发布

问题:

I have an array of rgb data generated from glReadPixels().
Note that RGB data is pixel packed (r1,g1,b1,r2,g2,b2,...).

How can I quickly write a YUV video frame using OpenCV or another C++ library, so that I can stream them to FFMPEG? Converting RGB pixel to YUV pixel is not a problem, as there are many conversion formula available online. However writing the YUV frame is the main problem for me. I have been trying to write the YUV video frame since the last few days and were not successful in doing that.

This is one of my other question about writing YUV frame and the issues that I encountered: Issue with writing YUV image frame in C/C++ I don't know what is wrong with my current approach in writing the YUV frame to a file.

So right now I may want to use existing library (if any), that accepts an RGB data, and convert them to YUV and write the YUV frame directly to a file or to a pipe. Of course it would be much better if I can fix my existing program to write the YUV frame, but you know, there is also a deadline in every software development project, so time is also a priority for me and my project team members.

回答1:

FFmpeg will happily receive RGB data in. You can see what pixel formats FFmpeg supports by running:

ffmpeg -pix_fmts

Any entry with an I in the first column can be used as an input.

Since you haven't specified the pixel bit depth, I am going to assume it's 8-bit and use the rgb8 pixel format. So to get FFmpeg to read rgb8 data from stdin you would use the following command (I am cating data in but you would be supplying via your pipe):

cat data.rgb | ffmpeg -f rawvideo -pix_fmt rgb8 -s WIDTHxHEIGHT -i pipe:0 output.mov

Since it is a raw pixel format with no framing, you need to subsitite WIDTH and HEIGHT for the appropriate values of your image dimensions so that FFmpeg knows how to frame the data.

I have specifed the output as a MOV file but you would need to configure your FFmpeg/Red5 output accordingly.



回答2:

OpenCV does not support the YUV format directly, as you know, so it's really up to you to find a way to do RGB <-> YUV conversions.

This is a very interesting post as it shows how to load and create YUV frames on the disk, while storing the data as IplImage.



回答3:

ffmpeg will write an AVI file with YUV but as karl says there isn't direct support for it in openCV.

Alternatively (and possibly simpler) you can just write the raw UYVY values to a file and then use ffmpeg to convert it to an AVI/MP4 in any format you want. It's also possible to write directly to a pipe and call ffmpeg directly from your app avoiding the temporary yuv file

eg. to convert an HD yuv422 stream to a h264 MP4 file at 30fps

ffmpeg -pix_fmt yuyv422 -s 1920x1080 -i input.yuv -vcodec libx264 -x264opts -r 30 output.mp4