Mercurial > mplayer.hg
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); |