summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRudolf Polzer <divverent@xonotic.org>2013-06-09 15:37:28 +0200
committerRudolf Polzer <divverent@xonotic.org>2013-06-09 15:37:28 +0200
commit0cbc75c0834a4ba93b67a79467b80324b06165f4 (patch)
tree74ad6b13f0b921a3fcec74743ee740952c3600df
parent4af59abbb416a365a98efca8875c0f0c1b0c872f (diff)
downloadmpv-0cbc75c0834a4ba93b67a79467b80324b06165f4.tar.bz2
mpv-0cbc75c0834a4ba93b67a79467b80324b06165f4.tar.xz
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.
-rw-r--r--DOCS/man/en/encode.rst5
-rw-r--r--core/options.c1
-rw-r--r--core/options.h1
-rw-r--r--etc/encoding-example-profiles.conf6
-rw-r--r--video/out/vo_lavc.c16
5 files changed, 29 insertions, 0 deletions
diff --git a/DOCS/man/en/encode.rst b/DOCS/man/en/encode.rst
index 93b1b84f28..0676cb1479 100644
--- a/DOCS/man/en/encode.rst
+++ b/DOCS/man/en/encode.rst
@@ -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
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
If set, the frame rate given by --ofps is attained not by skipping time
codes, but by duplicating frames (constant frame rate mode).
diff --git a/core/options.c b/core/options.c
index 79d1370e7e..60eb86a448 100644
--- a/core/options.c
+++ b/core/options.c
@@ -709,6 +709,7 @@ const m_option_t mp_opts[] = {
OPT_STRING("of", encode_output.format, CONF_GLOBAL),
OPT_STRINGLIST("ofopts*", encode_output.fopts, CONF_GLOBAL),
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_STRINGLIST("ovcopts*", encode_output.vopts, CONF_GLOBAL),
OPT_STRING("oac", encode_output.acodec, CONF_GLOBAL),
diff --git a/core/options.h b/core/options.h
index 42955cd730..36af43e3f1 100644
--- a/core/options.h
+++ b/core/options.h
@@ -252,6 +252,7 @@ typedef struct MPOpts {
char *format;
char **fopts;
float fps;
+ float maxfps;
char *vcodec;
char **vopts;
char *acodec;
diff --git a/etc/encoding-example-profiles.conf b/etc/encoding-example-profiles.conf
index 890cbc0067..7d67a3e4e4 100644
--- a/etc/encoding-example-profiles.conf
+++ b/etc/encoding-example-profiles.conf
@@ -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
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
+omaxfps = 30
[enc-to-nok-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
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
+omaxfps = 30
[enc-to-nok-6300]
profile-desc = "3GP for Nokia 6300"
@@ -186,18 +188,22 @@ profile = enc-f-mp4
oautofps = yes # iphone supports 30fps max
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
+omaxfps = 30
[enc-to-iphone]
profile-desc = "MP4 for iPhone (480x320)"
profile = enc-to-iphone-noscale
vf-add = dsize=480:320:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
+omaxfps = 30
[enc-to-iphone-4]
profile-desc = "MP4 for iPhone 4 (960x640)"
profile = enc-to-iphone-noscale
vf-add = dsize=960:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
+omaxfps = 30
[enc-to-iphone-5]
profile-desc = "MP4 for iPhone 5 (1136x640)"
profile = enc-to-iphone-noscale
vf-add = dsize=1136:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
+omaxfps = 30
diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c
index 5140720f92..840103c0c2 100644
--- a/video/out/vo_lavc.c
+++ b/video/out/vo_lavc.c
@@ -48,6 +48,7 @@ struct priv {
double lastpts;
int64_t lastipts;
int64_t lastframeipts;
+ int64_t mindeltapts;
double expected_next_pts;
mp_image_t *lastimg;
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_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:
// 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);
}
+ // 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) {
frame = avcodec_alloc_frame();