# include "config.h"
#endif
+#include "gstbaseaudioencoder.h"
+#include <gst/base/gstadapter.h>
+#include <gst/audio/audio.h>
+
#include <stdlib.h>
#include <string.h>
-#include "gstbaseaudioencoder.h"
-
-#include <gst/audio/audio.h>
GST_DEBUG_CATEGORY_STATIC (gst_base_audio_encoder_debug);
#define GST_CAT_DEFAULT gst_base_audio_encoder_debug
DEFAULT_HARD_RESYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_TOLERANCE,
g_param_spec_int64 ("tolerance", "Tolerance",
- "Consider discontinuity if timestamp jitter/imperfection exceeds tolerance",
+ "Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns)",
0, G_MAXINT64, DEFAULT_TOLERANCE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
}
}
-#define CHECK_VALUE(res, var, val) \
- if (!res) \
- goto refuse_caps; \
- if (var != val) \
- changed = TRUE; \
- var = val;
-
static gboolean
gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
{
GstBaseAudioEncoderContext *ctx;
GstAudioState *state;
gboolean res = TRUE, changed = FALSE;
- GstStructure *s;
- gboolean vb;
- gint vi;
enc = GST_BASE_AUDIO_ENCODER (GST_PAD_PARENT (pad));
klass = GST_BASE_AUDIO_ENCODER_GET_CLASS (enc);
if (!gst_caps_is_fixed (caps))
goto refuse_caps;
- s = gst_caps_get_structure (caps, 0);
- /* parse caps here to save subclass the trouble */
- if (gst_structure_has_name (s, "audio/x-raw-int"))
- state->is_int = TRUE;
- else if (gst_structure_has_name (s, "audio/x-raw-float"))
- state->is_int = FALSE;
- else
- goto refuse_caps;
-
- res = gst_structure_get_int (s, "rate", &vi);
- CHECK_VALUE (res, state->rate, vi);
- res &= gst_structure_get_int (s, "channels", &vi);
- CHECK_VALUE (res, state->channels, vi);
- res &= gst_structure_get_int (s, "width", &vi);
- CHECK_VALUE (res, state->width, vi);
- res &= (!state->is_int || gst_structure_get_int (s, "depth", &vi));
- CHECK_VALUE (res, state->depth, vi);
- res &= gst_structure_get_int (s, "endianness", &vi);
- CHECK_VALUE (res, state->endian, vi);
- res &= (!state->is_int || gst_structure_get_boolean (s, "signed", &vb));
- CHECK_VALUE (res, state->sign, vb);
-
- state->bpf = (state->width / 8) * state->channels;
- GST_LOG_OBJECT (enc, "bpf: %d", state->bpf);
- if (!state->bpf)
+ if (!gst_base_audio_parse_caps (caps, state, &changed))
goto refuse_caps;
- g_free (state->channel_pos);
- state->channel_pos = gst_audio_get_channel_positions (s);
-
if (changed) {
GstClockTime old_min_latency;
GstClockTime old_max_latency;
}
static gboolean
-gst_base_audio_encoder_convert_sink (GstPad * pad, GstFormat src_format,
- gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
+gst_base_audio_encoder_sink_query (GstPad * pad, GstQuery * query)
{
+ gboolean res = TRUE;
GstBaseAudioEncoder *enc;
- gboolean res = FALSE;
- guint scale = 1;
- gint bytes_per_sample, rate, byterate;
enc = GST_BASE_AUDIO_ENCODER (gst_pad_get_parent (pad));
- bytes_per_sample = enc->ctx->state.bpf;
- rate = enc->ctx->state.rate;
- byterate = bytes_per_sample * rate;
-
- if (G_UNLIKELY (bytes_per_sample == 0 || rate == 0)) {
- GST_DEBUG_OBJECT (enc, "not enough metadata yet to convert");
- goto exit;
- }
-
- switch (src_format) {
- case GST_FORMAT_BYTES:
- switch (*dest_format) {
- case GST_FORMAT_DEFAULT:
- *dest_value = src_value / bytes_per_sample;
- res = TRUE;
- break;
- case GST_FORMAT_TIME:
- *dest_value =
- gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
- res = TRUE;
- break;
- default:
- res = FALSE;
- }
- break;
- case GST_FORMAT_DEFAULT:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- *dest_value = src_value * bytes_per_sample;
- res = TRUE;
- break;
- case GST_FORMAT_TIME:
- *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, rate);
- res = TRUE;
- break;
- default:
- res = FALSE;
- }
- break;
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- scale = bytes_per_sample;
- /* fallthrough */
- case GST_FORMAT_DEFAULT:
- *dest_value = gst_util_uint64_scale_int (src_value,
- scale * rate, GST_SECOND);
- res = TRUE;
- break;
- default:
- res = FALSE;
- }
- break;
- default:
- res = FALSE;
- }
-
-exit:
- gst_object_unref (enc);
- return res;
-}
-
-static gboolean
-gst_base_audio_encoder_sink_query (GstPad * pad, GstQuery * query)
-{
- gboolean res = TRUE;
-
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_FORMATS:
{
gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- if (!(res =
- gst_base_audio_encoder_convert_sink (pad, src_fmt, src_val,
- &dest_fmt, &dest_val)))
+ if (!(res = gst_base_audio_raw_audio_convert (&enc->ctx->state,
+ src_fmt, src_val, &dest_fmt, &dest_val)))
goto error;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
break;
}
error:
- return res;
-}
-
-static gboolean
-gst_base_audio_encoder_convert_src (GstPad * pad, GstFormat src_format,
- gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
-{
- GstBaseAudioEncoder *enc;
- gboolean res = FALSE;
- gint64 avg;
-
- enc = GST_BASE_AUDIO_ENCODER (gst_pad_get_parent (pad));
-
- if (enc->priv->samples_in == 0 ||
- enc->priv->bytes_out == 0 || enc->ctx->state.rate == 0) {
- GST_DEBUG_OBJECT (enc, "not enough metadata yet to convert");
- goto exit;
- }
-
- avg = (enc->priv->bytes_out * enc->ctx->state.rate) / (enc->priv->samples_in);
-
- switch (src_format) {
- case GST_FORMAT_BYTES:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, avg);
- res = TRUE;
- break;
- default:
- res = FALSE;
- }
- break;
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_BYTES:
- *dest_value = gst_util_uint64_scale_int (src_value, avg, GST_SECOND);
- res = TRUE;
- break;
- default:
- res = FALSE;
- }
- break;
- default:
- res = FALSE;
- }
-
-exit:
gst_object_unref (enc);
return res;
}
GstFormat fmt, req_fmt;
gint64 pos, val;
- if ((res = gst_pad_peer_query (pad, query))) {
+ if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
GST_LOG_OBJECT (enc, "returning peer response");
break;
}
GstFormat fmt, req_fmt;
gint64 dur, val;
- if ((res = gst_pad_peer_query (pad, query))) {
+ if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
GST_LOG_OBJECT (enc, "returning peer response");
break;
}
gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- if (!(res = gst_base_audio_encoder_convert_src (pad, src_fmt, src_val,
+ if (!(res = gst_base_audio_encoded_audio_convert (&enc->ctx->state,
+ enc->priv->bytes_out, enc->priv->samples_in, src_fmt, src_val,
&dest_fmt, &dest_val)))
break;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
}
case GST_QUERY_LATENCY:
{
- if ((res = gst_pad_peer_query (pad, query))) {
+ if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
gboolean live;
GstClockTime min_latency, max_latency;
gst_query_set_latency (query, live, min_latency, max_latency);
}
+ break;
}
default:
res = gst_pad_query_default (pad, query);
gst_object_unref (enc);
return result;
}
-
-/**
- * gst_base_audio_encoder_add_streamheader:
- * @caps: a #GstCaps
- * @buf: header buffers
- *
- * Adds given buffers to an array of buffers set as streamheader field
- * on the given @caps. List of buffer arguments must be NULL-terminated.
- *
- * Returns: input caps with a streamheader field added, or NULL if some error
- */
-GstCaps *
-gst_base_audio_encoder_add_streamheader (GstCaps * caps, GstBuffer * buf, ...)
-{
- GstStructure *structure = NULL;
- va_list va;
- GValue array = { 0 };
- GValue value = { 0 };
-
- g_return_val_if_fail (caps != NULL, NULL);
- g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
-
- caps = gst_caps_make_writable (caps);
- structure = gst_caps_get_structure (caps, 0);
-
- g_value_init (&array, GST_TYPE_ARRAY);
-
- va_start (va, buf);
- /* put buffers in a fixed list */
- while (buf) {
- g_assert (gst_buffer_is_metadata_writable (buf));
-
- /* mark buffer */
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
-
- g_value_init (&value, GST_TYPE_BUFFER);
- buf = gst_buffer_copy (buf);
- GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
- gst_value_set_buffer (&value, buf);
- gst_buffer_unref (buf);
- gst_value_array_append_value (&array, &value);
- g_value_unset (&value);
-
- buf = va_arg (va, GstBuffer *);
- }
-
- gst_structure_set_value (structure, "streamheader", &array);
- g_value_unset (&array);
-
- return caps;
-}
#endif
#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-#include <gst/audio/multichannel.h>
+#include <gst/audio/gstbaseaudioutils.h>
G_BEGIN_DECLS
typedef struct _GstBaseAudioEncoderContext GstBaseAudioEncoderContext;
/**
- * GstAudioState:
- * @xint: whether sample data is int or float
- * @rate: rate of sample data
- * @channels: number of channels in sample data
- * @width: width (in bits) of sample data
- * @depth: used bits in sample data (if integer)
- * @sign: rate of sample data (if integer)
- * @endian: endianness of sample data
- * @bpf: bytes per audio frame
- */
-typedef struct _GstAudioState {
- gboolean is_int;
- gint rate;
- gint channels;
- gint width;
- gint depth;
- gboolean sign;
- gint endian;
- GstAudioChannelPosition *channel_pos;
-
- gint bpf;
-} GstAudioState;
-
-/**
* GstBaseAudioEncoderContext:
* @state: a #GstAudioState describing input audio format
* @frame_samples: number of samples (per channel) subclass needs to be handed,
GstCaps * gst_base_audio_encoder_proxy_getcaps (GstBaseAudioEncoder * enc,
GstCaps * caps);
-GstCaps * gst_base_audio_encoder_add_streamheader (GstCaps * caps,
- GstBuffer * buf, ...);
-
G_END_DECLS
#endif /* __GST_BASE_AUDIO_ENCODER_H__ */
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
+ * Copyright (C) 2011 Nokia Corporation. All rights reserved.
+ * Contact: Stefan Kost <stefan.kost@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gstbaseaudioutils.h"
+
+#include <gst/gst.h>
+#include <gst/audio/multichannel.h>
+
+
+#define CHECK_VALUE(var, val) \
+G_STMT_START { \
+ if (!res) \
+ goto fail; \
+ if (var != val) \
+ changed = TRUE; \
+ var = val; \
+} G_STMT_END
+
+/**
+ * gst_base_audio_parse_caps:
+ * @caps: a #GstCaps
+ * @state: a #GstAudioState
+ * @changed: whether @caps introduced a change in current @state
+ *
+ * Parses audio format as represented by @caps into a more concise form
+ * as represented by @state, while checking if for changes to currently
+ * defined audio format.
+ *
+ * Returns: TRUE if parsing succeeded, otherwise FALSE
+ */
+gboolean
+gst_base_audio_parse_caps (GstCaps * caps, GstAudioState * state,
+ gboolean * _changed)
+{
+ gboolean res = TRUE, changed = FALSE;
+ GstStructure *s;
+ gboolean vb;
+ gint vi;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+ s = gst_caps_get_structure (caps, 0);
+ if (gst_structure_has_name (s, "audio/x-raw-int"))
+ state->is_int = TRUE;
+ else if (gst_structure_has_name (s, "audio/x-raw-float"))
+ state->is_int = FALSE;
+ else
+ goto fail;
+
+ res = gst_structure_get_int (s, "rate", &vi);
+ CHECK_VALUE (state->rate, vi);
+ res &= gst_structure_get_int (s, "channels", &vi);
+ CHECK_VALUE (state->channels, vi);
+ res &= gst_structure_get_int (s, "width", &vi);
+ CHECK_VALUE (state->width, vi);
+ res &= (!state->is_int || gst_structure_get_int (s, "depth", &vi));
+ CHECK_VALUE (state->depth, vi);
+ res &= gst_structure_get_int (s, "endianness", &vi);
+ CHECK_VALUE (state->endian, vi);
+ res &= (!state->is_int || gst_structure_get_boolean (s, "signed", &vb));
+ CHECK_VALUE (state->sign, vb);
+
+ state->bpf = (state->width / 8) * state->channels;
+ GST_LOG ("bpf: %d", state->bpf);
+ if (!state->bpf)
+ goto fail;
+
+ g_free (state->channel_pos);
+ state->channel_pos = gst_audio_get_channel_positions (s);
+
+ if (_changed)
+ *_changed = changed;
+
+ return res;
+
+ /* ERRORS */
+fail:
+ {
+ /* there should not be caps out there that fail parsing ... */
+ GST_WARNING ("failed to parse caps %" GST_PTR_FORMAT, caps);
+ return res;
+ }
+}
+
+/**
+ * gst_base_audio_add_streamheader:
+ * @caps: a #GstCaps
+ * @buf: header buffers
+ *
+ * Adds given buffers to an array of buffers set as streamheader field
+ * on the given @caps. List of buffer arguments must be NULL-terminated.
+ *
+ * Returns: input caps with a streamheader field added, or NULL if some error
+ */
+GstCaps *
+gst_base_audio_add_streamheader (GstCaps * caps, GstBuffer * buf, ...)
+{
+ GstStructure *structure = NULL;
+ va_list va;
+ GValue array = { 0 };
+ GValue value = { 0 };
+
+ g_return_val_if_fail (caps != NULL, NULL);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
+
+ caps = gst_caps_make_writable (caps);
+ structure = gst_caps_get_structure (caps, 0);
+
+ g_value_init (&array, GST_TYPE_ARRAY);
+
+ va_start (va, buf);
+ /* put buffers in a fixed list */
+ while (buf) {
+ g_assert (gst_buffer_is_metadata_writable (buf));
+
+ /* mark buffer */
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
+
+ g_value_init (&value, GST_TYPE_BUFFER);
+ buf = gst_buffer_copy (buf);
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
+ gst_value_set_buffer (&value, buf);
+ gst_buffer_unref (buf);
+ gst_value_array_append_value (&array, &value);
+ g_value_unset (&value);
+
+ buf = va_arg (va, GstBuffer *);
+ }
+
+ gst_structure_set_value (structure, "streamheader", &array);
+ g_value_unset (&array);
+
+ return caps;
+}
+
+/**
+ * gst_base_audio_encoded_audio_convert:
+ * @fmt: audio format of the encoded audio
+ * @bytes: number of encoded bytes
+ * @samples: number of encoded samples
+ * @src_format: source format
+ * @src_value: source value
+ * @dest_format: destination format
+ * @dest_value: destination format
+ *
+ * Helper function to convert @src_value in @src_format to @dest_value in
+ * @dest_format for encoded audio data. Conversion is possible between
+ * BYTE and TIME format by using estimated bitrate based on
+ * @samples and @bytes (and @fmt).
+ */
+gboolean
+gst_base_audio_encoded_audio_convert (GstAudioState * fmt,
+ gint64 bytes, gint64 samples, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
+{
+ gboolean res = FALSE;
+
+ g_return_val_if_fail (dest_format != NULL, FALSE);
+ g_return_val_if_fail (dest_value != NULL, FALSE);
+
+ if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
+ src_value == -1)) {
+ if (dest_value)
+ *dest_value = src_value;
+ return TRUE;
+ }
+
+ if (samples == 0 || bytes == 0 || fmt->rate == 0) {
+ GST_DEBUG ("not enough metadata yet to convert");
+ goto exit;
+ }
+
+ bytes *= fmt->rate;
+
+ switch (src_format) {
+ case GST_FORMAT_BYTES:
+ switch (*dest_format) {
+ case GST_FORMAT_TIME:
+ *dest_value = gst_util_uint64_scale (src_value,
+ GST_SECOND * samples, bytes);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ *dest_value = gst_util_uint64_scale (src_value, bytes,
+ samples * GST_SECOND);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ default:
+ res = FALSE;
+ }
+
+exit:
+ return res;
+}
+
+/**
+ * gst_base_audio_raw_audio_convert:
+ * @fmt: audio format of the encoded audio
+ * @src_format: source format
+ * @src_value: source value
+ * @dest_format: destination format
+ * @dest_value: destination format
+ *
+ * Helper function to convert @src_value in @src_format to @dest_value in
+ * @dest_format for encoded audio data. Conversion is possible between
+ * BYTE, DEFAULT and TIME format based on audio characteristics provided
+ * by @fmt.
+ */
+gboolean
+gst_base_audio_raw_audio_convert (GstAudioState * fmt, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
+{
+ gboolean res = FALSE;
+ guint scale = 1;
+ gint bytes_per_sample, rate, byterate;
+
+ g_return_val_if_fail (dest_format != NULL, FALSE);
+ g_return_val_if_fail (dest_value != NULL, FALSE);
+
+ if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
+ src_value == -1)) {
+ if (dest_value)
+ *dest_value = src_value;
+ return TRUE;
+ }
+
+ bytes_per_sample = fmt->bpf;
+ rate = fmt->rate;
+ byterate = bytes_per_sample * rate;
+
+ if (G_UNLIKELY (bytes_per_sample == 0 || rate == 0)) {
+ GST_DEBUG ("not enough metadata yet to convert");
+ goto exit;
+ }
+
+ switch (src_format) {
+ case GST_FORMAT_BYTES:
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_value = src_value / bytes_per_sample;
+ res = TRUE;
+ break;
+ case GST_FORMAT_TIME:
+ *dest_value =
+ gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_DEFAULT:
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ *dest_value = src_value * bytes_per_sample;
+ res = TRUE;
+ break;
+ case GST_FORMAT_TIME:
+ *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND, rate);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ scale = bytes_per_sample;
+ /* fallthrough */
+ case GST_FORMAT_DEFAULT:
+ *dest_value = gst_util_uint64_scale_int (src_value,
+ scale * rate, GST_SECOND);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ default:
+ res = FALSE;
+ }
+
+exit:
+ return res;
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
+ * Copyright (C) 2011 Nokia Corporation. All rights reserved.
+ * Contact: Stefan Kost <stefan.kost@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_BASE_AUDIO_UTILS_H_
+#define _GST_BASE_AUDIO_UTILS_H_
+
+#ifndef GST_USE_UNSTABLE_API
+#warning "Base audio utils provide unstable API and may change in future."
+#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
+#endif
+
+#include <gst/gst.h>
+#include <gst/audio/multichannel.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstAudioState:
+ * @is_int: whether sample data is int or float
+ * @rate: rate of sample data
+ * @channels: number of channels in sample data
+ * @width: width (in bits) of sample data
+ * @depth: used bits in sample data (if integer)
+ * @sign: sign of sample data (if integer)
+ * @endian: endianness of sample data
+ * @bpf: bytes per audio frame
+ */
+typedef struct _GstAudioState {
+ gboolean is_int;
+ gint rate;
+ gint channels;
+ gint width;
+ gint depth;
+ gboolean sign;
+ gint endian;
+ GstAudioChannelPosition *channel_pos;
+
+ gint bpf;
+} GstAudioState;
+
+gboolean gst_base_audio_parse_caps (GstCaps * caps,
+ GstAudioState * state, gboolean * changed);
+
+GstCaps *gst_base_audio_add_streamheader (GstCaps * caps, GstBuffer * buf, ...);
+
+gboolean gst_base_audio_encoded_audio_convert (GstAudioState * fmt,
+ gint64 bytes, gint64 samples, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
+
+gboolean gst_base_audio_raw_audio_convert (GstAudioState * fmt, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
+
+G_END_DECLS
+
+#endif
+