diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-09-22 14:44:42 +0200 |
---|---|---|
committer | Wim Taymans <wim@metal.(none)> | 2009-09-28 22:16:48 +0200 |
commit | c199b1d039c1f8673829d6465b08de7a537658ca (patch) | |
tree | 474caa5ce387998ddb238f08e2494b8b8b10676e | |
parent | 0d70fe30a8fad452627e2f6c9402bacc4506bc39 (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.c | 243 | ||||
-rw-r--r-- | gst/avi/gstavidemux.h | 12 |
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, - ×tamp, &duration, NULL, NULL, NULL); + gst_avi_demux_get_buffer_info (avi, stream, index, + ×tamp, &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, - ×tamp, &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; |