Some android variable fps videos are detected as 120/240fps (instead of 30)

What is your operating system?
Windows 10 x64

What is your Shotcut version (see Help > About Shotcut)?
24.08.29

Can you repeat the problem? If so, what are the steps?

Some specific .mp4 files are interpreted as 120 fps (and one of them 240) even though they were recorded at 30fps (1080p).

After a bit of digging I found that in Properties → More Information the only 120 is reported for r_frame_rate (120/1) so I assume this is where shotcut reads it and takes precedence over the 2 other fields that have the correct fps. Converting to edit friendly also assumes 120fps and just duplicates each frame 4 times.

I don’t know how widespread this issue is (I have randomly checked some clips from the same day and about 5 out of 30 report wrong fps) but I never noticed it before. I’ll try to grep the r_frame_rate and check to see if my phone randomly decided to start doing this after an update or has always randomly done this.

r_frame_rate=120/1
avg_frame_rate=1800000/60521
...
com.android.capture.fps=30.000000

From this ffmpeg page it seems that this field is not actually the framerate but:

Real base framerate of the stream.

This is the lowest framerate with which all timestamps can be represented accurately (it is the least common multiple of all framerates in the stream). Note, this value is just a guess! For example, if the time base is 1/90000 and all frames have either approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.

I’ll attach the complete more info output for some files.

more info correct 30fps.txt (2.7 KB)
more info 240.txt (2.7 KB)
more info 120.txt (2.7 KB)

I actually used chatgpt succesfully to make a useful quick script, I’m impressed.

Most of the files are ok, but this random r_frame_rate “mismatch” seems to go way back since my first videos with this phone. I don’t see any pattern but it goes both ways (r_frame_rate of 30 on a 240fps slow motion video and r_frame_rate of 120 on a 30fps video).

20220911_104055.mp4: r_frame_rate=120/1, com.android.capture.fps=30.000000
20200905_212140.mp4: r_frame_rate=30/1, com.android.capture.fps=240.000000
20200906_162151.mp4: r_frame_rate=30/1, com.android.capture.fps=30.000000
20200906_163457.mp4: r_frame_rate=30/1, com.android.capture.fps=30.000000

some clips from way back 2016 (all are 29.xx fps):

20160719_100231.mp4: r_frame_rate=90000/1, com.android.capture.fps=
20160719_140153.mp4: r_frame_rate=359/12, com.android.capture.fps=

for file in *.mp4; do
    echo -n "$file: "
    r_frame_rate=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "$file")
    capture_fps=$(ffprobe -v error -show_entries format_tags=com.android.capture.fps -of default=noprint_wrappers=1:nokey=1 "$file")
    echo "r_frame_rate=$r_frame_rate, com.android.capture.fps=$capture_fps"
done

Sadly the “com.android.capture.fps” is only present on my current phone, I guess they added it in a later android release so this can’t be used generally.

The documentation is misleading as it implies there is another better one but does not name it, and yet it is the one that ffmpeg the command line utility uses in your case when using Properties > Convert.

2 other fields that have the correct fps

What other 2 fields? Your avg_frame_rate computes to 29.741742536. Do you want to base your video mode on that and require other videos with sane frame rate values to conform to that? com.android.capture.fps is not actually a field in the stream/codec APIs but I guess something in metadata, which is not something actually used by FFmpeg.

Try using Advanced > Override frate rate in the Convert dialog.

Sure… but let’s look at the full context: 29.741742536 as an automatic video mode is significantly better than 120/240 (or that one r_frame_rate=90000/1 lol).

I agree there’s no standard/clearly defined field for the framerate, I’m just reporting on an issue that I haven’t seen discussion around and I think it’s worth mentioning.


//ok I had to test this 90000 one, I guess it somehow ignores the value from r_frame_rate and just uses the computed avg of 29.827586.

But for the 120/1 (and 240/1) files it creates a 120fps (240fps) project so I’m not sure if it’s better. I’d rather choose the bad yet still close to 30 fps project, the small ghosting/jitter would be way less noticeable than trying to play a 240 fps video on a low power device or tv and simply fail hard.

If it’s working fine for 99% of users I can work around it but seems to be consistently wrong among 3 flagship Samsung phones I have clips to test from, albeit all of them a bit older (galaxy S20, S10 and S7) I assume the android OS is still doing this.

I now realise I haven’t proposed a better solution.

The only reasonable way I can think of is to have a list of standard framerates (24, 25, 29.97, 30 and the x2 values which are very common) and for a variable framerate file test to see if it’s within 10% of any of the values and override it with that.

Otherwise I see a long list of device/software specific fields to individually check for but that just sounds like an unending issue.

Did you do that?

We can try to make convert detect and use com.android.capture.fps but I need to know if the above works and where exactly that value lives. Do you see it in Properties > Metadata?

Yes, it converts correctly if I manually choose 30fps.

Yes, it is there. Here’s a small file with the issue wetransfer.

I fixed it in Properties > Convert (detect metadata and automatically set Override frame rate) as well as in the engine in case one does not convert.

1 Like