vdr/epg.h
Klaus Schmidinger 939081e274 Version 1.7.11
- Fixed resetting the file size when regenerating the index file.
- The new function cDevice::PatPmtParser() can be used in derived devices to access
  the PAT/PMT of the currently replayed material.
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- The PCR pid in generated PMTs is now set to 0x1FFF ("no PCR pid") in
  cPatPmtGenerator::GeneratePmt(), because VDR doesn't record the PCR pid.
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- The 'sky' plugin is no longer part of the VDR source.
- Improved SPU handling on devices with limited OSD capabilities (thanks to
  Matthieu Castet).
- Several code modifications to avoid compiler warnings (thanks to Winfried Köhler).
- Added stream type 11172 AUDIO to cPatPmtParser::ParsePmt() (thanks to Johann
  Friedrichs).
- Removed debug output of '-' from cTransfer::Receive().
- Added defines for large files to the 'newplugin' script (reported by Udo Richter).
- Removed the workaround for short channel names of "Kabel Deutschland", because
  apparently they now have their data according to the DVB standard (thanks to
  Johann Friedrichs).
- Some fixes to dvbspu.[hc] (thanks to Johann Friedrichs).
- Fixed a busy loop when moving editing marks (thanks to Johann Friedrichs).
- Updated sources.conf (thanks to Derek Kelly).
- Modified cCharSetConv so that it can be used to convert from "whatever VDR uses"
  to a given code (thanks to Joachim Wilke).
- Channel names containing commas are now handled correctly in channels.conf.
  If a channel's short name contains a comma, it is replaced with a '.'.
- cDevice now logs the device number when a new device is created.
- Fixed handling STREAMTYPE_11172_AUDIO in cPatPmtParser::ParsePmt().
- cParsePatPmt now has functions to retrieve the audio, dolby and subtitle pids.
- cPatFilter::Process() now only stores CA descriptors for video and audio pids
  (thanks to Francesco Saverio Schiavarelli for reporting a problem with channels
  that have some encrypted components that VDR doesn't use).
- cDevice::AddPid() now stores the stream type of the given pid (thanks to Andreas
  Regel).
- Added cFont::FontName() and cFont::Size() (thanks to Andreas Regel).
- cPatPmtParser now also stores the audio stream types.
- The support for full featured DVB cards of the TT/FuSi design has been moved
  into the new plugin 'dvbsddevice'. On systems that use such a card as their
  primary device, this plugin now needs to be loaded when running VDR in order
  to view live or recorded video. If the plugin is not loaded, the card will
  be treated like a budget DVB card, and there will be no OSD or viewing
  capability.
- Fixed handling the "CA PMT" generation (revised a change not mentioned in version
  1.7.9's changes, which caused a malfunction with Conax and Viaccess CAMs).
- Fixed stopping subtitle display when switching the primary device (thanks to
  Anssi Hannula).
  IMPORTANT NOTE TO PLUGIN AUTHORS: a plugin that implements a derived cDevice
  class that can replay video must now call the MakePrimaryDevice() function of
  its base class.
- Fixed compiler warnings "format not a string literal and no format arguments"
  in some syslog calls (thanks to Rolf Ahrenberg).
- The new command line options --edit and --genindex can be used to edit a
  recording or generate its index without actually starting the entire VDR
  (based on a patch from Helmut Auer).
- Improved the description of the transponder parameters in vdr.5 (thanks to
  Winfried Köhler).
- Avoiding setting the video stream type to 2 if the vpid is 0 (problem reported
  by Arthur Konovalov).
- Implemented handling the "Content Descriptor" (based on a patch from Rolf
  Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the textual
  representation of the content descriptors as "genre". The epg.data file stores
  the genre using the tag character 'G'.
- Implemented handling the "Parental Rating Descriptor" (based on a patch from Rolf
  Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the parental
  rating (if given) in their event displays. The epg.data file stores
  the parental rating using the tag character 'R'.
  IMPORTANT NOTE: if VDR doesn't display a parental rating, this does not
  necessarily mean that the given programme is suitable for all audiences!
- Rearranged cEvent members to minimize memory waste.
- After a CLRE command, no further EPG processing is now done for 10 seconds,
  so that data sent with subsequent PUTE commands doesn't interfere with data
  from the broadcasters (suggested by Helmut Auer).
- Added support for DVB cards with multiple fontends. Note that this only
  works for DVB cards where each frontend can be used independently of all
  the others on the same adapter.
- Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to
  Anssi Hannula).
2010-01-06 13:34:00 +01:00

216 lines
8.5 KiB
C++

/*
* epg.h: Electronic Program Guide
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
*
* $Id: epg.h 2.3 2010/01/03 14:39:14 kls Exp $
*/
#ifndef __EPG_H
#define __EPG_H
#include "channels.h"
#include "thread.h"
#include "tools.h"
#define MAXEPGBUGFIXLEVEL 3
#define MAXEVCONTENTS 4
#define EVCONTENTMASK_MOVIEDRAMA 0x10
#define EVCONTENTMASK_NEWSCURRENTAFFAIRS 0x20
#define EVCONTENTMASK_SHOW 0x30
#define EVCONTENTMASK_SPORTS 0x40
#define EVCONTENTMASK_CHILDRENYOUTH 0x50
#define EVCONTENTMASK_MUSICBALLETDANCE 0x60
#define EVCONTENTMASK_ARTSCULTURE 0x70
#define EVCONTENTMASK_SOCIALPOLITICALECONOMICS 0x80
#define EVCONTENTMASK_EDUCATIONALSCIENCE 0x90
#define EVCONTENTMASK_LEISUREHOBBIES 0xA0
#define EVCONTENTMASK_SPECIAL 0xB0
#define EVCONTENTMASK_USERDEFINED 0xF0
enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
struct tComponent {
uchar stream;
uchar type;
char language[MAXLANGCODE2];
char *description;
cString ToString(void);
bool FromString(const char *s);
};
class cComponents {
private:
int numComponents;
tComponent *components;
void Realloc(int Index);
public:
cComponents(void);
~cComponents(void);
int NumComponents(void) const { return numComponents; }
void SetComponent(int Index, const char *s);
void SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description);
tComponent *Component(int Index) const { return (Index < numComponents) ? &components[Index] : NULL; }
tComponent *GetComponent(int Index, uchar Stream, uchar Type); // Gets the Index'th component of Stream and Type, skipping other components
// In case of an audio stream the 'type' check actually just distinguishes between "normal" and "Dolby Digital"
};
class cSchedule;
typedef u_int32_t tEventID;
class cEvent : public cListObject {
friend class cSchedule;
private:
// The sequence of these parameters is optimized for minimal memory waste!
cSchedule *schedule; // The Schedule this event belongs to
tEventID eventID; // Event ID of this event
uchar tableID; // Table ID this event came from
uchar version; // Version number of section this event came from
uchar runningStatus; // 0=undefined, 1=not running, 2=starts in a few seconds, 3=pausing, 4=running
uchar parentalRating; // Parental rating of this event
char *title; // Title of this event
char *shortText; // Short description of this event (typically the episode name in case of a series)
char *description; // Description of this event
cComponents *components; // The stream components of this event
uchar contents[MAXEVCONTENTS]; // Contents of this event
time_t startTime; // Start time of this event
int duration; // Duration of this event in seconds
time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
time_t seen; // When this event was last seen in the data stream
public:
cEvent(tEventID EventID);
~cEvent();
virtual int Compare(const cListObject &ListObject) const;
tChannelID ChannelID(void) const;
const cSchedule *Schedule(void) const { return schedule; }
tEventID EventID(void) const { return eventID; }
uchar TableID(void) const { return tableID; }
uchar Version(void) const { return version; }
int RunningStatus(void) const { return runningStatus; }
const char *Title(void) const { return title; }
const char *ShortText(void) const { return shortText; }
const char *Description(void) const { return description; }
const cComponents *Components(void) const { return components; }
uchar Contents(int i = 0) const { return (0 <= i && i < MAXEVCONTENTS) ? contents[i] : 0; }
int ParentalRating(void) const { return parentalRating; }
time_t StartTime(void) const { return startTime; }
time_t EndTime(void) const { return startTime + duration; }
int Duration(void) const { return duration; }
time_t Vps(void) const { return vps; }
time_t Seen(void) const { return seen; }
bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; }
bool HasTimer(void) const;
bool IsRunning(bool OrAboutToStart = false) const;
static const char *ContentToString(uchar Content);
cString GetParentalRatingString(void) const;
cString GetDateString(void) const;
cString GetTimeString(void) const;
cString GetEndTimeString(void) const;
cString GetVpsString(void) const;
void SetEventID(tEventID EventID);
void SetTableID(uchar TableID);
void SetVersion(uchar Version);
void SetRunningStatus(int RunningStatus, cChannel *Channel = NULL);
void SetTitle(const char *Title);
void SetShortText(const char *ShortText);
void SetDescription(const char *Description);
void SetComponents(cComponents *Components); // Will take ownership of Components!
void SetContents(uchar *Contents);
void SetParentalRating(int ParentalRating);
void SetStartTime(time_t StartTime);
void SetDuration(int Duration);
void SetVps(time_t Vps);
void SetSeen(void);
cString ToDescr(void) const;
void Dump(FILE *f, const char *Prefix = "", bool InfoOnly = false) const;
bool Parse(char *s);
static bool Read(FILE *f, cSchedule *Schedule);
void FixEpgBugs(void);
};
class cSchedules;
class cSchedule : public cListObject {
private:
tChannelID channelID;
cList<cEvent> events;
cHash<cEvent> eventsHashID;
cHash<cEvent> eventsHashStartTime;
bool hasRunning;
time_t modified;
time_t presentSeen;
public:
cSchedule(tChannelID ChannelID);
tChannelID ChannelID(void) const { return channelID; }
time_t Modified(void) const { return modified; }
time_t PresentSeen(void) const { return presentSeen; }
bool PresentSeenWithin(int Seconds) const { return time(NULL) - presentSeen < Seconds; }
void SetModified(void) { modified = time(NULL); }
void SetPresentSeen(void) { presentSeen = time(NULL); }
void SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel = NULL);
void ClrRunningStatus(cChannel *Channel = NULL);
void ResetVersions(void);
void Sort(void);
void DropOutdated(time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version);
void Cleanup(time_t Time);
void Cleanup(void);
cEvent *AddEvent(cEvent *Event);
void DelEvent(cEvent *Event);
void HashEvent(cEvent *Event);
void UnhashEvent(cEvent *Event);
const cList<cEvent> *Events(void) const { return &events; }
const cEvent *GetPresentEvent(void) const;
const cEvent *GetFollowingEvent(void) const;
const cEvent *GetEvent(tEventID EventID, time_t StartTime = 0) const;
const cEvent *GetEventAround(time_t Time) const;
void Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0) const;
static bool Read(FILE *f, cSchedules *Schedules);
};
class cSchedulesLock {
private:
bool locked;
public:
cSchedulesLock(bool WriteLock = false, int TimeoutMs = 0);
~cSchedulesLock();
bool Locked(void) { return locked; }
};
class cSchedules : public cList<cSchedule> {
friend class cSchedule;
friend class cSchedulesLock;
private:
cRwLock rwlock;
static cSchedules schedules;
static const char *epgDataFileName;
static time_t lastCleanup;
static time_t lastDump;
static time_t modified;
public:
static void SetEpgDataFileName(const char *FileName);
static const cSchedules *Schedules(cSchedulesLock &SchedulesLock);
///< Caller must provide a cSchedulesLock which has to survive the entire
///< time the returned cSchedules is accessed. Once the cSchedules is no
///< longer used, the cSchedulesLock must be destroyed.
static time_t Modified(void) { return modified; }
static void SetModified(cSchedule *Schedule);
static void Cleanup(bool Force = false);
static void ResetVersions(void);
static bool ClearAll(void);
static bool Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0);
static bool Read(FILE *f = NULL);
cSchedule *AddSchedule(tChannelID ChannelID);
const cSchedule *GetSchedule(tChannelID ChannelID) const;
const cSchedule *GetSchedule(const cChannel *Channel, bool AddIfMissing = false) const;
};
void ReportEpgBugFixStats(bool Reset = false);
#endif //__EPG_H