diff options
Diffstat (limited to 'mplayer.c')
-rw-r--r-- | mplayer.c | 459 |
1 files changed, 239 insertions, 220 deletions
@@ -5,6 +5,7 @@ #include <stdio.h> #include <stdlib.h> #include "config.h" +#include "talloc.h" #ifdef WIN32 #define _UWIN 1 /*disable Non-underscored versions of non-ANSI functions as otherwise int eof would conflict with eof()*/ @@ -53,6 +54,7 @@ #include "subreader.h" +#include "mp_osd.h" #include "libvo/video_out.h" #include "libvo/font_load.h" @@ -150,7 +152,7 @@ static int cfg_include(m_option_t *conf, char *filename){ // XScreensaver //**************************************************************************// -void xscreensaver_heartbeat(void); +void xscreensaver_heartbeat(struct vo_x11_state *); //**************************************************************************// //**************************************************************************// @@ -180,6 +182,8 @@ static int max_framesize=0; #include "mixer.h" #include "mp_core.h" +#include "options.h" +#include "defaultopts.h" //**************************************************************************// //**************************************************************************// @@ -189,24 +193,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 HAS_DVBIN_SUPPORT - .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; @@ -220,8 +206,6 @@ int benchmark=0; int auto_quality=0; static int output_quality=0; -float playback_speed=1.0; - int use_gui=0; #ifdef HAVE_NEW_GUI @@ -249,10 +233,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 @@ -264,10 +244,6 @@ 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; @@ -307,10 +283,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; @@ -338,7 +310,7 @@ char* current_module=NULL; // for debugging #ifdef HAVE_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[] = { &vf_info_menu, @@ -405,7 +377,7 @@ int mpctx_get_osd_function(MPContext *mpctx) return mpctx->osd_function; } -static int is_valid_metadata_type (metadata_t type) { +static int is_valid_metadata_type(struct MPContext *mpctx, metadata_t type) { switch (type) { /* check for valid video stream */ @@ -449,7 +421,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; @@ -463,12 +435,13 @@ 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) @@ -538,25 +511,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; @@ -579,7 +552,7 @@ static void mp_dvdnav_context_free(MPContext *ctx){ } #endif -void uninit_player(unsigned int mask){ +void uninit_player(struct MPContext *mpctx, unsigned int mask){ mask=initialized_flags&mask; mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n*** uninit(0x%X)\n",mask); @@ -626,7 +599,7 @@ void uninit_player(unsigned int mask){ if(mask&INITIALIZED_VO){ initialized_flags&=~INITIALIZED_VO; current_module="uninit_vo"; - mpctx->video_out->uninit(); + vo_destroy(mpctx->video_out); mpctx->video_out=NULL; #ifdef USE_DVDNAV mp_dvdnav_context_free(mpctx); @@ -684,15 +657,15 @@ void uninit_player(unsigned int mask){ 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); #ifdef HAVE_X11 #ifdef HAVE_NEW_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 #ifdef HAVE_FREETYPE @@ -726,8 +699,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__ @@ -817,13 +791,13 @@ extern void mp_input_register_options(m_config_t* cfg); #include "cfg-mplayer.h" -static void parse_cfgfiles( m_config_t* conf ) +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 { @@ -843,7 +817,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); } } @@ -949,12 +923,13 @@ 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 eof) +{ mp_cmd_t* cmd; if((cmd = mp_input_get_cmd(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; mpctx->play_tree_step = (cmd->args[0].v.i == 0) ? 1 : cmd->args[0].v.i; @@ -973,7 +948,7 @@ static int libmpdemux_was_interrupted(int eof) { #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); @@ -1010,7 +985,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 USE_ASS @@ -1055,7 +1030,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; @@ -1076,7 +1051,8 @@ 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; @@ -1193,8 +1169,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; @@ -1242,9 +1219,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) { @@ -1266,8 +1243,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) { @@ -1287,8 +1264,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) @@ -1301,17 +1279,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, @@ -1422,7 +1400,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(); @@ -1481,7 +1460,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; @@ -1507,7 +1486,8 @@ 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]; @@ -1516,7 +1496,7 @@ static void update_osd_msg(void) { vo_osd_text = (unsigned char*)osd_text; // Look if we have a msg - if((msg = get_osd_msg())) { + if((msg = get_osd_msg(mpctx))) { if(strcmp(osd_text,msg->msg)) { strncpy((char*)osd_text, msg->msg, 63); if(mpctx->sh_video) vo_osd_changed(OSDTYPE_OSD); else @@ -1575,7 +1555,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"); @@ -1601,18 +1583,18 @@ 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; @@ -1631,10 +1613,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 @@ -1651,8 +1633,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; @@ -1695,25 +1679,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 @@ -1729,15 +1713,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 @@ -1759,7 +1746,7 @@ 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)) break; @@ -1864,7 +1851,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; @@ -1938,8 +1925,11 @@ static void mp_dvdnav_save_smpi(int in_size, } #endif /* USE_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){ @@ -1957,9 +1947,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; @@ -1977,7 +1967,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) @@ -1991,19 +1981,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; @@ -2067,7 +2058,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 @@ -2079,8 +2070,10 @@ 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"; @@ -2100,12 +2093,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 soundcard/driver if (delay > 0.25) delay=0.25; else @@ -2130,22 +2123,23 @@ static int sleep_until_update(float *time_frame, float *aq_sleep_time) //============================== SLEEP: =================================== // flag 256 means: libvo driver does its timing (dvb card) - if (*time_frame > 0.001 && !(vo_flags&256)) + if (*time_frame > 0.001 && !(mpctx->sh_video->output_flags&256)) *time_frame = timing_sleep(*time_frame); return frame_time_remaining; } -int reinit_video_chain(void) { +int reinit_video_chain(struct MPContext *mpctx) +{ + struct MPOpts *opts = &mpctx->opts; sh_video_t * const sh_video = mpctx->sh_video; double ar=-1.0; //================== Init VIDEO (codec & libvo) ========================== - if(!fixed_vo || !(initialized_flags&INITIALIZED_VO)){ + if(opts->fixed_vo || !(initialized_flags&INITIALIZED_VO)){ current_module="preinit_libvo"; //shouldn't we set dvideo->id=-2 when we fail? - vo_config_count=0; //if((mpctx->video_out->preinit(vo_subdevice))!=0){ - if(!(mpctx->video_out=init_best_video_out(video_driver_list))){ + if(!(mpctx->video_out=init_best_video_out(opts, mpctx->x11_state))){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_ErrorInitializingVODevice); goto err_out; } @@ -2157,12 +2151,12 @@ int reinit_video_chain(void) { current_module="init_video_filters"; { char* vf_arg[] = { "_oldargs_", (char*)mpctx->video_out , NULL }; - sh_video->vfilter=(void*)vf_open_filter(NULL,"vo",vf_arg); + sh_video->vfilter=(void*)vf_open_filter(opts, NULL,"vo",vf_arg); } #ifdef HAVE_MENU if(use_menu) { char* vf_arg[] = { "_oldargs_", menu_root, NULL }; - vf_menu = vf_open_plugin(libmenu_vfs,sh_video->vfilter,"menu",vf_arg); + vf_menu = vf_open_plugin(opts,libmenu_vfs,sh_video->vfilter,"menu",vf_arg); if(!vf_menu) { mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantOpenLibmenuFilterWithThisRootMenu,menu_root); use_menu = 0; @@ -2176,9 +2170,9 @@ int reinit_video_chain(void) { if(ass_enabled) { int i; int insert = 1; - if (vf_settings) - for (i = 0; vf_settings[i].name; ++i) - if (strcmp(vf_settings[i].name, "ass") == 0) { + if (opts->vf_settings) + for (i = 0; opts->vf_settings[i].name; ++i) + if (strcmp(opts->vf_settings[i].name, "ass") == 0) { insert = 0; break; } @@ -2186,7 +2180,7 @@ int reinit_video_chain(void) { extern vf_info_t vf_info_ass; const vf_info_t* libass_vfs[] = {&vf_info_ass, NULL}; char* vf_arg[] = {"auto", "1", NULL}; - vf_instance_t* vf_ass = vf_open_plugin(libass_vfs,sh_video->vfilter,"ass",vf_arg); + vf_instance_t* vf_ass = vf_open_plugin(opts, libass_vfs,sh_video->vfilter,"ass",vf_arg); if (vf_ass) sh_video->vfilter=(void*)vf_ass; else @@ -2195,7 +2189,7 @@ int reinit_video_chain(void) { } #endif - sh_video->vfilter=(void*)append_filters(sh_video->vfilter); + sh_video->vfilter=(void*)append_filters(sh_video->vfilter, opts->vf_settings); #ifdef USE_ASS if (ass_enabled) @@ -2209,7 +2203,7 @@ int reinit_video_chain(void) { mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); if(!sh_video->initialized){ - if(!fixed_vo) uninit_player(INITIALIZED_VO); + if(!opts->fixed_vo) uninit_player(mpctx, INITIALIZED_VO); goto err_out; } @@ -2242,13 +2236,14 @@ err_out: return 0; } -static double update_video(int *blit_frame) +static double update_video(struct MPContext *mpctx, int *blit_frame) { + struct MPOpts *opts = &mpctx->opts; sh_video_t * const sh_video = mpctx->sh_video; //-------------------- Decode a frame: ----------------------- double frame_time; *blit_frame = 0; // Don't blit if we hit EOF - if (!correct_pts) { + if (!opts->correct_pts) { unsigned char* start=NULL; void *decoded_frame = NULL; int drop_frame=0; @@ -2276,10 +2271,10 @@ static double update_video(int *blit_frame) mpctx->delay -= frame_time; // video_read_frame can change fps (e.g. for ASF video) vo_fps = sh_video->fps; - drop_frame = check_framedrop(frame_time); + drop_frame = check_framedrop(mpctx, frame_time); update_subtitles(sh_video, mpctx->d_sub, 0); update_teletext(sh_video, mpctx->demuxer, 0); - update_osd_msg(); + update_osd_msg(mpctx); current_module = "decode_video"; #ifdef USE_DVDNAV decoded_frame = mp_dvdnav_restore_smpi(&in_size,&start,decoded_frame); @@ -2297,7 +2292,7 @@ static double update_video(int *blit_frame) sh_video->pts)); } else { - int res = generate_video_frame(sh_video, mpctx->d_video); + int res = generate_video_frame(mpctx); if (!res) return -1; ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, @@ -2322,7 +2317,7 @@ static double update_video(int *blit_frame) return frame_time; } -static void pause_loop(void) +static void pause_loop(struct MPContext *mpctx) { mp_cmd_t* cmd; if (!quiet) { @@ -2334,7 +2329,7 @@ static void pause_loop(void) int mlen = strlen(msg); msg[mlen-1] = '\0'; set_osd_msg(OSD_MSG_PAUSE, 1, 0, "%s", msg+1); - update_osd_msg(); + update_osd_msg(mpctx); } else mp_msg(MSGT_CPLAYER,MSGL_STATUS,MSGTR_Paused); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_PAUSED\n"); @@ -2343,8 +2338,8 @@ static void pause_loop(void) if (use_gui) guiGetEvent(guiCEvent, (char *)guiSetPause); #endif - if (mpctx->video_out && mpctx->sh_video && vo_config_count) - mpctx->video_out->control(VOCTRL_PAUSE, NULL); + if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); if (mpctx->audio_out && mpctx->sh_audio) mpctx->audio_out->pause(); // pause audio, keep data if possible @@ -2356,13 +2351,13 @@ static void pause_loop(void) mp_cmd_free(cmd); continue; } - if (mpctx->sh_video && mpctx->video_out && vo_config_count) - mpctx->video_out->check_events(); + if (mpctx->sh_video && mpctx->video_out) + vo_check_events(mpctx->video_out); #ifdef HAVE_NEW_GUI if (use_gui) { guiEventHandling(); guiGetEvent(guiReDraw, NULL); - if (guiIntfStruct.Playing!=2 || (rel_seek_secs || abs_seek_pos)) + if (guiIntfStruct.Playing!=2 || (mpctx->rel_seek_secs || mpctx->abs_seek_pos)) break; } #endif @@ -2379,8 +2374,8 @@ static void pause_loop(void) mpctx->osd_function=OSD_PLAY; if (mpctx->audio_out && mpctx->sh_audio) mpctx->audio_out->resume(); // resume audio - if (mpctx->video_out && mpctx->sh_video && vo_config_count) - mpctx->video_out->control(VOCTRL_RESUME, NULL); // resume video + if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video (void)GetRelativeTime(); // ignore time that passed during pause #ifdef HAVE_NEW_GUI if (use_gui) { @@ -2466,8 +2461,8 @@ static void edl_update(MPContext *mpctx) if (mpctx->sh_video->pts >= next_edl_record->start_sec) { if (next_edl_record->action == EDL_SKIP) { mpctx->osd_function = OSD_FFW; - abs_seek_pos = 0; - rel_seek_secs = next_edl_record->length_sec; + mpctx->abs_seek_pos = 0; + mpctx->rel_seek_secs = next_edl_record->length_sec; mp_msg(MSGT_CPLAYER, MSGL_DBG4, "EDL_SKIP: start [%f], stop " "[%f], length [%f]\n", next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec); @@ -2497,8 +2492,8 @@ static int seek(MPContext *mpctx, double amount, int style) if (mpctx->sh_video) { current_module = "seek_video_reset"; resync_video_stream(mpctx->sh_video); - if (vo_config_count) - mpctx->video_out->control(VOCTRL_RESET, NULL); + if (mpctx->video_out->config_ok) + vo_control(mpctx->video_out, VOCTRL_RESET, NULL); mpctx->sh_video->num_buffered_pts = 0; mpctx->sh_video->last_pts = MP_NOPTS_VALUE; mpctx->num_buffered_frames = 0; @@ -2534,6 +2529,13 @@ static int seek(MPContext *mpctx, double amount, int style) return 0; } + +static void read_keys(void *ctx) +{ + getch2(); +} + + int main(int argc,char* argv[]){ @@ -2552,12 +2554,28 @@ int gui_no_filename=0; srand((int) time(NULL)); + struct MPContext *mpctx = &(struct MPContext){ + .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, + .last_dvb_step = 1, + }; + InitTimer(); mp_msg_init(); +#ifdef HAVE_X11 + mpctx->x11_state = talloc_ptrtype(NULL, mpctx->x11_state); + vo_x11_init_state(mpctx->x11_state); +#endif + struct MPOpts *opts = &mpctx->opts; + set_default_mplayer_options(opts); // Create the config context and register the options - mconfig = m_config_new(); + mconfig = m_config_new(opts); m_config_register_options(mconfig,mplayer_opts); mp_input_register_options(mconfig); @@ -2588,7 +2606,7 @@ int gui_no_filename=0; use_gui=1; } - parse_cfgfiles(mconfig); + parse_cfgfiles(mpctx, mconfig); #ifdef HAVE_NEW_GUI if ( use_gui ) cfg_read(); @@ -2667,12 +2685,12 @@ int gui_no_filename=0; } #endif /* HAVE_NEW_GUI */ - if(video_driver_list && strcmp(video_driver_list[0],"help")==0){ + if(opts->video_driver_list && strcmp(opts->video_driver_list[0],"help")==0){ list_video_out(); opt_exit = 1; } - if(audio_driver_list && strcmp(audio_driver_list[0],"help")==0){ + if(opts->audio_driver_list && strcmp(opts->audio_driver_list[0],"help")==0){ list_audio_out(); opt_exit = 1; } @@ -2682,7 +2700,7 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ if(!parse_codec_cfg(mem_ptr=get_path("codecs.conf"))){ if(!parse_codec_cfg(MPLAYER_CONFDIR "/codecs.conf")){ if(!parse_codec_cfg(NULL)){ - exit_player_with_rc(NULL, 0); + exit_player_with_rc(mpctx, NULL, 0); } mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_BuiltinCodecsConf); } @@ -2747,18 +2765,18 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){ } if(opt_exit) - exit_player(NULL); + exit_player(mpctx, NULL); if (player_idle_mode && use_gui) { mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_NoIdleAndGui); - exit_player_with_rc(NULL, 1); + exit_player_with_rc(mpctx, NULL, 1); } if(!filename && !player_idle_mode){ if(!use_gui){ // no file/vcd/dvd -> show HELP: mp_msg(MSGT_CPLAYER, MSGL_INFO, help_text); - exit_player_with_rc(NULL, 0); + exit_player_with_rc(mpctx, NULL, 0); } else gui_no_filename=1; } @@ -2856,7 +2874,7 @@ mp_input_init(use_gui); if(slave_mode) mp_input_add_cmd_fd(0,USE_SELECT,MP_INPUT_SLAVE_CMD_FUNC,NULL); else if(!noconsolecontrols) - mp_input_add_event_fd(0, getch2); + mp_input_add_event_fd(0, read_keys, NULL); // Set the libstream interrupt callback stream_set_interrupt_callback(mp_input_check_interrupt); @@ -2936,10 +2954,10 @@ play_next_file: load_per_file_config (mconfig, filename); } - if (video_driver_list) - load_per_output_config (mconfig, PROFILE_CFG_VO, video_driver_list[0]); - if (audio_driver_list) - load_per_output_config (mconfig, PROFILE_CFG_AO, audio_driver_list[0]); + if (opts->video_driver_list) + load_per_output_config (mconfig, PROFILE_CFG_VO, opts->video_driver_list[0]); + if (opts->audio_driver_list) + load_per_output_config (mconfig, PROFILE_CFG_AO, opts->audio_driver_list[0]); // We must enable getch2 here to be able to interrupt network connection // or cache filling @@ -2997,7 +3015,8 @@ while (player_idle_mode && !filename) { play_tree_t * entry = NULL; mp_cmd_t * cmd; while (!(cmd = mp_input_get_cmd(0,1,0))) { // wait for command - if (mpctx->video_out && vo_config_count) mpctx->video_out->check_events(); + if (mpctx->video_out) + vo_check_events(mpctx->video_out); usec_sleep(20000); } switch (cmd->id) { @@ -3011,7 +3030,7 @@ while (player_idle_mode && !filename) { entry = parse_playlist_file(cmd->args[0].v.s); break; 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); break; |