mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-31 09:21:18 +02:00
Dynamic channel manager
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1566 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "ci.h"
|
||||
#include <basicclient.h>
|
||||
#include "types.h"
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
#define DEMUX_DECODE_0 1
|
||||
#define DEMUX_DECODE_1 2
|
||||
@@ -34,19 +36,48 @@
|
||||
#define DEMUX_SOURCE_1 1
|
||||
#define DEMUX_SOURCE_2 2
|
||||
|
||||
#define LIVE_DEMUX 0
|
||||
#define STREAM_DEMUX 1
|
||||
#define RECORD_DEMUX 2
|
||||
|
||||
class CCam : public CBasicClient
|
||||
{
|
||||
private:
|
||||
virtual unsigned char getVersion(void) const;
|
||||
virtual const char *getSocketName(void) const;
|
||||
int camask, demux;
|
||||
int camask, demuxes[3];
|
||||
|
||||
public:
|
||||
CCam();
|
||||
bool sendMessage(const char * const data, const size_t length, bool update = false);
|
||||
bool setCaPmt(CCaPmt * const caPmt, int _demux = 0, int _camask = 1, bool update = false);
|
||||
int getCaMask(void) { return camask; };
|
||||
int getDemux(void) { return demux; };
|
||||
int makeMask(int demux, bool add);
|
||||
};
|
||||
|
||||
typedef std::map<t_channel_id, CCam*> cammap_t;
|
||||
typedef cammap_t::iterator cammap_iterator_t;
|
||||
|
||||
class CCamManager
|
||||
{
|
||||
public:
|
||||
enum runmode {
|
||||
PLAY,
|
||||
RECORD,
|
||||
STREAM
|
||||
};
|
||||
private:
|
||||
cammap_t channel_map;
|
||||
OpenThreads::Mutex mutex;
|
||||
static CCamManager * manager;
|
||||
bool SetMode(t_channel_id id, enum runmode mode, bool enable, bool force_update = false);
|
||||
|
||||
public:
|
||||
CCamManager();
|
||||
~CCamManager();
|
||||
static CCamManager * getInstance(void);
|
||||
bool Start(t_channel_id id, enum runmode mode, bool force_update = false) { return SetMode(id, mode, true, force_update); };
|
||||
bool Stop(t_channel_id id, enum runmode mode) { return SetMode(id, mode, false); };
|
||||
|
||||
};
|
||||
#endif /* __cam_h__ */
|
||||
|
@@ -25,11 +25,15 @@
|
||||
#include <zapit/cam.h>
|
||||
#include <zapit/settings.h> /* CAMD_UDS_NAME */
|
||||
#include <messagetools.h> /* get_length_field_size */
|
||||
#include <zapit/bouquets.h>
|
||||
#include <zapit/satconfig.h>
|
||||
|
||||
extern tallchans allchans;
|
||||
|
||||
CCam::CCam()
|
||||
{
|
||||
camask = 1;
|
||||
demux = 0;
|
||||
camask = 0;
|
||||
demuxes[0] = demuxes[1] = demuxes[2] = 0;
|
||||
}
|
||||
|
||||
unsigned char CCam::getVersion(void) const
|
||||
@@ -58,7 +62,6 @@ bool CCam::sendMessage(const char * const data, const size_t length, bool update
|
||||
|
||||
if(!data || !length) {
|
||||
camask = 1;
|
||||
demux = 0;
|
||||
return false;
|
||||
}
|
||||
if (!open_connection())
|
||||
@@ -70,15 +73,122 @@ bool CCam::sendMessage(const char * const data, const size_t length, bool update
|
||||
bool CCam::setCaPmt(CCaPmt * const caPmt, int _demux, int _camask, bool update)
|
||||
{
|
||||
camask = _camask;
|
||||
demux = _demux;
|
||||
|
||||
printf("CCam::setCaPmt cam %x source %d camask %d update %s\n", (int) this, _demux, camask, update ? "yes" : "no" );
|
||||
if(camask == 0) {
|
||||
close_connection();
|
||||
return true;
|
||||
}
|
||||
if (!caPmt)
|
||||
return true;
|
||||
|
||||
printf("CCam::setCaPmt cam %x source %d camask %d update %s\n", (int) this, demux, camask, update ? "yes" : "no" );
|
||||
unsigned int size = caPmt->getLength();
|
||||
unsigned char buffer[3 + get_length_field_size(size) + size];
|
||||
size_t pos = caPmt->writeToBuffer(buffer, demux, camask);
|
||||
size_t pos = caPmt->writeToBuffer(buffer, _demux, camask);
|
||||
|
||||
return sendMessage((char *)buffer, pos, update);
|
||||
}
|
||||
|
||||
int CCam::makeMask(int demux, bool add)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if(add)
|
||||
demuxes[demux]++;
|
||||
else if(demuxes[demux] > 0)
|
||||
demuxes[demux]--;
|
||||
|
||||
for(int i = 0; i < 3; i++) {
|
||||
if(demuxes[i] > 0)
|
||||
mask |= 1 << i;
|
||||
}
|
||||
printf("CCam::MakeMask: demuxes %d:%d:%d old mask %d new mask %d\n", demuxes[0], demuxes[1], demuxes[2], camask, mask);
|
||||
return mask;
|
||||
}
|
||||
|
||||
CCamManager * CCamManager::manager = NULL;
|
||||
|
||||
CCamManager::CCamManager()
|
||||
{
|
||||
channel_map.clear();
|
||||
}
|
||||
|
||||
CCamManager::~CCamManager()
|
||||
{
|
||||
for(cammap_iterator_t it = channel_map.begin(); it != channel_map.end(); it++)
|
||||
delete it->second;
|
||||
channel_map.clear();
|
||||
}
|
||||
|
||||
CCamManager * CCamManager::getInstance(void)
|
||||
{
|
||||
if(manager == NULL)
|
||||
manager = new CCamManager();
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
bool CCamManager::SetMode(t_channel_id id, enum runmode mode, bool start, bool force_update)
|
||||
{
|
||||
CCam * cam;
|
||||
int oldmask, newmask;
|
||||
int demux = DEMUX_SOURCE_0;
|
||||
int source = DEMUX_SOURCE_0;
|
||||
|
||||
tallchans_iterator cit = allchans.find(id);
|
||||
if(cit == allchans.end()) {
|
||||
printf("CCamManager: channel %llx not found\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
CZapitChannel * channel = &(cit->second);
|
||||
|
||||
mutex.lock();
|
||||
if(channel->getCaPmt() == NULL) {
|
||||
printf("CCamManager: channel %llx dont have caPmt\n", id);
|
||||
mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
sat_iterator_t sit = satellitePositions.find(channel->getSatellitePosition());
|
||||
|
||||
cammap_iterator_t it = channel_map.find(id);
|
||||
if(it == channel_map.end()) {
|
||||
cam = new CCam();
|
||||
channel_map.insert(std::pair<t_channel_id, CCam*>(id, cam));
|
||||
} else
|
||||
cam = it->second;
|
||||
|
||||
switch(mode) {
|
||||
case PLAY:
|
||||
source = DEMUX_SOURCE_0;
|
||||
demux = LIVE_DEMUX;
|
||||
break;
|
||||
case RECORD:
|
||||
source = DEMUX_SOURCE_0;
|
||||
demux = RECORD_DEMUX;//FIXME
|
||||
break;
|
||||
case STREAM:
|
||||
source = DEMUX_SOURCE_0;
|
||||
demux = STREAM_DEMUX;//FIXME
|
||||
break;
|
||||
}
|
||||
|
||||
oldmask = cam->getCaMask();
|
||||
newmask = cam->makeMask(demux, start);
|
||||
|
||||
if((oldmask != newmask) || force_update)
|
||||
cam->setCaPmt(channel->getCaPmt(), source, newmask, true);
|
||||
|
||||
if(newmask == 0) {
|
||||
/* FIXME: back to live channel from playback dont parse pmt and call setCaPmt
|
||||
* (see CMD_SB_LOCK / UNLOCK PLAYBACK */
|
||||
//channel->setCaPmt(NULL);
|
||||
channel->setRawPmt(NULL);
|
||||
channel_map.erase(id);
|
||||
delete cam;
|
||||
}
|
||||
mutex.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user