summaryrefslogtreecommitdiff
path: root/server/livestreamer.c
diff options
context:
space:
mode:
authorFrank Schmirler <vdr@schmirler.de>2010-12-02 09:44:53 +0100
committerFrank Schmirler <vdr@schmirler.de>2010-12-02 09:44:53 +0100
commit008ea7f151dd84b314062a272ad61448f51df605 (patch)
treef239ede406d0c0bb1bf5e9d2b08a37027c14e635 /server/livestreamer.c
parent7254a6752808830d5fc133e5362da6c47f3f84ff (diff)
downloadvdr-plugin-streamdev-008ea7f151dd84b314062a272ad61448f51df605.tar.gz
vdr-plugin-streamdev-008ea7f151dd84b314062a272ad61448f51df605.tar.bz2
Snapshot 2009-07-01
Diffstat (limited to 'server/livestreamer.c')
-rw-r--r--server/livestreamer.c226
1 files changed, 91 insertions, 135 deletions
diff --git a/server/livestreamer.c b/server/livestreamer.c
index 97dffd7..71a3565 100644
--- a/server/livestreamer.c
+++ b/server/livestreamer.c
@@ -4,6 +4,7 @@
#include <libsi/descriptor.h>
#include "remux/ts2ps.h"
+#include "remux/ts2pes.h"
#include "remux/ts2es.h"
#include "remux/extern.h"
@@ -13,7 +14,7 @@
#include "server/livefilter.h"
#include "common.h"
-#define TSPATREPACKER
+using namespace Streamdev;
// --- cStreamdevLiveReceiver -------------------------------------------------
@@ -64,6 +65,8 @@ private:
int pmtPid;
int pmtSid;
int pmtVersion;
+ uchar tspat_buf[TS_SIZE];
+ cStreamdevBuffer siBuffer;
const cChannel *m_Channel;
cStreamdevLiveStreamer *m_Streamer;
@@ -73,9 +76,11 @@ private:
int GetPid(SI::PMT::Stream& stream);
public:
cStreamdevPatFilter(cStreamdevLiveStreamer *Streamer, const cChannel *Channel);
+ uchar* Get(int &Count) { return siBuffer.Get(Count); }
+ void Del(int Count) { return siBuffer.Del(Count); }
};
-cStreamdevPatFilter::cStreamdevPatFilter(cStreamdevLiveStreamer *Streamer, const cChannel *Channel)
+cStreamdevPatFilter::cStreamdevPatFilter(cStreamdevLiveStreamer *Streamer, const cChannel *Channel): siBuffer(10 * TS_SIZE, TS_SIZE)
{
Dprintf("cStreamdevPatFilter(\"%s\")\n", Channel->Name());
assert(Streamer);
@@ -85,6 +90,29 @@ cStreamdevPatFilter::cStreamdevPatFilter(cStreamdevLiveStreamer *Streamer, const
pmtSid = 0;
pmtVersion = -1;
Set(0x00, 0x00); // PAT
+ // initialize PAT buffer. Only some values are dynamic (see comments)
+ memset(tspat_buf, 0xff, TS_SIZE);
+ 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, DYNAMIC: Continuity counter
+ tspat_buf[4] = 0x0; // SI pointer field
+ 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] = 0; // DYNAMIC: Transport stream ID (bits 8-15)
+ tspat_buf[9] = 0; // DYNAMIC: Transport stream ID (bits 0-7)
+ tspat_buf[10] = 0xc0; // Reserved, DYNAMIC: Version number, DYNAMIC: Current next indicator
+ tspat_buf[11] = 0x0; // Section number
+ tspat_buf[12] = 0x0; // Last section number
+ tspat_buf[13] = 0; // DYNAMIC: Program number (bits 8-15)
+ tspat_buf[14] = 0; // DYNAMIC: Program number (bits 0-7)
+ tspat_buf[15] = 0xe0; // Reserved, DYNAMIC: Network ID (bits 8-12)
+ tspat_buf[16] = 0; // DYNAMIC: Network ID (bits 0-7)
+ tspat_buf[17] = 0; // DYNAMIC: Checksum
+ tspat_buf[18] = 0; // DYNAMIC: Checksum
+ tspat_buf[19] = 0; // DYNAMIC: Checksum
+ tspat_buf[20] = 0; // DYNAMIC: Checksum
}
static const char * const psStreamTypes[] = {
@@ -224,54 +252,37 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
if (0 != (pmtPid = assoc.getPid())) {
Dprintf("cStreamdevPatFilter: PMT pid for channel %s: %d\n", Channel->Name(), pmtPid);
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];
- static uint8_t ccounter = 0;
- ccounter = (ccounter + 1) % 16;
- memset(tspat_buf, 0xff, TS_SIZE);
- 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 | ccounter; // Set payload flag, Continuity counter
- tspat_buf[4] = 0x0; // SI pointer field
- 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); // Transport stream ID (bits 8-15)
- tspat_buf[9] = (ts_id & 0xff); // Transport stream ID (bits 0-7)
- tspat_buf[10] = 0xc0 | ((pat.getVersionNumber() << 1) & 0x3e) |
- pat.getCurrentNextIndicator();// Version number, Current next indicator
- tspat_buf[11] = 0x0; // Section number
- tspat_buf[12] = 0x0; // Last section number
- tspat_buf[13] = (pmtSid >> 8); // Program number (bits 8-15)
- tspat_buf[14] = (pmtSid & 0xff); // Program number (bits 0-7)
- tspat_buf[15] = 0xe0 | (pmtPid >> 8); // 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);
+ // repack PAT to TS frame and send to client
+ int ts_id;
+ unsigned int crc, i, len;
+ uint8_t *tmp;
+ static uint8_t ccounter = 0;
+ ccounter = (ccounter + 1) % 16;
+ ts_id = Channel->Tid(); // Get transport stream id of the channel
+ tspat_buf[3] = 0x10 | ccounter; // Set payload flag, Continuity counter
+ tspat_buf[8] = (ts_id >> 8); // Transport stream ID (bits 8-15)
+ tspat_buf[9] = (ts_id & 0xff); // Transport stream ID (bits 0-7)
+ tspat_buf[10] = 0xc0 | ((pat.getVersionNumber() << 1) & 0x3e) |
+ pat.getCurrentNextIndicator();// Version number, Current next indicator
+ tspat_buf[13] = (pmtSid >> 8); // Program number (bits 8-15)
+ tspat_buf[14] = (pmtSid & 0xff); // Program number (bits 0-7)
+ tspat_buf[15] = 0xe0 | (pmtPid >> 8); // 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
+ int written = siBuffer.PutTS(tspat_buf, TS_SIZE);
+ if (written != TS_SIZE)
+ siBuffer.ReportOverflow(TS_SIZE - written);
if (pmtPid != prevPmtPid) {
m_Streamer->SetPids(pmtPid);
Add(pmtPid, 0x02);
@@ -292,7 +303,7 @@ void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, i
if (pmtVersion != -1) {
if (pmtVersion != pmt.getVersionNumber()) {
Dprintf("cStreamdevPatFilter: PMT version changed, detaching all pids\n");
- Del(pmtPid, 0x02);
+ cFilter::Del(pmtPid, 0x02);
pmtPid = 0; // this triggers PAT scan
}
return;
@@ -329,12 +340,7 @@ cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority, std::string Paramet
m_Device(NULL),
m_Receiver(NULL),
m_PatFilter(NULL),
-#if APIVERSNUM < 10703
- m_PESRemux(NULL),
-#endif
- m_ESRemux(NULL),
- m_PSRemux(NULL),
- m_ExtRemux(NULL)
+ m_Remux(NULL)
{
}
@@ -347,12 +353,7 @@ cStreamdevLiveStreamer::~cStreamdevLiveStreamer()
DELETENULL(m_PatFilter);
}
DELETENULL(m_Receiver);
-#if APIVERSNUM < 10703
- delete m_PESRemux;
-#endif
- delete m_ESRemux;
- delete m_PSRemux;
- delete m_ExtRemux;
+ delete m_Remux;
}
bool cStreamdevLiveStreamer::HasPid(int Pid)
@@ -459,19 +460,17 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str
int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid();
if (Apid != 0)
pid = Apid;
- m_ESRemux = new cTS2ESRemux(pid);
+ m_Remux = new cTS2ESRemux(pid);
return SetPids(pid);
}
-#if APIVERSNUM < 10703
case stPES:
- m_PESRemux = new cRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
- m_Channel->Spids(), false);
+ m_Remux = new cTS2PESRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
+ m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
-#endif
case stPS:
- m_PSRemux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
+ m_Remux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
m_Channel->Spids());
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
@@ -490,7 +489,7 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str
return true;
case stExtern:
- m_ExtRemux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
+ m_Remux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
m_Channel->Spids(), m_Parameter);
return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
@@ -503,82 +502,39 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str
int cStreamdevLiveStreamer::Put(const uchar *Data, int Count)
{
- switch (m_StreamType) {
- case stTS:
- case stTSPIDS:
- return cStreamdevStreamer::Put(Data, Count);
-
-#if APIVERSNUM < 10703
- case stPES:
- return m_PESRemux->Put(Data, Count);
-#endif
-
- case stES:
- return m_ESRemux->Put(Data, Count);
-
- case stPS:
- return m_PSRemux->Put(Data, Count);
-
- case stExtern:
- return m_ExtRemux->Put(Data, Count);
-
- default: // shouldn't happen???
- return 0;
+ // insert si data
+ if (m_PatFilter) {
+ int siCount;
+ uchar *siData = m_PatFilter->Get(siCount);
+ if (siData) {
+ if (m_Remux)
+ siCount = m_Remux->Put(siData, siCount);
+ else
+ siCount = cStreamdevStreamer::Put(siData, siCount);
+ if (siCount)
+ m_PatFilter->Del(siCount);
+ }
}
+ if (m_Remux)
+ return m_Remux->Put(Data, Count);
+ else
+ return cStreamdevStreamer::Put(Data, Count);
}
uchar *cStreamdevLiveStreamer::Get(int &Count)
{
- switch (m_StreamType) {
- case stTS:
- case stTSPIDS:
+ if (m_Remux)
+ return m_Remux->Get(Count);
+ else
return cStreamdevStreamer::Get(Count);
-
-#if APIVERSNUM < 10703
- case stPES:
- return m_PESRemux->Get(Count);
-#endif
-
- case stES:
- return m_ESRemux->Get(Count);
-
- case stPS:
- return m_PSRemux->Get(Count);
-
- case stExtern:
- return m_ExtRemux->Get(Count);
-
- default: // shouldn't happen???
- return 0;
- }
}
void cStreamdevLiveStreamer::Del(int Count)
{
- switch (m_StreamType) {
- case stTS:
- case stTSPIDS:
+ if (m_Remux)
+ m_Remux->Del(Count);
+ else
cStreamdevStreamer::Del(Count);
- break;
-
-#if APIVERSNUM < 10703
- case stPES:
- m_PESRemux->Del(Count);
- break;
-#endif
-
- case stES:
- m_ESRemux->Del(Count);
- break;
-
- case stPS:
- m_PSRemux->Del(Count);
- break;
-
- case stExtern:
- m_ExtRemux->Del(Count);
- break;
- }
}
void cStreamdevLiveStreamer::Attach(void)