diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/command.c | 6 | ||||
-rw-r--r-- | core/encode_lavc.c | 60 | ||||
-rw-r--r-- | core/mp_memory_barrier.h | 23 | ||||
-rw-r--r-- | core/mp_ring.c | 155 | ||||
-rw-r--r-- | core/mp_ring.h | 125 | ||||
-rw-r--r-- | core/mplayer.c | 60 | ||||
-rw-r--r-- | core/options.c | 15 | ||||
-rw-r--r-- | core/options.h | 4 |
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; |