Fixed aout visual vout recycling.
authorLaurent Aimar <fenrir@videolan.org>
Thu, 5 Feb 2009 22:22:01 +0000 (23:22 +0100)
committerLaurent Aimar <fenrir@videolan.org>
Thu, 5 Feb 2009 22:22:01 +0000 (23:22 +0100)
It closes #2471
It changes a bit the public API but cannot(?) be avoided.

include/vlc_aout.h
src/audio_output/filters.c
src/audio_output/input.c
src/input/decoder.c

index 98a2a58..e721fa2 100644 (file)
@@ -226,7 +226,7 @@ struct aout_fifo_t
 typedef struct
 {
     vout_thread_t  *(*pf_request_vout)( void *,
-                                        vout_thread_t *, video_format_t * );
+                                        vout_thread_t *, video_format_t *, bool b_recycle );
     void *p_private;
 } aout_request_vout_t;
 
@@ -314,6 +314,7 @@ struct aout_input_t
     mtime_t           i_pause_date;
 
     /* */
+    bool                b_recycle_vout;
     aout_request_vout_t request_vout;
  };
 
index 4cd202b..d29352f 100644 (file)
@@ -383,6 +383,7 @@ vout_thread_t *aout_filter_RequestVout( aout_filter_t *p_filter,
 {
     if( !p_filter->request_vout.pf_request_vout )
         return NULL;
-    return p_filter->request_vout.pf_request_vout( p_filter->request_vout.p_private, p_vout, p_fmt );
+    return p_filter->request_vout.pf_request_vout( p_filter->request_vout.p_private,
+                                                   p_vout, p_fmt, true );
 }
 
index c2dd544..b4d9c48 100644 (file)
@@ -63,7 +63,10 @@ static int ReplayGainCallback( vlc_object_t *, char const *,
 static void ReplayGainSelect( aout_instance_t *, aout_input_t * );
 
 static vout_thread_t *RequestVout( void *,
-                                   vout_thread_t *, video_format_t * );
+                                   vout_thread_t *, video_format_t *, bool );
+static vout_thread_t *RequestVoutFromFilter( void *,
+                                             vout_thread_t *, video_format_t *, bool  );
+
 /*****************************************************************************
  * aout_InputNew : allocate a new input and rework the filter pipeline
  *****************************************************************************/
@@ -232,9 +235,10 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
 
     psz_filters = var_GetString( p_aout, "audio-filter" );
     psz_visual = var_GetString( p_aout, "audio-visual");
-
     psz_scaletempo = var_GetBool( p_aout, "audio-time-stretch" ) ? strdup( "scaletempo" ) : NULL;
 
+    p_input->b_recycle_vout = psz_visual && *psz_visual;
+
     /* parse user filter lists */
     for( i_visual = 0; i_visual < 3 && !AOUT_FMT_NON_LINEAR(&chain_output_format); i_visual++ )
     {
@@ -282,7 +286,9 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
 
             vlc_object_attach( p_filter , p_aout );
 
-            p_filter->request_vout = p_input->request_vout;
+            p_filter->request_vout.pf_request_vout = RequestVoutFromFilter;
+            p_filter->request_vout.p_private = p_input;
+
             p_filter->p_owner = malloc( sizeof(*p_filter->p_owner) );
             p_filter->p_owner->p_aout  = p_aout;
             p_filter->p_owner->p_input = p_input;
@@ -479,7 +485,16 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
 int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
 {
     AOUT_ASSERT_MIXER_LOCKED;
-    if ( p_input->b_error ) return 0;
+    if ( p_input->b_error )
+        return 0;
+
+    /* XXX We need to update b_recycle_vout before calling aout_FiltersDestroyPipeline.
+     * FIXME They can be a race condition if audio-visual is updated between
+     * aout_InputDelete and aout_InputNew.
+     */
+    char *psz_visual = var_GetString( p_aout, "audio-visual");
+    p_input->b_recycle_vout = psz_visual && *psz_visual;
+    free( psz_visual );
 
     aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
                                  p_input->i_nb_filters );
@@ -803,12 +818,23 @@ static void inputResamplingStop( aout_input_t *p_input )
 }
 
 static vout_thread_t *RequestVout( void *p_private,
-                                   vout_thread_t *p_vout, video_format_t *p_fmt )
+                                   vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle )
 {
     aout_instance_t *p_aout = p_private;
+    VLC_UNUSED(b_recycle);
     return vout_Request( p_aout, p_vout, p_fmt );
 }
 
+static vout_thread_t *RequestVoutFromFilter( void *p_private,
+                                            vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle )
+{
+    aout_input_t *p_input = p_private;
+    aout_request_vout_t *p_request = &p_input->request_vout;
+
+    return p_request->pf_request_vout( p_request->p_private,
+                                       p_vout, p_fmt, p_input->b_recycle_vout && b_recycle );
+}
+
 static int ChangeFiltersString( aout_instance_t * p_aout, const char* psz_variable,
                                  const char *psz_name, bool b_add )
 {
index 4a5eeff..bcae5fe 100644 (file)
@@ -2105,12 +2105,17 @@ static void DecoderUpdateFormatLocked( decoder_t *p_dec )
     p_dec->p_description = NULL;
 }
 static vout_thread_t *aout_request_vout( void *p_private,
-                                         vout_thread_t *p_vout, video_format_t *p_fmt )
+                                         vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recyle )
 {
     decoder_t *p_dec = p_private;
-
-    p_vout = input_ressource_RequestVout( p_dec->p_owner->p_input->p->p_ressource, p_vout, p_fmt );
-    input_SendEventVout( p_dec->p_owner->p_input );
+    input_thread_t *p_input = p_dec->p_owner->p_input;
+
+    p_vout = input_ressource_RequestVout( p_input->p->p_ressource, p_vout, p_fmt );
+    /* TODO it would be better to give b_recyle to input_ressource_RequestVout
+     * as here we are not sure of which vout we destroy */
+    if( !b_recyle )
+        input_ressource_TerminateVout( p_input->p->p_ressource );
+    input_SendEventVout( p_input );
 
     return p_vout;
 }