summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS38
-rw-r--r--HISTORY67
-rw-r--r--MANUAL2
-rw-r--r--Make.config.template4
-rw-r--r--Makefile10
-rw-r--r--PLUGINS/src/skincurses/HISTORY4
-rw-r--r--PLUGINS/src/skincurses/skincurses.c29
-rw-r--r--channels.c57
-rw-r--r--channels.conf32
-rw-r--r--channels.h16
-rw-r--r--config.h6
-rw-r--r--cutter.c4
-rw-r--r--dvbdevice.c4
-rw-r--r--dvbosd.c6
-rw-r--r--dvbplayer.c4
-rw-r--r--eit.c37
-rw-r--r--epg.c203
-rw-r--r--epg.h27
-rw-r--r--i18n.c39
-rw-r--r--libsi/Makefile4
-rw-r--r--libsi/si.c35
-rw-r--r--libsi/util.c5
-rw-r--r--menu.c161
-rw-r--r--menu.h4
-rw-r--r--osd.c8
-rw-r--r--osd.h6
-rw-r--r--player.h3
-rw-r--r--recording.c206
-rw-r--r--recording.h30
-rw-r--r--sdt.c11
-rw-r--r--sections.c3
-rw-r--r--skinclassic.c30
-rw-r--r--skins.h4
-rw-r--r--skinsttng.c36
-rw-r--r--sources.h5
-rwxr-xr-xsummary2info.pl47
-rw-r--r--svdrp.c32
-rw-r--r--thread.c8
-rw-r--r--thread.h3
-rw-r--r--tools.c91
-rw-r--r--tools.h39
-rw-r--r--vdr.510
-rw-r--r--vdr.c58
43 files changed, 1015 insertions, 413 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index cc5bdb4..eff35c7 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -197,6 +197,8 @@ Stefan Huelswitt <huels@iname.com>
for fixing handling symbolic links in cRecordings::ScanVideoDir()
for reporting a memory leak in tComponent
for fixing a memory leak in cDvbPlayer
+ for pointing out that recordings with empty episode names were not listed correctly
+ in the LSTR command
Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than 27500
@@ -408,6 +410,7 @@ Mirko Dölle <mdoelle@linux-user.de>
change in Daylight Saving Time
for suggesting to avoid the external 'find' command to scan the video directory
for reporting a problem with inconsistent channel and timer lists
+ for making the "Play" key in live viewing mode resume a previous replay session
Michael Rakowski <mrak@gmx.de>
for translating OSD texts to the Polish language
@@ -563,6 +566,7 @@ Oliver Endriss <o.endriss@gmx.de>
for reporting a problem with the name of the remote control for which the keys are
being learned overwriting the date/time in the 'classic' skin
for making cDvbOsd check available OSD memory at runtime
+ for making cEIT::cEIT() drop EPG events that have a zero start time or duration
Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf'
@@ -603,6 +607,8 @@ Gerhard Steiner <steiner@mail.austria.com>
for reporting a problem with newly created timers in case they are not confirmed
with "Ok"
for reporting an occasional "Broken pipe" error in SVDRP connections
+ for reporting that some cable channels don't mark short channel names according
+ to the standard
Jaakko Hyvätti <jaakko@hyvatti.iki.fi>
for translating OSD texts to the Finnish language
@@ -642,6 +648,7 @@ Andreas Kool <akool@akool.de>
for fixing detecting the /dev/videoN devices for GRAB in case there are others
before the DVB devices
for fixing a possible NULL pointer access in cEITScanner::Process()
+ for pointing out that 'vdr --version' failed on an UTF-8 system
Guy Roussin <guy.roussin@teledetection.fr>
for suggesting not to display channel group delimiters without text
@@ -768,6 +775,8 @@ Sascha Volkenandt <sascha@akv-soft.de>
Digital audio after switching to a channel that has DD and selecting the DD audio
track
for reporting a bug in timeout handling in cRwLock::Lock()
+ for pointing out that the SVDRP command DELR deleted recordings that are currently
+ being written to by a timer
Malcolm Caldwell <malcolm.caldwell@ntu.edu.au>
for modifying LOF handling to allow for C-band reception
@@ -786,6 +795,7 @@ Ludwig Nussel <ludwig.nussel@web.de>
for adding some checks when canceling a thread and removing the usleep() in
cThread::Start()
for removing the LOCK_THREAD from the LIRC thread
+ for making the Makefile patch friendlier
Thomas Koch <tom@harhar.net>
for his support in keeping the Premiere World channels up to date in 'channels.conf'
@@ -869,6 +879,7 @@ Niko Tarnanen <niko.tarnanen@hut.fi>
Rolf Ahrenberg <rahrenbe@cc.hut.fi>
for translating OSD texts to the Finnish language
for fixing internationalization of the text for "Setup/DVB/Audio language(s)"
+ for making pressing the Power button not stop Transfer Mode or replay immediately
Ralf Klueber <ralf.klueber@vodafone.com>
for reporting a bug in cutting a recording if there is only a single editing mark
@@ -941,7 +952,7 @@ Reinhard Nissl <rnissl@gmx.de>
for fixing a possible freeze in pause mode in case a device's PlayPesPacket()
function permanently returns 0
for fixing a typo in detecting UTF-8
- for fixing handling fragments of less than 3 byte in cPesAssembler
+ for fixing handling fragments of less than 4 byte in cPesAssembler
for some rearrangements in cDvbPlayer::Action() to avoid lockups on NPTL systems
Richard Robson <richard_robson@beeb.net>
@@ -1061,6 +1072,7 @@ Andreas Regel <andreas.regel@gmx.de>
for pointing out a missing call to cStatus::MsgOsdtatusMessage(NULL) in
cSkins::Message()
for reporting a problem in handling Transfer Mode for radio channels
+ for reporting a problem with messages when a cOsdObject uses the raw OSD
Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de>
for fixing the validity check for channel IDs, because some providers use TIDs
@@ -1169,6 +1181,11 @@ Marco Schlüßler <marco@lordzodiac.de>
for fixing a bug in libsi's SubtitlingDescriptor::getLength()
for removing scaling coordinates in letterbox mode from cDvbSpu
for fixing a wrong inheritance in libsi's SubtitlingDescriptor::Subtitling
+ for adding cPlayer::DeviceSetVideoDisplayFormat()
+ for making the setup not being saved in case of a fatal error, to keep the volume
+ level from being set to a wrong value
+ for fixing a possible hangup when ending a replay session while cIndexFile::CatchUp()
+ is waiting
Jürgen Schmitz <j.schmitz@web.de>
for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -1331,3 +1348,22 @@ Matthias Lötzke <Matthias@Loetzke.de>
Wolfgang Fritz <wolfgang.fritz@gmx.net>
for making recordings avoid zero sized video data files
+
+Michael Reinelt <reinelt@eunet.at>
+ for reporting a problem with the EPG scan on systems that don't use DiSEqC
+
+Johannes Stezenbach <js@linuxtv.org>
+ for pointing out that the byte swap for big endian systems in cDvbOsd::Flush()
+ is wrong
+
+Paavo Hartikainen <pahartik@sci.fi>
+ for verifying that the byte swap for big endian systems in cDvbOsd::Flush() was
+ wrong
+
+Georg Acher <acher@baycom.de>
+ for making tChannelID::operator==() inline for better performance
+ for introducing cListBase::count for better performance
+ for a patch that was used to implement hash tables to speed up cSchedule::GetEvent()
+ for avoiding unnecessary calls to getLength() in libsi/si.c, and avoiding the
+ '& 0xff' in CRC32::crc32() of libsi/util.c
+ for suggesting to reduce the priority of the section handler threads
diff --git a/HISTORY b/HISTORY
index 0b30015..2e5778a 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3487,7 +3487,7 @@ Video Disk Recorder Revision History
- Fixed handling transparent areas in cDvbSpuBitmap (thanks to Marco Schlüßler).
- Now also considering the "EPG linger time" when saving the EPG data to file or
listing it via LSTE (thanks to Roman Krenický).
-- Fixed handling fragments of less than 3 byte in cPesAssembler (thanks to
+- Fixed handling fragments of less than 4 byte in cPesAssembler (thanks to
Reinhard Nissl).
- Fixed a bug in libsi's SubtitlingDescriptor::getLength() (thanks to Marco
Schlüßler).
@@ -3512,3 +3512,68 @@ Video Disk Recorder Revision History
(thanks to Reinhard Nissl).
- Fixed a wrong inheritance in libsi's SubtitlingDescriptor::Subtitling (thanks to
Marco Schlüßler).
+
+2005-05-29: Version 1.3.25
+
+- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
+- Some cable providers don't mark short channel names according to the standard,
+ but rather go their own way and use "name>short name". VDR now splits at this
+ character for cable channels (thanks to Gerhard Steiner for reporting this one).
+- Added a check for Setup.DiSEqC in cDvbDevice::ProvidesTransponder(), otherwise
+ the EPG scan didn't work on systems that don't use DiSEqC (thanks to Michael
+ Reinelt for reporting this one).
+- Made the Makefile patch friendlier (thanks to Ludwig Nussel).
+- Made cOsd::isOpen an integer counter to avoid problems with messages when a
+ cOsdObject uses the raw OSD (thanks to Andreas Regel for reporting this one).
+- Updated the Danish OSD texts (thanks to Mogens Elneff).
+- The file 'summary.vdr' has been replaced with 'info.vdr' and now contains the
+ information about a recording, in the same format as the events are stored in
+ 'epg.data' (see man vdr(5) for details). Existing summary files can be converted
+ to the new format by running the Perl script 'summary2info.pl', as in
+
+ summary2info.pl /video
+
+ (the parameter given has to be the video directory). If there is no 'info.vdr'
+ file for a recording, an attempt is made to read a 'summary.vdr'.
+- The "Summary" button in the "Recordings" menu has been renamed to "Info", and
+ the page it brings up now shows the recording's information, much like the EPG
+ event page. Therefore it now no longer uses the skin's SetText() function, but
+ rather the SetRecording() function. Skin plugins may need to adjust that function
+ accordingly (see skinsttng.c, for instance).
+- The SVDRP command LSTR now lists the recording information in the same tagged
+ format as the LSTE command lists the EPG data.
+- The audio track menu now contains track descriptions when replaying (provided
+ such descriptions were available in the EPG data when the recording was made,
+ and are stored in the info.vdr file).
+- Avoiding extra blanks at the end of names of instant recordings.
+- Removed converting byte order on big endian systems from cDvbOsd::Flush(),
+ which, according to Johannes Stezenbach and Paavo Hartikainen, is wrong.
+- Added cPlayer::DeviceSetVideoDisplayFormat() (thanks to Marco Schlüßler).
+- No longer saving the setup in case of a fatal error, to keep the volume level
+ from being set to a wrong value (thanks to Marco Schlüßler).
+- Fixed a possible hangup when ending a replay session while cIndexFile::CatchUp()
+ is waiting (thanks to Marco Schlüßler).
+- The SVDRP command DELR no longer deletes recordings that are currently being
+ written to by a timer (thanks to Sascha Volkenandt for pointing out this one).
+- Pressing the "Play" key in live viewing mode now resumes a previous replay
+ session (thanks to Mirko Dölle).
+- Now dropping EPG events that have a zero start time or duration (thanks to
+ Oliver Endriss).
+- No longer stopping Transfer Mode or replay immediately when the Power button
+ is pressed (thanks to Rolf Ahrenberg).
+- Moved the NPTL and UTF-8 checks after the version and help output (thanks to
+ Andreas Kool for pointing out that 'vdr --version' failed on an UTF-8 system).
+- Made tChannelID::operator==() inline for better performance (thanks to Georg
+ Acher).
+- Introduced cListBase::count for better performance (thanks to Georg Acher).
+- cEvent no longer stores the channelID directly, but rather has a pointer to
+ the schedule it is in.
+- Now using hash tables to speed up cSchedule::GetEvent() (partially based on
+ a patch from Georg Acher).
+- Avoiding unnecessary calls to getLength() in libsi/si.c, and avoiding the
+ '& 0xff' in CRC32::crc32() of libsi/util.c (thanks to Georg Acher).
+- Speeded up deleting duplicate channels.
+- Fixed listing recordings with empty episode names in the LSTR command (thanks
+ to Stefan Huelswitt for pointing this out).
+- Added cThread::SetPriority() and using it in cSectionHandler::Action() to
+ reduce the priority of the section handler threads (as suggested by Georg Acher).
diff --git a/MANUAL b/MANUAL
index ebf8ce0..8a65809 100644
--- a/MANUAL
+++ b/MANUAL
@@ -23,7 +23,7 @@ Version 1.2
Red - Record Edit Edit ABC/abc Play/Commands(2) Jump -
Green - Audio New New Ins/Ovr Rewind Skip -60s -
Yellow - Pause live Delete Delete Delete Delete Skip +60s -
- Blue - Stop/Resume Mark On/Off(1) - Summary Stop -
+ Blue - Stop/Resume Mark On/Off(1) - Info Stop -
0..9 Ch select - Sort(3) Day(4) Numeric inp. Exec cmd(2) Editing -
In a numerical input field (like the response to a CAM enquiry) the keys 0..9
diff --git a/Make.config.template b/Make.config.template
index b39b1f4..3c429e7 100644
--- a/Make.config.template
+++ b/Make.config.template
@@ -6,7 +6,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Make.config.template 1.3 2003/08/09 11:03:25 kls Exp $
+# $Id: Make.config.template 1.4 2005/05/14 10:32:33 kls Exp $
### The C compiler and options:
@@ -14,7 +14,7 @@ CC = gcc
CFLAGS = -O2
CXX = g++
-CXXFLAGS = -g -O2 -Wall -Woverloaded-virtual
+CXXFLAGS = -fPIC -g -O2 -Wall -Woverloaded-virtual
### The directory environment:
diff --git a/Makefile b/Makefile
index 59e7e78..7bc8a57 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.74 2005/02/13 10:13:45 kls Exp $
+# $Id: Makefile 1.75 2005/05/14 10:32:13 kls Exp $
.DELETE_ON_ERROR:
@@ -12,12 +12,14 @@ CC ?= gcc
CFLAGS ?= -O2
CXX ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
+CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual
DVBDIR = ../DVB
LSIDIR = ./libsi
MANDIR = /usr/local/man
BINDIR = /usr/local/bin
+LIBS = -ljpeg -lpthread -ldl
+INCLUDES =
PLUGINDIR= ./PLUGINS
PLUGINLIBDIR= $(PLUGINDIR)/lib
@@ -29,7 +31,7 @@ DOXYFILE = Doxyfile
-include Make.config
-INCLUDES = -I$(DVBDIR)/include
+INCLUDES += -I$(DVBDIR)/include
SILIB = $(LSIDIR)/libsi.a
@@ -106,7 +108,7 @@ $(DEPFILE): Makefile
# The main program:
vdr: $(OBJS) $(SILIB)
- $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(SILIB) -o vdr
+ $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
# The font files:
diff --git a/PLUGINS/src/skincurses/HISTORY b/PLUGINS/src/skincurses/HISTORY
index 8ba4ae4..33119f4 100644
--- a/PLUGINS/src/skincurses/HISTORY
+++ b/PLUGINS/src/skincurses/HISTORY
@@ -13,3 +13,7 @@ VDR Plugin 'skincurses' Revision History
- Made several functions threadsafe.
- New audio track display.
+
+2005-05-16: Version 0.0.4
+
+- New "recording info" display.
diff --git a/PLUGINS/src/skincurses/skincurses.c b/PLUGINS/src/skincurses/skincurses.c
index a1c5954..ad1a26b 100644
--- a/PLUGINS/src/skincurses/skincurses.c
+++ b/PLUGINS/src/skincurses/skincurses.c
@@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: skincurses.c 1.5 2005/01/09 11:56:26 kls Exp $
+ * $Id: skincurses.c 1.6 2005/05/16 10:45:12 kls Exp $
*/
#include <ncurses.h>
@@ -11,7 +11,7 @@
#include <vdr/plugin.h>
#include <vdr/skins.h>
-static const char *VERSION = "0.0.3";
+static const char *VERSION = "0.0.4";
static const char *DESCRIPTION = "A text only skin";
static const char *MAINMENUENTRY = NULL;
@@ -407,7 +407,30 @@ void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event)
void cSkinCursesDisplayMenu::SetRecording(const cRecording *Recording)
{
- SetText(Recording->Summary(), false); //TODO
+ if (!Recording)
+ return;
+ const cRecordingInfo *Info = Recording->Info();
+ int y = 2;
+ cTextScroller ts;
+ char t[32];
+ snprintf(t, sizeof(t), "%s %s", *DateString(Recording->start), *TimeString(Recording->start));
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
+ y += ts.Height();
+ y += 1;
+ const char *Title = Info->Title();
+ if (isempty(Title))
+ Title = Recording->Name();
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, Title, &Font, clrCyan, clrBackground);
+ y += ts.Height();
+ if (!isempty(Info->ShortText())) {
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, Info->ShortText(), &Font, clrYellow, clrBackground);
+ y += ts.Height();
+ }
+ y += 1;
+ if (!isempty(Info->Description())) {
+ textScroller.Set(osd, 0, y, OsdWidth - 2, OsdHeight - y - 2, Info->Description(), &Font, clrCyan, clrBackground);
+ SetScrollbar();
+ }
}
void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont)
diff --git a/channels.c b/channels.c
index e571aed..b2d741e 100644
--- a/channels.c
+++ b/channels.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.c 1.38 2005/05/07 13:14:32 kls Exp $
+ * $Id: channels.c 1.42 2005/05/29 10:32:38 kls Exp $
*/
#include "channels.h"
@@ -124,11 +124,6 @@ int MapToDriver(int Value, const tChannelParameterMap *Map)
const tChannelID tChannelID::InvalidID;
-bool tChannelID::operator== (const tChannelID &arg) const
-{
- return source == arg.source && nid == arg.nid && tid == arg.tid && sid == arg.sid && rid == arg.rid;
-}
-
tChannelID tChannelID::FromString(const char *s)
{
char *sourcebuf = NULL;
@@ -146,7 +141,7 @@ tChannelID tChannelID::FromString(const char *s)
return tChannelID::InvalidID;
}
-cString tChannelID::ToString(void)
+cString tChannelID::ToString(void) const
{
char buffer[256];
snprintf(buffer, sizeof(buffer), rid ? "%s-%d-%d-%d-%d" : "%s-%d-%d-%d", *cSource::ToString(source), nid, tid, sid, rid);
@@ -263,11 +258,6 @@ int cChannel::Transponder(void) const
return tf;
}
-tChannelID cChannel::GetChannelID(void) const
-{
- return tChannelID(source, nid, (nid || tid) ? tid : Transponder(), sid, rid);
-}
-
int cChannel::Modification(int Mask)
{
int Result = modification & Mask;
@@ -814,6 +804,22 @@ bool cChannel::Save(FILE *f)
return fprintf(f, "%s", *ToText()) > 0;
}
+// -- cChannelSorter ---------------------------------------------------------
+
+class cChannelSorter : public cListObject {
+public:
+ cChannel *channel;
+ tChannelID channelID;
+ cChannelSorter(cChannel *Channel) {
+ channel = Channel;
+ channelID = channel->GetChannelID();
+ }
+ virtual int Compare(const cListObject &ListObject) const {
+ cChannelSorter *cs = (cChannelSorter *)&ListObject;
+ return memcmp(&channelID, &cs->channelID, sizeof(channelID));
+ }
+ };
+
// -- cChannels --------------------------------------------------------------
cChannels Channels;
@@ -826,22 +832,21 @@ cChannels::cChannels(void)
void cChannels::DeleteDuplicateChannels(void)
{
+ cList<cChannelSorter> ChannelSorter;
for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep()) {
- tChannelID ChannelID = channel->GetChannelID();
- cChannel *other = Next(channel);
- while (other) {
- cChannel *d = NULL;
- if (!other->GroupSep() && other->GetChannelID() == ChannelID)
- d = other;
- other = Next(other);
- if (d) {
- dsyslog("deleting duplicate channel %s", *d->ToText());
- Del(d);
- }
- }
- }
+ if (!channel->GroupSep())
+ ChannelSorter.Add(new cChannelSorter(channel));
}
+ ChannelSorter.Sort();
+ cChannelSorter *cs = ChannelSorter.First();
+ while (cs) {
+ cChannelSorter *next = ChannelSorter.Next(cs);
+ if (next && cs->channelID == next->channelID) {
+ dsyslog("deleting duplicate channel %s", *next->channel->ToText());
+ Del(next->channel);
+ }
+ cs = next;
+ }
}
bool cChannels::Load(const char *FileName, bool AllowComments, bool MustExist)
diff --git a/channels.conf b/channels.conf
index 9f83d12..f62e0fe 100644
--- a/channels.conf
+++ b/channels.conf
@@ -26,14 +26,14 @@ NEUN LIVE Television,NEUN LIVE;BetaDigital:12480:vC34:S19.2E:27500:767:768=deu:3
DSF;BetaDigital:12480:vC34:S19.2E:27500:1023:1024=deu:0:0:900:133:33:0
HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0
Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
-EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
+EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,91=rus,93=eng,94=ita,95=esl,98=por,99=deu:0:0:8004:1:1070:0
rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0
Sky News;BSkyB:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
Veronica/JETIX;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,100:5020:53:1109:0
BVN;CANAL+:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
n-tv;RTL World:12187:hC34:S19.2E:27500:169:73=deu:80:0:12090:1:1089:0
Al Jazeera;CANALSATELLITE:11567:vC56:S19.2E:22000:55:56=ara:0:0:9021:1:1024:0
-TW1 - 28Feb05;ORF:12692:hC56:S19.2E:22000:166:167=deu:168:0:13013:1:1117:0
+TW1;ORF:12662:hC56:S19.2E:22000:1010:1011=deu:1013:0:13101:1:1115:0
Eurosport;ZDFvision:11953:hC34:S19.2E:27500:410:420=deu:430:0:28009:1:1079:0
EinsExtra;ARD:12109:hC34:S19.2E:27500:101:102=deu:0:0:28201:1:1073:0
EinsFestival;ARD:12109:hC34:S19.2E:27500:201:202=deu:0:0:28202:1:1073:0
@@ -45,10 +45,10 @@ rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
:Premiere World
PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0
PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1801,1702:10:133:2:0
-PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1722,1801,1702:11:133:2:0
+PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu;1795=deu:32:1722,1801,1702:11:133:2:0
PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0
-PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0
-PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1801,1722,1702:29:133:2:0
+PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu:32:1801,1722,1702:9:133:2:0
+PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1801,1722,1702:29:133:2:0
PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0
PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0
DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1722,1801,1702:34:133:17:0
@@ -58,7 +58,7 @@ PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2
BEATE-UHSE.TV,B-UHSE;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1702,1801,1722:21:133:1:0
DIREKT EROTIK,EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1801,1702:513:133:4:0
:Sportsworld
-Konferenz:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1801,1722:17:133:3:0
+F1-Portal:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1801,1722:17:133:3:0
PREMIERE SPORT 2,SPORT 2;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1722,1702,1801:27:133:4:0
:Beta Digital
N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0
@@ -72,14 +72,14 @@ FRANCE 5;CSAT:12207:vC34:S19.2E:27500:160:80=fra:32:500,100:8501:1:1090:0
LCP;CSAT:12207:vC34:S19.2E:27500:2047+8191:0:0:0:8506:1:1090:0
ESCALES;ABSAT:12285:vC34:S19.2E:27500:165:100:41:500,100:17025:1:1094:0
Best of Shopping;CSAT:12324:vC34:S19.2E:27500:160:80=fra:0:0:8612:1:1096:0
-ASTRA-Mosaic;ASTRA:12551:vC56:S19.2E:22000:175:176=fra:0:0:3988:1:1108:0
-ASTRA-Mosaic 2;ASTRA:12551:vC56:S19.2E:22000:179:120=fra:0:0:3987:1:1108:0
-ASTRA-Mosaic 3;ASTRA:12551:vC56:S19.2E:22000:182:169=fra:0:0:3986:1:1108:0
-ASTRA-Mosaic 4;ASTRA:12551:vC56:S19.2E:22000:185:170=fra:0:0:3985:1:1108:0
-ASTRA-Mosaic 5;ASTRA:12551:vC56:S19.2E:22000:163:164:0:0:3984:1:1108:0
+ASTRA-Mosaic;SES ASTRA:12551:vC56:S19.2E:22000:175:176=fra:0:0:3988:1:1108:0
+ASTRA-Mosaic 2;SES ASTRA:12551:vC56:S19.2E:22000:179:120=fra:0:0:3987:1:1108:0
+ASTRA-Mosaic 3;SES ASTRA:12551:vC56:S19.2E:22000:182:169=fra:0:0:3986:1:1108:0
+ASTRA-Mosaic 4;SES ASTRA:12551:vC56:S19.2E:22000:185:170=fra:0:0:3985:1:1108:0
+ASTRA-Mosaic 5;SES ASTRA:12551:vC56:S19.2E:22000:163:164:0:0:3984:1:1108:0
Chamber TV;Chambre des Députées:12551:vC56:S19.2E:22000:55:56=ltz:0:0:12180:1:1108:0
RTL TELE Letzebuerg:12551:vC56:S19.2E:22000:168:144=eng,146=fra,151=ltz:74:0:3994:1:1108:0
-Yorin;CANAL+:12574:hC56:S19.2E:22000:512+8190:84=dut:33:622,602,100:5010:53:1109:0
+Yorin;CANAL+:12574:hC56:S19.2E:22000:512+8190:84=dut:33:622,100:5010:53:1109:0
MTV2 Pop Channel;MTV Networks:12226:hC34:S19.2E:27500:513+8190:661=deu:577:0:28640:1:1091:0
MTV Central;MTV Networks:11739:vC34:S19.2E:27500:3031:3032:3034:0:28653:1:1066:0
Via 1 - Schöner Reisen:12148:h:S19.2E:27500:511:512:0:0:44:0:0:0
@@ -88,9 +88,9 @@ VIVA PLUS;VIVA Fernsehen GmbH & Co. KG:12551:vC56:S19.2E:22000:171:172=deu:173:0
QVC Deutschland;QVC:12551:vC56:S19.2E:22000:165:166:167:0:12100:1:1108:0
TELE 5;BetaDigital:12480:vC34:S19.2E:27500:1535:1536=deu:38:0:51:133:33:0
:@201 Sky
-Sky One;BSkyB:12226:hC23:S28.2E:27500:2305+2304:2306=eng:2307:960,961:4705:2:2027:0
-Sky Mix;BSkyB:12226:hC23:S28.2E:27500:2311+2304:2312=eng,2313=NAR:2314:960,961:5104:2:2027:0
-ITV2;BSkyB:10906:vC56:S28.2E:22000:2350:2351=eng:2353:960,961:10240:2:2054:0
+Sky One;BSkyB:12226:hC23:S28.2E:27500:515+8190:643=eng:579:960,961:4705:2:2027:0
+Sky Mix;BSkyB:12226:hC23:S28.2E:27500:514+8190:642=eng,662=NAR:578:960,961:5104:2:2027:0
+ITV2;BSkyB:10906:vC56:S28.2E:22000:2350:2351=eng,2374=UND:2353:960,961:10240:2:2054:0
Sci-Fi;BSkyB:12148:hC23:S28.2E:27500:512+8190:640=eng:576:960,961:4905:2:2023:0
Paramount;BSkyB:12187:hC23:S28.2E:27500:2313+2304:2317=eng,2318=NAR:2315:960,961:5904:2:2025:0
Discovery;BSkyB:11875:hC23:S28.2E:27500:2304:2306=eng,2307=NAR:2305:960,961:6201:2:2009:0
@@ -113,7 +113,7 @@ Animal Plnt+;BSkyB:12070:hC23:S28.2E:27500:2314+2307:2315=eng:0:960,961:50002:2:
S1T;BSkyB:12285:vC23:S28.2E:27500:513+8190:641=eng,661=NAR:577:960,961:4409:2:2030:0
CNN;BSkyB:12051:vC23:S28.2E:27500:2313:2315=eng:2314:0:7140:2:2018:0
BBC PARL'MNT:12129:vC23:S28.2E:27500:2304:2306=eng,2307=eng:2305:0:7300:2:2022:0
-BTL TV;T-Systems/MTI:11200:vC56:S13.0E:27500:413:414=ita:0:0:4733:318:13400:0
+Bethel TV;T-Systems/MTI:11200:vC56:S13.0E:27500:413:414=ita:0:0:4733:318:13400:0
Euro1080;EURO1080:12168:vC34:S19.2E:27500:308:256:0:FF:21100:1:1088:0
Astra HD:12441:vC34:S19.2E:27500:133+80:134=eng:0:FF:29700:0:0:0
eng-WRN-multi;WRN:12597:vC34:S13.0E:27500:0:2132:0:0:8230:318:9400:0
diff --git a/channels.h b/channels.h
index 86fffe0..3cb7e8f 100644
--- a/channels.h
+++ b/channels.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.h 1.28 2005/05/07 13:07:09 kls Exp $
+ * $Id: channels.h 1.32 2005/05/28 13:57:08 kls Exp $
*/
#ifndef __CHANNELS_H
@@ -65,12 +65,12 @@ private:
public:
tChannelID(void) { source = nid = tid = sid = rid = 0; }
tChannelID(int Source, int Nid, int Tid, int Sid, int Rid = 0) { source = Source; nid = Nid; tid = Tid; sid = Sid; rid = Rid; }
- bool operator== (const tChannelID &arg) const;
- bool Valid(void) { return (nid || tid) && sid; } // rid is optional and source may be 0//XXX source may not be 0???
+ bool operator== (const tChannelID &arg) const { return source == arg.source && nid == arg.nid && tid == arg.tid && sid == arg.sid && rid == arg.rid; }
+ bool Valid(void) const { return (nid || tid) && sid; } // rid is optional and source may be 0//XXX source may not be 0???
tChannelID &ClrRid(void) { rid = 0; return *this; }
tChannelID &ClrPolarization(void);
static tChannelID FromString(const char *s);
- cString ToString(void);
+ cString ToString(void) const;
static const tChannelID InvalidID;
};
@@ -176,10 +176,10 @@ public:
int Transmission(void) const { return transmission; }
int Guard(void) const { return guard; }
int Hierarchy(void) const { return hierarchy; }
- bool IsCable(void) const { return (source & cSource::st_Mask) == cSource::stCable; }
- bool IsSat(void) const { return (source & cSource::st_Mask) == cSource::stSat; }
- bool IsTerr(void) const { return (source & cSource::st_Mask) == cSource::stTerr; }
- tChannelID GetChannelID(void) const;
+ bool IsCable(void) const { return cSource::IsCable(source); }
+ bool IsSat(void) const { return cSource::IsSat(source); }
+ bool IsTerr(void) const { return cSource::IsTerr(source); }
+ tChannelID GetChannelID(void) const { return tChannelID(source, nid, (nid || tid) ? tid : Transponder(), sid, rid); }
int Modification(int Mask = CHANNELMOD_ALL);
bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
diff --git a/config.h b/config.h
index d44e865..ebe2123 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.217 2005/05/05 11:04:18 kls Exp $
+ * $Id: config.h 1.218 2005/05/14 09:18:08 kls Exp $
*/
#ifndef __CONFIG_H
@@ -20,8 +20,8 @@
#include "i18n.h"
#include "tools.h"
-#define VDRVERSION "1.3.24"
-#define VDRVERSNUM 10324 // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION "1.3.25"
+#define VDRVERSNUM 10325 // Version * 10000 + Major * 100 + Minor
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/cutter.c b/cutter.c
index c8ed60e..82c7fe5 100644
--- a/cutter.c
+++ b/cutter.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: cutter.c 1.7 2004/06/13 16:04:08 kls Exp $
+ * $Id: cutter.c 1.8 2005/05/15 14:21:08 kls Exp $
*/
#include "cutter.h"
@@ -204,7 +204,7 @@ bool cCutter::Start(const char *FileName)
free(s);
// XXX
editedVersionName = strdup(evn);
- Recording.WriteSummary();
+ Recording.WriteInfo();
Recordings.AddByName(editedVersionName);
cuttingThread = new cCuttingThread(FileName, editedVersionName);
return true;
diff --git a/dvbdevice.c b/dvbdevice.c
index 9c8a0ac..3a3b19b 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 1.127 2005/03/20 10:10:38 kls Exp $
+ * $Id: dvbdevice.c 1.129 2005/05/16 15:23:43 kls Exp $
*/
#include "dvbdevice.h"
@@ -741,7 +741,7 @@ bool cDvbDevice::ProvidesSource(int Source) const
bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
{
- return ProvidesSource(Channel->Source()) && ((Channel->Source() & cSource::st_Mask) != cSource::stSat || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()));
+ return ProvidesSource(Channel->Source()) && (!cSource::IsSat(Channel->Source()) || !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()));
}
bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
diff --git a/dvbosd.c b/dvbosd.c
index 360825f..458ec9c 100644
--- a/dvbosd.c
+++ b/dvbosd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbosd.c 1.26 2005/02/12 15:36:31 kls Exp $
+ * $Id: dvbosd.c 1.27 2005/05/22 10:57:45 kls Exp $
*/
#include "dvbosd.h"
@@ -151,10 +151,6 @@ void cDvbOsd::Flush(void)
for (int i = 0; i < NumColors; i++) {
// convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way):
colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16);
-#if __BYTE_ORDER == __BIG_ENDIAN
- // actually the driver itself should access the bytes according to the current endianness!
- colors[i] = ((colors[i] & 0xFF) << 24) | ((colors[i] & 0xFF00) << 8) | ((colors[i] & 0xFF0000) >> 8) | ((colors[i] & 0xFF000000) >> 24);
-#endif
}
Colors = colors;
//TODO end of stuff that should be fixed in the driver
diff --git a/dvbplayer.c b/dvbplayer.c
index 477a6c0..2d4e1e4 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.c 1.33 2005/05/08 14:52:49 kls Exp $
+ * $Id: dvbplayer.c 1.34 2005/05/22 11:26:51 kls Exp $
*/
#include "dvbplayer.h"
@@ -355,7 +355,7 @@ void cDvbPlayer::Activate(bool On)
}
else if (active) {
running = false;
- Cancel(3);
+ Cancel(9);
active = false;
}
}
diff --git a/eit.c b/eit.c
index 6c6381b..a8ac9df 100644
--- a/eit.c
+++ b/eit.c
@@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
- * $Id: eit.c 1.103 2005/03/20 12:33:51 kls Exp $
+ * $Id: eit.c 1.107 2005/05/28 11:35:55 kls Exp $
*/
#include "eit.h"
@@ -48,12 +48,16 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
SI::EIT::Event SiEitEvent;
for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) {
+ // Drop bogus events.
+ if (SiEitEvent.getStartTime() == 0 || SiEitEvent.getDuration() == 0)
+ continue;
Empty = false;
+ cEvent *newEvent = NULL;
cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), SiEitEvent.getStartTime());
if (!pEvent) {
// If we don't have that event yet, we create a new one.
// Otherwise we copy the information into the existing event anyway, because the data might have changed.
- pEvent = pSchedule->AddEvent(new cEvent(channelID, SiEitEvent.getEventId()));
+ pEvent = newEvent = new cEvent(SiEitEvent.getEventId());
if (!pEvent)
continue;
}
@@ -91,8 +95,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
cLinkChannels *LinkChannels = NULL;
- int NumComponents = 0;
- SI::ComponentDescriptor *ComponentDescriptors[MAXCOMPONENTS];
+ cComponents *Components = NULL;
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
switch (d->getDescriptorTag()) {
case SI::ExtendedEventDescriptorTag: {
@@ -193,12 +196,10 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
uchar Stream = cd->getStreamContent();
uchar Type = cd->getComponentType();
if (1 <= Stream && Stream <= 2 && Type != 0) {
- if (NumComponents < MAXCOMPONENTS) {
- ComponentDescriptors[NumComponents++] = cd;
- d = NULL; // so that it is not deleted
- }
- else
- dsyslog("more than %d component descriptors!", MAXCOMPONENTS);
+ if (!Components)
+ Components = new cComponents;
+ char buffer[256];
+ Components->SetComponent(Components->NumComponents(), cd->getStreamContent(), cd->getComponentType(), I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer)));
}
}
break;
@@ -221,18 +222,10 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
delete ExtendedEventDescriptors;
delete ShortEventDescriptor;
- if (NumComponents > 0) {
- cComponents *Components = new cComponents(NumComponents);
- for (int i = 0; i < NumComponents; i++) {
- char buffer[256];
- SI::ComponentDescriptor *cd = ComponentDescriptors[i];
- Components->SetComponent(i, cd->getStreamContent(), cd->getComponentType(), I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer)));
- delete cd;
- }
- pEvent->SetComponents(Components);
- }
- else
- pEvent->SetComponents(NULL);
+ if (newEvent)
+ pSchedule->AddEvent(newEvent);
+
+ pEvent->SetComponents(Components);
pEvent->FixEpgBugs();
if (LinkChannels)
diff --git a/epg.c b/epg.c
index 21bdeb5..509b702 100644
--- a/epg.c
+++ b/epg.c
@@ -7,7 +7,7 @@
* 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.c 1.29 2005/05/05 13:53:19 kls Exp $
+ * $Id: epg.c 1.34 2005/05/29 10:19:48 kls Exp $
*/
#include "epg.h"
@@ -40,11 +40,10 @@ bool tComponent::FromString(const char *s)
// --- cComponents -----------------------------------------------------------
-cComponents::cComponents(int NumComponents)
+cComponents::cComponents(void)
{
- numComponents = NumComponents;
- components = MALLOC(tComponent, numComponents);
- memset(components, 0, sizeof(tComponent) * numComponents);
+ numComponents = 0;
+ components = NULL;
}
cComponents::~cComponents(void)
@@ -54,31 +53,37 @@ cComponents::~cComponents(void)
free(components);
}
-bool cComponents::SetComponent(int Index, const char *s)
+void cComponents::Realloc(int Index)
{
- if (Index < numComponents)
- return components[Index].FromString(s);
- return false;
+ if (Index >= numComponents) {
+ int n = numComponents;
+ numComponents = Index + 1;
+ components = (tComponent *)realloc(components, numComponents * sizeof(tComponent));
+ memset(&components[n], 0, sizeof(tComponent) * (numComponents - n));
+ }
}
-bool cComponents::SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description)
+void cComponents::SetComponent(int Index, const char *s)
{
- if (Index < numComponents) {
- tComponent *p = &components[Index];
- p->stream = Stream;
- p->type = Type;
- strn0cpy(p->language, Language, sizeof(p->language));
- p->description = strcpyrealloc(p->description, !isempty(Description) ? Description : NULL);
- return true;
- }
- return false;
+ Realloc(Index);
+ components[Index].FromString(s);
+}
+
+void cComponents::SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description)
+{
+ Realloc(Index);
+ tComponent *p = &components[Index];
+ p->stream = Stream;
+ p->type = Type;
+ strn0cpy(p->language, Language, sizeof(p->language));
+ p->description = strcpyrealloc(p->description, !isempty(Description) ? Description : NULL);
}
// --- cEvent ----------------------------------------------------------------
-cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
+cEvent::cEvent(u_int16_t EventID)
{
- channelID = ChannelID;
+ schedule = NULL;
eventID = EventID;
tableID = 0;
version = 0xFF; // actual version numbers are 0..31
@@ -107,9 +112,20 @@ int cEvent::Compare(const cListObject &ListObject) const
return startTime - e->startTime;
}
+tChannelID cEvent::ChannelID(void) const
+{
+ return schedule ? schedule->ChannelID() : tChannelID();
+}
+
void cEvent::SetEventID(u_int16_t EventID)
{
- eventID = EventID;
+ if (eventID != EventID) {
+ if (schedule)
+ schedule->UnhashEvent(this);
+ eventID = EventID;
+ if (schedule)
+ schedule->HashEvent(this);
+ }
}
void cEvent::SetTableID(uchar TableID)
@@ -153,7 +169,13 @@ void cEvent::SetComponents(cComponents *Components)
void cEvent::SetStartTime(time_t StartTime)
{
- startTime = StartTime;
+ if (startTime != StartTime) {
+ if (schedule)
+ schedule->UnhashEvent(this);
+ startTime = StartTime;
+ if (schedule)
+ schedule->HashEvent(this);
+ }
}
void cEvent::SetDuration(int Duration)
@@ -187,30 +209,17 @@ bool cEvent::IsRunning(bool OrAboutToStart) const
cString cEvent::GetDateString(void) const
{
- char buf[32];
- struct tm tm_r;
- tm *tm = localtime_r(&startTime, &tm_r);
- char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
- *p++ = ' ';
- strftime(p, sizeof(buf) - (p - buf), "%d.%m.%Y", tm);
- return buf;
+ return DateString(startTime);
}
cString cEvent::GetTimeString(void) const
{
- char buf[25];
- struct tm tm_r;
- strftime(buf, sizeof(buf), "%R", localtime_r(&startTime, &tm_r));
- return buf;
+ return TimeString(startTime);
}
cString cEvent::GetEndTimeString(void) const
{
- char buf[25];
- time_t EndTime = startTime + duration;
- struct tm tm_r;
- strftime(buf, sizeof(buf), "%R", localtime_r(&EndTime, &tm_r));
- return buf;
+ return TimeString(startTime + duration);
}
cString cEvent::GetVpsString(void) const
@@ -221,10 +230,11 @@ cString cEvent::GetVpsString(void) const
return buf;
}
-void cEvent::Dump(FILE *f, const char *Prefix) const
+void cEvent::Dump(FILE *f, const char *Prefix, bool InfoOnly) const
{
- if (startTime + duration + Setup.EPGLinger * 60 >= time(NULL)) {
- fprintf(f, "%sE %u %ld %d %X\n", Prefix, eventID, startTime, duration, tableID);
+ if (InfoOnly || startTime + duration + Setup.EPGLinger * 60 >= time(NULL)) {
+ if (!InfoOnly)
+ fprintf(f, "%sE %u %ld %d %X\n", Prefix, eventID, startTime, duration, tableID);
if (!isempty(title))
fprintf(f, "%sT %s\n", Prefix, title);
if (!isempty(shortText))
@@ -240,18 +250,40 @@ void cEvent::Dump(FILE *f, const char *Prefix) const
fprintf(f, "%sX %s\n", Prefix, *p->ToString());
}
}
- if (vps)
+ if (!InfoOnly && vps)
fprintf(f, "%sV %ld\n", Prefix, vps);
- fprintf(f, "%se\n", Prefix);
+ if (!InfoOnly)
+ fprintf(f, "%se\n", Prefix);
}
}
+bool cEvent::Parse(char *s)
+{
+ char *t = skipspace(s + 1);
+ switch (*s) {
+ case 'T': SetTitle(t);
+ break;
+ case 'S': SetShortText(t);
+ break;
+ case 'D': strreplace(t, '|', '\n');
+ SetDescription(t);
+ break;
+ case 'X': if (!components)
+ components = new cComponents;
+ components->SetComponent(components->NumComponents(), t);
+ break;
+ case 'V': SetVps(atoi(t));
+ break;
+ default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s);
+ return false;
+ }
+ return true;
+}
+
bool cEvent::Read(FILE *f, cSchedule *Schedule)
{
if (Schedule) {
cEvent *Event = NULL;
- int NumComponents = 0;
- char *ComponentStrings[MAXCOMPONENTS];
char *s;
cReadLine ReadLine;
while ((s = ReadLine.Read(f)) != NULL) {
@@ -265,53 +297,25 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
int n = sscanf(t, "%u %ld %d %X", &EventID, &StartTime, &Duration, &TableID);
if (n == 3 || n == 4) {
Event = (cEvent *)Schedule->GetEvent(EventID, StartTime);
+ cEvent *newEvent = NULL;
if (!Event)
- Event = Schedule->AddEvent(new cEvent(Schedule->ChannelID(), EventID));
+ Event = newEvent = new cEvent(EventID);
if (Event) {
Event->SetTableID(TableID);
Event->SetStartTime(StartTime);
Event->SetDuration(Duration);
+ if (newEvent)
+ Schedule->AddEvent(newEvent);
}
}
- NumComponents = 0;
- }
- break;
- case 'T': if (Event)
- Event->SetTitle(t);
- break;
- case 'S': if (Event)
- Event->SetShortText(t);
- break;
- case 'D': if (Event) {
- strreplace(t, '|', '\n');
- Event->SetDescription(t);
- }
- break;
- case 'X': if (Event) {
- if (NumComponents < MAXCOMPONENTS)
- ComponentStrings[NumComponents++] = strdup(t);
- else
- dsyslog("more than %d component descriptors!", MAXCOMPONENTS);
}
break;
- case 'V': if (Event)
- Event->SetVps(atoi(t));
- break;
- case 'e': if (Event && NumComponents > 0) {
- cComponents *Components = new cComponents(NumComponents);
- for (int i = 0; i < NumComponents; i++) {
- if (!Components->SetComponent(i, ComponentStrings[i]))
- esyslog("ERROR: faulty component string in EPG data: '%s'", ComponentStrings[i]);
- free(ComponentStrings[i]);
- }
- Event->SetComponents(Components);
- }
- Event = NULL;
+ case 'e': Event = NULL;
break;
case 'c': // to keep things simple we react on 'c' here
return true;
- default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s);
- return false;
+ default: if (Event && !Event->Parse(s))
+ return false;
}
}
esyslog("ERROR: unexpected end of file while reading EPG data");
@@ -649,9 +653,34 @@ cSchedule::cSchedule(tChannelID ChannelID)
cEvent *cSchedule::AddEvent(cEvent *Event)
{
events.Add(Event);
+ Event->schedule = this;
+ HashEvent(Event);
return Event;
}
+void cSchedule::DelEvent(cEvent *Event)
+{
+ if (Event->schedule == this) {
+ UnhashEvent(Event);
+ events.Del(Event);
+ Event->schedule = NULL;
+ }
+}
+
+void cSchedule::HashEvent(cEvent *Event)
+{
+ eventsHashID.Add(Event, Event->EventID());
+ if (Event->StartTime() > 0) // 'StartTime < 0' is apparently used with NVOD channels
+ eventsHashStartTime.Add(Event, Event->StartTime());
+}
+
+void cSchedule::UnhashEvent(cEvent *Event)
+{
+ eventsHashID.Del(Event, Event->EventID());
+ if (Event->StartTime() > 0) // 'StartTime < 0' is apparently used with NVOD channels
+ eventsHashStartTime.Del(Event, Event->StartTime());
+}
+
const cEvent *cSchedule::GetPresentEvent(bool CheckRunningStatus) const
{
const cEvent *pe = NULL;
@@ -680,13 +709,9 @@ const cEvent *cSchedule::GetEvent(u_int16_t EventID, time_t StartTime) const
{
// Returns either the event info with the given EventID or, if that one can't
// be found, the one with the given StartTime (or NULL if neither can be found)
- cEvent *pt = NULL;
- for (cEvent *pe = events.First(); pe; pe = events.Next(pe)) {
- if (pe->EventID() == EventID)
- return pe;
- if (StartTime > 0 && pe->StartTime() == StartTime) // 'StartTime < 0' is apparently used with NVOD channels
- pt = pe;
- }
+ cEvent *pt = eventsHashID.Get(EventID);
+ if (!pt && StartTime > 0) // 'StartTime < 0' is apparently used with NVOD channels
+ pt = eventsHashStartTime.Get(StartTime);
return pt;
}
@@ -753,7 +778,7 @@ void cSchedule::Cleanup(time_t Time)
if (!Event)
break;
if (!Event->HasTimer() && Event->EndTime() + Setup.EPGLinger * 60 + 3600 < Time) { // adding one hour for safety
- events.Del(Event);
+ DelEvent(Event);
a--;
}
}
diff --git a/epg.h b/epg.h
index 6668a61..83ae0d2 100644
--- a/epg.h
+++ b/epg.h
@@ -7,7 +7,7 @@
* 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 1.21 2005/03/20 12:32:36 kls Exp $
+ * $Id: epg.h 1.25 2005/05/28 11:32:36 kls Exp $
*/
#ifndef __EPG_H
@@ -18,7 +18,6 @@
#include "tools.h"
#define MAXEPGBUGFIXLEVEL 3
-#define MAXCOMPONENTS 32
enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
@@ -35,20 +34,22 @@ class cComponents {
private:
int numComponents;
tComponent *components;
+ void Realloc(int Index);
public:
- cComponents(int NumComponents);
+ cComponents(void);
~cComponents(void);
int NumComponents(void) const { return numComponents; }
- bool SetComponent(int Index, const char *s);
- bool SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description);
+ 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; }
};
class cSchedule;
class cEvent : public cListObject {
+ friend class cSchedule;
private:
- tChannelID channelID; // Channel ID of program for this event
+ cSchedule *schedule; // The Schedule this event belongs to
u_int16_t eventID; // Event ID of this event
uchar tableID; // Table ID this event came from
uchar version; // Version number of section this event came from
@@ -56,16 +57,16 @@ private:
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 (separated by '\n')
+ cComponents *components; // The stream components 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(tChannelID ChannelID, u_int16_t EventID);
+ cEvent(u_int16_t EventID);
~cEvent();
virtual int Compare(const cListObject &ListObject) const;
- tChannelID ChannelID(void) const { return channelID; }
+ tChannelID ChannelID(void) const;
u_int16_t EventID(void) const { return eventID; }
uchar TableID(void) const { return tableID; }
uchar Version(void) const { return version; }
@@ -98,7 +99,8 @@ public:
void SetDuration(int Duration);
void SetVps(time_t Vps);
void SetSeen(void);
- void Dump(FILE *f, const char *Prefix = "") 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);
};
@@ -109,6 +111,8 @@ class cSchedule : public cListObject {
private:
tChannelID channelID;
cList<cEvent> events;
+ cHash<cEvent> eventsHashID;
+ cHash<cEvent> eventsHashStartTime;
bool hasRunning;
time_t modified;
time_t presentSeen;
@@ -127,6 +131,9 @@ public:
void Cleanup(time_t Time);
void Cleanup(void);
cEvent *AddEvent(cEvent *Event);
+ void DelEvent(cEvent *Event);
+ void cSchedule::HashEvent(cEvent *Event);
+ void cSchedule::UnhashEvent(cEvent *Event);
const cList<cEvent> *Events(void) const { return &events; }
const cEvent *GetPresentEvent(bool CheckRunningStatus = false) const;
const cEvent *GetFollowingEvent(bool CheckRunningStatus = false) const;
diff --git a/i18n.c b/i18n.c
index 1d755f1..e1a187d 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.188 2005/05/05 13:12:54 kls Exp $
+ * $Id: i18n.c 1.191 2005/05/15 14:37:59 kls Exp $
*
* Translations provided by:
*
@@ -399,6 +399,27 @@ const tI18nPhrase Phrases[] = {
"Kokkuvõte",
"Omtale",
},
+ { "Info",
+ "Info",
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ },
{ "Schedule - %s",
"Programm - %s",
"Program - %s",
@@ -3112,7 +3133,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"ÈØàÞÚÞíÚàÐÝÝÞÕ Ø×ÞÑàÐÖÕÝØÕ",
"",//TODO
- "",//TODO
+ "Video kuvamise formaat",
"Video display format",
},
{ "pan&scan",
@@ -3343,7 +3364,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"¿àÕÔßÞçØâÐÕÜëÕ ï×ëÚØ (×ÒãÚ)",
"",//TODO
- "",//TODO
+ "Audio keeled",
"Audio sprog (ant.)",
},
{ "Setup.DVB$Audio language", // note the singular
@@ -3364,7 +3385,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"²ëÑàÐÝ",
"",//TODO
- "",//TODO
+ "Audio keel",
"Audio sprog",
},
{ "Setup.LNB$SLOF (MHz)",
@@ -4039,7 +4060,7 @@ const tI18nPhrase Phrases[] = {
"Fase 1: Detectant el tipus de receptor",
"ÈÐÓ 1: ¾ßàÕÔÕÛÕÝØÕ âØßÐ ÚÞÔÐ ßãÛìâÐ",
"Faza 1: detektiranje kôda daljinskog upravljaèa.",
- "Aste 1: Koodeerimissüsteemi tuvastamine",
+ "Aste 1: Kodeerimissüsteemi tuvastamine",
"Fase 1: Detekterer fjernbetjenings-kodetype",
},
{ "Press any key on the RC unit",
@@ -4081,7 +4102,7 @@ const tI18nPhrase Phrases[] = {
"Codi detectat!",
"¾ÑÝÐàãÖÕÝ ÚÞÔ ßãÛìâÐ!",
"Kôd daljinskog upravljaèa je prepoznat!",
- "Koodeerimissüsteem tuvastatud!",
+ "Kodeerimissüsteem tuvastatud!",
"Fjernbetjenings-kodetype fundet!",
},
{ "Do not press any key...",
@@ -5049,7 +5070,7 @@ const tI18nPhrase Phrases[] = {
" Aturar la reproducció",
" ¿àÕÚàÐâØâì ÒÞáßàÞØ×ÒÕÔÕÝØÕ",
" Prekini reprodukciju",
- " Lõpeta kordus",
+ " Lõpeta taasesitamine",
" Stop afspilning",
},
{ " Stop recording ", // note the leading and trailing blanks!
@@ -5259,8 +5280,8 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
- "",// TODO
+ "EPG skaneerimine käivitatud",
+ "Starter EPG skanning",
},
{ "This plugin has no setup parameters!",
"Dieses Plugin hat keine Setup-Parameter!",
diff --git a/libsi/Makefile b/libsi/Makefile
index fdc630d..1554217 100644
--- a/libsi/Makefile
+++ b/libsi/Makefile
@@ -1,12 +1,12 @@
#
# Makefile for a libsi
#
-# $Id: Makefile 1.4 2005/05/05 11:01:46 kls Exp $
+# $Id: Makefile 1.5 2005/05/29 11:47:12 kls Exp $
### The C++ compiler and options:
CXX ?= g++
-CXXFLAGS ?= -O2 -g -Wall -Woverloaded-virtual
+CXXFLAGS ?= -fPIC -O2 -g -Wall -Woverloaded-virtual
AR = ar
ARFLAGS = ru
RANLIB = ranlib
diff --git a/libsi/si.c b/libsi/si.c
index ba97c6e..90d4030 100644
--- a/libsi/si.c
+++ b/libsi/si.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: si.c 1.13 2004/10/16 15:12:57 kls Exp $
+ * $Id: si.c 1.14 2005/05/28 14:11:16 kls Exp $
* *
***************************************************************************/
@@ -114,9 +114,10 @@ Descriptor *DescriptorLoop::getNext(Iterator &it) {
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor) {
Descriptor *d=0;
- if (isValid() && it.i<getLength()) {
+ int len;
+ if (isValid() && it.i<(len=getLength())) {
const unsigned char *p=data.getData(it.i);
- const unsigned char *end=p+getLength()-it.i;
+ const unsigned char *end=p+len-it.i;
while (p < end) {
if (Descriptor::getDescriptorTag(p) == tag) {
d=createDescriptor(it.i, returnUnimplemetedDescriptor);
@@ -132,9 +133,10 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool return
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) {
Descriptor *d=0;
- if (isValid() && it.i<getLength()) {
+ int len;
+ if (isValid() && it.i<(len=getLength())) {
const unsigned char *p=data.getData(it.i);
- const unsigned char *end=p+getLength()-it.i;
+ const unsigned char *end=p+len-it.i;
while (p < end) {
for (int u=0; u<arrayLength;u++)
if (Descriptor::getDescriptorTag(p) == tags[u]) {
@@ -211,15 +213,17 @@ bool DescriptorGroup::isComplete() {
}
char *String::getText() {
- if (getLength() < 0 || getLength() >4095)
+ int len=getLength();
+ if (len < 0 || len > 4095)
return strdup("text error"); // caller will delete it!
- char *data=new char(getLength()+1);
- decodeText(data, getLength()+1);
+ char *data=new char(len+1);
+ decodeText(data, len+1);
return data;
}
char *String::getText(char *buffer, int size) {
- if (getLength() < 0 || getLength() >= size) {
+ int len=getLength();
+ if (len < 0 || len >= size) {
strncpy(buffer, "text error", size);
buffer[size-1] = 0;
return buffer;
@@ -230,7 +234,8 @@ char *String::getText(char *buffer, int size) {
//taken from VDR, Copyright Klaus Schmidinger <kls@cadsoft.de>
char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
- if (getLength() < 0 || getLength() >= sizeBuffer) {
+ int len=getLength();
+ if (len < 0 || len >= sizeBuffer) {
strncpy(buffer, "text error", sizeBuffer);
buffer[sizeBuffer-1] = 0;
*shortVersion = 0;
@@ -254,7 +259,8 @@ void String::decodeText(char *buffer, int size) {
if (*from == 0x10)
from += 3; // skips code table info
- for (int i = 0; i < getLength(); i++) {
+ int len=getLength();
+ for (int i = 0; i < len; i++) {
if (*from == 0)
break;
if ( ((' ' <= *from) && (*from <= '~'))
@@ -281,9 +287,8 @@ void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int si
if (*from == 0x10)
from += 3; // skips code table info
- for (int i = 0; i < getLength(); i++) {
- if (*from == 0)
- break;
+ int len=getLength();
+ for (int i = 0; i < len; i++) {
if ( ((' ' <= *from) && (*from <= '~'))
|| (*from == '\n')
|| (0xA0 <= *from)
@@ -299,6 +304,8 @@ void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int si
IsShortName++;
else if (*from == 0x87)
IsShortName--;
+ else if (*from == 0)
+ break;
from++;
if (to - buffer >= sizeBuffer - 1 || toShort - shortVersion >= sizeShortVersion - 1)
break;
diff --git a/libsi/util.c b/libsi/util.c
index c6ad234..3465794 100644
--- a/libsi/util.c
+++ b/libsi/util.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: util.c 1.4 2004/10/16 09:58:41 kls Exp $
+ * $Id: util.c 1.5 2005/05/28 14:15:29 kls Exp $
* *
***************************************************************************/
@@ -263,9 +263,10 @@ u_int32_t CRC32::crc_table[256] = {
u_int32_t CRC32::crc32 (const char *d, int len, u_int32_t crc)
{
register int i;
+ const unsigned char *u=(unsigned char*)d; // Saves '& 0xff'
for (i=0; i<len; i++)
- crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *d++) & 0xff];
+ crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];
return crc;
}
diff --git a/menu.c b/menu.c
index 30183df..e36cc65 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.348 2005/03/20 15:14:51 kls Exp $
+ * $Id: menu.c 1.349 2005/05/16 13:59:03 kls Exp $
*/
#include "menu.h"
@@ -872,7 +872,6 @@ eOSState cMenuTimers::Summary(void)
cTimer *ti = CurrentTimer();
if (ti && !isempty(ti->Summary()))
return AddSubMenu(new cMenuText(tr("Summary"), ti->Summary()));
- //XXX cSkin::SetRecording()???
return Edit(); // convenience for people not using the Summary feature ;-)
}
@@ -1297,8 +1296,12 @@ eOSState cMenuCommands::ProcessKey(eKeys Key)
if (state == osUnknown) {
switch (Key) {
- case kOk: return Execute();
- default: break;
+ case kRed:
+ case kGreen:
+ case kYellow:
+ case kBlue: return osContinue;
+ case kOk: return Execute();
+ default: break;
}
}
return state;
@@ -1430,6 +1433,63 @@ cOsdObject *CamControl(void)
return NULL;
}
+// --- cMenuRecording --------------------------------------------------------
+
+class cMenuRecording : public cOsdMenu {
+private:
+ const cRecording *recording;
+public:
+ cMenuRecording(const cRecording *Recording);
+ virtual void Display(void);
+ virtual eOSState ProcessKey(eKeys Key);
+};
+
+cMenuRecording::cMenuRecording(const cRecording *Recording)
+:cOsdMenu(tr("Recording"))
+{
+ recording = Recording;
+ if (recording)
+ SetHelp(tr("Play"), tr("Rewind"));
+}
+
+void cMenuRecording::Display(void)
+{
+ cOsdMenu::Display();
+ DisplayMenu()->SetRecording(recording);
+ cStatus::MsgOsdTextItem(recording->Info()->Description());
+}
+
+eOSState cMenuRecording::ProcessKey(eKeys Key)
+{
+ switch (Key) {
+ case kUp|k_Repeat:
+ case kUp:
+ case kDown|k_Repeat:
+ case kDown:
+ case kLeft|k_Repeat:
+ case kLeft:
+ case kRight|k_Repeat:
+ case kRight:
+ DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
+ cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp);
+ return osContinue;
+ default: break;
+ }
+
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kRed: Key = kOk; // will play the recording, even if recording commands are defined
+ case kGreen: cRemote::Put(Key, true);
+ // continue with osBack to close the info menu and process the key
+ case kOk: return osBack;
+ default: break;
+ }
+ }
+ return state;
+}
+
// --- cMenuRecordingItem ----------------------------------------------------
class cMenuRecordingItem : public cOsdItem {
@@ -1530,7 +1590,7 @@ void cMenuRecordings::SetHelpKeys(void)
else {
NewHelpKeys = 2;
cRecording *recording = GetRecording(ri);
- if (recording && recording->Summary())
+ if (recording && recording->Info()->Title())
NewHelpKeys = 3;
}
}
@@ -1539,7 +1599,7 @@ void cMenuRecordings::SetHelpKeys(void)
case 0: SetHelp(NULL); break;
case 1: SetHelp(tr("Open")); break;
case 2:
- case 3: SetHelp(RecordingCommands.Count() ? tr("Commands") : tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL);
+ case 3: SetHelp(RecordingCommands.Count() ? tr("Commands") : tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Info") : NULL);
}
helpKeys = NewHelpKeys;
}
@@ -1644,15 +1704,15 @@ eOSState cMenuRecordings::Delete(void)
return osContinue;
}
-eOSState cMenuRecordings::Summary(void)
+eOSState cMenuRecordings::Info(void)
{
if (HasSubMenu() || Count() == 0)
return osContinue;
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
if (ri && !ri->IsDirectory()) {
cRecording *recording = GetRecording(ri);
- if (recording && recording->Summary() && *recording->Summary())
- return AddSubMenu(new cMenuText(tr("Summary"), recording->Summary()));
+ if (recording && recording->Info()->Title())
+ return AddSubMenu(new cMenuRecording(recording));
}
return osContinue;
}
@@ -1689,7 +1749,7 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
case kRed: return (helpKeys > 1 && RecordingCommands.Count()) ? Commands() : Play();
case kGreen: return Rewind();
case kYellow: return Delete();
- case kBlue: return Summary();
+ case kBlue: return Info();
case k1...k9: return Commands(Key);
default: break;
}
@@ -2568,36 +2628,43 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
// --- SetTrackDescriptions --------------------------------------------------
-static void SetTrackDescriptions(void)
+static void SetTrackDescriptions(bool Live)
{
cDevice::PrimaryDevice()->ClrAvailableTracks(true);
- cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
- if (Channel) {
- cSchedulesLock SchedulesLock;
- const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
- if (Schedules) {
- const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
- if (Schedule) {
- const cEvent *Present = Schedule->GetPresentEvent(true);
- if (Present) {
- const cComponents *Components = Present->Components();
- if (Components) {
- int indexAudio = 0;
- int indexDolby = 0;
- for (int i = 0; i < Components->NumComponents(); i++) {
- const tComponent *p = Components->Component(i);
- if (p->stream == 2) {
- if (p->type == 0x05)
- cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, NULL, p->description);
- else
- cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, NULL, p->description);
- }
- }
- }
+ const cComponents *Components = NULL;
+ cSchedulesLock SchedulesLock;
+ if (Live) {
+ cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
+ if (Channel) {
+ const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
+ if (Schedules) {
+ const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
+ if (Schedule) {
+ const cEvent *Present = Schedule->GetPresentEvent(true);
+ if (Present)
+ Components = Present->Components();
}
}
}
}
+ else if (cReplayControl::LastReplayed()) {
+ cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed());
+ if (Recording)
+ Components = Recording->Info()->Components();
+ }
+ if (Components) {
+ int indexAudio = 0;
+ int indexDolby = 0;
+ for (int i = 0; i < Components->NumComponents(); i++) {
+ const tComponent *p = Components->Component(i);
+ if (p->stream == 2) {
+ if (p->type == 0x05)
+ cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, NULL, p->description);
+ else
+ cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, NULL, p->description);
+ }
+ }
+ }
}
// --- cDisplayChannel -------------------------------------------------------
@@ -2657,7 +2724,7 @@ void cDisplayChannel::DisplayInfo(void)
const cEvent *Present = Schedule->GetPresentEvent(true);
const cEvent *Following = Schedule->GetFollowingEvent(true);
if (Present != lastPresent || Following != lastFollowing) {
- SetTrackDescriptions();
+ SetTrackDescriptions(true);
displayChannel->SetEvents(Present, Following);
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, Present ? Present->Title() : NULL, Present ? Present->ShortText() : NULL, Following ? Following->StartTime() : 0, Following ? Following->Title() : NULL, Following ? Following->ShortText() : NULL);
lastPresent = Present;
@@ -2877,9 +2944,7 @@ cDisplayTracks::cDisplayTracks(void)
:cOsdObject(true)
{
cDevice::PrimaryDevice()->EnsureAudioTrack();
- // Get the actual audio track descriptions from the EPG if we're not replaying:
- if (!cDevice::PrimaryDevice()->Replaying() || cTransferControl::ReceiverDevice())
- SetTrackDescriptions();
+ SetTrackDescriptions(!cDevice::PrimaryDevice()->Replaying() || cTransferControl::ReceiverDevice());
currentDisplayTracks = this;
numTracks = track = 0;
audioChannel = cDevice::PrimaryDevice()->GetAudioChannel();
@@ -2994,6 +3059,11 @@ eOSState cDisplayTracks::ProcessKey(eKeys Key)
cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
{
+ // We're going to manipulate an event here, so we need to prevent
+ // others from modifying any EPG data:
+ cSchedulesLock SchedulesLock;
+ cSchedules::Schedules(SchedulesLock);
+
event = NULL;
instantId = NULL;
fileName = NULL;
@@ -3011,16 +3081,9 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
timer->SetRecording(true);
event = timer->Event();
- const char *Title = NULL;
- const char *Subtitle = NULL;
- const char *Summary = NULL;
- if (event || GetEvent()) {
- Title = event->Title();
- Subtitle = event->ShortText();
- Summary = event->Description();
- dsyslog("Title: '%s' Subtitle: '%s'", Title, Subtitle);
- }
- cRecording Recording(timer, Title, Subtitle, Summary);
+ if (event || GetEvent())
+ dsyslog("Title: '%s' Subtitle: '%s'", event->Title(), event->ShortText());
+ cRecording Recording(timer, event);
fileName = strdup(Recording.FileName());
// crude attempt to avoid duplicate recordings:
@@ -3047,7 +3110,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
const cChannel *ch = timer->Channel();
recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids());
if (device->AttachReceiver(recorder)) {
- Recording.WriteSummary();
+ Recording.WriteInfo();
cStatus::MsgRecording(device, Recording.Name());
if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
cReplayControl::SetRecording(fileName, Recording.Name());
diff --git a/menu.h b/menu.h
index d142bbc..93712e4 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 1.69 2005/03/20 10:57:29 kls Exp $
+ * $Id: menu.h 1.70 2005/05/15 14:34:54 kls Exp $
*/
#ifndef __MENU_H
@@ -133,7 +133,7 @@ private:
eOSState Play(void);
eOSState Rewind(void);
eOSState Delete(void);
- eOSState Summary(void);
+ eOSState Info(void);
eOSState Commands(eKeys Key = kNone);
public:
cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false);
diff --git a/osd.c b/osd.c
index ff0b565..2d12597 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.59 2004/12/19 12:27:38 kls Exp $
+ * $Id: osd.c 1.60 2005/05/14 11:16:30 kls Exp $
*/
#include "osd.h"
@@ -574,7 +574,7 @@ const tIndex *cBitmap::Data(int x, int y)
// --- cOsd ------------------------------------------------------------------
-bool cOsd::isOpen = false;
+int cOsd::isOpen = 0;
cOsd::cOsd(int Left, int Top)
{
@@ -585,7 +585,7 @@ cOsd::cOsd(int Left, int Top)
left = Left;
top = Top;
width = height = 0;
- isOpen = true;
+ isOpen++;
}
cOsd::~cOsd()
@@ -593,7 +593,7 @@ cOsd::~cOsd()
for (int i = 0; i < numBitmaps; i++)
delete bitmaps[i];
delete savedRegion;
- isOpen = false;
+ isOpen--;
}
cBitmap *cOsd::GetBitmap(int Area)
diff --git a/osd.h b/osd.h
index bd69084..2f5de4d 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 1.47 2004/10/16 10:33:44 kls Exp $
+ * $Id: osd.h 1.48 2005/05/14 11:15:55 kls Exp $
*/
#ifndef __OSD_H
@@ -210,7 +210,7 @@ struct tArea {
class cOsd {
friend class cOsdProvider;
private:
- static bool isOpen;
+ static int isOpen;
cBitmap *savedRegion;
cBitmap *bitmaps[MAXOSDAREAS];
int numBitmaps;
@@ -235,7 +235,7 @@ protected:
public:
virtual ~cOsd();
///< Shuts down the OSD.
- static bool IsOpen(void) { return isOpen; }
+ static int IsOpen(void) { return isOpen; }
int Left(void) { return left; }
int Top(void) { return top; }
int Width(void) { return width; }
diff --git a/player.h b/player.h
index 6b08178..4316a75 100644
--- a/player.h
+++ b/player.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: player.h 1.16 2005/02/12 14:45:29 kls Exp $
+ * $Id: player.h 1.17 2005/05/22 11:07:42 kls Exp $
*/
#ifndef __PLAYER_H
@@ -29,6 +29,7 @@ protected:
void DevicePlay(void) { if (device) device->Play(); }
void DeviceFreeze(void) { if (device) device->Freeze(); }
void DeviceMute(void) { if (device) device->Mute(); }
+ void DeviceSetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat) { if (device) device->SetVideoDisplayFormat(VideoDisplayFormat); }
void DeviceStillPicture(const uchar *Data, int Length) { if (device) device->StillPicture(Data, Length); }
void Detach(void);
virtual void Activate(bool On) {}
diff --git a/recording.c b/recording.c
index ed74c46..93b0af8 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.c 1.98 2005/05/07 15:25:15 kls Exp $
+ * $Id: recording.c 1.107 2005/05/29 11:16:57 kls Exp $
*/
#include "recording.h"
@@ -23,6 +23,8 @@
#include "tools.h"
#include "videodir.h"
+#define SUMMARYFALLBACK
+
#define RECEXT ".rec"
#define DELEXT ".del"
/* This was the original code, which works fine in a Linux only environment.
@@ -45,7 +47,10 @@
// end of implementation for brain dead systems
#define RESUMEFILESUFFIX "/resume%s%s.vdr"
+#ifdef SUMMARYFALLBACK
#define SUMMARYFILESUFFIX "/summary.vdr"
+#endif
+#define INFOFILESUFFIX "/info.vdr"
#define MARKSFILESUFFIX "/marks.vdr"
#define MINDISKSPACE 1024 // MB
@@ -213,6 +218,68 @@ void cResumeFile::Delete(void)
}
}
+// --- cRecordingInfo --------------------------------------------------------
+
+cRecordingInfo::cRecordingInfo(const cEvent *Event)
+{
+ if (Event) {
+ event = Event;
+ channelID = event->ChannelID();
+ ownEvent = NULL;
+ }
+ else
+ event = ownEvent = new cEvent(0);
+}
+
+cRecordingInfo::~cRecordingInfo()
+{
+ delete ownEvent;
+}
+
+void cRecordingInfo::SetData(const char *Title, const char *ShortText, const char *Description)
+{
+ if (!isempty(Title))
+ ((cEvent *)event)->SetTitle(Title);
+ if (!isempty(ShortText))
+ ((cEvent *)event)->SetShortText(ShortText);
+ if (!isempty(Description))
+ ((cEvent *)event)->SetDescription(Description);
+}
+
+bool cRecordingInfo::Read(FILE *f)
+{
+ if (ownEvent) {
+ cReadLine ReadLine;
+ char *s;
+ while ((s = ReadLine.Read(f)) != NULL) {
+ char *t = skipspace(s + 1);
+ switch (*s) {
+ case 'C': {
+ char *p = strchr(t, ' ');
+ if (p)
+ *p = 0; // strips optional channel name
+ if (*t)
+ channelID = tChannelID::FromString(t);
+ }
+ break;
+ default: if (!ownEvent->Parse(s))
+ return false;
+ break;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool cRecordingInfo::Write(FILE *f, const char *Prefix) const
+{
+ if (channelID.Valid())
+ fprintf(f, "%sC %s\n", Prefix, *channelID.ToString());
+ event->Dump(f, Prefix, true);
+ return true;
+}
+
// --- cRecording ------------------------------------------------------------
#define RESUME_NOT_INITIALIZED (-2)
@@ -308,7 +375,7 @@ static char *ExchangeChars(char *s, bool ToFileSystem)
return s;
}
-cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary)
+cRecording::cRecording(cTimer *Timer, const cEvent *Event)
{
resume = RESUME_NOT_INITIALIZED;
titleBuffer = NULL;
@@ -316,7 +383,8 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c
fileName = NULL;
name = NULL;
// set up the actual name:
- const char *OriginalSubtitle = Subtitle;
+ const char *Title = Event ? Event->Title() : NULL;
+ const char *Subtitle = Event ? Event->ShortText() : NULL;
char SubtitleBuffer[MAX_SUBTITLE_LENGTH];
if (isempty(Title))
Title = Timer->Channel()->Name();
@@ -333,6 +401,14 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c
name = strdup(Timer->File());
name = strreplace(name, TIMERMACRO_TITLE, Title);
name = strreplace(name, TIMERMACRO_EPISODE, Subtitle);
+ // avoid blanks at the end:
+ int l = strlen(name);
+ while (l-- > 2) {
+ if (name[l] == ' ' && name[l - 1] != '~')
+ name[l] = 0;
+ else
+ break;
+ }
if (Timer->IsSingleEvent()) {
Timer->SetFile(name); // this was an instant recording, so let's set the actual data
Timers.SetModified();
@@ -347,17 +423,13 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c
start = Timer->StartTime();
priority = Timer->Priority();
lifetime = Timer->Lifetime();
- // handle summary:
- summary = !isempty(Timer->Summary()) ? strdup(Timer->Summary()) : NULL;
- if (!summary) {
- Subtitle = OriginalSubtitle;
- if (isempty(Subtitle))
- Subtitle = "";
- if (isempty(Summary))
- Summary = "";
- if (*Subtitle || *Summary)
- asprintf(&summary, "%s\n\n%s%s%s", Title, Subtitle, (*Subtitle && *Summary) ? "\n\n" : "", Summary);
- }
+ // handle info:
+ info = new cRecordingInfo(Event);
+ // this is a somewhat ugly hack to get the 'summary' information from the
+ // timer into the recording info, but it saves us from having to actually
+ // copy the entire event data:
+ if (!isempty(Timer->Summary()))
+ info->SetData(isempty(info->Title()) ? Timer->File() : NULL, NULL, Timer->Summary());
}
cRecording::cRecording(const char *FileName)
@@ -370,7 +442,7 @@ cRecording::cRecording(const char *FileName)
char *p = strrchr(FileName, '/');
name = NULL;
- summary = NULL;
+ info = new cRecordingInfo;
if (p) {
time_t now = time(NULL);
struct tm tm_r;
@@ -386,39 +458,57 @@ cRecording::cRecording(const char *FileName)
name[p - FileName] = 0;
name = ExchangeChars(name, false);
}
- // read an optional summary file:
- char *SummaryFileName = NULL;
- asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX);
- int f = open(SummaryFileName, O_RDONLY);
- if (f >= 0) {
- struct stat buf;
- if (fstat(f, &buf) == 0) {
- int size = buf.st_size;
- summary = MALLOC(char, size + 1); // +1 for terminating 0
- if (summary) {
- int rbytes = safe_read(f, summary, size);
- if (rbytes >= 0) {
- summary[rbytes] = 0;
- if (rbytes != size)
- esyslog("%s: expected %d bytes but read %d", SummaryFileName, size, rbytes);
- }
- else {
- LOG_ERROR_STR(SummaryFileName);
- free(summary);
- summary = NULL;
+ // read an optional info file:
+ char *InfoFileName = NULL;
+ asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
+ FILE *f = fopen(InfoFileName, "r");
+ if (f) {
+ info->Read(f);
+ fclose(f);
+ }
+ else if (errno != ENOENT)
+ LOG_ERROR_STR(InfoFileName);
+ free(InfoFileName);
+#ifdef SUMMARYFALLBACK
+ // fall back to the old 'summary.vdr' if there was no 'info.vdr':
+ if (isempty(info->Title())) {
+ char *SummaryFileName = NULL;
+ asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX);
+ FILE *f = fopen(SummaryFileName, "r");
+ if (f) {
+ int line = 0;
+ char *data[3] = { NULL };
+ cReadLine ReadLine;
+ char *s;
+ while ((s = ReadLine.Read(f)) != NULL && line < 3) {
+ if (*s) {
+ if (data[line]) {
+ int len = strlen(s);
+ len += strlen(data[line]) + 1;
+ data[line] = (char *)realloc(data[line], len + 1);
+ strcat(data[line], "\n");
+ strcat(data[line], s);
+ }
+ else
+ data[line] = strdup(s);
+ }
+ else
+ line++;
}
-
+ fclose(f);
+ if (line == 1) {
+ data[2] = data[1];
+ data[1] = NULL;
}
- else
- esyslog("can't allocate %d byte of memory for summary file '%s'", size + 1, SummaryFileName);
- close(f);
+ info->SetData(data[0], data[1], data[2]);
+ for (int i = 0; i < 3; i ++)
+ free(data[i]);
}
- else
+ else if (errno != ENOENT)
LOG_ERROR_STR(SummaryFileName);
+ free(SummaryFileName);
}
- else if (errno != ENOENT)
- LOG_ERROR_STR(SummaryFileName);
- free(SummaryFileName);
+#endif
}
}
@@ -428,7 +518,7 @@ cRecording::~cRecording()
free(sortBuffer);
free(fileName);
free(name);
- free(summary);
+ delete info;
}
char *cRecording::StripEpisodeName(char *s)
@@ -513,7 +603,8 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons
Delimiter,
s);
// let's not display a trailing '~':
- stripspace(titleBuffer);
+ if (!NewIndicator)
+ stripspace(titleBuffer);
s = &titleBuffer[strlen(titleBuffer) - 1];
if (*s == '~')
*s = 0;
@@ -568,21 +659,18 @@ bool cRecording::IsEdited(void) const
return *s == '%';
}
-bool cRecording::WriteSummary(void)
+bool cRecording::WriteInfo(void)
{
- if (summary) {
- char *SummaryFileName = NULL;
- asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX);
- FILE *f = fopen(SummaryFileName, "w");
- if (f) {
- if (fputs(summary, f) < 0)
- LOG_ERROR_STR(SummaryFileName);
- fclose(f);
- }
- else
- LOG_ERROR_STR(SummaryFileName);
- free(SummaryFileName);
+ char *InfoFileName = NULL;
+ asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
+ FILE *f = fopen(InfoFileName, "w");
+ if (f) {
+ info->Write(f);
+ fclose(f);
}
+ else
+ LOG_ERROR_STR(InfoFileName);
+ free(InfoFileName);
return true;
}
@@ -956,7 +1044,7 @@ bool cIndexFile::CatchUp(int Index)
LOG_ERROR_STR(fileName);
if (Index < last - (i ? 2 * INDEXSAFETYLIMIT : 0) || Index > 10 * INDEXSAFETYLIMIT) // keep off the end in case of "Pause live video"
break;
- sleep(1);
+ cCondWait::SleepMs(1000);
}
}
return index != NULL;
diff --git a/recording.h b/recording.h
index be1a5c4..0adb036 100644
--- a/recording.h
+++ b/recording.h
@@ -4,14 +4,16 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.h 1.34 2005/01/16 15:11:31 kls Exp $
+ * $Id: recording.h 1.38 2005/05/28 09:34:07 kls Exp $
*/
#ifndef __RECORDING_H
#define __RECORDING_H
#include <time.h>
+#include "channels.h"
#include "config.h"
+#include "epg.h"
#include "thread.h"
#include "timers.h"
#include "tools.h"
@@ -32,6 +34,24 @@ public:
void Delete(void);
};
+class cRecordingInfo {
+ friend class cRecording;
+private:
+ tChannelID channelID;
+ const cEvent *event;
+ cEvent *ownEvent;
+ cRecordingInfo(const cEvent *Event = NULL);
+ void SetData(const char *Title, const char *ShortText, const char *Description);
+public:
+ ~cRecordingInfo();
+ const char *Title(void) const { return event->Title(); }
+ const char *ShortText(void) const { return event->ShortText(); }
+ const char *Description(void) const { return event->Description(); }
+ const cComponents *Components(void) const { return event->Components(); }
+ bool Read(FILE *f);
+ bool Write(FILE *f, const char *Prefix = "") const;
+ };
+
class cRecording : public cListObject {
private:
mutable int resume;
@@ -39,7 +59,7 @@ private:
mutable char *sortBuffer;
mutable char *fileName;
mutable char *name;
- char *summary;
+ cRecordingInfo *info;
static char *StripEpisodeName(char *s);
char *SortName(void) const;
int GetResume(void) const;
@@ -47,19 +67,19 @@ public:
time_t start;
int priority;
int lifetime;
- cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary);
+ cRecording(cTimer *Timer, const cEvent *Event);
cRecording(const char *FileName);
~cRecording();
virtual int Compare(const cListObject &ListObject) const;
const char *Name(void) const { return name; }
const char *FileName(void) const;
const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const;
- const char *Summary(void) const { return summary; }
+ const cRecordingInfo *Info(void) const { return info; }
const char *PrefixFileName(char Prefix);
int HierarchyLevels(void) const;
bool IsNew(void) const { return GetResume() <= 0; }
bool IsEdited(void) const;
- bool WriteSummary(void);
+ bool WriteInfo(void);
bool Delete(void);
// Changes the file name so that it will no longer be visible in the "Recordings" menu
// Returns false in case of error
diff --git a/sdt.c b/sdt.c
index 8bb7009..dcf6dc1 100644
--- a/sdt.c
+++ b/sdt.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: sdt.c 1.13 2004/10/31 12:10:20 kls Exp $
+ * $Id: sdt.c 1.14 2005/05/14 09:39:46 kls Exp $
*/
#include "sdt.h"
@@ -62,6 +62,15 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf));
char *pn = compactspace(NameBuf);
char *ps = compactspace(ShortNameBuf);
+ if (!*ps && cSource::IsCable(Source())) {
+ // Some cable providers don't mark short channel names according to the
+ // standard, but rather go their own way and use "name>short name":
+ char *p = strchr(pn, '>');
+ if (p && p > pn) {
+ *p++ = 0;
+ strcpy(ShortNameBuf, p);
+ }
+ }
sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf));
char *pp = compactspace(ProviderNameBuf);
if (channel) {
diff --git a/sections.c b/sections.c
index 7c42a6e..6552d56 100644
--- a/sections.c
+++ b/sections.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: sections.c 1.10 2004/10/24 11:05:12 kls Exp $
+ * $Id: sections.c 1.11 2005/05/29 11:43:17 kls Exp $
*/
#include "sections.h"
@@ -167,6 +167,7 @@ void cSectionHandler::SetStatus(bool On)
void cSectionHandler::Action(void)
{
active = true;
+ SetPriority(19);
while (active) {
Lock();
diff --git a/skinclassic.c b/skinclassic.c
index 7eb0513..fd3ab0b 100644
--- a/skinclassic.c
+++ b/skinclassic.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: skinclassic.c 1.11 2005/01/09 11:56:29 kls Exp $
+ * $Id: skinclassic.c 1.12 2005/05/16 10:45:07 kls Exp $
*/
#include "skinclassic.h"
@@ -326,7 +326,33 @@ void cSkinClassicDisplayMenu::SetEvent(const cEvent *Event)
void cSkinClassicDisplayMenu::SetRecording(const cRecording *Recording)
{
- SetText(Recording->Summary(), false); //TODO
+ if (!Recording)
+ return;
+ const cRecordingInfo *Info = Recording->Info();
+ const cFont *font = cFont::GetFont(fontOsd);
+ int xl = x0 + 10;
+ int y = y2;
+ cTextScroller ts;
+ char t[32];
+ snprintf(t, sizeof(t), "%s %s", *DateString(Recording->start), *TimeString(Recording->start));
+ ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
+ y += ts.Height();
+ y += font->Height();
+ const char *Title = Info->Title();
+ if (isempty(Title))
+ Title = Recording->Name();
+ ts.Set(osd, xl, y, x1 - xl, y3 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
+ y += ts.Height();
+ if (!isempty(Info->ShortText())) {
+ const cFont *font = cFont::GetFont(fontSml);
+ ts.Set(osd, xl, y, x1 - xl, y3 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
+ y += ts.Height();
+ }
+ y += font->Height();
+ if (!isempty(Info->Description())) {
+ textScroller.Set(osd, xl, y, x1 - xl - 2 * ScrollWidth, y3 - y, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
+ SetScrollbar();
+ }
}
void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
diff --git a/skins.h b/skins.h
index add8d56..5fc6344 100644
--- a/skins.h
+++ b/skins.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: skins.h 1.7 2005/02/27 14:37:37 kls Exp $
+ * $Id: skins.h 1.8 2005/05/15 14:41:41 kls Exp $
*/
#ifndef __SKINS_H
@@ -150,7 +150,7 @@ public:
///< that text if necessary.
virtual void SetRecording(const cRecording *Recording) = 0;
///< Sets the Recording that shall be displayed, using the entire central area
- ///< of the menu. The Recording's 'summary' shall be displayed using a
+ ///< of the menu. The Recording's 'description' shall be displayed using a
///< cTextScroller, and the Scroll() function will be called to drive scrolling
///< that text if necessary.
virtual void SetText(const char *Text, bool FixedFont) = 0;
diff --git a/skinsttng.c b/skinsttng.c
index 3760ad4..b9d9ccb 100644
--- a/skinsttng.c
+++ b/skinsttng.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: skinsttng.c 1.13 2005/02/27 14:45:19 kls Exp $
+ * $Id: skinsttng.c 1.14 2005/05/16 10:44:58 kls Exp $
*/
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@@ -576,7 +576,39 @@ void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
void cSkinSTTNGDisplayMenu::SetRecording(const cRecording *Recording)
{
- SetText(Recording->Summary(), false); //XXX
+ if (!Recording)
+ return;
+ const cRecordingInfo *Info = Recording->Info();
+ const cFont *font = cFont::GetFont(fontOsd);
+ int xl = x3 + 5;
+ int y = y3;
+ cTextScroller ts;
+ char t[32];
+ snprintf(t, sizeof(t), "%s %s", *DateString(Recording->start), *TimeString(Recording->start));
+ ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
+ y += ts.Height();
+ y += font->Height();
+ const char *Title = Info->Title();
+ if (isempty(Title))
+ Title = Recording->Name();
+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
+ y += ts.Height();
+ if (!isempty(Info->ShortText())) {
+ const cFont *font = cFont::GetFont(fontSml);
+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
+ y += ts.Height();
+ }
+ y += font->Height();
+ if (!isempty(Info->Description())) {
+ int yt = y;
+ int yb = y4 - Roundness;
+ textScroller.Set(osd, xl, yt, x4 - xl, yb - yt, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
+ yb = yt + textScroller.Height();
+ osd->DrawEllipse (x1, yt - Roundness, x2, yt, frameColor, -3);
+ osd->DrawRectangle(x1, yt, x2, yb, frameColor);
+ osd->DrawEllipse (x1, yb, x2, yb + Roundness, frameColor, -2);
+ SetScrollbar();
+ }
}
void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
diff --git a/sources.h b/sources.h
index 22076ea..ae941f8 100644
--- a/sources.h
+++ b/sources.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: sources.h 1.3 2004/12/26 11:59:21 kls Exp $
+ * $Id: sources.h 1.4 2005/05/14 09:30:41 kls Exp $
*/
#ifndef __SOURCES_H
@@ -35,6 +35,9 @@ public:
static cString ToString(int Code);
static int FromString(const char *s);
static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
+ static bool IsCable(int Code) { return (Code & st_Mask) == stCable; }
+ static bool IsSat(int Code) { return (Code & st_Mask) == stSat; }
+ static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; }
};
class cSources : public cConfig<cSource> {
diff --git a/summary2info.pl b/summary2info.pl
new file mode 100755
index 0000000..8e80abe
--- /dev/null
+++ b/summary2info.pl
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+# Convert 'summary.vdr' files to 'info.vdr'
+#
+# Converts all 'summary.vdr' files in the video directory to the
+# 'info.vdr' format as used from VDR version 1.3.25 upward.
+#
+# Usage: summary2info.pl /video
+#
+# See the main source file 'vdr.c' for copyright information and
+# how to reach the author.
+#
+# $Id: summary2info.pl 1.2 2005/05/22 10:37:47 kls Exp $
+
+$VideoDir = $ARGV[0] || die "please provide the name of the video directory\n";
+
+@SummaryFiles = `find "$VideoDir" -name summary.vdr`;
+
+for $SummaryFile (@SummaryFiles) {
+ chomp($SummaryFile);
+ print STDERR "converting $SummaryFile...";
+ open(F, $SummaryFile) || die "$SummaryFile: $!\n";
+ $line = 0;
+ @data = ();
+ while (<F>) {
+ chomp;
+ if ($_) {
+ $data[$line] .= '|' if ($data[$line]);
+ $data[$line] .= $_;
+ }
+ else {
+ $line++;
+ }
+ }
+ close(F);
+ if ($line == 1) {
+ $data[2] = $data[1];
+ $data[1] = "";
+ }
+ ($InfoFile = $SummaryFile) =~ s/summary\.vdr$/info.vdr/;
+ open(F, ">$InfoFile") || die "$InfoFile: $!\n";
+ print F "T $data[0]\n" if ($data[0]);
+ print F "S $data[1]\n" if ($data[1]);
+ print F "D $data[2]\n" if ($data[2]);
+ close(F);
+ print STDERR "done.\n";
+ }
diff --git a/svdrp.c b/svdrp.c
index 5104026..a63a575 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.70 2005/05/06 13:47:39 kls Exp $
+ * $Id: svdrp.c 1.72 2005/05/26 09:59:09 kls Exp $
*/
#include "svdrp.h"
@@ -31,6 +31,7 @@
#include "device.h"
#include "eitscan.h"
#include "keys.h"
+#include "menu.h"
#include "remote.h"
#include "timers.h"
#include "tools.h"
@@ -214,7 +215,7 @@ const char *HelpPages[] = {
" events at the given time (which must be in time_t form).",
"LSTR [ <number> ]\n"
" List recordings. Without option, all recordings are listed. Otherwise\n"
- " the summary for the given recording is listed.",
+ " the information for the given recording is listed.",
"LSTT [ <number> ]\n"
" List timers. Without option, all timers are listed. Otherwise\n"
" only the given timer is listed.",
@@ -281,7 +282,7 @@ const char *HelpPages[] = {
/* SVDRP Reply Codes:
214 Help message
- 215 EPG data record
+ 215 EPG or recording data record
220 VDR service ready
221 VDR service closing transmission channel
250 Requested VDR action okay, completed
@@ -505,12 +506,17 @@ void cSVDRP::CmdDELR(const char *Option)
if (isnumber(Option)) {
cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
if (recording) {
- if (recording->Delete()) {
- Reply(250, "Recording \"%s\" deleted", Option);
- ::Recordings.Load(); // must make sure the global recordings list is updated
+ cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName());
+ if (!rc) {
+ if (recording->Delete()) {
+ Reply(250, "Recording \"%s\" deleted", Option);
+ ::Recordings.Load(); // must make sure the global recordings list is updated
+ }
+ else
+ Reply(554, "Error while deleting recording!");
}
else
- Reply(554, "Error while deleting recording!");
+ Reply(550, "Recording \"%s\" is in use by timer %d", Option, rc->Timer()->Index() + 1);
}
else
Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before deleting)");
@@ -800,13 +806,15 @@ void cSVDRP::CmdLSTR(const char *Option)
if (isnumber(Option)) {
cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
if (recording) {
- if (recording->Summary()) {
- char *summary = strdup(recording->Summary());
- Reply(250, "%s", strreplace(summary,'\n','|'));
- free(summary);
+ FILE *f = fdopen(file, "w");
+ if (f) {
+ recording->Info()->Write(f, "215-");
+ fflush(f);
+ Reply(215, "End of recording information");
+ // don't 'fclose(f)' here!
}
else
- Reply(550, "No summary available");
+ Reply(451, "Can't open file connection");
}
else
Reply(550, "Recording \"%s\" not found", Option);
diff --git a/thread.c b/thread.c
index 013b217..9ac1b7e 100644
--- a/thread.c
+++ b/thread.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: thread.c 1.42 2005/05/06 14:39:15 kls Exp $
+ * $Id: thread.c 1.43 2005/05/29 11:40:30 kls Exp $
*/
#include "thread.h"
@@ -208,6 +208,12 @@ cThread::~cThread()
free(description);
}
+void cThread::SetPriority(int Priority)
+{
+ if (setpriority(PRIO_PROCESS, 0, Priority) < 0)
+ LOG_ERROR;
+}
+
void cThread::SetDescription(const char *Description, ...)
{
free(description);
diff --git a/thread.h b/thread.h
index 2c0ebcb..48d0499 100644
--- a/thread.h
+++ b/thread.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: thread.h 1.27 2005/01/14 14:02:14 kls Exp $
+ * $Id: thread.h 1.28 2005/05/29 11:31:24 kls Exp $
*/
#ifndef __THREAD_H
@@ -82,6 +82,7 @@ private:
static bool emergencyExitRequested;
static void *StartThread(cThread *Thread);
protected:
+ void SetPriority(int Priority);
void Lock(void) { mutex.Lock(); }
void Unlock(void) { mutex.Unlock(); }
virtual void Action(void) = 0;
diff --git a/tools.c b/tools.c
index 28ea2af..5561216 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.c 1.91 2005/03/20 14:44:33 kls Exp $
+ * $Id: tools.c 1.95 2005/05/29 10:18:26 kls Exp $
*/
#include "tools.h"
@@ -571,6 +571,25 @@ cString TimeToString(time_t t)
return "???";
}
+cString DateString(time_t t)
+{
+ char buf[32];
+ struct tm tm_r;
+ tm *tm = localtime_r(&t, &tm_r);
+ char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
+ *p++ = ' ';
+ strftime(p, sizeof(buf) - (p - buf), "%d.%m.%Y", tm);
+ return buf;
+}
+
+cString TimeString(time_t t)
+{
+ char buf[25];
+ struct tm tm_r;
+ strftime(buf, sizeof(buf), "%R", localtime_r(&t, &tm_r));
+ return buf;
+}
+
// --- cReadLine -------------------------------------------------------------
char *cReadLine::Read(FILE *f)
@@ -913,6 +932,7 @@ int cListObject::Index(void) const
cListBase::cListBase(void)
{
objects = lastObject = NULL;
+ count = 0;
}
cListBase::~cListBase()
@@ -933,6 +953,7 @@ void cListBase::Add(cListObject *Object, cListObject *After)
objects = Object;
lastObject = Object;
}
+ count++;
}
void cListBase::Ins(cListObject *Object, cListObject *Before)
@@ -948,6 +969,7 @@ void cListBase::Ins(cListObject *Object, cListObject *Before)
lastObject = Object;
objects = Object;
}
+ count++;
}
void cListBase::Del(cListObject *Object, bool DeleteObject)
@@ -959,6 +981,7 @@ void cListBase::Del(cListObject *Object, bool DeleteObject)
Object->Unlink();
if (DeleteObject)
delete Object;
+ count--;
}
void cListBase::Move(int From, int To)
@@ -998,6 +1021,7 @@ void cListBase::Clear(void)
objects = object;
}
objects = lastObject = NULL;
+ count = 0;
}
cListObject *cListBase::Get(int Index) const
@@ -1010,18 +1034,6 @@ cListObject *cListBase::Get(int Index) const
return object;
}
-int cListBase::Count(void) const
-{
- int n = 0;
- cListObject *object = objects;
-
- while (object) {
- n++;
- object = object->Next();
- }
- return n;
-}
-
static int CompareListObjects(const void *a, const void *b)
{
const cListObject *la = *(const cListObject **)a;
@@ -1043,7 +1055,60 @@ void cListBase::Sort(void)
objects = lastObject = NULL;
for (i = 0; i < n; i++) {
a[i]->Unlink();
+ count--;
Add(a[i]);
}
}
+// --- cHashBase -------------------------------------------------------------
+
+cHashBase::cHashBase(int Size)
+{
+ size = Size;
+ hashTable = (cList<cHashObject>**)calloc(size, sizeof(cList<cHashObject>*));
+}
+
+cHashBase::~cHashBase(void)
+{
+ for (int i = 0; i < size; i++)
+ delete hashTable[i];
+ free(hashTable);
+}
+
+void cHashBase::Add(cListObject *Object, unsigned int Id)
+{
+ unsigned int hash = hashfn(Id);
+ if (!hashTable[hash])
+ hashTable[hash] = new cList<cHashObject>;
+ hashTable[hash]->Add(new cHashObject(Object, Id));
+}
+
+void cHashBase::Del(cListObject *Object, unsigned int Id)
+{
+ cList<cHashObject> *list = hashTable[hashfn(Id)];
+ if (list) {
+ for (cHashObject *hob = list->First(); hob; hob = list->Next(hob)) {
+ if (hob->object == Object) {
+ list->Del(hob);
+ break;
+ }
+ }
+ }
+}
+
+cListObject *cHashBase::Get(unsigned int Id) const
+{
+ cList<cHashObject> *list = hashTable[hashfn(Id)];
+ if (list) {
+ for (cHashObject *hob = list->First(); hob; hob = list->Next(hob)) {
+ if (hob->id == Id)
+ return hob->object;
+ }
+ }
+ return NULL;
+}
+
+cList<cHashObject> *cHashBase::GetList(unsigned int Id) const
+{
+ return hashTable[hashfn(Id)];
+}
diff --git a/tools.h b/tools.h
index d9e85f3..079e58d 100644
--- a/tools.h
+++ b/tools.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.h 1.68 2005/03/20 14:44:24 kls Exp $
+ * $Id: tools.h 1.72 2005/05/29 10:24:54 kls Exp $
*/
#ifndef __TOOLS_H
@@ -102,6 +102,8 @@ cString WeekDayName(int WeekDay);
cString WeekDayName(time_t t);
cString DayDateTime(time_t t = 0);
cString TimeToString(time_t t);
+cString DateString(time_t t);
+cString TimeString(time_t t);
class cTimeMs {
private:
@@ -211,6 +213,7 @@ class cListBase {
protected:
cListObject *objects, *lastObject;
cListBase(void);
+ int count;
public:
virtual ~cListBase();
void Add(cListObject *Object, cListObject *After = NULL);
@@ -220,7 +223,7 @@ public:
void Move(cListObject *From, cListObject *To);
virtual void Clear(void);
cListObject *Get(int Index) const;
- int Count(void) const;
+ int Count(void) const { return count; }
void Sort(void);
};
@@ -233,4 +236,36 @@ public:
T *Next(const T *object) const { return (T *)object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
};
+class cHashObject : public cListObject {
+ friend class cHashBase;
+private:
+ unsigned int id;
+ cListObject *object;
+public:
+ cHashObject(cListObject *Object, unsigned int Id) { object = Object; id = Id; }
+ };
+
+class cHashBase {
+private:
+ cList<cHashObject> **hashTable;
+ int size;
+ unsigned int hashfn(unsigned int Id) const { return Id % size; }
+protected:
+ cHashBase(int Size);
+public:
+ virtual ~cHashBase();
+ void Add(cListObject *Object, unsigned int Id);
+ void Del(cListObject *Object, unsigned int Id);
+ cListObject *Get(unsigned int Id) const;
+ cList<cHashObject> *GetList(unsigned int Id) const;
+ };
+
+#define HASHSIZE 512
+
+template<class T> class cHash : public cHashBase {
+public:
+ cHash(int Size = HASHSIZE) : cHashBase(Size) {}
+ T *Get(unsigned int Id) const { return (T *)cHashBase::Get(Id); }
+};
+
#endif //__TOOLS_H
diff --git a/vdr.5 b/vdr.5
index 96136a1..5be6da8 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.36 2005/05/07 10:40:23 kls Exp $
+.\" $Id: vdr.5 1.37 2005/05/16 14:16:48 kls Exp $
.\"
.TH vdr 5 "19 Mar 2005" "1.3.23" "Video Disk Recorder Files"
.SH NAME
@@ -578,11 +578,13 @@ the current position within the recording, and to implement skipping
and fast forward/back functions.
See the definition of the \fBcIndexFile\fR class for details about the
actual contents of this file.
-.SS SUMMARY
-The file \fIsummary.vdr\fR (if present in a recording directory) contains
+.SS INFO
+The file \fIinfo.vdr\fR (if present in a recording directory) contains
a description of the recording, derived from the EPG data at recording time
(if such data was available) or the \fBSummary\fR field of the corresponding
-timer. This is a plain ASCII file and can contain arbitrary text.
+timer. This is a plain ASCII file and contains tagged lines like the \fBEPG DATA\fR
+file (see the description of the \fIepg.data\fR file). Note that the tags
+c, E, e and V will not appear in an \fIinfo.vdr\fR file.
.SS RESUME
The file \fIresume.vdr\fR (if present in a recording directory) contains
the position within the recording where the last replay session left off.
diff --git a/vdr.c b/vdr.c
index 72975e3..10a5888 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/vdr
*
- * $Id: vdr.c 1.203 2005/03/20 10:58:59 kls Exp $
+ * $Id: vdr.c 1.207 2005/05/26 10:45:29 kls Exp $
*/
#include <getopt.h>
@@ -87,25 +87,6 @@ static void Watchdog(int signum)
int main(int argc, char *argv[])
{
-#ifdef _CS_GNU_LIBPTHREAD_VERSION
- // Check for NPTL and exit if present - VDR apparently doesn't run well with NPTL:
- char LibPthreadVersion[128];
- if (confstr(_CS_GNU_LIBPTHREAD_VERSION, LibPthreadVersion, sizeof(LibPthreadVersion)) > 0) {
- if (strstr(LibPthreadVersion, "NPTL")) {
- fprintf(stderr, "vdr: please turn off NPTL by setting 'export LD_ASSUME_KERNEL=2.4.1' before starting VDR\n");
- return 2;
- }
- }
-#endif
-
- // Check for UTF-8 and exit if present - asprintf() will fail if it encounters 8 bit ASCII codes
- char *LangEnv;
- if ((LangEnv = getenv("LANG")) != NULL && strcasestr(LangEnv, "utf") ||
- (LangEnv = getenv("LC_CTYPE")) != NULL && strcasestr(LangEnv, "utf")) {
- fprintf(stderr, "vdr: please turn off UTF-8 before starting VDR\n");
- return 2;
- }
-
// Save terminal settings:
struct termios savedTm;
@@ -321,6 +302,25 @@ int main(int argc, char *argv[])
return 0;
}
+#ifdef _CS_GNU_LIBPTHREAD_VERSION
+ // Check for NPTL and exit if present - VDR apparently doesn't run well with NPTL:
+ char LibPthreadVersion[128];
+ if (confstr(_CS_GNU_LIBPTHREAD_VERSION, LibPthreadVersion, sizeof(LibPthreadVersion)) > 0) {
+ if (strstr(LibPthreadVersion, "NPTL")) {
+ fprintf(stderr, "vdr: please turn off NPTL by setting 'export LD_ASSUME_KERNEL=2.4.1' before starting VDR\n");
+ return 2;
+ }
+ }
+#endif
+
+ // Check for UTF-8 and exit if present - asprintf() will fail if it encounters 8 bit ASCII codes
+ char *LangEnv;
+ if ((LangEnv = getenv("LANG")) != NULL && strcasestr(LangEnv, "utf") ||
+ (LangEnv = getenv("LC_CTYPE")) != NULL && strcasestr(LangEnv, "utf")) {
+ fprintf(stderr, "vdr: please turn off UTF-8 before starting VDR\n");
+ return 2;
+ }
+
// Log file:
if (SysLogLevel > 0)
@@ -744,7 +744,6 @@ int main(int argc, char *argv[])
// Power off:
case kPower: isyslog("Power button pressed");
DELETENULL(Menu);
- cControl::Shutdown();
Temp = NULL;
if (!Shutdown) {
Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!"));
@@ -846,6 +845,14 @@ int main(int argc, char *argv[])
break;
// Viewing Control:
case kOk: LastChannel = -1; break; // forces channel display
+ // Instant resume of the last viewed recording:
+ case kPlay:
+ if (cReplayControl::LastReplayed()) {
+ cControl::Shutdown();
+ Temp = NULL;
+ cControl::Launch(new cReplayControl);
+ }
+ break;
// Key macros:
case kRed:
case kGreen:
@@ -898,6 +905,7 @@ int main(int argc, char *argv[])
if (WatchdogTimeout > 0)
signal(SIGALRM, SIG_IGN);
if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
+ cControl::Shutdown();
int Channel = timer ? timer->Channel()->Number() : 0;
const char *File = timer ? timer->File() : "";
Delta = Next - time(NULL); // compensates for Confirm() timeout
@@ -940,9 +948,11 @@ Exit:
Remotes.Clear();
Audios.Clear();
Skins.Clear();
- Setup.CurrentChannel = cDevice::CurrentChannel();
- Setup.CurrentVolume = cDevice::CurrentVolume();
- Setup.Save();
+ if (ExitCode != 2) {
+ Setup.CurrentChannel = cDevice::CurrentChannel();
+ Setup.CurrentVolume = cDevice::CurrentVolume();
+ Setup.Save();
+ }
cDevice::Shutdown();
PluginManager.Shutdown();
ReportEpgBugFixStats();