Bug 1359451 - Update cubeb from upstream to 17503c4. r?padenot
MozReview-Commit-ID: C3NXIvjwjgD
--- a/media/libcubeb/README_MOZILLA
+++ b/media/libcubeb/README_MOZILLA
@@ -1,8 +1,8 @@
The source from this directory was copied from the cubeb
git repository using the update.sh script. The only changes
made were those applied by update.sh and the addition of
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 6e52314f24bba463d6ca97951f7d9fcc677d76a4 (2017-04-18 17:28:50 +0200)
+The git commit ID used was 17503c41318ec7a18ba3d728fb803a66ec60cf84 (2017-04-25 15:26:11 +0200)
--- a/media/libcubeb/gtest/test_record.cpp
+++ b/media/libcubeb/gtest/test_record.cpp
@@ -87,17 +87,17 @@ TEST(cubeb, record)
* have one. */
if (!has_available_input_device(ctx)) {
return;
}
params.format = STREAM_FORMAT;
params.rate = SAMPLE_FREQUENCY;
params.channels = 1;
- params.layout = CUBEB_LAYOUT_MONO;
+ params.layout = CUBEB_LAYOUT_UNDEFINED;
r = cubeb_stream_init(ctx, &stream, "Cubeb record (mono)", NULL, ¶ms, NULL, nullptr,
4096, data_cb_record, state_cb_record, &stream_state);
ASSERT_EQ(r, CUBEB_OK) << "Error initializing cubeb stream";
std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)>
cleanup_stream_at_exit(stream, cubeb_stream_destroy);
--- a/media/libcubeb/src/cubeb_audiounit.cpp
+++ b/media/libcubeb/src/cubeb_audiounit.cpp
@@ -221,16 +221,17 @@ channel_label_to_cubeb_channel(UInt32 la
case kAudioChannelLabel_Right: return CHANNEL_RIGHT;
case kAudioChannelLabel_Center: return CHANNEL_CENTER;
case kAudioChannelLabel_LFEScreen: return CHANNEL_LFE;
case kAudioChannelLabel_LeftSurround: return CHANNEL_LS;
case kAudioChannelLabel_RightSurround: return CHANNEL_RS;
case kAudioChannelLabel_RearSurroundLeft: return CHANNEL_RLS;
case kAudioChannelLabel_RearSurroundRight: return CHANNEL_RRS;
case kAudioChannelLabel_CenterSurround: return CHANNEL_RCENTER;
+ case kAudioChannelLabel_Unknown: return CHANNEL_UNMAPPED;
default: return CHANNEL_INVALID;
}
}
AudioChannelLabel
cubeb_channel_to_channel_label(cubeb_channel channel)
{
switch (channel) {
@@ -239,16 +240,17 @@ cubeb_channel_to_channel_label(cubeb_cha
case CHANNEL_RIGHT: return kAudioChannelLabel_Right;
case CHANNEL_CENTER: return kAudioChannelLabel_Center;
case CHANNEL_LFE: return kAudioChannelLabel_LFEScreen;
case CHANNEL_LS: return kAudioChannelLabel_LeftSurround;
case CHANNEL_RS: return kAudioChannelLabel_RightSurround;
case CHANNEL_RLS: return kAudioChannelLabel_RearSurroundLeft;
case CHANNEL_RRS: return kAudioChannelLabel_RearSurroundRight;
case CHANNEL_RCENTER: return kAudioChannelLabel_CenterSurround;
+ case CHANNEL_UNMAPPED: return kAudioChannelLabel_Unknown;
default: return kAudioChannelLabel_Unknown;
}
}
#if TARGET_OS_IPHONE
typedef UInt32 AudioDeviceID;
typedef UInt32 AudioObjectID;
@@ -638,20 +640,20 @@ audiounit_get_input_device_id(AudioDevic
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)
+audiounit_reinit_stream(cubeb_stream * stm)
{
auto_lock context_lock(stm->context->mutex);
- if (is_started) {
+ if (!stm->shutdown) {
audiounit_stream_stop_internal(stm);
}
{
auto_lock lock(stm->mutex);
float volume = 0.0;
int vol_rv = audiounit_stream_get_volume(stm, &volume);
@@ -666,32 +668,30 @@ audiounit_reinit_stream(cubeb_stream * s
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;
// If the stream was running, start it again.
- if (is_started) {
+ if (!stm->shutdown) {
audiounit_stream_start_internal(stm);
}
}
return CUBEB_OK;
}
static OSStatus
audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_count,
const AudioObjectPropertyAddress * addresses,
void * user)
{
cubeb_stream * stm = (cubeb_stream*) user;
stm->switching_device = true;
- // Note if the stream was running or not
- bool was_running = !stm->shutdown;
LOG("(%p) Audio device changed, %u events.", stm, (unsigned int) address_count);
for (UInt32 i = 0; i < address_count; i++) {
switch(addresses[i].mSelector) {
case kAudioHardwarePropertyDefaultOutputDevice: {
LOG("Event[%u] - mSelector == kAudioHardwarePropertyDefaultOutputDevice", (unsigned int) i);
// Allow restart to choose the new default
stm->output_device = 0;
@@ -710,18 +710,22 @@ audiounit_property_listener_callback(Aud
if (stm->is_default_input) {
LOG("It's the default input device, ignore the event");
return noErr;
}
// Allow restart to choose the new default. Event register only for input.
stm->input_device = 0;
}
break;
- case kAudioDevicePropertyDataSource:
- LOG("Event[%u] - mSelector == kAudioHardwarePropertyDataSource", (unsigned int) i);
+ case kAudioDevicePropertyDataSource: {
+ LOG("Event[%u] - mSelector == kAudioHardwarePropertyDataSource", (unsigned int) i);
+ if (has_output(stm)) {
+ stm->output_device = 0;
+ }
+ }
break;
default:
LOG("Event[%u] - mSelector == Unexpected Event id %d, return", (unsigned int) i, addresses[i].mSelector);
return noErr;
}
}
for (UInt32 i = 0; i < address_count; i++) {
@@ -738,17 +742,17 @@ audiounit_property_listener_callback(Aud
break;
}
}
}
// Use a new thread, through the queue, to avoid deadlock when calling
// Get/SetProperties method from inside notify callback
dispatch_async(stm->context->serial_queue, ^() {
- if (audiounit_reinit_stream(stm, was_running) != CUBEB_OK) {
+ if (audiounit_reinit_stream(stm) != CUBEB_OK) {
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
LOG("(%p) Could not reopen the stream after switching.", stm);
}
stm->switching_device = false;
});
return noErr;
}
@@ -1084,16 +1088,22 @@ audiounit_convert_channel_layout(AudioCh
// kAudioChannelLayoutTag_UseChannelBitmap
// kAudioChannelLayoutTag_Mono
// kAudioChannelLayoutTag_Stereo
// ....
LOG("Only handle UseChannelDescriptions for now.\n");
return CUBEB_LAYOUT_UNDEFINED;
}
+ // This devices has more channels that we can support, bail out.
+ if (layout->mNumberChannelDescriptions >= CHANNEL_MAX) {
+ LOG("Audio device has more than %d channels, bailing out.", CHANNEL_MAX);
+ return CUBEB_LAYOUT_UNDEFINED;
+ }
+
cubeb_channel_map cm;
cm.channels = layout->mNumberChannelDescriptions;
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; ++i) {
cm.map[i] = channel_label_to_cubeb_channel(layout->mChannelDescriptions[i].mChannelLabel);
}
return cubeb_channel_map_to_layout(&cm);
}
@@ -2574,20 +2584,20 @@ audiounit_stream_start_internal(cubeb_st
r = AudioOutputUnitStart(stm->output_unit);
assert(r == 0);
}
}
static int
audiounit_stream_start(cubeb_stream * stm)
{
+ auto_lock context_lock(stm->context->mutex);
stm->shutdown = false;
stm->draining = false;
- auto_lock context_lock(stm->context->mutex);
audiounit_stream_start_internal(stm);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
LOG("Cubeb stream (%p) started successfully.", stm);
return CUBEB_OK;
}
@@ -2603,19 +2613,19 @@ audiounit_stream_stop_internal(cubeb_str
r = AudioOutputUnitStop(stm->output_unit);
assert(r == 0);
}
}
static int
audiounit_stream_stop(cubeb_stream * stm)
{
+ auto_lock context_lock(stm->context->mutex);
stm->shutdown = true;
- auto_lock context_lock(stm->context->mutex);
audiounit_stream_stop_internal(stm);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
LOG("Cubeb stream (%p) stopped successfully.", stm);
return CUBEB_OK;
}
--- a/media/libcubeb/src/cubeb_mixer.cpp
+++ b/media/libcubeb/src/cubeb_mixer.cpp
@@ -26,17 +26,18 @@
#define MASK_3F2_LFE (MASK_3F2 | (1 << CHANNEL_LFE))
#define MASK_3F3R_LFE (MASK_3F2_LFE | (1 << CHANNEL_RCENTER))
#define MASK_3F4_LFE (MASK_3F2_LFE | (1 << CHANNEL_RLS) | (1 << CHANNEL_RRS))
cubeb_channel_layout cubeb_channel_map_to_layout(cubeb_channel_map const * channel_map)
{
uint32_t channel_mask = 0;
for (uint8_t i = 0 ; i < channel_map->channels ; ++i) {
- if (channel_map->map[i] == CHANNEL_INVALID) {
+ if (channel_map->map[i] == CHANNEL_INVALID ||
+ channel_map->map[i] == CHANNEL_UNMAPPED) {
return CUBEB_LAYOUT_UNDEFINED;
}
channel_mask |= 1 << channel_map->map[i];
}
switch(channel_mask) {
case MASK_MONO: return CUBEB_LAYOUT_MONO;
case MASK_MONO_LFE: return CUBEB_LAYOUT_MONO_LFE;
--- a/media/libcubeb/src/cubeb_mixer.h
+++ b/media/libcubeb/src/cubeb_mixer.h
@@ -22,17 +22,18 @@ typedef enum {
CHANNEL_RIGHT,
CHANNEL_CENTER,
CHANNEL_LS,
CHANNEL_RS,
CHANNEL_RLS,
CHANNEL_RCENTER,
CHANNEL_RRS,
CHANNEL_LFE,
- CHANNEL_MAX // Max number of supported channels.
+ CHANNEL_UNMAPPED,
+ CHANNEL_MAX = 256 // Max number of supported channels.
} cubeb_channel;
static cubeb_channel const CHANNEL_INDEX_TO_ORDER[CUBEB_LAYOUT_MAX][CHANNEL_MAX] = {
{ CHANNEL_INVALID }, // UNDEFINED
{ CHANNEL_LEFT, CHANNEL_RIGHT }, // DUAL_MONO
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE }, // DUAL_MONO_LFE
{ CHANNEL_MONO }, // MONO
{ CHANNEL_MONO, CHANNEL_LFE }, // MONO_LFE
@@ -45,16 +46,18 @@ static cubeb_channel const CHANNEL_INDEX
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_RCENTER }, // 3F1
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RCENTER }, // 3F1_LFE
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LS, CHANNEL_RS }, // 2F2
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE, CHANNEL_LS, CHANNEL_RS }, // 2F2_LFE
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LS, CHANNEL_RS }, // 3F2
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_LS, CHANNEL_RS }, // 3F2_LFE
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RCENTER, CHANNEL_LS, CHANNEL_RS }, // 3F3R_LFE
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RLS, CHANNEL_RRS, CHANNEL_LS, CHANNEL_RS } // 3F4_LFE
+ // When more channels are present, the stream is considered unmapped to a
+ // particular speaker set.
};
typedef struct {
unsigned int channels;
cubeb_channel map[CHANNEL_MAX];
} cubeb_channel_map;
cubeb_channel_layout cubeb_channel_map_to_layout(cubeb_channel_map const * channel_map);
--- a/media/libcubeb/src/cubeb_pulse.c
+++ b/media/libcubeb/src/cubeb_pulse.c
@@ -743,30 +743,35 @@ to_pulse_format(cubeb_sample_format form
}
static int
create_pa_stream(cubeb_stream * stm,
pa_stream ** pa_stm,
cubeb_stream_params * stream_params,
char const * stream_name)
{
- assert(stm && stream_params && stream_params->layout != CUBEB_LAYOUT_UNDEFINED &&
- CUBEB_CHANNEL_LAYOUT_MAPS[stream_params->layout].channels == stream_params->channels);
+ assert(stm && stream_params);
+ assert(&stm->input_stream == pa_stm || (&stm->output_stream == pa_stm &&
+ stream_params->layout != CUBEB_LAYOUT_UNDEFINED &&
+ CUBEB_CHANNEL_LAYOUT_MAPS[stream_params->layout].channels == stream_params->channels));
*pa_stm = NULL;
pa_sample_spec ss;
ss.format = to_pulse_format(stream_params->format);
if (ss.format == PA_SAMPLE_INVALID)
return CUBEB_ERROR_INVALID_FORMAT;
ss.rate = stream_params->rate;
ss.channels = stream_params->channels;
- pa_channel_map cm;
- layout_to_channel_map(stream_params->layout, &cm);
-
- *pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, &cm);
+ if (stream_params->layout == CUBEB_LAYOUT_UNDEFINED) {
+ *pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, NULL);
+ } else {
+ pa_channel_map cm;
+ layout_to_channel_map(stream_params->layout, &cm);
+ *pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, &cm);
+ }
return (*pa_stm == NULL) ? CUBEB_ERROR : CUBEB_OK;
}
static pa_buffer_attr
set_buffering_attribute(unsigned int latency_frames, pa_sample_spec * sample_spec)
{
pa_buffer_attr battr;
battr.maxlength = -1;
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -1551,21 +1551,16 @@ int setup_wasapi_stream_one_side(cubeb_s
mix_format->wBitsPerSample = stm->bytes_per_sample * 8;
format_pcm->SubFormat = stm->waveformatextensible_sub_format;
waveformatex_update_derived_properties(mix_format.get());
/* Set channel layout only when there're more than two channels. Otherwise,
* use the default setting retrieved from the stream format of the audio
* engine's internal processing by GetMixFormat. */
if (mix_format->nChannels > 2) {
- /* Currently, we only support mono and stereo for capture stream. */
- if (direction == eCapture) {
- XASSERT(false && "Multichannel recording is not supported.");
- }
-
handle_channel_layout(stm, mix_format, stream_params);
}
mix_params->format = stream_params->format;
mix_params->rate = mix_format->nSamplesPerSec;
mix_params->channels = mix_format->nChannels;
mix_params->layout = mask_to_channel_layout(format_pcm->dwChannelMask);
if (mix_params->layout == CUBEB_LAYOUT_UNDEFINED) {