mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Compare commits
67 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1dca279938 | ||
|
cd125ef4da | ||
|
ba9651e863 | ||
|
da404e00c0 | ||
|
e823560ec5 | ||
|
ff1422a75a | ||
|
d406be694d | ||
|
fdf9c8df8e | ||
|
c94b4a803c | ||
|
7271a160e4 | ||
|
1c47cf37ca | ||
|
d55c134333 | ||
|
a179b725b7 | ||
|
4709eb94fa | ||
|
3736508d95 | ||
|
058177d24c | ||
|
1ae32cdd6f | ||
|
fb66c3ec6b | ||
|
7d6c54d63a | ||
|
719b46b305 | ||
|
5b65ff5b37 | ||
|
c1ddb52405 | ||
|
9e9219d8fb | ||
|
538a4f7674 | ||
|
dd95f4ed61 | ||
|
6bd94489de | ||
|
c7316989f5 | ||
|
bc89bda239 | ||
|
426cf5710d | ||
|
a7728f9db7 | ||
|
4e7ef3214f | ||
|
6a4004a8a2 | ||
|
1045069fee | ||
|
cca9d858a7 | ||
|
7b634a092c | ||
|
25e05054a6 | ||
|
578cfe64a8 | ||
|
746a9f88e7 | ||
|
fb74e0feeb | ||
|
cb1498a609 | ||
|
ddce16326c | ||
|
c8d77e241f | ||
|
965b3471b7 | ||
|
0f75df5452 | ||
|
c37fb11a08 | ||
|
c169e20141 | ||
|
c3a3b70fa0 | ||
|
fc03e021bb | ||
|
6e6e468148 | ||
|
1f0a55ca7d | ||
|
917331767b | ||
|
0161639e93 | ||
|
77da7bb20c | ||
|
acdfbb5aad | ||
|
cd53d57779 | ||
|
0d14872adc | ||
|
90f4648a7c | ||
|
be88699b00 | ||
|
1b1fe2c887 | ||
|
fa77b5c2b2 | ||
|
cffde6ee09 | ||
|
2266b0e633 | ||
|
06f7c2d414 | ||
|
1b1dc6d775 | ||
|
e5971d2684 | ||
|
ae208771e8 | ||
|
df4ea10419 |
83
CONTRIBUTORS
83
CONTRIBUTORS
@ -618,6 +618,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 +704,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 +1021,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 +1175,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 +2028,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 +2115,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 +2143,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 +2494,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 +2557,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 +2620,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 +2856,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 +2891,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 +2901,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 +2979,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 +3028,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 +3174,43 @@ 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
|
||||||
|
137
HISTORY
137
HISTORY
@ -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,137 @@ 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().
|
||||||
|
@ -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).
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
@ -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).
|
||||||
|
@ -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);
|
||||||
|
16
channels.c
16
channels.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.c 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
4
ci.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 2.76 2013/03/31 09:30:18 kls Exp $
|
* $Id: config.h 2.76.1.7 2014/03/22 11:00:00 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.6"
|
||||||
#define VDRVERSNUM 20000 // Version * 10000 + Major * 100 + Minor
|
#define VDRVERSNUM 20006 // 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
|
||||||
|
8
cutter.c
8
cutter.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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:
|
||||||
|
10
device.c
10
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 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);
|
||||||
}
|
}
|
||||||
|
4
device.h
4
device.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
|
4
diseqc.c
4
diseqc.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
72
dvbdevice.c
72
dvbdevice.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
|
55
dvbdevice.h
55
dvbdevice.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
4
eit.c
@ -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
19
epg.c
@ -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
28
font.c
@ -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
4
font.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
20
lirc.c
@ -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;
|
||||||
}
|
}
|
||||||
|
44
menu.c
44
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 2.82 2013/03/18 09:11:48 kls Exp $
|
* $Id: menu.c 2.82.1.8 2014/02/26 11:42:28 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;
|
||||||
@ -4779,8 +4791,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 +4982,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
4
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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);
|
||||||
};
|
};
|
||||||
|
@ -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
8
nit.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
6
nit.h
@ -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
10
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.c 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
133
pat.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
20
pat.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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);
|
||||||
|
12
recorder.c
12
recorder.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
131
recording.c
131
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 2.91 2013/03/11 10:34:41 kls Exp $
|
* $Id: recording.c 2.91.1.7 2014/03/16 11:03:18 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -72,6 +72,7 @@ bool DirectoryEncoding = false;
|
|||||||
int InstanceId = 0;
|
int InstanceId = 0;
|
||||||
|
|
||||||
cRecordings DeletedRecordings(true);
|
cRecordings DeletedRecordings(true);
|
||||||
|
static cRecordings VanishedRecordings;
|
||||||
|
|
||||||
// --- cRemoveDeletedRecordingsThread ----------------------------------------
|
// --- cRemoveDeletedRecordingsThread ----------------------------------------
|
||||||
|
|
||||||
@ -178,40 +179,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 +574,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 +597,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 +958,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 +1250,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 +1282,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 +1303,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 +1379,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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
4
remote.c
4
remote.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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);
|
||||||
}
|
}
|
||||||
|
98
remux.c
98
remux.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 2.75 2013/03/03 10:37:58 kls Exp $
|
* $Id: remux.c 2.75.1.5 2014/03/08 15:10:24 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,7 @@ 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;
|
uint32_t Delta = ptsValues[0] / (framesPerPayloadUnit + parser->IFrameTemporalReferenceOffset());
|
||||||
// determine frame info:
|
// determine frame info:
|
||||||
if (isVideo) {
|
if (isVideo) {
|
||||||
if (abs(Delta - 3600) <= 1)
|
if (abs(Delta - 3600) <= 1)
|
||||||
@ -1475,7 +1529,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
13
remux.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
27
sdt.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
5
sdt.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
|
||||||
|
16
skinlcars.c
16
skinlcars.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
|
4
skins.h
4
skins.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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);
|
||||||
|
@ -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
|
||||||
|
11
sources.c
11
sources.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
|
}
|
||||||
|
137
sources.conf
137
sources.conf
@ -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
|
||||||
|
@ -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;
|
||||||
|
4
thread.c
4
thread.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
4
vdr.1
@ -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
12
vdr.c
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user