diff options
author | Torsten Jager <t.jager@gmx.de> | 2013-10-14 17:44:15 +0200 |
---|---|---|
committer | Torsten Jager <t.jager@gmx.de> | 2013-10-14 17:44:15 +0200 |
commit | 0d07ee6607fd1b910cec4b2bda4520140f318fd7 (patch) | |
tree | c4c883af999332d5692d8ddaa504d228dc720fe8 /src | |
parent | c2a1e087ac54a165dbf632650143f6a90ba51784 (diff) | |
download | xine-lib-0d07ee6607fd1b910cec4b2bda4520140f318fd7.tar.gz xine-lib-0d07ee6607fd1b910cec4b2bda4520140f318fd7.tar.bz2 |
demux_real.c: better a/v sync.
Metronom does not strictly follow audio pts. They usually are too coarse
for seamless playback. Instead, it takes the latest discontinuity as a
starting point. This can lead to terrible lags for our very long audio frames
(nearly 2" for cook). So let's make sure audio has the last word here.
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_real.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 8f0ce22b9..01efe3b1c 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -158,7 +158,6 @@ typedef struct { int64_t last_pts[2]; int send_newpts; - int buf_flag_seek; int fragment_size; /* video sub-demux */ int fragment_count; @@ -971,27 +970,30 @@ static int demux_real_parse_references( demux_real_t *this) { #define WRAP_THRESHOLD 220000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 +#define PTS_BOTH 2 static void check_newpts (demux_real_t *this, int64_t pts, int video, int preview) { const int64_t diff = pts - this->last_pts[video]; - lprintf ("check_newpts %"PRId64"\n", pts); - if (!preview && pts && - (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { - - lprintf ("diff=%"PRId64"\n", diff); + if (preview) + return; - if (this->buf_flag_seek) { - _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); - this->buf_flag_seek = 0; - } else { - _x_demux_control_newpts(this->stream, pts, 0); - } - this->send_newpts = 0; - this->last_pts[1-video] = 0; + /* Metronom does not strictly follow audio pts. They usually are too coarse + for seamless playback. Instead, it takes the latest discontinuity as a + starting point. This can lead to terrible lags for our very long audio frames. + So let's make sure audio has the last word here. */ + if (this->send_newpts > video) { + _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK); + this->send_newpts = video; + this->last_pts[video] = pts; + this->last_pts[1 - video] = 0; + } else if (pts && (this->last_pts[video]) && (abs (diff) > WRAP_THRESHOLD)) { + _x_demux_control_newpts (this->stream, pts, 0); + this->send_newpts = 0; + this->last_pts[1 - video] = 0; } - if (!preview && pts ) + if (pts) this->last_pts[video] = pts; } @@ -1515,6 +1517,7 @@ static void demux_real_send_headers(demux_plugin_t *this_gen) { this->last_pts[0] = 0; this->last_pts[1] = 0; + this->send_newpts = PTS_BOTH; this->avg_bitrate = 1; @@ -1590,7 +1593,6 @@ static int demux_real_seek (demux_plugin_t *this_gen, if(this->audio_stream) this->audio_stream->sub_packet_cnt = 0; - this->buf_flag_seek = 1; _x_demux_flush_engine(this->stream); } } @@ -1602,7 +1604,7 @@ static int demux_real_seek (demux_plugin_t *this_gen, this->input->seek_time(this->input, start_time, SEEK_SET); } - this->send_newpts = 1; + this->send_newpts = PTS_BOTH; this->old_seqnum = -1; this->fragment_size = 0; |