Merge remote-tracking branch 'check/next-cc'

build-tested only, needs fixing

Conflicts:
	data/locale/deutsch.locale
	data/locale/english.locale
	src/Makefile.am
	src/driver/rcinput.cpp
	src/driver/streamts.cpp
	src/eitd/sectionsd.cpp
	src/gui/Makefile.am
	src/gui/bouquetlist.cpp
	src/gui/hdd_menu.cpp
	src/gui/luainstance.cpp
	src/gui/luainstance.h
	src/gui/moviebrowser.cpp
	src/gui/movieplayer.cpp
	src/gui/pluginlist.cpp
	src/gui/plugins.cpp
	src/gui/plugins.h
	src/gui/scan.cpp
	src/gui/scan_setup.cpp
	src/gui/user_menue.cpp
	src/gui/videosettings.cpp
	src/gui/widget/menue.cpp
	src/neutrino.cpp
	src/neutrinoMessages.h
	src/system/locals.h
	src/system/locals_intern.h
	src/zapit/include/zapit/scan.h
	src/zapit/src/femanager.cpp
	src/zapit/src/frontend.cpp
	src/zapit/src/getservices.cpp
	src/zapit/src/transponder.cpp
This commit is contained in:
Stefan Seyfried
2014-04-27 19:14:06 +02:00
178 changed files with 6683 additions and 3601 deletions

View File

@@ -43,7 +43,7 @@
const char * const file_extension_list[] =
{
"aac", "asf", "avi", "bmp", "cdr", "crw",
"dts", "flac", "gif", "imu", "jpeg", "jpg",
"dts", "flac", "gif", "imu", "iso", "jpeg", "jpg",
"m2a", "m3u", "m4a", "mkv", "mp2", "mp3",
"mpa", "ogg", "pls", "png", "sh",
"txt", "url", "wav", "xml"
@@ -53,7 +53,7 @@ const char * const file_extension_list[] =
const CFile::FileType file_type_list[] =
{
CFile::FILE_AAC , CFile::FILE_ASF , CFile::FILE_AVI , CFile::FILE_PICTURE , CFile::FILE_CDR , CFile::FILE_PICTURE ,
CFile::FILE_WAV , CFile::FILE_FLAC , CFile::FILE_PICTURE , CFile::STREAM_PICTURE, CFile::FILE_PICTURE , CFile::FILE_PICTURE ,
CFile::FILE_WAV , CFile::FILE_FLAC , CFile::FILE_PICTURE , CFile::STREAM_PICTURE, CFile::FILE_ISO , CFile::FILE_PICTURE , CFile::FILE_PICTURE ,
CFile::FILE_MP3 , CFile::FILE_PLAYLIST , CFile::FILE_AAC , CFile::FILE_MKV , CFile::FILE_MP3 , CFile::FILE_MP3 ,
CFile::FILE_MP3 , CFile::FILE_OGG , CFile::FILE_PLAYLIST, CFile::FILE_PICTURE , CFile::FILE_TEXT ,
CFile::FILE_TEXT , CFile::STREAM_AUDIO , CFile::FILE_WAV , CFile::FILE_XML

View File

@@ -60,6 +60,7 @@ public:
FILE_AVI,
FILE_ASF,
FILE_DIR,
FILE_ISO,
FILE_TEXT,
FILE_CDR,
FILE_MP3,

View File

@@ -102,6 +102,29 @@ CPictureViewer::CFormathandler * CPictureViewer::fh_getsize (const char *name, i
}
return (NULL);
}
std::string CPictureViewer::DownloadImage(std::string url)
{
if (strstr(url.c_str(), "://")) {
std::string tmpname = "/tmp/pictureviewer" + url.substr(url.find_last_of("."));
FILE *tmpFile = fopen(tmpname.c_str(), "wb");
if (tmpFile) {
CURL *ch = curl_easy_init();
curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(ch, CURLOPT_WRITEDATA, tmpFile);
curl_easy_setopt(ch, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(ch, CURLOPT_URL, url.c_str());
curl_easy_perform(ch);
curl_easy_cleanup(ch);
fclose(tmpFile);
url = true;
}
url = tmpname;
}
return url;
}
bool CPictureViewer::DecodeImage (const std::string & _name, bool showBusySign, bool unscaled)
{
@@ -121,29 +144,9 @@ bool CPictureViewer::DecodeImage (const std::string & _name, bool showBusySign,
if (showBusySign)
showBusy (m_startx + 3, m_starty + 3, 10, 0xff, 00, 00);
std::string name = _name;
bool url = false;
if (strstr(name.c_str(), "://")) {
std::string tmpname;
tmpname = "/tmp/pictureviewer" + name.substr(name.find_last_of("."));
FILE *tmpFile = fopen(tmpname.c_str(), "wb");
if (tmpFile) {
CURL *ch = curl_easy_init();
curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(ch, CURLOPT_WRITEDATA, tmpFile);
curl_easy_setopt(ch, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(ch, CURLOPT_URL, name.c_str());
curl_easy_perform(ch);
curl_easy_cleanup(ch);
fclose(tmpFile);
url = true;
}
name = tmpname;
}
std::string name = DownloadImage(_name);
CFormathandler *fh;
if (unscaled)
@@ -499,6 +502,7 @@ void CPictureViewer::getSize(const char* name, int* width, int *height)
}
#define LOGO_FLASH_DIR DATADIR "/neutrino/icons/logo"
#define LOGO_FLASH_DIR_VAR "/var/tuxbox/icons/logo"
bool CPictureViewer::GetLogoName(const uint64_t& channel_id, const std::string& ChannelName, std::string & name, int *width, int *height)
{
@@ -523,6 +527,16 @@ bool CPictureViewer::GetLogoName(const uint64_t& channel_id, const std::string&
id_tmp_path += strChnId + fileType[i];
v_path.push_back(id_tmp_path);
//create filename with channel name (LOGO_FLASH_DIR_VAR)
id_tmp_path = LOGO_FLASH_DIR_VAR "/";
id_tmp_path += ChannelName + fileType[i];
v_path.push_back(id_tmp_path);
//create filename with id (LOGO_FLASH_DIR_VAR)
id_tmp_path = LOGO_FLASH_DIR_VAR "/";
id_tmp_path += strChnId + fileType[i];
v_path.push_back(id_tmp_path);
//create filename with channel name (LOGO_FLASH_DIR)
id_tmp_path = LOGO_FLASH_DIR "/";
id_tmp_path += ChannelName + fileType[i];

View File

@@ -54,6 +54,7 @@ class CPictureViewer
bool ShowImage(const std::string & filename, bool unscaled=false);
bool DecodeImage(const std::string & name, bool showBusySign=false, bool unscaled=false);
bool DisplayNextImage();
std::string DownloadImage(std::string url);
void SetScaling(ScalingMode s){m_scaling=s;}
void SetAspectRatio(float aspect_ratio) {m_aspect=aspect_ratio;}
void showBusy(int sx, int sy, int width, char r, char g, char b);

View File

@@ -5,6 +5,7 @@
2003 thegoodguy
Copyright (C) 2008-2012 Stefan Seyfried
Copyright (C) 2013-2014 martii
License: GPL
@@ -29,6 +30,7 @@
#include <driver/rcinput.h>
#include <driver/abstime.h>
#include <system/helpers.h>
#include <stdio.h>
#include <asm/types.h>
@@ -52,13 +54,14 @@
#include <global.h>
#include <driver/shutdown_count.h>
#include <neutrino.h>
//#include <neutrino.h>
#include <neutrinoMessages.h>
#include <timerd/timermanager.h>
#include <timerdclient/timerdclient.h>
#include <sectionsdclient/sectionsdclient.h>
#include <cs_api.h>
//#define RCDEBUG
//#define USE_GETTIMEOFDAY
#define ENABLE_REPEAT_CHECK
@@ -88,6 +91,8 @@ static bool input_stopped = false;
CRCInput::CRCInput()
{
timerid= 1;
repeatkeys = NULL;
longPressAny = false;
// pipe for internal event-queue
// -----------------------------
@@ -119,7 +124,7 @@ CRCInput::CRCInput()
int clilen;
memset(&servaddr, 0, sizeof(struct sockaddr_un));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, NEUTRINO_UDS_NAME);
cstrncpy(servaddr.sun_path, NEUTRINO_UDS_NAME, sizeof(servaddr.sun_path));
clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
unlink(NEUTRINO_UDS_NAME);
@@ -150,7 +155,7 @@ CRCInput::CRCInput()
repeat_block = repeat_block_generic = 0;
open();
rc_last_key = KEY_MAX;
firstKey = true;
longPressEnd = 0;
//select and setup remote control hardware
set_rc_hw();
@@ -176,6 +181,8 @@ void CRCInput::open(int dev)
//+++++++++++++++++++++++++++++++++++++++
#ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL
fd_keyb = STDIN_FILENO;
if (fd_rc[0] < 0)
fd_rc[0] = fd_keyb;
#else
fd_keyb = 0;
#endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */
@@ -352,13 +359,7 @@ int CRCInput::messageLoop( bool anyKeyCancels, int timeout )
int CRCInput::addTimer(uint64_t Interval, bool oneshot, bool correct_time )
{
#ifdef USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday( &tv, NULL );
uint64_t timeNow = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t timeNow = time_monotonic_us();
#endif
timer _newtimer;
if (!oneshot)
@@ -390,19 +391,6 @@ int CRCInput::addTimer(uint64_t Interval, bool oneshot, bool correct_time )
return _newtimer.id;
}
#ifdef USE_GETTIMEOFDAY
int CRCInput::addTimer(struct timeval Timeout)
{
uint64_t timesout = (uint64_t) Timeout.tv_usec + (uint64_t)((uint64_t) Timeout.tv_sec * (uint64_t) 1000000);
return addTimer( timesout, true, false );
}
int CRCInput::addTimer(const time_t *Timeout)
{
return addTimer( (uint64_t)*Timeout* (uint64_t) 1000000, true, false );
}
#endif
void CRCInput::killTimer(uint32_t &id)
{
//printf("killing timer %d\n", id);
@@ -422,13 +410,7 @@ void CRCInput::killTimer(uint32_t &id)
int CRCInput::checkTimers()
{
int _id = 0;
#ifdef USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday( &tv, NULL );
uint64_t timeNow = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t timeNow = time_monotonic_us();
#endif
std::vector<timer>::iterator e;
for ( e= timers.begin(); e!= timers.end(); ++e )
if ( e->times_out< timeNow+ 2000 )
@@ -468,36 +450,18 @@ int CRCInput::checkTimers()
int64_t CRCInput::calcTimeoutEnd(const int timeout_in_seconds)
{
#ifdef USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec + (uint64_t)timeout_in_seconds) * (uint64_t) 1000000;
#else
return time_monotonic_us() + ((uint64_t)timeout_in_seconds * (uint64_t) 1000000);
#endif
}
int64_t CRCInput::calcTimeoutEnd_MS(const int timeout_in_milliseconds)
{
#ifdef USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday(&tv, NULL);
uint64_t timeNow = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t timeNow = time_monotonic_us();
#endif
return ( timeNow + timeout_in_milliseconds * 1000 );
}
void CRCInput::getMsgAbsoluteTimeout(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint64_t *TimeoutEnd, bool bAllowRepeatLR)
{
#ifdef USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday( &tv, NULL );
uint64_t timeNow = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t timeNow = time_monotonic_us();
#endif
uint64_t diff;
if ( *TimeoutEnd < timeNow+ 100 )
@@ -507,16 +471,6 @@ void CRCInput::getMsgAbsoluteTimeout(neutrino_msg_t * msg, neutrino_msg_data_t *
//printf("CRCInput::getMsgAbsoluteTimeout diff %llx TimeoutEnd %llx now %llx\n", diff, *TimeoutEnd, timeNow);
getMsg_us( msg, data, diff, bAllowRepeatLR );
#ifdef USE_GETTIMEOFDAY
if ( *msg == NeutrinoMessages::EVT_TIMESET )
{
// recalculate timeout....
//uint64_t ta= *TimeoutEnd;
*TimeoutEnd= *TimeoutEnd + *(int64_t*) *data;
//printf("[getMsgAbsoluteTimeout]: EVT_TIMESET - recalculate timeout\n%llx/%llx - %llx/%llx\n", timeNow, *(int64_t*) *data, *TimeoutEnd, ta );
}
#endif
}
void CRCInput::getMsg(neutrino_msg_t * msg, neutrino_msg_data_t * data, int Timeout, bool bAllowRepeatLR)
@@ -529,6 +483,43 @@ void CRCInput::getMsg_ms(neutrino_msg_t * msg, neutrino_msg_data_t * data, int T
getMsg_us(msg, data, (uint64_t) Timeout * 1000, bAllowRepeatLR);
}
uint32_t *CRCInput::setAllowRepeat(uint32_t *rk) {
uint32_t *r = repeatkeys;
repeatkeys = rk;
return r;
}
bool checkLongPress(uint32_t key); // keybind_setup.cpp
bool CRCInput::mayLongPress(uint32_t key, bool bAllowRepeatLR)
{
if (mayRepeat(key, bAllowRepeatLR))
return false;
if (longPressAny)
return true;
return checkLongPress(key);
}
bool CRCInput::mayRepeat(uint32_t key, bool bAllowRepeatLR)
{
if((key == RC_up) || (key == RC_down)
|| (key == RC_plus) || (key == RC_minus)
|| (key == RC_page_down) || (key == RC_page_up)
|| ((bAllowRepeatLR) && ((key == RC_left ) || (key == RC_right))))
return true;
if (repeatkeys) {
uint32_t *k = repeatkeys;
while (*k != RC_nokey) {
if (*k == key) {
return true;
}
k++;
}
}
return false;
}
void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint64_t Timeout, bool bAllowRepeatLR)
{
static uint64_t last_keypress = 0ULL;
@@ -544,7 +535,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
int timer_id;
fd_set rfds;
t_input_event ev;
*data = 0;
@@ -559,25 +549,13 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
}
// wiederholung reinmachen - dass wirklich die ganze zeit bis timeout gewartet wird!
#ifdef USE_GETTIMEOFDAY
gettimeofday( &tv, NULL );
uint64_t getKeyBegin = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t getKeyBegin = time_monotonic_us();
#endif
while(1) {
/* we later check for ev.type = EV_SYN which is 0x00, so set something invalid here... */
memset(&ev, 0, sizeof(ev));
ev.type = EV_MAX;
timer_id = 0;
if ( !timers.empty() )
{
#ifdef USE_GETTIMEOFDAY
gettimeofday( &tv, NULL );
uint64_t t_n= (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
#else
uint64_t t_n = time_monotonic_us();
#endif
if ( timers[0].times_out< t_n )
{
timer_id = checkTimers();
@@ -950,12 +928,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
if ((int64_t)last_keypress > *(int64_t*)p)
last_keypress += *(int64_t *)p;
#ifdef USE_GETTIMEOFDAY
// Timer anpassen
for(std::vector<timer>::iterator e = timers.begin(); e != timers.end(); ++e)
if (e->correct_time)
e->times_out+= *(int64_t*) p;
#endif
*msg = NeutrinoMessages::EVT_TIMESET;
*data = (neutrino_msg_data_t) p;
dont_delete_p = true;
@@ -1197,7 +1169,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
*data = (unsigned long) p;
dont_delete_p = true;
break;
default :
printf("[neutrino] event INITID_TIMERD - unknown eventID 0x%x\n", emsg.eventID );
@@ -1205,6 +1176,13 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
}
else if (emsg.initiatorID == CEventServer::INITID_NEUTRINO)
{
printf("CRCInput::getMsg_us: INITID_NEUTRINO: msg %x size %d data %x\n", (int) emsg.eventID, emsg.dataSize, (int) p);
if (emsg.eventID == NeutrinoMessages::EVT_HOTPLUG) {
printf("EVT_HOTPLUG: [%s]\n", (char *) p);
*msg = emsg.eventID;
*data = (neutrino_msg_data_t) p;
dont_delete_p = true;
}
#if 0
if ((emsg.eventID == NeutrinoMessages::EVT_RECORDING_ENDED) &&
(read_bytes == sizeof(stream2file_status2_t)))
@@ -1225,10 +1203,21 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
}
else
printf("[neutrino] event - unknown initiatorID 0x%x\n", emsg.initiatorID);
if ( !dont_delete_p )
{
delete[] p;//new [] delete []
p= NULL;
switch (emsg.eventID) {
case NeutrinoMessages::EVT_CURRENTEPG:
case NeutrinoMessages::EVT_NEXTEPG:
{
CSectionsdClient::CurrentNextInfo *cn = (CSectionsdClient::CurrentNextInfo *) p;
delete cn;
p = NULL;
break;
}
default:
if (!dont_delete_p) {
delete[] p;
p = NULL;
}
}
}
}
@@ -1249,8 +1238,11 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) {
if ((fd_rc[i] != -1) && (FD_ISSET(fd_rc[i], &rfds))) {
int ret;
ret = read(fd_rc[i], &ev, sizeof(t_input_event));
t_input_event ev;
memset(&ev, 0, sizeof(ev));
/* we later check for ev.type = EV_SYN = 0x00, so set something invalid here... */
ev.type = EV_MAX;
int ret = read(fd_rc[i], &ev, sizeof(t_input_event));
if (ret != sizeof(t_input_event)) {
if (errno == ENODEV) {
/* hot-unplugged? */
@@ -1262,19 +1254,44 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
if (ev.type == EV_SYN)
continue; /* ignore... */
SHTDCNT::getInstance()->resetSleepTimer();
if (firstKey) {
firstKey = false;
CTimerManager::getInstance()->cancelShutdownOnWakeup();
}
uint32_t trkey = translate(ev.code);
#ifdef _DEBUG
printf("key: %04x value %d, translate: %04x -%s-\n", ev.code, ev.value, trkey, getKeyName(trkey).c_str());
#endif
if (trkey == RC_nokey)
continue;
if (g_settings.longkeypress_duration > LONGKEYPRESS_OFF) {
uint64_t longPressNow = time_monotonic_us();
if (ev.value == 0 && longPressEnd) {
if (longPressNow < longPressEnd) {
// Key was a potential long press, but wasn't pressed long enough
longPressEnd = 0;
ev.value = 1;
} else {
// Long-press, key released after time limit
longPressEnd = 0;
continue;
}
} else if (ev.value == 1 && mayLongPress(trkey, bAllowRepeatLR)) {
// A long-press may start here.
longPressEnd = longPressNow + 1000 * g_settings.longkeypress_duration;
rc_last_key = KEY_MAX;
continue;
} else if (ev.value == 2 && longPressEnd) {
if (longPressEnd < longPressNow) {
// Key was pressed long enough.
ev.value = 1;
trkey |= RC_Repeat;
} else {
// Long-press, but key still not released. Skip.
continue;
}
}
}
if (ev.value) {
#ifdef RCDEBUG
printf("got keydown native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str());
printf("rc_last_key %04x rc_last_repeat_key %04x\n\n", rc_last_key, rc_last_repeat_key);
#endif
uint64_t now_pressed;
@@ -1282,21 +1299,17 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
tv = ev.time;
now_pressed = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
if (ev.code == rc_last_key) {
if (trkey == rc_last_key) {
/* only allow selected keys to be repeated */
/* (why?) */
if( (trkey == RC_up) || (trkey == RC_down ) ||
(trkey == RC_plus ) || (trkey == RC_minus ) ||
(trkey == RC_page_down ) || (trkey == RC_page_up ) ||
((bAllowRepeatLR) && ((trkey == RC_left ) || (trkey == RC_right))) ||
(g_settings.shutdown_real_rcdelay && ((trkey == RC_standby) && (g_info.hw_caps->can_shutdown))))
if (mayRepeat(trkey, bAllowRepeatLR) ||
(g_settings.shutdown_real_rcdelay && ((trkey == RC_standby) && (g_info.hw_caps->can_shutdown))))
{
#ifdef ENABLE_REPEAT_CHECK
if (rc_last_repeat_key != ev.code) {
if (rc_last_repeat_key != trkey) {
if ((now_pressed > last_keypress + repeat_block) ||
/* accept all keys after time discontinuity: */
(now_pressed < last_keypress))
rc_last_repeat_key = ev.code;
rc_last_repeat_key = trkey;
else
keyok = false;
}
@@ -1308,7 +1321,7 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
else
rc_last_repeat_key = KEY_MAX;
rc_last_key = ev.code;
rc_last_key = trkey;
if (keyok) {
#ifdef ENABLE_REPEAT_CHECK
@@ -1329,9 +1342,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
} /* if (ev.value) */
else {
// clear rc_last_key on keyup event
#ifdef RCDEBUG
printf("got keyup native key: %04x %04x, translate: %04x -%s-\n", ev.code, ev.code&0x1f, translate(ev.code, 0), getKeyName(translate(ev.code, 0)).c_str() );
#endif
rc_last_key = KEY_MAX;
if (trkey == RC_standby) {
*msg = RC_standby;
@@ -1341,8 +1351,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
}
}/* if FDSET */
} /* for NUMBER_OF_EVENT_DEVICES */
if (ev.type == EV_SYN)
continue; /* ignore... */
if(FD_ISSET(fd_pipe_low_priority[0], &rfds))
{
@@ -1368,12 +1376,7 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6
else
{
//timeout neu kalkulieren
#ifdef USE_GETTIMEOFDAY
gettimeofday( &tv, NULL );
int64_t getKeyNow = (int64_t) tv.tv_usec + (int64_t)((int64_t) tv.tv_sec * (int64_t) 1000000);
#else
int64_t getKeyNow = time_monotonic_us();
#endif
int64_t diff = (getKeyNow - getKeyBegin);
if( Timeout <= (uint64_t) diff )
{
@@ -1447,21 +1450,21 @@ unsigned int CRCInput::convertDigitToKey(const unsigned int digit)
}
/**************************************************************************
* getUnicodeValue - return unicode value of the key or -1
* getUnicodeValue - return unicode value of the key or \0
*
**************************************************************************/
#define UNICODE_VALUE_SIZE 58
static const int unicode_value[UNICODE_VALUE_SIZE] = {-1 , -1 , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', -1 , -1 ,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', -1 , -1 , 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', -1 /* FIXME */, -1 /* FIXME */, -1 , '\\', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', ',', '.', '/', -1, -1, -1, ' '};
static const char unicode_value[UNICODE_VALUE_SIZE * 2] =
"\0\0" "\0\0" "1\0" "2\0" "3\0" "4\0" "5\0" "6\0" "7\0" "8\0" "9\0" "0\0" "-\0" "=\0" "\0\0" "\0\0"
"Q\0" "W\0" "E\0" "R\0" "T\0" "Y\0" "U\0" "I\0" "O\0" "P\0" "{\0" "}\0" "\0\0" "\0\0" "A\0" "S\0"
"D\0" "F\0" "G\0" "H\0" "J\0" "K\0" "L\0" ";\0" "'\0" "\140\0" "\0\0" "\\\0" "Z\0" "X\0" "C\0" "V\0"
"B\0" "N\0" "M\0" "\0\0" ".\0" "/\0" "\0\0" "\0\0" "\0\0" " ";
int CRCInput::getUnicodeValue(const neutrino_msg_t key)
const char *CRCInput::getUnicodeValue(const neutrino_msg_t key)
{
if (key < UNICODE_VALUE_SIZE)
return unicode_value[key];
else
return -1;
return unicode_value + key * 2;
return "";
}
/**************************************************************************
@@ -1524,20 +1527,6 @@ const char * CRCInput::getSpecialKeyName(const unsigned int key)
return "radio";
case RC_text:
return "text";
#if 0
case RC_shift_red:
return "shift-red";
case RC_shift_green:
return "shift-green";
case RC_shift_yellow:
return "shift-yellow";
case RC_shift_blue:
return "shift-blue";
case RC_shift_tv:
return "shift-tv";
case RC_shift_radio:
return "shift-radio";
#endif
case RC_epg:
return "epg";
case RC_recall:
@@ -1606,21 +1595,18 @@ const char * CRCInput::getSpecialKeyName(const unsigned int key)
std::string CRCInput::getKeyName(const unsigned int key)
{
return (std::string)getKeyNameC(key);
std::string res(getKeyNameC(key & ~RC_Repeat));
if ((key & RC_Repeat) && res != "unknown")
res += " (long)";
return res;
}
const char *CRCInput::getKeyNameC(const unsigned int key)
{
int lunicode_value = getUnicodeValue(key);
if (lunicode_value == -1)
return getSpecialKeyName(key);
else
{
static char tmp[2];
tmp[0] = lunicode_value;
tmp[1] = 0;
return tmp;
}
const char *lunicode_value = getUnicodeValue(key);
if (*lunicode_value)
return lunicode_value;
return getSpecialKeyName(key);
}
/**************************************************************************
@@ -1631,9 +1617,9 @@ int CRCInput::translate(int code)
{
switch(code)
{
case 0x100:
case 0x100: // FIXME -- needed?
return RC_up;
case 0x101:
case 0x101: // FIXME -- needed?
return RC_down;
#ifdef HAVE_AZBOX_HARDWARE
case KEY_HOME:

View File

@@ -141,6 +141,9 @@ class CRCInput
uint32_t timerid;
std::vector<timer> timers;
uint32_t *repeatkeys;
uint64_t longPressEnd;
bool longPressAny;
int fd_pipe_high_priority[2];
int fd_pipe_low_priority[2];
int fd_gamerc;
@@ -155,7 +158,6 @@ class CRCInput
int fd_max;
int clickfd;
bool firstKey;
__u16 rc_last_key;
void set_dsp();
@@ -164,6 +166,8 @@ class CRCInput
int translate(int code);
void calculateMaxFd(void);
int checkTimers();
bool mayRepeat(uint32_t key, bool bAllowRepeatLR = false);
bool mayLongPress(uint32_t key, bool bAllowRepeatLR = false);
#ifdef IOC_IR_SET_PRI_PROTOCOL
void set_rc_hw(ir_protocol_t ir_protocol, unsigned int ir_address);
#endif
@@ -290,7 +294,8 @@ class CRCInput
static bool isNumeric(const neutrino_msg_t key);
static int getNumericValue(const neutrino_msg_t key);
static unsigned int convertDigitToKey(const unsigned int digit);
static int getUnicodeValue(const neutrino_msg_t key);
static const char *getUnicodeValue(const neutrino_msg_t key);
uint32_t *setAllowRepeat(uint32_t *);
static const char * getSpecialKeyName(const unsigned int key);
static const char *getKeyNameC(const unsigned int key);
@@ -317,6 +322,8 @@ class CRCInput
void close_click();
void play_click();
void reset_dsp(int rate);
void setLongPressAny(bool b) { longPressAny = b; };
};

View File

@@ -97,7 +97,6 @@ CRecordInstance::CRecordInstance(const CTimerd::RecordingInfo * const eventinfo,
cMovieInfo = new CMovieInfo();
recMovieInfo = new MI_MOVIE_INFO();
record = NULL;
tshift_mode = TSHIFT_MODE_OFF;
rec_stop_msg = g_Locale->getText(LOCALE_RECORDING_STOP);
}
@@ -260,6 +259,7 @@ bool CRecordInstance::Stop(bool remove_event)
hintBox.paint();
printf("%s: channel %" PRIx64 " recording_id %d\n", __func__, channel_id, recording_id);
printf("%s: file %s.ts\n", __FUNCTION__, filename);
SaveXml();
/* Stop do close fd - if started */
record->Stop();
@@ -450,15 +450,19 @@ record_error_msg_t CRecordInstance::Record()
//FIXME recording_id (timerd eventID) is 0 means its user recording, in this case timer always added ?
if(ret == RECORD_OK && recording_id == 0) {
time_t now = time(NULL);
int record_end = now+g_settings.record_hours*60*60;
if (g_settings.recording_epg_for_end)
{
int pre=0, post=0;
CEPGData epgData;
if (CEitManager::getInstance()->getActualEPGServiceKey(channel_id, &epgData )) {
g_Timerd->getRecordingSafety(pre, post);
if (epgData.epg_times.startzeit > 0)
record_end = epgData.epg_times.startzeit + epgData.epg_times.dauer + post;
int record_end;
if (autoshift) {
record_end = now+g_settings.timeshift_hours*60*60;
} else {
record_end = now+g_settings.record_hours*60*60;
if (g_settings.recording_epg_for_end) {
int pre=0, post=0;
CEPGData epgData;
if (CEitManager::getInstance()->getActualEPGServiceKey(channel_id, &epgData )) {
g_Timerd->getRecordingSafety(pre, post);
if (epgData.epg_times.startzeit > 0)
record_end = epgData.epg_times.startzeit + epgData.epg_times.dauer + post;
}
}
}
recording_id = g_Timerd->addImmediateRecordTimerEvent(channel_id, now, record_end, epgid, epg_time, apidmode);
@@ -676,25 +680,13 @@ record_error_msg_t CRecordInstance::MakeFileName(CZapitChannel * channel)
strncat(filename, "_",FILENAMEBUFFERSIZE - strlen(filename)-1);
}
pos = strlen(filename);
if (g_settings.recording_epg_for_filename) {
if(epgid != 0) {
CShortEPGData epgdata;
if(CEitManager::getInstance()->getEPGidShort(epgid, &epgdata)) {
if (!(epgdata.title.empty())) {
strcpy(&(filename[pos]), epgdata.title.c_str());
ZapitTools::replace_char(&filename[pos]);
}
}
} else if (!epgTitle.empty()) {
strcpy(&(filename[pos]), epgTitle.c_str());
ZapitTools::replace_char(&filename[pos]);
}
}
pos = strlen(filename) - ((!autoshift && g_settings.recording_save_in_channeldir) ? 0 : (ext_channel_name.length() /*remove last "_"*/ +1));
std::string ext_file_name = g_settings.recording_filename_template;
MakeExtFileName(channel, ext_file_name);
strcpy(&(filename[pos]), UTF8_TO_FILESYSTEM_ENCODING(ext_file_name.c_str()));
pos = strlen(filename);
time_t t = time(NULL);
pos += strftime(&(filename[pos]), sizeof(filename) - pos - 1, "%Y%m%d_%H%M%S", localtime(&t));
if(autoshift)
strncat(filename, "_temp",FILENAMEBUFFERSIZE - strlen(filename)-1);
@@ -702,6 +694,60 @@ record_error_msg_t CRecordInstance::MakeFileName(CZapitChannel * channel)
return RECORD_OK;
}
void CRecordInstance::StringReplace(std::string &str, const std::string search, const std::string rstr)
{
std::string::size_type ptr = 0;
std::string::size_type pos = 0;
while((ptr = str.find(search,pos)) != std::string::npos){
str.replace(ptr,search.length(),rstr);
pos = ptr + rstr.length();
}
}
void CRecordInstance::MakeExtFileName(CZapitChannel * channel, std::string &FilenameTemplate)
{
char buf[256];
// %C == channel, %T == title, %I == info1, %d == date, %t == time_t
if (FilenameTemplate.empty())
FilenameTemplate = "%C_%T_%d_%t";
time_t t = time(NULL);
strftime(buf,sizeof(buf),"%Y%m%d",localtime(&t));
StringReplace(FilenameTemplate,"%d",buf);
strftime(buf,sizeof(buf),"%H%M%S",localtime(&t));
StringReplace(FilenameTemplate,"%t",buf);
std::string channel_name = channel->getName();
if (!(channel_name.empty())) {
strcpy(buf, UTF8_TO_FILESYSTEM_ENCODING(channel_name.c_str()));
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%C",buf);
}
else
StringReplace(FilenameTemplate,"%C","no_channel");
CShortEPGData epgdata;
if(CEitManager::getInstance()->getEPGidShort(epgid, &epgdata)) {
if (!(epgdata.title.empty())) {
strcpy(buf, epgdata.title.c_str());
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%T",buf);
}
else
StringReplace(FilenameTemplate,"%T","no_title");
if (!(epgdata.info1.empty())) {
strcpy(buf, epgdata.info1.c_str());
ZapitTools::replace_char(buf);
StringReplace(FilenameTemplate,"%I",buf);
}
else
StringReplace(FilenameTemplate,"%I","no_info");
}
}
void CRecordInstance::GetRecordString(std::string &str, std::string &dur)
{
CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(channel_id);
@@ -832,28 +878,6 @@ const std::string CRecordManager::GetFileName(t_channel_id channel_id, bool time
/* return record mode mask, for channel_id not 0, or global */
int CRecordManager::GetRecordMode(const t_channel_id channel_id)
{
#if 0
if (RecordingStatus(channel_id) || IsTimeshift(channel_id))
{
if (RecordingStatus(channel_id) && !IsTimeshift(channel_id))
return RECMODE_REC;
if (channel_id == 0)
{
int records = GetRecordCount();
if (IsTimeshift(channel_id) && (records == 1))
return RECMODE_TSHIFT;
else if (IsTimeshift(channel_id) && (records > 1))
return RECMODE_REC_TSHIFT;
else
return RECMODE_OFF;
} else
{
if (IsTimeshift(channel_id))
return RECMODE_TSHIFT;
}
}
return RECMODE_OFF;
#endif
int recmode = RECMODE_OFF;
mutex.lock();
if (channel_id == 0) {
@@ -913,10 +937,6 @@ bool CRecordManager::Record(const CTimerd::RecordingInfo * const eventinfo, cons
if (g_settings.recording_type == CNeutrinoApp::RECORDING_OFF)
return false;
#if 0
if(!CheckRecording(eventinfo))
return false;
#endif
#if 1 // FIXME test
StopSectionsd = false;
@@ -926,18 +946,6 @@ bool CRecordManager::Record(const CTimerd::RecordingInfo * const eventinfo, cons
RunStartScript();
mutex.lock();
#if 0
inst = FindInstance(eventinfo->channel_id);
if(inst) {
if(direct_record) {
error_msg = RECORD_BUSY;
} else {
CTimerd::RecordingInfo * evt = new CTimerd::RecordingInfo(*eventinfo);
printf("%s add %llx : %s to pending\n", __FUNCTION__, evt->channel_id, evt->epgTitle);
nextmap.push_back((CTimerd::RecordingInfo *)evt);
}
} else
#endif
if(recmap.size() < RECORD_MAX_COUNT) {
CFrontend * frontend = NULL;
if(CutBackNeutrino(eventinfo->channel_id, frontend)) {
@@ -1034,18 +1042,6 @@ bool CRecordManager::StopAutoRecord(bool lock)
return (inst != NULL);
}
#if 0
bool CRecordManager::CheckRecording(const CTimerd::RecordingInfo * const eventinfo)
{
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
/* FIXME check if frontend used for timeshift the same and will zap ?? */
if(/*(eventinfo->channel_id == live_channel_id) ||*/ !SAME_TRANSPONDER(eventinfo->channel_id, live_channel_id))
StopAutoRecord();
return true;
}
#endif
void CRecordManager::StartNextRecording()
{
CTimerd::RecordingInfo * eventinfo = NULL;
@@ -1053,25 +1049,6 @@ void CRecordManager::StartNextRecording()
for(nextmap_iterator_t it = nextmap.begin(); it != nextmap.end(); it++) {
eventinfo = *it;
#if 0
bool tested = true;
if( !recmap.empty() ) {
CRecordInstance * inst = FindInstance(eventinfo->channel_id);
/* same channel recording and not auto - skip */
if(inst && !inst->Timeshift())
tested = false;
/* there is only auto-record which can be stopped */
else if(recmap.size() == 1 && autoshift)
tested = true;
else {
/* there are some recordings, test any (first) for now */
recmap_iterator_t fit = recmap.begin();
t_channel_id channel_id = fit->second->GetChannelId();
tested = (SAME_TRANSPONDER(channel_id, eventinfo->channel_id));
}
}
if(tested)
#endif
CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(eventinfo->channel_id);
if (channel && CFEManager::getInstance()->canTune(channel))
{
@@ -1140,11 +1117,6 @@ void CRecordManager::StopInstance(CRecordInstance * inst, bool remove_event)
if(inst->Timeshift())
autoshift = false;
#if 0
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
if(inst->GetChannelId() == live_channel_id)
recordingstatus = 0;
#endif
delete inst;
}
@@ -1278,47 +1250,6 @@ int CRecordManager::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data
return messages_return::unhandled;
}
#if 0
bool CRecordManager::IsTimeshift(t_channel_id channel_id)
{
bool ret = false;
CRecordInstance * inst;
mutex.lock();
if (channel_id != 0)
{
inst = FindInstance(channel_id);
if(inst && inst->tshift_mode)
ret = true;
else
ret = false;
} else
{
for(recmap_iterator_t it = recmap.begin(); it != recmap.end(); it++)
{
if(it->second->tshift_mode)
{
mutex.unlock();
return true;
}
}
}
mutex.unlock();
return ret;
}
void CRecordManager::SetTimeshiftMode(CRecordInstance * inst, int mode)
{
mutex.lock();
/* reset all instances mode ? */
for(recmap_iterator_t it = recmap.begin(); it != recmap.end(); it++)
it->second->tshift_mode = TSHIFT_MODE_OFF;
mutex.unlock();
if (inst)
inst->tshift_mode = mode;
}
#endif
void CRecordManager::StartTimeshift()
{
if(g_RemoteControl->is_video_started)
@@ -1326,26 +1257,6 @@ void CRecordManager::StartTimeshift()
std::string tmode = "ptimeshift"; // already recording, pause
bool res = true;
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
#if 0
if(RecordingStatus(live_channel_id))
{
tmode = "ptimeshift"; // already recording, pause
if(GetRecordMode(live_channel_id) == RECMODE_TSHIFT)
SetTimeshiftMode(FindInstance(live_channel_id), TSHIFT_MODE_PAUSE);
} else
{
if(g_settings.temp_timeshift)
{
res = StartAutoRecord();
SetTimeshiftMode(FindInstance(live_channel_id), TSHIFT_MODE_TEMPORAER);
} else
{
res = Record(live_channel_id);
SetTimeshiftMode(FindInstance(live_channel_id), TSHIFT_MODE_PERMANET);
}
tmode = "timeshift"; // record just started
}
#endif
/* start temporary timeshift if enabled and not running, but dont start second record */
if (g_settings.temp_timeshift) {
if (!FindTimeshift()) {
@@ -1427,10 +1338,6 @@ int CRecordManager::exec(CMenuTarget* parent, const std::string & actionKey )
return menu_return::RETURN_EXIT_ALL;
}
#if 0
else
DisplayInfoMessage(g_Locale->getText(LOCALE_RECORDING_IS_RUNNING));
#endif
} else if(actionKey == "Timeshift")
{
StartTimeshift();
@@ -1497,7 +1404,6 @@ bool CRecordManager::ShowMenu(void)
durations.push_back(duration);
const char* mode_icon = NEUTRINO_ICON_REC;
//if (inst->tshift_mode)
if (inst->Timeshift())
mode_icon = NEUTRINO_ICON_AUTO_SHIFT;
@@ -1551,7 +1457,6 @@ bool CRecordManager::ShowMenu(void)
bool CRecordManager::AskToStop(const t_channel_id channel_id, const int recid)
{
//int recording_id = 0;
std::string title, duration;
CRecordInstance * inst;
@@ -1562,7 +1467,6 @@ bool CRecordManager::AskToStop(const t_channel_id channel_id, const int recid)
inst = FindInstance(channel_id);
if(inst) {
//recording_id = inst->GetRecordingId();
inst->GetRecordString(title, duration);
title += duration;
}
@@ -1572,9 +1476,6 @@ bool CRecordManager::AskToStop(const t_channel_id channel_id, const int recid)
if(ShowMsg(LOCALE_SHUTDOWN_RECODING_QUERY, title.c_str(),
CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, false) == CMessageBox::mbrYes) {
#if 0
g_Timerd->stopTimerEvent(recording_id);
#endif
mutex.lock();
if (recid)
inst = FindInstanceID(recid);

View File

@@ -82,6 +82,7 @@ class CRecordInstance
t_channel_id channel_id;
event_id_t epgid;
std::string epgTitle;
std::string epgInfo1;
unsigned char apidmode;
time_t epg_time;
time_t start_time;
@@ -110,7 +111,9 @@ class CRecordInstance
bool SaveXml();
record_error_msg_t Start(CZapitChannel * channel);
void WaitRecMsg(time_t StartTime, time_t WaitTime);
public:
void MakeExtFileName(CZapitChannel * channel, std::string &FilenameTemplate);
void StringReplace(std::string &str, const std::string search, const std::string rstr);
public:
CRecordInstance(const CTimerd::RecordingInfo * const eventinfo, std::string &dir, bool timeshift = false, bool stream_vtxt_pid = false, bool stream_pmt_pid = false, bool stream_subtitle_pids = false);
~CRecordInstance();
@@ -166,14 +169,12 @@ class CRecordManager : public CMenuTarget /*, public CChangeObserver*/
bool CutBackNeutrino(const t_channel_id channel_id, CFrontend * &frontend);
void RestoreNeutrino(void);
bool CheckRecording(const CTimerd::RecordingInfo * const eventinfo);
void StartNextRecording();
void StopPostProcess();
void StopInstance(CRecordInstance * inst, bool remove_event = true);
CRecordInstance * FindInstance(t_channel_id);
CRecordInstance * FindInstanceID(int recid);
CRecordInstance * FindTimeshift();
//void SetTimeshiftMode(CRecordInstance * inst=NULL, int mode=TSHIFT_MODE_OFF);
public:
enum record_modes_t
@@ -228,7 +229,6 @@ class CRecordManager : public CMenuTarget /*, public CChangeObserver*/
CRecordInstance* getRecordInstance(std::string file);
// old code
#if 0
bool IsTimeshift(t_channel_id channel_id=0);
bool MountDirectory(const char *recordingDir);
bool ChooseRecDir(std::string &dir);
int recordingstatus;

View File

@@ -37,11 +37,13 @@
#include <driver/scanepg.h>
#include <driver/record.h>
#include <driver/streamts.h>
#define EPG_RESCAN_TIME (24*60*60)
extern CBouquetList * bouquetList;
extern CBouquetList * TVfavList;
extern CBouquetList * TVbouquetList;
CEpgScan::CEpgScan()
{
@@ -71,11 +73,12 @@ void CEpgScan::Clear()
current_bmode = -1;
next_chid = 0;
allfav_done = false;
selected_done = false;
}
bool CEpgScan::Running()
{
return (g_settings.epg_scan && !scanmap.empty());
return (CheckMode() && !scanmap.empty());
}
void CEpgScan::AddBouquet(CChannelList * clist)
@@ -90,7 +93,7 @@ void CEpgScan::AddBouquet(CChannelList * clist)
bool CEpgScan::AddFavorites()
{
INFO("allfav_done: %d", allfav_done);
if ((g_settings.epg_scan != 2) || allfav_done)
if ((g_settings.epg_scan != SCAN_FAV) || allfav_done)
return false;
allfav_done = true;
@@ -103,6 +106,30 @@ bool CEpgScan::AddFavorites()
return (old_size != scanmap.size());
}
bool CEpgScan::AddSelected()
{
INFO("selected_done: %d", selected_done);
if ((g_settings.epg_scan != SCAN_SEL) || selected_done)
return false;
selected_done = true;
unsigned old_size = scanmap.size();
for (unsigned j = 0; j < TVfavList->Bouquets.size(); ++j) {
if (TVfavList->Bouquets[j]->zapitBouquet && TVfavList->Bouquets[j]->zapitBouquet->bScanEpg) {
CChannelList * clist = TVfavList->Bouquets[j]->channelList;
AddBouquet(clist);
}
}
for (unsigned j = 0; j < TVbouquetList->Bouquets.size(); ++j) {
if (TVbouquetList->Bouquets[j]->zapitBouquet && TVbouquetList->Bouquets[j]->zapitBouquet->bScanEpg) {
CChannelList * clist = TVbouquetList->Bouquets[j]->channelList;
AddBouquet(clist);
}
}
INFO("scan map size: %d -> %d\n", old_size, scanmap.size());
return (old_size != scanmap.size());
}
void CEpgScan::AddTransponders()
{
if(bouquetList->Bouquets.empty())
@@ -114,7 +141,25 @@ void CEpgScan::AddTransponders()
}
int mode = CNeutrinoApp::getInstance()->GetChannelMode();
if ((g_settings.epg_scan == 1) || (mode == LIST_MODE_FAV)) {
if (g_settings.epg_scan == SCAN_SEL) {
if (current_bmode != mode) {
current_bmode = mode;
current_bnum = -1;
}
int bnum = bouquetList->getActiveBouquetNumber();
bool bscan = bouquetList->Bouquets[bnum]->zapitBouquet &&
bouquetList->Bouquets[bnum]->zapitBouquet->bScanEpg;
if ((current_bnum != bnum) && bscan) {
current_bnum = bnum;
AddBouquet(bouquetList->Bouquets[current_bnum]->channelList);
} else {
AddSelected();
}
return;
}
if ((g_settings.epg_scan == SCAN_CURRENT) || (mode == LIST_MODE_FAV)) {
/* current bouquet mode */
if (current_bmode != mode) {
current_bmode = mode;
@@ -132,17 +177,23 @@ void CEpgScan::AddTransponders()
}
}
bool CEpgScan::CheckMode()
{
if (!g_settings.epg_scan
|| (standby && !(g_settings.epg_scan_mode & MODE_STANDBY))
|| (!standby && !(g_settings.epg_scan_mode & MODE_LIVE))
|| (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1))) {
return false;
}
return true;
}
void CEpgScan::Start(bool instandby)
{
if (!g_settings.epg_scan)
return;
if (!instandby && (CFEManager::getInstance()->getEnabledCount() <= 1))
return;
standby = instandby;
live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
AddTransponders();
standby = instandby;
//g_RCInput->killTimer(rescan_timer);
INFO("starting %s scan, scanning %d, scan map size: %d", standby ? "standby" : "live", scan_in_progress, scanmap.size());
if (standby || !scan_in_progress)
Next();
@@ -167,14 +218,16 @@ int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data)
scanned.clear();
Clear();
g_RCInput->killTimer(rescan_timer);
if (standby || (CFEManager::getInstance()->getEnabledCount() > 1)) {
if (CheckMode()) {
if (standby)
g_Zapit->setStandby(false);
CNeutrinoApp::getInstance()->wakeupFromStandby();
Start(standby);
} else {
AddTimer();
}
return messages_return::handled;
}
if (!g_settings.epg_scan || (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1))) {
if (!CheckMode()) {
int ret = messages_return::handled;
if (msg == NeutrinoMessages::EVT_EIT_COMPLETE)
scan_in_progress = false;
@@ -232,36 +285,44 @@ int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data)
return messages_return::unhandled;
}
void CEpgScan::EnterStandby()
void CEpgScan::AddTimer()
{
if (standby) {
CZapit::getInstance()->SetCurrentChannelID(live_channel_id);
//CZapit::getInstance()->EnablePlayback(true);
g_Zapit->setStandby(true);
g_Sectionsd->setPauseScanning(true);
}
//g_RCInput->killTimer(rescan_timer);
if (rescan_timer == 0)
rescan_timer = g_RCInput->addTimer(EPG_RESCAN_TIME*1000ULL*1000ULL, true);
INFO("rescan timer id %d", rescan_timer);
}
void CEpgScan::EnterStandby()
{
AddTimer();
if (standby) {
CZapit::getInstance()->SetCurrentChannelID(live_channel_id);
CNeutrinoApp::getInstance()->standbyToStandby();
}
}
void CEpgScan::Next()
{
bool locked = false;
next_chid = 0;
#if 0
if (!g_settings.epg_scan)
return;
if (!CheckMode())
return;
#endif
if (!standby && CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_standby)
return;
if (CRecordManager::getInstance()->RecordingStatus())
if (CRecordManager::getInstance()->RecordingStatus() || CStreamManager::getInstance()->StreamStatus())
return;
if (g_settings.epg_scan == 2 && scanmap.empty())
if (g_settings.epg_scan == SCAN_FAV && scanmap.empty())
AddFavorites();
if (g_settings.epg_scan == SCAN_SEL && scanmap.empty())
AddSelected();
if (scanmap.empty()) {
if (!CheckMode() || scanmap.empty()) {
EnterStandby();
return;
}
@@ -299,7 +360,9 @@ _repeat:
INFO("skip [%s], cannot tune", newchan->getName().c_str());
++it;
}
if (!next_chid && AddFavorites())
if (!next_chid && ((g_settings.epg_scan == SCAN_FAV) && AddFavorites()))
goto _repeat;
if (!next_chid && ((g_settings.epg_scan == SCAN_SEL) && AddSelected()))
goto _repeat;
if (locked) {

View File

@@ -28,11 +28,24 @@ typedef eit_scanmap_t::iterator eit_scanmap_iterator_t;
class CEpgScan
{
public:
enum {
SCAN_OFF,
SCAN_CURRENT,
SCAN_FAV,
SCAN_SEL
};
enum {
MODE_LIVE = 0x1,
MODE_STANDBY = 0x2,
MODE_ALWAYS = 0x3
};
private:
int current_bnum;
int current_mode;
int current_bmode;
bool allfav_done;
bool selected_done;
bool standby;
eit_scanmap_t scanmap;
t_channel_id next_chid;
@@ -43,8 +56,11 @@ class CEpgScan
void AddBouquet(CChannelList * clist);
bool AddFavorites();
bool AddSelected();
void AddTransponders();
void EnterStandby();
bool CheckMode();
void AddTimer();
CEpgScan();
public:

View File

@@ -1,9 +1,7 @@
/*
Neutrino-GUI - DBoxII-Project
Copyright (C) 2011-2012 CoolStream International Ltd
Copyright (C) 2010-2012, 2014 Stefan Seyfried
Copyright (C) 2011-2014 CoolStream International Ltd
based on code which is
Copyright (C) 2002 Andreas Oberritter <obi@tuxbox.org>
@@ -58,17 +56,12 @@
#include <driver/streamts.h>
#include <driver/record.h>
#include <driver/genpsi.h>
#include <pwrmngr.h>
/* defined in neutrino.cpp */
extern cCpuFreqManager * cpuFreq;
/* experimental mode:
* stream not possible, if record running
* pids in url ignored, and added from channel, with fake PAT/PMT
* different channels supported, only from the same transponder - no zap is done,
* different channels supported,
* with url like http://coolstream:31339/id=c32400030070283e (channel id)
* TODO: multi-tuner support
*/
#define ENABLE_MULTI_CHANNEL
@@ -120,23 +113,28 @@ bool CStreamInstance::Stop()
bool CStreamInstance::Send(ssize_t r)
{
//OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
stream_fds_t cfds;
mutex.lock();
for (stream_fds_t::iterator it = fds.begin(); it != fds.end(); ++it) {
int ret, i = 10;
do {
ret = send(*it, buf, r, MSG_DONTWAIT);
#if 0
if (ret != r)
usleep(100);
#endif
} while ((ret != r) && (i-- > 0));
if (ret != r) {
if (r < 0)
perror("send");
printf("send err, fd %d: (%d from %d)\n", *it, ret, (int)r);
}
}
cfds = fds;
mutex.unlock();
int flags = 0;
if (cfds.size() > 1)
flags = MSG_DONTWAIT;
for (stream_fds_t::iterator it = cfds.begin(); it != cfds.end(); ++it) {
int i = 10;
unsigned char *b = buf;
ssize_t count = r;
do {
int ret = send(*it, b, count, flags);
if (ret > 0) {
b += ret;
count -= ret;
}
} while ((count > 0) && (i-- > 0));
if (count)
printf("send err, fd %d: (%d from %d)\n", *it, r-count, r);
}
return true;
}
@@ -149,35 +147,23 @@ void CStreamInstance::Close()
void CStreamInstance::AddClient(int clientfd)
{
mutex.lock();
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
fds.insert(clientfd);
printf("CStreamInstance::AddClient: %d (count %d)\n", clientfd, (int)fds.size());
mutex.unlock();
}
void CStreamInstance::RemoveClient(int clientfd)
{
mutex.lock();
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
fds.erase(clientfd);
close(clientfd);
printf("CStreamInstance::RemoveClient: %d (count %d)\n", clientfd, (int)fds.size());
mutex.unlock();
}
void CStreamInstance::run()
{
printf("CStreamInstance::run: %" PRIx64 "\n", channel_id);
#if 0
// TODO: check if this works... #ifndef HAVE_COOL_HARDWARE
/* right now, only one stream is possible anyway and it is not possible
* to stream a different channel than the live channel AFAICT, so we can
* as well use the live demux */
dmx = new cDemux(0);
#endif
#if 0
dmx = new cDemux(STREAM_DEMUX);//FIXME
#endif
CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(channel_id);
if (!tmpchan)
return;
@@ -204,7 +190,7 @@ void CStreamInstance::run()
while (running) {
ssize_t r = dmx->Read(buf, IN_SIZE, 100);
if(r > 0)
if (r > 0)
Send(r);
}
@@ -265,7 +251,10 @@ bool CStreamManager::Stop()
if (!running)
return false;
running = false;
return (OpenThreads::Thread::join() == 0);
cancel();
bool ret = (OpenThreads::Thread::join() == 0);
StopAll();
return ret;
}
bool CStreamManager::SetPort(int newport)
@@ -286,13 +275,83 @@ bool CStreamManager::SetPort(int newport)
return ret;
}
bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel)
{
std::set<CFrontend*> frontends;
CFrontend * frontend = NULL;
t_channel_id chid = channel->getChannelID();
if (CRecordManager::getInstance()->RecordingStatus(chid)) {
printf("CStreamManager::Parse: channel %llx recorded, aborting..\n", chid);
return frontend;
}
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend();
if (live_channel_id == chid)
return live_fe;
CFEManager::getInstance()->Lock();
bool unlock = true;
CFEManager::getInstance()->lockFrontend(live_fe);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it)
frontends.insert(it->second->frontend);
for (std::set<CFrontend*>::iterator ft = frontends.begin(); ft != frontends.end(); ft++)
CFEManager::getInstance()->lockFrontend(*ft);
frontend = CFEManager::getInstance()->allocateFE(channel, true);
if (frontend == NULL) {
unlock = false;
CFEManager::getInstance()->unlockFrontend(live_fe);
frontend = CFEManager::getInstance()->allocateFE(channel, true);
}
CFEManager::getInstance()->Unlock();
if (frontend) {
bool found = (live_fe != frontend) || SAME_TRANSPONDER(live_channel_id, chid);
bool ret = false;
if (found)
ret = zapit.zapTo_record(chid) > 0;
else
ret = zapit.zapTo_serviceID(chid) > 0;
if (ret) {
#ifdef ENABLE_PIP
/* FIXME until proper demux management */
t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID();
if ((pip_channel_id == chid) && (channel->getRecordDemux() == channel->getPipDemux()))
zapit.stopPip();
#endif
} else {
frontend = NULL;
}
}
CFEManager::getInstance()->Lock();
for (std::set<CFrontend*>::iterator ft = frontends.begin(); ft != frontends.end(); ft++)
CFEManager::getInstance()->unlockFrontend(*ft);
if (unlock)
CFEManager::getInstance()->unlockFrontend(live_fe);
CFEManager::getInstance()->Unlock();
return frontend;
}
bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend)
{
char cbuf[512];
char *bp;
FILE * fp = fdopen(fd, "r+");
if(fp == NULL) {
if (fp == NULL) {
perror("fdopen");
return false;
}
@@ -303,7 +362,7 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
while (bp - &cbuf[0] < (int) sizeof(cbuf)) {
unsigned char c;
int res = read(fd, &c, 1);
if(res < 0) {
if (res < 0) {
perror("read");
return false;
}
@@ -326,74 +385,54 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
return false;
}
chid = CZapit::getInstance()->GetCurrentChannelID();
CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel();
#ifndef ENABLE_MULTI_CHANNEL
/* parse stdin / url path, start dmx filters */
do {
int pid;
int res = sscanf(bp, "%x", &pid);
if(res == 1) {
printf("New pid: 0x%x\n", pid);
if (res == 1) {
printf("CStreamManager::Parse: pid: 0x%x\n", pid);
pids.insert(pid);
}
} while ((bp = strchr(bp, ',')) && (bp++));
#else
t_channel_id tmpid;
bp = &cbuf[5];
if (sscanf(bp, "id=%llx", &tmpid) == 1) {
channel = CServiceManager::getInstance()->FindChannel(tmpid);
chid = tmpid;
}
while ((bp = strchr(bp, ',')) && (bp++));
#endif
if (!channel)
return false;
chid = CZapit::getInstance()->GetCurrentChannelID();
CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel();
printf("CStreamManager::Parse: channel_id %llx [%s]\n", chid, channel->getName().c_str());
int mode = CNeutrinoApp::getInstance()->getMode();
if (mode == NeutrinoMessages::mode_standby && streams.empty()) {
printf("CStreamManager::Parse: wakeup zapit..\n");
cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000);
g_Zapit->setStandby(false);
g_Zapit->getMode();
frontend = FindFrontend(channel);
if (!frontend) {
printf("CStreamManager::Parse: no free frontend\n");
return false;
}
if(pids.empty()) {
#ifdef ENABLE_MULTI_CHANNEL
t_channel_id tmpid;
bp = &cbuf[5];
if (sscanf(bp, "id=%" SCNx64, &tmpid) == 1) {
printf("############################# channel_id %" PRIx64 "\n", tmpid);
CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(tmpid);
/* we may switch channels if neutrino is in standby and we are not recording
* the current channel TODO: check interaction with recording */
bool may_switch =
(CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_standby) &&
!CRecordManager::getInstance()->RecordingStatus(chid);
if (tmpchan && (tmpid != chid) && (may_switch || SAME_TRANSPONDER(tmpid, chid))) {
printf("############################# channel_id %" PRIx64 " -> zap\n", tmpid);
bool ret = g_Zapit->zapTo_record(tmpid) > 0;
if (ret) {
channel = tmpchan;
chid = tmpid;
}
}
}
if(CRecordManager::getInstance()->RecordingStatus(chid)) {
printf("CStreamManager::Parse: channel %" PRIx64 " recorded, aborting..\n", chid);
return false;
}
#ifdef ENABLE_PIP
t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID();
if ((chid == pip_channel_id) && (channel->getRecordDemux() == channel->getPipDemux())) {
printf("CStreamManager::Parse: channel %llx used for pip, aborting..\n", chid);
return false;
}
#endif
#endif
AddPids(fd, channel, pids);
printf("CStreamManager::Parse: no pids in url, using channel %" PRIx64 " pids\n", chid);
if(!channel)
return false;
//pids.insert(0);
//pids.insert(channel->getPmtPid());
pids.insert(channel->getVideoPid());
return !pids.empty();
}
void CStreamManager::AddPids(int fd, CZapitChannel *channel, stream_pids_t &pids)
{
if (pids.empty()) {
printf("CStreamManager::AddPids: no pids in url, using channel %llx pids\n", channel->getChannelID());
if (channel->getVideoPid())
pids.insert(channel->getVideoPid());
for (int i = 0; i < channel->getAudioChannelCount(); i++)
pids.insert(channel->getAudioChannel(i)->pid);
}
CGenPsi psi;
for (stream_pids_t::iterator it = pids.begin(); it != pids.end(); ++it) {
if (*it == channel->getVideoPid()) {
@@ -404,9 +443,9 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
if (*it == channel->getAudioChannel(i)->pid) {
CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType;
printf("CStreamManager::Parse: genpsi apid %x (%d)\n", *it, atype);
if(channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3){
if (channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3) {
psi.addPid(*it, EN_TYPE_AUDIO_EAC3, atype, channel->getAudioChannel(i)->description.c_str());
}else{
} else {
psi.addPid(*it, EN_TYPE_AUDIO, atype, channel->getAudioChannel(i)->description.c_str());
}
}
@@ -414,43 +453,85 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
}
}
//add pcr pid
if(channel->getPcrPid() != channel->getVideoPid()){
if (channel->getPcrPid() && (channel->getPcrPid() != channel->getVideoPid())) {
pids.insert(channel->getPcrPid());
psi.addPid(channel->getPcrPid(), EN_TYPE_PCR, 0);
}
//add teletext pid
if (g_settings.recording_stream_vtxt_pid && channel->getTeletextPid() != 0){
if (g_settings.recording_stream_vtxt_pid && channel->getTeletextPid() != 0) {
pids.insert(channel->getTeletextPid());
psi.addPid(channel->getTeletextPid(), EN_TYPE_TELTEX, 0, channel->getTeletextLang());
}
//add dvb sub pid
if (g_settings.recording_stream_subtitle_pids){
if (g_settings.recording_stream_subtitle_pids) {
for (int i = 0 ; i < (int)channel->getSubtitleCount() ; ++i) {
CZapitAbsSub* s = channel->getChannelSub(i);
if (s->thisSubType == CZapitAbsSub::DVB) {
if(i>9)//max sub pids
if (i>9)//max sub pids
break;
CZapitDVBSub* sd = reinterpret_cast<CZapitDVBSub*>(s);
pids.insert(sd->pId);
psi.addPid( sd->pId, EN_TYPE_DVBSUB, 0, sd->ISO639_language_code.c_str() );
psi.addPid(sd->pId, EN_TYPE_DVBSUB, 0, sd->ISO639_language_code.c_str());
}
}
}
psi.genpsi(fd);
}
return !pids.empty();
bool CStreamManager::AddClient(int connfd)
{
stream_pids_t pids;
t_channel_id channel_id;
CFrontend *frontend;
if (Parse(connfd, pids, channel_id, frontend)) {
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
streammap_iterator_t it = streams.find(channel_id);
if (it != streams.end()) {
it->second->AddClient(connfd);
} else {
CStreamInstance * stream = new CStreamInstance(connfd, channel_id, pids);
stream->frontend = frontend;
int sendsize = 10*IN_SIZE;
unsigned int m = sizeof(sendsize);
setsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, (void *)&sendsize, m);
if (stream->Start())
streams.insert(streammap_pair_t(channel_id, stream));
else
delete stream;
}
return true;
}
return false;
}
void CStreamManager::RemoveClient(int fd)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) {
if (it->second->HasFd(fd)) {
CStreamInstance *stream = it->second;
stream->RemoveClient(fd);
if (stream->GetFds().empty()) {
streams.erase(stream->GetChannelId());
delete stream;
}
break;
}
}
}
void CStreamManager::run()
{
struct sockaddr_in servaddr;
int clilen = sizeof(servaddr);;
int clilen = sizeof(servaddr);
struct pollfd pfd[128];
int poll_cnt;
int poll_timeout = -1;
printf("Starting STREAM thread keeper, tid %ld\n", syscall(__NR_gettid));
@@ -471,67 +552,36 @@ void CStreamManager::run()
}
mutex.unlock();
//printf("polling, count= %d\n", poll_cnt);
int pollres = poll (pfd, poll_cnt, 1000);
if (pollres < 0) {
perror("CStreamManager::run(): poll");
int pollres = poll (pfd, poll_cnt, poll_timeout);
if (pollres <= 0) {
if (pollres < 0)
perror("CStreamManager::run(): poll");
continue;
}
if(pollres == 0)
continue;
for (int i = poll_cnt - 1; i >= 0; i--) {
if (pfd[i].revents & (POLLIN | POLLPRI | POLLHUP | POLLRDHUP)) {
printf("fd %d has events %x\n", pfd[i].fd, pfd[i].revents);
if (pfd[i].fd == listenfd) {
int connfd = accept (listenfd, (struct sockaddr *) &servaddr, (socklen_t *) & clilen);
int connfd = accept(listenfd, (struct sockaddr *) &servaddr, (socklen_t *) & clilen);
printf("CStreamManager::run(): connection, fd %d\n", connfd);
if(connfd < 0) {
if (connfd < 0) {
perror("CStreamManager::run(): accept");
continue;
}
stream_pids_t pids;
t_channel_id channel_id;
if (Parse(connfd, pids, channel_id)) {
mutex.lock();
streammap_iterator_t it = streams.find(channel_id);
if (it != streams.end()) {
it->second->AddClient(connfd);
} else {
CStreamInstance * stream = new CStreamInstance(connfd, channel_id, pids);
if (stream->Start())
streams.insert(streammap_pair_t(channel_id, stream));
else
delete stream;
}
mutex.unlock();
} else {
#if 0
if (!AddClient(connfd))
close(connfd);
}
#endif
g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_START, connfd);
poll_timeout = 1000;
} else {
if (pfd[i].revents & (POLLHUP | POLLRDHUP)) {
printf("CStreamManager::run(): POLLHUP, fd %d\n", pfd[i].fd);
mutex.lock();
for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) {
if (it->second->HasFd(pfd[i].fd)) {
CStreamInstance *stream = it->second;
stream->RemoveClient(pfd[i].fd);
if (stream->GetFds().empty()) {
streams.erase(stream->GetChannelId());
delete stream;
}
break;
}
RemoveClient(pfd[i].fd);
if (streams.empty()) {
poll_timeout = -1;
g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_STOP, 0);
}
mutex.unlock();
}
}
/* this is a cheap check */
if (streams.empty() &&
CNeutrinoApp::getInstance()->getMode() == NeutrinoMessages::mode_standby) {
/* this check is more expensive (goes through the socket) */
if (g_Zapit->getMode() != 0) {
printf("CStreamManager::run: put zapit into standby...\n");
g_Zapit->setStandby(true);
cpuFreq->SetCpuFreq(g_settings.standby_cpufreq * 1000 * 1000);
}
}
}
@@ -588,8 +638,6 @@ bool CStreamManager::Listen()
{
struct sockaddr_in socketAddr;
int socketOptActive = 1;
int sendsize = 10*IN_SIZE;
unsigned int m = sizeof(sendsize);
if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf (stderr, "network port %u open: ", port);
@@ -619,12 +667,7 @@ bool CStreamManager::Listen()
goto _error;
}
#if 1
setsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, (void *)&sendsize, m);
sendsize = 0;
getsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, (void *)&sendsize, &m);
printf("CStreamManager::Listen: on %d, fd %d (%d)\n", port, listenfd, sendsize);
#endif
printf("CStreamManager::Listen: on %d, fd %d\n", port, listenfd);
return true;
_error:
close (listenfd);

View File

@@ -27,6 +27,7 @@
#include <dmx.h>
#include <zapit/client/zapittypes.h>
#include <zapit/femanager.h>
#include <set>
#include <map>
@@ -38,6 +39,7 @@ class CStreamInstance : public OpenThreads::Thread
private:
bool running;
cDemux * dmx;
CFrontend * frontend;
OpenThreads::Mutex mutex;
unsigned char * buf;
@@ -48,6 +50,7 @@ class CStreamInstance : public OpenThreads::Thread
bool Send(ssize_t r);
void Close();
void run();
friend class CStreamManager;
public:
CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &pids);
~CStreamInstance();
@@ -74,12 +77,17 @@ class CStreamManager : public OpenThreads::Thread
OpenThreads::Mutex mutex;
static CStreamManager * sm;
CZapitClient zapit;
streammap_t streams;
bool Listen();
bool Parse(int fd, stream_pids_t &pids, t_channel_id &chid);
bool Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend);
void AddPids(int fd, CZapitChannel * channel, stream_pids_t &pids);
void CheckStandby(bool enter);
CFrontend * FindFrontend(CZapitChannel * channel);
bool StopAll();
void RemoveClient(int fd);
void run();
CStreamManager();
public:
@@ -91,6 +99,7 @@ class CStreamManager : public OpenThreads::Thread
bool StreamStatus(t_channel_id channel_id = 0);
bool SetPort(int newport);
int GetPort() { return port; }
bool AddClient(int fd);
};
#endif