summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c848
1 files changed, 439 insertions, 409 deletions
diff --git a/mplayer.c b/mplayer.c
index 54bb2c6f60..d9eb28129d 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
+#include "talloc.h"
#if defined(__MINGW32__) || defined(__CYGWIN__)
#define _UWIN 1 /*disable Non-underscored versions of non-ANSI functions as otherwise int eof would conflict with eof()*/
@@ -45,6 +46,8 @@
#include "m_option.h"
#include "m_config.h"
+#include "mplayer.h"
+#include "access_mpcontext.h"
#include "m_property.h"
#include "cfg-mplayer-def.h"
@@ -53,6 +56,7 @@
#include "subreader.h"
+#include "mp_osd.h"
#include "libvo/video_out.h"
#include "libvo/font_load.h"
@@ -133,27 +137,15 @@ extern int import_initial_playtree_into_gui(play_tree_t* my_playtree, m_config_t
#include "parser-cfg.h"
#include "parser-mpcmd.h"
-m_config_t* mconfig;
-
//**************************************************************************//
// Config file
//**************************************************************************//
static int cfg_inc_verbose(m_option_t *conf){ ++verbose; return 0;}
-static int cfg_include(m_option_t *conf, char *filename){
- return m_config_parse_config_file(mconfig, filename);
-}
-
#include "get_path.h"
//**************************************************************************//
-// XScreensaver
-//**************************************************************************//
-
-void xscreensaver_heartbeat(void);
-
-//**************************************************************************//
//**************************************************************************//
// Input media streaming & demultiplexer:
//**************************************************************************//
@@ -181,6 +173,8 @@ static int max_framesize=0;
#include "mixer.h"
#include "mp_core.h"
+#include "options.h"
+#include "defaultopts.h"
//**************************************************************************//
//**************************************************************************//
@@ -190,24 +184,6 @@ static int max_framesize=0;
int noconsolecontrols=0;
//**************************************************************************//
-// Not all functions in mplayer.c take the context as an argument yet
-static MPContext mpctx_s = {
- .osd_function = OSD_PLAY,
- .begin_skip = MP_NOPTS_VALUE,
- .play_tree_step = 1,
- .global_sub_pos = -1,
- .set_of_sub_pos = -1,
- .file_format = DEMUXER_TYPE_UNKNOWN,
- .loop_times = -1,
-#ifdef CONFIG_DVBIN
- .last_dvb_step = 1,
-#endif
-};
-
-static MPContext *mpctx = &mpctx_s;
-
-int fixed_vo=0;
-
// benchmark:
double video_time_usage=0;
double vout_time_usage=0;
@@ -221,8 +197,6 @@ int benchmark=0;
int auto_quality=0;
static int output_quality=0;
-float playback_speed=1.0;
-
int use_gui=0;
#ifdef CONFIG_GUI
@@ -250,10 +224,6 @@ static m_time_size_t end_at = { .type = END_AT_NONE, .pos = 0 };
// A/V sync:
int autosync=0; // 30 might be a good default value.
-// may be changed by GUI: (FIXME!)
-float rel_seek_secs=0;
-int abs_seek_pos=0;
-
// codecs:
char **audio_codec_list=NULL; // override audio codec
char **video_codec_list=NULL; // override video codec
@@ -265,15 +235,10 @@ extern char *demuxer_name; // override demuxer
extern char *audio_demuxer_name; // override audio demuxer
extern char *sub_demuxer_name; // override sub demuxer
-// streaming:
-int audio_id=-1;
-int video_id=-1;
-int dvdsub_id=-2;
int vobsub_id=-1;
char* audio_lang=NULL;
char* dvdsub_lang=NULL;
static char* spudec_ifo=NULL;
-char* filename=NULL; //"MI2-Trailer.avi";
int forced_subs_only=0;
int file_filter=1;
@@ -308,10 +273,6 @@ static int audio_output_format=-1; // AF_FORMAT_UNKNOWN
static int play_n_frames=-1;
static int play_n_frames_mf=-1;
-// screen info:
-char** video_driver_list=NULL;
-char** audio_driver_list=NULL;
-
// sub:
char *font_name=NULL;
char *sub_font_name=NULL;
@@ -339,9 +300,9 @@ char* current_module=NULL; // for debugging
#ifdef CONFIG_MENU
#include "m_struct.h"
#include "libmenu/menu.h"
-extern void vf_menu_pause_update(struct vf_instance_s* vf);
+extern void vf_menu_pause_update(struct vf_instance* vf);
extern vf_info_t vf_info_menu;
-static vf_info_t* libmenu_vfs[] = {
+static const vf_info_t* const libmenu_vfs[] = {
&vf_info_menu,
NULL
};
@@ -363,7 +324,6 @@ short edl_decision = 0; ///< 1 when an EDL operation has been made.
FILE* edl_fd = NULL; ///< fd to write to when in -edlout mode.
int use_filedir_conf;
-static unsigned int initialized_flags=0;
#include "mpcommon.h"
#include "command.h"
@@ -376,7 +336,7 @@ const void *mpctx_get_video_out(MPContext *mpctx)
return mpctx->video_out;
}
-void *mpctx_get_audio_out(MPContext *mpctx)
+const void *mpctx_get_audio_out(MPContext *mpctx)
{
return mpctx->audio_out;
}
@@ -406,7 +366,15 @@ int mpctx_get_osd_function(MPContext *mpctx)
return mpctx->osd_function;
}
-static int is_valid_metadata_type (metadata_t type) {
+static float get_relative_time(struct MPContext *mpctx)
+{
+ unsigned int new_time = GetTimer();
+ unsigned int delta = new_time - mpctx->last_time;
+ mpctx->last_time = new_time;
+ return delta * 0.000001;
+}
+
+static int is_valid_metadata_type(struct MPContext *mpctx, metadata_t type) {
switch (type)
{
/* check for valid video stream */
@@ -450,7 +418,7 @@ static int is_valid_metadata_type (metadata_t type) {
return 1;
}
-static char *get_demuxer_info (char *tag) {
+static char *get_demuxer_info(struct MPContext *mpctx, char *tag) {
char **info = mpctx->demuxer->info;
int n;
@@ -464,19 +432,20 @@ static char *get_demuxer_info (char *tag) {
return info[2*n+1] ? strdup (info[2*n+1]) : NULL;
}
-char *get_metadata (metadata_t type) {
+char *get_metadata(struct MPContext *mpctx, metadata_t type)
+{
char *meta = NULL;
sh_audio_t * const sh_audio = mpctx->sh_audio;
sh_video_t * const sh_video = mpctx->sh_video;
- if (!is_valid_metadata_type (type))
+ if (!is_valid_metadata_type(mpctx, type))
return NULL;
switch (type)
{
case META_NAME:
{
- return strdup (mp_basename2 (filename));
+ return strdup (mp_basename2 (mpctx->filename));
}
case META_VIDEO_CODEC:
@@ -539,25 +508,25 @@ char *get_metadata (metadata_t type) {
/* check for valid demuxer */
case META_INFO_TITLE:
- return get_demuxer_info ("Title");
+ return get_demuxer_info(mpctx, "Title");
case META_INFO_ARTIST:
- return get_demuxer_info ("Artist");
+ return get_demuxer_info(mpctx, "Artist");
case META_INFO_ALBUM:
- return get_demuxer_info ("Album");
+ return get_demuxer_info(mpctx, "Album");
case META_INFO_YEAR:
- return get_demuxer_info ("Year");
+ return get_demuxer_info(mpctx, "Year");
case META_INFO_COMMENT:
- return get_demuxer_info ("Comment");
+ return get_demuxer_info(mpctx, "Comment");
case META_INFO_TRACK:
- return get_demuxer_info ("Track");
+ return get_demuxer_info(mpctx, "Track");
case META_INFO_GENRE:
- return get_demuxer_info ("Genre");
+ return get_demuxer_info(mpctx, "Genre");
default:
break;
@@ -580,13 +549,13 @@ static void mp_dvdnav_context_free(MPContext *ctx){
}
#endif
-void uninit_player(unsigned int mask){
- mask=initialized_flags&mask;
+void uninit_player(struct MPContext *mpctx, unsigned int mask){
+ mask=mpctx->initialized_flags&mask;
mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n*** uninit(0x%X)\n",mask);
if(mask&INITIALIZED_ACODEC){
- initialized_flags&=~INITIALIZED_ACODEC;
+ mpctx->initialized_flags&=~INITIALIZED_ACODEC;
current_module="uninit_acodec";
if(mpctx->sh_audio) uninit_audio(mpctx->sh_audio);
#ifdef CONFIG_GUI
@@ -597,7 +566,7 @@ void uninit_player(unsigned int mask){
}
if(mask&INITIALIZED_VCODEC){
- initialized_flags&=~INITIALIZED_VCODEC;
+ mpctx->initialized_flags&=~INITIALIZED_VCODEC;
current_module="uninit_vcodec";
if(mpctx->sh_video) uninit_video(mpctx->sh_video);
mpctx->sh_video=NULL;
@@ -607,7 +576,7 @@ void uninit_player(unsigned int mask){
}
if(mask&INITIALIZED_DEMUXER){
- initialized_flags&=~INITIALIZED_DEMUXER;
+ mpctx->initialized_flags&=~INITIALIZED_DEMUXER;
current_module="free_demuxer";
if(mpctx->demuxer){
mpctx->stream=mpctx->demuxer->stream;
@@ -618,16 +587,16 @@ void uninit_player(unsigned int mask){
// kill the cache process:
if(mask&INITIALIZED_STREAM){
- initialized_flags&=~INITIALIZED_STREAM;
+ mpctx->initialized_flags&=~INITIALIZED_STREAM;
current_module="uninit_stream";
if(mpctx->stream) free_stream(mpctx->stream);
mpctx->stream=NULL;
}
if(mask&INITIALIZED_VO){
- initialized_flags&=~INITIALIZED_VO;
+ mpctx->initialized_flags&=~INITIALIZED_VO;
current_module="uninit_vo";
- mpctx->video_out->uninit();
+ vo_destroy(mpctx->video_out);
mpctx->video_out=NULL;
#ifdef CONFIG_DVDNAV
mp_dvdnav_context_free(mpctx);
@@ -636,7 +605,7 @@ void uninit_player(unsigned int mask){
// Must be after libvo uninit, as few vo drivers (svgalib) have tty code.
if(mask&INITIALIZED_GETCH2){
- initialized_flags&=~INITIALIZED_GETCH2;
+ mpctx->initialized_flags&=~INITIALIZED_GETCH2;
current_module="uninit_getch2";
mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n[[[uninit getch2]]]\n");
// restore terminal:
@@ -644,51 +613,42 @@ void uninit_player(unsigned int mask){
}
if(mask&INITIALIZED_VOBSUB){
- initialized_flags&=~INITIALIZED_VOBSUB;
+ mpctx->initialized_flags&=~INITIALIZED_VOBSUB;
current_module="uninit_vobsub";
if(vo_vobsub) vobsub_close(vo_vobsub);
vo_vobsub=NULL;
}
if (mask&INITIALIZED_SPUDEC){
- initialized_flags&=~INITIALIZED_SPUDEC;
+ mpctx->initialized_flags&=~INITIALIZED_SPUDEC;
current_module="uninit_spudec";
spudec_free(vo_spudec);
vo_spudec=NULL;
}
if(mask&INITIALIZED_AO){
- initialized_flags&=~INITIALIZED_AO;
+ mpctx->initialized_flags&=~INITIALIZED_AO;
current_module="uninit_ao";
if (mpctx->edl_muted) mixer_mute(&mpctx->mixer);
- mpctx->audio_out->uninit(mpctx->eof?0:1); mpctx->audio_out=NULL;
+ mpctx->audio_out->uninit(mpctx->stop_play != AT_END_OF_FILE);
+ mpctx->audio_out=NULL;
}
#ifdef CONFIG_GUI
if(mask&INITIALIZED_GUI){
- initialized_flags&=~INITIALIZED_GUI;
+ mpctx->initialized_flags&=~INITIALIZED_GUI;
current_module="uninit_gui";
guiDone();
}
#endif
- if(mask&INITIALIZED_INPUT){
- initialized_flags&=~INITIALIZED_INPUT;
- current_module="uninit_input";
- mp_input_uninit();
-#ifdef CONFIG_MENU
- if (use_menu)
- menu_uninit();
-#endif
- }
-
current_module=NULL;
}
-void exit_player_with_rc(const char* how, int rc){
+void exit_player_with_rc(struct MPContext *mpctx, const char* how, int rc){
if (mpctx->user_muted && !mpctx->edl_muted) mixer_mute(&mpctx->mixer);
- uninit_player(INITIALIZED_ALL);
+ uninit_player(mpctx, INITIALIZED_ALL);
#if defined(__MINGW32__) || defined(__CYGWIN__)
timeEndPeriod(1);
#endif
@@ -696,18 +656,25 @@ void exit_player_with_rc(const char* how, int rc){
#ifdef CONFIG_GUI
if ( !use_gui )
#endif
- vo_uninit(); // Close the X11 connection (if any is open).
+ vo_uninit(mpctx->x11_state); // Close the X11 connection (if any is open).
+#endif
+
+ current_module="uninit_input";
+ mp_input_uninit(mpctx->input);
+#ifdef CONFIG_MENU
+ if (use_menu)
+ menu_uninit();
#endif
#ifdef CONFIG_FREETYPE
current_module="uninit_font";
- if (sub_font && sub_font != vo_font) free_font_desc(sub_font);
- sub_font = NULL;
- if (vo_font) free_font_desc(vo_font);
+ if (mpctx->osd && mpctx->osd->sub_font != vo_font)
+ free_font_desc(mpctx->osd->sub_font);
+ free_font_desc(vo_font);
vo_font = NULL;
done_freetype();
#endif
- free_osd_list();
+ osd_free(mpctx->osd);
#ifdef CONFIG_ASS
ass_library_done(ass_library);
@@ -716,12 +683,13 @@ void exit_player_with_rc(const char* how, int rc){
current_module="exit_player";
// free mplayer config
- if(mconfig)
- m_config_free(mconfig);
+ if(mpctx->mconfig)
+ m_config_free(mpctx->mconfig);
if(mpctx->playtree)
play_tree_free(mpctx->playtree, 1);
+ talloc_free(mpctx->key_fifo);
if(edl_records != NULL) free(edl_records); // free mem allocated for EDL
if(how) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_ExitingHow,how);
@@ -730,8 +698,9 @@ void exit_player_with_rc(const char* how, int rc){
exit(rc);
}
-void exit_player(const char* how){
- exit_player_with_rc(how, 1);
+static void exit_player(struct MPContext *mpctx, const char* how)
+{
+ exit_player_with_rc(mpctx, how, 1);
}
#ifndef __MINGW32__
@@ -752,7 +721,6 @@ static void exit_sighandler(int x){
if (!crash_debug || x != SIGTRAP)
#endif
++sig_count;
- if(initialized_flags==0 && sig_count>1) exit(1);
if(sig_count==5)
{
/* We're crashing bad and can't uninit cleanly :(
@@ -817,17 +785,20 @@ static void exit_sighandler(int x){
exit(1);
}
-extern void mp_input_register_options(m_config_t* cfg);
-
#include "cfg-mplayer.h"
-static void parse_cfgfiles( m_config_t* conf )
+static int cfg_include(m_option_t *conf, char *filename)
+{
+ return m_config_parse_config_file(conf->priv, filename);
+}
+
+static void parse_cfgfiles(struct MPContext *mpctx, m_config_t* conf)
{
char *conffile;
int conffile_fd;
if (!disable_system_conf &&
m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mplayer.conf") < 0)
- exit_player(NULL);
+ exit_player(mpctx, NULL);
if ((conffile = get_path("")) == NULL) {
mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_NoHomeDir);
} else {
@@ -847,7 +818,7 @@ if ((conffile = get_path("")) == NULL) {
}
if (!disable_user_conf &&
m_config_parse_config_file(conf, conffile) < 0)
- exit_player(NULL);
+ exit_player(mpctx, NULL);
free(conffile);
}
}
@@ -885,7 +856,7 @@ static void load_per_extension_config (m_config_t* conf, const char *const file)
m_profile_t *p;
/* does filename actually have an extension ? */
- str = strrchr (filename, '.');
+ str = strrchr (file, '.');
if (!str)
return;
@@ -953,38 +924,39 @@ static void load_per_file_config (m_config_t* conf, const char *const file)
* cache filling) if the operation fails we use this function to check
* if it was interrupted by the user.
* The function returns a new value for eof. */
-static int libmpdemux_was_interrupted(int eof) {
+static int libmpdemux_was_interrupted(struct MPContext *mpctx, int stop_play)
+{
mp_cmd_t* cmd;
- if((cmd = mp_input_get_cmd(0,0,0)) != NULL) {
+ if((cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) {
switch(cmd->id) {
case MP_CMD_QUIT:
- exit_player_with_rc(MSGTR_Exit_quit, (cmd->nargs > 0)? cmd->args[0].v.i : 0);
+ exit_player_with_rc(mpctx, MSGTR_Exit_quit, (cmd->nargs > 0)? cmd->args[0].v.i : 0);
case MP_CMD_PLAY_TREE_STEP: {
- eof = (cmd->args[0].v.i > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY;
+ stop_play = (cmd->args[0].v.i > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY;
mpctx->play_tree_step = (cmd->args[0].v.i == 0) ? 1 : cmd->args[0].v.i;
} break;
case MP_CMD_PLAY_TREE_UP_STEP: {
- eof = (cmd->args[0].v.i > 0) ? PT_UP_NEXT : PT_UP_PREV;
+ stop_play = (cmd->args[0].v.i > 0) ? PT_UP_NEXT : PT_UP_PREV;
} break;
case MP_CMD_PLAY_ALT_SRC_STEP: {
- eof = (cmd->args[0].v.i > 0) ? PT_NEXT_SRC : PT_PREV_SRC;
+ stop_play = (cmd->args[0].v.i > 0) ? PT_NEXT_SRC : PT_PREV_SRC;
} break;
}
mp_cmd_free(cmd);
}
- return eof;
+ return stop_play;
}
#define mp_basename(s) (strrchr(s,'\\')==NULL?(mp_basename2(s)):(strrchr(s,'\\')+1))
-static int playtree_add_playlist(play_tree_t* entry)
+static int playtree_add_playlist(struct MPContext *mpctx, play_tree_t* entry)
{
- play_tree_add_bpf(entry,filename);
+ play_tree_add_bpf(entry,mpctx->filename);
#ifdef CONFIG_GUI
if (use_gui) {
if (entry) {
- import_playtree_playlist_into_gui(entry, mconfig);
+ import_playtree_playlist_into_gui(entry, mpctx->mconfig);
play_tree_free_list(entry,1);
}
} else
@@ -1014,7 +986,7 @@ static int playtree_add_playlist(play_tree_t* entry)
return PT_NEXT_SRC;
}
-void add_subtitles(char *filename, float fps, int noerr)
+void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr)
{
sub_data *subd;
#ifdef CONFIG_ASS
@@ -1059,7 +1031,7 @@ void add_subtitles(char *filename, float fps, int noerr)
}
// FIXME: if/when the GUI calls this, global sub numbering gets (potentially) broken.
-void update_set_of_subtitles(void)
+void update_set_of_subtitles(struct MPContext *mpctx)
// subdata was changed, set_of_sub... have to be updated.
{
sub_data ** const set_of_subtitles = mpctx->set_of_subtitles;
@@ -1080,10 +1052,11 @@ void update_set_of_subtitles(void)
}
}
-void init_vo_spudec(void) {
+void init_vo_spudec(struct MPContext *mpctx)
+{
if (vo_spudec)
spudec_free(vo_spudec);
- initialized_flags &= ~INITIALIZED_SPUDEC;
+ mpctx->initialized_flags &= ~INITIALIZED_SPUDEC;
vo_spudec = NULL;
if (spudec_ifo) {
unsigned int palette[16], width, height;
@@ -1117,7 +1090,7 @@ void init_vo_spudec(void) {
}
if (vo_spudec!=NULL)
- initialized_flags|=INITIALIZED_SPUDEC;
+ mpctx->initialized_flags|=INITIALIZED_SPUDEC;
}
/*
@@ -1178,8 +1151,9 @@ static void sadd_hhmmssf(char *buf, unsigned *pos, int len, float time) {
* \param a_v A-V desynchronization
* \param corr amount out A-V synchronization
*/
-static void print_status(float a_pos, float a_v, float corr)
+static void print_status(struct MPContext *mpctx, float a_pos, float a_v, float corr)
{
+ struct MPOpts *opts = &mpctx->opts;
sh_video_t * const sh_video = mpctx->sh_video;
int width;
char *line;
@@ -1227,9 +1201,9 @@ static void print_status(float a_pos, float a_v, float corr)
if (sh_video) {
if (sh_video->timer > 0.5)
saddf(line, &pos, width, "%2d%% %2d%% %4.1f%% ",
- (int)(100.0*video_time_usage*playback_speed/(double)sh_video->timer),
- (int)(100.0*vout_time_usage*playback_speed/(double)sh_video->timer),
- (100.0*audio_time_usage*playback_speed/(double)sh_video->timer));
+ (int)(100.0*video_time_usage*opts->playback_speed/(double)sh_video->timer),
+ (int)(100.0*vout_time_usage*opts->playback_speed/(double)sh_video->timer),
+ (100.0*audio_time_usage*opts->playback_speed/(double)sh_video->timer));
else
saddf(line, &pos, width, "??%% ??%% ??,?%% ");
} else if (mpctx->sh_audio) {
@@ -1251,8 +1225,8 @@ static void print_status(float a_pos, float a_v, float corr)
#endif
// other
- if (playback_speed != 1)
- saddf(line, &pos, width, "%4.2fx ", playback_speed);
+ if (opts->playback_speed != 1)
+ saddf(line, &pos, width, "%4.2fx ", opts->playback_speed);
// end
if (erase_to_end_of_line) {
@@ -1272,8 +1246,9 @@ static void print_status(float a_pos, float a_v, float corr)
* \param sh_audio describes the requested input format of the chain.
* \param ao_data describes the requested output format of the chain.
*/
-int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data)
+int build_afilter_chain(struct MPContext *mpctx, sh_audio_t *sh_audio, ao_data_t *ao_data)
{
+ struct MPOpts *opts = &mpctx->opts;
int new_srate;
int result;
if (!sh_audio)
@@ -1286,17 +1261,17 @@ int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data)
}
if(af_control_any_rev(sh_audio->afilter,
AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET,
- &playback_speed)) {
+ &opts->playback_speed)) {
new_srate = sh_audio->samplerate;
} else {
- new_srate = sh_audio->samplerate * playback_speed;
+ new_srate = sh_audio->samplerate * opts->playback_speed;
if (new_srate != ao_data->samplerate) {
// limits are taken from libaf/af_resample.c
if (new_srate < 8000)
new_srate = 8000;
if (new_srate > 192000)
new_srate = 192000;
- playback_speed = (float)new_srate / (float)sh_audio->samplerate;
+ opts->playback_speed = (float)new_srate / (float)sh_audio->samplerate;
}
}
result = init_audio_filters(sh_audio, new_srate,
@@ -1407,7 +1382,8 @@ static void clear_osd_msgs(void) {
*
*/
-static mp_osd_msg_t* get_osd_msg(void) {
+static mp_osd_msg_t* get_osd_msg(struct MPContext *mpctx)
+{
mp_osd_msg_t *msg,*prev,*last = NULL;
static unsigned last_update = 0;
unsigned now = GetTimerMS();
@@ -1466,7 +1442,7 @@ static mp_osd_msg_t* get_osd_msg(void) {
*
*/
-void set_osd_bar(int type,const char* name,double min,double max,double val) {
+void set_osd_bar(struct MPContext *mpctx, int type,const char* name,double min,double max,double val) {
if(osd_level < 1) return;
@@ -1492,18 +1468,16 @@ void set_osd_bar(int type,const char* name,double min,double max,double val) {
*
*/
-static void update_osd_msg(void) {
+static void update_osd_msg(struct MPContext *mpctx)
+{
mp_osd_msg_t *msg;
- static char osd_text[64] = "";
- static char osd_text_timer[64];
-
- // we need some mem for vo_osd_text
- vo_osd_text = (unsigned char*)osd_text;
+ struct osd_state *osd = mpctx->osd;
+ char osd_text_timer[64];
// Look if we have a msg
- if((msg = get_osd_msg())) {
- if(strcmp(osd_text,msg->msg)) {
- strncpy((char*)osd_text, msg->msg, 63);
+ if((msg = get_osd_msg(mpctx))) {
+ if (strcmp(osd->osd_text, msg->msg)) {
+ strncpy(osd->osd_text, msg->msg, 63);
if(mpctx->sh_video) vo_osd_changed(OSDTYPE_OSD); else
if(term_osd) mp_msg(MSGT_CPLAYER,MSGL_STATUS,"%s%s\n",term_osd_esc,msg->msg);
}
@@ -1542,16 +1516,16 @@ static void update_osd_msg(void) {
if(mpctx->osd_show_percentage)
mpctx->osd_show_percentage--;
- if(strcmp(osd_text,osd_text_timer)) {
- strncpy(osd_text, osd_text_timer, 63);
+ if (strcmp(osd->osd_text, osd_text_timer)) {
+ strncpy(osd->osd_text, osd_text_timer, 63);
vo_osd_changed(OSDTYPE_OSD);
}
return;
}
// Clear the term osd line
- if(term_osd && osd_text[0]) {
- osd_text[0] = 0;
+ if (term_osd && osd->osd_text[0]) {
+ osd->osd_text[0] = 0;
printf("%s\n",term_osd_esc);
}
}
@@ -1560,7 +1534,9 @@ static void update_osd_msg(void) {
// OSDMsgStack
-void reinit_audio_chain(void) {
+void reinit_audio_chain(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
if(mpctx->sh_audio){
current_module="init_audio_codec";
mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
@@ -1569,7 +1545,7 @@ if(mpctx->sh_audio){
mpctx->d_audio->id = -2;
return;
} else
- initialized_flags|=INITIALIZED_ACODEC;
+ mpctx->initialized_flags|=INITIALIZED_ACODEC;
mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
@@ -1586,24 +1562,24 @@ if(mpctx->sh_audio){
// output:
&ao_data.samplerate, &ao_data.channels, &ao_data.format)){
mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_AudioFilterChainPreinitError);
- exit_player(MSGTR_Exit_error);
+ exit_player(mpctx, MSGTR_Exit_error);
}
#endif
current_module="ao2_init";
- if(!(mpctx->audio_out=init_best_audio_out(audio_driver_list,
+ if(!(mpctx->audio_out=init_best_audio_out(opts->audio_driver_list,
0, // plugin flag
ao_data.samplerate,
ao_data.channels,
ao_data.format,0))){
// FAILED:
mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CannotInitAO);
- uninit_player(INITIALIZED_ACODEC); // close codec
+ uninit_player(mpctx, INITIALIZED_ACODEC); // close codec
mpctx->sh_audio=mpctx->d_audio->sh=NULL; // -> nosound
mpctx->d_audio->id = -2;
return;
} else {
// SUCCESS:
- initialized_flags|=INITIALIZED_AO;
+ mpctx->initialized_flags|=INITIALIZED_AO;
mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bytes per sample)\n",
mpctx->audio_out->info->short_name,
ao_data.samplerate, ao_data.channels,
@@ -1616,10 +1592,10 @@ if(mpctx->sh_audio){
// init audio filters:
#if 1
current_module="af_init";
- if(!build_afilter_chain(mpctx->sh_audio, &ao_data)) {
+ if(!build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data)) {
mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_NoMatchingFilter);
// mp_msg(MSGT_CPLAYER,MSGL_ERR,"Couldn't find matching filter / ao format! -> NOSOUND\n");
-// uninit_player(INITIALIZED_ACODEC|INITIALIZED_AO); // close codec & ao
+// uninit_player(mpctx, INITIALIZED_ACODEC|INITIALIZED_AO); // close codec & ao
// sh_audio=mpctx->d_audio->sh=NULL; // -> nosound
}
#endif
@@ -1636,8 +1612,10 @@ if(mpctx->sh_audio){
// Return pts value corresponding to the end point of audio written to the
// ao so far.
-static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
+static double written_audio_pts(struct MPContext *mpctx)
{
+ sh_audio_t *sh_audio = mpctx->sh_audio;
+ demux_stream_t *d_audio = mpctx->d_audio;
double buffered_output;
// first calculate the end pts of audio that has been output by decoder
double a_pts = sh_audio->pts;
@@ -1680,25 +1658,25 @@ static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
// Filters divide audio length by playback_speed, so multiply by it
// to get the length in original units without speedup or slowdown
- a_pts -= buffered_output * playback_speed / ao_data.bps;
+ a_pts -= buffered_output * mpctx->opts.playback_speed / ao_data.bps;
return a_pts;
}
// Return pts value corresponding to currently playing audio.
-double playing_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio,
- const ao_functions_t *audio_out)
+double playing_audio_pts(struct MPContext *mpctx)
{
- return written_audio_pts(sh_audio, d_audio) - playback_speed *
- audio_out->get_delay();
+ return written_audio_pts(mpctx) - mpctx->opts.playback_speed *
+ mpctx->audio_out->get_delay();
}
-static int check_framedrop(double frame_time) {
+static int check_framedrop(struct MPContext *mpctx, double frame_time) {
+ struct MPOpts *opts = &mpctx->opts;
// check for frame-drop:
current_module = "check_framedrop";
if (mpctx->sh_audio && !mpctx->d_audio->eof) {
static int dropped_frames;
- float delay = playback_speed*mpctx->audio_out->get_delay();
+ float delay = opts->playback_speed*mpctx->audio_out->get_delay();
float d = delay-mpctx->delay;
++total_frame_cnt;
// we should avoid dropping too many frames in sequence unless we
@@ -1714,15 +1692,18 @@ static int check_framedrop(double frame_time) {
return 0;
}
-static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
+static int generate_video_frame(struct MPContext *mpctx)
{
+ sh_video_t * const sh_video = mpctx->sh_video;
+ demux_stream_t *d_video = mpctx->d_video;
+
unsigned char *start;
int in_size;
int hit_eof=0;
double pts;
while (1) {
- int drop_frame = check_framedrop(sh_video->frametime);
+ int drop_frame = check_framedrop(mpctx, sh_video->frametime);
void *decoded_frame;
current_module = "decode video";
// XXX Time used in this call is not counted in any performance
@@ -1744,9 +1725,10 @@ static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
if (decoded_frame) {
update_subtitles(sh_video, mpctx->d_sub, 0);
update_teletext(sh_video, mpctx->demuxer, 0);
- update_osd_msg();
+ update_osd_msg(mpctx);
current_module = "filter video";
- if (filter_video(sh_video, decoded_frame, sh_video->pts))
+ if (filter_video(sh_video, decoded_frame, sh_video->pts,
+ mpctx->osd))
break;
} else if (drop_frame)
return -1;
@@ -1760,7 +1742,7 @@ static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
int rtc_fd = -1;
#endif
-static float timing_sleep(float time_frame)
+static float timing_sleep(struct MPContext *mpctx, float time_frame)
{
#ifdef HAVE_RTC
if (rtc_fd >= 0){
@@ -1770,7 +1752,7 @@ static float timing_sleep(float time_frame)
unsigned long rtc_ts;
if (read(rtc_fd, &rtc_ts, sizeof(rtc_ts)) <= 0)
mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_LinuxRTCReadError, strerror(errno));
- time_frame -= GetRelativeTime();
+ time_frame -= get_relative_time(mpctx);
}
} else
#endif
@@ -1781,14 +1763,14 @@ static float timing_sleep(float time_frame)
current_module = "sleep_timer";
while (time_frame > margin) {
usec_sleep(1000000 * (time_frame - margin));
- time_frame -= GetRelativeTime();
+ time_frame -= get_relative_time(mpctx);
}
if (softsleep){
current_module = "sleep_soft";
if (time_frame < 0)
mp_msg(MSGT_AVSYNC, MSGL_WARN, MSGTR_SoftsleepUnderflow);
while (time_frame > 0)
- time_frame-=GetRelativeTime(); // burn the CPU
+ time_frame -= get_relative_time(mpctx); // burn the CPU
}
}
return time_frame;
@@ -1825,6 +1807,7 @@ static mp_image_t * mp_dvdnav_copy_mpi(mp_image_t *to_mpi,
}
static void mp_dvdnav_reset_stream (MPContext *ctx) {
+ struct MPOpts *opts = &ctx->opts;
if (ctx->sh_video) {
/// clear video pts
ctx->d_video->pts = 0.0f;
@@ -1849,7 +1832,7 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) {
resync_audio_stream(ctx->sh_audio);
}
- if (ctx->d_sub) dvdsub_id = -2;
+ if (ctx->d_sub) opts->sub_id = -2;
audio_delay = 0.0f;
@@ -1858,7 +1841,8 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) {
}
/// Restore last decoded DVDNAV (still frame)
-static mp_image_t *mp_dvdnav_restore_smpi(int *in_size,
+static mp_image_t *mp_dvdnav_restore_smpi(struct MPContext *mpctx,
+ int *in_size,
unsigned char **start,
mp_image_t *decoded_frame)
{
@@ -1902,7 +1886,7 @@ static mp_image_t *mp_dvdnav_restore_smpi(int *in_size,
}
/// Save last decoded DVDNAV (still frame)
-static void mp_dvdnav_save_smpi(int in_size,
+static void mp_dvdnav_save_smpi(struct MPContext *mpctx, int in_size,
unsigned char *start,
mp_image_t *decoded_frame)
{
@@ -1923,8 +1907,11 @@ static void mp_dvdnav_save_smpi(int in_size,
}
#endif /* CONFIG_DVDNAV */
-static void adjust_sync_and_print_status(int between_frames, float timing_error)
+static void adjust_sync_and_print_status(struct MPContext *mpctx,
+ int between_frames,
+ float timing_error)
{
+ struct MPOpts *opts = &mpctx->opts;
current_module="av_sync";
if(mpctx->sh_audio){
@@ -1942,9 +1929,9 @@ static void adjust_sync_and_print_status(int between_frames, float timing_error)
* value here, even a "corrected" one, would be incompatible with
* autosync mode.)
*/
- a_pts = written_audio_pts(mpctx->sh_audio, mpctx->d_audio) - mpctx->delay;
+ a_pts = written_audio_pts(mpctx) - mpctx->delay;
else
- a_pts = playing_audio_pts(mpctx->sh_audio, mpctx->d_audio, mpctx->audio_out);
+ a_pts = playing_audio_pts(mpctx);
v_pts = mpctx->sh_video->pts;
@@ -1962,7 +1949,7 @@ static void adjust_sync_and_print_status(int between_frames, float timing_error)
/* Do not correct target time for the next frame if this frame
* was late not because of wrong target time but because the
* target time could not be met */
- x = (AV_delay + timing_error * playback_speed) * 0.1f;
+ x = (AV_delay + timing_error * opts->playback_speed) * 0.1f;
if (x < -max_pts_correction)
x = -max_pts_correction;
else if (x> max_pts_correction)
@@ -1976,19 +1963,20 @@ static void adjust_sync_and_print_status(int between_frames, float timing_error)
c_total+=x;
}
if(!quiet)
- print_status(a_pts - audio_delay, AV_delay, c_total);
+ print_status(mpctx, a_pts - audio_delay, AV_delay, c_total);
}
} else {
// No audio:
if (!quiet)
- print_status(0, 0, 0);
+ print_status(mpctx, 0, 0, 0);
}
}
-static int fill_audio_out_buffers(void)
+static int fill_audio_out_buffers(struct MPContext *mpctx)
{
+ struct MPOpts *opts = &mpctx->opts;
unsigned int t;
double tt;
int playsize;
@@ -2052,7 +2040,7 @@ static int fill_audio_out_buffers(void)
sh_audio->a_out_buffer_len -= playsize;
memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize],
sh_audio->a_out_buffer_len);
- mpctx->delay += playback_speed*playsize/(double)ao_data.bps;
+ mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps;
}
else if (audio_eof && mpctx->audio_out->get_delay() < .04) {
// Sanity check to avoid hanging in case current ao doesn't output
@@ -2064,12 +2052,14 @@ static int fill_audio_out_buffers(void)
return 1;
}
-static int sleep_until_update(float *time_frame, float *aq_sleep_time)
+static int sleep_until_update(struct MPContext *mpctx, float *time_frame,
+ float *aq_sleep_time)
{
+ struct MPOpts *opts = &mpctx->opts;
int frame_time_remaining = 0;
current_module="calc_sleep_time";
- *time_frame -= GetRelativeTime(); // reset timer
+ *time_frame -= get_relative_time(mpctx); // reset timer
if (mpctx->sh_audio && !mpctx->d_audio->eof) {
float delay = mpctx->audio_out->get_delay();
@@ -2085,12 +2075,12 @@ static int sleep_until_update(float *time_frame, float *aq_sleep_time)
* sync to settle at the right value (but it eventually will.)
* This settling time is very short for values below 100.
*/
- float predicted = mpctx->delay / playback_speed + *time_frame;
+ float predicted = mpctx->delay / opts->playback_speed + *time_frame;
float difference = delay - predicted;
delay = predicted + difference / (float)autosync;
}
- *time_frame = delay - mpctx->delay / playback_speed;
+ *time_frame = delay - mpctx->delay / opts->playback_speed;
// delay = amount of audio buffered in sou