summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/connectionHTTP.c6
-rw-r--r--server/connectionVTP.c4
-rw-r--r--server/livestreamer.c140
-rw-r--r--server/livestreamer.h22
-rw-r--r--server/menuHTTP.c4
-rw-r--r--server/streamer.c22
-rw-r--r--server/streamer.h43
7 files changed, 133 insertions, 108 deletions
diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c
index fc10bfc..83e568d 100644
--- a/server/connectionHTTP.c
+++ b/server/connectionHTTP.c
@@ -1,5 +1,5 @@
/*
- * $Id: connectionHTTP.c,v 1.16 2009/02/13 07:02:19 schmirl Exp $
+ * $Id: connectionHTTP.c,v 1.17 2009/06/19 06:32:45 schmirl Exp $
*/
#include <ctype.h>
@@ -211,10 +211,8 @@ bool cConnectionHTTP::CmdGET(const std::string &Opts)
const char* pType = type.c_str();
if (strcasecmp(pType, "PS") == 0) {
m_StreamType = stPS;
-#if APIVERSNUM < 10703
} else if (strcasecmp(pType, "PES") == 0) {
m_StreamType = stPES;
-#endif
} else if (strcasecmp(pType, "TS") == 0) {
m_StreamType = stTS;
} else if (strcasecmp(pType, "ES") == 0) {
@@ -266,9 +264,7 @@ bool cConnectionHTTP::CmdGET(const std::string &Opts)
{
case stTS: base += "TS/"; break;
case stPS: base += "PS/"; break;
-#if APIVERSNUM < 10703
case stPES: base += "PES/"; break;
-#endif
case stES: base += "ES/"; break;
case stExtern: base += "Extern/"; break;
default: break;
diff --git a/server/connectionVTP.c b/server/connectionVTP.c
index e0edb6e..ebe339b 100644
--- a/server/connectionVTP.c
+++ b/server/connectionVTP.c
@@ -1,5 +1,5 @@
/*
- * $Id: connectionVTP.c,v 1.19 2009/01/16 11:35:44 schmirl Exp $
+ * $Id: connectionVTP.c,v 1.20 2009/06/19 06:32:45 schmirl Exp $
*/
#include "server/connectionVTP.h"
@@ -595,12 +595,10 @@ bool cConnectionVTP::CmdCAPS(char *Opts)
return Respond(220, "Capability \"%s\" accepted", Opts);
}
-#if APIVERSNUM < 10703
if (strcasecmp(Opts, "PES") == 0) {
m_StreamType = stPES;
return Respond(220, "Capability \"%s\" accepted", Opts);
}
-#endif
if (strcasecmp(Opts, "EXTERN") == 0) {
m_StreamType = stExtern;
diff --git a/server/livestreamer.c b/server/livestreamer.c
index 97dffd7..684e701 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,9 +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)
@@ -347,9 +356,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;
@@ -463,12 +470,10 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str
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_PESRemux = 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(),
@@ -505,13 +510,22 @@ int cStreamdevLiveStreamer::Put(const uchar *Data, int Count)
{
switch (m_StreamType) {
case stTS:
+ // insert si data
+ if (m_PatFilter) {
+ int got;
+ uchar *si = m_PatFilter->Get(got);
+ if (si) {
+ int count = cStreamdevStreamer::Put(si, got);
+ if (count)
+ m_PatFilter->Del(count);
+ }
+ }
+ // fall through
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);
@@ -534,10 +548,8 @@ uchar *cStreamdevLiveStreamer::Get(int &Count)
case stTSPIDS:
return cStreamdevStreamer::Get(Count);
-#if APIVERSNUM < 10703
case stPES:
return m_PESRemux->Get(Count);
-#endif
case stES:
return m_ESRemux->Get(Count);
@@ -561,11 +573,9 @@ void cStreamdevLiveStreamer::Del(int Count)
cStreamdevStreamer::Del(Count);
break;
-#if APIVERSNUM < 10703
case stPES:
m_PESRemux->Del(Count);
break;
-#endif
case stES:
m_ESRemux->Del(Count);
diff --git a/server/livestreamer.h b/server/livestreamer.h
index 5c4ae8f..cf64559 100644
--- a/server/livestreamer.h
+++ b/server/livestreamer.h
@@ -7,12 +7,12 @@
#include "server/streamer.h"
#include "common.h"
-class cTS2PSRemux;
-class cTS2ESRemux;
-class cExternRemux;
-#if APIVERSNUM < 10703
-class cRemux;
-#endif
+namespace Streamdev {
+ class cTS2PSRemux;
+ class cTS2ESRemux;
+ class cExternRemux;
+ class cTS2PESRemux;
+}
class cStreamdevPatFilter;
class cStreamdevLiveReceiver;
@@ -29,12 +29,10 @@ private:
cDevice *m_Device;
cStreamdevLiveReceiver *m_Receiver;
cStreamdevPatFilter *m_PatFilter;
-#if APIVERSNUM < 10703
- cRemux *m_PESRemux;
-#endif
- cTS2ESRemux *m_ESRemux;
- cTS2PSRemux *m_PSRemux;
- cExternRemux *m_ExtRemux;
+ Streamdev::cTS2PESRemux *m_PESRemux;
+ Streamdev::cTS2ESRemux *m_ESRemux;
+ Streamdev::cTS2PSRemux *m_PSRemux;
+ Streamdev::cExternRemux *m_ExtRemux;
void StartReceiver(void);
bool HasPid(int Pid);
diff --git a/server/menuHTTP.c b/server/menuHTTP.c
index 41b1f10..8d3e404 100644
--- a/server/menuHTTP.c
+++ b/server/menuHTTP.c
@@ -201,10 +201,8 @@ std::string cHtmlChannelList::StreamTypeMenu()
(std::string) "[<a href=\"/TS/" + self + "\">TS</a>] ");
typeMenu += (streamType == stPS ? (std::string) "[PS] " :
(std::string) "[<a href=\"/PS/" + self + "\">PS</a>] ");
-#if APIVERSNUM < 10703
typeMenu += (streamType == stPES ? (std::string) "[PES] " :
(std::string) "[<a href=\"/PES/" + self + "\">PES</a>] ");
-#endif
typeMenu += (streamType == stES ? (std::string) "[ES] " :
(std::string) "[<a href=\"/ES/" + self + "\">ES</a>] ");
typeMenu += (streamType == stExtern ? (std::string) "[Extern] " :
@@ -343,10 +341,8 @@ std::string cHtmlChannelList::ItemText()
switch (streamType) {
case stTS: suffix = (std::string) ".ts"; break;
case stPS: suffix = (std::string) ".vob"; break;
-#if APIVERSNUM < 10703
// for Network Media Tank
case stPES: suffix = (std::string) ".vdr"; break;
-#endif
default: suffix = "";
}
line += (std::string) "<li value=\"" + (const char*) itoa(current->Number()) + "\">";
diff --git a/server/streamer.c b/server/streamer.c
index 9795cc6..42e7efa 100644
--- a/server/streamer.c
+++ b/server/streamer.c
@@ -1,5 +1,5 @@
/*
- * $Id: streamer.c,v 1.18 2009/02/13 10:39:22 schmirl Exp $
+ * $Id: streamer.c,v 1.19 2009/06/19 06:32:45 schmirl Exp $
*/
#include <vdr/ringbuffer.h>
@@ -14,6 +14,13 @@
#include "tools/select.h"
#include "common.h"
+// --- cStreamdevBuffer -------------------------------------------------------
+
+cStreamdevBuffer::cStreamdevBuffer(int Size, int Margin, bool Statistics, const char *Description):
+ cRingBufferLinear(Size, Margin, Statistics, Description)
+{
+}
+
// --- cStreamdevWriter -------------------------------------------------------
cStreamdevWriter::cStreamdevWriter(cTBSocket *Socket,
@@ -95,14 +102,13 @@ void cStreamdevWriter::Action(void)
cStreamdevStreamer::cStreamdevStreamer(const char *Name):
cThread(Name),
- m_Running(false),
m_Writer(NULL),
- m_RingBuffer(new cRingBufferLinear(STREAMERBUFSIZE, TS_SIZE * 2,
+ m_RingBuffer(new cStreamdevBuffer(STREAMERBUFSIZE, TS_SIZE * 2,
true, "streamdev-streamer")),
- m_SendBuffer(new cRingBufferLinear(WRITERBUFSIZE, TS_SIZE * 2))
+ m_SendBuffer(new cStreamdevBuffer(WRITERBUFSIZE, TS_SIZE * 2))
{
m_RingBuffer->SetTimeouts(0, 100);
- m_SendBuffer->SetTimeouts(0, 100);
+ m_SendBuffer->SetTimeouts(100, 100);
}
cStreamdevStreamer::~cStreamdevStreamer()
@@ -116,7 +122,6 @@ void cStreamdevStreamer::Start(cTBSocket *Socket)
{
Dprintf("start streamer\n");
m_Writer = new cStreamdevWriter(Socket, this);
- m_Running = true;
Attach();
}
@@ -135,9 +140,8 @@ void cStreamdevStreamer::Stop(void)
Dprintf("stopping streamer\n");
Cancel(3);
}
- if (m_Running) {
+ if (m_Writer) {
Detach();
- m_Running = false;
DELETENULL(m_Writer);
}
}
@@ -152,8 +156,6 @@ void cStreamdevStreamer::Action(void)
int count = Put(block, got);
if (count)
m_RingBuffer->Del(count);
- else
- cCondWait::SleepMs(100);
}
}
}
diff --git a/server/streamer.h b/server/streamer.h
index 20323b7..6561bc2 100644
--- a/server/streamer.h
+++ b/server/streamer.h
@@ -1,5 +1,5 @@
/*
- * $Id: streamer.h,v 1.10 2009/02/13 10:39:22 schmirl Exp $
+ * $Id: streamer.h,v 1.11 2009/06/19 06:32:45 schmirl Exp $
*/
#ifndef VDR_STREAMDEV_STREAMER_H
@@ -16,8 +16,34 @@ class cStreamdevStreamer;
#define TS_SIZE 188
#endif
-#define STREAMERBUFSIZE MEGABYTE(4)
-#define WRITERBUFSIZE KILOBYTE(256)
+#define STREAMERBUFSIZE (20000 * TS_SIZE)
+#define WRITERBUFSIZE (5000 * TS_SIZE)
+
+// --- cStreamdevBuffer -------------------------------------------------------
+
+class cStreamdevBuffer: public cRingBufferLinear {
+public:
+ // make public
+ void WaitForPut(void) { cRingBuffer::WaitForPut(); }
+ // Always write complete TS packets
+ // (assumes Count is a multiple of TS_SIZE)
+ int PutTS(const uchar *Data, int Count);
+ cStreamdevBuffer(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL);
+};
+
+inline int cStreamdevBuffer::PutTS(const uchar *Data, int Count)
+{
+ int free = Free();
+ if (free < Count)
+ Count = free;
+
+ Count -= Count % TS_SIZE;
+ if (Count)
+ Count = Put(Data, Count);
+ else
+ WaitForPut();
+ return Count;
+}
// --- cStreamdevWriter -------------------------------------------------------
@@ -38,15 +64,14 @@ public:
class cStreamdevStreamer: public cThread {
private:
- bool m_Running;
cStreamdevWriter *m_Writer;
- cRingBufferLinear *m_RingBuffer;
- cRingBufferLinear *m_SendBuffer;
+ cStreamdevBuffer *m_RingBuffer;
+ cStreamdevBuffer *m_SendBuffer;
protected:
virtual void Action(void);
- bool IsRunning(void) const { return m_Running; }
+ bool IsRunning(void) const { return m_Writer; }
public:
cStreamdevStreamer(const char *Name);
@@ -57,10 +82,10 @@ public:
bool Abort(void);
void Activate(bool On);
- int Receive(uchar *Data, int Length) { return m_RingBuffer->Put(Data, Length); }
+ int Receive(uchar *Data, int Length) { return m_RingBuffer->PutTS(Data, Length); }
void ReportOverflow(int Bytes) { m_RingBuffer->ReportOverflow(Bytes); }
- virtual int Put(const uchar *Data, int Count) { return m_SendBuffer->Put(Data, Count); }
+ virtual int Put(const uchar *Data, int Count) { return m_SendBuffer->PutTS(Data, Count); }
virtual uchar *Get(int &Count) { return m_SendBuffer->Get(Count); }
virtual void Del(int Count) { m_SendBuffer->Del(Count); }