summaryrefslogtreecommitdiffstats
path: root/gst/avi/gstavidemux.c
diff options
context:
space:
mode:
authorStefan Kost <ensonic@users.sourceforge.net>2006-11-24 07:46:54 +0000
committerStefan Kost <ensonic@users.sourceforge.net>2006-11-24 07:46:54 +0000
commit90431d788ecfa895049790133f60dd62648eab79 (patch)
treebd50cefdb099f85bcf732b72ee6db158d44d6967 /gst/avi/gstavidemux.c
parent466a76bd9d32fa5c8c7068925d1645ee0c2910b1 (diff)
gst/avi/gstavidemux.c: remove dead code, tweak debugs statements, add comments, use _uint64_scale instead _uint64_sca...
Original commit message from CVS: * gst/avi/gstavidemux.c: (gst_avi_demux_index_entry_for_time), (gst_avi_demux_src_convert), (gst_avi_demux_handle_src_query), (gst_avi_demux_peek_chunk), (gst_avi_demux_parse_subindex), (gst_avi_demux_read_subindexes_push), (gst_avi_demux_read_subindexes_pull), (gst_avi_demux_parse_stream), (gst_avi_demux_parse_index), (gst_avi_demux_stream_index), (gst_avi_demux_sync), (gst_avi_demux_next_data_buffer), (gst_avi_demux_massage_index), (gst_avi_demux_calculate_durations_from_index), (gst_avi_demux_stream_header_pull), (gst_avi_demux_do_seek), (gst_avi_demux_handle_seek), (gst_avi_demux_process_next_entry), (gst_avi_demux_stream_data), (gst_avi_demux_loop): remove dead code, tweak debugs statements, add comments, use _uint64_scale instead _uint64_scale_int when using guint64 values, small optimizations, reflow some error handling
Diffstat (limited to 'gst/avi/gstavidemux.c')
-rw-r--r--gst/avi/gstavidemux.c246
1 files changed, 171 insertions, 75 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 76469e5c..100272f7 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -289,6 +289,17 @@ gst_avi_demux_index_next (GstAviDemux * avi, gint stream_nr, gint start)
return result;
}
+/*
+ * gst_avi_index_entry:
+ * @avi: Avi object
+ * @stream_nr: stream number
+ * @time: seek time position
+ * @flags: index entry flags to match
+ *
+ * Finds the index entry which time is less or equal than the requested time.
+ *
+ * Returns: the found index entry or %NULL
+ */
static gst_avi_index_entry *
gst_avi_demux_index_entry_for_time (GstAviDemux * avi,
gint stream_nr, guint64 time, guint32 flags)
@@ -296,24 +307,24 @@ gst_avi_demux_index_entry_for_time (GstAviDemux * avi,
gst_avi_index_entry *entry = NULL, *last_entry = NULL;
gint i;
- GST_LOG_OBJECT (avi, "stream_nr:%d , time:%" GST_TIME_FORMAT " flags:%d",
+ GST_LOG_OBJECT (avi, "stream_nr:%d , time:%" GST_TIME_FORMAT " flags:%x",
stream_nr, GST_TIME_ARGS (time), flags);
i = -1;
do {
+ /* get next entry for given stream */
entry = gst_avi_demux_index_next (avi, stream_nr, i + 1);
if (!entry)
break;
i = entry->index_nr;
+ if (entry->ts <= time && (entry->flags & flags) == flags)
+ last_entry = entry;
GST_LOG_OBJECT (avi,
"looking at entry %d / ts:%" GST_TIME_FORMAT " / dur:%" GST_TIME_FORMAT
" flags:%d", i, GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (entry->dur),
entry->flags);
- if (entry->ts <= time &&
- (entry->flags & flags) == flags && stream_nr == entry->stream_nr)
- last_entry = entry;
} while (entry->ts < time);
return last_entry;
@@ -377,9 +388,8 @@ gst_avi_demux_src_convert (GstPad * pad,
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
- *dest_value =
- gst_util_uint64_scale_int (src_value, stream->strf.auds->av_bps,
- GST_SECOND);
+ *dest_value = gst_util_uint64_scale (src_value,
+ (guint64) stream->strf.auds->av_bps, GST_SECOND);
break;
case GST_FORMAT_DEFAULT:
*dest_value = gst_util_uint64_scale (src_value, stream->strh->rate,
@@ -394,8 +404,8 @@ gst_avi_demux_src_convert (GstPad * pad,
switch (*dest_format) {
case GST_FORMAT_TIME:
if (stream->strf.auds->av_bps != 0) {
- *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
- stream->strf.auds->av_bps);
+ *dest_value = gst_util_uint64_scale (src_value, GST_SECOND,
+ (guint64) stream->strf.auds->av_bps);
} else
res = FALSE;
break;
@@ -407,9 +417,8 @@ gst_avi_demux_src_convert (GstPad * pad,
case GST_FORMAT_DEFAULT:
switch (*dest_format) {
case GST_FORMAT_TIME:
- *dest_value =
- gst_util_uint64_scale (src_value,
- stream->strh->scale * GST_SECOND, stream->strh->rate);
+ *dest_value = gst_util_uint64_scale (src_value,
+ stream->strh->scale * GST_SECOND, (guint64) stream->strh->rate);
break;
default:
res = FALSE;
@@ -444,7 +453,7 @@ static gboolean
gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
{
gboolean res = TRUE;
- GstAviDemux *demux = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
+ GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
avi_stream_context *stream = gst_pad_get_element_private (pad);
@@ -455,34 +464,37 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
case GST_QUERY_POSITION:{
gint64 pos = 0;
+ GST_DEBUG ("pos query for stream %d: frames %d, bytes %" G_GUINT64_FORMAT,
+ stream->num, stream->current_frame, stream->current_byte);
+
if (stream->strh->type == GST_RIFF_FCC_auds) {
if (stream->is_vbr) {
/* VBR */
- pos = gst_util_uint64_scale_int ((gint64) stream->current_frame *
- stream->strh->scale, GST_SECOND, stream->strh->rate);
- GST_DEBUG_OBJECT (demux, "VBR convert frame %u, time %"
+ pos = gst_util_uint64_scale ((gint64) stream->current_frame *
+ stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate);
+ GST_DEBUG_OBJECT (avi, "VBR convert frame %u, time %"
GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos));
} else if (stream->strf.auds->av_bps != 0) {
/* CBR */
- pos = gst_util_uint64_scale_int (stream->current_byte, GST_SECOND,
- stream->strf.auds->av_bps);
- GST_DEBUG_OBJECT (demux,
+ pos = gst_util_uint64_scale (stream->current_byte, GST_SECOND,
+ (guint64) stream->strf.auds->av_bps);
+ GST_DEBUG_OBJECT (avi,
"CBR convert bytes %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT,
stream->current_byte, GST_TIME_ARGS (pos));
} else if (stream->total_frames != 0 && stream->total_bytes != 0) {
/* calculate timestamps based on percentage of length */
- guint64 xlen = demux->avih->us_frame *
- demux->avih->tot_frames * GST_USECOND;
+ guint64 xlen = avi->avih->us_frame *
+ avi->avih->tot_frames * GST_USECOND;
if (stream->is_vbr) {
pos = gst_util_uint64_scale (xlen, stream->current_frame,
stream->total_frames);
- GST_DEBUG_OBJECT (demux, "VBR perc convert frame %u, time %"
+ GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %"
GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos));
} else {
pos = gst_util_uint64_scale (xlen, stream->current_byte,
stream->total_bytes);
- GST_DEBUG_OBJECT (demux, "CBR perc convert bytes %" G_GUINT64_FORMAT
+ GST_DEBUG_OBJECT (avi, "CBR perc convert bytes %" G_GUINT64_FORMAT
", time %" GST_TIME_FORMAT, stream->current_byte,
GST_TIME_ARGS (pos));
}
@@ -492,11 +504,10 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
}
} else {
if (stream->strh->rate != 0) {
- pos =
- gst_util_uint64_scale_int ((guint64) stream->current_frame *
- stream->strh->scale, GST_SECOND, stream->strh->rate);
+ pos = gst_util_uint64_scale ((guint64) stream->current_frame *
+ stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate);
} else {
- pos = stream->current_frame * demux->avih->us_frame * GST_USECOND;
+ pos = stream->current_frame * avi->avih->us_frame * GST_USECOND;
}
}
if (res) {
@@ -607,6 +618,7 @@ static gboolean
gst_avi_demux_peek_chunk (GstAviDemux * avi, guint32 * tag, guint32 * size)
{
guint32 peek_size = 0;
+ gint available;
if (!gst_avi_demux_peek_chunk_info (avi, tag, size)) {
return FALSE;
@@ -617,11 +629,13 @@ gst_avi_demux_peek_chunk (GstAviDemux * avi, guint32 * tag, guint32 * size)
*size, GST_FOURCC_ARGS (*tag));
return FALSE;
}
- GST_DEBUG ("Need to peek chunk of %d bytes to read chunk %" GST_FOURCC_FORMAT,
- *size, GST_FOURCC_ARGS (*tag));
peek_size = (*size + 1) & ~1;
+ available = gst_adapter_available (avi->adapter);
- if (gst_adapter_available (avi->adapter) >= (8 + peek_size)) {
+ GST_DEBUG ("Need to peek chunk of %d bytes to read chunk %" GST_FOURCC_FORMAT
+ ", %d bytes available", *size, GST_FOURCC_ARGS (*tag), available);
+
+ if (available >= (8 + peek_size)) {
return TRUE;
} else {
return FALSE;
@@ -868,7 +882,7 @@ too_small:
/*
* gst_avi_demux_parse_subindex:
- * @element: caller element (used for errors/debug).
+ * @avi: Avi object
* @buf: input data to use for parsing.
* @stream: stream context.
* @entries_list: a list (returned by the function) containing all the
@@ -884,7 +898,7 @@ too_small:
* throw an error, caller should bail out asap.
*/
static gboolean
-gst_avi_demux_parse_subindex (GstElement * element,
+gst_avi_demux_parse_subindex (GstAviDemux * avi,
GstBuffer * buf, avi_stream_context * stream, GList ** _entries_list)
{
guint8 *data = GST_BUFFER_DATA (buf);
@@ -913,7 +927,7 @@ gst_avi_demux_parse_subindex (GstElement * element,
bpe = (data[2] & 0x01) ? 12 : 8;
if (GST_READ_UINT16_LE (data) != bpe / 4 ||
(data[2] & 0xfe) != 0x0 || data[3] != 0x1) {
- GST_WARNING_OBJECT (element,
+ GST_WARNING_OBJECT (avi,
"Superindex for stream %d has unexpected "
"size_entry %d (bytes) or flags 0x%02x/0x%02x",
stream->num, GST_READ_UINT16_LE (data), data[2], data[3]);
@@ -969,7 +983,7 @@ gst_avi_demux_parse_subindex (GstElement * element,
entries_list = g_list_prepend (entries_list, entry);
}
- GST_LOG_OBJECT (element, "Read %d index entries", x);
+ GST_LOG_OBJECT (avi, "Read %d index entries", x);
gst_buffer_unref (buf);
@@ -984,7 +998,7 @@ gst_avi_demux_parse_subindex (GstElement * element,
/* ERRORS */
too_small:
{
- GST_ERROR_OBJECT (element,
+ GST_ERROR_OBJECT (avi,
"Not enough data to parse subindex (%d available, 24 needed)", size);
if (buf)
gst_buffer_unref (buf);
@@ -992,7 +1006,7 @@ too_small:
}
not_implemented:
{
- GST_ELEMENT_ERROR (element, STREAM, NOT_IMPLEMENTED, (NULL),
+ GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
("Subindex-is-data is not implemented"));
gst_buffer_unref (buf);
return FALSE;
@@ -1012,7 +1026,7 @@ gst_avi_demux_read_subindexes_push (GstAviDemux * avi,
GstBuffer *buf = NULL;
gint i, n;
- GST_DEBUG_OBJECT (avi, "gst_avi_demux_read_subindexes_pull for %d streams",
+ GST_DEBUG_OBJECT (avi, "gst_avi_demux_read_subindexes_push for %d streams",
avi->num_streams);
for (n = 0; n < avi->num_streams; n++) {
@@ -1034,7 +1048,7 @@ gst_avi_demux_read_subindexes_push (GstAviDemux * avi,
GST_BUFFER_DATA (buf) = gst_adapter_take (avi->adapter, size);
GST_BUFFER_SIZE (buf) = size;
- if (!gst_avi_demux_parse_subindex (GST_ELEMENT (avi), buf, stream, &list))
+ if (!gst_avi_demux_parse_subindex (avi, buf, stream, &list))
continue;
if (list) {
GST_DEBUG_OBJECT (avi, " adding %d entries", g_list_length (list));
@@ -1080,7 +1094,7 @@ gst_avi_demux_read_subindexes_pull (GstAviDemux * avi,
continue;
}
- if (!gst_avi_demux_parse_subindex (GST_ELEMENT (avi), buf, stream, &list))
+ if (!gst_avi_demux_parse_subindex (avi, buf, stream, &list))
continue;
if (list) {
GST_DEBUG_OBJECT (avi, " adding %5d entries, total %2d %5d",
@@ -1290,6 +1304,10 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
goto fail;
}
+ GST_DEBUG_OBJECT (element, "codec-name=%s",
+ (codec_name ? codec_name : "NULL"));
+ GST_DEBUG_OBJECT (element, "caps=%" GST_PTR_FORMAT, caps);
+
/* set proper settings and add it */
if (stream->pad)
gst_object_unref (stream->pad);
@@ -1509,6 +1527,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
avi->index_offset = pos_before + 8;
else
avi->index_offset = 0;
+ GST_DEBUG ("index_offset = %" G_GUINT64_FORMAT, avi->index_offset);
}
format = GST_FORMAT_TIME;
@@ -1571,31 +1590,51 @@ static void
gst_avi_demux_stream_index (GstAviDemux * avi,
GList ** index, GList ** alloc_list)
{
+ GstFlowReturn res;
guint64 offset = avi->offset;
GstBuffer *buf;
guint32 tag;
+ guint size;
gint i;
- GST_DEBUG ("Demux stream index");
+ GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
*alloc_list = NULL;
*index = NULL;
/* get chunk information */
- if (gst_pad_pull_range (avi->sinkpad, offset, 8, &buf) != GST_FLOW_OK)
- return;
+ res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
+ if (res != GST_FLOW_OK)
+ goto pull_failed;
else if (GST_BUFFER_SIZE (buf) < 8)
goto too_small;
- offset += 8 + GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+ /* check tag first before blindy trying to read 'size' bytes */
+ tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
+ size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+ if (tag == GST_RIFF_TAG_LIST) {
+ GST_WARNING_OBJECT (avi, "skip LIST chunk");
+ offset += 8 + ((size + 1) & ~1);
+ res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
+ if (res != GST_FLOW_OK)
+ goto pull_failed;
+ else if (GST_BUFFER_SIZE (buf) < 8)
+ goto too_small;
+ tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
+ size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+ }
+
+ if (tag != GST_RIFF_TAG_idx1)
+ goto no_index;
+
gst_buffer_unref (buf);
+ GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
+
/* read chunk, advance offset */
if (gst_riff_read_chunk (GST_ELEMENT_CAST (avi),
avi->sinkpad, &offset, &tag, &buf) != GST_FLOW_OK)
return;
- else if (tag != GST_RIFF_TAG_idx1)
- goto no_index;
gst_avi_demux_parse_index (avi, buf, index);
if (*index)
@@ -1612,6 +1651,12 @@ gst_avi_demux_stream_index (GstAviDemux * avi,
return;
/* ERRORS */
+pull_failed:
+ {
+ GST_DEBUG_OBJECT (avi,
+ "pull range failed: pos=%" G_GUINT64_FORMAT " size=8", offset);
+ return;
+ }
too_small:
{
GST_DEBUG_OBJECT (avi, "Buffer is too small");
@@ -1621,7 +1666,7 @@ too_small:
no_index:
{
GST_WARNING_OBJECT (avi,
- "No index data after movi chunk, but %" GST_FOURCC_FORMAT,
+ "No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (tag));
gst_buffer_unref (buf);
return;
@@ -1834,7 +1879,7 @@ gst_avi_demux_next_data_buffer (GstAviDemux * avi, guint64 * offset,
if (res != GST_FLOW_OK)
break;
if (*tag == GST_RIFF_TAG_LIST)
- off += 12;
+ off += 8 + 4; /* skip tag + size + subtag */
else {
*offset = off + 8;
*size = _size;
@@ -2059,7 +2104,7 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
guint32 init_frames;
GstFormat fmt = GST_FORMAT_TIME;
#endif
- gint64 delay = 0;
+ gint64 delay = G_GINT64_CONSTANT (0);
GST_LOG_OBJECT (avi, "Starting index massage");
@@ -2177,24 +2222,35 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
/* re-order for time */
list = g_list_sort (list, (GCompareFunc) sort);
- GST_LOG_OBJECT (avi, "Filling in index array");
-
avi->index_size = g_list_length (list);
+ GST_LOG_OBJECT (avi, "Filling in index array, nr_entries = %d",
+ avi->index_size);
+
avi->index_entries = g_new (gst_avi_index_entry, avi->index_size);
- entry = (gst_avi_index_entry *) (list->data);
- delay = entry->ts;
+ if (list) {
+ entry = (gst_avi_index_entry *) (list->data);
+ delay = entry->ts;
+ }
+
GST_DEBUG ("Fixing time offset : %" GST_TIME_FORMAT, GST_TIME_ARGS (delay));
for (i = 0, one = list; one != NULL; one = one->next, i++) {
entry = one->data;
entry->ts -= delay;
memcpy (&avi->index_entries[i], entry, sizeof (gst_avi_index_entry));
avi->index_entries[i].index_nr = i;
+
GST_DEBUG ("Sorted index entry %3d for stream %d of size %6u"
" at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
" dur %" GST_TIME_FORMAT,
avi->index_entries[i].index_nr, entry->stream_nr, entry->size,
entry->offset, GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (entry->dur));
}
+ if (delay) {
+ for (i = 0; i < avi->num_streams; i++) {
+ stream = &avi->stream[i];
+ stream->idx_duration -= delay;
+ }
+ }
GST_LOG_OBJECT (avi, "Freeing original index list");
@@ -2227,11 +2283,14 @@ gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
/* get header duration */
hduration = gst_util_uint64_scale ((guint64) strh->length *
- strh->scale, GST_SECOND, strh->rate);
+ strh->scale, GST_SECOND, (guint64) strh->rate);
GST_INFO ("Stream %d duration according to header: %" GST_TIME_FORMAT,
stream, GST_TIME_ARGS (hduration));
+ if (hduration == 0)
+ hduration = GST_CLOCK_TIME_NONE;
+
/* set duration for the stream */
streamc->hdr_duration = hduration;
@@ -2260,6 +2319,21 @@ gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
total = duration;
}
+ if (GST_CLOCK_TIME_IS_VALID (total) && (total > 0)) {
+ /* now update the duration for those streams where we had none */
+ for (stream = 0; stream < avi->num_streams; stream++) {
+ avi_stream_context *streamc = &avi->stream[stream];
+
+ if (!GST_CLOCK_TIME_IS_VALID (streamc->duration)
+ || streamc->duration == 0) {
+ streamc->duration = total;
+
+ GST_INFO ("Stream %d duration according to total: %" GST_TIME_FORMAT,
+ stream, GST_TIME_ARGS (total));
+ }
+ }
+ }
+
/* and set the total duration in the segment. */
GST_INFO ("Setting total duration to: %" GST_TIME_FORMAT,
GST_TIME_ARGS (total));
@@ -2638,8 +2712,8 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
}
default:
GST_WARNING_OBJECT (avi,
- "Unknown off %d tag %" GST_FOURCC_FORMAT " in AVI header",
- offset, GST_FOURCC_ARGS (tag));
+ "Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
+ GST_FOURCC_ARGS (tag), offset);
/* fall-through */
case GST_RIFF_TAG_JUNK:
next:
@@ -2722,6 +2796,7 @@ skipping_done:
/* create or read stream index (for seeking) */
if (avi->stream[0].indexes != NULL) {
+ /* we read a super index already (gst_avi_demux_parse_superindex() ) */
gst_avi_demux_read_subindexes_pull (avi, &index, &alloc);
}
if (!index) {
@@ -2838,7 +2913,7 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
old_entry = avi->current_entry;
/* get the entry for the requested position, which is always in last_stop.
- * we search the index intry for stream 0, since all entries are sorted by
+ * we search the index entry for stream 0, since all entries are sorted by
* time and stream we automagically are positioned for the other streams as
* well. FIXME, this code assumes the main stream with keyframes is stream 0,
* which is mostly correct... */
@@ -2850,6 +2925,7 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
" / duration:%" GST_TIME_FORMAT "]", entry->index_nr,
entry->stream_nr, GST_TIME_ARGS (entry->ts),
GST_TIME_ARGS (entry->dur));
+
avi->current_entry = entry->index_nr;
} else {
GST_WARNING_OBJECT (avi,
@@ -2919,21 +2995,25 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
format = fmt;
}
+ /* FIXME: can we do anything with rate!=1.0 */
} else {
GST_DEBUG_OBJECT (avi, "doing seek without event");
flags = 0;
+ rate = 1.0;
}
/* save flush flag */
flush = flags & GST_SEEK_FLAG_FLUSH;
if (flush) {
+ GstEvent *event = gst_event_new_flush_start ();
+
/* for a flushing seek, we send a flush_start on all pads. This will
* eventually stop streaming with a WRONG_STATE. We can thus eventually
* take the STREAM_LOCK. */
GST_DEBUG_OBJECT (avi, "sending flush start");
- gst_avi_demux_push_event (avi, gst_event_new_flush_start ());
- gst_pad_push_event (avi->sinkpad, gst_event_new_flush_start ());
+ gst_avi_demux_push_event (avi, gst_event_ref (event));
+ gst_pad_push_event (avi->sinkpad, event);
} else {
/* a non-flushing seek, we PAUSE the task so that we can take the
* STREAM_LOCK */
@@ -2942,6 +3022,7 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
}
/* wait for streaming to stop */
+ GST_DEBUG_OBJECT (avi, "wait for streaming to stop");
GST_PAD_STREAM_LOCK (avi->sinkpad);
/* copy segment, we need this because we still need the old
@@ -3100,7 +3181,7 @@ gst_avi_demux_aggregated_flow (GstAviDemux * avi)
}
/*
- * Read data from index
+ * Read data from one index entry
*/
static GstFlowReturn
gst_avi_demux_process_next_entry (GstAviDemux * avi)
@@ -3144,6 +3225,10 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
goto next;
}
+ GST_LOG ("reading buffer (size=%d) from stream %d at current pos %"
+ G_GUINT64_FORMAT " (%llx)", entry->size, entry->stream_nr,
+ avi->index_offset + entry->offset, avi->index_offset + entry->offset);
+
/* pull in the data */
res = gst_pad_pull_range (avi->sinkpad, entry->offset +
avi->index_offset, entry->size, &buf);
@@ -3166,7 +3251,7 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
GST_BUFFER_DURATION (buf) = entry->dur;
gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
- GST_DEBUG_OBJECT (avi, "Processing buffer of size %d and time %"
+ GST_DEBUG_OBJECT (avi, "Pushing buffer of size %d and time %"
GST_TIME_FORMAT " on pad %s",
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (entry->ts),
GST_PAD_NAME (stream->pad));
@@ -3242,6 +3327,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
guint32 size = 0;
gint stream_nr = 0;
GstFlowReturn res = GST_FLOW_OK;
+ GstFormat format = GST_FORMAT_TIME;
/* if we have a avi->index_entries[], we don't want to read
* the stream linearly, but seek to the next ts/index_entry. */
@@ -3306,12 +3392,11 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
/* recoverable */
GST_WARNING ("Invalid stream ID %d (%" GST_FOURCC_FORMAT ")",
stream_nr, GST_FOURCC_ARGS (tag));
-
+ avi->offset += 8 + ((size + 1) & ~1);
gst_adapter_flush (avi->adapter, 8 + ((size + 1) & ~1));
} else {
avi_stream_context *stream;
GstClockTime next_ts = 0;
- GstFormat format;
GstBuffer *buf;
gst_adapter_flush (avi->adapter, 8);
@@ -3324,8 +3409,9 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
/* get time of this buffer */
stream = &avi->stream[stream_nr];
- format = GST_FORMAT_TIME;
gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
+ if (format != GST_FORMAT_TIME)
+ goto wrong_format;
/* set delay (if any)
if (stream->strh->init_frames == stream->current_frame &&
@@ -3336,12 +3422,6 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
stream->current_frame++;
stream->current_byte += size;
- /* should we skip this buffer? */
- /*
- if (stream->skip) {
- stream->skip--;
- gst_buffer_unref (buf);
- } else { */
if (!stream->pad) {
GST_WARNING ("No pad.");
gst_buffer_unref (buf);
@@ -3353,8 +3433,11 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
buf = gst_avi_demux_invert (stream, buf);
}
- GST_BUFFER_TIMESTAMP (buf) = next_ts;
gst_pad_query_position (stream->pad, &format, (gint64 *) & dur_ts);
+ if (format != GST_FORMAT_TIME)
+ goto wrong_format;
+
+ GST_BUFFER_TIMESTAMP (buf) = next_ts;
GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
GST_DEBUG_OBJECT (avi,
@@ -3376,11 +3459,20 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
return res;
}
}
- /*} */
}
}
+done:
return res;
+
+ /* ERRORS */
+wrong_format:
+ {
+ GST_DEBUG_OBJECT (avi, "format %s != GST_FORMAT_TIME",
+ gst_format_get_name (format));
+ res = GST_FLOW_ERROR;
+ goto done;
+ }
}
/*
@@ -3413,7 +3505,7 @@ push_tag_lists (GstAviDemux * avi)
static void
gst_avi_demux_loop (GstPad * pad)
{
- GstFlowReturn res = GST_FLOW_OK;
+ GstFlowReturn res = GST_FLOW_OK, agg_res = GST_FLOW_OK;
GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
switch (avi->state) {
@@ -3449,10 +3541,14 @@ gst_avi_demux_loop (GstPad * pad)
GST_DEBUG_OBJECT (avi, "state: %d res:%s", avi->state,
gst_flow_get_name (res));
- /* Get Aggregated flow return */
- if ((res != GST_FLOW_OK)
- && ((res = gst_avi_demux_aggregated_flow (avi)) != GST_FLOW_OK))
+ /* if a pad is in e.g. WRONG_STATE, we want to pause to unlock the STREAM_LOCK */
+ if ((res == GST_FLOW_WRONG_STATE) || ((res != GST_FLOW_OK)
+ && ((agg_res = gst_avi_demux_aggregated_flow (avi)) != GST_FLOW_OK))) {
+ GST_WARNING ("stream_movi flow: %s / %s", gst_flow_get_name (res),
+ gst_flow_get_name (agg_res));
+ res = agg_res;
goto pause;
+ }
return;