static gboolean gst_openal_src_prepare (GstAudioSrc * audiosrc, GstAudioRingBufferSpec * spec) { GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc); gst_openal_src_parse_spec (openalsrc, spec); if (openalsrc->format == AL_NONE) { GST_ELEMENT_ERROR (openalsrc, RESOURCE, SETTINGS, (NULL), ("Unable to get type %d, format %d, and %d channels", spec->type, GST_AUDIO_INFO_FORMAT (&spec->info), GST_AUDIO_INFO_CHANNELS (&spec->info))); return FALSE; } openalsrc->device = alcCaptureOpenDevice (openalsrc->default_device, openalsrc->rate, openalsrc->format, openalsrc->buffer_length); if (!openalsrc->device) { GST_ELEMENT_ERROR (openalsrc, RESOURCE, OPEN_READ, ("Could not open device."), GST_ALC_ERROR (openalsrc->device)); return FALSE; } openalsrc->default_device_name = g_strdup (alcGetString (openalsrc->device, ALC_DEVICE_SPECIFIER)); alcCaptureStart (openalsrc->device); return TRUE; }
static void gst_openal_src_finalize (GObject * object) { GstOpenalSrc *osrc = GST_OPENAL_SRC (object); g_free (osrc->deviceName); g_free (osrc->device); G_OBJECT_CLASS (parent_class)->finalize (object); }
static guint gst_openal_src_delay (GstAudioSrc * asrc) { GstOpenalSrc *osrc = GST_OPENAL_SRC (asrc); gint samples; alcGetIntegerv (osrc->deviceHandle, ALC_CAPTURE_SAMPLES, sizeof (samples), &samples); return samples; }
static void gst_openal_src_dispose (GObject * object) { GstOpenalSrc *openalsrc = GST_OPENAL_SRC (object); if (openalsrc->probed_caps) gst_caps_unref (openalsrc->probed_caps); openalsrc->probed_caps = NULL; G_OBJECT_CLASS (gst_openal_src_parent_class)->dispose (object); }
static GstCaps * gst_openal_src_getcaps (GstBaseSrc * basesrc, GstCaps * filter) { GstOpenalSrc *openalsrc = GST_OPENAL_SRC (basesrc); GstCaps *caps; ALCdevice *device; device = alcOpenDevice (NULL); if (device == NULL) { GstPad *pad = GST_BASE_SRC_PAD (basesrc); GstCaps *tcaps = gst_pad_get_pad_template_caps (pad); GST_ELEMENT_WARNING (openalsrc, RESOURCE, OPEN_WRITE, ("Could not open temporary device."), GST_ALC_ERROR (device)); caps = gst_caps_copy (tcaps); gst_caps_unref (tcaps); } else if (openalsrc->probed_caps) caps = gst_caps_copy (openalsrc->probed_caps); else { ALCcontext *context = alcCreateContext (device, NULL); if (context) { caps = gst_openal_helper_probe_caps (context); alcDestroyContext (context); } else { GST_ELEMENT_WARNING (openalsrc, RESOURCE, FAILED, ("Could not create temporary context."), GST_ALC_ERROR (device)); caps = NULL; } if (caps && !gst_caps_is_empty (caps)) openalsrc->probed_caps = gst_caps_copy (caps); } if (device != NULL) { if (alcCloseDevice (device) == ALC_FALSE) { GST_ELEMENT_WARNING (openalsrc, RESOURCE, CLOSE, ("Could not close temporary device."), GST_ALC_ERROR (device)); } } if (filter) { GstCaps *intersection; intersection = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); return intersection; } else { return caps; } }
static gboolean gst_openal_src_unprepare (GstAudioSrc * asrc) { GstOpenalSrc *osrc = GST_OPENAL_SRC (asrc); GST_INFO_OBJECT (osrc, "Close device : %s", osrc->deviceName); if (osrc->deviceHandle) { alcCaptureStop (osrc->deviceHandle); alcCaptureCloseDevice (osrc->deviceHandle); } return TRUE; }
static guint gst_openal_src_delay (GstAudioSrc * audiosrc) { GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc); ALint samples; alcGetIntegerv (openalsrc->device, ALC_CAPTURE_SAMPLES, sizeof (samples), &samples); if (G_UNLIKELY (samples < 0)) { /* make sure we never return a negative delay */ GST_WARNING_OBJECT (openal_debug, "negative delay"); samples = 0; } return samples; }
static gboolean gst_openal_src_unprepare (GstAudioSrc * audiosrc) { GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc); if (openalsrc->device) { alcCaptureStop (openalsrc->device); if (alcCaptureCloseDevice (openalsrc->device) == ALC_FALSE) { GST_ELEMENT_ERROR (openalsrc, RESOURCE, CLOSE, ("Could not close device."), GST_ALC_ERROR (openalsrc->device)); return FALSE; } } return TRUE; }
static gboolean gst_openal_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) { GstOpenalSrc *osrc = GST_OPENAL_SRC (asrc); ALenum format; guint64 bufferSize; switch (spec->width) { case 8: format = AL_FORMAT_STEREO8; break; case 16: format = AL_FORMAT_STEREO16; break; default: g_assert_not_reached (); } bufferSize = spec->buffer_time * spec->rate * spec->bytes_per_sample / 1000000; GST_INFO_OBJECT (osrc, "Open device : %s", osrc->deviceName); osrc->deviceHandle = alcCaptureOpenDevice (osrc->device, spec->rate, format, bufferSize); if (!osrc->deviceHandle) { GST_ELEMENT_ERROR (osrc, RESOURCE, FAILED, ("Can't open device \"%s\"", osrc->device), ("Can't open device \"%s\"", osrc->device) ); return FALSE; } osrc->deviceName = g_strdup (alcGetString (osrc->deviceHandle, ALC_DEVICE_SPECIFIER)); osrc->bytes_per_sample = spec->bytes_per_sample; GST_INFO_OBJECT (osrc, "Start capture"); alcCaptureStart (osrc->deviceHandle); return TRUE; }
static void gst_openal_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstOpenalSrc *osrc = GST_OPENAL_SRC (object); switch (prop_id) { case PROP_DEVICE: g_value_set_string (value, osrc->device); break; case PROP_DEVICE_NAME: g_value_set_string (value, osrc->deviceName); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static guint gst_openal_src_read (GstAudioSrc * asrc, gpointer data, guint length) { GstOpenalSrc *osrc = GST_OPENAL_SRC (asrc); gint samples; alcGetIntegerv (osrc->deviceHandle, ALC_CAPTURE_SAMPLES, sizeof (samples), &samples); if (samples * osrc->bytes_per_sample > length) { samples = length / osrc->bytes_per_sample; } if (samples) { GST_DEBUG_OBJECT (osrc, "Read samples : %d", samples); alcCaptureSamples (osrc->deviceHandle, data, samples); } return samples * osrc->bytes_per_sample; }