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; } }
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; } }
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; }