summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-09-22 17:42:48 +0200
committerWim Taymans <wim@metal.(none)>2009-09-28 22:16:53 +0200
commit3338f91cfeb1bc2fc109766f15d1fe19e2475216 (patch)
treecd1bc9ba6ea78fa642dce9ff7547e7d1a88f67c7
parent1b325945e579cc9ed32953ab1f2d036e61c68de7 (diff)
avi: fix prev keyframe search and cleanups
-rw-r--r--gst/avi/gstavidemux.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 3233c5bd3..c6ee30bec 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -1885,7 +1885,7 @@ gst_avi_demux_index_prev (GstAviDemux * avi, GstAviStream * stream,
1885 for (i = last; i > 0; i--) { 1885 for (i = last; i > 0; i--) {
1886 entry = &stream->index[i - 1]; 1886 entry = &stream->index[i - 1];
1887 if (!keyframe || ENTRY_IS_KEYFRAME (entry)) { 1887 if (!keyframe || ENTRY_IS_KEYFRAME (entry)) {
1888 return i; 1888 return i - 1;
1889 } 1889 }
1890 } 1890 }
1891 return 0; 1891 return 0;
@@ -2158,7 +2158,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
2158 } 2158 }
2159 2159
2160 GST_LOG_OBJECT (avi, 2160 GST_LOG_OBJECT (avi,
2161 "Adding stream %d, index entry %d, kf %d, size %u " 2161 "Adding stream %u, index entry %d, kf %d, size %u "
2162 ", offset %" G_GUINT64_FORMAT ", total %" G_GUINT64_FORMAT, stream_nr, 2162 ", offset %" G_GUINT64_FORMAT ", total %" G_GUINT64_FORMAT, stream_nr,
2163 stream->idx_n, ENTRY_IS_KEYFRAME (&entry), entry.size, entry.offset, 2163 stream->idx_n, ENTRY_IS_KEYFRAME (&entry), entry.size, entry.offset,
2164 entry.total); 2164 entry.total);
@@ -2203,7 +2203,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
2203 total_max += stream->idx_max; 2203 total_max += stream->idx_max;
2204#endif 2204#endif
2205 GST_INFO_OBJECT (avi, "Stream %d, dur %" GST_TIME_FORMAT ", %6u entries, " 2205 GST_INFO_OBJECT (avi, "Stream %d, dur %" GST_TIME_FORMAT ", %6u entries, "
2206 "%5lu keyframes, entry size = %2u, total size = %10u, allocated %10u", 2206 "%5u keyframes, entry size = %2u, total size = %10u, allocated %10u",
2207 i, GST_TIME_ARGS (stream->idx_duration), stream->idx_n, 2207 i, GST_TIME_ARGS (stream->idx_duration), stream->idx_n,
2208 stream->n_keyframes, (guint) sizeof (GstAviIndexEntry), 2208 stream->n_keyframes, (guint) sizeof (GstAviIndexEntry),
2209 (guint) (stream->idx_n * sizeof (GstAviIndexEntry)), 2209 (guint) (stream->idx_n * sizeof (GstAviIndexEntry)),
@@ -3048,7 +3048,8 @@ gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
3048} 3048}
3049 3049
3050/* returns FALSE if there are no pads to deliver event to, 3050/* returns FALSE if there are no pads to deliver event to,
3051 * otherwise TRUE (whatever the outcome of event sending) */ 3051 * otherwise TRUE (whatever the outcome of event sending),
3052 * takes ownership of the event. */
3052static gboolean 3053static gboolean
3053gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event) 3054gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event)
3054{ 3055{
@@ -3058,14 +3059,12 @@ gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event)
3058 GST_DEBUG_OBJECT (avi, "sending %s event to %d streams", 3059 GST_DEBUG_OBJECT (avi, "sending %s event to %d streams",
3059 GST_EVENT_TYPE_NAME (event), avi->num_streams); 3060 GST_EVENT_TYPE_NAME (event), avi->num_streams);
3060 3061
3061 if (avi->num_streams) { 3062 for (i = 0; i < avi->num_streams; i++) {
3062 for (i = 0; i < avi->num_streams; i++) { 3063 GstAviStream *stream = &avi->stream[i];
3063 GstAviStream *stream = &avi->stream[i];
3064 3064
3065 if (stream->pad) { 3065 if (stream->pad) {
3066 result = TRUE; 3066 result = TRUE;
3067 gst_pad_push_event (stream->pad, gst_event_ref (event)); 3067 gst_pad_push_event (stream->pad, gst_event_ref (event));
3068 }
3069 } 3068 }
3070 } 3069 }
3071 gst_event_unref (event); 3070 gst_event_unref (event);
@@ -3735,7 +3734,6 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
3735 gboolean keyframe; 3734 gboolean keyframe;
3736 guint i, index; 3735 guint i, index;
3737 GstAviStream *stream; 3736 GstAviStream *stream;
3738 GstClockTime timestamp, duration;
3739 3737
3740 seek_time = segment->last_stop; 3738 seek_time = segment->last_stop;
3741 keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT); 3739 keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
@@ -3760,28 +3758,21 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
3760 GST_DEBUG_OBJECT (avi, "previous keyframe at %u", index); 3758 GST_DEBUG_OBJECT (avi, "previous keyframe at %u", index);
3761 } 3759 }
3762 3760
3763 /* take a look at the final entry */ 3761 /* move the main stream to this position */
3764 gst_avi_demux_get_buffer_info (avi, stream, index, 3762 gst_avi_demux_move_stream (avi, stream, segment, index);
3765 &timestamp, &duration, NULL, NULL);
3766
3767 GST_DEBUG_OBJECT (avi,
3768 "Got keyframe entry %d [ts:%" GST_TIME_FORMAT
3769 " / duration:%" GST_TIME_FORMAT "]", index,
3770 GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
3771 3763
3772 if (keyframe) { 3764 if (keyframe) {
3773 /* when seeking to a keyframe, we update the result seek time 3765 /* when seeking to a keyframe, we update the result seek time
3774 * to the time of the keyframe. */ 3766 * to the time of the keyframe. */
3775 seek_time = timestamp; 3767 seek_time = stream->current_timestamp;
3768 GST_DEBUG_OBJECT (avi, "keyframe adjusted to %" GST_TIME_FORMAT,
3769 GST_TIME_ARGS (seek_time));
3776 } 3770 }
3777 3771
3778 /* the seek time is also the last_stop and stream time */ 3772 /* the seek time is also the last_stop and stream time */
3779 segment->last_stop = seek_time; 3773 segment->last_stop = seek_time;
3780 segment->time = seek_time; 3774 segment->time = seek_time;
3781 3775
3782 /* move the main stream to this position */
3783 gst_avi_demux_move_stream (avi, stream, segment, index);
3784
3785 /* now set DISCONT and align the other streams */ 3776 /* now set DISCONT and align the other streams */
3786 for (i = 0; i < avi->num_streams; i++) { 3777 for (i = 0; i < avi->num_streams; i++) {
3787 GstAviStream *ostream; 3778 GstAviStream *ostream;
@@ -3887,11 +3878,13 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
3887 gst_avi_demux_do_seek (avi, &seeksegment); 3878 gst_avi_demux_do_seek (avi, &seeksegment);
3888 3879
3889 if (flush) { 3880 if (flush) {
3881 GstEvent *event = gst_event_new_flush_stop ();
3890 gint i; 3882 gint i;
3891 3883
3892 GST_DEBUG_OBJECT (avi, "sending flush stop"); 3884 GST_DEBUG_OBJECT (avi, "sending flush stop");
3893 gst_avi_demux_push_event (avi, gst_event_new_flush_stop ()); 3885 gst_avi_demux_push_event (avi, gst_event_ref (event));
3894 gst_pad_push_event (avi->sinkpad, gst_event_new_flush_stop ()); 3886 gst_pad_push_event (avi->sinkpad, event);
3887
3895 /* reset the last flow and mark discont, FLUSH is always DISCONT */ 3888 /* reset the last flow and mark discont, FLUSH is always DISCONT */
3896 for (i = 0; i < avi->num_streams; i++) { 3889 for (i = 0; i < avi->num_streams; i++) {
3897 avi->stream[i].last_flow = GST_FLOW_OK; 3890 avi->stream[i].last_flow = GST_FLOW_OK;
@@ -3928,13 +3921,15 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
3928 if (avi->seek_event) 3921 if (avi->seek_event)
3929 gst_event_unref (avi->seek_event); 3922 gst_event_unref (avi->seek_event);
3930 if (avi->segment.rate > 0.0) { 3923 if (avi->segment.rate > 0.0) {
3924 /* forwards goes from last_stop to stop */
3931 avi->seek_event = gst_event_new_new_segment (FALSE, 3925 avi->seek_event = gst_event_new_new_segment (FALSE,
3932 avi->segment.rate, avi->segment.format, 3926 avi->segment.rate, avi->segment.format,
3933 avi->segment.last_stop, stop, avi->segment.time); 3927 avi->segment.last_stop, stop, avi->segment.time);
3934 } else { 3928 } else {
3929 /* reverse goes from start to last_stop */
3935 avi->seek_event = gst_event_new_new_segment (FALSE, 3930 avi->seek_event = gst_event_new_new_segment (FALSE,
3936 avi->segment.rate, avi->segment.format, 3931 avi->segment.rate, avi->segment.format,
3937 avi->segment.start, avi->segment.last_stop, avi->segment.start); 3932 avi->segment.start, avi->segment.last_stop, avi->segment.time);
3938 } 3933 }
3939 3934
3940 if (!avi->streaming) { 3935 if (!avi->streaming) {
@@ -4210,8 +4205,9 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
4210 /* correct for index offset */ 4205 /* correct for index offset */
4211 offset += avi->index_offset + 8; 4206 offset += avi->index_offset + 8;
4212 4207
4213 GST_LOG ("reading buffer (size=%d) from stream %d at current pos %" 4208 GST_LOG ("reading buffer (size=%d), stream %d, pos %"
4214 G_GUINT64_FORMAT " (%llx)", size, stream_num, offset, offset); 4209 G_GUINT64_FORMAT " (%llx), kf %d", size, stream_num, offset,
4210 offset, keyframe);
4215 4211
4216 /* pull in the data */ 4212 /* pull in the data */
4217 ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf); 4213 ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf);
@@ -4226,7 +4222,9 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
4226 buf = gst_avi_demux_invert (stream, buf); 4222 buf = gst_avi_demux_invert (stream, buf);
4227 4223
4228 /* mark non-keyframes */ 4224 /* mark non-keyframes */
4229 if (!keyframe) 4225 if (keyframe)
4226 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
4227 else
4230 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); 4228 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
4231 4229
4232 GST_BUFFER_TIMESTAMP (buf) = timestamp; 4230 GST_BUFFER_TIMESTAMP (buf) = timestamp;
@@ -4234,6 +4232,12 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
4234 GST_BUFFER_OFFSET (buf) = out_offset; 4232 GST_BUFFER_OFFSET (buf) = out_offset;
4235 GST_BUFFER_OFFSET_END (buf) = out_offset_end; 4233 GST_BUFFER_OFFSET_END (buf) = out_offset_end;
4236 4234
4235 /* mark discont when pending */
4236 if (stream->discont) {
4237 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
4238 stream->discont = FALSE;
4239 }
4240
4237 gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); 4241 gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
4238 4242
4239 GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %" 4243 GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
@@ -4246,12 +4250,6 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
4246 /* update current position in the segment */ 4250 /* update current position in the segment */
4247 gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp); 4251 gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp);
4248 4252
4249 /* mark discont when pending */
4250 if (stream->discont) {
4251 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
4252 stream->discont = FALSE;
4253 }
4254
4255 ret = gst_pad_push (stream->pad, buf); 4253 ret = gst_pad_push (stream->pad, buf);
4256 4254
4257 /* mark as processed, we increment the frame and byte counters then 4255 /* mark as processed, we increment the frame and byte counters then