gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
src->device_id = kAudioDeviceUnknown;
- src->deviceChannels = -1;
+ src->cached_caps = NULL;
}
static void
GstOsxAudioRingBuffer *ringbuffer =
GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SRC (osxsrc)->ringbuffer);
GstCoreAudio *core_audio = ringbuffer->core_audio;
+ GstCaps *caps;
AudioStreamBasicDescription asbd_in;
UInt32 propertySize;
OSStatus status;
status = AudioUnitGetProperty (core_audio->audiounit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 1, &asbd_in, &propertySize);
+ if (status)
+ goto fail;
- if (status) {
- AudioComponentInstanceDispose (core_audio->audiounit);
- core_audio->audiounit = NULL;
- GST_WARNING_OBJECT (core_audio,
- "Unable to obtain device properties: %d", (int) status);
- } else {
- osxsrc->deviceChannels = asbd_in.mChannelsPerFrame;
- }
+ caps = gst_core_audio_asbd_to_caps (&asbd_in);
+ if (!caps)
+ GST_WARNING_OBJECT (osxsrc, "Could not get caps from stream description");
+ else
+ GST_DEBUG_OBJECT (osxsrc, "Got caps on device: %p", caps);
+
+ if (osxsrc->cached_caps)
+ gst_caps_unref (osxsrc->cached_caps);
+
+ osxsrc->cached_caps = caps;
+
+ return;
+
+fail:
+ AudioComponentInstanceDispose (core_audio->audiounit);
+ core_audio->audiounit = NULL;
+ GST_WARNING_OBJECT (osxsrc,
+ "Unable to obtain device properties: %d", (int) status);
}
static GstCaps *
GstElementClass *gstelement_class;
GstOsxAudioSrc *osxsrc;
GstAudioRingBuffer *buf;
- GstPadTemplate *pad_template;
- GstCaps *caps;
- gint min, max;
+ GstCaps *ret = NULL;
gstelement_class = GST_ELEMENT_GET_CLASS (src);
osxsrc = GST_OSX_AUDIO_SRC (src);
if (buf) {
GST_OBJECT_LOCK (buf);
- if (buf->open && osxsrc->deviceChannels == -1) {
+
+ if (buf->acquired) {
+ /* Caps are fixed, use what we have */
+ ret = gst_pad_get_current_caps (GST_BASE_SINK_PAD (src));
+ if (!ret) {
+ GST_OBJECT_UNLOCK (buf);
+ g_return_val_if_reached (NULL);
+ }
+
+ } else if (buf->open && !osxsrc->cached_caps) {
/* Device is open, let's probe its caps */
gst_osx_audio_src_probe_caps (osxsrc);
}
- GST_OBJECT_UNLOCK (buf);
- }
- if (osxsrc->deviceChannels == -1) {
- /* -1 means we don't know the number of channels yet. for now, return
- * template caps.
- */
- return NULL;
+ GST_OBJECT_UNLOCK (buf);
}
- max = osxsrc->deviceChannels;
- if (max < 1)
- max = 1; /* 0 channels means 1 channel? */
+ if (!ret && osxsrc->cached_caps)
+ ret = gst_caps_ref (osxsrc->cached_caps);
- min = MIN (1, max);
-
- pad_template = gst_element_class_get_pad_template (gstelement_class, "src");
- g_return_val_if_fail (pad_template != NULL, NULL);
-
- caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
-
- if (min == max) {
- gst_caps_set_simple (caps, "channels", G_TYPE_INT, max, NULL);
- } else {
- gst_caps_set_simple (caps, "channels", GST_TYPE_INT_RANGE, min, max, NULL);
+ if (filter) {
+ GstCaps *tmp;
+ tmp = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (ret);
+ ret = tmp;
}
- return caps;
+ return ret;
}
static GstAudioRingBuffer *
{
return gst_core_audio_audio_device_is_spdif_avail_impl (device_id);
}
+
+GstCaps *
+gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd)
+{
+ GstAudioInfo info;
+ GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
+ int rate, channels, bps, endianness;
+ gboolean sign, interleaved;
+
+ if (asbd->mFormatID != kAudioFormatLinearPCM) {
+ GST_WARNING ("Only linear PCM is supported");
+ goto error;
+ }
+
+ if (!(asbd->mFormatFlags & kAudioFormatFlagIsPacked)) {
+ GST_WARNING ("Only packed formats supported");
+ goto error;
+ }
+
+ if (asbd->mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) {
+ GST_WARNING ("Fixed point audio is unsupported");
+ goto error;
+ }
+
+ rate = asbd->mSampleRate;
+ if (rate == kAudioStreamAnyRate)
+ rate = GST_AUDIO_DEF_RATE;
+
+ channels = asbd->mChannelsPerFrame;
+ if (channels == 0) {
+ /* The documentation says this should not happen! */
+ channels = 1;
+ }
+
+ bps = asbd->mBitsPerChannel;
+ endianness = asbd->mFormatFlags & kAudioFormatFlagIsBigEndian ?
+ G_BIG_ENDIAN : G_LITTLE_ENDIAN;
+ sign = asbd->mFormatID & kAudioFormatFlagIsSignedInteger ? TRUE : FALSE;
+ interleaved = asbd->mFormatFlags & kAudioFormatFlagIsNonInterleaved ?
+ TRUE : FALSE;
+
+ if (asbd->mFormatFlags & kAudioFormatFlagIsFloat) {
+ if (bps == 32) {
+ if (endianness == G_LITTLE_ENDIAN)
+ format = GST_AUDIO_FORMAT_F32LE;
+ else
+ format = GST_AUDIO_FORMAT_F32BE;
+
+ } else if (bps == 64) {
+ if (endianness == G_LITTLE_ENDIAN)
+ format = GST_AUDIO_FORMAT_F64LE;
+ else
+ format = GST_AUDIO_FORMAT_F64BE;
+ }
+ } else {
+ format = gst_audio_format_build_integer (sign, endianness, bps, bps);
+ }
+
+ if (format == GST_AUDIO_FORMAT_UNKNOWN) {
+ GST_WARNING ("Unsupported sample format");
+ goto error;
+ }
+
+ gst_audio_info_set_format (&info, format, rate, channels, NULL);
+
+ return gst_audio_info_to_caps (&info);
+
+error:
+ return NULL;
+}