[MPlayer-dev-eng] [PATCH] float comparisons and A/V desynchronization fix (mainly with real videos)
Pierre Lombard
p_l at gmx.fr
Fri May 5 10:33:50 CEST 2006
Hi,
The culprit file is libmpdemux/video.c: because of how floats are
encoded in computers, you may almost never compare directly floating
points values (floats are not a totally ordered set unlike integers for
instance).
This is why most math libs have an epsilon and also why a (myfloat ==
0.0f) will almost always fail...
FWIW, I chose epsilon to be 1.0f/1000.0f as it seems to match a 1000fps
precision - though it should indeed be related to both compared numbers.
This improves dramatically the A/V sync for some real videos I have (
the A/V sync goes wild because of incorrect frame durations because of
this incorrect comparison).
Patch attached - please test and apply (or some flavor of it as you see
fit).
--
Pierre Lombard
-------------- next part --------------
Index: libmpdemux/video.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/video.c,v
retrieving revision 1.62
diff -u -r1.62 video.c
--- libmpdemux/video.c 23 Apr 2006 12:29:10 -0000 1.62
+++ libmpdemux/video.c 5 May 2006 08:29:35 -0000
@@ -609,18 +609,22 @@
case DEMUXER_TYPE_VIVO:
case DEMUXER_TYPE_REAL:
case DEMUXER_TYPE_ASF: {
+ const float epsilon = 0.001f;
float next_pts = ds_get_next_pts(d_video);
- float d= next_pts > 0 ? next_pts - d_video->pts : d_video->pts-pts1;
- if(d>=0){
- if(d>0){
- if((int)sh_video->fps==1000)
+ float d = next_pts > -epsilon ? next_pts - d_video->pts : d_video->pts-pts1;
+ if(d > -epsilon){
+ if(fabs(d)>epsilon){
+ if((int)sh_video->fps==1000) {
mp_msg(MSGT_CPLAYER,MSGL_V,"\navg. framerate: %d fps \n",(int)(1.0f/d));
+ }
sh_video->frametime=d; // 1ms
sh_video->fps=1.0f/d;
+ frame_time = d;
+ } else {
+ frame_time = 0.0f;
}
- frame_time = d;
} else {
- mp_msg(MSGT_CPLAYER,MSGL_WARN,"\nInvalid frame duration value (%5.3f/%5.3f => %5.3f). Defaulting to %5.3f sec.\n",d_video->pts,next_pts,d,frame_time);
+ mp_msg(MSGT_CPLAYER,MSGL_WARN,"\nInvalid frame duration value (%5.8f/%5.8f => %5.8f). Defaulting to %5.8f sec.\n",d_video->pts,next_pts,d,frame_time);
// frame_time = 1/25.0;
}
}
More information about the MPlayer-dev-eng
mailing list