# HG changeset patch # User arpi # Date 1033511344 0 # Node ID c135f76460363edd56a920364ba3b56ec5872fe2 # Parent 3a6d7933a6adff8a7c60bda9d732d8641244188b new opt: -autosync, controls ao->get_delay() smoothing (default: disabled) patch by Sidik Isani diff -r 3a6d7933a6ad -r c135f7646036 DOCS/mplayer.1 --- a/DOCS/mplayer.1 Tue Oct 01 21:47:32 2002 +0000 +++ b/DOCS/mplayer.1 Tue Oct 01 22:29:04 2002 +0000 @@ -159,14 +159,26 @@ can use some big number. You may not use it together with \-pp but it is OK with \-npp! .TP +.B \-autosync +Gradually adjusts the A/V sync based on audio delay measurements. +Specifying \-autosync 0, the default, will cause frame timing to be based +entirely on audio delay measurements. Specifying \-autosync 1 will do the +same, but will subtly change the A/V correction algorithm used. An uneven +video frame rate in a movie which plays fine with -nosound can often be +helped by setting this to an integer value greater than 1. The higher +the value, the closer the timing will be to -nosound. + +Try \-autosync 30 to smooth out problems with sound drivers which do +not implement a perfect audio delay measurement. With this value, if +large A/V sync offsets occur, they will only take about 1 or 2 seconds +to settle out. This delay in reaction time to sudden A/V offsets should +be the only side-effect of turning this option on, for all sound drivers. +.TP .B \-benchmark Prints some statistics on CPU usage and dropped frames at the end. Used in combination with \-nosound and \-vo null for benchmarking only video codec. .TP -.B \-dapsync (OBSOLETE) -Use alternative A/V sync method. -.TP .B \-framedrop (see \-hardframedrop option too!) Frame dropping: decode all (except B) frames, video may skip. Useful for playback on slow VGA card/bus. diff -r 3a6d7933a6ad -r c135f7646036 cfg-mplayer.h --- a/cfg-mplayer.h Tue Oct 01 21:47:32 2002 +0000 +++ b/cfg-mplayer.h Tue Oct 01 22:29:04 2002 +0000 @@ -349,6 +349,8 @@ {"playlist", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL}, // a-v sync stuff: + {"noautosync", &autosync, CONF_TYPE_FLAG, 0, 0, -1, NULL}, + {"autosync", &autosync, CONF_TYPE_INT, CONF_RANGE, 0, 10000, NULL}, // {"dapsync", &dapsync, CONF_TYPE_FLAG, 0, 0, 1, NULL}, // {"nodapsync", &dapsync, CONF_TYPE_FLAG, 0, 1, 0, NULL}, diff -r 3a6d7933a6ad -r c135f7646036 mplayer.c --- a/mplayer.c Tue Oct 01 21:47:32 2002 +0000 +++ b/mplayer.c Tue Oct 01 22:29:04 2002 +0000 @@ -164,6 +164,9 @@ static off_t step_sec=0; static int loop_times=-1; +// A/V sync: +static int autosync=0; // 30 might be a good default value. + // may be changed by GUI: (FIXME!) float rel_seek_secs=0; int abs_seek_pos=0; @@ -1446,7 +1449,16 @@ } #endif - if(drop_frame && !frame_time_remaining){ + if(drop_frame && !frame_time_remaining && !autosync){ + /* + * Note: time_frame should not be forced to 0 in autosync mode. + * It is used as a cumulative counter to predict and correct the + * delay measurements from the audio driver. time_frame is already + * < 0, so the "time to sleep" code does not actually sleep. Also, + * blit_frame is already 0 because drop_frame was true when + * decode_video was called (which causes it to set blit_frame to 0.) + * When autosync==0, the default behavior is still completely unchanged. + */ time_frame=0; // don't sleep! blit_frame=0; // don't display! @@ -1462,6 +1474,21 @@ float delay=audio_out->get_delay(); mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"delay=%f\n",delay); + if (autosync){ + /* + * Adjust this raw delay value by calculating the expected + * delay for this frame and generating a new value which is + * weighted between the two. The higher autosync is, the + * closer to the delay value gets to that which "-nosound" + * would have used, and the longer it will take for A/V + * sync to settle at the right value (but it eventually will.) + * This settling time is very short for values below 100. + */ + float predicted = sh_audio->timer-sh_video->timer+time_frame; + float difference = delay - predicted; + delay = predicted + difference / (float)autosync; + } + time_frame=sh_video->timer; time_frame-=sh_audio->timer-delay; @@ -1565,6 +1592,22 @@ // unplayed bytes in our and soundcard/dma buffer: float delay=audio_out->get_delay()+(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps; + if (autosync){ + /* + * If autosync is enabled, the value for delay must be calculated + * a bit differently. It is set only to the difference between + * the audio and video timers. Any attempt to include the real + * or corrected delay causes the pts_correction code below to + * try to correct for the changes in delay which autosync is + * trying to measure. This keeps the two from competing, but still + * allows the code to correct for PTS drift *only*. (Using a delay + * value here, even a "corrected" one, would be incompatible with + * autosync mode.) + */ + delay=sh_audio->timer-sh_video->timer; + delay+=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps; + } + if(pts_from_bps){ // PTS = sample_no / samplerate unsigned int samples=(sh_audio->audio.dwSampleSize)?