/***************************************************************************** * End: terminate logo video thread output method *****************************************************************************/ static void End( vout_thread_t *p_vout ) { vout_sys_t *p_sys = p_vout->p_sys; int i_index; /* Free the fake output buffers we allocated */ for( i_index = I_OUTPUTPICTURES ; i_index ; ) { i_index--; free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); } var_DelCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout); var_DelCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout); if( p_sys->p_vout ) { DEL_CALLBACKS( p_sys->p_vout, SendEvents ); vlc_object_detach( p_sys->p_vout ); vout_Destroy( p_sys->p_vout ); } if( p_sys->p_blend->p_module ) module_Unneed( p_sys->p_blend, p_sys->p_blend->p_module ); vlc_object_detach( p_sys->p_blend ); vlc_object_destroy( p_sys->p_blend ); }
/***************************************************************************** * Open: open a scope effect plugin *****************************************************************************/ static int Open( vlc_object_t *p_this ) { aout_filter_t *p_filter = (aout_filter_t *)p_this; aout_filter_sys_t *p_sys; galaktos_thread_t *p_thread; if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' ) || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') ) { msg_Warn( p_filter, "bad input or output format" ); return VLC_EGENERIC; } if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) { msg_Warn( p_filter, "input and output formats are not similar" ); return VLC_EGENERIC; } p_filter->pf_do_work = DoWork; p_filter->b_in_place = 1; /* Allocate structure */ p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) ); /* Create galaktos thread */ p_sys->p_thread = p_thread = vlc_object_create( p_filter, sizeof( galaktos_thread_t ) ); vlc_object_attach( p_thread, p_this ); /* var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "galaktos-width", &width ); var_Create( p_thread, "galaktos-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "galaktos-height", &height ); */ p_thread->i_cur_sample = 0; bzero( p_thread->p_data, 2*2*512 ); p_thread->i_width = 600; p_thread->i_height = 600; p_thread->b_fullscreen = 0; galaktos_init( p_thread ); p_thread->i_channels = aout_FormatNbChannels( &p_filter->input ); p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) ); if( vlc_thread_create( p_thread, "galaktos update thread", Thread, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) { msg_Err( p_filter, "cannot lauch galaktos thread" ); if( p_thread->psz_title ) free( p_thread->psz_title ); vlc_object_detach( p_thread ); vlc_object_destroy( p_thread ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * FindFilter: find an audio filter for a specific transformation *****************************************************************************/ static aout_filter_t * FindFilter( aout_instance_t * p_aout, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) { aout_filter_t * p_filter = vlc_object_create( p_aout, sizeof(aout_filter_t) ); if ( p_filter == NULL ) return NULL; vlc_object_attach( p_filter, p_aout ); memcpy( &p_filter->input, p_input_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->output, p_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_Need( p_filter, "audio filter", NULL, 0 ); if ( p_filter->p_module == NULL ) { vlc_object_detach( p_filter ); vlc_object_destroy( p_filter ); return NULL; } p_filter->b_continuity = VLC_FALSE; return p_filter; }
/***************************************************************************** * CloseVideo: destroy Sys video thread output method ***************************************************************************** * Terminate an output method created by Open *****************************************************************************/ static void Close ( vlc_object_t *p_this ) { vout_thread_t * p_vout = (vout_thread_t *)p_this; msg_Dbg( p_vout, "close" ); if( p_vout->p_sys->p_event ) { vlc_object_detach( p_vout->p_sys->p_event ); /* Kill RunQtThread */ vlc_object_kill( p_vout->p_sys->p_event ); CloseDisplay(p_vout); vlc_thread_join( p_vout->p_sys->p_event ); vlc_object_release( p_vout->p_sys->p_event ); } #ifdef NEED_QTE_MAIN msg_Dbg( p_vout, "releasing gui-helper" ); module_unneed( p_vout, p_vout->p_sys->p_qte_main ); #endif if( p_vout->p_sys ) { free( p_vout->p_sys ); p_vout->p_sys = NULL; } }
/***************************************************************************** * Close: close the plugin *****************************************************************************/ static void Close( vlc_object_t *p_this ) { aout_filter_t *p_filter = (aout_filter_t *)p_this; aout_filter_sys_t *p_sys = p_filter->p_sys; /* Stop Goom Thread */ p_sys->p_thread->b_die = VLC_TRUE; vlc_mutex_lock( &p_sys->p_thread->lock ); vlc_cond_signal( &p_sys->p_thread->wait ); vlc_mutex_unlock( &p_sys->p_thread->lock ); vlc_thread_join( p_sys->p_thread ); /* Free data */ vout_Request( p_filter, p_sys->p_thread->p_vout, 0, 0, 0, 0 ); vlc_mutex_destroy( &p_sys->p_thread->lock ); vlc_cond_destroy( &p_sys->p_thread->wait ); vlc_object_detach( p_sys->p_thread ); while( p_sys->p_thread->i_blocks-- ) { block_Release( p_sys->p_thread->pp_blocks[p_sys->p_thread->i_blocks] ); } vlc_object_destroy( p_sys->p_thread ); free( p_sys ); }
static int AddIntfCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ) { intf_thread_t *p_intf; char *psz_intf = malloc( strlen(newval.psz_string) + sizeof(",none") ); (void)psz_cmd; (void)oldval; (void)p_data; /* Try to create the interface */ sprintf( psz_intf, "%s,none", newval.psz_string ); p_intf = intf_Create( p_this->p_libvlc, psz_intf ); free( psz_intf ); if( p_intf == NULL ) { msg_Err( p_this, "interface \"%s\" initialization failed", newval.psz_string ); return VLC_EGENERIC; } /* Try to run the interface */ if( intf_RunThread( p_intf ) != VLC_SUCCESS ) { vlc_object_detach( p_intf ); vlc_object_release( p_intf ); return VLC_EGENERIC; } return VLC_SUCCESS; }
void filter_DeleteBlend( filter_t *p_blend ) { if( p_blend->p_module ) module_unneed( p_blend, p_blend->p_module ); vlc_object_detach( p_blend ); vlc_object_release( p_blend ); }
/** * Releases data allocated with tls_ClientCreate. * It is your job to close the underlying socket. */ void tls_ClientDelete (tls_session_t *cl) { if (cl == NULL) return; module_unneed (cl, cl->p_module); vlc_object_detach (cl); vlc_object_release (cl); }
/** * Releases data allocated with tls_ServerCreate. * @param srv TLS server object to be destroyed, or NULL */ void tls_ServerDelete (tls_server_t *srv) { if (srv == NULL) return; module_unneed (srv, srv->p_module); vlc_object_detach (srv); vlc_object_release (srv); }
int libvlc_video_destroy( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e ) { vout_thread_t *p_vout = GetVout( p_mi, p_e ); vlc_object_detach( p_vout ); vlc_object_release( p_vout ); vlc_object_release( p_vout ); return 0; }
void video_splitter_Delete( video_splitter_t *p_splitter ) { if( p_splitter->p_module ) module_unneed( p_splitter, p_splitter->p_module ); video_format_Clean( &p_splitter->fmt ); vlc_object_detach( p_splitter ); vlc_object_release( p_splitter ); }
/*********************************************************************** * Destroy ***********************************************************************/ void services_discovery_Destroy ( services_discovery_t * p_sd ) { vlc_event_manager_fini( &p_sd->event_manager ); free( p_sd->psz_module ); free( p_sd->psz_localized_name ); vlc_object_detach( p_sd ); vlc_object_release( p_sd ); }
/***************************************************************************** * RemoveAllVout: destroy all the child video output threads *****************************************************************************/ static void RemoveAllVout( vout_thread_t *p_vout ) { while( p_vout->p_sys->i_clones ) { --p_vout->p_sys->i_clones; DEL_CALLBACKS( p_vout->p_sys->pp_vout[p_vout->p_sys->i_clones], SendEvents ); vlc_object_detach( p_vout->p_sys->pp_vout[p_vout->p_sys->i_clones] ); vout_Destroy( p_vout->p_sys->pp_vout[p_vout->p_sys->i_clones] ); } }
/***************************************************************************** * aout_FiltersDestroyPipeline: deallocate a filters pipeline *****************************************************************************/ void aout_FiltersDestroyPipeline( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int i_nb_filters ) { int i; for ( i = 0; i < i_nb_filters; i++ ) { module_Unneed( pp_filters[i], pp_filters[i]->p_module ); vlc_object_detach( pp_filters[i] ); vlc_object_destroy( pp_filters[i] ); } }
void vout_window_Delete(vout_window_t *window) { if (!window) return; window_t *w = (window_t *)window; if (w->inhibit) vlc_inhibit_Destroy (w->inhibit); vlc_object_detach(window); module_unneed(window, w->module); vlc_object_release(window); }
/***************************************************************************** * Destroy: destroy Transform video thread output method ***************************************************************************** * Terminate an output method created by TransformCreateOutputMethod *****************************************************************************/ static void Destroy( vlc_object_t *p_this ) { vout_thread_t *p_vout = (vout_thread_t *)p_this; if( p_vout->p_sys->p_vout ) { DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vlc_object_detach( p_vout->p_sys->p_vout ); vout_Destroy( p_vout->p_sys->p_vout ); } DEL_PARENT_CALLBACKS( SendEventsToChild ); free( p_vout->p_sys ); }
Dialogs::~Dialogs() { if( m_pProvider && m_pModule ) { // Detach the dialogs provider from its parent interface vlc_object_detach( m_pProvider ); module_unneed( m_pProvider, m_pModule ); vlc_object_release( m_pProvider ); } /* Unregister callbacks */ var_DelCallback( getIntf()->p_libvlc, "intf-popupmenu", PopupMenuCB, this ); }
vout_window_t *vout_window_New(vlc_object_t *obj, const char *module, const vout_window_cfg_t *cfg) { static char const name[] = "window"; window_t *w = vlc_custom_create(obj, sizeof(*w), VLC_OBJECT_GENERIC, name); vout_window_t *window = &w->wnd; window->cfg = cfg; memset(&window->handle, 0, sizeof(window->handle)); window->control = NULL; window->sys = NULL; vlc_object_attach(window, obj); const char *type; switch (cfg->type) { case VOUT_WINDOW_TYPE_HWND: type = "vout window hwnd"; break; case VOUT_WINDOW_TYPE_XID: type = "vout window xid"; break; default: assert(0); } w->module = module_need(window, type, module, module && *module != '\0'); if (!w->module) { vlc_object_detach(window); vlc_object_release(window); return NULL; } /* Hook for screensaver inhibition */ if (cfg->type == VOUT_WINDOW_TYPE_XID) { w->inhibit = vlc_inhibit_Create (VLC_OBJECT (window), window->handle.xid); if (w->inhibit != NULL) vlc_inhibit_Set (w->inhibit, true); /* FIXME: ^ wait for vout activation, pause */ } else w->inhibit = NULL; return window; }
/***************************************************************************** * RemoveAllVout: destroy all the child video output threads *****************************************************************************/ static void RemoveAllVout( vout_thread_t *p_vout ) { while( p_vout->p_sys->i_vout ) { --p_vout->p_sys->i_vout; if( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].b_active ) { DEL_CALLBACKS( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout, SendEvents ); vlc_object_detach( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout ); vout_Destroy( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout ); } } }
/***************************************************************************** * Close: close the plugin *****************************************************************************/ static void Close( vlc_object_t *p_this ) { aout_filter_t *p_filter = (aout_filter_t *)p_this; aout_filter_sys_t *p_sys = p_filter->p_sys; /* Stop galaktos Thread */ p_sys->p_thread->b_die = VLC_TRUE; galaktos_done( p_sys->p_thread ); vlc_thread_join( p_sys->p_thread ); /* Free data */ vlc_object_detach( p_sys->p_thread ); vlc_object_destroy( p_sys->p_thread ); free( p_sys ); }
static int Intf( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ) { intf_thread_t *p_newintf; p_newintf = intf_Create( p_this->p_vlc, newval.psz_string ); if( p_newintf ) { p_newintf->b_block = VLC_FALSE; if( intf_RunThread( p_newintf ) ) { vlc_object_detach( p_newintf ); intf_Destroy( p_newintf ); } } return VLC_SUCCESS; }
static int filter_chain_DeleteFilterInternal( filter_chain_t *p_chain, filter_t *p_filter ) { chained_filter_t *p_chained = chained( p_filter ); /* Remove it from the chain */ if( p_chained->prev != NULL ) p_chained->prev->next = p_chained->next; else { assert( p_chained == p_chain->first ); p_chain->first = p_chained->next; } if( p_chained->next != NULL ) p_chained->next->prev = p_chained->prev; else { assert( p_chained == p_chain->last ); p_chain->last = p_chained->prev; } p_chain->length--; msg_Dbg( p_chain->p_this, "Filter %p removed from chain", p_filter ); /* Destroy the filter object */ if( IsInternalVideoAllocator( p_chained ) ) AllocatorClean( &internal_video_allocator, p_chained ); else AllocatorClean( &p_chain->allocator, p_chained ); vlc_object_detach( p_filter ); if( p_filter->p_module ) module_unneed( p_filter, p_filter->p_module ); free( p_chained->mouse ); vlc_object_release( p_filter ); /* FIXME: check fmt_in/fmt_out consitency */ return VLC_SUCCESS; }
static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type, mtime_t destroy_date ) { vlc_object_t *p_obj; if( destroy_date > mdate() ) return destroy_date; if( destroy_date == 0 ) { /* give a little time */ return mdate() + I64C(1000000); } else { while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) ) { if( p_obj->p_parent != (vlc_object_t*)p_playlist ) { /* only first child (ie unused) */ vlc_object_release( p_obj ); break; } if( i_type == VLC_OBJECT_VOUT ) { msg_Dbg( p_playlist, "garbage collector destroying 1 vout" ); vlc_object_detach( p_obj ); vlc_object_release( p_obj ); vout_Destroy( (vout_thread_t *)p_obj ); } else if( i_type == VLC_OBJECT_SOUT ) { vlc_object_release( p_obj ); sout_DeleteInstance( (sout_instance_t*)p_obj ); } } return 0; } }
/***************************************************************************** * CloseDecoder: clean up the decoder *****************************************************************************/ static void CloseDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys = p_dec->p_sys; intf_thread_t *p_intf; /* Destroy the interface object/thread */ p_intf = vlc_object_find( p_dec, VLC_OBJECT_INTF, FIND_CHILD ); if( p_intf != NULL ) { #ifdef CMML_DEBUG msg_Dbg( p_dec, "CMML decoder is freeing interface thread" ); #endif intf_StopThread( p_intf ); vlc_object_detach( p_intf ); vlc_object_release( p_intf ); intf_Destroy( p_intf ); } p_sys->p_intf = NULL; free( p_sys ); }
/** * Starts and runs the interface thread. * * \param p_intf the interface thread * \return VLC_SUCCESS on success, an error number else */ int intf_RunThread( intf_thread_t *p_intf ) { #if defined( __APPLE__ ) || defined( WIN32 ) /* Hack to get Mac OS X Cocoa runtime running * (it needs access to the main thread) */ if( p_intf->b_should_run_on_first_thread ) { if( vlc_thread_create( p_intf, "interface", MonitorLibVLCDeath, VLC_THREAD_PRIORITY_LOW, false ) ) { msg_Err( p_intf, "cannot spawn libvlc death monitoring thread" ); return VLC_EGENERIC; } RunInterface( VLC_OBJECT(p_intf) ); /* Make sure our MonitorLibVLCDeath thread exit */ vlc_object_kill( p_intf ); /* It is monitoring libvlc, not the p_intf */ vlc_object_signal( p_intf->p_libvlc ); vlc_thread_join( p_intf ); vlc_object_detach( p_intf ); vlc_object_release( p_intf ); return VLC_SUCCESS; } #endif /* Run the interface in a separate thread */ if( vlc_thread_create( p_intf, "interface", RunInterface, VLC_THREAD_PRIORITY_LOW, false ) ) { msg_Err( p_intf, "cannot spawn interface thread" ); return VLC_EGENERIC; } return VLC_SUCCESS; }
/* Helpers */ static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *p_chain, const char *psz_name, config_chain_t *p_cfg, const es_format_t *p_fmt_in, const es_format_t *p_fmt_out ) { chained_filter_t *p_chained = vlc_custom_create( p_chain->p_this, sizeof(*p_chained), VLC_OBJECT_GENERIC, "filter" ); filter_t *p_filter = &p_chained->filter; if( !p_filter ) return NULL; vlc_object_attach( p_filter, p_chain->p_this ); if( !p_fmt_in ) { if( p_chain->last != NULL ) p_fmt_in = &p_chain->last->filter.fmt_out; else p_fmt_in = &p_chain->fmt_in; } if( !p_fmt_out ) { p_fmt_out = &p_chain->fmt_out; } es_format_Copy( &p_filter->fmt_in, p_fmt_in ); es_format_Copy( &p_filter->fmt_out, p_fmt_out ); p_filter->p_cfg = p_cfg; p_filter->b_allow_fmt_out_change = p_chain->b_allow_fmt_out_change; p_filter->p_module = module_need( p_filter, p_chain->psz_capability, psz_name, psz_name != NULL ); if( !p_filter->p_module ) goto error; if( p_filter->b_allow_fmt_out_change ) { es_format_Clean( &p_chain->fmt_out ); es_format_Copy( &p_chain->fmt_out, &p_filter->fmt_out ); } if( AllocatorInit( &p_chain->allocator, p_chained ) ) goto error; if( p_chain->last == NULL ) { assert( p_chain->first == NULL ); p_chain->first = p_chained; } else p_chain->last->next = p_chained; p_chained->prev = p_chain->last; p_chain->last = p_chained; p_chained->next = NULL; p_chain->length++; vlc_mouse_t *p_mouse = malloc( sizeof(*p_mouse) ); if( p_mouse ) vlc_mouse_Init( p_mouse ); p_chained->mouse = p_mouse; msg_Dbg( p_chain->p_this, "Filter '%s' (%p) appended to chain", psz_name ? psz_name : module_get_name(p_filter->p_module, false), p_filter ); return p_filter; error: if( psz_name ) msg_Err( p_chain->p_this, "Failed to create %s '%s'", p_chain->psz_capability, psz_name ); else msg_Err( p_chain->p_this, "Failed to create %s", p_chain->psz_capability ); if( p_filter->p_module ) module_unneed( p_filter, p_filter->p_module ); es_format_Clean( &p_filter->fmt_in ); es_format_Clean( &p_filter->fmt_out ); vlc_object_detach( p_filter ); vlc_object_release( p_filter ); return NULL; }
/***************************************************************************** * aout_FiltersCreatePipeline: create a filters pipeline to transform a sample * format to another ***************************************************************************** * TODO : allow the user to add/remove specific filters *****************************************************************************/ int aout_FiltersCreatePipeline( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format ) { audio_sample_format_t temp_format; int i_nb_conversions; if ( AOUT_FMTS_IDENTICAL( p_input_format, p_output_format ) ) { msg_Dbg( p_aout, "no need for any filter" ); *pi_nb_filters = 0; return 0; } aout_FormatsPrint( p_aout, "filter(s)", p_input_format, p_output_format ); /* Try to find a filter to do the whole conversion. */ pp_filters[0] = FindFilter( p_aout, p_input_format, p_output_format ); if ( pp_filters[0] != NULL ) { msg_Dbg( p_aout, "found a filter for the whole conversion" ); *pi_nb_filters = 1; return 0; } /* We'll have to split the conversion. We always do the downmixing * before the resampling, because the audio decoder can probably do it * for us. */ i_nb_conversions = SplitConversion( p_input_format, p_output_format, &temp_format ); if ( !i_nb_conversions ) { /* There was only one conversion to do, and we already failed. */ msg_Err( p_aout, "couldn't find a filter for the conversion" ); return -1; } pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); if ( pp_filters[0] == NULL && i_nb_conversions == 2 ) { /* Try with only one conversion. */ SplitConversion( p_input_format, &temp_format, &temp_format ); pp_filters[0] = FindFilter( p_aout, p_input_format, &temp_format ); } if ( pp_filters[0] == NULL ) { msg_Err( p_aout, "couldn't find a filter for the first part of the conversion" ); return -1; } /* We have the first stage of the conversion. Find a filter for * the rest. */ pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, p_output_format ); if ( pp_filters[1] == NULL ) { /* Try to split the conversion. */ i_nb_conversions = SplitConversion( &pp_filters[0]->output, p_output_format, &temp_format ); if ( !i_nb_conversions ) { vlc_object_detach( pp_filters[0] ); vlc_object_destroy( pp_filters[0] ); msg_Err( p_aout, "couldn't find a filter for the second part of the conversion" ); } pp_filters[1] = FindFilter( p_aout, &pp_filters[0]->output, &temp_format ); pp_filters[2] = FindFilter( p_aout, &temp_format, p_output_format ); if ( pp_filters[1] == NULL || pp_filters[2] == NULL ) { vlc_object_detach( pp_filters[0] ); vlc_object_destroy( pp_filters[0] ); if ( pp_filters[1] != NULL ) { vlc_object_detach( pp_filters[1] ); vlc_object_destroy( pp_filters[1] ); } if ( pp_filters[2] != NULL ) { vlc_object_detach( pp_filters[2] ); vlc_object_destroy( pp_filters[2] ); } msg_Err( p_aout, "couldn't find filters for the second part of the conversion" ); } *pi_nb_filters = 3; } else { *pi_nb_filters = 2; } /* We have enough filters. */ msg_Dbg( p_aout, "found %d filters for the whole conversion", *pi_nb_filters ); return 0; }
/***************************************************************************** * RunThread: main playlist thread *****************************************************************************/ static void RunThread ( playlist_t *p_playlist ) { vlc_object_t *p_obj; vlc_value_t val; mtime_t i_vout_destroyed_date = 0; mtime_t i_sout_destroyed_date = 0; playlist_item_t *p_autodelete_item = 0; /* Tell above that we're ready */ vlc_thread_ready( p_playlist ); while( !p_playlist->b_die ) { vlc_mutex_lock( &p_playlist->object_lock ); /* If there is an input, check that it doesn't need to die. */ if( p_playlist->p_input ) { /* This input is dead. Remove it ! */ if( p_playlist->p_input->b_dead ) { input_thread_t *p_input; p_input = p_playlist->p_input; p_playlist->p_input = NULL; /* Release the playlist lock, because we may get stuck * in input_DestroyThread() for some time. */ vlc_mutex_unlock( &p_playlist->object_lock ); /* Destroy input */ input_DestroyThread( p_input ); /* Unlink current input * (_after_ input_DestroyThread for vout garbage collector) */ vlc_object_detach( p_input ); /* Destroy object */ vlc_object_destroy( p_input ); i_vout_destroyed_date = 0; i_sout_destroyed_date = 0; /* Check for autodeletion */ if( p_autodelete_item ) { playlist_ItemDelete( p_autodelete_item ); p_autodelete_item = 0; } continue; } /* This input is dying, let him do */ else if( p_playlist->p_input->b_die ) { ; } /* This input has finished, ask him to die ! */ else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof ) { input_StopThread( p_playlist->p_input ); if( p_playlist->pp_items[p_playlist->i_index]->b_autodeletion ) { /* This ain't pretty but hey it works */ p_autodelete_item = p_playlist->pp_items[p_playlist->i_index]; p_playlist->pp_items[p_playlist->i_index] = playlist_ItemNew( p_playlist, p_autodelete_item->input.psz_uri, 0); vlc_mutex_unlock( &p_playlist->object_lock ); p_playlist->i_status = PLAYLIST_STOPPED; playlist_Delete( p_playlist, p_playlist->i_index ); p_playlist->i_status = PLAYLIST_RUNNING; vlc_mutex_lock( &p_playlist->object_lock ); } SkipItem( p_playlist, 1 ); vlc_mutex_unlock( &p_playlist->object_lock ); continue; } else if( p_playlist->p_input->i_state != INIT_S ) { vlc_mutex_unlock( &p_playlist->object_lock ); i_vout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, i_vout_destroyed_date ); i_sout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, i_sout_destroyed_date ); vlc_mutex_lock( &p_playlist->object_lock ); } } else if( p_playlist->i_status != PLAYLIST_STOPPED ) { /* Start another input. Let's check if that item has * been forced. In that case, we override random (by not skipping) * and play-and-stop */ vlc_bool_t b_forced; var_Get( p_playlist, "prevent-skip", &val ); b_forced = val.b_bool; if( val.b_bool == VLC_FALSE ) { SkipItem( p_playlist, 0 ); } /* Reset forced status */ val.b_bool = VLC_FALSE; var_Set( p_playlist, "prevent-skip", val ); /* Check for play-and-stop */ var_Get( p_playlist, "play-and-stop", &val ); if( val.b_bool == VLC_FALSE || b_forced == VLC_TRUE ) { PlayItem( p_playlist ); } } else if( p_playlist->i_status == PLAYLIST_STOPPED ) { vlc_mutex_unlock( &p_playlist->object_lock ); i_sout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() ); i_vout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() ); vlc_mutex_lock( &p_playlist->object_lock ); } vlc_mutex_unlock( &p_playlist->object_lock ); msleep( INTF_IDLE_SLEEP ); } /* If there is an input, kill it */ while( 1 ) { vlc_mutex_lock( &p_playlist->object_lock ); if( p_playlist->p_input == NULL ) { vlc_mutex_unlock( &p_playlist->object_lock ); break; } if( p_playlist->p_input->b_dead ) { input_thread_t *p_input; /* Unlink current input */ p_input = p_playlist->p_input; p_playlist->p_input = NULL; vlc_mutex_unlock( &p_playlist->object_lock ); /* Destroy input */ input_DestroyThread( p_input ); /* Unlink current input (_after_ input_DestroyThread for vout * garbage collector)*/ vlc_object_detach( p_input ); /* Destroy object */ vlc_object_destroy( p_input ); continue; } else if( p_playlist->p_input->b_die ) { /* This input is dying, leave him alone */ ; } else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof ) { input_StopThread( p_playlist->p_input ); vlc_mutex_unlock( &p_playlist->object_lock ); continue; } else { p_playlist->p_input->b_eof = 1; } vlc_mutex_unlock( &p_playlist->object_lock ); msleep( INTF_IDLE_SLEEP ); } /* close all remaining sout */ while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD ) ) ) { vlc_object_release( p_obj ); sout_DeleteInstance( (sout_instance_t*)p_obj ); } /* close all remaining vout */ while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_VOUT, FIND_CHILD ) ) ) { vlc_object_detach( p_obj ); vlc_object_release( p_obj ); vout_Destroy( (vout_thread_t *)p_obj ); } }
/***************************************************************************** * Init: initialize logo video thread output method *****************************************************************************/ static int Init( vout_thread_t *p_vout ) { vout_sys_t *p_sys = p_vout->p_sys; picture_t *p_pic; int i_index; I_OUTPUTPICTURES = 0; /* Initialize the output structure */ p_vout->output.i_chroma = p_vout->render.i_chroma; p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_aspect = p_vout->render.i_aspect; /* Load the video blending filter */ p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) ); vlc_object_attach( p_sys->p_blend, p_vout ); p_sys->p_blend->fmt_out.video.i_x_offset = p_sys->p_blend->fmt_out.video.i_y_offset = 0; p_sys->p_blend->fmt_in.video.i_x_offset = p_sys->p_blend->fmt_in.video.i_y_offset = 0; p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect; p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma; p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A'); p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR; p_sys->p_blend->fmt_in.video.i_width = p_sys->p_blend->fmt_in.video.i_visible_width = p_sys->p_pic->p[Y_PLANE].i_visible_pitch; p_sys->p_blend->fmt_in.video.i_height = p_sys->p_blend->fmt_in.video.i_visible_height = p_sys->p_pic->p[Y_PLANE].i_visible_lines; p_sys->p_blend->fmt_out.video.i_width = p_sys->p_blend->fmt_out.video.i_visible_width = p_vout->output.i_width; p_sys->p_blend->fmt_out.video.i_height = p_sys->p_blend->fmt_out.video.i_visible_height = p_vout->output.i_height; p_sys->p_blend->p_module = module_Need( p_sys->p_blend, "video blending", 0, 0 ); if( !p_sys->p_blend->p_module ) { msg_Err( p_vout, "can't open blending filter, aborting" ); vlc_object_detach( p_sys->p_blend ); vlc_object_destroy( p_sys->p_blend ); return VLC_EGENERIC; } if( p_sys->posx < 0 || p_sys->posy < 0 ) { p_sys->posx = 0; p_sys->posy = 0; if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM ) { p_sys->posy = p_vout->render.i_height - p_sys->i_height; } else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) ) { p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2; } if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT ) { p_sys->posx = p_vout->render.i_width - p_sys->i_width; } else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) ) { p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2; } } /* Try to open the real video output */ msg_Dbg( p_vout, "spawning the real video output" ); p_sys->p_vout = vout_Create( p_vout, p_vout->render.i_width, p_vout->render.i_height, p_vout->render.i_chroma, p_vout->render.i_aspect ); /* Everything failed */ if( p_sys->p_vout == NULL ) { msg_Err( p_vout, "can't open vout, aborting" ); return VLC_EGENERIC; } var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout); var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout); ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); ADD_CALLBACKS( p_sys->p_vout, SendEvents ); ADD_PARENT_CALLBACKS( SendEventsToChild ); return VLC_SUCCESS; }
/***************************************************************************** * Thread: *****************************************************************************/ static void Thread( vlc_object_t *p_this ) { galaktos_thread_t *p_thread = (galaktos_thread_t*)p_this; int count=0; double realfps=0,fpsstart=0; int timed=0; int timestart=0; int mspf=0; /* Get on OpenGL provider */ p_thread->p_opengl = (vout_thread_t *)vlc_object_create( p_this, VLC_OBJECT_OPENGL ); if( p_thread->p_opengl == NULL ) { msg_Err( p_thread, "out of memory" ); return; } vlc_object_attach( p_thread->p_opengl, p_this ); /* Initialize vout parameters */ vout_InitFormat( &p_thread->p_opengl->fmt_in, VLC_FOURCC('R','V','3','2'), p_thread->i_width, p_thread->i_height, 1 ); p_thread->p_opengl->i_window_width = p_thread->i_width; p_thread->p_opengl->i_window_height = p_thread->i_height; p_thread->p_opengl->render.i_width = p_thread->i_width; p_thread->p_opengl->render.i_height = p_thread->i_width; p_thread->p_opengl->render.i_aspect = VOUT_ASPECT_FACTOR; p_thread->p_opengl->b_scale = VLC_TRUE; p_thread->p_opengl->b_fullscreen = VLC_FALSE; p_thread->p_opengl->i_alignment = 0; p_thread->p_opengl->fmt_in.i_sar_num = 1; p_thread->p_opengl->fmt_in.i_sar_den = 1; p_thread->p_opengl->fmt_render = p_thread->p_opengl->fmt_in; p_thread->p_module = module_Need( p_thread->p_opengl, "opengl provider", NULL, 0 ); if( p_thread->p_module == NULL ) { msg_Err( p_thread, "unable to initialize OpenGL" ); vlc_object_detach( p_thread->p_opengl ); vlc_object_destroy( p_thread->p_opengl ); return; } p_thread->p_opengl->pf_init( p_thread->p_opengl ); setup_opengl( p_thread->i_width, p_thread->i_height ); CreateRenderTarget(512, &RenderTargetTextureID, NULL); timestart=mdate()/1000; while( !p_thread->b_die ) { mspf = 1000 / 60; if( galaktos_update( p_thread ) == 1 ) { p_thread->b_die = 1; } if( p_thread->psz_title ) { free( p_thread->psz_title ); p_thread->psz_title = NULL; } if (++count%100==0) { realfps=100/((mdate()/1000-fpsstart)/1000); // printf("%f\n",realfps); fpsstart=mdate()/1000; } //framerate limiter timed=mspf-(mdate()/1000-timestart); // printf("%d,%d\n",time,mspf); if (timed>0) msleep(1000*timed); // printf("Limiter %d\n",(mdate()/1000-timestart)); timestart=mdate()/1000; } /* Free the openGL provider */ module_Unneed( p_thread->p_opengl, p_thread->p_module ); vlc_object_detach( p_thread->p_opengl ); vlc_object_destroy( p_thread->p_opengl ); }