From c853d8dac0585b43ae6d2a559bf5306deb080047 Mon Sep 17 00:00:00 2001 From: Andoni Morales Alastruey Date: Tue, 5 Mar 2013 21:22:18 +0100 Subject: [PATCH] osxaudio: add support for iOS using the RemoteIO AudioUnit --- configure.ac | 12 +++- sys/osxaudio/Makefile.am | 13 +++- sys/osxaudio/gstosxaudioelement.h | 8 +++ sys/osxaudio/gstosxaudiosink.c | 6 ++ sys/osxaudio/gstosxcoreaudio.c | 4 ++ sys/osxaudio/gstosxcoreaudioremoteio.c | 127 +++++++++++++++++++++++++++++++++ 6 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 sys/osxaudio/gstosxcoreaudioremoteio.c diff --git a/configure.ac b/configure.ac index 9817ab7..352b0c8 100644 --- a/configure.ac +++ b/configure.ac @@ -444,9 +444,19 @@ AG_GST_CHECK_FEATURE(SUNAUDIO, [Sun Audio], sunaudio, [ dnl *** OSX Audio *** translit(dnm, m, l) AM_CONDITIONAL(USE_OSX_AUDIO, true) +have_ios="no" AG_GST_CHECK_FEATURE(OSX_AUDIO, [OSX audio], osxaudio, [ - AC_CHECK_HEADER(CoreAudio/CoreAudio.h, HAVE_OSX_AUDIO="yes", HAVE_OSX_AUDIO="no") + AC_CHECK_HEADER(CoreAudio/CoreAudio.h, + HAVE_OSX_AUDIO="yes", + dnl *** Check for the iOS headers *** + [AC_CHECK_HEADER(CoreAudio/CoreAudioTypes.h, + [HAVE_OSX_AUDIO="YES";have_ios="yes"], HAVE_OSX_AUDIO="no" + )]) ]) +if test "x$have_ios" = "xyes"; then + AC_DEFINE(HAVE_IOS, 1, [building for iOS platofrm]) +fi +AM_CONDITIONAL(HAVE_IOS, test "x$have_ios" = "xyes") dnl *** OS X video *** translit(dnm, m, l) AM_CONDITIONAL(USE_OSX_VIDEO, true) diff --git a/sys/osxaudio/Makefile.am b/sys/osxaudio/Makefile.am index caddda2..6f75b12 100644 --- a/sys/osxaudio/Makefile.am +++ b/sys/osxaudio/Makefile.am @@ -16,8 +16,14 @@ libgstosxaudio_la_LIBADD = \ $(GST_PLUGINS_BASE_LIBS) \ $(GST_BASE_LIBS) \ $(GST_LIBS) -libgstosxaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework -Wl,CoreAudio -Wl,-framework -Wl,AudioUnit -Wl,-framework -Wl,AudioToolbox -Wl,-framework -Wl,CoreServices -libgstosxaudio_la_LIBTOOLFLAGS = --tag=disable-static + +libgstosxaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox + +if !HAVE_IOS +libgstosxaudio_la_LDFLAGS += -Wl,-framework,AudioUnit -Wl,-framework,CoreServices +endif + +libgstosxaudio_la_LIBTOOLFLAGS = --tag=disable-static --tag=CC noinst_HEADERS = gstosxaudiosink.h \ gstosxaudioelement.h \ @@ -25,7 +31,8 @@ noinst_HEADERS = gstosxaudiosink.h \ gstosxaudiosrc.h \ gstosxcoreaudiocommon.h \ gstosxcoreaudio.h \ - gstosxcoreaudiohal.c + gstosxcoreaudiohal.c \ + gstosxcoreaudioremoteio.c diff --git a/sys/osxaudio/gstosxaudioelement.h b/sys/osxaudio/gstosxaudioelement.h index 3bcb421..3e09dc1 100644 --- a/sys/osxaudio/gstosxaudioelement.h +++ b/sys/osxaudio/gstosxaudioelement.h @@ -49,8 +49,16 @@ #ifndef __GST_OSX_AUDIO_ELEMENT_H__ #define __GST_OSX_AUDIO_ELEMENT_H__ +#ifdef HAVE_CONFIG_H +# include +#endif + #include +#ifdef HAVE_IOS +#include +#else #include +#endif #include G_BEGIN_DECLS diff --git a/sys/osxaudio/gstosxaudiosink.c b/sys/osxaudio/gstosxaudiosink.c index 43a9d30..5de0443 100644 --- a/sys/osxaudio/gstosxaudiosink.c +++ b/sys/osxaudio/gstosxaudiosink.c @@ -210,9 +210,11 @@ gst_osx_audio_sink_class_init (GstOsxAudioSinkClass * klass) gobject_class->set_property = gst_osx_audio_sink_set_property; gobject_class->get_property = gst_osx_audio_sink_get_property; +#ifndef HAVE_IOS g_object_class_install_property (gobject_class, ARG_DEVICE, g_param_spec_int ("device", "Device ID", "Device ID of output device", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif g_object_class_install_property (gobject_class, ARG_VOLUME, g_param_spec_double ("volume", "Volume", "Volume of this stream", @@ -248,9 +250,11 @@ gst_osx_audio_sink_set_property (GObject * object, guint prop_id, GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (object); switch (prop_id) { +#ifndef HAVE_IOS case ARG_DEVICE: sink->device_id = g_value_get_int (value); break; +#endif case ARG_VOLUME: sink->volume = g_value_get_double (value); gst_osx_audio_sink_set_volume (sink); @@ -267,9 +271,11 @@ gst_osx_audio_sink_get_property (GObject * object, guint prop_id, { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (object); switch (prop_id) { +#ifndef HAVE_IOS case ARG_DEVICE: g_value_set_int (value, sink->device_id); break; +#endif case ARG_VOLUME: g_value_set_double (value, sink->volume); break; diff --git a/sys/osxaudio/gstosxcoreaudio.c b/sys/osxaudio/gstosxcoreaudio.c index aa08223..6109bb9 100644 --- a/sys/osxaudio/gstosxcoreaudio.c +++ b/sys/osxaudio/gstosxcoreaudio.c @@ -30,7 +30,11 @@ GST_DEBUG_CATEGORY_STATIC (osx_audio_debug); G_DEFINE_TYPE (GstCoreAudio, gst_core_audio, G_TYPE_OBJECT); +#ifdef HAVE_IOS +#include "gstosxcoreaudioremoteio.c" +#else #include "gstosxcoreaudiohal.c" +#endif static void diff --git a/sys/osxaudio/gstosxcoreaudioremoteio.c b/sys/osxaudio/gstosxcoreaudioremoteio.c new file mode 100644 index 0000000..076bd11 --- /dev/null +++ b/sys/osxaudio/gstosxcoreaudioremoteio.c @@ -0,0 +1,127 @@ +/* + * GStreamer + * Copyright (C) 2012 Fluendo S.A. + * Authors: Andoni Morales Alastruey + * + * 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. + * + */ + +#import + +static gboolean +gst_core_audio_open_impl (GstCoreAudio * core_audio) +{ + return gst_core_audio_open_device (core_audio, kAudioUnitSubType_RemoteIO, + "RemoteIO"); +} + +static gboolean +gst_core_audio_start_processing_impl (GstCoreAudio * core_audio) +{ + return gst_core_audio_io_proc_start (core_audio); +} + +static gboolean +gst_core_audio_pause_processing_impl (GstCoreAudio * core_audio) +{ + GST_DEBUG_OBJECT (core_audio, + "osx ring buffer pause ioproc: %p device_id %lu", + core_audio->element->io_proc, (gulong) core_audio->device_id); + + if (core_audio->io_proc_active) { + /* CoreAudio isn't threadsafe enough to do this here; + * we must deactivate the render callback elsewhere. See: + * http://lists.apple.com/archives/Coreaudio-api/2006/Mar/msg00010.html + */ + core_audio->io_proc_needs_deactivation = TRUE; + } + return TRUE; +} + +static gboolean +gst_core_audio_stop_processing_impl (GstCoreAudio * core_audio) +{ + gst_core_audio_io_proc_stop (core_audio); + return TRUE; +} + +static gboolean +gst_core_audio_get_samples_and_latency_impl (GstCoreAudio * core_audio, + gdouble rate, guint * samples, gdouble * latency) +{ + OSStatus status; + UInt32 size; + + status = AudioUnitGetProperty (core_audio->audiounit, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, /* N/A for global */ + latency, &size); + + if (status) { + GST_WARNING_OBJECT (core_audio, "Failed to get latency: %" + GST_FOURCC_FORMAT, GST_FOURCC_ARGS (status)); + *samples = 0; + return FALSE; + } + + *samples = *latency * rate; + return TRUE; +} + +static gboolean +gst_core_audio_initialize_impl (GstCoreAudio * core_audio, + AudioStreamBasicDescription format, GstCaps * caps, + gboolean is_passthrough, guint32 * frame_size) +{ + core_audio->is_passthrough = is_passthrough; + core_audio->stream_idx = 0; + if (!gst_core_audio_set_format (core_audio, format)) + return FALSE; + + /* FIXME: Use kAudioSessionProperty_CurrentHardwareSampleRate and + * kAudioSessionProperty_CurrentHardwareIOBufferDuration with property + * listeners to detect changes in screen locks. + * For now use the maximum value */ + *frame_size = 4196; + + GST_DEBUG_OBJECT (core_audio, "osxbuf ring buffer acquired"); + return TRUE; +} + +AudioChannelLayout * +gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id) +{ + return NULL; +} + +static gboolean +gst_core_audio_select_device_impl (AudioDeviceID * device_id) +{ + /* No device selection in iOS */ + return TRUE; +} + +static gboolean +gst_core_audio_select_source_device_impl (AudioDeviceID * device_id) +{ + return TRUE; +} + +static gboolean +gst_core_audio_audio_device_is_spdif_avail_impl (AudioDeviceID device_id) +{ + /* No SPDIF in iOS */ + return FALSE; +} -- 2.7.4