[PATCH 9/9] winepulse: Move timer loop to unix lib.

Andrew Eikum aeikum at codeweavers.com
Mon May 17 15:00:09 CDT 2021


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Thu, May 13, 2021 at 04:05:06PM +0200, Jacek Caban wrote:
> Signed-off-by: Jacek Caban <jacek at codeweavers.com>
> ---
>  dlls/winepulse.drv/mmdevdrv.c |  87 +--------------------------
>  dlls/winepulse.drv/pulse.c    | 107 +++++++++++++++++++++++++++++++++-
>  dlls/winepulse.drv/unixlib.h  |   2 +-
>  3 files changed, 107 insertions(+), 89 deletions(-)
> 
> 

> diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
> index 975f38794ac..f9b16bee66b 100644
> --- a/dlls/winepulse.drv/mmdevdrv.c
> +++ b/dlls/winepulse.drv/mmdevdrv.c
> @@ -251,93 +251,8 @@ static void pulse_op_cb(pa_stream *s, int success, void *user) {
>  
>  static DWORD WINAPI pulse_timer_cb(void *user)
>  {
> -    LARGE_INTEGER delay;
> -    UINT32 adv_bytes;
>      ACImpl *This = user;
> -    int success;
> -    pa_operation *o;
> -
> -    pulse->lock();
> -    delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10;
> -    pa_stream_get_time(This->pulse_stream->stream, &This->pulse_stream->last_time);
> -    pulse->unlock();
> -
> -    while(!This->pulse_stream->please_quit){
> -        pa_usec_t now, adv_usec = 0;
> -        int err;
> -
> -        NtDelayExecution(FALSE, &delay);
> -
> -        pulse->lock();
> -
> -        delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10;
> -
> -        o = pa_stream_update_timing_info(This->pulse_stream->stream, pulse_op_cb, &success);
> -        if (o)
> -        {
> -            while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
> -                pulse->cond_wait();
> -            pa_operation_unref(o);
> -        }
> -        err = pa_stream_get_time(This->pulse_stream->stream, &now);
> -        if(err == 0){
> -            TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(This->pulse_stream->last_time));
> -            if(This->pulse_stream->started && (This->dataflow == eCapture || This->pulse_stream->held_bytes)){
> -                if(This->pulse_stream->just_underran){
> -                    This->pulse_stream->last_time = now;
> -                    This->pulse_stream->just_started = TRUE;
> -                }
> -
> -                if(This->pulse_stream->just_started){
> -                    /* let it play out a period to absorb some latency and get accurate timing */
> -                    pa_usec_t diff = now - This->pulse_stream->last_time;
> -
> -                    if(diff > This->pulse_stream->mmdev_period_usec){
> -                        This->pulse_stream->just_started = FALSE;
> -                        This->pulse_stream->last_time = now;
> -                    }
> -                }else{
> -                    INT32 adjust = This->pulse_stream->last_time + This->pulse_stream->mmdev_period_usec - now;
> -
> -                    adv_usec = now - This->pulse_stream->last_time;
> -
> -                    if(adjust > ((INT32)(This->pulse_stream->mmdev_period_usec / 2)))
> -                        adjust = This->pulse_stream->mmdev_period_usec / 2;
> -                    else if(adjust < -((INT32)(This->pulse_stream->mmdev_period_usec / 2)))
> -                        adjust = -1 * This->pulse_stream->mmdev_period_usec / 2;
> -
> -                    delay.QuadPart = -(This->pulse_stream->mmdev_period_usec + adjust) * 10;
> -
> -                    This->pulse_stream->last_time += This->pulse_stream->mmdev_period_usec;
> -                }
> -
> -                if(This->dataflow == eRender){
> -                    pulse->write(This->pulse_stream);
> -
> -                    /* regardless of what PA does, advance one period */
> -                    adv_bytes = min(This->pulse_stream->period_bytes, This->pulse_stream->held_bytes);
> -                    This->pulse_stream->lcl_offs_bytes += adv_bytes;
> -                    This->pulse_stream->lcl_offs_bytes %= This->pulse_stream->real_bufsize_bytes;
> -                    This->pulse_stream->held_bytes -= adv_bytes;
> -                }else if(This->dataflow == eCapture){
> -                    pulse->read(This->pulse_stream);
> -                }
> -            }else{
> -                This->pulse_stream->last_time = now;
> -                delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10;
> -            }
> -        }
> -
> -        if (This->pulse_stream->event)
> -            SetEvent(This->pulse_stream->event);
> -
> -        TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n",
> -                This, (int)adv_usec,
> -                (int)(This->pulse_stream->held_bytes/ pa_frame_size(&This->pulse_stream->ss)), (unsigned int)(-delay.QuadPart / 10));
> -
> -        pulse->unlock();
> -    }
> -
> +    pulse->timer_loop(This->pulse_stream);
>      return 0;
>  }
>  
> diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c
> index 1dd906aef68..d720b79a22d 100644
> --- a/dlls/winepulse.drv/pulse.c
> +++ b/dlls/winepulse.drv/pulse.c
> @@ -1054,7 +1054,7 @@ static void WINAPI pulse_write(struct pulse_stream *stream)
>      stream->pa_held_bytes -= to_write;
>  }
>  
> -static void WINAPI pulse_read(struct pulse_stream *stream)
> +static void pulse_read(struct pulse_stream *stream)
>  {
>      size_t bytes = pa_stream_readable_size(stream->stream);
>  
> @@ -1154,6 +1154,109 @@ static void WINAPI pulse_read(struct pulse_stream *stream)
>      }
>  }
>  
> +static void WINAPI pulse_timer_loop(struct pulse_stream *stream)
> +{
> +    LARGE_INTEGER delay;
> +    UINT32 adv_bytes;
> +    int success;
> +    pa_operation *o;
> +
> +    pulse_lock();
> +    delay.QuadPart = -stream->mmdev_period_usec * 10;
> +    pa_stream_get_time(stream->stream, &stream->last_time);
> +    pulse_unlock();
> +
> +    while (!stream->please_quit)
> +    {
> +        pa_usec_t now, adv_usec = 0;
> +        int err;
> +
> +        NtDelayExecution(FALSE, &delay);
> +
> +        pulse_lock();
> +
> +        delay.QuadPart = -stream->mmdev_period_usec * 10;
> +
> +        o = pa_stream_update_timing_info(stream->stream, pulse_op_cb, &success);
> +        if (o)
> +        {
> +            while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
> +                pulse_cond_wait();
> +            pa_operation_unref(o);
> +        }
> +        err = pa_stream_get_time(stream->stream, &now);
> +        if (err == 0)
> +        {
> +            TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(stream->last_time));
> +            if (stream->started && (stream->dataflow == eCapture || stream->held_bytes))
> +            {
> +                if(stream->just_underran)
> +                {
> +                    stream->last_time = now;
> +                    stream->just_started = TRUE;
> +                }
> +
> +                if (stream->just_started)
> +                {
> +                    /* let it play out a period to absorb some latency and get accurate timing */
> +                    pa_usec_t diff = now - stream->last_time;
> +
> +                    if (diff > stream->mmdev_period_usec)
> +                    {
> +                        stream->just_started = FALSE;
> +                        stream->last_time = now;
> +                    }
> +                }
> +                else
> +                {
> +                    INT32 adjust = stream->last_time + stream->mmdev_period_usec - now;
> +
> +                    adv_usec = now - stream->last_time;
> +
> +                    if(adjust > ((INT32)(stream->mmdev_period_usec / 2)))
> +                        adjust = stream->mmdev_period_usec / 2;
> +                    else if(adjust < -((INT32)(stream->mmdev_period_usec / 2)))
> +                        adjust = -1 * stream->mmdev_period_usec / 2;
> +
> +                    delay.QuadPart = -(stream->mmdev_period_usec + adjust) * 10;
> +
> +                    stream->last_time += stream->mmdev_period_usec;
> +                }
> +
> +                if (stream->dataflow == eRender)
> +                {
> +                    pulse_write(stream);
> +
> +                    /* regardless of what PA does, advance one period */
> +                    adv_bytes = min(stream->period_bytes, stream->held_bytes);
> +                    stream->lcl_offs_bytes += adv_bytes;
> +                    stream->lcl_offs_bytes %= stream->real_bufsize_bytes;
> +                    stream->held_bytes -= adv_bytes;
> +                }
> +                else if(stream->dataflow == eCapture)
> +                {
> +                    pulse_read(stream);
> +                }
> +            }
> +            else
> +            {
> +                stream->last_time = now;
> +                delay.QuadPart = -stream->mmdev_period_usec * 10;
> +            }
> +        }
> +
> +        if (stream->event)
> +            NtSetEvent(stream->event, NULL);
> +
> +        TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n",
> +                stream, (int)adv_usec,
> +                (int)(stream->held_bytes/ pa_frame_size(&stream->ss)),
> +                (unsigned int)(-delay.QuadPart / 10));
> +
> +        pulse_unlock();
> +    }
> +}
> +
>  static HRESULT WINAPI pulse_stop(struct pulse_stream *stream)
>  {
>      HRESULT hr = S_OK;
> @@ -1212,8 +1315,8 @@ static const struct unix_funcs unix_funcs =
>      pulse_create_stream,
>      pulse_release_stream,
>      pulse_write,
> -    pulse_read,
>      pulse_stop,
> +    pulse_timer_loop,
>      pulse_set_volumes,
>      pulse_test_connect,
>  };
> diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h
> index 5413c4d2c78..4188dacc25f 100644
> --- a/dlls/winepulse.drv/unixlib.h
> +++ b/dlls/winepulse.drv/unixlib.h
> @@ -79,8 +79,8 @@ struct unix_funcs
>                                      struct pulse_stream **ret);
>      void (WINAPI *release_stream)(struct pulse_stream *stream, HANDLE timer);
>      void (WINAPI *write)(struct pulse_stream *stream);
> -    void (WINAPI *read)(struct pulse_stream *stream);
>      HRESULT (WINAPI *stop)(struct pulse_stream *stream);
> +    void (WINAPI *timer_loop)(struct pulse_stream *stream);
>      void (WINAPI *set_volumes)(struct pulse_stream *stream, float master_volume,
>                                 const float *volumes, const float *session_volumes);
>      HRESULT (WINAPI *test_connect)(const char *name, struct pulse_config *config);
> 




More information about the wine-devel mailing list