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; dec->priv->error_count = 0;
gst_base_audio_decoder_clear_queues (dec); 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)); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
if (dec->priv->taglist) { if (dec->priv->taglist) {
@ -470,7 +470,7 @@ gst_base_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
{ {
GstBaseAudioDecoder *dec; GstBaseAudioDecoder *dec;
GstAudioFormatInfo *state; GstAudioFormatInfo *state;
gboolean res = TRUE, changed; gboolean res = TRUE;
dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad)); dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
state = &dec->priv->ctx.info; state = &dec->priv->ctx.info;
@ -489,7 +489,7 @@ gst_base_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
dec->priv->samples = 0; dec->priv->samples = 0;
} }
if (!gst_base_audio_parse_caps (caps, state, &changed)) if (!gst_base_audio_parse_caps (caps, state))
goto refuse_caps; goto refuse_caps;
gst_object_unref (dec); 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->active = FALSE;
enc->priv->samples_in = 0; enc->priv->samples_in = 0;
enc->priv->bytes_out = 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)); 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; GstBaseAudioEncoder *enc;
GstBaseAudioEncoderClass *klass; GstBaseAudioEncoderClass *klass;
GstBaseAudioEncoderContext *ctx; GstBaseAudioEncoderContext *ctx;
GstAudioFormatInfo *state; GstAudioFormatInfo *state, *ostate;
gboolean res = TRUE, changed = FALSE; gboolean res = TRUE, changed = FALSE;
enc = GST_BASE_AUDIO_ENCODER (GST_PAD_PARENT (pad)); 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; 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; goto refuse_caps;
changed = gst_base_audio_compare_format_info (state, ostate);
gst_base_audio_format_info_free (ostate);
if (changed) { if (changed) {
GstClockTime old_min_latency; GstClockTime old_min_latency;
GstClockTime old_max_latency; GstClockTime old_max_latency;

View file

@ -24,13 +24,98 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/audio/multichannel.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) \ #define CHECK_VALUE(var, val) \
G_STMT_START { \ G_STMT_START { \
if (!res) \ if (!res) \
goto fail; \ goto fail; \
if (var != val) \
changed = TRUE; \
var = val; \ var = val; \
} G_STMT_END } G_STMT_END
@ -38,19 +123,16 @@ G_STMT_START { \
* gst_base_audio_parse_caps: * gst_base_audio_parse_caps:
* @caps: a #GstCaps * @caps: a #GstCaps
* @state: a #GstAudioFormatInfo * @state: a #GstAudioFormatInfo
* @changed: whether @caps introduced a change in current @state
* *
* Parses audio format as represented by @caps into a more concise form * Parses audio format as represented by @caps into a more concise form
* as represented by @state, while checking if for changes to currently * as represented by @state.
* defined audio format.
* *
* Returns: TRUE if parsing succeeded, otherwise FALSE * Returns: TRUE if parsing succeeded, otherwise FALSE
*/ */
gboolean gboolean
gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * state, gst_base_audio_parse_caps (GstCaps * caps, GstAudioFormatInfo * info)
gboolean * _changed)
{ {
gboolean res = TRUE, changed = FALSE; gboolean res = TRUE;
GstStructure *s; GstStructure *s;
gboolean vb; gboolean vb;
gint vi; 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 (caps != NULL, FALSE);
g_return_val_if_fail (gst_caps_is_fixed (caps), 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); s = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (s, "audio/x-raw-int")) 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")) else if (gst_structure_has_name (s, "audio/x-raw-float"))
state->is_int = FALSE; info->is_int = FALSE;
else else
goto fail; goto fail;
res = gst_structure_get_int (s, "rate", &vi); 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); 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); res &= gst_structure_get_int (s, "width", &vi);
CHECK_VALUE (state->width, vi); CHECK_VALUE (info->width, vi);
res &= (!state->is_int || gst_structure_get_int (s, "depth", &vi)); res &= (!info->is_int || gst_structure_get_int (s, "depth", &vi));
CHECK_VALUE (state->depth, vi); CHECK_VALUE (info->depth, vi);
res &= gst_structure_get_int (s, "endianness", &vi); res &= gst_structure_get_int (s, "endianness", &vi);
CHECK_VALUE (state->endian, vi); CHECK_VALUE (info->endian, vi);
res &= (!state->is_int || gst_structure_get_boolean (s, "signed", &vb)); res &= (!info->is_int || gst_structure_get_boolean (s, "signed", &vb));
CHECK_VALUE (state->sign, vb); CHECK_VALUE (info->sign, vb);
state->bpf = (state->width / 8) * state->channels; info->bpf = (info->width / 8) * info->channels;
GST_LOG ("bpf: %d", state->bpf); GST_LOG ("bpf: %d", info->bpf);
if (!state->bpf) if (!info->bpf)
goto fail; goto fail;
g_free (state->channel_pos); info->channel_pos = gst_audio_get_channel_positions (s);
state->channel_pos = gst_audio_get_channel_positions (s);
if (_changed)
*_changed = changed;
return res; 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: * gst_base_audio_add_streamheader:
* @caps: a #GstCaps * @caps: a #GstCaps

View file

@ -56,8 +56,15 @@ typedef struct _GstAudioFormatInfo {
gint bpf; gint bpf;
} GstAudioFormatInfo; } GstAudioFormatInfo;
gboolean gst_base_audio_parse_caps (GstCaps * caps, void gst_base_audio_format_info_init (GstAudioFormatInfo * info);
GstAudioFormatInfo * state, gboolean * changed); 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, ...); GstCaps *gst_base_audio_add_streamheader (GstCaps * caps, GstBuffer * buf, ...);