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
This commit is contained in:
parent
52590aae8f
commit
bfedb2363f
@ -87,6 +87,11 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory,
|
|||||||
),
|
),
|
||||||
"rate", GST_PROPS_INT_RANGE (8000, 48000),
|
"rate", GST_PROPS_INT_RANGE (8000, 48000),
|
||||||
"channels", GST_PROPS_INT_RANGE (1, 2)
|
"channels", GST_PROPS_INT_RANGE (1, 2)
|
||||||
|
),
|
||||||
|
GST_CAPS_NEW (
|
||||||
|
"wavparse_mp3",
|
||||||
|
"audio/x-mp3",
|
||||||
|
NULL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -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
|
static void
|
||||||
gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
||||||
{
|
{
|
||||||
@ -215,20 +244,22 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
|||||||
/* we're in the data region */
|
/* we're in the data region */
|
||||||
if (wavparse->state == GST_WAVPARSE_DATA) {
|
if (wavparse->state == GST_WAVPARSE_DATA) {
|
||||||
/* if we're expected to see a new chunk in this buffer */
|
/* if we're expected to see a new chunk in this buffer */
|
||||||
if ((wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf)) < GST_BUFFER_SIZE (buf)) {
|
if ((wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf))
|
||||||
|
< GST_BUFFER_SIZE (buf)) {
|
||||||
GST_BUFFER_SIZE (buf) = wavparse->riff_nextlikely - GST_BUFFER_OFFSET (buf);
|
GST_BUFFER_SIZE (buf) = wavparse->riff_nextlikely
|
||||||
|
- GST_BUFFER_OFFSET (buf);
|
||||||
|
|
||||||
wavparse->state = GST_WAVPARSE_OTHER;
|
wavparse->state = GST_WAVPARSE_OTHER;
|
||||||
/* I suppose we could signal an EOF at this point, but that may be
|
/* 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. */
|
premature. We've stopped data flow, that's the main thing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (buf) = wavparse->offset * GST_SECOND / wavparse->rate;
|
gst_wavparse_set_timestamp (wavparse, buf);
|
||||||
wavparse->offset += GST_BUFFER_SIZE (buf) * 8 / wavparse->width / wavparse->channels;
|
|
||||||
|
|
||||||
if (GST_PAD_IS_USABLE (wavparse->srcpad))
|
if (GST_PAD_IS_USABLE (wavparse->srcpad))
|
||||||
gst_pad_push (wavparse->srcpad, buf);
|
gst_pad_push (wavparse->srcpad, buf);
|
||||||
|
else
|
||||||
|
gst_buffer_unref (buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,8 +318,7 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
|||||||
|
|
||||||
/* if we've got something, deal with it */
|
/* if we've got something, deal with it */
|
||||||
if (fmt != NULL) {
|
if (fmt != NULL) {
|
||||||
GstCaps *caps;
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* we can gather format information now */
|
/* we can gather format information now */
|
||||||
format = (GstWavParseFormat *)((guchar *) GST_BUFFER_DATA (buf) + fmt->offset);
|
format = (GstWavParseFormat *)((guchar *) GST_BUFFER_DATA (buf) + fmt->offset);
|
||||||
@ -297,8 +327,13 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
|||||||
wavparse->rate = GUINT32_FROM_LE(format->dwSamplesPerSec);
|
wavparse->rate = GUINT32_FROM_LE(format->dwSamplesPerSec);
|
||||||
wavparse->channels = GUINT16_FROM_LE(format->wChannels);
|
wavparse->channels = GUINT16_FROM_LE(format->wChannels);
|
||||||
wavparse->width = GUINT16_FROM_LE(format->wBitsPerSample);
|
wavparse->width = GUINT16_FROM_LE(format->wBitsPerSample);
|
||||||
|
wavparse->format = GINT16_FROM_LE(format->wFormatTag);
|
||||||
|
|
||||||
/* set the caps on the src pad */
|
/* set the caps on the src pad */
|
||||||
|
/* FIXME: handle all of the other formats as well */
|
||||||
|
switch (wavparse->format)
|
||||||
|
{
|
||||||
|
case GST_RIFF_WAVE_FORMAT_PCM:
|
||||||
caps = GST_CAPS_NEW (
|
caps = GST_CAPS_NEW (
|
||||||
"parsewav_src",
|
"parsewav_src",
|
||||||
"audio/raw",
|
"audio/raw",
|
||||||
@ -311,6 +346,18 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
|||||||
"rate", GST_PROPS_INT (wavparse->rate),
|
"rate", GST_PROPS_INT (wavparse->rate),
|
||||||
"channels", GST_PROPS_INT (wavparse->channels)
|
"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) {
|
if (gst_pad_try_set_caps (wavparse->srcpad, caps) <= 0) {
|
||||||
gst_element_error (GST_ELEMENT (wavparse), "Could not set caps");
|
gst_element_error (GST_ELEMENT (wavparse), "Could not set caps");
|
||||||
@ -359,15 +406,18 @@ gst_wavparse_chain (GstPad *pad, GstBuffer *buf)
|
|||||||
newbuf = gst_buffer_new ();
|
newbuf = gst_buffer_new ();
|
||||||
GST_BUFFER_DATA (newbuf) = g_malloc (subsize);
|
GST_BUFFER_DATA (newbuf) = g_malloc (subsize);
|
||||||
GST_BUFFER_SIZE (newbuf) = 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);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
if (GST_PAD_IS_USABLE (wavparse->srcpad))
|
if (GST_PAD_IS_USABLE (wavparse->srcpad))
|
||||||
gst_pad_push (wavparse->srcpad, newbuf);
|
gst_pad_push (wavparse->srcpad, newbuf);
|
||||||
|
else
|
||||||
|
gst_buffer_unref (newbuf);
|
||||||
|
|
||||||
/* now we're ready to go, the next buffer should start data */
|
/* now we're ready to go, the next buffer should start data */
|
||||||
wavparse->state = GST_WAVPARSE_DATA;
|
wavparse->state = GST_WAVPARSE_DATA;
|
||||||
|
@ -69,6 +69,9 @@ struct _GstWavParse {
|
|||||||
/* expected length of audio */
|
/* expected length of audio */
|
||||||
gulong size;
|
gulong size;
|
||||||
|
|
||||||
|
/* format of audio, see defines below */
|
||||||
|
gint format;
|
||||||
|
|
||||||
/* useful audio data */
|
/* useful audio data */
|
||||||
gint bps;
|
gint bps;
|
||||||
gint rate;
|
gint rate;
|
||||||
@ -95,9 +98,38 @@ struct _GstWavParseFormat {
|
|||||||
guint16 wBitsPerSample;
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_PARSEAU_H__ */
|
#endif /* __GST_WAVPARSE_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user