Convert to YUV using FFmpeg and Playback Using ffplay

ffmpeg-video-to-yuv
Tags:

Learn how to convert any video into YUV raw video using ffmpeg, play back a YUV file using ffplay, and to calculate the size of a YUV file by hand.


Raw YUV video is often very important in the early steps of video compression research or video processing. It is good to know how to take a compressed and containerized video (like an AVI or MP4 file) and extract the raw video out of it.

In this tutorial, let’s learn how to extract the raw YUV video out of an AVI file and then play it back using ffplay. As a bonus, let’s also learn how to calculate the size of a YUV file by hand.

Convert to Raw YUV Video Using FFmpeg

Let’s take an AVI format video and learn how to convert it to YUV using FFmpeg. The command to do so is shown below –

ffmpeg -i input_720x480p.avi -c:v rawvideo -pixel_format yuv420p output_720x480p.yuv

This command is pretty self-explanatory. Here’s what you are doing –

  • providing an input video to FFmpeg (in my case, it is an AVI file, 720x480p, and 24fps)
  • specifying the output filename (with an .yuv extension)
  • -c:v rawvideo selects the video codec (-c:v) and uses the rawvideo stream specifier to access the raw video via FFmpeg.
  • specify the pixel_format: when you use rawvideo, you need to tell FFmpeg what is the pixel format being used – is it yuv420p, or yuv422p, or any of the many pixel formats that FFmpeg supports.

That’s it – run this command and you’ll get the raw YUV video.

But, you should be careful as raw YUV files tend to be huge in comparison to the input AVI or MP4 files.

Beware of the size of the YUV file – I’m not kidding

The output YUV file is going to be HUGE because the video is uncompressed and the file simply contains raw video pixels.

Here is what I’m talking about –

$ ls -lh *720x480*
-rw-r--r--@ 1 krishna  staff   6.1M Jul  2 14:23 input_720x480.avi
-rw-r--r--  1 krishna  staff   618M Jul  2 11:31 output_720x480.yuv

The input AVI file is 6.1M whereas the output YUV file is 618M. We are talking 618M for a 52 second clip at 720x480p.

Now, just imagine how much space a 1-hour long 1080p 60fps video will occupy, right? You might just run out of disk-space if you aren’t careful.

This is why video compression is so critical to any video service! You can read more about the “why” of video compression here on OTTVerse.

Playing YUV files using ffplay

Most commercial video players cannot play back YUV or raw video files. One of the main reasons is that YUV files are not inside a container format that the players can recognize (i.e, mp4, or avi). So there is no way for the player to know the size of a frame, the frame-rate, number of frames, pixel format, etc.

However, you can use ffplay to playback YUV files by specifying a few commandline parameters. ffplay is a playback utility and is basically a wrapper around ffmpeg with additional code to be able to display video.

When you install ffmpeg on Windows/MacOS/Ubuntu, ffplay gets installed automatically (along with ffprobe – an amazing file analyzer!).Note: If you don’t know how to install ffmpeg or ffplay, then head on over to our easy FFmpeg installation guide for Windows/MacOS/Ubuntu.

You need to tell ffplay the size of a single frame, the frame rate, pixel format, etc. so that it can correctly decipher the size and format of a single frame and proceed to play the video.

Here is the command to play a YUV video using ffplay. The parameters are pretty self-explanatory at this point.

ffplay -f rawvideo -pixel_format yuv420p -video_size 720x480 -i output.yuv

To control ffplay, you can use your spacebar to pause/play, f to toggle between full-screen and native display size, and the arrow keys to skip forward and back.

Here is what the ffplay display looks like –

It’s very basic as you can imagine, but, have no doubts — ffplay is powerful and can be your best friend when every other player doesn’t like your video 🙂

To cement our understanding, let’s provide the wrong frame size to ffplay. Let’s tell ffplay that the size of each frame is 720x240 pixels when in reality, it is 720x480 pixels. This will cause ffplay to read the raw bitstream wrong and create the frame-boundaries at the wrong positions.

ffplay -f rawvideo -pixel_format yuv420p -video_size 720x240 -i output.yuv

Here is what the output looks like when you use ffplay to play YUV files with the wrong file size parameters.

Now we know how to convert a video into YUV format using ffmpeg and play it back using ffplay.

As a final step, let’s learn how to calculate the size of a YUV file. This will help us estimate the required storage space before attempting the conversion process.

Calculating the Size of a YUV420p File

The interesting part of a yuv420p file is that its size can be easily calcuated using some straight-forward video parameters.

So, here is what you need –

  • the resolution of the file (height and width in pixels),
  • the number of frames, and
  • the number of bits per pixel.

After you gather these details, all you need to do is,

  • calculate the number of pixels in a single YUV420 frame
  • multiply that by the bpp (bits per pixel) value to get the size of 1 frame in bits
  • multiply that number by the number of frames in the complete video to get the size of the video in bits
  • divide that by 8 to get the size in bytes.

If you don’t know how to get the number of frames for your video, you can use ffprobe to do so. Here is the command – please modify it for your use-case.

ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 720.avi

Below, I have shown the calculation for an example AVI file. This video’s parameters are :-

  • resolution = 720x480 pixels for the Y-plane, 360x240 pixels for the U and V-planes each. (Why? Because, we are using the yuv420p pixel format where the U and V planes are half the height and width of the Y plane.)
  • number of frames = 1237 (I used ffprobe to get this number)
  • it uses 8 bits to represent each pixel of video. i.e., 8 bpp

Let’s calculate the number of pixels in a single YUV frame –

The number of pixels in a single frame =  (number of pixels in the Y-plane) 
                                        + (number of pixels in the U-plane)
                                        + (number of pixels in the V-plane)

That gives us 720*480 + 360*240 + 360*240 = 518400. The remaining calculations are shown below.

Now, if I go to my Linux terminal and check the size of the YUV file, I see the following –

$ ls -l output.yuv
-rw-r--r--  1 krishna  staff  648000000 Jul  2 11:31 output.yuv

The filesize reported by the OS is 648000000 which matches our calculations exactly. Great job!

See how simple it is to verify a raw YUV video’s filesize?

Conclusion

In this article, you learned

  • how to convert any video format into YUV raw video format,
  • play back a YUV file using ffplay,
  • and to calculate the size of a YUV file by hand.

Hope this helped. In future articles, let’s learn more about the YUV420p pixel format, and why these formats exist in the first place.

About The Author

I’m Dr. Krishna Rao Vijayanagar, and I am the Founder and Editor of OTTVerse.com. I've spent several years working hands-on with Video Codecs (AVC, HEVC, MultiView Plus Depth), ABR streaming, and Video Analytics (QoE, Content & Audience, and Ad). I hope to use my experience and love for video streaming to bring you information and insights into the OTT universe. Please use the Contact Page to get in touch with me.

Leave a Reply