diff options
Diffstat (limited to 'src/demuxers/demux_ts.c')
-rw-r--r-- | src/demuxers/demux_ts.c | 90 |
1 files changed, 60 insertions, 30 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index aea0c8ca1..07f466adb 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -180,6 +180,8 @@ #define MAX_PES_BUF_SIZE 2048 +#define CORRUPT_PES_THRESHOLD 10 + #define NULL_PID 0x1fff #define INVALID_PID ((unsigned int)(-1)) #define INVALID_PROGRAM ((unsigned int)(-1)) @@ -337,9 +339,10 @@ typedef struct { int32_t packet_number; /* NEW: var to keep track of number of last read packets */ int32_t npkt_read; - int32_t read_zero; uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */ + + int numPreview; } demux_ts_t; @@ -683,7 +686,11 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, stream_id = p[3]; if (packet_len==0) + { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "demux_ts: error pes length 0\n"); return 0; + } #ifdef TS_LOG printf ("demux_ts: packet stream id: %.2x len: %d (%x)\n", @@ -890,6 +897,16 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; } + else { + if (this->numPreview<5) + ++this->numPreview; + if ( this->numPreview==1 ) + m->buf->decoder_flags=BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; + else if ( this->numPreview<5 ) + m->buf->decoder_flags=BUF_FLAG_PREVIEW; + else + m->buf->decoder_flags=BUF_FLAG_FRAME_END; + } m->buf->pts = m->pts; m->buf->decoder_info[0] = 1; @@ -910,12 +927,17 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, m->buf = m->fifo->buffer_pool_alloc(m->fifo); if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len, this->stream)) { - m->corrupted_pes = 1; m->buf->free_buffer(m->buf); m->buf = NULL; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + + if (m->corrupted_pes > CORRUPT_PES_THRESHOLD) { + if (this->videoPid == m->pid) + this->videoPid = INVALID_PID; + } else { + m->corrupted_pes++; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID 0x%.4x: corrupted pes encountered\n", m->pid); - + } } else { m->corrupted_pes = 0; @@ -1244,7 +1266,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num case ISO_14496_PART10_VIDEO: if (this->videoPid == INVALID_PID) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT video pid 0x%.4x\n", pid); + printf ("demux_ts: PMT video pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif demux_ts_pes_new(this, this->media_num, pid, this->video_fifo,stream[0]); this->videoMedia = this->media_num; @@ -1266,7 +1288,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num } if(!found) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT audio pid 0x%.4x\n", pid); + printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo,stream[0]); this->audio_tracks[this->audio_tracks_count].pid = pid; @@ -1280,7 +1302,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num break; case ISO_13818_PRIVATE: #ifdef TS_PMT_LOG - printf ("demux_ts: PMT streamtype 13818_PRIVATE, pid: 0x%.4x\n", pid); + printf ("demux_ts: PMT streamtype 13818_PRIVATE, pid: 0x%.4x type %2.2x\n", pid, stream[0]); for (i = 5; i < coded_length; i++) printf ("%.2x ", stream[i]); @@ -1289,13 +1311,12 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num break; case ISO_13818_TYPE_C: /* data carousel */ #ifdef TS_PMT_LOG - printf ("demux_ts: PMT streamtype 13818_TYPE_C, pid: 0x%.4x\n", pid); + printf ("demux_ts: PMT streamtype 13818_TYPE_C, pid: 0x%.4x type %2.2x\n", pid, stream[0]); #endif break; 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) { @@ -1305,7 +1326,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num } if(!found) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT AC3 audio pid 0x%.4x\n", pid); + 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); @@ -1323,7 +1344,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num else if (stream[i] == 0x56) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT Teletext, pid: 0x%.4x\n", pid); + printf ("demux_ts: PMT Teletext, pid: 0x%.4x type %2.2x\n", pid, stream[0]); for (i = 5; i < coded_length; i++) printf ("%.2x ", stream[i]); @@ -1358,10 +1379,11 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num pid, this->video_fifo, stream[0]); #ifdef TS_LOG - printf("demux_ts: DVBSUB: pid 0x%.4x: %s page %ld %ld\n", + printf("demux_ts: DVBSUB: pid 0x%.4x: %s page %ld %ld type %2.2x\n", pid, lang->desc.lang, lang->desc.comp_page_id, - lang->desc.aux_page_id); + lang->desc.aux_page_id, + stream[0]); #endif } } @@ -1531,12 +1553,7 @@ static unsigned char * demux_synchronise(demux_ts_t* this) { */ if (this->npkt_read == 0) { - /* printf ("demux_ts: read 0 packets! (%d)\n", this->read_zero); */ - this->read_zero++; - } else this->read_zero = 0; - - if (this->read_zero > 200) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read 0 packets too many times!\n"); + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read 0 packets\n"); this->status = DEMUX_FINISHED; return NULL; } @@ -1785,13 +1802,27 @@ static void demux_ts_parse_packet (demux_ts_t*this) { if ( (pes_stream_id >= VIDEO_STREAM_S) && (pes_stream_id <= VIDEO_STREAM_E) ) { if ( this->videoPid == INVALID_PID) { - - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_ts: auto-detected video pid 0x%.4x\n", pid); - - this->videoPid = pid; - this->videoMedia = this->media_num; - demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, pes_stream_id); + int i, found = 0; + for(i = 0; i < this->media_num; i++) { + if (this->media[i].pid == pid) { + found = 1; + break; + } + } + + if (found && (this->media[i].corrupted_pes == 0)) { + this->videoPid = pid; + this->videoMedia = i; + } 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); + } + + if (this->videoPid != INVALID_PID) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_ts: auto-detected video pid 0x%.4x\n", pid); + } } } else if ( (pes_stream_id >= AUDIO_STREAM_S) && (pes_stream_id <= AUDIO_STREAM_E) ) { if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { @@ -2061,7 +2092,6 @@ static int demux_ts_get_optional_data(demux_plugin_t *this_gen, demux_ts_t *this = (demux_ts_t *) this_gen; char *str = data; int channel = *((int *)data); - int track_num; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) @@ -2227,9 +2257,7 @@ 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; - } + memset(this-rstat, 0, sizeof(*this->rstat)*NPKT_PER_READ); #endif /* DVBSUB */ @@ -2240,6 +2268,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, /* dvb */ this->event_queue = xine_event_new_queue (this->stream); + this->numPreview=0; + return &this->demux_plugin; } |