audioutils: modify _parse, add GType support functions

This commit is contained in:
Mark Nauwelaerts 2011-08-17 18:32:54 +02:00 committed by Tim-Philipp Müller
parent a4d5e33224
commit 35b172004c
4 changed files with 146 additions and 34 deletions

View file

@ -418,7 +418,7 @@ gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full)
dec->priv->error_count = 0;
gst_base_audio_decoder_clear_queues (dec);
g_free (dec->priv->ctx.info.channel_pos);
gst_base_audio_format_info_clear (&dec->priv->ctx.info);
memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
if (dec->priv->taglist) {
@ -470,7 +470,7 @@ gst_base_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
{
GstBaseAudioDecoder *dec;
GstAudioFormatInfo *state;
gboolean res = TRUE, changed;
gboolean res = TRUE;
dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
state = &dec->priv->ctx.info;
@ -489,7 +489,7 @@ gst_base_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
dec->priv->samples = 0;
}
if (!gst_base_audio_parse_caps (caps, state, &changed))
if (!gst_base_audio_parse_caps (caps, state))
goto refuse_caps;
gst_object_unref (dec);

View file

@ -410,7 +410,7 @@ gst_base_audio_encoder_reset (GstBaseAudioEncoder * enc, gboolean full)
enc->priv->active = FALSE;
enc->priv->samples_in = 0;
enc->priv->bytes_out = 0;
g_free (enc->priv->ctx.info.channel_pos);
gst_base_audio_format_info_clear (&enc->priv->ctx.info);
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
}
@ -941,7 +941,7 @@ gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
GstBaseAudioEncoder *enc;
GstBaseAudioEncoderClass *klass;
GstBaseAudioEncoderContext *ctx;
GstAudioFormatInfo *state;
GstAudioFormatInfo *state, *ostate;
gboolean res = TRUE, changed = FALSE;
enc = GST_BASE_AUDIO_ENCODER (GST_PAD_PARENT (pad));
@ -965,9 +965,13 @@ gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
enc->priv->samples = 0;
}
if (!gst_base_audio_parse_caps (caps, state, &changed))
ostate = gst_base_audio_format_info_copy (state);
if (!gst_base_audio_parse_caps (caps, state))
goto refuse_caps;
changed = gst_base_audio_compare_format_info (state, ostate);
gst_base_audio_format_info_free (ostate);
if (changed) {
GstClockTime old_min_latency;
GstClockTime old_max_latency;

View file

@ -24,13 +24,98 @@
#include <gst/gst.h>
#include <gst/audio/multichannel.h>
#include <string.h>
/**
* gst_base_audio_format_init:
* @info: (transfer none): a #GstAudioFormatInfo instance
*
* Initializes a #GstAudioFormatInfo instance for subsequent use.
* The instance must either have been previously cleared or set to 0
* upon allocation.
*/
void
gst_base_audio_format_info_init (GstAudioFormatInfo * info)
{
g_return_if_fail (info != NULL);
/* no-op for now */
}
/**
* gst_base_audio_format_info_new:
*
* Allocate a new #GstAudioFormatInfo structure and initialize it using
* gst_base_audio_format_info().
*
* Free-function: gst_base_audio_format_info_free
*
* Returns: (transfer full): a new #GstAudioFormatInfo,
* free with gst_base_audio_format_info_free().
*/
GstAudioFormatInfo *
gst_base_audio_format_info_new (void)
{
GstAudioFormatInfo *result;
result = g_slice_new0 (GstAudioFormatInfo);
gst_base_audio_format_info_init (result);
return result;
}
/**
* gst_base_audio_format_clear:
* @info: (transfer none): a #GstAudioFormatInfo instance
*
* Clears a #GstAudioFormatInfo instance.
*/
void
gst_base_audio_format_info_clear (GstAudioFormatInfo * info)
{
g_return_if_fail (info != NULL);
g_free (info->channel_pos);
memset (info, 0, sizeof (*info));
}
/**
* gst_base_audio_format_copy:
* @info: (transfer none): a #GstAudioFormatInfo instance
*
* Create a copy of a given #GstAudioFormatInfo instance.
*
* Returns: (transfer full): a new #GstAudioFormatInfo,
* free with gst_base_audio_format_info_free()
*/
GstAudioFormatInfo *
gst_base_audio_format_info_copy (GstAudioFormatInfo * info)
{
GstAudioFormatInfo *result = NULL;
if (info) {
result = (GstAudioFormatInfo *) g_slice_copy (sizeof (GstAudioFormatInfo),
info);
}
return result;
}
/**
* gst_base_audio_format_free:
* @info: (in) (transfer full): a #GstAudioFormatInfo instance
*
* Frees the allocated @info.
*/
void
gst_base_audio_format_info_free (GstAudioFormatInfo * info)
{
g_slice_free (GstAudioFormatInfo, info);
}
#define CHECK_VALUE(var, val) \
G_STMT_START { \
if (!res) \
goto fail; \
if (var != val) \
changed = TRUE; \
var = val; \
} G_STMT_END
@ -38,19 +123,16 @@ G_STMT_START { \
* gst_base_audio_parse_caps:
* @caps: a #GstCaps
* @state: a #GstAudioFormatInfo
* @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.
* as represented by @state.
*
* Returns: TRUE if parsing succeeded, otherwise FALSE
*/
gboolean
gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * state,
gboolean * _changed)
gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * info)
{
gboolean res = TRUE, changed = FALSE;
gboolean res = TRUE;
GstStructure *s;
gboolean vb;
gint vi;
@ -58,37 +140,35 @@ gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * state,
g_return_val_if_fail (caps != NULL, FALSE);
g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
gst_base_audio_format_info_clear (info);
s = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (s, "audio/x-raw-int"))
state->is_int = TRUE;
info->is_int = TRUE;
else if (gst_structure_has_name (s, "audio/x-raw-float"))
state->is_int = FALSE;
info->is_int = FALSE;
else
goto fail;
res = gst_structure_get_int (s, "rate", &vi);
CHECK_VALUE (state->rate, vi);
CHECK_VALUE (info->rate, vi);
res &= gst_structure_get_int (s, "channels", &vi);
CHECK_VALUE (state->channels, vi);
CHECK_VALUE (info->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);
CHECK_VALUE (info->width, vi);
res &= (!info->is_int || gst_structure_get_int (s, "depth", &vi));
CHECK_VALUE (info->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);
CHECK_VALUE (info->endian, vi);
res &= (!info->is_int || gst_structure_get_boolean (s, "signed", &vb));
CHECK_VALUE (info->sign, vb);
state->bpf = (state->width / 8) * state->channels;
GST_LOG ("bpf: %d", state->bpf);
if (!state->bpf)
info->bpf = (info->width / 8) * info->channels;
GST_LOG ("bpf: %d", info->bpf);
if (!info->bpf)
goto fail;
g_free (state->channel_pos);
state->channel_pos = gst_audio_get_channel_positions (s);
if (_changed)
*_changed = changed;
info->channel_pos = gst_audio_get_channel_positions (s);
return res;
@ -101,6 +181,27 @@ fail:
}
}
/**
* gst_base_audio_compare_format_info:
* @from: a #GstAudioFormatInfo
* @to: a #GstAudioFormatInfo
*
* Checks whether provides #GstAudioFormatInfo instances represent identical
* audio dat.
*
* Returns: TRUE if represent audio formats are identical
*/
gboolean
gst_base_audio_compare_format_info (GstAudioFormatInfo * from,
GstAudioFormatInfo * to)
{
g_return_val_if_fail (from != NULL, FALSE);
g_return_val_if_fail (to != NULL, FALSE);
/* this is a bit silly, so maybe should not need this function at all */
return memcmp (from, to, sizeof (*from));
}
/**
* gst_base_audio_add_streamheader:
* @caps: a #GstCaps

View file

@ -56,8 +56,15 @@ typedef struct _GstAudioFormatInfo {
gint bpf;
} GstAudioFormatInfo;
gboolean gst_base_audio_parse_caps (GstCaps * caps,
GstAudioFormatInfo * state, gboolean * changed);
void gst_base_audio_format_info_init (GstAudioFormatInfo * info);
void gst_base_audio_format_info_clear (GstAudioFormatInfo * info);
GstAudioFormatInfo *gst_base_audio_format_info_new (void);
void gst_base_audio_format_info_free (GstAudioFormatInfo * info);
GstAudioFormatInfo *gst_base_audio_format_info_copy (GstAudioFormatInfo * info);
gboolean gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * info);
gboolean gst_base_audio_compare_format_info (GstAudioFormatInfo * from,
GstAudioFormatInfo * to);
GstCaps *gst_base_audio_add_streamheader (GstCaps * caps, GstBuffer * buf, ...);