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