📄 es_out.c
字号:
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 selected */ val.i_int = -1; var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL ); var_SetBool( p_sys->p_input, "intf-change", VLC_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, vlc_bool_t 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( !es->p_dec ) 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( !es->p_dec ) 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 return; } } else if( i_cat == SPU_ES ) { int idx1 = LanguageArrayIndex( p_sys->ppsz_sub_language, es->psz_language_code ); if( p_sys->p_es_sub && p_sys->p_es_sub->fmt.i_priority >= es->fmt.i_priority ) { int idx2 = LanguageArrayIndex( p_sys->ppsz_sub_language, p_sys->p_es_sub->psz_language_code ); msg_Dbg( p_sys->p_input, "idx1=%d(%s) idx2=%d(%s)", idx1, es->psz_language_code, idx2, p_sys->p_es_sub->psz_language_code ); if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) ) return; /* We found a SPU that matches our language request */ i_wanted = es->i_channel; } else if( idx1 >= 0 ) { msg_Dbg( p_sys->p_input, "idx1=%d(%s)", idx1, es->psz_language_code ); i_wanted = es->i_channel; } if( p_sys->i_sub_last >= 0 ) i_wanted = p_sys->i_sub_last; if( p_sys->i_sub_id >= 0 ) { if( es->i_id == p_sys->i_sub_id ) i_wanted = es->i_channel; else return; } } else if( i_cat == VIDEO_ES ) { i_wanted = es->i_channel; } if( i_wanted == es->i_channel && es->p_dec == NULL ) EsSelect( out, es ); } /* FIXME TODO handle priority here */ if( es->p_dec ) { if( i_cat == AUDIO_ES ) { if( p_sys->i_mode == ES_OUT_MODE_AUTO && p_sys->p_es_audio && p_sys->p_es_audio != es && p_sys->p_es_audio->p_dec ) { EsUnselect( out, p_sys->p_es_audio, VLC_FALSE ); } p_sys->p_es_audio = es; } else if( i_cat == SPU_ES ) { if( p_sys->i_mode == ES_OUT_MODE_AUTO && p_sys->p_es_sub && p_sys->p_es_sub != es && p_sys->p_es_sub->p_dec ) { EsUnselect( out, p_sys->p_es_sub, VLC_FALSE ); } p_sys->p_es_sub = es; } else if( i_cat == VIDEO_ES ) { p_sys->p_es_video = es; } }}/** * Send a block for the given es_out * * \param out the es_out to send from * \param es the es_out_id * \param p_block the data block to send */static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; es_out_pgrm_t *p_pgrm = es->p_pgrm; int64_t i_delay; int i_total=0; if( es->fmt.i_cat == AUDIO_ES ) i_delay = p_sys->i_audio_delay; else if( es->fmt.i_cat == SPU_ES ) i_delay = p_sys->i_spu_delay; else i_delay = 0; if( p_input->p_libvlc->b_stats ) { stats_UpdateInteger( p_input, STATS_DEMUX_READ, p_block->i_buffer, &i_total ); stats_UpdateFloat( p_input , STATS_DEMUX_BITRATE, (float)i_total, NULL ); } /* Mark preroll blocks */ if( es->i_preroll_end >= 0 ) { int64_t i_date = p_block->i_pts; if( i_date <= 0 ) i_date = p_block->i_dts; if( i_date < es->i_preroll_end ) p_block->i_flags |= BLOCK_FLAG_PREROLL; else es->i_preroll_end = -1; } /* +11 -> avoid null value with non null dts/pts */ if( p_block->i_dts > 0 ) { p_block->i_dts = input_ClockGetTS( p_input, &p_pgrm->clock, ( p_block->i_dts + 11 ) * 9 / 100 ) + i_delay; } if( p_block->i_pts > 0 ) { p_block->i_pts = input_ClockGetTS( p_input, &p_pgrm->clock, ( p_block->i_pts + 11 ) * 9 / 100 ) + i_delay; } if ( es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) ) { mtime_t current_date = mdate(); if( !p_block->i_pts || p_block->i_pts > current_date + 10000000 || current_date > p_block->i_pts ) { /* ETSI EN 300 472 Annex A : do not take into account the PTS * for teletext streams. */ p_block->i_pts = current_date + 400000 + p_input->i_pts_delay + i_delay; } } p_block->i_rate = p_input->i_rate; /* TODO handle mute */ if( es->p_dec && ( es->fmt.i_cat != AUDIO_ES || p_input->i_rate == INPUT_RATE_DEFAULT ) ) { input_DecoderDecode( es->p_dec, p_block ); } else { block_Release( p_block ); } return VLC_SUCCESS;}/***************************************************************************** * EsOutDel: *****************************************************************************/static void EsOutDel( es_out_t *out, es_out_id_t *es ){ es_out_sys_t *p_sys = out->p_sys; vlc_bool_t b_reselect = VLC_FALSE; int i; /* We don't try to reselect */ if( es->p_dec ) EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm ); if( es->p_pgrm == p_sys->p_pgrm ) EsOutESVarUpdate( out, es, VLC_TRUE ); TAB_REMOVE( p_sys->i_es, p_sys->es, es ); es->p_pgrm->i_es--; if( es->p_pgrm->i_es == 0 ) { msg_Dbg( p_sys->p_input, "Program doesn't contain anymore ES" ); } if( p_sys->p_es_audio == es || p_sys->p_es_video == es || p_sys->p_es_sub == es ) b_reselect = VLC_TRUE; if( p_sys->p_es_audio == es ) p_sys->p_es_audio = NULL; if( p_sys->p_es_video == es ) p_sys->p_es_video = NULL; if( p_sys->p_es_sub == es ) p_sys->p_es_sub = NULL; switch( es->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; } /* Re-select another track when needed */ if( b_reselect ) for( i = 0; i < p_sys->i_es; i++ ) { if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat ) EsOutSelect( out, p_sys->es[i], VLC_FALSE ); } if( es->psz_language ) free( es->psz_language ); if( es->psz_language_code ) free( es->psz_language_code ); es_format_Clean( &es->fmt ); free( es );}/** * Control query handler * * \param out the es_out to control * \param i_query A es_out query as defined in include/ninput.h * \param args a variable list of arguments for the query * \return VLC_SUCCESS or an error code */static int EsOutControl( es_out_t *out, int i_query, va_list args ){ es_out_sys_t *p_sys = out->p_sys; vlc_bool_t b, *pb; int i, *pi; es_out_id_t *es; switch( i_query ) { case ES_OUT_SET_ES_STATE: es = (es_out_id_t*) va_arg( args, es_out_id_t * ); b = (vlc_bool_t) va_arg( args, vlc_bool_t ); if( b && es->p_dec == NULL ) { EsSelect( out, es ); return es->p_dec ? VLC_SUCCESS : VLC_EGENERIC; } else if( !b && es->p_dec ) { EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm ); return VLC_SUCCESS; } return VLC_SUCCESS; case ES_OUT_GET_ES_STATE: es = (es_out_id_t*) va_arg( args, es_out_id_t * ); pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * ); *pb = es->p_dec ? VLC_TRUE : VLC_FALSE; return VLC_SUCCESS; case ES_OUT_SET_ACTIVE: { b = (vlc_bool_t) va_arg( args, vlc_bool_t ); p_sys->b_active = b; /* Needed ? */ if( b ) var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE ); return VLC_SUCCESS; } case ES_OUT_GET_ACTIVE: pb = (vlc_bool_t*) va_arg( args, vlc_bool_t * ); *pb = p_sys->b_active; return VLC_SUCCESS; case ES_OUT_SET_MODE: i = (int) va_arg( args, int ); if( i == ES_OUT_MODE_NONE || i == ES_OUT_MODE_ALL || i == ES_OUT_MODE_AUTO || i == ES_OUT_MODE_PARTIAL ) { p_sys->i_mode = i; /* Reapply policy mode */ for( i = 0; i < p_sys->i_es; i++ ) { if( p_sys->es[i]->p_dec ) { EsUnselect( out, p_sys->es[i], p_sys->es[i]->p_pgrm == p_sys->p_pgrm ); } } for( i = 0; i < p_sys->i_es; i++ ) { EsOutSelect( out, p_sys->es[i], VLC_FALSE ); } return VLC_SUCCESS; } return VLC_EGENERIC; case ES_OUT_GET_MODE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -