mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
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:
parent
6de492dea8
commit
84e86aebf7
3 changed files with 60 additions and 27 deletions
16
ChangeLog
16
ChangeLog
|
@ -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):
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue