vdr-plugin-streamdev/server/livestreamer.c

325 lines
7.4 KiB
C
Raw Normal View History

2004-12-30 23:43:55 +01:00
#include <vdr/ringbuffer.h>
#include "server/livestreamer.h"
#include "remux/ts2ps.h"
#include "remux/ts2es.h"
2005-02-11 17:44:14 +01:00
#include "remux/extern.h"
2004-12-30 23:43:55 +01:00
#include "common.h"
// --- cStreamdevLiveReceiver -------------------------------------------------
class cStreamdevLiveReceiver: public cReceiver {
friend class cStreamdevStreamer;
private:
cStreamdevStreamer *m_Streamer;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
public:
#if VDRVERSNUM < 10500
cStreamdevLiveReceiver(cStreamdevStreamer *Streamer, int Ca, int Priority, const int *Pids);
#else
cStreamdevLiveReceiver(cStreamdevStreamer *Streamer, tChannelID ChannelID, int Priority, const int *Pids);
#endif
virtual ~cStreamdevLiveReceiver();
};
#if VDRVERSNUM < 10500
cStreamdevLiveReceiver::cStreamdevLiveReceiver(cStreamdevStreamer *Streamer, int Ca,
2005-02-08 14:59:16 +01:00
int Priority, const int *Pids):
cReceiver(Ca, Priority, 0, Pids),
#else
cStreamdevLiveReceiver::cStreamdevLiveReceiver(cStreamdevStreamer *Streamer, tChannelID ChannelID,
int Priority, const int *Pids):
cReceiver(ChannelID, Priority, 0, Pids),
#endif
2005-02-08 14:59:16 +01:00
m_Streamer(Streamer)
{
2004-12-30 23:43:55 +01:00
}
2005-02-08 14:59:16 +01:00
cStreamdevLiveReceiver::~cStreamdevLiveReceiver()
{
2004-12-30 23:43:55 +01:00
Dprintf("Killing live receiver\n");
Detach();
}
void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) {
2005-02-08 20:54:52 +01:00
int p = m_Streamer->Receive(Data, Length);
2005-02-08 14:59:16 +01:00
if (p != Length)
m_Streamer->ReportOverflow(Length - p);
2004-12-30 23:43:55 +01:00
}
inline void cStreamdevLiveReceiver::Activate(bool On)
{
Dprintf("LiveReceiver->Activate(%d)\n", On);
m_Streamer->Activate(On);
}
// --- cStreamdevLiveStreamer -------------------------------------------------
2004-12-30 23:43:55 +01:00
cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority):
cStreamdevStreamer("streamdev-livestreaming"),
m_Priority(Priority),
m_NumPids(0),
m_StreamType(stTSPIDS),
m_Channel(NULL),
m_Device(NULL),
m_Receiver(NULL),
m_PESRemux(NULL),
2005-02-11 17:44:14 +01:00
m_ESRemux(NULL),
m_PSRemux(NULL),
m_ExtRemux(NULL)
{
2004-12-30 23:43:55 +01:00
}
cStreamdevLiveStreamer::~cStreamdevLiveStreamer()
{
2004-12-30 23:43:55 +01:00
Dprintf("Desctructing Live streamer\n");
2005-02-11 17:44:14 +01:00
Stop();
2004-12-30 23:43:55 +01:00
delete m_Receiver;
2005-02-11 17:44:14 +01:00
delete m_PESRemux;
delete m_ESRemux;
delete m_PSRemux;
delete m_ExtRemux;
2004-12-30 23:43:55 +01:00
#if VDRVERSNUM >= 10300
2005-02-08 16:34:38 +01:00
//delete m_Filter; TODO
2004-12-30 23:43:55 +01:00
#endif
}
bool cStreamdevLiveStreamer::SetPid(int Pid, bool On)
{
2004-12-30 23:43:55 +01:00
int idx;
if (Pid == 0)
return true;
2004-12-30 23:43:55 +01:00
if (On) {
2005-02-08 14:59:16 +01:00
for (idx = 0; idx < m_NumPids; ++idx) {
2004-12-30 23:43:55 +01:00
if (m_Pids[idx] == Pid)
return true; // No change needed
}
2005-02-08 14:59:16 +01:00
if (m_NumPids == MAXRECEIVEPIDS) {
2004-12-30 23:43:55 +01:00
esyslog("ERROR: Streamdev: No free slot to receive pid %d\n", Pid);
return false;
}
2005-02-08 14:59:16 +01:00
m_Pids[m_NumPids++] = Pid;
m_Pids[m_NumPids] = 0;
2004-12-30 23:43:55 +01:00
} else {
2005-02-08 14:59:16 +01:00
for (idx = 0; idx < m_NumPids; ++idx) {
if (m_Pids[idx] == Pid) {
--m_NumPids;
memmove(&m_Pids[idx], &m_Pids[idx + 1], sizeof(int) * (m_NumPids - idx));
}
2004-12-30 23:43:55 +01:00
}
}
DELETENULL(m_Receiver);
2005-02-08 14:59:16 +01:00
if (m_NumPids > 0) {
2004-12-30 23:43:55 +01:00
Dprintf("Creating Receiver to respect changed pids\n");
#if VDRVERSNUM < 10500
2005-02-08 14:59:16 +01:00
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->Ca(), m_Priority, m_Pids);
#else
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->GetChannelID(), m_Priority, m_Pids);
#endif
2005-02-11 18:02:22 +01:00
if (IsRunning() && m_Device != NULL) {
2004-12-30 23:43:55 +01:00
Dprintf("Attaching new receiver\n");
2005-02-08 20:54:52 +01:00
Attach();
2004-12-30 23:43:55 +01:00
}
}
return true;
}
bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid)
2005-02-08 16:34:38 +01:00
{
2004-12-30 23:43:55 +01:00
Dprintf("Initializing Remuxer for full channel transfer\n");
printf("ca pid: %d\n", Channel->Ca());
m_Channel = Channel;
2005-02-09 20:47:09 +01:00
m_StreamType = StreamType;
switch (m_StreamType) {
2004-12-30 23:43:55 +01:00
case stES:
{
int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid();
if (Apid != 0)
pid = Apid;
2005-02-11 17:44:14 +01:00
m_ESRemux = new cTS2ESRemux(pid);
2004-12-30 23:43:55 +01:00
return SetPid(pid, true);
}
case stPES:
Dprintf("PES\n");
m_PESRemux = new cRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
m_Channel->Spids(), false);
if (Apid != 0)
return SetPid(m_Channel->Vpid(), true)
&& SetPid(Apid, true);
else
return SetPid(m_Channel->Vpid(), true)
&& SetPid(m_Channel->Apid(0), true)
&& SetPid(m_Channel->Dpid(0), true);
2004-12-30 23:43:55 +01:00
case stPS:
2005-02-11 17:44:14 +01:00
m_PSRemux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
m_Channel->Spids());
if (Apid != 0)
return SetPid(m_Channel->Vpid(), true)
&& SetPid(Apid, true);
else
return SetPid(m_Channel->Vpid(), true)
&& SetPid(m_Channel->Apid(0), true)
&& SetPid(m_Channel->Dpid(0), true);
2004-12-30 23:43:55 +01:00
case stTS:
if (Apid != 0)
return SetPid(m_Channel->Vpid(), true)
&& SetPid(Apid, true);
else
return SetPid(m_Channel->Vpid(), true)
&& SetPid(m_Channel->Apid(0), true)
&& SetPid(m_Channel->Dpid(0), true);
2005-02-08 16:34:38 +01:00
2005-02-11 17:44:14 +01:00
case stExtern:
m_ExtRemux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
m_Channel->Spids());
if (Apid != 0)
return SetPid(m_Channel->Vpid(), true)
&& SetPid(Apid, true);
else
return SetPid(m_Channel->Vpid(), true)
&& SetPid(m_Channel->Apid(0), true)
&& SetPid(m_Channel->Dpid(0), true);
2005-02-08 16:34:38 +01:00
case stTSPIDS:
2004-12-30 23:43:55 +01:00
Dprintf("pid streaming mode\n");
return true;
}
return false;
}
bool cStreamdevLiveStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On)
{
2005-02-08 16:34:38 +01:00
#if 0
2004-12-30 23:43:55 +01:00
Dprintf("setting filter\n");
if (On) {
if (m_Filter == NULL) {
m_Filter = new cStreamdevLiveFilter(this);
Dprintf("attaching filter to device\n");
m_Device->AttachFilter(m_Filter);
}
m_Filter->Set(Pid, Tid, Mask);
} else if (m_Filter != NULL)
m_Filter->Del(Pid, Tid, Mask);
return true;
#else
return false;
#endif
}
2005-02-09 20:47:09 +01:00
int cStreamdevLiveStreamer::Put(const uchar *Data, int Count)
{
switch (m_StreamType) {
case stTS:
case stTSPIDS:
return cStreamdevStreamer::Put(Data, Count);
case stPES:
return m_PESRemux->Put(Data, Count);
2005-02-11 17:44:14 +01:00
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;
2005-02-09 20:47:09 +01:00
}
}
uchar *cStreamdevLiveStreamer::Get(int &Count)
{
switch (m_StreamType) {
case stTS:
case stTSPIDS:
return cStreamdevStreamer::Get(Count);
case stPES:
return m_PESRemux->Get(Count);
2005-02-11 17:44:14 +01:00
case stES:
return m_ESRemux->Get(Count);
case stPS:
return m_PSRemux->Get(Count);
2005-02-09 20:47:09 +01:00
2005-02-11 17:44:14 +01:00
case stExtern:
return m_ExtRemux->Get(Count);
default: // shouldn't happen???
return 0;
2005-02-09 20:47:09 +01:00
}
}
void cStreamdevLiveStreamer::Del(int Count)
{
switch (m_StreamType) {
case stTS:
case stTSPIDS:
cStreamdevStreamer::Del(Count);
break;
2005-02-09 20:47:09 +01:00
case stPES:
m_PESRemux->Del(Count);
break;
2005-02-11 17:44:14 +01:00
case stES:
m_ESRemux->Del(Count);
break;
2005-02-09 20:47:09 +01:00
2005-02-11 17:44:14 +01:00
case stPS:
m_PSRemux->Del(Count);
break;
case stExtern:
m_ExtRemux->Del(Count);
break;
2005-02-09 20:47:09 +01:00
}
}
2005-03-12 13:54:19 +01:00
void cStreamdevLiveStreamer::Attach(void)
{
printf("RIGHT ATTACH\n");
m_Device->AttachReceiver(m_Receiver);
}
void cStreamdevLiveStreamer::Detach(void)
{
printf("RIGHT DETACH\n");
m_Device->Detach(m_Receiver);
}
2005-02-09 20:47:09 +01:00
std::string cStreamdevLiveStreamer::Report(void)
{
2005-02-08 18:22:35 +01:00
std::string result;
2004-12-30 23:43:55 +01:00
if (m_Device != NULL)
2005-02-08 18:22:35 +01:00
result += (std::string)"+- Device is " + (const char*)itoa(m_Device->CardIndex()) + "\n";
2004-12-30 23:43:55 +01:00
if (m_Receiver != NULL)
result += "+- Receiver is allocated\n";
result += "+- Pids are ";
for (int i = 0; i < MAXRECEIVEPIDS; ++i)
if (m_Pids[i] != 0)
2005-02-08 18:22:35 +01:00
result += (std::string)(const char*)itoa(m_Pids[i]) + ", ";
2004-12-30 23:43:55 +01:00
result += "\n";
return result;
}