summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Swain <robert.swain@collabora.co.uk>2010-01-19 10:51:08 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2010-01-26 16:55:27 +0100
commitacac3a34000822585b6ceb79dc52f83d54b998c7 (patch)
treec1f4b64afd838d6b2417a5706584d9e53d65a34d
parent6b4aa7fb0b923a58062e81db4ec305207b205d66 (diff)
avidemux: Fix _handle_seek_push () and new segement behaviourste-avi-push-seek
-rw-r--r--gst/avi/gstavidemux.c110
1 files changed, 61 insertions, 49 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 1d6ab460d..029923a9e 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -777,25 +777,30 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
if (avi->have_index) {
GstAviIndexEntry *entry;
- guint index;
- /* FIXME, this code assumes the main stream with keyframes is stream 0,
- * which is mostly correct... */
- GstAviStream *stream = &avi->stream[avi->main_stream];
-
- /* find the index for start bytes offset, calculate the corresponding
- * time and (reget?) start offset in bytes */
- entry = gst_util_array_binary_search (stream->index,
- stream->idx_n, sizeof (GstAviIndexEntry),
- (GCompareDataFunc) gst_avi_demux_index_entry_offset_search,
- GST_SEARCH_MODE_BEFORE, &start, NULL);
-
- if (entry == NULL) {
- index = 0;
- } else {
- index = entry - stream->index;
- }
+ guint i = 0, index;
+ GstAviStream *stream;
+
+ /* find which stream we're on */
+ do {
+ stream = &avi->stream[i];
+
+ /* find the index for start bytes offset */
+ entry = gst_util_array_binary_search (stream->index,
+ stream->idx_n, sizeof (GstAviIndexEntry),
+ (GCompareDataFunc) gst_avi_demux_index_entry_offset_search,
+ GST_SEARCH_MODE_BEFORE, &start, NULL);
+
+ if (entry == NULL) {
+ index = 0;
+ } else {
+ index = entry - stream->index;
+ }
+
+ if (stream->index[index].offset == start)
+ break;
+ } while (++i < avi->num_streams);
- start = stream->index[index].offset;
+ /* get the ts corresponding to start offset bytes for the stream */
gst_avi_demux_get_buffer_info (avi, stream, index,
(GstClockTime *) & time, NULL, NULL, NULL);
} else if (avi->element_index) {
@@ -4146,87 +4151,94 @@ avi_demux_handle_seek_push (GstAviDemux * avi, GstPad * pad, GstEvent * event)
format = fmt;
}
- GST_DEBUG_OBJECT (avi,
- "seek requested: rate %g cur %" GST_TIME_FORMAT " stop %"
- GST_TIME_FORMAT, rate, GST_TIME_ARGS (cur), GST_TIME_ARGS (stop));
- /* FIXME: can we do anything with rate!=1.0 */
keyframe = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
- GST_DEBUG_OBJECT (avi, "seek to: %" GST_TIME_FORMAT
- " keyframe seeking:%d", GST_TIME_ARGS (cur), keyframe);
+ GST_DEBUG_OBJECT (avi,
+ "Seek requested: ts %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
+ ", kf %u, rate %lf", GST_TIME_ARGS (cur), GST_TIME_ARGS (stop), keyframe,
+ rate);
+ /* FIXME: can we do anything with rate!=1.0 */
/* FIXME, this code assumes the main stream with keyframes is stream 0,
* which is mostly correct... */
str_num = avi->main_stream;
- stream = &avi->stream[avi->main_stream];
+ stream = &avi->stream[str_num];
/* get the entry index for the requested position */
index = gst_avi_demux_index_for_time (avi, stream, cur);
- GST_DEBUG_OBJECT (avi, "Got entry %u", index);
+ GST_DEBUG_OBJECT (avi, "str %u: Found entry %u for %" GST_TIME_FORMAT,
+ str_num, index, GST_TIME_ARGS (cur));
/* check if we are already on a keyframe */
if (!ENTRY_IS_KEYFRAME (&stream->index[index])) {
- GST_DEBUG_OBJECT (avi, "not keyframe, searching back");
+ GST_DEBUG_OBJECT (avi, "Entry is not a keyframe - searching back");
/* now go to the previous keyframe, this is where we should start
* decoding from. */
index = gst_avi_demux_index_prev (avi, stream, index, TRUE);
- GST_DEBUG_OBJECT (avi, "previous keyframe at %u", index);
+ GST_DEBUG_OBJECT (avi, "Found previous keyframe at %u", index);
}
gst_avi_demux_get_buffer_info (avi, stream, index,
&stream->current_timestamp, &stream->current_ts_end,
&stream->current_offset, &stream->current_offset_end);
- min_offset = stream->current_offset;
+ /* re-use cur to be the timestamp of the seek as it _will_ be */
+ cur = stream->current_timestamp;
+
+ min_offset = stream->index[index].offset;
+
+ GST_DEBUG_OBJECT (avi,
+ "Seek to: ts %" GST_TIME_FORMAT " (on str %u, idx %u, offset %"
+ G_GUINT64_FORMAT ")", GST_TIME_ARGS (stream->current_timestamp), str_num,
+ index, min_offset);
+
for (n = 0; n < avi->num_streams; n++) {
GstAviStream *str = &avi->stream[n];
guint idx;
- guint64 off;
if (n == avi->main_stream)
continue;
/* get the entry index for the requested position */
- idx = gst_avi_demux_index_for_time (avi, str, stream->current_timestamp);
- GST_DEBUG_OBJECT (avi, "Got entry %u", idx);
+ idx = gst_avi_demux_index_for_time (avi, str, cur);
+ GST_DEBUG_OBJECT (avi, "str %u: Found entry %u for %" GST_TIME_FORMAT, n,
+ idx, GST_TIME_ARGS (cur));
/* check if we are already on a keyframe */
if (!ENTRY_IS_KEYFRAME (&str->index[idx])) {
- GST_DEBUG_OBJECT (avi, "not keyframe, searching back");
+ GST_DEBUG_OBJECT (avi, "Entry is not a keyframe - searching back");
/* now go to the previous keyframe, this is where we should start
* decoding from. */
idx = gst_avi_demux_index_prev (avi, str, idx, TRUE);
- GST_DEBUG_OBJECT (avi, "previous keyframe at %u", idx);
+ GST_DEBUG_OBJECT (avi, "Found previous keyframe at %u", idx);
}
- gst_avi_demux_get_buffer_info (avi, str, idx, NULL, NULL, &off, NULL);
- if (off < min_offset) {
+ gst_avi_demux_get_buffer_info (avi, str, idx,
+ &str->current_timestamp, &str->current_ts_end,
+ &str->current_offset, &str->current_offset_end);
+
+ if (str->index[idx].offset < min_offset) {
+ min_offset = str->index[idx].offset;
GST_DEBUG_OBJECT (avi,
- "Found an earlier offset at %" G_GUINT64_FORMAT ", str %u", off, n);
- min_offset = off;
+ "Found an earlier offset at %" G_GUINT64_FORMAT ", str %u",
+ min_offset, n);
str_num = n;
stream = str;
index = idx;
}
}
- gst_avi_demux_get_buffer_info (avi, stream, index,
- &stream->current_timestamp, &stream->current_ts_end,
- &stream->current_offset, &stream->current_offset_end);
-
- GST_DEBUG_OBJECT (avi, "Moved to str %u, idx %u, ts %" GST_TIME_FORMAT
- ", ts_end %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
- ", off_end %" G_GUINT64_FORMAT, str_num, index,
+ GST_DEBUG_OBJECT (avi,
+ "Seek performed: str %u, offset %" G_GUINT64_FORMAT ", idx %u, ts %"
+ GST_TIME_FORMAT ", ts_end %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
+ ", off_end %" G_GUINT64_FORMAT, str_num, min_offset, index,
GST_TIME_ARGS (stream->current_timestamp),
GST_TIME_ARGS (stream->current_ts_end), stream->current_offset,
stream->current_offset_end);
- GST_DEBUG_OBJECT (avi, "Seeking to offset %" G_GUINT64_FORMAT,
- stream->index[index].offset);
-
if (!perform_seek_to_offset (avi,
- stream->index[index].offset - (avi->stream[0].indexes ? 8 : 0))) {
+ min_offset - (avi->stream[0].indexes ? 8 : 0))) {
GST_DEBUG_OBJECT (avi, "seek event failed!");
return FALSE;
}