diff options
-rw-r--r-- | xine/demux_xvdr.c | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/xine/demux_xvdr.c b/xine/demux_xvdr.c index 04fcc634..652c34e2 100644 --- a/xine/demux_xvdr.c +++ b/xine/demux_xvdr.c @@ -150,18 +150,34 @@ static int32_t parse_padding_stream(demux_xvdr_t *this, uint8_t *p, buf_element_ static void pts_wrap_workaround(demux_xvdr_t *this, buf_element_t *buf, int video) { + /* PTS wrap workaround */ + if (buf->pts > 0) { + #ifdef LOG_PES_AV_DIFF - static int64_t vpts = 0, apts = 0; - if (video) vpts = buf->pts; - else apts = buf->pts; - if (vpts > 0 && apts > 0) - LOGMSG("pts diff [%d] %d", video, (int)(vpts - apts)); + static int64_t vpts = 0, apts = 0; + if (video) vpts = buf->pts; + else apts = buf->pts; + if (vpts > 0 && apts > 0) + LOGMSG("pts diff [%d] %d", video, (int)(vpts - apts)); #endif - /* PTS wrap workaround */ - if (buf->pts >= 0) { - if (video) + if (video) { + + /* VIDEO wrap in middle of GOP */ + if (this->last_vpts < 14400 && + this->last_vpts > 0 && + buf->pts > (INT64_C(0x1ffffffff) - 14400) && + !this->send_newpts) { + LOGMSG("VIDEO pts wrap in middle of GOP, ignoring video pts %" PRId64, buf->pts); + buf->pts = INT64_C(0); + return; + } + this->last_vpts = buf->pts; + return; + } + + /* VIDEO wrap before AUDIO wrap */ else if (buf->pts > INT64_C( 0x40400000 ) && this->last_vpts < INT64_C( 0x40000000 ) && this->last_vpts > INT64_C( 0 )) { @@ -173,23 +189,27 @@ static void pts_wrap_workaround(demux_xvdr_t *this, buf_element_t *buf, int vide static void check_newpts(demux_xvdr_t *this, buf_element_t *buf, int video ) { - pts_wrap_workaround(this, buf, video); - - if (buf->pts) { + if (buf->pts <= 0) + return; - if (video) { - int still_mode = (int)this->stream->metronom->get_option(this->stream->metronom, XVDR_METRONOM_STILL_MODE); - int trick_speed = (int)this->stream->metronom->get_option(this->stream->metronom, XVDR_METRONOM_TRICK_SPEED); - if (still_mode > 0 || trick_speed > 0) { - LOGMSG("Skipping new pts %"PRId64" (still=%d trickspeed=%d)", buf->pts, still_mode, trick_speed); - return; - } + if (video) { + int still_mode = (int)this->stream->metronom->get_option(this->stream->metronom, XVDR_METRONOM_STILL_MODE); + int trick_speed = (int)this->stream->metronom->get_option(this->stream->metronom, XVDR_METRONOM_TRICK_SPEED); + if (still_mode > 0 || trick_speed > 0) { + LOGMSG("Skipping new pts %"PRId64" (still=%d trickspeed=%d)", buf->pts, still_mode, trick_speed); + return; } + } + + pts_wrap_workaround(this, buf, video); + if (buf->pts) { int64_t diff = buf->pts - this->last_pts[video]; if (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD)) { + LOGVERBOSE("New PTS: %"PRId64" (%s)", buf->pts, video ? "VIDEO" : "AUDIO"); + if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; |