+static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, vlc_bool_t *pb_sout_keep )
+{
+ vlc_bool_t b_keep_sout = var_CreateGetBool( p_parent, "sout-keep" );
+ sout_instance_t *p_sout = NULL;
+ int i;
+
+ /* Search sout-keep options
+ * XXX it has to be done here, but it is duplicated work :( */
+ vlc_mutex_lock( &p_item->lock );
+ for( i = 0; i < p_item->i_options; i++ )
+ {
+ const char *psz_option = p_item->ppsz_options[i];
+ if( !psz_option )
+ continue;
+ if( *psz_option == ':' )
+ psz_option++;
+
+ if( !strcmp( psz_option, "sout-keep" ) )
+ b_keep_sout = VLC_TRUE;
+ else if( !strcmp( psz_option, "no-sout-keep" ) || !strcmp( psz_option, "nosout-keep" ) )
+ b_keep_sout = VLC_FALSE;
+ }
+ vlc_mutex_unlock( &p_item->lock );
+
+ /* Find a potential sout to reuse
+ * XXX it might be unusable but this will be checked later */
+ if( b_keep_sout )
+ {
+ /* Remove the sout from the playlist garbage collector */
+ playlist_t *p_playlist = pl_Yield( p_parent );
+
+ vlc_mutex_lock( &p_playlist->gc_lock );
+ p_sout = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD );
+ if( p_sout )
+ {
+ if( p_sout->p_parent != VLC_OBJECT(p_playlist) )
+ {
+ vlc_object_release( p_sout );
+ p_sout = NULL;
+ }
+ else
+ {
+ vlc_object_detach( p_sout ); /* Remove it from the GC */
+
+ vlc_object_release( p_sout );
+ }
+ }
+ vlc_mutex_unlock( &p_playlist->gc_lock );
+
+ pl_Release( p_parent );
+ }
+
+ if( pb_sout_keep )
+ *pb_sout_keep = b_keep_sout;
+
+ return p_sout;
+}
+static void SoutKeep( sout_instance_t *p_sout )
+{
+ /* attach sout to the playlist */
+ playlist_t *p_playlist = pl_Yield( p_sout );
+
+ msg_Dbg( p_sout, "sout has been kept" );
+ vlc_object_attach( p_sout, p_playlist );
+
+ pl_Release( p_sout );
+}
+