comparison libmpcodecs/dec_video.c @ 18917:d9a75b26da6c

Add a new video pts tracking mode, enabled by option -correct-pts. This mode has the following differences: - Video timing is correct for streams with B frames, at least with some demuxers. - Video filters can modify frame timestamps and insert new frames, and removing frames is handled better than before. - Some things are known to break, it's not usable as the default yet. Things should work as before when the -correct-pts option is not used.
author uau
date Thu, 06 Jul 2006 06:58:17 +0000
parents e60c8c7399d2
children 39d8fd7e7543
comparison
equal deleted inserted replaced
18916:a95ed361d16b 18917:d9a75b26da6c
133 } 133 }
134 134
135 void resync_video_stream(sh_video_t *sh_video) 135 void resync_video_stream(sh_video_t *sh_video)
136 { 136 {
137 if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL); 137 if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL);
138 }
139
140 int get_current_video_decoder_lag(sh_video_t *sh_video)
141 {
142 int ret;
143
144 if (!mpvdec)
145 return -1;
146 ret = mpvdec->control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, NULL);
147 if (ret >= 10)
148 return ret-10;
149 return -1;
138 } 150 }
139 151
140 void uninit_video(sh_video_t *sh_video){ 152 void uninit_video(sh_video_t *sh_video){
141 if(!sh_video->inited) return; 153 if(!sh_video->inited) return;
142 mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv); 154 mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv);
309 unsigned int t=GetTimer(); 321 unsigned int t=GetTimer();
310 unsigned int t2; 322 unsigned int t2;
311 double tt; 323 double tt;
312 int ret; 324 int ret;
313 325
326 if (correct_pts) {
327 int delay = get_current_video_decoder_lag(sh_video);
328 if (delay >= 0) {
329 if (delay > sh_video->num_buffered_pts)
330 #if 0
331 // this is disabled because vd_ffmpeg reports the same lag
332 // after seek even when there are no buffered frames,
333 // leading to incorrect error messages
334 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Not enough buffered pts\n");
335 #else
336 ;
337 #endif
338 else
339 sh_video->num_buffered_pts = delay;
340 }
341 if (sh_video->num_buffered_pts ==
342 sizeof(sh_video->buffered_pts)/sizeof(double))
343 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n");
344 else {
345 int i, j;
346 for (i = 0; i < sh_video->num_buffered_pts; i++)
347 if (sh_video->buffered_pts[i] < pts)
348 break;
349 for (j = sh_video->num_buffered_pts; j > i; j--)
350 sh_video->buffered_pts[j] = sh_video->buffered_pts[j-1];
351 sh_video->buffered_pts[i] = pts;
352 sh_video->num_buffered_pts++;
353 }
354 }
355
314 //if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5) 356 //if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5)
315 mpi=mpvdec->decode(sh_video, start, in_size, drop_frame); 357 mpi=mpvdec->decode(sh_video, start, in_size, drop_frame);
316 358
317 //------------------------ frame decoded. -------------------- 359 //------------------------ frame decoded. --------------------
318 360
331 tt = t*0.000001f; 373 tt = t*0.000001f;
332 video_time_usage+=tt; 374 video_time_usage+=tt;
333 375
334 if(!mpi || drop_frame) return 0; // error / skipped frame 376 if(!mpi || drop_frame) return 0; // error / skipped frame
335 377
378 if (correct_pts) {
379 sh_video->num_buffered_pts--;
380 pts = sh_video->buffered_pts[sh_video->num_buffered_pts];
381 }
382
336 //vo_draw_image(video_out,mpi); 383 //vo_draw_image(video_out,mpi);
337 vf=sh_video->vfilter; 384 vf=sh_video->vfilter;
338 ret = vf->put_image(vf,mpi, pts); // apply video filters and call the leaf vo/ve 385 ret = vf->put_image(vf,mpi, pts); // apply video filters and call the leaf vo/ve
339 if(ret>0) vf->control(vf,VFCTRL_DRAW_OSD,NULL); 386 if(ret>0) vf->control(vf,VFCTRL_DRAW_OSD,NULL);
340 387