mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
gst/matroska/: Disgustingly evil hack for working around INTERRUPT events and their extremely annoying habit of being...
Original commit message from CVS: * gst/matroska/ebml-read.c: (gst_ebml_read_class_init), (gst_ebml_read_init), (gst_ebml_read_use_event), (gst_ebml_read_element_id), (gst_ebml_peek_id), (gst_ebml_read_seek), (gst_ebml_read_skip), (gst_ebml_read_reserve), (gst_ebml_read_buffer), (gst_ebml_read_master): * gst/matroska/ebml-read.h: * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_contents), (gst_matroska_demux_loop_stream), (gst_matroska_demux_audio_caps): Disgustingly evil hack for working around INTERRUPT events and their extremely annoying habit of being a pain in the ass. We simply peek a cluster before reading any of it.
This commit is contained in:
parent
5d986b1772
commit
75ff7535dd
4 changed files with 93 additions and 7 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2004-12-03 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
|
* gst/matroska/ebml-read.c: (gst_ebml_read_class_init),
|
||||||
|
(gst_ebml_read_init), (gst_ebml_read_use_event),
|
||||||
|
(gst_ebml_read_element_id), (gst_ebml_peek_id),
|
||||||
|
(gst_ebml_read_seek), (gst_ebml_read_skip),
|
||||||
|
(gst_ebml_read_reserve), (gst_ebml_read_buffer),
|
||||||
|
(gst_ebml_read_master):
|
||||||
|
* gst/matroska/ebml-read.h:
|
||||||
|
* gst/matroska/matroska-demux.c:
|
||||||
|
(gst_matroska_demux_parse_contents),
|
||||||
|
(gst_matroska_demux_loop_stream), (gst_matroska_demux_audio_caps):
|
||||||
|
Disgustingly evil hack for working around INTERRUPT events and
|
||||||
|
their extremely annoying habit of being a pain in the ass. We
|
||||||
|
simply peek a cluster before reading any of it.
|
||||||
|
|
||||||
2004-12-03 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
2004-12-03 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
* ext/musepack/gstmusepackdec.cpp:
|
* ext/musepack/gstmusepackdec.cpp:
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include "ebml-read.h"
|
#include "ebml-read.h"
|
||||||
#include "ebml-ids.h"
|
#include "ebml-ids.h"
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_STATIC (ebmlread_debug);
|
||||||
|
#define GST_CAT_DEFAULT ebmlread_debug
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
|
@ -73,6 +76,9 @@ gst_ebml_read_class_init (GstEbmlReadClass * klass)
|
||||||
|
|
||||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
|
||||||
|
0, "EBML stream helper class");
|
||||||
|
|
||||||
gstelement_class->change_state = gst_ebml_read_change_state;
|
gstelement_class->change_state = gst_ebml_read_change_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +88,7 @@ gst_ebml_read_init (GstEbmlRead * ebml)
|
||||||
ebml->sinkpad = NULL;
|
ebml->sinkpad = NULL;
|
||||||
ebml->bs = NULL;
|
ebml->bs = NULL;
|
||||||
ebml->level = NULL;
|
ebml->level = NULL;
|
||||||
|
ebml->id_cache = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
|
@ -132,6 +139,8 @@ gst_ebml_read_use_event (GstEbmlRead * ebml, GstEvent * event)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_LOG ("Received event of type %d", GST_EVENT_TYPE (event));
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
gst_pad_event_default (ebml->sinkpad, event);
|
gst_pad_event_default (ebml->sinkpad, event);
|
||||||
|
@ -143,7 +152,7 @@ gst_ebml_read_use_event (GstEbmlRead * ebml, GstEvent * event)
|
||||||
|
|
||||||
case GST_EVENT_DISCONTINUOUS:
|
case GST_EVENT_DISCONTINUOUS:
|
||||||
GST_WARNING_OBJECT (ebml, "Unexpected discont - might lose sync");
|
GST_WARNING_OBJECT (ebml, "Unexpected discont - might lose sync");
|
||||||
gst_pad_event_default (ebml->sinkpad, event);
|
gst_event_unref (event);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case GST_EVENT_FLUSH:
|
case GST_EVENT_FLUSH:
|
||||||
|
@ -212,6 +221,14 @@ gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
|
||||||
gint len_mask = 0x80, read = 1, n = 1;
|
gint len_mask = 0x80, read = 1, n = 1;
|
||||||
guint32 total;
|
guint32 total;
|
||||||
|
|
||||||
|
if (ebml->id_cache) {
|
||||||
|
*id = ebml->id_cache;
|
||||||
|
if (level_up)
|
||||||
|
*level_up = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
|
while (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
|
||||||
if (!gst_ebml_read_handle_event (ebml))
|
if (!gst_ebml_read_handle_event (ebml))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -237,13 +254,15 @@ gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
|
||||||
while (n < read)
|
while (n < read)
|
||||||
total = (total << 8) | data[n++];
|
total = (total << 8) | data[n++];
|
||||||
|
|
||||||
*id = total;
|
*id = ebml->id_cache = total;
|
||||||
|
|
||||||
/* level */
|
/* level */
|
||||||
if (level_up)
|
if (level_up)
|
||||||
*level_up = gst_ebml_read_element_level_up (ebml);
|
*level_up = gst_ebml_read_element_level_up (ebml);
|
||||||
|
|
||||||
return read;
|
gst_bytestream_flush_fast (ebml->bs, read);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -330,7 +349,7 @@ gst_ebml_peek_id (GstEbmlRead * ebml, guint * level_up)
|
||||||
|
|
||||||
g_assert (level_up);
|
g_assert (level_up);
|
||||||
|
|
||||||
if (gst_ebml_read_element_id (ebml, &id, level_up) <= 0)
|
if (gst_ebml_read_element_id (ebml, &id, level_up) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
@ -385,6 +404,9 @@ gst_ebml_read_seek (GstEbmlRead * ebml, guint64 offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* at the end of a seek, we have no cached ID anymore */
|
||||||
|
ebml->id_cache = 0;
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,8 +438,12 @@ gst_ebml_read_skip (GstEbmlRead * ebml)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remaining >= length)
|
if (remaining >= length) {
|
||||||
return gst_bytestream_flush (ebml->bs, length);
|
ebml->id_cache = 0;
|
||||||
|
gst_bytestream_flush_fast (ebml->bs, length);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(event = gst_ebml_read_seek (ebml,
|
if (!(event = gst_ebml_read_seek (ebml,
|
||||||
gst_bytestream_tell (ebml->bs) + length))) {
|
gst_bytestream_tell (ebml->bs) + length))) {
|
||||||
|
@ -425,10 +451,43 @@ gst_ebml_read_skip (GstEbmlRead * ebml)
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
ebml->id_cache = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure there's one whole next chunk available
|
||||||
|
* for uninterrupted reading.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_ebml_read_reserve (GstEbmlRead * ebml)
|
||||||
|
{
|
||||||
|
guint64 length;
|
||||||
|
gint bytes;
|
||||||
|
guint8 *data;
|
||||||
|
guint32 id;
|
||||||
|
|
||||||
|
/* make sure the ID is cached */
|
||||||
|
if (gst_ebml_read_element_id (ebml, &id, NULL) < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* now we can peek the length */
|
||||||
|
if ((bytes = gst_ebml_read_element_length (ebml, &length)) < 0)
|
||||||
|
return FALSE;
|
||||||
|
length += bytes;
|
||||||
|
|
||||||
|
/* now check if we have that amount available */
|
||||||
|
while (gst_bytestream_peek_bytes (ebml->bs, &data, length) != length) {
|
||||||
|
if (!gst_ebml_read_handle_event (ebml))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* yes, available */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the next element as a GstBuffer (binary).
|
* Read the next element as a GstBuffer (binary).
|
||||||
*/
|
*/
|
||||||
|
@ -446,6 +505,7 @@ gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
|
||||||
if ((bytes = gst_ebml_read_element_length (ebml, &length)) < 0)
|
if ((bytes = gst_ebml_read_element_length (ebml, &length)) < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gst_bytestream_flush_fast (ebml->bs, bytes);
|
gst_bytestream_flush_fast (ebml->bs, bytes);
|
||||||
|
ebml->id_cache = 0;
|
||||||
|
|
||||||
return ((*buf = gst_ebml_read_element_data (ebml, length)) != NULL);
|
return ((*buf = gst_ebml_read_element_data (ebml, length)) != NULL);
|
||||||
}
|
}
|
||||||
|
@ -662,6 +722,7 @@ gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
|
||||||
level->start = gst_bytestream_tell (ebml->bs);
|
level->start = gst_bytestream_tell (ebml->bs);
|
||||||
level->length = length;
|
level->length = length;
|
||||||
ebml->level = g_list_append (ebml->level, level);
|
ebml->level = g_list_append (ebml->level, level);
|
||||||
|
ebml->id_cache = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,9 @@ typedef struct _GstEbmlRead {
|
||||||
GstByteStream *bs;
|
GstByteStream *bs;
|
||||||
|
|
||||||
GList *level;
|
GList *level;
|
||||||
|
|
||||||
|
/* cache of ID (peeking) */
|
||||||
|
guint32 id_cache;
|
||||||
} GstEbmlRead;
|
} GstEbmlRead;
|
||||||
|
|
||||||
typedef struct _GstEbmlReadClass {
|
typedef struct _GstEbmlReadClass {
|
||||||
|
@ -66,6 +69,7 @@ guint32 gst_ebml_peek_id (GstEbmlRead *ebml,
|
||||||
GstEvent *gst_ebml_read_seek (GstEbmlRead *ebml,
|
GstEvent *gst_ebml_read_seek (GstEbmlRead *ebml,
|
||||||
guint64 offset);
|
guint64 offset);
|
||||||
gboolean gst_ebml_read_skip (GstEbmlRead *ebml);
|
gboolean gst_ebml_read_skip (GstEbmlRead *ebml);
|
||||||
|
gboolean gst_ebml_read_reserve (GstEbmlRead *ebml);
|
||||||
gboolean gst_ebml_read_buffer (GstEbmlRead *ebml,
|
gboolean gst_ebml_read_buffer (GstEbmlRead *ebml,
|
||||||
guint32 *id,
|
guint32 *id,
|
||||||
GstBuffer **buf);
|
GstBuffer **buf);
|
||||||
|
|
|
@ -2142,6 +2142,7 @@ gst_matroska_demux_parse_contents (GstMatroskaDemux * demux)
|
||||||
case GST_MATROSKA_ID_TAGS:{
|
case GST_MATROSKA_ID_TAGS:{
|
||||||
guint level_up = demux->level_up;
|
guint level_up = demux->level_up;
|
||||||
guint64 before_pos, length;
|
guint64 before_pos, length;
|
||||||
|
guint32 id_cache = ebml->id_cache;
|
||||||
GstEbmlLevel *level;
|
GstEbmlLevel *level;
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
|
||||||
|
@ -2224,6 +2225,7 @@ gst_matroska_demux_parse_contents (GstMatroskaDemux * demux)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
demux->level_up = level_up;
|
demux->level_up = level_up;
|
||||||
|
ebml->id_cache = id_cache;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2333,6 +2335,10 @@ gst_matroska_demux_loop_stream (GstMatroskaDemux * demux)
|
||||||
demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
|
demux->state = GST_MATROSKA_DEMUX_STATE_DATA;
|
||||||
gst_element_no_more_pads (GST_ELEMENT (demux));
|
gst_element_no_more_pads (GST_ELEMENT (demux));
|
||||||
} else {
|
} else {
|
||||||
|
if (!gst_ebml_read_reserve (ebml)) {
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!gst_ebml_read_master (ebml, &id)) {
|
if (!gst_ebml_read_master (ebml, &id)) {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -2670,7 +2676,6 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext * audiocontext,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
|
GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
|
||||||
g_print ("Codec=%s\n", codec_id);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue