mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
gst/matroska/: Reverse the level list as we usually are only interested in the first element or want to add a new fir...
Original commit message from CVS: * gst/matroska/ebml-read.c: (gst_ebml_level_free), (gst_ebml_finalize), (gst_ebml_read_change_state), (gst_ebml_read_element_level_up), (gst_ebml_read_master): * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_contents_seekentry): Reverse the level list as we usually are only interested in the first element or want to add a new first element. Having the first element stored at the end and calling g_list_last() and g_list_append() is more expensive. Also use GSlice for allocating the GstEbmlLevel structs.
This commit is contained in:
parent
7a118610ed
commit
1051e57b36
3 changed files with 71 additions and 14 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2008-06-14 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* gst/matroska/ebml-read.c: (gst_ebml_level_free),
|
||||||
|
(gst_ebml_finalize), (gst_ebml_read_change_state),
|
||||||
|
(gst_ebml_read_element_level_up), (gst_ebml_read_master):
|
||||||
|
* gst/matroska/matroska-demux.c:
|
||||||
|
(gst_matroska_demux_parse_contents_seekentry):
|
||||||
|
Reverse the level list as we usually are only interested in the
|
||||||
|
first element or want to add a new first element. Having the
|
||||||
|
first element stored at the end and calling g_list_last() and
|
||||||
|
g_list_append() is more expensive.
|
||||||
|
|
||||||
|
Also use GSlice for allocating the GstEbmlLevel structs.
|
||||||
|
|
||||||
2008-06-13 Tim-Philipp Müller <tim.muller at collabora co uk>
|
2008-06-13 Tim-Philipp Müller <tim.muller at collabora co uk>
|
||||||
|
|
||||||
* gst/debug/gsttaginject.c: (gst_tag_inject_finalize),
|
* gst/debug/gsttaginject.c: (gst_tag_inject_finalize),
|
||||||
|
|
|
@ -34,7 +34,9 @@ GST_DEBUG_CATEGORY_STATIC (ebmlread_debug);
|
||||||
#define GST_CAT_DEFAULT ebmlread_debug
|
#define GST_CAT_DEFAULT ebmlread_debug
|
||||||
|
|
||||||
static void gst_ebml_read_class_init (GstEbmlReadClass * klass);
|
static void gst_ebml_read_class_init (GstEbmlReadClass * klass);
|
||||||
|
|
||||||
static void gst_ebml_read_init (GstEbmlRead * ebml);
|
static void gst_ebml_read_init (GstEbmlRead * ebml);
|
||||||
|
|
||||||
static GstStateChangeReturn gst_ebml_read_change_state (GstElement * element,
|
static GstStateChangeReturn gst_ebml_read_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
|
||||||
|
@ -73,12 +75,18 @@ gst_ebml_read_get_type (void)
|
||||||
return gst_ebml_read_type;
|
return gst_ebml_read_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ebml_level_free (GstEbmlLevel * level)
|
||||||
|
{
|
||||||
|
g_slice_free (GstEbmlLevel, level);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ebml_finalize (GObject * obj)
|
gst_ebml_finalize (GObject * obj)
|
||||||
{
|
{
|
||||||
GstEbmlRead *ebml = GST_EBML_READ (obj);
|
GstEbmlRead *ebml = GST_EBML_READ (obj);
|
||||||
|
|
||||||
g_list_foreach (ebml->level, (GFunc) g_free, NULL);
|
g_list_foreach (ebml->level, (GFunc) gst_ebml_level_free, NULL);
|
||||||
g_list_free (ebml->level);
|
g_list_free (ebml->level);
|
||||||
ebml->level = NULL;
|
ebml->level = NULL;
|
||||||
if (ebml->cached_buffer) {
|
if (ebml->cached_buffer) {
|
||||||
|
@ -93,6 +101,7 @@ static void
|
||||||
gst_ebml_read_class_init (GstEbmlReadClass * klass)
|
gst_ebml_read_class_init (GstEbmlReadClass * klass)
|
||||||
{
|
{
|
||||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||||
|
|
||||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
@ -117,6 +126,7 @@ static GstStateChangeReturn
|
||||||
gst_ebml_read_change_state (GstElement * element, GstStateChange transition)
|
gst_ebml_read_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
GstEbmlRead *ebml = GST_EBML_READ (element);
|
GstEbmlRead *ebml = GST_EBML_READ (element);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
|
@ -134,7 +144,7 @@ gst_ebml_read_change_state (GstElement * element, GstStateChange transition)
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
{
|
{
|
||||||
g_list_foreach (ebml->level, (GFunc) g_free, NULL);
|
g_list_foreach (ebml->level, (GFunc) gst_ebml_level_free, NULL);
|
||||||
g_list_free (ebml->level);
|
g_list_free (ebml->level);
|
||||||
ebml->level = NULL;
|
ebml->level = NULL;
|
||||||
if (ebml->cached_buffer) {
|
if (ebml->cached_buffer) {
|
||||||
|
@ -162,15 +172,15 @@ static guint
|
||||||
gst_ebml_read_element_level_up (GstEbmlRead * ebml)
|
gst_ebml_read_element_level_up (GstEbmlRead * ebml)
|
||||||
{
|
{
|
||||||
guint num = 0;
|
guint num = 0;
|
||||||
|
|
||||||
guint64 pos = ebml->offset;
|
guint64 pos = ebml->offset;
|
||||||
|
|
||||||
while (ebml->level != NULL) {
|
while (ebml->level != NULL) {
|
||||||
GList *last = g_list_last (ebml->level);
|
GstEbmlLevel *level = ebml->level->data;
|
||||||
GstEbmlLevel *level = last->data;
|
|
||||||
|
|
||||||
if (pos >= level->start + level->length) {
|
if (pos >= level->start + level->length) {
|
||||||
ebml->level = g_list_remove (ebml->level, level);
|
ebml->level = g_list_delete_link (ebml->level, ebml->level);
|
||||||
g_free (level);
|
gst_ebml_level_free (level);
|
||||||
num++;
|
num++;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -193,6 +203,7 @@ gst_ebml_read_peek_bytes (GstEbmlRead * ebml, guint size, GstBuffer ** p_buf,
|
||||||
* We do it mainly to avoid pulling buffers of 1 byte all the time */
|
* We do it mainly to avoid pulling buffers of 1 byte all the time */
|
||||||
if (ebml->cached_buffer) {
|
if (ebml->cached_buffer) {
|
||||||
guint64 cache_offset = GST_BUFFER_OFFSET (ebml->cached_buffer);
|
guint64 cache_offset = GST_BUFFER_OFFSET (ebml->cached_buffer);
|
||||||
|
|
||||||
guint cache_size = GST_BUFFER_SIZE (ebml->cached_buffer);
|
guint cache_size = GST_BUFFER_SIZE (ebml->cached_buffer);
|
||||||
|
|
||||||
if (cache_offset <= ebml->offset &&
|
if (cache_offset <= ebml->offset &&
|
||||||
|
@ -291,9 +302,13 @@ static GstFlowReturn
|
||||||
gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
|
gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
|
||||||
{
|
{
|
||||||
guint8 *buf;
|
guint8 *buf;
|
||||||
|
|
||||||
gint len_mask = 0x80, read = 1, n = 1;
|
gint len_mask = 0x80, read = 1, n = 1;
|
||||||
|
|
||||||
guint32 total;
|
guint32 total;
|
||||||
|
|
||||||
guint8 b;
|
guint8 b;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
|
ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
|
||||||
|
@ -347,9 +362,13 @@ gst_ebml_read_element_length (GstEbmlRead * ebml, guint64 * length,
|
||||||
gint * rread)
|
gint * rread)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
guint8 *buf;
|
guint8 *buf;
|
||||||
|
|
||||||
gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
|
gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
|
||||||
|
|
||||||
guint64 total;
|
guint64 total;
|
||||||
|
|
||||||
guint8 b;
|
guint8 b;
|
||||||
|
|
||||||
ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
|
ret = gst_ebml_read_peek_bytes (ebml, 1, NULL, &buf);
|
||||||
|
@ -412,6 +431,7 @@ GstFlowReturn
|
||||||
gst_ebml_peek_id (GstEbmlRead * ebml, guint * level_up, guint32 * id)
|
gst_ebml_peek_id (GstEbmlRead * ebml, guint * level_up, guint32 * id)
|
||||||
{
|
{
|
||||||
guint64 off;
|
guint64 off;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
g_assert (level_up);
|
g_assert (level_up);
|
||||||
|
@ -433,6 +453,7 @@ gint64
|
||||||
gst_ebml_read_get_length (GstEbmlRead * ebml)
|
gst_ebml_read_get_length (GstEbmlRead * ebml)
|
||||||
{
|
{
|
||||||
GstFormat fmt = GST_FORMAT_BYTES;
|
GstFormat fmt = GST_FORMAT_BYTES;
|
||||||
|
|
||||||
gint64 end;
|
gint64 end;
|
||||||
|
|
||||||
/* FIXME: what to do if we don't get the upstream length */
|
/* FIXME: what to do if we don't get the upstream length */
|
||||||
|
@ -466,7 +487,9 @@ GstFlowReturn
|
||||||
gst_ebml_read_skip (GstEbmlRead * ebml)
|
gst_ebml_read_skip (GstEbmlRead * ebml)
|
||||||
{
|
{
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
|
||||||
guint32 id;
|
guint32 id;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_element_id (ebml, &id, NULL);
|
ret = gst_ebml_read_element_id (ebml, &id, NULL);
|
||||||
|
@ -489,6 +512,7 @@ GstFlowReturn
|
||||||
gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
|
gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
|
||||||
{
|
{
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_element_id (ebml, id, NULL);
|
ret = gst_ebml_read_element_id (ebml, id, NULL);
|
||||||
|
@ -519,6 +543,7 @@ gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, guint8 ** data,
|
||||||
guint * size)
|
guint * size)
|
||||||
{
|
{
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
@ -554,7 +579,9 @@ GstFlowReturn
|
||||||
gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
|
gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
||||||
|
@ -586,8 +613,11 @@ GstFlowReturn
|
||||||
gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
|
gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
gboolean negative = 0;
|
gboolean negative = 0;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
||||||
|
@ -638,7 +668,9 @@ static gdouble
|
||||||
_ext2dbl (guint8 * data)
|
_ext2dbl (guint8 * data)
|
||||||
{
|
{
|
||||||
struct _ext_float *ext = (struct _ext_float *) data;
|
struct _ext_float *ext = (struct _ext_float *) data;
|
||||||
|
|
||||||
guint64 m = 0;
|
guint64 m = 0;
|
||||||
|
|
||||||
gint e, i;
|
gint e, i;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
|
@ -662,7 +694,9 @@ GstFlowReturn
|
||||||
gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
|
gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
||||||
|
@ -718,7 +752,9 @@ GstFlowReturn
|
||||||
gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str)
|
gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
||||||
|
@ -766,6 +802,7 @@ GstFlowReturn
|
||||||
gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
|
gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
|
||||||
{
|
{
|
||||||
gint64 ebml_date;
|
gint64 ebml_date;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_sint (ebml, id, &ebml_date);
|
ret = gst_ebml_read_sint (ebml, id, &ebml_date);
|
||||||
|
@ -786,7 +823,9 @@ GstFlowReturn
|
||||||
gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
|
gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
|
||||||
{
|
{
|
||||||
GstEbmlLevel *level;
|
GstEbmlLevel *level;
|
||||||
|
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_element_id (ebml, id, NULL);
|
ret = gst_ebml_read_element_id (ebml, id, NULL);
|
||||||
|
@ -798,10 +837,10 @@ gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* remember level */
|
/* remember level */
|
||||||
level = g_new (GstEbmlLevel, 1);
|
level = g_slice_new (GstEbmlLevel);
|
||||||
level->start = ebml->offset;
|
level->start = ebml->offset;
|
||||||
level->length = length;
|
level->length = length;
|
||||||
ebml->level = g_list_append (ebml->level, level);
|
ebml->level = g_list_prepend (ebml->level, level);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
@ -815,7 +854,9 @@ gst_ebml_read_binary (GstEbmlRead * ebml,
|
||||||
guint32 * id, guint8 ** binary, guint64 * length)
|
guint32 * id, guint8 ** binary, guint64 * length)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
ret = gst_ebml_read_bytes (ebml, id, &data, &size);
|
||||||
|
@ -837,7 +878,9 @@ gst_ebml_read_header (GstEbmlRead * ebml, gchar ** doctype, guint * version)
|
||||||
{
|
{
|
||||||
/* this function is the first to be called */
|
/* this function is the first to be called */
|
||||||
guint32 id;
|
guint32 id;
|
||||||
|
|
||||||
guint level_up;
|
guint level_up;
|
||||||
|
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
/* default init */
|
/* default init */
|
||||||
|
|
|
@ -3577,10 +3577,10 @@ gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
|
||||||
|
|
||||||
/* we don't want to lose our seekhead level, so we add
|
/* we don't want to lose our seekhead level, so we add
|
||||||
* a dummy. This is a crude hack. */
|
* a dummy. This is a crude hack. */
|
||||||
level = g_new (GstEbmlLevel, 1);
|
level = g_slice_new (GstEbmlLevel);
|
||||||
level->start = 0;
|
level->start = 0;
|
||||||
level->length = G_MAXUINT64;
|
level->length = G_MAXUINT64;
|
||||||
ebml->level = g_list_append (ebml->level, level);
|
ebml->level = g_list_prepend (ebml->level, level);
|
||||||
|
|
||||||
/* check ID */
|
/* check ID */
|
||||||
if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
|
if ((ret = gst_ebml_peek_id (ebml, &demux->level_up, &id)) != GST_FLOW_OK)
|
||||||
|
@ -3652,7 +3652,7 @@ gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
|
||||||
for (l = ebml->level; l; l = l->next) {
|
for (l = ebml->level; l; l = l->next) {
|
||||||
GstEbmlLevel *level = (GstEbmlLevel *) l->data;
|
GstEbmlLevel *level = (GstEbmlLevel *) l->data;
|
||||||
|
|
||||||
if (level->start == ebml->offset && l->next)
|
if (level->start == ebml->offset && l->prev)
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3695,10 +3695,10 @@ gst_matroska_demux_parse_contents_seekentry (GstMatroskaDemux * demux,
|
||||||
while (ebml->level) {
|
while (ebml->level) {
|
||||||
guint64 length;
|
guint64 length;
|
||||||
|
|
||||||
level = g_list_last (ebml->level)->data;
|
level = ebml->level->data;
|
||||||
ebml->level = g_list_remove (ebml->level, level);
|
ebml->level = g_list_delete_link (ebml->level, ebml->level);
|
||||||
length = level->length;
|
length = level->length;
|
||||||
g_free (level);
|
g_slice_free (GstEbmlLevel, level);
|
||||||
if (length == G_MAXUINT64)
|
if (length == G_MAXUINT64)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue