mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
First step towards a 'unique channel ID'
This commit is contained in:
parent
c67fe26e66
commit
9fee2b67ab
45
HISTORY
45
HISTORY
@ -249,7 +249,7 @@ Video Disk Recorder Revision History
|
|||||||
- The EIT information is now gathered in a separate thread.
|
- The EIT information is now gathered in a separate thread.
|
||||||
- The sytem time can now be synchronized to the time broadcast in the DVB data
|
- The sytem time can now be synchronized to the time broadcast in the DVB data
|
||||||
stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to
|
stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to
|
||||||
1. Note that this works only if VDR is running under a user id that has
|
1. Note that this works only if VDR is running under a user ID that has
|
||||||
permisson to set the system time.
|
permisson to set the system time.
|
||||||
- The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert
|
- The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert
|
||||||
Schneider). See the MANUAL file for a detailed description.
|
Schneider). See the MANUAL file for a detailed description.
|
||||||
@ -1722,9 +1722,46 @@ Video Disk Recorder Revision History
|
|||||||
which can be used to disable simultaneous recording and replaying on the primary
|
which can be used to disable simultaneous recording and replaying on the primary
|
||||||
DVB device in case there are problems with this.
|
DVB device in case there are problems with this.
|
||||||
|
|
||||||
2002-11-08: Version 1.1.16
|
2002-11-10: Version 1.1.16
|
||||||
|
|
||||||
- Fixed saving the polarization parameter of channels that have a number in the
|
- Fixed saving the polarization parameter of channels that have a number in the
|
||||||
'source' parameter (thanks to Peter Seyringer for reporting this one).
|
'source' parameter (thanks to Peter Seyringer for reporting this one).
|
||||||
- Updated channels.conf.terr (thanks to Andy Carter).
|
- Updated 'channels.conf.terr' (thanks to Andy Carter).
|
||||||
- Updated channels.conf.cable (thanks to Achim Lange).
|
- Updated 'channels.conf.cable' (thanks to Achim Lange).
|
||||||
|
- First step towards a "unique channel ID". The channel ID is a human readable
|
||||||
|
string, made up from several parameters of the channel's definition in the file
|
||||||
|
'channels.conf' (see man vdr(5) for details).
|
||||||
|
In order for the "unique channel ID" to work, all channel definitions now must
|
||||||
|
be unique with respect to the combination of their Source, Frequency and SID
|
||||||
|
parameters. You may have to fix your 'channels.conf' manually if there are error
|
||||||
|
messages in the log file when loading it. BE SURE TO MAKE A BACKUP COPY OF YOUR
|
||||||
|
'channels.conf' AND 'timers.conf' FILE BEFORE SWITCHING TO THIS VERSION, AND CHECK
|
||||||
|
VERY CAREFULLY WHETHER YOUR TIMERS ARE STILL SET TO THE RIGHT CHANNELS!
|
||||||
|
When reading an existing 'timers.conf', the channels will be identified as before
|
||||||
|
by their numbers. As soon as this file is written back, the channel numbers will
|
||||||
|
be replaced by the channel IDs. After that it is possible to manually edit the
|
||||||
|
'channels.conf' file and rearrange the channels without breaking the timers.
|
||||||
|
Note that you can still define new timers manually by using the channel number.
|
||||||
|
VDR will correctly identify the 'channel' parameter in a timer definition and
|
||||||
|
use it as a channel number or a channel ID, respectively. Also, the SVDRP commands
|
||||||
|
that return timer definitions will list them with channel numbers in order to
|
||||||
|
stay compatible with existing applications.
|
||||||
|
The channel ID is also used in the 'epg.data' file to allow EPG information from
|
||||||
|
different sources to be stored, which would previously have been mixed up in case
|
||||||
|
they were using the same 'service ID'. Note that the contents of an existing
|
||||||
|
'epg.data' file from a previous version will be silently ignored, since it doesn't
|
||||||
|
contain the new channel IDs. When inserting EPG data into VDR via SVDRP you now also
|
||||||
|
need to use the channel IDs.
|
||||||
|
Currently the EPG data received from the DVB data stream only uses the 'Source'
|
||||||
|
and 'Service ID' part of the channel ID. This makes it work for channels with
|
||||||
|
the same service IDs on different sources (like satellites, cable or terrestrial).
|
||||||
|
However, it doesn't work yet if the service IDs are not unique within a specific
|
||||||
|
source. This will be fixed later.
|
||||||
|
- Added missing SID parameters to 'channels.conf'. Some channels have been removed
|
||||||
|
since they are apparently no longer broadcasted.
|
||||||
|
- Removed dropping EPG events from "other" streams that have a duration of 86400
|
||||||
|
seconds or more (was introduced in version 1.1.10). This has become obsolete by
|
||||||
|
the modification in version 1.1.13, which fixed fetching the current/next information
|
||||||
|
to handle cases where the duration of an event is set wrongly and would last beyond
|
||||||
|
the start time of the next event. Besides, the change in 1.1.10 broke handling EPG
|
||||||
|
data for NVOD channels.
|
||||||
|
106
channels.c
106
channels.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.c 1.7 2002/11/08 13:21:16 kls Exp $
|
* $Id: channels.c 1.8 2002/11/10 13:01:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
@ -126,19 +126,18 @@ char *cChannel::buffer = NULL;
|
|||||||
|
|
||||||
cChannel::cChannel(void)
|
cChannel::cChannel(void)
|
||||||
{
|
{
|
||||||
*name = 0;
|
strcpy(name, "Pro7");
|
||||||
frequency = 0;
|
frequency = 12480;
|
||||||
source = cSource::FromString("S19.2E");
|
source = cSource::FromString("S19.2E");
|
||||||
srate = 0;
|
srate = 27500;
|
||||||
vpid = 0;
|
vpid = 255;
|
||||||
apid1 = 0;
|
apid1 = 256;
|
||||||
apid2 = 0;
|
apid2 = 0;
|
||||||
dpid1 = 0;
|
dpid1 = 257;
|
||||||
dpid2 = 0;
|
dpid2 = 0;
|
||||||
tpid = 0;
|
tpid = 32;
|
||||||
ca = 0;
|
ca = 0;
|
||||||
sid = 0;
|
sid = 0;
|
||||||
number = 0;
|
|
||||||
groupSep = false;
|
groupSep = false;
|
||||||
polarization = 'v';
|
polarization = 'v';
|
||||||
inversion = INVERSION_AUTO;
|
inversion = INVERSION_AUTO;
|
||||||
@ -151,30 +150,44 @@ cChannel::cChannel(void)
|
|||||||
hierarchy = HIERARCHY_AUTO;
|
hierarchy = HIERARCHY_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
cChannel::cChannel(const cChannel *Channel)
|
cChannel& cChannel::operator= (const cChannel &Channel)
|
||||||
{
|
{
|
||||||
strcpy(name, Channel ? Channel->name : "Pro7");
|
memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
|
||||||
frequency = Channel ? Channel->frequency : 12480;
|
return *this;
|
||||||
source = Channel ? Channel->source : cSource::FromString("S19.2E");
|
}
|
||||||
srate = Channel ? Channel->srate : 27500;
|
|
||||||
vpid = Channel ? Channel->vpid : 255;
|
static int MHz(int frequency)
|
||||||
apid1 = Channel ? Channel->apid1 : 256;
|
{
|
||||||
apid2 = Channel ? Channel->apid2 : 0;
|
while (frequency > 20000) {
|
||||||
dpid1 = Channel ? Channel->dpid1 : 257;
|
frequency /= 1000;
|
||||||
dpid2 = Channel ? Channel->dpid2 : 0;
|
}
|
||||||
tpid = Channel ? Channel->tpid : 32;
|
return frequency;
|
||||||
ca = Channel ? Channel->ca : 0;
|
}
|
||||||
sid = Channel ? Channel->sid : 0;
|
|
||||||
groupSep = Channel ? Channel->groupSep : false;
|
uint64 cChannel::GetChannelID(void) const
|
||||||
polarization = Channel ? Channel->polarization : 'v';
|
{
|
||||||
inversion = Channel ? Channel->inversion : INVERSION_AUTO;
|
return (uint64(source) << 48) | (uint64(0) << 32) | ((MHz(frequency)) << 16) | sid;
|
||||||
bandwidth = Channel ? Channel->bandwidth : BANDWIDTH_AUTO;
|
}
|
||||||
coderateH = Channel ? Channel->coderateH : FEC_AUTO;
|
|
||||||
coderateL = Channel ? Channel->coderateL : FEC_AUTO;
|
const char *cChannel::GetChannelIDStr(void) const
|
||||||
modulation = Channel ? Channel->modulation : QAM_AUTO;
|
{
|
||||||
transmission = Channel ? Channel->transmission : TRANSMISSION_MODE_AUTO;
|
static char buffer[256];
|
||||||
guard = Channel ? Channel->guard : GUARD_INTERVAL_AUTO;
|
snprintf(buffer, sizeof(buffer), "%s-%d-%d-%d", cSource::ToString(source), 0, MHz(frequency), sid);
|
||||||
hierarchy = Channel ? Channel->hierarchy : HIERARCHY_AUTO;
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 cChannel::StringToChannelID(const char *s)
|
||||||
|
{
|
||||||
|
char *sourcebuf = NULL;
|
||||||
|
int reserved;
|
||||||
|
int frequency;
|
||||||
|
int sid;
|
||||||
|
if (4 == sscanf(s, "%a[^-]-%d-%d-%d", &sourcebuf, &reserved, &frequency, &sid)) {
|
||||||
|
int source = cSource::FromString(sourcebuf);
|
||||||
|
if (source >= 0)
|
||||||
|
return (uint64(source) << 48) | (uint64(reserved) << 32) | (frequency << 16) | sid;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PrintParameter(char *p, char Name, int Value)
|
static int PrintParameter(char *p, char Name, int Value)
|
||||||
@ -278,7 +291,7 @@ const char *cChannel::ToText(void)
|
|||||||
return ToText(this);
|
return ToText(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cChannel::Parse(const char *s)
|
bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
|
||||||
{
|
{
|
||||||
if (*s == ':') {
|
if (*s == ':') {
|
||||||
groupSep = true;
|
groupSep = true;
|
||||||
@ -324,6 +337,10 @@ bool cChannel::Parse(const char *s)
|
|||||||
free(sourcebuf);
|
free(sourcebuf);
|
||||||
free(apidbuf);
|
free(apidbuf);
|
||||||
free(namebuf);
|
free(namebuf);
|
||||||
|
if (!AllowNonUniqueID && Channels.GetByChannelID(GetChannelID())) {
|
||||||
|
esyslog("ERROR: channel data not unique!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -404,15 +421,34 @@ cChannel *cChannels::GetByNumber(int Number, int SkipGap)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
|
cChannel *cChannels::GetByServiceID(int Source, unsigned short ServiceID)
|
||||||
{
|
{
|
||||||
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||||
if (!channel->GroupSep() && channel->Sid() == ServiceId)
|
if (!channel->GroupSep() && channel->Source() == Source && channel->Sid() == ServiceID)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cChannel *cChannels::GetByChannelID(uint64 ChannelID)
|
||||||
|
{
|
||||||
|
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||||
|
if (!channel->GroupSep() && channel->GetChannelID() == ChannelID)
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cChannels::HasUniqueChannelID(cChannel *NewChannel, cChannel *OldChannel)
|
||||||
|
{
|
||||||
|
uint64 NewChannelID = NewChannel->GetChannelID();
|
||||||
|
for (cChannel *channel = First(); channel; channel = Next(channel)) {
|
||||||
|
if (!channel->GroupSep() && channel != OldChannel && channel->GetChannelID() == NewChannelID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool cChannels::SwitchTo(int Number)
|
bool cChannels::SwitchTo(int Number)
|
||||||
{
|
{
|
||||||
cChannel *channel = GetByNumber(Number);
|
cChannel *channel = GetByNumber(Number);
|
||||||
|
18
channels.h
18
channels.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.h 1.3 2002/10/20 11:50:36 kls Exp $
|
* $Id: channels.h 1.4 2002/11/10 13:01:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CHANNELS_H
|
#ifndef __CHANNELS_H
|
||||||
@ -41,6 +41,7 @@ private:
|
|||||||
static char *buffer;
|
static char *buffer;
|
||||||
static const char *ToText(cChannel *Channel);
|
static const char *ToText(cChannel *Channel);
|
||||||
enum { MaxChannelName = 32 }; // 31 chars + terminating 0!
|
enum { MaxChannelName = 32 }; // 31 chars + terminating 0!
|
||||||
|
int __BeginData__;
|
||||||
char name[MaxChannelName];
|
char name[MaxChannelName];
|
||||||
int frequency; // MHz
|
int frequency; // MHz
|
||||||
int source;
|
int source;
|
||||||
@ -53,7 +54,6 @@ private:
|
|||||||
int sid;
|
int sid;
|
||||||
int number; // Sequence number assigned on load
|
int number; // Sequence number assigned on load
|
||||||
bool groupSep;
|
bool groupSep;
|
||||||
//XXX
|
|
||||||
char polarization;
|
char polarization;
|
||||||
int inversion;
|
int inversion;
|
||||||
int bandwidth;
|
int bandwidth;
|
||||||
@ -63,13 +63,14 @@ private:
|
|||||||
int transmission;
|
int transmission;
|
||||||
int guard;
|
int guard;
|
||||||
int hierarchy;
|
int hierarchy;
|
||||||
|
int __EndData__;
|
||||||
const char *ParametersToString(void);
|
const char *ParametersToString(void);
|
||||||
bool StringToParameters(const char *s);
|
bool StringToParameters(const char *s);
|
||||||
public:
|
public:
|
||||||
cChannel(void);
|
cChannel(void);
|
||||||
cChannel(const cChannel *Channel);
|
cChannel& operator= (const cChannel &Channel);
|
||||||
const char *ToText(void);
|
const char *ToText(void);
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s, bool AllowNonUniqueID = false);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
const char *Name(void) const { return name; }
|
const char *Name(void) const { return name; }
|
||||||
int Frequency(void) const { return frequency; }
|
int Frequency(void) const { return frequency; }
|
||||||
@ -86,7 +87,6 @@ public:
|
|||||||
int Number(void) const { return number; }
|
int Number(void) const { return number; }
|
||||||
void SetNumber(int Number) { number = Number; }
|
void SetNumber(int Number) { number = Number; }
|
||||||
bool GroupSep(void) const { return groupSep; }
|
bool GroupSep(void) const { return groupSep; }
|
||||||
//XXX
|
|
||||||
char Polarization(void) const { return polarization; }
|
char Polarization(void) const { return polarization; }
|
||||||
int Inversion(void) const { return inversion; }
|
int Inversion(void) const { return inversion; }
|
||||||
int Bandwidth(void) const { return bandwidth; }
|
int Bandwidth(void) const { return bandwidth; }
|
||||||
@ -96,10 +96,12 @@ public:
|
|||||||
int Transmission(void) const { return transmission; }
|
int Transmission(void) const { return transmission; }
|
||||||
int Guard(void) const { return guard; }
|
int Guard(void) const { return guard; }
|
||||||
int Hierarchy(void) const { return hierarchy; }
|
int Hierarchy(void) const { return hierarchy; }
|
||||||
//XXX
|
|
||||||
bool IsCable(void) { return (source & cSource::st_Mask) == cSource::stCable; }
|
bool IsCable(void) { return (source & cSource::st_Mask) == cSource::stCable; }
|
||||||
bool IsSat(void) { return (source & cSource::st_Mask) == cSource::stSat; }
|
bool IsSat(void) { return (source & cSource::st_Mask) == cSource::stSat; }
|
||||||
bool IsTerr(void) { return (source & cSource::st_Mask) == cSource::stTerr; }
|
bool IsTerr(void) { return (source & cSource::st_Mask) == cSource::stTerr; }
|
||||||
|
uint64 GetChannelID(void) const;
|
||||||
|
const char *GetChannelIDStr(void) const;
|
||||||
|
static uint64 StringToChannelID(const char *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cChannels : public cConfig<cChannel> {
|
class cChannels : public cConfig<cChannel> {
|
||||||
@ -113,7 +115,9 @@ public:
|
|||||||
int GetNextNormal(int Idx); // Get next normal channel (not group)
|
int GetNextNormal(int Idx); // Get next normal channel (not group)
|
||||||
void ReNumber(void); // Recalculate 'number' based on channel type
|
void ReNumber(void); // Recalculate 'number' based on channel type
|
||||||
cChannel *GetByNumber(int Number, int SkipGap = 0);
|
cChannel *GetByNumber(int Number, int SkipGap = 0);
|
||||||
cChannel *GetByServiceID(unsigned short ServiceId);
|
cChannel *GetByServiceID(int Source, unsigned short ServiceID);
|
||||||
|
cChannel *GetByChannelID(uint64 ChannelID);
|
||||||
|
bool HasUniqueChannelID(cChannel *NewChannel, cChannel *OldChannel = NULL);
|
||||||
bool SwitchTo(int Number);
|
bool SwitchTo(int Number);
|
||||||
int MaxNumber(void) { return maxNumber; }
|
int MaxNumber(void) { return maxNumber; }
|
||||||
};
|
};
|
||||||
|
4
device.c
4
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 1.34 2002/11/03 11:51:24 kls Exp $
|
* $Id: device.c 1.35 2002/11/10 10:17:57 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -379,7 +379,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|||||||
|
|
||||||
if (Result == scrOk) {
|
if (Result == scrOk) {
|
||||||
if (LiveView && IsPrimaryDevice()) {
|
if (LiveView && IsPrimaryDevice()) {
|
||||||
cSIProcessor::SetCurrentServiceID(Channel->Sid());
|
cSIProcessor::SetCurrentChannelID(Channel->GetChannelID());
|
||||||
currentChannel = Channel->Number();
|
currentChannel = Channel->Number();
|
||||||
}
|
}
|
||||||
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbdevice.c 1.34 2002/11/03 12:31:11 kls Exp $
|
* $Id: dvbdevice.c 1.35 2002/11/10 12:57:17 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -412,7 +412,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
// Stop setting system time:
|
// Stop setting system time:
|
||||||
|
|
||||||
if (siProcessor)
|
if (siProcessor)
|
||||||
siProcessor->SetCurrentTransponder(0);
|
siProcessor->SetCurrentTransponder(0, 0);
|
||||||
|
|
||||||
// Turn off live PIDs if necessary:
|
// Turn off live PIDs if necessary:
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
// Start setting system time:
|
// Start setting system time:
|
||||||
|
|
||||||
if (siProcessor)
|
if (siProcessor)
|
||||||
siProcessor->SetCurrentTransponder(Channel->Frequency());
|
siProcessor->SetCurrentTransponder(Channel->Source(), Channel->Frequency());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
122
eit.c
122
eit.c
@ -16,7 +16,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.c 1.59 2002/11/02 12:46:53 kls Exp $
|
* $Id: eit.c 1.60 2002/11/10 15:50:21 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -180,7 +180,7 @@ bool cTDT::SetSystemTime()
|
|||||||
|
|
||||||
// --- cEventInfo ------------------------------------------------------------
|
// --- cEventInfo ------------------------------------------------------------
|
||||||
|
|
||||||
cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid)
|
cEventInfo::cEventInfo(uint64 channelid, unsigned short eventid)
|
||||||
{
|
{
|
||||||
pTitle = NULL;
|
pTitle = NULL;
|
||||||
pSubtitle = NULL;
|
pSubtitle = NULL;
|
||||||
@ -190,7 +190,7 @@ cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid)
|
|||||||
tTime = 0;
|
tTime = 0;
|
||||||
uTableID = 0;
|
uTableID = 0;
|
||||||
uEventID = eventid;
|
uEventID = eventid;
|
||||||
uServiceID = serviceid;
|
uChannelID = channelid;
|
||||||
nChannelNumber = 0;
|
nChannelNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,15 +325,15 @@ void cEventInfo::SetEventID(unsigned short evid)
|
|||||||
uEventID = evid;
|
uEventID = evid;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
void cEventInfo::SetServiceID(unsigned short servid)
|
void cEventInfo::SetChannelID(uint64 channelid)
|
||||||
{
|
{
|
||||||
uServiceID = servid;
|
uChannelID = channelid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
unsigned short cEventInfo::GetServiceID() const
|
uint64 cEventInfo::GetChannelID() const
|
||||||
{
|
{
|
||||||
return uServiceID;
|
return uChannelID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
@ -368,7 +368,7 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule)
|
|||||||
if (n == 3 || n == 4) {
|
if (n == 3 || n == 4) {
|
||||||
pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime);
|
pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime);
|
||||||
if (!pEvent)
|
if (!pEvent)
|
||||||
pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetServiceID(), uEventID));
|
pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetChannelID(), uEventID));
|
||||||
if (pEvent) {
|
if (pEvent) {
|
||||||
pEvent->SetTableID(uTableID);
|
pEvent->SetTableID(uTableID);
|
||||||
pEvent->SetTime(tTime);
|
pEvent->SetTime(tTime);
|
||||||
@ -404,24 +404,24 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule)
|
|||||||
struct tEpgBugFixStats {
|
struct tEpgBugFixStats {
|
||||||
int hits;
|
int hits;
|
||||||
int n;
|
int n;
|
||||||
unsigned short serviceIDs[MAXEPGBUGFIXCHANS];
|
uint64 channelIDs[MAXEPGBUGFIXCHANS];
|
||||||
tEpgBugFixStats(void) { hits = n = 0; }
|
tEpgBugFixStats(void) { hits = n = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS];
|
tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS];
|
||||||
|
|
||||||
static void EpgBugFixStat(int Number, unsigned int ServiceID)
|
static void EpgBugFixStat(int Number, uint64 ChannelID)
|
||||||
{
|
{
|
||||||
if (0 <= Number && Number < MAXEPGBUGFIXSTATS) {
|
if (0 <= Number && Number < MAXEPGBUGFIXSTATS) {
|
||||||
tEpgBugFixStats *p = &EpgBugFixStats[Number];
|
tEpgBugFixStats *p = &EpgBugFixStats[Number];
|
||||||
p->hits++;
|
p->hits++;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < p->n; i++) {
|
for (; i < p->n; i++) {
|
||||||
if (p->serviceIDs[i] == ServiceID)
|
if (p->channelIDs[i] == ChannelID)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == p->n && p->n < MAXEPGBUGFIXCHANS)
|
if (i == p->n && p->n < MAXEPGBUGFIXCHANS)
|
||||||
p->serviceIDs[p->n++] = ServiceID;
|
p->channelIDs[p->n++] = ChannelID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +448,7 @@ static void ReportEpgBugFixStats(bool Reset = false)
|
|||||||
char *q = buffer;
|
char *q = buffer;
|
||||||
q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits);
|
q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits);
|
||||||
for (int c = 0; c < p->n; c++) {
|
for (int c = 0; c < p->n; c++) {
|
||||||
cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]);
|
cChannel *channel = Channels.GetByChannelID(p->channelIDs[c]);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name());
|
q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name());
|
||||||
delim = ", ";
|
delim = ", ";
|
||||||
@ -499,7 +499,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
char *s = e ? strdup(e) : NULL;
|
char *s = e ? strdup(e) : NULL;
|
||||||
free(pSubtitle);
|
free(pSubtitle);
|
||||||
pSubtitle = s;
|
pSubtitle = s;
|
||||||
EpgBugFixStat(0, GetServiceID());
|
EpgBugFixStat(0, GetChannelID());
|
||||||
// now the fixes #1 and #2 below will handle the rest
|
// now the fixes #1 and #2 below will handle the rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -524,7 +524,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
free(pExtendedDescription);
|
free(pExtendedDescription);
|
||||||
pSubtitle = s;
|
pSubtitle = s;
|
||||||
pExtendedDescription = d;
|
pExtendedDescription = d;
|
||||||
EpgBugFixStat(1, GetServiceID());
|
EpgBugFixStat(1, GetChannelID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle));
|
memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle));
|
||||||
pExtendedDescription = pSubtitle;
|
pExtendedDescription = pSubtitle;
|
||||||
pSubtitle = NULL;
|
pSubtitle = NULL;
|
||||||
EpgBugFixStat(2, GetServiceID());
|
EpgBugFixStat(2, GetChannelID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +553,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) {
|
if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) {
|
||||||
free(pSubtitle);
|
free(pSubtitle);
|
||||||
pSubtitle = NULL;
|
pSubtitle = NULL;
|
||||||
EpgBugFixStat(3, GetServiceID());
|
EpgBugFixStat(3, GetChannelID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZDF.info puts the Subtitle between double quotes, which is nothing
|
// ZDF.info puts the Subtitle between double quotes, which is nothing
|
||||||
@ -569,7 +569,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
char *p = strrchr(pSubtitle, '"');
|
char *p = strrchr(pSubtitle, '"');
|
||||||
if (p)
|
if (p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
EpgBugFixStat(4, GetServiceID());
|
EpgBugFixStat(4, GetChannelID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
|
if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
|
||||||
if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten"
|
if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten"
|
||||||
memmove(p, p + 2, strlen(p + 2) + 1);
|
memmove(p, p + 2, strlen(p + 2) + 1);
|
||||||
EpgBugFixStat(5, GetServiceID());
|
EpgBugFixStat(5, GetChannelID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
@ -608,10 +608,10 @@ void cEventInfo::FixEpgBugs(void)
|
|||||||
|
|
||||||
// --- cSchedule -------------------------------------------------------------
|
// --- cSchedule -------------------------------------------------------------
|
||||||
|
|
||||||
cSchedule::cSchedule(unsigned short servid)
|
cSchedule::cSchedule(uint64 channelid)
|
||||||
{
|
{
|
||||||
pPresent = pFollowing = NULL;
|
pPresent = pFollowing = NULL;
|
||||||
uServiceID = servid;
|
uChannelID = channelid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -645,14 +645,14 @@ const cEventInfo *cSchedule::GetFollowingEvent(void) const
|
|||||||
return pe;
|
return pe;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSchedule::SetServiceID(unsigned short servid)
|
void cSchedule::SetChannelID(uint64 channelid)
|
||||||
{
|
{
|
||||||
uServiceID = servid;
|
uChannelID = channelid;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
unsigned short cSchedule::GetServiceID() const
|
uint64 cSchedule::GetChannelID() const
|
||||||
{
|
{
|
||||||
return uServiceID;
|
return uChannelID;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) const
|
const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) const
|
||||||
@ -735,10 +735,10 @@ void cSchedule::Cleanup(time_t tTime)
|
|||||||
/** */
|
/** */
|
||||||
void cSchedule::Dump(FILE *f, const char *Prefix) const
|
void cSchedule::Dump(FILE *f, const char *Prefix) const
|
||||||
{
|
{
|
||||||
cChannel *channel = Channels.GetByServiceID(uServiceID);
|
cChannel *channel = Channels.GetByChannelID(uChannelID);
|
||||||
if (channel)
|
if (channel)
|
||||||
{
|
{
|
||||||
fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->Name());
|
fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelIDStr(), channel->Name());
|
||||||
for (cEventInfo *p = Events.First(); p; p = Events.Next(p))
|
for (cEventInfo *p = Events.First(); p; p = Events.Next(p))
|
||||||
p->Dump(f, Prefix);
|
p->Dump(f, Prefix);
|
||||||
fprintf(f, "%sc\n", Prefix);
|
fprintf(f, "%sc\n", Prefix);
|
||||||
@ -751,14 +751,24 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
|
|||||||
char *s;
|
char *s;
|
||||||
while ((s = readline(f)) != NULL) {
|
while ((s = readline(f)) != NULL) {
|
||||||
if (*s == 'C') {
|
if (*s == 'C') {
|
||||||
unsigned int uServiceID;
|
s = skipspace(s + 1);
|
||||||
if (1 == sscanf(s + 1, "%u", &uServiceID)) {
|
char *p = strchr(s, ' ');
|
||||||
cSchedule *p = (cSchedule *)Schedules->AddServiceID(uServiceID);
|
if (p)
|
||||||
|
*p = 0; // strips optional channel name
|
||||||
|
if (*s) {
|
||||||
|
uint64 uChannelID = cChannel::StringToChannelID(s);
|
||||||
|
if (uChannelID) {
|
||||||
|
cSchedule *p = (cSchedule *)Schedules->AddChannelID(uChannelID);
|
||||||
if (p) {
|
if (p) {
|
||||||
if (!cEventInfo::Read(f, p))
|
if (!cEventInfo::Read(f, p))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
esyslog("ERROR: illegal channel ID: %s", s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
esyslog("ERROR: unexpected tag while reading EPG data: %s", s);
|
esyslog("ERROR: unexpected tag while reading EPG data: %s", s);
|
||||||
@ -775,28 +785,28 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
|
|||||||
cSchedules::cSchedules()
|
cSchedules::cSchedules()
|
||||||
{
|
{
|
||||||
pCurrentSchedule = NULL;
|
pCurrentSchedule = NULL;
|
||||||
uCurrentServiceID = 0;
|
uCurrentChannelID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSchedules::~cSchedules()
|
cSchedules::~cSchedules()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
const cSchedule *cSchedules::AddServiceID(unsigned short servid)
|
const cSchedule *cSchedules::AddChannelID(uint64 channelid)
|
||||||
{
|
{
|
||||||
const cSchedule *p = GetSchedule(servid);
|
const cSchedule *p = GetSchedule(channelid);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
Add(new cSchedule(servid));
|
Add(new cSchedule(channelid));
|
||||||
p = GetSchedule(servid);
|
p = GetSchedule(channelid);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
const cSchedule *cSchedules::SetCurrentServiceID(unsigned short servid)
|
const cSchedule *cSchedules::SetCurrentChannelID(uint64 channelid)
|
||||||
{
|
{
|
||||||
pCurrentSchedule = AddServiceID(servid);
|
pCurrentSchedule = AddChannelID(channelid);
|
||||||
if (pCurrentSchedule)
|
if (pCurrentSchedule)
|
||||||
uCurrentServiceID = servid;
|
uCurrentChannelID = channelid;
|
||||||
return pCurrentSchedule;
|
return pCurrentSchedule;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
@ -805,14 +815,14 @@ const cSchedule * cSchedules::GetSchedule() const
|
|||||||
return pCurrentSchedule;
|
return pCurrentSchedule;
|
||||||
}
|
}
|
||||||
/** */
|
/** */
|
||||||
const cSchedule * cSchedules::GetSchedule(unsigned short servid) const
|
const cSchedule * cSchedules::GetSchedule(uint64 channelid) const
|
||||||
{
|
{
|
||||||
cSchedule *p;
|
cSchedule *p;
|
||||||
|
|
||||||
p = First();
|
p = First();
|
||||||
while (p != NULL)
|
while (p != NULL)
|
||||||
{
|
{
|
||||||
if (p->GetServiceID() == servid)
|
if (p->GetChannelID() == channelid)
|
||||||
return p;
|
return p;
|
||||||
p = Next(p);
|
p = Next(p);
|
||||||
}
|
}
|
||||||
@ -856,7 +866,7 @@ public:
|
|||||||
cEIT(unsigned char *buf, int length, cSchedules *Schedules);
|
cEIT(unsigned char *buf, int length, cSchedules *Schedules);
|
||||||
~cEIT();
|
~cEIT();
|
||||||
/** */
|
/** */
|
||||||
int ProcessEIT(unsigned char *buffer);
|
int ProcessEIT(unsigned char *buffer, int CurrentSource);
|
||||||
|
|
||||||
protected: // Protected methods
|
protected: // Protected methods
|
||||||
/** returns true if this EIT covers a
|
/** returns true if this EIT covers a
|
||||||
@ -879,7 +889,7 @@ cEIT::~cEIT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
int cEIT::ProcessEIT(unsigned char *buffer)
|
int cEIT::ProcessEIT(unsigned char *buffer, int CurrentSource)
|
||||||
{
|
{
|
||||||
cEventInfo *pEvent, *rEvent = NULL;
|
cEventInfo *pEvent, *rEvent = NULL;
|
||||||
cSchedule *pSchedule, *rSchedule = NULL;
|
cSchedule *pSchedule, *rSchedule = NULL;
|
||||||
@ -893,18 +903,19 @@ int cEIT::ProcessEIT(unsigned char *buffer)
|
|||||||
|
|
||||||
if (VdrProgramInfos) {
|
if (VdrProgramInfos) {
|
||||||
for (VdrProgramInfo = (struct VdrProgramInfo *) VdrProgramInfos->Head; VdrProgramInfo; VdrProgramInfo = (struct VdrProgramInfo *) xSucc (VdrProgramInfo)) {
|
for (VdrProgramInfo = (struct VdrProgramInfo *) VdrProgramInfos->Head; VdrProgramInfo; VdrProgramInfo = (struct VdrProgramInfo *) xSucc (VdrProgramInfo)) {
|
||||||
// Drop events that belong to an "other TS" and are very long (some stations broadcast bogus data for "other" channels):
|
//XXX TODO use complete channel ID
|
||||||
if (VdrProgramInfo->Duration >= 86400 && (tid == 0x4F || tid == 0x60 || tid == 0x61))
|
cChannel *channel = Channels.GetByServiceID(CurrentSource, VdrProgramInfo->ServiceID);
|
||||||
continue;
|
uint64 channelID = channel ? channel->GetChannelID() : (uint64(CurrentSource) << 48) | VdrProgramInfo->ServiceID;
|
||||||
pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
|
//XXX
|
||||||
|
pSchedule = (cSchedule *)schedules->GetSchedule(channelID);
|
||||||
if (!pSchedule) {
|
if (!pSchedule) {
|
||||||
schedules->Add(new cSchedule(VdrProgramInfo->ServiceID));
|
schedules->Add(new cSchedule(channelID));
|
||||||
pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
|
pSchedule = (cSchedule *)schedules->GetSchedule(channelID);
|
||||||
if (!pSchedule)
|
if (!pSchedule)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (VdrProgramInfo->ReferenceServiceID) {
|
if (VdrProgramInfo->ReferenceServiceID) {
|
||||||
rSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ReferenceServiceID);
|
rSchedule = (cSchedule *)schedules->GetSchedule((uint64(CurrentSource) << 48) | VdrProgramInfo->ReferenceServiceID);
|
||||||
if (!rSchedule)
|
if (!rSchedule)
|
||||||
break;
|
break;
|
||||||
rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID);
|
rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID);
|
||||||
@ -915,7 +926,7 @@ int cEIT::ProcessEIT(unsigned char *buffer)
|
|||||||
if (!pEvent) {
|
if (!pEvent) {
|
||||||
// If we don't have that event ID yet, we create a new one.
|
// If we don't have that event ID yet, we create a new one.
|
||||||
// Otherwise we copy the information into the existing event anyway, because the data might have changed.
|
// Otherwise we copy the information into the existing event anyway, because the data might have changed.
|
||||||
pEvent = pSchedule->AddEvent(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID));
|
pEvent = pSchedule->AddEvent(new cEventInfo(channelID, VdrProgramInfo->EventID));
|
||||||
if (!pEvent)
|
if (!pEvent)
|
||||||
break;
|
break;
|
||||||
pEvent->SetTableID(tid);
|
pEvent->SetTableID(tid);
|
||||||
@ -988,6 +999,8 @@ cSIProcessor::cSIProcessor(const char *FileName)
|
|||||||
{
|
{
|
||||||
fileName = strdup(FileName);
|
fileName = strdup(FileName);
|
||||||
masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master'
|
masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master'
|
||||||
|
currentSource = 0;
|
||||||
|
currentTransponder = 0;
|
||||||
filters = NULL;
|
filters = NULL;
|
||||||
if (!numSIProcessors++) // the first one creates it
|
if (!numSIProcessors++) // the first one creates it
|
||||||
schedules = new cSchedules;
|
schedules = new cSchedules;
|
||||||
@ -1167,7 +1180,7 @@ void cSIProcessor::Action()
|
|||||||
{
|
{
|
||||||
cMutexLock MutexLock(&schedulesMutex);
|
cMutexLock MutexLock(&schedulesMutex);
|
||||||
cEIT ceit(buf, seclen, schedules);
|
cEIT ceit(buf, seclen, schedules);
|
||||||
ceit.ProcessEIT(buf);
|
ceit.ProcessEIT(buf, currentSource);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dsyslog("Received stuffing section in EIT\n");
|
dsyslog("Received stuffing section in EIT\n");
|
||||||
@ -1250,16 +1263,17 @@ bool cSIProcessor::ShutDownFilters(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
void cSIProcessor::SetCurrentTransponder(int CurrentTransponder)
|
void cSIProcessor::SetCurrentTransponder(int CurrentSource, int CurrentTransponder)
|
||||||
{
|
{
|
||||||
|
currentSource = CurrentSource;
|
||||||
currentTransponder = CurrentTransponder;
|
currentTransponder = CurrentTransponder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
bool cSIProcessor::SetCurrentServiceID(unsigned short servid)
|
bool cSIProcessor::SetCurrentChannelID(uint64 channelid)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&schedulesMutex);
|
cMutexLock MutexLock(&schedulesMutex);
|
||||||
return schedules ? schedules->SetCurrentServiceID(servid) : false;
|
return schedules ? schedules->SetCurrentChannelID(channelid) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSIProcessor::TriggerDump(void)
|
void cSIProcessor::TriggerDump(void)
|
||||||
|
31
eit.h
31
eit.h
@ -16,7 +16,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.h 1.20 2002/11/02 12:36:36 kls Exp $
|
* $Id: eit.h 1.21 2002/11/10 12:58:27 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef __EIT_H
|
#ifndef __EIT_H
|
||||||
@ -32,7 +32,7 @@ class cEventInfo : public cListObject {
|
|||||||
friend class cEIT;
|
friend class cEIT;
|
||||||
private:
|
private:
|
||||||
unsigned char uTableID; // Table ID this event came from
|
unsigned char uTableID; // Table ID this event came from
|
||||||
unsigned short uServiceID; // Service ID of program for that event
|
uint64 uChannelID; // Channel ID of program for that event
|
||||||
bool bIsFollowing; // true if this is the next event on this channel
|
bool bIsFollowing; // true if this is the next event on this channel
|
||||||
bool bIsPresent; // true if this is the present event running
|
bool bIsPresent; // true if this is the present event running
|
||||||
char *pExtendedDescription; // Extended description of this event
|
char *pExtendedDescription; // Extended description of this event
|
||||||
@ -47,13 +47,13 @@ protected:
|
|||||||
void SetFollowing(bool foll);
|
void SetFollowing(bool foll);
|
||||||
void SetPresent(bool pres);
|
void SetPresent(bool pres);
|
||||||
void SetTitle(const char *string);
|
void SetTitle(const char *string);
|
||||||
void SetServiceID(unsigned short servid);
|
void SetChannelID(uint64 channelid);
|
||||||
void SetEventID(unsigned short evid);
|
void SetEventID(unsigned short evid);
|
||||||
void SetDuration(long l);
|
void SetDuration(long l);
|
||||||
void SetTime(time_t t);
|
void SetTime(time_t t);
|
||||||
void SetExtendedDescription(const char *string);
|
void SetExtendedDescription(const char *string);
|
||||||
void SetSubtitle(const char *string);
|
void SetSubtitle(const char *string);
|
||||||
cEventInfo(unsigned short serviceid, unsigned short eventid);
|
cEventInfo(uint64 channelid, unsigned short eventid);
|
||||||
public:
|
public:
|
||||||
~cEventInfo();
|
~cEventInfo();
|
||||||
const unsigned char GetTableID(void) const;
|
const unsigned char GetTableID(void) const;
|
||||||
@ -68,7 +68,7 @@ public:
|
|||||||
unsigned short GetEventID(void) const;
|
unsigned short GetEventID(void) const;
|
||||||
long GetDuration(void) const;
|
long GetDuration(void) const;
|
||||||
time_t GetTime(void) const;
|
time_t GetTime(void) const;
|
||||||
unsigned short GetServiceID(void) const;
|
uint64 GetChannelID(void) const;
|
||||||
int GetChannelNumber(void) const { return nChannelNumber; }
|
int GetChannelNumber(void) const { return nChannelNumber; }
|
||||||
void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const'
|
void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const'
|
||||||
void Dump(FILE *f, const char *Prefix = "") const;
|
void Dump(FILE *f, const char *Prefix = "") const;
|
||||||
@ -82,21 +82,21 @@ class cSchedule : public cListObject {
|
|||||||
private:
|
private:
|
||||||
cEventInfo *pPresent;
|
cEventInfo *pPresent;
|
||||||
cEventInfo *pFollowing;
|
cEventInfo *pFollowing;
|
||||||
unsigned short uServiceID;
|
uint64 uChannelID;
|
||||||
cList<cEventInfo> Events;
|
cList<cEventInfo> Events;
|
||||||
protected:
|
protected:
|
||||||
void SetServiceID(unsigned short servid);
|
void SetChannelID(uint64 channelid);
|
||||||
bool SetFollowingEvent(cEventInfo *pEvent);
|
bool SetFollowingEvent(cEventInfo *pEvent);
|
||||||
bool SetPresentEvent(cEventInfo *pEvent);
|
bool SetPresentEvent(cEventInfo *pEvent);
|
||||||
void Cleanup(time_t tTime);
|
void Cleanup(time_t tTime);
|
||||||
void Cleanup(void);
|
void Cleanup(void);
|
||||||
cSchedule(unsigned short servid = 0);
|
cSchedule(uint64 channelid = 0);
|
||||||
public:
|
public:
|
||||||
~cSchedule();
|
~cSchedule();
|
||||||
cEventInfo *AddEvent(cEventInfo *EventInfo);
|
cEventInfo *AddEvent(cEventInfo *EventInfo);
|
||||||
const cEventInfo *GetPresentEvent(void) const;
|
const cEventInfo *GetPresentEvent(void) const;
|
||||||
const cEventInfo *GetFollowingEvent(void) const;
|
const cEventInfo *GetFollowingEvent(void) const;
|
||||||
unsigned short GetServiceID(void) const;
|
uint64 GetChannelID(void) const;
|
||||||
const cEventInfo *GetEvent(unsigned short uEventID, time_t tTime = 0) const;
|
const cEventInfo *GetEvent(unsigned short uEventID, time_t tTime = 0) const;
|
||||||
const cEventInfo *GetEventAround(time_t tTime) const;
|
const cEventInfo *GetEventAround(time_t tTime) const;
|
||||||
const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); }
|
const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); }
|
||||||
@ -110,15 +110,15 @@ class cSchedules : public cList<cSchedule> {
|
|||||||
friend class cSIProcessor;
|
friend class cSIProcessor;
|
||||||
private:
|
private:
|
||||||
const cSchedule *pCurrentSchedule;
|
const cSchedule *pCurrentSchedule;
|
||||||
unsigned short uCurrentServiceID;
|
uint64 uCurrentChannelID;
|
||||||
protected:
|
protected:
|
||||||
const cSchedule *AddServiceID(unsigned short servid);
|
const cSchedule *AddChannelID(uint64 channelid);
|
||||||
const cSchedule *SetCurrentServiceID(unsigned short servid);
|
const cSchedule *SetCurrentChannelID(uint64 channelid);
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
public:
|
public:
|
||||||
cSchedules(void);
|
cSchedules(void);
|
||||||
~cSchedules();
|
~cSchedules();
|
||||||
const cSchedule *GetSchedule(unsigned short servid) const;
|
const cSchedule *GetSchedule(uint64 channelid) const;
|
||||||
const cSchedule *GetSchedule(void) const;
|
const cSchedule *GetSchedule(void) const;
|
||||||
void Dump(FILE *f, const char *Prefix = "") const;
|
void Dump(FILE *f, const char *Prefix = "") const;
|
||||||
static bool Read(FILE *f);
|
static bool Read(FILE *f);
|
||||||
@ -141,6 +141,7 @@ private:
|
|||||||
static const char *epgDataFileName;
|
static const char *epgDataFileName;
|
||||||
static time_t lastDump;
|
static time_t lastDump;
|
||||||
bool masterSIProcessor;
|
bool masterSIProcessor;
|
||||||
|
int currentSource;
|
||||||
int currentTransponder;
|
int currentTransponder;
|
||||||
SIP_FILTER *filters;
|
SIP_FILTER *filters;
|
||||||
char *fileName;
|
char *fileName;
|
||||||
@ -160,8 +161,8 @@ public:
|
|||||||
static bool Read(FILE *f = NULL);
|
static bool Read(FILE *f = NULL);
|
||||||
static void Clear(void);
|
static void Clear(void);
|
||||||
void SetStatus(bool On);
|
void SetStatus(bool On);
|
||||||
void SetCurrentTransponder(int CurrentTransponder);
|
void SetCurrentTransponder(int CurrentSource, int CurrentTransponder);
|
||||||
static bool SetCurrentServiceID(unsigned short servid);
|
static bool SetCurrentChannelID(uint64 channelid);
|
||||||
static void TriggerDump(void);
|
static void TriggerDump(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
i18n.c
18
i18n.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: i18n.c 1.99 2002/10/27 14:24:00 kls Exp $
|
* $Id: i18n.c 1.100 2002/11/10 12:32:30 kls Exp $
|
||||||
*
|
*
|
||||||
* Translations provided by:
|
* Translations provided by:
|
||||||
*
|
*
|
||||||
@ -1468,6 +1468,22 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
},
|
},
|
||||||
|
{ "Channel settings are not unique!",
|
||||||
|
"Kanaleinstellungen sind nicht eindeutig!",
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
},
|
||||||
{ "Channel locked (recording)!",
|
{ "Channel locked (recording)!",
|
||||||
"Kanal blockiert (zeichnet auf)!",
|
"Kanal blockiert (zeichnet auf)!",
|
||||||
"Zaklenjen kanal (snemanje)!",
|
"Zaklenjen kanal (snemanje)!",
|
||||||
|
69
menu.c
69
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.222 2002/11/01 12:15:45 kls Exp $
|
* $Id: menu.c 1.223 2002/11/10 12:32:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -546,16 +546,18 @@ private:
|
|||||||
cChannel data;
|
cChannel data;
|
||||||
void Setup(void);
|
void Setup(void);
|
||||||
public:
|
public:
|
||||||
cMenuEditChannel(int Index);
|
cMenuEditChannel(cChannel *Channel, bool New = false);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuEditChannel::cMenuEditChannel(int Index)
|
cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
|
||||||
:cOsdMenu(tr("Edit channel"), 14)
|
:cOsdMenu(tr("Edit channel"), 14)
|
||||||
{
|
{
|
||||||
channel = Channels.Get(Index);
|
channel = Channel;
|
||||||
if (channel) {
|
if (channel) {
|
||||||
data = *channel;
|
data = *channel;
|
||||||
|
if (New)
|
||||||
|
channel = NULL;
|
||||||
Setup();
|
Setup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -603,11 +605,27 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
if (Key == kOk) {
|
if (Key == kOk) {
|
||||||
if (channel)
|
if (Channels.HasUniqueChannelID(&data, channel)) {
|
||||||
|
if (channel) {
|
||||||
*channel = data;
|
*channel = data;
|
||||||
Channels.Save();
|
isyslog("edited channel %d %s", channel->Number(), data.ToText());
|
||||||
state = osBack;
|
state = osBack;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
channel = new cChannel;
|
||||||
|
*channel = data;
|
||||||
|
Channels.Add(channel);
|
||||||
|
Channels.ReNumber();
|
||||||
|
isyslog("added channel %d %s", channel->Number(), data.ToText());
|
||||||
|
state = osUser1;
|
||||||
|
}
|
||||||
|
Channels.Save();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Interface->Error(tr("Channel settings are not unique!"));
|
||||||
|
state = osContinue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Key != kNone && (data.source & cSource::st_Mask) != (oldSource & cSource::st_Mask))
|
if (Key != kNone && (data.source & cSource::st_Mask) != (oldSource & cSource::st_Mask))
|
||||||
Setup();
|
Setup();
|
||||||
@ -696,10 +714,8 @@ eOSState cMenuChannels::Edit(void)
|
|||||||
if (HasSubMenu() || Count() == 0)
|
if (HasSubMenu() || Count() == 0)
|
||||||
return osContinue;
|
return osContinue;
|
||||||
cChannel *ch = Channels.Get(Current());
|
cChannel *ch = Channels.Get(Current());
|
||||||
if (ch) {
|
if (ch)
|
||||||
isyslog("editing channel %d", ch->Number());
|
return AddSubMenu(new cMenuEditChannel(ch));
|
||||||
return AddSubMenu(new cMenuEditChannel(Current()));
|
|
||||||
}
|
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,13 +723,7 @@ eOSState cMenuChannels::New(void)
|
|||||||
{
|
{
|
||||||
if (HasSubMenu())
|
if (HasSubMenu())
|
||||||
return osContinue;
|
return osContinue;
|
||||||
cChannel *channel = new cChannel(Channels.Get(Current()));
|
return AddSubMenu(new cMenuEditChannel(Channels.Get(Current()), true));
|
||||||
Channels.Add(channel);
|
|
||||||
Channels.ReNumber();
|
|
||||||
Add(new cMenuChannelItem(channel), true);
|
|
||||||
Channels.Save();
|
|
||||||
isyslog("channel %d added", channel->Number());
|
|
||||||
return AddSubMenu(new cMenuEditChannel(Current()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuChannels::Del(void)
|
eOSState cMenuChannels::Del(void)
|
||||||
@ -753,6 +763,16 @@ eOSState cMenuChannels::ProcessKey(eKeys Key)
|
|||||||
{
|
{
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case osUser1: {
|
||||||
|
cChannel *channel = Channels.Last();
|
||||||
|
if (channel) {
|
||||||
|
Add(new cMenuChannelItem(channel), true);
|
||||||
|
return CloseSubMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case kOk: return Switch();
|
case kOk: return Switch();
|
||||||
@ -763,6 +783,7 @@ eOSState cMenuChannels::ProcessKey(eKeys Key)
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1068,7 +1089,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
|
|||||||
{
|
{
|
||||||
eventInfo = EventInfo;
|
eventInfo = EventInfo;
|
||||||
if (eventInfo) {
|
if (eventInfo) {
|
||||||
cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID());
|
cChannel *channel = Channels.GetByChannelID(eventInfo->GetChannelID());
|
||||||
if (channel) {
|
if (channel) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
|
asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
|
||||||
@ -1162,7 +1183,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha
|
|||||||
|
|
||||||
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
|
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
|
||||||
if (pArray[num]) {
|
if (pArray[num]) {
|
||||||
cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID());
|
cChannel *channel = Channels.GetByChannelID(pArray[num]->GetChannelID());
|
||||||
if (channel) {
|
if (channel) {
|
||||||
pArray[num]->SetChannelNumber(channel->Number());
|
pArray[num]->SetChannelNumber(channel->Number());
|
||||||
num++;
|
num++;
|
||||||
@ -1192,7 +1213,7 @@ eOSState cMenuWhatsOn::Switch(void)
|
|||||||
{
|
{
|
||||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||||
if (item) {
|
if (item) {
|
||||||
cChannel *channel = Channels.GetByServiceID(item->eventInfo->GetServiceID());
|
cChannel *channel = Channels.GetByChannelID(item->eventInfo->GetChannelID());
|
||||||
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
@ -1313,7 +1334,7 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
|
|||||||
SetTitle(buffer);
|
SetTitle(buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
if (schedules) {
|
if (schedules) {
|
||||||
const cSchedule *Schedule = Channel->Sid() ? schedules->GetSchedule(Channel->Sid()) : schedules->GetSchedule();
|
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
|
||||||
int num = Schedule->NumEvents();
|
int num = Schedule->NumEvents();
|
||||||
const cEventInfo **pArray = MALLOC(const cEventInfo *, num);
|
const cEventInfo **pArray = MALLOC(const cEventInfo *, num);
|
||||||
if (pArray) {
|
if (pArray) {
|
||||||
@ -1376,7 +1397,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
|||||||
if (!now && !next) {
|
if (!now && !next) {
|
||||||
int ChannelNr = 0;
|
int ChannelNr = 0;
|
||||||
if (Count()) {
|
if (Count()) {
|
||||||
cChannel *channel = Channels.GetByServiceID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetServiceID());
|
cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetChannelID());
|
||||||
if (channel)
|
if (channel)
|
||||||
ChannelNr = channel->Number();
|
ChannelNr = channel->Number();
|
||||||
}
|
}
|
||||||
@ -1403,7 +1424,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
|||||||
now = next = false;
|
now = next = false;
|
||||||
const cEventInfo *ei = cMenuWhatsOn::ScheduleEventInfo();
|
const cEventInfo *ei = cMenuWhatsOn::ScheduleEventInfo();
|
||||||
if (ei) {
|
if (ei) {
|
||||||
cChannel *channel = Channels.GetByServiceID(ei->GetServiceID());
|
cChannel *channel = Channels.GetByChannelID(ei->GetChannelID());
|
||||||
if (channel) {
|
if (channel) {
|
||||||
PrepareSchedule(channel);
|
PrepareSchedule(channel);
|
||||||
if (channel->Number() != cDevice::CurrentChannel()) {
|
if (channel->Number() != cDevice::CurrentChannel()) {
|
||||||
@ -2713,7 +2734,7 @@ bool cRecordControl::GetEventInfo(void)
|
|||||||
cMutexLock MutexLock;
|
cMutexLock MutexLock;
|
||||||
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
|
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
const cSchedule *Schedule = Schedules->GetSchedule(channel->Sid());
|
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
||||||
if (Schedule) {
|
if (Schedule) {
|
||||||
eventInfo = Schedule->GetEventAround(Time);
|
eventInfo = Schedule->GetEventAround(Time);
|
||||||
if (eventInfo) {
|
if (eventInfo) {
|
||||||
|
22
osd.c
22
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.c 1.36 2002/10/13 10:31:28 kls Exp $
|
* $Id: osd.c 1.37 2002/11/10 12:30:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
@ -599,20 +599,24 @@ eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
|
|||||||
delete subMenu;
|
delete subMenu;
|
||||||
subMenu = SubMenu;
|
subMenu = SubMenu;
|
||||||
subMenu->Display();
|
subMenu->Display();
|
||||||
return osContinue; // convenience return value (see cMenuMain)
|
return osContinue; // convenience return value
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cOsdMenu::CloseSubMenu()
|
||||||
|
{
|
||||||
|
delete subMenu;
|
||||||
|
subMenu = NULL;
|
||||||
|
RefreshCurrent();
|
||||||
|
Display();
|
||||||
|
return osContinue; // convenience return value
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cOsdMenu::ProcessKey(eKeys Key)
|
eOSState cOsdMenu::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
if (subMenu) {
|
if (subMenu) {
|
||||||
eOSState state = subMenu->ProcessKey(Key);
|
eOSState state = subMenu->ProcessKey(Key);
|
||||||
if (state == osBack) {
|
if (state == osBack)
|
||||||
delete subMenu;
|
return CloseSubMenu();
|
||||||
subMenu = NULL;
|
|
||||||
RefreshCurrent();
|
|
||||||
Display();
|
|
||||||
state = osContinue;
|
|
||||||
}
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
osd.h
3
osd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.h 1.35 2002/11/03 18:03:55 kls Exp $
|
* $Id: osd.h 1.36 2002/11/10 12:28:57 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSD_H
|
#ifndef __OSD_H
|
||||||
@ -147,6 +147,7 @@ protected:
|
|||||||
void Mark(void);
|
void Mark(void);
|
||||||
eOSState HotKey(eKeys Key);
|
eOSState HotKey(eKeys Key);
|
||||||
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
||||||
|
eOSState CloseSubMenu();
|
||||||
bool HasSubMenu(void) { return subMenu; }
|
bool HasSubMenu(void) { return subMenu; }
|
||||||
void SetStatus(const char *s);
|
void SetStatus(const char *s);
|
||||||
void SetTitle(const char *Title, bool ShowDate = true);
|
void SetTitle(const char *Title, bool ShowDate = true);
|
||||||
|
4
remote.h
4
remote.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remote.h 1.19 2002/11/01 10:48:11 kls Exp $
|
* $Id: remote.h 1.20 2002/11/09 11:07:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMOTE_H
|
#ifndef __REMOTE_H
|
||||||
@ -16,8 +16,6 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
typedef unsigned long long int uint64;
|
|
||||||
|
|
||||||
class cRemote : public cListObject {
|
class cRemote : public cListObject {
|
||||||
private:
|
private:
|
||||||
enum { MaxKeys = MAXKEYSINMACRO };
|
enum { MaxKeys = MAXKEYSINMACRO };
|
||||||
|
31
svdrp.c
31
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.48 2002/10/20 12:45:03 kls Exp $
|
* $Id: svdrp.c 1.49 2002/11/10 12:09:56 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
@ -776,16 +776,21 @@ void cSVDRP::CmdMODC(const char *Option)
|
|||||||
tail = skipspace(tail);
|
tail = skipspace(tail);
|
||||||
cChannel *channel = Channels.GetByNumber(n);
|
cChannel *channel = Channels.GetByNumber(n);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
cChannel c = *channel;
|
cChannel ch;
|
||||||
if (!c.Parse(tail)) {
|
if (ch.Parse(tail, true)) {
|
||||||
Reply(501, "Error in channel settings");
|
if (Channels.HasUniqueChannelID(&ch, channel)) {
|
||||||
return;
|
*channel = ch;
|
||||||
}
|
Channels.ReNumber();
|
||||||
*channel = c;
|
|
||||||
Channels.Save();
|
Channels.Save();
|
||||||
isyslog("channel %d modified", channel->Number());
|
isyslog("modifed channel %d %s", channel->Number(), channel->ToText());
|
||||||
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Channel settings are not unique");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Error in channel settings");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Channel \"%d\" not defined", n);
|
Reply(501, "Channel \"%d\" not defined", n);
|
||||||
}
|
}
|
||||||
@ -844,14 +849,20 @@ void cSVDRP::CmdMOVT(const char *Option)
|
|||||||
void cSVDRP::CmdNEWC(const char *Option)
|
void cSVDRP::CmdNEWC(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
|
cChannel ch;
|
||||||
|
if (ch.Parse(Option, true)) {
|
||||||
|
if (Channels.HasUniqueChannelID(&ch)) {
|
||||||
cChannel *channel = new cChannel;
|
cChannel *channel = new cChannel;
|
||||||
if (channel->Parse(Option)) {
|
*channel = ch;
|
||||||
Channels.Add(channel);
|
Channels.Add(channel);
|
||||||
Channels.ReNumber();
|
Channels.ReNumber();
|
||||||
Channels.Save();
|
Channels.Save();
|
||||||
isyslog("channel %d added", channel->Number());
|
isyslog("new channel %d %s", channel->Number(), channel->ToText());
|
||||||
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Channel settings are not unique");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Error in channel settings");
|
Reply(501, "Error in channel settings");
|
||||||
}
|
}
|
||||||
|
53
timers.c
53
timers.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.c 1.1 2002/10/20 12:28:55 kls Exp $
|
* $Id: timers.c 1.2 2002/11/10 10:19:12 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
@ -49,7 +49,7 @@ cTimer::cTimer(const cEventInfo *EventInfo)
|
|||||||
startTime = stopTime = 0;
|
startTime = stopTime = 0;
|
||||||
recording = pending = false;
|
recording = pending = false;
|
||||||
active = true;
|
active = true;
|
||||||
channel = Channels.GetByServiceID(EventInfo->GetServiceID());
|
channel = Channels.GetByChannelID(EventInfo->GetChannelID());
|
||||||
time_t tstart = EventInfo->GetTime();
|
time_t tstart = EventInfo->GetTime();
|
||||||
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
|
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
|
||||||
tstart -= Setup.MarginStart * 60;
|
tstart -= Setup.MarginStart * 60;
|
||||||
@ -92,22 +92,17 @@ bool cTimer::operator< (const cListObject &ListObject)
|
|||||||
return t1 < t2 || (t1 == t2 && priority > ti->priority);
|
return t1 < t2 || (t1 == t2 && priority > ti->priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cTimer::ToText(cTimer *Timer)
|
const char *cTimer::ToText(bool UseChannelID)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
strreplace(Timer->file, ':', '|');
|
strreplace(file, ':', '|');
|
||||||
strreplace(Timer->summary, '\n', '|');
|
strreplace(summary, '\n', '|');
|
||||||
asprintf(&buffer, "%d:%d:%s:%04d:%04d:%d:%d:%s:%s\n", Timer->active, Timer->Channel()->Number(), PrintDay(Timer->day, Timer->firstday), Timer->start, Timer->stop, Timer->priority, Timer->lifetime, Timer->file, Timer->summary ? Timer->summary : "");
|
asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", active, UseChannelID ? Channel()->GetChannelIDStr() : itoa(Channel()->Number()), PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : "");
|
||||||
strreplace(Timer->summary, '|', '\n');
|
strreplace(summary, '|', '\n');
|
||||||
strreplace(Timer->file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cTimer::ToText(void)
|
|
||||||
{
|
|
||||||
return ToText(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cTimer::TimeToInt(int t)
|
int cTimer::TimeToInt(int t)
|
||||||
{
|
{
|
||||||
return (t / 100 * 60 + t % 100) * 60;
|
return (t / 100 * 60 + t % 100) * 60;
|
||||||
@ -189,8 +184,9 @@ const char *cTimer::PrintFirstDay(void)
|
|||||||
|
|
||||||
bool cTimer::Parse(const char *s)
|
bool cTimer::Parse(const char *s)
|
||||||
{
|
{
|
||||||
char *buffer1 = NULL;
|
char *channelbuffer = NULL;
|
||||||
char *buffer2 = NULL;
|
char *daybuffer = NULL;
|
||||||
|
char *filebuffer = NULL;
|
||||||
free(summary);
|
free(summary);
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
//XXX Apparently sscanf() doesn't work correctly if the last %a argument
|
//XXX Apparently sscanf() doesn't work correctly if the last %a argument
|
||||||
@ -208,34 +204,35 @@ bool cTimer::Parse(const char *s)
|
|||||||
strcat(strn0cpy(s2, s, l2 + 1), " \n");
|
strcat(strn0cpy(s2, s, l2 + 1), " \n");
|
||||||
s = s2;
|
s = s2;
|
||||||
}
|
}
|
||||||
int ch = 0;
|
bool result = false;
|
||||||
if (8 <= sscanf(s, "%d :%d :%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &active, &ch, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) {
|
if (8 <= sscanf(s, "%d :%a[^:]:%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &active, &channelbuffer, &daybuffer, &start, &stop, &priority, &lifetime, &filebuffer, &summary)) {
|
||||||
if (summary && !*skipspace(summary)) {
|
if (summary && !*skipspace(summary)) {
|
||||||
free(summary);
|
free(summary);
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
}
|
}
|
||||||
//TODO add more plausibility checks
|
//TODO add more plausibility checks
|
||||||
day = ParseDay(buffer1, &firstday);
|
day = ParseDay(daybuffer, &firstday);
|
||||||
strn0cpy(file, buffer2, MaxFileName);
|
result = day != 0;
|
||||||
|
strn0cpy(file, filebuffer, MaxFileName);
|
||||||
strreplace(file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
strreplace(summary, '|', '\n');
|
strreplace(summary, '|', '\n');
|
||||||
free(buffer1);
|
uint64 cid = cChannel::StringToChannelID(channelbuffer);
|
||||||
free(buffer2);
|
channel = cid ? Channels.GetByChannelID(cid) : Channels.GetByNumber(atoi(channelbuffer));
|
||||||
free(s2);
|
|
||||||
channel = Channels.GetByNumber(ch);
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
esyslog("ERROR: channel %d not defined", ch);
|
esyslog("ERROR: channel %s not defined", channelbuffer);
|
||||||
return false;
|
result = false;
|
||||||
}
|
}
|
||||||
return day != 0;
|
|
||||||
}
|
}
|
||||||
|
free(channelbuffer);
|
||||||
|
free(daybuffer);
|
||||||
|
free(filebuffer);
|
||||||
free(s2);
|
free(s2);
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cTimer::Save(FILE *f)
|
bool cTimer::Save(FILE *f)
|
||||||
{
|
{
|
||||||
return fprintf(f, ToText()) > 0;
|
return fprintf(f, ToText(true)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cTimer::IsSingleEvent(void)
|
bool cTimer::IsSingleEvent(void)
|
||||||
|
5
timers.h
5
timers.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.h 1.1 2002/10/20 11:52:23 kls Exp $
|
* $Id: timers.h 1.2 2002/11/10 10:17:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TIMERS_H
|
#ifndef __TIMERS_H
|
||||||
@ -36,7 +36,6 @@ private:
|
|||||||
char file[MaxFileName];
|
char file[MaxFileName];
|
||||||
time_t firstday;
|
time_t firstday;
|
||||||
char *summary;
|
char *summary;
|
||||||
static const char *ToText(cTimer *Timer);
|
|
||||||
public:
|
public:
|
||||||
cTimer(bool Instant = false);
|
cTimer(bool Instant = false);
|
||||||
cTimer(const cEventInfo *EventInfo);
|
cTimer(const cEventInfo *EventInfo);
|
||||||
@ -55,7 +54,7 @@ public:
|
|||||||
const char *File(void) { return file; }
|
const char *File(void) { return file; }
|
||||||
time_t FirstDay(void) { return firstday; }
|
time_t FirstDay(void) { return firstday; }
|
||||||
const char *Summary(void) { return summary; }
|
const char *Summary(void) { return summary; }
|
||||||
const char *ToText(void);
|
const char *ToText(bool UseChannelID = false);
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
bool IsSingleEvent(void);
|
bool IsSingleEvent(void);
|
||||||
|
9
tools.c
9
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.72 2002/10/19 12:32:53 kls Exp $
|
* $Id: tools.c 1.73 2002/11/09 15:33:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@ -243,6 +243,13 @@ bool isnumber(const char *s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *itoa(int n)
|
||||||
|
{
|
||||||
|
static char buf[16];
|
||||||
|
snprintf(buf, sizeof(buf), "%d", n);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
const char *AddDirectory(const char *DirName, const char *FileName)
|
const char *AddDirectory(const char *DirName, const char *FileName)
|
||||||
{
|
{
|
||||||
static char *buf = NULL;
|
static char *buf = NULL;
|
||||||
|
4
tools.h
4
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.51 2002/10/19 12:31:50 kls Exp $
|
* $Id: tools.h 1.52 2002/11/09 15:32:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
typedef unsigned long long int uint64;
|
||||||
|
|
||||||
extern int SysLogLevel;
|
extern int SysLogLevel;
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ int numdigits(int n);
|
|||||||
int time_ms(void);
|
int time_ms(void);
|
||||||
void delay_ms(int ms);
|
void delay_ms(int ms);
|
||||||
bool isnumber(const char *s);
|
bool isnumber(const char *s);
|
||||||
|
const char *itoa(int n); // returns a statically allocated string!
|
||||||
const char *AddDirectory(const char *DirName, const char *FileName); // returns a statically allocated string!
|
const char *AddDirectory(const char *DirName, const char *FileName); // returns a statically allocated string!
|
||||||
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
|
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
|
||||||
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
||||||
|
30
vdr.5
30
vdr.5
@ -8,9 +8,9 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.5 1.11 2002/10/27 15:36:44 kls Exp $
|
.\" $Id: vdr.5 1.12 2002/11/10 10:10:15 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 5 "7 Oct 2002" "1.2.0" "Video Disk Recorder Files"
|
.TH vdr 5 "10 Nov 2002" "1.2.0" "Video Disk Recorder Files"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vdr file formats - the Video Disk Recorder Files
|
vdr file formats - the Video Disk Recorder Files
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@ -120,6 +120,18 @@ l l.
|
|||||||
.TP
|
.TP
|
||||||
.B SID
|
.B SID
|
||||||
The service ID of this channel.
|
The service ID of this channel.
|
||||||
|
.PP
|
||||||
|
A particular channel can be uniquely identified by its \fBchannel\ ID\fR,
|
||||||
|
which is a string that looks like this:
|
||||||
|
|
||||||
|
\fBS19.2E-0-12188-12003\fR
|
||||||
|
|
||||||
|
The components of this string are the \fBSource\fR (S19.2E), \fBFrequency\fR
|
||||||
|
(12188, MHz) and \fBSID\fR (12003) as defined above. The part that is currently
|
||||||
|
\fB0\fR is reserved for future use.
|
||||||
|
.br
|
||||||
|
The \fBchannel\ ID\fR is used in the \fItimers.conf\fR and \fIepg.data\fR
|
||||||
|
files to properly identify the channels.
|
||||||
.SS TIMERS
|
.SS TIMERS
|
||||||
The file \fItimers.conf\fR contains the timer setup.
|
The file \fItimers.conf\fR contains the timer setup.
|
||||||
Each line contains one timer definition, with individual fields
|
Each line contains one timer definition, with individual fields
|
||||||
@ -143,7 +155,13 @@ Note: in order to allow future extensibility, external programs using the
|
|||||||
and leave the lower 16 bit untouched.
|
and leave the lower 16 bit untouched.
|
||||||
.TP
|
.TP
|
||||||
.B Channel
|
.B Channel
|
||||||
The number of the channel to record.
|
The channel to record from. This is either the channel number as shown in the
|
||||||
|
on-screen menus, or a complete channel ID. When reading \fItimers.conf\fR
|
||||||
|
any channel numbers will be mapped to the respective channel ids and when
|
||||||
|
the file is written again, there will only be channel ids. Channel numbers
|
||||||
|
are accepted as input in order to allow easier creation of timers when
|
||||||
|
manually editing \fItimers.conf\fR. Also, when timers are listed via SVDRP
|
||||||
|
commands, the channels are given as numbers.
|
||||||
.TP
|
.TP
|
||||||
.B Day
|
.B Day
|
||||||
The day when this timer shall record.
|
The day when this timer shall record.
|
||||||
@ -472,7 +490,7 @@ The following tag characters are defined:
|
|||||||
.TS
|
.TS
|
||||||
tab (@);
|
tab (@);
|
||||||
l l.
|
l l.
|
||||||
\fBC\fR@<service id> <channel name>
|
\fBC\fR@<channel id> <channel name>
|
||||||
\fBE\fR@<event id> <start time> <duration> <table id>
|
\fBE\fR@<event id> <start time> <duration> <table id>
|
||||||
\fBT\fR@<title>
|
\fBT\fR@<title>
|
||||||
\fBS\fR@<subtitle>
|
\fBS\fR@<subtitle>
|
||||||
@ -491,8 +509,8 @@ should at least have a \fBT\fR entry).
|
|||||||
.TS
|
.TS
|
||||||
tab (@);
|
tab (@);
|
||||||
l l.
|
l l.
|
||||||
<service id> @is the "program number" as defined in 'channels.conf'
|
<channel id> @is the "channel ID", made up from the parameters defined in 'channels.conf'
|
||||||
<channel name> @is the "name" as in 'channels.conf' (for information only)
|
<channel name> @is the "name" as in 'channels.conf' (for information only, may be left out)
|
||||||
<start time> @is the time (as a time_t integer) in UTC when this event starts
|
<start time> @is the time (as a time_t integer) in UTC when this event starts
|
||||||
<duration> @is the time (in seconds) that this event will take
|
<duration> @is the time (in seconds) that this event will take
|
||||||
<table id> @is a hex number that indicates the table this event is contained\
|
<table id> @is a hex number that indicates the table this event is contained\
|
||||||
|
Loading…
Reference in New Issue
Block a user