Пример #1
0
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;
}
Пример #2
0
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;
}