📄 es_out.c
字号:
vlc_value_t val, text; const char *psz_var; if( fmt->i_cat == AUDIO_ES ) psz_var = "audio-es"; else if( fmt->i_cat == VIDEO_ES ) psz_var = "video-es"; else if( fmt->i_cat == SPU_ES ) psz_var = "spu-es"; else return; if( b_delete ) { if( b_teletext ) var_SetInteger( p_sys->p_input, "teletext-es", -1 ); val.i_int = i_id; var_Change( p_input, psz_var, VLC_VAR_DELCHOICE, &val, NULL ); var_SetBool( p_sys->p_input, "intf-change", true ); return; } /* Get the number of ES already added */ var_Change( p_input, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL ); if( val.i_int == 0 ) { vlc_value_t val2; /* First one, we need to add the "Disable" choice */ val2.i_int = -1; text.psz_string = _("Disable"); var_Change( p_input, psz_var, VLC_VAR_ADDCHOICE, &val2, &text ); val.i_int++; } /* Take care of the ES description */ if( fmt->psz_description && *fmt->psz_description ) { if( psz_language && *psz_language ) { text.psz_string = malloc( strlen( fmt->psz_description) + strlen( psz_language ) + 10 ); sprintf( text.psz_string, "%s - [%s]", fmt->psz_description, psz_language ); } else text.psz_string = strdup( fmt->psz_description ); } else { if( psz_language && *psz_language ) { if( asprintf( &text.psz_string, "%s %i - [%s]", _( "Track" ), val.i_int, psz_language ) == -1 ) text.psz_string = NULL; } else { if( asprintf( &text.psz_string, "%s %i", _( "Track" ), val.i_int ) == -1 ) text.psz_string = NULL; } } val.i_int = i_id; var_Change( p_input, psz_var, VLC_VAR_ADDCHOICE, &val, &text ); free( text.psz_string ); if( b_teletext ) { if( var_GetInteger( p_sys->p_input, "teletext-es" ) < 0 ) var_SetInteger( p_sys->p_input, "teletext-es", i_id ); } var_SetBool( p_sys->p_input, "intf-change", true );}static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es, bool b_delete ){ EsOutESVarUpdateGeneric( out, es->i_id, &es->fmt, es->psz_language, b_delete );}/* EsOutProgramSelect: * Select a program and update the object variable */static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; vlc_value_t val; int i; if( p_sys->p_pgrm == p_pgrm ) return; /* Nothing to do */ if( p_sys->p_pgrm ) { es_out_pgrm_t *old = p_sys->p_pgrm; msg_Dbg( p_input, "unselecting program id=%d", old->i_id ); for( i = 0; i < p_sys->i_es; i++ ) { if( p_sys->es[i]->p_pgrm == old && EsIsSelected( p_sys->es[i] ) && p_sys->i_mode != ES_OUT_MODE_ALL ) EsUnselect( out, p_sys->es[i], true ); } p_sys->p_es_audio = NULL; p_sys->p_es_sub = NULL; p_sys->p_es_video = NULL; } msg_Dbg( p_input, "selecting program id=%d", p_pgrm->i_id ); /* Mark it selected */ p_pgrm->b_selected = true; /* Switch master stream */ if( p_sys->p_pgrm && p_sys->p_pgrm->clock.b_master ) { p_sys->p_pgrm->clock.b_master = false; } p_pgrm->clock.b_master = true; p_sys->p_pgrm = p_pgrm; /* Update "program" */ val.i_int = p_pgrm->i_id; var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL ); /* Update "es-*" */ var_Change( p_input, "audio-es", VLC_VAR_CLEARCHOICES, NULL, NULL ); var_Change( p_input, "video-es", VLC_VAR_CLEARCHOICES, NULL, NULL ); var_Change( p_input, "spu-es", VLC_VAR_CLEARCHOICES, NULL, NULL ); var_SetInteger( p_input, "teletext-es", -1 ); for( i = 0; i < p_sys->i_es; i++ ) { if( p_sys->es[i]->p_pgrm == p_sys->p_pgrm ) EsOutESVarUpdate( out, p_sys->es[i], false ); EsOutSelect( out, p_sys->es[i], false ); } /* Update now playing */ input_item_SetNowPlaying( p_input->p->input.p_item, p_pgrm->psz_now_playing ); input_item_SetPublisher( p_input->p->input.p_item, p_pgrm->psz_publisher ); var_SetBool( p_sys->p_input, "intf-change", true );}/* EsOutAddProgram: * Add a program */static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; vlc_value_t val; es_out_pgrm_t *p_pgrm = malloc( sizeof( es_out_pgrm_t ) ); if( !p_pgrm ) return NULL; /* Init */ p_pgrm->i_id = i_group; p_pgrm->i_es = 0; p_pgrm->b_selected = false; p_pgrm->psz_name = NULL; p_pgrm->psz_now_playing = NULL; p_pgrm->psz_publisher = NULL; p_pgrm->p_epg = NULL; input_ClockInit( &p_pgrm->clock, false, p_input->p->input.i_cr_average, p_sys->i_rate ); /* Append it */ TAB_APPEND( p_sys->i_pgrm, p_sys->pgrm, p_pgrm ); /* Update "program" variable */ val.i_int = i_group; var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, NULL ); if( i_group == var_GetInteger( p_input, "program" ) ) { EsOutProgramSelect( out, p_pgrm ); } else { var_SetBool( p_sys->p_input, "intf-change", true ); } return p_pgrm;}/* EsOutDelProgram: * Delete a program */static int EsOutProgramDel( es_out_t *out, int i_group ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; es_out_pgrm_t *p_pgrm = NULL; vlc_value_t val; int i; for( i = 0; i < p_sys->i_pgrm; i++ ) { if( p_sys->pgrm[i]->i_id == i_group ) { p_pgrm = p_sys->pgrm[i]; break; } } if( p_pgrm == NULL ) return VLC_EGENERIC; if( p_pgrm->i_es ) { msg_Dbg( p_input, "can't delete program %d which still has %i ES", i_group, p_pgrm->i_es ); return VLC_EGENERIC; } TAB_REMOVE( p_sys->i_pgrm, p_sys->pgrm, p_pgrm ); /* If program is selected we need to unselect it */ if( p_sys->p_pgrm == p_pgrm ) p_sys->p_pgrm = NULL; free( p_pgrm->psz_name ); free( p_pgrm->psz_now_playing ); free( p_pgrm->psz_publisher ); if( p_pgrm->p_epg ) vlc_epg_Delete( p_pgrm->p_epg ); free( p_pgrm ); /* Update "program" variable */ val.i_int = i_group; var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL ); var_SetBool( p_sys->p_input, "intf-change", true ); return VLC_SUCCESS;}/* EsOutProgramMeta: */static char *EsOutProgramGetMetaName( es_out_pgrm_t *p_pgrm ){ char *psz = NULL; if( p_pgrm->psz_name ) { if( asprintf( &psz, _("%s [%s %d]"), p_pgrm->psz_name, _("Program"), p_pgrm->i_id ) == -1 ) return NULL; } else { if( asprintf( &psz, "%s %d", _("Program"), p_pgrm->i_id ) == -1 ) return NULL; } return psz;}static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ){ es_out_sys_t *p_sys = out->p_sys; es_out_pgrm_t *p_pgrm = NULL; input_thread_t *p_input = p_sys->p_input; char *psz_cat; const char *psz_title = NULL; const char *psz_provider = NULL; int i; msg_Dbg( p_input, "EsOutProgramMeta: number=%d", i_group ); /* Check against empty meta data (empty for what we handle) */ if( !vlc_meta_Get( p_meta, vlc_meta_Title) && !vlc_meta_Get( p_meta, vlc_meta_NowPlaying) && !vlc_meta_Get( p_meta, vlc_meta_Publisher) && vlc_dictionary_keys_count( &p_meta->extra_tags ) <= 0 ) { return; } /* Find program */ for( i = 0; i < p_sys->i_pgrm; i++ ) { if( p_sys->pgrm[i]->i_id == i_group ) { p_pgrm = p_sys->pgrm[i]; break; } } if( p_pgrm == NULL ) p_pgrm = EsOutProgramAdd( out, i_group ); /* Create it */ /* */ psz_title = vlc_meta_Get( p_meta, vlc_meta_Title); psz_provider = vlc_meta_Get( p_meta, vlc_meta_Publisher); /* Update the description text of the program */ if( psz_title && *psz_title ) { vlc_value_t val; vlc_value_t text; if( !p_pgrm->psz_name || strcmp( p_pgrm->psz_name, psz_title ) ) { char *psz_cat = EsOutProgramGetMetaName( p_pgrm ); /* Remove old entries */ input_Control( p_input, INPUT_DEL_INFO, psz_cat, NULL ); /* TODO update epg name */ free( psz_cat ); } free( p_pgrm->psz_name ); p_pgrm->psz_name = strdup( psz_title ); /* ugly but it works */ val.i_int = i_group; var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL ); if( psz_provider && *psz_provider ) { if( asprintf( &text.psz_string, "%s [%s]", psz_title, psz_provider ) != -1 ) { var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text ); free( text.psz_string ); } } else { text.psz_string = (char *)psz_title; var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text ); } } psz_cat = EsOutProgramGetMetaName( p_pgrm ); if( psz_provider ) { if( p_sys->p_pgrm == p_pgrm ) input_item_SetPublisher( p_input->p->input.p_item, psz_provider ); input_Control( p_input, INPUT_ADD_INFO, psz_cat, input_MetaTypeToLocalizedString(vlc_meta_Publisher), psz_provider ); } char ** ppsz_all_keys = vlc_dictionary_all_keys( &p_meta->extra_tags ); for( i = 0; ppsz_all_keys[i]; i++ ) { input_Control( p_input, INPUT_ADD_INFO, psz_cat, _(ppsz_all_keys[i]), vlc_dictionary_value_for_key( &p_meta->extra_tags, ppsz_all_keys[i] ) ); free( ppsz_all_keys[i] ); } free( ppsz_all_keys ); free( psz_cat );}static void vlc_epg_Merge( vlc_epg_t *p_dst, const vlc_epg_t *p_src ){ int i; /* Add new event */ for( i = 0; i < p_src->i_event; i++ ) { vlc_epg_event_t *p_evt = p_src->pp_event[i]; bool b_add = true; int j; for( j = 0; j < p_dst->i_event; j++ ) { if( p_dst->pp_event[j]->i_start == p_evt->i_start && p_dst->pp_event[j]->i_duration == p_evt->i_duration ) { b_add = false; break; } if( p_dst->pp_event[j]->i_start > p_evt->i_start ) break; } if( b_add ) { vlc_epg_event_t *p_copy = malloc( sizeof(vlc_epg_event_t) ); if( !p_copy ) break; memset( p_copy, 0, sizeof(vlc_epg_event_t) ); p_copy->i_start = p_evt->i_start; p_copy->i_duration = p_evt->i_duration; p_copy->psz_name = p_evt->psz_name ? strdup( p_evt->psz_name ) : NULL; p_copy->psz_short_description = p_evt->psz_short_description ? strdup( p_evt->psz_short_description ) : NULL; p_copy->psz_description = p_evt->psz_description ? strdup( p_evt->psz_description ) : NULL; TAB_INSERT( p_dst->i_event, p_dst->pp_event, p_copy, j ); } } /* Update current */ vlc_epg_SetCurrent( p_dst, p_src->p_current ? p_src->p_current->i_start : -1 ); /* Keep only 1 old event */ if( p_dst->p_current ) { while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current ) TAB_REMOVE( p_dst->i_event, p_dst->pp_event, p_dst->pp_event[0] ); }}static void EsOutProgramEpg( es_out_t *out, int i_group, vlc_epg_t *p_epg ){ es_out_sys_t *p_sys = out->p_sys; input_thread_t *p_input = p_sys->p_input; es_out_pgrm_t *p_pgrm = NULL; char *psz_cat; int i; /* Find program */ for( i = 0; i < p_sys->i_pgrm; i++ ) { if( p_sys->pgrm[i]->i_id == i_group ) { p_pgrm = p_sys->pgrm[i]; break; } } if( p_pgrm == NULL ) p_pgrm = EsOutProgramAdd( out, i_group ); /* Create it */ /* Merge EPG */ if( !p_pgrm->p_epg ) p_pgrm->p_epg = vlc_epg_New( p_pgrm->psz_name ); vlc_epg_Merge( p_pgrm->p_epg, p_epg ); /* Update info */ psz_cat = EsOutProgramGetMetaName( p_pgrm );#ifdef HAVE_LOCALTIME_R
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -