vdr-plugin-streamdev/server/livestreamer.c

210 lines
5.3 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"
#include "common.h"
2005-02-08 14:59:16 +01:00
cStreamdevLiveReceiver::cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, int Ca,
int Priority, const int *Pids):
cReceiver(Ca, Priority, 0, Pids),
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) {
int p = m_Streamer->Put(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
}
cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority):
cStreamdevStreamer("Live streamer") {
m_Priority = Priority;
2005-02-08 14:59:16 +01:00
m_NumPids = 0;
2004-12-30 23:43:55 +01:00
m_Channel = NULL;
m_Device = NULL;
m_Receiver = NULL;
m_Remux = NULL;
m_Buffer = NULL;
m_Sequence = 0;
#if VDRVERSNUM >= 10300
m_Filter = NULL;
#endif
memset(m_Pids, 0, sizeof(m_Pids));
}
cStreamdevLiveStreamer::~cStreamdevLiveStreamer() {
Dprintf("Desctructing Live streamer\n");
delete m_Receiver;
delete m_Remux;
#if VDRVERSNUM >= 10300
delete m_Filter;
#endif
free(m_Buffer);
}
void cStreamdevLiveStreamer::Detach(void) {
m_Device->Detach(m_Receiver);
}
void cStreamdevLiveStreamer::Attach(void) {
m_Device->AttachReceiver(m_Receiver);
}
void cStreamdevLiveStreamer::Start(cTBSocket *Socket) {
Dprintf("LIVESTREAMER START\n");
cStreamdevStreamer::Start(Socket);
}
bool cStreamdevLiveStreamer::SetPid(int Pid, bool On) {
int idx;
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");
2005-02-08 14:59:16 +01:00
m_Receiver = new cStreamdevLiveReceiver(this, m_Channel->Ca(), m_Priority, m_Pids);
2004-12-30 23:43:55 +01:00
if (m_Device != NULL) {
Dprintf("Attaching new receiver\n");
m_Device->AttachReceiver(m_Receiver);
}
}
return true;
}
bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, int StreamType,
bool StreamPIDS) {
Dprintf("Initializing Remuxer for full channel transfer\n");
printf("ca pid: %d\n", Channel->Ca());
m_Channel = Channel;
switch (StreamType) {
case stES:
{
2005-02-08 14:59:16 +01:00
int pid = ISRADIO(Channel) ? Channel->Apid(0) : Channel->Vpid();
2004-12-30 23:43:55 +01:00
m_Remux = new cTS2ESRemux(pid);
return SetPid(pid, true);
}
case stPES:
2005-02-08 14:59:16 +01:00
m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid(0), Channel->Apid(1),
Channel->Dpid(0), 0, false);
2004-12-30 23:43:55 +01:00
return SetPid(Channel->Vpid(), true)
2005-02-08 14:59:16 +01:00
&& SetPid(Channel->Apid(0), true)
&& SetPid(Channel->Apid(1), true)
&& SetPid(Channel->Dpid(0), true);
2004-12-30 23:43:55 +01:00
break;
case stPS:
2005-02-08 14:59:16 +01:00
m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid(0), 0, 0, 0, true);
2004-12-30 23:43:55 +01:00
return SetPid(Channel->Vpid(), true)
2005-02-08 14:59:16 +01:00
&& SetPid(Channel->Apid(0), true);
2004-12-30 23:43:55 +01:00
break;
case stTS:
if (!StreamPIDS) {
return SetPid(Channel->Vpid(), true)
2005-02-08 14:59:16 +01:00
&& SetPid(Channel->Apid(0), true)
&& SetPid(Channel->Apid(1), true)
&& SetPid(Channel->Dpid(0), true);
2004-12-30 23:43:55 +01:00
}
Dprintf("pid streaming mode\n");
return true;
break;
}
return false;
}
bool cStreamdevLiveStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask,
bool On) {
#if VDRVERSNUM >= 10300
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
}
uchar *cStreamdevLiveStreamer::Process(const uchar *Data, int &Count,
int &Result) {
uchar *remuxed = m_Remux != NULL ? m_Remux->Process(Data, Count, Result)
: cStreamdevStreamer::Process(Data, Count, Result);
if (remuxed) {
/*if (Socket()->Type() == SOCK_DGRAM) {
free(m_Buffer);
Result += 12;
m_Buffer = MALLOC(uchar, Result);
m_Buffer[0] = 0x01;
m_Buffer[1] = 0x02;
m_Buffer[2] = 0x03;
m_Buffer[3] = 0x04;
m_Buffer[4] = (Result & 0xff000000) >> 24;
m_Buffer[5] = (Result & 0xff0000) >> 16;
m_Buffer[6] = (Result & 0xff00) >> 8;
m_Buffer[7] = (Result & 0xff);
m_Buffer[8] = (m_Sequence & 0xff000000) >> 24;
m_Buffer[9] = (m_Sequence & 0xff0000) >> 16;
m_Buffer[10] = (m_Sequence & 0xff00) >> 8;
m_Buffer[11] = (m_Sequence & 0xff);
memcpy(m_Buffer + 12, Data, Result - 12);
if (m_Sequence++ == 0x7fffffff)
m_Sequence = 0;
return m_Buffer;
}*/
return remuxed;
}
return NULL;
}
cTBString cStreamdevLiveStreamer::Report(void) {
cTBString result;
if (m_Device != NULL)
result += "+- Device is " + cTBString::Number(m_Device->CardIndex()) + "\n";
if (m_Receiver != NULL)
result += "+- Receiver is allocated\n";
result += "+- Pids are ";
for (int i = 0; i < MAXRECEIVEPIDS; ++i)
if (m_Pids[i] != 0)
result += cTBString::Number(m_Pids[i]) + ", ";
result += "\n";
return result;
}