Bug 1023947 - Part 2 - Allow getting the current input device in cubeb. r=kinetik
☠☠ backed out by 5dc0231d0153 ☠ ☠
authorPaul Adenot <paul@paul.cx>
Fri, 18 Jul 2014 19:21:27 +0200
changeset 196019 a56aad94c7c9b2f35439a1f7c414a8fdabb9e2d9
parent 196018 63af4528bd9c723e9faf228b33cffeb896d35c99
child 196020 ad05dc816fa0ad34be4c258ae13a6a6b1683b520
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerskinetik
bugs1023947
milestone34.0a1
Bug 1023947 - Part 2 - Allow getting the current input device in cubeb. r=kinetik
content/media/AudioStream.cpp
layout/media/symbols.def.in
media/libcubeb/include/cubeb.h
media/libcubeb/src/cubeb-internal.h
media/libcubeb/src/cubeb.c
media/libcubeb/src/cubeb_alsa.c
media/libcubeb/src/cubeb_audiotrack.c
media/libcubeb/src/cubeb_audiounit.c
media/libcubeb/src/cubeb_opensl.c
media/libcubeb/src/cubeb_pulse.c
media/libcubeb/src/cubeb_sndio.c
media/libcubeb/src/cubeb_wasapi.cpp
media/libcubeb/src/cubeb_winmm.c
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -549,46 +549,46 @@ AudioStream::Init(int32_t aNumChannels, 
 }
 
 // On certain MacBookPro, the microphone is located near the left speaker.
 // We need to pan the sound output to the right speaker if we are using the mic
 // and the built-in speaker, or we will have terrible echo.
 void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive)
 {
 #ifdef XP_MACOSX
-  cubeb_output_device* out;
+  cubeb_device* device;
   int rv;
   char name[128];
   size_t length = sizeof(name);
 
   rv = sysctlbyname("hw.model", name, &length, NULL, 0);
   if (rv) {
     return;
   }
 
   if (!strncmp(name, "MacBookPro", 10)) {
-    if (cubeb_stream_get_current_output_device(mCubebStream, &out) == CUBEB_OK) {
+    if (cubeb_stream_get_current_evice(mCubebStream, &device) == CUBEB_OK) {
       // Check if we are currently outputing sound on external speakers.
-      if (!strcmp(out->name, "ispk")) {
+      if (!strcmp(device->name, "ispk")) {
         // Pan everything to the right speaker.
         if (aMicrophoneActive) {
           if (cubeb_stream_set_panning(mCubebStream, 1.0) != CUBEB_OK) {
             NS_WARNING("Could not pan audio output to the right.");
           }
         } else {
           if (cubeb_stream_set_panning(mCubebStream, 0.0) != CUBEB_OK) {
             NS_WARNING("Could not pan audio output to the center.");
           }
         }
       } else {
         if (cubeb_stream_set_panning(mCubebStream, 0.0) != CUBEB_OK) {
           NS_WARNING("Could not pan audio output to the center.");
         }
       }
-      cubeb_stream_output_device_destroy(mCubebStream, out);
+      cubeb_stream_device_destroy(mCubebStream, device);
     }
   }
 #endif
 }
 
 void AudioStream::DeviceChangedCallback() {
   MonitorAutoLock mon(mMonitor);
   PanOutputIfNeeded(mMicrophoneActive);
--- a/layout/media/symbols.def.in
+++ b/layout/media/symbols.def.in
@@ -132,18 +132,18 @@ cubeb_get_preferred_sample_rate
 cubeb_stream_destroy
 cubeb_stream_get_position
 cubeb_stream_init
 cubeb_stream_start
 cubeb_stream_stop
 cubeb_stream_get_latency
 cubeb_stream_set_volume
 cubeb_stream_set_panning
-cubeb_stream_get_current_output_device
-cubeb_stream_output_device_destroy
+cubeb_stream_get_current_device
+cubeb_stream_device_destroy
 cubeb_stream_register_device_changed_callback
 th_comment_clear
 th_comment_init
 th_decode_alloc
 th_decode_free
 th_decode_headerin
 th_decode_packetin
 th_decode_ycbcr_out
--- a/media/libcubeb/include/cubeb.h
+++ b/media/libcubeb/include/cubeb.h
@@ -126,18 +126,19 @@ typedef struct {
   unsigned int channels;      /**< Requested channel count.  Valid range is [1, 32]. */
 #if defined(__ANDROID__)
   cubeb_stream_type stream_type; /**< Used to map Android audio stream types */
 #endif
 } cubeb_stream_params;
 
 /** Output device description */
 typedef struct {
-  char * name; /**< The name of the output device */
-} cubeb_output_device;
+  char * output_name; /**< The name of the output device */
+  char * input_name; /**< The name of the input device */
+} cubeb_device;
 
 /** Stream states signaled via state_callback. */
 typedef enum {
   CUBEB_STATE_STARTED, /**< Stream started. */
   CUBEB_STATE_STOPPED, /**< Stream stopped. */
   CUBEB_STATE_DRAINED, /**< Stream drained. */
   CUBEB_STATE_ERROR    /**< Stream disabled due to error. */
 } cubeb_state;
@@ -298,28 +299,28 @@ int cubeb_stream_set_panning(cubeb_strea
 /**
  * Get the current output device for this stream.
  * @param stm the stream for which to query the current output device
  * @param device a pointer in which the current output device will be stored.
  * @return CUBEB_OK in case of success
  * @return CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
  *         invalid pointers
  */
-int cubeb_stream_get_current_output_device(cubeb_stream * stm,
-                                           cubeb_output_device ** const device);
+int cubeb_stream_get_current_device(cubeb_stream * stm,
+                                    cubeb_device ** const device);
 
 /**
- * Destroy a cubeb_output_device structure.
- * @param stream the stream passed in cubeb_stream_get_current_output_device
+ * Destroy a cubeb_device structure.
+ * @param stream the stream passed in cubeb_stream_get_current_device
  * @param devices the devices to destroy
  * @return CUBEB_OK in case of success
  * @return CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
  */
-int cubeb_stream_output_device_destroy(cubeb_stream * stream,
-                                       cubeb_output_device * devices);
+int cubeb_stream_device_destroy(cubeb_stream * stream,
+                                cubeb_device * devices);
 
 /**
  * Set a callback to be notified when the output device changes.
  * @param stream the stream for which to set the callback.
  * @param device_changed_callback a function called whenever the device has
  *        changed. Passing NULL allow to unregister a function
  * @return CUBEB_ERROR_INVALID_PARAMETER if either stream or
  *         device_changed_callback are invalid pointers.
--- a/media/libcubeb/src/cubeb-internal.h
+++ b/media/libcubeb/src/cubeb-internal.h
@@ -25,19 +25,19 @@ struct cubeb_ops {
                       void * user_ptr);
   void (* stream_destroy)(cubeb_stream * stream);
   int (* stream_start)(cubeb_stream * stream);
   int (* stream_stop)(cubeb_stream * stream);
   int (* stream_get_position)(cubeb_stream * stream, uint64_t * position);
   int (* stream_get_latency)(cubeb_stream * stream, uint32_t * latency);
   int (* stream_set_volume)(cubeb_stream * stream, float volumes);
   int (* stream_set_panning)(cubeb_stream * stream, float panning);
-  int (* stream_get_current_output_device)(cubeb_stream * stream,
-                                           cubeb_output_device ** const device);
-  int (* stream_output_device_destroy)(cubeb_stream * stream,
-                                       cubeb_output_device * device);
+  int (* stream_get_current_device)(cubeb_stream * stream,
+                                    cubeb_device ** const device);
+  int (* stream_device_destroy)(cubeb_stream * stream,
+                                cubeb_device * device);
   int (*stream_register_device_changed_callback)(cubeb_stream * stream,
                                                  cubeb_device_changed_callback device_changed_callback);
 
 };
 
 #endif /* CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5 */
 
--- a/media/libcubeb/src/cubeb.c
+++ b/media/libcubeb/src/cubeb.c
@@ -273,44 +273,44 @@ int cubeb_stream_set_panning(cubeb_strea
 {
   if (!stream || panning < -1.0 || panning > 1.0) {
     return CUBEB_ERROR_INVALID_PARAMETER;
   }
 
   return stream->context->ops->stream_set_panning(stream, panning);
 }
 
-int cubeb_stream_get_current_output_device(cubeb_stream * stream,
-                                           cubeb_output_device ** const device)
+int cubeb_stream_get_current_device(cubeb_stream * stream,
+                                    cubeb_device ** const device)
 {
   if (!stream || !device) {
     return CUBEB_ERROR_INVALID_PARAMETER;
   }
 
   // If we find an implementation, call the function, it might not be available
   // on some platforms.
-  if (stream->context->ops->stream_get_current_output_device) {
-    return stream->context->ops->stream_get_current_output_device(stream,
-                                                                  device);
+  if (stream->context->ops->stream_get_current_device) {
+    return stream->context->ops->stream_get_current_device(stream,
+                                                           device);
   }
 
   return CUBEB_ERROR;
 }
 
-int cubeb_stream_output_device_destroy(cubeb_stream * stream,
-                                       cubeb_output_device * device)
+int cubeb_stream_device_destroy(cubeb_stream * stream,
+                                cubeb_device * device)
 {
   if (!stream || !device) {
     return CUBEB_ERROR_INVALID_PARAMETER;
   }
 
   // If we find an implementation, call the function, it might not be available
   // on some platforms.
-  if (stream->context->ops->stream_output_device_destroy) {
-    return stream->context->ops->stream_output_device_destroy(stream, device);
+  if (stream->context->ops->stream_device_destroy) {
+    return stream->context->ops->stream_device_destroy(stream, device);
   }
 
   return CUBEB_ERROR;
 }
 
 int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
                                                   cubeb_device_changed_callback device_changed_callback)
 {
--- a/media/libcubeb/src/cubeb_alsa.c
+++ b/media/libcubeb/src/cubeb_alsa.c
@@ -1126,12 +1126,12 @@ static struct cubeb_ops const alsa_ops =
   .stream_init = alsa_stream_init,
   .stream_destroy = alsa_stream_destroy,
   .stream_start = alsa_stream_start,
   .stream_stop = alsa_stream_stop,
   .stream_get_position = alsa_stream_get_position,
   .stream_get_latency = alsa_stream_get_latency,
   .stream_set_volume = alsa_stream_set_volume,
   .stream_set_panning = alsa_stream_set_panning,
-  .stream_get_current_output_device = NULL,
-  .stream_output_device_destroy = NULL,
+  .stream_get_current_device = NULL,
+  .stream_device_destroy = NULL,
   .stream_register_device_changed_callback = NULL
 };
--- a/media/libcubeb/src/cubeb_audiotrack.c
+++ b/media/libcubeb/src/cubeb_audiotrack.c
@@ -500,12 +500,12 @@ static struct cubeb_ops const audiotrack
   .stream_init = audiotrack_stream_init,
   .stream_destroy = audiotrack_stream_destroy,
   .stream_start = audiotrack_stream_start,
   .stream_stop = audiotrack_stream_stop,
   .stream_get_position = audiotrack_stream_get_position,
   .stream_get_latency = audiotrack_stream_get_latency,
   .stream_set_volume = audiotrack_stream_set_volume,
   .stream_set_panning = audiotrack_stream_set_panning,
-  .stream_get_current_output_device = NULL,
-  .stream_output_device_destroy = NULL,
+  .stream_get_current_device = NULL,
+  .stream_device_destroy = NULL,
   .stream_register_device_changed_callback = NULL
 };
--- a/media/libcubeb/src/cubeb_audiounit.c
+++ b/media/libcubeb/src/cubeb_audiounit.c
@@ -177,16 +177,42 @@ audiounit_get_output_device_id(AudioDevi
                                  device_id);
   if (r != noErr) {
     return CUBEB_ERROR;
   }
 
   return CUBEB_OK;
 }
 
+static int
+audiounit_get_input_device_id(AudioDeviceID * device_id)
+{
+  UInt32 size;
+  OSStatus r;
+  AudioObjectPropertyAddress input_device_address = {
+    kAudioHardwarePropertyDefaultInputDevice,
+    kAudioObjectPropertyScopeGlobal,
+    kAudioObjectPropertyElementMaster
+  };
+
+  size = sizeof(*device_id);
+
+  r = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                 &input_device_address,
+                                 0,
+                                 NULL,
+                                 &size,
+                                 device_id);
+  if (r != noErr) {
+    return CUBEB_ERROR;
+  }
+
+  return CUBEB_OK;
+}
+
 static int audiounit_install_device_changed_callback(cubeb_stream * stm);
 static int audiounit_uninstall_device_changed_callback();
 
 static OSStatus
 audiounit_property_listener_callback(AudioObjectID id, UInt32 address_count,
                                      const AudioObjectPropertyAddress * addresses,
                                      void * user)
 {
@@ -789,73 +815,112 @@ int audiounit_stream_set_panning(cubeb_s
 
   pthread_mutex_lock(&stm->mutex);
   stm->panning = panning;
   pthread_mutex_unlock(&stm->mutex);
 
   return CUBEB_OK;
 }
 
-int audiounit_stream_get_current_output_device(cubeb_stream * stm,
-                                               cubeb_output_device ** const  device)
+int audiounit_stream_get_current_device(cubeb_stream * stm,
+                                        cubeb_device ** const  device)
 {
   OSStatus r;
   UInt32 size;
   UInt32 data;
   char strdata[4];
   AudioDeviceID output_device_id;
+  AudioDeviceID input_device_id;
 
   AudioObjectPropertyAddress datasource_address = {
     kAudioDevicePropertyDataSource,
     kAudioDevicePropertyScopeOutput,
     kAudioObjectPropertyElementMaster
   };
 
+  AudioObjectPropertyAddress datasource_address_input = {
+    kAudioDevicePropertyDataSource,
+    kAudioDevicePropertyScopeInput,
+    kAudioObjectPropertyElementMaster
+  };
+
   *device = NULL;
 
   if (audiounit_get_output_device_id(&output_device_id) != CUBEB_OK) {
     return CUBEB_ERROR;
   }
 
+  *device = malloc(sizeof(cubeb_device));
+  if (!*device) {
+    return CUBEB_ERROR;
+  }
+
   size = sizeof(UInt32);
   /* This fails with some USB headset, so simply return an empty string. */
   r = AudioObjectGetPropertyData(output_device_id,
                                  &datasource_address,
                                  0, NULL, &size, &data);
   if (r != noErr) {
     size = 0;
     data = 0;
   }
 
-  *device = malloc(sizeof(cubeb_output_device));
-  if (!*device) {
+  (*device)->output_name = malloc(size + 1);
+  if (!(*device)->output_name) {
     return CUBEB_ERROR;
   }
 
-  (*device)->name = malloc(size + 1);
-  if (!(*device)->name) {
+  (*device)->output_name = malloc(size + 1);
+  if (!(*device)->output_name) {
     return CUBEB_ERROR;
   }
 
   // Turn the four chars packed into a uint32 into a string
   strdata[0] = (char)(data >> 24);
   strdata[1] = (char)(data >> 16);
   strdata[2] = (char)(data >> 8);
   strdata[3] = (char)(data);
 
-  memcpy((*device)->name, strdata, size);
-  (*device)->name[size] = '\0';
+  memcpy((*device)->output_name, strdata, size);
+  (*device)->output_name[size] = '\0';
+
+  if (audiounit_get_input_device_id(&input_device_id) != CUBEB_OK) {
+    return CUBEB_ERROR;
+  }
+
+  size = sizeof(UInt32);
+  r = AudioObjectGetPropertyData(input_device_id, &datasource_address_input, 0, NULL, &size, &data);
+  if (r != noErr) {
+    printf("Error when getting device !\n");
+    size = 0;
+    data = 0;
+  }
+
+  (*device)->input_name = malloc(size + 1);
+  if (!(*device)->input_name) {
+    return CUBEB_ERROR;
+  }
+
+  // Turn the four chars packed into a uint32 into a string
+  strdata[0] = (char)(data >> 24);
+  strdata[1] = (char)(data >> 16);
+  strdata[2] = (char)(data >> 8);
+  strdata[3] = (char)(data);
+
+  memcpy((*device)->input_name, strdata, size);
+  (*device)->input_name[size] = '\0';
 
   return CUBEB_OK;
 }
 
-int audiounit_stream_output_device_destroy(cubeb_stream * stream,
-                                           cubeb_output_device * device)
+int audiounit_stream_device_destroy(cubeb_stream * stream,
+                                    cubeb_device * device)
 {
-  free(device->name);
+  free(device->output_name);
+  free(device->input_name);
   free(device);
   return CUBEB_OK;
 }
 
 int audiounit_stream_register_device_changed_callback(cubeb_stream * stream,
                                                   cubeb_device_changed_callback  device_changed_callback)
 {
   pthread_mutex_lock(&stream->mutex);
@@ -875,12 +940,12 @@ static struct cubeb_ops const audiounit_
   .stream_init = audiounit_stream_init,
   .stream_destroy = audiounit_stream_destroy,
   .stream_start = audiounit_stream_start,
   .stream_stop = audiounit_stream_stop,
   .stream_get_position = audiounit_stream_get_position,
   .stream_get_latency = audiounit_stream_get_latency,
   .stream_set_volume = audiounit_stream_set_volume,
   .stream_set_panning = audiounit_stream_set_panning,
-  .stream_get_current_output_device = audiounit_stream_get_current_output_device,
-  .stream_output_device_destroy = audiounit_stream_output_device_destroy,
+  .stream_get_current_device = audiounit_stream_get_current_device,
+  .stream_device_destroy = audiounit_stream_device_destroy,
   .stream_register_device_changed_callback = audiounit_stream_register_device_changed_callback
 };
--- a/media/libcubeb/src/cubeb_opensl.c
+++ b/media/libcubeb/src/cubeb_opensl.c
@@ -783,12 +783,12 @@ static struct cubeb_ops const opensl_ops
   .stream_init = opensl_stream_init,
   .stream_destroy = opensl_stream_destroy,
   .stream_start = opensl_stream_start,
   .stream_stop = opensl_stream_stop,
   .stream_get_position = opensl_stream_get_position,
   .stream_get_latency = opensl_stream_get_latency,
   .stream_set_volume = opensl_stream_set_volume,
   .stream_set_panning = opensl_stream_set_panning,
-  .stream_get_current_output_device = NULL,
-  .stream_output_device_destroy = NULL,
+  .stream_get_current_device = NULL,
+  .stream_device_destroy = NULL,
   .stream_register_device_changed_callback = NULL
 };
--- a/media/libcubeb/src/cubeb_pulse.c
+++ b/media/libcubeb/src/cubeb_pulse.c
@@ -744,12 +744,12 @@ static struct cubeb_ops const pulse_ops 
   .stream_init = pulse_stream_init,
   .stream_destroy = pulse_stream_destroy,
   .stream_start = pulse_stream_start,
   .stream_stop = pulse_stream_stop,
   .stream_get_position = pulse_stream_get_position,
   .stream_get_latency = pulse_stream_get_latency,
   .stream_set_volume = pulse_stream_set_volume,
   .stream_set_panning = pulse_stream_set_panning,
-  .stream_get_current_output_device = NULL,
-  .stream_output_device_destroy = NULL,
+  .stream_get_current_device = NULL,
+  .stream_device_destroy = NULL,
   .stream_register_device_changed_callback = NULL
 };
--- a/media/libcubeb/src/cubeb_sndio.c
+++ b/media/libcubeb/src/cubeb_sndio.c
@@ -357,12 +357,12 @@ static struct cubeb_ops const sndio_ops 
   .stream_init = sndio_stream_init,
   .stream_destroy = sndio_stream_destroy,
   .stream_start = sndio_stream_start,
   .stream_stop = sndio_stream_stop,
   .stream_get_position = sndio_stream_get_position,
   .stream_get_latency = sndio_stream_get_latency,
   .stream_set_volume = sndio_stream_set_volume,
   .stream_set_panning = sndio_stream_set_panning,
-  .stream_get_current_output_device = NULL,
-  .stream_output_device_destroy = NULL,
+  .stream_get_current_device = NULL,
+  .stream_device_destroy = NULL,
   .stream_register_device_changed_callback = NULL
 };
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -935,14 +935,14 @@ cubeb_ops const wasapi_ops = {
   /*.stream_init =*/ wasapi_stream_init,
   /*.stream_destroy =*/ wasapi_stream_destroy,
   /*.stream_start =*/ wasapi_stream_start,
   /*.stream_stop =*/ wasapi_stream_stop,
   /*.stream_get_position =*/ wasapi_stream_get_position,
   /*.stream_get_latency =*/ wasapi_stream_get_latency,
   /*.stream_set_volume =*/ wasapi_stream_set_volume,
   /*.stream_set_panning =*/ wasapi_stream_set_panning,
-  /*.stream_get_current_output_device =*/ NULL,
-  /*.stream_output_device_destroy =*/ NULL,
+  /*.stream_get_current_device =*/ NULL,
+  /*.stream_device_destroy =*/ NULL,
   /*.stream_register_device_changed_callback =*/ NULL
  };
 } // namespace anonymous
 
--- a/media/libcubeb/src/cubeb_winmm.c
+++ b/media/libcubeb/src/cubeb_winmm.c
@@ -710,12 +710,12 @@ static struct cubeb_ops const winmm_ops 
   /*.stream_init =*/ winmm_stream_init,
   /*.stream_destroy =*/ winmm_stream_destroy,
   /*.stream_start =*/ winmm_stream_start,
   /*.stream_stop =*/ winmm_stream_stop,
   /*.stream_get_position =*/ winmm_stream_get_position,
   /*.stream_get_latency = */ winmm_stream_get_latency,
   /*.stream_set_volume =*/ winmm_stream_set_volume,
   /*.stream_set_panning =*/ winmm_stream_set_panning,
-  /*.stream_get_current_output_device =*/ NULL,
-  /*.stream_output_device_destroy =*/ NULL,
+  /*.stream_get_current_device =*/ NULL,
+  /*.stream_device_destroy =*/ NULL,
   /*.stream_register_device_changed_callback=*/ NULL
 };