Originally committed as revision 3586 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michael Niedermayer authored on 2004/10/12 10:51:04... | ... |
@@ -816,20 +816,30 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, |
816 | 816 |
return size; |
817 | 817 |
} |
818 | 818 |
|
819 |
-int64_t dv_frame_offset(DVDemuxContext *c, int64_t timestamp) |
|
819 |
+static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, |
|
820 |
+ int64_t timestamp, int flags) |
|
820 | 821 |
{ |
821 |
- const DVprofile* sys; |
|
822 |
- int64_t frame_number, offset; |
|
823 |
- |
|
824 | 822 |
// FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk) |
825 |
- sys = dv_codec_profile(&c->vst->codec); |
|
823 |
+ const DVprofile* sys = dv_codec_profile(&c->vst->codec); |
|
824 |
+ int64_t frame_number, offset; |
|
825 |
+ int64_t size = url_filesize(url_fileno(&s->pb)); |
|
826 |
+ int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size; |
|
826 | 827 |
|
827 |
- // timestamp was scaled by time_base/AV_BASE_RATE by av_seek_frame() |
|
828 |
- frame_number = (timestamp * sys->frame_rate) / |
|
829 |
- ((int64_t) 30000 * sys->frame_rate_base); |
|
828 |
+ if (flags & AVSEEK_FLAG_BACKWARD) { |
|
829 |
+ frame_number = av_rescale_rnd(timestamp, sys->frame_rate, |
|
830 |
+ (int64_t) 30000 * sys->frame_rate_base, |
|
831 |
+ AV_ROUND_DOWN); |
|
832 |
+ } |
|
833 |
+ else { |
|
834 |
+ frame_number = av_rescale_rnd(timestamp, sys->frame_rate, |
|
835 |
+ (int64_t) 30000 * sys->frame_rate_base, |
|
836 |
+ AV_ROUND_UP); |
|
837 |
+ } |
|
830 | 838 |
|
831 |
- // offset must be a multiple of frame_size else dv_read_packet() will fail |
|
832 |
- offset = (int64_t) sys->frame_size * frame_number; |
|
839 |
+ offset = sys->frame_size * frame_number; |
|
840 |
+ |
|
841 |
+ if (offset > max_offset) offset = max_offset; |
|
842 |
+ else if (offset < 0) offset = 0; |
|
833 | 843 |
|
834 | 844 |
return offset; |
835 | 845 |
} |
... | ... |
@@ -883,11 +893,36 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) |
883 | 883 |
return size; |
884 | 884 |
} |
885 | 885 |
|
886 |
-static int dv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp) |
|
886 |
+static int dv_read_seek(AVFormatContext *s, int stream_index, |
|
887 |
+ int64_t timestamp, int flags) |
|
887 | 888 |
{ |
888 |
- RawDVContext *c = s->priv_data; |
|
889 |
+ RawDVContext *r = s->priv_data; |
|
890 |
+ DVDemuxContext *c = r->dv_demux; |
|
891 |
+ int i; |
|
892 |
+ int64_t offset= dv_frame_offset(s, c, timestamp, flags); |
|
893 |
+ const DVprofile* sys = dv_codec_profile(&c->vst->codec); |
|
894 |
+ |
|
895 |
+ c->frames= offset / sys->frame_size; |
|
896 |
+ c->abytes= av_rescale(c->frames, |
|
897 |
+ c->ast[0]->codec.bit_rate * (int64_t)sys->frame_rate_base, |
|
898 |
+ 8*sys->frame_rate); |
|
899 |
+ for (i=0; i<c->ach; i++) { |
|
900 |
+ if (c->ast[i] && c->audio_pkt[i].size) { |
|
901 |
+ av_free_packet(&c->audio_pkt[i]); |
|
902 |
+ c->audio_pkt[i].size = 0; |
|
903 |
+ } |
|
904 |
+ } |
|
905 |
+ |
|
906 |
+ for(i = 0; i < s->nb_streams; i++) { |
|
907 |
+ AVStream *st = s->streams[stream_index]; |
|
908 |
+ AVStream *st2 = s->streams[i]; |
|
909 |
+ |
|
910 |
+ st->cur_dts = av_rescale(timestamp, |
|
911 |
+ st2->time_base.den * (int64_t)st ->time_base.num, |
|
912 |
+ st ->time_base.den * (int64_t)st2->time_base.num); |
|
913 |
+ } |
|
889 | 914 |
|
890 |
- return url_fseek(&s->pb, dv_frame_offset(c->dv_demux, timestamp), SEEK_SET); |
|
915 |
+ return url_fseek(&s->pb, offset, SEEK_SET); |
|
891 | 916 |
} |
892 | 917 |
|
893 | 918 |
static int dv_read_close(AVFormatContext *s) |