diff options
author | schmirl <schmirl> | 2008-02-22 12:02:48 +0000 |
---|---|---|
committer | schmirl <schmirl> | 2008-02-22 12:02:48 +0000 |
commit | eb6fbd3bbea50c4ecf345f41ee87fd51bbcde113 (patch) | |
tree | eda61076ead9f7d8fd9eedcdb34941f81d360185 | |
parent | cd558858e6b619c47377223ecc9e79a08775c991 (diff) | |
download | vdr-plugin-streamdev-eb6fbd3bbea50c4ecf345f41ee87fd51bbcde113.tar.gz vdr-plugin-streamdev-eb6fbd3bbea50c4ecf345f41ee87fd51bbcde113.tar.bz2 |
TS PAT repacker for streamtype TS. The PAT shoudln't refer to PMTs we don't
transmit. Particularely causes problems with some settop boxes.
Thanks to Rolf Ahrenberg (#309)
-rw-r--r-- | server/livestreamer.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/server/livestreamer.c b/server/livestreamer.c index 1bbeddb..fb5de5a 100644 --- a/server/livestreamer.c +++ b/server/livestreamer.c @@ -12,6 +12,8 @@ #include "remux/extern.h" #include "common.h" +#define TSPATREPACKER + // --- cStreamdevLiveReceiver ------------------------------------------------- class cStreamdevLiveReceiver: public cReceiver { @@ -232,9 +234,48 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i pmtSid = assoc.getServiceId(); if (Length < TS_SIZE-5) { // repack PAT to TS frame and send to client +#ifndef TSPATREPACKER uint8_t pat_ts[TS_SIZE] = {TS_SYNC_BYTE, 0x40 /* pusi=1 */, 0 /* pid=0 */, 0x10 /* adaption=1 */, 0 /* pointer */}; memcpy(pat_ts + 5, Data, Length); m_Streamer->Put(pat_ts, TS_SIZE); +#else + int ts_id; + unsigned int crc, i, len; + uint8_t *tmp, tspat_buf[TS_SIZE]; + memset(tspat_buf, 0xff, TS_SIZE); + memset(tspat_buf, 0x0, 4 + 12 + 5); // TS_HDR_LEN + PAT_TABLE_LEN + 5 + ts_id = Channel->Tid(); // Get transport stream id of the channel + tspat_buf[0] = TS_SYNC_BYTE; // Transport packet header sunchronization byte (1000011 = 0x47h) + tspat_buf[1] = 0x40; // Set payload unit start indicator bit + tspat_buf[2] = 0x0; // PID + tspat_buf[3] = 0x10; // Set payload flag to indicate precence of payload data + tspat_buf[4] = 0x0; // PSI + tspat_buf[5] = 0x0; // PAT table id + tspat_buf[6] = 0xb0; // Section syntax indicator bit and reserved bits set + tspat_buf[7] = 12 + 1; // Section length (12 bit): PAT_TABLE_LEN + 1 + tspat_buf[8] = (ts_id >> 8) & 0xff; // Transport stream ID (bits 8-15) + tspat_buf[9] = (ts_id & 0xff); // Transport stream ID (bits 0-7) + tspat_buf[10] = 0x01; // Version number 0, Current next indicator bit set + tspat_buf[11] = 0x0; // Section number + tspat_buf[12] = 0x0; // Last section number + tspat_buf[13] = (pmtSid >> 8) & 0xff; // Program number (bits 8-15) + tspat_buf[14] = (pmtSid & 0xff); // Program number (bits 0-7) + tspat_buf[15] = (pmtPid >> 8) & 0xff; // Network ID (bits 8-12) + tspat_buf[16] = (pmtPid & 0xff); // Network ID (bits 0-7) + crc = 0xffffffff; + len = 12; // PAT_TABLE_LEN + tmp = &tspat_buf[4 + 1]; // TS_HDR_LEN + 1 + while (len--) { + crc ^= *tmp++ << 24; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x80000000) ? 0x04c11db7 : 0); // CRC32POLY + } + tspat_buf[17] = crc >> 24 & 0xff; // Checksum + tspat_buf[18] = crc >> 16 & 0xff; // Checksum + tspat_buf[19] = crc >> 8 & 0xff; // Checksum + tspat_buf[20] = crc & 0xff; // Checksum + m_Streamer->Put(tspat_buf, TS_SIZE); +#endif } else isyslog("cStreamdevPatFilter: PAT size %d too large to fit in one TS", Length); m_Streamer->SetPids(pmtPid); |