summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-08-03 08:18:40 +0200
committerwm4 <wm4@nowhere>2012-08-03 12:48:02 +0200
commite13c05366557cbe3bf371010f2087a57f072a7eb (patch)
treeb7ea2222ce209ae2e4992f59a26890edf638cf84 /mplayer.c
parent6f564fe82b66d8fbffb794cc93448413e8c8ed60 (diff)
downloadmpv-e13c05366557cbe3bf371010f2087a57f072a7eb.tar.bz2
mpv-e13c05366557cbe3bf371010f2087a57f072a7eb.tar.xz
mplayer: move file loading out of main()
The structure is now as follows: - main(): * basic initializations (e.g. init_libav() and more) * pre-parse command line (verbosity level, config file locations) * load config files (parse_cfgfiles()) * parse command line, add files from the command line to playlist (m_config_parse_mp_command_line()) * call: - handle_help_options(): * check each help-related option * print help if requested * main() exits if help was requested * call function that works down the playlist: - play_files(): * run idle loop (idle_loop()), until there are files in the playlist or an exit command was given (slave mode only) * actually load and play a file: - play_current_file(): * run all the dozens of functions to load the file and initialize playback * run a small loop that does normal playback, until the file is done or a slave command terminates playback (each iteration, run_playloop() is called) * uninitialize playback * determine next entry on the playlist to play * loop * call exit_player_with_rc() (there are many other places which use this function, though)
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c517
1 files changed, 264 insertions, 253 deletions
diff --git a/mplayer.c b/mplayer.c
index fabb67f392..f221421521 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3566,233 +3566,11 @@ static void idle_loop(struct MPContext *mpctx)
}
}
-static void print_version(int always)
-{
- mp_msg(MSGT_CPLAYER, always ? MSGL_INFO : MSGL_V,
- "%s (C) 2000-2012\n", mplayer_version);
-}
-
-static bool handle_help_options(struct MPContext *mpctx)
+// Start playing the current playlist entry.
+// Handle initialization and deinitialization.
+static void play_current_file(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
- int opt_exit = 0;
- if (opts->video_driver_list &&
- strcmp(opts->video_driver_list[0], "help") == 0) {
- list_video_out();
- opt_exit = 1;
- }
- if (opts->audio_driver_list &&
- strcmp(opts->audio_driver_list[0], "help") == 0) {
- list_audio_out();
- opt_exit = 1;
- }
- if (audio_codec_list && strcmp(audio_codec_list[0], "help") == 0) {
- mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Available audio codecs:\n");
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_CODECS\n");
- list_codecs(1);
- mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
- opt_exit = 1;
- }
- if (video_codec_list && strcmp(video_codec_list[0], "help") == 0) {
- mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Available video codecs:\n");
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_CODECS\n");
- list_codecs(0);
- mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
- opt_exit = 1;
- }
- if (video_fm_list && strcmp(video_fm_list[0], "help") == 0) {
- vfm_help();
- mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
- opt_exit = 1;
- }
- if (audio_fm_list && strcmp(audio_fm_list[0], "help") == 0) {
- afm_help();
- mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
- opt_exit = 1;
- }
- if (af_cfg.list && strcmp(af_cfg.list[0], "help") == 0) {
- af_help();
- printf("\n");
- opt_exit = 1;
- }
-#ifdef CONFIG_X11
- if (vo_fstype_list && strcmp(vo_fstype_list[0], "help") == 0) {
- fstype_help();
- mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
- opt_exit = 1;
- }
-#endif
- if ((opts->demuxer_name && strcmp(opts->demuxer_name, "help") == 0) ||
- (opts->audio_demuxer_name && strcmp(opts->audio_demuxer_name, "help") == 0) ||
- (opts->sub_demuxer_name && strcmp(opts->sub_demuxer_name, "help") == 0)) {
- demuxer_help();
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
- opt_exit = 1;
- }
- if (opts->list_properties) {
- property_print_help();
- opt_exit = 1;
- }
- return opt_exit;
-}
-
-#ifdef PTW32_STATIC_LIB
-static void detach_ptw32(void)
-{
- pthread_win32_thread_detach_np();
- pthread_win32_process_detach_np();
-}
-#endif
-
-static void osdep_preinit(int *p_argc, char ***p_argv)
-{
- GetCpuCaps(&gCpuCaps);
-
-#ifdef __MINGW32__
- mp_get_converted_argv(&argc, &argv);
-#endif
-
-#ifdef PTW32_STATIC_LIB
- pthread_win32_process_attach_np();
- pthread_win32_thread_attach_np();
- atexit(detach_ptw32);
-#endif
-
- InitTimer();
- srand(GetTimerMS());
-
-#if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_WIN32DLL)
- set_path_env();
-#endif
-
-#if defined(__MINGW32__) || defined(__CYGWIN__)
- {
- HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
- BOOL WINAPI (*setDEP)(DWORD) = NULL;
- BOOL WINAPI (*setDllDir)(LPCTSTR) = NULL;
- if (kernel32) {
- setDEP = GetProcAddress(kernel32, "SetProcessDEPPolicy");
- setDllDir = GetProcAddress(kernel32, "SetDllDirectoryA");
- }
- if (setDEP)
- setDEP(3);
- if (setDllDir)
- setDllDir("");
- }
- // stop Windows from showing all kinds of annoying error dialogs
- SetErrorMode(0x8003);
- // request 1ms timer resolution
- timeBeginPeriod(1);
-#endif
-
-#ifdef HAVE_TERMCAP
- load_termcap(NULL); // load key-codes
-#endif
-}
-
-/* This preprocessor directive is a hack to generate a mplayer-nomain.o object
- * file for some tools to link against. */
-#ifndef DISABLE_MAIN
-int main(int argc, char *argv[])
-{
- osdep_preinit(&argc, &argv);
-
- if (argc > 1 && (!strcmp(argv[1], "-leak-report")
- || !strcmp(argv[1], "--leak-report")))
- talloc_enable_leak_report();
-
- struct MPContext *mpctx = talloc(NULL, MPContext);
- *mpctx = (struct MPContext){
- .osd_function = OSD_PLAY,
- .begin_skip = MP_NOPTS_VALUE,
- .global_sub_pos = -1,
- .set_of_sub_pos = -1,
- .file_format = DEMUXER_TYPE_UNKNOWN,
- .last_dvb_step = 1,
- .terminal_osd_text = talloc_strdup(mpctx, ""),
- };
-
- mp_msg_init();
- init_libav();
- screenshot_init(mpctx);
-
- struct MPOpts *opts = &mpctx->opts;
- set_default_mplayer_options(opts);
- // Create the config context and register the options
- mpctx->mconfig = m_config_new(opts, cfg_include);
- m_config_register_options(mpctx->mconfig, mplayer_opts);
- m_config_register_options(mpctx->mconfig, common_opts);
- mp_input_register_options(mpctx->mconfig);
-
- // Preparse the command line
- m_config_preparse_command_line(mpctx->mconfig, argc, argv, &verbose);
-
- print_version(false);
- print_libav_versions();
-
- parse_cfgfiles(mpctx, mpctx->mconfig);
-
- mpctx->playlist = talloc_struct(mpctx, struct playlist, {0});
- if (m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist,
- argc, argv))
- {
- mpctx->playlist->current = mpctx->playlist->first;
- } else {
- exit_player(mpctx, EXIT_ERROR);
- }
-
-#ifdef CONFIG_PRIORITY
- set_priority();
-#endif
-
- /* Check codecs.conf. */
- if (!codecs_file || !parse_codec_cfg(codecs_file)) {
- char *mem_ptr;
- 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(mpctx, EXIT_NONE, 0);
- mp_tmsg(MSGT_CPLAYER, MSGL_V,
- "Using built-in default codecs.conf.\n");
- }
- }
- free(mem_ptr); // release the buffer created by get_path()
- }
-
- if (handle_help_options(mpctx))
- exit_player(mpctx, EXIT_NONE);
-
- if (!mpctx->playlist->first && !opts->player_idle_mode) {
- // no file/vcd/dvd -> show HELP:
- print_version(true);
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", mp_gtext(help_text));
- exit_player_with_rc(mpctx, EXIT_NONE, 0);
- }
-
- /* Display what configure line was used */
- mp_msg(MSGT_CPLAYER, MSGL_V, "Configuration: " CONFIGURATION "\n");
-
- // Many users forget to include command line in bugreports...
- if (mp_msg_test(MSGT_CPLAYER, MSGL_V)) {
- mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "CommandLine:");
- for (int i = 1; i < argc; i++)
- mp_msg(MSGT_CPLAYER, MSGL_INFO, " '%s'", argv[i]);
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
- }
-
- //------ load global data first ------
-
-#ifdef CONFIG_ASS
- mpctx->ass_library = mp_ass_init(opts);
-#endif
-
- mpctx->osd = osd_create(opts, mpctx->ass_library);
-
- init_input(mpctx);
-
- // ***************** Now, let's see the per-file stuff ******************
-
-play_next_file:
mpctx->stop_play = 0;
@@ -3804,10 +3582,8 @@ play_next_file:
if (mpctx->playlist->current)
mpctx->filename = mpctx->playlist->current->filename;
- if (!mpctx->filename) {
- idle_loop(mpctx);
- goto play_next_file;
- }
+ if (!mpctx->filename)
+ goto terminate_playback;
m_config_enter_file_local(mpctx->mconfig);
@@ -3871,7 +3647,7 @@ play_next_file:
mpctx->stream = open_stream(mpctx->filename, opts, &mpctx->file_format);
if (!mpctx->stream) { // error...
libmpdemux_was_interrupted(mpctx);
- goto goto_next_file;
+ goto terminate_playback;
}
mpctx->initialized_flags |= INITIALIZED_STREAM;
@@ -3894,7 +3670,7 @@ play_next_file:
if (empty)
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Playlist was invalid or empty!\n");
mpctx->stop_play = PT_NEXT_ENTRY;
- goto goto_next_file;
+ goto terminate_playback;
#endif
}
mpctx->stream->start_pos += seek_to_byte;
@@ -3936,7 +3712,7 @@ goto_enable_cache:
stream_cache_size * 1024ull * (stream_cache_seek_min_percent / 100.0));
if (res == 0)
if (libmpdemux_was_interrupted(mpctx))
- goto goto_next_file;
+ goto terminate_playback;
}
//============ Open DEMUXERS --- DETECT file type =======================
@@ -3946,11 +3722,11 @@ goto_enable_cache:
mpctx->filename);
if (process_playlist_demuxer(mpctx))
- goto goto_next_file;
+ goto terminate_playback;
if (!mpctx->demuxer) {
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Failed to recognize file format.\n");
- goto goto_next_file;
+ goto terminate_playback;
}
if (mpctx->demuxer->matroska_data.ordered_chapters)
@@ -4030,7 +3806,7 @@ goto_enable_cache:
}
}
#endif
- goto goto_next_file; // exit_player(_("Fatal error"));
+ goto terminate_playback; // exit_player(_("Fatal error"));
}
/* display clip info */
@@ -4051,7 +3827,7 @@ goto_enable_cache:
if (mpctx->sh_video) {
osd_font_invalidate();
} else if (!mpctx->sh_audio)
- goto goto_next_file;
+ goto terminate_playback;
//================== MAIN: ==========================
@@ -4104,7 +3880,7 @@ goto_enable_cache:
}
if (!mpctx->sh_video && !mpctx->sh_audio)
- goto goto_next_file;
+ goto terminate_playback;
if (force_fps && mpctx->sh_video) {
vo_fps = mpctx->sh_video->fps = force_fps;
@@ -4135,7 +3911,7 @@ goto_enable_cache:
if (play_n_frames == 0) {
mpctx->stop_play = PT_NEXT_ENTRY;
- goto goto_next_file;
+ goto terminate_playback;
}
mpctx->time_frame = 0;
@@ -4203,7 +3979,7 @@ goto_enable_cache:
}
#endif
-goto_next_file: // don't jump here after ao/vo/getch initialization!
+terminate_playback: // don't jump here after ao/vo/getch initialization!
mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
@@ -4237,26 +4013,261 @@ goto_next_file: // don't jump here after ao/vo/getch initialization!
if (mpctx->ass_library)
ass_clear_fonts(mpctx->ass_library);
#endif
+}
- if (!mpctx->stop_play || mpctx->stop_play == AT_END_OF_FILE)
- mpctx->stop_play = PT_NEXT_ENTRY;
+// Play all entries on the playlist, starting from the current entry.
+// Return if all done.
+static void play_files(struct MPContext *mpctx)
+{
+ for (;;) {
+ idle_loop(mpctx);
+ play_current_file(mpctx);
+
+ if (!mpctx->stop_play || mpctx->stop_play == AT_END_OF_FILE)
+ mpctx->stop_play = PT_NEXT_ENTRY;
+
+ struct playlist_entry *new_entry = NULL;
- struct playlist_entry *new_entry = NULL;
+ if (mpctx->stop_play == PT_NEXT_ENTRY) {
+ new_entry = playlist_get_next(mpctx->playlist, +1);
+ } else if (mpctx->stop_play == PT_CURRENT_ENTRY) {
+ new_entry = mpctx->playlist->current;
+ } else { // PT_STOP
+ playlist_clear(mpctx->playlist);
+ }
- if (mpctx->stop_play == PT_NEXT_ENTRY) {
- new_entry = playlist_get_next(mpctx->playlist, +1);
- } else if (mpctx->stop_play == PT_CURRENT_ENTRY) {
- new_entry = mpctx->playlist->current;
- } else { // PT_STOP
- playlist_clear(mpctx->playlist);
+ mpctx->playlist->current = new_entry;
+ mpctx->playlist->current_was_replaced = false;
+ mpctx->stop_play = 0;
+
+ if (!mpctx->playlist->current && !mpctx->opts.player_idle_mode)
+ break;
}
+}
- mpctx->playlist->current = new_entry;
- mpctx->playlist->current_was_replaced = false;
- mpctx->stop_play = 0;
+static void print_version(int always)
+{
+ mp_msg(MSGT_CPLAYER, always ? MSGL_INFO : MSGL_V,
+ "%s (C) 2000-2012\n", mplayer_version);
+}
+
+static bool handle_help_options(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ int opt_exit = 0;
+ if (opts->video_driver_list &&
+ strcmp(opts->video_driver_list[0], "help") == 0) {
+ list_video_out();
+ opt_exit = 1;
+ }
+ if (opts->audio_driver_list &&
+ strcmp(opts->audio_driver_list[0], "help") == 0) {
+ list_audio_out();
+ opt_exit = 1;
+ }
+ if (audio_codec_list && strcmp(audio_codec_list[0], "help") == 0) {
+ mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Available audio codecs:\n");
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_CODECS\n");
+ list_codecs(1);
+ mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
+ opt_exit = 1;
+ }
+ if (video_codec_list && strcmp(video_codec_list[0], "help") == 0) {
+ mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Available video codecs:\n");
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_CODECS\n");
+ list_codecs(0);
+ mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
+ opt_exit = 1;
+ }
+ if (video_fm_list && strcmp(video_fm_list[0], "help") == 0) {
+ vfm_help();
+ mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
+ opt_exit = 1;
+ }
+ if (audio_fm_list && strcmp(audio_fm_list[0], "help") == 0) {
+ afm_help();
+ mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
+ opt_exit = 1;
+ }
+ if (af_cfg.list && strcmp(af_cfg.list[0], "help") == 0) {
+ af_help();
+ printf("\n");
+ opt_exit = 1;
+ }
+#ifdef CONFIG_X11
+ if (vo_fstype_list && strcmp(vo_fstype_list[0], "help") == 0) {
+ fstype_help();
+ mp_msg(MSGT_FIXME, MSGL_FIXME, "\n");
+ opt_exit = 1;
+ }
+#endif
+ if ((opts->demuxer_name && strcmp(opts->demuxer_name, "help") == 0) ||
+ (opts->audio_demuxer_name && strcmp(opts->audio_demuxer_name, "help") == 0) ||
+ (opts->sub_demuxer_name && strcmp(opts->sub_demuxer_name, "help") == 0)) {
+ demuxer_help();
+ mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
+ opt_exit = 1;
+ }
+ if (opts->list_properties) {
+ property_print_help();
+ opt_exit = 1;
+ }
+ return opt_exit;
+}
+
+static void load_codecs_conf(struct MPContext *mpctx)
+{
+ /* Check codecs.conf. */
+ if (!codecs_file || !parse_codec_cfg(codecs_file)) {
+ char *mem_ptr;
+ 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(mpctx, EXIT_NONE, 0);
+ mp_tmsg(MSGT_CPLAYER, MSGL_V,
+ "Using built-in default codecs.conf.\n");
+ }
+ }
+ free(mem_ptr); // release the buffer created by get_path()
+ }
+}
+
+#ifdef PTW32_STATIC_LIB
+static void detach_ptw32(void)
+{
+ pthread_win32_thread_detach_np();
+ pthread_win32_process_detach_np();
+}
+#endif
+
+static void osdep_preinit(int *p_argc, char ***p_argv)
+{
+ GetCpuCaps(&gCpuCaps);
+
+#ifdef __MINGW32__
+ mp_get_converted_argv(&argc, &argv);
+#endif
+
+#ifdef PTW32_STATIC_LIB
+ pthread_win32_process_attach_np();
+ pthread_win32_thread_attach_np();
+ atexit(detach_ptw32);
+#endif
+
+ InitTimer();
+ srand(GetTimerMS());
+
+#if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_WIN32DLL)
+ set_path_env();
+#endif
+
+#if defined(__MINGW32__) || defined(__CYGWIN__)
+ {
+ HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
+ BOOL WINAPI (*setDEP)(DWORD) = NULL;
+ BOOL WINAPI (*setDllDir)(LPCTSTR) = NULL;
+ if (kernel32) {
+ setDEP = GetProcAddress(kernel32, "SetProcessDEPPolicy");
+ setDllDir = GetProcAddress(kernel32, "SetDllDirectoryA");
+ }
+ if (setDEP)
+ setDEP(3);
+ if (setDllDir)
+ setDllDir("");
+ }
+ // stop Windows from showing all kinds of annoying error dialogs
+ SetErrorMode(0x8003);
+ // request 1ms timer resolution
+ timeBeginPeriod(1);
+#endif
+
+#ifdef HAVE_TERMCAP
+ load_termcap(NULL); // load key-codes
+#endif
+}
+
+/* This preprocessor directive is a hack to generate a mplayer-nomain.o object
+ * file for some tools to link against. */
+#ifndef DISABLE_MAIN
+int main(int argc, char *argv[])
+{
+ osdep_preinit(&argc, &argv);
+
+ if (argc > 1 && (!strcmp(argv[1], "-leak-report")
+ || !strcmp(argv[1], "--leak-report")))
+ talloc_enable_leak_report();
+
+ struct MPContext *mpctx = talloc(NULL, MPContext);
+ *mpctx = (struct MPContext){
+ .osd_function = OSD_PLAY,
+ .begin_skip = MP_NOPTS_VALUE,
+ .global_sub_pos = -1,
+ .set_of_sub_pos = -1,
+ .file_format = DEMUXER_TYPE_UNKNOWN,
+ .last_dvb_step = 1,
+ .terminal_osd_text = talloc_strdup(mpctx, ""),
+ };
+
+ mp_msg_init();
+ init_libav();
+ screenshot_init(mpctx);
+
+ struct MPOpts *opts = &mpctx->opts;
+ set_default_mplayer_options(opts);
+ // Create the config context and register the options
+ mpctx->mconfig = m_config_new(opts, cfg_include);
+ m_config_register_options(mpctx->mconfig, mplayer_opts);
+ m_config_register_options(mpctx->mconfig, common_opts);
+ mp_input_register_options(mpctx->mconfig);
+
+ // Preparse the command line
+ m_config_preparse_command_line(mpctx->mconfig, argc, argv, &verbose);
+
+ print_version(false);
+ print_libav_versions();
+
+ parse_cfgfiles(mpctx, mpctx->mconfig);
+
+ mpctx->playlist = talloc_struct(mpctx, struct playlist, {0});
+ if (m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist,
+ argc, argv))
+ {
+ mpctx->playlist->current = mpctx->playlist->first;
+ } else {
+ exit_player(mpctx, EXIT_ERROR);
+ }
+
+ load_codecs_conf(mpctx);
+
+ if (handle_help_options(mpctx))
+ exit_player(mpctx, EXIT_NONE);
+
+ mp_msg(MSGT_CPLAYER, MSGL_V, "Configuration: " CONFIGURATION "\n");
+ mp_tmsg(MSGT_CPLAYER, MSGL_V, "Command line:");
+ for (int i = 1; i < argc; i++)
+ mp_msg(MSGT_CPLAYER, MSGL_V, " '%s'", argv[i]);
+ mp_msg(MSGT_CPLAYER, MSGL_V, "\n");
+
+ if (!mpctx->playlist->first && !opts->player_idle_mode) {
+ // no file/vcd/dvd -> show HELP:
+ print_version(true);
+ mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", mp_gtext(help_text));
+ exit_player_with_rc(mpctx, EXIT_NONE, 0);
+ }
+
+#ifdef CONFIG_PRIORITY
+ set_priority();
+#endif
+
+#ifdef CONFIG_ASS
+ mpctx->ass_library = mp_ass_init(opts);
+#endif
+
+ mpctx->osd = osd_create(opts, mpctx->ass_library);
+
+ init_input(mpctx);
- if (mpctx->playlist->current || opts->player_idle_mode)
- goto play_next_file;
+ play_files(mpctx);
exit_player_with_rc(mpctx, EXIT_EOF, 0);