summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_ts.c87
1 files changed, 58 insertions, 29 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index ce2755ee0..931316e82 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -270,6 +270,7 @@ typedef struct {
int64_t pts;
buf_element_t *buf;
unsigned int counter;
+ unsigned int numPreview;
uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
int corrupted_pes;
uint32_t buffered_bytes;
@@ -362,8 +363,6 @@ typedef struct {
uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */
- int numPreview;
-
} demux_ts_t;
typedef struct {
@@ -640,7 +639,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
*/
program_count = 0;
for (program = pkt + 13;
- program < pkt + 13 + section_length - 9;
+ (program < pkt + 13 + section_length - 9) && (program_count < MAX_PMTS);
program += 4) {
program_number = ((unsigned int)program[0] << 8) | program[1];
pmt_pid = (((unsigned int)program[2] & 0x1f) << 8) | program[3];
@@ -652,18 +651,14 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
continue;
/*
- * If we have yet to learn our program number, then learn it,
- * use this loop to eventually add support for dynamically changing
- * PATs.
+ * Add the program number to the table if we haven't already
+ * seen it. The order of the program numbers is assumed not
+ * to change between otherwise identical PATs.
*/
- program_count = 0;
-
- while ((this->program_number[program_count] != INVALID_PROGRAM) &&
- (this->program_number[program_count] != program_number) &&
- (program_count+1 < MAX_PMTS ) ) {
- program_count++;
+ if (this->program_number[program_count] != program_number) {
+ this->program_number[program_count] = program_number;
+ this->pmt_pid[program_count] = INVALID_PID;
}
- this->program_number[program_count] = program_number;
/* force PMT reparsing when pmt_pid changes */
if (this->pmt_pid[program_count] != pmt_pid) {
@@ -687,6 +682,14 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
this->program_number[program_count],
this->pmt_pid[program_count]);
#endif
+
+ ++program_count;
+ }
+
+ /* Add "end of table" markers. */
+ if (program_count < MAX_PMTS) {
+ this->program_number[program_count] = INVALID_PROGRAM;
+ this->pmt_pid[program_count] = INVALID_PID;
}
}
@@ -951,6 +954,14 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
/*
+ * Track how many of these types of packets we have seen in this stream.
+ */
+static inline unsigned get_preview_frame_number(unsigned *numPreview, unsigned limit) {
+ unsigned preview = *numPreview;
+ return (preview < limit) ? ++(*numPreview) : preview;
+}
+
+/*
* buffer arriving pes data
*/
static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
@@ -980,26 +991,45 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
m->counter++;
if (pus) { /* new PES packet */
-
if (m->buffered_bytes) {
+ unsigned previewLimit = 0;
+
m->buf->content = m->buf->mem;
m->buf->size = m->buffered_bytes;
m->buf->type = m->type;
- if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) {
- m->buf->decoder_flags |= BUF_FLAG_SPECIAL;
- m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
- m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
+
+ switch (m->type & BUF_MAJOR_MASK) {
+ case BUF_SPU_BASE:
+ if( (m->buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB ) {
+ /* TODO: DVBSUB handling needed? */
+ }
+ break;
+
+ case BUF_VIDEO_BASE:
+ previewLimit = 5;
+ break;
+
+ case BUF_AUDIO_BASE:
+ previewLimit = 2;
+ break;
+
+ default:
+ break;
}
- 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;
+
+ if (previewLimit != 0) {
+ unsigned numPreview;
+
+ numPreview = get_preview_frame_number(&m->numPreview, previewLimit);
+
+ if (numPreview == 1)
+ m->buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
+ else if (numPreview < previewLimit)
+ 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;
@@ -1080,6 +1110,7 @@ static void demux_ts_pes_new(demux_ts_t*this,
if (m->buf != NULL) m->buf->free_buffer(m->buf);
m->buf = NULL;
m->counter = INVALID_CC;
+ m->numPreview = 0;
m->descriptor_tag = descriptor;
m->corrupted_pes = 1;
m->buffered_bytes = 0;
@@ -2404,8 +2435,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->pkt_offset = (hdmv > 0) ? 4 : 0;
this->pkt_size = PKT_SIZE + this->pkt_offset;
- this->numPreview=0;
-
return &this->demux_plugin;
}