Why does ffmpeg / ffprobe report wrong fps for raw MPEG-2 video?
Thanks to this answer, I find out that fps refers to AVStream.avg_frame_rate in the source code.
Then I realize that the raw MPEG video demuxer (which is used for both raw MPEG-1 and MPEG-2 video) is created with common code shared by a bunch of raw demuxers:
[1]
[2]
[3]
The raw video demuxers have a common framerate option, which has a default value of 25, and AVStream.avg_frame_rate would be set to the value of the option by ff_raw_video_read_header():
[4]
[5]
Therefore, -framerate 24000/1001 can be used to allow the muxer to inherit a correct fps / AVStream.avg_frame_rate. Note that the option must be placed before -i input.m2v (but after other -i file, if any) so that it would be used as an demuxer option for that particular input file. For example:
ffmpeg -fflags +genpts -framerate 24000/1001 -i input.m2v -c:v copy output.mkv
Input #0, matroska,webm, from 'output.mkv':
Metadata:
ENCODER : Lavf61.1.100
Duration: 00:23:22.32, start: 0.042000, bitrate: 7963 kb/s
Stream #0:0: Video: mpeg2video (Main), yuv420p(tv, progressive), 720x480 [SAR 8:9 DAR 4:3], 23.98 fps, 23.98 tbr, 1k tbn
Metadata:
DURATION : 00:23:22.318000000
Side data:
cpb: bitrate max/min/avg: 8600000/0/0 buffer size: 1835008 vbv_delay: N/A
P.S. AVStream.avg_frame_rate, if unset (i.e., 0/0), would be set to AVStream.r_frame_rate (tbr), if that is set, at a certain point. However, apparently -framerate 0(/0) is not acceptable even when the min of the AVOption is 0. My guess is that the option parsing code forbids 0(/0) when the option type is AV_OPT_TYPE_VIDEO_RATE. And the reason that ff_raw_video_read_header() has to set AVStream.avg_frame_rate is probably because not all raw video stream / file carries frame rate metadata (which is apparently used to set AVStream.r_frame_rate) like raw MPEG-1/2 video does, and that the function / method is called before AVStream.r_frame_rate is set.
Read more here: Source link
