When encoding H.264 using ffmpeg I get the following type of warnings en masse:
Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large
What do they mean? I have not found anything clear online or in the ffmpeg documentation.
One of the maintainers for the DVDStyler project on SourceForge said this about it:
FFMpeg versions after Jan 15 2015 often display this warning. It has
been added to warn about possible rate control distortion, otherwise
it does not cause any harm.
This warning message appears when trying to encode a high frame rate source to a low frame rate output, which means frames need to be dropped.
I had this error because I wanted to convert a series of images to a video:
ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv
The problem seems to be, that if no frame rate is give for the input, then a frame rate of 25 fps is assumed:
Input #0, image2, from 'frames/%04d.bmp':
Duration: 00:00:15.96, start: 0.000000, bitrate: N/A
Stream #0:0: Video: bmp, bgra, 920x650, 25 fps, 25 tbr, 25 tbn, 25 tbc
This also can be seen on the total number of frames encoded. I had 400 images, but the above command only encoded 384:
frame= 384 fps= 68 q=-1.0 Lsize= 10931kB time=00:00:15.91 bitrate=5626.1kbits/s dup=0 drop=15
video:10928kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033807%
The error messages disappears by setting the input frame rate instead if the output frame rate. The output frame rate will then be automatically chosen to be that of the input. Additionally in newer ffmpeg versions you have to watch out, because when using PNG images with the -i option or rather the image2 or v4l2 input format, you have to use -framerate instead of -r, see the documentation for the -r option.
ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv
It is also possible to specify the frame rate of both input and output separately:
ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv
In this case only 161/400 frames will be encoded. The other frames interim will be dropped.
Also the error message disappears, I guess in order to not slow down ffmpeg by spamming to stdout, see:
https://trac.ffmpeg.org/ticket/4700
https://trac.ffmpeg.org/ticket/4401
Looking at the source code it seems to be that the difference between the presentation time (pts) in the input stream differs from the one in the output stream by more than a fixed limit set to 0.6 .
Snippets from the source:
delta0 = sync_ipts - ost->sync_opts;
delta = delta0 + duration;
...
if (delta0 < 0 &&
delta > 0 &&
format_video_sync != VSYNC_PASSTHROUGH &&
format_video_sync != VSYNC_DROP) {
double cor = FFMIN(-delta0, duration);
if (delta0 < -0.6) {
av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
} else
av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
sync_ipts += cor;
duration -= cor;
delta0 += cor;
}
This is only a quick glance, so please feel free to dig deeper.
I was getting thousands of these warnings with a particular encode. I was downscaling 1080p video to 480p. At an edit point, where there was some dodgy video due to a defect in the source laserdisc, these messages started coming up and then appeared for, I think, every frame thereafter. They went on and on, like this short excerpt:
Past duration 0.901115 too large= 535031kB time=00:54:15.06 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x
Last message repeated 31 times
Past duration 0.901115 too large= 535031kB time=00:54:15.62 bitrate=1346.3kbits/s dup=0 drop=19 speed=1.15x
Last message repeated 34 times
Past duration 0.901115 too large= 535031kB time=00:54:16.21 bitrate=1346.0kbits/s dup=0 drop=19 speed=1.15x
Last message repeated 36 times
Past duration 0.901115 too large= 535338kB time=00:54:16.83 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x
Last message repeated 39 times
The original ffmpeg invocation was this:
ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower \
-crf 17 -c:a copy -y output.mkv
Following suggestions here I first added -framerate 60000/1001 to the input. That did not improve anything. I retained -framerate and added -r 60000/1001 to the output. That still did not improve anything. Retaining both I finally added -async 1 -vsync 1. This resulted in my receiving a single warning, and that's all. That invocation was:
ffmpeg -i input.mp4 -framerate 60000/1001 -s 720x480 -c:v libx264 \
-preset slower -crf 17 -c:a copy -y output.mkv \
-r 60000/1001 -async 1 -vsync 1
The only difference I found in a detailed dump from MediaInfo was the removal of this line found in the original invocation but not in the second one:
Delay relative to video : -33ms
However, I checked A/V sync near the beginning of the files and near the end, and there was no discernible difference in sync between the two files. Their running times were also the same, but that was only measured to the nearest second, in VLC. So I checked the frame counts using ffmpeg like so:
ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -
and looking for "frame=#" near the end of the output.
Turns out the source video was 375226 frames long, the original invocation yielded 375195 frames, and the second invocation yielded 375200. So the second invocation, with vastly fewer warning messages also dropped 5 fewer frames.
Subsequent testing showed that -framerate and -r were unnecessary, and just using the two sync flags was sufficient. This produced identical results to the second invocation above, so the third and simplest invocation I found to solve the problem is this:
ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower \
-crf 17 -c:a copy -y output.mkv -async 1 -vsync 1
And yet another file subsequently produced a bunch of these warnings even with the sync flags, but adding back the rate flags "fixed" it (only produced two instead of thousands of warnings). So sometimes the second invocation works when the third doesn't. For my immediate purposes I'm going to settle on the second invocation and hope it fixes most of these problems.
This was all with ffmpeg version 4.0.
The command should actually be:
ffmpeg -loglevel quiet -i input_file.xyz ...
There is no "-" prefix to the "quiet" parameter, as it's not an option, rather a value for the "-loglevel" option.
As per FFmpeg issue #4700 -
Past duration 0.999992 too large
it is only a warning.
Use -loglevel option to stop it:
ffmpeg -loglevel quiet -i input_file.xyz ....
Possible levels are numbers or:
"quiet"
"panic"
"fatal"
"error"
"warning"
"info"
"verbose"
"debug"
"trace"
Related
I recorded slo-mo video on an iPhone SE (2) by mistake instead of timelapse.
I know there's a lot of answers to this question here, but I'm trying again and again and always something's wrong (like a video that has a correct total no. of frames, but lasts 3 hours and is basically a freeze :D )
My recent command was
ffmpeg -i IMG_2174.MOV -vf framestep=1440,setpts=N/120/TB -c:v libx264
-preset slow -crf 22 -an -r 30 IMG_2174.timelapse.MOV
but it resulted in a one-second-long video, so way over-timelapsed. Should be several seconds IINM. The source video is 30 minutes long #240fps, 17GB.
Thx.
This command seems to do the trick:
ffmpeg -i IMG_2174.MOV -vf framestep=1440,setpts=N/30/TB -c:v libx264 -preset slow -crf 22 -an -r 30 IMG_2174.timelapse.MOV
Here is the explanation for OP's self-answer.
ffmpeg -i IMG_2174.MOV
-vf framestep=1440,setpts=N/30/TB
-r 30 -c:v libx264 -preset slow -crf 22 -an IMG_2174.timelapse.MOV
Given input video at 240 fps cfr:
framestep=1440 keep every 1440th frame, yielding 240/1440 = 1/6 fps
setpts=N/30/TB speeds up the video by x180 (30 / 1/6)
-r 30 output option: match the new pts interval set above
For a vfr video, framestep=1440 likely results in incorrect timing (though on the average correct). For such video, replace the framestep filter with fps=1/6 filter so it picks the frames based on pts rather than frame count.
[edit note: iPhone's slo-mo recording does keep 240fps cfr so the OP's solution is 100% correct, edited down just to mention a vfr-correct approach]
I have a directory that contains 2001 PNG files. I can convert all of the frames to an mp4 video using ffmpeg and the following command:
ffmpeg -framerate 60 -start_number 0 \
-i pic.comp2.%07d.png -c:v libx264 -r 30 \
-pix_fmt yuv420p input1ia.mp4
This works fine. However, I am creating a more complicated application that needs to read only the first 1020 files in the directory (specifically 0 thru 1019). Some googling around led me to the -vframes option. My problem is -- it seems to get ignored or at least interpreted differently than I expect.
My modified command looks like:
ffmpeg -framerate 60 -start_number 0 \
-i pic.comp2.%07d.png -vframes 1020 -c:v libx264
-r 30 -pix_fmt yuv420p input1.mp4
It seems like many other people doing the same thing as me do not encounter this issue. So I did some more digging. I tried changing vframes from 1020 to -vframes 20, and this seemed to work properly. So now I am thinking it might be some kind of mismatch between -framerate and -r?
The full resultant video is 33 sec long... which makes sense mathematically.
1 sec
--------- x 2001 frames = 33.35 seconds
60 frames
That's why I thought that specifying ~1/2 of the PNGs as the 'end point' would result in a video of the first ~16-17 seconds. But I always get the full length video from using the -vframes option.
I assume my input to -vframes must be incorrect mathematically, since a small number of frames seems to work. However, I do not understand why.
The most educated guess I can seem to make is that it is reading the PNGs as 60fps (-framerate), but the -r makes the output video 30fps or something? However, then I would assume that the full output video would not be 33 seconds long.
When the input and output rates don't match, ffmpeg drops or duplicate frames as per a regular scheme to achieve the output rate. So, for an input rate of 60 and an output rate of 30, half the frames are dropped. With the vframes option, 1020 frames at a output rate of 30 should produce a video of duration 1020/30 = 34 seconds.
To achieve what you want, use the t option
ffmpeg -framerate 60 -start_number 0 -t 17 \
-i pic.comp2.%07d.png -c:v libx264 -r 30 \
-pix_fmt yuv420p input1ia.mp4
where 17 is number of frames to be used / input rate
I encounter problems encoding video that I ripped from DVD, after ripping the video size is around 300MB and it plays well and subtitle sync well, then I want a smaller size for tablet and encode it using ffmpeg and the result is around 100MB but the subtitle will always late for 1 frame
# ffmpeg -i "Original.mkv" -level 5.1 -preset veryslow -tune animation -keyint_min 12 -sc_threshold 45 -bf 8 -b_strategy 2 -refs 16 -qmin 10 -qmax 51 -qcomp 0.6 -direct-pred auto -me_range 24 -me_method umh -subq 10 -trellis 2 -an -sn -vcodec libx264 -crf 28.0 output1.mkv
# ffmpeg -i "Original.mkv" -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of output2.aac
# mkvmerge -o outputFF.mkv --language "0:jpn" --track-name "0:SmallAnime Encode # CRF 28.0" output1.mkv --no-chapters --language "0:jpn" --track-name "0:2.0 AAC-LC # 0.4" output2.aac -A -D --language "2:eng" --track-name "2:Styled Subtitle (.ass)" "Original.mkv"
In aegis sub, the video looks well which the subtitle appear normally, however when played using MPC, the subtitle always late 1 frame
Aegis show correctly screenshot : http://puu.sh/6N2gy
Play using MPC problems : http://puu.sh/6N38E.jpg
Anyone know why this happens? The ffmpeg uses libx264 video codec and it is configured using bit depth=10. The OS I am using is CentOS 6.4
It's likely a rounding error - it's something that I've encountered too. Aegisub saves subtitles with timecodes (not frame numbers), and it's possible that Aegisub's timecode does not match what FFMPEG considers to be the correct timecode, resulting in the off-by-one frames.
I've experimented with the -itsoffset flag, which allows you to adjust the input file's time offset. With a 23.98 fps input, I was able to find that a delay of 0.045 (using 1/23.98 == 0.0417014178, and some testing) would work with correcting my early subtitles. As a result, I added -itsoffset -0.045 right before my -i input_file to re-sync the subtitles.
For your case, assuming that you have a similar frame rate, you can try ffmpeg -itsoffset 0.045 -i "Original.mkv" ... and see if that prevents your subtitle delay. Note that -itsoffset 0.045 MUST come before the -i FILE argument since itsoffset DELAY argument modifies inputs after it.
More documentation about -itsoffset can be found here.
Alternatively, you can use the Shift Times tool in Aegisub (Timing > Shift Times) and specify a time of 0:00:01.05 to try and correct the timing there... though I just stuck with the -itsoffset flag since it's much easier to experiment on IMO.
I have been trying to extract keyframes from video using ffmpeg 0.11.1 . So far all the commands I have tried do not extract keyframes but return all the frames ie 25fps*total time number of frames in the output.
I tried setting the keyint_min as 25 to make sure there is a amximum of 1 keyframe per second.
ffmpeg -vf select="eq(pict_type\,PICT_TYPE_I)" -g 250 -keyint_min 25 -i C:\test.mp4 -vsync 2 -f image2 C:\testTemp\thumbnails-%02d.jpeg
But still all the frames are returned.
Then i tried, to separate the keyframes by 20 seconds.
ffmpeg -i C:\test.mp4 -vf select='eq(pict_type\,I)*(isnan(prev_selected_t)+gte(t-prev_selected_t\,20))' -vsync 0 -f image2 C:\testTemp\%09d.jpg
Again same result, all the frames are returned.
What should I do?
In your first command you are using the filter as an input option. I don't know how ffmpeg will interpret that.
Try this:
ffmpeg -i C:\test.mp4 -vf select='eq(pict_type\,I)',setpts='N/(25*TB)' C:\testTemp\%09d.jpg
Change 25 to the frame rate of your source: 30000/1001 for NTSC video, 24000/1001 for NTSC film, 25 for PAL, etc.
Control output quality with the -q:v or -qscale:v option (just called -qscale in old ffmpeg). Range for mpeg* is 1-31 where 31 is the worst quality.
Next time remember that ffmpeg usage questions are to be asked at superuser.com since stackoverflow is specifically for programming.
I'm dealing with a very big issue about bit rate , ffmpeg provide the -b option for the bit rate and for adjustment it provide -minrate and -maxrate, -bufsize but it don't work proper. If i'm giving 256kbps at -b option , when the trans-coding finishes , it provide the 380kbps. How can we achieve the constant bit rate using ffmpeg. If their is +-10Kb it's adjustable. but the video bit rate always exceed by 50-100 kbps.
I'm using following command
ffmpeg -i "demo.avs" -vcodec libx264 -s 320x240 -aspect 4:3 -r 15 -b 256kb \
-minrate 200kb -maxrate 280kb -bufsize 256kb -acodec libmp3lame -ac 2 \
-ar 22050 -ab 64kb -y "output.mp4"
When trans-coding is done, the Media Info show overall bit rate 440kb (it should be 320kb).
Is their something wrong in the command. Or i have to use some other parameter? Plz provide your suggestion its very important.
Those options don't do what you think they do. From the FFmpeg FAQ:
3.18 FFmpeg does not adhere to the -maxrate setting, some frames are bigger than
maxrate/fps.
Read the MPEG spec about video buffer verifier.
3.19 I want CBR, but no matter what I do frame sizes differ.
You do not understand what CBR is, please read the MPEG spec. Read
about video buffer verifier and constant bitrate. The one sentence
summary is that there is a buffer and the input rate is constant, the
output can vary as needed.
Let me highlight a sentance for you:
The one sentence summary is that there is a buffer and the input rate is constant, the output can vary as needed.
That means, in essence that the -maxrate and other settings don't control the output stream rate like you thought they did.