summaryrefslogtreecommitdiffstats
path: root/gst/wavparse
diff options
context:
space:
mode:
authorThomas Vander Stichele <thomas@apestaart.org>2003-01-14 14:01:49 +0000
committerThomas Vander Stichele <thomas@apestaart.org>2003-01-14 14:01:49 +0000
commitbfedb2363fbe88fd208c23f98b9e4a43b4ec2200 (patch)
tree17aa685d1e614d982e970860fd9b722d9d1c9f02 /gst/wavparse
parent52590aae8f43348f235a44560273b3d604cedcd2 (diff)
fix wavparse so that it handles mp1/2/3 unref buffers that aren't pushed out
Original commit message from CVS: fix wavparse so that it handles mp1/2/3 unref buffers that aren't pushed out
Diffstat (limited to 'gst/wavparse')
-rw-r--r--gst/wavparse/gstwavparse.c110
-rw-r--r--gst/wavparse/gstwavparse.h34
2 files changed, 113 insertions, 31 deletions
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 8eb863b8..a6fd2089 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -57,8 +57,8 @@ GST_PAD_TEMPLATE_FACTORY (sink_template_factory,
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
- "wavparse_wav",
- "audio/x-wav",
+ "wavparse_wav",
+ "audio/x-wav",
NULL
)
)
@@ -68,14 +68,14 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory,
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
- "wavparse_raw",
- "audio/raw",
+ "wavparse_raw",
+ "audio/raw",
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_LIST (
- GST_PROPS_BOOLEAN (FALSE),
- GST_PROPS_BOOLEAN (TRUE)
+ GST_PROPS_BOOLEAN (FALSE),
+ GST_PROPS_BOOLEAN (TRUE)
),
"width", GST_PROPS_LIST (
GST_PROPS_INT (8),
@@ -85,14 +85,19 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory,
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
- "rate", GST_PROPS_INT_RANGE (8000, 48000),
+ "rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2)
+ ),
+ GST_CAPS_NEW (
+ "wavparse_mp3",
+ "audio/x-mp3",
+ NULL
)
)
/* typefactory for 'wav' */
-static GstTypeDefinition
-wavdefinition =
+static GstTypeDefinition
+wavdefinition =
{
"wavparse_audio/x-wav",
"audio/x-wav",
@@ -164,7 +169,7 @@ gst_wavparse_init (GstWavParse *wavparse)
gst_element_add_pad (GST_ELEMENT (wavparse), wavparse->srcpad);
gst_pad_set_formats_function (wavparse->srcpad, gst_wavparse_get_formats);
gst_pad_set_convert_function (wavparse->srcpad, gst_wavparse_pad_convert);
- gst_pad_set_query_type_function (wavparse->srcpad,
+ gst_pad_set_query_type_function (wavparse->srcpad,
gst_wavparse_get_query_types);
gst_pad_set_query_function (wavparse->srcpad, gst_wavparse_pad_query);
@@ -192,6 +197,30 @@ wav_type_find (GstBuffer *buf, gpointer private)
}
+/* set timestamp on outgoing buffer
+ * returns TRUE if a timestamp was set
+ */
+static gboolean
+gst_wavparse_set_timestamp (GstWavParse *wavparse, GstBuffer *buf)
+{
+ gboolean retval = FALSE;
+
+ /* only do timestamps on linear audio */
+ switch (wavparse->format)
+ {
+ case GST_RIFF_WAVE_FORMAT_PCM:
+ GST_BUFFER_TIMESTAMP (buf) = wavparse->offset * GST_SECOND
+ / wavparse->rate;
+ wavparse->offset += GST_BUFFER_SIZE (buf) * 8
+ / (wavparse->width * wavparse->channels);
+ retval = TRUE;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
static void
gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
{
@@ -215,20 +244,22 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
/* we're in the data region */
if (wavparse->state == GST_WAVPARSE_DATA) {
/* if we're expected to see a new chunk in this buffer */
- if ((wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf)) < GST_BUFFER_SIZE (buf)) {
-
- GST_BUFFER_SIZE (buf) = wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf);
-
+ if ((wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf))
+ < GST_BUFFER_SIZE (buf)) {
+ GST_BUFFER_SIZE (buf) = wavparse->riff_nextlikely
+ - GST_BUFFER_OFFSET (buf);
+
wavparse->state = GST_WAVPARSE_OTHER;
/* I suppose we could signal an EOF at this point, but that may be
premature. We've stopped data flow, that's the main thing. */
- }
+ }
- GST_BUFFER_TIMESTAMP (buf) = wavparse->offset * GST_SECOND / wavparse->rate;
- wavparse->offset += GST_BUFFER_SIZE (buf) * 8 / wavparse->width / wavparse->channels;
+ gst_wavparse_set_timestamp (wavparse, buf);
if (GST_PAD_IS_USABLE (wavparse->srcpad))
gst_pad_push (wavparse->srcpad, buf);
+ else
+ gst_buffer_unref (buf);
return;
}
@@ -250,7 +281,7 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
/* create a new RIFF parser */
wavparse->riff = gst_riff_new ();
-
+
/* give it the current buffer to start parsing */
retval = gst_riff_next_buffer (wavparse->riff, buf, 0);
buffer_riffed = TRUE;
@@ -287,8 +318,7 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
/* if we've got something, deal with it */
if (fmt != NULL) {
- GstCaps *caps;
-
+ GstCaps *caps = NULL;
/* we can gather format information now */
format = (GstWavParseFormat *)((guchar *) GST_BUFFER_DATA (buf) + fmt->offset);
@@ -297,20 +327,37 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
wavparse->rate = GUINT32_FROM_LE(format->dwSamplesPerSec);
wavparse->channels = GUINT16_FROM_LE(format->wChannels);
wavparse->width = GUINT16_FROM_LE(format->wBitsPerSample);
-
+ wavparse->format = GINT16_FROM_LE(format->wFormatTag);
+
/* set the caps on the src pad */
- caps = GST_CAPS_NEW (
+ /* FIXME: handle all of the other formats as well */
+ switch (wavparse->format)
+ {
+ case GST_RIFF_WAVE_FORMAT_PCM:
+ caps = GST_CAPS_NEW (
"parsewav_src",
"audio/raw",
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0), /*FIXME */
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
- "signed", GST_PROPS_BOOLEAN ((wavparse->width > 8) ? TRUE : FALSE),
+ "signed", GST_PROPS_BOOLEAN ((wavparse->width > 8) ? TRUE : FALSE),
"width", GST_PROPS_INT (wavparse->width),
"depth", GST_PROPS_INT (wavparse->width),
"rate", GST_PROPS_INT (wavparse->rate),
"channels", GST_PROPS_INT (wavparse->channels)
- );
+ );
+ break;
+ case GST_RIFF_WAVE_FORMAT_MPEGL12:
+ case GST_RIFF_WAVE_FORMAT_MPEGL3:
+ caps = GST_CAPS_NEW (
+ "parsewav_src",
+ "audio/x-mp3",
+ NULL
+ );
+ break;
+ default:
+ g_warning ("wavparse: format %d not handled", wavparse->format);
+ }
if (gst_pad_try_set_caps (wavparse->srcpad, caps) <= 0) {
gst_element_error (GST_ELEMENT (wavparse), "Could not set caps");
@@ -318,7 +365,7 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
}
GST_DEBUG (0, "frequency %d, channels %d",
- wavparse->rate, wavparse->channels);
+ wavparse->rate, wavparse->channels);
/* we're now looking for the data chunk */
wavparse->state = GST_WAVPARSE_CHUNK_DATA;
@@ -355,19 +402,22 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
/* now we construct a new buffer for the remainder */
subsize = size - datachunk->offset;
GST_DEBUG (0, "sending last %ld bytes along as audio", subsize);
-
+
newbuf = gst_buffer_new ();
GST_BUFFER_DATA (newbuf) = g_malloc (subsize);
GST_BUFFER_SIZE (newbuf) = subsize;
- GST_BUFFER_TIMESTAMP (newbuf) = wavparse->offset * GST_SECOND / wavparse->rate;
- wavparse->offset += subsize * 8 / wavparse->width / wavparse->channels;
-
- memcpy (GST_BUFFER_DATA (newbuf), GST_BUFFER_DATA (buf) + datachunk->offset, subsize);
+
+ gst_wavparse_set_timestamp (wavparse, newbuf);
+
+ memcpy (GST_BUFFER_DATA (newbuf),
+ GST_BUFFER_DATA (buf) + datachunk->offset, subsize);
gst_buffer_unref (buf);
if (GST_PAD_IS_USABLE (wavparse->srcpad))
gst_pad_push (wavparse->srcpad, newbuf);
+ else
+ gst_buffer_unref (newbuf);
/* now we're ready to go, the next buffer should start data */
wavparse->state = GST_WAVPARSE_DATA;
diff --git a/gst/wavparse/gstwavparse.h b/gst/wavparse/gstwavparse.h
index 59769973..99e16fae 100644
--- a/gst/wavparse/gstwavparse.h
+++ b/gst/wavparse/gstwavparse.h
@@ -69,6 +69,9 @@ struct _GstWavParse {
/* expected length of audio */
gulong size;
+ /* format of audio, see defines below */
+ gint format;
+
/* useful audio data */
gint bps;
gint rate;
@@ -95,9 +98,38 @@ struct _GstWavParseFormat {
guint16 wBitsPerSample;
};
+/**** from public Microsoft RIFF docs ******/
+#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000)
+#define GST_RIFF_WAVE_FORMAT_PCM (0x0001)
+#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002)
+#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005)
+#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006)
+#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007)
+#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010)
+#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011)
+#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015)
+#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016)
+#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020)
+#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022)
+#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031)
+#define GST_RIFF_WAVE_FORMAT_MSN (0x0032)
+#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050)
+#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055)
+#define GST_RIFF_IBM_FORMAT_MULAW (0x0101)
+#define GST_RIFF_IBM_FORMAT_ALAW (0x0102)
+#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103)
+#define GST_RIFF_WAVE_FORMAT_DIVX (0x0160)
+#define GST_RIFF_WAVE_FORMAT_divx (0x0161)
+#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f)
+#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750)
+#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751)
+#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f)
+#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770)
+#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771)
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* __GST_PARSEAU_H__ */
+#endif /* __GST_WAVPARSE_H__ */