avi: fix prev keyframe search and cleanups

This commit is contained in:
Wim Taymans 2009-09-22 17:42:48 +02:00 committed by Wim Taymans
parent 1b325945e5
commit 3338f91cfe

View file

@ -1885,7 +1885,7 @@ gst_avi_demux_index_prev (GstAviDemux * avi, GstAviStream * stream,
for (i = last; i > 0; i--) { for (i = last; i > 0; i--) {
entry = &stream->index[i - 1]; entry = &stream->index[i - 1];
if (!keyframe || ENTRY_IS_KEYFRAME (entry)) { if (!keyframe || ENTRY_IS_KEYFRAME (entry)) {
return i; return i - 1;
} }
} }
return 0; return 0;
@ -2158,7 +2158,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
} }
GST_LOG_OBJECT (avi, GST_LOG_OBJECT (avi,
"Adding stream %d, index entry %d, kf %d, size %u " "Adding stream %u, index entry %d, kf %d, size %u "
", offset %" G_GUINT64_FORMAT ", total %" G_GUINT64_FORMAT, stream_nr, ", offset %" G_GUINT64_FORMAT ", total %" G_GUINT64_FORMAT, stream_nr,
stream->idx_n, ENTRY_IS_KEYFRAME (&entry), entry.size, entry.offset, stream->idx_n, ENTRY_IS_KEYFRAME (&entry), entry.size, entry.offset,
entry.total); entry.total);
@ -2203,7 +2203,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
total_max += stream->idx_max; total_max += stream->idx_max;
#endif #endif
GST_INFO_OBJECT (avi, "Stream %d, dur %" GST_TIME_FORMAT ", %6u entries, " GST_INFO_OBJECT (avi, "Stream %d, dur %" GST_TIME_FORMAT ", %6u entries, "
"%5lu keyframes, entry size = %2u, total size = %10u, allocated %10u", "%5u keyframes, entry size = %2u, total size = %10u, allocated %10u",
i, GST_TIME_ARGS (stream->idx_duration), stream->idx_n, i, GST_TIME_ARGS (stream->idx_duration), stream->idx_n,
stream->n_keyframes, (guint) sizeof (GstAviIndexEntry), stream->n_keyframes, (guint) sizeof (GstAviIndexEntry),
(guint) (stream->idx_n * sizeof (GstAviIndexEntry)), (guint) (stream->idx_n * sizeof (GstAviIndexEntry)),
@ -3048,7 +3048,8 @@ gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
} }
/* returns FALSE if there are no pads to deliver event to, /* returns FALSE if there are no pads to deliver event to,
* otherwise TRUE (whatever the outcome of event sending) */ * otherwise TRUE (whatever the outcome of event sending),
* takes ownership of the event. */
static gboolean static gboolean
gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event) gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event)
{ {
@ -3058,14 +3059,12 @@ gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event)
GST_DEBUG_OBJECT (avi, "sending %s event to %d streams", GST_DEBUG_OBJECT (avi, "sending %s event to %d streams",
GST_EVENT_TYPE_NAME (event), avi->num_streams); GST_EVENT_TYPE_NAME (event), avi->num_streams);
if (avi->num_streams) { for (i = 0; i < avi->num_streams; i++) {
for (i = 0; i < avi->num_streams; i++) { GstAviStream *stream = &avi->stream[i];
GstAviStream *stream = &avi->stream[i];
if (stream->pad) { if (stream->pad) {
result = TRUE; result = TRUE;
gst_pad_push_event (stream->pad, gst_event_ref (event)); gst_pad_push_event (stream->pad, gst_event_ref (event));
}
} }
} }
gst_event_unref (event); gst_event_unref (event);
@ -3735,7 +3734,6 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
gboolean keyframe; gboolean keyframe;
guint i, index; guint i, index;
GstAviStream *stream; GstAviStream *stream;
GstClockTime timestamp, duration;
seek_time = segment->last_stop; seek_time = segment->last_stop;
keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT); keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
@ -3760,28 +3758,21 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
GST_DEBUG_OBJECT (avi, "previous keyframe at %u", index); GST_DEBUG_OBJECT (avi, "previous keyframe at %u", index);
} }
/* take a look at the final entry */ /* move the main stream to this position */
gst_avi_demux_get_buffer_info (avi, stream, index, gst_avi_demux_move_stream (avi, stream, segment, index);
&timestamp, &duration, NULL, NULL);
GST_DEBUG_OBJECT (avi,
"Got keyframe entry %d [ts:%" GST_TIME_FORMAT
" / duration:%" GST_TIME_FORMAT "]", index,
GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
if (keyframe) { if (keyframe) {
/* when seeking to a keyframe, we update the result seek time /* when seeking to a keyframe, we update the result seek time
* to the time of the keyframe. */ * to the time of the keyframe. */
seek_time = timestamp; seek_time = stream->current_timestamp;
GST_DEBUG_OBJECT (avi, "keyframe adjusted to %" GST_TIME_FORMAT,
GST_TIME_ARGS (seek_time));
} }
/* the seek time is also the last_stop and stream time */ /* the seek time is also the last_stop and stream time */
segment->last_stop = seek_time; segment->last_stop = seek_time;
segment->time = seek_time; segment->time = seek_time;
/* move the main stream to this position */
gst_avi_demux_move_stream (avi, stream, segment, index);
/* now set DISCONT and align the other streams */ /* now set DISCONT and align the other streams */
for (i = 0; i < avi->num_streams; i++) { for (i = 0; i < avi->num_streams; i++) {
GstAviStream *ostream; GstAviStream *ostream;
@ -3887,11 +3878,13 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
gst_avi_demux_do_seek (avi, &seeksegment); gst_avi_demux_do_seek (avi, &seeksegment);
if (flush) { if (flush) {
GstEvent *event = gst_event_new_flush_stop ();
gint i; gint i;
GST_DEBUG_OBJECT (avi, "sending flush stop"); GST_DEBUG_OBJECT (avi, "sending flush stop");
gst_avi_demux_push_event (avi, gst_event_new_flush_stop ()); gst_avi_demux_push_event (avi, gst_event_ref (event));
gst_pad_push_event (avi->sinkpad, gst_event_new_flush_stop ()); gst_pad_push_event (avi->sinkpad, event);
/* reset the last flow and mark discont, FLUSH is always DISCONT */ /* reset the last flow and mark discont, FLUSH is always DISCONT */
for (i = 0; i < avi->num_streams; i++) { for (i = 0; i < avi->num_streams; i++) {
avi->stream[i].last_flow = GST_FLOW_OK; avi->stream[i].last_flow = GST_FLOW_OK;
@ -3928,13 +3921,15 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
if (avi->seek_event) if (avi->seek_event)
gst_event_unref (avi->seek_event); gst_event_unref (avi->seek_event);
if (avi->segment.rate > 0.0) { if (avi->segment.rate > 0.0) {
/* forwards goes from last_stop to stop */
avi->seek_event = gst_event_new_new_segment (FALSE, avi->seek_event = gst_event_new_new_segment (FALSE,
avi->segment.rate, avi->segment.format, avi->segment.rate, avi->segment.format,
avi->segment.last_stop, stop, avi->segment.time); avi->segment.last_stop, stop, avi->segment.time);
} else { } else {
/* reverse goes from start to last_stop */
avi->seek_event = gst_event_new_new_segment (FALSE, avi->seek_event = gst_event_new_new_segment (FALSE,
avi->segment.rate, avi->segment.format, avi->segment.rate, avi->segment.format,
avi->segment.start, avi->segment.last_stop, avi->segment.start); avi->segment.start, avi->segment.last_stop, avi->segment.time);
} }
if (!avi->streaming) { if (!avi->streaming) {
@ -4210,8 +4205,9 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
/* correct for index offset */ /* correct for index offset */
offset += avi->index_offset + 8; offset += avi->index_offset + 8;
GST_LOG ("reading buffer (size=%d) from stream %d at current pos %" GST_LOG ("reading buffer (size=%d), stream %d, pos %"
G_GUINT64_FORMAT " (%llx)", size, stream_num, offset, offset); G_GUINT64_FORMAT " (%llx), kf %d", size, stream_num, offset,
offset, keyframe);
/* pull in the data */ /* pull in the data */
ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf); ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf);
@ -4226,7 +4222,9 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
buf = gst_avi_demux_invert (stream, buf); buf = gst_avi_demux_invert (stream, buf);
/* mark non-keyframes */ /* mark non-keyframes */
if (!keyframe) if (keyframe)
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
else
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
GST_BUFFER_TIMESTAMP (buf) = timestamp; GST_BUFFER_TIMESTAMP (buf) = timestamp;
@ -4234,6 +4232,12 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
GST_BUFFER_OFFSET (buf) = out_offset; GST_BUFFER_OFFSET (buf) = out_offset;
GST_BUFFER_OFFSET_END (buf) = out_offset_end; GST_BUFFER_OFFSET_END (buf) = out_offset_end;
/* mark discont when pending */
if (stream->discont) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
stream->discont = FALSE;
}
gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %" GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
@ -4246,12 +4250,6 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
/* update current position in the segment */ /* update current position in the segment */
gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp); gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp);
/* mark discont when pending */
if (stream->discont) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
stream->discont = FALSE;
}
ret = gst_pad_push (stream->pad, buf); ret = gst_pad_push (stream->pad, buf);
/* mark as processed, we increment the frame and byte counters then /* mark as processed, we increment the frame and byte counters then