Backed out 2 changesets (bug 1136360)

Backed out changeset 004f6db9c2dd (bug 1136360)
Backed out changeset 9b568fb8d447 (bug 1136360)
This commit is contained in:
Matthew Gregan 2015-08-24 13:25:57 +12:00
parent 52219f5e5c
commit cea13e8bed

View File

@ -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;
}