gst/wavparse/gstwavparse.c: When operating chain-based, don't make any assumptions about the chunking of the incoming...

Original commit message from CVS:
* gst/wavparse/gstwavparse.c: (gst_wavparse_peek_chunk_info),
(gst_wavparse_peek_chunk), (gst_wavparse_stream_headers),
(gst_wavparse_chain):
When operating chain-based, don't make any assumptions about the
chunking of the incoming data and make streaming work on days other
than the second Thursday after a full moon. Also fix up debug
messages here and there and make use of the most excellent new
gst_pad_query_peer_duration() utility function.
Skip any 'bext' chunks in front of the 'fmt ' chunk. Fixes #343837.
* gst/wavparse/gstwavparse.h:
Remove trailing comma after last enum value, some compilers don't
like that.
This commit is contained in:
Tim-Philipp Müller 2006-06-14 08:06:43 +00:00
parent 6de492dea8
commit 84e86aebf7
3 changed files with 60 additions and 27 deletions

View file

@ -1,3 +1,19 @@
2006-06-14 Tim-Philipp Müller <tim at centricular dot net>
* gst/wavparse/gstwavparse.c: (gst_wavparse_peek_chunk_info),
(gst_wavparse_peek_chunk), (gst_wavparse_stream_headers),
(gst_wavparse_chain):
When operating chain-based, don't make any assumptions about the
chunking of the incoming data and make streaming work on days other
than the second Thursday after a full moon. Also fix up debug
messages here and there and make use of the most excellent new
gst_pad_query_peer_duration() utility function.
Skip any 'bext' chunks in front of the 'fmt ' chunk. Fixes #343837.
* gst/wavparse/gstwavparse.h:
Remove trailing comma after last enum value, some compilers don't
like that.
2006-06-13 Wim Taymans <wim@fluendo.com> 2006-06-13 Wim Taymans <wim@fluendo.com>
* gst/wavparse/gstwavparse.c: (gst_wavparse_stream_data): * gst/wavparse/gstwavparse.c: (gst_wavparse_stream_data):

View file

@ -930,11 +930,13 @@ gst_wavparse_peek_chunk_info (GstWavParse * wav, guint32 * tag, guint32 * size)
return FALSE; return FALSE;
} }
GST_DEBUG ("Next chunk size is %d bytes", *size);
data = gst_adapter_peek (wav->adapter, 8); data = gst_adapter_peek (wav->adapter, 8);
*tag = GST_READ_UINT32_LE (data); *tag = GST_READ_UINT32_LE (data);
*size = GST_READ_UINT32_LE (data + 4); *size = GST_READ_UINT32_LE (data + 4);
GST_DEBUG ("Next chunk size is %d bytes, type %" GST_FOURCC_FORMAT, *size,
GST_FOURCC_ARGS (*tag));
return TRUE; return TRUE;
} }
@ -952,32 +954,30 @@ static gboolean
gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size) gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size)
{ {
guint32 peek_size = 0; guint32 peek_size = 0;
guint available;
if (!gst_wavparse_peek_chunk_info (wav, tag, size))
return FALSE;
gst_wavparse_peek_chunk_info (wav, tag, size);
GST_DEBUG ("Need to peek chunk of %d bytes", *size); GST_DEBUG ("Need to peek chunk of %d bytes", *size);
peek_size = (*size + 1) & ~1; peek_size = (*size + 1) & ~1;
if (gst_adapter_available (wav->adapter) >= (8 + peek_size)) { available = gst_adapter_available (wav->adapter);
if (available >= (8 + peek_size)) {
return TRUE; return TRUE;
} else { } else {
GST_LOG ("but only %u bytes available now", available);
return FALSE; return FALSE;
} }
} }
static gboolean /* FIXME: remove once -base 0.10.9 is out */
gst_wavparse_get_upstream_size (GstWavParse * wav, gint64 * len) #ifndef GST_RIFF_TAG_bext
{ #define GST_RIFF_TAG_bext GST_MAKE_FOURCC ('b', 'e', 'x', 't')
gboolean res = FALSE; #endif
GstFormat fmt = GST_FORMAT_BYTES; #ifndef GST_RIFF_TAG_BEXT
GstPad *peer; #define GST_RIFF_TAG_BEXT GST_MAKE_FOURCC ('B', 'E', 'X', 'T')
#endif
if ((peer = gst_pad_get_peer (wav->sinkpad))) {
res = gst_pad_query_duration (peer, &fmt, len);
gst_object_unref (peer);
}
return res;
}
static GstFlowReturn static GstFlowReturn
gst_wavparse_stream_headers (GstWavParse * wav) gst_wavparse_stream_headers (GstWavParse * wav)
@ -992,11 +992,10 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gchar *codec_name = NULL; gchar *codec_name = NULL;
GstEvent **event_p; GstEvent **event_p;
if (!wav->got_fmt) { while (!wav->got_fmt) {
GstBuffer *extra; GstBuffer *extra;
/* The header start with a 'fmt ' tag */ /* The header starts with a 'fmt ' tag */
if (wav->streaming) { if (wav->streaming) {
if (!gst_wavparse_peek_chunk (wav, &tag, &size)) if (!gst_wavparse_peek_chunk (wav, &tag, &size))
return GST_FLOW_OK; return GST_FLOW_OK;
@ -1007,13 +1006,25 @@ gst_wavparse_stream_headers (GstWavParse * wav)
wav->offset += 8; wav->offset += 8;
GST_BUFFER_DATA (buf) = (guint8 *) gst_adapter_peek (wav->adapter, size); GST_BUFFER_DATA (buf) = (guint8 *) gst_adapter_peek (wav->adapter, size);
GST_BUFFER_SIZE (buf) = size; GST_BUFFER_SIZE (buf) = size;
} else { } else {
if ((res = gst_riff_read_chunk (GST_ELEMENT (wav), wav->sinkpad, if ((res = gst_riff_read_chunk (GST_ELEMENT (wav), wav->sinkpad,
&wav->offset, &tag, &buf)) != GST_FLOW_OK) &wav->offset, &tag, &buf)) != GST_FLOW_OK)
return res; return res;
} }
if (tag == GST_RIFF_TAG_JUNK || tag == GST_RIFF_TAG_bext ||
tag == GST_RIFF_TAG_BEXT) {
GST_DEBUG_OBJECT (wav, "skipping %" GST_FOURCC_FORMAT " chunk",
GST_FOURCC_ARGS (tag));
if (wav->streaming) {
gst_adapter_flush (wav->adapter, size);
wav->offset += size;
}
gst_buffer_unref (buf);
buf = NULL;
continue;
}
if (tag != GST_RIFF_TAG_fmt) if (tag != GST_RIFF_TAG_fmt)
goto invalid_wav; goto invalid_wav;
@ -1108,6 +1119,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
switch (tag) { switch (tag) {
/* TODO : Implement the various cases */ /* TODO : Implement the various cases */
case GST_RIFF_TAG_data:{ case GST_RIFF_TAG_data:{
GstFormat fmt;
gint64 upstream_size; gint64 upstream_size;
GST_DEBUG_OBJECT (wav, "Got 'data' TAG, size : %d", size); GST_DEBUG_OBJECT (wav, "Got 'data' TAG, size : %d", size);
@ -1120,7 +1132,8 @@ gst_wavparse_stream_headers (GstWavParse * wav)
wav->offset += 8; wav->offset += 8;
wav->datastart = wav->offset; wav->datastart = wav->offset;
/* file might be truncated */ /* file might be truncated */
if (gst_wavparse_get_upstream_size (wav, &upstream_size)) { fmt = GST_FORMAT_BYTES;
if (gst_pad_query_peer_duration (wav->sinkpad, &fmt, &upstream_size)) {
size = MIN (size, (upstream_size - wav->datastart)); size = MIN (size, (upstream_size - wav->datastart));
} }
wav->datasize = size; wav->datasize = size;
@ -1520,8 +1533,7 @@ gst_wavparse_chain (GstPad * pad, GstBuffer * buf)
GstFlowReturn ret; GstFlowReturn ret;
GstWavParse *wav = GST_WAVPARSE (GST_PAD_PARENT (pad)); GstWavParse *wav = GST_WAVPARSE (GST_PAD_PARENT (pad));
GST_LOG_OBJECT (wav, "adapter_push %" G_GINT64_FORMAT " bytes", GST_LOG_OBJECT (wav, "adapter_push %u bytes", GST_BUFFER_SIZE (buf));
GST_BUFFER_SIZE (buf));
gst_adapter_push (wav->adapter, buf); gst_adapter_push (wav->adapter, buf);
@ -1531,14 +1543,19 @@ gst_wavparse_chain (GstPad * pad, GstBuffer * buf)
if ((ret = gst_wavparse_parse_stream_init (wav)) != GST_FLOW_OK) if ((ret = gst_wavparse_parse_stream_init (wav)) != GST_FLOW_OK)
goto pause; goto pause;
wav->state = GST_WAVPARSE_HEADER; if (wav->state != GST_WAVPARSE_HEADER)
/* fall-through */ break;
/* otherwise fall-through */
case GST_WAVPARSE_HEADER: case GST_WAVPARSE_HEADER:
GST_DEBUG_OBJECT (wav, "GST_WAVPARSE_HEADER"); GST_DEBUG_OBJECT (wav, "GST_WAVPARSE_HEADER");
if ((ret = gst_wavparse_stream_headers (wav)) != GST_FLOW_OK) if ((ret = gst_wavparse_stream_headers (wav)) != GST_FLOW_OK)
goto pause; goto pause;
if (!wav->got_fmt || wav->datastart == 0)
break;
wav->state = GST_WAVPARSE_DATA; wav->state = GST_WAVPARSE_DATA;
/* fall-through */ /* fall-through */

View file

@ -44,7 +44,7 @@ G_BEGIN_DECLS
typedef enum { typedef enum {
GST_WAVPARSE_START, GST_WAVPARSE_START,
GST_WAVPARSE_HEADER, GST_WAVPARSE_HEADER,
GST_WAVPARSE_DATA, GST_WAVPARSE_DATA
} GstWavParseState; } GstWavParseState;
typedef struct _GstWavParse GstWavParse; typedef struct _GstWavParse GstWavParse;