From e3ed00e4eb89a9821d57c6a81ce40d9d945833e9 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 28 Jan 2015 13:06:39 +0530 Subject: [PATCH] openslessink: Allow setting the stream type via a property --- sys/opensles/openslescommon.c | 62 +++++++++++++++++++++++++++++++ sys/opensles/openslescommon.h | 17 +++++++++ sys/opensles/openslesringbuffer.c | 32 ++++++++++++++-- sys/opensles/openslesringbuffer.h | 1 + sys/opensles/openslessink.c | 19 ++++++++++ sys/opensles/openslessink.h | 2 + 6 files changed, 130 insertions(+), 3 deletions(-) diff --git a/sys/opensles/openslescommon.c b/sys/opensles/openslescommon.c index e35640f735..3f4c89ecc6 100644 --- a/sys/opensles/openslescommon.c +++ b/sys/opensles/openslescommon.c @@ -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; + } +} diff --git a/sys/opensles/openslescommon.h b/sys/opensles/openslescommon.h index 44ae065d23..181442b3ec 100644 --- a/sys/opensles/openslescommon.h +++ b/sys/opensles/openslescommon.h @@ -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__ */ diff --git a/sys/opensles/openslesringbuffer.c b/sys/opensles/openslesringbuffer.c index 28263e5793..085baa55e7 100644 --- a/sys/opensles/openslesringbuffer.c +++ b/sys/opensles/openslesringbuffer.c @@ -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); diff --git a/sys/opensles/openslesringbuffer.h b/sys/opensles/openslesringbuffer.h index 3d2242641d..2b90d36ef3 100644 --- a/sys/opensles/openslesringbuffer.h +++ b/sys/opensles/openslesringbuffer.h @@ -81,6 +81,7 @@ struct _GstOpenSLESRingBuffer gfloat volume; gboolean mute; gint is_prerolled; /* ATOMIC */ + GstOpenSLESStreamType stream_type; /* recorder interfaces */ SLObjectItf recorderObject; diff --git a/sys/opensles/openslessink.c b/sys/opensles/openslessink.c index 236f8b3c6f..ce93d25083 100644 --- a/sys/opensles/openslessink.c +++ b/sys/opensles/openslessink.c @@ -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; diff --git a/sys/opensles/openslessink.h b/sys/opensles/openslessink.h index 84abf9fc35..69e6f2d919 100644 --- a/sys/opensles/openslessink.h +++ b/sys/opensles/openslessink.h @@ -40,6 +40,8 @@ struct _GstOpenSLESSink { GstAudioBaseSink sink; + GstOpenSLESStreamType stream_type; + gfloat volume; gboolean mute; };