Compare commits

...

73 Commits

Author SHA1 Message Date
Klaus Schmidinger
296c9e95fa Adjusted release date 2015-01-20 09:13:08 +01:00
Klaus Schmidinger
fe5bb7c5e0 Fixed generating the index file of an existing recording 2015-01-17 13:52:34 +01:00
Klaus Schmidinger
1c9cd049b4 Now returning from removing deleted recordings after at most 10 seconds, or if the user presses a remote control key 2015-01-17 10:55:42 +01:00
Klaus Schmidinger
ff2f39b440 Fixed jumping to an absolute position via the Red key in case replay was paused 2015-01-13 09:55:37 +01:00
Klaus Schmidinger
a4169ceb22 Fixed a bug in the Makefile when installing plugins with LCLBLD=1 2015-01-01 14:01:50 +01:00
Klaus Schmidinger
99d7fe6cf9 Fixed a possible division by zero in frame rate detection 2014-04-13 14:00:42 +02:00
Klaus Schmidinger
1dca279938 The APIVERSION has been increased to 2.0.6 2014-03-22 11:03:39 +01:00
Klaus Schmidinger
cd125ef4da Now initializing the isOnVideoDirectoryFileSystem member of cRecording when scanning the video directory 2014-03-16 11:03:44 +01:00
Klaus Schmidinger
ba9651e863 The SDT is now only parsed *after* the NIT has been read 2014-03-11 09:32:48 +01:00
Klaus Schmidinger
da404e00c0 Fixed drawing the live indicator in the LCARS skin in case there are no devices 2014-03-10 12:12:44 +01:00
Klaus Schmidinger
e823560ec5 Fixed adding new source types in case they are already registered 2014-03-09 12:15:08 +01:00
Klaus Schmidinger
ff1422a75a Fixed handling PAT packets when detecting frames 2014-03-08 15:10:24 +01:00
Klaus Schmidinger
d406be694d Fixed a possible endless loop in cH264Parser::GetGolombUe() 2014-03-08 15:08:30 +01:00
Klaus Schmidinger
fdf9c8df8e Changed email address of Christopher Reimer 2014-03-05 10:19:20 +01:00
Klaus Schmidinger
c94b4a803c Fixed handling transfer mode on full featured DVB cards for encrypted channels that have no audio pid 2014-02-27 17:12:14 +01:00
Klaus Schmidinger
7271a160e4 Fixed keeping the current position in the Recordings menu if a recording was deleted in a sub folder 2014-02-26 11:45:28 +01:00
Klaus Schmidinger
1c47cf37ca Fixed handling frame detection buffer length 2014-02-21 15:17:08 +01:00
Klaus Schmidinger
d55c134333 Fixed detecting broken video data streams when recording 2014-02-21 09:21:45 +01:00
Klaus Schmidinger
a179b725b7 No section number in debug message 2014-02-19 09:31:29 +01:00
Klaus Schmidinger
4709eb94fa Improved PAT/PMT scanning to speed up initial tuning to encrypted channels on transponders with many PAT entries 2014-02-18 14:14:33 +01:00
Klaus Schmidinger
3736508d95 Fixed the replay progress display for very long recordings 2014-02-18 14:07:36 +01:00
Klaus Schmidinger
058177d24c Fixed learning keyboard remote control codes 2014-02-15 12:45:48 +01:00
Klaus Schmidinger
1ae32cdd6f Revoked 'Fixed numbering frames' to not break compatibility within the stable 2.0.x 2014-02-08 10:57:26 +01:00
Klaus Schmidinger
fb66c3ec6b Fixed a possible crash in the OSD demo 2014-02-06 12:00:36 +01:00
Klaus Schmidinger
7d6c54d63a Fixed numbering frames 2014-02-06 11:04:03 +01:00
Klaus Schmidinger
719b46b305 Fixed flickering if subtitles are active while the OSD demo is running 2014-02-04 10:48:10 +01:00
Klaus Schmidinger
5b65ff5b37 Fixed clearing non-editable members in the channel editor 2014-01-30 09:14:17 +01:00
Klaus Schmidinger
c1ddb52405 Fixed sorting recordings by time in the Recordings menu if "Setup/OSD/Recording directories" is set to "no" 2014-01-29 10:51:18 +01:00
Klaus Schmidinger
9e9219d8fb Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 100 and introduced counting the number of actual video TS packets in cTsPayload 2014-01-28 12:40:04 +01:00
Klaus Schmidinger
538a4f7674 Now checking whether the primary device actually has a decoder before retuning the current channel after a change in its parameters 2014-01-26 12:45:46 +01:00
Klaus Schmidinger
dd95f4ed61 Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying GOP structures 2014-01-25 14:37:05 +01:00
Klaus Schmidinger
6bd94489de cFont::CreateFont() now returns a dummy font in case there are no fonts installed 2014-01-25 14:26:26 +01:00
Klaus Schmidinger
c7316989f5 Fixed a wrong alignment in cCiDateTime::SendDateTime() 2014-01-22 09:44:30 +01:00
Klaus Schmidinger
bc89bda239 Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 10 2014-01-16 10:36:37 +01:00
Klaus Schmidinger
426cf5710d Updated 'sources.conf' 2014-01-07 09:30:06 +01:00
Klaus Schmidinger
a7728f9db7 Adjusted release date 2014-01-07 09:10:31 +01:00
Klaus Schmidinger
4e7ef3214f Fixed setting the name of the video directory to avoid a crash when using --genindex, and also to use the correct directory with --edit 2013-12-25 11:41:28 +01:00
Klaus Schmidinger
6a4004a8a2 Added a missing closing ')' in the help and man page entry of the --vfat option 2013-12-25 11:06:10 +01:00
Klaus Schmidinger
1045069fee Fixed a possible crash if the recordings list is updated externally while the Recordings menu is open 2013-12-25 10:57:36 +01:00
Klaus Schmidinger
cca9d858a7 Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu 2013-11-16 13:29:34 +01:00
Klaus Schmidinger
7b634a092c Fixed a missing initialization in the c'tor of cSkinLCARSDisplayChannel 2013-11-15 15:26:49 +01:00
Klaus Schmidinger
25e05054a6 The LIRC remote control now connects to the socket even if it doesn't yet exist whe VDR is started 2013-10-29 16:09:03 +01:00
Klaus Schmidinger
578cfe64a8 Adjusted release date 2013-10-23 08:59:34 +02:00
Klaus Schmidinger
746a9f88e7 Revoked "Added maximum signal strength value for TechniSat SkyStar 2 DVB-S rev 2.3P" 2013-10-21 09:01:53 +02:00
Klaus Schmidinger
fb74e0feeb Fixed an inconsistent behavior between opening the Recordings menu manually via the main menu and by pressing the Recordings key 2013-10-16 09:49:26 +02:00
Klaus Schmidinger
cb1498a609 Added maximum signal strength value for TechniSat SkyStar 2 DVB-S rev 2.3P 2013-10-13 14:47:41 +02:00
Klaus Schmidinger
ddce16326c Changed cRecorder::Action() to use cTimeMs instead of time() 2013-10-12 12:11:21 +02:00
Klaus Schmidinger
c8d77e241f Now also checking the source (in addition to the transponder) when setting the system time from the TDT 2013-10-12 11:26:07 +02:00
Klaus Schmidinger
965b3471b7 Fixed writing group separators to channels.conf that contain a comma 2013-10-11 11:42:19 +02:00
Klaus Schmidinger
0f75df5452 The Yellow button in the main menu no longer acts as "Pause" if "Pause key handling" is set to "do not pause live video" 2013-09-07 12:54:59 +02:00
Klaus Schmidinger
c37fb11a08 Unified the internal sequence of actions when pressing the Blue and the Back key, respectively, during replay 2013-09-07 10:25:10 +02:00
Klaus Schmidinger
c169e20141 Fixed cleaning up old EPG events in case no epg data file is given 2013-09-01 09:20:07 +02:00
Klaus Schmidinger
c3a3b70fa0 All bonded devices (except for the master) now turn off their LNB power completely to avoid problems when receiving vertically polarized transponders 2013-08-23 09:53:47 +02:00
Klaus Schmidinger
fc03e021bb Increased the value of MAXRETRIES to 20 to reduce the probability of disturbances in transfer mode 2013-08-22 12:37:19 +02:00
Klaus Schmidinger
6e6e468148 cDevice::IsPrimaryDevice() now also checks whether the primary device actually has a decoder and returns false otherwise 2013-08-22 12:02:12 +02:00
Klaus Schmidinger
1f0a55ca7d Fixed a possible crash when shutting down VDR while subtitles are being displayed 2013-08-22 10:36:07 +02:00
Klaus Schmidinger
917331767b Fixed handling LIRC events in case repeated events are lost 2013-08-22 09:37:12 +02:00
Klaus Schmidinger
0161639e93 Fixed handling the -o option (short form of --outputonly) 2013-08-22 08:30:52 +02:00
Klaus Schmidinger
77da7bb20c No longer trying to delete old recordings in AssertFreeDiskSpace() if the given Priority is less than 1 2013-08-21 13:59:06 +02:00
Klaus Schmidinger
acdfbb5aad Fixed asserting free disk space in the cutter 2013-08-21 13:46:13 +02:00
Klaus Schmidinger
cd53d57779 Fixed a crash in the LCARS skin's main menu in case there is no current channel 2013-05-19 12:09:55 +02:00
Klaus Schmidinger
0d14872adc Fixed an endless loop in the DrawEllipse() functions for very small ellipses 2013-05-18 12:43:41 +02:00
Klaus Schmidinger
90f4648a7c Fixed unwanted version tag on checkout of older version 2013-05-02 10:21:37 +02:00
Klaus Schmidinger
be88699b00 Fixed an error message when parsing SCR values in diseqc.conf 2013-05-02 09:33:47 +02:00
Klaus Schmidinger
1b1fe2c887 Fixed no longer generating any editing marks if the edited recording results in just one single sequence 2013-05-02 09:23:21 +02:00
Klaus Schmidinger
fa77b5c2b2 Fixed displaying the frame number when setting an editing mark 2013-04-27 10:34:08 +02:00
Klaus Schmidinger
cffde6ee09 Fixed multiple occurrences of the same directory in the recordings list in case there are directories that only differ in non-alphanumeric characters 2013-04-27 10:18:08 +02:00
Klaus Schmidinger
2266b0e633 Adjusted release date 2013-04-13 11:30:25 +02:00
Klaus Schmidinger
06f7c2d414 Changed cThread::SetIOPriority() from "best effort class" to "idle class" in order to improve overall performance when an editing process is running 2013-04-11 08:59:26 +02:00
Klaus Schmidinger
1b1dc6d775 Fixed handling '/' and '~' in recording file names in case DirectoryEncoding is used 2013-04-11 08:24:04 +02:00
Klaus Schmidinger
e5971d2684 Added definitions for older DVB API versions, back until 5.0 2013-04-09 13:44:50 +02:00
Klaus Schmidinger
ae208771e8 Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than one character 2013-04-07 14:54:15 +02:00
Klaus Schmidinger
df4ea10419 Fixed initializing cDevice::keepTracks 2013-04-05 10:48:51 +02:00
48 changed files with 932 additions and 378 deletions

View File

@ -232,6 +232,7 @@ Stefan Huelswitt <s.huelswitt@gmx.de>
featured DVB cards featured DVB cards
for pointing out a bug in handling lowercase polarization characters in channel for pointing out a bug in handling lowercase polarization characters in channel
definitions if no DiSEqC is used definitions if no DiSEqC is used
for fixing a bug in the Makefile when installing plugins with LCLBLD=1
Ulrich Röder <roeder@efr-net.de> Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than 27500 for pointing out that there are channels that have a symbol rate higher than 27500
@ -618,6 +619,10 @@ Helmut Auer <vdr@helmutauer.de>
for suggesting to read the epg.data file in a separate thread for suggesting to read the epg.data file in a separate thread
for some improvements to allowing the parameters PATH and NAME to the --dirnames for some improvements to allowing the parameters PATH and NAME to the --dirnames
command line option to be left empty to use the default values if only ENC shall be set command line option to be left empty to use the default values if only ENC shall be set
for reporting an inconsistent behavior between opening the Recordings menu manually
via the main menu and by pressing the Recordings key
for helping to debug a problem with frame detection in MPEG-2 streams that have "bottom fields"
or varying GOP structures
Jeremy Hall <jhall@UU.NET> Jeremy Hall <jhall@UU.NET>
for fixing an incomplete initialization of the filter parameters in eit.c for fixing an incomplete initialization of the filter parameters in eit.c
@ -700,6 +705,10 @@ Oliver Endriss <o.endriss@gmx.de>
for helping to debug a problem with reduced number of retries in Transfer Mode on for helping to debug a problem with reduced number of retries in Transfer Mode on
SD-FF cards SD-FF cards
for reporting a problem with resuming replay of PES recordings for reporting a problem with resuming replay of PES recordings
for suggesting to make all bonded devices (except for the master) turn off their LNB
power completely to avoid problems when receiving vertically polarized transponders
for reporting that there are channels that need even more than 10 TS packets in order
to detect the frame type
Reinhard Walter Buchner <rw.buchner@freenet.de> Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf' for adding some satellites to 'sources.conf'
@ -1013,9 +1022,11 @@ Andreas Mair <amair.sob@googlemail.com>
for fixing the type of MBperMinute in cVideoDiskUsage::HasChanged() for fixing the type of MBperMinute in cVideoDiskUsage::HasChanged()
for reporting a bug in sorting recordings in case two folders have the same name, for reporting a bug in sorting recordings in case two folders have the same name,
but one of them ends in an additional digit, as in "abc" and "abc2" but one of them ends in an additional digit, as in "abc" and "abc2"
for reporting multiple occurrences of the same directory in the recordings list ini for reporting multiple occurrences of the same directory in the recordings list in
case there are directories that only differ in non-alphanumeric characters case there are directories that only differ in non-alphanumeric characters
for reporting a problem with reduced number of retries in Transfer Mode on SD-FF cards for reporting a problem with reduced number of retries in Transfer Mode on SD-FF cards
for fixing multiple occurrences of the same directory in the recordings list in case
there are directories that only differ in non-alphanumeric characters
Olivier Jacques <jacquesolivier@hotmail.com>) Olivier Jacques <jacquesolivier@hotmail.com>)
for translating OSD texts to the French language for translating OSD texts to the French language
@ -1165,6 +1176,9 @@ Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>
for fixing the call to ChannelString() in cSkinLCARSDisplayChannel::SetChannel() for fixing the call to ChannelString() in cSkinLCARSDisplayChannel::SetChannel()
for a patch that was used to rename the "plp id" to a more general "stream id" for a patch that was used to rename the "plp id" to a more general "stream id"
and add support for DVB-S2 "Input Stream Identifier" (ISI) and add support for DVB-S2 "Input Stream Identifier" (ISI)
for fixing clearing non-editable members in the channel editor
for reporting a problem with adding new source types in case they are already
registered
Ralf Klueber <ralf.klueber@vodafone.com> Ralf Klueber <ralf.klueber@vodafone.com>
for reporting a bug in cutting a recording if there is only a single editing mark for reporting a bug in cutting a recording if there is only a single editing mark
@ -2015,6 +2029,8 @@ Ville Skytt
be escaped be escaped
for changing the template for PLGCFG to $(CONFDIR)/plugins.mk for changing the template for PLGCFG to $(CONFDIR)/plugins.mk
for updating the help and man page entry about the location of the epg.data file for updating the help and man page entry about the location of the epg.data file
for reporting a possible crash when shutting down VDR while subtitles are being
displayed
Steffen Beyer <cpunk@reactor.de> Steffen Beyer <cpunk@reactor.de>
for fixing setting the colored button help after deleting a recording in case the next for fixing setting the colored button help after deleting a recording in case the next
@ -2100,6 +2116,7 @@ Thomas G
for suggesting to make the 'Allowed' parameter in cMenuEditStrItem() NULL by default, for suggesting to make the 'Allowed' parameter in cMenuEditStrItem() NULL by default,
which results in using tr(FileNameChars) which results in using tr(FileNameChars)
for fixing handling "none" color entries in XPM files for fixing handling "none" color entries in XPM files
for fixing displaying the frame number when setting an editing mark
David Woodhouse <dwmw2@infradead.org> David Woodhouse <dwmw2@infradead.org>
for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with
@ -2127,6 +2144,9 @@ Marko M
pressed in string input fields pressed in string input fields
for fixing missing ',' in the Italian and Polish OSD texts for fixing missing ',' in the Italian and Polish OSD texts
for pointing out that "Menu button closes" should actually be "Menu key closes" for pointing out that "Menu button closes" should actually be "Menu key closes"
for fixing a missing initialization in the c'tor of cSkinLCARSDisplayChannel
for reporting some uninitialized item area coordinates in cSkinLCARSDisplayMenu
for reporting a problem with the video directory not being set correctly with --edit
Patrick Rother <krd-vdr@gulu.net> Patrick Rother <krd-vdr@gulu.net>
for reporting a bug in defining timers that only differ in the day of week for reporting a bug in defining timers that only differ in the day of week
@ -2475,6 +2495,7 @@ Anssi Hannula <anssi.hannula@gmail.com>
Antti Hartikainen <ami+vdr@ah.fi> Antti Hartikainen <ami+vdr@ah.fi>
for updating 'S13E' in 'sources.conf' for updating 'S13E' in 'sources.conf'
for adding maximum SNR value for PCTV Systems nanoStick T2 290e for adding maximum SNR value for PCTV Systems nanoStick T2 290e
for updating 'sources.conf'
Bernd Melcher <bernd@bernd-melcher.de> Bernd Melcher <bernd@bernd-melcher.de>
for reporting a problem with the 'servicedemo' plugin having no PLUGIN macro for reporting a problem with the 'servicedemo' plugin having no PLUGIN macro
@ -2537,6 +2558,8 @@ Ulf Kiener <webmaster@ulf-kiener.de>
for suggesting to add user defined key kUser0 for suggesting to add user defined key kUser0
for suggesting to perform absolute jumps when replaying a recording (via the Red key) for suggesting to perform absolute jumps when replaying a recording (via the Red key)
only if an actual value has been entered only if an actual value has been entered
for suggesting to make the Yellow button in the main menu not act as "Pause" if
"Pause key handling" is set to "do not pause live video"
Jörg Wendel <vdr-ml@jwendel.de> Jörg Wendel <vdr-ml@jwendel.de>
for reporting that cPlugin::Active() was called too often for reporting that cPlugin::Active() was called too often
@ -2598,6 +2621,8 @@ Halim Sahin <halim.sahin@t-online.de>
for suggesting to make the "Source" item in the "Edit channel" menu wrap around the for suggesting to make the "Source" item in the "Edit channel" menu wrap around the
list of sources list of sources
for reporting a crash when creating a new channel if the channel list is empty for reporting a crash when creating a new channel if the channel list is empty
for reporting that editing marks were generated even if the edited recording resulted
in just one single sequence
Denis Knauf <denis.knauf@gmail.com> Denis Knauf <denis.knauf@gmail.com>
for reporting a missing '-' at the next to last line of SVDRP help texts for reporting a missing '-' at the next to last line of SVDRP help texts
@ -2832,6 +2857,14 @@ Lars Hanisch <dvb@flensrocker.de>
for fixing a typo in skins.h for fixing a typo in skins.h
for fixing some #include statements in plugins to use <vdr/...> instead of "vdr/..." for fixing some #include statements in plugins to use <vdr/...> instead of "vdr/..."
for reporting an invalid line in channels.conf.terr for reporting an invalid line in channels.conf.terr
for fixing handling '/' and '~' in recording file names in case DirectoryEncoding is
used
for making the LIRC remote control connect to the socket even if it doesn't yet exist
when VDR is started
for reporting a possible crash if the recordings list is updated externally while the
Recordings menu is open
for reporting a missing closing ')' in the help entry of the --vfat option
for fixing learning keyboard remote control codes
Alex Lasnier <alex@fepg.org> Alex Lasnier <alex@fepg.org>
for adding tuning support for ATSC devices for adding tuning support for ATSC devices
@ -2859,7 +2892,7 @@ Luis Fernandes <telping@gmail.com>
for suggesting to add handling MPEG audio type "ISO/IEC 14496-3 Audio with LATM for suggesting to add handling MPEG audio type "ISO/IEC 14496-3 Audio with LATM
transport syntax" transport syntax"
Christopher Reimer <reimer.christopher@freenet.de> Christopher Reimer <vdr@creimer.net>
for reporting a problem with external Dolby Digital processing via the '-a' option for reporting a problem with external Dolby Digital processing via the '-a' option
in live mode and with TS recordings in live mode and with TS recordings
for contributing to a patch that implements FHS support for contributing to a patch that implements FHS support
@ -2869,6 +2902,7 @@ Christopher Reimer <reimer.christopher@freenet.de>
for making plugin Makefiles use DESTDIR and the 'install' program for making plugin Makefiles use DESTDIR and the 'install' program
for suggesting to make sure that plugins include the VDR header files from the actual for suggesting to make sure that plugins include the VDR header files from the actual
VDR source directory when doing "make plugins" VDR source directory when doing "make plugins"
for reporting a possible crash in the OSD demo
Stefan Huskamp <coca_cola1@gmx.de> Stefan Huskamp <coca_cola1@gmx.de>
for suggesting to make entering characters via the number keys for suggesting to make entering characters via the number keys
@ -2946,6 +2980,7 @@ Johan Andersson <jna@jna.pp.se>
Dave Pickles <dave@pickles.me.uk> Dave Pickles <dave@pickles.me.uk>
for adding support for "content identifier descriptor" and "default authority for adding support for "content identifier descriptor" and "default authority
descriptor" to 'libsi' descriptor" to 'libsi'
for reporting that old EPG events are not cleaned up in case no epg data file is given
Holger Dengler <holger.dengler@gmx.de> Holger Dengler <holger.dengler@gmx.de>
for making the isnumber() function check the given pointer for NULL for making the isnumber() function check the given pointer for NULL
@ -2994,6 +3029,11 @@ Torsten Lang <info@torstenlang.de>
for suggesting to increase the size of the TS buffer to 5MB and that of the Recorder for suggesting to increase the size of the TS buffer to 5MB and that of the Recorder
buffer to 20MB to better handle HD recordings buffer to 20MB to better handle HD recordings
for fixing setting the video format in the dvbhdffdevice for fixing setting the video format in the dvbhdffdevice
for reporting a problem with setting the system time from the TDT in case devices
are tuned to the same transponder on different sources, and these broadcast different
time data
for reporting a problem with unjustified "video data stream broken" errors in case
the system time is changed while a recording is active
Christian Ruppert <idl0r@gentoo.org> Christian Ruppert <idl0r@gentoo.org>
for some improvements to the Makefiles for some improvements to the Makefiles
@ -3135,3 +3175,49 @@ Zoran Turalija <zoran.turalija@gmail.com>
for translating OSD texts to the Serbian language for translating OSD texts to the Serbian language
for adding maximum SNR and signal strength value for TechniSat SkyStar HD2 for adding maximum SNR and signal strength value for TechniSat SkyStar HD2
for pointing out that the language file sr_SR.po should be renamed to sr_RS.po for pointing out that the language file sr_SR.po should be renamed to sr_RS.po
Stefan Braun <louis.braun@gmx.de>
for reporting an endless loop in cTextWrapper::Set() in case the given Width is smaller
than one character
for reporting an endless loop in the DrawEllipse() functions for very small ellipses
Jochen Dolze <vdr@dolze.de>
for changing cThread::SetIOPriority() from "best effort class" to "idle class" in order
to improve overall performance when an editing process is running
Dominique Dumont <domi.dumont@free.fr>
for reporting a crash in the LCARS skin's main menu in case there is no current channel
Manfred Völkel <mvoelkel@digitaldevices.de>
for suggesting to make all bonded devices (except for the master) turn off their LNB
power completely to avoid problems when receiving vertically polarized transponders
Thomas Maass <mase@setho.org>
for reporting a difference in the internal sequence of actions when pressing the Blue
and the Back key, respectively, during replay
Eike Edener <eike@edener.de>
for reporting a bug in writing group separators to channels.conf that contain a comma
Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting
frame borders
for reporting a problem in handling the frame detection buffer length
Christian Paulick <cpaulick@xeatre.tv>
for reporting a problem with frame detection in MPEG-2 streams that have "bottom fields"
or varying GOP structures
Mariusz Bialonczyk <manio@skyboo.net>
for reporting that acquiring the CA descriptors takes way too long on transponders
with many PAT entries, and his help in debugging this
Christian Winkler <winkler_chr@yahoo.de>
for reporting a problem with transfer mode on full featured DVB cards for encrypted
channels that have no audio pid
Dieter Ferdinand <dieter.ferdinand@gmx.de>
for reporting a problem with jumping to an absolute position via the Red key in
case replay was paused
for reporting a problem with the system getting unresponsive when removing a huge
number of files in the thread that removes deleted recordings

156
HISTORY
View File

@ -7328,7 +7328,7 @@ Video Disk Recorder Revision History
+ no longer generating an editing mark at the "end" of the edited recording (this + no longer generating an editing mark at the "end" of the edited recording (this
was actually generated at the beginning of the last GOP, so that a subsequent was actually generated at the beginning of the last GOP, so that a subsequent
edit would have cut off the last GOP) edit would have cut off the last GOP)
+ no longer generating any editing marks if the edited recording results on just + no longer generating any editing marks if the edited recording results in just
one single sequence one single sequence
+ ignoring pairs of editing marks that are placed at exactly the same position of + ignoring pairs of editing marks that are placed at exactly the same position of
a recording when actually cutting the recording a recording when actually cutting the recording
@ -7773,7 +7773,6 @@ Video Disk Recorder Revision History
Dominic Evans). Dominic Evans).
- Updated the default channels.conf file. - Updated the default channels.conf file.
2013-03-31: Version 2.0.0 2013-03-31: Version 2.0.0
- Updated the Lithuanian OSD texts (thanks to Valdemaras Pipiras). - Updated the Lithuanian OSD texts (thanks to Valdemaras Pipiras).
@ -7782,3 +7781,156 @@ Video Disk Recorder Revision History
- Fixed handling overlapping pending timers (reported by Matthias Senzel). - Fixed handling overlapping pending timers (reported by Matthias Senzel).
- Bumped all version numbers to 2.0.0. - Bumped all version numbers to 2.0.0.
- Official release. - Official release.
2013-04-13: Version 2.0.1
- Fixed initializing cDevice::keepTracks.
- Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than
one character (reported by Stefan Braun).
- Added definitions for older DVB API versions, back until 5.0 (based on a patch from
Udo Richter).
- Fixed handling '/' and '~' in recording file names in case DirectoryEncoding is
used (thanks to Lars Hanisch).
- Changed cThread::SetIOPriority() from "best effort class" to "idle class" in order to
improve overall performance when an editing process is running (thanks to Jochen
Dolze).
2013-05-19: Version 2.0.2
- Fixed multiple occurrences of the same directory in the recordings list in case there
are directories that only differ in non-alphanumeric characters (was broken by
"Fixed selecting the last replayed recording in the Recordings menu in case there
are folders and plain recordings with names that differ only in non-alphanumeric
characters" in version 1.7.36).
- Fixed displaying the frame number when setting an editing mark (thanks to Thomas
Günther).
- Fixed no longer generating any editing marks if the edited recording results in just
one single sequence.
- Fixed an error message when parsing SCR values in diseqc.conf.
- Fixed an unexpected RCS version tag in the newplugin script.
- Fixed an endless loop in the DrawEllipse() functions for very small ellipses (reported
by Stefan Braun).
- Fixed a crash in the LCARS skin's main menu in case there is no current channel
(reported by Dominique Dumont).
2013-09-01: Version 2.0.3
- Fixed asserting free disk space in the cutter.
- No longer trying to delete old recordings in AssertFreeDiskSpace() if the given
Priority is less than 1.
- Fixed handling LIRC events in case repeated events are lost.
- Fixed a possible crash when shutting down VDR while subtitles are being displayed
(reported by Ville Skyttä).
- cDevice::IsPrimaryDevice() now also checks whether the primary device actually has
a decoder and returns false otherwise. This should improve device allocation on
systems that are only used as a receiver and don't actually display anything.
- Increased the value of MAXRETRIES to 20 to reduce the probability of disturbances
in transfer mode.
- All bonded devices (except for the master) now turn off their LNB power completely
to avoid problems when receiving vertically polarized transponders (suggested by
Manfred Völkel and Oliver Endriss).
- Fixed cleaning up old EPG events in case no epg data file is given (reported by
Dave Pickles).
2013-10-23: Version 2.0.4
- Unified the internal sequence of actions when pressing the Blue and the Back key,
respectively, during replay (reported by Thomas Maass).
- The Yellow button in the main menu no longer acts as "Pause" if "Pause key handling"
is set to "do not pause live video" (suggested by Ulf Kiener).
- Fixed writing group separators to channels.conf that contain a comma (reported by
Eike Edener).
- Now also checking the source (in addition to the transponder) when setting the
system time from the TDT, which avoids problems in case devices are tuned to the
same transponder on different sources, and these broadcast different time data
(reported by Torsten Lang).
- Changed cRecorder::Action() to use cTimeMs instead of time() to avoid problems with
unjustified "video data stream broken" errors in case the system time is changed
while a recording is active (reported by Torsten Lang).
- Fixed an inconsistent behavior between opening the Recordings menu manually via the
main menu and by pressing the Recordings key. In the latter case it automatically
opened all sub folders to position the cursor to the last replayed recording, which
is unexpected at this point (reported by Helmut Auer). You can still navigate to
the last replayed recording (if any) by pressing Ok repeatedly in the Recordings
menu.
2014-01-07: Version 2.0.5
- The LIRC remote control now connects to the socket even if it doesn't yet exist when
VDR is started (thanks to Lars Hanisch).
- Fixed a missing initialization in the c'tor of cSkinLCARSDisplayChannel (thanks to
Marko Mäkelä).
- Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by
Marko Mäkelä).
- Fixed a possible crash if the recordings list is updated externally while the
Recordings menu is open (reported by Lars Hanisch).
- Added a missing closing ')' in the help and man page entry of the --vfat option
(reported by Lars Hanisch).
- Fixed setting the name of the video directory to avoid a crash when using --genindex,
and also to use the correct directory with --edit (the latter reported by Marko
Mäkelä).
2014-03-16: Version 2.0.6
- Updated 'sources.conf' (thanks to Antti Hartikainen).
- cFont::CreateFont() now returns a dummy font in case there are no fonts installed.
This prevents a crash with the LCARS skin on a system that has no fonts.
- Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying
GOP structures (reported by Christian Paulick, with help from Helmut Auer).
- Fixed a wrong alignment in cCiDateTime::SendDateTime().
- Now checking whether the primary device actually has a decoder before retuning the
current channel after a change in its parameters. This fixes broken recordings on
the primary device on "headless" systems.
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 100 and introduced counting the number
of actual video TS packets in cTsPayload in order to be able to record channels that
sometimes need even more than 10 TS packets for detecting frame borders (reported by
Eike Sauer and Oliver Endriss).
- Fixed sorting recordings by time in the Recordings menu if "Setup/OSD/Recording
directories" is set to "no".
- Fixed clearing non-editable members in the channel editor (thanks to Rolf Ahrenberg).
- Fixed flickering if subtitles are active while the OSD demo is running.
- Fixed a possible crash in the OSD demo (reported by Christopher Reimer).
- Fixed learning keyboard remote control codes (thanks to Lars Hanisch).
- Fixed the replay progress display for very long recordings.
- Improved PAT/PMT scanning to speed up initial tuning to encrypted channels on
transponders with many PAT entries (reported by Mariusz Bialonczyk).
- Fixed detecting broken video data streams when recording.
- Fixed handling frame detection buffer length (reported by Eike Sauer).
- Fixed keeping the current position in the Recordings menu if a recording was
deleted in a sub folder.
- Fixed handling transfer mode on full featured DVB cards for encrypted channels
that have no audio pid (reported by Christian Winkler).
- Fixed a possible endless loop in cH264Parser::GetGolombUe(), which caused recordings
on some HD channels to get stuck and resulted in buffer overflows.
- Fixed handling PAT packets when detecting frames, so that they can be properly
taken into account when regenerating the index of a recording.
- Fixed adding new source types in case they are already registered (reported by Rolf
Ahrenberg).
- Fixed drawing the live indicator in the LCARS skin in case there are no devices.
- The SDT is now only parsed *after* the NIT has been read, and it explicitly uses
the source value derived from the NIT. This should prevent new channels from being
created with the wrong source.
- Now initializing the isOnVideoDirectoryFileSystem member of cRecording when
scanning the video directory, so that it won't cause a delay when opening the menu
on a system with a large number of recordings.
- The APIVERSION has been increased to 2.0.6 due to the changes to pat.h, sdt.h and
the functional modification to cFont::CreateFont().
2015-01-20: Version 2.0.7
- Fixed a possible division by zero in frame rate detection.
- Fixed a bug in the Makefile when installing plugins with LCLBLD=1 (thanks to
Stefan Huelswitt).
- Fixed jumping to an absolute position via the Red key in case replay was paused
(reported by Dieter Ferdinand).
- Now returning from removing deleted recordings after at most 10 seconds, or if the
user presses a remote control key, to keep the system from getting unresponsive
when removing a huge number of files (reported by Dieter Ferdinand).
- Fixed generating the index file of an existing recording in case at the of a TS file
there is less data in the buffer than needed by the frame detector. In such a case
it was possible that frames were missed, and there was most likely a distortion
when replaying that part of a recording. This is mostly a problem for recordings that
consist of more than one *.ts file. Single file recordings could only lose some
frames at their very end, which probably doesn't matter. At any rate, if you have
generated an index file with VDR version 2.0.6 you may want to do so again with this
version to make sure the index is OK.

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and # See the main source file 'vdr.c' for copyright information and
# how to reach the author. # how to reach the author.
# #
# $Id: Makefile 2.54 2013/03/11 15:01:01 kls Exp $ # $Id: Makefile 2.54.1.1 2015/01/01 13:59:51 kls Exp $
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
@ -220,7 +220,7 @@ plugins: include-dir vdr.pc
INCLUDES="-I$(CWD)/include"\ INCLUDES="-I$(CWD)/include"\
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" || failed="$$failed $$i";\ $(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" || failed="$$failed $$i";\
if [ -n "$(LCLBLD)" ] ; then\ if [ -n "$(LCLBLD)" ] ; then\
(cd $(PLUGINDIR)/src/$$i; for l in `find -name 'libvdr-*.so' -o -name 'lib$$i-*.so'`; do install $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\ (cd $(PLUGINDIR)/src/$$i; for l in `find -name "libvdr-*.so" -o -name "lib$$i-*.so"`; do install $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\
if [ -d $(PLUGINDIR)/src/$$i/po ]; then\ if [ -d $(PLUGINDIR)/src/$$i/po ]; then\
for l in `ls $(PLUGINDIR)/src/$$i/po/*.mo`; do\ for l in `ls $(PLUGINDIR)/src/$$i/po/*.mo`; do\
install -D -m644 $$l $(LOCDIR)/`basename $$l | cut -d. -f1`/LC_MESSAGES/vdr-$$i.mo;\ install -D -m644 $$l $(LOCDIR)/`basename $$l | cut -d. -f1`/LC_MESSAGES/vdr-$$i.mo;\

View File

@ -45,3 +45,8 @@ VDR Plugin 'dvbsddevice' Revision History
2013-03-31: Version 2.0.0 2013-03-31: Version 2.0.0
- Official release. - Official release.
2013-08-22: Version 2.0.1
- Fixed handling the -o option (short form of --outputonly; problem reported by
Mario Edelmann).

View File

@ -3,14 +3,14 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsddevice.c 1.10 2013/03/31 09:30:18 kls Exp $ * $Id: dvbsddevice.c 1.10.1.1 2013/08/22 08:30:52 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
#include "dvbsdffdevice.h" #include "dvbsdffdevice.h"
static const char *VERSION = "2.0.0"; static const char *VERSION = "2.0.1";
static const char *DESCRIPTION = "SD Full Featured DVB device"; static const char *DESCRIPTION = "SD Full Featured DVB device";
class cPluginDvbsddevice : public cPlugin { class cPluginDvbsddevice : public cPlugin {
@ -48,7 +48,7 @@ bool cPluginDvbsddevice::ProcessArgs(int argc, char *argv[])
}; };
int c; int c;
while ((c = getopt_long(argc, argv, "", long_options, NULL)) != -1) { while ((c = getopt_long(argc, argv, "o", long_options, NULL)) != -1) {
switch (c) { switch (c) {
case 'o': probe->SetOutputOnly(true); case 'o': probe->SetOutputOnly(true);
break; break;

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsdffdevice.c 2.35 2013/02/17 13:16:18 kls Exp $ * $Id: dvbsdffdevice.c 2.35.1.1 2014/02/27 17:10:51 kls Exp $
*/ */
#include "dvbsdffdevice.h" #include "dvbsdffdevice.h"
@ -400,8 +400,8 @@ bool cDvbSdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
bool DoTune = !IsTunedToTransponder(Channel); bool DoTune = !IsTunedToTransponder(Channel);
bool pidHandlesVideo = pidHandles[ptVideo].pid == vpid; bool pidHandlesVideo = vpid && pidHandles[ptVideo].pid == vpid;
bool pidHandlesAudio = pidHandles[ptAudio].pid == apid; bool pidHandlesAudio = apid && pidHandles[ptAudio].pid == apid;
bool TurnOffLivePIDs = DoTune bool TurnOffLivePIDs = DoTune
|| !IsPrimaryDevice() || !IsPrimaryDevice()

View File

@ -59,3 +59,8 @@ VDR Plugin 'osddemo' Revision History
2013-03-31: Version 2.0.0 2013-03-31: Version 2.0.0
- Official release. - Official release.
2014-02-06: Version 2.0.1
- Fixed flickering if subtitles are active while the OSD demo is running.
- Fixed a possible crash in the OSD demo (reported by Christopher Reimer).

View File

@ -3,13 +3,13 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: osddemo.c 2.12 2013/03/31 09:30:18 kls Exp $ * $Id: osddemo.c 2.12.1.2 2014/02/06 11:59:40 kls Exp $
*/ */
#include <vdr/osd.h> #include <vdr/osd.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.0.0"; static const char *VERSION = "2.0.1";
static const char *DESCRIPTION = "Demo of arbitrary OSD setup"; static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
static const char *MAINMENUENTRY = "Osd Demo"; static const char *MAINMENUENTRY = "Osd Demo";
@ -119,7 +119,7 @@ cLineGame::~cLineGame()
void cLineGame::Show(void) void cLineGame::Show(void)
{ {
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50); osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
if (osd) { if (osd) {
int x1 = cOsd::OsdWidth() - 1; int x1 = cOsd::OsdWidth() - 1;
int y1 = cOsd::OsdHeight() - 1; int y1 = cOsd::OsdHeight() - 1;
@ -480,6 +480,8 @@ void cTrueColorDemo::Action(void)
if (Delta < FrameTime) if (Delta < FrameTime)
cCondWait::SleepMs(FrameTime - Delta); cCondWait::SleepMs(FrameTime - Delta);
} }
destroyablePixmap = NULL;
toggleablePixmap = NULL;
delete OsdFont; delete OsdFont;
delete SmlFont; delete SmlFont;
delete LrgFont; delete LrgFont;
@ -496,7 +498,7 @@ bool cTrueColorDemo::SetArea(void)
void cTrueColorDemo::Show(void) void cTrueColorDemo::Show(void)
{ {
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50); osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
if (osd) { if (osd) {
if (SetArea()) { if (SetArea()) {
osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, clrGray50); osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, clrGray50);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.c 2.24 2012/07/14 12:15:00 kls Exp $ * $Id: channels.c 2.24.1.1 2013/10/11 11:40:02 kls Exp $
*/ */
#include "channels.h" #include "channels.h"
@ -503,12 +503,14 @@ cString cChannel::ToText(const cChannel *Channel)
char FullName[strlen(Channel->name) + 1 + strlen(Channel->shortName) + 1 + strlen(Channel->provider) + 1 + 10]; // +10: paranoia char FullName[strlen(Channel->name) + 1 + strlen(Channel->shortName) + 1 + strlen(Channel->provider) + 1 + 10]; // +10: paranoia
char *q = FullName; char *q = FullName;
q += sprintf(q, "%s", Channel->name); q += sprintf(q, "%s", Channel->name);
if (!isempty(Channel->shortName)) if (!Channel->groupSep) {
q += sprintf(q, ",%s", Channel->shortName); if (!isempty(Channel->shortName))
else if (strchr(Channel->name, ',')) q += sprintf(q, ",%s", Channel->shortName);
q += sprintf(q, ","); else if (strchr(Channel->name, ','))
if (!isempty(Channel->provider)) q += sprintf(q, ",");
q += sprintf(q, ";%s", Channel->provider); if (!isempty(Channel->provider))
q += sprintf(q, ";%s", Channel->provider);
}
*q = 0; *q = 0;
strreplace(FullName, ':', '|'); strreplace(FullName, ':', '|');
cString buffer; cString buffer;

4
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 2.12 2013/02/17 13:17:28 kls Exp $ * $Id: ci.c 2.12.1.1 2014/01/22 09:43:48 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -846,7 +846,9 @@ void cCiDateTime::SendDateTime(void)
int L = (M == 1 || M == 2) ? 1 : 0; int L = (M == 1 || M == 2) ? 1 : 0;
int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001); int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
#define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10)) #define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10))
#pragma pack(1)
struct tTime { uint16_t mjd; uint8_t h, m, s; short offset; }; struct tTime { uint16_t mjd; uint8_t h, m, s; short offset; };
#pragma pack()
tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) }; tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) };
bool OldDumpTPDUDataTransfer = DumpTPDUDataTransfer; bool OldDumpTPDUDataTransfer = DumpTPDUDataTransfer;
DumpTPDUDataTransfer &= DumpDateTime; DumpTPDUDataTransfer &= DumpDateTime;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: config.h 2.76 2013/03/31 09:30:18 kls Exp $ * $Id: config.h 2.76.1.8 2014/04/13 14:00:42 kls Exp $
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
@ -22,13 +22,13 @@
// VDR's own version number: // VDR's own version number:
#define VDRVERSION "2.0.0" #define VDRVERSION "2.0.7"
#define VDRVERSNUM 20000 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 20007 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number: // The plugin API's version number:
#define APIVERSION "2.0.0" #define APIVERSION "2.0.6"
#define APIVERSNUM 20000 // Version * 10000 + Major * 100 + Minor #define APIVERSNUM 20006 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which // When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to // may be smaller than VDRVERSION in case there have been no changes to

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: cutter.c 2.25 2013/03/18 09:40:49 kls Exp $ * $Id: cutter.c 2.25.1.2 2013/08/21 13:43:46 kls Exp $
*/ */
#include "cutter.h" #include "cutter.h"
@ -556,6 +556,8 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
bool Independent; bool Independent;
int Length; int Length;
if (LoadFrame(Index, Buffer, Independent, Length)) { if (LoadFrame(Index, Buffer, Independent, Length)) {
// Make sure there is enough disk space:
AssertFreeDiskSpace(-1);
bool CutIn = !SeamlessBegin && Index == BeginIndex; bool CutIn = !SeamlessBegin && Index == BeginIndex;
bool CutOut = !SeamlessEnd && Index == EndIndex - 1; bool CutOut = !SeamlessEnd && Index == EndIndex - 1;
bool DeletedFrame = false; bool DeletedFrame = false;
@ -581,7 +583,7 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
} }
fileSize += Length; fileSize += Length;
// Generate marks at the editing points in the edited recording: // Generate marks at the editing points in the edited recording:
if (numSequences > 0 && Index == BeginIndex) { if (numSequences > 1 && Index == BeginIndex) {
if (toMarks.Count() > 0) if (toMarks.Count() > 0)
toMarks.Add(toIndex->Last()); toMarks.Add(toIndex->Last());
toMarks.Add(toIndex->Last()); toMarks.Add(toIndex->Last());
@ -608,8 +610,6 @@ void cCuttingThread::Action(void)
cCondWait::SleepMs(100); cCondWait::SleepMs(100);
continue; continue;
} }
// Make sure there is enough disk space:
AssertFreeDiskSpace(-1);
// Determine the actual begin and end marks, skipping any marks at the same position: // Determine the actual begin and end marks, skipping any marks at the same position:
cMark *EndMark = fromMarks.GetNextEnd(BeginMark); cMark *EndMark = fromMarks.GetNextEnd(BeginMark);
// Process the current sequence: // Process the current sequence:

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 2.74 2013/03/07 13:18:35 kls Exp $ * $Id: device.c 2.74.1.4 2014/03/11 09:29:52 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -94,11 +94,11 @@ cDevice::cDevice(void)
player = NULL; player = NULL;
isPlayingVideo = false; isPlayingVideo = false;
keepTracks = false; // used in ClrAvailableTracks()!
ClrAvailableTracks(); ClrAvailableTracks();
currentAudioTrack = ttNone; currentAudioTrack = ttNone;
currentAudioTrackMissingCount = 0; currentAudioTrackMissingCount = 0;
currentSubtitleTrack = ttNone; currentSubtitleTrack = ttNone;
keepTracks = false;
liveSubtitle = NULL; liveSubtitle = NULL;
dvbSubtitleConverter = NULL; dvbSubtitleConverter = NULL;
autoSelectPreferredSubtitleLanguage = true; autoSelectPreferredSubtitleLanguage = true;
@ -118,6 +118,8 @@ cDevice::~cDevice()
DetachAllReceivers(); DetachAllReceivers();
delete liveSubtitle; delete liveSubtitle;
delete dvbSubtitleConverter; delete dvbSubtitleConverter;
if (this == primaryDevice)
primaryDevice = NULL;
} }
bool cDevice::WaitForAllDevicesReady(int Timeout) bool cDevice::WaitForAllDevicesReady(int Timeout)
@ -362,7 +364,6 @@ void cDevice::SetCamSlot(cCamSlot *CamSlot)
void cDevice::Shutdown(void) void cDevice::Shutdown(void)
{ {
deviceHooks.Clear(); deviceHooks.Clear();
primaryDevice = NULL;
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++) {
delete device[i]; delete device[i];
device[i] = NULL; device[i] = NULL;
@ -573,7 +574,7 @@ void cDevice::StartSectionHandler(void)
AttachFilter(eitFilter = new cEitFilter); AttachFilter(eitFilter = new cEitFilter);
AttachFilter(patFilter = new cPatFilter); AttachFilter(patFilter = new cPatFilter);
AttachFilter(sdtFilter = new cSdtFilter(patFilter)); AttachFilter(sdtFilter = new cSdtFilter(patFilter));
AttachFilter(nitFilter = new cNitFilter); AttachFilter(nitFilter = new cNitFilter(sdtFilter));
} }
} }
@ -784,6 +785,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (SetChannelDevice(Channel, LiveView)) { if (SetChannelDevice(Channel, LiveView)) {
// Start section handling: // Start section handling:
if (sectionHandler) { if (sectionHandler) {
patFilter->Trigger(Channel->Sid());
sectionHandler->SetChannel(Channel); sectionHandler->SetChannel(Channel);
sectionHandler->SetStatus(true); sectionHandler->SetStatus(true);
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.h 2.47 2013/02/16 15:20:01 kls Exp $ * $Id: device.h 2.47.1.1 2013/08/22 12:01:48 kls Exp $
*/ */
#ifndef __DEVICE_H #ifndef __DEVICE_H
@ -196,7 +196,7 @@ protected:
///< A derived class must call the MakePrimaryDevice() function of its ///< A derived class must call the MakePrimaryDevice() function of its
///< base class. ///< base class.
public: public:
bool IsPrimaryDevice(void) const { return this == primaryDevice; } bool IsPrimaryDevice(void) const { return this == primaryDevice && HasDecoder(); }
int CardIndex(void) const { return cardIndex; } int CardIndex(void) const { return cardIndex; }
///< Returns the card index of this device (0 ... MAXDEVICES - 1). ///< Returns the card index of this device (0 ... MAXDEVICES - 1).
int DeviceNumber(void) const; int DeviceNumber(void) const;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: diseqc.c 2.9 2011/09/17 14:13:31 kls Exp $ * $Id: diseqc.c 2.9.1.1 2013/05/02 09:33:12 kls Exp $
*/ */
#include "diseqc.h" #include "diseqc.h"
@ -192,7 +192,7 @@ const char *cDiseqc::GetScrBank(const char *s) const
} }
return p; return p;
} }
esyslog("ERROR: more than one scr bank in '%s'", s - 1); esyslog("ERROR: invalid value for scr bank in '%s'", s - 1);
return NULL; return NULL;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.c 2.88 2013/03/16 15:23:35 kls Exp $ * $Id: dvbdevice.c 2.88.1.4 2013/10/21 09:01:21 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -21,10 +21,7 @@
#include "menuitems.h" #include "menuitems.h"
#include "sourceparams.h" #include "sourceparams.h"
#if (DVB_API_VERSION << 8 | DVB_API_VERSION_MINOR) < 0x0508 static int DvbApiVersion = 0x0000; // the version of the DVB driver actually in use (will be determined by the first device created)
#define DTV_STREAM_ID DTV_DVBT2_PLP_ID
#define FE_CAN_MULTISTREAM 0x4000000
#endif
#define DVBS_TUNE_TIMEOUT 9000 //ms #define DVBS_TUNE_TIMEOUT 9000 //ms
#define DVBS_LOCK_TIMEOUT 2000 //ms #define DVBS_LOCK_TIMEOUT 2000 //ms
@ -700,7 +697,7 @@ void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
void cDvbTuner::ResetToneAndVoltage(void) void cDvbTuner::ResetToneAndVoltage(void)
{ {
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, bondedTuner ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_13));
CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
} }
@ -801,7 +798,8 @@ bool cDvbTuner::SetFrontend(void)
// DVB-S2 // DVB-S2
SETCMD(DTV_PILOT, PILOT_AUTO); SETCMD(DTV_PILOT, PILOT_AUTO);
SETCMD(DTV_ROLLOFF, dtp.RollOff()); SETCMD(DTV_ROLLOFF, dtp.RollOff());
SETCMD(DTV_STREAM_ID, dtp.StreamId()); if (DvbApiVersion >= 0x0508)
SETCMD(DTV_STREAM_ID, dtp.StreamId());
} }
else { else {
// DVB-S // DVB-S
@ -835,7 +833,11 @@ bool cDvbTuner::SetFrontend(void)
SETCMD(DTV_HIERARCHY, dtp.Hierarchy()); SETCMD(DTV_HIERARCHY, dtp.Hierarchy());
if (frontendType == SYS_DVBT2) { if (frontendType == SYS_DVBT2) {
// DVB-T2 // DVB-T2
SETCMD(DTV_STREAM_ID, dtp.StreamId()); if (DvbApiVersion >= 0x0508) {
SETCMD(DTV_STREAM_ID, dtp.StreamId());
}
else if (DvbApiVersion >= 0x0503)
SETCMD(DTV_DVBT2_PLP_ID_LEGACY, dtp.StreamId());
} }
tuneTimeout = DVBT_TUNE_TIMEOUT; tuneTimeout = DVBT_TUNE_TIMEOUT;
@ -1178,28 +1180,44 @@ bool cDvbDevice::QueryDeliverySystems(int fd_frontend)
LOG_ERROR; LOG_ERROR;
return false; return false;
} }
#if (DVB_API_VERSION << 8 | DVB_API_VERSION_MINOR) >= 0x0505
dtv_property Frontend[1]; dtv_property Frontend[1];
memset(&Frontend, 0, sizeof(Frontend));
dtv_properties CmdSeq; dtv_properties CmdSeq;
memset(&CmdSeq, 0, sizeof(CmdSeq)); // Determine the version of the running DVB API:
CmdSeq.props = Frontend; if (!DvbApiVersion) {
SETCMD(DTV_ENUM_DELSYS, 0); memset(&Frontend, 0, sizeof(Frontend));
int Result = ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq); memset(&CmdSeq, 0, sizeof(CmdSeq));
if (Result == 0) { CmdSeq.props = Frontend;
for (uint i = 0; i < Frontend[0].u.buffer.len; i++) { SETCMD(DTV_API_VERSION, 0);
if (numDeliverySystems >= MAXDELIVERYSYSTEMS) { if (ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
esyslog("ERROR: too many delivery systems on frontend %d/%d", adapter, frontend); LOG_ERROR;
break; return false;
} }
deliverySystems[numDeliverySystems++] = Frontend[0].u.buffer.data[i]; DvbApiVersion = Frontend[0].u.data;
} isyslog("DVB API version is 0x%04X (VDR was built with 0x%04X)", DvbApiVersion, DVBAPIVERSION);
} }
else { // Determine the types of delivery systems this device provides:
esyslog("ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode", adapter, frontend); bool LegacyMode = true;
#else if (DvbApiVersion >= 0x0505) {
{ memset(&Frontend, 0, sizeof(Frontend));
#endif memset(&CmdSeq, 0, sizeof(CmdSeq));
CmdSeq.props = Frontend;
SETCMD(DTV_ENUM_DELSYS, 0);
int Result = ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq);
if (Result == 0) {
for (uint i = 0; i < Frontend[0].u.buffer.len; i++) {
if (numDeliverySystems >= MAXDELIVERYSYSTEMS) {
esyslog("ERROR: too many delivery systems on frontend %d/%d", adapter, frontend);
break;
}
deliverySystems[numDeliverySystems++] = Frontend[0].u.buffer.data[i];
}
LegacyMode = false;
}
else {
esyslog("ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode", adapter, frontend);
}
}
if (LegacyMode) {
// Legacy mode (DVB-API < 5.5): // Legacy mode (DVB-API < 5.5):
switch (frontendInfo.type) { switch (frontendInfo.type) {
case FE_QPSK: deliverySystems[numDeliverySystems++] = SYS_DVBS; case FE_QPSK: deliverySystems[numDeliverySystems++] = SYS_DVBS;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.h 2.29 2013/03/07 09:42:29 kls Exp $ * $Id: dvbdevice.h 2.29.1.1 2013/04/09 13:43:33 kls Exp $
*/ */
#ifndef __DVBDEVICE_H #ifndef __DVBDEVICE_H
@ -14,10 +14,59 @@
#include <linux/dvb/version.h> #include <linux/dvb/version.h>
#include "device.h" #include "device.h"
#if (DVB_API_VERSION << 8 | DVB_API_VERSION_MINOR) < 0x0503 #define DVBAPIVERSION (DVB_API_VERSION << 8 | DVB_API_VERSION_MINOR)
#error VDR requires Linux DVB driver API version 5.3 or higher!
#if DVBAPIVERSION < 0x0500
#error VDR requires Linux DVB driver API version 5.0 or higher!
#endif #endif
// --- Definitions for older DVB API versions --------------------------------
#if DVBAPIVERSION < 0x0501
enum {
FE_CAN_2G_MODULATION = 0x10000000,
};
enum {
TRANSMISSION_MODE_4K = TRANSMISSION_MODE_AUTO + 1,
};
#endif
#if DVBAPIVERSION < 0x0502
enum {
FE_CAN_TURBO_FEC = 0x8000000,
};
#endif
#if DVBAPIVERSION < 0x0503
enum {
TRANSMISSION_MODE_1K = TRANSMISSION_MODE_4K + 1,
TRANSMISSION_MODE_16K,
TRANSMISSION_MODE_32K,
};
enum {
GUARD_INTERVAL_1_128 = GUARD_INTERVAL_AUTO + 1,
GUARD_INTERVAL_19_128,
GUARD_INTERVAL_19_256,
};
enum {
SYS_DVBT2 = SYS_DAB + 1,
};
#endif
#if DVBAPIVERSION < 0x0505
#define DTV_ENUM_DELSYS 44
#endif
#if DVBAPIVERSION < 0x0508
enum {
FE_CAN_MULTISTREAM = 0x4000000,
};
#define DTV_STREAM_ID 42
#define DTV_DVBT2_PLP_ID_LEGACY 43
#endif
// --- End of definitions for older DVB API versions -------------------------
#define MAXDVBDEVICES 8 #define MAXDVBDEVICES 8
#define MAXDELIVERYSYSTEMS 8 #define MAXDELIVERYSYSTEMS 8

4
eit.c
View File

@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * 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>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
* *
* $Id: eit.c 2.23 2012/12/04 11:10:10 kls Exp $ * $Id: eit.c 2.23.1.1 2013/10/12 11:24:51 kls Exp $
*/ */
#include "eit.h" #include "eit.h"
@ -404,7 +404,7 @@ void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
break; break;
case 0x14: { case 0x14: {
if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) if (Setup.SetSystemTime && Setup.TimeSource == Source() && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder))
cTDT TDT(Data); cTDT TDT(Data);
} }
break; break;

19
epg.c
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by * Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* *
* $Id: epg.c 2.23 2013/02/17 14:12:07 kls Exp $ * $Id: epg.c 2.23.1.1 2013/09/01 09:16:53 kls Exp $
*/ */
#include "epg.h" #include "epg.h"
@ -1140,16 +1140,19 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
class cEpgDataWriter : public cThread { class cEpgDataWriter : public cThread {
private: private:
cMutex mutex; cMutex mutex;
bool dump;
protected: protected:
virtual void Action(void); virtual void Action(void);
public: public:
cEpgDataWriter(void); cEpgDataWriter(void);
void SetDump(bool Dump) { dump = Dump; }
void Perform(void); void Perform(void);
}; };
cEpgDataWriter::cEpgDataWriter(void) cEpgDataWriter::cEpgDataWriter(void)
:cThread("epg data writer", true) :cThread("epg data writer", true)
{ {
dump = false;
} }
void cEpgDataWriter::Action(void) void cEpgDataWriter::Action(void)
@ -1169,7 +1172,8 @@ void cEpgDataWriter::Perform(void)
p->Cleanup(now); p->Cleanup(now);
} }
} }
cSchedules::Dump(); if (dump)
cSchedules::Dump();
} }
static cEpgDataWriter EpgDataWriter; static cEpgDataWriter EpgDataWriter;
@ -1203,6 +1207,7 @@ void cSchedules::SetEpgDataFileName(const char *FileName)
{ {
free(epgDataFileName); free(epgDataFileName);
epgDataFileName = FileName ? strdup(FileName) : NULL; epgDataFileName = FileName ? strdup(FileName) : NULL;
EpgDataWriter.SetDump(epgDataFileName != NULL);
} }
void cSchedules::SetModified(cSchedule *Schedule) void cSchedules::SetModified(cSchedule *Schedule)
@ -1217,12 +1222,10 @@ void cSchedules::Cleanup(bool Force)
lastDump = 0; lastDump = 0;
time_t now = time(NULL); time_t now = time(NULL);
if (now - lastDump > EPGDATAWRITEDELTA) { if (now - lastDump > EPGDATAWRITEDELTA) {
if (epgDataFileName) { if (Force)
if (Force) EpgDataWriter.Perform();
EpgDataWriter.Perform(); else if (!EpgDataWriter.Active())
else if (!EpgDataWriter.Active()) EpgDataWriter.Start();
EpgDataWriter.Start();
}
lastDump = now; lastDump = now;
} }
} }

28
font.c
View File

@ -6,7 +6,7 @@
* *
* BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya. * BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya.
* *
* $Id: font.c 2.13 2012/06/02 13:38:28 kls Exp $ * $Id: font.c 2.13.1.2 2014/01/25 14:25:29 kls Exp $
*/ */
#include "font.h" #include "font.h"
@ -382,10 +382,13 @@ void cFreetypeFont::DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColo
// A dummy font, in case there are no fonts installed: // A dummy font, in case there are no fonts installed:
class cDummyFont : public cFont { class cDummyFont : public cFont {
private:
int height;
public: public:
virtual int Width(uint c) const { return 10; } cDummyFont(int CharHeight) { height = CharHeight; }
virtual int Width(const char *s) const { return 50; } virtual int Width(uint c) const { return height; }
virtual int Height(void) const { return 20; } virtual int Width(const char *s) const { return height; }
virtual int Height(void) const { return height; }
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}; virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {};
}; };
@ -396,11 +399,8 @@ cFont *cFont::fonts[eDvbFontSize] = { NULL };
void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight) void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
{ {
cFont *f = CreateFont(Name, constrain(CharHeight, MINFONTSIZE, MAXFONTSIZE));
if (!f || !f->Height())
f = new cDummyFont;
delete fonts[Font]; delete fonts[Font];
fonts[Font] = f; fonts[Font] = CreateFont(Name, constrain(CharHeight, MINFONTSIZE, MAXFONTSIZE));
} }
const cFont *cFont::GetFont(eDvbFont Font) const cFont *cFont::GetFont(eDvbFont Font)
@ -423,9 +423,10 @@ const cFont *cFont::GetFont(eDvbFont Font)
cFont *cFont::CreateFont(const char *Name, int CharHeight, int CharWidth) cFont *cFont::CreateFont(const char *Name, int CharHeight, int CharWidth)
{ {
cString fn = GetFontFileName(Name); cString fn = GetFontFileName(Name);
if (*fn) cFont *f = *fn ? new cFreetypeFont(fn, CharHeight, CharWidth) : NULL;
return new cFreetypeFont(fn, CharHeight, CharWidth); if (!f || !f->Height())
return NULL; f = new cDummyFont(CharHeight);
return f;
} }
bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced) bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced)
@ -592,7 +593,7 @@ void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
p = Blank; p = Blank;
continue; continue;
} }
else { else if (w > 0) { // there has to be at least one character before the newline
// Here's the ugly part, where we don't have any whitespace to // Here's the ugly part, where we don't have any whitespace to
// punch in a newline, so we need to make room for it: // punch in a newline, so we need to make room for it:
if (Delim) if (Delim)
@ -608,8 +609,7 @@ void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
continue; continue;
} }
} }
else w += cw;
w += cw;
if (strchr("-.,:;!?_", *p)) { if (strchr("-.,:;!?_", *p)) {
Delim = p; Delim = p;
Blank = NULL; Blank = NULL;

4
font.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: font.h 2.7 2013/02/17 13:17:42 kls Exp $ * $Id: font.h 2.7.1.1 2014/01/25 14:24:51 kls Exp $
*/ */
#ifndef __FONT_H #ifndef __FONT_H
@ -75,7 +75,7 @@ public:
///< default width. Name is of the form "Family:Style", for instance ///< default width. Name is of the form "Family:Style", for instance
///< "Verdana:Bold Italic" or "Times New Roman". See GetAvailableFontNames() ///< "Verdana:Bold Italic" or "Times New Roman". See GetAvailableFontNames()
///< for how to get a list of all available font names. ///< for how to get a list of all available font names.
///< If the requested font can't be created, NULL is returned. ///< If the requested font can't be created, a dummy font is returned.
///< The caller must delete the font when it is no longer needed. ///< The caller must delete the font when it is no longer needed.
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false); static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false);
///< Queries the font configuration for a list of available font names, ///< Queries the font configuration for a list of available font names,

20
lirc.c
View File

@ -6,7 +6,7 @@
* *
* LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16. * LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
* *
* $Id: lirc.c 2.5 2013/02/11 15:25:42 kls Exp $ * $Id: lirc.c 2.5.1.2 2013/10/29 16:06:20 kls Exp $
*/ */
#include "lirc.h" #include "lirc.h"
@ -21,11 +21,9 @@ cLircRemote::cLircRemote(const char *DeviceName)
{ {
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, DeviceName); strcpy(addr.sun_path, DeviceName);
if (Connect()) { if (!Connect())
Start(); f = -1;
return; Start();
}
f = -1;
} }
cLircRemote::~cLircRemote() cLircRemote::~cLircRemote()
@ -67,14 +65,15 @@ void cLircRemote::Action(void)
bool repeat = false; bool repeat = false;
int timeout = -1; int timeout = -1;
while (Running() && f >= 0) { while (Running()) {
bool ready = cFile::FileReady(f, timeout); bool ready = f >= 0 && cFile::FileReady(f, timeout);
int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1; int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
if (ready && ret <= 0 ) { if (f < 0 || ready && ret <= 0) {
esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(RECONNECTDELAY) / 1000); esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(RECONNECTDELAY) / 1000);
close(f); if (f >= 0)
close(f);
f = -1; f = -1;
while (Running() && f < 0) { while (Running() && f < 0) {
cCondWait::SleepMs(RECONNECTDELAY); cCondWait::SleepMs(RECONNECTDELAY);
@ -111,6 +110,7 @@ void cLircRemote::Action(void)
else if (LastTime.Elapsed() < (uint)Setup.RcRepeatDelta) else if (LastTime.Elapsed() < (uint)Setup.RcRepeatDelta)
continue; // skip same keys coming in too fast continue; // skip same keys coming in too fast
else { else {
pressed = true;
repeat = true; repeat = true;
timeout = Delta * 10 / 9; timeout = Delta * 10 / 9;
} }

49
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 2.82 2013/03/18 09:11:48 kls Exp $ * $Id: menu.c 2.82.1.9 2015/01/13 09:52:59 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -181,9 +181,13 @@ cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
strn0cpy(name, data.name, sizeof(name)); strn0cpy(name, data.name, sizeof(name));
if (New) { if (New) {
channel = NULL; channel = NULL;
// clear non-editable members:
data.nid = 0; data.nid = 0;
data.tid = 0; data.tid = 0;
data.rid = 0; data.rid = 0;
*data.shortName = 0;
*data.provider = 0;
*data.portalName = 0;
} }
} }
Setup(); Setup();
@ -2185,6 +2189,7 @@ public:
const char *Name(void) { return name; } const char *Name(void) { return name; }
cRecording *Recording(void) { return recording; } cRecording *Recording(void) { return recording; }
bool IsDirectory(void) { return name != NULL; } bool IsDirectory(void) { return name != NULL; }
void SetRecording(cRecording *Recording) { recording = Recording; }
virtual void SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable); virtual void SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable);
}; };
@ -2302,14 +2307,12 @@ void cMenuRecordings::Set(bool Refresh)
} }
else else
delete Item; delete Item;
if (LastItem) { if (LastItem || LastDir) {
if (CurrentRecording && strcmp(CurrentRecording, recording->FileName()) == 0) if (CurrentRecording && strcmp(CurrentRecording, recording->FileName()) == 0)
SetCurrent(LastItem); SetCurrent(LastDir ? LastDir : LastItem);
} }
if (LastDir) { if (LastDir)
LastDir->IncrementCounter(recording->IsNew()); LastDir->IncrementCounter(recording->IsNew());
LastItem = LastDir;
}
} }
} }
if (Refresh) if (Refresh)
@ -2418,6 +2421,7 @@ eOSState cMenuRecordings::Delete(void)
Display(); Display();
if (!Count()) if (!Count())
return osBack; return osBack;
return osUser2;
} }
else else
Skins.Message(mtError, tr("Error while deleting recording!")); Skins.Message(mtError, tr("Error while deleting recording!"));
@ -2483,6 +2487,14 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
default: break; default: break;
} }
} }
else if (state == osUser2) {
// a recording in a sub folder was deleted, so update the current item
cOsdMenu *m = HasSubMenu() ? SubMenu() : this;
if (cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current())) {
if (cMenuRecordingItem *riSub = (cMenuRecordingItem *)m->Get(m->Current()))
ri->SetRecording(riSub->Recording());
}
}
if (Key == kYellow && HadSubMenu && !HasSubMenu()) { if (Key == kYellow && HadSubMenu && !HasSubMenu()) {
// the last recording in a subdirectory was deleted, so let's go back up // the last recording in a subdirectory was deleted, so let's go back up
cOsdMenu::Del(Current()); cOsdMenu::Del(Current());
@ -2650,7 +2662,7 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
ModifiedAppearance = true; ModifiedAppearance = true;
if (strcmp(data.FontFix, Setup.FontFix) || !DoubleEqual(data.FontFixSizeP, Setup.FontFixSizeP)) if (strcmp(data.FontFix, Setup.FontFix) || !DoubleEqual(data.FontFixSizeP, Setup.FontFixSizeP))
ModifiedAppearance = true; ModifiedAppearance = true;
if (data.AlwaysSortFoldersFirst != Setup.AlwaysSortFoldersFirst) if (data.AlwaysSortFoldersFirst != Setup.AlwaysSortFoldersFirst || data.RecordingDirs != Setup.RecordingDirs)
Recordings.ClearSortNames(); Recordings.ClearSortNames();
} }
@ -3366,7 +3378,7 @@ cMenuPluginItem::cMenuPluginItem(const char *Name, int Index)
cOsdObject *cMenuMain::pluginOsdObject = NULL; cOsdObject *cMenuMain::pluginOsdObject = NULL;
cMenuMain::cMenuMain(eOSState State) cMenuMain::cMenuMain(eOSState State, bool OpenSubMenus)
:cOsdMenu("") :cOsdMenu("")
{ {
SetMenuCategory(mcMain); SetMenuCategory(mcMain);
@ -3383,7 +3395,7 @@ cMenuMain::cMenuMain(eOSState State)
case osSchedule: AddSubMenu(new cMenuSchedule); break; case osSchedule: AddSubMenu(new cMenuSchedule); break;
case osChannels: AddSubMenu(new cMenuChannels); break; case osChannels: AddSubMenu(new cMenuChannels); break;
case osTimers: AddSubMenu(new cMenuTimers); break; case osTimers: AddSubMenu(new cMenuTimers); break;
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, OpenSubMenus)); break;
case osSetup: AddSubMenu(new cMenuSetup); break; case osSetup: AddSubMenu(new cMenuSetup); break;
case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break; case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break;
default: break; default: break;
@ -3450,7 +3462,7 @@ bool cMenuMain::Update(bool Force)
stopReplayItem = NULL; stopReplayItem = NULL;
} }
// Color buttons: // Color buttons:
SetHelp(!replaying ? tr("Button$Record") : NULL, tr("Button$Audio"), replaying ? NULL : tr("Button$Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Button$Resume") : tr("Button$Play")); SetHelp(!replaying ? tr("Button$Record") : NULL, tr("Button$Audio"), replaying || !Setup.PauseKeyHandling ? NULL : tr("Button$Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Button$Resume") : tr("Button$Play"));
result = true; result = true;
} }
@ -3545,7 +3557,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
} }
break; break;
case kYellow: if (!HadSubMenu) case kYellow: if (!HadSubMenu)
state = replaying ? osContinue : osPause; state = replaying || !Setup.PauseKeyHandling ? osContinue : osPause;
break; break;
case kBlue: if (!HadSubMenu) case kBlue: if (!HadSubMenu)
state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osRecordings; state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osRecordings;
@ -4731,7 +4743,10 @@ void cReplayControl::TimeSearchProcess(eKeys Key)
case kOk: case kOk:
if (timeSearchPos > 0) { if (timeSearchPos > 0) {
Seconds = min(Total - STAY_SECONDS_OFF_END, Seconds); Seconds = min(Total - STAY_SECONDS_OFF_END, Seconds);
Goto(SecondsToFrames(Seconds, FramesPerSecond()), Key == kDown || Key == kPause || Key == kOk); bool Still = Key == kDown || Key == kPause || Key == kOk;
Goto(SecondsToFrames(Seconds, FramesPerSecond()), Still);
if (!Still)
Play();
} }
timeSearchActive = false; timeSearchActive = false;
break; break;
@ -4779,8 +4794,10 @@ void cReplayControl::MarkToggle(void)
marks.Add(Current); marks.Add(Current);
bool Play, Forward; bool Play, Forward;
int Speed; int Speed;
if (Setup.PauseOnMarkSet || GetReplayMode(Play, Forward, Speed) && !Play) if (Setup.PauseOnMarkSet || GetReplayMode(Play, Forward, Speed) && !Play) {
Goto(Current, true); Goto(Current, true);
displayFrames = true;
}
} }
ShowTimed(2); ShowTimed(2);
marksModified = true; marksModified = true;
@ -4968,10 +4985,8 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
else else
Show(); Show();
break; break;
case kBack: if (Setup.DelTimeshiftRec) { case kBack: Hide();
cRecordControl* rc = cRecordControls::GetRecordControl(fileName); Stop();
return rc && rc->InstantId() ? osEnd : osRecordings;
}
return osRecordings; return osRecordings;
default: return osUnknown; default: return osUnknown;
} }

4
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.h 2.13 2012/12/07 13:44:13 kls Exp $ * $Id: menu.h 2.13.1.1 2013/10/16 09:46:15 kls Exp $
*/ */
#ifndef __MENU_H #ifndef __MENU_H
@ -107,7 +107,7 @@ private:
void Set(void); void Set(void);
bool Update(bool Force = false); bool Update(bool Force = false);
public: public:
cMenuMain(eOSState State = osUnknown); cMenuMain(eOSState State = osUnknown, bool OpenSubMenus = false);
virtual eOSState ProcessKey(eKeys Key); virtual eOSState ProcessKey(eKeys Key);
static cOsdObject *PluginOsdObject(void); static cOsdObject *PluginOsdObject(void);
}; };

View File

@ -12,7 +12,7 @@
# See the main source file 'vdr.c' for copyright information and # See the main source file 'vdr.c' for copyright information and
# how to reach the author. # how to reach the author.
# #
# $Id: newplugin 2.17 2013/01/12 13:46:00 kls Exp $ # $Id: newplugin 2.17.1.1 2013/05/02 10:04:06 kls Exp $
$PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n"; $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
@ -352,8 +352,8 @@ The next steps you should perform now are:
sub CreateFile sub CreateFile
{ {
my ($Name, $Content) = @_; my ($FileName, $Content) = @_;
open(FILE, ">$PLUGINDIR/$Name") || die "$Name: $!\n"; open(FILE, ">$PLUGINDIR/$FileName") || die "$FileName: $!\n";
print FILE $Content; print FILE $Content;
close(FILE); close(FILE);
} }

8
nit.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: nit.c 2.10 2013/03/07 09:42:29 kls Exp $ * $Id: nit.c 2.10.1.1 2014/03/11 09:29:59 kls Exp $
*/ */
#include "nit.h" #include "nit.h"
@ -19,8 +19,9 @@
#define DVB_SYSTEM_1 0 // see also dvbdevice.c #define DVB_SYSTEM_1 0 // see also dvbdevice.c
#define DVB_SYSTEM_2 1 #define DVB_SYSTEM_2 1
cNitFilter::cNitFilter(void) cNitFilter::cNitFilter(cSdtFilter *SdtFilter)
{ {
sdtFilter = SdtFilter;
numNits = 0; numNits = 0;
networkId = 0; networkId = 0;
Set(0x10, 0x40); // NIT Set(0x10, 0x40); // NIT
@ -183,6 +184,7 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
} }
} }
sdtFilter->Trigger(Source);
} }
break; break;
case SI::S2SatelliteDeliverySystemDescriptorTag: { case SI::S2SatelliteDeliverySystemDescriptorTag: {
@ -253,6 +255,7 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
} }
} }
sdtFilter->Trigger(Source);
} }
break; break;
case SI::TerrestrialDeliverySystemDescriptorTag: { case SI::TerrestrialDeliverySystemDescriptorTag: {
@ -316,6 +319,7 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
} }
} }
sdtFilter->Trigger(Source);
} }
break; break;
case SI::ExtensionDescriptorTag: { case SI::ExtensionDescriptorTag: {

6
nit.h
View File

@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: nit.h 1.3 2007/06/10 08:50:21 kls Exp $ * $Id: nit.h 2.0.1.1 2014/03/11 09:30:05 kls Exp $
*/ */
#ifndef __NIT_H #ifndef __NIT_H
#define __NIT_H #define __NIT_H
#include "filter.h" #include "filter.h"
#include "sdt.h"
#define MAXNITS 16 #define MAXNITS 16
#define MAXNETWORKNAME Utf8BufSize(256) #define MAXNETWORKNAME Utf8BufSize(256)
@ -26,13 +27,14 @@ private:
}; };
cSectionSyncer sectionSyncer; cSectionSyncer sectionSyncer;
cSdtFilter *sdtFilter;
cNit nits[MAXNITS]; cNit nits[MAXNITS];
u_short networkId; u_short networkId;
int numNits; int numNits;
protected: protected:
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
public: public:
cNitFilter(void); cNitFilter(cSdtFilter *SdtFilter);
virtual void SetStatus(bool On); virtual void SetStatus(bool On);
}; };

10
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.c 2.38 2013/02/14 15:50:19 kls Exp $ * $Id: osd.c 2.38.1.1 2013/05/18 12:41:48 kls Exp $
*/ */
#include "osd.h" #include "osd.h"
@ -639,8 +639,8 @@ void cBitmap::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quad
case 8: cy = y1; rx /= 2; break; case 8: cy = y1; rx /= 2; break;
default: ; default: ;
} }
int TwoASquare = 2 * rx * rx; int TwoASquare = max(1, 2 * rx * rx);
int TwoBSquare = 2 * ry * ry; int TwoBSquare = max(1, 2 * ry * ry);
int x = rx; int x = rx;
int y = 0; int y = 0;
int XChange = ry * ry * (1 - 2 * rx); int XChange = ry * ry * (1 - 2 * rx);
@ -1380,8 +1380,8 @@ void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants)
case 8: cy = y1; rx /= 2; break; case 8: cy = y1; rx /= 2; break;
default: ; default: ;
} }
int TwoASquare = 2 * rx * rx; int TwoASquare = max(1, 2 * rx * rx);
int TwoBSquare = 2 * ry * ry; int TwoBSquare = max(1, 2 * ry * ry);
int x = rx; int x = rx;
int y = 0; int y = 0;
int XChange = ry * ry * (1 - 2 * rx); int XChange = ry * ry * (1 - 2 * rx);

133
pat.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: pat.c 2.19 2012/11/25 14:12:21 kls Exp $ * $Id: pat.c 2.19.1.2 2014/02/19 09:31:29 kls Exp $
*/ */
#include "pat.h" #include "pat.h"
@ -12,9 +12,8 @@
#include "channels.h" #include "channels.h"
#include "libsi/section.h" #include "libsi/section.h"
#include "libsi/descriptor.h" #include "libsi/descriptor.h"
#include "thread.h"
#define PMT_SCAN_TIMEOUT 10 // seconds #define PMT_SCAN_TIMEOUT 1000 // ms
// --- cCaDescriptor --------------------------------------------------------- // --- cCaDescriptor ---------------------------------------------------------
@ -229,94 +228,115 @@ int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSy
// --- cPatFilter ------------------------------------------------------------ // --- cPatFilter ------------------------------------------------------------
//#define DEBUG_PAT_PMT
#ifdef DEBUG_PAT_PMT
#define DBGLOG(a...) { cString s = cString::sprintf(a); fprintf(stderr, "%s\n", *s); dsyslog("%s", *s); }
#else
#define DBGLOG(a...)
#endif
cPatFilter::cPatFilter(void) cPatFilter::cPatFilter(void)
{ {
pmtIndex = 0; Trigger(0);
pmtPid = 0;
pmtSid = 0;
lastPmtScan = 0;
numPmtEntries = 0;
Set(0x00, 0x00); // PAT Set(0x00, 0x00); // PAT
} }
void cPatFilter::SetStatus(bool On) void cPatFilter::SetStatus(bool On)
{ {
cMutexLock MutexLock(&mutex);
DBGLOG("PAT filter set status %d", On);
cFilter::SetStatus(On); cFilter::SetStatus(On);
pmtIndex = 0; Trigger();
pmtPid = 0;
pmtSid = 0;
lastPmtScan = 0;
numPmtEntries = 0;
} }
void cPatFilter::Trigger(void) void cPatFilter::Trigger(int Sid)
{ {
cMutexLock MutexLock(&mutex);
patVersion = -1;
pmtIndex = -1;
numPmtEntries = 0; numPmtEntries = 0;
if (Sid >= 0) {
sid = Sid;
DBGLOG("PAT filter trigger SID %d", Sid);
}
} }
bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version) bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion)
{ {
uint64_t v = Version; int Id = MakePmtId(PmtPid, Sid);
v <<= 32;
uint64_t id = (PmtPid | (Sid << 16)) & 0x00000000FFFFFFFFLL;
for (int i = 0; i < numPmtEntries; i++) { for (int i = 0; i < numPmtEntries; i++) {
if ((pmtVersion[i] & 0x00000000FFFFFFFFLL) == id) { if (pmtId[i] == Id) {
bool Changed = (pmtVersion[i] & 0x000000FF00000000LL) != v; if (pmtVersion[i] != Version) {
if (Changed) if (SetNewVersion)
pmtVersion[i] = id | v; pmtVersion[i] = Version;
return Changed; else
DBGLOG("PMT %d %2d %5d %2d -> %2d", Transponder(), i, PmtPid, pmtVersion[i], Version);
return true;
}
break;
} }
} }
if (numPmtEntries < MAXPMTENTRIES) return false;
pmtVersion[numPmtEntries++] = id | v; }
return true;
void cPatFilter::SwitchToNextPmtPid(void)
{
if (pmtIndex >= 0) {
Del(GetPmtPid(pmtIndex), SI::TableIdPMT);
pmtIndex = (pmtIndex + 1) % numPmtEntries;
Add(GetPmtPid(pmtIndex), SI::TableIdPMT);
}
} }
void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
{ {
cMutexLock MutexLock(&mutex);
if (Pid == 0x00) { if (Pid == 0x00) {
if (Tid == 0x00) { if (Tid == SI::TableIdPAT) {
if (pmtPid && time(NULL) - lastPmtScan > PMT_SCAN_TIMEOUT) { SI::PAT pat(Data, false);
Del(pmtPid, 0x02); if (!pat.CheckCRCAndParse())
pmtPid = 0; return;
pmtIndex++; if (pat.getVersionNumber() != patVersion) {
lastPmtScan = time(NULL); DBGLOG("PAT %d %d -> %d", Transponder(), patVersion, pat.getVersionNumber());
} if (pmtIndex >= 0) {
if (!pmtPid) { Del(GetPmtPid(pmtIndex), SI::TableIdPMT);
SI::PAT pat(Data, false); pmtIndex = -1;
if (!pat.CheckCRCAndParse()) }
return; numPmtEntries = 0;
SI::PAT::Association assoc; SI::PAT::Association assoc;
int Index = 0;
for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) { for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
if (!assoc.isNITPid()) { if (!assoc.isNITPid() && numPmtEntries < MAXPMTENTRIES) {
if (Index++ >= pmtIndex && Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId())) { DBGLOG(" PMT pid %2d %5d SID %5d", numPmtEntries, assoc.getPid(), assoc.getServiceId());
pmtPid = assoc.getPid(); pmtId[numPmtEntries] = MakePmtId(assoc.getPid(), assoc.getServiceId());
pmtSid = assoc.getServiceId(); pmtVersion[numPmtEntries] = -1;
Add(pmtPid, 0x02); if (sid == assoc.getServiceId()) {
break; pmtIndex = numPmtEntries;
DBGLOG("sid = %d pmtIndex = %d", sid, pmtIndex);
} }
numPmtEntries++;
} }
} }
if (!pmtPid) if (numPmtEntries > 0 && pmtIndex < 0)
pmtIndex = 0; pmtIndex = 0;
Add(GetPmtPid(pmtIndex), SI::TableIdPMT);
patVersion = pat.getVersionNumber();
timer.Set(PMT_SCAN_TIMEOUT);
} }
} }
} }
else if (Pid == pmtPid && Tid == SI::TableIdPMT && Source() && Transponder()) { else if (Tid == SI::TableIdPMT && Source() && Transponder()) {
timer.Set(PMT_SCAN_TIMEOUT);
SI::PMT pmt(Data, false); SI::PMT pmt(Data, false);
if (!pmt.CheckCRCAndParse()) if (!pmt.CheckCRCAndParse())
return; return;
if (pmt.getServiceId() != pmtSid) if (!PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber())) {
return; // skip broken PMT records SwitchToNextPmtPid();
if (!PmtVersionChanged(pmtPid, pmt.getTableIdExtension(), pmt.getVersionNumber())) {
lastPmtScan = 0; // this triggers the next scan
return; return;
} }
if (!Channels.Lock(true, 10)) { if (!Channels.Lock(true, 10))
numPmtEntries = 0; // to make sure we try again
return; return;
} PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber(), true);
SwitchToNextPmtPid();
cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), pmt.getServiceId()); cChannel *Channel = Channels.GetByServiceID(Source(), Transponder(), pmt.getServiceId());
if (Channel) { if (Channel) {
SI::CaDescriptor *d; SI::CaDescriptor *d;
@ -552,7 +572,12 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors)); Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
} }
lastPmtScan = 0; // this triggers the next scan
Channels.Unlock(); Channels.Unlock();
} }
if (timer.TimedOut()) {
if (pmtIndex >= 0)
DBGLOG("PMT timeout %d", pmtIndex);
SwitchToNextPmtPid();
timer.Set(PMT_SCAN_TIMEOUT);
}
} }

20
pat.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: pat.h 2.3 2013/02/16 15:20:24 kls Exp $ * $Id: pat.h 2.3.1.1 2014/02/18 14:12:24 kls Exp $
*/ */
#ifndef __PAT_H #ifndef __PAT_H
@ -12,24 +12,30 @@
#include <stdint.h> #include <stdint.h>
#include "filter.h" #include "filter.h"
#include "thread.h"
#define MAXPMTENTRIES 64 #define MAXPMTENTRIES 64
class cPatFilter : public cFilter { class cPatFilter : public cFilter {
private: private:
time_t lastPmtScan; cMutex mutex;
cTimeMs timer;
int patVersion;
int pmtIndex; int pmtIndex;
int pmtPid; int pmtId[MAXPMTENTRIES];
int pmtSid; int pmtVersion[MAXPMTENTRIES];
uint64_t pmtVersion[MAXPMTENTRIES];
int numPmtEntries; int numPmtEntries;
bool PmtVersionChanged(int PmtPid, int Sid, int Version); int sid;
int GetPmtPid(int Index) { return pmtId[Index] & 0x0000FFFF; }
int MakePmtId(int PmtPid, int Sid) { return PmtPid | (Sid << 16); }
bool PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion = false);
void SwitchToNextPmtPid(void);
protected: protected:
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
public: public:
cPatFilter(void); cPatFilter(void);
virtual void SetStatus(bool On); virtual void SetStatus(bool On);
void Trigger(void); void Trigger(int Sid = -1);
}; };
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid); int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recorder.c 2.17 2012/09/22 11:53:57 kls Exp $ * $Id: recorder.c 2.17.1.2 2014/02/21 09:21:30 kls Exp $
*/ */
#include "recorder.h" #include "recorder.h"
@ -14,7 +14,7 @@
// The maximum time we wait before assuming that a recorded video data stream // The maximum time we wait before assuming that a recorded video data stream
// is broken: // is broken:
#define MAXBROKENTIMEOUT 30 // seconds #define MAXBROKENTIMEOUT 30000 // milliseconds
#define MINFREEDISKSPACE (512) // MB #define MINFREEDISKSPACE (512) // MB
#define DISKCHECKINTERVAL 100 // seconds #define DISKCHECKINTERVAL 100 // seconds
@ -117,7 +117,7 @@ void cRecorder::Receive(uchar *Data, int Length)
void cRecorder::Action(void) void cRecorder::Action(void)
{ {
time_t t = time(NULL); cTimeMs t(MAXBROKENTIMEOUT);
bool InfoWritten = false; bool InfoWritten = false;
bool FirstIframeSeen = false; bool FirstIframeSeen = false;
while (Running()) { while (Running()) {
@ -154,22 +154,22 @@ void cRecorder::Action(void)
recordFile->Write(pmt, TS_SIZE); recordFile->Write(pmt, TS_SIZE);
fileSize += TS_SIZE; fileSize += TS_SIZE;
} }
t.Set(MAXBROKENTIMEOUT);
} }
if (recordFile->Write(b, Count) < 0) { if (recordFile->Write(b, Count) < 0) {
LOG_ERROR_STR(fileName->Name()); LOG_ERROR_STR(fileName->Name());
break; break;
} }
fileSize += Count; fileSize += Count;
t = time(NULL);
} }
} }
ringBuffer->Del(Count); ringBuffer->Del(Count);
} }
} }
if (time(NULL) - t > MAXBROKENTIMEOUT) { if (t.TimedOut()) {
esyslog("ERROR: video data stream broken"); esyslog("ERROR: video data stream broken");
ShutdownHandler.RequestEmergencyExit(); ShutdownHandler.RequestEmergencyExit();
t = time(NULL); t.Set(MAXBROKENTIMEOUT);
} }
} }
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.c 2.91 2013/03/11 10:34:41 kls Exp $ * $Id: recording.c 2.91.1.9 2015/01/17 13:50:38 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -63,6 +63,7 @@
#define REMOVELATENCY 10 // seconds to wait until next check after removing a file #define REMOVELATENCY 10 // seconds to wait until next check after removing a file
#define MARKSUPDATEDELTA 10 // seconds between checks for updating editing marks #define MARKSUPDATEDELTA 10 // seconds between checks for updating editing marks
#define MININDEXAGE 3600 // seconds before an index file is considered no longer to be written #define MININDEXAGE 3600 // seconds before an index file is considered no longer to be written
#define MAXREMOVETIME 10 // seconds after which to return from removing deleted recordings
#define MAX_LINK_LEVEL 6 #define MAX_LINK_LEVEL 6
@ -72,6 +73,7 @@ bool DirectoryEncoding = false;
int InstanceId = 0; int InstanceId = 0;
cRecordings DeletedRecordings(true); cRecordings DeletedRecordings(true);
static cRecordings VanishedRecordings;
// --- cRemoveDeletedRecordingsThread ---------------------------------------- // --- cRemoveDeletedRecordingsThread ----------------------------------------
@ -92,11 +94,16 @@ void cRemoveDeletedRecordingsThread::Action(void)
// Make sure only one instance of VDR does this: // Make sure only one instance of VDR does this:
cLockFile LockFile(VideoDirectory); cLockFile LockFile(VideoDirectory);
if (LockFile.Lock()) { if (LockFile.Lock()) {
time_t StartTime = time(NULL);
bool deleted = false; bool deleted = false;
cThreadLock DeletedRecordingsLock(&DeletedRecordings); cThreadLock DeletedRecordingsLock(&DeletedRecordings);
for (cRecording *r = DeletedRecordings.First(); r; ) { for (cRecording *r = DeletedRecordings.First(); r; ) {
if (cIoThrottle::Engaged()) if (cIoThrottle::Engaged())
return; return;
if (time(NULL) - StartTime > MAXREMOVETIME)
return; // don't stay here too long
if (cRemote::HasKeys())
return; // react immediately on user input
if (r->Deleted() && time(NULL) - r->Deleted() > DELETEDLIFETIME) { if (r->Deleted() && time(NULL) - r->Deleted() > DELETEDLIFETIME) {
cRecording *next = DeletedRecordings.Next(r); cRecording *next = DeletedRecordings.Next(r);
r->Remove(); r->Remove();
@ -178,40 +185,52 @@ void AssertFreeDiskSpace(int Priority, bool Force)
return; // the next call will actually remove it return; // the next call will actually remove it
} }
// No "deleted" files to remove, so let's see if we can delete a recording: // No "deleted" files to remove, so let's see if we can delete a recording:
isyslog("...no deleted recording found, trying to delete an old recording..."); if (Priority > 0) {
cThreadLock RecordingsLock(&Recordings); isyslog("...no deleted recording found, trying to delete an old recording...");
if (Recordings.Count()) { cThreadLock RecordingsLock(&Recordings);
cRecording *r = Recordings.First(); if (Recordings.Count()) {
cRecording *r0 = NULL; cRecording *r = Recordings.First();
while (r) { cRecording *r0 = NULL;
if (r->IsOnVideoDirectoryFileSystem()) { // only delete recordings that will actually increase the free video disk space while (r) {
if (!r->IsEdited() && r->Lifetime() < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever if (r->IsOnVideoDirectoryFileSystem()) { // only delete recordings that will actually increase the free video disk space
if ((r->Lifetime() == 0 && Priority > r->Priority()) || // the recording has no guaranteed lifetime and the new recording has higher priority if (!r->IsEdited() && r->Lifetime() < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever
(r->Lifetime() > 0 && (time(NULL) - r->Start()) / SECSINDAY >= r->Lifetime())) { // the recording's guaranteed lifetime has expired if ((r->Lifetime() == 0 && Priority > r->Priority()) || // the recording has no guaranteed lifetime and the new recording has higher priority
if (r0) { (r->Lifetime() > 0 && (time(NULL) - r->Start()) / SECSINDAY >= r->Lifetime())) { // the recording's guaranteed lifetime has expired
if (r->Priority() < r0->Priority() || (r->Priority() == r0->Priority() && r->Start() < r0->Start())) if (r0) {
r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities) if (r->Priority() < r0->Priority() || (r->Priority() == r0->Priority() && r->Start() < r0->Start()))
r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
}
else
r0 = r;
} }
else
r0 = r;
} }
} }
r = Recordings.Next(r);
} }
r = Recordings.Next(r); if (r0 && r0->Delete()) {
Recordings.Del(r0);
return;
} }
if (r0 && r0->Delete()) {
Recordings.Del(r0);
return;
} }
// Unable to free disk space, but there's nothing we can do about that...
isyslog("...no old recording found, giving up");
} }
// Unable to free disk space, but there's nothing we can do about that... else
isyslog("...no old recording found, giving up"); isyslog("...no deleted recording found, priority %d too low to trigger deleting an old recording", Priority);
Skins.QueueMessage(mtWarning, tr("Low disk space!"), 5, -1); Skins.QueueMessage(mtWarning, tr("Low disk space!"), 5, -1);
} }
LastFreeDiskCheck = time(NULL); LastFreeDiskCheck = time(NULL);
} }
} }
// --- Clear vanished recordings ---------------------------------------------
void ClearVanishedRecordings(void)
{
cThreadLock RecordingsLock(&Recordings); // yes, it *is* Recordings!
VanishedRecordings.Clear();
}
// --- cResumeFile ----------------------------------------------------------- // --- cResumeFile -----------------------------------------------------------
cResumeFile::cResumeFile(const char *FileName, bool IsPesRecording) cResumeFile::cResumeFile(const char *FileName, bool IsPesRecording)
@ -561,6 +580,7 @@ char *ExchangeChars(char *s, bool ToFileSystem)
// characters that can be mapped to other characters: // characters that can be mapped to other characters:
case ' ': *p = '_'; break; case ' ': *p = '_'; break;
case FOLDERDELIMCHAR: *p = '/'; break; case FOLDERDELIMCHAR: *p = '/'; break;
case '/': *p = FOLDERDELIMCHAR; break;
// characters that have to be encoded: // characters that have to be encoded:
default: default:
if (NeedsConversion(p)) { if (NeedsConversion(p)) {
@ -583,6 +603,7 @@ char *ExchangeChars(char *s, bool ToFileSystem)
switch (*p) { switch (*p) {
// mapped characters: // mapped characters:
case '_': *p = ' '; break; case '_': *p = ' '; break;
case FOLDERDELIMCHAR: *p = '/'; break;
case '/': *p = FOLDERDELIMCHAR; break; case '/': *p = FOLDERDELIMCHAR; break;
// encoded characters: // encoded characters:
case '#': { case '#': {
@ -943,14 +964,22 @@ char *cRecording::SortName(void) const
{ {
char **sb = (RecordingsSortMode == rsmName) ? &sortBufferName : &sortBufferTime; char **sb = (RecordingsSortMode == rsmName) ? &sortBufferName : &sortBufferTime;
if (!*sb) { if (!*sb) {
char *s = strdup(FileName() + strlen(VideoDirectory)); if (RecordingsSortMode == rsmTime && !Setup.RecordingDirs) {
if (RecordingsSortMode != rsmName || Setup.AlwaysSortFoldersFirst) char buf[32];
s = StripEpisodeName(s, RecordingsSortMode != rsmName); struct tm tm_r;
strreplace(s, '/', '0'); // some locales ignore '/' when sorting strftime(buf, sizeof(buf), "%Y%m%d%H%I", localtime_r(&start, &tm_r));
int l = strxfrm(NULL, s, 0) + 1; *sb = strdup(buf);
*sb = MALLOC(char, l); }
strxfrm(*sb, s, l); else {
free(s); char *s = strdup(FileName() + strlen(VideoDirectory));
if (RecordingsSortMode != rsmName || Setup.AlwaysSortFoldersFirst)
s = StripEpisodeName(s, RecordingsSortMode != rsmName);
strreplace(s, '/', '0'); // some locales ignore '/' when sorting
int l = strxfrm(NULL, s, 0) + 1;
*sb = MALLOC(char, l);
strxfrm(*sb, s, l);
free(s);
}
} }
return *sb; return *sb;
} }
@ -1227,6 +1256,7 @@ cRecordings::cRecordings(bool Deleted)
:cThread("video directory scanner") :cThread("video directory scanner")
{ {
deleted = Deleted; deleted = Deleted;
initial = true;
lastUpdate = 0; lastUpdate = 0;
state = 0; state = 0;
} }
@ -1258,8 +1288,9 @@ void cRecordings::Refresh(bool Foreground)
ScanVideoDir(VideoDirectory, Foreground); ScanVideoDir(VideoDirectory, Foreground);
} }
void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel) void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel, int DirLevel)
{ {
// Find any new recordings:
cReadDir d(DirName); cReadDir d(DirName);
struct dirent *e; struct dirent *e;
while ((Foreground || Running()) && (e = d.Next()) != NULL) { while ((Foreground || Running()) && (e = d.Next()) != NULL) {
@ -1278,25 +1309,42 @@ void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLev
} }
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) { if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
cRecording *r = new cRecording(buffer); if (deleted || initial || !GetByName(buffer)) {
if (r->Name()) { cRecording *r = new cRecording(buffer);
r->NumFrames(); // initializes the numFrames member if (r->Name()) {
r->FileSizeMB(); // initializes the fileSizeMB member r->NumFrames(); // initializes the numFrames member
if (deleted) r->FileSizeMB(); // initializes the fileSizeMB member
r->deleted = time(NULL); r->IsOnVideoDirectoryFileSystem(); // initializes the isOnVideoDirectoryFileSystem member
Lock(); if (deleted)
Add(r); r->deleted = time(NULL);
ChangeState(); Lock();
Unlock(); Add(r);
ChangeState();
Unlock();
}
else
delete r;
} }
else
delete r;
} }
else else
ScanVideoDir(buffer, Foreground, LinkLevel + Link); ScanVideoDir(buffer, Foreground, LinkLevel + Link, DirLevel + 1);
} }
} }
} }
// Handle any vanished recordings:
if (!deleted && !initial && DirLevel == 0) {
for (cRecording *recording = First(); recording; ) {
cRecording *r = recording;
recording = Next(recording);
if (access(r->FileName(), F_OK) != 0) {
Lock();
Del(r, false);
VanishedRecordings.Add(r);
ChangeState();
Unlock();
}
}
}
} }
bool cRecordings::StateChanged(int &State) bool cRecordings::StateChanged(int &State)
@ -1337,6 +1385,7 @@ bool cRecordings::Update(bool Wait)
cRecording *cRecordings::GetByName(const char *FileName) cRecording *cRecordings::GetByName(const char *FileName)
{ {
if (FileName) { if (FileName) {
LOCK_THREAD;
for (cRecording *recording = First(); recording; recording = Next(recording)) { for (cRecording *recording = First(); recording; recording = Next(recording)) {
if (strcmp(recording->FileName(), FileName) == 0) if (strcmp(recording->FileName(), FileName) == 0)
return recording; return recording;
@ -1697,6 +1746,7 @@ void cIndexFileGenerator::Action(void)
off_t FileSize = 0; off_t FileSize = 0;
off_t FrameOffset = -1; off_t FrameOffset = -1;
Skins.QueueMessage(mtInfo, tr("Regenerating index file")); Skins.QueueMessage(mtInfo, tr("Regenerating index file"));
bool Stuffed = false;
while (Running()) { while (Running()) {
// Rewind input file: // Rewind input file:
if (Rewind) { if (Rewind) {
@ -1760,10 +1810,25 @@ void cIndexFileGenerator::Action(void)
else if (ReplayFile) { else if (ReplayFile) {
int Result = Buffer.Read(ReplayFile, BufferChunks); int Result = Buffer.Read(ReplayFile, BufferChunks);
if (Result == 0) { // EOF if (Result == 0) { // EOF
ReplayFile = FileName.NextFile(); if (Buffer.Available() > 0 && !Stuffed) {
FileSize = 0; // So the last call to Buffer.Get() returned NULL, but there is still
FrameOffset = -1; // data in the buffer, and we're at the end of the current TS file.
Buffer.Clear(); // The remaining data in the buffer is less than what's needed for the
// frame detector to analyze frames, so we need to put some stuffing
// packets into the buffer to flush out the rest of the data (otherwise
// any frames within the remaining data would not be seen here):
uchar StuffingPacket[TS_SIZE] = { TS_SYNC_BYTE, 0xFF };
for (int i = 0; i <= MIN_TS_PACKETS_FOR_FRAME_DETECTOR; i++)
Buffer.Put(StuffingPacket, sizeof(StuffingPacket));
Stuffed = true;
}
else {
ReplayFile = FileName.NextFile();
FileSize = 0;
FrameOffset = -1;
Buffer.Clear();
Stuffed = false;
}
} }
} }
// Recording has been processed: // Recording has been processed:

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.h 2.46 2013/03/04 14:01:23 kls Exp $ * $Id: recording.h 2.46.1.1 2013/12/25 10:54:05 kls Exp $
*/ */
#ifndef __RECORDING_H #ifndef __RECORDING_H
@ -26,6 +26,7 @@ extern bool DirectoryEncoding;
extern int InstanceId; extern int InstanceId;
void RemoveDeletedRecordings(void); void RemoveDeletedRecordings(void);
void ClearVanishedRecordings(void);
void AssertFreeDiskSpace(int Priority = 0, bool Force = false); void AssertFreeDiskSpace(int Priority = 0, bool Force = false);
///< The special Priority value -1 means that we shall get rid of any ///< The special Priority value -1 means that we shall get rid of any
///< deleted recordings faster than normal (because we're cutting). ///< deleted recordings faster than normal (because we're cutting).
@ -160,11 +161,12 @@ class cRecordings : public cList<cRecording>, public cThread {
private: private:
static char *updateFileName; static char *updateFileName;
bool deleted; bool deleted;
bool initial;
time_t lastUpdate; time_t lastUpdate;
int state; int state;
const char *UpdateFileName(void); const char *UpdateFileName(void);
void Refresh(bool Foreground = false); void Refresh(bool Foreground = false);
void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0, int DirLevel = 0);
protected: protected:
void Action(void); void Action(void);
public: public:
@ -199,6 +201,8 @@ public:
///< this value is unknown. ///< this value is unknown.
}; };
/// Any access to Recordings that loops through the list of recordings
/// needs to hold a thread lock on this object!
extern cRecordings Recordings; extern cRecordings Recordings;
extern cRecordings DeletedRecordings; extern cRecordings DeletedRecordings;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remote.c 2.8 2013/02/03 15:44:55 kls Exp $ * $Id: remote.c 2.8.1.1 2014/02/15 12:44:48 kls Exp $
*/ */
#include "remote.h" #include "remote.h"
@ -297,7 +297,7 @@ int cKbdRemote::MapCodeToFunc(uint64_t Code)
void cKbdRemote::PutKey(uint64_t Code, bool Repeat, bool Release) void cKbdRemote::PutKey(uint64_t Code, bool Repeat, bool Release)
{ {
if (rawMode || !Put(Code, Repeat, Release)) { if (rawMode || (!Put(Code, Repeat, Release) && !IsLearning())) {
if (int func = MapCodeToFunc(Code)) if (int func = MapCodeToFunc(Code))
Put(KBDKEY(func), Repeat, Release); Put(KBDKEY(func), Repeat, Release);
} }

103
remux.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.c 2.75 2013/03/03 10:37:58 kls Exp $ * $Id: remux.c 2.75.1.6 2014/04/13 13:59:21 kls Exp $
*/ */
#include "remux.h" #include "remux.h"
@ -23,6 +23,10 @@ static bool DebugFrames = false;
#define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a) #define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
#define dbgframes(a...) if (DebugFrames) fprintf(stderr, a) #define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
#define MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION 6
#define WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION (MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION / 2)
#define WRN_TS_PACKETS_FOR_FRAME_DETECTOR (MIN_TS_PACKETS_FOR_FRAME_DETECTOR / 2)
#define EMPTY_SCANNER (0xFFFFFFFF) #define EMPTY_SCANNER (0xFFFFFFFF)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader) ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
@ -231,7 +235,7 @@ cTsPayload::cTsPayload(void)
data = NULL; data = NULL;
length = 0; length = 0;
pid = -1; pid = -1;
index = 0; Reset();
} }
cTsPayload::cTsPayload(uchar *Data, int Length, int Pid) cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
@ -239,12 +243,25 @@ cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
Setup(Data, Length, Pid); Setup(Data, Length, Pid);
} }
uchar cTsPayload::SetEof(void)
{
length = index; // triggers EOF
return 0x00;
}
void cTsPayload::Reset(void)
{
index = 0;
numPacketsPid = 0;
numPacketsOther = 0;
}
void cTsPayload::Setup(uchar *Data, int Length, int Pid) void cTsPayload::Setup(uchar *Data, int Length, int Pid)
{ {
data = Data; data = Data;
length = Length; length = Length;
pid = Pid >= 0 ? Pid : TsPid(Data); pid = Pid >= 0 ? Pid : TsPid(Data);
index = 0; Reset();
} }
uchar cTsPayload::GetByte(void) uchar cTsPayload::GetByte(void)
@ -255,20 +272,22 @@ uchar cTsPayload::GetByte(void)
if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end
uchar *p = data + index; uchar *p = data + index;
if (TsPid(p) == pid) { // only handle TS packets for the initial PID if (TsPid(p) == pid) { // only handle TS packets for the initial PID
if (++numPacketsPid > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
return SetEof();
if (TsHasPayload(p)) { if (TsHasPayload(p)) {
if (index > 0 && TsPayloadStart(p)) { // checking index to not skip the very first TS packet if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet
length = index; // triggers EOF return SetEof();
return 0x00;
}
index += TsPayloadOffset(p); index += TsPayloadOffset(p);
break; break;
} }
} }
else if (TsPid(p) == PATPID)
return SetEof(); // caller must see PAT packets in case of index regeneration
else
numPacketsOther++;
} }
else { else
length = index; // triggers EOF return SetEof();
return 0x00;
}
} }
} }
return data[index++]; return data[index++];
@ -302,6 +321,8 @@ void cTsPayload::SetByte(uchar Byte, int Index)
bool cTsPayload::Find(uint32_t Code) bool cTsPayload::Find(uint32_t Code)
{ {
int OldIndex = index; int OldIndex = index;
int OldNumPacketsPid = numPacketsPid;
int OldNumPacketsOther = numPacketsOther;
uint32_t Scanner = EMPTY_SCANNER; uint32_t Scanner = EMPTY_SCANNER;
while (!Eof()) { while (!Eof()) {
Scanner = (Scanner << 8) | GetByte(); Scanner = (Scanner << 8) | GetByte();
@ -309,9 +330,19 @@ bool cTsPayload::Find(uint32_t Code)
return true; return true;
} }
index = OldIndex; index = OldIndex;
numPacketsPid = OldNumPacketsPid;
numPacketsOther = OldNumPacketsOther;
return false; return false;
} }
void cTsPayload::Statistics(void) const
{
if (numPacketsPid + numPacketsOther > WRN_TS_PACKETS_FOR_FRAME_DETECTOR)
dsyslog("WARNING: required (%d+%d) TS packets to determine frame type", numPacketsOther, numPacketsPid);
if (numPacketsPid > WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
dsyslog("WARNING: required %d video TS packets to determine frame type", numPacketsPid);
}
// --- cPatPmtGenerator ------------------------------------------------------ // --- cPatPmtGenerator ------------------------------------------------------
cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel) cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
@ -1004,6 +1035,7 @@ protected:
bool debug; bool debug;
bool newFrame; bool newFrame;
bool independentFrame; bool independentFrame;
int iFrameTemporalReferenceOffset;
public: public:
cFrameParser(void); cFrameParser(void);
virtual ~cFrameParser() {}; virtual ~cFrameParser() {};
@ -1017,6 +1049,7 @@ public:
void SetDebug(bool Debug) { debug = Debug; } void SetDebug(bool Debug) { debug = Debug; }
bool NewFrame(void) { return newFrame; } bool NewFrame(void) { return newFrame; }
bool IndependentFrame(void) { return independentFrame; } bool IndependentFrame(void) { return independentFrame; }
int IFrameTemporalReferenceOffset(void) { return iFrameTemporalReferenceOffset; }
}; };
cFrameParser::cFrameParser(void) cFrameParser::cFrameParser(void)
@ -1024,6 +1057,7 @@ cFrameParser::cFrameParser(void)
debug = true; debug = true;
newFrame = false; newFrame = false;
independentFrame = false; independentFrame = false;
iFrameTemporalReferenceOffset = 0;
} }
// --- cAudioParser ---------------------------------------------------------- // --- cAudioParser ----------------------------------------------------------
@ -1056,6 +1090,7 @@ class cMpeg2Parser : public cFrameParser {
private: private:
uint32_t scanner; uint32_t scanner;
bool seenIndependentFrame; bool seenIndependentFrame;
int lastIFrameTemporalReference;
public: public:
cMpeg2Parser(void); cMpeg2Parser(void);
virtual int Parse(const uchar *Data, int Length, int Pid); virtual int Parse(const uchar *Data, int Length, int Pid);
@ -1065,6 +1100,7 @@ cMpeg2Parser::cMpeg2Parser(void)
{ {
scanner = EMPTY_SCANNER; scanner = EMPTY_SCANNER;
seenIndependentFrame = false; seenIndependentFrame = false;
lastIFrameTemporalReference = -1; // invalid
} }
int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid) int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
@ -1089,10 +1125,25 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
scanner = OldScanner; scanner = OldScanner;
return tsPayload.Used() - TS_SIZE; return tsPayload.Used() - TS_SIZE;
} }
uchar b1 = tsPayload.GetByte();
uchar b2 = tsPayload.GetByte();
int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
uchar FrameType = (b2 >> 3) & 0x07;
if (tsPayload.Find(0x000001B5)) { // Extension start code
if (((tsPayload.GetByte() & 0xF0) >> 4) == 0x08) { // Picture coding extension
tsPayload.GetByte();
uchar PictureStructure = tsPayload.GetByte() & 0x03;
if (PictureStructure == 0x02) // bottom field
break;
}
}
newFrame = true; newFrame = true;
tsPayload.GetByte();
uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07;
independentFrame = FrameType == 1; // I-Frame independentFrame = FrameType == 1; // I-Frame
if (independentFrame) {
if (lastIFrameTemporalReference >= 0)
iFrameTemporalReferenceOffset = TemporalReference - lastIFrameTemporalReference;
lastIFrameTemporalReference = TemporalReference;
}
if (debug) { if (debug) {
seenIndependentFrame |= independentFrame; seenIndependentFrame |= independentFrame;
if (seenIndependentFrame) { if (seenIndependentFrame) {
@ -1100,11 +1151,11 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
dbgframes("%c", FrameTypes[FrameType]); dbgframes("%c", FrameTypes[FrameType]);
} }
} }
tsPayload.Statistics();
break; break;
} }
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit... || tsPayload.Eof()) // or if we're out of data
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
break; break;
} }
return tsPayload.Used(); return tsPayload.Used();
@ -1203,7 +1254,7 @@ uint32_t cH264Parser::GetBits(int Bits)
uint32_t cH264Parser::GetGolombUe(void) uint32_t cH264Parser::GetGolombUe(void)
{ {
int z = -1; int z = -1;
for (int b = 0; !b; z++) for (int b = 0; !b && z < 32; z++) // limiting z to no get stuck if GetBit() always returns 0
b = GetBit(); b = GetBit();
return (1 << z) - 1 + GetBits(z); return (1 << z) - 1 + GetBits(z);
} }
@ -1239,13 +1290,17 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid)
case nutAccessUnitDelimiter: ParseAccessUnitDelimiter(); case nutAccessUnitDelimiter: ParseAccessUnitDelimiter();
gotAccessUnitDelimiter = true; gotAccessUnitDelimiter = true;
break; break;
case nutSequenceParameterSet: ParseSequenceParameterSet(); case nutSequenceParameterSet: if (gotAccessUnitDelimiter) {
gotSequenceParameterSet = true; ParseSequenceParameterSet();
gotSequenceParameterSet = true;
}
break; break;
case nutCodedSliceNonIdr: case nutCodedSliceNonIdr:
case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) { case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
ParseSliceHeader(); ParseSliceHeader();
gotAccessUnitDelimiter = false; gotAccessUnitDelimiter = false;
if (newFrame)
tsPayload.Statistics();
return tsPayload.Used(); return tsPayload.Used();
} }
break; break;
@ -1253,8 +1308,7 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid)
} }
} }
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit... || tsPayload.Eof()) // or if we're out of data
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
break; break;
} }
return tsPayload.Used(); return tsPayload.Used();
@ -1457,7 +1511,12 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
for (int i = 0; i < numPtsValues; i++) for (int i = 0; i < numPtsValues; i++)
ptsValues[i] = ptsValues[i + 1] - ptsValues[i]; ptsValues[i] = ptsValues[i + 1] - ptsValues[i];
qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32);
uint32_t Delta = ptsValues[0] / framesPerPayloadUnit; int Div = framesPerPayloadUnit;
if (framesPerPayloadUnit > 1)
Div += parser->IFrameTemporalReferenceOffset();
if (Div <= 0)
Div = 1;
uint32_t Delta = ptsValues[0] / Div;
// determine frame info: // determine frame info:
if (isVideo) { if (isVideo) {
if (abs(Delta - 3600) <= 1) if (abs(Delta - 3600) <= 1)
@ -1475,7 +1534,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
} }
else // audio else // audio
framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1); dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d TRO = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1, parser->IFrameTemporalReferenceOffset());
synced = true; synced = true;
parser->SetDebug(false); parser->SetDebug(false);
} }

13
remux.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.h 2.37 2013/01/20 11:43:59 kls Exp $ * $Id: remux.h 2.37.1.2 2014/01/28 12:36:26 kls Exp $
*/ */
#ifndef __REMUX_H #ifndef __REMUX_H
@ -217,8 +217,11 @@ private:
int length; int length;
int pid; int pid;
int index; // points to the next byte to process int index; // points to the next byte to process
int numPacketsPid; // the number of TS packets with the given PID (for statistical purposes)
int numPacketsOther; // the number of TS packets with other PIDs (for statistical purposes)
uchar SetEof(void);
protected: protected:
void Reset(void) { index = 0; } void Reset(void);
public: public:
cTsPayload(void); cTsPayload(void);
cTsPayload(uchar *Data, int Length, int Pid = -1); cTsPayload(uchar *Data, int Length, int Pid = -1);
@ -246,6 +249,10 @@ public:
///< is counted with its full size. ///< is counted with its full size.
bool Eof(void) const { return index >= length; } bool Eof(void) const { return index >= length; }
///< Returns true if all available bytes of the TS payload have been processed. ///< Returns true if all available bytes of the TS payload have been processed.
void Statistics(void) const;
///< May be called after a new frame has been detected, and will log a warning
///< if the number of TS packets required to determine the frame type exceeded
///< some safety limits.
uchar GetByte(void); uchar GetByte(void);
///< Gets the next byte of the TS payload, skipping any intermediate TS header data. ///< Gets the next byte of the TS payload, skipping any intermediate TS header data.
bool SkipBytes(int Bytes); bool SkipBytes(int Bytes);
@ -462,7 +469,7 @@ void PesDump(const char *Name, const u_char *Data, int Length);
// Frame detector: // Frame detector:
#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 5 #define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 100
class cFrameParser; class cFrameParser;

27
sdt.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: sdt.c 2.5 2010/05/16 14:23:21 kls Exp $ * $Id: sdt.c 2.5.1.2 2014/03/11 09:30:59 kls Exp $
*/ */
#include "sdt.h" #include "sdt.h"
@ -17,19 +17,30 @@
cSdtFilter::cSdtFilter(cPatFilter *PatFilter) cSdtFilter::cSdtFilter(cPatFilter *PatFilter)
{ {
source = cSource::stNone;
patFilter = PatFilter; patFilter = PatFilter;
Set(0x11, 0x42); // SDT Set(0x11, 0x42); // SDT
} }
void cSdtFilter::SetStatus(bool On) void cSdtFilter::SetStatus(bool On)
{ {
cMutexLock MutexLock(&mutex);
cFilter::SetStatus(On); cFilter::SetStatus(On);
sectionSyncer.Reset(); sectionSyncer.Reset();
if (!On)
source = cSource::stNone;
}
void cSdtFilter::Trigger(int Source)
{
cMutexLock MutexLock(&mutex);
source = Source;
} }
void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
{ {
if (!(Source() && Transponder())) cMutexLock MutexLock(&mutex);
if (!(source && Transponder()))
return; return;
SI::SDT sdt(Data, false); SI::SDT sdt(Data, false);
if (!sdt.CheckCRCAndParse()) if (!sdt.CheckCRCAndParse())
@ -40,9 +51,9 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
return; return;
SI::SDT::Service SiSdtService; SI::SDT::Service SiSdtService;
for (SI::Loop::Iterator it; sdt.serviceLoop.getNext(SiSdtService, it); ) { for (SI::Loop::Iterator it; sdt.serviceLoop.getNext(SiSdtService, it); ) {
cChannel *channel = Channels.GetByChannelID(tChannelID(Source(), sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId())); cChannel *channel = Channels.GetByChannelID(tChannelID(source, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()));
if (!channel) if (!channel)
channel = Channels.GetByChannelID(tChannelID(Source(), 0, Transponder(), SiSdtService.getServiceId())); channel = Channels.GetByChannelID(tChannelID(source, 0, Transponder(), SiSdtService.getServiceId()));
cLinkChannels *LinkChannels = NULL; cLinkChannels *LinkChannels = NULL;
SI::Descriptor *d; SI::Descriptor *d;
@ -64,7 +75,7 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf)); sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf));
char *pn = compactspace(NameBuf); char *pn = compactspace(NameBuf);
char *ps = compactspace(ShortNameBuf); char *ps = compactspace(ShortNameBuf);
if (!*ps && cSource::IsCable(Source())) { if (!*ps && cSource::IsCable(source)) {
// Some cable providers don't mark short channel names according to the // Some cable providers don't mark short channel names according to the
// standard, but rather go their own way and use "name>short name": // standard, but rather go their own way and use "name>short name":
char *p = strchr(pn, '>'); // fix for UPC Wien char *p = strchr(pn, '>'); // fix for UPC Wien
@ -92,7 +103,7 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
else if (*pn && Setup.UpdateChannels >= 4) { else if (*pn && Setup.UpdateChannels >= 4) {
channel = Channels.NewChannel(Channel(), pn, ps, pp, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); channel = Channels.NewChannel(Channel(), pn, ps, pp, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
patFilter->Trigger(); patFilter->Trigger(SiSdtService.getServiceId());
} }
} }
default: ; default: ;
@ -115,10 +126,10 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
SI::NVODReferenceDescriptor *nrd = (SI::NVODReferenceDescriptor *)d; SI::NVODReferenceDescriptor *nrd = (SI::NVODReferenceDescriptor *)d;
SI::NVODReferenceDescriptor::Service Service; SI::NVODReferenceDescriptor::Service Service;
for (SI::Loop::Iterator it; nrd->serviceLoop.getNext(Service, it); ) { for (SI::Loop::Iterator it; nrd->serviceLoop.getNext(Service, it); ) {
cChannel *link = Channels.GetByChannelID(tChannelID(Source(), Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId())); cChannel *link = Channels.GetByChannelID(tChannelID(source, Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()));
if (!link && Setup.UpdateChannels >= 4) { if (!link && Setup.UpdateChannels >= 4) {
link = Channels.NewChannel(Channel(), "NVOD", "", "", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()); link = Channels.NewChannel(Channel(), "NVOD", "", "", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId());
patFilter->Trigger(); patFilter->Trigger(Service.getServiceId());
} }
if (link) { if (link) {
if (!LinkChannels) if (!LinkChannels)

5
sdt.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: sdt.h 1.2 2004/01/05 14:30:14 kls Exp $ * $Id: sdt.h 2.0.1.1 2014/03/11 09:31:08 kls Exp $
*/ */
#ifndef __SDT_H #ifndef __SDT_H
@ -15,13 +15,16 @@
class cSdtFilter : public cFilter { class cSdtFilter : public cFilter {
private: private:
cMutex mutex;
cSectionSyncer sectionSyncer; cSectionSyncer sectionSyncer;
int source;
cPatFilter *patFilter; cPatFilter *patFilter;
protected: protected:
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
public: public:
cSdtFilter(cPatFilter *PatFilter); cSdtFilter(cPatFilter *PatFilter);
virtual void SetStatus(bool On); virtual void SetStatus(bool On);
void Trigger(int Source);
}; };
#endif //__SDT_H #endif //__SDT_H

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: skinlcars.c 2.21 2013/03/09 10:43:34 kls Exp $ * $Id: skinlcars.c 2.21.1.4 2014/03/10 12:12:19 kls Exp $
*/ */
// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures, // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
@ -837,6 +837,15 @@ cSkinLCARSDisplayMenu::cSkinLCARSDisplayMenu(void)
ys03 = ys04 - Gap; ys03 = ys04 - Gap;
ys05 = yb15; ys05 = yb15;
// The item area (just to have them initialized, actual setting will be done in SetMenuCategory():
xi00 = 0;
xi01 = 0;
xi02 = 0;
xi03 = 1;
yi00 = 0;
yi01 = 1;
// The color buttons in submenus: // The color buttons in submenus:
xb00 = xa06; xb00 = xa06;
xb15 = xa07; xb15 = xa07;
@ -1289,7 +1298,7 @@ void cSkinLCARSDisplayMenu::DrawLiveIndicator(void)
if (initial || y != lastLiveIndicatorY || Transferring != lastLiveIndicatorTransferring) { if (initial || y != lastLiveIndicatorY || Transferring != lastLiveIndicatorTransferring) {
if (lastLiveIndicatorY >= 0) if (lastLiveIndicatorY >= 0)
osd->DrawRectangle(xs12, lastLiveIndicatorY, xs13 - 1, lastLiveIndicatorY + lineHeight - 1, Theme.Color(clrBackground)); osd->DrawRectangle(xs12, lastLiveIndicatorY, xs13 - 1, lastLiveIndicatorY + lineHeight - 1, Theme.Color(clrBackground));
if (y >= 0) { if (y > 0) {
tColor ColorBg = Theme.Color(clrChannelFrameBg); tColor ColorBg = Theme.Color(clrChannelFrameBg);
osd->DrawRectangle(xs12, y, xs12 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg); osd->DrawRectangle(xs12, y, xs12 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg);
osd->DrawEllipse (xs12 + lineHeight / 2, y, xs13 - 1, y + lineHeight - 1, ColorBg, 5); osd->DrawEllipse (xs12 + lineHeight / 2, y, xs13 - 1, y + lineHeight - 1, ColorBg, 5);
@ -1340,6 +1349,8 @@ void cSkinLCARSDisplayMenu::DrawLive(const cChannel *Channel)
DrawMainFrameUpper(Theme.Color(clrChannelFrameBg)); DrawMainFrameUpper(Theme.Color(clrChannelFrameBg));
osd->DrawText(xd00, yd00, tr("LIVE"), Theme.Color(clrChannelFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder); osd->DrawText(xd00, yd00, tr("LIVE"), Theme.Color(clrChannelFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder);
} }
if (!Channel)
return;
if (initial || Channel != lastChannel) { if (initial || Channel != lastChannel) {
osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder); osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder);
osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft); osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
@ -1708,6 +1719,7 @@ cSkinLCARSDisplayReplay::cSkinLCARSDisplayReplay(bool ModeOnly)
frameColor = Theme.Color(clrReplayFrameBg); frameColor = Theme.Color(clrReplayFrameBg);
lastCurrentWidth = 0; lastCurrentWidth = 0;
lastTotalWidth = 0; lastTotalWidth = 0;
memset(&lastTrackId, 0, sizeof(lastTrackId));
int d = 5 * lineHeight; int d = 5 * lineHeight;
xp00 = 0; xp00 = 0;
xp01 = xp00 + d / 2; xp01 = xp00 + d / 2;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: skins.h 2.9 2012/12/21 11:09:13 kls Exp $ * $Id: skins.h 2.9.1.1 2014/02/18 14:06:50 kls Exp $
*/ */
#ifndef __SKINS_H #ifndef __SKINS_H
@ -264,7 +264,7 @@ protected:
class cProgressBar : public cBitmap { class cProgressBar : public cBitmap {
protected: protected:
int total; int total;
int Pos(int p) { return p * Width() / total; } int Pos(int p) { return int(int64_t(p) * Width() / total); }
void Mark(int x, bool Start, bool Current, tColor ColorMark, tColor ColorCurrent); void Mark(int x, bool Start, bool Current, tColor ColorMark, tColor ColorCurrent);
public: public:
cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent); cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: sourceparams.c 1.2 2010/03/06 11:13:39 kls Exp $ * $Id: sourceparams.c 1.2.1.1 2014/03/09 12:13:18 kls Exp $
*/ */
#include "sourceparams.h" #include "sourceparams.h"
@ -21,8 +21,8 @@ cSourceParam::cSourceParam(char Source, const char *Description)
return; return;
} }
SourceParams.Add(this); SourceParams.Add(this);
if (!strchr("ACST", Source)) // no, it's not "ATSC" ;-) if (!Sources.ContainsSourceType(source))
Sources.Add(new cSource(Source, Description)); Sources.Add(new cSource(source, Description));
dsyslog("registered source parameters for '%c - %s'", source, Description); dsyslog("registered source parameters for '%c - %s'", source, Description);
} }
else else

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: sources.c 2.2 2010/02/28 15:15:39 kls Exp $ * $Id: sources.c 2.2.1.1 2014/03/09 12:13:25 kls Exp $
*/ */
#include "sources.h" #include "sources.h"
@ -112,3 +112,12 @@ cSource *cSources::Get(int Code)
} }
return NULL; return NULL;
} }
bool cSources::ContainsSourceType(char SourceType)
{
for (cSource *p = First(); p; p = Next(p)) {
if (cSource::ToChar(p->Code()) == SourceType)
return true;
}
return false;
}

View File

@ -19,57 +19,59 @@
# Europe # Europe
S3E Eutelsat 3A & Rascom 1R S3E Eutelsat 3A/3D & Rascom 1R
S4E Eurobird 4A S4E Eutelsat 4B
S4.8E Astra 4A S4.8E Astra 4A & SES 5
S7E Eutelsat W3A S7E Eutelsat 7A
S9E Eurobird 9A S9E Eutelsat 9A/Ka-Sat 9A
S10E Eutelsat W2A S10E Eutelsat 10A
S13E Hotbird 6/8/9 S13E Eutelsat Hot Bird 13B/13C/13D
S16E Eutelsat W2M & Eurobird 16A S16E Eutelsat 16A/16B
S19.2E Astra 1H/1KR/1L/1M/2C S17E Amos 5
S21.6E Eutelsat W6 S19.2E Astra 1KR/1L/1M/2C
S23.5E Astra 3A/3B S21.6E Eutelsat 21B
S25.5E Eurobird 2 S23.5E Astra 3B
S25.5E Eutelsat 25B
S26E Badr 4/5/6 S26E Badr 4/5/6
S28.2E Astra 2A/2B/2D S28.2E Astra 1N/2A/2F
S28.5E Eurobird 1 S28.5E Eutelsat 28A
S30.5E Arabsat 5A S30.5E Arabsat 5A
S31.5E Astra 1G S31.5E Astra 1G
S33E Eurobird 3 & Intelsat New Dawn S33E Eutelsat 33A & Intelsat 28
S36E Eutelsat W4/W7 S36E Eutelsat 36A/36B
S38E Paksat 1 S38E Paksat 1R
S39E Hellas Sat 2 S39E Hellas Sat 2
S40E Express AM1
S42E Turksat 2A/3A S42E Turksat 2A/3A
S45E Intelsat 12 S45E Intelsat 12
S46E Azerspace-1
S47.5E Intelsat 10
S49E Yamal 202 S49E Yamal 202
S52.5E Yahsat 1A
S53E Express AM22 S53E Express AM22
S55E Insat 3E S56E DirecTV 1R
S56E Bonum 1
S57E NSS 12 S57E NSS 12
S60E Intelsat 904 S60E Intelsat 904
S62E Intelsat 902 S62E Intelsat 902
S64E Intelsat 906 S64E Intelsat 906
S66E Intelsat 17 S66E Intelsat 17
S68.5E Intelsat 7/10 S68.5E Intelsat 7/10
S70.5E Eutelsat W5 S70.5E Eutelsat 70B
S72E Intelsat 709 S72E Intelsat 22
# Asia # Asia
S74E Insat 3C/4CR S74E Insat 3C/4CR
S75E ABS 1A S75E ABS 1A
S76.5E Apstar 2R S76.5E Apstar 7
S78.5E Thaicom 5 S78.5E Thaicom 5/6A
S80E Express AM2/MD1 S80E Express AM2
S83E Insat 2E/4A S83E Insat 4A
S85.2E Intelsat 15 S85.2E Intelsat 15 & Horizons 2
S87.5E Chinasat 5A S87.5E ChinaSat 12
S88E ST 1/2 S88E ST 2
S90E Yamal 201 S90E Yamal 201/300K
S91.5E Measat 3/3A S91.5E Measat 3/3A
S92.2E Chinasat 9 S92.2E ChinaSat 9
S93.5E Insat 3A/4B S93.5E Insat 3A/4B
S95E NSS 6 S95E NSS 6
S96.5E Express AM33 S96.5E Express AM33
@ -77,21 +79,22 @@ S100.5E Asiasat 5
S103E Express A2 S103E Express A2
S105.5E Asiasat 3S S105.5E Asiasat 3S
S108.2E Telkom 1 & NSS 11 & SES 7 S108.2E Telkom 1 & NSS 11 & SES 7
S110E N-Sat 110 & BSAT 2C/3A S110E N-Sat 110 & BSAT 3A/3C
S110.5E Chinasat 10 S110.5E ChinaSat 10
S113E Palapa D & Koreasat 5 S113E Palapa D & Koreasat 5
S116E Koreasat 6 S115.5E ChinaSat 6B
S116E ABS 7 & Koreasat 6
S118E Telkom 2 S118E Telkom 2
S119.5E Thaicom 4
S122.2E Asiasat 4 S122.2E Asiasat 4
S124E JCSAT 4A S124E JCSAT 4B
S125E Chinasat 6A S125E ChinaSat 6A
S128E JCSAT RA S128E JCSAT 3A
S132E Vinasat 1 & JCSAT5A S132E Vinasat 1/2 & JCSAT 5A
S134E Apstar 6 S134E Apstar 6
S138E Telstar 18 S138E Telstar 18
S140E Express AM3 S140E Express AM3
S144E Superbird C2 S144E Superbird C2
S146E ABS 5
S150E JCSAT 1B S150E JCSAT 1B
S152E Optus D2 S152E Optus D2
S154E JCSAT 2A S154E JCSAT 2A
@ -99,73 +102,73 @@ S156E Optus C1/D3
S160E Optus D1 S160E Optus D1
S162E Superbird B2 S162E Superbird B2
S164E Optus B3 S164E Optus B3
S166E Intelsat 8 S166E Intelsat 19
S169E Intelsat 5 S169E Intelsat 8
S172E GE 23 S172E Eutelsat 172A
S180E Intelsat 701 S180E Intelsat 18
S177W NSS 9 S177W NSS 9
# Atlantic # Atlantic
S1W Thor 5/6 & Intelsat 10-02 S1W Thor 5/6 & Intelsat 10-02
S4W Amos 2/3 S4W Amos 2/3
S5W Atlantic Bird 3 S5W Eutelsat 5 West A
S7W Nilesat 101/102/201 & Atlantic Bird 4A S7W Nilesat 101/201 & Eutelsat 7 West A
S8W Telecom 2D & Atlantic Bird 2 S8W Eutelsat 8 West A/C
S11W Express AM44 S11W Express AM44
S12.5W Atlantic Bird 1 S12.5W Eutelsat 12 West A
S14W Express A4 S14W Express A4
S15W Telstar 12 S15W Telstar 12
S18W Intelsat 901 S18W Intelsat 901
S20W NSS 5 S20W NSS 7
S22W NSS 7 S22W SES 4
S24.5W Intelsat 905 S24.5W Intelsat 905
S27.5W Intelsat 907 S27.5W Intelsat 907
S30W Hispasat 1C/1D/1E S30W Hispasat 1D/1E
S31.5W Intelsat 25 S31.5W Intelsat 25
S34.5W Intelsat 903 S34.5W Intelsat 903
S37.5W NSS 10 & Telstar 11N S37.5W NSS 10 & Telstar 11N
S40.5W NSS 806 S40.5W SES 6
S43W Intelsat 11 S43W Intelsat 11
S45W Intelsat 14 S45W Intelsat 14
S50W Intelsat 1R S50W Intelsat 1R
S53W Intelsat 707 S53W Intelsat 23
S55.5W Intelsat 805 S55.5W Intelsat 805
S58W Intelsat 9/16 S58W Intelsat 21
S61W Amazonas 1/2 S61W Amazonas 2/3
# America # America
S61.5W Echostar 12/15 S61.5W Echostar 16
S63W Telstar 14R S63W Telstar 14R
S65W Star One C1 S65W Star One C1
S67W AMC 4
S70W Star One C2 S70W Star One C2
S72W AMC 6 S72W AMC 6
S72.5W DirecTV 1R & Nimiq 5 S72.7W Nimiq 5
S74W Horizons 2 S75W Star One C3
S77W Echostar 1/8 S77W QuetzSat 1
S79W AMC 2/5
S82W Nimiq 4 S82W Nimiq 4
S83W AMC 9 S83W AMC 9
S84W Brasilsat B4 S84W Brasilsat B4
S85W AMC 16 S85W AMC 16
S85.1W XM 3 S85.1W XM 3
S87W AMC 3 S87W SES 2
S89W Galaxy 28 S89W Galaxy 28
S91W Galaxy 17 & Nimiq 1 S91W Galaxy 17 & Nimiq 6
S93W Galaxy 25 S93.1W Galaxy 25
S95W Galaxy 3C S95W Galaxy 3C
S97W Galaxy 19 S97W Galaxy 19
S99W Galaxy 16 S99.2W Galaxy 16
S99.2W Spaceway 2 & DirecTV 11
S101W DirecTV 4S/8 & SES 1 S101W DirecTV 4S/8 & SES 1
S103W AMC 1 S103W AMC 1
S105W AMC 15/18 S105W AMC 15/18
S107.3W Anik F1/F1R S107.3W Anik F1R/G1
S110W DirecTV 5 & Echostar 10/11 S110W DirecTV 5 & Echostar 10/11
S111.1W Anik F2 S111.1W Anik F2
S113W SatMex 6 S113W SatMex 6
S116.8W SatMex 5 S114.9W SatMex 5
S116.8W SatMex 8
S118.8W Anik F3 S118.8W Anik F3
S119W Echostar 14 & DirecTV 7S S119W Echostar 14 & DirecTV 7S
S121W Echostar 9/Galaxy 23 S121W Echostar 9/Galaxy 23
@ -174,7 +177,7 @@ S125W Galaxy 14 & AMC 21
S127W Galaxy 13/Horizons 1 S127W Galaxy 13/Horizons 1
S129W Ciel 2 S129W Ciel 2
S131W AMC 11 S131W AMC 11
S133W Galaxy 13/15 S133W Galaxy 15
S135W AMC 10 S135W AMC 10
S137W AMC 7 S137W AMC 7
S139W AMC 8 S139W AMC 8

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: sources.h 2.4 2012/06/17 11:19:23 kls Exp $ * $Id: sources.h 2.4.1.1 2014/03/09 12:13:34 kls Exp $
*/ */
#ifndef __SOURCES_H #ifndef __SOURCES_H
@ -47,6 +47,7 @@ public:
class cSources : public cConfig<cSource> { class cSources : public cConfig<cSource> {
public: public:
cSource *Get(int Code); cSource *Get(int Code);
bool ContainsSourceType(char SourceType);
}; };
extern cSources Sources; extern cSources Sources;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: thread.c 2.7 2013/02/22 14:52:49 kls Exp $ * $Id: thread.c 2.7.1.1 2013/04/11 08:59:26 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
@ -229,7 +229,7 @@ void cThread::SetPriority(int Priority)
void cThread::SetIOPriority(int Priority) void cThread::SetIOPriority(int Priority)
{ {
if (syscall(SYS_ioprio_set, 1, 0, (Priority & 0xff) | (2 << 13)) < 0) // best effort class if (syscall(SYS_ioprio_set, 1, 0, (Priority & 0xff) | (3 << 13)) < 0) // idle class
LOG_ERROR; LOG_ERROR;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: transfer.c 2.8 2013/03/01 09:50:15 kls Exp $ * $Id: transfer.c 2.8.1.1 2013/08/22 12:37:02 kls Exp $
*/ */
#include "transfer.h" #include "transfer.h"
@ -35,7 +35,7 @@ void cTransfer::Activate(bool On)
cPlayer::Detach(); cPlayer::Detach();
} }
#define MAXRETRIES 5 // max. number of retries for a single TS packet #define MAXRETRIES 20 // max. number of retries for a single TS packet
#define RETRYWAIT 5 // time (in ms) between two retries #define RETRYWAIT 5 // time (in ms) between two retries
void cTransfer::Receive(uchar *Data, int Length) void cTransfer::Receive(uchar *Data, int Length)

4
vdr.1
View File

@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the .\" License as specified in the file COPYING that comes with the
.\" vdr distribution. .\" vdr distribution.
.\" .\"
.\" $Id: vdr.1 2.17 2013/03/15 10:44:54 kls Exp $ .\" $Id: vdr.1 2.17.1.1 2013/12/25 11:05:27 kls Exp $
.\" .\"
.TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder" .TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder"
.SH NAME .SH NAME
@ -201,7 +201,7 @@ operation.
Allow coredumps if -u is given (only for debugging). Allow coredumps if -u is given (only for debugging).
.TP .TP
.BI \-\-vfat .BI \-\-vfat
For backwards compatibility (same as \-\-dirnames= 250,40,1. For backwards compatibility (same as \-\-dirnames= 250,40,1).
.TP .TP
.BI \-v\ dir ,\ \-\-video= dir .BI \-v\ dir ,\ \-\-video= dir
Use \fIdir\fR as video directory. Use \fIdir\fR as video directory.

12
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * The project's page is at http://www.tvdr.de
* *
* $Id: vdr.c 2.57 2013/03/15 10:44:54 kls Exp $ * $Id: vdr.c 2.57.1.5 2014/01/26 12:45:00 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -223,6 +223,7 @@ int main(int argc, char *argv[])
VdrUser = VDR_USER; VdrUser = VDR_USER;
#endif #endif
SetVideoDirectory(VideoDirectory);
cPluginManager PluginManager(DEFAULTPLUGINDIR); cPluginManager PluginManager(DEFAULTPLUGINDIR);
static struct option long_options[] = { static struct option long_options[] = {
@ -443,6 +444,7 @@ int main(int argc, char *argv[])
case 'v': VideoDirectory = optarg; case 'v': VideoDirectory = optarg;
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/') while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
optarg[strlen(optarg) - 1] = 0; optarg[strlen(optarg) - 1] = 0;
SetVideoDirectory(VideoDirectory);
break; break;
case 'w': if (isnumber(optarg)) { case 'w': if (isnumber(optarg)) {
int t = atoi(optarg); int t = atoi(optarg);
@ -540,7 +542,7 @@ int main(int argc, char *argv[])
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n" " -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
" -V, --version print version information and exit\n" " -V, --version print version information and exit\n"
" --vfat for backwards compatibility (same as\n" " --vfat for backwards compatibility (same as\n"
" --dirnames=250,40,1\n" " --dirnames=250,40,1)\n"
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n" " -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
" seconds (default: %d); '0' disables the watchdog\n" " seconds (default: %d); '0' disables the watchdog\n"
"\n", "\n",
@ -663,7 +665,6 @@ int main(int argc, char *argv[])
// Directories: // Directories:
SetVideoDirectory(VideoDirectory);
if (!ConfigDirectory) if (!ConfigDirectory)
ConfigDirectory = DEFAULTCONFDIR; ConfigDirectory = DEFAULTCONFDIR;
cPlugin::SetConfigDirectory(ConfigDirectory); cPlugin::SetConfigDirectory(ConfigDirectory);
@ -908,7 +909,7 @@ int main(int argc, char *argv[])
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
if (Channel->Modification(CHANNELMOD_RETUNE)) { if (Channel->Modification(CHANNELMOD_RETUNE)) {
cRecordControls::ChannelDataModified(Channel); cRecordControls::ChannelDataModified(Channel);
if (Channel->Number() == cDevice::CurrentChannel()) { if (Channel->Number() == cDevice::CurrentChannel() && cDevice::PrimaryDevice()->HasDecoder()) {
if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) { if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) {
if (cDevice::ActualDevice()->ProvidesTransponder(Channel)) { // avoids retune on devices that don't really access the transponder if (cDevice::ActualDevice()->ProvidesTransponder(Channel)) { // avoids retune on devices that don't really access the transponder
isyslog("retuning due to modification of channel %d", Channel->Number()); isyslog("retuning due to modification of channel %d", Channel->Number());
@ -1234,7 +1235,7 @@ int main(int argc, char *argv[])
case osRecordings: case osRecordings:
DELETE_MENU; DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
Menu = new cMenuMain(osRecordings); Menu = new cMenuMain(osRecordings, true);
break; break;
case osReplay: DELETE_MENU; case osReplay: DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
@ -1360,6 +1361,7 @@ int main(int argc, char *argv[])
// Disk housekeeping: // Disk housekeeping:
RemoveDeletedRecordings(); RemoveDeletedRecordings();
ClearVanishedRecordings();
cSchedules::Cleanup(); cSchedules::Cleanup();
// Plugins housekeeping: // Plugins housekeeping:
PluginManager.Housekeeping(); PluginManager.Housekeeping();