diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-11-01 15:35:17 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-11-01 15:38:23 +0100 |
commit | 40ca6ed9770eeb66ebf47fadca71ac9c8a584850 (patch) | |
tree | 74cd218b2b82346d24afefc3f727dfd3727dd319 /sys/opensles | |
parent | 92fffc8cbec464f9fef96fbd3e3ec5855f98c812 (diff) |
opensles: Make sure to only ever create a single engine object
The OpenSL ES spec defines:
An implementation shall enable creation of at least one such object, but
attempting to create more instances (either by a single application or by
several different applications) may fail.
Diffstat (limited to 'sys/opensles')
-rw-r--r-- | sys/opensles/opensles.c | 55 | ||||
-rw-r--r-- | sys/opensles/opensles.h | 30 | ||||
-rw-r--r-- | sys/opensles/openslesringbuffer.c | 19 | ||||
-rw-r--r-- | sys/opensles/openslessink.c | 18 |
4 files changed, 97 insertions, 25 deletions
diff --git a/sys/opensles/opensles.c b/sys/opensles/opensles.c index 5f331be31..9351783cf 100644 --- a/sys/opensles/opensles.c +++ b/sys/opensles/opensles.c @@ -21,12 +21,67 @@ #include "config.h" #endif +#include <gst/gst.h> +#include <SLES/OpenSLES.h> + +#include "opensles.h" #include "openslessink.h" #include "openslessrc.h" +static GMutex engine_mutex; +static SLObjectItf engine_object = NULL; +static gint engine_object_refcount = 0; + +SLObjectItf +gst_opensles_get_engine (void) +{ + g_mutex_lock (&engine_mutex); + if (!engine_object) { + SLresult result; + result = slCreateEngine (&engine_object, 0, NULL, 0, NULL, NULL); + if (result != SL_RESULT_SUCCESS) { + GST_ERROR ("slCreateEngine failed(0x%08x)", (guint32) result); + engine_object = NULL; + } + + result = (*engine_object)->Realize (engine_object, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) { + GST_ERROR ("engine.Realize failed(0x%08x)", (guint32) result); + (*engine_object)->Destroy (engine_object); + engine_object = NULL; + } + } + + if (engine_object) { + engine_object_refcount++; + } + g_mutex_unlock (&engine_mutex); + + return engine_object; +} + +void +gst_opensles_release_engine (SLObjectItf engine_object_parameter) +{ + g_mutex_lock (&engine_mutex); + g_assert (engine_object == engine_object_parameter); + + if (engine_object) { + engine_object_refcount--; + + if (engine_object_refcount == 0) { + (*engine_object)->Destroy (engine_object); + engine_object = NULL; + } + } + g_mutex_unlock (&engine_mutex); +} + static gboolean plugin_init (GstPlugin * plugin) { + g_mutex_init (&engine_mutex); + if (!gst_element_register (plugin, "openslessink", GST_RANK_PRIMARY, GST_TYPE_OPENSLES_SINK)) { return FALSE; diff --git a/sys/opensles/opensles.h b/sys/opensles/opensles.h new file mode 100644 index 000000000..57039af33 --- /dev/null +++ b/sys/opensles/opensles.h @@ -0,0 +1,30 @@ +/* GStreamer + * Copyright (C) 2012 Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __OPENSLES_H__ +#define __OPENSLES_H__ + +#include <gst/gst.h> +#include <SLES/OpenSLES.h> + +SLObjectItf gst_opensles_get_engine (void); +void gst_opensles_release_engine (SLObjectItf engine_object); + +#endif /* __OPENSLES_H__ */ diff --git a/sys/opensles/openslesringbuffer.c b/sys/opensles/openslesringbuffer.c index 9db86c6e2..b5dbc80cb 100644 --- a/sys/opensles/openslesringbuffer.c +++ b/sys/opensles/openslesringbuffer.c @@ -21,6 +21,7 @@ # include <config.h> #endif +#include "opensles.h" #include "openslesringbuffer.h" GST_DEBUG_CATEGORY_STATIC (opensles_ringbuffer_debug); @@ -683,18 +684,10 @@ gst_opensles_ringbuffer_open_device (GstAudioRingBuffer * rb) thiz = GST_OPENSLES_RING_BUFFER_CAST (rb); - /* Create the engine object */ - result = slCreateEngine (&thiz->engineObject, 0, NULL, 0, NULL, NULL); - if (result != SL_RESULT_SUCCESS) { - GST_ERROR_OBJECT (thiz, "slCreateEngine failed(0x%08x)", (guint32) result); - goto failed; - } - - /* Realize the engine object */ - result = (*thiz->engineObject)->Realize (thiz->engineObject, - SL_BOOLEAN_FALSE); - if (result != SL_RESULT_SUCCESS) { - GST_ERROR_OBJECT (thiz, "engine.Realize failed(0x%08x)", (guint32) result); + /* Create and realize the engine object */ + thiz->engineObject = gst_opensles_get_engine (); + if (!thiz->engineObject) { + GST_ERROR_OBJECT (thiz, "Failed to get engine object"); goto failed; } @@ -771,7 +764,7 @@ gst_opensles_ringbuffer_close_device (GstAudioRingBuffer * rb) /* Destroy the engine object and invalidate all associated interfaces */ if (thiz->engineObject) { - (*thiz->engineObject)->Destroy (thiz->engineObject); + gst_opensles_release_engine (thiz->engineObject); thiz->engineObject = NULL; thiz->engineEngine = NULL; } diff --git a/sys/opensles/openslessink.c b/sys/opensles/openslessink.c index 60deb1815..e679db189 100644 --- a/sys/opensles/openslessink.c +++ b/sys/opensles/openslessink.c @@ -36,6 +36,7 @@ # include <config.h> #endif +#include "opensles.h" #include "openslessink.h" GST_DEBUG_CATEGORY_STATIC (opensles_sink_debug); @@ -109,17 +110,10 @@ _opensles_query_capabilities (GstOpenSLESSink * sink) SLuint32 outputDeviceIDs[MAX_NUMBER_OUTPUT_DEVICES]; SLAudioOutputDescriptor audioOutputDescriptor; - /* Create engine */ - result = slCreateEngine (&engineObject, 0, NULL, 0, NULL, NULL); - if (result != SL_RESULT_SUCCESS) { - GST_ERROR_OBJECT (sink, "slCreateEngine failed(0x%08x)", (guint32) result); - goto beach; - } - - /* Realize the engine */ - result = (*engineObject)->Realize (engineObject, SL_BOOLEAN_FALSE); - if (result != SL_RESULT_SUCCESS) { - GST_ERROR_OBJECT (sink, "engine.Realize failed(0x%08x)", (guint32) result); + /* Create and realize engine */ + engineObject = gst_opensles_get_engine (); + if (!engineObject) { + GST_ERROR_OBJECT (sink, "Getting engine failed"); goto beach; } @@ -171,7 +165,7 @@ _opensles_query_capabilities (GstOpenSLESSink * sink) beach: /* Destroy the engine object */ if (engineObject) { - (*engineObject)->Destroy (engineObject); + gst_opensles_release_engine (engineObject); } return res; |