summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/command.c6
-rw-r--r--core/encode_lavc.c60
-rw-r--r--core/mp_memory_barrier.h23
-rw-r--r--core/mp_ring.c155
-rw-r--r--core/mp_ring.h125
-rw-r--r--core/mplayer.c60
-rw-r--r--core/options.c15
-rw-r--r--core/options.h4
8 files changed, 386 insertions, 62 deletions
diff --git a/core/command.c b/core/command.c
index 31097e1030..4da0653425 100644
--- a/core/command.c
+++ b/core/command.c
@@ -571,12 +571,12 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg,
case M_PROPERTY_PRINT: {
char **list = demuxer->info;
char *res = NULL;
- for (int n = 0; list[n]; n += 2) {
+ for (int n = 0; list && list[n]; n += 2) {
res = talloc_asprintf_append_buffer(res, "%s: %s\n",
list[n], list[n + 1]);
}
*(char **)arg = res;
- return M_PROPERTY_OK;
+ return res ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE;
}
case M_PROPERTY_KEY_ACTION: {
struct m_property_action_arg *ka = arg;
@@ -629,7 +629,7 @@ static int mp_property_clock(m_option_t *prop, int action, void *arg,
time_t t = time(NULL);
struct tm *tmp = localtime(&t);
- if ((tmp != NULL) && (strftime(outstr, sizeof(outstr), "%k:%M", tmp) == 5))
+ if ((tmp != NULL) && (strftime(outstr, sizeof(outstr), "%H:%M", tmp) == 5))
return m_property_strdup_ro(prop, action, arg, outstr);
return M_PROPERTY_UNAVAILABLE;
}
diff --git a/core/encode_lavc.c b/core/encode_lavc.c
index 1677baf838..e7c52be221 100644
--- a/core/encode_lavc.c
+++ b/core/encode_lavc.c
@@ -116,10 +116,18 @@ int encode_lavc_oformat_flags(struct encode_lavc_context *ctx)
struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
{
struct encode_lavc_context *ctx;
-
- if (options->file && (
- !strcmp(options->file, "pipe:") ||
- !strcmp(options->file, "pipe:1")))
+ const char *filename = options->file;
+
+ // STUPID STUPID STUPID STUPID avio
+ // does not support "-" as file name to mean stdin/stdout
+ // ffmpeg.c works around this too, the same way
+ if (!strcmp(filename, "-"))
+ filename = "pipe:1";
+
+ if (filename && (
+ !strcmp(filename, "/dev/stdout") ||
+ !strcmp(filename, "pipe:") ||
+ !strcmp(filename, "pipe:1")))
mp_msg_stdout_in_use = 1;
ctx = talloc_zero(NULL, struct encode_lavc_context);
@@ -133,7 +141,7 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
const char *in = ctx->options->format;
while (*in) {
tok = av_get_token(&in, ",");
- ctx->avc->oformat = av_guess_format(tok, ctx->options->file, NULL);
+ ctx->avc->oformat = av_guess_format(tok, filename, NULL);
av_free(tok);
if (ctx->avc->oformat)
break;
@@ -141,14 +149,14 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
++in;
}
} else
- ctx->avc->oformat = av_guess_format(NULL, ctx->options->file, NULL);
+ ctx->avc->oformat = av_guess_format(NULL, filename, NULL);
if (!ctx->avc->oformat) {
encode_lavc_fail(ctx, "encode-lavc: format not found\n");
return NULL;
}
- av_strlcpy(ctx->avc->filename, ctx->options->file,
+ av_strlcpy(ctx->avc->filename, filename,
sizeof(ctx->avc->filename));
ctx->foptions = NULL;
@@ -471,8 +479,8 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
else if (ctx->options->autofps && ctx->vo_fps > 0) {
r = av_d2q(ctx->vo_fps, ctx->vo_fps * 1001 + 2);
mp_msg(
- MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified "
- "but -oautofps is active, using guess of %u/%u\n",
+ MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified "
+ "but --oautofps is active, using guess of %u/%u\n",
(unsigned)r.num, (unsigned)r.den);
} else {
// we want to handle:
@@ -485,7 +493,7 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
r.num = 24000;
r.den = 1;
mp_msg(
- MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified "
+ MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified "
"and fps could not be inferred, using guess of %u/%u\n",
(unsigned)r.num, (unsigned)r.den);
}
@@ -610,7 +618,7 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
"- Codec implementation in ffmpeg/libav is not finished yet.\n"
" Try updating ffmpeg or libav.\n"
"- Bad picture quality, blocks, blurriness.\n"
- " Experiment with codec settings (-ovcopts) to maybe still get the\n"
+ " Experiment with codec settings (--ovcopts) to maybe still get the\n"
" desired quality output at the expense of bitrate.\n"
"- Slow compression.\n"
" Bear with it.\n"
@@ -646,7 +654,7 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
"- Codec implementation in ffmpeg/libav is not finished yet.\n"
" Try updating ffmpeg or libav.\n"
"- Bad sound quality, noise, clicking, whistles, choppiness.\n"
- " Experiment with codec settings (-oacopts) to maybe still get the\n"
+ " Experiment with codec settings (--oacopts) to maybe still get the\n"
" desired quality output at the expense of bitrate.\n"
"- Slow compression.\n"
" Bear with it.\n"
@@ -859,7 +867,7 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
AVOutputFormat *c = NULL;
mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output formats:\n");
while ((c = av_oformat_next(c)))
- mp_msg(MSGT_ENCODE, MSGL_INFO, " -of %-13s %s\n", c->name,
+ mp_msg(MSGT_ENCODE, MSGL_INFO, " --of=%-13s %s\n", c->name,
c->long_name ? c->long_name : "");
av_free(c);
}
@@ -868,16 +876,16 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
AVOutputFormat *format = NULL;
mp_msg(MSGT_ENCODE, MSGL_INFO,
"Available output format ctx->options:\n");
- encode_lavc_printoptions(c, " -ofopts ", " ", NULL,
+ encode_lavc_printoptions(c, " --ofopts=", " ", NULL,
AV_OPT_FLAG_ENCODING_PARAM,
AV_OPT_FLAG_ENCODING_PARAM);
av_free(c);
while ((format = av_oformat_next(format))) {
if (format->priv_class) {
- mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for -of %s:\n",
+ mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --of=%s:\n",
format->name);
- encode_lavc_printoptions(&format->priv_class, " -ofopts ",
- " ", NULL,
+ encode_lavc_printoptions(&format->priv_class, " --ofopts=",
+ " ", NULL,
AV_OPT_FLAG_ENCODING_PARAM,
AV_OPT_FLAG_ENCODING_PARAM);
}
@@ -889,7 +897,7 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
mp_msg(MSGT_ENCODE, MSGL_INFO,
"Available output video codec ctx->options:\n");
encode_lavc_printoptions(
- c, " -ovcopts ", " ", NULL,
+ c, " --ovcopts=", " ", NULL,
AV_OPT_FLAG_ENCODING_PARAM |
AV_OPT_FLAG_VIDEO_PARAM,
AV_OPT_FLAG_ENCODING_PARAM |
@@ -904,11 +912,11 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
strcmp(opts->encode_output.vcodec, codec->name) != 0)
continue;
if (codec->priv_class) {
- mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for -ovc %s:\n",
+ mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --ovc=%s:\n",
codec->name);
encode_lavc_printoptions(
- &codec->priv_class, " -ovcopts ",
- " ", NULL,
+ &codec->priv_class, " --ovcopts=",
+ " ", NULL,
AV_OPT_FLAG_ENCODING_PARAM |
AV_OPT_FLAG_VIDEO_PARAM,
AV_OPT_FLAG_ENCODING_PARAM |
@@ -922,7 +930,7 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
mp_msg(MSGT_ENCODE, MSGL_INFO,
"Available output audio codec ctx->options:\n");
encode_lavc_printoptions(
- c, " -oacopts ", " ", NULL,
+ c, " --oacopts=", " ", NULL,
AV_OPT_FLAG_ENCODING_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
AV_OPT_FLAG_ENCODING_PARAM |
@@ -937,10 +945,10 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
strcmp(opts->encode_output.acodec, codec->name) != 0)
continue;
if (codec->priv_class) {
- mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for -oac %s:\n",
+ mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --oac=%s:\n",
codec->name);
encode_lavc_printoptions(
- &codec->priv_class, " -oacopts ",
+ &codec->priv_class, " --oacopts=",
" ", NULL,
AV_OPT_FLAG_ENCODING_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
@@ -957,7 +965,7 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
continue;
if (c->type != AVMEDIA_TYPE_VIDEO)
continue;
- mp_msg(MSGT_ENCODE, MSGL_INFO, " -ovc %-12s %s\n", c->name,
+ mp_msg(MSGT_ENCODE, MSGL_INFO, " --ovc=%-12s %s\n", c->name,
c->long_name ? c->long_name : "");
}
av_free(c);
@@ -970,7 +978,7 @@ bool encode_lavc_showhelp(struct MPOpts *opts)
continue;
if (c->type != AVMEDIA_TYPE_AUDIO)
continue;
- mp_msg(MSGT_ENCODE, MSGL_INFO, " -oac %-12s %s\n", c->name,
+ mp_msg(MSGT_ENCODE, MSGL_INFO, " --oac=%-12s %s\n", c->name,
c->long_name ? c->long_name : "");
}
av_free(c);
diff --git a/core/mp_memory_barrier.h b/core/mp_memory_barrier.h
new file mode 100644
index 0000000000..e27825de8f
--- /dev/null
+++ b/core/mp_memory_barrier.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of mpv.
+ * Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// At this point both gcc and clang had __sync_synchronize support for some
+// time. We only support a full memory barrier.
+
+#define mp_memory_barrier() __sync_synchronize()
+#define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b)
diff --git a/core/mp_ring.c b/core/mp_ring.c
new file mode 100644
index 0000000000..207dc62e86
--- /dev/null
+++ b/core/mp_ring.c
@@ -0,0 +1,155 @@
+/*
+ * This file is part of mpv.
+ * Copyright (c) 2012 wm4
+ * Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <inttypes.h>
+#include <libavutil/common.h>
+#include <assert.h>
+#include "talloc.h"
+#include "core/mp_memory_barrier.h"
+#include "core/mp_ring.h"
+
+struct mp_ring {
+ uint8_t *buffer;
+
+ /* Positions of thes first readable/writeable chunks. Do not read this
+ * fields but use the atomic private accessors `mp_ring_get_wpos`
+ * and `mp_ring_get_rpos`. */
+ uint32_t rpos, wpos;
+};
+
+static uint32_t mp_ring_get_wpos(struct mp_ring *buffer)
+{
+ mp_memory_barrier();
+ return buffer->wpos;
+}
+
+static uint32_t mp_ring_get_rpos(struct mp_ring *buffer)
+{
+ mp_memory_barrier();
+ return buffer->rpos;
+}
+
+struct mp_ring *mp_ring_new(void *talloc_ctx, int size)
+{
+ struct mp_ring *ringbuffer =
+ talloc_zero(talloc_ctx, struct mp_ring);
+
+ *ringbuffer = (struct mp_ring) {
+ .buffer = talloc_size(talloc_ctx, size),
+ };
+
+ return ringbuffer;
+}
+
+int mp_ring_drain(struct mp_ring *buffer, int len)
+{
+ int buffered = mp_ring_buffered(buffer);
+ int drain_len = FFMIN(len, buffered);
+ mp_atomic_add_and_fetch(&buffer->rpos, drain_len);
+ mp_memory_barrier();
+ return drain_len;
+}
+
+int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len)
+{
+ if (!dest) return mp_ring_drain(buffer, len);
+
+ int size = mp_ring_size(buffer);
+ int buffered = mp_ring_buffered(buffer);
+ int read_len = FFMIN(len, buffered);
+ int read_ptr = mp_ring_get_rpos(buffer) % size;
+
+ int len1 = FFMIN(size - read_ptr, read_len);
+ int len2 = read_len - len1;
+
+ memcpy(dest, buffer->buffer + read_ptr, len1);
+ memcpy(dest + len1, buffer->buffer, len2);
+
+ mp_atomic_add_and_fetch(&buffer->rpos, read_len);
+ mp_memory_barrier();
+
+ return read_len;
+}
+
+int mp_ring_read_cb(struct mp_ring *buffer, void *ctx, int len,
+ void (*func)(void*, void*, int))
+{
+ // The point of this function is defining custom read behaviour, assume
+ // it's a programmers error if func is null.
+ assert(func);
+
+ int size = mp_ring_size(buffer);
+ int buffered = mp_ring_buffered(buffer);
+ int read_len = FFMIN(len, buffered);
+ int read_ptr = mp_ring_get_rpos(buffer) % size;
+
+ func(ctx, buffer->buffer + read_ptr, len);
+
+ return mp_ring_drain(buffer, read_len);
+}
+
+int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len)
+{
+ int size = mp_ring_size(buffer);
+ int free = mp_ring_available(buffer);
+ int write_len = FFMIN(len, free);
+ int write_ptr = mp_ring_get_wpos(buffer) % size;
+
+ int len1 = FFMIN(size - write_ptr, write_len);
+ int len2 = write_len - len1;
+
+ memcpy(buffer->buffer + write_ptr, src, len1);
+ memcpy(buffer->buffer, src + len1, len2);
+
+ mp_atomic_add_and_fetch(&buffer->wpos, write_len);
+ mp_memory_barrier();
+
+ return write_len;
+}
+
+void mp_ring_reset(struct mp_ring *buffer)
+{
+ buffer->wpos = buffer->rpos = 0;
+ mp_memory_barrier();
+}
+
+int mp_ring_available(struct mp_ring *buffer)
+{
+ return mp_ring_size(buffer) - mp_ring_buffered(buffer);
+}
+
+int mp_ring_size(struct mp_ring *buffer)
+{
+ return talloc_get_size(buffer->buffer);
+}
+
+int mp_ring_buffered(struct mp_ring *buffer)
+{
+ return (mp_ring_get_wpos(buffer) - mp_ring_get_rpos(buffer));
+}
+
+char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx)
+{
+ return talloc_asprintf(
+ talloc_ctx,
+ "Ringbuffer { .size = %dB, .buffered = %dB, .available = %dB }",
+ mp_ring_size(buffer),
+ mp_ring_buffered(buffer),
+ mp_ring_available(buffer));
+}
diff --git a/core/mp_ring.h b/core/mp_ring.h
new file mode 100644
index 0000000000..52e885287d
--- /dev/null
+++ b/core/mp_ring.h
@@ -0,0 +1,125 @@
+/*
+ * This file is part of mpv.
+ * Copyright (c) 2012 wm4
+ * Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MPV_MP_RING_H
+#define MPV_MP_RING_H
+
+/**
+ * A simple non-blocking SPSC (single producer, single consumer) ringbuffer
+ * implementation. Thread safety is accomplished through atomic operations.
+ */
+
+struct mp_ring;
+
+/**
+ * Instantiate a new ringbuffer
+ *
+ * talloc_ctx: talloc context of the newly created object
+ * size: total size in bytes
+ * return: the newly created ringbuffer
+ */
+struct mp_ring *mp_ring_new(void *talloc_ctx, int size);
+
+/**
+ * Read data from the ringbuffer
+ *
+ * buffer: target ringbuffer instance
+ * dest: destination buffer for the read data. If NULL read data is discarded.
+ * len: maximum number of bytes to read
+ * return: number of bytes read
+ */
+int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len);
+
+/**
+ * Read data from the ringbuffer
+ *
+ * This function behaves similarly to `av_fifo_generic_read` and was actually
+ * added for compatibility with code that was written for it.
+ * This function will drain the returned amount of bytes from the ringbuffer
+ * so you don't have to handle that in inside `func`.
+ *
+ * buffer: target ringbuffer instance
+ * ctx: context for the callback function
+ * len: maximum number of bytes to read
+ * func: callback function to customize reading behaviour
+ * return: number of bytes read
+ */
+int mp_ring_read_cb(struct mp_ring *buffer, void *ctx, int len,
+ void (*func)(void*, void*, int));
+
+/**
+ * Write data to the ringbuffer
+ *
+ * buffer: target ringbuffer instance
+ * src: source buffer for the write data
+ * len: maximum number of bytes to write
+ * return: number of bytes written
+ */
+int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len);
+
+/**
+ * Drain data from the ringbuffer
+ *
+ * buffer: target ringbuffer instance
+ * len: maximum number of bytes to drain
+ * return: number of bytes drained
+ */
+int mp_ring_drain(struct mp_ring *buffer, int len);
+
+/**
+ * Reset the ringbuffer discarding any content
+ *
+ * buffer: target ringbuffer instance
+ */
+void mp_ring_reset(struct mp_ring *buffer);
+
+/**
+ * Get the available size for writing
+ *
+ * buffer: target ringbuffer instance
+ * return: number of bytes that can be written
+ */
+int mp_ring_available(struct mp_ring *buffer);
+
+/**
+ * Get the total size
+ *
+ * buffer: target ringbuffer instance
+ * return: total ringbuffer size
+ */
+int mp_ring_size(struct mp_ring *buffer);
+
+/**
+ * Get the available size for reading
+ *
+ * buffer: target ringbuffer instance
+ * return: number of bytes ready for reading
+ */
+int mp_ring_buffered(struct mp_ring *buffer);
+
+/**
+ * Get a string representation of the ringbuffer
+ *
+ * buffer: target ringbuffer instance
+ * talloc_ctx: talloc context of the newly created string
+ * return: string representing the ringbuffer
+ */
+char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx);
+
+#endif
diff --git a/core/mplayer.c b/core/mplayer.c
index 7080c5a02e..86260a0598 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -836,7 +836,7 @@ static const char *backup_properties[] = {
"sid",
"sub-delay",
"sub-pos",
- //"sub-visibility",
+ "sub-visibility",
"sub-scale",
"ass-use-margins",
"ass-vsfilter-aspect-compat",
@@ -1112,6 +1112,22 @@ static bool mp_get_cache_idle(struct MPContext *mpctx)
return idle;
}
+static void vo_update_window_title(struct MPContext *mpctx)
+{
+ if (!mpctx->video_out)
+ return;
+ char *title = mp_property_expand_string(mpctx, mpctx->opts.wintitle);
+ if (!mpctx->video_out->window_title ||
+ strcmp(title, mpctx->video_out->window_title))
+ {
+ talloc_free(mpctx->video_out->window_title);
+ mpctx->video_out->window_title = talloc_steal(mpctx, title);
+ vo_control(mpctx->video_out, VOCTRL_UPDATE_WINDOW_TITLE, title);
+ } else {
+ talloc_free(title);
+ }
+}
+
#define saddf(var, ...) (*(var) = talloc_asprintf_append((*var), __VA_ARGS__))
// append time in the hh:mm:ss format (plus fractions if wanted)
@@ -1159,6 +1175,8 @@ static void print_status(struct MPContext *mpctx)
struct MPOpts *opts = &mpctx->opts;
sh_video_t * const sh_video = mpctx->sh_video;
+ vo_update_window_title(mpctx);
+
if (opts->quiet)
return;
@@ -1683,7 +1701,6 @@ void reinit_audio_chain(struct MPContext *mpctx)
goto init_error;
}
if (!ao->initialized) {
- ao->buffersize = opts->ao_buffersize;
ao->encode_lavc_ctx = mpctx->encode_lavc_ctx;
mp_chmap_remove_useless_channels(&ao->channels,
&opts->audio_output_channels);
@@ -2355,15 +2372,6 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
return -partial_fill;
}
-static void vo_update_window_title(struct MPContext *mpctx)
-{
- if (!mpctx->video_out)
- return;
- char *title = mp_property_expand_string(mpctx, mpctx->opts.wintitle);
- talloc_free(mpctx->video_out->window_title);
- mpctx->video_out->window_title = talloc_steal(mpctx, title);
-}
-
static void update_fps(struct MPContext *mpctx)
{
#ifdef CONFIG_ENCODING
@@ -2471,6 +2479,13 @@ int reinit_video_chain(struct MPContext *mpctx)
mpctx->initialized_flags |= INITIALIZED_VCODEC;
+ bool saver_state = opts->pause || !opts->stop_screensaver;
+ vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
+ : VOCTRL_KILL_SCREENSAVER, NULL);
+
+ vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE
+ : VOCTRL_RESUME, NULL);
+
sh_video->last_pts = MP_NOPTS_VALUE;
sh_video->num_buffered_pts = 0;
sh_video->next_frame_time = 0;
@@ -2483,8 +2498,7 @@ int reinit_video_chain(struct MPContext *mpctx)
return 1;
err_out:
- if (!opts->fixed_vo)
- uninit_player(mpctx, INITIALIZED_VO);
+ uninit_player(mpctx, INITIALIZED_VO);
cleanup_demux_stream(mpctx, STREAM_VIDEO);
no_video:
mpctx->current_track[STREAM_VIDEO] = NULL;
@@ -2689,7 +2703,7 @@ static double update_video(struct MPContext *mpctx, double endpts)
if (sh_video->last_pts == MP_NOPTS_VALUE)
sh_video->last_pts = sh_video->pts;
else if (sh_video->last_pts > sh_video->pts) {
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "Decreasing video pts: %f < %f\n",
+ mp_msg(MSGT_CPLAYER, MSGL_WARN, "Decreasing video pts: %f < %f\n",
sh_video->pts, sh_video->last_pts);
/* If the difference in pts is small treat it as jitter around the
* right value (possibly caused by incorrect timestamp ordering) and
@@ -2700,6 +2714,11 @@ static double update_video(struct MPContext *mpctx, double endpts)
sh_video->last_pts = sh_video->pts;
else
sh_video->pts = sh_video->last_pts;
+ } else if (sh_video->pts >= sh_video->last_pts + 60) {
+ // Assume a PTS difference >= 60 seconds is a discontinuity.
+ mp_msg(MSGT_CPLAYER, MSGL_WARN, "Jump in video pts: %f -> %f\n",
+ sh_video->last_pts, sh_video->pts);
+ sh_video->last_pts = sh_video->pts;
}
double frame_time = sh_video->pts - sh_video->last_pts;
sh_video->last_pts = sh_video->pts;
@@ -2712,6 +2731,9 @@ void pause_player(struct MPContext *mpctx)
{
mpctx->opts.pause = 1;
+ if (mpctx->video_out)
+ vo_control(mpctx->video_out, VOCTRL_RESTORE_SCREENSAVER, NULL);
+
if (mpctx->paused)
return;
mpctx->paused = true;
@@ -2738,6 +2760,9 @@ void unpause_player(struct MPContext *mpctx)
{
mpctx->opts.pause = 0;
+ if (mpctx->video_out && mpctx->opts.stop_screensaver)
+ vo_control(mpctx->video_out, VOCTRL_KILL_SCREENSAVER, NULL);
+
if (!mpctx->paused)
return;
// Don't actually unpause while cache is loading.
@@ -2748,8 +2773,7 @@ void unpause_player(struct MPContext *mpctx)
if (mpctx->ao && mpctx->sh_audio)
ao_resume(mpctx->ao);
- if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok
- && !mpctx->step_frames)
+ if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video
(void)get_relative_time(mpctx); // ignore time that passed during pause
}
@@ -2778,8 +2802,6 @@ void add_step_frame(struct MPContext *mpctx, int dir)
{
if (dir > 0) {
mpctx->step_frames += 1;
- if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
- vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
unpause_player(mpctx);
} else if (dir < 0) {
if (!mpctx->backstep_active && !mpctx->hrseek_active) {
@@ -4147,8 +4169,6 @@ static void play_current_file(struct MPContext *mpctx)
if (opts->ass_style_override)
ass_set_style_overrides(mpctx->ass_library, opts->ass_force_style_list);
#endif
- if (mpctx->video_out && mpctx->video_out->config_ok)
- vo_control(mpctx->video_out, VOCTRL_RESUME, NULL);
mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Playing %s.\n", mpctx->filename);
diff --git a/core/options.c b/core/options.c
index b7dd5d7e62..f3e262fc17 100644
--- a/core/options.c
+++ b/core/options.c
@@ -38,15 +38,13 @@
#include "audio/filter/af.h"
#include "audio/decode/dec_audio.h"
#include "mp_core.h"
+#include "osdep/priority.h"
extern char *lirc_configfile;
extern int mp_msg_color;
extern int mp_msg_module;
-/* from dec_audio, currently used for ac3surround decoder only */
-extern int fakemono;
-
extern int dvd_speed; /* stream/stream_dvd.c */
/* defined in demux: */
@@ -452,9 +450,6 @@ const m_option_t mp_opts[] = {
// ------------------------- codec/vfilter options --------------------
- // MP3-only: select stereo/left/right
- {"stereo", &fakemono, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
-
{"af*", &af_cfg.list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
OPT_SETTINGSLIST("vf*", vf_settings, 0, (void *) &vf_obj_list),
@@ -549,8 +544,6 @@ const m_option_t mp_opts[] = {
{"no", 0},
{"yes", 1}, {"", 1})),
OPT_FLAG("gapless-audio", gapless_audio, 0),
- // override audio buffer size (used only by -ao oss/win32, obsolete)
- OPT_INT("abs", ao_buffersize, 0),
// set screen dimensions (when not detectable or virtual!=visible)
OPT_INTRANGE("screenw", vo.screenwidth, CONF_GLOBAL, 0, 4096),
@@ -593,10 +586,10 @@ const m_option_t mp_opts[] = {
OPT_CHOICE_OR_INT("cursor-autohide", vo.cursor_autohide_delay, 0,
0, 30000, ({"no", -1}, {"always", -2})),
+ OPT_FLAG("stop-screensaver", stop_screensaver, 0),
OPT_INT64("wid", vo.WinID, CONF_GLOBAL),
#ifdef CONFIG_X11
- OPT_FLAG("stop-xscreensaver", vo.stop_screensaver, 0),
OPT_STRINGLIST("fstype", vo.fstype_list, 0),
#endif
OPT_STRING("heartbeat-cmd", heartbeat_cmd, 0),
@@ -710,6 +703,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),
@@ -739,7 +733,6 @@ const struct MPOpts mp_default_opts = {
.mixer_init_volume = -1,
.mixer_init_mute = -1,
.volstep = 3,
- .ao_buffersize = -1,
.vo = {
.video_driver_list = NULL,
.cursor_autohide_delay = 1000,
@@ -748,7 +741,6 @@ const struct MPOpts mp_default_opts = {
.fs = false,
.screen_id = -1,
.fsscreen_id = -1,
- .stop_screensaver = 1,
.nomouse_input = 0,
.enable_mouse_movements = 1,
.fsmode = 0,
@@ -761,6 +753,7 @@ const struct MPOpts mp_default_opts = {
},
.wintitle = "mpv - ${media-title}",
.heartbeat_interval = 30.0,
+ .stop_screensaver = 1,
.gamma_gamma = 1000,
.gamma_brightness = 1000,
.gamma_contrast = 1000,
diff --git a/core/options.h b/core/options.h
index 42955cd730..f925990a6c 100644
--- a/core/options.h
+++ b/core/options.h
@@ -14,7 +14,6 @@ typedef struct mp_vo_opts {
bool fs;
int screen_id;
int fsscreen_id;
- int stop_screensaver;
char *winname;
char** fstype_list;
int native_keyrepeat;
@@ -58,7 +57,6 @@ typedef struct MPOpts {
int volstep;
float softvol_max;
int gapless_audio;
- int ao_buffersize;
mp_vo_opts vo;
@@ -72,6 +70,7 @@ typedef struct MPOpts {
int gamma_saturation;
int gamma_hue;
+ int stop_screensaver;
int fullscreen;
int requested_colorspace;
int requested_input_range;
@@ -252,6 +251,7 @@ typedef struct MPOpts {
char *format;
char **fopts;
float fps;
+ float maxfps;
char *vcodec;
char **vopts;
char *acodec;