static gboolean gst_openal_sink_prepare (GstAudioSink * audiosink, GstAudioRingBufferSpec * spec) { GstOpenALSink *sink = GST_OPENAL_SINK (audiosink); ALCcontext *context, *old; if (sink->default_context && !gst_openal_sink_unprepare (audiosink)) return FALSE; if (sink->user_context) context = sink->user_context; else { ALCint attribs[3] = { 0, 0, 0 }; /* Don't try to change the playback frequency of an app's device */ if (!sink->user_device) { attribs[0] = ALC_FREQUENCY; attribs[1] = GST_AUDIO_INFO_RATE (&spec->info); attribs[2] = 0; } context = alcCreateContext (sink->default_device, attribs); if (!context) { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, ("Unable to prepare device."), GST_ALC_ERROR (sink->default_device)); return FALSE; } } old = pushContext (context); if (sink->user_source) { if (!sink->user_context || !alIsSource (sink->user_source)) { GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, (NULL), ("Invalid source specified for context")); goto fail; } sink->default_source = sink->user_source; } else { ALuint source; alGenSources (1, &source); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate source")); goto fail; } sink->default_source = source; } gst_openal_sink_parse_spec (sink, spec); if (sink->format == AL_NONE) { GST_ELEMENT_ERROR (sink, 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))); goto fail; } sink->buffers = g_malloc (sink->buffer_count * sizeof (*sink->buffers)); if (!sink->buffers) { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, ("Out of memory."), ("Unable to allocate buffers")); goto fail; } alGenBuffers (sink->buffer_count, sink->buffers); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate %d buffers", sink->buffer_count)); goto fail; } sink->buffer_idx = 0; popContext (old, context); sink->default_context = context; return TRUE; fail: if (!sink->user_source && sink->default_source) alDeleteSources (1, &sink->default_source); sink->default_source = 0; g_free (sink->buffers); sink->buffers = NULL; sink->buffer_count = 0; sink->buffer_length = 0; popContext (old, context); if (!sink->user_context) alcDestroyContext (context); return FALSE; }
static gboolean gst_openal_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstOpenALSink *openal = GST_OPENAL_SINK (asink); ALCcontext *ctx, *old; if (openal->context && !gst_openal_sink_unprepare (asink)) return FALSE; if (openal->custom_ctx) ctx = openal->custom_ctx; else { ALCint attribs[3] = { 0, 0, 0 }; /* Don't try to change the playback frequency of an app's device */ if (!openal->custom_dev) { attribs[0] = ALC_FREQUENCY; attribs[1] = spec->rate; attribs[2] = 0; } ctx = alcCreateContext (openal->device, attribs); if (!ctx) { GST_ELEMENT_ERROR (openal, RESOURCE, FAILED, ("Unable to prepare device."), GST_ALC_ERROR (openal->device)); return FALSE; } } old = pushContext (ctx); if (openal->custom_sID) { if (!openal->custom_ctx || !alIsSource (openal->custom_sID)) { GST_ELEMENT_ERROR (openal, RESOURCE, NOT_FOUND, (NULL), ("Invalid source ID specified for context")); goto fail; } openal->sID = openal->custom_sID; } else { ALuint sourceID; alGenSources (1, &sourceID); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (openal, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate source")); goto fail; } openal->sID = sourceID; } gst_openal_sink_parse_spec (openal, spec); if (openal->format == AL_NONE) { GST_ELEMENT_ERROR (openal, RESOURCE, SETTINGS, (NULL), ("Unable to get type %d, format %d, and %d channels", spec->type, spec->format, spec->channels)); goto fail; } openal->bIDs = g_malloc (openal->bID_count * sizeof (*openal->bIDs)); if (!openal->bIDs) { GST_ELEMENT_ERROR (openal, RESOURCE, FAILED, ("Out of memory."), ("Unable to allocate buffer IDs")); goto fail; } alGenBuffers (openal->bID_count, openal->bIDs); if (checkALError () != AL_NO_ERROR) { GST_ELEMENT_ERROR (openal, RESOURCE, NO_SPACE_LEFT, (NULL), ("Unable to generate %d buffers", openal->bID_count)); goto fail; } openal->bID_idx = 0; popContext (old, ctx); openal->context = ctx; return TRUE; fail: if (!openal->custom_sID && openal->sID) alDeleteSources (1, &openal->sID); openal->sID = 0; g_free (openal->bIDs); openal->bIDs = NULL; openal->bID_count = 0; openal->bID_length = 0; popContext (old, ctx); if (!openal->custom_ctx) alcDestroyContext (ctx); return FALSE; }