diff options
author | phintuka <phintuka> | 2007-05-17 17:36:26 +0000 |
---|---|---|
committer | phintuka <phintuka> | 2007-05-17 17:36:26 +0000 |
commit | eeffeb6fbba38d2f622f81189308d82c7954250a (patch) | |
tree | e59a4761cd97e3f3a7cdaba3d8a3dc448f9f9c40 /xine_input_vdr.c | |
parent | 55e56beb2ba39740370c8654c6c4b9abdd315ba7 (diff) | |
download | xineliboutput-eeffeb6fbba38d2f622f81189308d82c7954250a.tar.gz xineliboutput-eeffeb6fbba38d2f622f81189308d82c7954250a.tar.bz2 |
PTS wrap workaround for mpeg_block demuxer
Diffstat (limited to 'xine_input_vdr.c')
-rw-r--r-- | xine_input_vdr.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/xine_input_vdr.c b/xine_input_vdr.c index 86ad7b18..0ee21494 100644 --- a/xine_input_vdr.c +++ b/xine_input_vdr.c @@ -4,7 +4,7 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: xine_input_vdr.c,v 1.81 2007-05-17 17:28:11 phintuka Exp $ + * $Id: xine_input_vdr.c,v 1.82 2007-05-17 17:36:26 phintuka Exp $ * */ @@ -286,6 +286,7 @@ typedef struct vdr_input_plugin_s { uint64_t curpos; /* current position (demux side) */ int curframe; int max_buffers; /* max no. of non-demuxed buffers */ + int64_t last_delivered_vid_pts; /* detect PTS wraps */ /* saved video properties */ int video_properties_saved; @@ -880,7 +881,7 @@ static char *strn0cpy(char *dest, const char *src, int n) static int64_t pts_from_pes(const uint8_t *buf, int size) { int64_t pts = -1; - if(size>13 && buf[7] & 0x80) { /* pts avail */ + if(size > 13 && buf[7] & 0x80) { /* pts avail */ pts = ((int64_t)( buf[ 9] & 0x0E)) << 29; pts |= (int64_t)( buf[10] << 22 ); pts |= (int64_t)((buf[11] & 0xFE) << 14 ); @@ -890,6 +891,18 @@ static int64_t pts_from_pes(const uint8_t *buf, int size) return pts; } +static void pes_strip_pts(uint8_t *buf, int size) +{ + if(size > 13 && buf[7] & 0x80) { /* pts avail */ + if ((buf[6] & 0xC0) != 0x80) + return; + if ((buf[6] & 0x30) != 0) + return; + buf[7] &= ~0x80; /* clear pts flag */ + memmove(buf+9, buf+14, size-14); + } +} + static void create_timeout_time(struct timespec *abstime, int timeout_ms) { struct timeval now; @@ -2955,9 +2968,10 @@ LOGMSG(" pip stream created"); static int handle_control_osdscaling(vdr_input_plugin_t *this, const char *cmd) { - int err = CONTROL_OK; + int err = CONTROL_OK, tmp; pthread_mutex_lock(&this->osd_lock); - if(1 == sscanf(cmd, "OSDSCALING %d", &this->rescale_osd)) { + if(1 == sscanf(cmd, "OSDSCALING %d", &tmp)) { + this->rescale_osd = tmp ? 1 : 0; this->rescale_osd_downscale = strstr(cmd, "NoDownscale") ? 0 : 1; this->unscaled_osd = strstr(cmd, "UnscaledAlways") ? 1 : 0; this->unscaled_osd_opaque = strstr(cmd, "UnscaledOpaque") ? 1 : 0; @@ -4829,6 +4843,7 @@ static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen, /* Handle discard */ if(this->discard_index > this->curpos && this->guard_index < this->curpos) { + this->last_delivered_vid_pts = INT64_C(-1); pthread_mutex_unlock(&this->lock); buf->free_buffer(buf); buf = NULL; @@ -4843,6 +4858,7 @@ static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen, /* Send current PTS ? */ if(this->stream_start) { + this->last_delivered_vid_pts = INT64_C(-1); this->send_pts = 1; this->stream_start = 0; pthread_mutex_lock (&this->stream->first_frame_lock); @@ -4860,6 +4876,26 @@ static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen, track_audio_stream_change(this, buf); +#if 1 + /* PTS wrap workaround for mpeg_block demuxer */ + { + int64_t pts = pts_from_pes(buf->content, buf->size); + if(pts >= 0) { + int video = ( buf->content[3] >= 0xe0 && buf->content[3] <= 0xef ); + if(video) + this->last_delivered_vid_pts = pts; + if(!video) { + if(pts > 0x40400000 && + this->last_delivered_vid_pts < 0x40000000 && + this->last_delivered_vid_pts > 0) { + LOGMSG("VIDEO pts wrap before AUDIO, ignoring audio pts %" PRId64, pts); + pes_strip_pts(buf->content, buf->size); + } + } + } + } +#endif + /* Send current PTS ? */ if(this->send_pts) { int64_t pts = pts_from_pes(buf->content, buf->size); @@ -5878,6 +5914,7 @@ static input_plugin_t *vdr_class_get_instance (input_class_t *cls_gen, this->guard_index = 0; this->curpos = 0; this->max_buffers = 10; + this->last_delivered_vid_pts = INT64_C(-1); this->scr = NULL; |