[PATCH 3/4] winealsa: Move get_capture_buffer to the unixlib.

Andrew Eikum aeikum at codeweavers.com
Wed Mar 9 12:40:03 CST 2022


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

On Fri, Mar 04, 2022 at 09:54:21AM +0000, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
>  dlls/winealsa.drv/alsa.c     | 62 ++++++++++++++++++++++++++++++++
>  dlls/winealsa.drv/mmdevdrv.c | 69 +++++-------------------------------
>  dlls/winealsa.drv/unixlib.h  | 12 +++++++
>  3 files changed, 83 insertions(+), 60 deletions(-)
> 
> diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
> index 302a525e52d..60ef49c4c1a 100644
> --- a/dlls/winealsa.drv/alsa.c
> +++ b/dlls/winealsa.drv/alsa.c
> @@ -1691,6 +1691,67 @@ static NTSTATUS release_render_buffer(void *args)
>      return alsa_unlock_result(stream, &params->result, S_OK);
>  }
>  
> +static NTSTATUS get_capture_buffer(void *args)
> +{
> +    struct get_capture_buffer_params *params = args;
> +    struct alsa_stream *stream = params->stream;
> +    UINT32 *frames = params->frames;
> +    SIZE_T size;
> +
> +    alsa_lock(stream);
> +
> +    if(stream->getbuf_last)
> +        return alsa_unlock_result(stream, &params->result, AUDCLNT_E_OUT_OF_ORDER);
> +
> +    if(stream->held_frames < stream->mmdev_period_frames){
> +        *frames = 0;
> +        return alsa_unlock_result(stream, &params->result, AUDCLNT_S_BUFFER_EMPTY);
> +    }
> +    *frames = stream->mmdev_period_frames;
> +
> +    if(stream->lcl_offs_frames + *frames > stream->bufsize_frames){
> +        UINT32 chunk_bytes, offs_bytes, frames_bytes;
> +        if(stream->tmp_buffer_frames < *frames){
> +            if(stream->tmp_buffer){
> +                size = 0;
> +                NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer, &size, MEM_RELEASE);
> +                stream->tmp_buffer = NULL;
> +            }
> +            size = *frames * stream->fmt->nBlockAlign;
> +            if(NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer, 0, &size,
> +                                       MEM_COMMIT, PAGE_READWRITE)){
> +                stream->tmp_buffer_frames = 0;
> +                return alsa_unlock_result(stream, &params->result, E_OUTOFMEMORY);
> +            }
> +            stream->tmp_buffer_frames = *frames;
> +        }
> +
> +        *params->data = stream->tmp_buffer;
> +        chunk_bytes = (stream->bufsize_frames - stream->lcl_offs_frames) *
> +            stream->fmt->nBlockAlign;
> +        offs_bytes = stream->lcl_offs_frames * stream->fmt->nBlockAlign;
> +        frames_bytes = *frames * stream->fmt->nBlockAlign;
> +        memcpy(stream->tmp_buffer, stream->local_buffer + offs_bytes, chunk_bytes);
> +        memcpy(stream->tmp_buffer + chunk_bytes, stream->local_buffer,
> +                frames_bytes - chunk_bytes);
> +    }else
> +        *params->data = stream->local_buffer +
> +            stream->lcl_offs_frames * stream->fmt->nBlockAlign;
> +
> +    stream->getbuf_last = *frames;
> +    *params->flags = 0;
> +
> +    if(params->devpos)
> +      *params->devpos = stream->written_frames;
> +    if(params->qpcpos){ /* fixme: qpc of recording time */
> +        LARGE_INTEGER stamp, freq;
> +        NtQueryPerformanceCounter(&stamp, &freq);
> +        *params->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
> +    }
> +
> +    return alsa_unlock_result(stream, &params->result, *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY);
> +}
> +
>  static NTSTATUS is_format_supported(void *args)
>  {
>      struct is_format_supported_params *params = args;
> @@ -2024,6 +2085,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
>      timer_loop,
>      get_render_buffer,
>      release_render_buffer,
> +    get_capture_buffer,
>      is_format_supported,
>      get_mix_format,
>      get_buffer_size,
> diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
> index e5512880442..cecb358bab7 100644
> --- a/dlls/winealsa.drv/mmdevdrv.c
> +++ b/dlls/winealsa.drv/mmdevdrv.c
> @@ -1369,8 +1369,7 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
>          UINT64 *qpcpos)
>  {
>      ACImpl *This = impl_from_IAudioCaptureClient(iface);
> -    struct alsa_stream *stream = This->stream;
> -    SIZE_T size;
> +    struct get_capture_buffer_params params;
>  
>      TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags,
>              devpos, qpcpos);
> @@ -1383,66 +1382,16 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
>      if(!frames || !flags)
>          return E_POINTER;
>  
> -    alsa_lock(stream);
> -
> -    if(stream->getbuf_last){
> -        alsa_unlock(stream);
> -        return AUDCLNT_E_OUT_OF_ORDER;
> -    }
> -
> -    /* hr = GetNextPacketSize(iface, frames); */
> -    if(stream->held_frames < stream->mmdev_period_frames){
> -        *frames = 0;
> -        alsa_unlock(stream);
> -        return AUDCLNT_S_BUFFER_EMPTY;
> -    }
> -    *frames = stream->mmdev_period_frames;
> -
> -    if(stream->lcl_offs_frames + *frames > stream->bufsize_frames){
> -        UINT32 chunk_bytes, offs_bytes, frames_bytes;
> -        if(stream->tmp_buffer_frames < *frames){
> -            if(stream->tmp_buffer){
> -                size = 0;
> -                NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer, &size, MEM_RELEASE);
> -                stream->tmp_buffer = NULL;
> -            }
> -            size = *frames * stream->fmt->nBlockAlign;
> -            if(NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->tmp_buffer, 0, &size,
> -                                       MEM_COMMIT, PAGE_READWRITE)){
> -                stream->tmp_buffer_frames = 0;
> -                alsa_unlock(stream);
> -                return E_OUTOFMEMORY;
> -            }
> -            stream->tmp_buffer_frames = *frames;
> -        }
> -
> -        *data = stream->tmp_buffer;
> -        chunk_bytes = (stream->bufsize_frames - stream->lcl_offs_frames) *
> -            stream->fmt->nBlockAlign;
> -        offs_bytes = stream->lcl_offs_frames * stream->fmt->nBlockAlign;
> -        frames_bytes = *frames * stream->fmt->nBlockAlign;
> -        memcpy(stream->tmp_buffer, stream->local_buffer + offs_bytes, chunk_bytes);
> -        memcpy(stream->tmp_buffer + chunk_bytes, stream->local_buffer,
> -                frames_bytes - chunk_bytes);
> -    }else
> -        *data = stream->local_buffer +
> -            stream->lcl_offs_frames * stream->fmt->nBlockAlign;
> -
> -    stream->getbuf_last = *frames;
> -    *flags = 0;
> -
> -    if(devpos)
> -      *devpos = stream->written_frames;
> -    if(qpcpos){ /* fixme: qpc of recording time */
> -        LARGE_INTEGER stamp, freq;
> -        QueryPerformanceCounter(&stamp);
> -        QueryPerformanceFrequency(&freq);
> -        *qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
> -    }
> +    params.stream = This->stream;
> +    params.data = data;
> +    params.frames = frames;
> +    params.flags = flags;
> +    params.devpos = devpos;
> +    params.qpcpos = qpcpos;
>  
> -    alsa_unlock(stream);
> +    ALSA_CALL(get_capture_buffer, &params);
>  
> -    return *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
> +    return params.result;
>  }
>  
>  static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
> diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
> index bef38c2a1a9..c4efe5ad764 100644
> --- a/dlls/winealsa.drv/unixlib.h
> +++ b/dlls/winealsa.drv/unixlib.h
> @@ -130,6 +130,17 @@ struct release_render_buffer_params
>      HRESULT result;
>  };
>  
> +struct get_capture_buffer_params
> +{
> +    struct alsa_stream *stream;
> +    HRESULT result;
> +    BYTE **data;
> +    UINT32 *frames;
> +    UINT *flags;
> +    UINT64 *devpos;
> +    UINT64 *qpcpos;
> +};
> +
>  struct is_format_supported_params
>  {
>      const char *alsa_name;
> @@ -187,6 +198,7 @@ enum alsa_funcs
>      alsa_timer_loop,
>      alsa_get_render_buffer,
>      alsa_release_render_buffer,
> +    alsa_get_capture_buffer,
>      alsa_is_format_supported,
>      alsa_get_mix_format,
>      alsa_get_buffer_size,
> -- 
> 2.25.1
> 
> 



More information about the wine-devel mailing list