📄 es_out.c
字号:
char *psz_epg; if( asprintf( &psz_epg, "EPG %s", psz_cat ) == -1 ) psz_epg = NULL; input_Control( p_input, INPUT_DEL_INFO, psz_epg, NULL ); msg_Dbg( p_input, "EsOutProgramEpg: number=%d name=%s", i_group, p_pgrm->p_epg->psz_name ); for( i = 0; i < p_pgrm->p_epg->i_event; i++ ) { const vlc_epg_event_t *p_evt = p_pgrm->p_epg->pp_event[i]; time_t t_start = (time_t)p_evt->i_start; struct tm tm_start; char psz_start[128]; localtime_r( &t_start, &tm_start ); snprintf( psz_start, sizeof(psz_start), "%2.2d:%2.2d:%2.2d", tm_start.tm_hour, tm_start.tm_min, tm_start.tm_sec ); if( p_evt->psz_short_description || p_evt->psz_description ) input_Control( p_input, INPUT_ADD_INFO, psz_epg, psz_start, "%s (%2.2d:%2.2d) - %s", p_evt->psz_name, p_evt->i_duration/60/60, (p_evt->i_duration/60)%60, p_evt->psz_short_description ? p_evt->psz_short_description : p_evt->psz_description ); else input_Control( p_input, INPUT_ADD_INFO, psz_epg, psz_start, "%s (%2.2d:%2.2d)", p_evt->psz_name, p_evt->i_duration/60/60, (p_evt->i_duration/60)%60 ); } free( psz_epg );#endif /* Update now playing */ free( p_pgrm->psz_now_playing ); p_pgrm->psz_now_playing = NULL; if( p_epg->p_current && p_epg->p_current->psz_name && *p_epg->p_current->psz_name ) p_pgrm->psz_now_playing = strdup( p_epg->p_current->psz_name ); if( p_pgrm == p_sys->p_pgrm ) input_item_SetNowPlaying( p_input->p->input.p_item, p_pgrm->psz_now_playing ); if( p_pgrm->psz_now_playing ) { input_Control( p_input, INPUT_ADD_INFO, psz_cat, input_MetaTypeToLocalizedString(vlc_meta_NowPlaying), p_pgrm->psz_now_playing ); } else { input_Control( p_input, INPUT_DEL_INFO, psz_cat, input_MetaTypeToLocalizedString(vlc_meta_NowPlaying) ); } free( psz_cat );}/* EsOutAdd: * Add an es_out */static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; es_out_id_t *es = malloc( sizeof( es_out_id_t ) ); es_out_pgrm_t *p_pgrm = NULL; int i; if( !es ) return NULL; if( fmt->i_group < 0 ) { msg_Err( p_input, "invalid group number" ); free( es ); return NULL; } /* Search the program */ for( i = 0; i < p_sys->i_pgrm; i++ ) { if( fmt->i_group == p_sys->pgrm[i]->i_id ) { p_pgrm = p_sys->pgrm[i]; break; } } if( p_pgrm == NULL ) { /* Create a new one */ p_pgrm = EsOutProgramAdd( out, fmt->i_group ); } /* Increase ref count for program */ p_pgrm->i_es++; /* Set up ES */ if( fmt->i_id < 0 ) fmt->i_id = out->p_sys->i_id; es->i_id = fmt->i_id; es->p_pgrm = p_pgrm; es_format_Copy( &es->fmt, fmt ); es->i_preroll_end = -1; switch( fmt->i_cat ) { case AUDIO_ES: { audio_replay_gain_t rg; es->i_channel = p_sys->i_audio; vlc_mutex_lock( &p_input->p->input.p_item->lock ); memset( &rg, 0, sizeof(rg) ); vlc_audio_replay_gain_MergeFromMeta( &rg, p_input->p->input.p_item->p_meta ); vlc_mutex_unlock( &p_input->p->input.p_item->lock ); for( i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ ) { if( !es->fmt.audio_replay_gain.pb_peak[i] ) { es->fmt.audio_replay_gain.pb_peak[i] = rg.pb_peak[i]; es->fmt.audio_replay_gain.pf_peak[i] = rg.pf_peak[i]; } if( !es->fmt.audio_replay_gain.pb_gain[i] ) { es->fmt.audio_replay_gain.pb_gain[i] = rg.pb_gain[i]; es->fmt.audio_replay_gain.pf_gain[i] = rg.pf_gain[i]; } } break; } case VIDEO_ES: es->i_channel = p_sys->i_video; if( fmt->video.i_frame_rate && fmt->video.i_frame_rate_base ) vlc_ureduce( &es->fmt.video.i_frame_rate, &es->fmt.video.i_frame_rate_base, fmt->video.i_frame_rate, fmt->video.i_frame_rate_base, 0 ); break; case SPU_ES: es->i_channel = p_sys->i_sub; break; default: es->i_channel = 0; break; } es->psz_language = LanguageGetName( fmt->psz_language ); /* remember so we only need to do it once */ es->psz_language_code = LanguageGetCode( fmt->psz_language ); es->p_dec = NULL; for( i = 0; i < 4; i++ ) es->pb_cc_present[i] = false; es->p_master = false; if( es->p_pgrm == p_sys->p_pgrm ) EsOutESVarUpdate( out, es, false ); /* Select it if needed */ EsOutSelect( out, es, false ); TAB_APPEND( out->p_sys->i_es, out->p_sys->es, es ); p_sys->i_id++; /* always incremented */ switch( fmt->i_cat ) { case AUDIO_ES: p_sys->i_audio++; break; case SPU_ES: p_sys->i_sub++; break; case VIDEO_ES: p_sys->i_video++; break; } EsOutAddInfo( out, es ); return es;}static bool EsIsSelected( es_out_id_t *es ){ if( es->p_master ) { bool b_decode = false; if( es->p_master->p_dec ) { int i_channel = EsOutGetClosedCaptionsChannel( es->fmt.i_codec ); if( i_channel != -1 ) input_DecoderGetCcState( es->p_master->p_dec, &b_decode, i_channel ); } return b_decode; } else { return es->p_dec != NULL; }}static void EsSelect( es_out_t *out, es_out_id_t *es ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; vlc_value_t val; const char *psz_var; if( EsIsSelected( es ) ) { msg_Warn( p_input, "ES 0x%x is already selected", es->i_id ); return; } if( es->p_master ) { int i_channel; if( !es->p_master->p_dec ) return; i_channel = EsOutGetClosedCaptionsChannel( es->fmt.i_codec ); if( i_channel == -1 || input_DecoderSetCcState( es->p_master->p_dec, true, i_channel ) ) return; } else { if( es->fmt.i_cat == VIDEO_ES || es->fmt.i_cat == SPU_ES ) { if( !var_GetBool( p_input, out->b_sout ? "sout-video" : "video" ) ) { msg_Dbg( p_input, "video is disabled, not selecting ES 0x%x", es->i_id ); return; } } else if( es->fmt.i_cat == AUDIO_ES ) { var_Get( p_input, "audio", &val ); if( !var_GetBool( p_input, out->b_sout ? "sout-audio" : "audio" ) ) { msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x", es->i_id ); return; } } if( es->fmt.i_cat == SPU_ES ) { var_Get( p_input, "spu", &val ); if( !var_GetBool( p_input, out->b_sout ? "sout-spu" : "spu" ) ) { msg_Dbg( p_input, "spu is disabled, not selecting ES 0x%x", es->i_id ); return; } } es->i_preroll_end = -1; es->p_dec = input_DecoderNew( p_input, &es->fmt, false ); if( es->p_dec == NULL || es->p_pgrm != p_sys->p_pgrm ) return; } if( es->fmt.i_cat == VIDEO_ES ) psz_var = "video-es"; else if( es->fmt.i_cat == AUDIO_ES ) psz_var = "audio-es"; else if( es->fmt.i_cat == SPU_ES ) psz_var = "spu-es"; else return; /* Mark it as selected */ val.i_int = es->i_id; var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL ); var_SetBool( p_sys->p_input, "intf-change", true );}static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; vlc_value_t val; const char *psz_var; if( !EsIsSelected( es ) ) { msg_Warn( p_input, "ES 0x%x is already unselected", es->i_id ); return; } if( es->p_master ) { if( es->p_master->p_dec ) { int i_channel = EsOutGetClosedCaptionsChannel( es->fmt.i_codec ); if( i_channel != -1 ) input_DecoderSetCcState( es->p_master->p_dec, false, i_channel ); } } else { const int i_spu_id = var_GetInteger( p_input, "spu-es"); int i; for( i = 0; i < 4; i++ ) { if( !es->pb_cc_present[i] || !es->pp_cc_es[i] ) continue; if( i_spu_id == es->pp_cc_es[i]->i_id ) { /* Force unselection of the CC */ val.i_int = -1; var_Change( p_input, "spu-es", VLC_VAR_SETVALUE, &val, NULL ); if( !b_update ) var_SetBool( p_sys->p_input, "intf-change", true ); } EsOutDel( out, es->pp_cc_es[i] ); es->pb_cc_present[i] = false; } input_DecoderDelete( es->p_dec ); es->p_dec = NULL; } if( !b_update ) return; /* Update var */ if( es->p_dec == NULL ) return; if( es->fmt.i_cat == VIDEO_ES ) psz_var = "video-es"; else if( es->fmt.i_cat == AUDIO_ES ) psz_var = "audio-es"; else if( es->fmt.i_cat == SPU_ES ) psz_var = "spu-es"; else return; /* Mark it as unselected */ val.i_int = -1; var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL ); var_SetBool( p_sys->p_input, "intf-change", true );}/** * Select an ES given the current mode * XXX: you need to take a the lock before (stream.stream_lock) * * \param out The es_out structure * \param es es_out_id structure * \param b_force ... * \return nothing */static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force ){ es_out_sys_t *p_sys = out->p_sys; int i_cat = es->fmt.i_cat; if( !p_sys->b_active || ( !b_force && es->fmt.i_priority < 0 ) ) { return; } if( p_sys->i_mode == ES_OUT_MODE_ALL || b_force ) { if( !EsIsSelected( es ) ) EsSelect( out, es ); } else if( p_sys->i_mode == ES_OUT_MODE_PARTIAL ) { vlc_value_t val; int i; var_Get( p_sys->p_input, "programs", &val ); for ( i = 0; i < val.p_list->i_count; i++ ) { if ( val.p_list->p_values[i].i_int == es->p_pgrm->i_id || b_force ) { if( !EsIsSelected( es ) ) EsSelect( out, es ); break; } } var_Change( p_sys->p_input, "programs", VLC_VAR_FREELIST, &val, NULL ); } else if( p_sys->i_mode == ES_OUT_MODE_AUTO ) { int i_wanted = -1; if( es->p_pgrm != p_sys->p_pgrm ) return; if( i_cat == AUDIO_ES ) { int idx1 = LanguageArrayIndex( p_sys->ppsz_audio_language, es->psz_language_code ); if( p_sys->p_es_audio && p_sys->p_es_audio->fmt.i_priority >= es->fmt.i_priority ) { int idx2 = LanguageArrayIndex( p_sys->ppsz_audio_language, p_sys->p_es_audio->psz_language_code ); if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) ) return; i_wanted = es->i_channel; } else { /* Select audio if (no audio selected yet) * - no audio-language * - no audio code for the ES * - audio code in the requested list */ if( idx1 >= 0 || !strcmp( es->psz_language_code, "??" ) || !p_sys->ppsz_audio_language ) i_wanted = es->i_channel; } if( p_sys->i_audio_last >= 0 ) i_wanted = p_sys->i_audio_last; if( p_sys->i_audio_id >= 0 ) { if( es->i_id == p_sys->i_audio_id ) i_wanted = es->i_channel; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -