Mercurial > mplayer.hg
diff 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 |
line wrap: on
line diff
--- a/libmpcodecs/dec_video.c Thu Jul 06 05:05:00 2006 +0000 +++ b/libmpcodecs/dec_video.c Thu Jul 06 06:58:17 2006 +0000 @@ -137,6 +137,18 @@ if(mpvdec) mpvdec->control(sh_video, VDCTRL_RESYNC_STREAM, NULL); } +int get_current_video_decoder_lag(sh_video_t *sh_video) +{ + int ret; + + if (!mpvdec) + return -1; + ret = mpvdec->control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, NULL); + if (ret >= 10) + return ret-10; + return -1; +} + void uninit_video(sh_video_t *sh_video){ if(!sh_video->inited) return; mp_msg(MSGT_DECVIDEO,MSGL_V,MSGTR_UninitVideoStr,sh_video->codec->drv); @@ -311,6 +323,36 @@ double tt; int ret; + if (correct_pts) { + int delay = get_current_video_decoder_lag(sh_video); + if (delay >= 0) { + if (delay > sh_video->num_buffered_pts) +#if 0 + // this is disabled because vd_ffmpeg reports the same lag + // after seek even when there are no buffered frames, + // leading to incorrect error messages + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Not enough buffered pts\n"); +#else + ; +#endif + else + sh_video->num_buffered_pts = delay; + } + if (sh_video->num_buffered_pts == + sizeof(sh_video->buffered_pts)/sizeof(double)) + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); + else { + int i, j; + for (i = 0; i < sh_video->num_buffered_pts; i++) + if (sh_video->buffered_pts[i] < pts) + break; + for (j = sh_video->num_buffered_pts; j > i; j--) + sh_video->buffered_pts[j] = sh_video->buffered_pts[j-1]; + sh_video->buffered_pts[i] = pts; + sh_video->num_buffered_pts++; + } + } + //if(!(sh_video->ds->flags&1) || sh_video->ds->pack_no<5) mpi=mpvdec->decode(sh_video, start, in_size, drop_frame); @@ -333,6 +375,11 @@ if(!mpi || drop_frame) return 0; // error / skipped frame + if (correct_pts) { + sh_video->num_buffered_pts--; + pts = sh_video->buffered_pts[sh_video->num_buffered_pts]; + } + //vo_draw_image(video_out,mpi); vf=sh_video->vfilter; ret = vf->put_image(vf,mpi, pts); // apply video filters and call the leaf vo/ve