When I use this command:
ffmpeg -i original.mp4 -codec:v:0 libx264 -b:v 650k -crf 21 -minrate:v 0k -maxrate:v 750k -bufsize:v 5000k -r 30 -preset slow -x264opts "no-scenecut" -vcodec libx264 -force_key_frames "expr:bitor(eq(t,0),gte(t,prev_forced_t+5))" -f mp4 test.mp4
I always get smaller file size than from this command (same command but without: -x264opts "no-scenecut"):
ffmpeg -i original.mp4 -codec:v:0 libx264 -b:v 650k -crf 21 -minrate:v 0k -maxrate:v 750k -bufsize:v 5000k -r 30 -preset slow -vcodec libx264 -force_key_frames "expr:bitor(eq(t,0),gte(t,prev_forced_t+5))" -f mp4 test.mp4
I thought that the scencut puts I frames only if it is more efficient to use I frame insted of P or B frame.
In what cases we need to use the scencut feature?
When a scenecut
triggers it puts either an IDR if the distance is greater than min-keyint
OR an I-frame otherwise.
Here's some pseudo-code posted on the doom9.org forum (adding it here for future reference):
encode current frame as (a really fast approximation of) a P-frame and an I-frame.
if ((distance from previous keyframe) > keyint) then
set IDR-frame
else if (1 - (bit size of P-frame) / (bit size of I-frame) < (scenecut / 100) * (distance from previous keyframe) / keyint) then
if ((distance from previous keyframe) >= minkeyint) then
set IDR-frame
else
set I-frame
else
set P-frame
encode frame for real.
You should use scenecut
when you don't need a fixed GOP / forced keyframes. If you're trying to encode for ABR delivery then you can alternatively use two-pass encoding and generate a stat file for the highest resolution on pass-1 and then reuse it on pass-2 for each rendition.