diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-09-22 17:42:48 +0200 |
---|---|---|
committer | Wim Taymans <wim@metal.(none)> | 2009-09-28 22:16:53 +0200 |
commit | 3338f91cfeb1bc2fc109766f15d1fe19e2475216 (patch) | |
tree | cd1bc9ba6ea78fa642dce9ff7547e7d1a88f67c7 | |
parent | 1b325945e579cc9ed32953ab1f2d036e61c68de7 (diff) |
avi: fix prev keyframe search and cleanups
-rw-r--r-- | gst/avi/gstavidemux.c | 70 |
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. */ | ||
3052 | static gboolean | 3053 | static gboolean |
3053 | gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event) | 3054 | gst_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 | ×tamp, &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 |