Discussion:
[FFmpeg-user] converting raw video in mkv to y4m looses framerate.
Andy Furniss
2015-07-27 14:19:01 UTC
Permalink
Original mkv containing raw yuv420p made by ffmpeg some months ago.

I needed to convert to y4m so I do -

ffmpeg -i ducks-2160p60-420.mkv -vcodec copy raw-ducks-2160p60.y4m
ffmpeg version N-74034-gce46627 Copyright (c) 2000-2015 the FFmpeg
developers
built with gcc 4.9.2 (GCC)
configuration: --prefix=/usr --disable-doc --enable-gpl
--enable-nonfree --enable-opencl --enable-libvpx
--enable-libschroedinger --enable-libx265 --enable-libdcadec
--enable-libfdk-aac --enable-libmp3lame --enable-libx264 --enable-x11grab
libavutil 54. 29.100 / 54. 29.100
libavcodec 56. 55.100 / 56. 55.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 29.100 / 5. 29.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
Input #0, matroska,webm, from 'ducks-2160p60-420.mkv':
Metadata:
ENCODER : Lavf56.40.100
Duration: 00:00:08.33, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p,
3840x2160, SAR 1:1 DAR 16:9, 60 fps, 60 tbr, 1k tbn, 1k tbc (default)
Metadata:
ENCODER : Lavc56.47.100 rawvideo
Output #0, yuv4mpegpipe, to 'raw-ducks-2160p60.y4m':
Metadata:
encoder : Lavf56.40.101
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p,
3840x2160 [SAR 1:1 DAR 16:9], q=2-31, 60 fps, 60 tbr, 1k tbn, 1k tbc
(default)
Metadata:
ENCODER : Lavc56.47.100 rawvideo
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 500 fps=3.6 q=-1.0 Lsize= 6075003kB time=00:00:08.31
bitrate=5982979.6kbits/s
video:47kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
muxing overhead: 12959906.000000%

The overhead is a bit high! but the framerate looks good.

Anyway players will play the vid but think it's 1000 fps ffmpeg -i below.

I very recently made a different y4m from scratch (images - same way as
the mkv was made) and all seemed OK with that.
I did note the probesize message but -probesize 500M -analyzeduration 500M
makes no difference (as expected really given y4m header is small)

ffmpeg -i raw-ducks-2160p60.y4m
ffmpeg version N-74034-gce46627 Copyright (c) 2000-2015 the FFmpeg
developers
built with gcc 4.9.2 (GCC)
configuration: --prefix=/usr --disable-doc --enable-gpl
--enable-nonfree --enable-opencl --enable-libvpx
--enable-libschroedinger --enable-libx265 --enable-libdcadec
--enable-libfdk-aac --enable-libmp3lame --enable-libx264 --enable-x11grab
libavutil 54. 29.100 / 54. 29.100
libavcodec 56. 55.100 / 56. 55.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 29.100 / 5. 29.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
[yuv4mpegpipe @ 0x2cc1f00] Stream #0: not enough frames to estimate
rate; consider increasing probesize
Input #0, yuv4mpegpipe, from 'raw-ducks-2160p60.y4m':
Duration: 00:00:00.50, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p,
3840x2160, SAR 1:1 DAR 16:9, 1k fps, 1k tbr, 1k tbn, 1k tbc
Moritz Barsnick
2015-07-27 14:47:41 UTC
Permalink
Post by Andy Furniss
The overhead is a bit high! but the framerate looks good.
:-)
Post by Andy Furniss
Anyway players will play the vid but think it's 1000 fps ffmpeg -i below.
I tried to reproduce, and noticed that indeed the y4m header (very easy
to read, check here: http://wiki.multimedia.cx/index.php?title=YUV4MPEG2)
says 1000 fps.

If I run ffmpeg with "-r 60" as an output option, the framerate is
recorded correctly in the y4m header, see this text diff of the two
output files, which are otherwise identical:

+YUV4MPEG2 W3840 H2160 F1000:1 Ip A1:1 C420jpeg XYSCSS=420JPEG
-YUV4MPEG2 W3840 H2160 F60:1 Ip A1:1 C420jpeg XYSCSS=420JPEG

So, that's your workaround.

If I dare to stab at the root cause of the problem: It might be this
code in libavformat/yuv4mpegenc.c, in yuv4_generate_header():

// TODO: should be avg_frame_rate
av_reduce(&raten, &rated, st->time_base.den,
st->time_base.num, (1UL << 31) - 1);

It shows that the time base of the input stream "st" is being used, and
not the frame rate. (av_reduce() creates numerator and denominator, to
be able to create the quoted string "F1000:1".) And the time base of
the input is indeed "1k", as seen in your logs. This may be a bug, and
the "TODO" may have something to do (excuse the pun) with that.

Moritz
Andy Furniss
2015-07-27 15:19:40 UTC
Permalink
Post by Moritz Barsnick
Post by Andy Furniss
The overhead is a bit high! but the framerate looks good.
:-)
Post by Andy Furniss
Anyway players will play the vid but think it's 1000 fps ffmpeg -i below.
I tried to reproduce, and noticed that indeed the y4m header (very
http://wiki.multimedia.cx/index.php?title=YUV4MPEG2) says 1000 fps.
If I run ffmpeg with "-r 60" as an output option, the framerate is
recorded correctly in the y4m header, see this text diff of the two
+YUV4MPEG2 W3840 H2160 F1000:1 Ip A1:1 C420jpeg XYSCSS=420JPEG
-YUV4MPEG2 W3840 H2160 F60:1 Ip A1:1 C420jpeg XYSCSS=420JPEG
So, that's your workaround.
If I dare to stab at the root cause of the problem: It might be this
// TODO: should be avg_frame_rate av_reduce(&raten, &rated,
st->time_base.den, st->time_base.num, (1UL << 31) - 1);
It shows that the time base of the input stream "st" is being used,
and not the frame rate. (av_reduce() creates numerator and
denominator, to be able to create the quoted string "F1000:1".) And
the time base of the input is indeed "1k", as seen in your logs. This
may be a bug, and the "TODO" may have something to do (excuse the
pun) with that.
That was quick - thanks for looking -r 60 it will be - I would count
it as a bug especially as the output says 60fps.

Loading...