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.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 86a14f019..98de1f9ea 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -185,9 +185,6 @@
#define INVALID_PROGRAM ((unsigned int)(-1))
#define INVALID_CC ((unsigned int)(-1))
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
#define PROG_STREAM_MAP 0xBC
#define PRIVATE_STREAM1 0xBD
#define PADDING_STREAM 0xBE
@@ -220,7 +217,9 @@
ISO_13818_PART7_AUDIO = 0x0f, /* ISO/IEC 13818-7 Audio with ADTS transport sytax */
ISO_14496_PART2_VIDEO = 0x10, /* ISO/IEC 14496-2 Visual (MPEG-4) */
ISO_14496_PART3_AUDIO = 0x11, /* ISO/IEC 14496-3 Audio with LATM transport syntax */
- ISO_14496_PART10_VIDEO = 0x1b /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
+ ISO_14496_PART10_VIDEO = 0x1b, /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
+ STREAM_VIDEO_MPEG = 0x80,
+ STREAM_AUDIO_AC3 = 0x81,
} streamType;
#define WRAP_THRESHOLD 270000
@@ -246,10 +245,11 @@ typedef struct {
int64_t pts;
buf_element_t *buf;
unsigned int counter;
- uint8_t descriptor_tag;
+ uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
int64_t packet_count;
int corrupted_pes;
uint32_t buffered_bytes;
+ int autodetected;
} demux_ts_media;
@@ -752,15 +752,16 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
* we check the descriptor tag first because some stations
* do not include any of the ac3 header info in their audio tracks
* these "raw" streams may begin with a byte that looks like a stream type.
+ * For audio streams, m->type already contains the stream no.
*/
- if((m->descriptor_tag == 0x81) || /* ac3 - raw */
+ if((m->descriptor_tag == STREAM_AUDIO_AC3) || /* ac3 - raw */
(p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */
m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_A52;
return 1;
- } else if (m->descriptor_tag == 0x06
+ } else if (m->descriptor_tag == ISO_13818_PES_PRIVATE
&& p[0] == 0x20 && p[1] == 0x00) {
/* DVBSUB */
long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
@@ -808,6 +809,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
switch (m->descriptor_tag) {
case ISO_11172_VIDEO:
case ISO_13818_VIDEO:
+ case STREAM_VIDEO_MPEG:
lprintf ("demux_ts: found MPEG video type.\n");
m->type = BUF_VIDEO_MPEG;
break;
@@ -931,9 +933,11 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
m->buf->free_buffer(m->buf);
m->buf = NULL;
- if (m->corrupted_pes > CORRUPT_PES_THRESHOLD) {
- if (this->videoPid == m->pid)
+ if (m->corrupted_pes > CORRUPT_PES_THRESHOLD && m->autodetected) {
+ if (this->videoPid == m->pid) {
this->videoPid = INVALID_PID;
+ this->last_pmt_crc = 0;
+ }
} else {
m->corrupted_pes++;
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -982,7 +986,7 @@ static void demux_ts_pes_new(demux_ts_t*this,
unsigned int mediaIndex,
unsigned int pid,
fifo_buffer_t *fifo,
- uint8_t descriptor) {
+ uint16_t descriptor) {
demux_ts_media *m = &this->media[mediaIndex];
@@ -1193,6 +1197,15 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
return;
}
+ if (!section_length) {
+ free (this->pmt[program_count]);
+ this->pmt[program_count] = NULL;
+#ifdef TS_PMT_LOG
+ printf ("ts_demux: eek, zero-length section?\n");
+#endif
+ return;
+ }
+
#ifdef TS_PMT_LOG
printf ("ts_demux: have all TS packets for the PMT section\n");
#endif
@@ -1230,6 +1243,15 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
}
}
+ /*
+ * Forget the current video, audio and subtitle PIDs; if the PMT has not
+ * changed, we'll pick them up again when we parse this PMT, while if the
+ * PMT has changed (e.g. an IPTV streamer that's just changed its source),
+ * we'll get new PIDs that we should follow.
+ */
+ this->audio_tracks_count = 0;
+ this->videoPid = INVALID_PID;
+ this->spu_pid = INVALID_PID;
/*
* ES definitions start here...we are going to learn upto one video
@@ -1331,7 +1353,6 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
case ISO_13818_PES_PRIVATE:
for (i = 5; i < coded_length; i += stream[i+1] + 2) {
if ((stream[i] == 0x6a) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) {
- uint32_t format_identifier=0;
int i, found = 0;
for(i = 0; i < this->audio_tracks_count; i++) {
if(this->audio_tracks[i].pid == pid) {
@@ -1344,7 +1365,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
#endif
demux_ts_pes_new(this, this->media_num, pid,
- this->audio_fifo, 0x81);
+ this->audio_fifo, STREAM_AUDIO_AC3);
this->audio_tracks[this->audio_tracks_count].pid = pid;
this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
@@ -1555,7 +1576,7 @@ static unsigned char * demux_synchronise(demux_ts_t* this) {
do {
read_length = this->input->read(this->input, this->buf,
PKT_SIZE * NPKT_PER_READ);
- if (read_length % PKT_SIZE) {
+ if (read_length < 0 || read_length % PKT_SIZE) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_ts: read returned %d bytes (not a multiple of %d!)\n",
read_length, PKT_SIZE);
@@ -1837,7 +1858,8 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
} else if (!found) {
this->videoPid = pid;
this->videoMedia = this->media_num;
- demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, pes_stream_id);
+ this->media[this->videoMedia].autodetected = 1;
+ demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, 0x100 + pes_stream_id);
}
if (this->videoPid != INVALID_PID) {
@@ -1859,11 +1881,12 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_ts: auto-detected audio pid 0x%.4x\n", pid);
#endif
+ /* store PID, index and stream no. */
this->audio_tracks[this->audio_tracks_count].pid = pid;
this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
this->media[this->media_num].type = this->audio_tracks_count;
demux_ts_pes_new(this, this->media_num++, pid,
- this->audio_fifo,pes_stream_id);
+ this->audio_fifo, 0x100 + pes_stream_id);
this->audio_tracks_count++;
}
}
@@ -2229,7 +2252,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc(sizeof(*this));
+ this = calloc(1, sizeof(*this));
this->stream = stream;
this->input = input;
this->blockSize = PKT_SIZE;
@@ -2250,6 +2273,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
for (i = 0; i < MAX_PIDS; i++) {
this->media[i].pid = INVALID_PID;
this->media[i].buf = NULL;
+ this->media[i].autodetected = 0;
}
for (i = 0; i < MAX_PMTS; i++) {
@@ -2270,12 +2294,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->status = DEMUX_FINISHED;
-#ifdef TS_READ_STATS
- for (i=0; i<=NPKT_PER_READ; i++) {
- this->rstat[i] = 0;
- }
-#endif
-
/* DVBSUB */
this->spu_pid = INVALID_PID;
this->spu_langs_count = 0;
@@ -2320,7 +2338,7 @@ static void *init_class (xine_t *xine, void *data) {
demux_ts_class_t *this;
- this = xine_xmalloc (sizeof (demux_ts_class_t));
+ this = calloc(1, sizeof(demux_ts_class_t));
this->config = xine->config;
this->xine = xine;