Browse code

flags, rounding and cliping fix by (Nathan Kurz <nate at verse dot com>) max_pos, buffer flush, audio and video timestamp fix by me

Originally committed as revision 3586 to svn://svn.ffmpeg.org/ffmpeg/trunk

Michael Niedermayer authored on 2004/10/12 10:51:04
Showing 1 changed files
... ...
@@ -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)