diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_ts.c | 130 |
1 files changed, 60 insertions, 70 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 797b58e07..931316e82 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -272,7 +272,6 @@ typedef struct { unsigned int counter; unsigned int numPreview; 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; @@ -317,7 +316,6 @@ typedef struct { int pkt_size; /* TS packet size */ int pkt_offset; /* TS packet offset */ - int blockSize; int rate; int media_num; demux_ts_media media[MAX_PIDS]; @@ -332,17 +330,12 @@ typedef struct { * and audio PIDs, we keep the index of the corresponding entry * inthe media[] array. */ - unsigned int programNumber; - unsigned int pcrPid; - unsigned int pid; - unsigned int pid_count; unsigned int videoPid; unsigned int videoMedia; demux_ts_audio_track audio_tracks[MAX_AUDIO_TRACKS]; int audio_tracks_count; - int send_end_buffers; int64_t last_pts[2]; int send_newpts; int buf_flag_seek; @@ -701,17 +694,20 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, } static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, - uint8_t *buf, int packet_len, - xine_stream_t *stream) { + uint8_t *buf, int packet_len) { unsigned char *p; uint32_t header_len; int64_t pts; uint32_t stream_id; - int pkt_len; + + if (packet_len < 9) { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "demux_ts: too short PES packet header (%d bytes)\n", packet_len); + return 0; + } p = buf; - pkt_len = packet_len; /* we should have a PES packet here */ @@ -721,14 +717,14 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 0 ; } - packet_len -= 6; /* packet_len = p[4] << 8 | p[5]; */ stream_id = p[3]; + header_len = p[8]; - if (packet_len==0) - { + /* sometimes corruption on header_len causes segfault in memcpy below */ + if (header_len + 9 > packet_len) { xprintf (xine, XINE_VERBOSITY_DEBUG, - "demux_ts: error pes length 0\n"); + "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len); return 0; } @@ -739,6 +735,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, if (p[7] & 0x80) { /* pts avail */ + if (header_len < 5) { + return 0; + } + pts = (int64_t)(p[ 9] & 0x0E) << 29 ; pts |= p[10] << 22 ; pts |= (p[11] & 0xFE) << 14 ; @@ -763,17 +763,8 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->pts = pts; - header_len = p[8]; - - /* sometimes corruption on header_len causes segfault in memcpy below */ - if (header_len + 9 > pkt_len) { - xprintf (xine, XINE_VERBOSITY_DEBUG, - "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len); - return 0; - } - p += header_len + 9; - packet_len -= header_len + 3; + packet_len -= header_len + 9; if (m->descriptor_tag == STREAM_VIDEO_VC1) { m->content = p; @@ -813,7 +804,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 1; } else if((m->descriptor_tag == STREAM_AUDIO_AC3) || /* ac3 - raw */ - (p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */ + (packet_len > 1 && p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */ m->content = p; m->size = packet_len; m->type |= BUF_AUDIO_A52; @@ -833,8 +824,15 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->type |= BUF_AUDIO_DTS; return 1; + } else if (packet_len < 2) { + return 0; + } else if (m->descriptor_tag == HDMV_AUDIO_80_PCM) { + if (packet_len < 4) { + return 0; + } + m->content = p + 4; m->size = packet_len - 4; m->type |= BUF_AUDIO_LPCM_BE; @@ -864,6 +862,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 1; } else if ((p[0] & 0xF0) == 0x80) { + if (packet_len < 4) { + return 0; + } + m->content = p+4; m->size = packet_len - 4; m->type |= BUF_AUDIO_A52; @@ -880,13 +882,17 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, } } + if (packet_len < pcm_offset) { + return 0; + } + m->content = p+pcm_offset; m->size = packet_len-pcm_offset; m->type |= BUF_AUDIO_LPCM_BE; return 1; } - } else if ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) { + } else if ((stream_id & 0xf0) == 0xe0) { m->content = p; m->size = packet_len; @@ -1043,7 +1049,7 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, /* allocate the buffer here, as pes_header needs a valid buf for dvbsubs */ m->buf = m->fifo->buffer_pool_alloc(m->fifo); - if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len, this->stream)) { + if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len)) { m->buf->free_buffer(m->buf); m->buf = NULL; @@ -1175,6 +1181,15 @@ static inline int ts_payloadsize(unsigned char * tsp) return 184; } +/* check if an apid is in the list of known apids */ +static int apid_check(demux_ts_t*this, unsigned int pid) { + int i; + for (i = 0; i < this->audio_tracks_count; i++) { + if (this->audio_tracks[i].pid == pid) + return i; + } + return -1; +} /* * NAME demux_ts_parse_pmt @@ -1221,7 +1236,7 @@ static void demux_ts_parse_pmt (demux_ts_t *this, pkt+=pkt[4]; /* pointer to start of section */ offset=1; - if (this->pmt[program_count] != NULL) free(this->pmt[program_count]); + free(this->pmt[program_count]); this->pmt[program_count] = (uint8_t *) calloc(4096, sizeof(unsigned char)); this->pmt_write_ptr[program_count] = this->pmt[program_count]; @@ -1424,14 +1439,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num case ISO_13818_PART7_AUDIO: case ISO_14496_PART3_AUDIO: if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { - int i, found = 0; - for(i = 0; i < this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) { - found = 1; - break; - } - } - if(!found) { + if (apid_check(this, pid) < 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif @@ -1462,14 +1470,7 @@ 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) || (stream[i] == 0x7a)) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { - int j, found = 0; - for(j = 0; j < this->audio_tracks_count; j++) { - if(this->audio_tracks[j].pid == pid) { - found = 1; - break; - } - } - if (!found) { + if (apid_check(this, pid) < 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif @@ -1588,14 +1589,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num * FIXME: This will need expanding if we ever see a DTS or other media format here. */ if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) { - int i, found = 0; - for(i = 0; i < this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) { - found = 1; - break; - } - } - if(!found) { + if (apid_check(this,pid) < 0) { uint32_t format_identifier=0; demux_ts_get_reg_desc(this, &format_identifier, stream + 5, stream_info_length); @@ -1631,6 +1625,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num section_length -= coded_length; } +#if 0 /* * Get the current PCR PID. */ @@ -1646,6 +1641,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num #endif this->pcrPid = pid; } +#endif if ( this->stream->spu_channel>=0 && this->spu_langs_count>0 ) demux_ts_update_spu_channel( this ); @@ -1841,6 +1837,9 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, } #endif if(PCR_flag) { + if (adaptation_field_length < offset + 6) + return 0; + PCR = (((int64_t) data[offset]) & 0xFF) << 25; PCR += (int64_t) ((data[offset+1] & 0xFF) << 17); PCR += (int64_t) ((data[offset+2] & 0xFF) << 9); @@ -1855,6 +1854,9 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, offset+=6; } if(OPCR_flag) { + if (adaptation_field_length < offset + 6) + return PCR; + OPCR = data[offset] << 25; OPCR |= data[offset+1] << 17; OPCR |= data[offset+2] << 9; @@ -1884,16 +1886,6 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, return PCR; } -/* check if an apid is in the list of known apids */ -static int apid_check(demux_ts_t*this, unsigned int pid) { - int i; - for(i=0; i<this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) - return i; - } - return -1; -} - /* transport stream packet layer */ static void demux_ts_parse_packet (demux_ts_t*this) { @@ -1962,8 +1954,10 @@ static void demux_ts_parse_packet (demux_ts_t*this) { for (i=0; i < this->scrambled_npids; i++) { if (this->scrambled_pids[i] == pid) return; } - this->scrambled_pids[this->scrambled_npids] = pid; - this->scrambled_npids++; + if (this->scrambled_npids < MAX_PIDS) { + this->scrambled_pids[this->scrambled_npids] = pid; + this->scrambled_npids++; + } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID 0x%.4x is scrambled!\n", pid); return; @@ -2177,7 +2171,6 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) { this->status = DEMUX_OK ; - this->send_end_buffers = 1; this->scrambled_npids = 0; /* DVBSUB */ @@ -2394,7 +2387,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this = calloc(1, sizeof(*this)); this->stream = stream; this->input = input; - this->blockSize = PKT_SIZE; this->demux_plugin.send_headers = demux_ts_send_headers; this->demux_plugin.send_chunk = demux_ts_send_chunk; @@ -2421,8 +2413,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->pmt_write_ptr[i] = NULL; } - this->programNumber = INVALID_PROGRAM; - this->pcrPid = INVALID_PID; this->scrambled_npids = 0; this->videoPid = INVALID_PID; this->audio_tracks_count = 0; @@ -2461,7 +2451,7 @@ static const char *get_identifier (demux_class_t *this_gen) { } static const char *get_extensions (demux_class_t *this_gen) { - return "ts m2t trp"; + return "ts m2t trp m2ts mts"; } static const char *get_mimetypes (demux_class_t *this_gen) { |