static GstAudioRingBuffer * gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink) { GstOsxAudioSink *osxsink; GstOsxAudioRingBuffer *ringbuffer; osxsink = GST_OSX_AUDIO_SINK (sink); if (!gst_osx_audio_sink_select_device (osxsink)) { GST_ERROR_OBJECT (sink, "Could not select device"); return NULL; } GST_DEBUG_OBJECT (sink, "Creating ringbuffer"); ringbuffer = g_object_new (GST_TYPE_OSX_AUDIO_RING_BUFFER, NULL); GST_DEBUG_OBJECT (sink, "osx sink %p element %p ioproc %p", osxsink, GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink), (void *) gst_osx_audio_sink_io_proc); gst_osx_audio_sink_set_volume (osxsink); ringbuffer->core_audio->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink); ringbuffer->core_audio->device_id = osxsink->device_id; ringbuffer->core_audio->is_src = FALSE; return GST_AUDIO_RING_BUFFER (ringbuffer); }
/* GstBaseSink vmethod implementations */ static GstCaps * gst_osx_audio_sink_getcaps (GstBaseSink * sink) { GstCaps *caps; GstOsxAudioSink *osxsink; OSStatus status; AudioValueRange rates[10]; UInt32 propertySize; int i; propertySize = sizeof (AudioValueRange) * 9; osxsink = GST_OSX_AUDIO_SINK (sink); caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (sink))); status = AudioDeviceGetProperty (osxsink->ringbuffer->device_id, 0, FALSE, kAudioDevicePropertyAvailableNominalSampleRates, &propertySize, &rates); GST_DEBUG ("Getting available sample rates: Status: %ld number of ranges: %lu", status, propertySize / sizeof (AudioValueRange)); for (i = 0; i < propertySize / sizeof (AudioValueRange); i++) { GST_LOG_OBJECT (osxsink, "Range from %f to %f", rates[i].mMinimum, rates[i].mMaximum); } return caps; }
static gboolean gst_osx_audio_sink_stop (GstBaseSink * base) { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (base); if (sink->cached_caps) { gst_caps_unref (sink->cached_caps); sink->cached_caps = NULL; } return GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SINK_CLASS, stop, (base), TRUE); }
static void gst_osx_audio_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (object); switch (prop_id) { case ARG_DEVICE: if (sink->ringbuffer) sink->ringbuffer->device_id = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/* GstBaseAudioSink vmethod implementations */ static GstRingBuffer * gst_osx_audio_sink_create_ringbuffer (GstBaseAudioSink * sink) { GstOsxAudioSink *osxsink; osxsink = GST_OSX_AUDIO_SINK (sink); if (!osxsink->ringbuffer) { GST_DEBUG ("Creating ringbuffer"); osxsink->ringbuffer = g_object_new (GST_TYPE_OSX_RING_BUFFER, NULL); GST_DEBUG ("osx sink 0x%p element 0x%p ioproc 0x%p", osxsink, GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink), (void *) gst_osx_audio_sink_io_proc); osxsink->ringbuffer->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink); } return GST_RING_BUFFER (osxsink->ringbuffer); }
static GstCaps * gst_osx_audio_sink_getcaps (GstBaseSink * base, GstCaps * filter) { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (base); gchar *caps_string = NULL; if (sink->cached_caps) { caps_string = gst_caps_to_string (sink->cached_caps); GST_DEBUG_OBJECT (sink, "using cached caps: %s", caps_string); g_free (caps_string); if (filter) return gst_caps_intersect_full (sink->cached_caps, filter, GST_CAPS_INTERSECT_FIRST); return gst_caps_ref (sink->cached_caps); } GST_DEBUG_OBJECT (sink, "using template caps"); return NULL; }
static void gst_osx_audio_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { 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; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static OSStatus _audio_stream_hardware_changed_listener (AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void *inClientData) { OSStatus status = noErr; guint i; GstCoreAudio *core_audio = inClientData; for (i = 0; i < inNumberAddresses; i++) { if (inAddresses[i].mSelector == kAudioDevicePropertyDeviceHasChanged) { if (!gst_core_audio_audio_device_is_spdif_avail (core_audio->device_id)) { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (GST_OBJECT_PARENT (core_audio->osxbuf)); GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, ("SPDIF output no longer available"), ("Audio device is reporting that SPDIF output isn't available")); } break; } } return (status); }
static gboolean gst_osx_audio_sink_query (GstBaseSink * base, GstQuery * query) { GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (base); gboolean ret = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_ACCEPT_CAPS: { GstCaps *caps = NULL; gst_query_parse_accept_caps (query, &caps); ret = gst_osx_audio_sink_acceptcaps (sink, caps); gst_query_set_accept_caps_result (query, ret); ret = TRUE; break; } default: ret = GST_BASE_SINK_CLASS (parent_class)->query (base, query); break; } return ret; }