From: Laurent Aimar Date: Thu, 20 Nov 2008 20:49:51 +0000 (+0100) Subject: Move/clean up input event code to its own file. X-Git-Tag: 1.0.0-pre1~2078 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=6d56066a71397f79b4d810e17e1c1cf0c061f7b4;p=vlc Move/clean up input event code to its own file. There is no functionnal changes except a few missing events added. --- diff --git a/include/vlc_input.h b/include/vlc_input.h index 2ea168637b..28973eeb24 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -179,7 +179,8 @@ VLC_EXPORT( void, input_item_MetaMerge, ( input_item_t *p_i, const vlc_meta_t #define input_item_GetSetting( item ) input_item_GetMeta( item, vlc_meta_Setting ) VLC_EXPORT( char *, input_item_GetInfo, ( input_item_t *p_i, const char *psz_cat,const char *psz_name ) ); -VLC_EXPORT(int, input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) LIBVLC_FORMAT( 4, 5 ) ); +VLC_EXPORT( int, input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) LIBVLC_FORMAT( 4, 5 ) ); +VLC_EXPORT( int, input_item_DelInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name ) ); #define input_item_New( a,b,c ) input_item_NewExt( a, b, c, 0, NULL, -1 ) #define input_item_NewExt(a,b,c,d,e,f) __input_item_NewExt( VLC_OBJECT(a),b,c,d,e,f) diff --git a/src/Makefile.am b/src/Makefile.am index b2de04b059..106cfafa66 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -310,6 +310,7 @@ SOURCES_libvlc_common = \ input/demux.c \ input/es_out.c \ input/es_out_timeshift.c \ + input/event.c \ input/input.c \ input/meta.c \ input/access.h \ @@ -318,6 +319,7 @@ SOURCES_libvlc_common = \ input/demux.h \ input/es_out.h \ input/es_out_timeshift.h \ + input/event.h \ input/stream.h \ input/input_internal.h \ input/vlm_internal.h \ diff --git a/src/input/control.c b/src/input/control.c index ed3d12ec72..953fd0bdac 100644 --- a/src/input/control.c +++ b/src/input/control.c @@ -31,6 +31,7 @@ #include #include "input_internal.h" +#include "event.h" static void UpdateBookmarksOption( input_thread_t * ); @@ -139,143 +140,30 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args ) char *psz_name = (char *)va_arg( args, char * ); char *psz_format = (char *)va_arg( args, char * ); - info_category_t *p_cat; - info_t *p_info; - int i; - - vlc_mutex_lock( &p_input->p->input.p_item->lock ); - for( i = 0; i < p_input->p->input.p_item->i_categories; i++ ) - { - if( !strcmp( p_input->p->input.p_item->pp_categories[i]->psz_name, - psz_cat ) ) break; - } - - if( i == p_input->p->input.p_item->i_categories ) - { - p_cat = malloc( sizeof( info_category_t ) ); - if( !p_cat ) - { - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); - return VLC_EGENERIC; - } - p_cat->psz_name = strdup( psz_cat ); - p_cat->i_infos = 0; - p_cat->pp_infos = NULL; - INSERT_ELEM( p_input->p->input.p_item->pp_categories, - p_input->p->input.p_item->i_categories, - p_input->p->input.p_item->i_categories, p_cat ); - } - - p_cat = p_input->p->input.p_item->pp_categories[i]; - - for( i = 0; i < p_cat->i_infos; i++ ) - { - if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) ) - { - if( p_cat->pp_infos[i]->psz_value ) - free( p_cat->pp_infos[i]->psz_value ); - break; - } - } - - if( i == p_cat->i_infos ) - { - p_info = malloc( sizeof( info_t ) ); - if( !p_info ) - { - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); - return VLC_EGENERIC; - } - - INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, - p_cat->i_infos, p_info ); - p_info->psz_name = strdup( psz_name ); - } - - p_info = p_cat->pp_infos[i]; - if( vasprintf( &p_info->psz_value, psz_format, args ) == -1 ) - p_info->psz_value = NULL; + char *psz_value; + + if( vasprintf( &psz_value, psz_format, args ) == -1 ) + return VLC_EGENERIC; - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); + int i_ret = input_item_AddInfo( p_input->p->input.p_item, + psz_cat, psz_name, "%s", psz_value ); - if( !p_input->b_preparsing ) - { - vlc_event_t event; - event.type = vlc_InputItemInfoChanged; - vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); - } + if( !p_input->b_preparsing && !i_ret ) + input_SendEventMetaInfo( p_input ); + return i_ret; } - return VLC_SUCCESS; case INPUT_DEL_INFO: { char *psz_cat = (char *)va_arg( args, char * ); char *psz_name = (char *)va_arg( args, char * ); - info_category_t *p_cat = NULL; - int i_cat; - int i; + int i_ret = input_item_DelInfo( p_input->p->input.p_item, + psz_cat, psz_name ); - vlc_mutex_lock( &p_input->p->input.p_item->lock ); - for( i_cat = 0; i_cat < p_input->p->input.p_item->i_categories; i_cat++ ) - { - if( !strcmp( p_input->p->input.p_item->pp_categories[i_cat]->psz_name, - psz_cat ) ) - { - p_cat = p_input->p->input.p_item->pp_categories[i_cat]; - break; - } - } - if( p_cat == NULL ) - { - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); - return VLC_EGENERIC; - } - - if( psz_name ) - { - /* Remove a specific info */ - for( i = 0; i < p_cat->i_infos; i++ ) - { - if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) ) - { - free( p_cat->pp_infos[i]->psz_name ); - if( p_cat->pp_infos[i]->psz_value ) - free( p_cat->pp_infos[i]->psz_value ); - free( p_cat->pp_infos[i] ); - REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i ); - break; - } - } - if( i >= p_cat->i_infos ) - { - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); - return VLC_EGENERIC; - } - } - else - { - /* Remove the complete categorie */ - for( i = 0; i < p_cat->i_infos; i++ ) - { - free( p_cat->pp_infos[i]->psz_name ); - if( p_cat->pp_infos[i]->psz_value ) - free( p_cat->pp_infos[i]->psz_value ); - free( p_cat->pp_infos[i] ); - } - if( p_cat->pp_infos ) - free( p_cat->pp_infos ); - REMOVE_ELEM( p_input->p->input.p_item->pp_categories, p_input->p->input.p_item->i_categories, i_cat ); - } - vlc_mutex_unlock( &p_input->p->input.p_item->lock ); - - if( !p_input->b_preparsing ) - { - vlc_event_t event; - event.type = vlc_InputItemInfoChanged; - vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); - } - return VLC_SUCCESS; + if( !p_input->b_preparsing && !i_ret ) + input_SendEventMetaInfo( p_input ); + return i_ret; } @@ -305,12 +193,7 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args ) vlc_mutex_unlock( &p_input->p->input.p_item->lock ); if( !p_input->b_preparsing ) - { - vlc_event_t event; - event.type = vlc_InputItemNameChanged; - event.u.input_item_name_changed.new_name = psz_name; - vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); - } + input_SendEventMetaName( p_input, psz_name ); return VLC_SUCCESS; } diff --git a/src/input/es_out.c b/src/input/es_out.c index bfbfcef7c7..37e6035870 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -42,6 +42,7 @@ #include "clock.h" #include "decoder.h" #include "es_out.h" +#include "event.h" #include "../stream_output/stream_output.h" @@ -797,30 +798,25 @@ static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, const bool b_teletext = fmt->i_cat == SPU_ES && fmt->i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ); 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 ) { + /* TODO event */ 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 ); + input_SendEventEsDel( p_input, SPU_ES, i_id ); return; } /* Get the number of ES already added */ + 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 + psz_var = "spu-es"; + var_Change( p_input, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL ); if( val.i_int == 0 ) { @@ -858,18 +854,16 @@ static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, } } - val.i_int = i_id; - var_Change( p_input, psz_var, VLC_VAR_ADDCHOICE, &val, &text ); + input_SendEventEsAdd( p_input, fmt->i_cat, i_id, text.psz_string ); free( text.psz_string ); if( b_teletext ) { + /* TODO event */ 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, @@ -885,7 +879,6 @@ 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 ) @@ -917,14 +910,16 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm ) 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 ); + input_SendEventProgramSelect( p_input, p_pgrm->i_id ); /* 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 ); + input_SendEventEsDel( p_input, AUDIO_ES, -1 ); + input_SendEventEsDel( p_input, VIDEO_ES, -1 ); + input_SendEventEsDel( p_input, SPU_ES, -1 ); + + /* TODO event */ 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 ) @@ -938,7 +933,7 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm ) input_item_SetPublisher( p_input->p->input.p_item, p_pgrm->psz_publisher ); - var_SetBool( p_sys->p_input, "intf-change", true ); + input_SendEventMeta( p_input ); } /* EsOutAddProgram: @@ -948,7 +943,6 @@ 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 ) @@ -973,17 +967,11 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group ) 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 ); + input_SendEventProgramAdd( p_input, i_group, 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; } @@ -995,7 +983,6 @@ 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++ ) @@ -1033,10 +1020,7 @@ static int EsOutProgramDel( es_out_t *out, int i_group ) 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 ); + input_SendEventProgramDel( p_input, i_group ); return VLC_SUCCESS; } @@ -1098,9 +1082,6 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ) /* 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 ); @@ -1113,22 +1094,24 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ) 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 ); - + char *psz_text; 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 ); - } + if( asprintf( &psz_text, "%s [%s]", psz_title, psz_provider ) < 0 ) + psz_text = NULL; } else { - text.psz_string = (char *)psz_title; - var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text ); + psz_text = strdup( psz_title ); + } + + /* ugly but it works */ + if( psz_text ) + { + input_SendEventProgramDel( p_input, i_group ); + input_SendEventProgramAdd( p_input, i_group, psz_text ); + + free( psz_text ); } } @@ -1136,7 +1119,10 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ) if( psz_provider ) { if( p_sys->p_pgrm == p_pgrm ) + { input_item_SetPublisher( p_input->p->input.p_item, psz_provider ); + input_SendEventMeta( p_input ); + } 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 ); @@ -1259,7 +1245,10 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, vlc_epg_t *p_epg ) 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 ); + input_SendEventMeta( p_input ); + } if( p_pgrm->psz_now_playing ) { @@ -1468,7 +1457,6 @@ 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 ) ) { @@ -1524,28 +1512,14 @@ static void EsSelect( es_out_t *out, es_out_id_t *es ) 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 ); + input_SendEventEsSelect( p_input, es->fmt.i_cat, es->i_id ); } 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 ) ) { @@ -1574,10 +1548,7 @@ static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update ) 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 ); + input_SendEventEsSelect( p_input, SPU_ES, -1 ); } EsOutDel( out, es->pp_cc_es[i] ); @@ -1592,20 +1563,9 @@ static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update ) /* 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 ); + input_SendEventEsSelect( p_input, es->fmt.i_cat, -1 ); } /** @@ -1836,7 +1796,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) /* Check CC status */ bool pb_cc[4]; - bool b_cc_new = false; input_DecoderIsCcPresent( es->p_dec, pb_cc ); for( int i = 0; i < 4; i++ ) @@ -1864,10 +1823,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) /* */ es->pb_cc_present[i] = true; - b_cc_new = true; } - if( b_cc_new ) - var_SetBool( p_sys->p_input, "intf-change", true ); vlc_mutex_unlock( &p_sys->lock ); @@ -1963,7 +1919,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) { es_out_sys_t *p_sys = out->p_sys; bool b, *pb; - int i, *pi; + int i; es_out_id_t *es; @@ -1995,9 +1951,6 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) { b = (bool) va_arg( args, int ); p_sys->b_active = b; - /* Needed ? */ - if( b ) - var_SetBool( p_sys->p_input, "intf-change", true ); return VLC_SUCCESS; } @@ -2076,12 +2029,6 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) } } } - if( i_query == ES_OUT_SET_ES ) - { - vlc_event_t event; - event.type = vlc_InputSelectedStreamChanged; - vlc_event_send( &p_sys->p_input->p->event_manager, &event ); - } return VLC_SUCCESS; } @@ -2533,6 +2480,7 @@ static void EsOutAddInfo( es_out_t *out, es_out_id_t *es ) { input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Sample rate"), _("%u Hz"), fmt->audio.i_rate ); + /* FIXME that should be removed or improved ! (used by text/strings.c) */ var_SetInteger( p_input, "sample-rate", fmt->audio.i_rate ); } @@ -2545,6 +2493,7 @@ static void EsOutAddInfo( es_out_t *out, es_out_id_t *es ) { input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Bitrate"), _("%u kb/s"), fmt->i_bitrate / 1000 ); + /* FIXME that should be removed or improved ! (used by text/strings.c) */ var_SetInteger( p_input, "bit-rate", fmt->i_bitrate ); } break; diff --git a/src/input/event.c b/src/input/event.c new file mode 100644 index 0000000000..90f029f09e --- /dev/null +++ b/src/input/event.c @@ -0,0 +1,291 @@ +/***************************************************************************** + * event.c: Events + ***************************************************************************** + * Copyright (C) 2008 Laurent Aimar + * $Id$ + * + * Authors: Laurent Aimar < fenrir _AT_ videolan _DOT_ org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "input_internal.h" +#include "event.h" + +/***************************************************************************** + * Event for input.c + *****************************************************************************/ +void input_SendEventTimes( input_thread_t *p_input, const input_event_times_t *p_times ) +{ + vlc_value_t val; + + /* */ + val.f_float = p_times->f_position; + var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL ); + + /* */ + val.i_time = p_times->i_time; + var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL ); + + /* FIXME ugly + what about meta change event ? */ + if( var_GetTime( p_input, "length" ) != p_times->i_length ) + input_item_SetDuration( p_input->p->input.p_item, p_times->i_length ); + val.i_time = p_times->i_length; + var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-times", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} +void input_SendEventStatistics( input_thread_t *p_input ) +{ + var_TriggerCallback( p_input, "stats-change" ); /* FIXME rename */ +} +void input_SendEventRate( input_thread_t *p_input, int i_rate ) +{ + vlc_value_t val; + + val.i_int = i_rate; + var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); + + var_TriggerCallback( p_input, "rate-change" ); /* TODO rename */ +} +void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay ) +{ + vlc_value_t val; + + val.i_time = i_delay; + var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-delay" ); /* TODO */ +} + +void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay ) +{ + vlc_value_t val; + + val.i_time = i_delay; + var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-delay" ); /* TODO */ +} + +/* TODO and file name ? */ +void input_SendEventRecord( input_thread_t *p_input, bool b_recording ) +{ + vlc_value_t val; + + val.b_bool = b_recording; + var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL ); + + var_TriggerCallback( p_input, "intf-change" ); /* FIXME */ +} + +void input_SendEventTitle( input_thread_t *p_input, int i_title ) +{ + vlc_value_t val; + + val.i_int = i_title; + var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL ); + + input_ControlVarTitle( p_input, i_title ); /* FIXME ??? */ + + //var_SetBool( p_input, "intf-change-title" ); /* TODO */ +} + +void input_SendEventSeekpoint( input_thread_t *p_input, int i_title, int i_seekpoint ) +{ + vlc_value_t val; + + VLC_UNUSED( i_title ); + val.i_int = i_seekpoint; + var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL); + + //var_SetBool( p_input, "intf-change-seekpoint" ); /* TODO. Merge with intf-change-title ? */ +} + +void input_SendEventSignal( input_thread_t *p_input, double f_quality, double f_strength ) +{ + var_SetFloat( p_input, "signal-quality", f_quality ); + var_SetFloat( p_input, "signal-strength", f_strength ); + + /* TODO use Change and then a intf-change-signal instead ? */ +} + +void input_SendEventState( input_thread_t *p_input, int i_state ) +{ + vlc_value_t val; + + val.i_int = i_state; + var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); + + var_TriggerCallback( p_input, "intf-change" ); + + /* FIXME remove this ugliness */ + vlc_event_t event; + + event.type = vlc_InputStateChanged; + event.u.input_state_changed.new_state = i_state; + vlc_event_send( &p_input->p->event_manager, &event ); +} + +#warning "TODO meta" +/* FIXME: review them because vlc_event_send might be + * moved inside input_item* functions. + */ +void input_SendEventMeta( input_thread_t *p_input ) +{ + var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-meta */ + + /* FIXME remove this ugliness ? */ + vlc_event_t event; + + event.type = vlc_InputItemMetaChanged; + event.u.input_item_meta_changed.meta_type = vlc_meta_ArtworkURL; + vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); +} + +void input_SendEventMetaInfo( input_thread_t *p_input ) +{ + var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-info */ + + /* FIXME remove this ugliness */ + vlc_event_t event; + + event.type = vlc_InputItemInfoChanged; + vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); +} + +void input_SendEventMetaName( input_thread_t *p_input, const char *psz_name ) +{ + var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-name */ + + /* FIXME remove this ugliness */ + vlc_event_t event; + + event.type = vlc_InputItemNameChanged; + event.u.input_item_name_changed.new_name = psz_name; + vlc_event_send( &p_input->p->input.p_item->event_manager, &event ); +} + +/***************************************************************************** + * Event for es_out.c + *****************************************************************************/ +void input_SendEventProgramAdd( input_thread_t *p_input, + int i_program, const char *psz_text ) +{ + vlc_value_t val; + vlc_value_t text; + + val.i_int = i_program; + text.psz_string = (char*)psz_text; + + var_Change( p_input, "program", VLC_VAR_ADDCHOICE, + &val, psz_text ? &text : NULL ); + + //var_SetBool( p_input, "intf-change-program", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} +void input_SendEventProgramDel( input_thread_t *p_input, int i_program ) +{ + vlc_value_t val; + + val.i_int = i_program; + var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-program", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} +void input_SendEventProgramSelect( input_thread_t *p_input, int i_program ) +{ + vlc_value_t val; + + val.i_int = i_program; + var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-program", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} + +static const char *GetEsVarName( int i_cat ) +{ + switch( i_cat ) + { + case VIDEO_ES: + return "video-es"; + case AUDIO_ES: + return "audio-es"; + default: + assert( i_cat == SPU_ES ); + return "spu-es"; + } +} +void input_SendEventEsDel( input_thread_t *p_input, int i_cat, int i_id ) +{ + vlc_value_t val; + + if( i_id >= 0 ) + { + val.i_int = i_id; + var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_DELCHOICE, &val, NULL ); + } + else + { + var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_CLEARCHOICES, NULL, NULL ); + } + + //var_SetBool( p_input, "intf-change-es", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} +void input_SendEventEsAdd( input_thread_t *p_input, int i_cat, int i_id, const char *psz_text ) +{ + vlc_value_t val; + vlc_value_t text; + + val.i_int = i_id; + text.psz_string = (char*)psz_text; + + var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_ADDCHOICE, + &val, psz_text ? &text : NULL ); + + //var_SetBool( p_input, "intf-change-es", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); +} + +/* i_id == -1 will unselect */ +void input_SendEventEsSelect( input_thread_t *p_input, int i_cat, int i_id ) +{ + vlc_value_t val; + + val.i_int = i_id; + var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_SETVALUE, &val, NULL ); + + //var_SetBool( p_input, "intf-change-es", true ); /* TODO */ + var_TriggerCallback( p_input, "intf-change" ); + + /* FIXME to remove this ugliness */ + vlc_event_t event; + event.type = vlc_InputSelectedStreamChanged; + vlc_event_send( &p_input->p->event_manager, &event ); +} + diff --git a/src/input/event.h b/src/input/event.h new file mode 100644 index 0000000000..6c4d959119 --- /dev/null +++ b/src/input/event.h @@ -0,0 +1,71 @@ +/***************************************************************************** + * event.h: Input event functions + ***************************************************************************** + * Copyright (C) 2008 Laurent Aimar + * $Id$ + * + * Authors: Laurent Aimar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__) +# error This header file can only be included from LibVLC. +#endif + +#ifndef _INPUT_EVENT_H +#define _INPUT_EVENT_H 1 + +#include + +/***************************************************************************** + * Event for input.c + *****************************************************************************/ +typedef struct +{ + double f_position; + mtime_t i_time; + mtime_t i_length; +} input_event_times_t; + +void input_SendEventTimes( input_thread_t *p_input, const input_event_times_t *p_times ); +void input_SendEventStatistics( input_thread_t *p_input ); +void input_SendEventRate( input_thread_t *p_input, int i_rate ); +void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay ); +void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay ); +void input_SendEventRecord( input_thread_t *p_input, bool b_recording ); +void input_SendEventTitle( input_thread_t *p_input, int i_title ); +void input_SendEventSeekpoint( input_thread_t *p_input, int i_title, int i_seekpoint ); +void input_SendEventSignal( input_thread_t *p_input, double f_quality, double f_strength ); +void input_SendEventState( input_thread_t *p_input, int i_state ); + +/* TODO rename Item* */ +void input_SendEventMeta( input_thread_t *p_input ); +void input_SendEventMetaInfo( input_thread_t *p_input ); +void input_SendEventMetaName( input_thread_t *p_input, const char *psz_name ); + +/***************************************************************************** + * Event for es_out.c + *****************************************************************************/ +void input_SendEventProgramAdd( input_thread_t *p_input, + int i_program, const char *psz_text ); +void input_SendEventProgramDel( input_thread_t *p_input, int i_program ); +void input_SendEventProgramSelect( input_thread_t *p_input, int i_program ); +void input_SendEventEsDel( input_thread_t *p_input, int i_cat, int i_id ); +void input_SendEventEsAdd( input_thread_t *p_input, int i_cat, int i_id, const char *psz_text ); +void input_SendEventEsSelect( input_thread_t *p_input, int i_cat, int i_id ); /* i_id == -1 will unselect */ + +#endif + diff --git a/src/input/input.c b/src/input/input.c index b054373f65..81ea306501 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -36,6 +36,7 @@ #include #include "input_internal.h" +#include "event.h" #include "es_out.h" #include "es_out_timeshift.h" #include "access.h" @@ -76,8 +77,6 @@ static bool Control( input_thread_t *, int, vlc_value_t ); static int UpdateFromAccess( input_thread_t * ); static int UpdateFromDemux( input_thread_t * ); -static void UpdateItemLength( input_thread_t *, int64_t i_length ); - static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *); static input_source_t *InputSourceNew( input_thread_t *); @@ -101,6 +100,8 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced ); +static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */ + /***************************************************************************** * This function creates a new input, and returns a pointer * to its description. On error, it returns NULL. @@ -119,7 +120,7 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for * * Get only: * - length * - bookmarks - * - seekable (if you can seek, it doesn't say if 'bar display' has be shown + * - seekable (if you can seek, it doesn't say if 'bar display' has be shown FIXME rename can-seek * or not, for that check position != 0.0) * - can-pause * - can-record (if a stream can be recorded while playing) @@ -307,6 +308,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, /* Remove 'Now playing' info as it is probably outdated */ input_item_SetNowPlaying( p_item, NULL ); + input_SendEventMeta( p_input ); /* */ if( p_input->b_preparsing ) @@ -667,39 +669,26 @@ static void MainLoopDemux( input_thread_t *p_input, bool *pb_changed, mtime_t *p */ static void MainLoopInterface( input_thread_t *p_input ) { - vlc_value_t val; - double f_pos; - int64_t i_time, i_length; + input_event_times_t ev; + + ev.f_position = 0.0; + ev.i_time = 0; + ev.i_length = 0; /* update input status variables */ - if( !demux_Control( p_input->p->input.p_demux, - DEMUX_GET_POSITION, &f_pos ) ) - { - val.f_float = (float)f_pos; - var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL ); - } - if( !demux_Control( p_input->p->input.p_demux, - DEMUX_GET_TIME, &i_time ) ) - { - p_input->i_time = i_time; - val.i_time = i_time; - var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL ); - } - if( !demux_Control( p_input->p->input.p_demux, - DEMUX_GET_LENGTH, &i_length ) ) - { - vlc_value_t old_val; - var_Get( p_input, "length", &old_val ); - val.i_time = i_length; - var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); + if( demux_Control( p_input->p->input.p_demux, + DEMUX_GET_POSITION, &ev.f_position ) ) + ev.f_position = 0.0; - if( old_val.i_time != val.i_time ) - { - UpdateItemLength( p_input, i_length ); - } - } + if( demux_Control( p_input->p->input.p_demux, + DEMUX_GET_TIME, &ev.i_time ) ) + ev.i_time = 0; + + if( demux_Control( p_input->p->input.p_demux, + DEMUX_GET_LENGTH, &ev.i_length ) ) + ev.i_length = 0; - var_SetBool( p_input, "intf-change", true ); + input_SendEventTimes( p_input, &ev ); } /** @@ -715,7 +704,7 @@ static void MainLoopStatistic( input_thread_t *p_input ) stats_ComputeGlobalStats( p_input->p_libvlc, p_input->p_libvlc->p_stats ); } - var_SetBool( p_input, "stats-change", true ); + input_SendEventStatistics( p_input ); } /** @@ -1159,7 +1148,6 @@ static void InitPrograms( input_thread_t * p_input ) static int Init( input_thread_t * p_input ) { vlc_meta_t *p_meta; - vlc_value_t val; int i, ret; for( i = 0; i < p_input->p->input.p_item->i_options; i++ ) @@ -1202,21 +1190,15 @@ static int Init( input_thread_t * p_input ) /* Load master infos */ /* Init length */ - if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH, - &val.i_time ) && val.i_time > 0 ) - { - var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); - UpdateItemLength( p_input, val.i_time ); - } - else - { - val.i_time = input_item_GetDuration( p_input->p->input.p_item ); - if( val.i_time > 0 ) - { /* fallback: gets length from metadata */ - var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); - UpdateItemLength( p_input, val.i_time ); - } - } + input_event_times_t ev_times; + ev_times.f_position = 0; + ev_times.i_time = 0; + if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH, + &ev_times.i_length ) ) + ev_times.i_length = 0; + if( ev_times.i_length <= 0 ) + ev_times.i_length = input_item_GetDuration( p_input->p->input.p_item ); + input_SendEventTimes( p_input, &ev_times ); StartTitle( p_input ); @@ -1529,7 +1511,7 @@ static void ControlPause( input_thread_t *p_input, mtime_t i_control_date ) } /* Switch to new state */ - input_ChangeStateWithVarCallback( p_input, i_state, false ); + input_ChangeState( p_input, i_state ); } @@ -1556,7 +1538,7 @@ static void ControlUnpause( input_thread_t *p_input, mtime_t i_control_date ) } /* Switch to play */ - input_ChangeStateWithVarCallback( p_input, PLAYING_S, false ); + input_ChangeState( p_input, PLAYING_S ); /* */ if( !i_ret ) @@ -1567,6 +1549,7 @@ static bool Control( input_thread_t *p_input, int i_type, vlc_value_t val ) { const mtime_t i_control_date = mdate(); + /* FIXME b_force_update is abused, it should be carefully checked */ bool b_force_update = false; if( !p_input ) @@ -1703,7 +1686,7 @@ static bool Control( input_thread_t *p_input, int i_type, b_force_update = true; /* Correct "state" value */ - input_ChangeStateWithVarCallback( p_input, p_input->i_state, false ); + input_ChangeState( p_input, p_input->i_state ); } else if( val.i_int != PLAYING_S && val.i_int != PAUSE_S ) { @@ -1830,11 +1813,8 @@ static bool Control( input_thread_t *p_input, int i_type, /* */ if( i_rate != p_input->p->i_rate ) { - val.i_int = i_rate; - var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); - var_SetBool( p_input, "rate-change", true ); - p_input->p->i_rate = i_rate; + input_SendEventRate( p_input, i_rate ); if( p_input->p->input.b_rescale_ts ) { @@ -1867,12 +1847,12 @@ static bool Control( input_thread_t *p_input, int i_type, case INPUT_CONTROL_SET_AUDIO_DELAY: if( !es_out_SetDelay( p_input->p->p_es_out_display, AUDIO_ES, val.i_time ) ) - var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL ); + input_SendEventAudioDelay( p_input, val.i_time ); break; case INPUT_CONTROL_SET_SPU_DELAY: if( !es_out_SetDelay( p_input->p->p_es_out_display, SPU_ES, val.i_time ) ) - var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); + input_SendEventSubtitleDelay( p_input, val.i_time ); break; case INPUT_CONTROL_SET_TITLE: @@ -2087,7 +2067,7 @@ static bool Control( input_thread_t *p_input, int i_type, } p_input->p->b_recording = val.b_bool; - var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL ); + input_SendEventRecord( p_input, val.b_bool ); b_force_update = true; } @@ -2121,24 +2101,47 @@ static bool Control( input_thread_t *p_input, int i_type, /***************************************************************************** * UpdateFromDemux: *****************************************************************************/ +static int UpdateTitleSeekpoint( input_thread_t *p_input, + int i_title, int i_seekpoint ) +{ + int i_title_end = p_input->p->input.i_title_end - + p_input->p->input.i_title_offset; + int i_seekpoint_end = p_input->p->input.i_seekpoint_end - + p_input->p->input.i_seekpoint_offset; + + if( i_title_end >= 0 && i_seekpoint_end >= 0 ) + { + if( i_title > i_title_end || + ( i_title == i_title_end && i_seekpoint > i_seekpoint_end ) ) + return 0; + } + else if( i_seekpoint_end >= 0 ) + { + if( i_seekpoint > i_seekpoint_end ) + return 0; + } + else if( i_title_end >= 0 ) + { + if( i_title > i_title_end ) + return 0; + } + return 1; +} static int UpdateFromDemux( input_thread_t *p_input ) { demux_t *p_demux = p_input->p->input.p_demux; - vlc_value_t v; + /* TODO event-like */ if( p_demux->info.i_update & INPUT_UPDATE_TITLE ) { - v.i_int = p_demux->info.i_title; - var_Change( p_input, "title", VLC_VAR_SETVALUE, &v, NULL ); - - input_ControlVarTitle( p_input, p_demux->info.i_title ); + input_SendEventTitle( p_input, p_demux->info.i_title ); p_demux->info.i_update &= ~INPUT_UPDATE_TITLE; } if( p_demux->info.i_update & INPUT_UPDATE_SEEKPOINT ) { - v.i_int = p_demux->info.i_seekpoint; - var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL); + input_SendEventSeekpoint( p_input, + p_demux->info.i_title, p_demux->info.i_seekpoint ); p_demux->info.i_update &= ~INPUT_UPDATE_SEEKPOINT; } @@ -2146,28 +2149,9 @@ static int UpdateFromDemux( input_thread_t *p_input ) /* Hmmm only works with master input */ if( p_input->p->input.p_demux == p_demux ) - { - int i_title_end = p_input->p->input.i_title_end - - p_input->p->input.i_title_offset; - int i_seekpoint_end = p_input->p->input.i_seekpoint_end - - p_input->p->input.i_seekpoint_offset; - - if( i_title_end >= 0 && i_seekpoint_end >= 0 ) - { - if( p_demux->info.i_title > i_title_end || - ( p_demux->info.i_title == i_title_end && - p_demux->info.i_seekpoint > i_seekpoint_end ) ) return 0; - } - else if( i_seekpoint_end >=0 ) - { - if( p_demux->info.i_seekpoint > i_seekpoint_end ) return 0; - } - else if( i_title_end >= 0 ) - { - if( p_demux->info.i_title > i_title_end ) return 0; - } - } - + return UpdateTitleSeekpoint( p_input, + p_demux->info.i_title, + p_demux->info.i_seekpoint ); return 1; } @@ -2177,14 +2161,10 @@ static int UpdateFromDemux( input_thread_t *p_input ) static int UpdateFromAccess( input_thread_t *p_input ) { access_t *p_access = p_input->p->input.p_access; - vlc_value_t v; if( p_access->info.i_update & INPUT_UPDATE_TITLE ) { - v.i_int = p_access->info.i_title; - var_Change( p_input, "title", VLC_VAR_SETVALUE, &v, NULL ); - - input_ControlVarTitle( p_input, p_access->info.i_title ); + input_SendEventTitle( p_input, p_access->info.i_title ); stream_AccessUpdate( p_input->p->input.p_stream ); @@ -2192,8 +2172,9 @@ static int UpdateFromAccess( input_thread_t *p_input ) } if( p_access->info.i_update & INPUT_UPDATE_SEEKPOINT ) { - v.i_int = p_access->info.i_seekpoint; - var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL); + input_SendEventSeekpoint( p_input, + p_access->info.i_title, p_access->info.i_seekpoint ); + p_access->info.i_update &= ~INPUT_UPDATE_SEEKPOINT; } if( p_access->info.i_update & INPUT_UPDATE_META ) @@ -2212,8 +2193,7 @@ static int UpdateFromAccess( input_thread_t *p_input ) if( access_Control( p_access, ACCESS_GET_SIGNAL, &f_quality, &f_strength ) ) f_quality = f_strength = -1; - var_SetFloat( p_input, "signal-quality", f_quality ); - var_SetFloat( p_input, "signal-strength", f_strength ); + input_SendEventSignal( p_input, f_quality, f_strength ); p_access->info.i_update &= ~INPUT_UPDATE_SIGNAL; } @@ -2222,39 +2202,12 @@ static int UpdateFromAccess( input_thread_t *p_input ) /* Hmmm only works with master input */ if( p_input->p->input.p_access == p_access ) - { - int i_title_end = p_input->p->input.i_title_end - - p_input->p->input.i_title_offset; - int i_seekpoint_end = p_input->p->input.i_seekpoint_end - - p_input->p->input.i_seekpoint_offset; - - if( i_title_end >= 0 && i_seekpoint_end >=0 ) - { - if( p_access->info.i_title > i_title_end || - ( p_access->info.i_title == i_title_end && - p_access->info.i_seekpoint > i_seekpoint_end ) ) return 0; - } - else if( i_seekpoint_end >=0 ) - { - if( p_access->info.i_seekpoint > i_seekpoint_end ) return 0; - } - else if( i_title_end >= 0 ) - { - if( p_access->info.i_title > i_title_end ) return 0; - } - } - + return UpdateTitleSeekpoint( p_input, + p_access->info.i_title, + p_access->info.i_seekpoint ); return 1; } -/***************************************************************************** - * UpdateItemLength: - *****************************************************************************/ -static void UpdateItemLength( input_thread_t *p_input, int64_t i_length ) -{ - input_item_SetDuration( p_input->p->input.p_item, (mtime_t) i_length ); -} - /***************************************************************************** * InputSourceNew: *****************************************************************************/ @@ -2807,7 +2760,6 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta ) input_item_t *p_item = p_input->p->input.p_item; char * psz_arturl = NULL; char *psz_title = NULL; - int i_arturl_event = false; if( !p_meta ) return; @@ -2815,31 +2767,27 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta ) psz_arturl = input_item_GetArtURL( p_item ); vlc_mutex_lock( &p_item->lock ); + if( vlc_meta_Get( p_meta, vlc_meta_Title ) && !p_item->b_fixed_name ) psz_title = strdup( vlc_meta_Get( p_meta, vlc_meta_Title ) ); vlc_meta_Merge( p_item->p_meta, p_meta ); + vlc_meta_Delete( p_meta ); + if( psz_arturl && *psz_arturl ) { vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, psz_arturl ); - i_arturl_event = true; - } - - vlc_meta_Delete( p_meta ); - if( psz_arturl && !strncmp( psz_arturl, "attachment://", strlen("attachment") ) ) - { - /* Don't look for art cover if sout - * XXX It can change when sout has meta data support */ - if( p_input->p->p_sout && !p_input->b_preparsing ) + if( !strncmp( psz_arturl, "attachment://", strlen("attachment") ) ) { - vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, "" ); - i_arturl_event = true; - + /* Don't look for art cover if sout + * XXX It can change when sout has meta data support */ + if( p_input->p->p_sout && !p_input->b_preparsing ) + vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, "" ); + else + input_ExtractAttachmentAndCacheArt( p_input ); } - else - input_ExtractAttachmentAndCacheArt( p_input ); } free( psz_arturl ); @@ -2850,25 +2798,16 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta ) p_meta = vlc_meta_New(); vlc_meta_Merge( p_meta, input_item_GetMetaObject( p_item ) ); } + + if( psz_title ) + input_item_SetName( p_item, psz_title ); + free( psz_title ); + vlc_mutex_unlock( &p_item->lock ); input_item_SetPreparsed( p_item, true ); - if( i_arturl_event == true ) - { - vlc_event_t event; - - /* Notify interested third parties */ - event.type = vlc_InputItemMetaChanged; - event.u.input_item_meta_changed.meta_type = vlc_meta_ArtworkURL; - vlc_event_send( &p_item->event_manager, &event ); - } - - if( psz_title ) - { - input_Control( p_input, INPUT_SET_NAME, psz_title ); - free( psz_title ); - } + input_SendEventMeta( p_input ); /** \todo handle sout meta */ } @@ -2920,7 +2859,6 @@ static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_d bool b_bool; module_t *p_id3; - #if 0 /* XXX I am not sure it is a great idea, besides, there is more than that * if we want to do it right */ @@ -2966,6 +2904,22 @@ static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_d free( p_demux->p_private ); } +static void input_ChangeState( input_thread_t *p_input, int i_state ) +{ + const bool b_changed = p_input->i_state != i_state; + + p_input->i_state = i_state; + if( i_state == ERROR_S ) + p_input->b_error = true; + else if( i_state == END_S ) + p_input->b_eof = true; + + input_item_SetHasErrorWhenReading( p_input->p->input.p_item, (i_state == ERROR_S) ); + + if( b_changed ) + input_SendEventState( p_input, i_state ); +} + /***************************************************************************** * MRLSplit: parse the access, demux and url part of the diff --git a/src/input/input_internal.h b/src/input/input_internal.h index 1c52d715b0..de169305df 100644 --- a/src/input/input_internal.h +++ b/src/input/input_internal.h @@ -332,42 +332,6 @@ void input_ConfigVarInit ( input_thread_t * ); char **subtitles_Detect( input_thread_t *, char* path, const char *fname ); int subtitles_Filter( const char *); -static inline void input_ChangeStateWithVarCallback( input_thread_t *p_input, int i_state, bool callback ) -{ - const bool changed = p_input->i_state != i_state; - - p_input->i_state = i_state; - if( i_state == ERROR_S ) - p_input->b_error = true; - else if( i_state == END_S ) - p_input->b_eof = true; - - input_item_SetHasErrorWhenReading( p_input->p->input.p_item, (i_state == ERROR_S) ); - - if( callback ) - { - var_SetInteger( p_input, "state", i_state ); - } - else - { - vlc_value_t val; - val.i_int = i_state; - var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); - } - if( changed ) - { - vlc_event_t event; - event.type = vlc_InputStateChanged; - event.u.input_state_changed.new_state = i_state; - vlc_event_send( &p_input->p->event_manager, &event ); - } -} - -static inline void input_ChangeState( input_thread_t *p_input, int state ) -{ - input_ChangeStateWithVarCallback( p_input, state, true ); -} - /* Helpers FIXME to export without input_ prefix */ char *input_CreateFilename( vlc_object_t *p_obj, const char *psz_path, const char *psz_prefix, const char *psz_extension ); diff --git a/src/input/item.c b/src/input/item.c index 75477a25e7..482baa0152 100644 --- a/src/input/item.c +++ b/src/input/item.c @@ -312,6 +312,7 @@ bool input_item_IsArtFetched( input_item_t *p_i ) return p_i->p_meta ? p_i->p_meta->i_status & ITEM_ART_FETCHED : false ; } +/* FIXME dangerous, unlocked */ const vlc_meta_t * input_item_GetMetaObject( input_item_t *p_i ) { if( !p_i->p_meta ) @@ -320,6 +321,7 @@ const vlc_meta_t * input_item_GetMetaObject( input_item_t *p_i ) return p_i->p_meta; } +/* FIXME dangerous, unlocked */ void input_item_MetaMerge( input_item_t *p_i, const vlc_meta_t * p_new_meta ) { if( !p_i->p_meta ) @@ -472,8 +474,84 @@ int input_item_AddInfo( input_item_t *p_i, vlc_mutex_unlock( &p_i->lock ); + if( p_info->psz_value ) + { + vlc_event_t event; + + event.type = vlc_InputItemInfoChanged; + vlc_event_send( &p_i->event_manager, &event ); + } return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM; } +int input_item_DelInfo( input_item_t *p_i, + const char *psz_cat, + const char *psz_name ) +{ + info_category_t *p_cat = NULL; + int i_cat; + int i; + + vlc_mutex_lock( &p_i->lock ); + for( i_cat = 0; i_cat < p_i->i_categories; i_cat++ ) + { + if( !strcmp( p_i->pp_categories[i_cat]->psz_name, + psz_cat ) ) + { + p_cat = p_i->pp_categories[i_cat]; + break; + } + } + if( p_cat == NULL ) + { + vlc_mutex_unlock( &p_i->lock ); + return VLC_EGENERIC; + } + + if( psz_name ) + { + /* Remove a specific info */ + for( i = 0; i < p_cat->i_infos; i++ ) + { + if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) ) + { + free( p_cat->pp_infos[i]->psz_name ); + if( p_cat->pp_infos[i]->psz_value ) + free( p_cat->pp_infos[i]->psz_value ); + free( p_cat->pp_infos[i] ); + REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i ); + break; + } + } + if( i >= p_cat->i_infos ) + { + vlc_mutex_unlock( &p_i->lock ); + return VLC_EGENERIC; + } + } + else + { + /* Remove the complete categorie */ + for( i = 0; i < p_cat->i_infos; i++ ) + { + free( p_cat->pp_infos[i]->psz_name ); + if( p_cat->pp_infos[i]->psz_value ) + free( p_cat->pp_infos[i]->psz_value ); + free( p_cat->pp_infos[i] ); + } + if( p_cat->pp_infos ) + free( p_cat->pp_infos ); + REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat ); + } + vlc_mutex_unlock( &p_i->lock ); + + + vlc_event_t event; + event.type = vlc_InputItemInfoChanged; + vlc_event_send( &p_i->event_manager, &event ); + + return VLC_SUCCESS; +} + input_item_t *__input_item_NewExt( vlc_object_t *p_obj, const char *psz_uri, const char *psz_name, diff --git a/src/input/var.c b/src/input/var.c index 04e70d7708..8218d6ad38 100644 --- a/src/input/var.c +++ b/src/input/var.c @@ -232,16 +232,19 @@ void input_ControlVarInit ( input_thread_t *p_input ) * * stats-change to inform when statistics are computed * - * TODO list all changes warn by this callbacks */ - var_Create( p_input, "intf-change", VLC_VAR_BOOL ); - var_SetBool( p_input, "intf-change", true ); - var_Create( p_input, "rate-change", VLC_VAR_BOOL ); - var_SetBool( p_input, "rate-change", true ); - var_Create( p_input, "stats-change", VLC_VAR_BOOL ); - var_SetBool( p_input, "stats-change", true ); - - var_Create( p_input, "intf-change-vout", VLC_VAR_BOOL ); - var_SetBool( p_input, "intf-change-vout", true ); + * TODO list all changes warn by these callbacks */ + static const char *ppsz_event[] = { + "intf-change", + "rate-change", + "stats-change", + "intf-change-vout", + NULL + }; + for( int i = 0; ppsz_event[i] != NULL; i++ ) + { + var_Create( p_input, ppsz_event[i], VLC_VAR_BOOL ); + var_SetBool( p_input, ppsz_event[i], true ); + } } /* Add all callbacks diff --git a/src/libvlccore.sym b/src/libvlccore.sym index dacec71f41..2c3cc310c5 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -167,6 +167,7 @@ input_item_AddOpt input_item_AddOption input_item_AddSubItem input_item_CopyOptions +input_item_DelInfo input_item_GetDuration input_item_GetInfo input_item_GetMeta