core: remove a number of global variables

Move them into per-instance structs. This should get rid of all global
variables in mplayer.c (not counting those referenced by cfg-mplayer.h).

In core/input/ar.c, just remove checking the slave_mode variable. I'm
not sure what this code was supposed to achieve, but slave mode is
broken, slave mode is actually infeasible on OSX (ar.c is completely OSX
specific), and the correct way of doing this would be to disable this
input device per command line switch.
This commit is contained in:
wm4 2013-03-08 02:08:02 +01:00
parent 14427ae2ee
commit bc20f2cb00
9 changed files with 103 additions and 112 deletions

View File

@ -342,11 +342,11 @@ const m_option_t common_opts[] = {
// ------------------------- demuxer options -------------------- // ------------------------- demuxer options --------------------
// number of frames to play/convert OPT_CHOICE_OR_INT("frames", play_frames, 0, 0, INT_MAX,
{"frames", &play_n_frames_mf, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL}, ({"all", -1})),
// seek to byte/seconds position // seek to byte/seconds position
{"sb", &seek_to_byte, CONF_TYPE_INT64, CONF_MIN, 0, 0, NULL}, OPT_INT64("sb", seek_to_byte, 0),
OPT_REL_TIME("start", play_start, 0), OPT_REL_TIME("start", play_start, 0),
OPT_REL_TIME("end", play_end, 0), OPT_REL_TIME("end", play_end, 0),
OPT_REL_TIME("length", play_length, 0), OPT_REL_TIME("length", play_length, 0),
@ -412,20 +412,20 @@ const m_option_t common_opts[] = {
{"bps", &pts_from_bps, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"bps", &pts_from_bps, CONF_TYPE_FLAG, 0, 0, 1, NULL},
// set A-V sync correction speed (0=disables it): // set A-V sync correction speed (0=disables it):
{"mc", &default_max_pts_correction, CONF_TYPE_FLOAT, CONF_RANGE, 0, 100, NULL}, OPT_FLOATRANGE("mc", default_max_pts_correction, 0, 0, 100),
// force video/audio rate: // force video/audio rate:
{"fps", &force_fps, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL}, OPT_DOUBLE("fps", force_fps, CONF_MIN, 0),
{"srate", &force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL}, OPT_INTRANGE("srate", force_srate, 0, 1000, 8*48000),
OPT_INTRANGE("channels", audio_output_channels, 0, 1, 8), OPT_INTRANGE("channels", audio_output_channels, 0, 1, 8),
OPT_AUDIOFORMAT("format", audio_output_format, 0), OPT_AUDIOFORMAT("format", audio_output_format, 0),
OPT_FLOATRANGE("speed", playback_speed, 0, 0.01, 100.0), OPT_FLOATRANGE("speed", playback_speed, 0, 0.01, 100.0),
// set a-v distance // set a-v distance
{"audio-delay", &audio_delay, CONF_TYPE_FLOAT, CONF_RANGE, -100.0, 100.0, NULL}, OPT_FLOATRANGE("audio-delay", audio_delay, 0, -100.0, 100.0),
// ignore header-specified delay (dwStart) // ignore header-specified delay (dwStart)
{"ignore-start", &ignore_start, CONF_TYPE_FLAG, 0, 0, 1, NULL}, OPT_FLAG("ignore-start", ignore_start, 0),
OPT_FLOATRANGE("a52drc", drc_level, 0, 0, 2), OPT_FLOATRANGE("a52drc", drc_level, 0, 0, 2),
@ -478,7 +478,7 @@ const m_option_t common_opts[] = {
{"sub-delay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL}, {"sub-delay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
{"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL}, {"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
OPT_FLAG("autosub", sub_auto, 0), OPT_FLAG("autosub", sub_auto, 0),
{"sub-forced-only", &forced_subs_only, CONF_TYPE_FLAG, 0, 0, 1, NULL}, OPT_FLAG("sub-forced-only", forced_subs_only, 0),
// enable Closed Captioning display // enable Closed Captioning display
{"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL}, {"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL},
{"sub-no-text-pp", &sub_no_text_pp, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"sub-no-text-pp", &sub_no_text_pp, CONF_TYPE_FLAG, 0, 0, 1, NULL},
@ -595,7 +595,7 @@ const m_option_t mplayer_opts[]={
OPT_FLAG("stop-xscreensaver", vo.stop_screensaver, 0), OPT_FLAG("stop-xscreensaver", vo.stop_screensaver, 0),
OPT_STRINGLIST("fstype", vo.fstype_list, 0), OPT_STRINGLIST("fstype", vo.fstype_list, 0),
#endif #endif
{"heartbeat-cmd", &heartbeat_cmd, CONF_TYPE_STRING, 0, 0, 0, NULL}, OPT_STRING("heartbeat-cmd", heartbeat_cmd, 0),
OPT_FLAG("mouseinput", vo.nomouse_input, 0), OPT_FLAG("mouseinput", vo.nomouse_input, 0),
OPT_CHOICE_OR_INT("screen", vo.screen_id, 0, 0, 32, OPT_CHOICE_OR_INT("screen", vo.screen_id, 0, 0, 32,
@ -613,13 +613,13 @@ const m_option_t mplayer_opts[]={
//---------------------- mplayer-only options ------------------------ //---------------------- mplayer-only options ------------------------
{"use-filedir-conf", &use_filedir_conf, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL}, OPT_FLAG("use-filedir-conf", use_filedir_conf, CONF_GLOBAL),
OPT_CHOICE("osd-level", osd_level, 0, OPT_CHOICE("osd-level", osd_level, 0,
({"0", 0}, {"1", 1}, {"2", 2}, {"3", 3})), ({"0", 0}, {"1", 1}, {"2", 2}, {"3", 3})),
OPT_INTRANGE("osd-duration", osd_duration, 0, 0, 3600000), OPT_INTRANGE("osd-duration", osd_duration, 0, 0, 3600000),
OPT_FLAG("osd-fractions", osd_fractions, 0), OPT_FLAG("osd-fractions", osd_fractions, 0),
{"sstep", &step_sec, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL}, OPT_DOUBLE("sstep", step_sec, CONF_MIN, 0),
OPT_CHOICE("framedrop", frame_dropping, 0, OPT_CHOICE("framedrop", frame_dropping, 0,
({"no", 0}, ({"no", 0},
@ -670,7 +670,7 @@ const m_option_t mplayer_opts[]={
OPT_STRING("status-msg", status_msg, M_OPT_PARSE_ESCAPES), OPT_STRING("status-msg", status_msg, M_OPT_PARSE_ESCAPES),
OPT_STRING("osd-status-msg", osd_status_msg, M_OPT_PARSE_ESCAPES), OPT_STRING("osd-status-msg", osd_status_msg, M_OPT_PARSE_ESCAPES),
{"slave-broken", &slave_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL}, OPT_FLAG("slave-broken", slave_mode, CONF_GLOBAL),
OPT_FLAG("idle", player_idle_mode, CONF_GLOBAL), OPT_FLAG("idle", player_idle_mode, CONF_GLOBAL),
OPT_INTRANGE("key-fifo-size", input.key_fifo_size, CONF_GLOBAL, 2, 65000), OPT_INTRANGE("key-fifo-size", input.key_fifo_size, CONF_GLOBAL, 2, 65000),
OPT_FLAG("consolecontrols", consolecontrols, CONF_GLOBAL), OPT_FLAG("consolecontrols", consolecontrols, CONF_GLOBAL),

View File

@ -594,14 +594,14 @@ static int mp_property_audio_delay(m_option_t *prop, int action,
{ {
if (!(mpctx->sh_audio && mpctx->sh_video)) if (!(mpctx->sh_audio && mpctx->sh_video))
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
float delay = audio_delay; float delay = mpctx->opts.audio_delay;
switch (action) { switch (action) {
case M_PROPERTY_PRINT: case M_PROPERTY_PRINT:
*(char **)arg = format_delay(delay); *(char **)arg = format_delay(delay);
return M_PROPERTY_OK; return M_PROPERTY_OK;
case M_PROPERTY_SET: case M_PROPERTY_SET:
audio_delay = *(float *)arg; mpctx->audio_delay = mpctx->opts.audio_delay = *(float *)arg;
mpctx->delay -= audio_delay - delay; mpctx->delay -= mpctx->audio_delay - delay;
return M_PROPERTY_OK; return M_PROPERTY_OK;
} }
return mp_property_generic_option(prop, action, arg, mpctx); return mp_property_generic_option(prop, action, arg, mpctx);
@ -1247,12 +1247,14 @@ static int mp_property_sub_visibility(m_option_t *prop, int action,
static int mp_property_sub_forced_only(m_option_t *prop, int action, static int mp_property_sub_forced_only(m_option_t *prop, int action,
void *arg, MPContext *mpctx) void *arg, MPContext *mpctx)
{ {
struct MPOpts *opts = &mpctx->opts;
if (!vo_spudec) if (!vo_spudec)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_SET) { if (action == M_PROPERTY_SET) {
forced_subs_only = *(int *)arg; opts->forced_subs_only = *(int *)arg;
spudec_set_forced_subs_only(vo_spudec, forced_subs_only); spudec_set_forced_subs_only(vo_spudec, opts->forced_subs_only);
return M_PROPERTY_OK; return M_PROPERTY_OK;
} }
return mp_property_generic_option(prop, action, arg, mpctx); return mp_property_generic_option(prop, action, arg, mpctx);

View File

@ -57,6 +57,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.term_osd = 2, .term_osd = 2,
.consolecontrols = 1, .consolecontrols = 1,
.doubleclick_time = 300, .doubleclick_time = 300,
.play_frames = -1,
.keep_open = 0, .keep_open = 0,
.audio_id = -1, .audio_id = -1,
.video_id = -1, .video_id = -1,

View File

@ -33,8 +33,6 @@
#include "ar.h" #include "ar.h"
#include "keycodes.h" #include "keycodes.h"
extern int slave_mode;
extern const double NSAppKitVersionNumber; extern const double NSAppKitVersionNumber;
typedef struct cookie_keycode_map { typedef struct cookie_keycode_map {
@ -313,9 +311,6 @@ static int is_mplayer_front(void)
&& SameProcess(&frProc, &myProc, &sameProc) == noErr) { && SameProcess(&frProc, &myProc, &sameProc) == noErr) {
if (sameProc) if (sameProc)
return 1; return 1;
// If MPlayer is running in slave mode, also check parent process.
if (slave_mode && GetProcessPID(&frProc, &parentPID) == noErr)
return parentPID==getppid();
} }
return 0; return 0;
} }

View File

@ -563,6 +563,9 @@ static inline void m_option_free(const m_option_t *opt, void *dst)
#define OPT_FLOAT(...) \ #define OPT_FLOAT(...) \
OPT_GENERAL(float, __VA_ARGS__, .type = &m_option_type_float) OPT_GENERAL(float, __VA_ARGS__, .type = &m_option_type_float)
#define OPT_DOUBLE(...) \
OPT_GENERAL(double, __VA_ARGS__, .type = &m_option_type_double)
#define OPT_STRING(...) \ #define OPT_STRING(...) \
OPT_GENERAL(char*, __VA_ARGS__, .type = &m_option_type_string) OPT_GENERAL(char*, __VA_ARGS__, .type = &m_option_type_string)

View File

@ -199,6 +199,11 @@ typedef struct MPContext {
// How much video timing has been changed to make it match the audio // How much video timing has been changed to make it match the audio
// timeline. Used for status line information only. // timeline. Used for status line information only.
double total_avsync_change; double total_avsync_change;
// Total number of dropped frames that were "approved" to be dropped.
// Actual dropping depends on --framedrop and decoder internals.
int drop_frame_cnt;
// Number of frames dropped in a row.
int dropped_frames;
// A-V sync difference when last frame was displayed. Kept to display // A-V sync difference when last frame was displayed. Kept to display
// the same value if the status line is updated at a time where no new // the same value if the status line is updated at a time where no new
// video frame is shown. // video frame is shown.
@ -211,6 +216,8 @@ typedef struct MPContext {
// period of time until a new frame is decoded and shown.) // period of time until a new frame is decoded and shown.)
double last_vo_pts; double last_vo_pts;
float audio_delay;
// used to prevent hanging in some error cases // used to prevent hanging in some error cases
unsigned int start_timestamp; unsigned int start_timestamp;
@ -246,6 +253,8 @@ typedef struct MPContext {
int paused; int paused;
// step this many frames, then pause // step this many frames, then pause
int step_frames; int step_frames;
// Counted down each frame, stop playback if 0 is reached. (-1 = disable)
int max_frames;
bool paused_for_cache; bool paused_for_cache;

View File

@ -94,16 +94,10 @@
#include "osdep/timer.h" #include "osdep/timer.h"
#include "core/input/input.h" #include "core/input/input.h"
#include "core/encode.h" #include "core/encode.h"
int slave_mode = 0;
int enable_mouse_movements = 0;
#include "osdep/priority.h" #include "osdep/priority.h"
char *heartbeat_cmd;
#include "stream/tv.h" #include "stream/tv.h"
#include "stream/stream_radio.h" #include "stream/stream_radio.h"
#ifdef CONFIG_DVBIN #ifdef CONFIG_DVBIN
@ -194,36 +188,11 @@ static const char av_desync_help_text[] = _(
//**************************************************************************// //**************************************************************************//
#include "core/mp_fifo.h" #include "core/mp_fifo.h"
static int drop_frame_cnt; // total number of dropped frames
// seek:
static int64_t seek_to_byte;
static double step_sec;
// this dvdsub_id was selected via slang
// use this to allow dvdnav to follow -slang across stream resets,
// in particular the subtitle ID for a language changes
int dvdsub_lang_id;
int forced_subs_only = 0;
// A-V sync:
static float default_max_pts_correction = -1;
float audio_delay = 0;
static int ignore_start = 0;
double force_fps = 0;
static int force_srate = 0;
static int play_n_frames = -1;
static int play_n_frames_mf = -1;
#include "sub/ass_mp.h" #include "sub/ass_mp.h"
// --- // ---
int use_filedir_conf;
#include "core/mp_common.h" #include "core/mp_common.h"
#include "core/command.h" #include "core/command.h"
@ -440,7 +409,7 @@ static void init_demux_stream(struct MPContext *mpctx, enum stream_type type)
demuxer_switch_track(stream->demuxer, type, stream); demuxer_switch_track(stream->demuxer, type, stream);
if (track->is_external) { if (track->is_external) {
double pts = get_main_demux_pts(mpctx); double pts = get_main_demux_pts(mpctx);
demux_seek(stream->demuxer, pts, audio_delay, SEEK_ABSOLUTE); demux_seek(stream->demuxer, pts, mpctx->audio_delay, SEEK_ABSOLUTE);
} }
} }
} }
@ -752,7 +721,8 @@ static int try_load_config(m_config_t *conf, const char *file)
return 1; return 1;
} }
static void load_per_file_config(m_config_t *conf, const char * const file) static void load_per_file_config(m_config_t *conf, const char * const file,
bool search_file_dir)
{ {
char *confpath; char *confpath;
char cfg[MP_PATH_MAX]; char cfg[MP_PATH_MAX];
@ -766,7 +736,7 @@ static void load_per_file_config(m_config_t *conf, const char * const file)
sprintf(cfg, "%s.conf", file); sprintf(cfg, "%s.conf", file);
name = mp_basename(cfg); name = mp_basename(cfg);
if (use_filedir_conf) { if (search_file_dir) {
char dircfg[MP_PATH_MAX]; char dircfg[MP_PATH_MAX];
strcpy(dircfg, cfg); strcpy(dircfg, cfg);
strcpy(dircfg + (name - cfg), "mpv.conf"); strcpy(dircfg + (name - cfg), "mpv.conf");
@ -1002,8 +972,8 @@ void init_vo_spudec(struct MPContext *mpctx)
if (vo_spudec != NULL) { if (vo_spudec != NULL) {
mpctx->initialized_flags |= INITIALIZED_SPUDEC; mpctx->initialized_flags |= INITIALIZED_SPUDEC;
mp_property_do("sub-forced-only", M_PROPERTY_SET, &forced_subs_only, mp_property_do("sub-forced-only", M_PROPERTY_SET,
mpctx); &mpctx->opts.forced_subs_only, mpctx);
} }
} }
@ -1131,9 +1101,9 @@ static void print_status(struct MPContext *mpctx)
if (endpos != -1) if (endpos != -1)
position = max(position, (get_current_time(mpctx) - startpos) position = max(position, (get_current_time(mpctx) - startpos)
/ (endpos - startpos)); / (endpos - startpos));
if (play_n_frames_mf) if (opts->play_frames > 0)
position = max(position, position = max(position,
1.0 - play_n_frames / (double) play_n_frames_mf); 1.0 - mpctx->max_frames / (double) opts->play_frames);
char lavcbuf[80]; char lavcbuf[80];
if (encode_lavc_getstatus(mpctx->encode_lavc_ctx, lavcbuf, sizeof(lavcbuf), if (encode_lavc_getstatus(mpctx->encode_lavc_ctx, lavcbuf, sizeof(lavcbuf),
position, get_current_time(mpctx) - startpos) >= 0) position, get_current_time(mpctx) - startpos) >= 0)
@ -1144,8 +1114,8 @@ static void print_status(struct MPContext *mpctx)
#endif #endif
{ {
// VO stats // VO stats
if (sh_video && drop_frame_cnt) if (sh_video && mpctx->drop_frame_cnt)
saddf(&line, " D: %d", drop_frame_cnt); saddf(&line, " D: %d", mpctx->drop_frame_cnt);
} }
int cache = mp_get_cache_percent(mpctx); int cache = mp_get_cache_percent(mpctx);
@ -1563,7 +1533,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
if (!(mpctx->initialized_flags & INITIALIZED_AO)) { if (!(mpctx->initialized_flags & INITIALIZED_AO)) {
mpctx->initialized_flags |= INITIALIZED_AO; mpctx->initialized_flags |= INITIALIZED_AO;
mpctx->ao = ao_create(opts, mpctx->input); mpctx->ao = ao_create(opts, mpctx->input);
mpctx->ao->samplerate = force_srate; mpctx->ao->samplerate = opts->force_srate;
mpctx->ao->format = opts->audio_output_format; mpctx->ao->format = opts->audio_output_format;
} }
ao = mpctx->ao; ao = mpctx->ao;
@ -1859,18 +1829,17 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time)
struct MPOpts *opts = &mpctx->opts; struct MPOpts *opts = &mpctx->opts;
// check for frame-drop: // check for frame-drop:
if (mpctx->sh_audio && !mpctx->ao->untimed && !mpctx->sh_audio->ds->eof) { if (mpctx->sh_audio && !mpctx->ao->untimed && !mpctx->sh_audio->ds->eof) {
static int dropped_frames;
float delay = opts->playback_speed * ao_get_delay(mpctx->ao); float delay = opts->playback_speed * ao_get_delay(mpctx->ao);
float d = delay - mpctx->delay; float d = delay - mpctx->delay;
// we should avoid dropping too many frames in sequence unless we // we should avoid dropping too many frames in sequence unless we
// are too late. and we allow 100ms A-V delay here: // are too late. and we allow 100ms A-V delay here:
if (d < -dropped_frames * frame_time - 0.100 && !mpctx->paused if (d < -mpctx->dropped_frames * frame_time - 0.100 && !mpctx->paused
&& !mpctx->restart_playback) { && !mpctx->restart_playback) {
++drop_frame_cnt; mpctx->drop_frame_cnt++;
++dropped_frames; mpctx->dropped_frames++;
return mpctx->opts.frame_dropping; return mpctx->opts.frame_dropping;
} else } else
dropped_frames = 0; mpctx->dropped_frames = 0;
} }
return 0; return 0;
} }
@ -2091,6 +2060,8 @@ bool mp_remove_track(struct MPContext *mpctx, struct track *track)
*/ */
static void adjust_sync(struct MPContext *mpctx, double frame_time) static void adjust_sync(struct MPContext *mpctx, double frame_time)
{ {
struct MPOpts *opts = &mpctx->opts;
if (!mpctx->sh_audio || mpctx->syncing_audio) if (!mpctx->sh_audio || mpctx->syncing_audio)
return; return;
@ -2099,11 +2070,11 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time)
double av_delay = a_pts - v_pts; double av_delay = a_pts - v_pts;
// Try to sync vo_flip() so it will *finish* at given time // Try to sync vo_flip() so it will *finish* at given time
av_delay += mpctx->last_vo_flip_duration; av_delay += mpctx->last_vo_flip_duration;
av_delay -= audio_delay; // This much pts difference is desired av_delay -= mpctx->audio_delay; // This much pts difference is desired
double change = av_delay * 0.1; double change = av_delay * 0.1;
double max_change = default_max_pts_correction >= 0 ? double max_change = opts->default_max_pts_correction >= 0 ?
default_max_pts_correction : frame_time * 0.1; opts->default_max_pts_correction : frame_time * 0.1;
if (change < -max_change) if (change < -max_change)
change = -max_change; change = -max_change;
else if (change > max_change) else if (change > max_change)
@ -2157,7 +2128,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
ptsdiff = written_pts - mpctx->hrseek_pts; ptsdiff = written_pts - mpctx->hrseek_pts;
else else
ptsdiff = written_pts - mpctx->sh_video->pts - mpctx->delay ptsdiff = written_pts - mpctx->sh_video->pts - mpctx->delay
- audio_delay; - mpctx->audio_delay;
bytes = ptsdiff * bps; bytes = ptsdiff * bps;
bytes -= bytes % (ao->channels * af_fmt2bits(ao->format) / 8); bytes -= bytes % (ao->channels * af_fmt2bits(ao->format) / 8);
@ -2265,7 +2236,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
} }
if (endpts != MP_NOPTS_VALUE && modifiable_audio_format) { if (endpts != MP_NOPTS_VALUE && modifiable_audio_format) {
double bytes = (endpts - written_audio_pts(mpctx) + audio_delay) double bytes = (endpts - written_audio_pts(mpctx) + mpctx->audio_delay)
* ao->bps / opts->playback_speed; * ao->bps / opts->playback_speed;
if (playsize > bytes) { if (playsize > bytes) {
playsize = FFMAX(bytes, 0); playsize = FFMAX(bytes, 0);
@ -2343,13 +2314,13 @@ int reinit_video_chain(struct MPContext *mpctx)
mpctx->master_demuxer->file_format, mpctx->sh_video->format, mpctx->master_demuxer->file_format, mpctx->sh_video->format,
mpctx->sh_video->disp_w, mpctx->sh_video->disp_h, mpctx->sh_video->disp_w, mpctx->sh_video->disp_h,
mpctx->sh_video->fps, mpctx->sh_video->frametime); mpctx->sh_video->fps, mpctx->sh_video->frametime);
if (force_fps) { if (opts->force_fps) {
mpctx->sh_video->fps = force_fps; mpctx->sh_video->fps = opts->force_fps;
mpctx->sh_video->frametime = 1.0f / mpctx->sh_video->fps; mpctx->sh_video->frametime = 1.0f / mpctx->sh_video->fps;
} }
update_fps(mpctx); update_fps(mpctx);
if (!mpctx->sh_video->fps && !force_fps && !opts->correct_pts) { if (!mpctx->sh_video->fps && !opts->force_fps && !opts->correct_pts) {
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "FPS not specified in the " mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "FPS not specified in the "
"header or invalid, use the -fps option.\n"); "header or invalid, use the -fps option.\n");
} }
@ -2455,7 +2426,7 @@ static double update_video_nocorrect_pts(struct MPContext *mpctx)
int in_size = 0; int in_size = 0;
while (!in_size) while (!in_size)
in_size = video_read_frame(sh_video, &sh_video->next_frame_time, in_size = video_read_frame(sh_video, &sh_video->next_frame_time,
&packet, force_fps); &packet, mpctx->opts.force_fps);
if (in_size < 0) if (in_size < 0)
return -1; return -1;
sh_video->timer += frame_time; sh_video->timer += frame_time;
@ -2700,7 +2671,8 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
mpctx->hrseek_framedrop = false; mpctx->hrseek_framedrop = false;
mpctx->total_avsync_change = 0; mpctx->total_avsync_change = 0;
mpctx->step_frames = 0; mpctx->step_frames = 0;
drop_frame_cnt = 0; mpctx->drop_frame_cnt = 0;
mpctx->dropped_frames = 0;
#ifdef CONFIG_ENCODING #ifdef CONFIG_ENCODING
encode_lavc_discontinuity(mpctx->encode_lavc_ctx); encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
@ -2832,8 +2804,8 @@ static int seek(MPContext *mpctx, struct seek_params seek,
if (hr_seek) if (hr_seek)
demuxer_amount -= opts->hr_seek_demuxer_offset; demuxer_amount -= opts->hr_seek_demuxer_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, audio_delay, int seekresult = demux_seek(mpctx->demuxer, demuxer_amount,
demuxer_style); mpctx->audio_delay, demuxer_style);
if (seekresult == 0) { if (seekresult == 0) {
if (need_reset) { if (need_reset) {
reinit_audio_chain(mpctx); reinit_audio_chain(mpctx);
@ -2858,7 +2830,7 @@ static int seek(MPContext *mpctx, struct seek_params seek,
for (int type = 0; type < STREAM_TYPE_COUNT; type++) { for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
struct track *track = mpctx->current_track[type]; struct track *track = mpctx->current_track[type];
if (track && track->is_external && track->demuxer) if (track && track->is_external && track->demuxer)
demux_seek(track->demuxer, main_new_pos, audio_delay, demux_seek(track->demuxer, main_new_pos, mpctx->audio_delay,
SEEK_ABSOLUTE); SEEK_ABSOLUTE);
} }
} }
@ -3127,13 +3099,13 @@ static void update_avsync(struct MPContext *mpctx)
double a_pos = playing_audio_pts(mpctx); double a_pos = playing_audio_pts(mpctx);
mpctx->last_av_difference = a_pos - mpctx->video_pts - audio_delay; mpctx->last_av_difference = a_pos - mpctx->video_pts - mpctx->audio_delay;
if (mpctx->time_frame > 0) if (mpctx->time_frame > 0)
mpctx->last_av_difference += mpctx->last_av_difference +=
mpctx->time_frame * mpctx->opts.playback_speed; mpctx->time_frame * mpctx->opts.playback_speed;
if (a_pos == MP_NOPTS_VALUE || mpctx->video_pts == MP_NOPTS_VALUE) if (a_pos == MP_NOPTS_VALUE || mpctx->video_pts == MP_NOPTS_VALUE)
mpctx->last_av_difference = MP_NOPTS_VALUE; mpctx->last_av_difference = MP_NOPTS_VALUE;
if (mpctx->last_av_difference > 0.5 && drop_frame_cnt > 50 if (mpctx->last_av_difference > 0.5 && mpctx->drop_frame_cnt > 50
&& !mpctx->drop_message_shown) { && !mpctx->drop_message_shown) {
mp_tmsg(MSGT_AVSYNC, MSGL_WARN, "%s", mp_gtext(av_desync_help_text)); mp_tmsg(MSGT_AVSYNC, MSGL_WARN, "%s", mp_gtext(av_desync_help_text));
mpctx->drop_message_shown = true; mpctx->drop_message_shown = true;
@ -3258,12 +3230,12 @@ static void run_playloop(struct MPContext *mpctx)
// ================================================================ // ================================================================
vo_check_events(vo); vo_check_events(vo);
if (heartbeat_cmd) { if (opts->heartbeat_cmd) {
static unsigned last_heartbeat; static unsigned last_heartbeat;
unsigned now = GetTimerMS(); unsigned now = GetTimerMS();
if (now - last_heartbeat > 30000) { if (now - last_heartbeat > 30000) {
last_heartbeat = now; last_heartbeat = now;
system(heartbeat_cmd); system(opts->heartbeat_cmd);
} }
} }
@ -3373,9 +3345,9 @@ static void run_playloop(struct MPContext *mpctx)
screenshot_flip(mpctx); screenshot_flip(mpctx);
new_video_frame_shown = true; new_video_frame_shown = true;
if (play_n_frames >= 0) { if (mpctx->max_frames >= 0) {
--play_n_frames; mpctx->max_frames--;
if (play_n_frames <= 0) if (mpctx->max_frames <= 0)
mpctx->stop_play = PT_NEXT_ENTRY; mpctx->stop_play = PT_NEXT_ENTRY;
} }
break; break;
@ -3512,9 +3484,9 @@ static void run_playloop(struct MPContext *mpctx)
} }
// handle -sstep // handle -sstep
if (step_sec > 0 && !mpctx->paused && !mpctx->restart_playback) { if (opts->step_sec > 0 && !mpctx->paused && !mpctx->restart_playback) {
set_osd_function(mpctx, OSD_FFW); set_osd_function(mpctx, OSD_FFW);
queue_seek(mpctx, MPSEEK_RELATIVE, step_sec, 0); queue_seek(mpctx, MPSEEK_RELATIVE, opts->step_sec, 0);
} }
if (opts->keep_open && mpctx->stop_play == AT_END_OF_FILE) { if (opts->keep_open && mpctx->stop_play == AT_END_OF_FILE) {
@ -3650,7 +3622,7 @@ static void init_input(struct MPContext *mpctx)
{ {
mpctx->input = mp_input_init(&mpctx->opts.input, mpctx->opts.load_config); mpctx->input = mp_input_init(&mpctx->opts.input, mpctx->opts.load_config);
mpctx->key_fifo = mp_fifo_create(mpctx->input, &mpctx->opts); mpctx->key_fifo = mp_fifo_create(mpctx->input, &mpctx->opts);
if (slave_mode) if (mpctx->opts.slave_mode)
mp_input_add_cmd_fd(mpctx->input, 0, USE_FD0_CMD_SELECT, MP_INPUT_SLAVE_CMD_FUNC, NULL); mp_input_add_cmd_fd(mpctx->input, 0, USE_FD0_CMD_SELECT, MP_INPUT_SLAVE_CMD_FUNC, NULL);
else if (mpctx->opts.consolecontrols) else if (mpctx->opts.consolecontrols)
mp_input_add_key_fd(mpctx->input, 0, 1, read_keys, NULL, mpctx->key_fifo); mp_input_add_key_fd(mpctx->input, 0, 1, read_keys, NULL, mpctx->key_fifo);
@ -3848,7 +3820,7 @@ static void play_current_file(struct MPContext *mpctx)
load_per_protocol_config(mpctx->mconfig, mpctx->filename); load_per_protocol_config(mpctx->mconfig, mpctx->filename);
load_per_extension_config(mpctx->mconfig, mpctx->filename); load_per_extension_config(mpctx->mconfig, mpctx->filename);
load_per_file_config(mpctx->mconfig, mpctx->filename); load_per_file_config(mpctx->mconfig, mpctx->filename, opts->use_filedir_conf);
if (opts->vo.video_driver_list) if (opts->vo.video_driver_list)
load_per_output_config(mpctx->mconfig, PROFILE_CFG_VO, load_per_output_config(mpctx->mconfig, PROFILE_CFG_VO,
@ -3863,7 +3835,7 @@ static void play_current_file(struct MPContext *mpctx)
// We must enable getch2 here to be able to interrupt network connection // We must enable getch2 here to be able to interrupt network connection
// or cache filling // or cache filling
if (opts->consolecontrols && !slave_mode) { if (opts->consolecontrols && !opts->slave_mode) {
if (mpctx->initialized_flags & INITIALIZED_GETCH2) if (mpctx->initialized_flags & INITIALIZED_GETCH2)
mp_tmsg(MSGT_CPLAYER, MSGL_WARN, mp_tmsg(MSGT_CPLAYER, MSGL_WARN,
"WARNING: getch2_init called twice!\n"); "WARNING: getch2_init called twice!\n");
@ -3923,7 +3895,7 @@ static void play_current_file(struct MPContext *mpctx)
goto terminate_playback; goto terminate_playback;
#endif #endif
} }
mpctx->stream->start_pos += seek_to_byte; mpctx->stream->start_pos += opts->seek_to_byte;
// CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts) // CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts)
#ifdef CONFIG_DVBIN #ifdef CONFIG_DVBIN
@ -3939,6 +3911,8 @@ goto_enable_cache: ;
//============ Open DEMUXERS --- DETECT file type ======================= //============ Open DEMUXERS --- DETECT file type =======================
mpctx->audio_delay = opts->audio_delay;
mpctx->demuxer = demux_open(opts, mpctx->stream, mpctx->file_format, mpctx->demuxer = demux_open(opts, mpctx->stream, mpctx->file_format,
opts->audio_id, opts->video_id, opts->sub_id, opts->audio_id, opts->video_id, opts->sub_id,
mpctx->filename); mpctx->filename);
@ -4049,8 +4023,8 @@ goto_enable_cache: ;
if (mpctx->sh_video) { if (mpctx->sh_video) {
mpctx->sh_video->timer = 0; mpctx->sh_video->timer = 0;
if (!ignore_start) if (!opts->ignore_start)
audio_delay += mpctx->sh_video->stream_delay; mpctx->audio_delay += mpctx->sh_video->stream_delay;
} }
if (mpctx->sh_audio) { if (mpctx->sh_audio) {
if (opts->mixer_init_volume >= 0) if (opts->mixer_init_volume >= 0)
@ -4058,12 +4032,12 @@ goto_enable_cache: ;
opts->mixer_init_volume); opts->mixer_init_volume);
if (opts->mixer_init_mute >= 0) if (opts->mixer_init_mute >= 0)
mixer_setmute(&mpctx->mixer, opts->mixer_init_mute); mixer_setmute(&mpctx->mixer, opts->mixer_init_mute);
if (!ignore_start) if (!opts->ignore_start)
audio_delay -= mpctx->sh_audio->stream_delay; mpctx->audio_delay -= mpctx->sh_audio->stream_delay;
} }
if (force_fps && mpctx->sh_video) { if (opts->force_fps && mpctx->sh_video) {
mpctx->sh_video->fps = force_fps; mpctx->sh_video->fps = opts->force_fps;
mpctx->sh_video->frametime = 1.0f / mpctx->sh_video->fps; mpctx->sh_video->frametime = 1.0f / mpctx->sh_video->fps;
mp_tmsg(MSGT_CPLAYER, MSGL_INFO, mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
"FPS forced to be %5.3f (ftime: %5.3f).\n", "FPS forced to be %5.3f (ftime: %5.3f).\n",
@ -4081,10 +4055,11 @@ goto_enable_cache: ;
mp_tmsg(MSGT_CPLAYER, MSGL_V, "Starting playback...\n"); mp_tmsg(MSGT_CPLAYER, MSGL_V, "Starting playback...\n");
drop_frame_cnt = 0; // fix for multifile fps benchmark mpctx->drop_frame_cnt = 0;
play_n_frames = play_n_frames_mf; mpctx->dropped_frames = 0;
mpctx->max_frames = opts->play_frames;
if (play_n_frames == 0) { if (mpctx->max_frames == 0) {
mpctx->stop_play = PT_NEXT_ENTRY; mpctx->stop_play = PT_NEXT_ENTRY;
goto terminate_playback; goto terminate_playback;
} }

View File

@ -23,14 +23,6 @@
#include "core/mp_msg.h" #include "core/mp_msg.h"
extern char ** audio_fm_list;
extern char ** video_fm_list;
extern char ** video_driver_list;
extern char ** audio_driver_list;
extern float audio_delay;
extern double force_fps;
struct MPContext; struct MPContext;
struct MPOpts; struct MPOpts;
struct subtitle; struct subtitle;

View File

@ -2,6 +2,7 @@
#define MPLAYER_OPTIONS_H #define MPLAYER_OPTIONS_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include "core/m_option.h" #include "core/m_option.h"
typedef struct mp_vo_opts { typedef struct mp_vo_opts {
@ -83,6 +84,7 @@ typedef struct MPOpts {
int chapter_merge_threshold; int chapter_merge_threshold;
int quiet; int quiet;
int load_config; int load_config;
int use_filedir_conf;
int stream_cache_size; int stream_cache_size;
float stream_cache_min_percent; float stream_cache_min_percent;
float stream_cache_seek_min_percent; float stream_cache_seek_min_percent;
@ -95,6 +97,9 @@ typedef struct MPOpts {
int initial_audio_sync; int initial_audio_sync;
int hr_seek; int hr_seek;
float hr_seek_demuxer_offset; float hr_seek_demuxer_offset;
float audio_delay;
float default_max_pts_correction;
int ignore_start;
int autosync; int autosync;
int softsleep; int softsleep;
int frame_dropping; int frame_dropping;
@ -103,13 +108,18 @@ typedef struct MPOpts {
char *playing_msg; char *playing_msg;
char *status_msg; char *status_msg;
char *osd_status_msg; char *osd_status_msg;
char *heartbeat_cmd;
int player_idle_mode; int player_idle_mode;
int slave_mode;
int consolecontrols; int consolecontrols;
int doubleclick_time; int doubleclick_time;
int list_properties; int list_properties;
struct m_rel_time play_start; struct m_rel_time play_start;
struct m_rel_time play_end; struct m_rel_time play_end;
struct m_rel_time play_length; struct m_rel_time play_length;
int play_frames;
double step_sec;
int64_t seek_to_byte;
int start_paused; int start_paused;
int keep_open; int keep_open;
int audio_id; int audio_id;
@ -119,6 +129,7 @@ typedef struct MPOpts {
char **sub_lang; char **sub_lang;
int audio_display; int audio_display;
int sub_visibility; int sub_visibility;
int forced_subs_only;
char *quvi_format; char *quvi_format;
char *audio_stream; char *audio_stream;
@ -132,8 +143,11 @@ typedef struct MPOpts {
struct image_writer_opts *screenshot_image_opts; struct image_writer_opts *screenshot_image_opts;
char *screenshot_template; char *screenshot_template;
double force_fps;
int audio_output_channels; int audio_output_channels;
int audio_output_format; int audio_output_format;
int force_srate;
int dtshd; int dtshd;
float playback_speed; float playback_speed;
float drc_level; float drc_level;