summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-09-22 14:44:42 +0200
committerWim Taymans <wim@metal.(none)>2009-09-28 22:16:48 +0200
commitc199b1d039c1f8673829d6465b08de7a537658ca (patch)
tree474caa5ce387998ddb238f08e2494b8b8b10676e
parent0d70fe30a8fad452627e2f6c9402bacc4506bc39 (diff)
avi: more cleanups
Remove some duplicate counters. Be smarter when updateing the current the timestamp and offset in the stream because we can reuse previously calculated values when simply go forward one step. Correctly set metadata on outgoing buffers.
-rw-r--r--gst/avi/gstavidemux.c243
-rw-r--r--gst/avi/gstavidemux.h12
2 files changed, 155 insertions, 100 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 7a1f96a85..42d5ce5d1 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -450,3 +450,3 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
GST_DEBUG ("pos query for stream %d: frames %d, bytes %" G_GUINT64_FORMAT,
- stream->num, stream->current_frame, stream->current_byte);
+ stream->num, stream->current_entry, stream->current_total);
@@ -455,9 +455,9 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
/* VBR */
- pos = gst_util_uint64_scale ((gint64) stream->current_frame *
+ pos = gst_util_uint64_scale ((gint64) stream->current_entry *
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));
+ GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos));
} else if (stream->strf.auds->av_bps != 0) {
/* CBR */
- pos = gst_util_uint64_scale (stream->current_byte, GST_SECOND,
+ pos = gst_util_uint64_scale (stream->current_total, GST_SECOND,
(guint64) stream->strf.auds->av_bps);
@@ -465,3 +465,3 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
"CBR convert bytes %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT,
- stream->current_byte, GST_TIME_ARGS (pos));
+ stream->current_total, GST_TIME_ARGS (pos));
} else if (stream->idx_n != 0 && stream->total_bytes != 0) {
@@ -472,11 +472,11 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
if (stream->is_vbr) {
- pos = gst_util_uint64_scale (xlen, stream->current_frame,
+ pos = gst_util_uint64_scale (xlen, stream->current_entry,
stream->idx_n);
GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %"
- GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos));
+ GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos));
} else {
- pos = gst_util_uint64_scale (xlen, stream->current_byte,
+ pos = gst_util_uint64_scale (xlen, stream->current_total,
stream->total_bytes);
GST_DEBUG_OBJECT (avi, "CBR perc convert bytes %" G_GUINT64_FORMAT
- ", time %" GST_TIME_FORMAT, stream->current_byte,
+ ", time %" GST_TIME_FORMAT, stream->current_total,
GST_TIME_ARGS (pos));
@@ -489,6 +489,6 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
if (stream->strh->rate != 0) {
- pos = gst_util_uint64_scale ((guint64) stream->current_frame *
+ pos = gst_util_uint64_scale ((guint64) stream->current_entry *
stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate);
} else {
- pos = stream->current_frame * avi->avih->us_frame * GST_USECOND;
+ pos = stream->current_entry * avi->avih->us_frame * GST_USECOND;
}
@@ -1757,4 +1757,4 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
stream->total_blocks = 0;
- stream->current_frame = 0;
- stream->current_byte = 0;
+ stream->current_entry = 0;
+ stream->current_total = 0;
gst_pad_set_element_private (pad, stream);
@@ -1977,2 +1977,4 @@ gst_avi_demux_index_for_time (GstAviDemux * avi,
}
+ } else {
+ GST_LOG_OBJECT (avi, "converted time to index %u", index);
}
@@ -1983,8 +1985,7 @@ gst_avi_demux_index_for_time (GstAviDemux * avi,
static void
-gst_avi_demux_get_entry_info (GstAviDemux * avi, GstAviStream * stream,
- guint entry_n, GstClockTime * timestamp, GstClockTime * duration,
- guint64 * offset, guint64 * size, gboolean * keyframe)
+gst_avi_demux_get_buffer_info (GstAviDemux * avi, GstAviStream * stream,
+ guint entry_n, GstClockTime * timestamp, GstClockTime * ts_end,
+ guint64 * offset, guint64 * offset_end)
{
GstAviIndexEntry *entry;
- GstClockTime next_ts = 0, ts = 0;
@@ -1995,12 +1996,14 @@ gst_avi_demux_get_entry_info (GstAviDemux * avi, GstAviStream * stream,
if (stream->strh->type == GST_RIFF_FCC_auds) {
- if (timestamp || duration)
- ts = avi_stream_convert_frames_to_time_unchecked (stream, entry->total);
- if (duration)
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
+ if (timestamp)
+ *timestamp =
+ avi_stream_convert_frames_to_time_unchecked (stream, entry->total);
+ if (ts_end)
+ *ts_end = avi_stream_convert_frames_to_time_unchecked (stream,
entry->total + entry->size);
} else {
- if (timestamp || duration)
- ts = avi_stream_convert_frames_to_time_unchecked (stream, entry_n);
- if (duration)
- next_ts = avi_stream_convert_frames_to_time_unchecked (stream,
+ if (timestamp)
+ *timestamp =
+ avi_stream_convert_frames_to_time_unchecked (stream, entry_n);
+ if (ts_end)
+ *ts_end = avi_stream_convert_frames_to_time_unchecked (stream,
entry_n + 1);
@@ -2009,19 +2012,22 @@ gst_avi_demux_get_entry_info (GstAviDemux * avi, GstAviStream * stream,
/* constant rate stream */
- if (timestamp || duration)
- ts = avi_stream_convert_bytes_to_time_unchecked (stream, entry->total);
- if (duration)
- next_ts = avi_stream_convert_bytes_to_time_unchecked (stream,
+ if (timestamp)
+ *timestamp =
+ avi_stream_convert_bytes_to_time_unchecked (stream, entry->total);
+ if (ts_end)
+ *ts_end = avi_stream_convert_bytes_to_time_unchecked (stream,
entry->total + entry->size);
}
- if (timestamp)
- *timestamp = ts;
- if (duration)
- *duration = next_ts - ts;
-
- if (offset)
- *offset = entry->offset;
- if (size)
- *size = entry->size;
- if (keyframe)
- *keyframe = ENTRY_IS_KEYFRAME (entry);
+ if (stream->strh->type == GST_RIFF_FCC_vids) {
+ /* video offsets are the frame number */
+ if (offset)
+ *offset = entry_n;
+ if (offset_end)
+ *offset_end = entry_n + 1;
+ } else {
+ /* no offsets for audio */
+ if (offset)
+ *offset = -1;
+ if (offset_end)
+ *offset_end = -1;
+ }
}
@@ -3855,3 +3861,3 @@ pull_range_failed:
-/* move a stream to an offset */
+/* move a stream to @index */
static void
@@ -3870,2 +3876,4 @@ gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream,
+ /* FIXME, we go back to 0, we should look at segment.start. We will however
+ * stop earlier when the see the timestamp < segment.start */
stream->start_entry = 0;
@@ -3883,2 +3891,4 @@ gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream,
if (stream->current_entry != index) {
+ GST_DEBUG_OBJECT (avi, "Move DISCONT from %u to %u",
+ stream->current_entry, index);
stream->current_entry = index;
@@ -3886,2 +3896,14 @@ gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream,
}
+
+ /* update the buffer info */
+ 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 %u, ts %" GST_TIME_FORMAT
+ ", ts_end %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
+ ", off_end %" G_GUINT64_FORMAT, index,
+ GST_TIME_ARGS (stream->current_timestamp),
+ GST_TIME_ARGS (stream->current_ts_end), stream->current_offset,
+ stream->current_offset_end);
}
@@ -3899,3 +3921,2 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
GstClockTime timestamp, duration;
- gboolean kentry;
@@ -3904,2 +3925,5 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
+ GST_DEBUG_OBJECT (avi, "seek to: %" GST_TIME_FORMAT
+ " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe);
+
/* FIXME, this code assumes the main stream with keyframes is stream 0,
@@ -3910,7 +3934,2 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
index = gst_avi_demux_index_for_time (avi, stream, seek_time);
-
- /* take a look at the entry info */
- gst_avi_demux_get_entry_info (avi, stream, index,
- NULL, NULL, NULL, NULL, &kentry);
-
GST_DEBUG_OBJECT (avi, "Got entry %u", index);
@@ -3918,3 +3937,3 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
/* check if we are already on a keyframe */
- if (!kentry) {
+ if (!ENTRY_IS_KEYFRAME (&stream->index[index])) {
GST_DEBUG_OBJECT (avi, "not keyframe, searching back");
@@ -3927,4 +3946,4 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
/* take a look at the final entry */
- gst_avi_demux_get_entry_info (avi, stream, index,
- &timestamp, &duration, NULL, NULL, NULL);
+ gst_avi_demux_get_buffer_info (avi, stream, index,
+ &timestamp, &duration, NULL, NULL);
@@ -3941,3 +3960,7 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
- /* move the main stream */
+ /* the seek time is also the last_stop and stream time */
+ segment->last_stop = seek_time;
+ segment->time = seek_time;
+
+ /* move the main stream to this position */
gst_avi_demux_move_stream (avi, stream, segment, index);
@@ -3955,16 +3978,9 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
- gst_avi_demux_get_entry_info (avi, ostream, index,
- NULL, NULL, NULL, NULL, &kentry);
- if (!kentry) {
+ if (!ENTRY_IS_KEYFRAME (&ostream->index[index]))
index = gst_avi_demux_index_prev (avi, ostream, index, TRUE);
- }
+
gst_avi_demux_move_stream (avi, ostream, segment, index);
}
-
- GST_DEBUG_OBJECT (avi, "seek: %" GST_TIME_FORMAT
- " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe);
-
- /* the seek time is also the last_stop and stream time */
- segment->last_stop = seek_time;
- segment->time = seek_time;
+ GST_DEBUG_OBJECT (avi, "done seek to: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (seek_time));
@@ -4444,10 +4460,10 @@ gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream,
{
- guint i;
+ guint old_entry, new_entry;
- /* move to the next entry */
- stream->current_entry++;
- stream->current_frame++;
+ old_entry = stream->current_entry;
+ /* move forwards */
+ new_entry = old_entry + 1;
/* see if we reached the end */
- if (stream->current_entry >= stream->stop_entry) {
+ if (new_entry >= stream->stop_entry) {
if (avi->segment.rate < 0.0) {
@@ -4462,3 +4478,2 @@ gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream,
stream->stop_entry, TRUE);
- stream->current_entry = stream->step_entry;
@@ -4468,7 +4483,4 @@ gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream,
- /* mark DISCONT */
- for (i = 0; i < avi->num_streams; i++) {
- avi->stream[i].last_flow = GST_FLOW_OK;
- avi->stream[i].discont = TRUE;
- }
+ /* and start from the previous keyframe now */
+ new_entry = stream->step_entry;
} else {
@@ -4479,2 +4491,27 @@ gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream,
}
+
+ if (new_entry != old_entry) {
+ stream->current_entry = new_entry;
+ stream->current_total = stream->index[new_entry].total;
+
+ if (new_entry == old_entry + 1) {
+ GST_DEBUG_OBJECT (avi, "moved forwards from %u to %u",
+ old_entry, new_entry);
+ /* we simply moved one step forwards, reuse current info */
+ stream->current_timestamp = stream->current_ts_end;
+ stream->current_offset = stream->current_offset_end;
+ gst_avi_demux_get_buffer_info (avi, stream, new_entry,
+ NULL, &stream->current_ts_end, NULL, &stream->current_offset_end);
+ } else {
+ GST_DEBUG_OBJECT (avi, "DISCONT move from %u to %u", old_entry,
+ new_entry);
+ /* we moved DISCONT, full update */
+ gst_avi_demux_get_buffer_info (avi, stream, new_entry,
+ &stream->current_timestamp, &stream->current_ts_end,
+ &stream->current_offset, &stream->current_offset_end);
+ /* and MARK discont for this stream */
+ stream->last_flow = GST_FLOW_OK;
+ stream->discont = TRUE;
+ }
+ }
return ret;
@@ -4485,4 +4522,4 @@ eos:
GST_DEBUG_OBJECT (avi, "we are EOS");
- /* setting current_time to -1 marks EOS */
- stream->current_time = -1;
+ /* setting current_timestamp to -1 marks EOS */
+ stream->current_timestamp = -1;
return GST_FLOW_UNEXPECTED;
@@ -4495,4 +4532,4 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
GstFlowReturn ret = GST_FLOW_OK;
- guint64 min_time;
guint stream_num, i;
+ guint64 min_time;
GstAviStream *stream;
@@ -4502,8 +4539,10 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
GstClockTime timestamp, duration;
+ guint64 out_offset, out_offset_end;
gboolean keyframe;
+ GstAviIndexEntry *entry;
do {
+ min_time = G_MAXUINT64;
/* first find the stream with the lowest current position, this is the one
* we should push from next */
- min_time = G_MAXUINT64;
stream_num = -1;
@@ -4513,3 +4552,3 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
stream = &avi->stream[i];
- position = stream->current_time;
+ position = stream->current_timestamp;
@@ -4539,4 +4578,12 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
/* get the timing info for the entry */
- gst_avi_demux_get_entry_info (avi, stream, stream->current_entry,
- &timestamp, &duration, &offset, &size, &keyframe);
+ timestamp = stream->current_timestamp;
+ duration = stream->current_ts_end - timestamp;
+ out_offset = stream->current_offset;
+ out_offset_end = stream->current_offset_end;
+
+ /* get the entry data info */
+ entry = &stream->index[stream->current_entry];
+ offset = entry->offset;
+ size = entry->size;
+ keyframe = ENTRY_IS_KEYFRAME (entry);
@@ -4544,3 +4591,3 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
if (size == 0) {
- GST_DEBUG_OBJECT (avi, "Skipping entry %d (%d, %p)",
+ GST_DEBUG_OBJECT (avi, "Skipping entry %u (%u, %p)",
stream->current_entry, size, stream->pad);
@@ -4551,4 +4598,3 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
/* only check this for fowards playback for now */
- if (keyframe && GST_CLOCK_TIME_IS_VALID (timestamp)
- && GST_CLOCK_TIME_IS_VALID (avi->segment.stop)
+ if (keyframe && GST_CLOCK_TIME_IS_VALID (avi->segment.stop)
&& (timestamp > avi->segment.stop)) {
@@ -4582,4 +4628,4 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
GST_BUFFER_DURATION (buf) = duration;
- GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
- GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
+ GST_BUFFER_OFFSET (buf) = out_offset;
+ GST_BUFFER_OFFSET_END (buf) = out_offset_end;
@@ -4587,7 +4633,8 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
- GST_DEBUG_OBJECT (avi, "Pushing buffer of size %d, offset %"
- G_GUINT64_FORMAT " and time %"
- GST_TIME_FORMAT " on pad %s",
- GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf),
- GST_TIME_ARGS (timestamp), GST_PAD_NAME (stream->pad));
+ GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
+ GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
+ ", off_end %" G_GUINT64_FORMAT " on pad %s",
+ GST_BUFFER_SIZE (buf), GST_TIME_ARGS (timestamp),
+ GST_TIME_ARGS (duration), GST_BUFFER_OFFSET (buf),
+ GST_BUFFER_OFFSET_END (buf), GST_PAD_NAME (stream->pad));
@@ -4607,3 +4654,3 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
processed = TRUE;
- GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", stream->current_entry,
+ GST_DEBUG_OBJECT (avi, "Processed buffer %u: %s", stream->current_entry,
gst_flow_get_name (ret));
@@ -4620,2 +4667,3 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
next:
+ /* move to next item */
ret = gst_avi_demux_advance (avi, stream, ret);
@@ -4793,4 +4841,4 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
- stream->current_frame++;
- stream->current_byte += size;
+ stream->current_entry++;
+ stream->current_total += size;
@@ -4805,6 +4853,9 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
- if (stream->strh->type == GST_RIFF_FCC_vids)
- GST_BUFFER_OFFSET (buf) = stream->current_frame - 1;
- else
+ if (stream->strh->type == GST_RIFF_FCC_vids) {
+ GST_BUFFER_OFFSET (buf) = stream->current_entry - 1;
+ GST_BUFFER_OFFSET_END (buf) = stream->current_entry;
+ } else {
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
+ GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
+ }
diff --git a/gst/avi/gstavidemux.h b/gst/avi/gstavidemux.h
index 93fb432ab..ff4235ff9 100644
--- a/gst/avi/gstavidemux.h
+++ b/gst/avi/gstavidemux.h
@@ -85,7 +85,11 @@ typedef struct {
guint stop_entry;
- /* current position (byte, frame, time) and other status vars */
+
+ /* current index entry */
guint current_entry;
- guint current_frame;
- guint64 current_byte;
- guint64 current_time;
+ /* position (byte, frame, time) for current_entry */
+ guint current_total;
+ GstClockTime current_timestamp;
+ GstClockTime current_ts_end;
+ guint64 current_offset;
+ guint64 current_offset_end;