Bug 1345049 - Update cubeb from upstream to f07ee6d. r=kinetik

MozReview-Commit-ID: 9vApWUIieJH

--HG--
extra : rebase_source : 02de16b962218747a52b5c6f71c2d681b8485fc6
This commit is contained in:
Alex Chronopoulos 2017-03-09 19:47:39 +01:00
Родитель a51561a1c4
Коммит 44ce83037f
3 изменённых файлов: 84 добавлений и 78 удалений

Просмотреть файл

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
The git commit ID used was a3c012fd29bf088d0fc006932b48080cb1f5d9c2 (2017-03-06 14:15:22 +1300)
The git commit ID used was f07ee6d5c536e2106ffe7a847074d7685ca07bd3 (2017-03-09 11:46:48 +0100)

Просмотреть файл

@ -139,53 +139,14 @@ private:
auto_array<T> ar;
};
class auto_channel_layout
static std::unique_ptr<AudioChannelLayout, decltype(&free)>
make_sized_audio_channel_layout(size_t sz)
{
public:
auto_channel_layout()
: layout(nullptr)
{
}
auto_channel_layout(size_t size)
: layout(reinterpret_cast<AudioChannelLayout*>(malloc(size)))
{
memset(layout, 0, size);
}
~auto_channel_layout()
{
release();
}
void reset(size_t size)
{
release();
layout = reinterpret_cast<AudioChannelLayout*>(malloc(size));
memset(layout, 0, size);
}
AudioChannelLayout* get()
{
return layout;
}
size_t size()
{
return sizeof(*layout);
}
private:
void release()
{
if (layout) {
free(layout);
layout = NULL;
}
}
AudioChannelLayout * layout;
};
assert(sz >= sizeof(AudioChannelLayout));
AudioChannelLayout * acl = reinterpret_cast<AudioChannelLayout *>(calloc(1, sz));
assert(acl); // Assert the allocation works.
return std::unique_ptr<AudioChannelLayout, decltype(&free)>(acl, free);
}
enum io_side {
INPUT,
@ -550,8 +511,16 @@ audiounit_output_callback(void * user_ptr,
stm->input_linear_buffer->pop(input_frames_before_fill * stm->input_desc.mChannelsPerFrame);
}
if (outframes < 0) {
if (outframes < 0 || outframes > output_frames) {
stm->shutdown = true;
OSStatus r = AudioOutputUnitStop(stm->output_unit);
assert(r == 0);
if (stm->input_unit) {
r = AudioOutputUnitStop(stm->input_unit);
assert(r == 0);
}
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
audiounit_make_silent(&outBufferList->mBuffers[0]);
return noErr;
}
@ -654,15 +623,21 @@ audiounit_get_input_device_id(AudioDeviceID * device_id)
return CUBEB_OK;
}
static int audiounit_stream_get_volume(cubeb_stream * stm, float * volume);
static int audiounit_stream_set_volume(cubeb_stream * stm, float volume);
static int
audiounit_reinit_stream(cubeb_stream * stm, bool is_started)
{
auto_lock context_lock(stm->context->mutex);
if (is_started) {
audiounit_stream_stop_internal(stm);
}
{
auto_lock lock(stm->mutex);
float volume = 0.0;
int vol_rv = audiounit_stream_get_volume(stm, &volume);
audiounit_close_stream(stm);
@ -671,6 +646,10 @@ audiounit_reinit_stream(cubeb_stream * stm, bool is_started)
return CUBEB_ERROR;
}
if (vol_rv == CUBEB_OK) {
audiounit_stream_set_volume(stm, volume);
}
// Reset input frames to force new stream pre-buffer
// silence if needed, check `is_extra_input_needed()`
stm->frames_read = 0;
@ -1120,7 +1099,7 @@ audiounit_get_current_channel_layout(AudioUnit output_unit)
}
assert(size > 0);
auto_channel_layout layout(size);
auto layout = make_sized_audio_channel_layout(size);
rv = AudioUnitGetProperty(output_unit,
kAudioUnitProperty_AudioChannelLayout,
kAudioUnitScope_Output,
@ -1155,7 +1134,7 @@ audiounit_get_preferred_channel_layout()
}
assert(size > 0);
auto_channel_layout layout(size);
auto layout = make_sized_audio_channel_layout(size);
rv = AudioObjectGetPropertyData(id, &adr, 0, NULL, &size, layout.get());
if (rv != noErr) {
return CUBEB_LAYOUT_UNDEFINED;
@ -1209,10 +1188,12 @@ audiounit_destroy(cubeb * ctx)
LOG("(%p) API misuse, %d streams active when context destroyed!", ctx, ctx->active_streams.load());
}
/* Unregister the callback if necessary. */
if(ctx->collection_changed_callback) {
{
auto_lock lock(ctx->mutex);
audiounit_remove_device_listener(ctx);
/* Unregister the callback if necessary. */
if (ctx->collection_changed_callback) {
audiounit_remove_device_listener(ctx);
}
}
delete ctx;
@ -1274,7 +1255,8 @@ audiounit_set_channel_layout(AudioUnit unit,
assert(stream_params->channels == CUBEB_CHANNEL_LAYOUT_MAPS[stream_params->layout].channels);
OSStatus r;
auto_channel_layout layout(sizeof(AudioChannelLayout));
size_t size = sizeof(AudioChannelLayout);
auto layout = make_sized_audio_channel_layout(size);
switch (stream_params->layout) {
case CUBEB_LAYOUT_DUAL_MONO:
@ -1310,8 +1292,8 @@ audiounit_set_channel_layout(AudioUnit unit,
// For those layouts that can't be matched to coreaudio's predefined layout,
// we use customized layout.
if (layout.get()->mChannelLayoutTag == kAudioChannelLayoutTag_Unknown) {
size_t size = offsetof(AudioChannelLayout, mChannelDescriptions[stream_params->channels]);
layout.reset(size);
size = offsetof(AudioChannelLayout, mChannelDescriptions[stream_params->channels]);
layout = make_sized_audio_channel_layout(size);
layout.get()->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
layout.get()->mNumberChannelDescriptions = stream_params->channels;
for (UInt32 i = 0 ; i < stream_params->channels ; ++i) {
@ -1326,7 +1308,7 @@ audiounit_set_channel_layout(AudioUnit unit,
kAudioUnitScope_Input,
AU_OUT_BUS,
layout.get(),
layout.size());
size);
if (r != noErr) {
LOG("AudioUnitSetProperty/%s/kAudioUnitProperty_AudioChannelLayout rv=%d", to_string(side), r);
return CUBEB_ERROR;
@ -1480,13 +1462,11 @@ get_device_name(AudioDeviceID id)
}
static int
audiounit_set_aggregate_sub_device_list(cubeb_stream * stm)
audiounit_set_aggregate_sub_device_list(AudioDeviceID aggregate_device_id,
AudioDeviceID input_device_id,
AudioDeviceID output_device_id)
{
AudioDeviceID input_device_id = audiounit_get_input_device_id(stm);
const std::vector<AudioDeviceID> input_sub_devices = audiounit_get_sub_devices(input_device_id);
AudioDeviceID output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
const std::vector<AudioDeviceID> output_sub_devices = audiounit_get_sub_devices(output_device_id);
CFMutableArrayRef aggregate_sub_devices_array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@ -1511,7 +1491,7 @@ audiounit_set_aggregate_sub_device_list(cubeb_stream * stm)
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
UInt32 size = sizeof(CFMutableArrayRef);
OSStatus rv = AudioObjectSetPropertyData(stm->aggregate_device_id,
OSStatus rv = AudioObjectSetPropertyData(aggregate_device_id,
&aggregate_sub_device_list,
0,
nullptr,
@ -1612,7 +1592,7 @@ audiounit_activate_clock_drift_compensation(const AudioDeviceID aggregate_device
return CUBEB_OK;
}
static int audiounit_destroy_aggregate_device(cubeb_stream * stm);
static int audiounit_destroy_aggregate_device(AudioObjectID plugin_id, AudioDeviceID aggregate_device_id);
/*
* Aggregate Device is a virtual audio interface which utilizes inputs and outputs
@ -1639,28 +1619,30 @@ audiounit_create_aggregate_device(cubeb_stream * stm)
int r = audiounit_create_blank_aggregate_device(&stm->plugin_id, &stm->aggregate_device_id);
if (r != CUBEB_OK) {
LOG("(%p) Failed to create blank aggregate device", stm);
audiounit_destroy_aggregate_device(stm);
audiounit_destroy_aggregate_device(stm->plugin_id, stm->aggregate_device_id);
return CUBEB_ERROR;
}
r = audiounit_set_aggregate_sub_device_list(stm);
AudioDeviceID input_device_id = audiounit_get_input_device_id(stm);
AudioDeviceID output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
r = audiounit_set_aggregate_sub_device_list(stm->aggregate_device_id, input_device_id, output_device_id);
if (r != CUBEB_OK) {
LOG("(%p) Failed to set aggregate sub-device list", stm);
audiounit_destroy_aggregate_device(stm);
audiounit_destroy_aggregate_device(stm->plugin_id, stm->aggregate_device_id);
return CUBEB_ERROR;
}
r = audiounit_set_master_aggregate_device(stm->aggregate_device_id);
if (r != CUBEB_OK) {
LOG("(%p) Failed to set master sub-device for aggregate device", stm);
audiounit_destroy_aggregate_device(stm);
audiounit_destroy_aggregate_device(stm->plugin_id, stm->aggregate_device_id);
return CUBEB_ERROR;
}
r = audiounit_activate_clock_drift_compensation(stm->aggregate_device_id);
if (r != CUBEB_OK) {
LOG("(%p) Failed to activate clock drift compensation for aggregate device", stm);
audiounit_destroy_aggregate_device(stm);
audiounit_destroy_aggregate_device(stm->plugin_id, stm->aggregate_device_id);
return CUBEB_ERROR;
}
@ -1668,13 +1650,13 @@ audiounit_create_aggregate_device(cubeb_stream * stm)
}
static int
audiounit_destroy_aggregate_device(cubeb_stream * stm)
audiounit_destroy_aggregate_device(AudioObjectID plugin_id, AudioDeviceID aggregate_device_id)
{
AudioObjectPropertyAddress destroy_aggregate_device_addr = { kAudioPlugInDestroyAggregateDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster};
UInt32 size;
OSStatus rv = AudioObjectGetPropertyDataSize(stm->plugin_id,
OSStatus rv = AudioObjectGetPropertyDataSize(plugin_id,
&destroy_aggregate_device_addr,
0,
NULL,
@ -1684,12 +1666,12 @@ audiounit_destroy_aggregate_device(cubeb_stream * stm)
return CUBEB_ERROR;
}
rv = AudioObjectGetPropertyData(stm->plugin_id,
rv = AudioObjectGetPropertyData(plugin_id,
&destroy_aggregate_device_addr,
0,
NULL,
&size,
&stm->aggregate_device_id);
&aggregate_device_id);
if (rv != noErr) {
LOG("AudioObjectGetPropertyData/kAudioPlugInDestroyAggregateDevice, rv=%d", rv);
return CUBEB_ERROR;
@ -2522,7 +2504,7 @@ audiounit_close_stream(cubeb_stream *stm)
stm->resampler.reset();
if (stm->aggregate_device_id) {
audiounit_destroy_aggregate_device(stm);
audiounit_destroy_aggregate_device(stm->plugin_id, stm->aggregate_device_id);
stm->aggregate_device_id = 0;
}
}
@ -2532,7 +2514,7 @@ audiounit_stream_destroy(cubeb_stream * stm)
{
stm->shutdown = true;
auto_lock context_locl(stm->context->mutex);
auto_lock context_lock(stm->context->mutex);
audiounit_stream_stop_internal(stm);
{
@ -2567,7 +2549,7 @@ audiounit_stream_start(cubeb_stream * stm)
stm->shutdown = false;
stm->draining = false;
auto_lock context_locl(stm->context->mutex);
auto_lock context_lock(stm->context->mutex);
audiounit_stream_start_internal(stm);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
@ -2595,7 +2577,7 @@ audiounit_stream_stop(cubeb_stream * stm)
{
stm->shutdown = true;
auto_lock context_locl(stm->context->mutex);
auto_lock context_lock(stm->context->mutex);
audiounit_stream_stop_internal(stm);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
@ -2692,7 +2674,23 @@ audiounit_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
#endif
}
int audiounit_stream_set_volume(cubeb_stream * stm, float volume)
static int
audiounit_stream_get_volume(cubeb_stream * stm, float * volume)
{
assert(stm->output_unit);
OSStatus r = AudioUnitGetParameter(stm->output_unit,
kHALOutputParam_Volume,
kAudioUnitScope_Global,
0, volume);
if (r != noErr) {
LOG("AudioUnitGetParameter/kHALOutputParam_Volume rv=%d", r);
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static int
audiounit_stream_set_volume(cubeb_stream * stm, float volume)
{
assert(stm->output_unit);
OSStatus r;

Просмотреть файл

@ -869,6 +869,13 @@ wasapi_stream_render_loop(LPVOID stream)
unsigned timeout_count = 0;
const unsigned timeout_limit = 5;
while (is_playing) {
// We want to check the emergency bailout variable before a
// and after the WaitForMultipleObject, because the handles WaitForMultipleObjects
// is going to wait on might have been closed already.
if (*emergency_bailout) {
delete emergency_bailout;
return 0;
}
DWORD waitResult = WaitForMultipleObjects(ARRAY_LENGTH(wait_array),
wait_array,
FALSE,
@ -1479,6 +1486,7 @@ int setup_wasapi_stream_one_side(cubeb_stream * stm,
if (devid && hr == AUDCLNT_E_DEVICE_INVALIDATED) {
LOG("Trying again with the default %s audio device.", DIRECTION_NAME);
devid = nullptr;
device = nullptr;
try_again = true;
} else {
return CUBEB_ERROR;