📄 mplayer.c
字号:
prog_path = argv[0];#endif //========= Catch terminate signals: ================ // terminate requests: signal(SIGTERM,exit_sighandler); // kill signal(SIGHUP,exit_sighandler); // kill -HUP / xterm closed signal(SIGINT,exit_sighandler); // Interrupt from keyboard signal(SIGQUIT,exit_sighandler); // Quit from keyboard#ifdef ENABLE_SIGHANDLER // fatal errors: signal(SIGBUS,exit_sighandler); // bus error signal(SIGSEGV,exit_sighandler); // segfault signal(SIGILL,exit_sighandler); // illegal instruction signal(SIGFPE,exit_sighandler); // floating point exc. signal(SIGABRT,exit_sighandler); // abort()#ifdef CRASH_DEBUG if (crash_debug) signal(SIGTRAP,exit_sighandler);#endif#endif#ifdef HAVE_NEW_GUI if(use_gui){ guiInit(); inited_flags|=INITED_GUI; guiGetEvent( guiCEvent,(char *)((gui_no_filename) ? 0 : 1) ); }#endif// ******************* Now, let's see the per-file stuff ********************play_next_file: // init global sub numbers if (filename) load_per_file_config (mconfig, filename);// We must enable getch2 here to be able to interrupt network connection// or cache fillingif(!noconsolecontrols && !slave_mode){ if(inited_flags&INITED_GETCH2) mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_Getch2InitializedTwice); else getch2_enable(); // prepare stdin for hotkeys... inited_flags|=INITED_GETCH2; mp_msg(MSGT_CPLAYER,MSGL_DBG2,"\n[[[init getch2]]]\n");}// =================== GUI idle loop (STOP state) ===========================#ifdef HAVE_NEW_GUI if ( use_gui ) { file_format=DEMUXER_TYPE_UNKNOWN; guiGetEvent( guiSetDefaults,0 ); while ( guiIntfStruct.Playing != 1 ) { mp_cmd_t* cmd; usec_sleep(20000); guiEventHandling(); guiGetEvent( guiReDraw,NULL ); if ( (cmd = mp_input_get_cmd(0,0,0)) != NULL) guiGetEvent( guiIEvent,(char *)cmd->id ); } guiGetEvent( guiSetParameters,NULL ); if ( guiIntfStruct.StreamType == STREAMTYPE_STREAM ) { play_tree_t * entry = play_tree_new(); play_tree_add_file( entry,guiIntfStruct.Filename ); if ( playtree ) play_tree_free_list( playtree->child,1 ); else playtree=play_tree_new(); play_tree_set_child( playtree,entry ); if(playtree) { playtree_iter = play_tree_iter_new(playtree,mconfig); if(playtree_iter) { if(play_tree_iter_step(playtree_iter,0,0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(playtree_iter); playtree_iter = NULL; } filename = play_tree_iter_get_file(playtree_iter,1); } } } }#endif//--------------------------------------------------------------------------- if(filename) mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_Playing, filename);//==================== Open VOB-Sub ============================//============ Open & Sync STREAM --- fork cache2 ==================== stream=NULL; demuxer=NULL; if (d_audio) { //free_demuxer_stream(d_audio); d_audio=NULL; } if (d_video) { //free_demuxer_stream(d_video); d_video=NULL; } sh_audio=NULL; sh_video=NULL; current_module="open_stream"; stream=open_stream(filename,0,&file_format); if(!stream) { // error... eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY); goto goto_next_file; } inited_flags|=INITED_STREAM;#ifdef HAVE_NEW_GUI if ( use_gui ) guiGetEvent( guiSetStream,(char *)stream );#endif if(file_format == DEMUXER_TYPE_PLAYLIST) { play_tree_t* entry; // Handle playlist current_module="handle_playlist"; mp_msg(MSGT_CPLAYER,MSGL_V,"Parsing playlist %s...\n",filename); entry = parse_playtree(stream,0); eof=playtree_add_playlist(entry); goto goto_next_file; } stream->start_pos+=seek_to_byte;if(stream_dump_type==5){ unsigned char buf[4096]; int len; FILE *f; current_module="dumpstream"; if(stream->type==STREAMTYPE_STREAM && stream->fd<0){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_DumpstreamFdUnavailable); exit_player(MSGTR_Exit_error); } stream_reset(stream); stream_seek(stream,stream->start_pos); f=fopen(stream_dump_name,"wb"); if(!f){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_CantOpenDumpfile); exit_player(MSGTR_Exit_error); } while(!stream->eof){ len=stream_read(stream,buf,4096); if(len>0) { if(fwrite(buf,len,1,f) != 1) { mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile,stream_dump_name); exit_player(MSGTR_Exit_error); } } } if(fclose(f)) { mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile,stream_dump_name); exit_player(MSGTR_Exit_error); } mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_CoreDumped); exit_player_with_rc(MSGTR_Exit_eof, 0);}#ifdef USE_DVDREADif(stream->type==STREAMTYPE_DVD){ current_module="dvd lang->id"; if(audio_id==-1) audio_id=dvd_aid_from_lang(stream,audio_lang); if(dvdsub_lang && dvdsub_id==-1) dvdsub_id=dvd_sid_from_lang(stream,dvdsub_lang); // setup global sub numbering global_sub_indices[SUB_SOURCE_DEMUX] = global_sub_size; // the global # of the first demux-specific sub. global_sub_size += dvd_number_of_subs(stream); current_module=NULL;}#endif#ifdef USE_DVDNAV if (stream->type==STREAMTYPE_DVDNAV) stream_cache_size=0; // must disable caching...#endif// CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts)#ifdef HAS_DVBIN_SUPPORTgoto_enable_cache:#endifif(stream_cache_size>0){ current_module="enable_cache"; if(!stream_enable_cache(stream,stream_cache_size*1024,stream_cache_size*1024*(stream_cache_min_percent / 100.0),stream_cache_size*1024*(stream_cache_prefill_percent / 100.0))) if((eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY))) goto goto_next_file;}//============ Open DEMUXERS --- DETECT file type =======================current_module="demux_open";demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename);// HACK to get MOV Reference Files workingif (demuxer && demuxer->type==DEMUXER_TYPE_PLAYLIST){ unsigned char* playlist_entry; play_tree_t *list = NULL, *entry = NULL; current_module="handle_demux_playlist"; while (ds_get_packet(demuxer->video,&playlist_entry)>0) { char *temp, *bname; mp_msg(MSGT_CPLAYER,MSGL_V,"Adding file %s to element entry.\n",playlist_entry); bname=mp_basename(playlist_entry); if ((strlen(bname)>10) && !strncmp(bname,"qt",2) && !strncmp(bname+3,"gateQT",6)) continue; if (!strncmp(bname,mp_basename(filename),strlen(bname))) // ignoring self-reference continue; entry = play_tree_new(); if (filename && !strcmp(mp_basename(playlist_entry),playlist_entry)) // add reference path of current file { temp=malloc((strlen(filename)-strlen(mp_basename(filename))+strlen(playlist_entry)+1)*sizeof(char)); if (temp) { strncpy(temp, filename, strlen(filename)-strlen(mp_basename(filename))); temp[strlen(filename)-strlen(mp_basename(filename))]='\0'; strcat(temp, playlist_entry); play_tree_add_file(entry,temp); mp_msg(MSGT_CPLAYER,MSGL_V,"Resolving reference to %s.\n",temp); free(temp); } } else play_tree_add_file(entry,playlist_entry); if(!list) list = entry; else play_tree_append_entry(list,entry); } free_demuxer(demuxer); demuxer = NULL; if (list) { entry = play_tree_new(); play_tree_set_child(entry,list); eof=playtree_add_playlist(entry); goto goto_next_file; }}if(!demuxer) {#if 0 play_tree_t* entry; // Handle playlist current_module="handle_playlist"; switch(stream->type){ case STREAMTYPE_VCD: case STREAMTYPE_DVD: case STREAMTYPE_DVDNAV: case STREAMTYPE_CDDA: case STREAMTYPE_VCDBINCUE: // don't try to parse raw media as playlist, it's unlikely goto goto_next_file; } mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_FallingBackOnPlaylist,filename); stream_reset(stream); stream_seek(stream,stream->start_pos); entry = parse_playtree(stream,0); if(!entry) mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); else eof=playtree_add_playlist(entry);#endif goto goto_next_file;}inited_flags|=INITED_DEMUXER;#ifdef HAVE_MATROSKAif (demuxer->type==DEMUXER_TYPE_MATROSKA) { // setup global sub numbering global_sub_indices[SUB_SOURCE_DEMUX] = global_sub_size; // the global # of the first demux-specific sub. global_sub_size += demux_mkv_num_subs(demuxer);}#endif#ifdef HAVE_OGGVORBISif (demuxer->type==DEMUXER_TYPE_OGG) { // setup global sub numbering global_sub_indices[SUB_SOURCE_DEMUX] = global_sub_size; // the global # of the first demux-specific sub. global_sub_size += demux_ogg_num_subs(demuxer);}#endifcurrent_module="demux_open2";file_format=demuxer->file_format;d_audio=demuxer->audio;d_video=demuxer->video;d_dvdsub=demuxer->sub;// DUMP STREAMS:if((stream_dump_type)&&(stream_dump_type<4)){ FILE *f; demux_stream_t *ds=NULL; current_module="dump"; // select stream to dump switch(stream_dump_type){ case 1: ds=d_audio;break; case 2: ds=d_video;break; case 3: ds=d_dvdsub;break; } if(!ds){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_DumpSelectedStreamMissing); exit_player(MSGTR_Exit_error); } // disable other streams: if(d_audio && d_audio!=ds) {ds_free_packs(d_audio); d_audio->id=-2; } if(d_video && d_video!=ds) {ds_free_packs(d_video); d_video->id=-2; } if(d_dvdsub && d_dvdsub!=ds) {ds_free_packs(d_dvdsub); d_dvdsub->id=-2; } // let's dump it! f=fopen(stream_dump_name,"wb"); if(!f){ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_CantOpenDumpfile); exit_player(MSGTR_Exit_error); } while(!ds->eof){ unsigned char* start; int in_size=ds_get_packet(ds,&start); if( (demuxer->file_format==DEMUXER_TYPE_AVI || demuxer->file_format==DEMUXER_TYPE_ASF || demuxer->file_format==DEMUXER_TYPE_MOV) && stream_dump_type==2) fwrite(&in_size,1,4,f); if(in_size>0) fwrite(start,in_size,1,f); } fclose(f); mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_CoreDumped); exit_player_with_rc(MSGTR_Exit_eof, 0);}sh_audio=d_audio->sh;sh_video=d_video->sh;fflush(stdout);if(!sh_audio){ mp_msg(MSGT_CPLAYER,MSGL_FATAL, MSGTR_NoStreamFound); goto goto_next_file; // exit_player(MSGTR_Exit_error);}/* display clip info */demux_info_print(demuxer);//================== Read SUBTITLES (DVD & TEXT) ==========================//================== Init AUDIO (codec) ==========================if(sh_audio){ // Go through the codec.conf and find the best codec... current_module="init_audio_codec"; mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); if(!init_best_audio_codec(sh_audio,audio_codec_list,audio_fm_list)){ sh_audio=d_audio->sh=NULL; // failed to init :( } else inited_flags|=INITED_ACODEC; mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");}if(identify) { mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_FILENAME=%s\n", filename); if (sh_audio) { if (sh_audio->codec) mp_msg(MSGT_GLOBAL,MSGL_INFO, "ID_AUDIO_CODEC=%s\n", sh_audio->codec->name); /* Assume FOURCC if all bytes >= 0x20 (' ') */ if (sh_audio->format >= 0x20202020) mp_msg(MSGT_GLOBAL,MSGL_INFO, "ID_AUDIO_FORMAT=%.4s\n", &sh_audio->format); else mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_FORMAT=%d\n", sh_audio->format); mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_BITRATE=%d\n", sh_audio->i_bps*8); mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_RATE=%d\n", sh_audio->samplerate); mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_AUDIO_NCH=%d\n", sh_audio->channels); } mp_msg(MSGT_GLOBAL,MSGL_INFO,"ID_LENGTH=%ld\n", demuxer_get_time_length(demuxer));}if(!sh_video) goto main; // audio-only//================== Init VIDEO (codec & libvo) ==========================//================== MAIN: ==========================main:current_module="main";// If there is no video OSD has to be disabled.// In case of playing a playtree we have to restore the// old OSD level after playing one or more audio-only files.if(!sh_video && osd_level >= 0) { // save OSD level only once osd_level_saved = osd_level; osd_level = 0;} else if (osd_level_saved > -1) { // if there is a saved OSD level, restore it osd_level = osd_level_saved; osd_level_saved = -1;}fflush(stdout);#ifdef HAVE_NEW_GUI if ( use_gui ) { if ( sh_audio ) guiIntfStruct.AudioType=sh_audio->channels; else guiIntfStruct.AudioType=0; if ( !sh_video && sh_audio ) guiGetEvent( guiSetAudioOnly,(char *)1 ); else guiGetEvent( guiSetAudioOnly,(char *)0 ); guiGetEvent( guiSetFileFormat,(char *)demuxer->file_format ); if ( guiGetEvent( guiSetValues,(char *)sh_video ) ) goto goto_next_file; guiGetEvent( guiSetDemuxer,(char *)demuxer ); }#endif{//int frame_corr_num=0; ////float v_frame=0; // Videofloat time_frame=0; // Timer//float num_frames=0; // number of frames playedint grab_frames=0;char osd_text_buffer[64];char osd_show_text_buffer[64];int drop_frame=0; // current dropping statusint dropped_frames=0; // how many frames dropped since last non-dropped frameint too_slow_frame_cnt=0;int too_fast_frame_cnt=0;// for auto-quality:float AV_delay=0; // average of A-V timestamp differencesdouble vdecode_time;unsigned int lastframeout_ts=0;/*float time_frame_corr_avg=0;*/ /* unused */float next_frame_time=0;int frame_time_remaining=0; // flagint blit_frame=0;osd_text_buffer[0]=0;//================ SETUP AUDIO ==========================if(sh_audio){ //const ao_info_t *info=audio_out->info; current_module="af_preinit"; ao_data.samplerate=force_srate?force_srate:sh_audio->samplerate*playback_speed; ao_data.channels=audio_output_channels?audio_output_channels:sh_audio->channels; ao_data.format=audio_output_format?audio_output_format:sh_audio->sample_format;#if 1 if(!preinit_audio_filters(sh_audio, // input: (int)(sh_audio->samplerate*playback_speed), sh_audio->channels, sh_audio->sample_format, // output: &ao_data.samplerate, &ao_data.channels, &ao_data.format)){ mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_AudioFilterChainPreinitError); }#endif current_module="ao2_init"; if(!(audio_out=init_best_audio_out(audio_driver_list, 0, // plugin flag force_srate?force_srate:ao_data.samplerate, audio_output_channels?audio_output_channels:ao_data.channels, audio_output_format?audio_output_format:ao_data.format,0))){ // FAILED: mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CannotInitAO); uninit_player(INITED_ACODEC); // close codec sh_audio=d_audio->sh=NULL; // -> nosound } else { // SUCCESS: inited_flags|=INITED_AO; mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bps)\n", audio_out->info->short_name, ao_data.samplerate, ao_data.channels, af_fmt2str_short(ao_data.format), af_fmt2bits(ao_data.format)/8 ); mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Description: %s\nAO: Author: %s\n", audio_out->info->name, audio_out->info->author); if(strlen(audio_out->info->comment) > 0) mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Comment: %s\n", audio_out->info->comment); // init audio filters:#if 1 current_module="af_init"; if(!build_afilter_chain(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(INITED_ACODEC|INITED_AO); // close codec & ao// sh_audio=d_audio->sh=NULL; // -> nosound }#endif } mixer.audio_out = audio_out; mixer.volstep = volstep;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -