Dynamic channel manager

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1566 e54a6e83-5905-42d5-8d5c-058d10e6a962


Origin commit data
------------------
Commit: fa20172141
Author: [CST] Focus <focus.cst@gmail.com>
Date: 2011-07-21 (Thu, 21 Jul 2011)
This commit is contained in:
[CST] Focus
2011-07-21 10:19:14 +00:00
parent a51f347b00
commit 0c051f71c3
2 changed files with 149 additions and 8 deletions

View File

@@ -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__ */

View File

@@ -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;
}