static int MarshalMetadata( intf_thread_t *p_intf, DBusMessageIter *container ) { DBusMessageIter a; input_thread_t *p_input = pl_CurrentInput( p_intf ); input_item_t *p_item = NULL; if( p_input != NULL ) { p_item = input_GetItem( p_input ); if( p_item ) { int result = GetInputMeta( p_item, container ); if (result != VLC_SUCCESS) { vlc_object_release( (vlc_object_t*) p_input ); return result; } } vlc_object_release( (vlc_object_t*) p_input ); } if (!p_item) { // avoid breaking the type marshalling if( !dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "{sv}", &a ) || !dbus_message_iter_close_container( container, &a ) ) return VLC_ENOMEM; } return VLC_SUCCESS; }
/***************************************************************************** * Close: destroy interface stuff *****************************************************************************/ static void Close(vlc_object_t *p_this) { intf_thread_t *p_intf = (intf_thread_t*) p_this; intf_sys_t *p_sys = p_intf->p_sys; var_DelCallback(pl_Get(p_intf), "activity", ItemChange, p_intf); vlc_cancel(p_sys->thread); vlc_join(p_sys->thread, NULL); input_thread_t *p_input = pl_CurrentInput(p_intf); if (p_input) { if (p_sys->b_state_cb) var_DelCallback(p_input, "intf-event", PlayingChange, p_intf); vlc_object_release(p_input); } int i; for (i = 0; i < p_sys->i_songs; i++) DeleteSong(&p_sys->p_queue[i]); vlc_UrlClean(&p_sys->p_submit_url); #if 0 //NOT USED free(p_sys->psz_nowp_host); free(p_sys->psz_nowp_file); #endif vlc_cond_destroy(&p_sys->wait); vlc_mutex_destroy(&p_sys->lock); free(p_sys); }
static int MarshalPlaybackStatus( intf_thread_t *p_intf, DBusMessageIter *container ) { input_thread_t *p_input = pl_CurrentInput( p_intf ); const char *psz_playback_status; if( p_input != NULL ) { switch( var_GetInteger( p_input, "state" ) ) { case OPENING_S: case PLAYING_S: psz_playback_status = PLAYBACK_STATUS_PLAYING; break; case PAUSE_S: psz_playback_status = PLAYBACK_STATUS_PAUSED; break; default: psz_playback_status = PLAYBACK_STATUS_STOPPED; } vlc_object_release( (vlc_object_t*) p_input ); } else psz_playback_status = PLAYBACK_STATUS_STOPPED; if( !dbus_message_iter_append_basic( container, DBUS_TYPE_STRING, &psz_playback_status ) ) return VLC_ENOMEM; return VLC_SUCCESS; }
/***************************************************************************** * ItemChange: Playlist item change callback *****************************************************************************/ static int ItemChange(vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data) { intf_thread_t *p_intf = (intf_thread_t*) p_data; intf_sys_t *p_sys = p_intf->p_sys; VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(oldval); VLC_UNUSED(newval); p_sys->b_state_cb = false; p_sys->b_meta_read = false; p_sys->b_submit = false; input_thread_t *p_input = pl_CurrentInput(p_intf); if (!p_input || p_input->b_dead) return VLC_SUCCESS; input_item_t *p_item = input_GetItem(p_input); if (!p_item) { vlc_object_release(p_input); return VLC_SUCCESS; } if (var_CountChoices(p_input, "video-es")) { msg_Dbg(p_this, "Not an audio-only input, not submitting"); vlc_object_release(p_input); return VLC_SUCCESS; } p_sys->time_total_pauses = 0; time(&p_sys->p_current_song.date); /* to be sent to last.fm */ p_sys->p_current_song.i_start = mdate(); /* only used locally */ var_AddCallback(p_input, "intf-event", PlayingChange, p_intf); p_sys->b_state_cb = true; if (input_item_IsPreparsed(p_item)) ReadMetaData(p_intf); /* if the input item was not preparsed, we'll do it in PlayingChange() * callback, when "state" == PLAYING_S */ vlc_object_release(p_input); return VLC_SUCCESS; }
static int MarshalCanSeek( intf_thread_t *p_intf, DBusMessageIter *container ) { dbus_bool_t b_can_seek = FALSE; input_thread_t *p_input = pl_CurrentInput( p_intf ); if( p_input ) { b_can_seek = var_GetBool( p_input, "can-seek" ); vlc_object_release( p_input ); } if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_can_seek ) ) return VLC_ENOMEM; return VLC_SUCCESS; }
/***************************************************************************** * TrackChange: callback on playlist "input-current" *****************************************************************************/ static int TrackChange( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; input_thread_t *p_input = NULL; input_item_t *p_item = NULL; if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; if( p_sys->p_input ) { var_DelCallback( p_sys->p_input, "intf-event", InputCallback, p_intf ); var_DelCallback( p_sys->p_input, "can-pause", AllCallback, p_intf ); var_DelCallback( p_sys->p_input, "can-seek", AllCallback, p_intf ); vlc_object_release( p_sys->p_input ); p_sys->p_input = NULL; } p_sys->b_meta_read = false; p_input = pl_CurrentInput( p_intf ); if( !p_input ) { return VLC_SUCCESS; } p_item = input_GetItem( p_input ); if( !p_item ) { vlc_object_release( p_input ); return VLC_EGENERIC; } if( input_item_IsPreparsed( p_item ) ) p_sys->b_meta_read = true; p_sys->p_input = p_input; var_AddCallback( p_input, "intf-event", InputCallback, p_intf ); var_AddCallback( p_input, "can-pause", AllCallback, p_intf ); var_AddCallback( p_input, "can-seek", AllCallback, p_intf ); return VLC_SUCCESS; }
static int MarshalRate( intf_thread_t *p_intf, DBusMessageIter *container ) { double d_rate; input_thread_t *p_input = pl_CurrentInput( p_intf ); if( p_input != NULL ) { d_rate = var_GetFloat( p_input, "rate" ); vlc_object_release( (vlc_object_t*) p_input ); } else d_rate = 1.0; if( !dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_rate ) ) return VLC_ENOMEM; return VLC_SUCCESS; }
static int MarshalPosition( intf_thread_t *p_intf, DBusMessageIter *container ) { /* returns position in microseconds */ dbus_int64_t i_pos; input_thread_t *p_input = pl_CurrentInput( p_intf ); if( !p_input ) i_pos = 0; else { i_pos = var_GetInteger( p_input, "time" ); vlc_object_release( p_input ); } if( !dbus_message_iter_append_basic( container, DBUS_TYPE_INT64, &i_pos ) ) return VLC_ENOMEM; return VLC_SUCCESS; }
/***************************************************************************** * ReadMetaData : Read meta data when parsed by vlc *****************************************************************************/ static void ReadMetaData(intf_thread_t *p_this) { intf_sys_t *p_sys = p_this->p_sys; input_thread_t *p_input = pl_CurrentInput(p_this); if (!p_input) return; input_item_t *p_item = input_GetItem(p_input); if (!p_item) { vlc_object_release(p_input); return; } #define ALLOC_ITEM_META(a, b) do { \ char *psz_meta = input_item_Get##b(p_item); \ if (psz_meta && *psz_meta) \ a = encode_URI_component(psz_meta); \ free(psz_meta); \ } while (0) vlc_mutex_lock(&p_sys->lock); p_sys->b_meta_read = true; ALLOC_ITEM_META(p_sys->p_current_song.psz_a, Artist); if (!p_sys->p_current_song.psz_a) { msg_Dbg(p_this, "No artist.."); DeleteSong(&p_sys->p_current_song); goto end; } ALLOC_ITEM_META(p_sys->p_current_song.psz_t, Title); if (!p_sys->p_current_song.psz_t) { msg_Dbg(p_this, "No track name.."); DeleteSong(&p_sys->p_current_song); goto end; } /* Now we have read the mandatory meta data, so we can submit that info */ p_sys->b_submit = true; ALLOC_ITEM_META(p_sys->p_current_song.psz_b, Album); if (!p_sys->p_current_song.psz_b) p_sys->p_current_song.psz_b = calloc(1, 1); ALLOC_ITEM_META(p_sys->p_current_song.psz_m, TrackID); if (!p_sys->p_current_song.psz_m) p_sys->p_current_song.psz_m = calloc(1, 1); p_sys->p_current_song.i_l = input_item_GetDuration(p_item) / 1000000; ALLOC_ITEM_META(p_sys->p_current_song.psz_n, TrackNum); if (!p_sys->p_current_song.psz_n) p_sys->p_current_song.psz_n = calloc(1, 1); #undef ALLOC_ITEM_META msg_Dbg(p_this, "Meta data registered"); end: vlc_mutex_unlock(&p_sys->lock); vlc_object_release(p_input); }
/** * ProcessEvents() reacts to a list of events originating from other VLC threads * * This function must be called with p_sys->lock unlocked * * @param intf_thread_t *p_intf This interface thread state * @param callback_info_t *p_events the list of events to process */ static void ProcessEvents( intf_thread_t *p_intf, callback_info_t **p_events, int i_events ) { bool b_can_play = p_intf->p_sys->b_can_play; vlc_dictionary_t player_properties, tracklist_properties, root_properties; vlc_dictionary_init( &player_properties, 0 ); vlc_dictionary_init( &tracklist_properties, 0 ); vlc_dictionary_init( &root_properties, 0 ); for( int i = 0; i < i_events; i++ ) { switch( p_events[i]->signal ) { case SIGNAL_ITEM_CURRENT: TrackChange( p_intf ); // rate depends on current item if( !vlc_dictionary_has_key( &player_properties, "Rate" ) ) vlc_dictionary_insert( &player_properties, "Rate", NULL ); vlc_dictionary_insert( &player_properties, "Metadata", NULL ); break; case SIGNAL_PLAYLIST_ITEM_APPEND: case SIGNAL_PLAYLIST_ITEM_DELETED: { playlist_t *p_playlist = p_intf->p_sys->p_playlist; PL_LOCK; b_can_play = playlist_CurrentSize( p_playlist ) > 0; PL_UNLOCK; if( b_can_play != p_intf->p_sys->b_can_play ) { p_intf->p_sys->b_can_play = b_can_play; vlc_dictionary_insert( &player_properties, "CanPlay", NULL ); } if( !vlc_dictionary_has_key( &tracklist_properties, "Tracks" ) ) vlc_dictionary_insert( &tracklist_properties, "Tracks", NULL ); break; } case SIGNAL_VOLUME_MUTED: case SIGNAL_VOLUME_CHANGE: vlc_dictionary_insert( &player_properties, "Volume", NULL ); break; case SIGNAL_RANDOM: vlc_dictionary_insert( &player_properties, "Shuffle", NULL ); break; case SIGNAL_FULLSCREEN: vlc_dictionary_insert( &root_properties, "Fullscreen", NULL ); break; case SIGNAL_REPEAT: case SIGNAL_LOOP: vlc_dictionary_insert( &player_properties, "LoopStatus", NULL ); break; case SIGNAL_STATE: vlc_dictionary_insert( &player_properties, "PlaybackStatus", NULL ); break; case SIGNAL_RATE: vlc_dictionary_insert( &player_properties, "Rate", NULL ); break; case SIGNAL_INPUT_METADATA: { input_thread_t *p_input = pl_CurrentInput( p_intf ); input_item_t *p_item; if( p_input ) { p_item = input_GetItem( p_input ); vlc_object_release( p_input ); if( p_item ) vlc_dictionary_insert( &player_properties, "Metadata", NULL ); } break; } case SIGNAL_CAN_SEEK: vlc_dictionary_insert( &player_properties, "CanSeek", NULL ); break; case SIGNAL_CAN_PAUSE: vlc_dictionary_insert( &player_properties, "CanPause", NULL ); break; case SIGNAL_SEEK: SeekedEmit( p_intf ); break; default: vlc_assert_unreachable(); } free( p_events[i] ); } if( vlc_dictionary_keys_count( &player_properties ) ) PlayerPropertiesChangedEmit( p_intf, &player_properties ); if( vlc_dictionary_keys_count( &tracklist_properties ) ) TrackListPropertiesChangedEmit( p_intf, &tracklist_properties ); if( vlc_dictionary_keys_count( &root_properties ) ) RootPropertiesChangedEmit( p_intf, &root_properties ); vlc_dictionary_clear( &player_properties, NULL, NULL ); vlc_dictionary_clear( &tracklist_properties, NULL, NULL ); vlc_dictionary_clear( &root_properties, NULL, NULL ); }
static void *RunIntf( void *data ) { intf_thread_t *p_intf = data; int i_oldx = 0; for( ;; ) { const char *psz_type; bool b_change = false; /* Wait a bit, get orientation, change filter if necessary */ #warning FIXME: check once (or less) per picture, not once per interval vlc_tick_sleep( INTF_IDLE_SLEEP ); int canc = vlc_savecancel(); int i_x = motion_get_angle( p_intf->p_sys->p_motion ); if( i_x < -HIGH_THRESHOLD && i_oldx > -LOW_THRESHOLD ) { b_change = true; psz_type = "90"; } else if( ( i_x > -LOW_THRESHOLD && i_oldx < -HIGH_THRESHOLD ) || ( i_x < LOW_THRESHOLD && i_oldx > HIGH_THRESHOLD ) ) { b_change = true; psz_type = NULL; } else if( i_x > HIGH_THRESHOLD && i_oldx < LOW_THRESHOLD ) { b_change = true; psz_type = "270"; } if( b_change ) { #warning FIXME: refactor this plugin as a video filter! input_thread_t *p_input = pl_CurrentInput( p_intf ); if( p_input ) { vout_thread_t *p_vout; p_vout = input_GetVout( p_input ); if( p_vout ) { if( psz_type != NULL ) { var_Create( p_vout, "transform-type", VLC_VAR_STRING ); var_SetString( p_vout, "transform-type", psz_type ); } else var_Destroy( p_vout, "transform-type" ); var_SetString( p_vout, "video-filter", psz_type != NULL ? "transform" : "" ); vlc_object_release( p_vout ); } vlc_object_release( p_input ); i_oldx = i_x; } } vlc_restorecancel( canc ); } vlc_assert_unreachable(); }