summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2013-10-14 17:44:15 +0200
committerTorsten Jager <t.jager@gmx.de>2013-10-14 17:44:15 +0200
commit0d07ee6607fd1b910cec4b2bda4520140f318fd7 (patch)
treec4c883af999332d5692d8ddaa504d228dc720fe8 /src
parentc2a1e087ac54a165dbf632650143f6a90ba51784 (diff)
downloadxine-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.c36
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;