static gboolean
gst_base_audio_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
  GstRingBufferSpec *spec;

  spec = &src->ringbuffer->spec;

  spec->buffer_time = src->buffer_time;
  spec->latency_time = src->latency_time;

  if (!gst_ring_buffer_parse_caps (spec, caps))
    goto parse_error;

  /* calculate suggested segsize and segtotal */
  spec->segsize =
      spec->rate * spec->bytes_per_sample * spec->latency_time / GST_MSECOND;
  spec->segtotal = spec->buffer_time / spec->latency_time;

  GST_DEBUG ("release old ringbuffer");

  gst_ring_buffer_release (src->ringbuffer);

  gst_ring_buffer_debug_spec_buff (spec);

  GST_DEBUG ("acquire new ringbuffer");

  if (!gst_ring_buffer_acquire (src->ringbuffer, spec))
    goto acquire_error;

  /* calculate actual latency and buffer times */
  spec->latency_time =
      spec->segsize * GST_MSECOND / (spec->rate * spec->bytes_per_sample);
  spec->buffer_time =
      spec->segtotal * spec->segsize * GST_MSECOND / (spec->rate *
      spec->bytes_per_sample);

  gst_ring_buffer_debug_spec_buff (spec);

  g_object_notify (G_OBJECT (src), "actual-buffer-time");
  g_object_notify (G_OBJECT (src), "actual-latency-time");

  return TRUE;

  /* ERRORS */
parse_error:
  {
    GST_DEBUG ("could not parse caps");
    return FALSE;
  }
acquire_error:
  {
    GST_DEBUG ("could not acquire ringbuffer");
    return FALSE;
  }
}
Exemple #2
0
static gboolean
gst_alsasink_acceptcaps (GstPad * pad, GstCaps * caps)
{
    GstAlsaSink *alsa = GST_ALSA_SINK (gst_pad_get_parent_element (pad));
    GstCaps *pad_caps;
    GstStructure *st;
    gboolean ret = FALSE;
    GstRingBufferSpec spec = { 0 };

    pad_caps = gst_pad_get_caps_reffed (pad);
    if (pad_caps) {
        ret = gst_caps_can_intersect (pad_caps, caps);
        gst_caps_unref (pad_caps);
        if (!ret)
            goto done;
    }

    /* If we've not got fixed caps, creating a stream might fail, so let's just
     * return from here with default acceptcaps behaviour */
    if (!gst_caps_is_fixed (caps))
        goto done;

    /* parse helper expects this set, so avoid nasty warning
     * will be set properly later on anyway  */
    spec.latency_time = GST_SECOND;
    if (!gst_ring_buffer_parse_caps (&spec, caps))
        goto done;

    /* Make sure input is framed (one frame per buffer) and can be payloaded */
    switch (spec.type) {
    case GST_BUFTYPE_AC3:
    case GST_BUFTYPE_EAC3:
    case GST_BUFTYPE_DTS:
    case GST_BUFTYPE_MPEG:
    {
        gboolean framed = FALSE, parsed = FALSE;
        st = gst_caps_get_structure (caps, 0);

        gst_structure_get_boolean (st, "framed", &framed);
        gst_structure_get_boolean (st, "parsed", &parsed);
        if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0)
            goto done;
    }
    default: {
    }
    }
    ret = TRUE;

done:
    gst_caps_replace (&spec.caps, NULL);
    gst_object_unref (alsa);
    return ret;
}
static gboolean
gst_audio_filter_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstAudioFilterClass *klass;
  GstAudioFilter *filter;
  gboolean ret = TRUE;

  filter = GST_AUDIO_FILTER (btrans);

  GST_LOG_OBJECT (filter, "caps: %" GST_PTR_FORMAT, incaps);

  if (!gst_ring_buffer_parse_caps (&filter->format, incaps)) {
    GST_WARNING_OBJECT (filter, "couldn't parse %" GST_PTR_FORMAT, incaps);
    return FALSE;
  }

  klass = GST_AUDIO_FILTER_CLASS (G_OBJECT_GET_CLASS (filter));

  if (klass->setup)
    ret = klass->setup (filter, &filter->format);

  return ret;
}
static gboolean
gst_audio_ringbuffer_setcaps (GstPad * pad, GstCaps * caps)
{
  GstAudioRingbuffer *ringbuffer;
  GstRingBufferSpec *spec;

  ringbuffer = GST_AUDIO_RINGBUFFER (GST_PAD_PARENT (pad));

  if (!ringbuffer->buffer)
    return FALSE;

  spec = &ringbuffer->buffer->spec;

  GST_DEBUG_OBJECT (ringbuffer, "release old ringbuffer");

  /* release old ringbuffer */
  gst_ring_buffer_activate (ringbuffer->buffer, FALSE);
  gst_ring_buffer_release (ringbuffer->buffer);

  GST_DEBUG_OBJECT (ringbuffer, "parse caps");

  spec->buffer_time = ringbuffer->buffer_time;
  spec->latency_time = ringbuffer->segment_time;

  /* parse new caps */
  if (!gst_ring_buffer_parse_caps (spec, caps))
    goto parse_error;

  gst_ring_buffer_debug_spec_buff (spec);

  GST_DEBUG_OBJECT (ringbuffer, "acquire ringbuffer");
  if (!gst_ring_buffer_acquire (ringbuffer->buffer, spec))
    goto acquire_error;

  GST_DEBUG_OBJECT (ringbuffer, "activate ringbuffer");
  gst_ring_buffer_activate (ringbuffer->buffer, TRUE);

  /* calculate actual latency and buffer times. 
   * FIXME: In 0.11, store the latency_time internally in ns */
  spec->latency_time = gst_util_uint64_scale (spec->segsize,
      (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample);

  spec->buffer_time = spec->segtotal * spec->latency_time;

  gst_ring_buffer_debug_spec_buff (spec);

  return TRUE;

  /* ERRORS */
parse_error:
  {
    GST_DEBUG_OBJECT (ringbuffer, "could not parse caps");
    GST_ELEMENT_ERROR (ringbuffer, STREAM, FORMAT,
        (NULL), ("cannot parse audio format."));
    return FALSE;
  }
acquire_error:
  {
    GST_DEBUG_OBJECT (ringbuffer, "could not acquire ringbuffer");
    return FALSE;
  }
}
Exemple #5
0
static gboolean
gst_pulsesrc_create_stream (GstPulseSrc * pulsesrc, GstCaps * caps)
{
  pa_channel_map channel_map;
  GstStructure *s;
  gboolean need_channel_layout = FALSE;
  GstRingBufferSpec spec;
  const gchar *name;

  memset (&spec, 0, sizeof (GstRingBufferSpec));
  spec.latency_time = GST_SECOND;
  if (!gst_ring_buffer_parse_caps (&spec, caps)) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, SETTINGS,
        ("Can't parse caps."), (NULL));
    goto fail;
  }
  /* Keep the refcount of the caps at 1 to make them writable */
  gst_caps_unref (spec.caps);

  if (!gst_pulse_fill_sample_spec (&spec, &pulsesrc->sample_spec)) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, SETTINGS,
        ("Invalid sample specification."), (NULL));
    goto fail;
  }

  pa_threaded_mainloop_lock (pulsesrc->mainloop);

  if (!pulsesrc->context) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Bad context"), (NULL));
    goto unlock_and_fail;
  }

  s = gst_caps_get_structure (caps, 0);
  if (!gst_structure_has_field (s, "channel-layout") ||
      !gst_pulse_gst_to_channel_map (&channel_map, &spec)) {
    if (spec.channels == 1)
      pa_channel_map_init_mono (&channel_map);
    else if (spec.channels == 2)
      pa_channel_map_init_stereo (&channel_map);
    else
      need_channel_layout = TRUE;
  }

  name = "Record Stream";
  if (pulsesrc->proplist) {
    if (!(pulsesrc->stream = pa_stream_new_with_proplist (pulsesrc->context,
                name, &pulsesrc->sample_spec,
                (need_channel_layout) ? NULL : &channel_map,
                pulsesrc->proplist))) {
      GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
          ("Failed to create stream: %s",
              pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
      goto unlock_and_fail;
    }
  } else if (!(pulsesrc->stream = pa_stream_new (pulsesrc->context,
              name, &pulsesrc->sample_spec,
              (need_channel_layout) ? NULL : &channel_map))) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
        ("Failed to create stream: %s",
            pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
    goto unlock_and_fail;
  }

  if (need_channel_layout) {
    const pa_channel_map *m = pa_stream_get_channel_map (pulsesrc->stream);

    gst_pulse_channel_map_to_gst (m, &spec);
    caps = spec.caps;
  }

  GST_DEBUG_OBJECT (pulsesrc, "Caps are %" GST_PTR_FORMAT, caps);

  pa_stream_set_state_callback (pulsesrc->stream, gst_pulsesrc_stream_state_cb,
      pulsesrc);
  pa_stream_set_read_callback (pulsesrc->stream, gst_pulsesrc_stream_request_cb,
      pulsesrc);
  pa_stream_set_underflow_callback (pulsesrc->stream,
      gst_pulsesrc_stream_underflow_cb, pulsesrc);
  pa_stream_set_overflow_callback (pulsesrc->stream,
      gst_pulsesrc_stream_overflow_cb, pulsesrc);
  pa_stream_set_latency_update_callback (pulsesrc->stream,
      gst_pulsesrc_stream_latency_update_cb, pulsesrc);

  pa_threaded_mainloop_unlock (pulsesrc->mainloop);

  return TRUE;

unlock_and_fail:
  gst_pulsesrc_destroy_stream (pulsesrc);

  pa_threaded_mainloop_unlock (pulsesrc->mainloop);

fail:
  return FALSE;
}