[vlc-devel] [PATCH] Erase regularily the already played directsound buffer outside of the play callback

Denis Charmet typx at dinauz.org
Thu Apr 24 09:42:04 CEST 2014


Hi,

Thanks for the review.

Le jeudi 24 avril 2014 à 10:26:48, Rémi Denis-Courmont a écrit :
> >+        vlc_mutex_lock( &sys->lock );
> >+        sys->b_playing = true;
> >+        vlc_cond_broadcast(&sys->cond);
> 
> NIT: By convention, signal is used when only one thread waits on the
> variable.
> 
Indeed it's a bad reflex.
> >+        vlc_mutex_unlock( &sys->lock );
> >+
> >+    }
> >     return dsresult;
> > }
> >
> >@@ -298,6 +295,14 @@ static HRESULT Pause( aout_stream_sys_t *sys,
> >bool pause )
> >         hr = IDirectSoundBuffer_Stop( sys->p_dsbuffer );
> >     else
> >         hr = IDirectSoundBuffer_Play( sys->p_dsbuffer, 0, 0,
> >DSBPLAY_LOOPING );
> >+    if( hr == DS_OK )
> >+    {
> >+        vlc_mutex_lock( &sys->lock );
> >+        sys->b_playing = !pause;
> >+        if( sys->b_playing )
> >+            vlc_cond_broadcast( &sys->cond );
> >+        vlc_mutex_unlock( &sys->lock );
> >+    }
> >     return hr;
> > }
> >
> >@@ -513,6 +518,12 @@ static HRESULT CreateDSBufferPCM( vlc_object_t
> >*obj, aout_stream_sys_t *sys,
> >  */
> > static HRESULT Stop( aout_stream_sys_t *p_sys )
> > {
> >+    vlc_mutex_lock( &p_sys->lock );
> >+    p_sys->b_playing =  true;
> >+    vlc_cond_broadcast( &p_sys->cond );
> 
> Leaving cancellation enabled in vlc_cond_wait() would be simpler IMHO.
> 
I have to admit that thread cancellation is quite a mystery to me
especially with Windows threads...
> >+    vlc_cancel( p_sys->eraser_thread );
> >+    vlc_mutex_unlock( &p_sys->lock );
> >+    vlc_join( p_sys->eraser_thread, NULL );
> >     if( p_sys->p_notify != NULL )
> >     {
> >         IDirectSoundNotify_Release(p_sys->p_notify );
> >@@ -729,7 +740,27 @@ static HRESULT Start( vlc_object_t *obj,
> >aout_stream_sys_t *sys,
> >         }
> >     }
> >
> >+    int ret = vlc_clone(&sys->eraser_thread, PlayedDataEraser,
> >(void*) obj,
> >+                        VLC_THREAD_PRIORITY_LOW);
> >+    if( unlikely( ret ) )
> >+    {
> >+        if( ret != ENOMEM )
> >+            msg_Err( obj, "Couldn't start eraser thread" );
> >+        if( sys->p_notify != NULL )
> >+        {
> >+            IDirectSoundNotify_Release( sys->p_notify );
> >+            sys->p_notify = NULL;
> >+        }
> >+        IDirectSoundBuffer_Release( sys->p_dsbuffer );
> >+        sys->p_dsbuffer = NULL;
> >+        IDirectSound_Release( sys->p_dsobject );
> >+        sys->p_dsobject = NULL;
> >+        return ret;
> >+    }
> >+    sys->b_playing = false;
> >     sys->i_write = 0;
> >+    vlc_mutex_unlock( &sys->lock );
> >+
> >     return DS_OK;
> >
> > error:
> >@@ -1028,6 +1059,9 @@ static int Open(vlc_object_t *obj)
> >     aout_DeviceReport(aout, dev);
> >     free(dev);
> >
> >+    vlc_mutex_init(&sys->s.lock);
> >+    vlc_cond_init(&sys->s.cond);
> >+
> >     return VLC_SUCCESS;
> > }
> >
> >@@ -1035,8 +1069,83 @@ static void Close(vlc_object_t *obj)
> > {
> >     audio_output_t *aout = (audio_output_t *)obj;
> >     aout_sys_t *sys = aout->sys;
> >+    vlc_cond_destroy( &sys->s.cond );
> >+    vlc_mutex_destroy( &sys->s.lock );
> >
> >     var_Destroy(aout, "directx-audio-device");
> >     FreeLibrary(sys->hdsound_dll); /* free DSOUND.DLL */
> >     free(sys);
> > }
> >+
> >+static void * PlayedDataEraser( void * data )
> >+{
> >+    const audio_output_t *aout = (audio_output_t *) data;
> >+    aout_stream_sys_t *p_sys = &aout->sys->s;
> >+    void *p_write_position, *p_wrap_around;
> >+    unsigned long l_bytes1, l_bytes2;
> >+    DWORD i_read;
> >+    int64_t toerase, tosleep;
> >+    HRESULT dsresult;
> >+
> >+    for(;;)
> >+    {
> >+        int canc = vlc_savecancel();
> >+        vlc_mutex_lock( &p_sys->lock );
> >+
> >+        while( !p_sys->b_playing )
> >+           vlc_cond_wait( &p_sys->cond, &p_sys->lock );
> >+
> >+        toerase = 0;
> >+        tosleep = 0;
> >+
> >+        dsresult = IDirectSoundBuffer_GetCurrentPosition(
> >p_sys->p_dsbuffer,
> >+
> >&i_read, NULL );
> >+        if( dsresult == DS_OK )
> >+        {
> >+            int64_t max = (int64_t) i_read - (int64_t)
> >p_sys->i_write;
> >+            tosleep = -max;
> >+            if( max <= 0 )
> >+                max += DS_BUF_SIZE;
> >+            else
> >+                tosleep += DS_BUF_SIZE;
> >+            toerase = max;
> >+            tosleep = ( tosleep / p_sys->i_bytes_per_sample ) *
> >CLOCK_FREQ / p_sys->i_rate;
> >+        }
> >+
> >+        tosleep = __MAX( tosleep, 20000 );
> >+        dsresult = IDirectSoundBuffer_Lock( p_sys->p_dsbuffer,
> >+                                            p_sys->i_write,
> >+                                            toerase,
> >+                                            &p_write_position,
> >+                                            &l_bytes1,
> >+                                            &p_wrap_around,
> >+                                            &l_bytes2,
> >+                                            0 );
> >+        if( dsresult == DSERR_BUFFERLOST )
> >+        {
> >+            IDirectSoundBuffer_Restore( p_sys->p_dsbuffer );
> >+            dsresult = IDirectSoundBuffer_Lock( p_sys->p_dsbuffer,
> >+                                                p_sys->i_write,
> >+                                                toerase,
> >+                                                &p_write_position,
> >+                                                &l_bytes1,
> >+                                                &p_wrap_around,
> >+                                                &l_bytes2,
> >+                                                0 );
> >+        }
> >+        if( dsresult != DS_OK )
> >+            goto wait;
> >+
> >+        memset( p_write_position, 0, l_bytes1 );
> >+        memset( p_wrap_around, 0, l_bytes2 );
> >+
> >+        IDirectSoundBuffer_Unlock( p_sys->p_dsbuffer,
> >p_write_position, l_bytes1,
> >+                                   p_wrap_around, l_bytes2 );
> >+wait:
> >+        vlc_mutex_unlock(&p_sys->lock);
> >+        vlc_restorecancel(canc);
> >+        msleep(tosleep);
> >+    }
> >+    vlc_mutex_unlock(&p_sys->lock);
> 
> Dead code?
> 
indeed
> >+    return NULL;
> >+}

Regards,

-- 
Denis Charmet - TypX
Le mauvais esprit est un art de vivre



More information about the vlc-devel mailing list