static vout_thread_t *RequestVout( void *p_private, vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle ) { aout_instance_t *p_aout = p_private; VLC_UNUSED(b_recycle); vout_configuration_t cfg = { .vout = p_vout, .input = NULL, .change_fmt = true, .fmt = p_fmt, .dpb_size = 1, }; return vout_Request( p_aout, &cfg ); } vout_thread_t *aout_filter_RequestVout( filter_t *p_filter, vout_thread_t *p_vout, video_format_t *p_fmt ) { aout_input_t *p_input = p_filter->p_owner->p_input; aout_request_vout_t *p_request = &p_input->request_vout; /* XXX: this only works from audio input */ /* If you want to use visualization filters from another place, you will * need to add a new pf_aout_request_vout callback or store a pointer * to aout_request_vout_t inside filter_t (i.e. a level of indirection). */ return p_request->pf_request_vout( p_request->p_private, p_vout, p_fmt, p_input->b_recycle_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 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 vout_thread_t *RequestVout( input_resource_t *p_resource, vout_thread_t *p_vout, video_format_t *p_fmt, unsigned dpb_size, bool b_recycle ) { vlc_assert_locked( &p_resource->lock ); if( !p_vout && !p_fmt ) { if( p_resource->p_vout_free ) { msg_Dbg( p_resource->p_vout_free, "destroying useless vout" ); vout_CloseAndRelease( p_resource->p_vout_free ); p_resource->p_vout_free = NULL; } return NULL; } if( p_fmt ) { /* */ if( !p_vout && p_resource->p_vout_free ) { msg_Dbg( p_resource->p_parent, "trying to reuse free vout" ); p_vout = p_resource->p_vout_free; p_resource->p_vout_free = NULL; } else if( p_vout ) { assert( p_vout != p_resource->p_vout_free ); vlc_mutex_lock( &p_resource->lock_hold ); TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout ); vlc_mutex_unlock( &p_resource->lock_hold ); } /* */ vout_configuration_t cfg = { // sunqueen modify start /* .vout =*/ p_vout, /* .input =*/ VLC_OBJECT(p_resource->p_input), /* .change_fmt =*/ true, /* .fmt =*/ p_fmt, /* .dpb_size =*/ dpb_size, // sunqueen modify end }; p_vout = vout_Request( p_resource->p_parent, &cfg ); if( !p_vout ) return NULL; DisplayVoutTitle( p_resource, p_vout ); vlc_mutex_lock( &p_resource->lock_hold ); TAB_APPEND( (vout_thread_t **), p_resource->i_vout, p_resource->pp_vout, p_vout ); // sunqueen modify vlc_mutex_unlock( &p_resource->lock_hold ); return p_vout; } else {
static vout_thread_t *RequestVout( input_resource_t *p_resource, vout_thread_t *p_vout, video_format_t *p_fmt, unsigned dpb_size, bool b_recycle ) { vlc_assert_locked( &p_resource->lock ); if( !p_vout && !p_fmt ) { if( p_resource->p_vout_free ) { msg_Dbg( p_resource->p_vout_free, "destroying useless vout" ); vout_CloseAndRelease( p_resource->p_vout_free ); p_resource->p_vout_free = NULL; } return NULL; } assert( p_resource->p_input ); if( p_fmt ) { /* */ if( !p_vout && p_resource->p_vout_free ) { msg_Dbg( p_resource->p_parent, "trying to reuse free vout" ); p_vout = p_resource->p_vout_free; p_resource->p_vout_free = NULL; } else if( p_vout ) { assert( p_vout != p_resource->p_vout_free ); vlc_mutex_lock( &p_resource->lock_hold ); TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout ); vlc_mutex_unlock( &p_resource->lock_hold ); } /* */ vout_configuration_t cfg = { .vout = p_vout, .input = VLC_OBJECT(p_resource->p_input), .change_fmt = true, .fmt = p_fmt, .dpb_size = dpb_size, }; p_vout = vout_Request( p_resource->p_parent, &cfg ); if( !p_vout ) return NULL; DisplayVoutTitle( p_resource, p_vout ); vlc_mutex_lock( &p_resource->lock_hold ); TAB_APPEND( p_resource->i_vout, p_resource->pp_vout, p_vout ); vlc_mutex_unlock( &p_resource->lock_hold ); return p_vout; } else { assert( p_vout ); vlc_mutex_lock( &p_resource->lock_hold ); TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout ); const int i_vout_active = p_resource->i_vout; vlc_mutex_unlock( &p_resource->lock_hold ); if( p_resource->p_vout_free || i_vout_active > 0 || !b_recycle ) { if( b_recycle ) msg_Dbg( p_resource->p_parent, "detroying vout (already one saved or active)" ); vout_CloseAndRelease( p_vout ); } else { msg_Dbg( p_resource->p_parent, "saving a free vout" ); vout_Flush( p_vout, 1 ); vout_FlushSubpictureChannel( p_vout, -1 ); vout_configuration_t cfg = { .vout = p_vout, .input = NULL, .change_fmt = false, .fmt = NULL, .dpb_size = 0, }; p_resource->p_vout_free = vout_Request( p_resource->p_parent, &cfg ); } return NULL; } } static vout_thread_t *HoldVout( input_resource_t *p_resource ) { /* TODO FIXME: p_resource->pp_vout order is NOT stable */ vlc_mutex_lock( &p_resource->lock_hold ); vout_thread_t *p_vout = p_resource->i_vout > 0 ? p_resource->pp_vout[0] : NULL; if( p_vout ) vlc_object_hold( p_vout ); vlc_mutex_unlock( &p_resource->lock_hold ); return p_vout; }
/***************************************************************************** * 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; goom_thread_t *p_thread; vlc_value_t width, height; 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 goom thread */ p_sys->p_thread = p_thread = vlc_object_create( p_filter, sizeof( goom_thread_t ) ); vlc_object_attach( p_thread, p_this ); var_Create( p_thread, "goom-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "goom-width", &width ); var_Create( p_thread, "goom-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "goom-height", &height ); p_thread->p_vout = vout_Request( p_filter, NULL, width.i_int, height.i_int, VLC_FOURCC('R','V','3','2'), VOUT_ASPECT_FACTOR * width.i_int/height.i_int ); if( p_thread->p_vout == NULL ) { msg_Err( p_filter, "no suitable vout module" ); vlc_object_detach( p_thread ); vlc_object_destroy( p_thread ); free( p_sys ); return VLC_EGENERIC; } vlc_mutex_init( p_filter, &p_thread->lock ); vlc_cond_init( p_filter, &p_thread->wait ); p_thread->i_blocks = 0; aout_DateInit( &p_thread->date, p_filter->output.i_rate ); aout_DateSet( &p_thread->date, 0 ); p_thread->i_channels = aout_FormatNbChannels( &p_filter->input ); p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) ); if( vlc_thread_create( p_thread, "Goom Update Thread", Thread, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) { msg_Err( p_filter, "cannot lauch goom thread" ); vout_Destroy( p_thread->p_vout ); vlc_mutex_destroy( &p_thread->lock ); vlc_cond_destroy( &p_thread->wait ); 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; }