summaryrefslogtreecommitdiff
path: root/src/demuxers/demux_ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers/demux_ts.c')
-rw-r--r--src/demuxers/demux_ts.c70
1 files changed, 27 insertions, 43 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index aae2d337d..a3ad4da07 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_ts.c,v 1.75 2003/01/10 21:11:10 miguelfreitas Exp $
+ * $Id: demux_ts.c,v 1.76 2003/01/16 22:25:54 miguelfreitas Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -188,6 +188,11 @@
#define ISO13522_STREAM 0xF3
#define PROG_STREAM_DIR 0xFF
+#define WRAP_THRESHOLD 120000
+
+#define PTS_AUDIO 0
+#define PTS_VIDEO 1
+
/*
**
** DATA STRUCTURES
@@ -255,8 +260,6 @@ typedef struct {
*/
unsigned int programNumber;
unsigned int pcrPid;
- int64_t PCR;
- int64_t last_PCR;
unsigned int pid;
unsigned int pid_count;
unsigned int videoPid;
@@ -266,7 +269,7 @@ typedef struct {
char audioLang[4];
int send_end_buffers;
- int ignore_scr_discont;
+ int64_t last_pts[2];
int send_newpts;
int buf_flag_seek;
@@ -321,14 +324,23 @@ static uint32_t demux_ts_compute_crc32(demux_ts_t*this, uint8_t *data,
return crc32;
}
-static void check_newpts( demux_ts_t*this, int64_t pts ) {
+/* redefine abs as macro to handle 64-bit diffs.
+ i guess llabs may not be available everywhere */
+#define abs(x) ( ((x)<0) ? -(x) : (x) )
+
+static void check_newpts( demux_ts_t *this, int64_t pts, int video )
+{
+ int64_t diff;
#ifdef TS_LOG
printf ("demux_ts: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n",
pts, this->send_newpts, this->buf_flag_seek);
#endif
-
- if (this->send_newpts && pts) {
+
+ diff = pts - this->last_pts[video];
+
+ if( pts &&
+ (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
if (this->buf_flag_seek) {
xine_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
@@ -337,8 +349,11 @@ static void check_newpts( demux_ts_t*this, int64_t pts ) {
xine_demux_control_newpts(this->stream, pts, 0);
}
this->send_newpts = 0;
- this->ignore_scr_discont = 1;
+ this->last_pts[1-video] = 0;
}
+
+ if( pts )
+ this->last_pts[video] = pts;
}
@@ -765,7 +780,6 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
} else {
- check_newpts(this, m->pts);
m->corrupted_pes = 0;
m->buf = m->fifo->buffer_pool_alloc(m->fifo);
memcpy(m->buf->mem, ts+len-m->size, m->size);
@@ -1455,35 +1469,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
if( adaptation_field_control & 0x2 ){
uint32_t adaptation_field_length = originalPkt[4];
if (adaptation_field_length > 0) {
- this->PCR = demux_ts_adaptation_field_parse (originalPkt+5,
- adaptation_field_length);
-
- if (pid == this->pcrPid && this->PCR) {
- int64_t scr_diff = this->PCR - this->last_PCR;
-
- /* note: comparing (abs(scr_diff) > 90000) isn't reliable
- * below because abs() give inconsistent results on int64_t
- * types */
- if ( (scr_diff > 90000 || scr_diff < -90000) && !this->send_newpts &&
- !this->ignore_scr_discont ) {
-
- buf_element_t *buf;
-
- buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->video_fifo->put (this->video_fifo, buf);
-
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
- }
- this->last_PCR = this->PCR;
- this->ignore_scr_discont = 0;
- }
+ demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length);
}
/*
* Skip adaptation header.
@@ -1516,7 +1502,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, t);
}
} else if (t == PRIVATE_STREAM1 ||
- t >= AUDIO_STREAM_S && t <= AUDIO_STREAM_E) {
+ (t >= AUDIO_STREAM_S && t <= AUDIO_STREAM_E)) {
if ( this->audioPid == INVALID_PID) {
printf ("demux_ts: auto-detected audio pid %d\n",
@@ -1543,6 +1529,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
#ifdef TS_LOG
printf ("demux_ts: Video pid: %.4x\n", pid);
#endif
+ check_newpts(this, this->media[this->videoMedia].pts, PTS_VIDEO);
demux_ts_buffer_pes (this, originalPkt+data_offset, this->videoMedia,
payload_unit_start_indicator, continuity_counter,
data_len);
@@ -1552,6 +1539,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
#ifdef TS_LOG
printf ("demux_ts: Audio pid: %.4x\n", pid);
#endif
+ check_newpts(this, this->media[this->audioMedia].pts, PTS_AUDIO);
demux_ts_buffer_pes (this, originalPkt+data_offset, this->audioMedia,
payload_unit_start_indicator, continuity_counter,
data_len);
@@ -1693,14 +1681,12 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) {
this->input->seek (this->input, 0, SEEK_SET);
this->send_newpts = 1;
- this->ignore_scr_discont = 0;
demux_ts_build_crc32_table (this);
this->status = DEMUX_OK ;
this->send_end_buffers = 1;
- this->last_PCR = 0;
this->scrambled_npids = 0;
/* DVBSUB */
@@ -1729,7 +1715,6 @@ static int demux_ts_seek (demux_plugin_t *this_gen,
}
this->send_newpts = 1;
- this->ignore_scr_discont = 0;
for (i=0; i<MAX_PIDS; i++) {
demux_ts_media *m = &this->media[i];
@@ -1967,7 +1952,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->programNumber = INVALID_PROGRAM;
this->pcrPid = INVALID_PID;
- this->PCR = 0;
this->scrambled_npids = 0;
this->videoPid = INVALID_PID;
this->audioPid = INVALID_PID;