mirror of https://github.com/mpv-player/mpv
Option -omaxfps: limit fps when encoding
Lower-fps content is left alone (NOT aligned to this fps); higher fps content is decimated to this frame rate.
This commit is contained in:
parent
4af59abbb4
commit
0cbc75c083
|
@ -45,6 +45,11 @@ You can encode files from one format/codec to another using this facility.
|
||||||
specified - use --ofps or --oautofps to force CFR encoding in these
|
specified - use --ofps or --oautofps to force CFR encoding in these
|
||||||
cases.
|
cases.
|
||||||
|
|
||||||
|
--omaxfps=<float value>
|
||||||
|
Specifies the minimum distance of adjacent frames (default: 0, which means
|
||||||
|
unset). Content of lower frame rate is not readjusted to this frame rate;
|
||||||
|
content of higher frame rate is decimated to this frame rate.
|
||||||
|
|
||||||
--oharddup
|
--oharddup
|
||||||
If set, the frame rate given by --ofps is attained not by skipping time
|
If set, the frame rate given by --ofps is attained not by skipping time
|
||||||
codes, but by duplicating frames (constant frame rate mode).
|
codes, but by duplicating frames (constant frame rate mode).
|
||||||
|
|
|
@ -709,6 +709,7 @@ const m_option_t mp_opts[] = {
|
||||||
OPT_STRING("of", encode_output.format, CONF_GLOBAL),
|
OPT_STRING("of", encode_output.format, CONF_GLOBAL),
|
||||||
OPT_STRINGLIST("ofopts*", encode_output.fopts, CONF_GLOBAL),
|
OPT_STRINGLIST("ofopts*", encode_output.fopts, CONF_GLOBAL),
|
||||||
OPT_FLOATRANGE("ofps", encode_output.fps, CONF_GLOBAL, 0.0, 1000000.0),
|
OPT_FLOATRANGE("ofps", encode_output.fps, CONF_GLOBAL, 0.0, 1000000.0),
|
||||||
|
OPT_FLOATRANGE("omaxfps", encode_output.maxfps, CONF_GLOBAL, 0.0, 1000000.0),
|
||||||
OPT_STRING("ovc", encode_output.vcodec, CONF_GLOBAL),
|
OPT_STRING("ovc", encode_output.vcodec, CONF_GLOBAL),
|
||||||
OPT_STRINGLIST("ovcopts*", encode_output.vopts, CONF_GLOBAL),
|
OPT_STRINGLIST("ovcopts*", encode_output.vopts, CONF_GLOBAL),
|
||||||
OPT_STRING("oac", encode_output.acodec, CONF_GLOBAL),
|
OPT_STRING("oac", encode_output.acodec, CONF_GLOBAL),
|
||||||
|
|
|
@ -252,6 +252,7 @@ typedef struct MPOpts {
|
||||||
char *format;
|
char *format;
|
||||||
char **fopts;
|
char **fopts;
|
||||||
float fps;
|
float fps;
|
||||||
|
float maxfps;
|
||||||
char *vcodec;
|
char *vcodec;
|
||||||
char **vopts;
|
char **vopts;
|
||||||
char *acodec;
|
char *acodec;
|
||||||
|
|
|
@ -153,6 +153,7 @@ profile = enc-f-mp4
|
||||||
vf-add = dsize=480:360:0:2,scale=w=0:h=0,dsize=-1:-1 # native screen res, letterbox
|
vf-add = dsize=480:360:0:2,scale=w=0:h=0,dsize=-1:-1 # native screen res, letterbox
|
||||||
ovcopts-add = maxrate=1500k,bufsize=1000k,rc_init_occupancy=900k,refs=1,profile=baseline
|
ovcopts-add = maxrate=1500k,bufsize=1000k,rc_init_occupancy=900k,refs=1,profile=baseline
|
||||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||||
|
omaxfps = 30
|
||||||
|
|
||||||
[enc-to-nok-n900]
|
[enc-to-nok-n900]
|
||||||
profile-desc = "MP4 for Nokia N900"
|
profile-desc = "MP4 for Nokia N900"
|
||||||
|
@ -160,6 +161,7 @@ profile = enc-f-mp4
|
||||||
vf-add = dsize=800:480:0:2,scale=w=0:h=0:noup=1,scale=w=-1:h=-2:noup=1,scale=w=-2:h=-1:noup=1,dsize=-1:-1 # native screen res, letterbox
|
vf-add = dsize=800:480:0:2,scale=w=0:h=0:noup=1,scale=w=-1:h=-2:noup=1,scale=w=-2:h=-1:noup=1,dsize=-1:-1 # native screen res, letterbox
|
||||||
ovcopts-add = profile=baseline,level=30,maxrate=10000k,bufsize=10000k,rc_init_occupancy=9000k,refs=5
|
ovcopts-add = profile=baseline,level=30,maxrate=10000k,bufsize=10000k,rc_init_occupancy=9000k,refs=5
|
||||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||||
|
omaxfps = 30
|
||||||
|
|
||||||
[enc-to-nok-6300]
|
[enc-to-nok-6300]
|
||||||
profile-desc = "3GP for Nokia 6300"
|
profile-desc = "3GP for Nokia 6300"
|
||||||
|
@ -186,18 +188,22 @@ profile = enc-f-mp4
|
||||||
oautofps = yes # iphone supports 30fps max
|
oautofps = yes # iphone supports 30fps max
|
||||||
ovcopts-add = maxrate=2500k,bufsize=1000k,rc_init_occupancy=900k,level=30,profile=baseline
|
ovcopts-add = maxrate=2500k,bufsize=1000k,rc_init_occupancy=900k,level=30,profile=baseline
|
||||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||||
|
omaxfps = 30
|
||||||
|
|
||||||
[enc-to-iphone]
|
[enc-to-iphone]
|
||||||
profile-desc = "MP4 for iPhone (480x320)"
|
profile-desc = "MP4 for iPhone (480x320)"
|
||||||
profile = enc-to-iphone-noscale
|
profile = enc-to-iphone-noscale
|
||||||
vf-add = dsize=480:320:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
vf-add = dsize=480:320:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
||||||
|
omaxfps = 30
|
||||||
|
|
||||||
[enc-to-iphone-4]
|
[enc-to-iphone-4]
|
||||||
profile-desc = "MP4 for iPhone 4 (960x640)"
|
profile-desc = "MP4 for iPhone 4 (960x640)"
|
||||||
profile = enc-to-iphone-noscale
|
profile = enc-to-iphone-noscale
|
||||||
vf-add = dsize=960:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
vf-add = dsize=960:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
||||||
|
omaxfps = 30
|
||||||
|
|
||||||
[enc-to-iphone-5]
|
[enc-to-iphone-5]
|
||||||
profile-desc = "MP4 for iPhone 5 (1136x640)"
|
profile-desc = "MP4 for iPhone 5 (1136x640)"
|
||||||
profile = enc-to-iphone-noscale
|
profile = enc-to-iphone-noscale
|
||||||
vf-add = dsize=1136:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
vf-add = dsize=1136:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
||||||
|
omaxfps = 30
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct priv {
|
||||||
double lastpts;
|
double lastpts;
|
||||||
int64_t lastipts;
|
int64_t lastipts;
|
||||||
int64_t lastframeipts;
|
int64_t lastframeipts;
|
||||||
|
int64_t mindeltapts;
|
||||||
double expected_next_pts;
|
double expected_next_pts;
|
||||||
mp_image_t *lastimg;
|
mp_image_t *lastimg;
|
||||||
int lastimg_wants_osd;
|
int lastimg_wants_osd;
|
||||||
|
@ -317,6 +318,11 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||||
vc->worst_time_base = vc->stream->time_base;
|
vc->worst_time_base = vc->stream->time_base;
|
||||||
vc->worst_time_base_is_stream = 1;
|
vc->worst_time_base_is_stream = 1;
|
||||||
}
|
}
|
||||||
|
if (ectx->options->maxfps)
|
||||||
|
vc->mindeltapts = ceil(vc->worst_time_base.den /
|
||||||
|
(vc->worst_time_base.num * ectx->options->maxfps));
|
||||||
|
else
|
||||||
|
vc->mindeltapts = 0;
|
||||||
|
|
||||||
// NOTE: we use the following "axiom" of av_rescale_q:
|
// NOTE: we use the following "axiom" of av_rescale_q:
|
||||||
// if time base A is worse than time base B, then
|
// if time base A is worse than time base B, then
|
||||||
|
@ -394,6 +400,16 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||||
vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream);
|
vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lastipts: pts of last vo frame
|
||||||
|
// frameipts: pts of current vo frame
|
||||||
|
// lastframeipts: pts of last ENCODED frame
|
||||||
|
// now we want to go forward in time until at least lastframeipts + mindeltapts
|
||||||
|
// so let's just assume this frame took place at this time or later
|
||||||
|
if (frameipts >= vc->lastframeipts && frameipts < vc->lastframeipts + vc->mindeltapts) {
|
||||||
|
frameipts = vc->lastframeipts + vc->mindeltapts;
|
||||||
|
vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream);
|
||||||
|
}
|
||||||
|
|
||||||
if (vc->lastipts != MP_NOPTS_VALUE) {
|
if (vc->lastipts != MP_NOPTS_VALUE) {
|
||||||
frame = avcodec_alloc_frame();
|
frame = avcodec_alloc_frame();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue