openslessink: Allow setting the stream type via a property
authorArun Raghavan <arun@centricular.com>
Wed, 28 Jan 2015 07:36:39 +0000 (13:06 +0530)
committerArun Raghavan <git@arunraghavan.net>
Sat, 13 Jun 2015 10:33:00 +0000 (16:03 +0530)
sys/opensles/openslescommon.c
sys/opensles/openslescommon.h
sys/opensles/openslesringbuffer.c
sys/opensles/openslesringbuffer.h
sys/opensles/openslessink.c
sys/opensles/openslessink.h

index e35640f..3f4c89e 100644 (file)
@@ -74,3 +74,65 @@ gst_to_opensles_recording_preset (GstOpenSLESRecordingPreset preset)
       return SL_ANDROID_RECORDING_PRESET_NONE;
   }
 }
+
+GType
+gst_opensles_stream_type_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {GST_OPENSLES_STREAM_TYPE_VOICE,
+        "GST_OPENSLES_STREAM_TYPE_VOICE", "voice"},
+    {GST_OPENSLES_STREAM_TYPE_SYSTEM,
+        "GST_OPENSLES_STREAM_TYPE_SYSTEM", "system"},
+    {GST_OPENSLES_STREAM_TYPE_RING,
+        "GST_OPENSLES_STREAM_TYPE_RING", "ring"},
+    {GST_OPENSLES_STREAM_TYPE_MEDIA,
+        "GST_OPENSLES_STREAM_TYPE_MEDIA", "media"},
+    {GST_OPENSLES_STREAM_TYPE_ALARM,
+        "GST_OPENSLES_STREAM_TYPE_ALARM", "alarm"},
+    {GST_OPENSLES_STREAM_TYPE_NOTIFICATION,
+        "GST_OPENSLES_STREAM_TYPE_NOTIFICATION", "notification"},
+    {GST_OPENSLES_STREAM_TYPE_NONE,
+        "GST_OPENSLES_STREAM_TYPE_NONE", "none"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstOpenSLESStreamType", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+
+SLint32
+gst_to_opensles_stream_type (GstOpenSLESStreamType stream_type)
+{
+  switch (stream_type) {
+    case GST_OPENSLES_STREAM_TYPE_VOICE:
+      return SL_ANDROID_STREAM_VOICE;
+
+    case GST_OPENSLES_STREAM_TYPE_SYSTEM:
+      return SL_ANDROID_STREAM_SYSTEM;
+
+    case GST_OPENSLES_STREAM_TYPE_RING:
+      return SL_ANDROID_STREAM_RING;
+
+    case GST_OPENSLES_STREAM_TYPE_MEDIA:
+      return SL_ANDROID_STREAM_MEDIA;
+
+    case GST_OPENSLES_STREAM_TYPE_ALARM:
+      return SL_ANDROID_STREAM_ALARM;
+
+    case GST_OPENSLES_STREAM_TYPE_NOTIFICATION:
+      return SL_ANDROID_STREAM_NOTIFICATION;
+
+    default:
+      GST_ERROR ("Unsupported stream type: %d", (int) stream_type);
+      return SL_ANDROID_STREAM_MEDIA;
+  }
+}
index 44ae065..181442b 100644 (file)
@@ -43,6 +43,23 @@ GType gst_opensles_recording_preset_get_type (void);
 
 SLint32 gst_to_opensles_recording_preset (GstOpenSLESRecordingPreset preset);
 
+typedef enum {
+  GST_OPENSLES_STREAM_TYPE_VOICE,
+  GST_OPENSLES_STREAM_TYPE_SYSTEM,
+  GST_OPENSLES_STREAM_TYPE_RING,
+  GST_OPENSLES_STREAM_TYPE_MEDIA,
+  GST_OPENSLES_STREAM_TYPE_ALARM,
+  GST_OPENSLES_STREAM_TYPE_NOTIFICATION,
+  GST_OPENSLES_STREAM_TYPE_NONE = -1, /* If we don't want to set a type */
+} GstOpenSLESStreamType;
+
+#define GST_TYPE_OPENSLES_STREAM_TYPE \
+  (gst_opensles_stream_type_get_type())
+
+GType gst_opensles_stream_type_get_type (void);
+
+SLint32 gst_to_opensles_stream_type (GstOpenSLESStreamType stream_type);
+
 G_END_DECLS
 
 #endif /* __OPENSLESCOMMON_H__ */
index 28263e5..085baa5 100644 (file)
@@ -378,6 +378,7 @@ _opensles_player_acquire (GstAudioRingBuffer * rb,
   GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
   SLresult result;
   SLDataFormat_PCM format;
+  SLAndroidConfigurationItf config;
 
   /* Configure audio source
    * 4 buffers is the "typical" size as optimized inside Android's
@@ -399,21 +400,46 @@ _opensles_player_acquire (GstAudioRingBuffer * rb,
   SLDataSink audioSink = { &loc_outmix, NULL };
 
   /* Define the required interfaces */
-  const SLInterfaceID ids[2] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME };
-  const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
+  const SLInterfaceID ids[3] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME,
+    SL_IID_ANDROIDCONFIGURATION
+  };
+  const SLboolean req[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
+    SL_BOOLEAN_FALSE
+  };
 
   /* Define the format in OpenSL ES terminology */
   _opensles_format (spec, &format);
 
   /* Create the player object */
   result = (*thiz->engineEngine)->CreateAudioPlayer (thiz->engineEngine,
-      &thiz->playerObject, &audioSrc, &audioSink, 2, ids, req);
+      &thiz->playerObject, &audioSrc, &audioSink, 3, ids, req);
   if (result != SL_RESULT_SUCCESS) {
     GST_ERROR_OBJECT (thiz, "engine.CreateAudioPlayer failed(0x%08x)",
         (guint32) result);
     goto failed;
   }
 
+  /* Set the stream type if we have one */
+  if (thiz->stream_type != GST_OPENSLES_STREAM_TYPE_NONE) {
+    SLint32 stream_type = gst_to_opensles_stream_type (thiz->stream_type);
+
+    result = (*thiz->playerObject)->GetInterface (thiz->playerObject,
+        SL_IID_ANDROIDCONFIGURATION, &config);
+
+    if (result == SL_RESULT_SUCCESS) {
+      result = (*config)->SetConfiguration (config,
+          SL_ANDROID_KEY_STREAM_TYPE, &stream_type, sizeof (stream_type));
+
+      if (result != SL_RESULT_SUCCESS) {
+        GST_WARNING_OBJECT (thiz, "Failed to set playback stream type (0x%08x)",
+            (guint32) result);
+      }
+    } else {
+      GST_WARNING_OBJECT (thiz,
+          "Could not get configuration interface 0x%08x", (guint32) result);
+    }
+  }
+
   /* Realize the player object */
   result =
       (*thiz->playerObject)->Realize (thiz->playerObject, SL_BOOLEAN_FALSE);
index 3d22426..2b90d36 100644 (file)
@@ -81,6 +81,7 @@ struct _GstOpenSLESRingBuffer
   gfloat volume;
   gboolean mute;
   gint is_prerolled; /* ATOMIC */
+  GstOpenSLESStreamType stream_type;
 
   /* recorder interfaces */
   SLObjectItf recorderObject;
index 236f8b3..ce93d25 100644 (file)
@@ -47,12 +47,15 @@ enum
   PROP_0,
   PROP_VOLUME,
   PROP_MUTE,
+  PROP_STREAM_TYPE,
   PROP_LAST
 };
 
 #define DEFAULT_VOLUME 1.0
 #define DEFAULT_MUTE   FALSE
 
+#define DEFAULT_STREAM_TYPE GST_OPENSLES_STREAM_TYPE_NONE
+
 
 /* According to Android's NDK doc the following are the supported rates */
 #define RATES "8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100"
@@ -85,6 +88,9 @@ gst_opensles_sink_create_ringbuffer (GstAudioBaseSink * base)
   rb = gst_opensles_ringbuffer_new (RB_MODE_SINK_PCM);
   gst_opensles_ringbuffer_set_volume (rb, sink->volume);
   gst_opensles_ringbuffer_set_mute (rb, sink->mute);
+
+  GST_OPENSLES_RING_BUFFER (rb)->stream_type = sink->stream_type;
+
   return rb;
 }
 
@@ -208,6 +214,9 @@ gst_opensles_sink_set_property (GObject * object, guint prop_id,
         gst_opensles_ringbuffer_set_mute (rb, sink->mute);
       }
       break;
+    case PROP_STREAM_TYPE:
+      sink->stream_type = g_value_get_enum (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -226,6 +235,9 @@ gst_opensles_sink_get_property (GObject * object, guint prop_id,
     case PROP_MUTE:
       g_value_set_boolean (value, sink->mute);
       break;
+    case PROP_STREAM_TYPE:
+      g_value_set_enum (value, sink->stream_type);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -254,6 +266,12 @@ gst_opensles_sink_class_init (GstOpenSLESSinkClass * klass)
       g_param_spec_boolean ("mute", "Mute", "Mute state of this stream",
           DEFAULT_MUTE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_STREAM_TYPE,
+      g_param_spec_enum ("stream-type", "Stream type",
+          "Stream type that this stream should be tagged with",
+          GST_TYPE_OPENSLES_STREAM_TYPE, DEFAULT_STREAM_TYPE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&sink_factory));
 
@@ -269,6 +287,7 @@ gst_opensles_sink_class_init (GstOpenSLESSinkClass * klass)
 static void
 gst_opensles_sink_init (GstOpenSLESSink * sink)
 {
+  sink->stream_type = DEFAULT_STREAM_TYPE;
   sink->volume = DEFAULT_VOLUME;
   sink->mute = DEFAULT_MUTE;
 
index 84abf9f..69e6f2d 100644 (file)
@@ -40,6 +40,8 @@ struct _GstOpenSLESSink
 {
   GstAudioBaseSink sink;
 
+  GstOpenSLESStreamType stream_type;
+
   gfloat volume;
   gboolean mute;
 };