summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschmirl <schmirl>2008-02-22 12:02:48 +0000
committerschmirl <schmirl>2008-02-22 12:02:48 +0000
commiteb6fbd3bbea50c4ecf345f41ee87fd51bbcde113 (patch)
treeeda61076ead9f7d8fd9eedcdb34941f81d360185
parentcd558858e6b619c47377223ecc9e79a08775c991 (diff)
downloadvdr-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.c41
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);