2004-12-30 23:43:55 +01:00
|
|
|
/*
|
2009-02-13 14:02:39 +01:00
|
|
|
* $Id: livefilter.c,v 1.7 2009/02/13 13:02:40 schmirl Exp $
|
2004-12-30 23:43:55 +01:00
|
|
|
*/
|
|
|
|
|
2012-11-24 23:35:10 +01:00
|
|
|
#include <vdr/filter.h>
|
|
|
|
|
2004-12-30 23:43:55 +01:00
|
|
|
#include "server/livefilter.h"
|
|
|
|
#include "common.h"
|
|
|
|
|
2007-04-23 17:44:55 +02:00
|
|
|
#ifndef TS_SYNC_BYTE
|
|
|
|
# define TS_SYNC_BYTE 0x47
|
|
|
|
#endif
|
|
|
|
|
2012-12-16 12:40:44 +01:00
|
|
|
#define FILTERBUFSIZE (1000 * TS_SIZE)
|
2012-11-24 23:35:10 +01:00
|
|
|
|
|
|
|
// --- cStreamdevLiveFilter -------------------------------------------------
|
|
|
|
|
|
|
|
class cStreamdevLiveFilter: public cFilter {
|
|
|
|
private:
|
2012-12-16 12:40:44 +01:00
|
|
|
cStreamdevFilterStreamer *m_Streamer;
|
2012-11-24 23:35:10 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
|
|
|
|
|
|
|
|
public:
|
2012-12-16 12:40:44 +01:00
|
|
|
cStreamdevLiveFilter(cStreamdevFilterStreamer *Streamer);
|
2012-11-24 23:35:10 +01:00
|
|
|
|
|
|
|
void Set(u_short Pid, u_char Tid, u_char Mask) {
|
|
|
|
cFilter::Set(Pid, Tid, Mask);
|
|
|
|
}
|
|
|
|
void Del(u_short Pid, u_char Tid, u_char Mask) {
|
|
|
|
cFilter::Del(Pid, Tid, Mask);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-12-16 12:40:44 +01:00
|
|
|
cStreamdevLiveFilter::cStreamdevLiveFilter(cStreamdevFilterStreamer *Streamer) {
|
2004-12-30 23:43:55 +01:00
|
|
|
m_Streamer = Streamer;
|
|
|
|
}
|
|
|
|
|
2005-02-08 14:59:16 +01:00
|
|
|
void cStreamdevLiveFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
|
|
|
|
{
|
2004-12-30 23:43:55 +01:00
|
|
|
uchar buffer[TS_SIZE];
|
|
|
|
int length = Length;
|
|
|
|
int pos = 0;
|
|
|
|
|
|
|
|
while (length > 0) {
|
|
|
|
int chunk = min(length, TS_SIZE - 5);
|
|
|
|
buffer[0] = TS_SYNC_BYTE;
|
2007-04-24 13:06:12 +02:00
|
|
|
buffer[1] = ((Pid >> 8) & 0x3f) | (pos==0 ? 0x40 : 0); /* bit 6: payload unit start indicator (PUSI) */
|
2004-12-30 23:43:55 +01:00
|
|
|
buffer[2] = Pid & 0xff;
|
|
|
|
buffer[3] = Tid;
|
2009-02-13 14:02:39 +01:00
|
|
|
// this makes it a proprietary stream
|
2004-12-30 23:43:55 +01:00
|
|
|
buffer[4] = (uchar)chunk;
|
|
|
|
memcpy(buffer + 5, Data + pos, chunk);
|
|
|
|
length -= chunk;
|
|
|
|
pos += chunk;
|
|
|
|
|
2012-12-16 12:40:44 +01:00
|
|
|
m_Streamer->Receive(buffer);
|
2004-12-30 23:43:55 +01:00
|
|
|
}
|
|
|
|
}
|
2012-11-24 23:35:10 +01:00
|
|
|
|
|
|
|
// --- cStreamdevFilterStreamer -------------------------------------------------
|
|
|
|
|
|
|
|
cStreamdevFilterStreamer::cStreamdevFilterStreamer():
|
|
|
|
cStreamdevStreamer("streamdev-filterstreaming"),
|
|
|
|
m_Device(NULL),
|
|
|
|
m_Filter(NULL)/*,
|
|
|
|
m_Channel(NULL)*/
|
|
|
|
{
|
2012-12-16 12:40:44 +01:00
|
|
|
m_ReceiveBuffer = new cStreamdevBuffer(FILTERBUFSIZE, TS_SIZE);
|
|
|
|
m_ReceiveBuffer->SetTimeouts(0, 500);
|
2012-11-24 23:35:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cStreamdevFilterStreamer::~cStreamdevFilterStreamer()
|
|
|
|
{
|
|
|
|
Dprintf("Desctructing Filter streamer\n");
|
|
|
|
Detach();
|
|
|
|
m_Device = NULL;
|
|
|
|
DELETENULL(m_Filter);
|
|
|
|
Stop();
|
2012-12-16 12:40:44 +01:00
|
|
|
delete m_ReceiveBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cStreamdevFilterStreamer::Receive(uchar *Data)
|
|
|
|
{
|
|
|
|
int p = m_ReceiveBuffer->PutTS(Data, TS_SIZE);
|
|
|
|
if (p != TS_SIZE)
|
|
|
|
m_ReceiveBuffer->ReportOverflow(TS_SIZE - p);
|
2012-11-24 23:35:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cStreamdevFilterStreamer::Attach(void)
|
|
|
|
{
|
|
|
|
Dprintf("cStreamdevFilterStreamer::Attach()\n");
|
|
|
|
LOCK_THREAD;
|
|
|
|
if(m_Device && m_Filter)
|
|
|
|
m_Device->AttachFilter(m_Filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cStreamdevFilterStreamer::Detach(void)
|
|
|
|
{
|
|
|
|
Dprintf("cStreamdevFilterStreamer::Detach()\n");
|
|
|
|
LOCK_THREAD;
|
|
|
|
if(m_Device && m_Filter)
|
|
|
|
m_Device->Detach(m_Filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cStreamdevFilterStreamer::SetDevice(cDevice *Device)
|
|
|
|
{
|
|
|
|
Dprintf("cStreamdevFilterStreamer::SetDevice()\n");
|
|
|
|
LOCK_THREAD;
|
|
|
|
Detach();
|
|
|
|
m_Device = Device;
|
|
|
|
Attach();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On)
|
|
|
|
{
|
|
|
|
Dprintf("cStreamdevFilterStreamer::SetFilter(%u,0x%x,0x%x,%s)\n", Pid, Tid, Mask, On?"On":"Off");
|
|
|
|
|
|
|
|
if(!m_Device)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (On) {
|
|
|
|
if (m_Filter == NULL) {
|
|
|
|
m_Filter = new cStreamdevLiveFilter(this);
|
|
|
|
Dprintf("attaching filter to device\n");
|
|
|
|
Attach();
|
|
|
|
}
|
|
|
|
m_Filter->Set(Pid, Tid, Mask);
|
|
|
|
} else if (m_Filter != NULL)
|
|
|
|
m_Filter->Del(Pid, Tid, Mask);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|