From e13c05366557cbe3bf371010f2087a57f072a7eb Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 3 Aug 2012 08:18:40 +0200 Subject: 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) --- mplayer.c | 517 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 264 insertions(+), 253 deletions(-) (limited to 'mplayer.c') 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); -- cgit v1.2.3