From 7a51ac9f855d90160076ea8aac125fcb41b605c6 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 12 Sep 2011 20:11:06 +0100 Subject: Count preview frames separately for all audio and video streams. Otherwise we risk not marking the first audio frame in each stream with BUF_FLAG_HEADER. This is the final fix for https://bugs.xine-project.org/show_bug.cgi?id=403 --- src/demuxers/demux_ts.c | 63 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index ed360ab38..3c758437d 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?) */ int64_t packet_count; int corrupted_pes; @@ -369,8 +370,6 @@ typedef struct { uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */ - int numPreview; - } demux_ts_t; typedef struct { @@ -944,6 +943,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 */ @@ -974,26 +981,47 @@ 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 & 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; + } + 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; @@ -1074,6 +1102,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; @@ -2414,8 +2443,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; } -- cgit v1.2.3 From dc76c437f16a4de6e1eb269749a5502cf5be6629 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sun, 11 Sep 2011 20:24:21 +0100 Subject: demux_ts_buffer_pes() is called for video, audio and DVBSUB packets only. So why does it try to handle SPU_DVD packets? DVB subtitles don't seem to work yet anyway. --- src/demuxers/demux_ts.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 3c758437d..1a8ae8f57 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -990,10 +990,8 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, switch (m->type & BUF_MAJOR_MASK) { case BUF_SPU_BASE: - 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; + if( (m->buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB ) { + /* TODO: DVBSUB handling needed? */ } break; -- cgit v1.2.3 From 51b8690e53ba175c585634df6ce6df9fdda65343 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sun, 11 Sep 2011 22:40:18 +0100 Subject: Update parsing of program numbers from PATs. The order of programs is assumed not to change among otherwise identical PATs. (Not an unreasonable assumption). --- src/demuxers/demux_ts.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 1a8ae8f57..797b58e07 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -646,7 +646,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]; @@ -658,18 +658,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) { @@ -693,6 +689,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; } } -- cgit v1.2.3