mirror of https://github.com/mpv-player/mpv
new opt: -autosync, controls ao->get_delay() smoothing (default: disabled)
patch by Sidik Isani <lksi@cfht.hawaii.edu> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7577 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
c9948174b9
commit
e93dfc0147
|
@ -159,14 +159,26 @@ available. The number you specify will be the maximum level used. Usually you
|
|||
can use some big number. You may not use it together with \-pp but it is OK
|
||||
with \-npp!
|
||||
.TP
|
||||
.B \-autosync <factor>
|
||||
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.
|
||||
|
|
|
@ -349,6 +349,8 @@ static config_t mplayer_opts[]={
|
|||
{"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},
|
||||
|
||||
|
|
45
mplayer.c
45
mplayer.c
|
@ -164,6 +164,9 @@ static off_t seek_to_byte=0;
|
|||
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 @@ if(!sh_video) {
|
|||
}
|
||||
#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 @@ if(!sh_video) {
|
|||
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 @@ if(time_frame>0.001 && !(vo_flags&256)){
|
|||
// 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)?
|
||||
|
|
Loading…
Reference in New Issue