mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 2 changesets (bug 1136360)
Backed out changeset 004f6db9c2dd (bug 1136360) Backed out changeset 9b568fb8d447 (bug 1136360)
This commit is contained in:
parent
e640422013
commit
42e93061e3
@ -220,17 +220,6 @@ struct cubeb_stream
|
||||
IAudioRenderClient * render_client;
|
||||
/* Interface pointer to use the volume facilities. */
|
||||
IAudioStreamVolume * audio_stream_volume;
|
||||
/* Interface pointer to use the stream audio clock. */
|
||||
IAudioClock * audio_clock;
|
||||
/* Frames written to the stream since it was opened. Reset on device
|
||||
* change. Uses mix_params.rate. */
|
||||
UINT64 frames_written;
|
||||
/* Frames written to the (logical) stream since it was first
|
||||
* created. Updated on device change. Uses stream_params.rate. */
|
||||
UINT64 total_frames_written;
|
||||
/* Last valid reported stream position. Used to ensure the position
|
||||
* reported by stream_get_position increases monotonically. */
|
||||
UINT64 prev_position;
|
||||
/* Device enumerator to be able to be notified when the default
|
||||
* device change. */
|
||||
IMMDeviceEnumerator * device_enumerator;
|
||||
@ -248,9 +237,8 @@ struct cubeb_stream
|
||||
HANDLE refill_event;
|
||||
/* Each cubeb_stream has its own thread. */
|
||||
HANDLE thread;
|
||||
/* The lock protects all members that are touched by the render thread or
|
||||
change during a device reset, including: audio_clock, audio_stream_volume,
|
||||
client, frames_written, mix_params, total_frames_written, prev_position. */
|
||||
/* We synthesize our clock from the callbacks. */
|
||||
LONG64 clock;
|
||||
owned_critical_section * stream_reset_lock;
|
||||
/* Maximum number of frames we can be requested in a callback. */
|
||||
uint32_t buffer_frame_count;
|
||||
@ -355,6 +343,16 @@ private:
|
||||
};
|
||||
|
||||
namespace {
|
||||
void clock_add(cubeb_stream * stm, LONG64 value)
|
||||
{
|
||||
InterlockedExchangeAdd64(&stm->clock, value);
|
||||
}
|
||||
|
||||
LONG64 clock_get(cubeb_stream * stm)
|
||||
{
|
||||
return InterlockedExchangeAdd64(&stm->clock, 0);
|
||||
}
|
||||
|
||||
bool should_upmix(cubeb_stream * stream)
|
||||
{
|
||||
return stream->mix_params.channels > stream->stream_params.channels;
|
||||
@ -365,10 +363,10 @@ bool should_downmix(cubeb_stream * stream)
|
||||
return stream->mix_params.channels < stream->stream_params.channels;
|
||||
}
|
||||
|
||||
double stream_to_mix_samplerate_ratio(cubeb_stream * stream)
|
||||
float stream_to_mix_samplerate_ratio(cubeb_stream * stream)
|
||||
{
|
||||
stream->stream_reset_lock->assert_current_thread_owns();
|
||||
return double(stream->stream_params.rate) / stream->mix_params.rate;
|
||||
auto_lock lock(stream->stream_reset_lock);
|
||||
return float(stream->stream_params.rate) / stream->mix_params.rate;
|
||||
}
|
||||
|
||||
/* Upmix function, copies a mono channel into L and R */
|
||||
@ -440,7 +438,7 @@ frames_to_bytes_before_mix(cubeb_stream * stm, size_t frames)
|
||||
return stream_frame_size * frames;
|
||||
}
|
||||
|
||||
long
|
||||
void
|
||||
refill(cubeb_stream * stm, float * data, long frames_needed)
|
||||
{
|
||||
/* If we need to upmix after resampling, resample into the mix buffer to
|
||||
@ -453,12 +451,12 @@ refill(cubeb_stream * stm, float * data, long frames_needed)
|
||||
}
|
||||
|
||||
long out_frames = cubeb_resampler_fill(stm->resampler, dest, frames_needed);
|
||||
/* TODO: Report frames < 0 as an error via the API. */
|
||||
XASSERT(frames >= 0);
|
||||
|
||||
{
|
||||
auto_lock lock(stm->stream_reset_lock);
|
||||
stm->frames_written += out_frames;
|
||||
clock_add(stm, roundf(frames_needed * stream_to_mix_samplerate_ratio(stm)));
|
||||
|
||||
/* XXX: Handle this error. */
|
||||
if (out_frames < 0) {
|
||||
XASSERT(false);
|
||||
}
|
||||
|
||||
/* Go in draining mode if we got fewer frames than requested. */
|
||||
@ -478,8 +476,6 @@ refill(cubeb_stream * stm, float * data, long frames_needed)
|
||||
downmix(dest, out_frames, data,
|
||||
stm->stream_params.channels, stm->mix_params.channels);
|
||||
}
|
||||
|
||||
return out_frames;
|
||||
}
|
||||
|
||||
static unsigned int __stdcall
|
||||
@ -581,10 +577,9 @@ wasapi_stream_render_loop(LPVOID stream)
|
||||
BYTE * data;
|
||||
hr = stm->render_client->GetBuffer(available, &data);
|
||||
if (SUCCEEDED(hr)) {
|
||||
long wrote = refill(stm, reinterpret_cast<float *>(data), available);
|
||||
XASSERT(wrote == available || stm->draining);
|
||||
refill(stm, reinterpret_cast<float *>(data), available);
|
||||
|
||||
hr = stm->render_client->ReleaseBuffer(wrote, 0);
|
||||
hr = stm->render_client->ReleaseBuffer(available, 0);
|
||||
if (FAILED(hr)) {
|
||||
LOG("failed to release buffer.\n");
|
||||
is_playing = false;
|
||||
@ -693,33 +688,6 @@ HRESULT get_default_endpoint(IMMDevice ** device)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
double
|
||||
current_stream_delay(cubeb_stream * stm)
|
||||
{
|
||||
stm->stream_reset_lock->assert_current_thread_owns();
|
||||
|
||||
UINT64 freq;
|
||||
HRESULT hr = stm->audio_clock->GetFrequency(&freq);
|
||||
if (FAILED(hr)) {
|
||||
LOG("GetFrequency failed: %x\n", hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT64 pos;
|
||||
hr = stm->audio_clock->GetPosition(&pos, NULL);
|
||||
if (FAILED(hr)) {
|
||||
LOG("GetPosition failed: %x\n", hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double cur_pos = static_cast<double>(pos) / freq;
|
||||
double max_pos = static_cast<double>(stm->frames_written) / stm->mix_params.rate;
|
||||
double delay = max_pos - cur_pos;
|
||||
XASSERT(delay >= 0);
|
||||
|
||||
return delay;
|
||||
}
|
||||
} // namespace anonymous
|
||||
|
||||
extern "C" {
|
||||
@ -1101,14 +1069,6 @@ int setup_wasapi_stream(cubeb_stream * stm)
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
XASSERT(stm->frames_written == 0);
|
||||
hr = stm->client->GetService(__uuidof(IAudioClock),
|
||||
(void **)&stm->audio_clock);
|
||||
if (FAILED(hr)) {
|
||||
LOG("Could not get the IAudioClock %x.\n", hr);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
/* If we are playing a mono stream, we only resample one channel,
|
||||
* and copy it over, so we are always resampling the number
|
||||
* of channels of the stream, not the number of channels
|
||||
@ -1153,6 +1113,15 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
stm->stream_params = stream_params;
|
||||
stm->draining = false;
|
||||
stm->latency = latency;
|
||||
stm->clock = 0;
|
||||
|
||||
/* Null out WASAPI-specific state */
|
||||
stm->resampler = NULL;
|
||||
stm->client = NULL;
|
||||
stm->render_client = NULL;
|
||||
stm->audio_stream_volume = NULL;
|
||||
stm->device_enumerator = NULL;
|
||||
stm->notification_client = NULL;
|
||||
|
||||
stm->stream_reset_lock = new owned_critical_section();
|
||||
|
||||
@ -1209,11 +1178,6 @@ void close_wasapi_stream(cubeb_stream * stm)
|
||||
SafeRelease(stm->audio_stream_volume);
|
||||
stm->audio_stream_volume = NULL;
|
||||
|
||||
SafeRelease(stm->audio_clock);
|
||||
stm->audio_clock = NULL;
|
||||
stm->total_frames_written += round(stm->frames_written * stream_to_mix_samplerate_ratio(stm));
|
||||
stm->frames_written = 0;
|
||||
|
||||
if (stm->resampler) {
|
||||
cubeb_resampler_destroy(stm->resampler);
|
||||
stm->resampler = NULL;
|
||||
@ -1319,24 +1283,8 @@ int wasapi_stream_stop(cubeb_stream * stm)
|
||||
int wasapi_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
{
|
||||
XASSERT(stm && position);
|
||||
auto_lock lock(stm->stream_reset_lock);
|
||||
|
||||
/* Calculate how far behind the current stream head the playback cursor is. */
|
||||
uint64_t stream_delay = current_stream_delay(stm) * stm->stream_params.rate;
|
||||
|
||||
/* Calculate the logical stream head in frames at the stream sample rate. */
|
||||
uint64_t max_pos = stm->total_frames_written +
|
||||
round(stm->frames_written * stream_to_mix_samplerate_ratio(stm));
|
||||
|
||||
*position = max_pos;
|
||||
if (stream_delay <= *position) {
|
||||
*position -= stream_delay;
|
||||
}
|
||||
|
||||
if (*position < stm->prev_position) {
|
||||
*position = stm->prev_position;
|
||||
}
|
||||
stm->prev_position = *position;
|
||||
*position = clock_get(stm);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user