diff options
Diffstat (limited to 'src/demuxers/demux_ts.c')
-rw-r--r-- | src/demuxers/demux_ts.c | 64 |
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; |