FFmpeg to the Rescue: Convert 60fps to 30fps

A recent consulting project involved computing the VMAF, SSIM, and PSNR scores of 30 fps 480p video encoded from a 60 fps 1080p source file. I’ve not performed measurements like this in the past and assumed that simply converting the 60 fps sources file to 30 fps via the “-r” option would convert from 60 fps to 30 fps and discard every other frame, which is what I needed. This assumption proved incorrect, and it cost me a morning to figure out a workaround. Here’s what I came up with.

By way of background, here’s MediaInfo on the source file:

Here’s what I tried first, a command that converts the file into a Y4M file at 1080p resolution.

ffmpeg -y -i input_60.mp4  -pix_fmt yuv420p -vsync 0 -r 30   output_30.Y4M

Here’s what MediaInfo said about the file I created. The frame rate looked correct, but when I loaded the file into the Moscow University Video Quality Measurement Tool and compared it to the 480p files I had scaled to 1080p files, I noticed the scores were abnormally low.

A bit more analysis revealed that while FFmpeg had delivered the requested frame rate, it had done so by halving the frame rate and converting the one-minute file to two-minutes and preserving every frame. In fairness, that’s what my argument asked FFmpeg to do, though clearly not what I wanted it to do.

To make a long story short, in FFmpeg-speak, I didn’t want to change the frame rate, I wanted to slow the video down, which you do with the setpts video filter documented here. According to the FFmpeg documentation, “The filter works by changing the presentation timestamp (PTS) of each video frame. For example, if there are two successive frames shown at timestamps 1 and 2, and you want to speed up the video, those timestamps need to become 0.5 and 1, respectively. Thus, we have to multiply them by 0.5.  Note that this method will drop frames to achieve the desired speed.”

This sounded exactly what I wanted, so I tried this argument.

ffmpeg -i input_60.mp4  -filter:v "setpts=0.5*PTS" -pix_fmt yuv420p  output_30.Y4M

This command kept the same speed but threw out every other frame, which is what I wanted. As luck would have it, however, it threw out the wrong frame –  I needed odd frames to compare to my encoded files, and this produced even frames. I fixed this with a simple seek command that advanced FFmpeg 1/60 of a second into the file before starting the conversion.

ffmpeg  -ss 0.0167 -i input_60.mp4  -filter:v "setpts=0.5*PTS" -pix_fmt yuv420p  output_30.Y4M

This created a file I could use to compare to the 30 fps 480p files that I scaled to 1080p Y4M files to perform the comparison.

Author’s Note: During the actual project, I created the 30 fps comparison file in two stages, first creating the 60 fps Y4M file via the first argument, then converting that to 30 fps and seeking to the right frame via the third argument (substituting the 60 fps Y4M file for the input file). While writing this note, I tried contacting the steps to the third argument, which seemed to work just fine, though strangely, the MediaInfo file read the following.

If you run into problems with your conversion, try converting to Y4M first, then from 60 fps to 30 fps. This creates a file that MediaInfo describes as follows.

In both cases, the file worked perfectly in the Moscow State University tool.

These FFmpeg to the Rescue articles will appear in future additions of my book Learn to Produce FFmpeg in 30 Minutes or Less, now in the 2018 Edition. The book helps beginning and intermediate FFmpeg users produce high-quality, bandwidth-efficient files and encoding ladders as efficiently as possible.

About Jan Ozer

Avatar photo
I help companies train new technical hires in streaming media-related positions; I also help companies optimize their codec selections and encoding stacks and evaluate new encoders and codecs. I am a contributing editor to Streaming Media Magazine, writing about codecs and encoding tools. I have written multiple authoritative books on video encoding, including Video Encoding by the Numbers: Eliminate the Guesswork from your Streaming Video (https://amzn.to/3kV6R1j) and Learn to Produce Video with FFmpeg: In Thirty Minutes or Less (https://amzn.to/3ZJih7e). I have multiple courses relating to streaming media production, all available at https://bit.ly/slc_courses. I currently work as www.netint.com as a Senior Director in Marketing.

Check Also

How GPAC Technology is Shaping the Future of Streaming: Key Insights from Fred Dawson

In a recent interview available on YouTube, Jan Ozer sat down with Fred Dawson, an …

New Lessons on Streaming Monetization Added to Streaming Media 101

The Streaming Learning Center is pleased to announce the addition of four new lessons on …

Streaming Summer Bootcamp Session 2: Producing H.264

Announcing session 2 of Streaming Summer Bootcamp: Learn to Produce H.264 Video. Thu, Jul 11, …

Leave a Reply

Your email address will not be published. Required fields are marked *