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.c476
1 files changed, 200 insertions, 276 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 38eca0bbb..bd67c269e 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -146,6 +146,13 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
+#include <arpa/inet.h>
+
+#ifdef HAVE_FFMPEG_AVUTIL_H
+# include <crc.h>
+#else
+# include <libavutil/crc.h>
+#endif
#define LOG_MODULE "demux_ts"
#define LOG_VERBOSE
@@ -153,9 +160,9 @@
#define LOG
*/
-#include "xine_internal.h"
-#include "xineutils.h"
-#include "demux.h"
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
+#include <xine/demux.h>
/*
#define TS_LOG
@@ -174,7 +181,10 @@
#define BODY_SIZE (188 - 4)
/* more PIDS are needed due "auto-detection". 40 spare media entries */
#define MAX_PIDS ((BODY_SIZE - 1 - 13) / 4) + 40
-#define MAX_PMTS ((BODY_SIZE - 1 - 13) / 4) + 10
+
+#define MAX_PMTS 128
+#define PAT_BUF_SIZE (4 * MAX_PMTS + 20)
+
#define SYNC_BYTE 0x47
#define MIN_SYNCS 3
@@ -319,6 +329,18 @@ typedef struct {
} demux_ts_audio_track;
typedef struct {
+
+ demux_class_t demux_class;
+
+ /* class-wide, global variables here */
+
+ xine_t *xine;
+ config_values_t *config;
+
+ const AVCRC *av_crc;
+} demux_ts_class_t;
+
+typedef struct {
/*
* The first field must be the "base class" for the plugin!
*/
@@ -334,25 +356,29 @@ typedef struct {
input_plugin_t *input;
unsigned int read_retries;
+ demux_ts_class_t *class;
+
int status;
int hdmv; /* -1 = unknown, 0 = mpeg-ts, 1 = hdmv/m2ts */
int pkt_size; /* TS packet size */
int pkt_offset; /* TS packet offset */
+ int blockSize;
int rate;
unsigned int media_num;
demux_ts_media media[MAX_PIDS];
/* PAT */
+ uint8_t pat[PAT_BUF_SIZE];
+ int pat_write_pos;
uint32_t last_pat_crc;
uint32_t transport_stream_id;
/* programs */
uint32_t program_number[MAX_PMTS];
uint32_t pmt_pid[MAX_PMTS];
uint8_t *pmt[MAX_PMTS];
- uint8_t *pmt_write_ptr[MAX_PMTS];
- uint32_t crc32_table[256];
+ int pmt_write_pos[MAX_PMTS];
uint32_t last_pmt_crc;
/*
* Stuff to do with the transport header. As well as the video
@@ -402,15 +428,6 @@ typedef struct {
} demux_ts_t;
-typedef struct {
-
- demux_class_t demux_class;
-
- /* class-wide, global variables here */
-
- xine_t *xine;
- config_values_t *config;
-} demux_ts_class_t;
static void reset_track_map(fifo_buffer_t *fifo)
{
@@ -443,7 +460,7 @@ static int demux_ts_dynamic_pmt_find (demux_ts_t *this,
if (i < MAX_PIDS) {
/* prepare new media descriptor */
#ifdef LOG_DYNAMIC_PMT
- char *name = "";
+ const char *name = "";
if (type == BUF_VIDEO_BASE) name = "video";
else if (type == BUF_AUDIO_BASE) name = "audio";
else if (type == BUF_SPU_BASE) name = "subtitle";
@@ -523,7 +540,7 @@ static void demux_ts_dynamic_pmt_clean (demux_ts_t *this) {
} else {
/* drop this no longer needed media descriptor */
#ifdef LOG_DYNAMIC_PMT
- char *name = "";
+ const char *name = "";
if (type == BUF_VIDEO_BASE) name = "video";
else if (type == BUF_AUDIO_BASE) name = "audio";
else if (type == BUF_SPU_BASE) name = "subtitle";
@@ -611,28 +628,6 @@ static void demux_ts_tbre_update (demux_ts_t *this, unsigned int mode, int64_t n
this->tbre_lasttime = now;
}
-static void demux_ts_build_crc32_table(demux_ts_t*this) {
- uint32_t i, j, k;
-
- for( i = 0 ; i < 256 ; i++ ) {
- k = 0;
- for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1) {
- k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
- }
- this->crc32_table[i] = k;
- }
-}
-
-static uint32_t demux_ts_compute_crc32(demux_ts_t*this, uint8_t *data,
- int32_t length, uint32_t crc32) {
- int32_t i;
-
- for(i = 0; i < length; i++) {
- crc32 = (crc32 << 8) ^ this->crc32_table[(crc32 >> 24) ^ data[i]];
- }
- return crc32;
-}
-
/* redefine abs as macro to handle 64-bit diffs.
i guess llabs may not be available everywhere */
#define abs(x) ( ((x)<0) ? -(x) : (x) )
@@ -808,14 +803,12 @@ static void demux_ts_flush(demux_ts_t *this)
* demux_ts_parse_pat
*
* Parse a program association table (PAT).
- * The PAT is expected to be exactly one section long,
- * and that section is expected to be contained in a single TS packet.
+ * The PAT is expected to be exactly one section long.
*
- * The PAT is assumed to contain a single program definition, though
- * we can cope with the stupidity of SPTSs which contain NITs.
+ * We can cope with the stupidity of SPTSs which contain NITs.
*/
static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
- unsigned char *pkt, unsigned int pusi) {
+ unsigned char *pkt, unsigned int pusi, int len) {
#ifdef TS_PAT_LOG
uint32_t table_id;
uint32_t version_number;
@@ -834,47 +827,67 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
unsigned int pmt_pid;
unsigned int program_count;
- /*
- * A PAT in a single section should start with a payload unit start
- * indicator set.
- */
- if (!pusi) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PAT without payload unit start indicator\n");
- return;
+ /* reassemble the section */
+ if (pusi) {
+ this->pat_write_pos = 0;
+ /* offset the section by n + 1 bytes. this is sometimes used to let it end
+ at an exact TS packet boundary */
+ len -= (unsigned int)pkt[0] + 1;
+ pkt += (unsigned int)pkt[0] + 1;
+ if (len < 1) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_ts: demux error! PAT with invalid pointer\n");
+ return;
+ }
+ } else {
+ if (!this->pat_write_pos)
+ return;
}
+ if (len > PAT_BUF_SIZE - this->pat_write_pos)
+ len = PAT_BUF_SIZE - this->pat_write_pos;
+ memcpy (this->pat + this->pat_write_pos, pkt, len);
+ this->pat_write_pos +=len;
- /*
- * sections start with a pointer. Skip it!
- */
- pkt += pkt[4];
- if (pkt - original_pkt > PKT_SIZE) {
+ /* lets see if we got the section length already */
+ pkt = this->pat;
+ if (this->pat_write_pos < 3)
+ return;
+ section_length = ((((uint32_t)pkt[1] << 8) | pkt[2]) & 0x03ff) + 3;
+ /* this should be at least the head plus crc */
+ if (section_length < 8 + 4) {
+ this->pat_write_pos = 0;
+ return;
+ }
+ /* and it should fit into buf */
+ if (section_length > PAT_BUF_SIZE) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PAT with invalid pointer\n");
+ "demux_ts: PAT too large (%d bytes)\n", section_length);
+ this->pat_write_pos = 0;
return;
}
+
+ /* lets see if we got the section complete */
+ if (this->pat_write_pos < section_length)
+ return;
+
+ /* OK now parse it */
+ this->pat_write_pos = 0;
#ifdef TS_PAT_LOG
- table_id = (unsigned int)pkt[5] ;
+ table_id = (unsigned int)pkt[0];
#endif
- section_syntax_indicator = (((unsigned int)pkt[6] >> 7) & 1) ;
- section_length = (((unsigned int)pkt[6] & 0x03) << 8) | pkt[7];
- transport_stream_id = ((uint32_t)pkt[8] << 8) | pkt[9];
+ section_syntax_indicator = (pkt[1] >> 7) & 0x01;
+ transport_stream_id = ((uint32_t)pkt[3] << 8) | pkt[4];
#ifdef TS_PAT_LOG
- version_number = ((uint32_t)pkt[10] >> 1) & 0x1f;
+ version_number = ((uint32_t)pkt[5] >> 1) & 0x1f;
#endif
- current_next_indicator = ((uint32_t)pkt[10] & 0x01);
- section_number = (uint32_t)pkt[11];
- last_section_number = (uint32_t)pkt[12];
- crc32 = (uint32_t)pkt[4+section_length] << 24;
- crc32 |= (uint32_t)pkt[5+section_length] << 16;
- crc32 |= (uint32_t)pkt[6+section_length] << 8;
- crc32 |= (uint32_t)pkt[7+section_length] ;
+ current_next_indicator = pkt[5] & 0x01;
+ section_number = pkt[6];
+ last_section_number = pkt[7];
#ifdef TS_PAT_LOG
printf ("demux_ts: PAT table_id: %.2x\n", table_id);
printf (" section_syntax: %d\n", section_syntax_indicator);
- printf (" section_length: %d (%#.3x)\n",
- section_length, section_length);
+ printf (" section_length: %d (%#.3x)\n", section_length, section_length);
printf (" transport_stream_id: %#.4x\n", transport_stream_id);
printf (" version_number: %d\n", version_number);
printf (" c/n indicator: %d\n", current_next_indicator);
@@ -882,25 +895,22 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
printf (" last_section_number: %d\n", last_section_number);
#endif
- if ((section_syntax_indicator != 1) || !(current_next_indicator)) {
- return;
- }
-
- if (pkt - original_pkt > BODY_SIZE - 1 - 3 - section_length) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME: (unsupported )PAT spans multiple TS packets\n");
+ if ((section_syntax_indicator != 1) || !current_next_indicator)
return;
- }
if ((section_number != 0) || (last_section_number != 0)) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME: (unsupported) PAT consists of multiple (%d) sections\n", last_section_number);
+ "demux_ts: FIXME (unsupported) PAT consists of multiple (%d) sections\n", last_section_number);
return;
}
/* Check CRC. */
- calc_crc32 = demux_ts_compute_crc32 (this, pkt+5, section_length+3-4,
- 0xffffffff);
+ crc32 = (uint32_t) pkt[section_length - 4] << 24;
+ crc32 |= (uint32_t) pkt[section_length - 3] << 16;
+ crc32 |= (uint32_t) pkt[section_length - 2] << 8;
+ crc32 |= (uint32_t) pkt[section_length - 1];
+
+ calc_crc32 = htonl (av_crc (this->class->av_crc, 0xffffffff, pkt, section_length - 4));
if (crc32 != calc_crc32) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_ts: demux error! PAT with invalid CRC32: packet_crc32: %.8x calc_crc32: %.8x\n",
@@ -931,8 +941,8 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
* Process all programs in the program loop.
*/
program_count = 0;
- for (program = pkt + 13;
- (program < pkt + 13 + section_length - 9) && (program_count < MAX_PMTS);
+ for (program = pkt + 8;
+ (program < pkt + section_length - 4) && (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];
@@ -961,7 +971,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
if (this->pmt[program_count] != NULL) {
free(this->pmt[program_count]);
this->pmt[program_count] = NULL;
- this->pmt_write_ptr[program_count] = NULL;
+ this->pmt_write_pos[program_count] = 0;
}
}
#ifdef TS_PAT_LOG
@@ -1403,8 +1413,7 @@ static int apid_check(demux_ts_t*this, unsigned int pid) {
/*
* NAME demux_ts_parse_pmt
*
- * Parse a PMT. The PMT is expected to be exactly one section long,
- * and that section is expected to be contained in a single TS packet.
+ * Parse a PMT. The PMT is expected to be exactly one section long.
*
* In other words, the PMT is assumed to describe a reasonable number of
* video, audio and other streams (with descriptors).
@@ -1414,6 +1423,7 @@ static void demux_ts_parse_pmt (demux_ts_t *this,
unsigned char *originalPkt,
unsigned char *pkt,
unsigned int pusi,
+ int plen,
uint32_t program_count) {
#ifdef TS_PMT_LOG
@@ -1421,7 +1431,7 @@ static void demux_ts_parse_pmt (demux_ts_t *this,
uint32_t version_number;
#endif
uint32_t section_syntax_indicator;
- uint32_t section_length = 0; /* to calm down gcc */
+ uint32_t section_length;
uint32_t program_number;
uint32_t current_next_indicator;
uint32_t section_number;
@@ -1433,154 +1443,119 @@ static void demux_ts_parse_pmt (demux_ts_t *this,
unsigned int pid;
unsigned char *stream;
unsigned int i;
- int count;
- char *ptr = NULL;
- unsigned char len;
- unsigned int offset=0;
int mi;
- /*
- * A new section should start with the payload unit start
- * indicator set. We allocate some mem (max. allowed for a PM section)
- * to copy the complete section into one chunk.
- */
+ /* reassemble the section */
if (pusi) {
- pkt+=pkt[4]; /* pointer to start of section */
- offset=1;
-
- 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];
-
-#ifdef TS_PMT_LOG
- table_id = pkt[5] ;
-#endif
- section_syntax_indicator = (pkt[6] >> 7) & 0x01;
- section_length = (((uint32_t) pkt[6] << 8) | pkt[7]) & 0x03ff;
- program_number = ((uint32_t) pkt[8] << 8) | pkt[9];
-#ifdef TS_PMT_LOG
- version_number = (pkt[10] >> 1) & 0x1f;
-#endif
- current_next_indicator = pkt[10] & 0x01;
- section_number = pkt[11];
- last_section_number = pkt[12];
-
-#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT table_id: %2x\n", table_id);
- printf (" section_syntax: %d\n", section_syntax_indicator);
- printf (" section_length: %d (%#.3x)\n",
- section_length, section_length);
- printf (" program_number: %#.4x\n", program_number);
- printf (" version_number: %d\n", version_number);
- printf (" c/n indicator: %d\n", current_next_indicator);
- printf (" section_number: %d\n", section_number);
- printf (" last_section_number: %d\n", last_section_number);
-#endif
-
- if ((section_syntax_indicator != 1) || !current_next_indicator) {
-#ifdef TS_PMT_LOG
- printf ("ts_demux: section_syntax_indicator != 1 "
- "|| !current_next_indicator\n");
-#endif
- return;
- }
-
- if (program_number != this->program_number[program_count]) {
- /* several programs can share the same PMT pid */
-#ifdef TS_PMT_LOG
-printf("Program Number is %i, looking for %i\n",program_number,this->program_number[program_count]);
- printf ("ts_demux: waiting for next PMT on this PID...\n");
-#endif
+ /* allocate space for largest possible section */
+ if (!this->pmt[program_count])
+ this->pmt[program_count] = malloc (4098);
+ if (!this->pmt[program_count])
return;
- }
-
- if ((section_number != 0) || (last_section_number != 0)) {
+ this->pmt_write_pos[program_count] = 0;
+ /* offset the section by n + 1 bytes. this is sometimes used to let it end
+ at an exact TS packet boundary */
+ plen -= (unsigned int)pkt[0] + 1;
+ pkt += (unsigned int)pkt[0] + 1;
+ if (plen < 1) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: FIXME (unsupported) PMT consists of multiple (%d) sections\n", last_section_number);
+ "demux_ts: demux error! PMT with invalid pointer\n");
return;
}
-
+ } else {
+ if (!this->pmt_write_pos[program_count])
+ return;
}
+ if (plen > 4098 - this->pmt_write_pos[program_count])
+ plen = 4098 - this->pmt_write_pos[program_count];
+ memcpy (this->pmt[program_count] + this->pmt_write_pos[program_count], pkt, plen);
+ this->pmt_write_pos[program_count] += plen;
- if (!this->pmt[program_count]) {
- /* not the first TS packet of a PMT, or the calloc didn't work */
-#ifdef TS_PMT_LOG
- printf ("ts_demux: not the first TS packet of a PMT...\n");
-#endif
+ /* lets see if we got the section length already */
+ pkt = this->pmt[program_count];
+ if (this->pmt_write_pos[program_count] < 3)
+ return;
+ section_length = ((((uint32_t)pkt[1] << 8) | pkt[2]) & 0xfff) + 3;
+ /* this should be at least the head plus crc */
+ if (section_length < 8 + 4) {
+ this->pmt_write_pos[program_count] = 0;
return;
}
- if (!pusi){
- section_length = (this->pmt[program_count][1] << 8
- | this->pmt[program_count][2]) & 0x03ff;
- }
-
- count=ts_payloadsize(originalPkt);
-
- ptr = originalPkt+offset+(PKT_SIZE-count);
- len = count-offset;
- memcpy (this->pmt_write_ptr[program_count], ptr, len);
- this->pmt_write_ptr[program_count] +=len;
+ /* lets see if we got the section complete */
+ if (this->pmt_write_pos[program_count] < section_length)
+ return;
+ /* OK now parse it */
+ this->pmt_write_pos[program_count] = 0;
#ifdef TS_PMT_LOG
- printf ("ts_demux: wr_ptr: %p, will be %p when finished\n",
- this->pmt_write_ptr[program_count],
- this->pmt[program_count] + section_length);
+ table_id = (unsigned int)pkt[0];
#endif
- if (this->pmt_write_ptr[program_count] < this->pmt[program_count]
- + section_length) {
- /* didn't get all TS packets for this section yet */
+ section_syntax_indicator = (pkt[1] >> 7) & 0x01;
+ program_number = ((uint32_t)pkt[3] << 8) | pkt[4];
#ifdef TS_PMT_LOG
- printf ("ts_demux: didn't get all PMT TS packets yet...\n");
+ version_number = ((uint32_t)pkt[5] >> 1) & 0x1f;
#endif
- return;
- }
+ current_next_indicator = pkt[5] & 0x01;
+ section_number = pkt[6];
+ last_section_number = pkt[7];
- if (!section_length) {
- free (this->pmt[program_count]);
- this->pmt[program_count] = NULL;
#ifdef TS_PMT_LOG
- printf ("ts_demux: eek, zero-length section?\n");
+ printf ("demux_ts: PMT table_id: %.2x\n", table_id);
+ printf (" section_syntax: %d\n", section_syntax_indicator);
+ printf (" section_length: %d (%#.3x)\n", section_length, section_length);
+ printf (" program_number: %#.4x\n", program_number);
+ printf (" version_number: %d\n", version_number);
+ printf (" c/n indicator: %d\n", current_next_indicator);
+ printf (" section_number: %d\n", section_number);
+ printf (" last_section_number: %d\n", last_section_number);
#endif
- return;
- }
-#ifdef TS_PMT_LOG
- printf ("ts_demux: have all TS packets for the PMT section\n");
-#endif
+ if ((section_syntax_indicator != 1) || !current_next_indicator)
+ return;
- crc32 = (uint32_t) this->pmt[program_count][section_length+3-4] << 24;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-3] << 16;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-2] << 8;
- crc32 |= (uint32_t) this->pmt[program_count][section_length+3-1] ;
+ if ((section_number != 0) || (last_section_number != 0)) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_ts: FIXME (unsupported) PMT consists of multiple (%d) sections\n", last_section_number);
+ return;
+ }
/* Check CRC. */
- calc_crc32 = demux_ts_compute_crc32 (this,
- this->pmt[program_count],
- section_length+3-4, 0xffffffff);
+ crc32 = (uint32_t) pkt[section_length - 4] << 24;
+ crc32 |= (uint32_t) pkt[section_length - 3] << 16;
+ crc32 |= (uint32_t) pkt[section_length - 2] << 8;
+ crc32 |= (uint32_t) pkt[section_length - 1];
+
+ calc_crc32 = htonl (av_crc (this->class->av_crc, 0xffffffff, pkt, section_length - 4));
if (crc32 != calc_crc32) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: demux error! PMT with invalid CRC32: packet_crc32: %#.8x calc_crc32: %#.8x\n",
- crc32,calc_crc32);
+ "demux_ts: demux error! PMT with invalid CRC32: packet_crc32: %#.8x calc_crc32: %#.8x\n",
+ crc32, calc_crc32);
return;
}
- else {
#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT CRC32 ok.\n");
+ printf ("demux_ts: PMT CRC32 ok.\n");
#endif
- if ( crc32==this->last_pmt_crc ) {
+
+ if (program_number != this->program_number[program_count]) {
+ /* several programs can share the same PMT pid */
#ifdef TS_PMT_LOG
- printf("demux_ts: PMT with CRC32=%d already parsed. Skipping.\n", crc32);
+printf("Program Number is %i, looking for %i\n",program_number,this->program_number[program_count]);
+ printf ("ts_demux: waiting for next PMT on this PID...\n");
#endif
- return;
- }
- else {
+ return;
+ }
+
+ if (crc32 == this->last_pmt_crc) {
#ifdef TS_PMT_LOG
- printf("demux_ts: new PMT, parsing...\n");
+ printf("demux_ts: PMT with CRC32=%d already parsed. Skipping.\n", crc32);
#endif
- this->last_pmt_crc = crc32;
- }
+ return;
}
+ this->last_pmt_crc = crc32;
+
+ /* dont "parse" the CRC */
+ section_length -= 4;
/*
* Forget the current video, audio and subtitle PIDs; if the PMT has not
@@ -1598,8 +1573,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
* ES definitions start here...we are going to learn upto one video
* PID and one audio PID.
*/
- program_info_length = ((this->pmt[program_count][10] << 8)
- | this->pmt[program_count][11]) & 0x0fff;
+ program_info_length = ((pkt[10] << 8) | pkt[11]) & 0x0fff;
/* Program info descriptor is currently just ignored.
* printf ("demux_ts: program_info_desc: ");
@@ -1607,8 +1581,8 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
* printf ("%.2x ", this->pmt[program_count][12+i]);
* printf ("\n");
*/
- stream = &this->pmt[program_count][12] + program_info_length;
- coded_length = 13 + program_info_length;
+ stream = pkt + 12 + program_info_length;
+ coded_length = 12 + program_info_length;
if (coded_length > section_length) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux error! PMT with inconsistent progInfo length\n");
@@ -2238,8 +2212,8 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
/* PAT */
if (pid == 0) {
- demux_ts_parse_pat(this, originalPkt, originalPkt+data_offset-4,
- payload_unit_start_indicator);
+ demux_ts_parse_pat(this, originalPkt, originalPkt + data_offset,
+ payload_unit_start_indicator, PKT_SIZE - data_offset);
return;
}
@@ -2254,8 +2228,8 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
this->program_number[program_count],
this->pmt_pid[program_count]);
#endif
- demux_ts_parse_pmt (this, originalPkt, originalPkt+data_offset-4,
- payload_unit_start_indicator,
+ demux_ts_parse_pmt (this, originalPkt, originalPkt + data_offset,
+ payload_unit_start_indicator, PKT_SIZE - data_offset,
program_count);
return;
}
@@ -2421,8 +2395,6 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) {
this->send_newpts = 1;
- demux_ts_build_crc32_table (this);
-
this->status = DEMUX_OK ;
this->scrambled_npids = 0;
@@ -2613,39 +2585,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
}
break;
- case METHOD_BY_EXTENSION: {
- const char *const mrl = input->get_mrl (input);
-
- if (_x_demux_check_extension (mrl, "m2ts mts"))
- hdmv = 1;
- else
- hdmv = 0;
-
- /* check extension */
- const char *const extensions = class_gen->get_extensions (class_gen);
-
- if (_x_demux_check_extension (mrl, extensions))
- break;
-
- /* accept dvb streams */
- /*
- * Also handle the special dvbs,dvbt and dvbc mrl formats:
- * the content is exactly the same but the input plugin
- * uses a different tuning algorithm [Pragma]
- */
-
- if (!strncasecmp (mrl, "dvb://", 6))
- break;
- if (!strncasecmp (mrl, "dvbs://", 7))
- break;
- if (!strncasecmp (mrl, "dvbc://", 7))
- break;
- if (!strncasecmp (mrl, "dvbt://", 7))
- break;
-
- return NULL;
- }
-
+ case METHOD_BY_MRL:
case METHOD_EXPLICIT:
break;
@@ -2660,6 +2600,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this = calloc(1, sizeof(*this));
this->stream = stream;
this->input = input;
+ this->class = (demux_ts_class_t*)class_gen;
this->demux_plugin.send_headers = demux_ts_send_headers;
this->demux_plugin.send_chunk = demux_ts_send_chunk;
@@ -2687,7 +2628,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->program_number[i] = INVALID_PROGRAM;
this->pmt_pid[i] = INVALID_PID;
this->pmt[i] = NULL;
- this->pmt_write_ptr[i] = NULL;
+ this->pmt_write_pos[i] = 0;
}
this->scrambled_npids = 0;
@@ -2720,30 +2661,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
/*
* ts demuxer class
*/
-
-static const char *get_description (demux_class_t *this_gen) {
- return "MPEG Transport Stream demuxer";
-}
-
-static const char *get_identifier (demux_class_t *this_gen) {
- return "MPEG_TS";
-}
-
-static const char *get_extensions (demux_class_t *this_gen) {
- return "ts m2t trp m2ts mts";
-}
-
-static const char *get_mimetypes (demux_class_t *this_gen) {
- return "video/mp2t: m2t: MPEG2 transport stream;";
-}
-
-static void class_dispose (demux_class_t *this_gen) {
-
- demux_ts_class_t *this = (demux_ts_class_t *) this_gen;
-
- free (this);
-}
-
static void *init_class (xine_t *xine, void *data) {
demux_ts_class_t *this;
@@ -2753,11 +2670,18 @@ static void *init_class (xine_t *xine, void *data) {
this->xine = xine;
this->demux_class.open_plugin = open_plugin;
- this->demux_class.get_description = get_description;
- this->demux_class.get_identifier = get_identifier;
- this->demux_class.get_mimetypes = get_mimetypes;
- this->demux_class.get_extensions = get_extensions;
- this->demux_class.dispose = class_dispose;
+ this->demux_class.description = N_("MPEG Transport Stream demuxer");
+ this->demux_class.identifier = "MPEG_TS";
+ this->demux_class.mimetypes = "video/mp2t: m2t: MPEG2 transport stream;";
+
+ /* accept dvb streams; also handle the special dvbs,dvbt and dvbc
+ * mrl formats: the content is exactly the same but the input plugin
+ * uses a different tuning algorithm [Pragma]
+ */
+ this->demux_class.extensions = "ts m2t trp m2ts mts dvb:// dvbs:// dvbc:// dvbt://";
+ this->demux_class.dispose = default_demux_class_dispose;
+
+ this->av_crc = av_crc_get_table(AV_CRC_32_IEEE);
return this;
}
@@ -2772,7 +2696,7 @@ static const demuxer_info_t demux_info_ts = {
const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 26, "mpeg-ts", XINE_VERSION_CODE, &demux_info_ts, init_class },
+ { PLUGIN_DEMUX, 27, "mpeg-ts", XINE_VERSION_CODE, &demux_info_ts, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};