From 8c6168555424789b8479f6c4ac4547a24164bcec Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 15 Mar 2011 17:27:42 +0100 Subject: [PATCH] baseaudio: add audioutils for caps and query handling helper utils --- gst-libs/gst/audio/gstbaseaudioencoder.c | 235 ++--------------------- gst-libs/gst/audio/gstbaseaudioencoder.h | 30 +-- gst-libs/gst/audio/gstbaseaudioutils.c | 315 +++++++++++++++++++++++++++++++ gst-libs/gst/audio/gstbaseaudioutils.h | 74 ++++++++ 4 files changed, 406 insertions(+), 248 deletions(-) create mode 100644 gst-libs/gst/audio/gstbaseaudioutils.c create mode 100644 gst-libs/gst/audio/gstbaseaudioutils.h diff --git a/gst-libs/gst/audio/gstbaseaudioencoder.c b/gst-libs/gst/audio/gstbaseaudioencoder.c index e4d3fa5..48dea5b 100644 --- a/gst-libs/gst/audio/gstbaseaudioencoder.c +++ b/gst-libs/gst/audio/gstbaseaudioencoder.c @@ -150,12 +150,13 @@ # include "config.h" #endif +#include "gstbaseaudioencoder.h" +#include +#include + #include #include -#include "gstbaseaudioencoder.h" - -#include GST_DEBUG_CATEGORY_STATIC (gst_base_audio_encoder_debug); #define GST_CAT_DEFAULT gst_base_audio_encoder_debug @@ -318,7 +319,7 @@ gst_base_audio_encoder_class_init (GstBaseAudioEncoderClass * klass) 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)); } @@ -887,13 +888,6 @@ wrong_buffer: } } -#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) { @@ -902,9 +896,6 @@ 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); @@ -920,36 +911,9 @@ gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps) 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; @@ -1186,83 +1150,13 @@ gst_base_audio_encoder_sink_event (GstPad * pad, GstEvent * event) } 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: { @@ -1277,9 +1171,8 @@ gst_base_audio_encoder_sink_query (GstPad * pad, GstQuery * query) 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; @@ -1290,53 +1183,6 @@ gst_base_audio_encoder_sink_query (GstPad * pad, GstQuery * query) } 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; } @@ -1377,7 +1223,7 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query) 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; } @@ -1402,7 +1248,7 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query) 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; } @@ -1434,7 +1280,8 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query) 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); @@ -1442,7 +1289,7 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query) } 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; @@ -1461,6 +1308,7 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query) gst_query_set_latency (query, live, min_latency, max_latency); } + break; } default: res = gst_pad_query_default (pad, query); @@ -1577,54 +1425,3 @@ gst_base_audio_encoder_sink_activate_push (GstPad * pad, gboolean active) 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; -} diff --git a/gst-libs/gst/audio/gstbaseaudioencoder.h b/gst-libs/gst/audio/gstbaseaudioencoder.h index 3ae69e9..f8d14f4 100644 --- a/gst-libs/gst/audio/gstbaseaudioencoder.h +++ b/gst-libs/gst/audio/gstbaseaudioencoder.h @@ -28,8 +28,7 @@ #endif #include -#include -#include +#include G_BEGIN_DECLS @@ -92,30 +91,6 @@ typedef struct _GstBaseAudioEncoderPrivate GstBaseAudioEncoderPrivate; 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, @@ -244,9 +219,6 @@ GstFlowReturn gst_base_audio_encoder_finish_frame (GstBaseAudioEncoder * enc, 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__ */ diff --git a/gst-libs/gst/audio/gstbaseaudioutils.c b/gst-libs/gst/audio/gstbaseaudioutils.c new file mode 100644 index 0000000..a2eb725 --- /dev/null +++ b/gst-libs/gst/audio/gstbaseaudioutils.c @@ -0,0 +1,315 @@ +/* GStreamer + * Copyright (C) 2011 Mark Nauwelaerts . + * Copyright (C) 2011 Nokia Corporation. All rights reserved. + * Contact: Stefan Kost + * + * 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 +#include + + +#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; +} diff --git a/gst-libs/gst/audio/gstbaseaudioutils.h b/gst-libs/gst/audio/gstbaseaudioutils.h new file mode 100644 index 0000000..ceba86a --- /dev/null +++ b/gst-libs/gst/audio/gstbaseaudioutils.h @@ -0,0 +1,74 @@ +/* GStreamer + * Copyright (C) 2011 Mark Nauwelaerts . + * Copyright (C) 2011 Nokia Corporation. All rights reserved. + * Contact: Stefan Kost + * + * 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 +#include + +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 + -- 2.7.4