mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-05 05:52:37 +00:00
gst/avi/: Don't abort on out-of-memory. Use stream-nr as unsigned integer only.
Original commit message from CVS: * gst/avi/README: * gst/avi/gstavidemux.c: (gst_avi_demux_handle_src_query), (gst_avi_demux_parse_stream), (gst_avi_demux_parse_index), (gst_avi_demux_stream_index), (gst_avi_demux_sync), (gst_avi_demux_stream_scan), (gst_avi_demux_massage_index), (gst_avi_demux_calculate_durations_from_index), (gst_avi_demux_stream_header_push), (gst_avi_demux_stream_header_pull), (gst_avi_demux_combine_flows), (gst_avi_demux_process_next_entry), (gst_avi_demux_stream_data): Don't abort on out-of-memory. Use stream-nr as unsigned integer only.
This commit is contained in:
parent
9598d82c0c
commit
30df72ccb7
3 changed files with 90 additions and 41 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2007-04-04 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
|
* gst/avi/README:
|
||||||
|
* gst/avi/gstavidemux.c: (gst_avi_demux_handle_src_query),
|
||||||
|
(gst_avi_demux_parse_stream), (gst_avi_demux_parse_index),
|
||||||
|
(gst_avi_demux_stream_index), (gst_avi_demux_sync),
|
||||||
|
(gst_avi_demux_stream_scan), (gst_avi_demux_massage_index),
|
||||||
|
(gst_avi_demux_calculate_durations_from_index),
|
||||||
|
(gst_avi_demux_stream_header_push),
|
||||||
|
(gst_avi_demux_stream_header_pull), (gst_avi_demux_combine_flows),
|
||||||
|
(gst_avi_demux_process_next_entry), (gst_avi_demux_stream_data):
|
||||||
|
Don't abort on out-of-memory. Use stream-nr as unsigned integer only.
|
||||||
|
|
||||||
2007-04-03 Wim Taymans <wim@fluendo.com>
|
2007-04-03 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/smpte/barboxwipes.c:
|
* gst/smpte/barboxwipes.c:
|
||||||
|
|
|
@ -1350,14 +1350,20 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
|
||||||
|
|
||||||
gst_pad_use_fixed_caps (pad);
|
gst_pad_use_fixed_caps (pad);
|
||||||
#if 0
|
#if 0
|
||||||
gst_pad_set_formats_function (pad, gst_avi_demux_get_src_formats);
|
gst_pad_set_formats_function (pad,
|
||||||
gst_pad_set_event_mask_function (pad, gst_avi_demux_get_event_mask);
|
GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_formats));
|
||||||
|
gst_pad_set_event_mask_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_avi_demux_get_event_mask));
|
||||||
#endif
|
#endif
|
||||||
gst_pad_set_event_function (pad, gst_avi_demux_handle_src_event);
|
gst_pad_set_event_function (pad,
|
||||||
gst_pad_set_query_type_function (pad, gst_avi_demux_get_src_query_types);
|
GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_event));
|
||||||
gst_pad_set_query_function (pad, gst_avi_demux_handle_src_query);
|
gst_pad_set_query_type_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_query_types));
|
||||||
|
gst_pad_set_query_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_query));
|
||||||
#if 0
|
#if 0
|
||||||
gst_pad_set_convert_function (pad, gst_avi_demux_src_convert);
|
gst_pad_set_convert_function (pad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_avi_demux_src_convert));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stream->num = avi->num_streams;
|
stream->num = avi->num_streams;
|
||||||
|
@ -1474,6 +1480,7 @@ gst_avi_demux_parse_odml (GstAviDemux * avi, GstBuffer * buf)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort helper for index entries that sorts by index time.
|
* Sort helper for index entries that sorts by index time.
|
||||||
|
* If times are equal we sort by stream number.
|
||||||
*/
|
*/
|
||||||
static gint
|
static gint
|
||||||
sort (gst_avi_index_entry * a, gst_avi_index_entry * b)
|
sort (gst_avi_index_entry * a, gst_avi_index_entry * b)
|
||||||
|
@ -1530,7 +1537,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
|
||||||
gint64 next_ts;
|
gint64 next_ts;
|
||||||
gst_riff_index_entry entry, *_entry;
|
gst_riff_index_entry entry, *_entry;
|
||||||
avi_stream_context *stream;
|
avi_stream_context *stream;
|
||||||
gint stream_nr;
|
guint stream_nr;
|
||||||
gst_avi_index_entry *target;
|
gst_avi_index_entry *target;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
|
|
||||||
|
@ -1546,7 +1553,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stream_nr = CHUNKID_TO_STREAMNR (entry.id);
|
stream_nr = CHUNKID_TO_STREAMNR (entry.id);
|
||||||
if (stream_nr >= avi->num_streams || stream_nr < 0) {
|
if (stream_nr >= avi->num_streams) {
|
||||||
GST_WARNING_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Index entry %d has invalid stream nr %d", i, stream_nr);
|
"Index entry %d has invalid stream nr %d", i, stream_nr);
|
||||||
continue;
|
continue;
|
||||||
|
@ -2023,8 +2030,8 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
||||||
G_GUINT64_FORMAT "+%u)", pos, length, entry->offset, entry->size);
|
G_GUINT64_FORMAT "+%u)", pos, length, entry->offset, entry->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (TRUE) {
|
||||||
gint stream_nr;
|
guint stream_nr;
|
||||||
guint size = 0;
|
guint size = 0;
|
||||||
gint64 tmpts, tmpnextts;
|
gint64 tmpts, tmpnextts;
|
||||||
|
|
||||||
|
@ -2034,8 +2041,11 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
||||||
|
|
||||||
/* check valid stream */
|
/* check valid stream */
|
||||||
stream_nr = CHUNKID_TO_STREAMNR (tag);
|
stream_nr = CHUNKID_TO_STREAMNR (tag);
|
||||||
if (stream_nr < 0 || stream_nr >= avi->num_streams)
|
if (stream_nr >= avi->num_streams) {
|
||||||
|
GST_WARNING_OBJECT (avi,
|
||||||
|
"Index entry has invalid stream nr %d", stream_nr);
|
||||||
goto next;
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
stream = &avi->stream[stream_nr];
|
stream = &avi->stream[stream_nr];
|
||||||
|
|
||||||
|
@ -2097,11 +2107,11 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
||||||
/* FIXME: why is this disabled */
|
/* FIXME: why is this disabled */
|
||||||
#if 0
|
#if 0
|
||||||
while (gst_avi_demux_sync (avi, &tag, TRUE)) {
|
while (gst_avi_demux_sync (avi, &tag, TRUE)) {
|
||||||
gint stream_nr = CHUNKID_TO_STREAMNR (tag);
|
guint stream_nr = CHUNKID_TO_STREAMNR (tag);
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
GstFormat format = GST_FORMAT_TIME;
|
GstFormat format = GST_FORMAT_TIME;
|
||||||
|
|
||||||
if (stream_nr < 0 || stream_nr >= avi->num_streams)
|
if (stream_nr >= avi->num_streams)
|
||||||
goto next;
|
goto next;
|
||||||
stream = &avi->stream[stream_nr];
|
stream = &avi->stream[stream_nr];
|
||||||
|
|
||||||
|
@ -2175,22 +2185,23 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
||||||
* smaller pieces. In the second case, we re-order chunk reading
|
* smaller pieces. In the second case, we re-order chunk reading
|
||||||
* order. The end result should be a smoother playing AVI.
|
* order. The end result should be a smoother playing AVI.
|
||||||
*/
|
*/
|
||||||
static void
|
static gboolean
|
||||||
gst_avi_demux_massage_index (GstAviDemux * avi,
|
gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
GList * list, GList * alloc_list)
|
GList * list, GList * alloc_list)
|
||||||
{
|
{
|
||||||
gst_avi_index_entry *entry;
|
gst_avi_index_entry *entry;
|
||||||
avi_stream_context *stream;
|
avi_stream_context *stream;
|
||||||
gint i;
|
guint i;
|
||||||
GList *node;
|
GList *node;
|
||||||
gint64 delay = G_GINT64_CONSTANT (0);
|
gint64 delay = G_GINT64_CONSTANT (0);
|
||||||
|
|
||||||
GST_LOG_OBJECT (avi, "Starting index massage, nr_entries = %d",
|
GST_LOG_OBJECT (avi, "Starting index massage, nr_entries = %d",
|
||||||
g_list_length (list));
|
list ? g_list_length (list) : 0);
|
||||||
|
|
||||||
if (list) {
|
if (list) {
|
||||||
#ifndef GST_DISABLE_DEBUG
|
#ifndef GST_DISABLE_DEBUG
|
||||||
guint num_added_total = 0;
|
guint num_added_total = 0;
|
||||||
|
guint num_per_stream[GST_AVI_DEMUX_MAX_STREAMS] = { 0, };
|
||||||
#endif
|
#endif
|
||||||
GST_LOG_OBJECT (avi,
|
GST_LOG_OBJECT (avi,
|
||||||
"I'm now going to cut large chunks into smaller pieces");
|
"I'm now going to cut large chunks into smaller pieces");
|
||||||
|
@ -2290,7 +2301,10 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
|
|
||||||
/* make a continous array out of the list */
|
/* make a continous array out of the list */
|
||||||
avi->index_size = g_list_length (list);
|
avi->index_size = g_list_length (list);
|
||||||
avi->index_entries = g_new (gst_avi_index_entry, avi->index_size);
|
avi->index_entries = g_try_new (gst_avi_index_entry, avi->index_size);
|
||||||
|
if (!avi->index_entries)
|
||||||
|
goto out_of_mem;
|
||||||
|
|
||||||
entry = (gst_avi_index_entry *) (list->data);
|
entry = (gst_avi_index_entry *) (list->data);
|
||||||
delay = entry->ts;
|
delay = entry->ts;
|
||||||
|
|
||||||
|
@ -2303,6 +2317,9 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
entry->index_nr = i;
|
entry->index_nr = i;
|
||||||
entry->ts -= delay;
|
entry->ts -= delay;
|
||||||
memcpy (&avi->index_entries[i], entry, sizeof (gst_avi_index_entry));
|
memcpy (&avi->index_entries[i], entry, sizeof (gst_avi_index_entry));
|
||||||
|
#ifndef GST_DISABLE_DEBUG
|
||||||
|
num_per_stream[entry->stream_nr]++;
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_DEBUG ("Sorted index entry %3d for stream %d of size %6u"
|
GST_DEBUG ("Sorted index entry %3d for stream %d of size %6u"
|
||||||
" at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
|
" at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
|
||||||
|
@ -2316,9 +2333,23 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
stream->idx_duration -= delay;
|
stream->idx_duration -= delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef GST_DISABLE_DEBUG
|
||||||
|
{
|
||||||
|
gchar str[GST_AVI_DEMUX_MAX_STREAMS * (1 + 6 + 2)];
|
||||||
|
gchar *pad_name;
|
||||||
|
|
||||||
|
for (i = 0; i < avi->num_streams; i++) {
|
||||||
|
pad_name = GST_OBJECT_NAME (avi->stream[i].pad);
|
||||||
|
sprintf (&str[i * (1 + 6 + 2)], " %6u %c", num_per_stream[i],
|
||||||
|
pad_name[0]);
|
||||||
|
}
|
||||||
|
GST_LOG_OBJECT (avi, "indizies per stream:%20s", str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_LOG_OBJECT (avi, "Freeing original index list");
|
GST_LOG_OBJECT (avi, "Freeing original index list");
|
||||||
/* all the node->data in list point to alloc_list chunks */
|
/* all the node->data in list point to alloc_list chunks */
|
||||||
|
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
}
|
}
|
||||||
if (alloc_list) {
|
if (alloc_list) {
|
||||||
|
@ -2333,6 +2364,13 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_LOG_OBJECT (avi, "Index massaging done");
|
GST_LOG_OBJECT (avi, "Index massaging done");
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
out_of_mem:
|
||||||
|
GST_WARNING_OBJECT (avi, "Out of memory for %lu bytes",
|
||||||
|
sizeof (gst_avi_index_entry) * avi->index_size);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2613,7 +2651,7 @@ skipping_done:
|
||||||
#if 0
|
#if 0
|
||||||
/*GList *index = NULL, *alloc = NULL; */
|
/*GList *index = NULL, *alloc = NULL; */
|
||||||
|
|
||||||
// ######################## this need to be integrated with the state
|
/* ######################## this need to be integrated with the state */
|
||||||
/* create or read stream index (for seeking) */
|
/* create or read stream index (for seeking) */
|
||||||
if (avi->stream[0].indexes != NULL) {
|
if (avi->stream[0].indexes != NULL) {
|
||||||
gst_avi_demux_read_subindexes_push (avi, &index, &alloc);
|
gst_avi_demux_read_subindexes_push (avi, &index, &alloc);
|
||||||
|
@ -2628,14 +2666,14 @@ skipping_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is a fatal error */
|
/* this is a fatal error */
|
||||||
if (!index) {
|
if (!index)
|
||||||
GST_WARNING ("file without index");
|
goto no_index;
|
||||||
|
|
||||||
|
if (!gst_avi_demux_massage_index (avi, index, alloc))
|
||||||
goto no_index;
|
goto no_index;
|
||||||
}
|
|
||||||
|
|
||||||
gst_avi_demux_massage_index (avi, index, alloc);
|
|
||||||
gst_avi_demux_calculate_durations_from_index (avi);
|
gst_avi_demux_calculate_durations_from_index (avi);
|
||||||
// ########################
|
/* ######################## */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* create initial NEWSEGMENT event */
|
/* create initial NEWSEGMENT event */
|
||||||
|
@ -2888,7 +2926,9 @@ skipping_done:
|
||||||
if (!index)
|
if (!index)
|
||||||
goto no_index;
|
goto no_index;
|
||||||
|
|
||||||
gst_avi_demux_massage_index (avi, index, alloc);
|
if (!gst_avi_demux_massage_index (avi, index, alloc))
|
||||||
|
goto no_index;
|
||||||
|
|
||||||
gst_avi_demux_calculate_durations_from_index (avi);
|
gst_avi_demux_calculate_durations_from_index (avi);
|
||||||
|
|
||||||
/* create initial NEWSEGMENT event */
|
/* create initial NEWSEGMENT event */
|
||||||
|
@ -2958,17 +2998,11 @@ no_streams:
|
||||||
}
|
}
|
||||||
no_index:
|
no_index:
|
||||||
{
|
{
|
||||||
GST_WARNING ("file without index");
|
GST_WARNING ("file without or too big index");
|
||||||
g_list_free (index);
|
g_list_free (index);
|
||||||
g_list_foreach (alloc, (GFunc) g_free, NULL);
|
g_list_foreach (alloc, (GFunc) g_free, NULL);
|
||||||
g_list_free (alloc);
|
g_list_free (alloc);
|
||||||
|
|
||||||
/* FIMXE: this happens e.g. if the file is empty (no index and not data
|
|
||||||
* chunks), wouldn't ERROR_DEMUX be better?
|
|
||||||
*
|
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("Could not get/create index"));
|
|
||||||
*/
|
|
||||||
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
|
||||||
("Could not get/create index"));
|
("Could not get/create index"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
@ -2981,7 +3015,8 @@ pull_range_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the actual seeking.
|
/*
|
||||||
|
* Do the actual seeking.
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
|
gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
|
||||||
|
@ -3048,7 +3083,7 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle seek.
|
* Handle seek event.
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
|
gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
|
||||||
|
@ -3249,13 +3284,12 @@ static GstFlowReturn
|
||||||
gst_avi_demux_combine_flows (GstAviDemux * avi, avi_stream_context * stream,
|
gst_avi_demux_combine_flows (GstAviDemux * avi, avi_stream_context * stream,
|
||||||
GstFlowReturn ret)
|
GstFlowReturn ret)
|
||||||
{
|
{
|
||||||
gint i;
|
guint i;
|
||||||
|
|
||||||
/* store the value */
|
/* store the value */
|
||||||
stream->last_flow = ret;
|
stream->last_flow = ret;
|
||||||
|
|
||||||
/* any other error that is not-linked can be returned right
|
/* any other error that is not-linked can be returned right away */
|
||||||
* away */
|
|
||||||
if (ret != GST_FLOW_NOT_LINKED)
|
if (ret != GST_FLOW_NOT_LINKED)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -3272,6 +3306,7 @@ gst_avi_demux_combine_flows (GstAviDemux * avi, avi_stream_context * stream,
|
||||||
/* if we get here, all other pads were unlinked and we return
|
/* if we get here, all other pads were unlinked and we return
|
||||||
* NOT_LINKED then */
|
* NOT_LINKED then */
|
||||||
done:
|
done:
|
||||||
|
GST_LOG_OBJECT (avi, "cobined return %s", gst_flow_get_name (ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3292,14 +3327,15 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
if (avi->current_entry >= avi->index_size)
|
if (avi->current_entry >= avi->index_size)
|
||||||
goto eos;
|
goto eos;
|
||||||
|
|
||||||
/* get next entry, this will work as we checked for the size above */
|
/* get next entry, this will work as we checked for the index size above */
|
||||||
entry = &avi->index_entries[avi->current_entry++];
|
entry = &avi->index_entries[avi->current_entry++];
|
||||||
|
|
||||||
/* see if we have a valid stream, ignore if not
|
/* see if we have a valid stream, ignore if not
|
||||||
* FIXME: can't we check this when building the index?
|
* FIXME: can't we check this when building the index?
|
||||||
|
* we check it in _parse_index(), _stream_scan()
|
||||||
*/
|
*/
|
||||||
if (entry->stream_nr >= avi->num_streams) {
|
if (entry->stream_nr >= avi->num_streams) {
|
||||||
GST_DEBUG_OBJECT (avi,
|
GST_WARNING_OBJECT (avi,
|
||||||
"Entry %d has non-existing stream nr %d",
|
"Entry %d has non-existing stream nr %d",
|
||||||
avi->current_entry - 1, entry->stream_nr);
|
avi->current_entry - 1, entry->stream_nr);
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue