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.c90
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;
}