summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c459
1 files changed, 239 insertions, 220 deletions
diff --git a/mplayer.c b/mplayer.c
index 3a5cb9238a..3a18f68a6a 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -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;