Пример #1
0
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;
  }
}
Пример #2
0
static gboolean
gst_openal_sink_open (GstAudioSink * audiosink)
{
  GstOpenALSink *sink = GST_OPENAL_SINK (audiosink);

  if (sink->user_device) {
    ALCint value = -1;
    alcGetIntegerv (sink->user_device, ALC_ATTRIBUTES_SIZE, 1, &value);
    if (value > 0) {
      if (!sink->user_context
          || alcGetContextsDevice (sink->user_context) == sink->user_device)
        sink->default_device = sink->user_device;
    }
  } else if (sink->user_context)
    sink->default_device = alcGetContextsDevice (sink->user_context);
  else
    sink->default_device = alcOpenDevice (sink->device_name);
  if (!sink->default_device) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        ("Could not open device."), GST_ALC_ERROR (sink->default_device));
    return FALSE;
  }

  return TRUE;
}
Пример #3
0
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;
}
Пример #4
0
static gboolean
gst_openal_sink_open (GstAudioSink * asink)
{
    GstOpenALSink *openal = GST_OPENAL_SINK (asink);

    if (openal->custom_dev) {
        ALCint val = -1;
        alcGetIntegerv (openal->custom_dev, ALC_ATTRIBUTES_SIZE, 1, &val);
        if (val > 0) {
            if (!openal->custom_ctx ||
                    alcGetContextsDevice (openal->custom_ctx) == openal->custom_dev)
                openal->device = openal->custom_dev;
        }
    } else if (openal->custom_ctx)
        openal->device = alcGetContextsDevice (openal->custom_ctx);
    else
        openal->device = alcOpenDevice (openal->devname);
    if (!openal->device) {
        GST_ELEMENT_ERROR (openal, RESOURCE, OPEN_WRITE,
                           ("Could not open audio device for playback."),
                           GST_ALC_ERROR (openal->device));
        return FALSE;
    }

    return TRUE;
}
Пример #5
0
static GstCaps *
gst_openal_sink_getcaps (GstBaseSink * bsink)
{
    GstOpenALSink *sink = GST_OPENAL_SINK (bsink);
    GstCaps *caps;

    if (sink->device == NULL) {
        GstPad *pad = GST_BASE_SINK_PAD (bsink);
        caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
    } else if (sink->probed_caps)
        caps = gst_caps_copy (sink->probed_caps);
    else {
        if (sink->context)
            caps = gst_openal_helper_probe_caps (sink->context);
        else if (sink->custom_ctx)
            caps = gst_openal_helper_probe_caps (sink->custom_ctx);
        else {
            ALCcontext *ctx = alcCreateContext (sink->device, NULL);
            if (ctx) {
                caps = gst_openal_helper_probe_caps (ctx);
                alcDestroyContext (ctx);
            } else {
                GST_ELEMENT_WARNING (sink, RESOURCE, FAILED,
                                     ("Could not create temporary context."),
                                     GST_ALC_ERROR (sink->device));
                caps = NULL;
            }
        }

        if (caps && !gst_caps_is_empty (caps))
            sink->probed_caps = gst_caps_copy (caps);
    }

    return caps;
}
Пример #6
0
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;
}
Пример #7
0
static GstCaps *
gst_openal_sink_getcaps (GstBaseSink * basesink, GstCaps * filter)
{
  GstOpenALSink *sink = GST_OPENAL_SINK (basesink);
  GstCaps *caps;

  if (sink->default_device == NULL) {
    GstPad *pad = GST_BASE_SINK_PAD (basesink);
    GstCaps *tcaps = gst_pad_get_pad_template_caps (pad);
    caps = gst_caps_copy (tcaps);
    gst_caps_unref (tcaps);
  } else if (sink->probed_caps)
    caps = gst_caps_copy (sink->probed_caps);
  else {
    if (sink->default_context)
      caps = gst_openal_helper_probe_caps (sink->default_context);
    else if (sink->user_context)
      caps = gst_openal_helper_probe_caps (sink->user_context);
    else {
      ALCcontext *context = alcCreateContext (sink->default_device, NULL);
      if (context) {
        caps = gst_openal_helper_probe_caps (context);
        alcDestroyContext (context);
      } else {
        GST_ELEMENT_WARNING (sink, RESOURCE, FAILED,
            ("Could not create temporary context."),
            GST_ALC_ERROR (sink->default_device));
        caps = NULL;
      }
    }

    if (caps && !gst_caps_is_empty (caps))
      sink->probed_caps = gst_caps_copy (caps);
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    return intersection;
  } else {
    return caps;
  }
}
Пример #8
0
static gboolean
gst_openal_sink_close (GstAudioSink * audiosink)
{
  GstOpenALSink *sink = GST_OPENAL_SINK (audiosink);

  if (!sink->user_device && !sink->user_context) {
    if (alcCloseDevice (sink->default_device) == ALC_FALSE) {
      GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
          ("Could not close device."), GST_ALC_ERROR (sink->default_device));
      return FALSE;
    }
  }
  sink->default_device = NULL;

  if (sink->probed_caps)
    gst_caps_unref (sink->probed_caps);
  sink->probed_caps = NULL;

  return TRUE;
}
Пример #9
0
static gboolean
gst_openal_sink_close (GstAudioSink * asink)
{
    GstOpenALSink *openal = GST_OPENAL_SINK (asink);

    if (!openal->custom_dev && !openal->custom_ctx) {
        if (alcCloseDevice (openal->device) == ALC_FALSE) {
            GST_ELEMENT_ERROR (openal, RESOURCE, CLOSE,
                               ("Could not close audio device."), GST_ALC_ERROR (openal->device));
            return FALSE;
        }
    }
    openal->device = NULL;

    if (openal->probed_caps)
        gst_caps_unref (openal->probed_caps);
    openal->probed_caps = NULL;

    return TRUE;
}
Пример #10
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;
}
Пример #11
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;
}