static void DelCallback( vlc_object_t *p_this, const char *psz_name, callback_entry_t entry, vlc_callback_type_t i_type ) { int i_entry; variable_t *p_var; #ifndef NDEBUG bool b_found_similar = false; #endif assert( p_this ); vlc_object_internals_t *p_priv = vlc_internals( p_this ); p_var = Lookup( p_this, psz_name ); if( p_var == NULL ) { vlc_mutex_unlock( &p_priv->var_lock ); msg_Err( p_this, "cannot delete callback %p from nonexistent " "variable '%s'", entry.p_callback, psz_name ); return; } WaitUnused( p_this, p_var ); callback_table_t *p_table; if (i_type == vlc_value_callback) p_table = &p_var->value_callbacks; else p_table = &p_var->list_callbacks; for( i_entry = p_table->i_entries ; i_entry-- ; ) { if( p_table->p_entries[i_entry].p_callback == entry.p_callback && p_table->p_entries[i_entry].p_data == entry.p_data ) { break; } #ifndef NDEBUG else if( p_table->p_entries[i_entry].p_callback == entry.p_callback ) b_found_similar = true; #endif } if( i_entry < 0 ) { #ifndef NDEBUG if( b_found_similar ) fprintf( stderr, "Calling var_DelCallback for '%s' with the same " "function but not the same data.", psz_name ); vlc_assert_unreachable(); #endif vlc_mutex_unlock( &p_priv->var_lock ); return; } TAB_ERASE(p_table->i_entries, p_table->p_entries, i_entry); vlc_mutex_unlock( &p_priv->var_lock ); }
/***************************************************************************** * Run: Thread entry-point ****************************************************************************/ static void* Run( void *data ) { services_discovery_t *p_sd = ( services_discovery_t * )data; services_discovery_sys_t *p_sys = p_sd->p_sys; lua_State *L = p_sys->L; int cancel = vlc_savecancel(); lua_getglobal( L, "main" ); if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Err( p_sd, "Error while running script %s, " "function main(): %s", p_sys->psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); vlc_restorecancel( cancel ); return NULL; } msg_Dbg( p_sd, "LuaSD script loaded: %s", p_sys->psz_filename ); /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); /* Main loop to handle search requests */ vlc_mutex_lock( &p_sys->lock ); mutex_cleanup_push( &p_sys->lock ); for( ;; ) { /* Wait for a request */ if( !p_sys->i_query ) { vlc_cond_wait( &p_sys->cond, &p_sys->lock ); continue; } /* Execute one query (protected against cancellation) */ char *psz_query = p_sys->ppsz_query[p_sys->i_query - 1]; TAB_ERASE(p_sys->i_query, p_sys->ppsz_query, p_sys->i_query - 1); vlc_mutex_unlock( &p_sys->lock ); cancel = vlc_savecancel(); DoSearch( p_sd, psz_query ); free( psz_query ); /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); vlc_mutex_lock( &p_sys->lock ); } vlc_cleanup_pop(); vlc_assert_unreachable(); }
static void vlc_epg_Prune( vlc_epg_t *p_dst ) { /* 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 ) { vlc_epg_event_Delete( p_dst->pp_event[0] ); TAB_ERASE( p_dst->i_event, p_dst->pp_event, 0 ); } } }
static void renderer_discovery_item_added( vlc_renderer_discovery_t *rd, vlc_renderer_item_t *p_item ) { libvlc_renderer_discoverer_t *p_lrd = rd->owner.sys; vlc_renderer_item_hold( p_item ); TAB_APPEND( p_lrd->i_items, p_lrd->pp_items, p_item ); libvlc_event_t event = { .type = libvlc_RendererDiscovererItemAdded, .u.renderer_discoverer_item_added.item = (libvlc_renderer_item_t*) p_item, }; libvlc_event_send( &p_lrd->event_manager, &event ); } static void renderer_discovery_item_removed( vlc_renderer_discovery_t *rd, vlc_renderer_item_t *p_item ) { libvlc_renderer_discoverer_t *p_lrd = rd->owner.sys; int i_idx; TAB_FIND( p_lrd->i_items, p_lrd->pp_items, p_item, i_idx ); assert( i_idx != -1 ); TAB_ERASE( p_lrd->i_items, p_lrd->pp_items, i_idx ); libvlc_event_t event = { .type = libvlc_RendererDiscovererItemDeleted, .u.renderer_discoverer_item_deleted.item = (libvlc_renderer_item_t*) p_item, }; libvlc_event_send( &p_lrd->event_manager, &event ); vlc_renderer_item_release( p_item ); } libvlc_renderer_item_t * libvlc_renderer_item_hold(libvlc_renderer_item_t *p_item) { vlc_renderer_item_hold( (vlc_renderer_item_t *) p_item ); return p_item; }
/** * Perform an action on a variable * * \param p_this The object that holds the variable * \param psz_name The name of the variable * \param i_action The action to perform. Must be one of \ref var_action * \param p_val First action parameter * \param p_val2 Second action parameter */ int var_Change( vlc_object_t *p_this, const char *psz_name, int i_action, vlc_value_t *p_val, vlc_value_t *p_val2 ) { int ret = VLC_SUCCESS; variable_t *p_var; vlc_value_t oldval; vlc_value_t newval; assert( p_this ); vlc_object_internals_t *p_priv = vlc_internals( p_this ); p_var = Lookup( p_this, psz_name ); if( p_var == NULL ) { vlc_mutex_unlock( &p_priv->var_lock ); return VLC_ENOVAR; } switch( i_action ) { case VLC_VAR_GETMIN: *p_val = p_var->min; break; case VLC_VAR_GETMAX: *p_val = p_var->max; break; case VLC_VAR_SETMINMAX: assert(p_var->ops->pf_free == FreeDummy); p_var->min = *p_val; p_var->max = *p_val2; break; case VLC_VAR_SETSTEP: assert(p_var->ops->pf_free == FreeDummy); p_var->step = *p_val; CheckValue( p_var, &p_var->val ); break; case VLC_VAR_GETSTEP: switch (p_var->i_type & VLC_VAR_TYPE) { case VLC_VAR_INTEGER: if (p_var->step.i_int == 0) ret = VLC_EGENERIC; break; case VLC_VAR_FLOAT: if (p_var->step.f_float == 0.f) ret = VLC_EGENERIC; break; default: ret = VLC_EGENERIC; } if (ret == VLC_SUCCESS) *p_val = p_var->step; break; case VLC_VAR_ADDCHOICE: { int i = p_var->choices.i_count; TAB_APPEND(p_var->choices.i_count, p_var->choices.p_values, *p_val); assert(i == p_var->choices_text.i_count); TAB_APPEND(p_var->choices_text.i_count, p_var->choices_text.p_values, *p_val); p_var->ops->pf_dup( &p_var->choices.p_values[i] ); p_var->choices_text.p_values[i].psz_string = ( p_val2 && p_val2->psz_string ) ? strdup( p_val2->psz_string ) : NULL; TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_ADDCHOICE, p_val); break; } case VLC_VAR_DELCHOICE: { int i; for( i = 0 ; i < p_var->choices.i_count ; i++ ) if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 ) break; if( i == p_var->choices.i_count ) { /* Not found */ vlc_mutex_unlock( &p_priv->var_lock ); return VLC_EGENERIC; } p_var->ops->pf_free( &p_var->choices.p_values[i] ); free( p_var->choices_text.p_values[i].psz_string ); TAB_ERASE(p_var->choices.i_count, p_var->choices.p_values, i); TAB_ERASE(p_var->choices_text.i_count, p_var->choices_text.p_values, i); TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_DELCHOICE, p_val); break; } case VLC_VAR_CHOICESCOUNT: p_val->i_int = p_var->choices.i_count; break; case VLC_VAR_CLEARCHOICES: for( int i = 0 ; i < p_var->choices.i_count ; i++ ) p_var->ops->pf_free( &p_var->choices.p_values[i] ); for( int i = 0 ; i < p_var->choices_text.i_count ; i++ ) free( p_var->choices_text.p_values[i].psz_string ); if( p_var->choices.i_count ) free( p_var->choices.p_values ); if( p_var->choices_text.i_count ) free( p_var->choices_text.p_values ); p_var->choices.i_count = 0; p_var->choices.p_values = NULL; p_var->choices_text.i_count = 0; p_var->choices_text.p_values = NULL; TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_CLEARCHOICES, NULL); break; case VLC_VAR_SETVALUE: /* Duplicate data if needed */ newval = *p_val; p_var->ops->pf_dup( &newval ); /* Backup needed stuff */ oldval = p_var->val; /* Check boundaries and list */ CheckValue( p_var, &newval ); /* Set the variable */ p_var->val = newval; /* Free data if needed */ p_var->ops->pf_free( &oldval ); break; case VLC_VAR_GETCHOICES: p_val->p_list = xmalloc( sizeof(vlc_list_t) ); p_val->p_list->p_values = xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) ); p_val->p_list->i_type = p_var->i_type; p_val->p_list->i_count = p_var->choices.i_count; if( p_val2 ) { p_val2->p_list = xmalloc( sizeof(vlc_list_t) ); p_val2->p_list->p_values = xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) ); p_val2->p_list->i_type = VLC_VAR_STRING; p_val2->p_list->i_count = p_var->choices.i_count; } for( int i = 0 ; i < p_var->choices.i_count ; i++ ) { p_val->p_list->p_values[i] = p_var->choices.p_values[i]; p_var->ops->pf_dup( &p_val->p_list->p_values[i] ); if( p_val2 ) { p_val2->p_list->p_values[i].psz_string = p_var->choices_text.p_values[i].psz_string ? strdup(p_var->choices_text.p_values[i].psz_string) : NULL; } } break; case VLC_VAR_SETTEXT: free( p_var->psz_text ); if( p_val && p_val->psz_string ) p_var->psz_text = strdup( p_val->psz_string ); else p_var->psz_text = NULL; break; case VLC_VAR_GETTEXT: p_val->psz_string = p_var->psz_text ? strdup( p_var->psz_text ) : NULL; break; default: break; } vlc_mutex_unlock( &p_priv->var_lock ); return ret; }
void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg ) { if( p_src_epg->i_event == 0 ) return; size_t i_dst=0; size_t i_src=0; for( ; i_src < p_src_epg->i_event; i_src++ ) { bool b_current = ( p_src_epg->pp_event[i_src] == p_src_epg->p_current ); vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] ); if( unlikely(!p_src) ) return; const int64_t i_src_end = p_src->i_start + p_src->i_duration; while( i_dst < p_dst_epg->i_event ) { vlc_epg_event_t *p_dst = p_dst_epg->pp_event[i_dst]; const int64_t i_dst_end = p_dst->i_start + p_dst->i_duration; /* appended is before current, no overlap */ if( p_dst->i_start >= i_src_end ) { break; } /* overlap case: appended would contain current's start (or are identical) */ else if( ( p_dst->i_start >= p_src->i_start && p_dst->i_start < i_src_end ) || /* overlap case: appended would contain current's end */ ( i_dst_end > p_src->i_start && i_dst_end <= i_src_end ) ) { vlc_epg_event_Delete( p_dst ); if( p_dst_epg->p_current == p_dst ) { b_current |= true; p_dst_epg->p_current = NULL; } TAB_ERASE( p_dst_epg->i_event, p_dst_epg->pp_event, i_dst ); } else { i_dst++; } } TAB_INSERT( p_dst_epg->i_event, p_dst_epg->pp_event, p_src, i_dst ); if( b_current ) p_dst_epg->p_current = p_src; } /* Remaining/trailing ones */ for( ; i_src < p_src_epg->i_event; i_src++ ) { vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] ); if( unlikely(!p_src) ) return; TAB_APPEND( p_dst_epg->i_event, p_dst_epg->pp_event, p_src ); if( p_src_epg->pp_event[i_src] == p_src_epg->p_current ) p_dst_epg->p_current = p_src; } vlc_epg_Prune( p_dst_epg ); }