diff options
Diffstat (limited to 'src/demuxers/demux_ts.c')
-rw-r--r-- | src/demuxers/demux_ts.c | 476 |
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 } }; |