mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +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>
|
||||
|
||||
* gst/smpte/barboxwipes.c:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
The avi decoder plugins
|
||||
The avi decoder plugins
|
||||
-----------------------
|
||||
|
||||
The avi decoder consists of a set of gstreamer plugins:
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* </para>
|
||||
* <para>
|
||||
* This element supports both push and pull-based scheduling, depending on the
|
||||
* capabilities of the upstream elements.
|
||||
* capabilities of the upstream elements.
|
||||
* </para>
|
||||
* <title>Example launch line</title>
|
||||
* <para>
|
||||
|
@ -1350,14 +1350,20 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
|
|||
|
||||
gst_pad_use_fixed_caps (pad);
|
||||
#if 0
|
||||
gst_pad_set_formats_function (pad, gst_avi_demux_get_src_formats);
|
||||
gst_pad_set_event_mask_function (pad, gst_avi_demux_get_event_mask);
|
||||
gst_pad_set_formats_function (pad,
|
||||
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
|
||||
gst_pad_set_event_function (pad, gst_avi_demux_handle_src_event);
|
||||
gst_pad_set_query_type_function (pad, gst_avi_demux_get_src_query_types);
|
||||
gst_pad_set_query_function (pad, gst_avi_demux_handle_src_query);
|
||||
gst_pad_set_event_function (pad,
|
||||
GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_event));
|
||||
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
|
||||
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
|
||||
|
||||
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.
|
||||
* If times are equal we sort by stream number.
|
||||
*/
|
||||
static gint
|
||||
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;
|
||||
gst_riff_index_entry entry, *_entry;
|
||||
avi_stream_context *stream;
|
||||
gint stream_nr;
|
||||
guint stream_nr;
|
||||
gst_avi_index_entry *target;
|
||||
GstFormat format;
|
||||
|
||||
|
@ -1546,7 +1553,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
|
|||
continue;
|
||||
|
||||
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,
|
||||
"Index entry %d has invalid stream nr %d", i, stream_nr);
|
||||
continue;
|
||||
|
@ -1972,7 +1979,7 @@ gst_avi_demux_next_data_buffer (GstAviDemux * avi, guint64 * offset,
|
|||
* @avi: calling element (used for debugging/errors).
|
||||
* @index: list of index entries, returned by this function.
|
||||
* @alloc_list: list of allocated data, returned by this function.
|
||||
*
|
||||
*
|
||||
* Scan the file for all chunks to "create" a new index.
|
||||
* Return value indicates if we can continue reading the stream. It
|
||||
* does not say anything about whether we created an index.
|
||||
|
@ -2023,8 +2030,8 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
|||
G_GUINT64_FORMAT "+%u)", pos, length, entry->offset, entry->size);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
gint stream_nr;
|
||||
while (TRUE) {
|
||||
guint stream_nr;
|
||||
guint size = 0;
|
||||
gint64 tmpts, tmpnextts;
|
||||
|
||||
|
@ -2034,8 +2041,11 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
|||
|
||||
/* check valid stream */
|
||||
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;
|
||||
}
|
||||
|
||||
stream = &avi->stream[stream_nr];
|
||||
|
||||
|
@ -2097,11 +2107,11 @@ gst_avi_demux_stream_scan (GstAviDemux * avi,
|
|||
/* FIXME: why is this disabled */
|
||||
#if 0
|
||||
while (gst_avi_demux_sync (avi, &tag, TRUE)) {
|
||||
gint stream_nr = CHUNKID_TO_STREAMNR (tag);
|
||||
guint stream_nr = CHUNKID_TO_STREAMNR (tag);
|
||||
guint8 *data;
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
|
||||
if (stream_nr < 0 || stream_nr >= avi->num_streams)
|
||||
if (stream_nr >= avi->num_streams)
|
||||
goto next;
|
||||
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
|
||||
* order. The end result should be a smoother playing AVI.
|
||||
*/
|
||||
static void
|
||||
static gboolean
|
||||
gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||
GList * list, GList * alloc_list)
|
||||
{
|
||||
gst_avi_index_entry *entry;
|
||||
avi_stream_context *stream;
|
||||
gint i;
|
||||
guint i;
|
||||
GList *node;
|
||||
gint64 delay = G_GINT64_CONSTANT (0);
|
||||
|
||||
GST_LOG_OBJECT (avi, "Starting index massage, nr_entries = %d",
|
||||
g_list_length (list));
|
||||
list ? g_list_length (list) : 0);
|
||||
|
||||
if (list) {
|
||||
#ifndef GST_DISABLE_DEBUG
|
||||
guint num_added_total = 0;
|
||||
guint num_per_stream[GST_AVI_DEMUX_MAX_STREAMS] = { 0, };
|
||||
#endif
|
||||
GST_LOG_OBJECT (avi,
|
||||
"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 */
|
||||
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);
|
||||
delay = entry->ts;
|
||||
|
||||
|
@ -2303,6 +2317,9 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
|||
entry->index_nr = i;
|
||||
entry->ts -= delay;
|
||||
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"
|
||||
" 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;
|
||||
}
|
||||
}
|
||||
#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");
|
||||
/* all the node->data in list point to alloc_list chunks */
|
||||
|
||||
g_list_free (list);
|
||||
}
|
||||
if (alloc_list) {
|
||||
|
@ -2333,6 +2364,13 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
|||
#endif
|
||||
|
||||
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
|
||||
|
@ -2613,7 +2651,7 @@ skipping_done:
|
|||
#if 0
|
||||
/*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) */
|
||||
if (avi->stream[0].indexes != NULL) {
|
||||
gst_avi_demux_read_subindexes_push (avi, &index, &alloc);
|
||||
|
@ -2628,14 +2666,14 @@ skipping_done:
|
|||
}
|
||||
|
||||
/* this is a fatal error */
|
||||
if (!index) {
|
||||
GST_WARNING ("file without index");
|
||||
if (!index)
|
||||
goto no_index;
|
||||
|
||||
if (!gst_avi_demux_massage_index (avi, index, alloc))
|
||||
goto no_index;
|
||||
}
|
||||
|
||||
gst_avi_demux_massage_index (avi, index, alloc);
|
||||
gst_avi_demux_calculate_durations_from_index (avi);
|
||||
// ########################
|
||||
/* ######################## */
|
||||
#endif
|
||||
|
||||
/* create initial NEWSEGMENT event */
|
||||
|
@ -2888,7 +2926,9 @@ skipping_done:
|
|||
if (!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);
|
||||
|
||||
/* create initial NEWSEGMENT event */
|
||||
|
@ -2958,17 +2998,11 @@ no_streams:
|
|||
}
|
||||
no_index:
|
||||
{
|
||||
GST_WARNING ("file without index");
|
||||
GST_WARNING ("file without or too big index");
|
||||
g_list_free (index);
|
||||
g_list_foreach (alloc, (GFunc) g_free, NULL);
|
||||
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),
|
||||
("Could not get/create index"));
|
||||
return GST_FLOW_ERROR;
|
||||
|
@ -2981,7 +3015,8 @@ pull_range_failed:
|
|||
}
|
||||
}
|
||||
|
||||
/* Do the actual seeking.
|
||||
/*
|
||||
* Do the actual seeking.
|
||||
*/
|
||||
static gboolean
|
||||
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
|
||||
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,
|
||||
GstFlowReturn ret)
|
||||
{
|
||||
gint i;
|
||||
guint i;
|
||||
|
||||
/* store the value */
|
||||
stream->last_flow = ret;
|
||||
|
||||
/* any other error that is not-linked can be returned right
|
||||
* away */
|
||||
/* any other error that is not-linked can be returned right away */
|
||||
if (ret != GST_FLOW_NOT_LINKED)
|
||||
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
|
||||
* NOT_LINKED then */
|
||||
done:
|
||||
GST_LOG_OBJECT (avi, "cobined return %s", gst_flow_get_name (ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3292,14 +3327,15 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
|||
if (avi->current_entry >= avi->index_size)
|
||||
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++];
|
||||
|
||||
/* see if we have a valid stream, ignore if not
|
||||
* 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) {
|
||||
GST_DEBUG_OBJECT (avi,
|
||||
GST_WARNING_OBJECT (avi,
|
||||
"Entry %d has non-existing stream nr %d",
|
||||
avi->current_entry - 1, entry->stream_nr);
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue