comparison seek.c @ 1408:71ad3e1ba014

some cleanup, asf/mpg seek precision improved
author arpi
date Sun, 29 Jul 2001 00:39:47 +0000
parents 8ecf18884ad8
children ea0a0b9e6fbc
comparison
equal deleted inserted replaced
1407:2e23a033d6f8 1408:71ad3e1ba014
21 21
22 extern int asf_packetsize; // for seeking 22 extern int asf_packetsize; // for seeking
23 23
24 extern float avi_audio_pts; 24 extern float avi_audio_pts;
25 extern float avi_video_pts; 25 extern float avi_video_pts;
26 extern float avi_video_ftime; 26 //extern float avi_video_ftime;
27 extern int skip_video_frames; 27 extern int skip_video_frames;
28 extern float initial_pts_delay; 28 extern float initial_pts_delay;
29 extern int seek_to_byte; 29 extern int seek_to_byte;
30 extern char* current_module; // for debugging 30 extern char* current_module; // for debugging
31 31
36 int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){ 36 int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
37 demux_stream_t *d_audio=demuxer->audio; 37 demux_stream_t *d_audio=demuxer->audio;
38 demux_stream_t *d_video=demuxer->video; 38 demux_stream_t *d_video=demuxer->video;
39 sh_audio_t *sh_audio=d_audio->sh; 39 sh_audio_t *sh_audio=d_audio->sh;
40 sh_video_t *sh_video=d_video->sh; 40 sh_video_t *sh_video=d_video->sh;
41 int skip_audio_bytes=0;
42 float skip_audio_secs=0; 41 float skip_audio_secs=0;
43 42
44 if(demuxer->file_format==DEMUXER_TYPE_AVI && demuxer->idx_size<=0){ 43 if(demuxer->file_format==DEMUXER_TYPE_AVI && demuxer->idx_size<=0){
45 printf("Can't seek in raw .AVI streams! (index required, try with the -idx switch!) \n"); 44 printf("Can't seek in raw .AVI streams! (index required, try with the -idx switch!) \n");
46 return 0; 45 return 0;
73 // seek forward 72 // seek forward
74 while(video_chunk_pos<demuxer->idx_size){ 73 while(video_chunk_pos<demuxer->idx_size){
75 int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid; 74 int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid;
76 if(avi_stream_id(id)==d_video->id){ // video frame 75 if(avi_stream_id(id)==d_video->id){ // video frame
77 if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; 76 if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
78 ++skip_audio_bytes; 77 // ++skip_audio_bytes;
79 } 78 }
80 ++video_chunk_pos; 79 ++video_chunk_pos;
81 } 80 }
82 } else { 81 } else {
83 // seek backward 82 // seek backward
84 while(video_chunk_pos>=0){ 83 while(video_chunk_pos>=0){
85 int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid; 84 int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid;
86 if(avi_stream_id(id)==d_video->id){ // video frame 85 if(avi_stream_id(id)==d_video->id){ // video frame
87 if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; 86 if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
88 --skip_audio_bytes; 87 // --skip_audio_bytes;
89 } 88 }
90 --video_chunk_pos; 89 --video_chunk_pos;
91 } 90 }
92 } 91 }
93 demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=video_chunk_pos; 92 demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=video_chunk_pos;
105 if(sh_audio){ 104 if(sh_audio){
106 int i; 105 int i;
107 int apos=0; 106 int apos=0;
108 int last=0; 107 int last=0;
109 int len=0; 108 int len=0;
109 int skip_audio_bytes=0;
110 110
111 // calc new audio position in audio stream: (using avg.bps value) 111 // calc new audio position in audio stream: (using avg.bps value)
112 curr_audio_pos=(avi_video_pts) * sh_audio->wf->nAvgBytesPerSec; 112 curr_audio_pos=(avi_video_pts) * sh_audio->wf->nAvgBytesPerSec;
113 if(curr_audio_pos<0)curr_audio_pos=0; 113 if(curr_audio_pos<0)curr_audio_pos=0;
114 #if 1 114 #if 1
168 int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid; 168 int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid;
169 if(avi_stream_id(id)==d_video->id) ++skip_video_frames; 169 if(avi_stream_id(id)==d_video->id) ++skip_video_frames;
170 } 170 }
171 // requires for correct audio pts calculation (demuxer): 171 // requires for correct audio pts calculation (demuxer):
172 avi_video_pts-=skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; 172 avi_video_pts-=skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
173 173
174 } 174 if(verbose) printf("SEEK: idx=%d (a:%d v:%d) v.skip=%d a.skip=%d/%4.3f \n",
175 175 demuxer->idx_pos,audio_chunk_pos,video_chunk_pos,
176 if(verbose) printf("SEEK: idx=%d (a:%d v:%d) v.skip=%d a.skip=%d/%4.3f \n", 176 skip_video_frames,skip_audio_bytes,skip_audio_secs);
177 demuxer->idx_pos,audio_chunk_pos,video_chunk_pos, 177
178 skip_video_frames,skip_audio_bytes,skip_audio_secs); 178 if(skip_audio_bytes){
179 demux_read_data(d_audio,NULL,skip_audio_bytes);
180 //d_audio->pts=0; // PTS is outdated because of the raw data skipping
181 }
182 resync_audio_stream(sh_audio);
183 }
179 184
180 } 185 }
181 break; 186 break;
182 187
183 case DEMUXER_TYPE_ASF: { 188 case DEMUXER_TYPE_ASF: {
193 if(newpos<0 || newpos<demuxer->movi_start) newpos=demuxer->movi_start; 198 if(newpos<0 || newpos<demuxer->movi_start) newpos=demuxer->movi_start;
194 // printf("\r -- asf: newpos=%d -- \n",newpos); 199 // printf("\r -- asf: newpos=%d -- \n",newpos);
195 stream_seek(demuxer->stream,newpos); 200 stream_seek(demuxer->stream,newpos);
196 201
197 ds_fill_buffer(d_video); 202 ds_fill_buffer(d_video);
198 if(sh_audio) ds_fill_buffer(d_audio); 203 if(sh_audio){
204 ds_fill_buffer(d_audio);
205 resync_audio_stream(sh_audio);
206 }
199 207
200 while(1){ 208 while(1){
201 if(sh_audio){ 209 if(sh_audio && !d_audio->eof){
210 float a_pts=d_audio->pts;
211 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
202 // sync audio: 212 // sync audio:
203 if (d_video->pts > d_audio->pts){ 213 if (d_video->pts > a_pts){
204 if(!ds_fill_buffer(d_audio)) sh_audio=NULL; // skip audio. EOF? 214 skip_audio_frame(sh_audio);
215 // if(!ds_fill_buffer(d_audio)) sh_audio=NULL; // skip audio. EOF?
205 continue; 216 continue;
206 } 217 }
207 } 218 }
208 if(d_video->flags&1) break; // found a keyframe! 219 if(d_video->flags&1) break; // found a keyframe!
209 if(!ds_fill_buffer(d_video)) break; // skip frame. EOF? 220 if(!ds_fill_buffer(d_video)) break; // skip frame. EOF?
222 newpos=demuxer->filepos+(sh_video->i_bps)*rel_seek_secs; 233 newpos=demuxer->filepos+(sh_video->i_bps)*rel_seek_secs;
223 234
224 if(newpos<seek_to_byte) newpos=seek_to_byte; 235 if(newpos<seek_to_byte) newpos=seek_to_byte;
225 newpos&=~(STREAM_BUFFER_SIZE-1); /* sector boundary */ 236 newpos&=~(STREAM_BUFFER_SIZE-1); /* sector boundary */
226 stream_seek(demuxer->stream,newpos); 237 stream_seek(demuxer->stream,newpos);
238
227 // re-sync video: 239 // re-sync video:
228 videobuf_code_len=0; // reset ES stream buffer 240 videobuf_code_len=0; // reset ES stream buffer
229 while(1){ 241
230 int i=sync_video_packet(d_video); 242 ds_fill_buffer(d_video);
243 if(sh_audio){
244 ds_fill_buffer(d_audio);
245 resync_audio_stream(sh_audio);
246 }
247
248 while(1){
249 int i;
250 if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
251 float a_pts=d_audio->pts;
252 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
253 if(d_video->pts>a_pts){
254 skip_audio_frame(sh_audio); // sync audio
255 continue;
256 }
257 }
258 i=sync_video_packet(d_video);
231 if(i==0x1B3 || i==0x1B8) break; // found it! 259 if(i==0x1B3 || i==0x1B8) break; // found it!
232 if(!i || !skip_video_packet(d_video)) break; // EOF? 260 if(!i || !skip_video_packet(d_video)) break; // EOF?
233 } 261 }
262
234 } 263 }
235 break; 264 break;
236 265
237 } // switch(demuxer->file_format) 266 } // switch(demuxer->file_format)
238 267
239 //====================== re-sync audio: ===================== 268 //====================== re-sync audio: =====================
240 if(sh_audio){ 269 if(sh_audio){
241 270 if(verbose){
242 if(skip_audio_bytes){ 271 float a_pts=d_audio->pts;
243 demux_read_data(d_audio,NULL,skip_audio_bytes); 272 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
244 //d_audio->pts=0; // PTS is outdated because of the raw data skipping 273 printf("SEEK: A: %5.3f V: %5.3f A-V: %5.3f \n",a_pts,d_video->pts,a_pts-d_video->pts);
245 } 274 }
246
247 current_module="resync_audio";
248 resync_audio_stream(sh_audio);
249
250 // re-sync PTS (MPEG-PS only!!!)
251 if(demuxer->file_format==DEMUXER_TYPE_MPEG_PS)
252 if(d_video->pts && d_audio->pts){
253 if (d_video->pts < d_audio->pts){
254
255 } else {
256 while(d_video->pts > d_audio->pts){
257 skip_audio_frame(sh_audio);
258 }
259 }
260 }
261
262 printf("A:%6.1f V:%6.1f A-V:%7.3f ct: ? \r",d_audio->pts,d_video->pts,0.0f); 275 printf("A:%6.1f V:%6.1f A-V:%7.3f ct: ? \r",d_audio->pts,d_video->pts,0.0f);
263 } else { 276 } else {
264 printf("A: --- V:%6.1f \r",d_video->pts); 277 printf("A: --- V:%6.1f \r",d_video->pts);
265 } 278 }
266 fflush(stdout); 279 fflush(stdout);