diff options
Diffstat (limited to 'gst/avi/gstavidemux.c')
-rw-r--r-- | gst/avi/gstavidemux.c | 243 |
1 files changed, 147 insertions, 96 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 | |||
@@ -448,37 +448,37 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query) | |||
448 | gint64 pos = 0; | 448 | gint64 pos = 0; |
449 | 449 | ||
450 | GST_DEBUG ("pos query for stream %d: frames %d, bytes %" G_GUINT64_FORMAT, | 450 | GST_DEBUG ("pos query for stream %d: frames %d, bytes %" G_GUINT64_FORMAT, |
451 | stream->num, stream->current_frame, stream->current_byte); | 451 | stream->num, stream->current_entry, stream->current_total); |
452 | 452 | ||
453 | if (stream->strh->type == GST_RIFF_FCC_auds) { | 453 | if (stream->strh->type == GST_RIFF_FCC_auds) { |
454 | if (stream->is_vbr) { | 454 | if (stream->is_vbr) { |
455 | /* VBR */ | 455 | /* VBR */ |
456 | pos = gst_util_uint64_scale ((gint64) stream->current_frame * | 456 | pos = gst_util_uint64_scale ((gint64) stream->current_entry * |
457 | stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate); | 457 | stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate); |
458 | GST_DEBUG_OBJECT (avi, "VBR convert frame %u, time %" | 458 | GST_DEBUG_OBJECT (avi, "VBR convert frame %u, time %" |
459 | GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos)); | 459 | GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos)); |
460 | } else if (stream->strf.auds->av_bps != 0) { | 460 | } else if (stream->strf.auds->av_bps != 0) { |
461 | /* CBR */ | 461 | /* CBR */ |
462 | pos = gst_util_uint64_scale (stream->current_byte, GST_SECOND, | 462 | pos = gst_util_uint64_scale (stream->current_total, GST_SECOND, |
463 | (guint64) stream->strf.auds->av_bps); | 463 | (guint64) stream->strf.auds->av_bps); |
464 | GST_DEBUG_OBJECT (avi, | 464 | GST_DEBUG_OBJECT (avi, |
465 | "CBR convert bytes %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT, | 465 | "CBR convert bytes %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT, |
466 | stream->current_byte, GST_TIME_ARGS (pos)); | 466 | stream->current_total, GST_TIME_ARGS (pos)); |
467 | } else if (stream->idx_n != 0 && stream->total_bytes != 0) { | 467 | } else if (stream->idx_n != 0 && stream->total_bytes != 0) { |
468 | /* calculate timestamps based on percentage of length */ | 468 | /* calculate timestamps based on percentage of length */ |
469 | guint64 xlen = avi->avih->us_frame * | 469 | guint64 xlen = avi->avih->us_frame * |
470 | avi->avih->tot_frames * GST_USECOND; | 470 | avi->avih->tot_frames * GST_USECOND; |
471 | 471 | ||
472 | if (stream->is_vbr) { | 472 | if (stream->is_vbr) { |
473 | pos = gst_util_uint64_scale (xlen, stream->current_frame, | 473 | pos = gst_util_uint64_scale (xlen, stream->current_entry, |
474 | stream->idx_n); | 474 | stream->idx_n); |
475 | GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %" | 475 | GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %" |
476 | GST_TIME_FORMAT, stream->current_frame, GST_TIME_ARGS (pos)); | 476 | GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos)); |
477 | } else { | 477 | } else { |
478 | pos = gst_util_uint64_scale (xlen, stream->current_byte, | 478 | pos = gst_util_uint64_scale (xlen, stream->current_total, |
479 | stream->total_bytes); | 479 | stream->total_bytes); |
480 | GST_DEBUG_OBJECT (avi, "CBR perc convert bytes %" G_GUINT64_FORMAT | 480 | GST_DEBUG_OBJECT (avi, "CBR perc convert bytes %" G_GUINT64_FORMAT |
481 | ", time %" GST_TIME_FORMAT, stream->current_byte, | 481 | ", time %" GST_TIME_FORMAT, stream->current_total, |
482 | GST_TIME_ARGS (pos)); | 482 | GST_TIME_ARGS (pos)); |
483 | } | 483 | } |
484 | } else { | 484 | } else { |
@@ -487,10 +487,10 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query) | |||
487 | } | 487 | } |
488 | } else { | 488 | } else { |
489 | if (stream->strh->rate != 0) { | 489 | if (stream->strh->rate != 0) { |
490 | pos = gst_util_uint64_scale ((guint64) stream->current_frame * | 490 | pos = gst_util_uint64_scale ((guint64) stream->current_entry * |
491 | stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate); | 491 | stream->strh->scale, GST_SECOND, (guint64) stream->strh->rate); |
492 | } else { | 492 | } else { |
493 | pos = stream->current_frame * avi->avih->us_frame * GST_USECOND; | 493 | pos = stream->current_entry * avi->avih->us_frame * GST_USECOND; |
494 | } | 494 | } |
495 | } | 495 | } |
496 | if (res) { | 496 | if (res) { |
@@ -1755,8 +1755,8 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf) | |||
1755 | stream->total_bytes = 0; | 1755 | stream->total_bytes = 0; |
1756 | stream->idx_n = 0; | 1756 | stream->idx_n = 0; |
1757 | stream->total_blocks = 0; | 1757 | stream->total_blocks = 0; |
1758 | stream->current_frame = 0; | 1758 | stream->current_entry = 0; |
1759 | stream->current_byte = 0; | 1759 | stream->current_total = 0; |
1760 | gst_pad_set_element_private (pad, stream); | 1760 | gst_pad_set_element_private (pad, stream); |
1761 | avi->num_streams++; | 1761 | avi->num_streams++; |
1762 | gst_pad_set_caps (pad, caps); | 1762 | gst_pad_set_caps (pad, caps); |
@@ -1975,55 +1975,61 @@ gst_avi_demux_index_for_time (GstAviDemux * avi, | |||
1975 | index = entry - stream->index; | 1975 | index = entry - stream->index; |
1976 | GST_LOG_OBJECT (avi, "found at %u", index); | 1976 | GST_LOG_OBJECT (avi, "found at %u", index); |
1977 | } | 1977 | } |
1978 | } else { | ||
1979 | GST_LOG_OBJECT (avi, "converted time to index %u", index); | ||
1978 | } | 1980 | } |
1979 | 1981 | ||
1980 | return index; | 1982 | return index; |
1981 | } | 1983 | } |
1982 | 1984 | ||
1983 | static void | 1985 | static void |
1984 | gst_avi_demux_get_entry_info (GstAviDemux * avi, GstAviStream * stream, | 1986 | gst_avi_demux_get_buffer_info (GstAviDemux * avi, GstAviStream * stream, |
1985 | guint entry_n, GstClockTime * timestamp, GstClockTime * duration, | 1987 | guint entry_n, GstClockTime * timestamp, GstClockTime * ts_end, |
1986 | guint64 * offset, guint64 * size, gboolean * keyframe) | 1988 | guint64 * offset, guint64 * offset_end) |
1987 | { | 1989 | { |
1988 | GstAviIndexEntry *entry; | 1990 | GstAviIndexEntry *entry; |
1989 | GstClockTime next_ts = 0, ts = 0; | ||
1990 | 1991 | ||
1991 | entry = &stream->index[entry_n]; | 1992 | entry = &stream->index[entry_n]; |
1992 | 1993 | ||
1993 | if (stream->is_vbr) { | 1994 | if (stream->is_vbr) { |
1994 | /* VBR stream next timestamp */ | 1995 | /* VBR stream next timestamp */ |
1995 | if (stream->strh->type == GST_RIFF_FCC_auds) { | 1996 | if (stream->strh->type == GST_RIFF_FCC_auds) { |
1996 | if (timestamp || duration) | 1997 | if (timestamp) |
1997 | ts = avi_stream_convert_frames_to_time_unchecked (stream, entry->total); | 1998 | *timestamp = |
1998 | if (duration) | 1999 | avi_stream_convert_frames_to_time_unchecked (stream, entry->total); |
1999 | next_ts = avi_stream_convert_frames_to_time_unchecked (stream, | 2000 | if (ts_end) |
2001 | *ts_end = avi_stream_convert_frames_to_time_unchecked (stream, | ||
2000 | entry->total + entry->size); | 2002 | entry->total + entry->size); |
2001 | } else { | 2003 | } else { |
2002 | if (timestamp || duration) | 2004 | if (timestamp) |
2003 | ts = avi_stream_convert_frames_to_time_unchecked (stream, entry_n); | 2005 | *timestamp = |
2004 | if (duration) | 2006 | avi_stream_convert_frames_to_time_unchecked (stream, entry_n); |
2005 | next_ts = avi_stream_convert_frames_to_time_unchecked (stream, | 2007 | if (ts_end) |
2008 | *ts_end = avi_stream_convert_frames_to_time_unchecked (stream, | ||
2006 | entry_n + 1); | 2009 | entry_n + 1); |
2007 | } | 2010 | } |
2008 | } else { | 2011 | } else { |
2009 | /* constant rate stream */ | 2012 | /* constant rate stream */ |
2010 | if (timestamp || duration) | 2013 | if (timestamp) |
2011 | ts = avi_stream_convert_bytes_to_time_unchecked (stream, entry->total); | 2014 | *timestamp = |
2012 | if (duration) | 2015 | avi_stream_convert_bytes_to_time_unchecked (stream, entry->total); |
2013 | next_ts = avi_stream_convert_bytes_to_time_unchecked (stream, | 2016 | if (ts_end) |
2017 | *ts_end = avi_stream_convert_bytes_to_time_unchecked (stream, | ||
2014 | entry->total + entry->size); | 2018 | entry->total + entry->size); |
2015 | } | 2019 | } |
2016 | if (timestamp) | 2020 | if (stream->strh->type == GST_RIFF_FCC_vids) { |
2017 | *timestamp = ts; | 2021 | /* video offsets are the frame number */ |
2018 | if (duration) | 2022 | if (offset) |
2019 | *duration = next_ts - ts; | 2023 | *offset = entry_n; |
2020 | 2024 | if (offset_end) | |
2021 | if (offset) | 2025 | *offset_end = entry_n + 1; |
2022 | *offset = entry->offset; | 2026 | } else { |
2023 | if (size) | 2027 | /* no offsets for audio */ |
2024 | *size = entry->size; | 2028 | if (offset) |
2025 | if (keyframe) | 2029 | *offset = -1; |
2026 | *keyframe = ENTRY_IS_KEYFRAME (entry); | 2030 | if (offset_end) |
2031 | *offset_end = -1; | ||
2032 | } | ||
2027 | } | 2033 | } |
2028 | 2034 | ||
2029 | 2035 | ||
@@ -3853,7 +3859,7 @@ pull_range_failed: | |||
3853 | } | 3859 | } |
3854 | } | 3860 | } |
3855 | 3861 | ||
3856 | /* move a stream to an offset */ | 3862 | /* move a stream to @index */ |
3857 | static void | 3863 | static void |
3858 | gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream, | 3864 | gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream, |
3859 | GstSegment * segment, guint index) | 3865 | GstSegment * segment, guint index) |
@@ -3868,6 +3874,8 @@ gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream, | |||
3868 | * are enough decoded frames to fill the segment. */ | 3874 | * are enough decoded frames to fill the segment. */ |
3869 | next_key = gst_avi_demux_index_next (avi, stream, index, TRUE); | 3875 | next_key = gst_avi_demux_index_next (avi, stream, index, TRUE); |
3870 | 3876 | ||
3877 | /* FIXME, we go back to 0, we should look at segment.start. We will however | ||
3878 | * stop earlier when the see the timestamp < segment.start */ | ||
3871 | stream->start_entry = 0; | 3879 | stream->start_entry = 0; |
3872 | stream->step_entry = index; | 3880 | stream->step_entry = index; |
3873 | stream->current_entry = index; | 3881 | stream->current_entry = index; |
@@ -3881,9 +3889,23 @@ gst_avi_demux_move_stream (GstAviDemux * avi, GstAviStream * stream, | |||
3881 | stream->stop_entry = gst_avi_demux_index_last (avi, stream); | 3889 | stream->stop_entry = gst_avi_demux_index_last (avi, stream); |
3882 | } | 3890 | } |
3883 | if (stream->current_entry != index) { | 3891 | if (stream->current_entry != index) { |
3892 | GST_DEBUG_OBJECT (avi, "Move DISCONT from %u to %u", | ||
3893 | stream->current_entry, index); | ||
3884 | stream->current_entry = index; | 3894 | stream->current_entry = index; |
3885 | stream->discont = TRUE; | 3895 | stream->discont = TRUE; |
3886 | } | 3896 | } |
3897 | |||
3898 | /* update the buffer info */ | ||
3899 | gst_avi_demux_get_buffer_info (avi, stream, index, | ||
3900 | &stream->current_timestamp, &stream->current_ts_end, | ||
3901 | &stream->current_offset, &stream->current_offset_end); | ||
3902 | |||
3903 | GST_DEBUG_OBJECT (avi, "Moved to %u, ts %" GST_TIME_FORMAT | ||
3904 | ", ts_end %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT | ||
3905 | ", off_end %" G_GUINT64_FORMAT, index, | ||
3906 | GST_TIME_ARGS (stream->current_timestamp), | ||
3907 | GST_TIME_ARGS (stream->current_ts_end), stream->current_offset, | ||
3908 | stream->current_offset_end); | ||
3887 | } | 3909 | } |
3888 | 3910 | ||
3889 | /* | 3911 | /* |
@@ -3897,26 +3919,23 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment) | |||
3897 | guint i, index; | 3919 | guint i, index; |
3898 | GstAviStream *stream; | 3920 | GstAviStream *stream; |
3899 | GstClockTime timestamp, duration; | 3921 | GstClockTime timestamp, duration; |
3900 | gboolean kentry; | ||
3901 | 3922 | ||
3902 | seek_time = segment->last_stop; | 3923 | seek_time = segment->last_stop; |
3903 | keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT); | 3924 | keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT); |
3904 | 3925 | ||
3926 | GST_DEBUG_OBJECT (avi, "seek to: %" GST_TIME_FORMAT | ||
3927 | " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe); | ||
3928 | |||
3905 | /* FIXME, this code assumes the main stream with keyframes is stream 0, | 3929 | /* FIXME, this code assumes the main stream with keyframes is stream 0, |
3906 | * which is mostly correct... */ | 3930 | * which is mostly correct... */ |
3907 | stream = &avi->stream[0]; | 3931 | stream = &avi->stream[0]; |
3908 | 3932 | ||
3909 | /* get the entry index for the requested position */ | 3933 | /* get the entry index for the requested position */ |
3910 | index = gst_avi_demux_index_for_time (avi, stream, seek_time); | 3934 | index = gst_avi_demux_index_for_time (avi, stream, seek_time); |
3911 | |||
3912 | /* take a look at the entry info */ | ||
3913 | gst_avi_demux_get_entry_info (avi, stream, index, | ||
3914 | NULL, NULL, NULL, NULL, &kentry); | ||
3915 | |||
3916 | GST_DEBUG_OBJECT (avi, "Got entry %u", index); | 3935 | GST_DEBUG_OBJECT (avi, "Got entry %u", index); |
3917 | 3936 | ||
3918 | /* check if we are already on a keyframe */ | 3937 | /* check if we are already on a keyframe */ |
3919 | if (!kentry) { | 3938 | if (!ENTRY_IS_KEYFRAME (&stream->index[index])) { |
3920 | GST_DEBUG_OBJECT (avi, "not keyframe, searching back"); | 3939 | GST_DEBUG_OBJECT (avi, "not keyframe, searching back"); |
3921 | /* now go to the previous keyframe, this is where we should start | 3940 | /* now go to the previous keyframe, this is where we should start |
3922 | * decoding from. */ | 3941 | * decoding from. */ |
@@ -3925,8 +3944,8 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment) | |||
3925 | } | 3944 | } |
3926 | 3945 | ||
3927 | /* take a look at the final entry */ | 3946 | /* take a look at the final entry */ |
3928 | gst_avi_demux_get_entry_info (avi, stream, index, | 3947 | gst_avi_demux_get_buffer_info (avi, stream, index, |
3929 | ×tamp, &duration, NULL, NULL, NULL); | 3948 | ×tamp, &duration, NULL, NULL); |
3930 | 3949 | ||
3931 | GST_DEBUG_OBJECT (avi, | 3950 | GST_DEBUG_OBJECT (avi, |
3932 | "Got keyframe entry %d [ts:%" GST_TIME_FORMAT | 3951 | "Got keyframe entry %d [ts:%" GST_TIME_FORMAT |
@@ -3939,7 +3958,11 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment) | |||
3939 | seek_time = timestamp; | 3958 | seek_time = timestamp; |
3940 | } | 3959 | } |
3941 | 3960 | ||
3942 | /* move the main stream */ | 3961 | /* the seek time is also the last_stop and stream time */ |
3962 | segment->last_stop = seek_time; | ||
3963 | segment->time = seek_time; | ||
3964 | |||
3965 | /* move the main stream to this position */ | ||
3943 | gst_avi_demux_move_stream (avi, stream, segment, index); | 3966 | gst_avi_demux_move_stream (avi, stream, segment, index); |
3944 | 3967 | ||
3945 | /* now set DISCONT and align the other streams */ | 3968 | /* now set DISCONT and align the other streams */ |
@@ -3953,20 +3976,13 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment) | |||
3953 | /* get the entry index for the requested position */ | 3976 | /* get the entry index for the requested position */ |
3954 | index = gst_avi_demux_index_for_time (avi, ostream, seek_time); | 3977 | index = gst_avi_demux_index_for_time (avi, ostream, seek_time); |
3955 | 3978 | ||
3956 | gst_avi_demux_get_entry_info (avi, ostream, index, | 3979 | if (!ENTRY_IS_KEYFRAME (&ostream->index[index])) |
3957 | NULL, NULL, NULL, NULL, &kentry); | ||
3958 | if (!kentry) { | ||
3959 | index = gst_avi_demux_index_prev (avi, ostream, index, TRUE); | 3980 | index = gst_avi_demux_index_prev (avi, ostream, index, TRUE); |
3960 | } | 3981 | |
3961 | gst_avi_demux_move_stream (avi, ostream, segment, index); | 3982 | gst_avi_demux_move_stream (avi, ostream, segment, index); |
3962 | } | 3983 | } |
3963 | 3984 | GST_DEBUG_OBJECT (avi, "done seek to: %" GST_TIME_FORMAT, | |
3964 | GST_DEBUG_OBJECT (avi, "seek: %" GST_TIME_FORMAT | 3985 | GST_TIME_ARGS (seek_time)); |
3965 | " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe); | ||
3966 | |||
3967 | /* the seek time is also the last_stop and stream time */ | ||
3968 | segment->last_stop = seek_time; | ||
3969 | segment->time = seek_time; | ||
3970 | 3986 | ||
3971 | return TRUE; | 3987 | return TRUE; |
3972 | } | 3988 | } |
@@ -4442,14 +4458,14 @@ static GstFlowReturn | |||
4442 | gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream, | 4458 | gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream, |
4443 | GstFlowReturn ret) | 4459 | GstFlowReturn ret) |
4444 | { | 4460 | { |
4445 | guint i; | 4461 | guint old_entry, new_entry; |
4446 | 4462 | ||
4447 | /* move to the next entry */ | 4463 | old_entry = stream->current_entry; |
4448 | stream->current_entry++; | 4464 | /* move forwards */ |
4449 | stream->current_frame++; | 4465 | new_entry = old_entry + 1; |
4450 | 4466 | ||
4451 | /* see if we reached the end */ | 4467 | /* see if we reached the end */ |
4452 | if (stream->current_entry >= stream->stop_entry) { | 4468 | if (new_entry >= stream->stop_entry) { |
4453 | if (avi->segment.rate < 0.0) { | 4469 | if (avi->segment.rate < 0.0) { |
4454 | if (stream->step_entry == stream->start_entry) { | 4470 | if (stream->step_entry == stream->start_entry) { |
4455 | /* we stepped all the way to the start, eos */ | 4471 | /* we stepped all the way to the start, eos */ |
@@ -4460,31 +4476,52 @@ gst_avi_demux_advance (GstAviDemux * avi, GstAviStream * stream, | |||
4460 | stream->stop_entry = stream->step_entry; | 4476 | stream->stop_entry = stream->step_entry; |
4461 | stream->step_entry = gst_avi_demux_index_prev (avi, stream, | 4477 | stream->step_entry = gst_avi_demux_index_prev (avi, stream, |
4462 | stream->stop_entry, TRUE); | 4478 | stream->stop_entry, TRUE); |
4463 | stream->current_entry = stream->step_entry; | ||
4464 | 4479 | ||
4465 | GST_DEBUG_OBJECT (avi, | 4480 | GST_DEBUG_OBJECT (avi, |
4466 | "reverse playback jump: start %u, step %u, stop %u", | 4481 | "reverse playback jump: start %u, step %u, stop %u", |
4467 | stream->start_entry, stream->step_entry, stream->stop_entry); | 4482 | stream->start_entry, stream->step_entry, stream->stop_entry); |
4468 | 4483 | ||
4469 | /* mark DISCONT */ | 4484 | /* and start from the previous keyframe now */ |
4470 | for (i = 0; i < avi->num_streams; i++) { | 4485 | new_entry = stream->step_entry; |
4471 | avi->stream[i].last_flow = GST_FLOW_OK; | ||
4472 | avi->stream[i].discont = TRUE; | ||
4473 | } | ||
4474 | } else { | 4486 | } else { |
4475 | /* EOS */ | 4487 | /* EOS */ |
4476 | GST_DEBUG_OBJECT (avi, "forward reached stop %u", stream->stop_entry); | 4488 | GST_DEBUG_OBJECT (avi, "forward reached stop %u", stream->stop_entry); |
4477 | goto eos; | 4489 | goto eos; |
4478 | } | 4490 | } |
4479 | } | 4491 | } |
4492 | |||
4493 | if (new_entry != old_entry) { | ||
4494 | stream->current_entry = new_entry; | ||
4495 | stream->current_total = stream->index[new_entry].total; | ||
4496 | |||
4497 | if (new_entry == old_entry + 1) { | ||
4498 | GST_DEBUG_OBJECT (avi, "moved forwards from %u to %u", | ||
4499 | old_entry, new_entry); | ||
4500 | /* we simply moved one step forwards, reuse current info */ | ||
4501 | stream->current_timestamp = stream->current_ts_end; | ||
4502 | stream->current_offset = stream->current_offset_end; | ||
4503 | gst_avi_demux_get_buffer_info (avi, stream, new_entry, | ||
4504 | NULL, &stream->current_ts_end, NULL, &stream->current_offset_end); | ||
4505 | } else { | ||
4506 | GST_DEBUG_OBJECT (avi, "DISCONT move from %u to %u", old_entry, | ||
4507 | new_entry); | ||
4508 | /* we moved DISCONT, full update */ | ||
4509 | gst_avi_demux_get_buffer_info (avi, stream, new_entry, | ||
4510 | &stream->current_timestamp, &stream->current_ts_end, | ||
4511 | &stream->current_offset, &stream->current_offset_end); | ||
4512 | /* and MARK discont for this stream */ | ||
4513 | stream->last_flow = GST_FLOW_OK; | ||
4514 | stream->discont = TRUE; | ||
4515 | } | ||
4516 | } | ||
4480 | return ret; | 4517 | return ret; |
4481 | 4518 | ||
4482 | /* ERROR */ | 4519 | /* ERROR */ |
4483 | eos: | 4520 | eos: |
4484 | { | 4521 | { |
4485 | GST_DEBUG_OBJECT (avi, "we are EOS"); | 4522 | GST_DEBUG_OBJECT (avi, "we are EOS"); |
4486 | /* setting current_time to -1 marks EOS */ | 4523 | /* setting current_timestamp to -1 marks EOS */ |
4487 | stream->current_time = -1; | 4524 | stream->current_timestamp = -1; |
4488 | return GST_FLOW_UNEXPECTED; | 4525 | return GST_FLOW_UNEXPECTED; |
4489 | } | 4526 | } |
4490 | } | 4527 | } |
@@ -4493,25 +4530,27 @@ static GstFlowReturn | |||
4493 | gst_avi_demux_loop_data (GstAviDemux * avi) | 4530 | gst_avi_demux_loop_data (GstAviDemux * avi) |
4494 | { | 4531 | { |
4495 | GstFlowReturn ret = GST_FLOW_OK; | 4532 | GstFlowReturn ret = GST_FLOW_OK; |
4496 | guint64 min_time; | ||
4497 | guint stream_num, i; | 4533 | guint stream_num, i; |
4534 | guint64 min_time; | ||
4498 | GstAviStream *stream; | 4535 | GstAviStream *stream; |
4499 | gboolean processed = FALSE; | 4536 | gboolean processed = FALSE; |
4500 | GstBuffer *buf; | 4537 | GstBuffer *buf; |
4501 | guint64 offset, size; | 4538 | guint64 offset, size; |
4502 | GstClockTime timestamp, duration; | 4539 | GstClockTime timestamp, duration; |
4540 | guint64 out_offset, out_offset_end; | ||
4503 | gboolean keyframe; | 4541 | gboolean keyframe; |
4542 | GstAviIndexEntry *entry; | ||
4504 | 4543 | ||
4505 | do { | 4544 | do { |
4545 | min_time = G_MAXUINT64; | ||
4506 | /* first find the stream with the lowest current position, this is the one | 4546 | /* first find the stream with the lowest current position, this is the one |
4507 | * we should push from next */ | 4547 | * we should push from next */ |
4508 | min_time = G_MAXUINT64; | ||
4509 | stream_num = -1; | 4548 | stream_num = -1; |
4510 | for (i = 0; i < avi->num_streams; i++) { | 4549 | for (i = 0; i < avi->num_streams; i++) { |
4511 | guint64 position; | 4550 | guint64 position; |
4512 | 4551 | ||
4513 | stream = &avi->stream[i]; | 4552 | stream = &avi->stream[i]; |
4514 | position = stream->current_time; | 4553 | position = stream->current_timestamp; |
4515 | 4554 | ||
4516 | /* position of -1 is EOS */ | 4555 | /* position of -1 is EOS */ |
4517 | if (position != -1 && position < min_time) { | 4556 | if (position != -1 && position < min_time) { |
@@ -4537,20 +4576,27 @@ gst_avi_demux_loop_data (GstAviDemux * avi) | |||
4537 | } | 4576 | } |
4538 | 4577 | ||
4539 | /* get the timing info for the entry */ | 4578 | /* get the timing info for the entry */ |
4540 | gst_avi_demux_get_entry_info (avi, stream, stream->current_entry, | 4579 | timestamp = stream->current_timestamp; |
4541 | ×tamp, &duration, &offset, &size, &keyframe); | 4580 | duration = stream->current_ts_end - timestamp; |
4581 | out_offset = stream->current_offset; | ||
4582 | out_offset_end = stream->current_offset_end; | ||
4583 | |||
4584 | /* get the entry data info */ | ||
4585 | entry = &stream->index[stream->current_entry]; | ||
4586 | offset = entry->offset; | ||
4587 | size = entry->size; | ||
4588 | keyframe = ENTRY_IS_KEYFRAME (entry); | ||
4542 | 4589 | ||
4543 | /* skip empty entries */ | 4590 | /* skip empty entries */ |
4544 | if (size == 0) { | 4591 | if (size == 0) { |
4545 | GST_DEBUG_OBJECT (avi, "Skipping entry %d (%d, %p)", | 4592 | GST_DEBUG_OBJECT (avi, "Skipping entry %u (%u, %p)", |
4546 | stream->current_entry, size, stream->pad); | 4593 | stream->current_entry, size, stream->pad); |
4547 | goto next; | 4594 | goto next; |
4548 | } | 4595 | } |
4549 | 4596 | ||
4550 | if (avi->segment.rate > 0.0) { | 4597 | if (avi->segment.rate > 0.0) { |
4551 | /* only check this for fowards playback for now */ | 4598 | /* only check this for fowards playback for now */ |
4552 | if (keyframe && GST_CLOCK_TIME_IS_VALID (timestamp) | 4599 | if (keyframe && GST_CLOCK_TIME_IS_VALID (avi->segment.stop) |
4553 | && GST_CLOCK_TIME_IS_VALID (avi->segment.stop) | ||
4554 | && (timestamp > avi->segment.stop)) { | 4600 | && (timestamp > avi->segment.stop)) { |
4555 | goto eos_stop; | 4601 | goto eos_stop; |
4556 | } | 4602 | } |
@@ -4580,16 +4626,17 @@ gst_avi_demux_loop_data (GstAviDemux * avi) | |||
4580 | 4626 | ||
4581 | GST_BUFFER_TIMESTAMP (buf) = timestamp; | 4627 | GST_BUFFER_TIMESTAMP (buf) = timestamp; |
4582 | GST_BUFFER_DURATION (buf) = duration; | 4628 | GST_BUFFER_DURATION (buf) = duration; |
4583 | GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE; | 4629 | GST_BUFFER_OFFSET (buf) = out_offset; |
4584 | GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE; | 4630 | GST_BUFFER_OFFSET_END (buf) = out_offset_end; |
4585 | 4631 | ||
4586 | gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); | 4632 | gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); |
4587 | 4633 | ||
4588 | GST_DEBUG_OBJECT (avi, "Pushing buffer of size %d, offset %" | 4634 | GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %" |
4589 | G_GUINT64_FORMAT " and time %" | 4635 | GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT |
4590 | GST_TIME_FORMAT " on pad %s", | 4636 | ", off_end %" G_GUINT64_FORMAT " on pad %s", |
4591 | GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf), | 4637 | GST_BUFFER_SIZE (buf), GST_TIME_ARGS (timestamp), |
4592 | GST_TIME_ARGS (timestamp), GST_PAD_NAME (stream->pad)); | 4638 | GST_TIME_ARGS (duration), GST_BUFFER_OFFSET (buf), |
4639 | GST_BUFFER_OFFSET_END (buf), GST_PAD_NAME (stream->pad)); | ||
4593 | 4640 | ||
4594 | /* update current position in the segment */ | 4641 | /* update current position in the segment */ |
4595 | gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp); | 4642 | gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp); |
@@ -4605,7 +4652,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi) | |||
4605 | /* mark as processed, we increment the frame and byte counters then | 4652 | /* mark as processed, we increment the frame and byte counters then |
4606 | * leave the while loop and return the GstFlowReturn */ | 4653 | * leave the while loop and return the GstFlowReturn */ |
4607 | processed = TRUE; | 4654 | processed = TRUE; |
4608 | GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", stream->current_entry, | 4655 | GST_DEBUG_OBJECT (avi, "Processed buffer %u: %s", stream->current_entry, |
4609 | gst_flow_get_name (ret)); | 4656 | gst_flow_get_name (ret)); |
4610 | 4657 | ||
4611 | if (avi->segment.rate < 0) { | 4658 | if (avi->segment.rate < 0) { |
@@ -4618,6 +4665,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi) | |||
4618 | } | 4665 | } |
4619 | } | 4666 | } |
4620 | next: | 4667 | next: |
4668 | /* move to next item */ | ||
4621 | ret = gst_avi_demux_advance (avi, stream, ret); | 4669 | ret = gst_avi_demux_advance (avi, stream, ret); |
4622 | 4670 | ||
4623 | /* combine flows */ | 4671 | /* combine flows */ |
@@ -4791,8 +4839,8 @@ gst_avi_demux_stream_data (GstAviDemux * avi) | |||
4791 | if (G_UNLIKELY (format != GST_FORMAT_TIME)) | 4839 | if (G_UNLIKELY (format != GST_FORMAT_TIME)) |
4792 | goto wrong_format; | 4840 | goto wrong_format; |
4793 | 4841 | ||
4794 | stream->current_frame++; | 4842 | stream->current_entry++; |
4795 | stream->current_byte += size; | 4843 | stream->current_total += size; |
4796 | 4844 | ||
4797 | /* invert the picture if needed */ | 4845 | /* invert the picture if needed */ |
4798 | buf = gst_avi_demux_invert (stream, buf); | 4846 | buf = gst_avi_demux_invert (stream, buf); |
@@ -4803,10 +4851,13 @@ gst_avi_demux_stream_data (GstAviDemux * avi) | |||
4803 | 4851 | ||
4804 | GST_BUFFER_TIMESTAMP (buf) = next_ts; | 4852 | GST_BUFFER_TIMESTAMP (buf) = next_ts; |
4805 | GST_BUFFER_DURATION (buf) = dur_ts - next_ts; | 4853 | GST_BUFFER_DURATION (buf) = dur_ts - next_ts; |
4806 | if (stream->strh->type == GST_RIFF_FCC_vids) | 4854 | if (stream->strh->type == GST_RIFF_FCC_vids) { |
4807 | GST_BUFFER_OFFSET (buf) = stream->current_frame - 1; | 4855 | GST_BUFFER_OFFSET (buf) = stream->current_entry - 1; |
4808 | else | 4856 | GST_BUFFER_OFFSET_END (buf) = stream->current_entry; |
4857 | } else { | ||
4809 | GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE; | 4858 | GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE; |
4859 | GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE; | ||
4860 | } | ||
4810 | 4861 | ||
4811 | gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); | 4862 | gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); |
4812 | GST_DEBUG_OBJECT (avi, | 4863 | GST_DEBUG_OBJECT (avi, |