/** * gst_audio_info_is_equal: * @info: a #GstAudioInfo * @other: a #GstAudioInfo * * Compares two #GstAudioInfo and returns whether they are equal or not * * Returns: %TRUE if @info and @other are equal, else %FALSE. * * Since: 1.2 * */ gboolean gst_audio_info_is_equal (const GstAudioInfo * info, const GstAudioInfo * other) { if (info == other) return TRUE; if (info->finfo == NULL || other->finfo == NULL) return FALSE; if (GST_AUDIO_INFO_FORMAT (info) != GST_AUDIO_INFO_FORMAT (other)) return FALSE; if (GST_AUDIO_INFO_FLAGS (info) != GST_AUDIO_INFO_FLAGS (other)) return FALSE; if (GST_AUDIO_INFO_LAYOUT (info) != GST_AUDIO_INFO_LAYOUT (other)) return FALSE; if (GST_AUDIO_INFO_RATE (info) != GST_AUDIO_INFO_RATE (other)) return FALSE; if (GST_AUDIO_INFO_CHANNELS (info) != GST_AUDIO_INFO_CHANNELS (other)) return FALSE; if (GST_AUDIO_INFO_CHANNELS (info) > 64) return TRUE; if (memcmp (info->position, other->position, GST_AUDIO_INFO_CHANNELS (info) * sizeof (GstAudioChannelPosition)) != 0) return FALSE; return TRUE; }
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; }
/* get notified of caps and plug in the correct process function */ static gboolean gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base, const GstAudioInfo * info) { GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base); g_mutex_lock (&self->lock); if (self->buffer) { gst_audio_fx_base_fir_filter_push_residue (self); g_free (self->buffer); self->buffer = NULL; self->buffer_fill = 0; self->buffer_length = 0; self->start_ts = GST_CLOCK_TIME_NONE; self->start_off = GST_BUFFER_OFFSET_NONE; self->nsamples_out = 0; self->nsamples_in = 0; } gst_audio_fx_base_fir_filter_select_process_function (self, GST_AUDIO_INFO_FORMAT (info), GST_AUDIO_INFO_CHANNELS (info)); g_mutex_unlock (&self->lock); return (self->process != NULL); }
static gboolean gst_audio_panorama_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { GstAudioPanorama *filter = GST_AUDIO_PANORAMA (base); GstAudioInfo info; /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */ if (!gst_audio_info_from_caps (&info, incaps)) goto no_format; GST_DEBUG ("try to process %d input with %d channels", GST_AUDIO_INFO_FORMAT (&info), GST_AUDIO_INFO_CHANNELS (&info)); if (!gst_audio_panorama_set_process_function (filter, &info)) goto no_format; filter->info = info; return TRUE; no_format: { GST_DEBUG ("invalid caps"); return FALSE; } }
static gboolean gst_audio_filter_template_setup (GstAudioFilter * filter, const GstAudioInfo * info) { GstAudioFilterTemplate *filter_template; GstAudioFormat fmt; gint chans, rate; filter_template = GST_AUDIO_FILTER_TEMPLATE (filter); rate = GST_AUDIO_INFO_RATE (info); chans = GST_AUDIO_INFO_CHANNELS (info); fmt = GST_AUDIO_INFO_FORMAT (info); GST_INFO_OBJECT (filter_template, "format %d (%s), rate %d, %d channels", fmt, GST_AUDIO_INFO_NAME (info), rate, chans); /* if any setup needs to be done (like memory allocated), do it here */ /* The audio filter base class also saves the audio info in * GST_AUDIO_FILTER_INFO(filter) so it's automatically available * later from there as well */ return TRUE; }
static gboolean gst_level_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out) { GstLevel *filter = GST_LEVEL (trans); GstAudioInfo info; gint i, channels; if (!gst_audio_info_from_caps (&info, in)) return FALSE; switch (GST_AUDIO_INFO_FORMAT (&info)) { case GST_AUDIO_FORMAT_S8: filter->process = gst_level_calculate_gint8; break; case GST_AUDIO_FORMAT_S16: filter->process = gst_level_calculate_gint16; break; case GST_AUDIO_FORMAT_S32: filter->process = gst_level_calculate_gint32; break; case GST_AUDIO_FORMAT_F32: filter->process = gst_level_calculate_gfloat; break; case GST_AUDIO_FORMAT_F64: filter->process = gst_level_calculate_gdouble; break; default: filter->process = NULL; break; } filter->info = info; channels = GST_AUDIO_INFO_CHANNELS (&info); /* allocate channel variable arrays */ g_free (filter->CS); g_free (filter->peak); g_free (filter->last_peak); g_free (filter->decay_peak); g_free (filter->decay_peak_base); g_free (filter->decay_peak_age); filter->CS = g_new (gdouble, channels); filter->peak = g_new (gdouble, channels); filter->last_peak = g_new (gdouble, channels); filter->decay_peak = g_new (gdouble, channels); filter->decay_peak_base = g_new (gdouble, channels); filter->decay_peak_age = g_new (GstClockTime, channels); for (i = 0; i < channels; ++i) { filter->CS[i] = filter->peak[i] = filter->last_peak[i] = filter->decay_peak[i] = filter->decay_peak_base[i] = 0.0; filter->decay_peak_age[i] = G_GUINT64_CONSTANT (0); } gst_level_recalc_interval_frames (filter); return TRUE; }
static gboolean gst_audio_echo_setup (GstAudioFilter * base, const GstAudioInfo * info) { GstAudioEcho *self = GST_AUDIO_ECHO (base); gboolean ret = TRUE; switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_F32: self->process = (GstAudioEchoProcessFunc) gst_audio_echo_transform_float; break; case GST_AUDIO_FORMAT_F64: self->process = (GstAudioEchoProcessFunc) gst_audio_echo_transform_double; break; default: ret = FALSE; break; } g_free (self->buffer); self->buffer = NULL; self->buffer_pos = 0; self->buffer_size = 0; self->buffer_size_frames = 0; return ret; }
static gboolean gst_iir_equalizer_setup (GstAudioFilter * audio, const GstAudioInfo * info) { GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio); switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_S16: equ->history_size = history_size_gint16; equ->process = gst_iir_equ_process_gint16; break; case GST_AUDIO_FORMAT_F32: equ->history_size = history_size_gfloat; equ->process = gst_iir_equ_process_gfloat; break; case GST_AUDIO_FORMAT_F64: equ->history_size = history_size_gdouble; equ->process = gst_iir_equ_process_gdouble; break; default: return FALSE; } alloc_history (equ, info); return TRUE; }
static gboolean gst_fastspectrum_setup (GstAudioFilter * base, const GstAudioInfo * info) { GstFastSpectrum *spectrum = GST_FASTSPECTRUM (base); GstFastSpectrumInputData input_data = NULL; g_mutex_lock (&spectrum->lock); switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_S16: input_data = input_data_mixed_int16_max; break; case GST_AUDIO_FORMAT_S24: input_data = input_data_mixed_int24_max; break; case GST_AUDIO_FORMAT_S32: input_data = input_data_mixed_int32_max; break; case GST_AUDIO_FORMAT_F32: input_data = input_data_mixed_float; break; case GST_AUDIO_FORMAT_F64: input_data = input_data_mixed_double; break; default: g_assert_not_reached (); break; } spectrum->input_data = input_data; gst_fastspectrum_reset_state (spectrum); g_mutex_unlock (&spectrum->lock); return TRUE; }
static gboolean gst_freeverb_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps) { GstFreeverb *filter = GST_FREEVERB (base); GstAudioInfo info; /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */ if (!gst_audio_info_from_caps (&info, incaps)) goto no_format; GST_DEBUG ("try to process %d input with %d channels", GST_AUDIO_INFO_FORMAT (&info), GST_AUDIO_INFO_CHANNELS (&info)); if (!gst_freeverb_set_process_function (filter, &info)) goto no_format; filter->info = info; gst_freeverb_init_rev_model (filter); filter->drained = FALSE; GST_INFO_OBJECT (base, "model configured"); return TRUE; no_format: { GST_DEBUG ("invalid caps"); return FALSE; } }
gboolean gst_pulse_fill_format_info (GstAudioRingBufferSpec * spec, pa_format_info ** f, guint * channels) { pa_format_info *format; pa_sample_format_t sf = PA_SAMPLE_INVALID; GstAudioInfo *ainfo = &spec->info; format = pa_format_info_new (); if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW && GST_AUDIO_INFO_WIDTH (ainfo) == 8) { format->encoding = PA_ENCODING_PCM; sf = PA_SAMPLE_ULAW; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW && GST_AUDIO_INFO_WIDTH (ainfo) == 8) { format->encoding = PA_ENCODING_PCM; sf = PA_SAMPLE_ALAW; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) { format->encoding = PA_ENCODING_PCM; if (!gstaudioformat_to_pasampleformat (GST_AUDIO_INFO_FORMAT (ainfo), &sf)) goto fail; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3) { format->encoding = PA_ENCODING_AC3_IEC61937; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3) { format->encoding = PA_ENCODING_EAC3_IEC61937; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS) { format->encoding = PA_ENCODING_DTS_IEC61937; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG) { format->encoding = PA_ENCODING_MPEG_IEC61937; } else { goto fail; } if (format->encoding == PA_ENCODING_PCM) { pa_format_info_set_sample_format (format, sf); pa_format_info_set_channels (format, GST_AUDIO_INFO_CHANNELS (ainfo)); } pa_format_info_set_rate (format, GST_AUDIO_INFO_RATE (ainfo)); if (!pa_format_info_valid (format)) goto fail; *f = format; *channels = GST_AUDIO_INFO_CHANNELS (ainfo); return TRUE; fail: if (format) pa_format_info_free (format); return FALSE; }
static gboolean gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base, const GstAudioInfo * info) { GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base); gboolean ret = TRUE; gint channels; g_mutex_lock (&filter->lock); switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_F32: filter->process = (GstAudioFXBaseIIRFilterProcessFunc) process_32; break; case GST_AUDIO_FORMAT_F64: filter->process = (GstAudioFXBaseIIRFilterProcessFunc) process_64; break; default: ret = FALSE; break; } channels = GST_AUDIO_INFO_CHANNELS (info); if (channels != filter->nchannels) { guint i; GstAudioFXBaseIIRFilterChannelCtx *ctx; if (filter->channels) { for (i = 0; i < filter->nchannels; i++) { ctx = &filter->channels[i]; g_free (ctx->x); g_free (ctx->y); } g_free (filter->channels); } filter->channels = g_new0 (GstAudioFXBaseIIRFilterChannelCtx, channels); for (i = 0; i < channels; i++) { ctx = &filter->channels[i]; ctx->x = g_new0 (gdouble, filter->nb); ctx->y = g_new0 (gdouble, filter->na); } filter->nchannels = channels; } g_mutex_unlock (&filter->lock); return ret; }
static void gst_audio_dynamic_set_process_function (GstAudioDynamic * filter, const GstAudioInfo * info) { gint func_index; func_index = (filter->mode == MODE_COMPRESSOR) ? 0 : 4; func_index += (filter->characteristics == CHARACTERISTICS_HARD_KNEE) ? 0 : 2; func_index += (GST_AUDIO_INFO_FORMAT (info) == GST_AUDIO_FORMAT_F32) ? 1 : 0; g_assert (func_index >= 0 && func_index < G_N_ELEMENTS (process_functions)); filter->process = process_functions[func_index]; }
static void pcm_config_from_spec (struct pcm_config *config, const GstAudioRingBufferSpec * spec) { gint64 frames; config->format = pcm_format_from_gst (GST_AUDIO_INFO_FORMAT (&spec->info)); config->channels = GST_AUDIO_INFO_CHANNELS (&spec->info); config->rate = GST_AUDIO_INFO_RATE (&spec->info); gst_audio_info_convert (&spec->info, GST_FORMAT_TIME, spec->latency_time * GST_USECOND, GST_FORMAT_DEFAULT /* frames */ , &frames); config->period_size = frames; config->period_count = spec->buffer_time / spec->latency_time; }
static void gst_deinterleave_add_new_pads (GstDeinterleave * self, GstCaps * caps) { GstPad *pad; guint i; for (i = 0; i < GST_AUDIO_INFO_CHANNELS (&self->audio_info); i++) { gchar *name = g_strdup_printf ("src_%u", i); GstCaps *srccaps; GstAudioInfo info; GstAudioFormat format = GST_AUDIO_INFO_FORMAT (&self->audio_info); gint rate = GST_AUDIO_INFO_RATE (&self->audio_info); GstAudioChannelPosition position = GST_AUDIO_CHANNEL_POSITION_MONO; CopyStickyEventsData data; /* Set channel position if we know it */ if (self->keep_positions) position = GST_AUDIO_INFO_POSITION (&self->audio_info, i); gst_audio_info_init (&info); gst_audio_info_set_format (&info, format, rate, 1, &position); srccaps = gst_audio_info_to_caps (&info); pad = gst_pad_new_from_static_template (&src_template, name); g_free (name); gst_pad_use_fixed_caps (pad); gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_deinterleave_src_query)); gst_pad_set_active (pad, TRUE); data.pad = pad; data.caps = srccaps; gst_pad_sticky_events_foreach (self->sink, copy_sticky_events, &data); if (data.caps) gst_pad_set_caps (pad, data.caps); gst_element_add_pad (GST_ELEMENT (self), pad); self->srcpads = g_list_prepend (self->srcpads, gst_object_ref (pad)); gst_caps_unref (srccaps); } gst_element_no_more_pads (GST_ELEMENT (self)); self->srcpads = g_list_reverse (self->srcpads); }
static gboolean gst_audio_invert_setup (GstAudioFilter * base, const GstAudioInfo * info) { GstAudioInvert *filter = GST_AUDIO_INVERT (base); gboolean ret = TRUE; switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_S16: filter->process = (GstAudioInvertProcessFunc) gst_audio_invert_transform_int; break; case GST_AUDIO_FORMAT_F32: filter->process = (GstAudioInvertProcessFunc) gst_audio_invert_transform_float; break; default: ret = FALSE; break; } return ret; }
gboolean gst_pulse_fill_sample_spec (GstAudioRingBufferSpec * spec, pa_sample_spec * ss) { if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) { if (!gstaudioformat_to_pasampleformat (GST_AUDIO_INFO_FORMAT (&spec->info), &ss->format)) return FALSE; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW) { ss->format = PA_SAMPLE_ULAW; } else if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW) { ss->format = PA_SAMPLE_ALAW; } else return FALSE; ss->channels = GST_AUDIO_INFO_CHANNELS (&spec->info); ss->rate = GST_AUDIO_INFO_RATE (&spec->info); if (!pa_sample_spec_valid (ss)) return FALSE; return TRUE; }
void gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, gdouble * kernel, guint kernel_length, guint64 latency, const GstAudioInfo * info) { gboolean latency_changed; GstAudioFormat format; gint channels; g_return_if_fail (kernel != NULL); g_return_if_fail (self != NULL); g_mutex_lock (&self->lock); latency_changed = (self->latency != latency || (!self->low_latency && self->kernel_length < FFT_THRESHOLD && kernel_length >= FFT_THRESHOLD) || (!self->low_latency && self->kernel_length >= FFT_THRESHOLD && kernel_length < FFT_THRESHOLD)); /* FIXME: If the latency changes, the buffer size changes too and we * have to drain in any case until this is fixed in the future */ if (self->buffer && (!self->drain_on_changes || latency_changed)) { gst_audio_fx_base_fir_filter_push_residue (self); self->start_ts = GST_CLOCK_TIME_NONE; self->start_off = GST_BUFFER_OFFSET_NONE; self->nsamples_out = 0; self->nsamples_in = 0; self->buffer_fill = 0; } g_free (self->kernel); if (!self->drain_on_changes || latency_changed) { g_free (self->buffer); self->buffer = NULL; self->buffer_fill = 0; self->buffer_length = 0; } self->kernel = kernel; self->kernel_length = kernel_length; if (info) { format = GST_AUDIO_INFO_FORMAT (info); channels = GST_AUDIO_INFO_CHANNELS (info); } else { format = GST_AUDIO_FILTER_FORMAT (self); channels = GST_AUDIO_FILTER_CHANNELS (self); } gst_audio_fx_base_fir_filter_calculate_frequency_response (self); gst_audio_fx_base_fir_filter_select_process_function (self, format, channels); if (latency_changed) { self->latency = latency; gst_element_post_message (GST_ELEMENT (self), gst_message_new_latency (GST_OBJECT (self))); } g_mutex_unlock (&self->lock); }
static GstFlowReturn gst_fdkaacenc_handle_frame (GstAudioEncoder * enc, GstBuffer * inbuf) { GstFdkAacEnc *self = GST_FDKAACENC (enc); GstFlowReturn ret = GST_FLOW_OK; GstAudioInfo *info; GstMapInfo imap, omap; GstBuffer *outbuf; AACENC_BufDesc in_desc = { 0 }; AACENC_BufDesc out_desc = { 0 }; AACENC_InArgs in_args = { 0 }; AACENC_OutArgs out_args = { 0 }; gint in_id = IN_AUDIO_DATA, out_id = OUT_BITSTREAM_DATA; gint in_sizes, out_sizes; gint in_el_sizes, out_el_sizes; AACENC_ERROR err; info = gst_audio_encoder_get_audio_info (enc); if (inbuf) { if (self->need_reorder) { inbuf = gst_buffer_copy (inbuf); gst_buffer_map (inbuf, &imap, GST_MAP_READWRITE); gst_audio_reorder_channels (imap.data, imap.size, GST_AUDIO_INFO_FORMAT (info), GST_AUDIO_INFO_CHANNELS (info), &GST_AUDIO_INFO_POSITION (info, 0), self->aac_positions); } else { gst_buffer_map (inbuf, &imap, GST_MAP_READ); } in_args.numInSamples = imap.size / GST_AUDIO_INFO_BPS (info); in_sizes = imap.size; in_el_sizes = GST_AUDIO_INFO_BPS (info); in_desc.numBufs = 1; } else { in_args.numInSamples = -1; in_sizes = 0; in_el_sizes = 0; in_desc.numBufs = 0; } in_desc.bufferIdentifiers = &in_id; in_desc.bufs = (void *) &imap.data; in_desc.bufSizes = &in_sizes; in_desc.bufElSizes = &in_el_sizes; outbuf = gst_audio_encoder_allocate_output_buffer (enc, self->outbuf_size); if (!outbuf) { ret = GST_FLOW_ERROR; goto out; } gst_buffer_map (outbuf, &omap, GST_MAP_WRITE); out_sizes = omap.size; out_el_sizes = 1; out_desc.bufferIdentifiers = &out_id; out_desc.numBufs = 1; out_desc.bufs = (void *) &omap.data; out_desc.bufSizes = &out_sizes; out_desc.bufElSizes = &out_el_sizes; err = aacEncEncode (self->enc, &in_desc, &out_desc, &in_args, &out_args); if (err == AACENC_ENCODE_EOF && !inbuf) goto out; else if (err != AACENC_OK) { GST_ERROR_OBJECT (self, "Failed to encode data: %d", err); ret = GST_FLOW_ERROR; goto out; } if (inbuf) { gst_buffer_unmap (inbuf, &imap); if (self->need_reorder) gst_buffer_unref (inbuf); inbuf = NULL; } if (!out_args.numOutBytes) goto out; gst_buffer_unmap (outbuf, &omap); gst_buffer_set_size (outbuf, out_args.numOutBytes); ret = gst_audio_encoder_finish_frame (enc, outbuf, self->samples_per_frame); outbuf = NULL; out: if (outbuf) { gst_buffer_unmap (outbuf, &omap); gst_buffer_unref (outbuf); } if (inbuf) { gst_buffer_unmap (inbuf, &imap); if (self->need_reorder) gst_buffer_unref (inbuf); } return ret; }
static gboolean gst_videoframe_audiolevel_asink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstVideoFrameAudioLevel *self = GST_VIDEOFRAME_AUDIOLEVEL (parent); GST_LOG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: self->first_time = GST_CLOCK_TIME_NONE; self->total_frames = 0; gst_adapter_clear (self->adapter); gst_event_copy_segment (event, &self->asegment); if (self->asegment.format != GST_FORMAT_TIME) return FALSE; break; case GST_EVENT_FLUSH_START: g_mutex_lock (&self->mutex); self->audio_flush_flag = TRUE; g_cond_signal (&self->cond); g_mutex_unlock (&self->mutex); break; case GST_EVENT_FLUSH_STOP: self->audio_flush_flag = FALSE; self->total_frames = 0; self->first_time = GST_CLOCK_TIME_NONE; gst_adapter_clear (self->adapter); gst_segment_init (&self->asegment, GST_FORMAT_UNDEFINED); break; case GST_EVENT_CAPS:{ GstCaps *caps; gint channels; gst_event_parse_caps (event, &caps); GST_DEBUG_OBJECT (self, "Got caps %" GST_PTR_FORMAT, caps); if (!gst_audio_info_from_caps (&self->ainfo, caps)) return FALSE; switch (GST_AUDIO_INFO_FORMAT (&self->ainfo)) { case GST_AUDIO_FORMAT_S8: self->process = gst_videoframe_audiolevel_calculate_gint8; break; case GST_AUDIO_FORMAT_S16: self->process = gst_videoframe_audiolevel_calculate_gint16; break; case GST_AUDIO_FORMAT_S32: self->process = gst_videoframe_audiolevel_calculate_gint32; break; case GST_AUDIO_FORMAT_F32: self->process = gst_videoframe_audiolevel_calculate_gfloat; break; case GST_AUDIO_FORMAT_F64: self->process = gst_videoframe_audiolevel_calculate_gdouble; break; default: self->process = NULL; break; } gst_adapter_clear (self->adapter); channels = GST_AUDIO_INFO_CHANNELS (&self->ainfo); self->first_time = GST_CLOCK_TIME_NONE; self->total_frames = 0; if (self->CS) g_free (self->CS); self->CS = g_new0 (gdouble, channels); break; } default: break; } return gst_pad_event_default (pad, parent, event); }
static gboolean gst_rg_analysis_set_caps (GstBaseTransform * base, GstCaps * in_caps, GstCaps * out_caps) { GstRgAnalysis *filter = GST_RG_ANALYSIS (base); GstAudioInfo info; gint rate, channels; g_return_val_if_fail (filter->ctx != NULL, FALSE); GST_DEBUG_OBJECT (filter, "set_caps in %" GST_PTR_FORMAT " out %" GST_PTR_FORMAT, in_caps, out_caps); if (!gst_audio_info_from_caps (&info, in_caps)) goto invalid_format; rate = GST_AUDIO_INFO_RATE (&info); if (!rg_analysis_set_sample_rate (filter->ctx, rate)) goto invalid_format; channels = GST_AUDIO_INFO_CHANNELS (&info); if (channels < 1 || channels > 2) goto invalid_format; switch (GST_AUDIO_INFO_FORMAT (&info)) { case GST_AUDIO_FORMAT_F32: /* The depth is not variable for float formats of course. It just * makes the transform function nice and simple if the * rg_analysis_analyze_* functions have a common signature. */ filter->depth = sizeof (gfloat) * 8; if (channels == 1) filter->analyze = rg_analysis_analyze_mono_float; else filter->analyze = rg_analysis_analyze_stereo_float; break; case GST_AUDIO_FORMAT_S16: filter->depth = sizeof (gint16) * 8; if (channels == 1) filter->analyze = rg_analysis_analyze_mono_int16; else filter->analyze = rg_analysis_analyze_stereo_int16; break; default: goto invalid_format; } return TRUE; /* Errors. */ invalid_format: { filter->analyze = NULL; GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION, ("Invalid incoming caps: %" GST_PTR_FORMAT, in_caps), (NULL)); return FALSE; } }
static void gst_openal_sink_parse_spec (GstOpenALSink * sink, const GstAudioRingBufferSpec * spec) { ALuint format = AL_NONE; GST_DEBUG_OBJECT (sink, "looking up format for type %d, gst-format %d, and %d channels", spec->type, GST_AUDIO_INFO_FORMAT (&spec->info), GST_AUDIO_INFO_CHANNELS (&spec->info)); /* Don't need to verify supported formats, since the probed caps will only * report what was detected and we shouldn't get anything different */ switch (spec->type) { case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW: switch (GST_AUDIO_INFO_FORMAT (&spec->info)) { case GST_AUDIO_FORMAT_U8: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO8; break; case 2: format = AL_FORMAT_STEREO8; break; case 4: format = AL_FORMAT_QUAD8; break; case 6: format = AL_FORMAT_51CHN8; break; case 7: format = AL_FORMAT_61CHN8; break; case 8: format = AL_FORMAT_71CHN8; break; default: break; } break; case GST_AUDIO_FORMAT_S16: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO16; break; case 2: format = AL_FORMAT_STEREO16; break; case 4: format = AL_FORMAT_QUAD16; break; case 6: format = AL_FORMAT_51CHN16; break; case 7: format = AL_FORMAT_61CHN16; break; case 8: format = AL_FORMAT_71CHN16; break; default: break; } break; case GST_AUDIO_FORMAT_F32: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_FLOAT32; break; case 2: format = AL_FORMAT_STEREO_FLOAT32; break; case 4: format = AL_FORMAT_QUAD32; break; case 6: format = AL_FORMAT_51CHN32; break; case 7: format = AL_FORMAT_61CHN32; break; case 8: format = AL_FORMAT_71CHN32; break; default: break; } break; case GST_AUDIO_FORMAT_F64: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_DOUBLE_EXT; break; case 2: format = AL_FORMAT_STEREO_DOUBLE_EXT; break; default: break; } break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IMA_ADPCM: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_IMA4; break; case 2: format = AL_FORMAT_STEREO_IMA4; break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_ALAW_EXT; break; case 2: format = AL_FORMAT_STEREO_ALAW_EXT; break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_MULAW; break; case 2: format = AL_FORMAT_STEREO_MULAW; break; case 4: format = AL_FORMAT_QUAD_MULAW; break; case 6: format = AL_FORMAT_51CHN_MULAW; break; case 7: format = AL_FORMAT_61CHN_MULAW; break; case 8: format = AL_FORMAT_71CHN_MULAW; break; default: break; } break; default: break; } sink->bytes_per_sample = GST_AUDIO_INFO_BPS (&spec->info); sink->rate = GST_AUDIO_INFO_RATE (&spec->info); sink->channels = GST_AUDIO_INFO_CHANNELS (&spec->info); sink->format = format; sink->buffer_count = spec->segtotal; sink->buffer_length = spec->segsize; }
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 alsasrc_parse_spec (GstAlsaSrc * alsa, GstAudioRingBufferSpec * spec) { switch (spec->type) { case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW: switch (GST_AUDIO_INFO_FORMAT (&spec->info)) { case GST_AUDIO_FORMAT_U8: alsa->format = SND_PCM_FORMAT_U8; break; case GST_AUDIO_FORMAT_S8: alsa->format = SND_PCM_FORMAT_S8; break; case GST_AUDIO_FORMAT_S16LE: alsa->format = SND_PCM_FORMAT_S16_LE; break; case GST_AUDIO_FORMAT_S16BE: alsa->format = SND_PCM_FORMAT_S16_BE; break; case GST_AUDIO_FORMAT_U16LE: alsa->format = SND_PCM_FORMAT_U16_LE; break; case GST_AUDIO_FORMAT_U16BE: alsa->format = SND_PCM_FORMAT_U16_BE; break; case GST_AUDIO_FORMAT_S24_32LE: alsa->format = SND_PCM_FORMAT_S24_LE; break; case GST_AUDIO_FORMAT_S24_32BE: alsa->format = SND_PCM_FORMAT_S24_BE; break; case GST_AUDIO_FORMAT_U24_32LE: alsa->format = SND_PCM_FORMAT_U24_LE; break; case GST_AUDIO_FORMAT_U24_32BE: alsa->format = SND_PCM_FORMAT_U24_BE; break; case GST_AUDIO_FORMAT_S32LE: alsa->format = SND_PCM_FORMAT_S32_LE; break; case GST_AUDIO_FORMAT_S32BE: alsa->format = SND_PCM_FORMAT_S32_BE; break; case GST_AUDIO_FORMAT_U32LE: alsa->format = SND_PCM_FORMAT_U32_LE; break; case GST_AUDIO_FORMAT_U32BE: alsa->format = SND_PCM_FORMAT_U32_BE; break; case GST_AUDIO_FORMAT_S24LE: alsa->format = SND_PCM_FORMAT_S24_3LE; break; case GST_AUDIO_FORMAT_S24BE: alsa->format = SND_PCM_FORMAT_S24_3BE; break; case GST_AUDIO_FORMAT_U24LE: alsa->format = SND_PCM_FORMAT_U24_3LE; break; case GST_AUDIO_FORMAT_U24BE: alsa->format = SND_PCM_FORMAT_U24_3BE; break; case GST_AUDIO_FORMAT_S20LE: alsa->format = SND_PCM_FORMAT_S20_3LE; break; case GST_AUDIO_FORMAT_S20BE: alsa->format = SND_PCM_FORMAT_S20_3BE; break; case GST_AUDIO_FORMAT_U20LE: alsa->format = SND_PCM_FORMAT_U20_3LE; break; case GST_AUDIO_FORMAT_U20BE: alsa->format = SND_PCM_FORMAT_U20_3BE; break; case GST_AUDIO_FORMAT_S18LE: alsa->format = SND_PCM_FORMAT_S18_3LE; break; case GST_AUDIO_FORMAT_S18BE: alsa->format = SND_PCM_FORMAT_S18_3BE; break; case GST_AUDIO_FORMAT_U18LE: alsa->format = SND_PCM_FORMAT_U18_3LE; break; case GST_AUDIO_FORMAT_U18BE: alsa->format = SND_PCM_FORMAT_U18_3BE; break; case GST_AUDIO_FORMAT_F32LE: alsa->format = SND_PCM_FORMAT_FLOAT_LE; break; case GST_AUDIO_FORMAT_F32BE: alsa->format = SND_PCM_FORMAT_FLOAT_BE; break; case GST_AUDIO_FORMAT_F64LE: alsa->format = SND_PCM_FORMAT_FLOAT64_LE; break; case GST_AUDIO_FORMAT_F64BE: alsa->format = SND_PCM_FORMAT_FLOAT64_BE; break; default: goto error; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW: alsa->format = SND_PCM_FORMAT_A_LAW; break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW: alsa->format = SND_PCM_FORMAT_MU_LAW; break; default: goto error; } alsa->rate = GST_AUDIO_INFO_RATE (&spec->info); alsa->channels = GST_AUDIO_INFO_CHANNELS (&spec->info); alsa->buffer_time = spec->buffer_time; alsa->period_time = spec->latency_time; alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED; if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC (alsa)->ringbuffer, alsa_position[alsa->channels - 1]); return TRUE; /* ERRORS */ error: { return FALSE; } }
static GstFlowReturn gst_cutter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; GstCutter *filter; GstMapInfo map; gint16 *in_data; gint bpf, rate; gsize in_size; guint num_samples; gdouble NCS = 0.0; /* Normalized Cumulative Square of buffer */ gdouble RMS = 0.0; /* RMS of signal in buffer */ gdouble NMS = 0.0; /* Normalized Mean Square of buffer */ GstBuffer *prebuf; /* pointer to a prebuffer element */ GstClockTime duration; filter = GST_CUTTER (parent); if (GST_AUDIO_INFO_FORMAT (&filter->info) == GST_AUDIO_FORMAT_UNKNOWN) goto not_negotiated; bpf = GST_AUDIO_INFO_BPF (&filter->info); rate = GST_AUDIO_INFO_RATE (&filter->info); gst_buffer_map (buf, &map, GST_MAP_READ); in_data = (gint16 *) map.data; in_size = map.size; GST_LOG_OBJECT (filter, "length of prerec buffer: %" GST_TIME_FORMAT, GST_TIME_ARGS (filter->pre_run_length)); /* calculate mean square value on buffer */ switch (GST_AUDIO_INFO_FORMAT (&filter->info)) { case GST_AUDIO_FORMAT_S16: num_samples = in_size / 2; gst_cutter_calculate_gint16 (in_data, num_samples, &NCS); NMS = NCS / num_samples; break; case GST_AUDIO_FORMAT_S8: num_samples = in_size; gst_cutter_calculate_gint8 ((gint8 *) in_data, num_samples, &NCS); NMS = NCS / num_samples; break; default: /* this shouldn't happen */ g_warning ("no mean square function for format"); break; } gst_buffer_unmap (buf, &map); filter->silent_prev = filter->silent; duration = gst_util_uint64_scale (in_size / bpf, GST_SECOND, rate); RMS = sqrt (NMS); /* if RMS below threshold, add buffer length to silent run length count * if not, reset */ GST_LOG_OBJECT (filter, "buffer stats: NMS %f, RMS %f, audio length %f", NMS, RMS, gst_guint64_to_gdouble (duration)); if (RMS < filter->threshold_level) filter->silent_run_length += gst_guint64_to_gdouble (duration); else { filter->silent_run_length = 0 * GST_SECOND; filter->silent = FALSE; } if (filter->silent_run_length > filter->threshold_length) /* it has been silent long enough, flag it */ filter->silent = TRUE; /* has the silent status changed ? if so, send right signal * and, if from silent -> not silent, flush pre_record buffer */ if (filter->silent != filter->silent_prev) { if (filter->silent) { GstMessage *m = gst_cutter_message_new (filter, FALSE, GST_BUFFER_TIMESTAMP (buf)); GST_DEBUG_OBJECT (filter, "signaling CUT_STOP"); gst_element_post_message (GST_ELEMENT (filter), m); } else { gint count = 0; GstMessage *m = gst_cutter_message_new (filter, TRUE, GST_BUFFER_TIMESTAMP (buf)); GST_DEBUG_OBJECT (filter, "signaling CUT_START"); gst_element_post_message (GST_ELEMENT (filter), m); /* first of all, flush current buffer */ GST_DEBUG_OBJECT (filter, "flushing buffer of length %" GST_TIME_FORMAT, GST_TIME_ARGS (filter->pre_run_length)); while (filter->pre_buffer) { prebuf = (g_list_first (filter->pre_buffer))->data; filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf); gst_pad_push (filter->srcpad, prebuf); ++count; } GST_DEBUG_OBJECT (filter, "flushed %d buffers", count); filter->pre_run_length = 0 * GST_SECOND; } } /* now check if we have to send the new buffer to the internal buffer cache * or to the srcpad */ if (filter->silent) { filter->pre_buffer = g_list_append (filter->pre_buffer, buf); filter->pre_run_length += gst_guint64_to_gdouble (duration); while (filter->pre_run_length > filter->pre_length) { GstClockTime pduration; gsize psize; prebuf = (g_list_first (filter->pre_buffer))->data; g_assert (GST_IS_BUFFER (prebuf)); psize = gst_buffer_get_size (prebuf); pduration = gst_util_uint64_scale (psize / bpf, GST_SECOND, rate); filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf); filter->pre_run_length -= gst_guint64_to_gdouble (pduration); /* only pass buffers if we don't leak */ if (!filter->leaky) ret = gst_pad_push (filter->srcpad, prebuf); else gst_buffer_unref (prebuf); } } else ret = gst_pad_push (filter->srcpad, buf); return ret; /* ERRORS */ not_negotiated: { return GST_FLOW_NOT_NEGOTIATED; } }
static void gst_openal_src_parse_spec (GstOpenalSrc * openalsrc, const GstAudioRingBufferSpec * spec) { ALuint format = AL_NONE; GST_DEBUG_OBJECT (openalsrc, "looking up format for type %d, gst-format %d, and %d channels", spec->type, GST_AUDIO_INFO_FORMAT (&spec->info), GST_AUDIO_INFO_CHANNELS (&spec->info)); switch (spec->type) { case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW: switch (GST_AUDIO_INFO_FORMAT (&spec->info)) { case GST_AUDIO_FORMAT_U8: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO8; break; default: break; } break; case GST_AUDIO_FORMAT_U16: case GST_AUDIO_FORMAT_S16: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO16; break; default: break; } break; case GST_AUDIO_FORMAT_F32: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_FLOAT32; break; default: break; } break; case GST_AUDIO_FORMAT_F64: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_DOUBLE_EXT; break; default: break; } break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IMA_ADPCM: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_IMA4; break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_ALAW_EXT; break; default: break; } break; case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW: switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) { case 1: format = AL_FORMAT_MONO_MULAW; break; default: break; } break; default: break; } openalsrc->bytes_per_sample = GST_AUDIO_INFO_BPS (&spec->info); openalsrc->rate = GST_AUDIO_INFO_RATE (&spec->info); openalsrc->buffer_length = spec->segsize; openalsrc->format = format; }
gboolean gst_sndio_prepare (struct gstsndio *sio, GstAudioRingBufferSpec *spec) { struct sio_par par, retpar; unsigned nchannels; GST_DEBUG_OBJECT (sio, "prepare"); if (spec->type != GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only raw buffer format supported by sndio"), (NULL)); return FALSE; } if (!GST_AUDIO_INFO_IS_INTEGER(&spec->info)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only integer format supported"), (NULL)); return FALSE; } if (GST_AUDIO_INFO_DEPTH(&spec->info) % 8) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only depths multiple of 8 are supported"), (NULL)); return FALSE; } sio_initpar (&par); switch (GST_AUDIO_INFO_FORMAT (&spec->info)) { case GST_AUDIO_FORMAT_S8: case GST_AUDIO_FORMAT_U8: case GST_AUDIO_FORMAT_S16LE: case GST_AUDIO_FORMAT_S16BE: case GST_AUDIO_FORMAT_U16LE: case GST_AUDIO_FORMAT_U16BE: case GST_AUDIO_FORMAT_S32LE: case GST_AUDIO_FORMAT_S32BE: case GST_AUDIO_FORMAT_U32LE: case GST_AUDIO_FORMAT_U32BE: case GST_AUDIO_FORMAT_S24_32LE: case GST_AUDIO_FORMAT_S24_32BE: case GST_AUDIO_FORMAT_U24_32LE: case GST_AUDIO_FORMAT_U24_32BE: case GST_AUDIO_FORMAT_S24LE: case GST_AUDIO_FORMAT_S24BE: case GST_AUDIO_FORMAT_U24LE: case GST_AUDIO_FORMAT_U24BE: break; default: GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Unsupported audio format"), ("format = %d", GST_AUDIO_INFO_FORMAT (&spec->info))); return FALSE; } par.sig = GST_AUDIO_INFO_IS_SIGNED(&spec->info); par.bits = GST_AUDIO_INFO_WIDTH(&spec->info); par.bps = GST_AUDIO_INFO_DEPTH(&spec->info) / 8; if (par.bps > 1) par.le = GST_AUDIO_INFO_IS_LITTLE_ENDIAN(&spec->info); if (par.bits < par.bps * 8) par.msb = 0; par.rate = GST_AUDIO_INFO_RATE(&spec->info); if (sio->mode == SIO_PLAY) par.pchan = GST_AUDIO_INFO_CHANNELS(&spec->info); else par.rchan = GST_AUDIO_INFO_CHANNELS(&spec->info); par.round = par.rate / 1000000. * spec->latency_time; par.appbufsz = par.rate / 1000000. * spec->buffer_time; if (!sio_setpar (sio->hdl, &par)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Unsupported audio encoding"), (NULL)); return FALSE; } if (!sio_getpar (sio->hdl, &retpar)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Couldn't get audio device parameters"), (NULL)); return FALSE; } #if 0 fprintf(stderr, "format = %s, " "requested: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, " "rate = %d, pchan = %d, round = %d, appbufsz = %d; " "returned: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, " "rate = %d, pchan = %d, round = %d, appbufsz = %d, bufsz = %d\n", GST_AUDIO_INFO_NAME(&spec->info), par.sig, par.bits, par.bps, par.le, par.msb, par.rate, par.pchan, par.round, par.appbufsz, retpar.sig, retpar.bits, retpar.bps, retpar.le, retpar.msb, retpar.rate, retpar.pchan, retpar.round, retpar.appbufsz, retpar.bufsz); #endif if (par.bits != retpar.bits || par.bps != retpar.bps || par.rate != retpar.rate || (sio->mode == SIO_PLAY && par.pchan != retpar.pchan) || (sio->mode == SIO_REC && par.rchan != retpar.rchan) || (par.bps > 1 && par.le != retpar.le) || (par.bits < par.bps * 8 && par.msb != retpar.msb)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Audio device refused requested parameters"), (NULL)); return FALSE; } nchannels = (sio->mode == SIO_PLAY) ? retpar.pchan : retpar.rchan; spec->segsize = retpar.round * retpar.bps * nchannels; spec->segtotal = retpar.bufsz / retpar.round; sio->bpf = retpar.bps * nchannels; sio->delay = 0; sio_onmove (sio->hdl, gst_sndio_cb, sio); if (!sio_start (sio->hdl)) { GST_ELEMENT_ERROR (sio->obj, RESOURCE, OPEN_READ_WRITE, ("Could not start sndio"), (NULL)); return FALSE; } return TRUE; }
static gboolean gst_raw_audio_parse_caps_to_config (GstRawAudioParse * raw_audio_parse, GstCaps * caps, GstRawAudioParseConfig * config) { gboolean ret = FALSE; GstStructure *structure; /* Caps might get copied, and the copy needs to be unref'd. * Also, the caller retains ownership over the original caps. * So, to make this mechanism also work with cases where the * caps are *not* copied, ref the original caps here first. */ gst_caps_ref (caps); structure = gst_caps_get_structure (caps, 0); /* For unaligned raw data, the output caps stay the same, * except that audio/x-unaligned-raw becomes audio/x-raw, * since the parser aligns the sample data */ if (gst_structure_has_name (structure, "audio/x-unaligned-raw")) { /* Copy the caps to be able to modify them */ GstCaps *new_caps = gst_caps_copy (caps); gst_caps_unref (caps); caps = new_caps; /* Change the media type to audio/x-raw , otherwise * gst_audio_info_from_caps() won't work */ structure = gst_caps_get_structure (caps, 0); gst_structure_set_name (structure, "audio/x-raw"); } if (gst_structure_has_name (structure, "audio/x-raw")) { guint num_channels; GstAudioInfo info; if (!gst_audio_info_from_caps (&info, caps)) { GST_ERROR_OBJECT (raw_audio_parse, "failed to parse caps %" GST_PTR_FORMAT, (gpointer) caps); goto done; } num_channels = GST_AUDIO_INFO_CHANNELS (&info); config->format = GST_RAW_AUDIO_PARSE_FORMAT_PCM; config->pcm_format = GST_AUDIO_INFO_FORMAT (&info); config->bpf = GST_AUDIO_INFO_BPF (&info); config->sample_rate = GST_AUDIO_INFO_RATE (&info); config->interleaved = (GST_AUDIO_INFO_LAYOUT (&info) == GST_AUDIO_LAYOUT_INTERLEAVED); gst_raw_audio_parse_set_config_channels (config, num_channels, 0, FALSE); memcpy (config->channel_positions, &(GST_AUDIO_INFO_POSITION (&info, 0)), sizeof (GstAudioChannelPosition) * num_channels); } else if (gst_structure_has_name (structure, "audio/x-alaw") || gst_structure_has_name (structure, "audio/x-mulaw")) { gint i; guint64 channel_mask; guint num_channels; config->format = gst_structure_has_name (structure, "audio/x-alaw") ? GST_RAW_AUDIO_PARSE_FORMAT_ALAW : GST_RAW_AUDIO_PARSE_FORMAT_MULAW; if (!gst_structure_get_int (structure, "rate", &i)) { GST_ERROR_OBJECT (raw_audio_parse, "missing rate value in caps %" GST_PTR_FORMAT, (gpointer) caps); goto done; } config->sample_rate = i; if (!gst_structure_get_int (structure, "channels", &i)) { GST_ERROR_OBJECT (raw_audio_parse, "missing channels value in caps %" GST_PTR_FORMAT, (gpointer) caps); goto done; } num_channels = i; if (!gst_structure_get (structure, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL)) { channel_mask = gst_audio_channel_get_fallback_mask (num_channels); GST_DEBUG_OBJECT (raw_audio_parse, "input caps have no channel mask - using fallback mask %#" G_GINT64_MODIFIER "x for %u channels", channel_mask, num_channels); } if (!gst_raw_audio_parse_set_config_channels (config, num_channels, channel_mask, TRUE)) { GST_ERROR_OBJECT (raw_audio_parse, "could not use channel mask %#" G_GINT64_MODIFIER "x for channel positions", channel_mask); goto done; } /* A-law and mu-law both use 1 byte per sample */ config->bpf = 1 * num_channels; } else { GST_ERROR_OBJECT (raw_audio_parse, "caps %" GST_PTR_FORMAT " have an unsupported media type", (gpointer) caps); goto done; } ret = TRUE; done: gst_caps_unref (caps); if (ret) config->ready = TRUE; return ret; }