Compare commits

..

No commits in common. "master" and "2.3.5" have entirely different histories.

210 changed files with 3819 additions and 14064 deletions

View File

@ -275,7 +275,7 @@ Aaron Holtzman
Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de> Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de>
for fixing calculating the timeout value in cFile::FileReady() for fixing calculating the timeout value in cFile::FileReady()
Uwe Scheffler <scheffler.u@web.de> Uwe Scheffler <linux_dvb@uni.de>
for his help in keeping 'channels.conf.cable' and 'channels.conf.terr' up to date for his help in keeping 'channels.conf.cable' and 'channels.conf.terr' up to date
for helping to test new DVB-T handling for helping to test new DVB-T handling
for reporting a bug in switching the video format in the Setup/DVB menu for reporting a bug in switching the video format in the Setup/DVB menu
@ -283,9 +283,6 @@ Uwe Scheffler <scheffler.u@web.de>
for reporting a problem in handling the PrimaryLimit when requesting a device for for reporting a problem in handling the PrimaryLimit when requesting a device for
live viewing live viewing
for reporting a black screen while a "Recording started" message is displayed for reporting a black screen while a "Recording started" message is displayed
for reporting a problem with the lock on the Channels list in cDisplayChannel still
being held when Flush() was called
for reporting a problem with failed tuning in SCR systems
Matjaz Thaler <matjaz.thaler@guest.arnes.si> Matjaz Thaler <matjaz.thaler@guest.arnes.si>
for improving AC3 decoding when replaying DVDs for improving AC3 decoding when replaying DVDs
@ -719,8 +716,6 @@ Oliver Endriss <o.endriss@gmx.de>
channels channels
for fixing a possible stack overflow in cListBase::Sort() for fixing a possible stack overflow in cListBase::Sort()
for reporting a crash when deleting a recording for reporting a crash when deleting a recording
for reporting a problem with sluggish setting of editing marks and a jumping progress
display with very short recordings
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'
@ -1206,7 +1201,6 @@ Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>
for suggesting to change the naming of "binary skip mode" to "adaptive skip mode" for suggesting to change the naming of "binary skip mode" to "adaptive skip mode"
for adding a Status parameter to the interface of cDevice::SignalStats() and for adding a Status parameter to the interface of cDevice::SignalStats() and
cDvbDevice::SignalStats() cDvbDevice::SignalStats()
for reporting a possible crash when scaling bitmaps with very small factors
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
@ -1226,9 +1220,6 @@ Peter Bieringer <pb@bieringer.de>
for suggesting to ignore lines tagged with '#' in the 'info.vdr' file of a recording for suggesting to ignore lines tagged with '#' in the 'info.vdr' file of a recording
for reporting a problem with the backslash ('\') in parameters when executing for reporting a problem with the backslash ('\') in parameters when executing
external commands external commands
for making the functions cRecordingInfo::SetData() and cRecordingInfo::SetAux() public
for adding some missing user command calls for copying, renaming and moving recordings
for fixing scaling subtitles with anti-aliasing
Alexander Damhuis <ad@phonedation.de> Alexander Damhuis <ad@phonedation.de>
for reporting problems when deleting a timer that is currently recording for reporting problems when deleting a timer that is currently recording
@ -1856,7 +1847,7 @@ Lucian Muresan <lucianm@users.sourceforge.net>
for exporting some libsi functions for exporting some libsi functions
for suggesting to add functions to cDevice that allow derived output devices to for suggesting to add functions to cDevice that allow derived output devices to
implement scaling the video to a given size and location implement scaling the video to a given size and location
for sorting sources.conf by continuous azimuth fpr sorting sources.conf by continous azimuth
Mattias Grönlund <Mattias@Gronlund.net> Mattias Grönlund <Mattias@Gronlund.net>
for pointing out a missing cleanup at program exit in case there is a problem for pointing out a missing cleanup at program exit in case there is a problem
@ -2124,10 +2115,6 @@ Martin Wache <M.Wache@gmx.net>
device, which avoids a busy loop on very fast machines device, which avoids a busy loop on very fast machines
for fixing a possible crash when loading an invalid XPM file for fixing a possible crash when loading an invalid XPM file
for suggesting to speed up anti-aliased font rendering by caching the blend indexes for suggesting to speed up anti-aliased font rendering by caching the blend indexes
for extending the option "Setup/Miscellaneous/Show channel names with source" to
"type" or "full"
for making the "Channels" menu indicate whether a channel is encrypted or a radio
channel
Matthias Lenk <matthias.lenk@amd.com> Matthias Lenk <matthias.lenk@amd.com>
for reporting an out-of-bounds memory access with audio language ids for reporting an out-of-bounds memory access with audio language ids
@ -2187,9 +2174,8 @@ Hardy Flor <HFlor@web.de>
Harald Milz <hm@seneca.muc.de> Harald Milz <hm@seneca.muc.de>
for his CUTR patch, which was used as a base to implement the SVDRP command EDIT for his CUTR patch, which was used as a base to implement the SVDRP command EDIT
for reporting a bug in parsing the '-l' command line option
Marko Mäkelä <marko.makela@iki.fi> Marko Mäkelä <marko.makela@hut.fi>
for making repeat keys be ignored when waiting for a keypress to cancel an operation for making repeat keys be ignored when waiting for a keypress to cancel an operation
for reporting that a menu was automatically closed when a replay ends for reporting that a menu was automatically closed when a replay ends
for suggesting to ignore k_Repeat when deciding whether the same key has been for suggesting to ignore k_Repeat when deciding whether the same key has been
@ -2200,18 +2186,6 @@ Marko M
for suggesting to simplify some conditional expressions in skinlcars.c and skinsttng.c for suggesting to simplify some conditional expressions in skinlcars.c and skinsttng.c
for reporting some uninitialized item area coordinates in cSkinLCARSDisplayMenu for reporting some uninitialized item area coordinates in cSkinLCARSDisplayMenu
for reporting a problem with the video directory not being set correctly with --edit for reporting a problem with the video directory not being set correctly with --edit
for reporting a compiler warning about the use of strncpy() in strreplace()
for adding support for kernel based LIRC driver
for reporting a possible heap-use-after-free in cDvbTuner::Action()
for reporting a flaw in initializing cDvbPlayerControl and cTransferControl
for reporting a possible call to poll() in cSectionHandler::Action() without any
filters
for avoiding the memcpy() call in cGlyph::cGlyph() if the bitmap is empty
for avoiding unnecessary processing in cDvbSubtitleConverter::FinishPage() if there
are no areas
for avoiding a zero sized array in cDevice::GetDevice()
for reporting a crash when deleting a recording that is currently being edited, and
then immediately deleting the edited version, too
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
@ -2355,7 +2329,6 @@ Andr
for reporting a bug in selecting the last replayed recording in the Recordings menu for reporting a bug in selecting the last replayed recording in the Recordings menu
in case there are folders and plain recordings with names that differ only in in case there are folders and plain recordings with names that differ only in
non-alphanumeric characters non-alphanumeric characters
for reporting a problem with permanently looping through PMT PIDs on a SatIP receiver
Jürgen Schilling <juergen_schilling@web.de> Jürgen Schilling <juergen_schilling@web.de>
for reporting that color buttons were displayed in the recording info menu if it for reporting that color buttons were displayed in the recording info menu if it
@ -2457,23 +2430,6 @@ Christoph Haubrich <christoph1.haubrich@arcor.de>
"Edit recording" menu "Edit recording" menu
for suggesting to add a confirmation before renaming a recording to its folder name for suggesting to add a confirmation before renaming a recording to its folder name
for reporting a problem with data loss in case renaming a recording fails for reporting a problem with data loss in case renaming a recording fails
for adding support for HEVC-video and AC-4-audio
for implementing anti-aliasing for cPixmap::DrawSlope() and cPixmap::DrawEllipse()
for reporting an unnecessary double call to Display() in cMenuRecording::RefreshRecording()
for reporting too much memory being allocated in the cImage constructors
for making the 'Edit path' dialog also show the total size of all recordings in that path
for suggesting to make cRecordingInfo::Errors() return -1 for old recordings, and
reporting a missing 'const'
for reporting that the edited recording is not deleted in case of an error
for reporting missing '0x09=H.265 video, 0x19 = AC4 audio' in vdr.5
for reporting a problem with the call to EpgHandlers.EndSegmentTransfer()
for fixing handling zero bytes in cH264Parser
for implementing parsing frame rate and image size for MPEG2, H.264 and H.265
for reporting a bug in generating the index file in the cutter
for adding the frame width, height, scan type and aspect ratio of a recording to the 'F'
tag of the 'info' file
for adding a workaround in detecting frame height for channels with wrong crop parameters
for reporting duplicate component entries in the info of an ongoing recording
Pekka Mauno <pekka.mauno@iki.fi> Pekka Mauno <pekka.mauno@iki.fi>
for fixing cSchedule::GetFollowingEvent() in case there is currently no present for fixing cSchedule::GetFollowingEvent() in case there is currently no present
@ -2526,11 +2482,6 @@ Tobias Grimm <tobias.grimm@e-tobi.net>
for adding a manual page for 'svdrpsend' for adding a manual page for 'svdrpsend'
for adding a missing dependency to the Makefile to avoid error messages in the for adding a missing dependency to the Makefile to avoid error messages in the
clean-plugins target clean-plugins target
for adding optional verbose output to the libsi Makefile
for making the call to pkg_config configurable via the PKG_CONFIG macro
for fixing a typo in svdrp.c
for suggesting to add CPPFLAGS to CXXFLAGS to allow extra preprocessor flags to be
given when doing make
Helge Lenz <h.lenz@gmx.de> Helge Lenz <h.lenz@gmx.de>
for reporting a bug in setting the 'Delta' parameter when calling the shutdown for reporting a bug in setting the 'Delta' parameter when calling the shutdown
@ -2552,50 +2503,6 @@ Nino Gerbino <ngerb@interfree.it>
Markus Ehrnsperger <markus.ehrnsperger@googlemail.com> Markus Ehrnsperger <markus.ehrnsperger@googlemail.com>
for reporting a problem with missing 'INCLUDES += -I$(DVBDIR)/include' in an existing for reporting a problem with missing 'INCLUDES += -I$(DVBDIR)/include' in an existing
Make.config Make.config
for reporting a bug in error handling when loading a plugin
for reporting a possible crash in cIndexFile::GetClosestIFrame()
for reporting a missing 'const' in cTimers::GetTimerForEvent()
for suggesting to add a chapter about locking to PLUGINS.html
for fixing unnecessary interruption of ongoing recordings if timers avoided the
transfer mode receiver device
for reporting broken video data streams on systems without output device when switching
live channel to a different transponder while recording
for fixing a possible crash in cDevice::StopSectionHandler()
for making using a dummy OSD if no OSD provider is available not be considered an error
any more
for removing syslog calls in child process after fork()
for adding the move constructor to cString for better performance
for fixing handling primary device on headless systems
for adding a 15 second grace period before actually stopping a VPS timer
for making the primary device no longer start unnecessary threads if it doesn't have
a decoder
for improving handling present/following data for VPS timers
for making logging event status changes also show the previous status
for making a device always being kept occupied if a timer is in VPS margin or needs the
transponder
for suggesting to enable unused devices to be put into a power save mode
for a patch that was used to implement power save mode for cDvbDevice
for suggesting to add 'lnbPowerTurnedOn = false' to cDvbTuner::ProvidesFrontend()
for reporting a crash in strreplace() for multiple replacements with strings of
different lengths
for suggesting to add the lines from 'Fixed a timeout in cDvbDevice while tuning after
the frontend has been reopened' to cDvbTuner::ProvidesFrontend()
for improving the error message when closing a frontend
for reporting a problem in cSchedule::Sort(), in case hasRunning was true, but there
was no event with RunningStatus() >= SI::RunningStatusPausing
for reporting problem with duplicate events if they are moved to a lower table ID and
at the same time get a new event ID
for reporting a bug in handling negative values in cSource::Position() on
systems where 'int' is 64 bit
for suggesting a fix for expiring of one-time VPS timers in case there is more than
one event with the same VPS time
for fixing handling margins for timers that are not VPS controlled and not spawned
for implementing cStatus::OsdItem2() with the information whether the item is selectable
for reporting an improper call of cStatus::OsdCurrentItem() before cStatus::OsdItem2()
for fixing unnecessary calls to DisplayCurrent() for editable menu items
for implementing cStatus::OsdCurrentItem2() with the index of the current item
for adding missing calls to cStatus::MsgOsdStatusMessage() and implementing
cStatus::OsdStatusMessage2() with the type of the message
Werner Färber <w.faerber@gmx.de> Werner Färber <w.faerber@gmx.de>
for reporting a bug in handling the cPluginManager::Active() result when pressing for reporting a bug in handling the cPluginManager::Active() result when pressing
@ -2716,12 +2623,6 @@ J
for making cEpgHandlers::BeginSegmentTransfer() boolean for making cEpgHandlers::BeginSegmentTransfer() boolean
for suggesting to change tEventID back to u_int32_t for suggesting to change tEventID back to u_int32_t
for adding the 'aux' member to cEvent for adding the 'aux' member to cEvent
for reporting a possible deadlock when quickly zapping through encrypted channels
for a patch that was used to implement cStatus::MarksModified()
for suggesting to no longer log unaligned marks in cMarks::Align()
for reporting some warnings from g++ 7.2.0 regarding fixed buffer sizes in
cMenuEditTimeItem::Set() and cCountdown::Update()
for fixing symmetry of Begin/EndSegmentTransfer() calls in cEIT::cEIT()
Peter Pinnau <vdr@unterbrecher.de> Peter Pinnau <vdr@unterbrecher.de>
for reporting that 'uint32_t' requires including stdint.h in font.h on some systems for reporting that 'uint32_t' requires including stdint.h in font.h on some systems
@ -2828,38 +2729,10 @@ Benjamin Hess <benjamin.h@gmx.ch>
for enhancing the SVDRP command CLRE to allow clearing the EPG data of a particular for enhancing the SVDRP command CLRE to allow clearing the EPG data of a particular
channel channel
Winfried Köhler <nvdec@quantentunnel.de> Winfried Koehler <w_koehl@gmx.de>
for fixing finding new transponders for fixing finding new transponders
for fixing wrong value for TableIdBAT in libsi/si.h
for reporting a compiler warning in calculations involving FramesPerSecond() for reporting a compiler warning in calculations involving FramesPerSecond()
for making several code modifications to avoid compiler warnings
for improving the description of the transponder parameters in vdr.5
for reporting a necessary fix in the description of cReceiver in PLUGINS.html,
regarding detaching a receiver from its device before deleting it
for fixing some copy&paste errors in PLUGINS.html for fixing some copy&paste errors in PLUGINS.html
for fixing the size of cChannel::dtypes[]
for adding a device hook for detecting whether a device provides EIT data
for improving deleting plugins in case the plugin uses its own memory management
for reporting a bug in handling newline characters in ci.c's CopyString()
for reporting a bug in checking the return value of the Open() call in
cFileName::SetOffset()
for adding initialization of cDvbFrontend::frontendInfo
for improving handling missing VDRPluginDestroyer()
for fixing a compiler warning
for fixing handling $(PKG_CONFIG) in newplugin
for using __cplusplus instead of DISABLE_TEMPLATES_COLLIDING_WITH_STL, and using
std::min(), std::max() and std::swap() is available
for adding some missing "AUTO" values to vdr.5
for fixing default values for DVB-T
for adding missing rounding when dividing frequencies in processing the NIT
for suggesting to add note about not messing with event ids in EPG handlers
for adding a missing initialization of cChannel::nameSourceMode
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
for reporting a compiler warning with gcc 14.1.0
for suggesting to remove defining DEPRECATED_* macros with value 0, because this
is the preprocessor's default
for suggesting a fix for handling negative values in cSource::Position() on
systems where 'int' is 64 bit
Hans-Werner Hilse <hilse@web.de> Hans-Werner Hilse <hilse@web.de>
for adding the command line option --userdump to enable core dumps in case VDR for adding the command line option --userdump to enable core dumps in case VDR
@ -2926,6 +2799,13 @@ Michael Nork <mnork0@gmx.net>
binary distributions to have full control over whether or not to use the --vfat binary distributions to have full control over whether or not to use the --vfat
option at runtime option at runtime
Winfried Köhler <w_koehl@gmx.de>
for fixing wrong value for TableIdBAT in libsi/si.h
for making several code modifications to avoid compiler warnings
for improving the description of the transponder parameters in vdr.5
for reporting a necessary fix in the description of cReceiver in PLUGINS.html,
regarding detaching a receiver from its device before deleting it
Igor M. Liplianin <liplianin@tut.by> Igor M. Liplianin <liplianin@tut.by>
for a patch that was used to convert VDR to the S2API driver API for a patch that was used to convert VDR to the S2API driver API
@ -2951,18 +2831,6 @@ Johann Friedrichs <johann.friedrichs@web.de>
respective recording did not exist respective recording did not exist
for fixing a double deletion of a cTimer in case HandleRemoteModifications() returned for fixing a double deletion of a cTimer in case HandleRemoteModifications() returned
false false
for reporting an invalid lock sequence in the epgsearch plugin, which turned out to
be an abandoned member of class cSchedulesLock
for fixing handling VPS events outside the LingerLimit, which could cause recordings to
stop prematurely
for fixing handling timers during the change from DST to winter time
for fixing a possible crash with plugins that retrieve player information after a
replay has been stopped, but before the replay control has been destroyed
for reporting a problem in processing SVDRP client responses in case the caller doesn't
want the actual response strings
for reporting a bug in handling the tfRecording flag in the SVDRP commands MODT and UPDT
for adding a missing '-D' to the 'plugins' target of the Makefile
for adding code for the 'qks' audio track
Timo Helkio <timolavi@mbnet.fi> Timo Helkio <timolavi@mbnet.fi>
for reporting a hangup when replaying a TS recording with subtitles activated for reporting a hangup when replaying a TS recording with subtitles activated
@ -2990,8 +2858,6 @@ Derek Kelly <user.vdr@gmail.com>
for suggesting to change the naming of "binary skip mode" to "adaptive skip mode" for suggesting to change the naming of "binary skip mode" to "adaptive skip mode"
for suggesting to make the -u option also accept a numerical user id for suggesting to make the -u option also accept a numerical user id
for reporting a problem with abs() in gcc6+ when called with an unsigned variable for reporting a problem with abs() in gcc6+ when called with an unsigned variable
for reporting a deadlock after the fix for a race between SVDRP CHAN and
cDevice::HasProgramme()
Marcel Unbehaun <frostworks@gmx.de> Marcel Unbehaun <frostworks@gmx.de>
for adding cRecordingInfo::GetEvent() for adding cRecordingInfo::GetEvent()
@ -3023,14 +2889,6 @@ Manuel Reimer <Manuel.Reimer@gmx.de>
order to avoid discontinuities order to avoid discontinuities
for setting the environment variables HOME, USER, LOGNAME and SHELL accordingly for setting the environment variables HOME, USER, LOGNAME and SHELL accordingly
when switching to a less privileged user id when switching to a less privileged user id
for reporting a bug in moving channels between number groups in SVDRP's MOVC command
for fixing compatibility with current versions of glibc
for suggesting to make the SVDRP command DELC accept a channel id
for reporting a crash in the SVDRP command CLRE in case a non-existing channel
number is given
for reporting that LSTE doesn't work after PUTE in case a channel didn't already
have EPG data
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
Rene van den Braken <rene@vandenbraken.name> Rene van den Braken <rene@vandenbraken.name>
for reporting a bug in writing the PCR pid into the PMT in for reporting a bug in writing the PCR pid into the PMT in
@ -3084,7 +2942,6 @@ Lars Hanisch <dvb@flensrocker.de>
for fixing a typo in the description of cTimers::GetTimersRead() for fixing a typo in the description of cTimers::GetTimersRead()
for suggesting to use dynamic buffering in handling CA descriptors to avoid a for suggesting to use dynamic buffering in handling CA descriptors to avoid a
possible buffer overflow possible buffer overflow
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
Alex Lasnier <alex@fepg.org> Alex Lasnier <alex@fepg.org>
for adding tuning support for ATSC devices for adding tuning support for ATSC devices
@ -3171,9 +3028,6 @@ Frank Neumann <fnu@yavdr.org>
is currently assigned to is currently assigned to
for reporting a problem with the default return value of cEpgHandler::BeginSegmentTransfer() for reporting a problem with the default return value of cEpgHandler::BeginSegmentTransfer()
in derived classes that don't implement this function in derived classes that don't implement this function
for reporting uninitialized variable SdWatchdog in vdr.c
for suggesting to use readdir() instead of readdir_r(), if GLIBC version 2.24 or
newer is used
Gerald Dachs <vdr@dachsweb.de> Gerald Dachs <vdr@dachsweb.de>
for reporting a problem with checking for minimum line length of 21 characters in for reporting a problem with checking for minimum line length of 21 characters in
@ -3239,10 +3093,6 @@ Frank Niederwipper <f.niederwipper@gmail.com>
Chris Mayo <aklhfex@gmail.com> Chris Mayo <aklhfex@gmail.com>
for reporting a problem with detecting frames on radio channels for reporting a problem with detecting frames on radio channels
for fixing the link to "svdrpsend (1)" in the vdr.1 man page for fixing the link to "svdrpsend (1)" in the vdr.1 man page
for updating links in the INSTALL file
for reporting double slashes in file names processed with AddDirectory()
for using the 'example' macro in vdr.5
for fixing the install target in case of multiple jobs
Dominic Evans <oldmanuk@gmail.com> Dominic Evans <oldmanuk@gmail.com>
for making the SVDRP command LSTC accepts channel IDs for making the SVDRP command LSTC accepts channel IDs
@ -3374,16 +3224,6 @@ Mike Hay <mike.hay@linenshorts.com>
Stefan Hofmann <stefan.hofmann@t-online.de> Stefan Hofmann <stefan.hofmann@t-online.de>
for suggesting to implement support for remote controls that only have a combined for suggesting to implement support for remote controls that only have a combined
"Play/Pause" key instead of separate keys for "Play" and "Pause" "Play/Pause" key instead of separate keys for "Play" and "Pause"
for a fix for compilers that don't like non-constant format strings
for suggesting to implement jumping between errors while replaying a recording
for adding vdrrootdir and incdir to vdr.pc
for fixing some typos in the translation files
for adding 1 to Utf8BufSize() for worst case
for adding a header to the backtrace
for adding parameter checks to strn0cpy()
for making the info files of recordings only be re-read if they have been modified
for reporting missing setting the file name of the info file after renaming a recording
for adding '~' to the list of delimiters in cTextWrapper
Stefan Blochberger <Stefan.Blochberger@gmx.de> Stefan Blochberger <Stefan.Blochberger@gmx.de>
for suggesting to automatically display the progress display whenever replay of a for suggesting to automatically display the progress display whenever replay of a
@ -3423,37 +3263,6 @@ Matthias Senzel <matthias.senzel@t-online.de>
for reporting a bug in switching channels in the Schedule menu after going through for reporting a bug in switching channels in the Schedule menu after going through
various Now and Schedule menus for different channels various Now and Schedule menus for different channels
for the "jumpingseconds" patch for the "jumpingseconds" patch
for reporting a bug in drawing very long menu titles in the LCARS skin
for reporting and helping to debug a crash when stopping VDR
for reporting a crash when moving a recording between different volumes
for reporting a deadlock when moving a folder containing several recordings between
different volumes
for fixing a lengthy write lock on the Recordings list in case of moving a folder with
more than one recording
for implementing the parameter "OSD/Sorting direction for recordings"
for suggesting to stay in the original folder when moving a recording to a different
folder
for reporting problem with locking the Recordings list in the cutting process
for suggesting to change the log message ""ERROR: copying directory '%s' to '%s' ended
prematurely" from "error" to "info"
for suggesting to allow opening a folder when selecting a folder for a recording or
timer, even if it doesn't contain any subfolders
for reporting a possible locking problem in cMenuPathEdit::ApplyChanges() when the
lock is held while the error message is displayed
for reporting that the info of a newly edited recording was not available immediately
after starting the editing process
for reporting a problem with setting the initial offset of the cursor in a list menu
for reporting a high CPU load during replay with active progress display
for reporting that the lock on the Channels list in cDisplayChannel was still held
when Flush() was called
for reporting that if an error occurs while recording, the respective entry in the list
of recordings was not updated immediately
for fixing restoring the volume at program start
for fixing height calculation in progress display
for fixing an unnecessary double display of the current menu item in page up/down
for fixing an unnecessary double display of menu items in the Recordings menu
for reporting a bug in handling cSkinDisplayMenu::GetTextAreaFont()
for reporting characters being cut off while editing in the LCARS skin
Marek Nazarko <mnazarko@gmail.com> Marek Nazarko <mnazarko@gmail.com>
for translating OSD texts to the Polish language for translating OSD texts to the Polish language
@ -3547,9 +3356,6 @@ Thomas Reufer <thomas@reufer.ch>
for adding cFont::Width(void) to get the default character width and allow stretched for adding cFont::Width(void) to get the default character width and allow stretched
font drawing in high level OSDs font drawing in high level OSDs
for fixing regenerating the index of audio recordings for fixing regenerating the index of audio recordings
for implementing the SVDRP commands 'LSTD' and 'PRIM'
for adding some comments regarding font height
for reporting a possible problem with plugins calling IsOpen() in ~cDisplayChannel()
Eike Sauer <EikeSauer@t-online.de> Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting for reporting a problem with channels that need more than 5 TS packets for detecting
@ -3594,7 +3400,6 @@ Dietmar Spingler <d_spingler@gmx.de>
for suggesting to optionally list the channels with channel ids in the SVDRP command LSTC for suggesting to optionally list the channels with channel ids in the SVDRP command LSTC
for suggesting to include the channel ID in log messages about switching channels for suggesting to include the channel ID in log messages about switching channels
for reporting a problem with the SVDRP command CHAN while the channel display is open for reporting a problem with the SVDRP command CHAN while the channel display is open
for suggesting to automatically close the CAM menu when the current channel is switched
Stefan Schallenberg <infos@nafets.de> Stefan Schallenberg <infos@nafets.de>
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement() for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
@ -3603,10 +3408,6 @@ Stefan Schallenberg <infos@nafets.de>
Claus Muus <email@clausmuus.de> Claus Muus <email@clausmuus.de>
for adding the new parameters "Setup/Miscellaneous/Volume steps" and for adding the new parameters "Setup/Miscellaneous/Volume steps" and
".../Volume linearize" ".../Volume linearize"
for reporting multiple recording entries in case a recording is started during the
initial reading of the video directory
for reporting that getting the lock for removing deleted recordings may fail if the
disk is full
Dieter Ferdinand <dieter.ferdinand@gmx.de> Dieter Ferdinand <dieter.ferdinand@gmx.de>
for reporting a problem with jumping to an absolute position via the Red key in for reporting a problem with jumping to an absolute position via the Red key in
@ -3623,14 +3424,6 @@ Jasmin Jessich <jasmin@anw.at>
debugging MTD support debugging MTD support
for fixing selecting delivery system names in case of undefined indexes for fixing selecting delivery system names in case of undefined indexes
for fixing detecting the inclusion of STL header files in tools.h for fixing detecting the inclusion of STL header files in tools.h
for help and suggestions when implementing debug output for checking the correct
sequence of locking global lists
for suggesting to use $(Q) to control Makefile verbosity
for adding handling DEBUG to the Make.config.template file, in order to control
code optimization
for suggesting to change the macros used to control deprecated code or functions
to numeric values (0 and 1), so that they can be controlled at compile time, without
having to edit the actual source code
Martin Schirrmacher <schirrmie@gmail.com> Martin Schirrmacher <schirrmie@gmail.com>
for suggesting to provide a way for skin plugins to get informed about the currently for suggesting to provide a way for skin plugins to get informed about the currently
@ -3645,13 +3438,6 @@ Stefan Herdler <herdler@gmx.de>
too early too early
for reporting a bug in using the default sort mode in a video directory without a for reporting a bug in using the default sort mode in a video directory without a
".sort" file ".sort" file
for reporting faulty memory handling in cString::Append()
for adding failsafe defaults for 'make LCLBLD=1' to the Makefile
for reporting the index file of a recording not being regenerated in case it is
present, but empty
for reporting a missing check for self-assignment in the move assignment operator
for modifying handling channel names with source to make it thread safe
for fixing setting T2 system ID from NIT
Tobias Faust <tobias.faust@gmx.de> Tobias Faust <tobias.faust@gmx.de>
for the original "jumpingseconds" patch for the original "jumpingseconds" patch
@ -3690,7 +3476,6 @@ Stefan P
Robert Hannebauer <vdr@hannebauer.org> Robert Hannebauer <vdr@hannebauer.org>
for fixing an overflow of PIDs in a receiver for fixing an overflow of PIDs in a receiver
for fixing opening the UDP port in peerdemo
Aitugan Sarbassov <isarbassov@gmail.com> Aitugan Sarbassov <isarbassov@gmail.com>
for adding 'S58.5E Kazsat 3' to sources.conf for adding 'S58.5E Kazsat 3' to sources.conf
@ -3703,118 +3488,3 @@ Sergey Chernyavskiy <glenvt18@gmail.com>
Frank Richter <kulpstur@t-online.de> Frank Richter <kulpstur@t-online.de>
for adding 'S3W ABS-3A' to sources.conf for adding 'S3W ABS-3A' to sources.conf
Daniel Scheller <d.scheller@gmx.net>
for reporting a problem with detecting whether a CAM replies to queries, which didn't
work on some systems since the implementation of RI_HOST_CONTROL
Onur Sentürk <onur@sentek.org>
for making the MTD mapper avoid immediately reusing unique PIDs when switching channels
for fixing handling shared CA pids
for fixing handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
in "backwards compatibility mode" according to ETSI EN 300 468
for pointing out some potentially mistakable code in cSectionHandler::SetStatus()
for adding periodic calls to malloc_trim(0) to reduce memory consumption
Helmut Binder <cco@aon.at>
for improving calculating signal strength and quality
for fixing switching through encrypted channels with the Up/Down keys
for deactivating MTD support if a non MCD capable CAM is inserted after removing
a previously used CAM that is MCD capable
for fixing accessing the actual frontend on multi frontend devices
for fixing processing the last entry in the scan list of the EIT scanner
for fixing processing transponder data in the NIT
for fixing triggering the SDT filter when parsing the NIT
for reporting a bug in processing SI::T2DeliverySystemDescriptor when typecasting it
over an SI::ExtensionDescriptor
for fixing mapping SIDs in MTD
for fixing updating the checksum in the CA table after mapping EMM PIDs for MTD
for fixing a compiler warning in ExchangeChars()
for suggesting to add __attribute__((packed)) to tIndexPes and tIndexTs
for helping with the implementation of retuning if the received transponder's SDT
doesn't contain the expected values for NID and TID
for adding the language code for Bulgarian
for a patch that was used as a base for fixing handling multi part ExtendedEventDescriptors
where only the first part contains information about the character table
for suggesting to check and report whether the given value is valid when setting the
override character table
for adding codes for more languages and special audio tracks
for adding cMtdCamSlot::TsPostProcess()
for adding cMtdHandler::StopDecrypting()
for adding support for detecting new channels broadcast in HEVC
for adding support for detecting 'advanced codec digital radio sound service'
for adding handling shared PMT pids and multiple PMT sections
for changing the country code in the generated ParentalRatingDescriptor from 'DEU' to
'902' to make it valid for all countries
for adjusting device selection in GetDeviceForTransponder() to that in GetDevice()
for adding CRC check of the CAT in cCaPidReceiver::Receive()
for reporting that the 'else if' branch in cDevice::GetDeviceForTransponder() hasn't
been active since version 1.7.29
for fixing handling inactive shared CA pids
for implementing handling multi packet CATs with MTD
for adding checking the symbol rate to cDvbTuner::IsTunedTo(), which apparently got
lost in version 1.7.13
for adding a check for an empty command in cDvbTuner::GetSignalStats() to avoid a
possible error message
for initializing the status variable in cDvbTuner::GetFrontendStatus() and
cDvbTuner::GetSignalStats() to avoid problems with drivers that don't do this
for fixing "read incomplete section" errors
for fixing generating the HashId in cEIT::cEIT()
for fixing a bug in handling shared PMTs, where after the first pass not all SIDs of a
PMT pid were checked any more
for reporting a problem with PMT handling in case locking the Channels list times out
for avoiding a lengthy lock on the Channels list when starting a recording
for preventing switching devices for pattern timers
for pointing out that cChannel::Transponder(void) is called very often
for fixing flushing old data from the section handler
for removing unused declaration of cDvbTuner::SetFrontendType()
for fixing handling incomplete multi-packet CAT
for fixing a memory leak in handling the NIT
for reporting a possible memory leak in creating fonts
for fixing a possible deadlock in cDevice::DetachAllReceivers()
Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is
keeping the OSD open
Stian B. Barmen <stian@barmen.nu>
for reporting missing EPG data on channels from Canal Digital Norway
Jürgen Schneider <jsffm@web.de>
for reporting a possible discrepancy of the primary device number in the LSTD and
PRIM commands
for adding support for EAC3 audio from other sources
for reporting a crash if a pattern timer spawns a timer that uses EPISODE and the
event has no short text
for reporting a bug in VPS handling when spawning a pattern timer, in case Setup.UseVps
is false
for reporting an endless spawning of pattern timers in case the spawned timer doesn't
use VPS and fully overlaps a second event that is longer than the original one
for reporting a missing EPISODE macro expansion in case the event doesn't yet have a
short text when generating the pattern timer file name
for reporting a problem with spawned timers jumping to the next event in case
Setup.EPGLinger is very small
Stefan Verse <Verse@amotronics.de>
for fixing an occasional black screen when switching channels
Jens Schleusener <Jens.Schleusener@fossies.org>
for reporting several typos
Bernd Kuhls <bernd.kuhls@t-online.de>
for fixing possible compilation errors with libjpeg
Ulf Grüne <ulf.gruene@t-online.de>
for reporting the need for more than 15 modulation systems in cDevice::GetDevice()
Timo Weingärtner <timo@tiwe.de>
for reporting an integer overflow in calculating the disk use percentage if there's
more than 20TB of recordings
Jose Angel <joseangelpp@gmail.com>
for reporting a bug in default values for DVB-T
Andreas Baierl <post@andreasbaierl.de>
for implementing scaling images
for reporting a problem in the progress display when switching from "pause" to
"slow back"

1040
HISTORY

File diff suppressed because it is too large Load Diff

59
INSTALL
View File

@ -1,7 +1,7 @@
Installation of the Video Disk Recorder Installation of the Video Disk Recorder
--------------------------------------- ---------------------------------------
Version 2.7 Version 2.2
----------- -----------
Compiling and running the program: Compiling and running the program:
@ -47,9 +47,9 @@ By default the 'vdr' program can be controlled via the PC keyboard.
If you want to disable control via the keyboard, you can add NO_KBD=1 If you want to disable control via the keyboard, you can add NO_KBD=1
to the 'make' call, or use the '--no-kbd' option at runtime. to the 'make' call, or use the '--no-kbd' option at runtime.
If you have a LIRC compatible infrared remote control receiver you can define If you have an infrared remote control unit you can define the REMOTE macro
the REMOTE macro to one of the following values in the 'make' call to make to one of the following values in the 'make' call to make the respective control
the respective control the default: the default:
REMOTE=LIRC control via the "Linux Infrared Remote Control" REMOTE=LIRC control via the "Linux Infrared Remote Control"
(see http://www.lirc.org) (see http://www.lirc.org)
@ -73,15 +73,16 @@ port ("Simple Video Disk Recorder Protocol"). By default, it listens
on port 6419 (use the --port=PORT option to change this). For details on port 6419 (use the --port=PORT option to change this). For details
about the SVDRP syntax see the source file 'svdrp.c'. about the SVDRP syntax see the source file 'svdrp.c'.
WARNING: DUE TO THE OPEN SVDRP PORT THIS PROGRAM MAY CONSTITUTE A
======= POTENTIAL SECURITY HAZARD! IF YOU ARE NOT RUNNING VDR IN
A CONTROLLED ENVIRONMENT, YOU MAY WANT TO DISABLE SVDRP
BY USING '--port=0'!
The file 'svdrphosts.conf' can be used to define which hosts are allowed The file 'svdrphosts.conf' can be used to define which hosts are allowed
to access the SVDRP port. By default only localhost (127.0.0.1) is granted to access the SVDRP port. By default only localhost (127.0.0.1) is granted
access. If you want to give other hosts access to your SVDRP port you need to access. If you want to give other hosts access to your SVDRP port you need to
add their IP numbers to 'svdrphosts.conf'. add their IP numbers to 'svdrphosts.conf'.
You can disable SVDRP access entirely by either running VDR with '--port=0',
or by removing all entries (including 127.0.0.1 for the localhost) from
'svdrphosts.conf'.
If the program shall run as a daemon, use the --daemon option. This If the program shall run as a daemon, use the --daemon option. This
will completely detach it from the terminal and will continue as a will completely detach it from the terminal and will continue as a
background process. background process.
@ -103,13 +104,13 @@ hardware in your system, for instance:
Plugin: Device: Plugin: Device:
dvbsddevice Full-Featured SD DVB cards (Fujitsu-Siemens Design) dvbsddevice Full-Featured SD DVB cards (Fujitsu-Siemens Design)
ftp://ftp.tvdr.de/vdr/Plugins (comes with the VDR source)
dvbhddevice Full-featured HD DVB cards (Technotrend TT S2-6400) dvbhddevice Full-featured HD DVB cards (Technotrend TT S2-6400)
https://bitbucket.org/powARman/dvbhddevice https://bitbucket.org/powARman/dvbhddevice
rpihddevice Raspberry Pi rpihddevice Raspberry Pi
https://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git http://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
See https://linuxtv.org/vdrwiki/index.php/Output_devices for more. See http://linuxtv.org/vdrwiki/index.php/Output_devices for more.
Standard compliance Standard compliance
------------------- -------------------
@ -264,10 +265,11 @@ Executing commands before and after a recording:
------------------------------------------------ ------------------------------------------------
You can use the '-r' option to define a program or script that gets called You can use the '-r' option to define a program or script that gets called
at various stages of handling recordings. before and after a recording is performed, and after an editing process
has finished or a recording has been deleted.
The program will be called with two or three string parameters. The program will be called with two or three (in case of "editing" and "edited")
The first parameter is one of string parameters. The first parameter is one of
before if this is *before* a recording starts before if this is *before* a recording starts
started if this is after a recording has *started* started if this is after a recording has *started*
@ -275,16 +277,13 @@ The first parameter is one of
editing if this is before *editing* a recording editing if this is before *editing* a recording
edited if this is after a recording has been *edited* edited if this is after a recording has been *edited*
deleted if this is after a recording has been *deleted* deleted if this is after a recording has been *deleted*
copying if this is before *copying* a recording
copied if this is after a recording has been *copied*
renamed if this is after a recording has been *renamed*
moved if this is after a recording has been *moved*
(note that a move across file system borders triggers a sequence
of "copying", "copied" and "deleted")
and the second and third parameter (if present) contain the full name of the recording's and the second parameter contains the full name of the recording's
directory (which may not yet exists at that moment in the "before" case). directory (which may not yet exists at that moment in the "before" case).
See the example below for the exact meaning of these parameters. In the "editing" and "edited" case it will be the name of the edited version
(second parameter) and the name of the source version (third parameter).
In the "deleted" case the extension of the directory name is ".del"
instead of ".rec".
Within this program you can do anything you would like to do before and/or Within this program you can do anything you would like to do before and/or
after a recording or after an editing process. However, the program must return after a recording or after an editing process. However, the program must return
@ -317,22 +316,6 @@ case "$1" in
deleted) deleted)
echo "Deleted recording $2" echo "Deleted recording $2"
;; ;;
copying)
echo "Destination recording $2"
echo "Source recording $3"
;;
copied)
echo "Destination recording $2"
echo "Source recording $3"
;;
renamed)
echo "New name of recording $2"
echo "Old name of recording $3"
;;
moved)
echo "New path of recording $2"
echo "Old path of recording $3"
;;
*) *)
echo "ERROR: unknown state: $1" echo "ERROR: unknown state: $1"
;; ;;

185
MANUAL
View File

@ -1,7 +1,7 @@
Video Disk Recorder User's Manual Video Disk Recorder User's Manual
--------------------------------- ---------------------------------
Version 2.7 Version 2.2
----------- -----------
* Remote Control Keys * Remote Control Keys
@ -50,8 +50,8 @@ Version 2.7
Next Next/previous channel group (in live tv mode) Next Next/previous channel group (in live tv mode)
Prev or next/previous editing mark (in replay mode) Prev or next/previous editing mark (in replay mode)
Channel+ channel up (live view), next error (replay) Channel+ channel up
Channel- channel down (live view), previous error (replay) Channel- channel down
PrevChannel previous channel PrevChannel previous channel
Power shutdown Power shutdown
@ -90,7 +90,7 @@ Version 2.7
be treated as part of that number, not as a sort mode toggle. If no numeric be treated as part of that number, not as a sort mode toggle. If no numeric
key has been pressed for more than one second, the number is reset and '0' key has been pressed for more than one second, the number is reset and '0'
functions as sort mode toggle again. functions as sort mode toggle again.
(3) In the "Edit timer" menu, when on the "Day" item, the '0' key toggles between (3) In the "Timers" menu, when on the "Day" item, the '0' key toggles between
a single shot and a repeating timer. If "Day" indicates a repeating timer, a single shot and a repeating timer. If "Day" indicates a repeating timer,
the keys '1'...'7' can be used to toggle the individual days ('1' is Monday). the keys '1'...'7' can be used to toggle the individual days ('1' is Monday).
@ -480,8 +480,6 @@ Version 2.7
"forever", and a value of 0 means that this recording can be "forever", and a value of 0 means that this recording can be
deleted any time if a recording with a higher priority needs disk deleted any time if a recording with a higher priority needs disk
space. space.
Pattern: The pattern to use for recordings matching events (only available
for pattern timers). See section "Pattern timers" below.
File: The name under which a recording created through this timer will File: The name under which a recording created through this timer will
be stored on disk (the actual name will also contain the date and be stored on disk (the actual name will also contain the date and
time, so it is possible to have a "repeating timer" store all its time, so it is possible to have a "repeating timer" store all its
@ -513,140 +511,6 @@ Version 2.7
The "Red" key in the "Edit timer" menu opens a list of folders, which can be The "Red" key in the "Edit timer" menu opens a list of folders, which can be
used to define the file name in which the recording will be stored. used to define the file name in which the recording will be stored.
The "Yellow" key in the "Edit timer" menu toggles the timer between "Pattern"
and "Regular".
When editing the "File" field, the "Blue" key in can be used to insert useful
macros.
* Pattern timers
There are cases where it would make sense to have a more flexible kind of
recording timer. For instance, some channels that provide VPS don't always
use the exact same VPS time for a series, which is extremely annoying.
Or you might want to record all films that have a certain pattern in their
title, no matter when they are broadcast. In such cases, "pattern timers"
can help.
In the "Edit timer" menu press the Yellow button to turn a regular timer into
a pattern timer. Pressing this button again switches back to regular.
The following rules apply to pattern timers:
- Pattern timers can only work for channels that provide EPG data.
- When using pattern timers, there should always be at least one free device that
can be used to regularly receive the EPG of the pattern timer's channel.
- A pattern timer records every matching event on the given channel that overlaps
with the given start/stop time. Overlapping events are recorded in full,
even if they extend outside the given start/stop interval.
- In order to actually record an event, a pattern timer "spawns" a separate timer
that does the recording. If there are matching events that would start while
the first spawned timer is still recording (due to the start/stop margins), timers
for those events are also spawned.
- Spawned timers are marked with the flag tfSpawned.
- Spawned timers take the Priority, Lifetime and VPS settings from the pattern timer.
- The special pattern "*" matches every event. So a timer with
a start/stop time of 00:00/23:59 will record every event of that day
into separate recordings. Note that when using this pattern there should
be no other timers for the same channel, because these might interfere.
- Once a timer has been spawned, it is treated like any other regular
timer. Any changes made to the corresponding pattern timer thereafter will have
no effect on spawned timers. Note that after deleting a spawned timer,
the corresponding pattern timer may respawn it.
- Recording is done according to the event's begin/end times, either
by adding the start/stop margins (for non-VPS timers) or by using the
event's running status (for VPS timers).
- If the start/stop margins of a spawned timer are reduced because the event
before and/or after that timer's event is shorter than the respective margin,
the actual recording still uses the full margins.
- If the times of the event change, a non-VPS pattern timer automatically adjusts
itself to the new times. This also happens if the start/stop margins are changed
in the setup.
- The recording of a pattern timer is stored under the given file name, just like
regular timers do. In addition to the "TITLE" and "EPISODE" macros the file
name of a pattern timer can also use "{<}" and "{>}" to reference the part of the
event's title before and after the pattern, respectively. For instance,
if the event's title is "Abc def ghi" and the pattern is "def ", "{<}"
would contain "Abc " and "{>}" would contain "ghi" (note the matching of the
blanks). For completeness, "{=}" can be used to reference the matching
pattern itself.
- In the "Timers" menu pressing the Red button on a pattern timer only toggles the
timer between "on" and "off", even if this is a repeating timer.
- In the "Timers" menu pattern timers are sorted alphabetically to the end of the
list of timers.
- A regular timer that is currently recording can't be changed into a pattern timer.
- In the "Edit timer" menu the file name and pattern are displayed as
separate items. The Yellow button can be used to toggle between a regular
timer and a pattern timer. When going from regular to pattern, the Pattern item will
be initialized with the base part of the file name.
- The characters '^' and '$' can be used at the very beginning and end of
the pattern to anchor the pattern to the begin or end of the title.
Using both of these will match only titles that consist of exactly the given pattern,
with nothing before and nothing after it.
- The Pattern field in the "Edit timer" menu allows blanks at the end of the string,
which may help to separate the text after the matching pattern.
- If the first character of the pattern is '@', an event that matches the
rest of the pattern is only recorded if the resulting recording's file
name (without any folders) is not contained in the donerecs.data file.
This avoids duplicate recordings of the same programme. Timers spawned from
such a pattern timer are marked with the flag tfAvoid.
- When editing the "File" field of a timer, the Blue button can be pressed to
insert one of the macros "TITLE", "EPISODE", "{<}", "{=}" or "{>}",
respectively. Pressing the Blue button repeatedly loops through the available
macros. The "{...}" macros are only available for pattern timers.
- In the "Schedule" and "What's on...?" menus the events that will be recorded
by a pattern timer are marked in the same way as regular timers.
- The TIMERS column in the LCARS skin doesn't show the basic definitions of
pattern timers, it only shows timers actually spawned from pattern timers.
If the pattern is prepended with '@', the name of the resulting recording (everything
after the rightmost '~', or the entire file name, if there is no '~') will be stored
in the file donerecs.data, so that multiple recordings of the same programme can be
avoided. When using this feature, special care must be taken regarding the recording's
file name. For instance, with a combination of
pattern file name
@Columbo Movies~TITLE
if the event's title is just "Columbo", this pattern timer would only record once,
and ignore any future events with that title, even if the episode would be different.
So you may want to use the episode name, as in
pattern file name
@Columbo Movies~TITLE - EPISODE
to make the file name unique. If you have several pattern timers for the same show on
different channels, chances are that the broadcasters handle title and episode
differently, as for example in
TITLE EPISODE pattern file name
Columbo Blueprint for Murder @^Columbo$ TITLE - EPISODE
Columbo - Blueprint for Murder @^Columbo TITLE
Columbo: Blueprint for Murder @^Columbo:_ Columbo - {>}
(note the '_' in the pattern of the third example; this is just used to visualize
the blank at the end of the pattern)
In order to have the same episode result in the same recording file name on all
channels, the file name needs to be generated differently for each channel. First
you need to decide on a proper combination of title and episode name, preferably
one that is already used by one of your channels (let's say the second one).
In the first case, title and episode name are correctly put in their respective
places, and "TITLE - EPISODE" as file name will do. The second case is our common
version, where everything is in the title, so TITLE is just fine. The third case
poses a problem, because everything is in the title, but with a different separator.
Here the special macro "{>}" can be used in the file name, which contains everything
following the matching pattern. There are three macros that can be used here:
{<} everything before the matching pattern
{>} everything after the matching pattern
{=} the matching pattern itself (just for completeness)
As of VDR version 2.5.2, the characters ' ' (blank), ':' and '-' are ignored
when checking whether a particular recording has already been made by a pattern
timer, making "TITLE - EPISODE" and "TITLE: EPISODE" the same.
VDR version 2.6.6 added '/' to this list.
* Managing folders * Managing folders
The "Select folder" menu, which can be accessed by pressing the "Red" key in The "Select folder" menu, which can be accessed by pressing the "Red" key in
@ -801,13 +665,6 @@ VDR version 2.6.6 added '/' to this list.
If a particular sort mode has been selected for a folder by If a particular sort mode has been selected for a folder by
pressing '0', the default no longer applies to that folder. pressing '0', the default no longer applies to that folder.
Sorting direction for recordings = ascending
When recordings are sorted "by time", they appear in ascending
order (i.e. "oldest" to "newest"). If this parameter is set to
"descending", they will be presented "newest" to "oldest.
Note that in the latter case, if "Always sort folders first"
is "yes", folders will appear in reverse alphabetical order.
Number keys for characters = yes Number keys for characters = yes
Controls whether the number keys can be used to enter Controls whether the number keys can be used to enter
characters in a text input field. You may want to set this characters in a text input field. You may want to set this
@ -829,16 +686,6 @@ VDR version 2.6.6 added '/' to this list.
A value of '0' completely turns off scanning on both single A value of '0' completely turns off scanning on both single
and multiple card systems. and multiple card systems.
EPG scan max. channel number = 0
The EPG scan will only tune to transponders of channels with
numbers below this limit. By default all transponders will
be scanned.
EPG pause after scan = no
After a complete scan of all transponders (optionally limited
by "EPG scan max. channel number") the EPG scan pauses for
"EPG scan timeout" hours if this option is set to "yes".
EPG bugfix level = 3 Some tv stations transmit weirdly formatted EPG data. EPG bugfix level = 3 Some tv stations transmit weirdly formatted EPG data.
VDR attempts to fix these bugs up to the given level: VDR attempts to fix these bugs up to the given level:
0 = no EPG fixing 0 = no EPG fixing
@ -1040,9 +887,6 @@ VDR version 2.6.6 added '/' to this list.
after the official end time it shall stop recording. after the official end time it shall stop recording.
These margins are added automatically to timers that These margins are added automatically to timers that
are created from the EPG data. are created from the EPG data.
Note that the actual margins used may be smaller than the
given values, if the event before and/or after the event
to be recorded is shorter than the respective margin.
Default priority = 50 The default Priority and Lifetime values used when Default priority = 50 The default Priority and Lifetime values used when
Default lifetime = 99 creating a new timer event. A Lifetime value of 99 Default lifetime = 99 creating a new timer event. A Lifetime value of 99
@ -1241,16 +1085,8 @@ VDR version 2.6.6 added '/' to this list.
connection after which the connection is automatically connection after which the connection is automatically
closed. Default is 300, a value of 0 means no timeout. closed. Default is 300, a value of 0 means no timeout.
SVDRP peering = off Activates automatic connections between VDRs in the same SVDRP peering = no Activates automatic connections between VDRs in the same
network. If set to "any hosts" this VDR will establish network.
connections with any available hosts. If set to "only
default host" this VDR will only connect to the VDR with
the name defined in "SVDRP default host". If no default
host has been defined, the behavior is the same as with
"any hosts". To switch from "off" to "only default host",
you may need to select "any hosts" first and confirm the
dialog by pressing "Ok" in order to be able to select a
default host.
SVDRP host name The name of this VDR, which is used when connecting VDRs SVDRP host name The name of this VDR, which is used when connecting VDRs
via SVDRP. By default, the machine's host name is used. via SVDRP. By default, the machine's host name is used.
@ -1280,7 +1116,7 @@ VDR version 2.6.6 added '/' to this list.
The time (in milliseconds) between two subsequent key The time (in milliseconds) between two subsequent key
presses generated by the remote control's repeat function. presses generated by the remote control's repeat function.
If the remote control in use has a repeat delta that is If the remote control in use has a repeat delta that is
longer than that given in this parameter, that longer delta longer than that given in this parameter, that longer delay
will prevail. will prevail.
Initial channel = The channel ID of the channel that shall be tuned to when Initial channel = The channel ID of the channel that shall be tuned to when
VDR starts. Default is empty, which means that it will VDR starts. Default is empty, which means that it will
@ -1307,11 +1143,10 @@ VDR version 2.6.6 added '/' to this list.
wrap around the beginning or end of the channel list if wrap around the beginning or end of the channel list if
this parameter is set to 'yes'. this parameter is set to 'yes'.
Show channel names with source = off Show channel names with source = no
If this option is turned on, channel names will be displayed If this option is turned on, channel names will be displayed
with the source appended to them, as in "ZDF (S)" (if the with the source appended to them, as in "ZDF (S)", where
option is set to "type), or "ZDF (S19.2E)" (if it is set to 'S' stands for "Satellite".
"full"), where 'S' stands for "Satellite".
Emergency exit = yes If, for some reason, a recording fails because the video Emergency exit = yes If, for some reason, a recording fails because the video
data stream is broken, or the CAM doesn't decrypt etc., data stream is broken, or the CAM doesn't decrypt etc.,

View File

@ -6,7 +6,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: Make.config.template 5.2 2024/10/11 14:21:04 kls Exp $ # $Id: Make.config.template 3.4 2015/02/09 09:58:45 kls Exp $
### The C compiler and options: ### The C compiler and options:
@ -16,12 +16,6 @@ CFLAGS = -g -O3 -Wall
CXX = g++ CXX = g++
CXXFLAGS = -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses CXXFLAGS = -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses
# Use 'make DEBUG=1 ...' to build a debug version of VDR and plugins:
ifdef DEBUG
CFLAGS += -O0
CXXFLAGS += -O0
endif
# Use 'make M32=1 ...' to build a 32-bit version of VDR on a 64-bit machine: # Use 'make M32=1 ...' to build a 32-bit version of VDR on a 64-bit machine:
ifdef M32 ifdef M32
CFLAGS += -m32 CFLAGS += -m32
@ -33,15 +27,14 @@ endif
# Default directories (adjust as necessary or desired): # Default directories (adjust as necessary or desired):
#PREFIX = /usr/local #PREFIX = /usr/local
#VDRROOT = $(PREFIX) #BINDIR = $(PREFIX)/bin
#BINDIR = $(VDRROOT)/bin #INCDIR = $(PREFIX)/include
#INCDIR = $(VDRROOT)/include #LIBDIR = $(PREFIX)/lib/vdr
#LIBDIR = $(VDRROOT)/lib #LOCDIR = $(PREFIX)/share/locale
#LOCDIR = $(VDRROOT)/locale #MANDIR = $(PREFIX)/share/man
#MANDIR = $(VDRROOT)/man #PCDIR = $(PREFIX)/lib/pkgconfig
#PCDIR = $(VDRROOT)/pkgconfig #RESDIR = $(PREFIX)/share/vdr
#RESDIR = $(VDRROOT)/share #DVBDIR = /usr/src/v4l-dvb/linux/include/uapi
#DVBDIR = /usr/include
#VIDEODIR = /srv/vdr/video #VIDEODIR = /srv/vdr/video
#CONFDIR = /var/lib/vdr #CONFDIR = /var/lib/vdr
@ -75,8 +68,6 @@ endif
### The remote control: ### The remote control:
LIRC_DEVICE = /var/run/lirc/lircd LIRC_DEVICE = /var/run/lirc/lircd
### Use this for kernel based driver:
#LIRC_DEVICE = /dev/lirc0
### Define if you always want to use LIRC, independent of the --lirc option: ### Define if you always want to use LIRC, independent of the --lirc option:
#REMOTE=LIRC #REMOTE=LIRC

View File

@ -4,26 +4,23 @@
# See the main source file 'vdr.c' for copyright information and # See the main source file 'vdr.c' for copyright information and
# how to reach the author. # how to reach the author.
# #
# $Id: Makefile 5.4 2024/10/21 19:01:16 kls Exp $ # $Id: Makefile 4.4 2017/05/22 15:33:30 kls Exp $
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
# Compiler flags: # Compiler flags:
PKG_CONFIG ?= pkg-config
CC ?= gcc CC ?= gcc
CFLAGS ?= -g -O3 -Wall CFLAGS ?= -g -O3 -Wall
CXX ?= g++ CXX ?= g++
CXXFLAGS ?= -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses CXXFLAGS ?= -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses
CXXFLAGS += $(CPPFLAGS)
CDEFINES = -D_GNU_SOURCE CDEFINES = -D_GNU_SOURCE
CDEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE CDEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
LIBS = -ljpeg -lpthread -ldl -lcap -lrt $(shell $(PKG_CONFIG) --libs freetype2 fontconfig) LIBS = -ljpeg -lpthread -ldl -lcap -lrt $(shell pkg-config --libs freetype2 fontconfig)
INCLUDES ?= $(shell $(PKG_CONFIG) --cflags freetype2 fontconfig) INCLUDES ?= $(shell pkg-config --cflags freetype2 fontconfig)
# Directories: # Directories:
@ -31,14 +28,6 @@ CWD ?= $(shell pwd)
LSIDIR ?= $(CWD)/libsi LSIDIR ?= $(CWD)/libsi
PLUGINDIR ?= $(CWD)/PLUGINS PLUGINDIR ?= $(CWD)/PLUGINS
# Failsafe defaults for "make LCLBLD=1":
ifdef LCLBLD
DESTDIR ?= $(CWD)
LOCDIR ?= $(CWD)/locale
HDRDIR ?= $(CWD)/include
LIBDIR ?= $(PLUGINDIR)/lib
endif
DESTDIR ?= DESTDIR ?=
VIDEODIR ?= /srv/vdr/video VIDEODIR ?= /srv/vdr/video
CONFDIR ?= /var/lib/vdr CONFDIR ?= /var/lib/vdr
@ -46,14 +35,13 @@ ARGSDIR ?= /etc/vdr/conf.d
CACHEDIR ?= /var/cache/vdr CACHEDIR ?= /var/cache/vdr
PREFIX ?= /usr/local PREFIX ?= /usr/local
VDRROOT ?= $(PREFIX) BINDIR ?= $(PREFIX)/bin
BINDIR ?= $(VDRROOT)/bin INCDIR ?= $(PREFIX)/include
INCDIR ?= $(VDRROOT)/include LIBDIR ?= $(PREFIX)/lib/vdr
LIBDIR ?= $(VDRROOT)/lib/vdr LOCDIR ?= $(PREFIX)/share/locale
LOCDIR ?= $(VDRROOT)/share/locale MANDIR ?= $(PREFIX)/share/man
MANDIR ?= $(VDRROOT)/share/man PCDIR ?= $(PREFIX)/lib/pkgconfig
PCDIR ?= $(VDRROOT)/lib/pkgconfig RESDIR ?= $(PREFIX)/share/vdr
RESDIR ?= $(VDRROOT)/share/vdr
# Source documentation # Source documentation
@ -64,15 +52,6 @@ DOXYFILE = Doxyfile
-include Make.config -include Make.config
# Output control
ifdef VERBOSE
Q =
else
Q = @
endif
export Q
# Mandatory compiler flags: # Mandatory compiler flags:
CFLAGS += -fPIC CFLAGS += -fPIC
@ -111,14 +90,14 @@ ifdef VDR_USER
DEFINES += -DVDR_USER=\"$(VDR_USER)\" DEFINES += -DVDR_USER=\"$(VDR_USER)\"
endif endif
ifdef BIDI ifdef BIDI
INCLUDES += $(shell $(PKG_CONFIG) --cflags fribidi) INCLUDES += $(shell pkg-config --cflags fribidi)
DEFINES += -DBIDI DEFINES += -DBIDI
LIBS += $(shell $(PKG_CONFIG) --libs fribidi) LIBS += $(shell pkg-config --libs fribidi)
endif endif
ifdef SDNOTIFY ifdef SDNOTIFY
INCLUDES += $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd-daemon || $(PKG_CONFIG) --cflags libsystemd) INCLUDES += $(shell pkg-config --silence-errors --cflags libsystemd-daemon || pkg-config --cflags libsystemd)
DEFINES += -DSDNOTIFY DEFINES += -DSDNOTIFY
LIBS += $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd-daemon || $(PKG_CONFIG) --libs libsystemd) LIBS += $(shell pkg-config --silence-errors --libs libsystemd-daemon || pkg-config --libs libsystemd)
endif endif
LIRC_DEVICE ?= /var/run/lirc/lircd LIRC_DEVICE ?= /var/run/lirc/lircd
@ -143,7 +122,7 @@ all: vdr i18n plugins
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
# Dependencies: # Dependencies:
@ -158,7 +137,7 @@ $(DEPFILE): Makefile
vdr: $(OBJS) $(SILIB) vdr: $(OBJS) $(SILIB)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) -rdynamic $(LDFLAGS) $(OBJS) $(LIBS) $(SILIB) -o vdr @$(CXX) $(CXXFLAGS) -rdynamic $(LDFLAGS) $(OBJS) $(LIBS) $(SILIB) -o vdr
# The libsi library: # The libsi library:
@ -170,9 +149,7 @@ make-libsi: # empty rule makes sure the sub-make for libsi is always called
.PHONY: vdr.pc .PHONY: vdr.pc
vdr.pc: vdr.pc:
@echo "vdrrootdir=$(VDRROOT)" > $@ @echo "bindir=$(BINDIR)" > $@
@echo "bindir=$(BINDIR)" >> $@
@echo "incdir=$(INCDIR)" >> $@
@echo "mandir=$(MANDIR)" >> $@ @echo "mandir=$(MANDIR)" >> $@
@echo "videodir=$(VIDEODIR)" >> $@ @echo "videodir=$(VIDEODIR)" >> $@
@echo "configdir=$(CONFDIR)" >> $@ @echo "configdir=$(CONFDIR)" >> $@
@ -188,7 +165,7 @@ vdr.pc:
@echo "" >> $@ @echo "" >> $@
@echo "Name: VDR" >> $@ @echo "Name: VDR" >> $@
@echo "Description: Video Disk Recorder" >> $@ @echo "Description: Video Disk Recorder" >> $@
@echo "URL: https://www.tvdr.de/" >> $@ @echo "URL: http://www.tvdr.de/" >> $@
@echo "Version: $(VDRVERSION)" >> $@ @echo "Version: $(VDRVERSION)" >> $@
@echo "Cflags: \$${cflags}" >> $@ @echo "Cflags: \$${cflags}" >> $@
@ -203,20 +180,20 @@ I18Npot = $(PODIR)/vdr.pot
%.mo: %.po %.mo: %.po
@echo MO $@ @echo MO $@
$(Q)msgfmt -c -o $@ $< @msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c) $(I18Npot): $(wildcard *.c)
@echo GT $@ @echo GT $@
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ `ls $^` @xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ `ls $^`
%.po: $(I18Npot) %.po: $(I18Npot)
@echo PO $@ @echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@ @touch $@
$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr.mo: $(PODIR)/%.mo $(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr.mo: $(PODIR)/%.mo
@echo IN $@ @echo IN $@
$(Q)install -D -m644 $< $@ @install -D -m644 $< $@
.PHONY: i18n .PHONY: i18n
i18n: $(I18Nmsgs) i18n: $(I18Nmsgs)
@ -258,7 +235,7 @@ plugins: include-dir vdr.pc
INCLUDES="-I$(CWD)/include"\ INCLUDES="-I$(CWD)/include"\
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" || failed="$$failed $$i";\ $(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" || failed="$$failed $$i";\
if [ -n "$(LCLBLD)" ] ; then\ if [ -n "$(LCLBLD)" ] ; then\
(cd $(PLUGINDIR)/src/$$i; for l in `find -name "libvdr-*.so" -o -name "lib$$i-*.so"`; do install -D $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\ (cd $(PLUGINDIR)/src/$$i; for l in `find -name "libvdr-*.so" -o -name "lib$$i-*.so"`; do install $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\
if [ -d $(PLUGINDIR)/src/$$i/po ]; then\ if [ -d $(PLUGINDIR)/src/$$i/po ]; then\
for l in `ls $(PLUGINDIR)/src/$$i/po/*.mo`; do\ for l in `ls $(PLUGINDIR)/src/$$i/po/*.mo`; do\
install -D -m644 $$l $(LOCDIR)/`basename $$l | cut -d. -f1`/LC_MESSAGES/vdr-$$i.mo;\ install -D -m644 $$l $(LOCDIR)/`basename $$l | cut -d. -f1`/LC_MESSAGES/vdr-$$i.mo;\
@ -285,7 +262,7 @@ clean-plugins: vdr.pc
# Install the files (note that 'install-pc' must be first!): # Install the files (note that 'install-pc' must be first!):
install: install-pc install-bin install-conf install-doc install-plugins install-i18n install-includes install: install-pc install-bin install-dirs install-conf install-doc install-plugins install-i18n install-includes
# VDR binary: # VDR binary:
@ -302,13 +279,8 @@ install-dirs:
@mkdir -p $(DESTDIR)$(CACHEDIR) @mkdir -p $(DESTDIR)$(CACHEDIR)
@mkdir -p $(DESTDIR)$(RESDIR) @mkdir -p $(DESTDIR)$(RESDIR)
install-conf: install-dirs install-conf:
# 'cp -n' may be broken, so let's do it the hard way @cp -pn *.conf $(DESTDIR)$(CONFDIR)
@for i in *.conf; do\
if ! [ -e $(DESTDIR)$(CONFDIR)/$$i ] ; then\
cp -p $$i $(DESTDIR)$(CONFDIR);\
fi\
done
# Documentation: # Documentation:
@ -323,7 +295,6 @@ install-doc:
install-plugins: plugins install-plugins: plugins
@-for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\ @-for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\
echo; echo "*** Plugin $$i:";\
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR=$(CWD) DESTDIR=$(DESTDIR) install;\ $(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR=$(CWD) DESTDIR=$(DESTDIR) install;\
done done
@if [ -d $(PLUGINDIR)/lib ] ; then\ @if [ -d $(PLUGINDIR)/lib ] ; then\
@ -351,7 +322,6 @@ install-pc: vdr.pc
srcdoc: srcdoc:
@cat $(DOXYFILE) > $(DOXYFILE).tmp @cat $(DOXYFILE) > $(DOXYFILE).tmp
@echo PROJECT_NUMBER = $(VDRVERSION) >> $(DOXYFILE).tmp @echo PROJECT_NUMBER = $(VDRVERSION) >> $(DOXYFILE).tmp
@chmod +x $(DOXYFILE).filter
$(DOXYGEN) $(DOXYFILE).tmp $(DOXYGEN) $(DOXYFILE).tmp
@rm $(DOXYFILE).tmp @rm $(DOXYFILE).tmp
@ -360,7 +330,7 @@ srcdoc:
clean: clean:
@$(MAKE) --no-print-directory -C $(LSIDIR) clean @$(MAKE) --no-print-directory -C $(LSIDIR) clean
@-rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~ @-rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~
@-rm -rf $(LOCALEDIR) $(PODIR)/*~ $(PODIR)/*.mo $(PODIR)/*.pot @-rm -rf $(LOCALEDIR) $(PODIR)/*.mo $(PODIR)/*.pot
@-rm -rf include @-rm -rf include
@-rm -rf srcdoc @-rm -rf srcdoc
CLEAN: clean CLEAN: clean

View File

@ -31,11 +31,14 @@ modified {
<div class="center"> <div class="center">
<h1>The VDR Plugin System</h1> <h1>The VDR Plugin System</h1>
<b>Version 2.7</b> <b>Version 2.2</b>
<p> <p>
Copyright &copy; 2021 Klaus Schmidinger<br> Copyright &copy; 2015 Klaus Schmidinger<br>
<a href="mailto:vdr@tvdr.de">vdr@tvdr.de</a><br> <a href="mailto:vdr@tvdr.de">vdr@tvdr.de</a><br>
<a href="https://www.tvdr.de">www.tvdr.de</a> <a href="http://www.tvdr.de">www.tvdr.de</a>
</div>
<div class="center">
<modified>Important modifications introduced since version 2.2 are marked like this.</modified>
</div> </div>
<p> <p>
VDR provides an easy to use plugin interface that allows additional functionality VDR provides an easy to use plugin interface that allows additional functionality
@ -74,6 +77,7 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#Main menu entry">Main menu entry</a> <li><a href="#Main menu entry">Main menu entry</a>
<li><a href="#User interaction">User interaction</a> <li><a href="#User interaction">User interaction</a>
<li><a href="#Housekeeping">Housekeeping</a> <li><a href="#Housekeeping">Housekeeping</a>
<li><a href="#Main thread hook">Main thread hook</a>
<li><a href="#Activity">Activity</a> <li><a href="#Activity">Activity</a>
<li><a href="#Wakeup">Wakeup</a> <li><a href="#Wakeup">Wakeup</a>
<li><a href="#Setup parameters">Setup parameters</a> <li><a href="#Setup parameters">Setup parameters</a>
@ -82,7 +86,6 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#Internationalization">Internationalization</a> <li><a href="#Internationalization">Internationalization</a>
<li><a href="#Custom services">Custom services</a> <li><a href="#Custom services">Custom services</a>
<li><a href="#SVDRP commands">SVDRP commands</a> <li><a href="#SVDRP commands">SVDRP commands</a>
<li><a href="#Locking">Locking</a>
<li><a href="#Loading plugins into VDR">Loading plugins into VDR</a> <li><a href="#Loading plugins into VDR">Loading plugins into VDR</a>
<li><a href="#Building the distribution package">Building the distribution package</a> <li><a href="#Building the distribution package">Building the distribution package</a>
</ul> </ul>
@ -165,7 +168,7 @@ is used:
VDR/PLUGINS/src VDR/PLUGINS/src
VDR/PLUGINS/src/hello VDR/PLUGINS/src/hello
VDR/PLUGINS/lib VDR/PLUGINS/lib
VDR/PLUGINS/lib/libvdr-hello.so.1 VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
</pre></td></tr></table><p> </pre></td></tr></table><p>
The <tt>src</tt> directory contains one subdirectory for each plugin, which carries The <tt>src</tt> directory contains one subdirectory for each plugin, which carries
@ -184,7 +187,7 @@ The <tt>lib</tt> directory contains the dynamically loadable libraries of all
available plugins. Note that the names of these files are created by concatenating available plugins. Note that the names of these files are created by concatenating
<p> <p>
<table border=2> <table border=2>
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1</tt></b></td></tr> <tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
<tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr> <tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr>
</table> </table>
<p> <p>
@ -195,11 +198,6 @@ the current VDR version. That way minor fixes to VDR, that don't require changes
to the VDR header files, can be made without requiring all plugins to be to the VDR header files, can be made without requiring all plugins to be
recompiled. recompiled.
<p> <p>
While in earlier versions of VDR the API version number was closely related to the
VDR version number, starting with VDR version 2.7.2 the API version number was changed
from a dot separated, three part number to a single integer, completely unrelated to
the VDR version. This was done to avoid confusion.
<p>
The plugin library files can be stored in any directory. If the default organization The plugin library files can be stored in any directory. If the default organization
is not used, the path to the plugin directory has be be given to VDR through the is not used, the path to the plugin directory has be be given to VDR through the
<b><tt>-L</tt></b> option. <b><tt>-L</tt></b> option.
@ -395,7 +393,13 @@ just like shown in the above example. This is a convention that allows the <tt>M
to extract the version number when generating the file name for the distribution archive. to extract the version number when generating the file name for the distribution archive.
<p> <p>
A new plugin project should start with version number <tt>0.0.1</tt> and should reach A new plugin project should start with version number <tt>0.0.1</tt> and should reach
version <tt>1.0.0</tt> once it is completely operative and well tested. version <tt>1.0.0</tt> once it is completely operative and well tested. Following the
Linux kernel version numbering scheme, versions with <i>even</i> release numbers
(like <tt>1.0.x</tt>, <tt>1.2.x</tt>, <tt>1.4.x</tt>...) should be stable releases,
while those with <i>odd</i> release numbers (like <tt>1.1.x</tt>, <tt>1.3.x</tt>,
<tt>1.5.x</tt>...) are usually considered "under development". The three parts of
a version number are not limited to single digits, so a version number of <tt>1.2.15</tt>
would be acceptable.
<hr><h2><a name="Description">Description</a></h2> <hr><h2><a name="Description">Description</a></h2>
@ -580,6 +584,7 @@ esyslog("pluginname: error #%d has occurred", ErrorNumber);
Note that the log messages will be given as provided, the plugin's name will not Note that the log messages will be given as provided, the plugin's name will not
automatically be added, so make sure your log messages are obvious enough. automatically be added, so make sure your log messages are obvious enough.
<p> <p>
<modified>
Only use the above logging functions for occasional log messages. Do not use Only use the above logging functions for occasional log messages. Do not use
them unconditionally for frequent messages that produce long sequences of lines them unconditionally for frequent messages that produce long sequences of lines
in the log file every few seconds. That might make it hard to work on other plugins in the log file every few seconds. That might make it hard to work on other plugins
@ -600,10 +605,8 @@ Under no circumstances must a plugin print anything to stdout or stderr during
normal operation! The only exceptions being special debug information as described normal operation! The only exceptions being special debug information as described
above, fatal error messages that will cause VDR to abort, or if it is the sole above, fatal error messages that will cause VDR to abort, or if it is the sole
purpose of the plugin to display something on stdout, like for instance the purpose of the plugin to display something on stdout, like for instance the
<i>skincurses</i> plugin, which displays the OSD at the console.<br> <i>skincurses</i> plugin, which displays the OSD at the console.
<br> </modified>
Please make any log messages in <b>ENGLISH</b>! Logs are usually sent to the developers
of a program, and they may not be able to read them if they are in an exotic language.
<hr><h2><a name="Main menu entry">Main menu entry</a></h2> <hr><h2><a name="Main menu entry">Main menu entry</a></h2>
@ -691,6 +694,27 @@ interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this. the plugin should launch a separate thread to do this.
</b> </b>
<hr><h2><a name="Main thread hook">Main thread hook</a></h2>
<div class="blurb">Pushing in...</div><p>
Normally a plugin only reacts on user input if directly called through its
<a href="#Main menu entry">main menu entry</a>, or performs some background
activity in a separate thread. However, sometimes a plugin may need to do
something in the context of the main program thread, without being explicitly
called up by the user. In such a case it can implement the function
<p><table><tr><td class="code"><pre>
virtual void MainThreadHook(void);
</pre></td></tr></table><p>
in which it can do this. This function is called for every plugin once during
every cycle of VDR's main program loop, which typically happens once every
second.
<b>Be very careful when using this function, and make sure you return from it
as soon as possible! If you spend too much time in this function, the user
interface performance will become sluggish!</b>
<hr><h2><a name="Activity">Activity</a></h2> <hr><h2><a name="Activity">Activity</a></h2>
<div class="blurb">Now is not a good time!</div><p> <div class="blurb">Now is not a good time!</div><p>
@ -1162,59 +1186,11 @@ The returned string may consist of several lines, separated by the newline chara
when presenting them to the caller, and the continuation character ('<tt>-</tt>') when presenting them to the caller, and the continuation character ('<tt>-</tt>')
will be set for all but the last one. will be set for all but the last one.
<p> <p>
<modified>
<b>The SVDRP functions are called from the separate "SVDRP server handler" thread. <b>The SVDRP functions are called from the separate "SVDRP server handler" thread.
Therefore the plugin needs to take care of proper <a href="#Locking">locking</a> if it accesses any Therefore the plugin needs to take care of proper locking if it accesses any
global data.</b> global data.</b>
</modified>
<hr><h2><a name="Locking">Locking</a></h2>
<div class="blurb">U can't touch this</div><p>
When accessing global data structures, proper locking is absolutely necessary.
<p>
There are several macros that allow for easy locking and unlocking. They all
follow the naming convention <tt>LOCK_*_READ|WRITE</tt>, where <tt>'*'</tt> is the name
of the global data structure, which can be one of <tt>TIMERS</tt>, <tt>CHANNELS</tt>,
<tt>RECORDINGS</tt> or <tt>SCHEDULES</tt>. To implicitly avoid deadlocks in case you
need to lock more than one structure, always make sure you use these macros in
this sequence!
<p>
Using one of these macros sets a lock on the structure, creates a local pointer to the
respective structure and makes sure the lock is released at the end of the current
block:
<p><table><tr><td class="code"><pre>
if (some condition) {
LOCK_TIMERS_READ; // creates local const cTimers *Timers
for (const cTimer *Timer = Timers-&gt;First(); Timer; Timer = Timers-&gt;Next(Timer)) {
// do something with Timer
}
}
</pre></td></tr></table><p>
Note the naming convention: TIMERS -&gt; Timers etc.
<p>
The <tt>LOCK_*_READ</tt> macros create pointers that are '<tt>const</tt>', while
the <tt>LOCK_*_WRITE</tt> macros allow modifications to the data structures.
Both wait indefinitely to obtain the lock. However, if <tt>LOCK_*_WRITE</tt> is
used twice in the same block, the second call will not obtain a lock and
immediately return <tt>NULL</tt>, which may lead to a crash. In such cases a
warning and backtrace is logged.
<p>
You may keep pointers to objects in such lists, even after releasing
the lock. However, you may only access such objects if you are
holding a proper lock again. If an object has been deleted from the list
while you did not hold a lock (for instance by an other thread), the
object will still be there, but no longer within this list (it is then
stored in the ListGarbageCollector for a few seconds). That way even if you
access the object after it has been deleted, you won't cause a segfault.
You can call the Contains() function to check whether an object you are
holding a pointer to is still in the list. Note that the garbage collector
is purged when the usual housekeeping is done.
<p>
See tools.h, class <tt>cListBase</tt> for more documentation and information on how
to use locking with timeouts, and thread.h, classes <tt>cStateLock</tt> and
<tt>cStateKey</tt> on how to easily react to changes in such lists.
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2> <hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
@ -1731,7 +1707,7 @@ restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuA
function, or any of the skin classes a plugin might implement. function, or any of the skin classes a plugin might implement.
<p> <p>
If a plugin runs a separate thread and wants to issue a message directly from If a plugin runs a separate thread and wants to issue a message directly from
within that thread, it can call within that tread, it can call
<p><table><tr><td class="code"><pre> <p><table><tr><td class="code"><pre>
int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0); int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0);
@ -2046,9 +2022,8 @@ operator!
<b>Device hooks</b> <b>Device hooks</b>
<p> <p>
VDR has builtin facilities that select which device is able to provide a given VDR has builtin facilities that select which device is able to provide a given
transponder, or, which device may provide EIT data. However, there may be transponder. However, there may be situations where the setup is so special
situations where the setup is so special that it requires considerations that that it requires considerations that exceed the scope of the core VDR code.
exceed the scope of the core VDR code.
This is where <i>device hooks</i> can be used. This is where <i>device hooks</i> can be used.
<p><table><tr><td class="code"><pre> <p><table><tr><td class="code"><pre>
@ -2056,7 +2031,6 @@ class cMyDeviceHook : public cDeviceHook {
public: public:
cMyDeviceHook(void); cMyDeviceHook(void);
virtual bool DeviceProvidesTransponder(const cDevice *Device, const cChannel *Channel) const; virtual bool DeviceProvidesTransponder(const cDevice *Device, const cChannel *Channel) const;
virtual bool DeviceProvidesEIT(const cDevice *Device) const;
}; };
</pre></td></tr></table><p> </pre></td></tr></table><p>
@ -2073,19 +2047,6 @@ bool cMyDeviceHook::DeviceProvidesTransponder(const cDevice *Device, const cChan
} }
</pre></td></tr></table><p> </pre></td></tr></table><p>
In its <tt>DeviceProvidesEIT()</tt> function the device hook can take
whatever actions are necessary to determine whether the given Device can
provide EIT data, as in
<p><table><tr><td class="code"><pre>
bool cMyDeviceHook::DeviceProvidesEIT(const cDevice *Device) const
{
if (<i>condition where Device can't provide EIT data</i>)
return false;
return true;
}
</pre></td></tr></table><p>
A plugin that creates a derived cDeviceHook shall do so in its <tt>Initialize()</tt> A plugin that creates a derived cDeviceHook shall do so in its <tt>Initialize()</tt>
function, as in function, as in
@ -2094,17 +2055,6 @@ new cMyDeviceHook;
</pre></td></tr></table><p> </pre></td></tr></table><p>
and shall not delete this object. It will be automatically deleted when the program ends. and shall not delete this object. It will be automatically deleted when the program ends.
<p>
<b>Power management</b>
<p>
A device that can be put into a power save mode can implement the function
<p><table><tr><td class="code"><pre>
virtual void SetPowerSaveMode(bool On);
</pre></td></tr></table><p>
If On is true, power save mode shall be activated, if it is false,
normal operating mode shall be restored.
<hr><h2><a name="Positioners">Positioners</a></h2> <hr><h2><a name="Positioners">Positioners</a></h2>

View File

@ -24,11 +24,3 @@ VDR Plugin 'epgtableid0' Revision History
2015-02-19: Version 2.2.0 2015-02-19: Version 2.2.0
- Official release. - Official release.
2018-04-15: Version 2.4.0
- Official release.
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:30:42 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
# #
@ -63,7 +62,7 @@ all: $(SOFILE)
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -78,7 +77,7 @@ $(DEPFILE): Makefile
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,13 +3,13 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: epgtableid0.c 4.1 2018/04/10 13:00:18 kls Exp $ * $Id: epgtableid0.c 3.2 2015/02/17 13:12:18 kls Exp $
*/ */
#include <vdr/epg.h> #include <vdr/epg.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.0"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = "EPG handler for events with table id 0x00"; static const char *DESCRIPTION = "EPG handler for events with table id 0x00";
// --- cTable0Handler -------------------------------------------------------- // --- cTable0Handler --------------------------------------------------------

View File

@ -94,12 +94,3 @@ VDR Plugin 'hello' Revision History
2015-02-19: Version 2.2.0 2015-02-19: Version 2.2.0
- Official release. - Official release.
2018-04-15: Version 2.4.0
- Updated the French OSD texts (thanks to Bernard Jaulin).
- Official release.
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:32:10 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir) LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
@ -64,7 +63,7 @@ all: $(SOFILE) i18n
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -85,15 +84,15 @@ I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po %.mo: %.po
@echo MO $@ @echo MO $@
$(Q)msgfmt -c -o $@ $< @msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c) $(I18Npot): $(wildcard *.c)
@echo GT $@ @echo GT $@
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^` @xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
%.po: $(I18Npot) %.po: $(I18Npot)
@echo PO $@ @echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@ @touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
@ -108,7 +107,7 @@ install-i18n: $(I18Nmsgs)
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: hello.c 4.1 2018/04/10 13:00:22 kls Exp $ * $Id: hello.c 3.2 2015/02/17 13:12:26 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -12,7 +12,7 @@
#include <vdr/interface.h> #include <vdr/interface.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.0"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = trNOOP("A friendly greeting"); static const char *DESCRIPTION = trNOOP("A friendly greeting");
static const char *MAINMENUENTRY = trNOOP("Hello"); static const char *MAINMENUENTRY = trNOOP("Hello");

View File

@ -1,5 +1,5 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Marc Rovira Vall <tm05462@salleURL.edu>, 2003 # Marc Rovira Vall <tm05462@salleURL.edu>, 2003
# Ramon Roca <ramon.roca@xcombo.com>, 2003 # Ramon Roca <ramon.roca@xcombo.com>, 2003
@ -7,7 +7,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006 # Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Mogens Elneff <mogens@elneff.dk>, 2004 # Mogens Elneff <mogens@elneff.dk>, 2004
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Klaus Schmidinger <vdr@tvdr.de>, 2000 # Klaus Schmidinger <vdr@tvdr.de>, 2000
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Dimitrios Dimitrakos <mail@dimitrios.de>, 2002 # Dimitrios Dimitrakos <mail@dimitrios.de>, 2002
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Ruben Nunez Francisco <ruben.nunez@tang-it.com>, 2002 # Ruben Nunez Francisco <ruben.nunez@tang-it.com>, 2002
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Arthur Konovalov <artlov@gmail.com>, 2004, 2015 # Arthur Konovalov <artlov@gmail.com>, 2004, 2015
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,5 +1,5 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Hannu Savolainen <hannu@opensound.com>, 2002 # Hannu Savolainen <hannu@opensound.com>, 2002
# Jaakko Hyvätti <jaakko@hyvatti.iki.fi>, 2002 # Jaakko Hyvätti <jaakko@hyvatti.iki.fi>, 2002
@ -8,7 +8,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,19 +1,18 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Jean-Claude Repetto <jc@repetto.org>, 2001 # Jean-Claude Repetto <jc@repetto.org>, 2001
# Olivier Jacques <jacquesolivier@hotmail.com>, 2003 # Olivier Jacques <jacquesolivier@hotmail.com>, 2003
# Gregoire Favre <greg@magma.unil.ch>, 2003 # Gregoire Favre <greg@magma.unil.ch>, 2003
# Nicolas Huillard <nhuillard@e-dition.fr>, 2005 # Nicolas Huillard <nhuillard@e-dition.fr>, 2005
# Bernard Jaulin <bernard.jaulin@gmail.com>, 2018
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2018-04-14 8:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"
"Last-Translator: Bernard Jaulin <bernard.jaulin@gmail.com>\n" "Last-Translator: Nicolas Huillard <nhuillard@e-dition.fr>\n"
"Language-Team: French <vdr@linuxtv.org>\n" "Language-Team: French <vdr@linuxtv.org>\n"
"Language: fr\n" "Language: fr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -21,19 +20,19 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
msgid "A friendly greeting" msgid "A friendly greeting"
msgstr "Bien le bonjour" msgstr ""
msgid "Hello" msgid "Hello"
msgstr "Hello" msgstr ""
msgid "Greeting time (s)" msgid "Greeting time (s)"
msgstr "Durée pour le salut (s)" msgstr ""
msgid "Use alternate greeting" msgid "Use alternate greeting"
msgstr "Changer de salutation" msgstr ""
msgid "Howdy folks!" msgid "Howdy folks!"
msgstr "Bonjour à tous !" msgstr ""
msgid "Hello world!" msgid "Hello world!"
msgstr "Bonjour le monde !" msgstr ""

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Adrian Caval <anrxc@sysphere.org>, 2008 # Adrian Caval <anrxc@sysphere.org>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2008-03-17 19:52+0100\n" "PO-Revision-Date: 2008-03-17 19:52+0100\n"

View File

@ -1,12 +1,12 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Istvan Koenigsberger <istvnko@hotmail.com>, 2002 # Istvan Koenigsberger <istvnko@hotmail.com>, 2002
# Guido Josten <guido.josten@t-online.de>, 2002 # Guido Josten <guido.josten@t-online.de>, 2002
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Diego Pierotto <vdr-italian@tiscali.it>, 2008 # Diego Pierotto <vdr-italian@tiscali.it>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2008-01-27 20:11+0100\n" "PO-Revision-Date: 2008-01-27 20:11+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Valdemaras Pipiras <varas@ambernet.lt>, 2009 # Valdemaras Pipiras <varas@ambernet.lt>, 2009
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2009-12-08 12:18+0200\n" "PO-Revision-Date: 2009-12-08 12:18+0200\n"

View File

@ -1,5 +1,5 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>, 2001 # Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>, 2001
# Hans Dingemans <hans.dingemans@tacticalops.nl>, 2003 # Hans Dingemans <hans.dingemans@tacticalops.nl>, 2003
@ -7,7 +7,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,12 +1,12 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Jørgen Tvedt <pjtvedt@online.no>, 2001 # Jørgen Tvedt <pjtvedt@online.no>, 2001
# Truls Slevigen <truls@slevigen.no>, 2002 # Truls Slevigen <truls@slevigen.no>, 2002
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,38 +1,35 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Michael Rakowski <mrak@gmx.de>, 2002 # Michael Rakowski <mrak@gmx.de>, 2002
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2018-02-19 00:41+0100\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n" "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
"Language-Team: Polish <vdr@linuxtv.org>\n" "Language-Team: Polish <vdr@linuxtv.org>\n"
"Language: pl_PL\n" "Language: pl\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=ISO-8859-2\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 2.0.6\n"
msgid "A friendly greeting" msgid "A friendly greeting"
msgstr "Przyjazne pozdrowienie" msgstr ""
msgid "Hello" msgid "Hello"
msgstr "Witaj" msgstr ""
msgid "Greeting time (s)" msgid "Greeting time (s)"
msgstr "Czas pozdrowienia (s)" msgstr ""
msgid "Use alternate greeting" msgid "Use alternate greeting"
msgstr "Użyj alternatywnego pozdrowienia" msgstr ""
msgid "Howdy folks!" msgid "Howdy folks!"
msgstr "Siema ziomy!" msgstr ""
msgid "Hello world!" msgid "Hello world!"
msgstr "Witaj świecie!" msgstr ""

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Paulo Lopes <pmml@netvita.pt>, 2001 # Paulo Lopes <pmml@netvita.pt>, 2001
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,12 +1,12 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Paul Lacatus <paul@campina.iiruc.ro>, 2002 # Paul Lacatus <paul@campina.iiruc.ro>, 2002
# Lucian Muresan <lucianm@users.sourceforge.net>, 2004 # Lucian Muresan <lucianm@users.sourceforge.net>, 2004
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Vyacheslav Dikonov <sdiconov@mail.ru>, 2004 # Vyacheslav Dikonov <sdiconov@mail.ru>, 2004
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006 # Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2009-09-30 09:48+0100\n" "PO-Revision-Date: 2009-09-30 09:48+0100\n"

View File

@ -1,12 +1,12 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Miha Setina <mihasetina@softhome.net>, 2000 # Miha Setina <mihasetina@softhome.net>, 2000
# Matjaz Thaler <matjaz.thaler@guest.arnes.si>, 2003 # Matjaz Thaler <matjaz.thaler@guest.arnes.si>, 2003
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,12 +1,12 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Tomas Prybil <tomas@prybil.se>, 2002 # Tomas Prybil <tomas@prybil.se>, 2002
# Jan Ekholm <chakie@infa.abo.fi>, 2003 # Jan Ekholm <chakie@infa.abo.fi>, 2003
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2007-08-11 12:34+0200\n" "PO-Revision-Date: 2007-08-11 12:34+0200\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Oktay Yolgeçen <oktay_73@yahoo.de>, 2007 # Oktay Yolgeçen <oktay_73@yahoo.de>, 2007
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2008-05-12 22:34:4800\n" "PO-Revision-Date: 2008-05-12 22:34:4800\n"

View File

@ -1,5 +1,5 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Marc Rovira Vall <tm05462@salleURL.edu>, 2003 # Marc Rovira Vall <tm05462@salleURL.edu>, 2003
# Ramon Roca <ramon.roca@xcombo.com>, 2003 # Ramon Roca <ramon.roca@xcombo.com>, 2003
@ -8,7 +8,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-hello 2.6.0\n" "Project-Id-Version: vdr-hello 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 14:04+0100\n" "POT-Creation-Date: 2012-12-18 14:04+0100\n"
"PO-Revision-Date: 2009-01-23 09:48+0800\n" "PO-Revision-Date: 2009-01-23 09:48+0800\n"

View File

@ -79,15 +79,3 @@ VDR Plugin 'osddemo' Revision History
- Fixed a vertical black line in the "TiledPixmaps" area on the rpihddevice OSD with - Fixed a vertical black line in the "TiledPixmaps" area on the rpihddevice OSD with
1280x800 pixel (thanks to Thomas Reufer). 1280x800 pixel (thanks to Thomas Reufer).
- Added a demo case for storing images (thanks to Thomas Reufer). - Added a demo case for storing images (thanks to Thomas Reufer).
2018-04-15: Version 2.4.0
- Official release.
2020-10-12: Version 2.4.1
- Added test cases for alignment of semi-circles (press key '4').
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:30:47 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
# #
@ -63,7 +62,7 @@ all: $(SOFILE)
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -78,7 +77,7 @@ $(DEPFILE): Makefile
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,13 +3,13 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: osddemo.c 4.5 2020/10/14 20:32:41 kls Exp $ * $Id: osddemo.c 4.3 2015/04/12 09:35:21 kls Exp $
*/ */
#include <vdr/osd.h> #include <vdr/osd.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.1"; static const char *VERSION = "2.3.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";
@ -136,91 +136,6 @@ void DrawImages(cOsd *Osd)
Osd->Flush(); Osd->Flush();
} }
// --- DrawEllipseAlignments -------------------------------------------------
void DrawEllipseAlignments(cOsd *Osd)
{
cFont *Font = cFont::CreateFont(Setup.FontOsd, 20);
int xa = 0;
int ya = 0;
int xb = Osd->Width() - 1;
int yb = Osd->Height() - 1;
Osd->DrawRectangle(xa, ya, xb, yb, clrBlack);
int d = 50;
int a = d / 2 + 1;
int t = a * 2;
int n = 30;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
Osd->DrawEllipse(a, t - d / 2, a + d - 1, t, clrGreen, 6);
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d / 2, clrGreen, 8);
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
d = 50;
a = d * 3;
n = 20;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
Osd->DrawEllipse(t - d / 2, a, t, a + d - 1, clrGreen, 7);
Osd->DrawEllipse(t + d, a, t + d + d / 2, a + d - 1, clrGreen, 5);
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
d = 50;
a = d * 3;
t = d * 5;
n = 30;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
Osd->DrawEllipse(a, t - d, a + d - 1, t, clrGreen, 2);
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d, clrGreen, 3);
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
d = 50;
a = d * 3;
t = d * 9;
n = 30;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
Osd->DrawEllipse(a, t - d, a + d - 1, t, clrGreen, 1);
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d, clrGreen, 4);
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
d = 50;
a = d * 12;
t = d * 5;
n = 20;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
Osd->DrawEllipse(t - d, a, t, a + d - 1, clrGreen, 2);
Osd->DrawEllipse(t + d, a, t + d + d, a + d - 1, clrGreen, 1);
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
d = 50;
a = d * 12;
t = d * 9;
n = 20;
for (int i = 0; i < n; i++) {
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
Osd->DrawEllipse(t - d, a, t, a + d - 1, clrGreen, 3);
Osd->DrawEllipse(t + d, a, t + d + d, a + d - 1, clrGreen, 4);
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
a += d + 5;
d++;
}
Osd->Flush();
delete Font;
}
// --- cLineGame ------------------------------------------------------------- // --- cLineGame -------------------------------------------------------------
class cLineGame : public cOsdObject { class cLineGame : public cOsdObject {
@ -675,10 +590,6 @@ eOSState cTrueColorDemo::ProcessKey(eKeys Key)
SetArea(); SetArea();
DrawImages(osd); DrawImages(osd);
break; break;
case k4: Cancel(3);
SetArea();
DrawEllipseAlignments(osd);
return osContinue;
case kBack: case kBack:
case kOk: return osEnd; case kOk: return osEnd;
default: return state; default: return state;

View File

@ -100,23 +100,6 @@ VDR Plugin 'pictures' Revision History
- Official release. - Official release.
2015-07-23: Version 2.3.1 2015-07.23: Version 2.3.1
- Added a missing 'const'. - Added a missing 'const'.
2017-10-06: Version 2.3.2
- Adapted the pic2mpg script to new ffmpeg options.
- No longer using 'convert' to scale/rotate the pictures.
2018-04-15: Version 2.4.0
- Official release.
2021-12-27: Version 2.6.0
- Official release.
2022-12-05: Version 2.6.1
Fixed initializing cPictureControl.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:31:28 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir) LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
@ -64,7 +63,7 @@ all: $(SOFILE) i18n
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -85,15 +84,15 @@ I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po %.mo: %.po
@echo MO $@ @echo MO $@
$(Q)msgfmt -c -o $@ $< @msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c) $(I18Npot): $(wildcard *.c)
@echo GT $@ @echo GT $@
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^` @xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
%.po: $(I18Npot) %.po: $(I18Npot)
@echo PO $@ @echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@ @touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
@ -108,7 +107,7 @@ install-i18n: $(I18Nmsgs)
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -7,7 +7,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: pic2mpg 4.1 2017/10/06 14:42:18 kls Exp $ # $Id: pic2mpg 3.1 2013/05/23 10:00:23 kls Exp $
use File::Path; use File::Path;
use File::Spec; use File::Spec;
@ -128,7 +128,7 @@ for ($i = 0; $i < 10; $i++) { # dirs might become empty when removing empty subd
for $dir (@Dirs) { for $dir (@Dirs) {
$dir = EscapeMeta($dir); $dir = EscapeMeta($dir);
print "removing $dir\n"; print "removing $dir\n";
Exec("rm -rf $dir"); !system("rm -rf $dir") || die "$dir: $!\n";
} }
} }
@ -142,18 +142,17 @@ sub ConvertFile
my $Exif = ImageInfo($Pict); my $Exif = ImageInfo($Pict);
my $Orientation = $$Exif{"Orientation"}; my $Orientation = $$Exif{"Orientation"};
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+)/; my ($Degrees) = $Orientation =~ /Rotate ([0-9]+)/;
my $Rotate = ($Degrees == 90) ? "transpose=clock" : ($Degrees == 180) ? "hflip,vflip" : ($Degrees == 270) ? "transpose=cclock" : ""; my $Rotate = $Degrees ? "-rotate $Degrees" : "";
$Rotate .= ',' if ($Rotate);
my $Background = '#000000@1';
print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed); print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed);
$Pict = EscapeMeta($Pict); $Pict = EscapeMeta($Pict);
$Mpeg = EscapeMeta($Mpeg); $Mpeg = EscapeMeta($Mpeg);
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles; print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
my $Cmd = "ffmpeg -i $Pict -vf '${Rotate}scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:$Background' -c:v libx264 -pix_fmt yuv420p -f mpegts -y $Mpeg " my $Cmd = "convert $Pict -background '#000000' $Rotate -resize $Size -gravity center -extent $Extent ppm:- | "
. "ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an -vcodec libx264 -vpre baseline -s $Size -qscale 2 -f mpegts -y $Mpeg "
. ($Detailed ? "" : "2>/dev/null"); . ($Detailed ? "" : "2>/dev/null");
Exec($Cmd); !system($Cmd) || die "$Cmd: $!\n";
$Cmd = "touch -r $Pict $Mpeg"; $Cmd = "touch -r $Pict $Mpeg";
Exec($Cmd); !system($Cmd) || die "$Cmd: $!\n";
} }
sub EscapeMeta sub EscapeMeta
@ -163,10 +162,3 @@ sub EscapeMeta
$s =~ s/([$META])/\\$1/g; $s =~ s/([$META])/\\$1/g;
return $s; return $s;
} }
sub Exec
{
my $Cmd = shift;
print "==> '$Cmd'\n" if ($Verbose);
!system($Cmd) || die "$Cmd: $!\n";
}

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: pictures.c 5.1 2022/12/05 15:26:23 kls Exp $ * $Id: pictures.c 4.1 2015/07/17 10:14:22 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -11,7 +11,7 @@
#include "menu.h" #include "menu.h"
#include "player.h" #include "player.h"
static const char *VERSION = "2.6.1"; static const char *VERSION = "2.3.1";
static const char *DESCRIPTION = trNOOP("A simple picture viewer"); static const char *DESCRIPTION = trNOOP("A simple picture viewer");
static const char *MAINMENUENTRY = trNOOP("Pictures"); static const char *MAINMENUENTRY = trNOOP("Pictures");

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: player.c 5.1 2022/12/05 15:26:23 kls Exp $ * $Id: player.c 3.1 2014/02/08 12:48:12 kls Exp $
*/ */
#include "player.h" #include "player.h"
@ -96,10 +96,8 @@ int cPictureControl::active = 0;
cString cPictureControl::lastDisplayed; cString cPictureControl::lastDisplayed;
cPictureControl::cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow) cPictureControl::cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow)
:cControl(NULL) :cControl(player = new cPicturePlayer)
{ {
player = new cPicturePlayer;
SetPlayer(player);
pictures = Pictures; pictures = Pictures;
pictureEntry = PictureEntry; pictureEntry = PictureEntry;
osd = NULL; osd = NULL;

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Klaus Schmidinger <vdr@tvdr.de>, 2008 # Klaus Schmidinger <vdr@tvdr.de>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-01-12 17:41+0100\n" "PO-Revision-Date: 2008-01-12 17:41+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Arthur Konovalov <artlov@gmail.com>, 2015 # Arthur Konovalov <artlov@gmail.com>, 2015
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-01-12 17:41+0100\n" "PO-Revision-Date: 2008-01-12 17:41+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2008 # Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-01-12 17:41+0100\n" "PO-Revision-Date: 2008-01-12 17:41+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Patrice Staudt <patrice.staudt@laposte.net>, 2008 # Patrice Staudt <patrice.staudt@laposte.net>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-01-12 17:41+0100\n" "PO-Revision-Date: 2008-01-12 17:41+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Diego Pierotto <vdr-italian@tiscali.it>, 2008 # Diego Pierotto <vdr-italian@tiscali.it>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-01-27 20:22+0100\n" "PO-Revision-Date: 2008-01-27 20:22+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Valdemaras Pipiras <varas@ambernet.lt>, 2009 # Valdemaras Pipiras <varas@ambernet.lt>, 2009
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2009-12-08 12:41+0100\n" "PO-Revision-Date: 2009-12-08 12:41+0100\n"

View File

@ -1,34 +0,0 @@
# VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package.
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2018-02-19 00:48+0100\n"
"PO-Revision-Date: 2018-02-19 00:53+0100\n"
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n"
"Language-Team: Polish <vdr@linuxtv.org>\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 2.0.6\n"
msgid "Pictures"
msgstr "Zdjęcia"
msgid "A simple picture viewer"
msgstr "Prosta przeglądarka zdjęć"
msgid "Picture directory"
msgstr "Katalog ze zdjęciami"
msgid "Slide show delay (s)"
msgstr "Pokaz slajdów opóźnienie (s)"
msgid "No picture directory has been defined!"
msgstr "Nie zdefiniowano katalogu ze zdjęciami!"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Alexander Gross <Bikalexander@gmail.com>, 2008 # Alexander Gross <Bikalexander@gmail.com>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2008-03-14 00:45+0100\n" "PO-Revision-Date: 2008-03-14 00:45+0100\n"

View File

@ -1,11 +1,11 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Klaus Schmidinger <vdr@tvdr.de>, 2008 # Klaus Schmidinger <vdr@tvdr.de>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-pictures 2.6.0\n" "Project-Id-Version: vdr-pictures 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2012-12-18 12:57+0100\n" "POT-Creation-Date: 2012-12-18 12:57+0100\n"
"PO-Revision-Date: 2009-09-30 12:54+0100\n" "PO-Revision-Date: 2009-09-30 12:54+0100\n"

View File

@ -29,11 +29,3 @@ VDR Plugin 'servicedemo' Revision History
2015-02-19: Version 2.2.0 2015-02-19: Version 2.2.0
- Official release. - Official release.
2018-04-15: Version 2.4.0
- Official release.
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:31:59 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -17,8 +17,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN1).c | awk '{ pr
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
# #
@ -60,7 +59,7 @@ all: libvdr-$(PLUGIN1).so libvdr-$(PLUGIN2).so
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -75,11 +74,11 @@ $(DEPFILE): Makefile
libvdr-$(PLUGIN1).so: $(PLUGIN1).o libvdr-$(PLUGIN1).so: $(PLUGIN1).o
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN1).o -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN1).o -o $@
libvdr-$(PLUGIN2).so: $(PLUGIN2).o libvdr-$(PLUGIN2).so: $(PLUGIN2).o
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN2).o -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN2).o -o $@
install-lib: libvdr-$(PLUGIN1).so libvdr-$(PLUGIN2).so install-lib: libvdr-$(PLUGIN1).so libvdr-$(PLUGIN2).so
install -D libvdr-$(PLUGIN1).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN1).so.$(APIVERSION) install -D libvdr-$(PLUGIN1).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN1).so.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Udo Richter <udo_richter@gmx.de> Written by: Udo Richter <udo_richter@gmx.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,14 +3,14 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: svccli.c 4.1 2018/04/10 13:00:53 kls Exp $ * $Id: svccli.c 3.2 2015/02/17 13:13:05 kls Exp $
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <vdr/interface.h> #include <vdr/interface.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.0"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = "Service demo client"; static const char *DESCRIPTION = "Service demo client";
static const char *MAINMENUENTRY = "Service demo"; static const char *MAINMENUENTRY = "Service demo";

View File

@ -3,14 +3,14 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: svcsvr.c 4.1 2018/04/10 13:00:57 kls Exp $ * $Id: svcsvr.c 3.2 2015/02/17 13:13:09 kls Exp $
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <vdr/interface.h> #include <vdr/interface.h>
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.0"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = "Service demo server"; static const char *DESCRIPTION = "Service demo server";
class cPluginSvcSvr : public cPlugin { class cPluginSvcSvr : public cPlugin {

View File

@ -137,27 +137,3 @@ VDR Plugin 'skincurses' Revision History
font drawing in high level OSDs (dummy for skincurses). font drawing in high level OSDs (dummy for skincurses).
- Fixed truncated date/time strings in the skins on multi-byte UTF-8 systems - Fixed truncated date/time strings in the skins on multi-byte UTF-8 systems
(reported by Sergey Chernyavskiy). (reported by Sergey Chernyavskiy).
2018-04-15: Version 2.4.0
- Official release.
2019-03-12: Version 2.4.1
- Changes for ncurses version 6 (thanks to Ulrick Eckhardt).
2020-05-11: Version 2.4.2
- Fixed 'Changes for ncurses version 6'.
- Reacting to changes in screen size.
- Simplified color handling.
- Using 'stdscr' directly instead of an additional window.
2021-07-01: Version 2.4.3
- The number of errors (if any) of a recording is now displayed in the recording's
Info menu.
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:31:47 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir) LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
@ -64,7 +63,7 @@ all: $(SOFILE) i18n
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -85,15 +84,15 @@ I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po %.mo: %.po
@echo MO $@ @echo MO $@
$(Q)msgfmt -c -o $@ $< @msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c) $(I18Npot): $(wildcard *.c)
@echo GT $@ @echo GT $@
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^` @xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
%.po: $(I18Npot) %.po: $(I18Npot)
@echo PO $@ @echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@ @touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
@ -108,7 +107,7 @@ install-i18n: $(I18Nmsgs)
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lncursesw -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lncursesw -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Klaus Schmidinger <vdr@tvdr.de>, 2007 # Klaus Schmidinger <vdr@tvdr.de>, 2007
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2007-08-15 16:07+0200\n" "PO-Revision-Date: 2007-08-15 16:07+0200\n"
"Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n" "Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n"
"Language-Team: German <vdr@linuxtv.org>\n" "Language-Team: German <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Eine reine Text-Oberfläche" msgstr "Eine reine Text-Oberfläche"
msgid "errors"
msgstr "Fehler"
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Stumm" msgstr "Stumm"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Arthur Konovalov <artlov@gmail.com>, 2015 # Arthur Konovalov <artlov@gmail.com>, 2015
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2007-08-14 20:48+0300\n" "PO-Revision-Date: 2007-08-14 20:48+0300\n"
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n" "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
"Language-Team: Estonian <vdr@linuxtv.org>\n" "Language-Team: Estonian <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Tekstipõhine kest" msgstr "Tekstipõhine kest"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Hääletu" msgstr "Hääletu"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2007 # Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2007
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2007-08-14 20:48+0300\n" "PO-Revision-Date: 2007-08-14 20:48+0300\n"
"Last-Translator: Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>\n" "Last-Translator: Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n" "Language-Team: Finnish <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Tekstipohjainen ulkoasu" msgstr "Tekstipohjainen ulkoasu"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Mykistys" msgstr "Mykistys"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Diego Pierotto <vdr-italian@tiscali.it>, 2008 # Diego Pierotto <vdr-italian@tiscali.it>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2008-01-27 20:35+0100\n" "PO-Revision-Date: 2008-01-27 20:35+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: Italian <vdr@linuxtv.org>\n" "Language-Team: Italian <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Una interfaccia solo testo" msgstr "Una interfaccia solo testo"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Muto" msgstr "Muto"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Valdemaras Pipiras <varas@ambernet.lt>, 2010 # Valdemaras Pipiras <varas@ambernet.lt>, 2010
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2010-02-22 18:18+0200\n" "PO-Revision-Date: 2010-02-22 18:18+0200\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n" "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian <vdr@linuxtv.org>\n" "Language-Team: Lithuanian <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Tekstinis apvalkalas" msgstr "Tekstinis apvalkalas"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Išjungti garsą" msgstr "Išjungti garsą"

View File

@ -1,35 +0,0 @@
# VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package.
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
"PO-Revision-Date: 2018-02-19 01:02+0100\n"
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n"
"Language-Team: Polish <vdr@linuxtv.org>\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 2.0.6\n"
msgid "A text only skin"
msgstr "Skóra tekstowa"
msgid "errors"
msgstr ""
msgid "Key$Mute"
msgstr "Wycisz"
#. TRANSLATORS: note the trailing blank!
msgid "Volume "
msgstr "Głośność "
msgid "Text mode"
msgstr "Tryb tekstowy"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Alexander Gross <Bikalexander@gmail.com>, 2008 # Alexander Gross <Bikalexander@gmail.com>, 2008
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2008-03-14 00:21+0100\n" "PO-Revision-Date: 2008-03-14 00:21+0100\n"
"Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n" "Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n"
"Language-Team: Russian <vdr@linuxtv.org>\n" "Language-Team: Russian <vdr@linuxtv.org>\n"
@ -20,9 +20,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "¿àÞáâÞ âÕÚáâÞÒëÙ ØÝâÕàäÕÙá" msgstr "¿àÞáâÞ âÕÚáâÞÒëÙ ØÝâÕàäÕÙá"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "²ëÚÛ. ÓàÞÜÚÞáâì" msgstr "²ëÚÛ. ÓàÞÜÚÞáâì"

View File

@ -1,13 +1,13 @@
# VDR plugin language source file. # VDR plugin language source file.
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de> # Copyright (C) 2015 Klaus Schmidinger <vdr@tvdr.de>
# This file is distributed under the same license as the VDR package. # This file is distributed under the same license as the VDR package.
# Klaus Schmidinger <vdr@tvdr.de>, 2007 # Klaus Schmidinger <vdr@tvdr.de>, 2007
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-skincurses 2.6.0\n" "Project-Id-Version: vdr-skincurses 2.2.0\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2021-07-01 17:28+0200\n" "POT-Creation-Date: 2015-02-08 11:16+0100\n"
"PO-Revision-Date: 2009-09-30 12:52+0100\n" "PO-Revision-Date: 2009-09-30 12:52+0100\n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <vdr@linuxtv.org>\n" "Language-Team: Slovak <vdr@linuxtv.org>\n"
@ -19,9 +19,6 @@ msgstr ""
msgid "A text only skin" msgid "A text only skin"
msgstr "Iba text vzhµadu" msgstr "Iba text vzhµadu"
msgid "errors"
msgstr ""
msgid "Key$Mute" msgid "Key$Mute"
msgstr "Stlmi» zvuk" msgstr "Stlmi» zvuk"

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: skincurses.c 5.1 2021/07/01 15:40:46 kls Exp $ * $Id: skincurses.c 4.2 2016/12/22 14:09:09 kls Exp $
*/ */
#include <ncurses.h> #include <ncurses.h>
@ -12,7 +12,7 @@
#include <vdr/skins.h> #include <vdr/skins.h>
#include <vdr/videodir.h> #include <vdr/videodir.h>
static const char *VERSION = "2.4.3"; static const char *VERSION = "2.3.2";
static const char *DESCRIPTION = trNOOP("A text only skin"); static const char *DESCRIPTION = trNOOP("A text only skin");
static const char *MAINMENUENTRY = NULL; static const char *MAINMENUENTRY = NULL;
@ -60,7 +60,9 @@ static int ScOsdHeight = 20;
class cCursesOsd : public cOsd { class cCursesOsd : public cOsd {
private: private:
WINDOW *savedRegion; WINDOW *savedRegion;
cVector<int> colorPairs; WINDOW *window;
enum { MaxColorPairs = 16 };
int colorPairs[MaxColorPairs];
void SetColor(int colorFg, int colorBg = clrBackground); void SetColor(int colorFg, int colorBg = clrBackground);
public: public:
cCursesOsd(int Left, int Top); cCursesOsd(int Left, int Top);
@ -77,34 +79,40 @@ cCursesOsd::cCursesOsd(int Left, int Top)
{ {
savedRegion = NULL; savedRegion = NULL;
memset(colorPairs, 0x00, sizeof(colorPairs));
start_color(); start_color();
leaveok(stdscr, true); leaveok(stdscr, true);
refresh(); // to react on changes to screen size
int begy, begx; window = subwin(stdscr, ScOsdHeight, ScOsdWidth, 0, 0);
int maxy, maxx; syncok(window, true);
getmaxyx(stdscr, maxy, maxx);
getbegyx(stdscr, begy, begx);
ScOsdWidth = maxx - begx;
ScOsdHeight = maxy - begy;
} }
cCursesOsd::~cCursesOsd() cCursesOsd::~cCursesOsd()
{ {
erase(); if (window) {
Flush(); werase(window);
Flush();
delwin(window);
window = NULL;
}
} }
void cCursesOsd::SetColor(int colorFg, int colorBg) void cCursesOsd::SetColor(int colorFg, int colorBg)
{ {
int color = (colorBg << 16) | colorFg | 0x80000000; int color = (colorBg << 16) | colorFg | 0x80000000;
int i = colorPairs.IndexOf(color); for (int i = 0; i < MaxColorPairs; i++) {
if (i < 0) { if (!colorPairs[i]) {
colorPairs.Append(color); colorPairs[i] = color;
i = colorPairs.Size() - 1; init_pair(i + 1, colorFg, colorBg);
init_pair(i + 1, colorFg, colorBg); //XXX??? attron(COLOR_PAIR(WHITE_ON_BLUE));
} wattrset(window, COLOR_PAIR(i + 1));
attrset(COLOR_PAIR(i + 1)); break;
}
else if (color == colorPairs[i]) {
wattrset(window, COLOR_PAIR(i + 1));
break;
}
}
} }
void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2) void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
@ -114,14 +122,13 @@ void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
savedRegion = NULL; savedRegion = NULL;
} }
savedRegion = newwin(y2 - y1 + 1, x2 - x1 + 1, y1, x1); savedRegion = newwin(y2 - y1 + 1, x2 - x1 + 1, y1, x1);
if (savedRegion) copywin(window, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
copywin(stdscr, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
} }
void cCursesOsd::RestoreRegion(void) void cCursesOsd::RestoreRegion(void)
{ {
if (savedRegion) { if (savedRegion) {
overwrite(savedRegion, stdscr); copywin(savedRegion, window, 0, 0, savedRegion->_begy, savedRegion->_begx, savedRegion->_maxy - savedRegion->_begy, savedRegion->_maxx - savedRegion->_begx, false);
delwin(savedRegion); delwin(savedRegion);
savedRegion = NULL; savedRegion = NULL;
} }
@ -161,22 +168,18 @@ void cCursesOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Co
} }
} }
SetColor(ColorFg, ColorBg); SetColor(ColorFg, ColorBg);
mvaddnstr(y, x, s, Width ? Width : ScOsdWidth - x); wmove(window, y, x); // ncurses wants 'y' before 'x'!
waddnstr(window, s, Width ? Width : ScOsdWidth - x);
} }
void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color) void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
{ {
SetColor(Color, Color); SetColor(Color, Color);
int dx = x2 - x1; for (int y = y1; y <= y2; y++) {
int dy = y2 - y1; wmove(window, y, x1); // ncurses wants 'y' before 'x'!
if (dx >= dy) { whline(window, ' ', x2 - x1 + 1);
for (int y = y1; y <= y2; y++) }
mvhline(y, x1, ' ', dx + 1); wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
}
else {
for (int x = x1; x <= x2; x++)
mvvline(y1, x, ' ', dy + 1);
}
} }
void cCursesOsd::Flush(void) void cCursesOsd::Flush(void)
@ -447,18 +450,9 @@ void cSkinCursesDisplayMenu::SetRecording(const cRecording *Recording)
cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : ""); cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground); ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
y += ts.Height(); y += ts.Height();
int xt = ScOsdWidth;
if (Info->GetEvent()->ParentalRating()) { if (Info->GetEvent()->ParentalRating()) {
cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString()); cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
int w = Utf8StrLen(buffer); osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
osd->DrawText(xt - w, y, buffer, clrBlack, clrYellow, &Font);
xt -= w + 1;
}
if (Info->Errors() > 0) {
cString buffer = cString::sprintf(" %d %s ", Info->Errors(), tr("errors"));
int w = Utf8StrLen(buffer);
osd->DrawText(xt - w, y, buffer, clrBlack, clrYellow, &Font);
xt -= w + 1;
} }
y += 1; y += 1;
const char *Title = Info->Title(); const char *Title = Info->Title();
@ -833,8 +827,12 @@ bool cPluginSkinCurses::ProcessArgs(int argc, char *argv[])
bool cPluginSkinCurses::Initialize(void) bool cPluginSkinCurses::Initialize(void)
{ {
// Initialize any background activities the plugin shall perform. // Initialize any background activities the plugin shall perform.
if (initscr()) WINDOW *w = initscr();
if (w) {
ScOsdWidth = w->_maxx - w->_begx + 1;
ScOsdHeight = w->_maxy - w->_begy + 1;
return true; return true;
}
return false; return false;
} }

View File

@ -68,18 +68,3 @@ VDR Plugin 'status' Revision History
2015-02-19: Version 2.2.0 2015-02-19: Version 2.2.0
- Official release. - Official release.
2018-04-15: Version 2.4.0
- Official release.
2021-12-27: Version 2.6.0
- Official release.
2025-02-10: Version 2.6.1
- Added cStatus::OsdItem2().
- Activated logging of OsdItem2().
- Added cStatus::OsdCurrentItem2().
- Added cStatus::OsdStatusMessage2().

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:30:58 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
# #
@ -63,7 +62,7 @@ all: $(SOFILE)
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -78,7 +77,7 @@ $(DEPFILE): Makefile
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <vdr@tvdr.de> Written by: Klaus Schmidinger <vdr@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,13 +3,13 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: status.c 5.4 2025/02/12 21:18:53 kls Exp $ * $Id: status.c 3.2 2015/02/17 13:13:21 kls Exp $
*/ */
#include <vdr/plugin.h> #include <vdr/plugin.h>
#include <vdr/status.h> #include <vdr/status.h>
static const char *VERSION = "2.6.1"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = "Status monitor test"; static const char *DESCRIPTION = "Status monitor test";
static const char *MAINMENUENTRY = NULL; static const char *MAINMENUENTRY = NULL;
@ -27,10 +27,10 @@ protected:
virtual void SetSubtitleTrack(int Index, const char * const *Tracks); virtual void SetSubtitleTrack(int Index, const char * const *Tracks);
virtual void OsdClear(void); virtual void OsdClear(void);
virtual void OsdTitle(const char *Title); virtual void OsdTitle(const char *Title);
virtual void OsdStatusMessage2(eMessageType Type, const char *Message); virtual void OsdStatusMessage(const char *Message);
virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue); virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
virtual void OsdItem2(const char *Text, int Index, bool Selectable); virtual void OsdItem(const char *Text, int Index);
virtual void OsdCurrentItem2(const char *Text, int Index); virtual void OsdCurrentItem(const char *Text);
virtual void OsdTextItem(const char *Text, bool Scroll); virtual void OsdTextItem(const char *Text, bool Scroll);
virtual void OsdChannel(const char *Text); virtual void OsdChannel(const char *Text);
virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
@ -86,9 +86,9 @@ void cStatusTest::OsdTitle(const char *Title)
dsyslog("status: cStatusTest::OsdTitle '%s'", Title); dsyslog("status: cStatusTest::OsdTitle '%s'", Title);
} }
void cStatusTest::OsdStatusMessage2(eMessageType Type, const char *Message) void cStatusTest::OsdStatusMessage(const char *Message)
{ {
dsyslog("status: cStatusTest::OsdStatusMessage2 %d '%s'", Type, Message); dsyslog("status: cStatusTest::OsdStatusMessage '%s'", Message);
} }
void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
@ -96,14 +96,14 @@ void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Ye
dsyslog("status: cStatusTest::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue); dsyslog("status: cStatusTest::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue);
} }
void cStatusTest::OsdItem2(const char *Text, int Index, bool Selected) void cStatusTest::OsdItem(const char *Text, int Index)
{ {
dsyslog("status: cStatusTest::OsdItem2 %s %d %d", Text, Index, Selected); //dsyslog("status: cStatusTest::OsdItem %s %d", Text, Index);
} }
void cStatusTest::OsdCurrentItem2(const char *Text, int Index) void cStatusTest::OsdCurrentItem(const char *Text)
{ {
dsyslog("status: cStatusTest::OsdCurrentItem %s %d", Text, Index); dsyslog("status: cStatusTest::OsdCurrentItem %s", Text);
} }
void cStatusTest::OsdTextItem(const char *Text, bool Scroll) void cStatusTest::OsdTextItem(const char *Text, bool Scroll)

View File

@ -33,11 +33,3 @@ VDR Plugin 'svdrpdemo' Revision History
2015-02-19: Version 2.2.0 2015-02-19: Version 2.2.0
- Official release. - Official release.
2018-04-15: Version 2.4.0
- Official release.
2021-12-27: Version 2.6.0
- Official release.

View File

@ -1,7 +1,7 @@
# #
# Makefile for a Video Disk Recorder plugin # Makefile for a Video Disk Recorder plugin
# #
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $ # $Id: Makefile 4.1 2017/05/22 15:31:19 kls Exp $
# The official name of this plugin. # The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin. # This name will be used in the '-P...' option of VDR to load the plugin.
@ -16,8 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment: ### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory: # Use package data if installed...otherwise assume we're under the VDR source directory:
PKG_CONFIG ?= pkg-config PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir) LIBDIR = $(call PKGCFG,libdir)
PLGCFG = $(call PKGCFG,plgcfg) PLGCFG = $(call PKGCFG,plgcfg)
# #
@ -63,7 +62,7 @@ all: $(SOFILE)
%.o: %.c %.o: %.c
@echo CC $@ @echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< @$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies: ### Dependencies:
@ -78,7 +77,7 @@ $(DEPFILE): Makefile
$(SOFILE): $(OBJS) $(SOFILE): $(OBJS)
@echo LD $@ @echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ @$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
install-lib: $(SOFILE) install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)

View File

@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de> Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
Project's homepage: https://www.tvdr.de Project's homepage: http://www.tvdr.de
Latest version available at: https://www.tvdr.de Latest version available at: http://www.tvdr.de
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -3,12 +3,12 @@
* *
* 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: svdrpdemo.c 4.1 2018/04/10 13:01:07 kls Exp $ * $Id: svdrpdemo.c 3.2 2015/02/17 13:13:29 kls Exp $
*/ */
#include <vdr/plugin.h> #include <vdr/plugin.h>
static const char *VERSION = "2.4.0"; static const char *VERSION = "2.2.0";
static const char *DESCRIPTION = "How to add SVDRP support to a plugin"; static const char *DESCRIPTION = "How to add SVDRP support to a plugin";
class cPluginSvdrpdemo : public cPlugin { class cPluginSvdrpdemo : public cPlugin {

4
README
View File

@ -4,7 +4,7 @@ Video Disk Recorder ('VDR')
These files contain the source code of the "Video Disk Recorder", These files contain the source code of the "Video Disk Recorder",
which is based on the DVB driver of the LinuxTV project (http://linuxtv.org). which is based on the DVB driver of the LinuxTV project (http://linuxtv.org).
For details about the "Video Disk Recorder" project please For details about the "Video Disk Recorder" project please
refer to https://www.tvdr.de. refer to http://www.tvdr.de.
Please see the INSTALL file for details on how to install Please see the INSTALL file for details on how to install
this program on your computer. this program on your computer.
@ -33,7 +33,7 @@ the ones in this system, but here we have the full source code
and can modify the menus in whatever way desired. and can modify the menus in whatever way desired.
If you actually use VDR, please add yourself to the "VDR User Counter" If you actually use VDR, please add yourself to the "VDR User Counter"
at https://www.tvdr.de/counter.htm. You can also like VDR on facebook at http://www.tvdr.de/counter.htm. You can also like VDR on facebook
at https://www.facebook.com/VideoDiskRecorder. at https://www.facebook.com/VideoDiskRecorder.

View File

@ -10,7 +10,7 @@ Plugins:
- Implemented a universal plugin interface. See the file PLUGINS.html - Implemented a universal plugin interface. See the file PLUGINS.html
for a detailed description. The man page vdr(1) describes the new options '-L' for a detailed description. The man page vdr(1) describes the new options '-L'
and '-P' used to load plugins. and '-P' used to load plugins.
See https://www.tvdr.de/plugins.htm for a list of available plugins. See http://www.tvdr.de/plugins.htm for a list of available plugins.
- Rearranged the remote control key handling to allow plugins to implement - Rearranged the remote control key handling to allow plugins to implement
additional types of remote controls (see PLUGINS.html, section "Remote Control"). additional types of remote controls (see PLUGINS.html, section "Remote Control").
The previously used files 'keys.conf' and 'keys-pc.conf' have been replaced The previously used files 'keys.conf' and 'keys-pc.conf' have been replaced

View File

@ -224,7 +224,7 @@ OSD:
- The OSD size is now automatically adjusted to the actual video display - The OSD size is now automatically adjusted to the actual video display
(provided the output device implements the GetOsdSize() function). (provided the output device implements the GetOsdSize() function).
- The OSD now has full TrueColor support. There can be several "pixmaps" that can - The OSD now has full TrueColor support. There can be several "pixmaps" that can
be overlaid with alpha blending. All existing skins should work out of the box be overlayed with alpha blending. All existing skins should work out of the box
with the TrueColor OSD - the only exception being cOsd::GetBitmap(). Since the with the TrueColor OSD - the only exception being cOsd::GetBitmap(). Since the
TrueColor OSD doesn't use bitmaps, this function will return a dummy bitmap, which TrueColor OSD doesn't use bitmaps, this function will return a dummy bitmap, which
may not be what the plugin expects. As long as this bitmap is only used for setting may not be what the plugin expects. As long as this bitmap is only used for setting

View File

@ -408,7 +408,7 @@ Misc:
- Updated sources.conf to reflect the fact that Astra 4A and SES5 are actually in - Updated sources.conf to reflect the fact that Astra 4A and SES5 are actually in
two separate positions. two separate positions.
- Fixed cMarks::GetNextBegin() and cMarks::GetNextEnd(). The behavior of these two - Fixed cMarks::GetNextBegin() and cMarks::GetNextEnd(). The behavior of these two
functions is now exactly as described in the header file. Editing marks that are functions is now exacly as described in the header file. Editing marks that are
placed at exactly the same offset in a recording are now preserved in the cutting placed at exactly the same offset in a recording are now preserved in the cutting
process. process.
- The new command line option --chartab can be used to set the default character - The new command line option --chartab can be used to set the default character

View File

@ -1,442 +0,0 @@
This is a summary of the changes in VDR 2.4.0 since the last stable
version 2.2.0. It only contains things that are of actual importance
to the user and doesn't mention the many fixes and improvements that
have been made "behind the scenes".
See the file HISTORY for a detailed list of all changes.
Peering:
- If there is more than one VDR in the local network, they can now form a peer-to-peer
network, so that timers can be moved freely between them.
The following changes have been made to implement this:
+ VDR now sends out a broadcast to port 6419/udp, which was assigned to 'svdrp-disc'
by the IANA. VDRs listening on that port will automatically initiate an SVDRP
connection to the broadcasting VDR, and in turn send out a broadcast to make
other VDRs connect to them. That way all VDRs within the local network will
have permanent "peer-to-peer" SVDRP connections between each other. The
configuration in the svdrphosts.conf file is taken into account when considering
whether or not to respond to an SVDRP discover broadcast.
+ The new SVDRP command PING is used by automatically established peer-to-peer
connections to keep them alive.
+ The new function GetSVDRPServerNames() can be used to get a list of all VDRs
this VDR is connected to via SVDRP.
+ The new function ExecSVDRPCommand() can be used to execute an SVDRP command on
one of the servers this VDR is connected to, and retrieve the result.
The helper functions SVDRPCode() and SVDRPValue() can be used to easily access
the codes and values returned by ExecSVDRPCommand().
+ The new SVDRP command POLL is used by automatically established peer-to-peer
connections to trigger fetching remote timers.
+ The new options "Setup/Miscellaneous/SVDRP peering", ".../SVDRP host name" and
".../SVDRP default host" can be used to configure automatic peering between VDRs
in the same network. Peering is disabled by default and can be enabled by setting
"SVDRP peering" to "yes".
+ The "Edit timer" menu now has a new parameter "Record on", which can be used to
select the VDR on which this timer shall record. Timers can be freely moved
between connected VDRs by simply selecting the desired machine in this field.
+ The cTimer class now has a new member named 'remote', which holds the name of the
remote server this timer will record on. If this is NULL, it is a local timer.
+ Added a note to the "Pausing live video" section of the MANUAL, stating that
the timer for paused live video will always record on the local VDR, even if
an "SVDRP default host" has been set for normal timer recordings.
+ The Perl script 'peerdemo' shows how one can find all the VDRs in the local network
using the peer connection mechanism.
Conditional Access:
- Implemented support for MTD ("Multi Transponder Decryption"). This allows a CAM
that is capable of decrypting more than one channel ("Multi Channel Decryption")
to decrypt channels from different transponders. See the remarks in mtd.h on
what a derived cCamSlot class needs to do in order to activate MTD.
- The Setup/CAM menu now displays which device an individual CAM is currently
assigned to.
- The channel/CAM relations (i.e. the information which CAM can decrypt a given
channel) are now stored in the file 'cam.data' in the cache directory.
This speeds up switching to encrypted channels after newly starting VDR, in case
there is more than one CAM in the system.
The file 'cam.data' is not written if it is read-only.
- The mechanism of trying different CAMs when switching to an encrypted channel is
now only triggered if there actually is more than one CAM in the system.
- CAMs that can handle multiple devices at the same time can now indicate this
by creating the first cCamSlot as usual, and every other cCamSlot by giving
it the first one as its "MasterSlot". To VDR this means that when searching
for a CAM that can decrypt a particular channel, it only needs to ask the
master CAM slot whether it is suitable for decrypting, and can skip all the
other slots belonging to the same master. This can greatly speed up channel
switching on systems with more than one CAM (that can handle multiple devices).
- The LCARS skin now displays the master CAM's number when a device is tuned to
an encrypted channel.
- The Setup/CAM menu now only displays master CAMs.
- Detecting whether a particular CAM actually decrypts a given channel is now
done separately for each receiver.
- The function cCamSlot::Decrypt() can now also be called with Data == NULL.
This is necessary to allow CAMs that copy the incoming data into a separate buffer
to return previously received and decrypted TS packets. See ci.h for details.
Plugins that implement a derived cCamSlot need to properly handle this case, and
plugins that implement a derived cDevice need to call Decrypt() in their
GetTSPacket() function even if the incoming buffer is currently empty (see
cDvbDevice::GetTSPacket()).
- CAMs are now sent a generated EIT packet that contains a single 'present event' for
the current SID, in order to avoid any parental rating dialogs.
- When selecting a device/CAM combination for live viewing, CAMs that are known to
decrypt the requested channel are now given a higher priority than preferring the
primary device.
- Extended the CI API to allow plugins to implement additional CAM resources.
- The new configuration file 'camresponses.conf' can be used to define automatic
responses to CAM menus, for instance to avoid annyoing popup messages or entering
the parental rating PIN. See vdr.5 for details.
Timers:
- The cTimer class now has a new member named 'remote', which holds the name of the
remote server this timer will record on. If this is NULL, it is a local timer.
- Timers from other VDRs that are connected to this VDR via SVDRP are now
automatically fetched and stored in the global Timers list. In order for this
to work, all of the channels used by timers on the remote VDR must also be
defined on the local VDR (however, not necessarily in the same sequence).
- Accessing the global Timers list now has to be protected by proper locking,
because SVDRP commands are now executed in a separate thread.
The introduction of this locking mechanism required the following changes:
+ The new classes cStateLock and cStateKey are used to implement locking
with quick detection of state changes.
+ cConfig::cConfig() now has a parameter that indicates whether this list
requires locking.
+ The global lists of Timers, Channels, Schedules and Recordings are no longer
static variables. They are now pointers that need to be retrieved through
a call to cTimers::GetTimersRead/Write(), cChannels::GetChannelsRead/Write(),
cSchedules::GetSchedulesRead/Write() and cRecordings::GetRecordingsRead/Write(),
respectively.
+ References from/to link channels are now removed in cChannels::Del() rather
than cChannel::~cChannel(), to make sure the caller holds a proper lock.
+ cChannel::HasTimer() has been removed. This information is now retrieved
via cSchedule::HasTimer().
+ Several member functions of cChannel, cTimer, cMarks and cRecording have
been made 'const', and some of them are now available as both 'const' and
'non-const' versions.
+ The cChannel::Set...() functions are now 'bool' and return true if they have
actually changed any of the channels's members.
+ cChannels::SetModified() has been renamed to cChannels::SetModifiedByUser().
+ cChannels::Modified() has been renamed to cChannels::ModifiedByUser(), and
now has a 'State' parameter that allows the caller to see whether a channel
has been modified since the last call to this function with the same State
variable.
+ The macros CHANNELSMOD_NONE/_AUTO/_USER have been removed.
+ cMarks now requires locking via cStateKey.
+ cSortedTimers now requires a pointer to the list of timers.
+ cEvent::HasTimer() no longer scans the list of timers to check whether an event
is referenced by a timer, but rather keeps score of how many timers reference
it. This was necessary in order to avoid having to lock the list of timers from
within a cEvent.
+ The new class cListGarbageCollector is used to temporary store any objects deleted
from cLists that require locking. This allows pointers to such objects to be
dereferenced even if the objects are no longer part of the list.
+ cListBase::Contains() can be used to check whether a particular object is still
contained in that list.
+ Outdated events are no longer "phased out", but rather deleted right away and thus
taken care of by the new "garbage collector" of the list.
+ Deleted cRecording objects are no longer kept in a list of "vanished" recordings,
but are rather taken care of by the new "garbage collector" of the list.
+ cSchedules::ClearAll() has been removed. The functionality is now implemented
directly in cSVDRPServer::CmdCLRE().
+ cSchedule now has a member Modified(), which can be used with a State variable
to quickly determine whether this schedule has been modified since the last call
to this function with the same State variable.
+ cSchedulesLock has been removed. Locking the list of schedules is now done via
the cList's new locking mechanism.
+ The 'OnlyRunningStatus' parameters in cEpgHandler::BeginSegmentTransfer() and
cEpgHandler::EndSegmentTransfer() are now obsolete. They are still present in
the interface for backward compatibility, but may be removed in a future version.
Their value is always 'false'.
+ The constant tcMod is no longer used in cStatus::TimerChange(). The definition is
still there for backward compatibility.
- Plugins that access the global lists of Timers, Channels, Recordings or Schedules
will need to be adapted as follows:
+ Instead of directly accessing the global variables Timers, Channels or Recordings,
they need to set up a cStateKey variable and call the proper getter function,
as in
cStateKey StateKey;
if (const cTimers *Timers = cTimers::GetTimersRead(StateKey)) {
// access the timers
StateKey.Remove();
}
and
cStateKey StateKey;
if (cTimers *Timers = cTimers::GetTimersWrite(StateKey)) {
// access the timers
StateKey.Remove();
}
See timers.h, thread.h and tools.h for details on this new locking mechanism.
+ There are convenience macros for easily accessing these lists without having
to explicitly set up a cStateKey and calling its Remove() function. These macros
have the form LOCK_*_READ/WRITE (with '*' being TIMERS, CHANNELS, SCHEDULES or
RECORDINGS). Simply put such a macro before the point where you need to access
the respective list, and there will be a pointer named Timers, Channels, Schedules
or Recordings, respectively, which is valid until the end of the current block.
+ If a plugin needs to access several of the global lists in parallel, locking must
always be done in the sequence Timers, Channels, Recordings, Schedules. This is
necessary to make sure that different threads that need to lock several lists at
the same time don't end up in a deadlock.
+ Some pointer variables may need to be made 'const'. The compiler will tell you
about these.
- If a timer is newly created with the Red button in the Schedule menu, and the timer
is presented to the user in the "Edit timer" menu because it will start immediately,
it now *must* be confirmed with "Ok" to set the timer. Otherwise the timer will not
be created.
- The function cTimer::ToText() no longer returns a newline character at the end of
the string. The newline is now added by the caller as necessary. This was changed
because cTimer::ToText() is now also needed in a context where the terminating
newline can't be used. Consequently, cChannel::ToText() and cMark::ToText() have
been modified accordingly.
- Timers now have unique ids instead of numbers, which remain valid as long as this
instance of VDR is running. This means that timers are no longer continuously
numbered from 1 to N in LSTT. There may be
gaps in the sequence, in case timers have been deleted.
- Timers are now linked to EPG events even if they are inactive. By default Events that
are linked to inactive timers are marked with 'I' and 'i', depending on whether the
timer would record the entire Event or only part of it.
The function cSkinDisplayMenu::SetItemEvent() now has an additional parameter named
TimerActive, which indicates whether the timer that would record this event (if any)
is active. A plugin may react on this when displaying a menu line for an event.
The old version of cSkinDisplayMenu::SetItemEvent() (without the TimerActive
parameter) is still there for backwards compatibility. It may be removed in a future
version, so plugin authors should switch to the new one.
- Improved handling VPS timers to better react to EPG changes during an ongoing recording.
Plugins:
- The dvbhddevice plugin is no longer part of the VDR source archive.
You can get the latest version of this plugin from the author's repository at
https://bitbucket.org/powARman/dvbhddevice.
- The dvbsddevice and rcu plugins are no longer part of the VDR source archive.
You can get the latest versions of these plugins from ftp://ftp.tvdr.de/vdr/Plugins.
- The -V and -h options now list the plugins in alphabetical order.
- Added some guidelines and recommendations to the 'Logging' section of PLUGINS.html.
The most important being: implement a command line option to control the level
of logging (in particular allow turning off logging completely!) and never print
anything to stdout or stderr (unless one of the listed exceptions applies).
- Added a note to PLUGINS.html about writing log messages in English.
- The new function cStatus::MarksModified() can be implemented by plugins to get
informed about any modifications to the editing marks of the currently played
recording.
Skins:
- The main menu of the LCARS skin now displays a small rectangle on the left side
of a timer if this is a remote timer. The color of that rectangle changes if
the timer is currently recording on the remote VDR.
- Skins can now implement cSkinDisplayMenu::MenuOrientation() to display horizontal
menus.
- The LCARS skin now displays the master CAM's number when a device is tuned to
an encrypted channel.
Remote control:
- The new setup option "Recording/Record key handling" can be used to define
what happens if the Record key on the remote control is pressed during
live tv.
- If the Channel+/- keys are pressed while in the Schedules menu, the menu is now
switched to the EPG of the new current channel.
Devices:
- The command line option -D now accepts the value '-' (as in -D-), which prevents
VDR from using any DVB devices.
- The function cDevice::SetCurrentChannel(const cChannel *Channel) is now deprecated
and may be removed in a future version. Use SetCurrentChannel(int ChannelNumber)
instead.
- Signal strength and quality (CNR) are now determined via DVB API 5 (if available).
Fallback is the old DVB API 3 method.
- The new function cDevice::SignalStats() (if implemented by an actual device) returns
statistics about the currently received signal.
- The function cDevice::GetVideoSystem() (which has been deprecated since version 2.1.6)
has been finally removed.
- Switching the primary device is no longer done via osSwitchDvb (which has been
removed), but rather by the main program loop reacting to changes in Setup.PrimaryDVB.
EPG:
- The character 0x0D is now stripped from EPG texts.
- The EPG scanner no longer moves the dish if there is a positioner.
- The function cEpgHandlers::BeginSegmentTransfer() is now boolean.
See the description in epg.h for the meaning of the return value.
- The cEvent class now has a new member 'aux', in which external applications can
store auxiliary information with an event. This string has no meaning whatsoever to
VDR itself, and it will not be written into the info file of a recording that is
made for such an event.
- Changed the default return value of cEpgHandler::BeginSegmentTransfer() to true, to
avoid problems with derived classes that don't implement this function.
- The EIT filter no longer parses data from "other TS", to avoid problems with
broadcasters who transmit faulty EIT data.
OSD:
- The new function cOsd::MaxPixmapSize() can be called to determine the maximum size
a cPixmap may have on the current OSD. The 'osddemo' example has been modified
accordingly. Plugin authors may want to use this function in case they use pixmaps
that are larger than the full OSD size. The default implementation sets this limit
to 2048x2048 pixel.
- Added some comment to cPixmap about the relation between OSD, ViewPort and DrawPort.
- The new setup option "OSD/Default sort mode for recordings" can be used to define
how recordings shall be sorted by default (either by time or by name, with "by time"
being the default). If a particular sort mode has been selected for a folder by
pressing '0', the default no longer applies to that folder. Repeating timers no
longer write a ".sort" file into a recordings folder to have the recordings sorted
by time.
- The function cOsd::GetBitmap() is now 'protected'. If a plugin doesn't compile with
this version of VDR, you can uncomment the line
//#define DEPRECATED_GETBITMAP
in osd.h as a quick workaround. In the long run the plugin will need to be adapted.
- Background modifications of channels, timers and events are now displayed immediately
in the corresponding menus.
- The Timers menu now displays the name of the remote VDR in front of the timer's
file name, if this is a remote timer.
- The width and height of the OSD are now limited to the actual maximum dimensions
of the output device, taking into account the top and left offset.
- Added a note to the description of cFont::Size(), regarding possible differences
between it and cFont::Height().
- Added cFont::Width(void) to get the default character width and allow stretched
font drawing in high level OSDs.
- cOsdMenu::Display() now checks whether the OSD size has changed and if so calls
SetDisplayMenu().
- The option "Setup/Miscellaneous/Show channel names with source" can now be set to
"type" or "full" to show either the type or the full name of the source.
- The "Channels" menu now indicates whether a channel is encrypted ('X') or a radio
channel ('R').
- The timeout for the channel display is now reset whenever the channel or EPG data
changes.
- OSD menus now try to keep the offset of the list cursor at a constant position on
the screen, even if the list is modified while being displayed.
- If an event in the Schedules menu is marked with a 'T' or 'I' and the user presses the
Red button to edit the timer, local timers are now preferred over remote timers
in case there is more than one timer that will record that event.
- The new setup option "OSD/Sorting direction for recordings" can be used to switch
the sequence in which recordings are presented in the "Recordings" menu between
ascending (oldest first) and descendeng (newest first).
- When selecting a folder for a recording or timer, it is now possible to open a folder
even if it doesn't contain any subfolders.
Recordings:
- Recordings now have unique ids instead of numbers, which remain valid as long as
this instance of VDR is running. This means that recordings are no longer continuously
numbered from 1 to N in LSTR. There may be gaps in the sequence, in case recordings
have been deleted, and they are not necessarily listed in numeric order.
- Added detection of 24fps.
- The script that gets called for recordings is now also called right before a
recording is edited, with the first parameter being "editing".
- Implemented a frame parser for H.265 (HEVC) recordings.
- When moving recordings between volumes, the "Recordings" menu now displays those items
that have not yet been moved completely as non-selectable. This avoids situations
where trying to play such a recording might fail.
- When moving a recording to a different folder, the cursor is no longer placed on the
new location of the recording, but rather stays in the original folder.
If the original folder got empty by moving away the last recording
it contained, the cursor is moved up until a non empty folder is found.
SVDRP:
- The SVDRP port now accepts multiple concurrent connections. You can now keep an
SVDRP connection open as long as you wish, without preventing others from
connecting. Note, though, that SVDRP connections still get closed automatically
if there has been no activity for 300 seconds (configurable via
"Setup/Miscellaneous/SVDRP timeout (s)").
- The SVDRP log messages have been unified and now always contain the IP and port
number of the remote host.
- SVDRP connections are now handled in a separate "SVDRP server handler" thread,
which makes them more responsive. Note that there is only one thread that handles
all concurrent SVDRP connections. That way each SVDRP command is guaranteed to be
processed separately, without interfering with any other SVDRP commands that might
be issued at the same time. Plugins that implement SVDRP commands may need to take
care of proper locking if the commands access global data.
- You can now set DumpSVDRPDataTransfer in svdrp.c to true to have all SVDRP
communication printed to the console for debugging.
- The SVDRP commands that deal with timers (DELT, LSTT, MODT, NEWT, NEXT and UPDT)
as well as any log messages that refer to timers, now use a unique id for each
timer, which remains valid as long as this instance of VDR is running. This means
that timers are no longer continuously numbered from 1 to N in LSTT. There may be
gaps in the sequence, in case timers have been deleted.
- All timer related response strings from SVDRP commands now use the channel ID
instead of channel numbers.
- The SVDRP command DELT no longer checks whether the timer that shall be deleted
is currently recording.
- The SVDRP command DELC now refuses to delete the very last channel in the list,
to avoid ending up with an empty channel list.
- The SVDRP commands that deal with recordings (DELR, EDIT, LSTR, MOVR, and PLAY)
now use a unique id for each recording, which remains valid as long as this
instance of VDR is running. This means that recordings are no longer continuously
numbered from 1 to N in LSTR. There may be gaps in the sequence, in case recordings
have been deleted, and they are not necessarily listed in numeric order.
- Changed 'number' to 'id' in the help texts of SVDRP commands that deal with
timers.
- The SVDRP command LSTC can now list the channels with channel ids if the option
':ids' is given.
- If 0 is given as the channel number in the SVDRP command LSTC, the data of the
current channel is listed.
- The new SVDRP commands 'LSTD' and 'PRIM' can be used to list all available devices
and to switch the primary device.
Misc:
- Added a section about Output Devices to the INSTALL file.
- The -u option now also accepts a numerical user id.
- The cRwLock class now allows nested read locks within a write lock from the
same thread. This fixes possible crashes when moving or deleting channels in
the menu or through SVDRP (as well as other operations that try to acquire a
read lock within a write lock).
- Added support for the systemd watchdog.
- PIDs can now be added to and deleted from a cReceiver while it is attached to
a cDevice, without having to detach it first and re-attach it afterwards.
- Log messages about switching channels now include the channel ID.
- The constructor of cHash (via cHashBase) now has an additional parameter (OwnObjects)
which, if set to true, makes the hash take ownership of the hashed objects, so that
they are deleted when the hash is cleared or destroyed.
- cListObject now implements a private copy constructor and assignment operator, to keep
derived objects from calling them implicitly.
- The Makefiles have been modified so that during the build process they no longer
display the actual (lengthy) commands, but rather just the name of the file that
is being built, as in
CC vdr.o
The first two characters indicate the kind of operation (CC=compile, LD=link,
AR=archive, MO=msgfmt, GT=xgettext, PO=msgmerge, IN=install).
This way it is much easier to spot error messages and warnings, since they are not
buried under tons of text.
Add VERBOSE=1 to the 'make' call in the VDR source directory to see the
actual commands that are executed.
Plugin authors should modify their makefiles accordingly, by simply preceding
the respective commands with '$(Q)' and inserting '@echo XX $@' (where XX is one
of the character combinations listed above) before the command.
The newplugin script has also been modified accordingly.
Note that if you build a plugin directly in the plugin's own source directory,
the $(Q) macro won't be defined and commands will be displayed. You can add
Q=@ to the make call to have it less verbose (provided the plugin's Makefile
was modified as described above).
- Added backtrace functions for debugging (see cBackTrace in thread.h).
- Added checking the correct sequence of locking global lists.
At the first occurrence of an invalid locking
sequence, the 20 most recent locks will be written to the log file, followed by a
backtrace that led to the call in question. This code can be activated by defining
the macro DEBUG_LOCKSEQ in thread.c (which is on by default).
When debugging an actual invalid locking sequence, you can additionally define
the macro DEBUG_LOCKCALL in thread.c, which will add information about the caller
of each lock. Note that this may cause some stress on the CPU, therefore it is off
by default.
- The file Make.config.template now reacts on DEBUG=1 in the 'make' command line,
and disables code optimizations by setting -O0.
This can be helpful when backtracing highly optimized code. You may want to
'make distclean' before running 'make' with a modified setting of DEBUG, to make
sure all object files are newly compiled.
- Introduced the new macro DISABLE_TEMPLATES_COLLIDING_WITH_STL, which can be defined
before including tools.h in case some plugin needs to use the STL and gets error
messages regarding one of the template functions defined in tools.h.
- The macros used to control deprecated code or functions have been changed to hold
numeric values (0 and 1), so that they can be controlled at compile time, without
having to edit the actual source code.
- The default for DEPRECATED_VDR_CHARSET_OVERRIDE has been set to 0, which means VDR
no longer reacts on the environment variable VDR_CHARSET_OVERRIDE. You can add
'DEPRECATED_VDR_CHARSET_OVERRIDE=1' when compiling in order to restore this
functionality. However, it is recommended to use the command line option --chartab
instead.
- Disabled the use of posix_fadvise() when reading (i.e. replaying), since it caused
stuttering replay in fast forward and fast rewind mode in case the video directory
is mounted via NFS. You can re-enable it by setting the macro USE_FADVISE_READ to 1
in tools.c.

View File

@ -1,119 +0,0 @@
This is a summary of the changes in VDR 2.6.0 since the last stable
version 2.4.0. It only contains things that are of actual importance
to the user and doesn't mention the many fixes and improvements that
have been made "behind the scenes".
See the file HISTORY for a detailed list of all changes.
Timers:
- Implemented "Pattern Timers" (see MANUAL, vdr.1 and vdr.5 for details).
- The margins for timer recordings are now always limited to the duration of the
previous and next event.
- Spawned timers that don't use VPS now automatically adjust their start/stop times
to changes in the respective event's times.
EPG:
- Events in the past are no longer marked as having a timer in the Schedules
menu.
- Improved handling EPG data from the EIT tables:
+ Table 0x4F is now completely ignored.
+ Once a schedule has seen events from 0x5X, tables 0x6X are ignored for that
schedule.
+ When looking up an event in its schedule, the start time is used for tables 0x6X, and the
event id for tables 0x4E and 0x5X.
+ When hashing events by event id or start time, existing older entries in the hash
tables are now deleted before entering the new ones.
+ The function cSchedule::GetEvent() is now deprecated and may be removed in a future
version. Use GetEventById() and GetEventByTime() instead.
+ On channels that use proper event ids a change of the start time no longer
causes a new event to be created, but rather modifies the existing one. This
avoids possible interruptions in VPS recordings in case the event's start time
is changed while the recording is already going on.
- Fixed the timer indicator in the Schedule menu in case an event is already over, but the
timer is still recording.
- Fixed unlocking vs. call to EpgHandlers.EndSegmentTransfer().
Devices:
- Increased the number of possible modulation systems in cDevice::GetDevice().
- Improved cSectionSyncer to make sure that no sections are missed, and to allow
handling partially used segments (as in the EIT) and processing sections in random
order. Segment syncing is now done with the two member functions Check() and
Processed(). The old functions Sync() and Repeat() are deprecated and may be
removed in a future version. See the comments in filter.h for a description on
how to use these new function.
- Added a device hook for detecting whether a device provides EIT data.
Recordings:
- Made the functions cRecordingInfo::SetData() and cRecordingInfo::SetAux() public.
- Fixed setting the 'title' of a recording's info to the recording's name if there
is no info file (the change in version 1.7.28 broke the fallback to the old 'summary.vdr').
- Added some missing user command calls for copying, renaming and moving recordings.
- Recordings are now checked for errors:
+ On TS level, the continuity counter, transport error indicator and scramble flags are
checked.
+ On frame level it is checked whether there are no gaps in the PTS.
+ The number of errors during a recording is stored in the recording's 'info' file, with
the new tag 'O'.
+ Spawned timers that shall avoid recording reruns only store the recording's name in
the donerecs,data file if there were no errors during recording, and if the timer has
actually finished.
- The Recordings menu now marks recordings with errors with an exclamation mark ('!'),
and the number of errors (if any) is displayed in the recording's Info menu.
Replay:
- Fixed scaling subtitles with anti-aliasing.
Conditional Access:
- Decreased the scrambling timeout for CAMs known to decrypt a certain channel, so
that it won't collide with MAXBROKENTIMEOUT in recorder.c.
Skins:
- The new functions cTimer::Start/StopTimeEvent() are now used in the LCARS skin to display
the start/stop times of timers in the main menu.
SVDRP:
- The SVDRP command DELC now also accepts a channel id.
Misc:
- Added support for HEVC-video and AC-4-audio.
- EXPIRELATENCY now only applies to VPS timers.
- Removed the macros __STL_CONFIG_H, _STL_ALGOBASE_H and _MOVE_H from tools.h. If your
plugin insists in using "using namespace std;" you can still define
DISABLE_TEMPLATES_COLLIDING_WITH_STL before including any VDR header files.
- The cFile class has been partially deprecated:
+ The handling of file handles was not thread-safe.
+ It was only actually used in svdrp.c.
+ cFile::Ready() now processes only its own file descriptor by calling FileReady()
instead of AnyFileReady().
- The transponder value of channels is now cached, because cChannel::Transponder(void)
is called very often.
- Added code for the 'qad' audio track.
- The 'Edit path' dialog now also shows the total size of all recordings in that path.
- The macro DEPRECATED_VDR_CHARSET_OVERRIDE and the related code has been removed.
- The default for DEPRECATED_SETCURRENTCHANNEL has been set to 0, which means that
the function SetCurrentChannel(const cChannel *Channel) is no longer available.
You can add 'DEPRECATED_SETCURRENTCHANNEL=1' when compiling in order to restore this
functionality. However, it is recommended to use SetCurrentChannel(int ChannelNumber)
instead.
- The macro DEPRECATED_GETBITMAP and the related code has been removed.
- The default for DEPRECATED_SKIN_SETITEMEVENT has been set to 0, which means that
the function cSkinDisplayMenu::SetItemEvent() without the TimerActive parameter is
no longer available. You can add 'DEPRECATED_SKIN_SETITEMEVENT=1' when compiling in
order to restore this functionality. However, it is recommended to use the function
with the TimerActive parameter instead.
- Now using __cplusplus instead of DISABLE_TEMPLATES_COLLIDING_WITH_STL, and using
std::min(), std::max() and std::swap() if available.
- No longer permanently looping through PMT PIDs, which caused problems with some
SatIP receivers.
- Replaced all umlauts in the example channels.conf with their ae, oe, ue substitutes
to avoid problems on UTF-8 systems.
- Added missing '0x09=H.265 video, 0x19 = AC4 audio' to vdr.5.

View File

@ -1,29 +0,0 @@
# CAM responses for VDR
#
# Format:
#
# nr text action
#
# nr: the number of the CAM this action applies to (0 = all CAMs)
# text: the text in the CAM menu to react on (must be quoted with '"' if it contains
# blanks, escape '"' with '\')
# action: the action to take if the given text is encountered
#
# Possible actions are:
#
# - DISCARD: simply discard the menu (equivalent to pressing 'Back' on the RC)
# - CONFIRM: confirm the menu (equivalent to pressing 'OK' without selecting a
# particular item)
# - SELECT: select the menu item containing the text (equivalent to positioning
# the cursor on the item and pressing 'OK')
# - <number>: the given number is sent to the CAM as if it were typed in by the user
# (provided this is an input field).
#
# Note that the text given in a rule must match exactly, including any leading or
# trailing blanks. If in doubt, you can get the exact text from the log file.
# Action keywords are case insensitive.
#
# Examples:
# * "Hello! This is your annoying \"nag\" message!" DISCARD
# 3 "Please enter your PIN" 1234

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.c 5.3 2024/03/02 16:21:16 kls Exp $ * $Id: channels.c 4.3 2015/09/09 10:21:22 kls Exp $
*/ */
#include "channels.h" #include "channels.h"
@ -97,32 +97,18 @@ cChannel& cChannel::operator= (const cChannel &Channel)
provider = strcpyrealloc(provider, Channel.provider); provider = strcpyrealloc(provider, Channel.provider);
portalName = strcpyrealloc(portalName, Channel.portalName); portalName = strcpyrealloc(portalName, Channel.portalName);
memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
UpdateNameSource(); nameSource = NULL; // these will be recalculated automatically
shortNameSource = NULL;
parameters = Channel.parameters; parameters = Channel.parameters;
return *this; return *this;
} }
void cChannel::UpdateNameSource(void)
{
if (Setup.ShowChannelNamesWithSource == 0) {
nameSource = NULL;
shortNameSource = NULL;
return;
}
if (Setup.ShowChannelNamesWithSource == 1)
nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source));
else
nameSource = cString::sprintf("%s (%s)", name, *cSource::ToString(source));
shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source));
}
const char *cChannel::Name(void) const const char *cChannel::Name(void) const
{ {
if (Setup.ShowChannelNamesWithSource && !groupSep) { if (Setup.ShowChannelNamesWithSource && !groupSep) {
if (!isempty(nameSource)) if (isempty(nameSource))
return nameSource; nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source));
return nameSource;
} }
return name; return name;
} }
@ -132,8 +118,9 @@ const char *cChannel::ShortName(bool OrName) const
if (OrName && isempty(shortName)) if (OrName && isempty(shortName))
return Name(); return Name();
if (Setup.ShowChannelNamesWithSource && !groupSep) { if (Setup.ShowChannelNamesWithSource && !groupSep) {
if (!isempty(shortNameSource)) if (isempty(shortNameSource))
return shortNameSource; shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source));
return shortNameSource;
} }
return shortName; return shortName;
} }
@ -153,18 +140,15 @@ int cChannel::Transponder(int Frequency, char Polarization)
int cChannel::Transponder(void) const int cChannel::Transponder(void) const
{ {
if (!transponder) { int tf = frequency;
int tf = frequency; while (tf > 20000)
while (tf > 20000) tf /= 1000;
tf /= 1000; if (IsSat()) {
if (IsSat()) { const char *p = strpbrk(parameters, "HVLRhvlr"); // lowercase for backwards compatibility
const char *p = strpbrk(parameters, "HVLRhvlr"); // lowercase for backwards compatibility if (p)
if (p) tf = Transponder(tf, *p);
tf = Transponder(tf, *p);
}
transponder = tf;
} }
return transponder; return tf;
} }
int cChannel::Modification(int Mask) const int cChannel::Modification(int Mask) const
@ -178,7 +162,6 @@ void cChannel::CopyTransponderData(const cChannel *Channel)
{ {
if (Channel) { if (Channel) {
frequency = Channel->frequency; frequency = Channel->frequency;
transponder = Channel->transponder;
source = Channel->source; source = Channel->source;
srate = Channel->srate; srate = Channel->srate;
parameters = Channel->parameters; parameters = Channel->parameters;
@ -207,11 +190,11 @@ bool cChannel::SetTransponderData(int Source, int Frequency, int Srate, const ch
cString OldTransponderData = TransponderDataToString(); cString OldTransponderData = TransponderDataToString();
source = Source; source = Source;
frequency = Frequency; frequency = Frequency;
transponder = 0;
srate = Srate; srate = Srate;
parameters = Parameters; parameters = Parameters;
schedule = NULL; schedule = NULL;
UpdateNameSource(); nameSource = NULL;
shortNameSource = NULL;
if (Number() && !Quiet) { if (Number() && !Quiet) {
dsyslog("changing transponder data of channel %d (%s) from %s to %s", Number(), name, *OldTransponderData, *TransponderDataToString()); dsyslog("changing transponder data of channel %d (%s) from %s to %s", Number(), name, *OldTransponderData, *TransponderDataToString());
modification |= CHANNELMOD_TRANSP; modification |= CHANNELMOD_TRANSP;
@ -276,12 +259,14 @@ bool cChannel::SetName(const char *Name, const char *ShortName, const char *Prov
dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider); dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider);
modification |= CHANNELMOD_NAME; modification |= CHANNELMOD_NAME;
} }
if (nn) if (nn) {
name = strcpyrealloc(name, Name); name = strcpyrealloc(name, Name);
if (ns) nameSource = NULL;
}
if (ns) {
shortName = strcpyrealloc(shortName, ShortName); shortName = strcpyrealloc(shortName, ShortName);
if (nn || ns) shortNameSource = NULL;
UpdateNameSource(); }
if (np) if (np)
provider = strcpyrealloc(provider, Provider); provider = strcpyrealloc(provider, Provider);
return true; return true;
@ -663,7 +648,6 @@ bool cChannel::Parse(const char *s)
if (parambuf && sourcebuf && vpidbuf && apidbuf) { if (parambuf && sourcebuf && vpidbuf && apidbuf) {
parameters = parambuf; parameters = parambuf;
ok = (source = cSource::FromString(sourcebuf)) >= 0; ok = (source = cSource::FromString(sourcebuf)) >= 0;
transponder = 0;
char *p; char *p;
if ((p = strchr(vpidbuf, '=')) != NULL) { if ((p = strchr(vpidbuf, '=')) != NULL) {
@ -807,7 +791,8 @@ bool cChannel::Parse(const char *s)
free(tpidbuf); free(tpidbuf);
free(caidbuf); free(caidbuf);
free(namebuf); free(namebuf);
UpdateNameSource(); nameSource = NULL;
shortNameSource = NULL;
if (!GetChannelID().Valid()) { if (!GetChannelID().Valid()) {
esyslog("ERROR: channel data results in invalid ID!"); esyslog("ERROR: channel data results in invalid ID!");
return false; return false;
@ -848,7 +833,7 @@ int cChannels::maxChannelNameLength = 0;
int cChannels::maxShortChannelNameLength = 0; int cChannels::maxShortChannelNameLength = 0;
cChannels::cChannels(void) cChannels::cChannels(void)
:cConfig<cChannel>("2 Channels") :cConfig<cChannel>("Channels")
{ {
modifiedByUser = 0; modifiedByUser = 0;
} }
@ -953,25 +938,6 @@ void cChannels::ReNumber(void)
} }
} }
bool cChannels::MoveNeedsDecrement(cChannel *From, cChannel *To)
{
int Number = From->Number();
if (Number < To->Number()) {
for (cChannel *Channel = Next(From); Channel; Channel = Next(Channel)) {
if (Channel == To)
break;
if (Channel->GroupSep()) {
if (Channel->Number() > Number)
Number = Channel->Number();
}
else
Number++;
}
return Number == To->Number();
}
return false;
}
void cChannels::Del(cChannel *Channel) void cChannels::Del(cChannel *Channel)
{ {
UnhashChannel(Channel); UnhashChannel(Channel);
@ -1127,8 +1093,8 @@ bool cChannels::MarkObsoleteChannels(int Source, int Nid, int Tid)
bool ChannelsModified = false; bool ChannelsModified = false;
for (cChannel *Channel = First(); Channel; Channel = Next(Channel)) { for (cChannel *Channel = First(); Channel; Channel = Next(Channel)) {
if (time(NULL) - Channel->Seen() > CHANNELTIMEOBSOLETE && Channel->Source() == Source && Channel->Nid() == Nid && Channel->Tid() == Tid && Channel->Rid() == 0) { if (time(NULL) - Channel->Seen() > CHANNELTIMEOBSOLETE && Channel->Source() == Source && Channel->Nid() == Nid && Channel->Tid() == Tid && Channel->Rid() == 0) {
int OldShowChannelNamesWithSource = Setup.ShowChannelNamesWithSource; bool OldShowChannelNamesWithSource = Setup.ShowChannelNamesWithSource;
Setup.ShowChannelNamesWithSource = 0; Setup.ShowChannelNamesWithSource = false;
if (!endswith(Channel->Name(), CHANNELMARKOBSOLETE)) if (!endswith(Channel->Name(), CHANNELMARKOBSOLETE))
ChannelsModified |= Channel->SetName(cString::sprintf("%s %s", Channel->Name(), CHANNELMARKOBSOLETE), Channel->ShortName(), cString::sprintf("%s %s", CHANNELMARKOBSOLETE, Channel->Provider())); ChannelsModified |= Channel->SetName(cString::sprintf("%s %s", Channel->Name(), CHANNELMARKOBSOLETE), Channel->ShortName(), cString::sprintf("%s %s", CHANNELMARKOBSOLETE, Channel->Provider()));
Setup.ShowChannelNamesWithSource = OldShowChannelNamesWithSource; Setup.ShowChannelNamesWithSource = OldShowChannelNamesWithSource;

View File

@ -1,162 +1,85 @@
RTL Television,RTL;CBC:12187:HC34M2S0:S19.2E:27500:163=2:104=deu@3;106=deu@106:105;110=deu:0:12003:1:1089:0 RTL Television,RTL;RTL World:12187:HC34M2S0:S19.2E:27500:163=2:104=deu@3;106=deu@106:105;110=deu:0:12003:1:1089:0
SAT.1;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:255=2:256=deu@3;259=deu@106:32:0:17500:1:1107:0 SAT.1;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:255=2:256=deu@3;259=deu@106:32:0:17500:1:1107:0
ProSieben;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:511=2:512=deu@3;515=deu@106:33:0:17501:1:1107:0 ProSieben;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:511=2:512=deu@3;515=deu@106:33:0:17501:1:1107:0
RTL2;CBC:12187:HC34M2S0:S19.2E:27500:166=2:128=deu@3:68;75=deu:0:12020:1:1089:0 RTL2;RTL World:12187:HC34M2S0:S19.2E:27500:166=2:128=deu@3:68:0:12020:1:1089:0
:ARD und ZDF
Das Erste HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5101=27:5102=deu@3,5103=mis@3;5106=deu@106:5104;5105=deu:0:10301:1:1019:0 Das Erste HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5101=27:5102=deu@3,5103=mis@3;5106=deu@106:5104;5105=deu:0:10301:1:1019:0
ZDF HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6110=27:6120=deu@3,6121=mis@3,6123=mul@3;6122=deu@106:6130;6131=deu:0:11110:1:1011:0 ZDF HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6110=27:6120=deu@3,6121=mis@3,6123=mul@3;6122=deu@106:6130;6131=deu:0:11110:1:1011:0
:Dritte Programme BR Süd HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204:0:10325:1:1025:0
BR Fernsehen Sued HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204;5205=deu:0:10325:1:1025:0 hr-fernsehen;ARD:11836:HC34M2S0:S19.2E:27500:301=2:302=deu@3,303=mis@3:304:0:28108:1:1101:0
hr-fernsehen HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5351=27:5352=deu@3,5353=mis@3;5356=deu@106:5354;5355=deu:0:10355:1:1061:0 NDR FS MV HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5221=27:5222=deu@3,5223=mis@3;5226=deu@106:5224;5225=deu:0:10328:1:1025:0
NDR FS NDS HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5221=27:5222=deu@3,5223=mis@3;5226=deu@106:5224;5225=deu:0:10327:1:1025:0 SR Fernsehen;ARD:12265:HC34M2S0:S19.2E:27500:1301=2:1302=deu@3,1303=mis@3:1304:0:28486:1:1093:0
WDR HD Koeln;ARD:12422:HC34M2S0:S19.2E:27500:5501=27:5502=deu@3,5503=mis@3;5506=deu@106:5504;5505=deu:0:28325:1:1201:0 WDR HD Köln;ARD:12422:HC34M2S0:S19.2E:27500:5501=27:5502=deu@3,5503=mis@3;5506=deu@106:5504:0:28325:1:1201:0
SWR BW HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5121=27:5122=deu@3,5123=mis@3;5126=deu@106:5124;5125=deu:0:10303:1:1019:0 SWR BW HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5121=27:5122=deu@3,5123=mis@3;5126=deu@106:5124;5125=deu:0:10303:1:1019:0
rbb Berlin HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5311=27:5312=deu@3,5313=mis@3;5316=deu@106:5314;5315=deu:0:10351:1:1061:0 rbb Berlin;ARD:12109:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28206:1:1073:0
MDR Sachsen HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5331=27:5332=deu@3,5333=mis@3;5336=deu@106:5334;5335=deu:0:10352:1:1061:0
PHOENIX HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5261=27:5262=deu@3,5263=mul@3:5264:0:10331:1:1025:0 PHOENIX HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5261=27:5262=deu@3,5263=mul@3:5264:0:10331:1:1025:0
ARD-alpha;ARD:12265:HC34M2S0:S19.2E:27500:1401=2:1402=deu@3,1403=mis@3;1406=deu@106:1404;1405=deu:0:28487:1:1093:0 BR-alpha;ARD:12265:HC34M2S0:S19.2E:27500:1401=2:1402=deu@3,1403=mis@3;1406=deu@106:1404:0:28487:1:1093:0
3sat HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6510=27:6520=deu@3,6521=mis@3,6523=mul@3;6522=deu@106:6530;6531=deu:0:11150:1:1010:0 3sat HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6510=27:6520=deu@3,6521=mis@3,6523=mul@3;6522=deu@106:6530;6531=deu:0:11150:1:1010:0
arte HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5111=27:5112=deu@3,5113=fra@3,5117=mis@3;5116=mul@106:5114;5115=deu,5118=fra,5119=deu:0:10302:1:1019:0 arte HD;ARD:11493:HC23M5O35P0S1:S19.2E:22000:5111=27:5112=deu@3,5113=fra@3;5116=deu@106:5114;5115=deu,5118=fra:0:10302:1:1019:0
zdf_neo HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6310=27:6320=deu@3,6321=mis@3,6323=mul@3;6322=deu@106:6330;6331=deu:0:11130:1:1011:0 MDR Sachsen;ARD:12109:HC34M2S0:S19.2E:27500:2901=2:2902=deu@3,2903=mis@3:2904:0:28228:1:1073:0
ZDFinfo HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6710=27:6720=deu@3,6721=mis@3,6723=mul@3;6722=deu@106:6730;6731=deu:0:11170:1:1010:0 ServusTV HD Oesterreich;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:3583=27:3584=deu@4,3585=eng@4;3586=deu@122,3587=deu@106:3588:0:4913:1:1007:0
ONE HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5411=27:5412=deu@3,5413=mis@3;5416=deu@106:5414;5415=deu:0:10376:1:1039:0 N24;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1023=2:1024=deu@3:35:0:17503:1:1107:0
KiKA HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6610=27:6620=deu@3,6621=mis@3;6622=deu@106:6630;6631=deu:0:11160:1:1010:0 Das Erste;ARD:11836:HC34M2S0:S19.2E:27500:101=2:102=deu@3,103=mis@3;106=deu@106:104;105=deu:0:28106:1:1101:0
:Regionalprogramme Bayerisches FS Süd;ARD:11836:HC34M2S0:S19.2E:27500:201=2:202=deu@3,203=mis@3;206=deu@106:204:0:28107:1:1101:0
Niederbayern;MB Satellite:11523:HC56M2S0:S19.2E:22000:2559=2:2560=deu@3:0:0:4609:1:1021:0 NDR FS MV;ARD:12109:HC34M2S0:S19.2E:27500:2601=2:2602=deu@3,2603=mis@3:2604:0:28224:1:1073:0
Franken Fernsehen;MB Satellite:11523:HC56M2S0:S19.2E:22000:511=2:512=deu@3:0:0:4601:1:1021:0 WDR Köln;ARD:11836:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28111:1:1101:0
muenchen.tv;MB Satellite:11523:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:0:0:4604:1:1021:0 SWR Fernsehen BW;ARD:11836:HC34M2S0:S19.2E:27500:801=2:802=deu@3,803=mis@3;806=deu@106:804:0:28113:1:1101:0
Mainfranken;MB Satellite:11523:HC56M2S0:S19.2E:22000:1791=2:1792=deu@3:0:0:4606:1:1021:0 PHOENIX;ARD:10744:HC56M2S0:S19.2E:22000:501=2:502=deu@3,503=mul@3:504:0:28725:1:1051:0
TV Oberfranken;MB Satellite:11523:HC56M2S0:S19.2E:22000:2047=2:2048=deu@3:0:0:4607:1:1021:0 ZDF;ZDFvision:11953:HC34M2S0:S19.2E:27500:110=2:120=deu@3,121=mis@3,122=mul@3;125=deu@106:130;131=deu:0:28006:1:1079:0
TVA-OTV;MB Satellite:11523:HC56M2S0:S19.2E:22000:2303=2:2304=deu@3:0:0:4608:1:1021:0 3sat;ZDFvision:11953:HC34M2S0:S19.2E:27500:210=2:220=deu@3,221=mis@3,222=mul@3;225=deu@106:230;231=deu:0:28007:1:1079:0
a.tv;MB Satellite:11523:HC56M2S0:S19.2E:22000:255=2:256=deu@3:0:0:4600:1:1021:0 KiKA HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6610=27:6620=deu@3,6621=mis@3;6622=deu@106:6630:0:11160:1:1010:0
BR Fernsehen Nord HD;ARD:11582:HC23M5O35P0S1:S19.2E:22000:5201=27:5202=deu@3,5203=mis@3;5206=deu@106:5204;5205=deu:0:10326:1:1025:0 KiKA;ZDFvision:11953:HC34M2S0:S19.2E:27500:310=2:320=deu@3,321=mis@3;325=deu@106:330:0:28008:1:1079:0
rbb Brandenburg HD;ARD:10891:HC23M5O35P0S1:S19.2E:22000:5311=27:5312=deu@3,5313=mis@3;5316=deu@106:5314;5315=deu:0:10350:1:1061:0 arte;ARD:10744:HC56M2S0:S19.2E:22000:401=2:402=deu@3,403=fra@3:404:0:28724:1:1051:0
SR Fernsehen HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5431=27:5432=deu@3,5433=mis@3;5436=deu@106:5434;5435=deu:0:10378:1:1039:0 ORF1 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:1920=27:1921=deu@4,1922=eng@4;1923=deu@106:1925:D05,D95,648,1702,1833,9C4,98C:4911:1:1007:0
Radio Bremen TV;ARD:12421:HC34M2S0:S19.2E:27500:1201=2:1202=deu@3:1204:0:28385:1:1201:0 ORF1;ORF:12692:HC56M2S0:S19.2E:22000:160=2:161=deu@3;163=deu@106:165:D05,D95,648,1702,1833,9C4,98C:13001:1:1117:0
:Oesterreichisches Fernsehen ORF2 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:2920=27:2921=deu@4,2922=eng@4;2923=deu@106:2925:D05,D95,648,1702,1833,9C4,98C:4912:1:1007:0
ORF1 HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:1920=27:0;1921=deu@106,1922=mis@106:1925:648,650,D95,D98,6E2,500,9C4,98C:4911:1:1007:0 ORF2;ORF:12692:HC56M2S0:S19.2E:22000:500=2:501=deu@3;503=deu@106:505:D95,D05,648,1702,1833,9C4,98C:13002:1:1117:0
ORF2W HD;ORF:11303:HC23M5O35P0S1:S19.2E:22000:2920=27:0;2921=deu@106,2922=mis@106:2925:648,650,D95,D98,6E2,500,9C4,98C:4912:1:1007:0 ZDFinfo HD;ZDFvision:11347:VC23M5O35P0S1:S19.2E:22000:6710=27:6720=deu@3,6721=mis@3,6723=mul@3;6722=deu@106:6730:0:11170:1:1010:0
ORF III;ORF:12662:HC56M2S0:S19.2E:22000:1010=2:1011=deu@4:1013:648,650,D95,D98,9C4,98C:13101:1:1115:0 ZDFinfo;ZDFvision:11953:HC34M2S0:S19.2E:27500:610=2:620=deu@3,621=mis@3,622=mul@3;625=deu@106:630:0:28011:1:1079:0
ServusTV HD Oesterreich;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:3583=27:3584=deu@4,3585=eng@4;3587=deu@106:3588:648,650,D95,D98,9C4,98C,6E2,500:4913:1:1007:0 CNN Int.;CNN:11778:VC34M2S0:S19.2E:27500:165=2:100=eng@3:0:0:28522:1:1068:0
ServusTV HD Deutschland;ServusTV:11303:HC23M5O35P0S1:S19.2E:22000:4920=27:4921=deu@4,4922=eng@4;4924=deu@106:4925:0:4914:1:1007:0 SUPER RTL;RTL World:12187:HC34M2S0:S19.2E:27500:165=2:120=deu@3:65:0:12040:1:1089:0
ATV;ATV+:12692:HC56M2S0:S19.2E:22000:506=2:507=deu@3:509:648,650,D95,D98,9C4,98C:13012:1:1117:0 VOX;RTL World:12187:HC34M2S0:S19.2E:27500:167=2:136=deu@3:71;74=deu:0:12060:1:1089:0
ORF SPORT+;ORF:11243:HC56M2S0:S19.2E:22000:2210=2:2211=deu@3,2212=mis@3:2215:648,650,D95,D98,9C4,98C:13221:1:1003:0
PULS 4 Austria;ProSiebenSat.1:12051:VC34M2S0:S19.2E:27500:1791=2:1792=deu@3:39:9C4,98C,D95,648,D98,650,500,6E2,98D:20007:1:1082:0
:Nachrichten
tagesschau24 HD;ARD:11052:HC23M5O35P0S1:S19.2E:22000:5401=27:5402=deu@3,5403=mis@3;5406=deu@106:5404:0:10375:1:1039:0
n-tv;CBC:12187:HC34M2S0:S19.2E:27500:169=2:73=deu@3,77=mul@3:80:0:12090:1:1089:0
WELT;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1023=2:1024=deu@3:35:0:17503:1:1107:0
N24 DOKU;BetaDigital:12460:HC34M2S0:S19.2E:27500:511=2:512=deu@3:34:0:48:133:5:0
CNN Int.;Harmonic:11626:VC56M2S0:S19.2E:22000:165=2:100=eng@3:0:0:4422:1:1028:0
EURONEWS FRENCH SD;Globecast:12226:HC34M2S0:S19.2E:27500:2432=2:2435=fra@3:0:0:31220:1:1091:0
Bloomberg Europe TV;Bloomberg TV:11597:VC56M2S0:S19.2E:22000:1360=2:1320=eng@3:0:0:10067:1:1026:0
CNBC Europe;CNBC:11597:VC56M2S0:S19.2E:22000:307=2:308=eng@3:0:0:10030:1:1026:0
Russia Today;GLOBECAST:11538:VC56M2S0:S19.2E:22000:604=2:624=eng@3:0:0:6904:1:1022:0
Sky News Intl;SES ASTRA:12604:HC56M2S0:S19.2E:22000:1290=2:2290=eng@3:1750:0:7290:1:1111:0
Al Jazeera English;Al Jazeera:11626:VC56M2S0:S19.2E:22000:3505=2:3625=eng@3:0:0:4440:1:1028:0
Al Jazeera Channel;GLOBECAST:11508:VC56M2S0:S19.2E:22000:709=2:729=ara@3:0:0:7009:1:1020:0
:Sport
SPORT1;BetaDigital:12480:VC34M2S0:S19.2E:27500:1023=2:1024=deu@3:39:0:900:133:33:0
Eurosport 1 Deutschland;SES Astra:12226:HC34M2S0:S19.2E:27500:101=2:103=deu@4:102:0:31200:1:1091:0
:Privatsender
RTLplus;CBC:12187:HC34M2S0:S19.2E:27500:168=2:137=deu@3:70:0:12080:1:1089:0
NITRO;CBC:12187:HC34M2S0:S19.2E:27500:173=2:146=deu@3:84;86=deu:0:12061:1:1089:0
SUPER RTL;CBC:12187:HC34M2S0:S19.2E:27500:165=2:120=deu@3:65;66=deu:0:12040:1:1089:0
SAT.1 Gold;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:36:0:17504:1:1107:0
Pro7 MAXX;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1535=2:1536=deu@3:37:0:17505:1:1107:0
kabel eins;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:767=2:768=deu@3:34:0:17502:1:1107:0 kabel eins;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:767=2:768=deu@3:34:0:17502:1:1107:0
kabel eins Doku;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:2559=2:2560=deu@3:41:0:17509:1:1107:0 DAS VIERTE,D VIERTE;BetaDigital:12460:HC34M2S0:S19.2E:27500:2047=2:2048=deu@3:36:0:1793:133:5:0
Family TV;BetaDigital:10920:HC78M2S0:S19.2E:22000:255=2:256=deu@3:0:0:33:133:15:0 BBC FOUR;BSkyB:10802:HC56M2S0:S28.2E:22000:5600=2:5601=eng@3,5602=NAR@3:5603;5604=eng:0:6416:2:2047:0
Disney Channel;BetaDigital:12460:HC34M2S0:S19.2E:27500:2047=2:2048=deu@3;2051=deu@106:36:0:1793:133:5:0 BBC HD;BSkyB:10847:vC56M2O0S1:S28.5E:23000:5500=27:5502=NAR@3;5501=eng@106:5503;5504=eng:0:6940:2:2050:0
TELE 5;BetaDigital:12480:VC34M2S0:S19.2E:27500:1535=2:1536=deu@3:38:0:51:133:33:0 BBC One HD;BSkyB:10847:VC23M5O25P0S1:S28.2E:23000:5400=27:5402=NAR@3;5401=eng@106:5403;5404=eng:0:6941:2:2050:0
VOX;CBC:12187:HC34M2S0:S19.2E:27500:167=2:136=deu@3:71;74=deu:0:12060:1:1089:0 SAT.1 Gold;ProSiebenSat.1:12544:HC56M2S0:S19.2E:22000:1279=2:1280=deu@3:36:0:17504:1:1107:0
SIXX;ProSiebenSat.1:12460:HC34M2S0:S19.2E:27500:767=2:768=deu@3:35:0:776:133:5:0 SPORT1;BetaDigital:12480:VC34M2S0:S19.2E:27500:1023=2:1024=deu@3:39:0:900:133:33:0
DMAX;BetaDigital:12480:VC34M2S0:S19.2E:27500:3327=2:3328=deu@3:44:0:63:133:33:0
ANIXE HD;BetaDigital:10773:HC34M5O20P0S1:S19.2E:22000:255=27:0;259=deu@106:0:0:21100:1:1053:0
Nickelodeon;MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4101=2:4102=deu@4,4103=eng@4:4104:0:28680:1:1078:0
TOGGO plus;CBC:12187:HC34M2S0:S19.2E:27500:301=2:303=deu@3:0:0:12030:1:1089:0
Comedy Central/VIVA;MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4061=2:4062=@4:4064:0:28676:1:1078:0
DELUXE MUSIC,DELUXE;BetaDigital:12148:HC34M2S0:S19.2E:27500:3327=2:3328=deu@3:0:0:65:133:7:0
sonnenklar.TV HD;BetaDigital:12574:HC23M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106:32:0:5400:1:1109:0
QVC Deutschland;SES ASTRA:12551:VC56M2S0:S19.2E:22000:165=2:166=deu@3:167:0:12100:1:1108:0
HSE24,HSE24;BetaDigital:12480:VC34M2S0:S19.2E:27500:1279=2:1280=deu@3:37:0:40:133:33:0 HSE24,HSE24;BetaDigital:12480:VC34M2S0:S19.2E:27500:1279=2:1280=deu@3:37:0:40:133:33:0
1-2-3.tv HD;BetaDigital:10802:HC34M5O35P0S1:S19.2E:22000:767=27:0;771=deu@106:34:0:5502:1:1055:0 Bloomberg Europe TV;Arqiva:11597:VC56M2S0:S19.2E:22000:1360=2:1320=eng@4:37:0:10067:1:1026:0
Juwelo HD;BetaDigital:12574:HC23M5O35P0S1:S19.2E:22000:1023=27:1024=deu@3:0:0:5403:1:1109:0 NRJ 12;CSAT:11817:VC34M2S0:S19.2E:27500:163=2:92=fra@4;93=fra@106:41:1811,1812,500,1863,100:8004:1:1070:0
:@100 rbb Brandenburg;ARD:12109:HC34M2S0:S19.2E:27500:601=2:602=deu@3,603=mis@3:604:0:28205:1:1073:0
:Sky HD Sky News Intl;SES ASTRA:12604:HC56M2S0:S19.2E:22000:1290=2:2290=@4:0:0:7290:1:1111:0
Sky Cinema HD,Sky Cinema HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:0:98C,9C4,9AF,98D:131:133:6:0 Veronica/DisneyXD;CANALDIGITAAL:12574:HC56M2O0S0:S19.2E:22000:0:0:0:622:5020:53:1109:0
Sky Cinema +1 HD,Sky Cine1 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:9C4,98C,9AF,98D:134:133:8:0 Test;CANALDIGITAAL:12574:HC56M2O0S0:S19.2E:22000:522+8190=2:97=dut@4:40:100:5025:53:1109:0
Sky Cinema +24 HD,Sky Cine24 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:9C4,98C,9AF,98D:135:133:8:0 n-tv;RTL World:12187:HC34M2S0:S19.2E:27500:169=2:73=deu@3:80:0:12090:1:1089:0
Sky Cinema Hits HD,Sky Hits HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106:0:9C4,98C,9AF,98D:107:133:12:0 Al Jazeera Channel;GlobeCast:11508:VC56M2S0:S19.2E:22000:709=2:729=ara@3:0:0:7009:1:1020:0
Sky Cinema Action HD,Action HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,9AF,98D:116:133:11:0 ORF III;ORF:12662:HC56M2S0:S19.2E:22000:1010=2:1011=deu@4:1013:D95,648,D05,9C4,1702,1833,98C:13101:1:1115:0
Sky Cinema Animation HD,Animation HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:9C4,98C,9AF,98D:139:133:8:0 Eurosport HD,EurospHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1535=27:0;1539=deu@106:32:1833,9C4,9AF,98C:132:133:6:0
SYFY HD,SYFY HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:9C4,98C,9AF,98D:126:133:12:0 Eurosport Deutschland;SES Astra:12226:HC34M2S0:S19.2E:27500:101=2:103=deu@4:102:0:31200:1:1091:0
Sky Atlantic HD,AtlanticHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:0:98C,9C4,9AF,98D:110:133:13:0 tagesschau24;ARD:10744:HC56M2S0:S19.2E:22000:101=2:102=deu@3:0:0:28721:1:1051:0
Sky 1 +1 HD,Sky 1 +1 HD;SKY:11797:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:144:133:16:0 Einsfestival HD;ARD:12422:HC34M2S0:S19.2E:27500:1601=27:1602=deu@3;1606=deu@106:1604:0:28396:1:1201:0
TNT Serie HD,TNTSerieHD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,9AF,98D:123:133:11:0 Einsfestival;ARD:10744:HC56M2S0:S19.2E:22000:201=2:202=deu@3,203=mis@3;206=deu@106:204:0:28722:1:1051:0
TNT Comedy HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,98D:136:133:14:0 EinsPlus;ARD:10744:HC56M2S0:S19.2E:22000:301=2:302=deu@3,303=mis@3;306=deu@106:304:0:28723:1:1051:0
Fox HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,98D:124:133:10:0 zdf.kultur HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6410=27:6420=deu@3,6421=mis@3,6423=mul@3;6422=deu@106:6430:0:11140:1:1011:0
13th Street HD,13th St HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:98C,9C4,9AF,98D:127:133:13:0 zdf.kultur;ZDFvision:11953:HC34M2S0:S19.2E:27500:1110=2:1120=deu@3,1121=mis@3,1122=mul@3;1125=deu@106:1130:0:28016:1:1079:0
Universal HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:1535=27:0;1539=deu@106,1540=eng@106:0:98C,9C4,98D:101:133:14:0 zdf_neo HD;ZDFvision:11362:HC23M5O35P0S1:S19.2E:22000:6310=27:6320=deu@3,6321=mis@3,6323=mul@3;6322=deu@106:6330:0:11130:1:1011:0
RTL Crime HD,RTL CrimeHD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106,260=eng@106:0:9C4,98C,98D:140:133:9:0 zdf_neo;ZDFvision:11953:HC34M2S0:S19.2E:27500:660=2:670=deu@3,671=mis@3,672=mul@3;675=deu@106:680:0:28014:1:1079:0
E! Entertainm. HD,E! HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,98D:128:133:14:0 SIXX;ProSiebenSat.1:12460:HC34M2S0:S19.2E:27500:767=2:768=deu@3:35:0:776:133:5:0
Spiegel Geschichte HD,Spiegel G HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:255=27:0;259=deu@106:0:98C,9C4,98D:137:133:10:0 :Sky
Discovery HD,DiscHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106,1028=eng@106:0:98C,9C4,9AF,98D:130:133:6:0 Sky Cinema,Cinema;SKY:11797:HC34M2S0:S19.2E:27500:511=2:512=deu@3,513=eng@3;515=deu@106:32:1702,1722,1833,1834,1836,9C4,9C7,9AF,98C,1861:10:133:2:0
History HD,HistHD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106,772=eng@106:0:98C,9C4,9AF,98D:113:133:11:0 Sky Cinema +1,Cinema1;SKY:11797:HC34M2S0:S19.2E:27500:1791=2:1792=deu@3,1793=eng@3;1795=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:11:133:2:0
NatGeo HD,NatGeoHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:112:133:13:0 Sky Cinema +24,Cinema24;SKY:11797:HC34M2S0:S19.2E:27500:2303=2:2304=deu@3,2305=eng@3;2307=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:43:133:2:0
Nat Geo Wild HD,NGWildHD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106,516=eng@106:0:98C,9C4,9AF,98D:118:133:6:0 Sky Action,Action;SKY:11797:HC34M2S0:S19.2E:27500:767=2:768=deu@3,769=eng@3;771=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:9:133:2:0
Disney Cinemagic HD,DisneyCinHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:255=27:0;259=deu@106,260=eng@106:0:98C,9C4,9AF,98D:111:133:13:0 Sky Comedy,Comedy;SKY:11797:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3,2561=eng@3;2563=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:8:133:2:0
Disney Junior HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106:0:9C4,98C,9AF,98D:138:133:8:0 Sky Atlantic HD,AtlanticHD;SKY:11993:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106,1284=eng@106:32:1833,9C4,9AF,98C:110:133:13:0
Sky Arts HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:767=27:0;771=deu@106,772=eng@106:0:9C4,98C,98D:145:133:9:0 Fox Serie,Fox;SKY:12070:HC34M2S0:S19.2E:27500:1279=2:1280=deu@3,1281=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:16:133:1:0
:Sky Film History HD,HistHD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:767=27:0;771=deu@106:32:1833,9C4,9AF,98C:113:133:13:0
Sky Cinema Comedy,Sky Comedy;SKY:11719:HC910M2O35P0S1:S19.2E:27500:1023=27:1024=deu@3,1025=eng@3;1027=deu@106:0:9C4,98C,9AF,98D:8:133:3:0 Sky Emotion,Emotion;SKY:11797:HC34M2S0:S19.2E:27500:2815=2:2816=deu@3,2817=eng@3;2819=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:20:133:2:0
Sky Cinema Western,Sky Western;SKY:12031:HC910M2O35P0S1:S19.2E:27500:767=27:768=deu@3,769=eng@3:0:9C4,98C,9AF,98D:516:133:4:0 Sky Nostalgie,Nostalgie;SKY:11719:HC34M2S0:S19.2E:27500:1535=2:1536=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:516:133:3:0
Sky Cinema Emotion,Sky Emotion;SKY:12031:HC910M2O35P0S1:S19.2E:27500:511=27:512=deu@3,513=eng@3;515=deu@106:0:9C4,98C,9AF,98D:20:133:4:0 Sky Hits,SkyHits;SKY:11719:HC34M2S0:S19.2E:27500:1023=2:1024=deu@3,1025=eng@3;1027=deu@106:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:41:133:3:0
:Sky Welt Discovery Channel,Discovery;SKY:12031:HC34M2S0:S19.2E:27500:3071=2:3072=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:14:133:4:0
RTL Passion,Passion;SKY:12031:HC910M2O35P0S1:S19.2E:27500:3839=27:3840=deu@3,3841=eng@3:0:9C4,98C,9AF,98D:29:133:4:0 National Geographic,NatGeo;SKY:12031:HC34M2S0:S19.2E:27500:3327=2:3328=deu@3,3329=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:13:133:4:0
Sky Krimi,SkyKrimi;SKY:12031:HC910M2O35P0S1:S19.2E:27500:1535=27:1536=deu@3:0:9C4,98C,9AF,98D:23:133:4:0 Disney Channel,Disney;SKY:11758:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:34:133:17:0
Disney XD,DisneyXD;SKY:11719:HC910M2O35P0S1:S19.2E:27500:1279=27:1280=deu@3,1281=eng@3:0:9C4,98C,9AF,98D:28:133:3:0 TNT Serie,TNTSerie;SKY:12070:HC34M2S0:S19.2E:27500:2559=2:2560=deu@3,2561=eng@3:32:1702,1722,1833,1834,9C4,9C7,9AF,98C,1861:50:133:1:0
Heimatkanal,Heimat;SKY:11758:HC910M2O35P0S1:S19.2E:27500:2815=27:2816=deu@3:0:9C4,98C,9AF,98D:22:133:2:0 :@1000 New channels
Romance TV,Romance;SKY:11758:HC910M2O35P0S1:S19.2E:27500:3071=27:3072=deu@3:0:9C4,98C,9AF,98D:518:133:2:0
Classica;SKY:11719:HC910M2O35P0S1:S19.2E:27500:2047=27:2048=deu@3:0:9C4,98C,9AF,98D:24:133:3:0
:Sky Welt Extra
TNT Film (TCM),TNT Film;SKY:11914:HC910M2O35P0S1:S19.2E:27500:4351=27:4352=deu@3,4353=eng@3:0:98C,9C4,9AF,98D:405:133:6:0
Kinowelt TV,Kinowelt;SKY:12031:HC910M2O35P0S1:S19.2E:27500:4351=27:4352=deu@3:0:9C4,98C,9AF,98D:406:133:4:0
.;BetaDigital:10920:HC78M2S0:S19.2E:22000:2047=27:2048=deu@3,2049=eng@3:0:9C4,98C:57:133:15:0
.;SKY:10920:HC78M2S0:S19.2E:22000:1023=27:1024=deu@3:0:1837,9C4,98C,1867:38:133:15:0
RTL Living;CBC:11082:HC34M5O20P0S1:S19.2E:22000:700=27:710=deu@3,711=qaa@3:0:9C4,98C,98D:11971:1:1041:0
Boomerang;SKY:11875:HC34M5O35P0S1:S19.2E:27500:4351=27:4352=deu@3,4353=eng@3:0:98C,9C4,98D:403:133:14:0
Cartoon Network,Cartoon Net;SKY:11875:HC34M5O35P0S1:S19.2E:27500:4607=27:4608=deu@3,4609=eng@3:0:98C,9C4,98D:404:133:14:0
Nicktoons (S);MTV Networks Europe:11973:VC34M2S0:S19.2E:27500:4121=2:4122=@4:0:500:28682:1:1078:0
Beate-Uhse.TV,BeateU;SKY:11719:HC910M2O35P0S1:S19.2E:27500:2303=27:2304=deu@3:0:9C4,98C,9AF,98D:21:133:3:0
:Sky Bundesliga HD
Sky Sport Bundesliga 1 HD,Sky Buli 1 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:255=27:0;258=qab@106,259=qab@106,260=qac@106:32;33=deu:9C4,98C,9AF,98D:105:133:12:0
Sky Sport Bundesliga 2 HD,Sky Buli 2 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106:32:9C4,98C,9AF,98D:267:133:6:0
Sky Sport Bundesliga 3 HD,Sky Buli 3 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,9AF,98D:277:133:13:0
Sky Sport Bundesliga 4 HD,Sky Buli 4 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:9C4,98C,9AF,98D:287:133:12:0
Sky Sport Bundesliga 5 HD,Sky Buli 5 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,9AF,98D:297:133:11:0
Sky Sport Bundesliga 6 HD,Sky Buli 6 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:2047=27:0;2050=qab@106,2051=qab@106,2052=qac@106:32:98C,9C4,98D:307:133:8:0
Sky Sport Bundesliga 7 HD,Sky Buli 7 HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1791=27:0;1794=qab@106,1795=qab@106,1796=qac@106:33:98C,9C4:317:133:9:0
Sky Sport Bundesliga 8 HD,Sky Buli 8 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2559=27:0;2562=deu@106,2563=deu@106,2564=deu@106:0:9C4,98C:327:133:14:0
Sky Sport Bundesliga 9 HD,Sky Buli 9 HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:2559=27:0;2562=qab@106,2563=qab@106,2564=qac@106:32:98C,9C4:337:133:10:0
Sky Sport Bundesliga 10 HD,Sky Buli 10 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2047=27:0;2050=deu@106,2051=deu@106,2052=deu@106:0:9C4,98C:257:133:14:0
Sky Sport Fanzone HD,Fanzone HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:1279=27:0:0:98C,9C4:102:133:10:0
:Sky Sport HD
Sky Sport News HD,SportNewsHD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1027=deu@106:0:0:108:133:12:0
Sky Sport 1 HD,Sky Sport 1 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:767=27:0;770=qae@106,771=qaf@106:32:98C,9C4,9AF,98D:129:133:6:0
Sky Sport 2 HD,Sky Sport 2 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:1023=27:0;1026=qae@106,1027=qaf@106,1028=qtz@106:32:98C,9C4,9AF,98D:114:133:13:0
Sky Sport 3 HD,Sky Sport 3 HD;SKY:11914:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF,98D:268:133:6:0
Sky Sport 4 HD,Sky Sport 4 HD;SKY:11992:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF:278:133:13:0
Sky Sport 5 HD,Sky Sport 5 HD;SKY:12304:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106:261:9C4,98C,9AF:288:133:12:0
Sky Sport 6 HD,Sky Sport 6 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,9AF,98D:298:133:11:0
Sky Sport 7 HD,Sky Sport 7 HD;SKY:12070:HC910M2O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,98D:308:133:8:0
Sky Sport 8 HD,Sky Sport 8 HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:3071=27:0;3074=qae@106,3075=qaf@106,3076=qtz@106:32:98C,9C4,98D:318:133:9:0
Sky Sport 9 HD,Sky Sport 9 HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2815=27:0;2818=deu@106,2819=deu@106:32:98C,9C4:328:133:14:0
Sky Sport 10 HD,Sky Sport 10HD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:2815=27:0;2818=qae@106,2819=qaf@106,2820=qtz@106:32:98C,9C4,98D:338:133:10:0
Sky Sport 11 HD,Sky Sport 11HD;SKY:11875:HC34M5O35P0S1:S19.2E:27500:2303=27:0;2306=qae@106,2307=qaf@106,2308=qtz@106:32:98C,9C4,98D:258:133:14:0
Eurosport 1 HD,Eurosp1 HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:511=27:0;515=deu@106:0:98C,9C4,9AF,98D:132:133:11:0
Eurosport 2 HD,Eurosp2HD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1279=27:0;1283=deu@106,1284=eng@106:0:9C4,98C,98D:109:133:9:0
Sport1+ HD,Sport1+HD;SKY:12382:HC910M2O35P0S1:S19.2E:27500:1279=27:0;1283=deu@106:0:98C,9C4,98D,9AF:122:133:11:0
Sport1 US HD,Sport1USHD;SKY:11332:HC34M5O35P0S1:S19.2E:22000:511=27:0;515=deu@106:32:98C,9C4:119:133:10:0
Sky Sport Austria HD,SportAutHD;SKY:11170:HC34M5O35P0S1:S19.2E:22000:1023=27:0;1027=deu@106:0:9C4,98C,98D:143:133:9:0
:@1000 Neue Kanaele

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.h 5.3 2024/03/02 16:21:16 kls Exp $ * $Id: channels.h 4.2 2015/08/17 09:39:48 kls Exp $
*/ */
#ifndef __CHANNELS_H #ifndef __CHANNELS_H
@ -87,7 +87,6 @@ class cChannels;
class cChannel : public cListObject { class cChannel : public cListObject {
friend class cSchedules; friend class cSchedules;
friend class cMenuEditChannel; friend class cMenuEditChannel;
friend class cMenuSetupMisc;
friend class cDvbSourceParam; friend class cDvbSourceParam;
private: private:
static cString ToText(const cChannel *Channel); static cString ToText(const cChannel *Channel);
@ -97,7 +96,6 @@ private:
char *portalName; char *portalName;
int __BeginData__; int __BeginData__;
int frequency; // MHz int frequency; // MHz
mutable int transponder; // cached value
int source; int source;
int srate; int srate;
int vpid; int vpid;
@ -107,7 +105,7 @@ private:
int atypes[MAXAPIDS + 1]; // list is zero-terminated int atypes[MAXAPIDS + 1]; // list is zero-terminated
char alangs[MAXAPIDS][MAXLANGCODE2]; char alangs[MAXAPIDS][MAXLANGCODE2];
int dpids[MAXDPIDS + 1]; // list is zero-terminated int dpids[MAXDPIDS + 1]; // list is zero-terminated
int dtypes[MAXDPIDS + 1]; // list is zero-terminated int dtypes[MAXAPIDS + 1]; // list is zero-terminated
char dlangs[MAXDPIDS][MAXLANGCODE2]; char dlangs[MAXDPIDS][MAXLANGCODE2];
int spids[MAXSPIDS + 1]; // list is zero-terminated int spids[MAXSPIDS + 1]; // list is zero-terminated
char slangs[MAXSPIDS][MAXLANGCODE2]; char slangs[MAXSPIDS][MAXLANGCODE2];
@ -124,8 +122,8 @@ private:
int number; // Sequence number assigned on load int number; // Sequence number assigned on load
bool groupSep; bool groupSep;
int __EndData__; int __EndData__;
cString nameSource; mutable cString nameSource;
cString shortNameSource; mutable cString shortNameSource;
cString parameters; cString parameters;
mutable int modification; mutable int modification;
time_t seen; // When this channel was last seen in the SDT of its transponder time_t seen; // When this channel was last seen in the SDT of its transponder
@ -133,7 +131,6 @@ private:
cLinkChannels *linkChannels; cLinkChannels *linkChannels;
cChannel *refChannel; cChannel *refChannel;
cString TransponderDataToString(void) const; cString TransponderDataToString(void) const;
void UpdateNameSource(void);
public: public:
cChannel(void); cChannel(void);
cChannel(const cChannel &Channel); cChannel(const cChannel &Channel);
@ -180,7 +177,6 @@ public:
void SetNumber(int Number) { number = Number; } void SetNumber(int Number) { number = Number; }
bool GroupSep(void) const { return groupSep; } bool GroupSep(void) const { return groupSep; }
const char *Parameters(void) const { return parameters; } const char *Parameters(void) const { return parameters; }
const cSchedule *Schedule(void) const { return schedule; }
const cLinkChannels* LinkChannels(void) const { return linkChannels; } const cLinkChannels* LinkChannels(void) const { return linkChannels; }
const cChannel *RefChannel(void) const { return refChannel; } const cChannel *RefChannel(void) const { return refChannel; }
bool IsAtsc(void) const { return cSource::IsAtsc(source); } bool IsAtsc(void) const { return cSource::IsAtsc(source); }
@ -233,7 +229,6 @@ public:
int GetNextNormal(int Idx) const; ///< Get next normal channel (not group) int GetNextNormal(int Idx) const; ///< Get next normal channel (not group)
int GetPrevNormal(int Idx) const; ///< Get previous normal channel (not group) int GetPrevNormal(int Idx) const; ///< Get previous normal channel (not group)
void ReNumber(void); ///< Recalculate 'number' based on channel type void ReNumber(void); ///< Recalculate 'number' based on channel type
bool MoveNeedsDecrement(cChannel *From, cChannel *To); // Detect special case when moving a channel (closely related to Renumber())
void Del(cChannel *Channel); ///< Delete the given Channel from the list void Del(cChannel *Channel); ///< Delete the given Channel from the list
const cChannel *GetByNumber(int Number, int SkipGap = 0) const; const cChannel *GetByNumber(int Number, int SkipGap = 0) const;
cChannel *GetByNumber(int Number, int SkipGap = 0) { return const_cast<cChannel *>(static_cast<const cChannels *>(this)->GetByNumber(Number, SkipGap)); } cChannel *GetByNumber(int Number, int SkipGap = 0) { return const_cast<cChannel *>(static_cast<const cChannels *>(this)->GetByNumber(Number, SkipGap)); }

432
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 5.1 2021/06/09 09:41:18 kls Exp $ * $Id: ci.c 4.16 2017/05/18 09:05:46 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -78,18 +78,17 @@ static char *CopyString(int Length, const uint8_t *Data)
///< Copies the string at Data. ///< Copies the string at Data.
///< Returns a pointer to a newly allocated string. ///< Returns a pointer to a newly allocated string.
{ {
char *s = MALLOC(char, Length + 1); // Some CAMs send funny characters at the beginning of strings.
char *p = s; // Let's just skip them:
while (Length > 0) { while (Length > 0 && (*Data == ' ' || *Data == 0x05 || *Data == 0x96 || *Data == 0x97)) {
int c = *Data;
if (isprint(c)) // some CAMs send funny characters in their strings, let's just skip them
*p++ = c;
else if (c == 0x8A) // the character 0x8A is used as newline, so let's put a real '\n' in there
*p++ = '\n';
Length--; Length--;
Data++; Data++;
} }
*p = 0; char *s = MALLOC(char, Length + 1);
strncpy(s, (char *)Data, Length);
s[Length] = 0;
// The character 0x8A is used as newline, so let's put a real '\n' in there:
strreplace(s, 0x8A, '\n');
return s; return s;
} }
@ -118,14 +117,10 @@ class cCaPidReceiver : public cReceiver {
private: private:
int catVersion; int catVersion;
cVector<int> emmPids; cVector<int> emmPids;
uchar buffer[1024]; // CAT table length: 10 bit -> max. 1021 + 3 bytes uchar buffer[2048]; // 11 bit length, max. 2048 byte
uchar *bufp; uchar *bufp;
#define CAT_MAXPACKETS 6 // 6 * 184 = 1104 bytes for CAT table uchar mtdCatBuffer[TS_SIZE]; // TODO: handle multi packet CATs!
uchar mtdCatBuffer[CAT_MAXPACKETS][TS_SIZE]; // TODO: handle multi table CATs!
int mtdNumCatPackets;
int length; int length;
cMutex mutex;
bool handlingPid;
void AddEmmPid(int Pid); void AddEmmPid(int Pid);
void DelEmmPids(void); void DelEmmPids(void);
public: public:
@ -134,28 +129,14 @@ public:
virtual void Receive(const uchar *Data, int Length); virtual void Receive(const uchar *Data, int Length);
bool HasCaPids(void) const { return NumPids() - emmPids.Size() - 1 > 0; } bool HasCaPids(void) const { return NumPids() - emmPids.Size() - 1 > 0; }
void Reset(void) { DelEmmPids(); catVersion = -1; } void Reset(void) { DelEmmPids(); catVersion = -1; }
bool HandlingPid(void);
///< The cCaPidReceiver adds/deletes PIDs to/from the base class cReceiver,
///< which in turn does the same on the cDevice it is attached to. The cDevice
///< then sets the PIDs on the assigned cCamSlot, which can cause a deadlock on the
///< cCamSlot's mutex if a cReceiver is detached from the device at the same time.
///< Since these PIDs, however, are none that have to be decrypted,
///< it is not necessary to set them in the CAM. Therefore this function is
///< used in cCamSlot::SetPid() to detect this situation, and thus avoid the
///< deadlock.
}; };
cCaPidReceiver::cCaPidReceiver(void) cCaPidReceiver::cCaPidReceiver(void)
{ {
catVersion = -1; catVersion = -1;
bufp = NULL; bufp = NULL;
mtdNumCatPackets = 0;
length = 0; length = 0;
handlingPid = false;
cMutexLock MutexLock(&mutex);
handlingPid = true;
AddPid(CATPID); AddPid(CATPID);
handlingPid = false;
} }
void cCaPidReceiver::AddEmmPid(int Pid) void cCaPidReceiver::AddEmmPid(int Pid)
@ -165,20 +146,14 @@ void cCaPidReceiver::AddEmmPid(int Pid)
return; return;
} }
emmPids.Append(Pid); emmPids.Append(Pid);
cMutexLock MutexLock(&mutex);
handlingPid = true;
AddPid(Pid); AddPid(Pid);
handlingPid = false;
} }
void cCaPidReceiver::DelEmmPids(void) void cCaPidReceiver::DelEmmPids(void)
{ {
cMutexLock MutexLock(&mutex);
handlingPid = true;
for (int i = 0; i < emmPids.Size(); i++) for (int i = 0; i < emmPids.Size(); i++)
DelPid(emmPids[i]); DelPid(emmPids[i]);
emmPids.Clear(); emmPids.Clear();
handlingPid = false;
} }
void cCaPidReceiver::Receive(const uchar *Data, int Length) void cCaPidReceiver::Receive(const uchar *Data, int Length)
@ -188,38 +163,30 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length)
const uchar *p = NULL; const uchar *p = NULL;
if (TsPayloadStart(Data)) { if (TsPayloadStart(Data)) {
if (Data[5] == SI::TableIdCAT) { if (Data[5] == SI::TableIdCAT) {
if (bufp) { // incomplete multi-packet CAT length = (int(Data[6] & 0x03) << 8) | Data[7]; // section length
catVersion = -1;
bufp = NULL;
}
length = (int(Data[6] & 0x0F) << 8) | Data[7]; // section length (12 bit field)
if (length > 5) { if (length > 5) {
int v = (Data[10] & 0x3E) >> 1; // version number int v = (Data[10] & 0x3E) >> 1; // version number
if (v != catVersion) { if (v != catVersion) {
if (Data[11] == 0 && Data[12] == 0) { // section number, last section number if (Data[11] == 0 && Data[12] == 0) { // section number, last section number
length += 3; // with TableIdCAT -> Data[5] if (length > TS_SIZE - 8) {
if (length > TS_SIZE - 5) { if (MtdCamSlot)
int n = TS_SIZE - 5; esyslog("ERROR: need to implement multi packet CAT handling for MTD!");
memcpy(buffer, Data + 5, n); int n = TS_SIZE - 13;
memcpy(buffer, Data + 13, n);
bufp = buffer + n; bufp = buffer + n;
length -= n; length -= n + 5; // 5 = header
} }
else { else {
p = Data + 5; // no need to copy the data p = Data + 13; // no need to copy the data
} length -= 5; // header
if (MtdCamSlot) {
mtdNumCatPackets = 0;
memcpy(mtdCatBuffer[mtdNumCatPackets++], Data, TS_SIZE);
} }
} }
else else
dsyslog("multi table CAT section - unhandled!"); dsyslog("multi table CAT section - unhandled!");
catVersion = v; catVersion = v;
} }
else if (MtdCamSlot) { else if (MtdCamSlot)
for (int i = 0; i < mtdNumCatPackets; i++) MtdCamSlot->PutCat(mtdCatBuffer, TS_SIZE);
MtdCamSlot->PutCat(mtdCatBuffer[i], TS_SIZE);
}
} }
} }
} }
@ -233,73 +200,44 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length)
p = buffer; p = buffer;
length = bufp - buffer; length = bufp - buffer;
} }
if (MtdCamSlot)
memcpy(mtdCatBuffer[mtdNumCatPackets++], Data, TS_SIZE);
} }
else { else {
esyslog("ERROR: buffer overflow in cCaPidReceiver::Receive()"); esyslog("ERROR: buffer overflow in cCaPidReceiver::Receive()");
bufp = NULL; bufp = 0;
length = 0; length = 0;
} }
} }
if (p) { if (p) {
if (!SI::CRC32::crc32((const char *)p, length, 0xFFFFFFFF)) { // <TableIdCAT,....,crc32> DelEmmPids();
DelEmmPids(); for (int i = 0; i < length - 4; i++) { // -4 = checksum
for (int i = 8; i < length - 4; i++) { // -4 = checksum if (p[i] == 0x09) {
if (p[i] == 0x09) { int CaId = int(p[i + 2] << 8) | p[i + 3];
int CaId = int(p[i + 2] << 8) | p[i + 3]; int EmmPid = Peek13(p + i + 4);
int EmmPid = Peek13(p + i + 4); AddEmmPid(EmmPid);
AddEmmPid(EmmPid); if (MtdCamSlot)
if (MtdCamSlot) MtdMapPid(const_cast<uchar *>(p + i + 4), MtdCamSlot->MtdMapper());
MtdMapPid(const_cast<uchar *>(p + i + 4), MtdCamSlot->MtdMapper()); switch (CaId >> 8) {
switch (CaId >> 8) { case 0x01: for (int j = i + 7; j < p[i + 1] + 2; j += 4) {
case 0x01: for (int j = i + 7; j < i + p[i + 1] + 2; j += 4) { EmmPid = Peek13(p + j);
EmmPid = Peek13(p + j); AddEmmPid(EmmPid);
AddEmmPid(EmmPid); if (MtdCamSlot)
if (MtdCamSlot) MtdMapPid(const_cast<uchar *>(p + j), MtdCamSlot->MtdMapper());
MtdMapPid(const_cast<uchar *>(p + j), MtdCamSlot->MtdMapper()); }
} break;
break; }
} i += p[i + 1] + 2 - 1; // -1 to compensate for the loop increment
i += p[i + 1] + 2 - 1; // -1 to compensate for the loop increment
}
} }
if (MtdCamSlot) { }
// update crc32
uint32_t crc = SI::CRC32::crc32((const char *)p, length - 4, 0xFFFFFFFF); // <TableIdCAT....>[crc32]
uchar *c = const_cast<uchar *>(p + length - 4);
*c++ = crc >> 24;
*c++ = crc >> 16;
*c++ = crc >> 8;
*c++ = crc;
// modify CAT packets
const uchar *t = p;
for (int i = 0, j = 5; i < mtdNumCatPackets; i++, j = 4) {
int n = min(length, TS_SIZE - j);
memcpy(mtdCatBuffer[i] + j, t, n);
t += n;
length -= n;
MtdCamSlot->PutCat(mtdCatBuffer[i], TS_SIZE);
}
}
}
else {
esyslog("ERROR: wrong checksum in CAT");
catVersion = -1;
}
p = NULL; p = NULL;
bufp = NULL; bufp = 0;
length = 0; length = 0;
memcpy(mtdCatBuffer, Data, TS_SIZE);
if (MtdCamSlot)
MtdCamSlot->PutCat(mtdCatBuffer, TS_SIZE);
} }
} }
} }
bool cCaPidReceiver::HandlingPid(void)
{
cMutexLock MutexLock(&mutex);
return handlingPid;
}
// --- cCaActivationReceiver ------------------------------------------------- // --- cCaActivationReceiver -------------------------------------------------
// A receiver that is used to make the device stay on a given channel and // A receiver that is used to make the device stay on a given channel and
@ -340,7 +278,7 @@ void cCaActivationReceiver::Receive(const uchar *Data, int Length)
if (TsIsScrambled(Data)) if (TsIsScrambled(Data))
lastScrambledTime = Now; lastScrambledTime = Now;
else if (Now - lastScrambledTime > UNSCRAMBLE_TIME) { else if (Now - lastScrambledTime > UNSCRAMBLE_TIME) {
dsyslog("CAM %d: activated!", camSlot->MasterSlotNumber()); dsyslog("CAM %d: activated!", camSlot->SlotNumber());
Skins.QueueMessage(mtInfo, tr("CAM activated!")); Skins.QueueMessage(mtInfo, tr("CAM activated!"));
cDevice *d = Device(); cDevice *d = Device();
Detach(); Detach();
@ -352,137 +290,6 @@ void cCaActivationReceiver::Receive(const uchar *Data, int Length)
} }
} }
// --- cCamResponse ----------------------------------------------------------
// CAM Response Actions:
#define CRA_NONE 0
#define CRA_DISCARD -1
#define CRA_CONFIRM -2
#define CRA_SELECT -3
class cCamResponse : public cListObject {
private:
int camNumber;
char *text;
int action;
public:
cCamResponse(void);
~cCamResponse();
bool Parse(const char *s);
int Matches(int CamNumber, const char *Text) const;
};
cCamResponse::cCamResponse(void)
{
camNumber = -1;
text = NULL;
action = CRA_NONE;
}
cCamResponse::~cCamResponse()
{
free(text);
}
bool cCamResponse::Parse(const char *s)
{
// Number:
s = skipspace(s);
if (*s == '*') {
camNumber = 0; // all CAMs
s++;
}
else {
char *e;
camNumber = strtol(s, &e, 10);
if (e == s || camNumber <= 0)
return false;
s = e;
}
// Text:
s = skipspace(s);
char *t = const_cast<char *>(s); // might have to modify it
char *q = NULL; // holds a copy in case of backslashes
bool InQuotes = false;
while (*t) {
if (*t == '"') {
if (t == s) { // opening quotes
InQuotes = true;
s++;
}
else if (InQuotes) // closing quotes
break;
}
else if (*t == '\\') {
if (!q) { // need to make a copy in order to strip backslashes
q = strdup(s);
t = q + (t - s);
s = q;
}
memmove(t, t + 1, strlen(t));
}
else if (*t == ' ') {
if (!InQuotes)
break;
}
t++;
}
free(text); // just for safety
text = NULL;
if (t != s) {
text = strndup(s, t - s);
s = t + 1;
}
free(q);
if (!text)
return false;
// Action:
s = skipspace(s);
if (strcasecmp(s, "DISCARD") == 0) action = CRA_DISCARD;
else if (strcasecmp(s, "CONFIRM") == 0) action = CRA_CONFIRM;
else if (strcasecmp(s, "SELECT") == 0) action = CRA_SELECT;
else if (isnumber(s)) action = atoi(s);
else
return false;
return true;
}
int cCamResponse::Matches(int CamNumber, const char *Text) const
{
if (!camNumber || camNumber == CamNumber) {
if (strcmp(text, Text) == 0)
return action;
}
return CRA_NONE;
}
// --- cCamResponses --------------------------------------------------------
class cCamResponses : public cConfig<cCamResponse> {
public:
int GetMatch(int CamNumber, const char *Text) const;
};
int cCamResponses::GetMatch(int CamNumber, const char *Text) const
{
for (const cCamResponse *cr = First(); cr; cr = Next(cr)) {
int Action = cr->Matches(CamNumber, Text);
if (Action != CRA_NONE) {
dsyslog("CAM %d: auto response %4d to '%s'\n", CamNumber, Action, Text);
return Action;
}
}
return CRA_NONE;
}
cCamResponses CamResponses;
bool CamResponsesLoad(const char *FileName, bool AllowComments, bool MustExist)
{
return CamResponses.Load(FileName, AllowComments, MustExist);
}
// --- cTPDU ----------------------------------------------------------------- // --- cTPDU -----------------------------------------------------------------
#define MAX_TPDU_SIZE 4096 #define MAX_TPDU_SIZE 4096
@ -611,7 +418,6 @@ uint8_t cTPDU::Status(void)
class cCiTransportConnection { class cCiTransportConnection {
private: private:
enum eState { stIDLE, stCREATION, stACTIVE, stDELETION }; enum eState { stIDLE, stCREATION, stACTIVE, stDELETION };
cMutex mutex;
cCamSlot *camSlot; cCamSlot *camSlot;
uint8_t tcid; uint8_t tcid;
eState state; eState state;
@ -1103,9 +909,8 @@ void cCiCaPmt::MtdMapPids(cMtdMapper *MtdMapper)
#define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0) #define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0)
#define QUERY_WAIT_TIME 500 // ms to wait before sending a query #define QUERY_WAIT_TIME 1000 // ms to wait before sending a query
#define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query #define QUERY_REPLY_TIMEOUT 2000 // ms to wait for a reply to a query
#define QUERY_RETRIES 6 // max. number of retries to check if there is a reply to a query
class cCiConditionalAccessSupport : public cCiSession { class cCiConditionalAccessSupport : public cCiSession {
private: private:
@ -1114,7 +919,6 @@ private:
int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
bool repliesToQuery; bool repliesToQuery;
cTimeMs timer; cTimeMs timer;
int numRetries;
public: public:
cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc); cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc);
virtual void Process(int Length = 0, const uint8_t *Data = NULL); virtual void Process(int Length = 0, const uint8_t *Data = NULL);
@ -1133,7 +937,6 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(uint16_t SessionId, cCi
state = 0; // inactive state = 0; // inactive
caSystemIds[numCaSystemIds = 0] = 0; caSystemIds[numCaSystemIds = 0] = 0;
repliesToQuery = false; repliesToQuery = false;
numRetries = 0;
} }
void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data) void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
@ -1163,8 +966,7 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
caSystemIds[numCaSystemIds] = 0; caSystemIds[numCaSystemIds] = 0;
dbgprotocol("\n"); dbgprotocol("\n");
if (state == 1) { if (state == 1) {
timer.Set(0); timer.Set(QUERY_WAIT_TIME); // WORKAROUND: Alphacrypt 3.09 doesn't reply to QUERY immediately after reset
numRetries = QUERY_RETRIES;
state = 2; // got ca info state = 2; // got ca info
} }
dsyslog("CAM %d: system ids:%s", CamSlot()->SlotNumber(), *Ids ? *Ids : " none"); dsyslog("CAM %d: system ids:%s", CamSlot()->SlotNumber(), *Ids ? *Ids : " none");
@ -1173,12 +975,10 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
case AOT_CA_PMT_REPLY: { case AOT_CA_PMT_REPLY: {
dbgprotocol("Slot %d: <== Ca Pmt Reply (%d)", CamSlot()->SlotNumber(), SessionId()); dbgprotocol("Slot %d: <== Ca Pmt Reply (%d)", CamSlot()->SlotNumber(), SessionId());
if (!repliesToQuery) { if (!repliesToQuery) {
if (CamSlot()->IsMasterSlot()) dsyslog("CAM %d: replies to QUERY - multi channel decryption (MCD) possible", CamSlot()->SlotNumber());
dsyslog("CAM %d: replies to QUERY - multi channel decryption (MCD) possible", CamSlot()->SlotNumber());
repliesToQuery = true; repliesToQuery = true;
if (CamSlot()->MtdAvailable()) { if (CamSlot()->MtdAvailable()) {
if (CamSlot()->IsMasterSlot()) dsyslog("CAM %d: supports multi transponder decryption (MTD)", CamSlot()->SlotNumber());
dsyslog("CAM %d: supports multi transponder decryption (MTD)", CamSlot()->SlotNumber());
CamSlot()->MtdActivate(true); CamSlot()->MtdActivate(true);
} }
} }
@ -1239,18 +1039,15 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
SendData(AOT_CA_INFO_ENQ); SendData(AOT_CA_INFO_ENQ);
state = 1; // enquired ca info state = 1; // enquired ca info
} }
else if ((state == 2 || state == 3) && timer.TimedOut()) { else if (state == 2 && timer.TimedOut()) {
if (numRetries-- > 0) { cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL);
cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL); SendPMT(&CaPmt);
SendPMT(&CaPmt); timer.Set(QUERY_REPLY_TIMEOUT);
timer.Set(QUERY_WAIT_TIME); state = 3; // waiting for reply
state = 3; // waiting for reply }
} else if (state == 3 && timer.TimedOut()) {
else { dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber());
dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber()); state = 4; // normal operation
CamSlot()->MtdActivate(false);
state = 4; // normal operation
}
} }
} }
@ -1495,41 +1292,15 @@ void cCiMMI::Process(int Length, const uint8_t *Data)
if (l > 0) menu->titleText = GetText(l, &d); if (l > 0) menu->titleText = GetText(l, &d);
if (l > 0) menu->subTitleText = GetText(l, &d); if (l > 0) menu->subTitleText = GetText(l, &d);
if (l > 0) menu->bottomText = GetText(l, &d); if (l > 0) menu->bottomText = GetText(l, &d);
int Action = CRA_NONE;
int Select = -1;
int Item = 0;
while (l > 0) { while (l > 0) {
char *s = GetText(l, &d); char *s = GetText(l, &d);
if (s) { if (s) {
if (!menu->AddEntry(s)) if (!menu->AddEntry(s))
free(s); free(s);
else if (Action == CRA_NONE) {
Action = CamResponses.GetMatch(CamSlot()->SlotNumber(), s);
if (Action == CRA_SELECT)
Select = Item;
}
} }
else else
break; break;
Item++;
} }
if (Action != CRA_NONE) {
delete menu;
menu = NULL;
cCondWait::SleepMs(100);
if (Action == CRA_DISCARD) {
SendCloseMMI();
dsyslog("CAM %d: DISCARD", CamSlot()->SlotNumber());
}
else if (Action == CRA_CONFIRM) {
SendMenuAnswer(1);
dsyslog("CAM %d: CONFIRM", CamSlot()->SlotNumber());
}
else if (Action == CRA_SELECT) {
SendMenuAnswer(Select + 1);
dsyslog("CAM %d: SELECT %d", CamSlot()->SlotNumber(), Select + 1);
}
}
} }
} }
break; break;
@ -1548,19 +1319,6 @@ void cCiMMI::Process(int Length, const uint8_t *Data)
l--; l--;
// I really wonder why there is no text length field here... // I really wonder why there is no text length field here...
enquiry->text = CopyString(l, d); enquiry->text = CopyString(l, d);
int Action = CamResponses.GetMatch(CamSlot()->SlotNumber(), enquiry->text);
if (Action > CRA_NONE) {
char s[enquiry->expectedLength * 2];
snprintf(s, sizeof(s), "%d", Action);
if (int(strlen(s)) == enquiry->expectedLength) {
delete enquiry;
enquiry = NULL;
SendAnswer(s);
dsyslog("CAM %d: PIN", CamSlot()->SlotNumber());
}
else
esyslog("CAM %d: ERROR: unexpected PIN length %d, expected %d", CamSlot()->SlotNumber(), int(strlen(s)), enquiry->expectedLength);
}
} }
} }
break; break;
@ -1616,12 +1374,9 @@ bool cCiMMI::SendAnswer(const char *Text)
struct tAnswer { uint8_t id; char text[256]; };//XXX struct tAnswer { uint8_t id; char text[256]; };//XXX
tAnswer answer; tAnswer answer;
answer.id = Text ? AI_ANSWER : AI_CANCEL; answer.id = Text ? AI_ANSWER : AI_CANCEL;
int len = 0; if (Text)
if (Text) { strncpy(answer.text, Text, sizeof(answer.text));
len = min(sizeof(answer.text), strlen(Text)); SendData(AOT_ANSW, Text ? strlen(Text) + 1 : 1, (uint8_t *)&answer);
memcpy(answer.text, Text, len);
}
SendData(AOT_ANSW, len + 1, (uint8_t *)&answer);
return true; return true;
} }
@ -1694,7 +1449,6 @@ void cCiMenu::Abort(void)
cCiEnquiry::cCiEnquiry(cCiMMI *MMI) cCiEnquiry::cCiEnquiry(cCiMMI *MMI)
{ {
mmi = MMI; mmi = MMI;
mutex = NULL;
text = NULL; text = NULL;
blind = false; blind = false;
expectedLength = 0; expectedLength = 0;
@ -1836,7 +1590,6 @@ void cCiTransportConnection::SetTsPostProcessor(cCiSession *CiSession)
bool cCiTransportConnection::TsPostProcess(uint8_t *TsPacket) bool cCiTransportConnection::TsPostProcess(uint8_t *TsPacket)
{ {
cMutexLock MutexLock(&mutex);
if (tsPostProcessor) if (tsPostProcessor)
return tsPostProcessor->TsPostProcess(TsPacket); return tsPostProcessor->TsPostProcess(TsPacket);
return false; return false;
@ -2259,14 +2012,14 @@ bool cCamSlot::Assign(cDevice *Device, bool Query)
return false; return false;
} }
bool cCamSlot::Devices(cVector<int> &DeviceNumbers) bool cCamSlot::Devices(cVector<int> &CardIndexes)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
if (mtdHandler) if (mtdHandler)
return mtdHandler->Devices(DeviceNumbers); return mtdHandler->Devices(CardIndexes);
if (assignedDevice) if (assignedDevice)
DeviceNumbers.Append(assignedDevice->DeviceNumber()); CardIndexes.Append(assignedDevice->CardIndex());
return DeviceNumbers.Size() > 0; return CardIndexes.Size() > 0;
} }
void cCamSlot::NewConnection(void) void cCamSlot::NewConnection(void)
@ -2544,10 +2297,8 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M
if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids) > 0) { if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids) > 0) {
if (Active) if (Active)
caPidReceiver->AddPids(CaPids); caPidReceiver->AddPids(CaPids);
else { else
KeepSharedCaPids(p->programNumber, CaSystemIds, CaPids);
caPidReceiver->DelPids(CaPids); caPidReceiver->DelPids(CaPids);
}
} }
} }
if (RepliesToQuery()) if (RepliesToQuery())
@ -2563,43 +2314,6 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M
} }
} }
void cCamSlot::KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids)
{
int numPids = 0;
int *pCaPids = CaPids;
while (*pCaPids) {
numPids++;
pCaPids++;
}
if (numPids <= 0)
return;
int CaPids2[MAXRECEIVEPIDS + 1];
for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) {
if (p->Active()) {
if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids2) > 0) {
int *pCaPids2 = CaPids2;
while (*pCaPids2) {
pCaPids = CaPids;
while (*pCaPids) {
if (*pCaPids == *pCaPids2) {
dsyslog("CAM %d: keeping shared CA pid %d", SlotNumber(), *pCaPids);
// To remove *pCaPids from CaPids we overwrite it with the last valie in the list, and then strip the last value:
*pCaPids = CaPids[numPids - 1];
numPids--;
CaPids[numPids] = 0;
if (numPids <= 0)
return;
}
else
pCaPids++;
}
pCaPids2++;
}
}
}
}
}
void cCamSlot::SendCaPmts(cCiCaPmtList &CaPmtList) void cCamSlot::SendCaPmts(cCiCaPmtList &CaPmtList)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
@ -2696,8 +2410,6 @@ void cCamSlot::AddPid(int ProgramNumber, int Pid, int StreamType)
void cCamSlot::SetPid(int Pid, bool Active) void cCamSlot::SetPid(int Pid, bool Active)
{ {
if (caPidReceiver && caPidReceiver->HandlingPid())
return;
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) { for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) {
for (cCiCaPidData *q = p->pidList.First(); q; q = p->pidList.Next(q)) { for (cCiCaPidData *q = p->pidList.First(); q; q = p->pidList.Next(q)) {
@ -2781,13 +2493,9 @@ void cCamSlot::StartDecrypting(void)
void cCamSlot::StopDecrypting(void) void cCamSlot::StopDecrypting(void)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
if (mtdHandler) {
mtdHandler->StopDecrypting();
return;
}
if (caProgramList.Count()) { if (caProgramList.Count()) {
caProgramList.Clear(); caProgramList.Clear();
if (!dynamic_cast<cMtdCamSlot *>(this) || !MasterSlot()->IsDecrypting()) if (!dynamic_cast<cMtdCamSlot *>(this))
SendCaPmt(CPCI_NOT_SELECTED); SendCaPmt(CPCI_NOT_SELECTED);
} }
} }
@ -3076,8 +2784,6 @@ void cChannelCamRelations::Load(const char *FileName)
void cChannelCamRelations::Save(void) void cChannelCamRelations::Save(void)
{ {
if (!*fileName)
return;
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
struct stat st; struct stat st;
if (stat(fileName, &st) == 0) { if (stat(fileName, &st) == 0) {

15
ci.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.h 4.14 2019/05/28 14:58:08 kls Exp $ * $Id: ci.h 4.9 2017/05/18 09:05:46 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -254,7 +254,6 @@ private:
cList<cCiCaProgramData> caProgramList; cList<cCiCaProgramData> caProgramList;
bool mtdAvailable; bool mtdAvailable;
cMtdHandler *mtdHandler; cMtdHandler *mtdHandler;
void KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids);
void NewConnection(void); void NewConnection(void);
void DeleteAllConnections(void); void DeleteAllConnections(void);
void Process(cTPDU *TPDU = NULL); void Process(cTPDU *TPDU = NULL);
@ -305,7 +304,7 @@ public:
virtual ~cCamSlot(); virtual ~cCamSlot();
bool IsMasterSlot(void) { return !masterSlot; } bool IsMasterSlot(void) { return !masterSlot; }
///< Returns true if this CAM slot itself is a master slot (which means that ///< Returns true if this CAM slot itself is a master slot (which means that
///< it doesn't have a pointer to another CAM slot that's its master). ///< it doesn't have pointer to another CAM slot that's its master).
cCamSlot *MasterSlot(void) { return masterSlot ? masterSlot : this; } cCamSlot *MasterSlot(void) { return masterSlot ? masterSlot : this; }
///< Returns this CAM slot's master slot, or a pointer to itself if it is a ///< Returns this CAM slot's master slot, or a pointer to itself if it is a
///< master slot. ///< master slot.
@ -331,9 +330,9 @@ public:
///< class function. ///< class function.
cDevice *Device(void) { return assignedDevice; } cDevice *Device(void) { return assignedDevice; }
///< Returns the device this CAM slot is currently assigned to. ///< Returns the device this CAM slot is currently assigned to.
bool Devices(cVector<int> &DeviceNumbers); bool Devices(cVector<int> &CardIndexes);
///< Adds the numbers of any devices that currently use this CAM to ///< Adds the card indexes of any devices that currently use this CAM to
///< the given DeviceNumbers. This can be more than one in case of MTD. ///< the given CardIndexes. This can be more than one in case of MTD.
///< Returns true if the array is not empty. ///< Returns true if the array is not empty.
bool WantsTsData(void) const { return caPidReceiver != NULL; } bool WantsTsData(void) const { return caPidReceiver != NULL; }
///< Returns true if this CAM slot wants to receive the TS data through ///< Returns true if this CAM slot wants to receive the TS data through
@ -403,7 +402,7 @@ public:
///< call to AddPid()) to Active. A later call to StartDecrypting() will ///< call to AddPid()) to Active. A later call to StartDecrypting() will
///< send the full list of currently active CA_PMT entries to the CAM. ///< send the full list of currently active CA_PMT entries to the CAM.
virtual void AddChannel(const cChannel *Channel); virtual void AddChannel(const cChannel *Channel);
///< Adds all PIDs of the given Channel to the current list of PIDs. ///< Adds all PIDs if the given Channel to the current list of PIDs.
///< If the source or transponder of the channel are different than ///< If the source or transponder of the channel are different than
///< what was given in a previous call to AddChannel(), any previously ///< what was given in a previous call to AddChannel(), any previously
///< added PIDs will be cleared. ///< added PIDs will be cleared.
@ -530,6 +529,4 @@ public:
extern cChannelCamRelations ChannelCamRelations; extern cChannelCamRelations ChannelCamRelations;
bool CamResponsesLoad(const char *FileName, bool AllowComments = false, bool MustExist = false);
#endif //__CI_H #endif //__CI_H

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: config.c 5.1 2024/03/04 21:13:58 kls Exp $ * $Id: config.c 4.6 2017/05/21 10:25:26 kls Exp $
*/ */
#include "config.h" #include "config.h"
@ -409,8 +409,6 @@ cSetup::cSetup(void)
SubtitleBgTransparency = 0; SubtitleBgTransparency = 0;
EPGLanguages[0] = -1; EPGLanguages[0] = -1;
EPGScanTimeout = 5; EPGScanTimeout = 5;
EPGScanMaxChannel = 0;
EPGPauseAfterScan = 0;
EPGBugfixLevel = 3; EPGBugfixLevel = 3;
EPGLinger = 0; EPGLinger = 0;
SVDRPTimeout = 300; SVDRPTimeout = 300;
@ -434,7 +432,6 @@ cSetup::cSetup(void)
FoldersInTimerMenu = 1; FoldersInTimerMenu = 1;
AlwaysSortFoldersFirst = 1; AlwaysSortFoldersFirst = 1;
DefaultSortModeRec = rsmTime; DefaultSortModeRec = rsmTime;
RecSortingDirection = rsdAscending;
NumberKeysForChars = 1; NumberKeysForChars = 1;
ColorKey0 = 0; ColorKey0 = 0;
ColorKey1 = 1; ColorKey1 = 1;
@ -639,14 +636,12 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "SubtitleBgTransparency")) SubtitleBgTransparency = atoi(Value); else if (!strcasecmp(Name, "SubtitleBgTransparency")) SubtitleBgTransparency = atoi(Value);
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages); else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value); else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGScanMaxChannel")) EPGScanMaxChannel = atoi(Value);
else if (!strcasecmp(Name, "EPGPauseAfterScan")) EPGPauseAfterScan = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value); else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value); else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value); else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
else if (!strcasecmp(Name, "SVDRPPeering")) SVDRPPeering = atoi(Value); else if (!strcasecmp(Name, "SVDRPPeering")) SVDRPPeering = atoi(Value);
else if (!strcasecmp(Name, "SVDRPHostName")) { if (*Value) strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName)); } else if (!strcasecmp(Name, "SVDRPHostName")) { if (*Value) strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName)); }
else if (!strcasecmp(Name, "SVDRPDefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost)); else if (!strcasecmp(Name, "SVDRPdefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));
else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value); else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value);
else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value); else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value);
else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value); else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value);
@ -663,7 +658,6 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value); else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
else if (!strcasecmp(Name, "FoldersInTimerMenu")) FoldersInTimerMenu = atoi(Value); else if (!strcasecmp(Name, "FoldersInTimerMenu")) FoldersInTimerMenu = atoi(Value);
else if (!strcasecmp(Name, "AlwaysSortFoldersFirst")) AlwaysSortFoldersFirst = atoi(Value); else if (!strcasecmp(Name, "AlwaysSortFoldersFirst")) AlwaysSortFoldersFirst = atoi(Value);
else if (!strcasecmp(Name, "RecSortingDirection")) RecSortingDirection= atoi(Value);
else if (!strcasecmp(Name, "DefaultSortModeRec")) DefaultSortModeRec = atoi(Value); else if (!strcasecmp(Name, "DefaultSortModeRec")) DefaultSortModeRec = atoi(Value);
else if (!strcasecmp(Name, "NumberKeysForChars")) NumberKeysForChars = atoi(Value); else if (!strcasecmp(Name, "NumberKeysForChars")) NumberKeysForChars = atoi(Value);
else if (!strcasecmp(Name, "ColorKey0")) ColorKey0 = atoi(Value); else if (!strcasecmp(Name, "ColorKey0")) ColorKey0 = atoi(Value);
@ -773,8 +767,6 @@ bool cSetup::Save(void)
Store("SubtitleBgTransparency", SubtitleBgTransparency); Store("SubtitleBgTransparency", SubtitleBgTransparency);
StoreLanguages("EPGLanguages", EPGLanguages); StoreLanguages("EPGLanguages", EPGLanguages);
Store("EPGScanTimeout", EPGScanTimeout); Store("EPGScanTimeout", EPGScanTimeout);
Store("EPGScanMaxChannel", EPGScanMaxChannel);
Store("EPGPauseAfterScan", EPGPauseAfterScan);
Store("EPGBugfixLevel", EPGBugfixLevel); Store("EPGBugfixLevel", EPGBugfixLevel);
Store("EPGLinger", EPGLinger); Store("EPGLinger", EPGLinger);
Store("SVDRPTimeout", SVDRPTimeout); Store("SVDRPTimeout", SVDRPTimeout);
@ -797,7 +789,6 @@ bool cSetup::Save(void)
Store("RecordingDirs", RecordingDirs); Store("RecordingDirs", RecordingDirs);
Store("FoldersInTimerMenu", FoldersInTimerMenu); Store("FoldersInTimerMenu", FoldersInTimerMenu);
Store("AlwaysSortFoldersFirst", AlwaysSortFoldersFirst); Store("AlwaysSortFoldersFirst", AlwaysSortFoldersFirst);
Store("RecSortingDirection",RecSortingDirection);
Store("DefaultSortModeRec", DefaultSortModeRec); Store("DefaultSortModeRec", DefaultSortModeRec);
Store("NumberKeysForChars", NumberKeysForChars); Store("NumberKeysForChars", NumberKeysForChars);
Store("ColorKey0", ColorKey0); Store("ColorKey0", ColorKey0);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: config.h 5.26 2025/02/26 10:35:03 kls Exp $ * $Id: config.h 4.9 2017/04/29 13:33:13 kls Exp $
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
@ -22,21 +22,19 @@
// VDR's own version number: // VDR's own version number:
#define VDRVERSION "2.7.4" #define VDRVERSION "2.3.5"
#define VDRVERSNUM 20704 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 20305 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number: // The plugin API's version number:
#define APIVERSION "6" #define APIVERSION "2.3.5"
#define APIVERSNUM 30006 #define APIVERSNUM 20305 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches files by their APIVERSION, which // When loading plugins, VDR searches them by their APIVERSION, which
// is different from VDRVERSION. APIVERSION is a plain number, incremented // may be smaller than VDRVERSION in case there have been no changes to
// only when there are changes to the plugin API. This allows compiled // VDR header files since the last APIVERSION. This allows compiled
// plugins to work with newer versions of the core VDR as long as no // plugins to work with newer versions of the core VDR as long as no
// interfaces have changed. APIVERSNUM begins with "300.." for backwards // VDR header files have changed.
// compatibility and can be used in #if preprocessor statements to handle
// version dependent code.
#define MAXPRIORITY 99 #define MAXPRIORITY 99
#define MINPRIORITY (-MAXPRIORITY) #define MINPRIORITY (-MAXPRIORITY)
@ -48,13 +46,6 @@
#define TIMERMACRO_TITLE "TITLE" #define TIMERMACRO_TITLE "TITLE"
#define TIMERMACRO_EPISODE "EPISODE" #define TIMERMACRO_EPISODE "EPISODE"
#define TIMERMACRO_BEFORE "{<}"
#define TIMERMACRO_MATCH "{=}"
#define TIMERMACRO_AFTER "{>}"
#define TIMERPATTERN_AVOID "@"
#define TIMERPATTERN_BEGIN "^"
#define TIMERPATTERN_END "$"
#define MINOSDWIDTH 480 #define MINOSDWIDTH 480
#define MAXOSDWIDTH 1920 #define MAXOSDWIDTH 1920
@ -293,8 +284,6 @@ public:
int SubtitleOffset; int SubtitleOffset;
int SubtitleFgTransparency, SubtitleBgTransparency; int SubtitleFgTransparency, SubtitleBgTransparency;
int EPGLanguages[I18N_MAX_LANGUAGES + 1]; int EPGLanguages[I18N_MAX_LANGUAGES + 1];
int EPGScanMaxChannel;
int EPGPauseAfterScan;
int EPGScanTimeout; int EPGScanTimeout;
int EPGBugfixLevel; int EPGBugfixLevel;
int EPGLinger; int EPGLinger;
@ -317,7 +306,6 @@ public:
int FoldersInTimerMenu; int FoldersInTimerMenu;
int AlwaysSortFoldersFirst; int AlwaysSortFoldersFirst;
int DefaultSortModeRec; int DefaultSortModeRec;
int RecSortingDirection;
int NumberKeysForChars; int NumberKeysForChars;
int ColorKey0, ColorKey1, ColorKey2, ColorKey3; int ColorKey0, ColorKey1, ColorKey2, ColorKey3;
int VideoDisplayFormat; int VideoDisplayFormat;

View File

@ -4,11 +4,12 @@
* 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 5.4 2025/01/10 13:12:04 kls Exp $ * $Id: cutter.c 4.3 2017/05/21 09:45:06 kls Exp $
*/ */
#include "cutter.h" #include "cutter.h"
#include "menu.h" #include "menu.h"
#include "recording.h"
#include "remux.h" #include "remux.h"
#include "videodir.h" #include "videodir.h"
@ -231,10 +232,6 @@ private:
int numSequences; int numSequences;
off_t maxVideoFileSize; off_t maxVideoFileSize;
off_t fileSize; off_t fileSize;
int frameErrors;
time_t lastErrorHandling;
cString editedRecordingName;
cRecordingInfo *recordingInfo;
bool suspensionLogged; bool suspensionLogged;
int sequence; // cutting sequence int sequence; // cutting sequence
int delta; // time between two frames (PTS ticks) int delta; // time between two frames (PTS ticks)
@ -249,7 +246,7 @@ private:
cPatPmtParser patPmtParser; cPatPmtParser patPmtParser;
bool Throttled(void); bool Throttled(void);
bool SwitchFile(bool Force = false); bool SwitchFile(bool Force = false);
bool LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length, bool *Errors = NULL, bool *Missing = NULL); bool LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length);
bool FramesAreEqual(int Index1, int Index2); bool FramesAreEqual(int Index1, int Index2);
void GetPendingPackets(uchar *Buffer, int &Length, int Index); void GetPendingPackets(uchar *Buffer, int &Length, int Index);
// Gather all non-video TS packets from Index upward that either belong to // Gather all non-video TS packets from Index upward that either belong to
@ -257,16 +254,15 @@ private:
// and add them to the end of the given Data. // and add them to the end of the given Data.
bool FixFrame(uchar *Data, int &Length, bool Independent, int Index, bool CutIn, bool CutOut); bool FixFrame(uchar *Data, int &Length, bool Independent, int Index, bool CutIn, bool CutOut);
bool ProcessSequence(int LastEndIndex, int BeginIndex, int EndIndex, int NextBeginIndex); bool ProcessSequence(int LastEndIndex, int BeginIndex, int EndIndex, int NextBeginIndex);
void HandleErrors(bool Force = false);
protected: protected:
virtual void Action(void); virtual void Action(void);
public: public:
cCuttingThread(const char *FromFileName, const char *ToFileName, cRecordingInfo *RecordingInfo); cCuttingThread(const char *FromFileName, const char *ToFileName);
virtual ~cCuttingThread(); virtual ~cCuttingThread();
const char *Error(void) { return error; } const char *Error(void) { return error; }
}; };
cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName, cRecordingInfo *RecordingInfo) cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
:cThread("video cutting", true) :cThread("video cutting", true)
{ {
error = NULL; error = NULL;
@ -278,10 +274,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName,
framesPerSecond = Recording.FramesPerSecond(); framesPerSecond = Recording.FramesPerSecond();
suspensionLogged = false; suspensionLogged = false;
fileSize = 0; fileSize = 0;
frameErrors = 0;
lastErrorHandling = 0;
editedRecordingName = ToFileName;
recordingInfo = RecordingInfo;
sequence = 0; sequence = 0;
delta = int(round(PTSTICKS / framesPerSecond)); delta = int(round(PTSTICKS / framesPerSecond));
lastVidPts = -1; lastVidPts = -1;
@ -302,10 +294,6 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName,
maxVideoFileSize = MEGABYTE(Setup.MaxVideoFileSize); maxVideoFileSize = MEGABYTE(Setup.MaxVideoFileSize);
if (isPesRecording && maxVideoFileSize > MEGABYTE(MAXVIDEOFILESIZEPES)) if (isPesRecording && maxVideoFileSize > MEGABYTE(MAXVIDEOFILESIZEPES))
maxVideoFileSize = MEGABYTE(MAXVIDEOFILESIZEPES); maxVideoFileSize = MEGABYTE(MAXVIDEOFILESIZEPES);
if (fromIndex->GetErrors()->Size() > 0) {
recordingInfo->SetErrors(0); // the fromIndex has error indicators, so we reset the error count
recordingInfo->Write();
}
Start(); Start();
} }
else else
@ -340,11 +328,11 @@ bool cCuttingThread::Throttled(void)
return false; return false;
} }
bool cCuttingThread::LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length, bool *Errors, bool *Missing) bool cCuttingThread::LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length)
{ {
uint16_t FileNumber; uint16_t FileNumber;
off_t FileOffset; off_t FileOffset;
if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length, Errors, Missing)) { if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length)) {
fromFile = fromFileName->SetOffset(FileNumber, FileOffset); fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
if (fromFile) { if (fromFile) {
fromFile->SetReadAhead(MEGABYTE(20)); fromFile->SetReadAhead(MEGABYTE(20));
@ -567,9 +555,7 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
for (int Index = BeginIndex; Running() && Index < EndIndex; Index++) { for (int Index = BeginIndex; Running() && Index < EndIndex; Index++) {
bool Independent; bool Independent;
int Length; int Length;
bool Errors; if (LoadFrame(Index, Buffer, Independent, Length)) {
bool Missing;
if (LoadFrame(Index, Buffer, Independent, Length, &Errors, &Missing)) {
// Make sure there is enough disk space: // Make sure there is enough disk space:
AssertFreeDiskSpace(-1); AssertFreeDiskSpace(-1);
bool CutIn = !SeamlessBegin && Index == BeginIndex; bool CutIn = !SeamlessBegin && Index == BeginIndex;
@ -586,12 +572,10 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
return false; return false;
} }
// Write index: // Write index:
if (!DeletedFrame && !toIndex->Write(Independent, toFileName->Number(), fileSize, Errors, Missing)) { if (!DeletedFrame && !toIndex->Write(Independent, toFileName->Number(), fileSize)) {
error = "toIndex"; error = "toIndex";
return false; return false;
} }
frameErrors += Errors + Missing;
HandleErrors();
// Write data: // Write data:
if (toFile->Write(Buffer, Length) < 0) { if (toFile->Write(Buffer, Length) < 0) {
error = "safe_write"; error = "safe_write";
@ -612,27 +596,6 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
return true; return true;
} }
#define ERROR_HANDLING_DELTA 1 // seconds between handling errors
void cCuttingThread::HandleErrors(bool Force)
{
if (Force || time(NULL) - lastErrorHandling >= ERROR_HANDLING_DELTA) {
if (frameErrors > recordingInfo->Errors()) {
recordingInfo->SetErrors(frameErrors);
recordingInfo->Write();
Force = true;
}
if (Force) {
cStateKey StateKey;
if (cRecordings *Recordings = cRecordings::GetRecordingsWrite(StateKey, 1)) {
Recordings->UpdateByName(editedRecordingName);
StateKey.Remove();
}
}
lastErrorHandling = time(NULL);
}
}
void cCuttingThread::Action(void) void cCuttingThread::Action(void)
{ {
if (cMark *BeginMark = fromMarks.GetNextBegin()) { if (cMark *BeginMark = fromMarks.GetNextBegin()) {
@ -641,7 +604,6 @@ void cCuttingThread::Action(void)
if (!fromFile || !toFile) if (!fromFile || !toFile)
return; return;
int LastEndIndex = -1; int LastEndIndex = -1;
HandleErrors(true); // to make sure an initially reset error count is displayed correctly
while (BeginMark && Running()) { while (BeginMark && Running()) {
// Suspend cutting if we have severe throughput problems: // Suspend cutting if we have severe throughput problems:
if (Throttled()) { if (Throttled()) {
@ -672,7 +634,6 @@ void cCuttingThread::Action(void)
} }
} }
} }
HandleErrors(true);
} }
else else
esyslog("no editing marks found!"); esyslog("no editing marks found!");
@ -681,7 +642,6 @@ void cCuttingThread::Action(void)
// --- cCutter --------------------------------------------------------------- // --- cCutter ---------------------------------------------------------------
cCutter::cCutter(const char *FileName) cCutter::cCutter(const char *FileName)
:recordingInfo(FileName)
{ {
cuttingThread = NULL; cuttingThread = NULL;
error = false; error = false;
@ -716,11 +676,10 @@ bool cCutter::Start(void)
if (strcmp(originalVersionName, editedVersionName) != 0) { // names must be different! if (strcmp(originalVersionName, editedVersionName) != 0) { // names must be different!
cRecordingUserCommand::InvokeCommand(RUC_EDITINGRECORDING, editedVersionName, originalVersionName); cRecordingUserCommand::InvokeCommand(RUC_EDITINGRECORDING, editedVersionName, originalVersionName);
if (cVideoDirectory::RemoveVideoFile(editedVersionName) && MakeDirs(editedVersionName, true)) { if (cVideoDirectory::RemoveVideoFile(editedVersionName) && MakeDirs(editedVersionName, true)) {
recordingInfo.Read(); Recording.WriteInfo(editedVersionName);
recordingInfo.SetFileName(editedVersionName); LOCK_RECORDINGS_WRITE;
recordingInfo.Write(); Recordings->AddByName(editedVersionName, false);
SetRecordingTimerId(editedVersionName, cString::sprintf("%d@%s", 0, Setup.SVDRPHostName)); cuttingThread = new cCuttingThread(originalVersionName, editedVersionName);
cuttingThread = new cCuttingThread(originalVersionName, editedVersionName, &recordingInfo);
return true; return true;
} }
} }
@ -736,7 +695,6 @@ void cCutter::Stop(void)
const char *Error = cuttingThread ? cuttingThread->Error() : NULL; const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
delete cuttingThread; delete cuttingThread;
cuttingThread = NULL; cuttingThread = NULL;
SetRecordingTimerId(editedVersionName, NULL);
if ((Interrupted || Error) && *editedVersionName) { if ((Interrupted || Error) && *editedVersionName) {
if (Interrupted) if (Interrupted)
isyslog("editing process has been interrupted"); isyslog("editing process has been interrupted");
@ -744,6 +702,9 @@ void cCutter::Stop(void)
esyslog("ERROR: '%s' during editing process", Error); esyslog("ERROR: '%s' during editing process", Error);
if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), editedVersionName) == 0) if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), editedVersionName) == 0)
cControl::Shutdown(); cControl::Shutdown();
cVideoDirectory::RemoveVideoFile(editedVersionName);
LOCK_RECORDINGS_WRITE;
Recordings->DelByName(editedVersionName);
} }
} }

View File

@ -4,13 +4,12 @@
* 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.h 5.1 2024/09/19 20:21:58 kls Exp $ * $Id: cutter.h 3.1 2013/10/05 11:34:55 kls Exp $
*/ */
#ifndef __CUTTER_H #ifndef __CUTTER_H
#define __CUTTER_H #define __CUTTER_H
#include "recording.h"
#include "thread.h" #include "thread.h"
#include "tools.h" #include "tools.h"
@ -20,7 +19,6 @@ class cCutter {
private: private:
cString originalVersionName; cString originalVersionName;
cString editedVersionName; cString editedVersionName;
cRecordingInfo recordingInfo;
cCuttingThread *cuttingThread; cCuttingThread *cuttingThread;
bool error; bool error;
public: public:

216
device.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 5.14 2024/07/06 11:19:21 kls Exp $ * $Id: device.c 4.22 2017/05/18 09:27:55 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -58,11 +58,6 @@ bool cDeviceHook::DeviceProvidesTransponder(const cDevice *Device, const cChanne
return true; return true;
} }
bool cDeviceHook::DeviceProvidesEIT(const cDevice *Device) const
{
return true;
}
// --- cDevice --------------------------------------------------------------- // --- cDevice ---------------------------------------------------------------
// The minimum number of unknown PS1 packets to consider this a "pre 1.3.19 private stream": // The minimum number of unknown PS1 packets to consider this a "pre 1.3.19 private stream":
@ -80,9 +75,9 @@ cDevice::cDevice(void)
:patPmtParser(true) :patPmtParser(true)
{ {
cardIndex = nextCardIndex++; cardIndex = nextCardIndex++;
dsyslog("new device number %d (card index %d)", numDevices + 1, CardIndex() + 1); dsyslog("new device number %d", CardIndex() + 1);
SetDescription("device %d receiver", numDevices + 1); SetDescription("device %d receiver", CardIndex() + 1);
mute = false; mute = false;
volume = Setup.CurrentVolume; volume = Setup.CurrentVolume;
@ -95,9 +90,7 @@ cDevice::cDevice(void)
camSlot = NULL; camSlot = NULL;
occupiedFrom = 0;
occupiedTimeout = 0; occupiedTimeout = 0;
occupiedPriority = MINPRIORITY;
player = NULL; player = NULL;
isPlayingVideo = false; isPlayingVideo = false;
@ -127,7 +120,6 @@ cDevice::~cDevice()
delete dvbSubtitleConverter; delete dvbSubtitleConverter;
if (this == primaryDevice) if (this == primaryDevice)
primaryDevice = NULL; primaryDevice = NULL;
Cancel(3);
} }
bool cDevice::WaitForAllDevicesReady(int Timeout) bool cDevice::WaitForAllDevicesReady(int Timeout)
@ -202,7 +194,6 @@ bool cDevice::SetPrimaryDevice(int n)
primaryDevice->MakePrimaryDevice(true); primaryDevice->MakePrimaryDevice(true);
primaryDevice->SetVideoFormat(Setup.VideoFormat); primaryDevice->SetVideoFormat(Setup.VideoFormat);
primaryDevice->SetVolumeDevice(Setup.CurrentVolume); primaryDevice->SetVolumeDevice(Setup.CurrentVolume);
Setup.PrimaryDVB = n + 1;
return true; return true;
} }
esyslog("ERROR: invalid primary device number: %d", n + 1); esyslog("ERROR: invalid primary device number: %d", n + 1);
@ -237,11 +228,11 @@ static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device)
int MaxNumProvidedSystems = (1 << AvailableBits) - 1; int MaxNumProvidedSystems = (1 << AvailableBits) - 1;
int NumProvidedSystems = Device->NumProvidedSystems(); int NumProvidedSystems = Device->NumProvidedSystems();
if (NumProvidedSystems > MaxNumProvidedSystems) { if (NumProvidedSystems > MaxNumProvidedSystems) {
esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->DeviceNumber() + 1, NumProvidedSystems, MaxNumProvidedSystems); esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
NumProvidedSystems = MaxNumProvidedSystems; NumProvidedSystems = MaxNumProvidedSystems;
} }
else if (NumProvidedSystems <= 0) { else if (NumProvidedSystems <= 0) {
esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->DeviceNumber() + 1, NumProvidedSystems); esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems);
NumProvidedSystems = 1; NumProvidedSystems = 1;
} }
return NumProvidedSystems; return NumProvidedSystems;
@ -251,7 +242,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
{ {
// Collect the current priorities of all CAM slots that can decrypt the channel: // Collect the current priorities of all CAM slots that can decrypt the channel:
int NumCamSlots = CamSlots.Count(); int NumCamSlots = CamSlots.Count();
int SlotPriority[NumCamSlots + 1]; // +1 to avoid a zero sized array in case there are no CAM slots int SlotPriority[NumCamSlots];
int NumUsableSlots = 0; int NumUsableSlots = 0;
bool InternalCamNeeded = false; bool InternalCamNeeded = false;
if (Channel->Ca() >= CA_ENCRYPTED_MIN) { if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
@ -279,19 +270,15 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
continue; // there is no CAM available in this slot continue; // there is no CAM available in this slot
for (int i = 0; i < numDevices; i++) { for (int i = 0; i < numDevices; i++) {
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->DeviceNumber() + 1) if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
continue; // a specific card was requested, but not this one continue; // a specific card was requested, but not this one
bool HasInternalCam = device[i]->HasInternalCam(); bool HasInternalCam = device[i]->HasInternalCam();
if (InternalCamNeeded && !HasInternalCam) if (InternalCamNeeded && !HasInternalCam)
continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs
if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(device[i], true)) if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(device[i], true))
continue; // CAM slot can't be used with this device continue; // CAM slot can't be used with this device
bool ndr = false; bool ndr;
bool TunedToTransponder = device[i]->IsTunedToTransponder(Channel); if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job
if (TunedToTransponder || device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job
bool OccupiedOtherTransponder = !TunedToTransponder && device[i]->Occupied();
if (OccupiedOtherTransponder)
ndr = true;
if (NumUsableSlots && !HasInternalCam) { if (NumUsableSlots && !HasInternalCam) {
if (cCamSlot *csi = device[i]->CamSlot()) { if (cCamSlot *csi = device[i]->CamSlot()) {
cCamSlot *csj = CamSlots.Get(j); cCamSlot *csj = CamSlots.Get(j);
@ -309,10 +296,10 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
imp <<= 1; imp |= (LiveView && NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlots.Get(j)->MasterSlotNumber()) || ndr : 0; // prefer CAMs that are known to decrypt this channel for live viewing, if we don't need to detach existing receivers imp <<= 1; imp |= (LiveView && NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlots.Get(j)->MasterSlotNumber()) || ndr : 0; // prefer CAMs that are known to decrypt this channel for live viewing, if we don't need to detach existing receivers
imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers
imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
imp <<= 1; imp |= device[i]->Receiving() || OccupiedOtherTransponder; // avoid devices that are receiving imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving
imp <<= 5; imp |= GetClippedNumProvidedSystems(5, device[i]) - 1; // avoid cards which support multiple delivery systems imp <<= 4; imp |= GetClippedNumProvidedSystems(4, device[i]) - 1; // avoid cards which support multiple delivery systems
imp <<= 8; imp |= device[i]->Priority() - IDLEPRIORITY; // use the device with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
imp <<= 8; imp |= device[i]->Priority() - IDLEPRIORITY; // use the device with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
imp <<= 8; imp |= ((NumUsableSlots && !HasInternalCam) ? SlotPriority[j] : IDLEPRIORITY) - IDLEPRIORITY;// use the CAM slot with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used) imp <<= 8; imp |= ((NumUsableSlots && !HasInternalCam) ? SlotPriority[j] : IDLEPRIORITY) - IDLEPRIORITY;// use the CAM slot with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers
imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels
@ -327,7 +314,6 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (NumUsableSlots && !HasInternalCam) if (NumUsableSlots && !HasInternalCam)
s = CamSlots.Get(j); s = CamSlots.Get(j);
} }
//dsyslog("device %d provides channel %d prio %d ndr %d imp %.8X", device[i]->DeviceNumber() + 1, Channel->Number(), Priority, ndr, imp);
} }
} }
if (!NumUsableSlots) if (!NumUsableSlots)
@ -433,9 +419,8 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
return d; // if any device is tuned to the transponder, we're done return d; // if any device is tuned to the transponder, we're done
if (d->ProvidesTransponder(Channel)) { if (d->ProvidesTransponder(Channel)) {
if (d->MaySwitchTransponder(Channel)) if (d->MaySwitchTransponder(Channel))
return d; // this device may switch to the transponder without disturbing any receiver or live view Device = d; // this device may switch to the transponder without disturbing any receiver or live view
else if (!d->Occupied(Priority) && !d->IsBonded() && d->Priority(true) < LIVEPRIORITY) { // MaySwitchTransponder() implicitly calls Occupied() else if (!d->Occupied() && d->MaySwitchTransponder(Channel)) { // MaySwitchTransponder() implicitly calls Occupied()
// we select only devices with priority < LIVEPRIORITY, so device can be switched without impact on recordings or live viewing
if (d->Priority() < Priority && (!Device || d->Priority() < Device->Priority())) if (d->Priority() < Priority && (!Device || d->Priority() < Device->Priority()))
Device = d; // use this one only if no other with less impact can be found Device = d; // use this one only if no other with less impact can be found
} }
@ -445,12 +430,6 @@ cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority)
return Device; return Device;
} }
void cDevice::ReleaseCamSlot(void)
{
if (camSlot && !camSlot->IsDecrypting() && !camSlot->IsActivating())
camSlot->Assign(NULL);
}
bool cDevice::HasCi(void) bool cDevice::HasCi(void)
{ {
return false; return false;
@ -544,7 +523,7 @@ void cDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
PixelAspect = 1.0; PixelAspect = 1.0;
} }
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", DeviceNumber() + 1, s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); } //#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", CardIndex(), s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); }
#define PRINTPIDS(s) #define PRINTPIDS(s)
bool cDevice::HasPid(int Pid) const bool cDevice::HasPid(int Pid) const
@ -579,7 +558,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
// It's a special PID that may have to be switched into "tap" mode // It's a special PID that may have to be switched into "tap" mode
PRINTPIDS("A"); PRINTPIDS("A");
if (!SetPid(&pidHandles[n], n, true)) { if (!SetPid(&pidHandles[n], n, true)) {
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1); esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
if (PidType <= ptTeletext) if (PidType <= ptTeletext)
DetachAll(Pid); DetachAll(Pid);
DelPid(Pid, PidType); DelPid(Pid, PidType);
@ -600,7 +579,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
n = a; n = a;
} }
else { else {
esyslog("ERROR: no free slot for PID %d on device %d", Pid, DeviceNumber() + 1); esyslog("ERROR: no free slot for PID %d on device %d", Pid, CardIndex() + 1);
return false; return false;
} }
if (n >= 0) { if (n >= 0) {
@ -609,7 +588,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
pidHandles[n].used = 1; pidHandles[n].used = 1;
PRINTPIDS("C"); PRINTPIDS("C");
if (!SetPid(&pidHandles[n], n, true)) { if (!SetPid(&pidHandles[n], n, true)) {
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1); esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
if (PidType <= ptTeletext) if (PidType <= ptTeletext)
DetachAll(Pid); DetachAll(Pid);
DelPid(Pid, PidType); DelPid(Pid, PidType);
@ -681,11 +660,11 @@ void cDevice::StartSectionHandler(void)
void cDevice::StopSectionHandler(void) void cDevice::StopSectionHandler(void)
{ {
if (sectionHandler) { if (sectionHandler) {
delete sectionHandler; // automatically detaches filters
delete nitFilter; delete nitFilter;
delete sdtFilter; delete sdtFilter;
delete patFilter; delete patFilter;
delete eitFilter; delete eitFilter;
delete sectionHandler;
nitFilter = NULL; nitFilter = NULL;
sdtFilter = NULL; sdtFilter = NULL;
patFilter = NULL; patFilter = NULL;
@ -737,17 +716,6 @@ bool cDevice::DeviceHooksProvidesTransponder(const cChannel *Channel) const
return true; return true;
} }
bool cDevice::DeviceHooksProvidesEIT(void) const
{
cDeviceHook *Hook = deviceHooks.First();
while (Hook) {
if (!Hook->DeviceProvidesEIT(this))
return false;
Hook = deviceHooks.Next(Hook);
}
return true;
}
bool cDevice::ProvidesTransponder(const cChannel *Channel) const bool cDevice::ProvidesTransponder(const cChannel *Channel) const
{ {
return false; return false;
@ -809,17 +777,7 @@ bool cDevice::IsTunedToTransponder(const cChannel *Channel) const
bool cDevice::MaySwitchTransponder(const cChannel *Channel) const bool cDevice::MaySwitchTransponder(const cChannel *Channel) const
{ {
return !Occupied() && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid); return time(NULL) > occupiedTimeout && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid);
}
void cDevice::SetPowerSaveMode(bool On)
{
}
void cDevice::SetPowerSaveIfUnused(void)
{
if (!Occupied() && !Receiving() && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid))
SetPowerSaveMode(true);
} }
bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
@ -827,14 +785,13 @@ bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
if (LiveView) { if (LiveView) {
isyslog("switching to channel %d %s (%s)", Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name()); isyslog("switching to channel %d %s (%s)", Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
// and, if decrypted, this removes the now superfluous PIDs from the CAM, too
} }
for (int i = 3; i--;) { for (int i = 3; i--;) {
switch (SetChannel(Channel, LiveView)) { switch (SetChannel(Channel, LiveView)) {
case scrOk: return true; case scrOk: return true;
case scrNotAvailable: Skins.QueueMessage(mtInfo, tr("Channel not available!")); case scrNotAvailable: Skins.Message(mtInfo, tr("Channel not available!"));
return false; return false;
case scrNoTransfer: Skins.QueueMessage(mtError, tr("Can't start Transfer Mode!")); case scrNoTransfer: Skins.Message(mtError, tr("Can't start Transfer Mode!"));
return false; return false;
case scrFailed: break; // loop will retry case scrFailed: break; // loop will retry
default: esyslog("ERROR: invalid return value from SetChannel"); default: esyslog("ERROR: invalid return value from SetChannel");
@ -850,7 +807,6 @@ bool cDevice::SwitchChannel(int Direction)
Direction = sgn(Direction); Direction = sgn(Direction);
if (Direction) { if (Direction) {
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
// and, if decrypted, this removes the now superfluous PIDs from the CAM, too
int n = CurrentChannel() + Direction; int n = CurrentChannel() + Direction;
int first = n; int first = n;
LOCK_CHANNELS_READ; LOCK_CHANNELS_READ;
@ -871,30 +827,23 @@ bool cDevice::SwitchChannel(int Direction)
result = true; result = true;
} }
else if (n != first) else if (n != first)
Skins.QueueMessage(mtError, tr("Channel not available!")); Skins.Message(mtError, tr("Channel not available!"));
} }
return result; return result;
} }
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
{ {
cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN and HasProgramme() cMutexLock MutexLock(&mutexReceiver); // to avoid a race between SVDRP CHAN and HasProgramme()
cStatus::MsgChannelSwitch(this, 0, LiveView); cStatus::MsgChannelSwitch(this, 0, LiveView);
if (LiveView) { if (LiveView) {
if (IsPrimaryDevice() && !Replaying() && !Transferring()) { // this is only for FF DVB cards!
LOCK_CHANNELS_READ;
if (const cChannel *ch = Channels->GetByNumber(currentChannel)) {
if (patFilter)
patFilter->Release(ch->Sid());
}
}
StopReplay(); StopReplay();
DELETENULL(liveSubtitle); DELETENULL(liveSubtitle);
DELETENULL(dvbSubtitleConverter); DELETENULL(dvbSubtitleConverter);
} }
cDevice *Device = (LiveView && IsPrimaryDevice(false)) ? GetDevice(Channel, LIVEPRIORITY, true) : this; cDevice *Device = (LiveView && IsPrimaryDevice()) ? GetDevice(Channel, LIVEPRIORITY, true) : this;
bool NeedsTransferMode = LiveView && Device != PrimaryDevice(); bool NeedsTransferMode = LiveView && Device != PrimaryDevice();
// If the CAM slot wants the TS data, we need to switch to Transfer Mode: // If the CAM slot wants the TS data, we need to switch to Transfer Mode:
@ -926,10 +875,11 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
// channel to it, for possible later decryption: // channel to it, for possible later decryption:
if (camSlot) if (camSlot)
camSlot->AddChannel(Channel); camSlot->AddChannel(Channel);
SetPowerSaveMode(false);
if (SetChannelDevice(Channel, LiveView)) { if (SetChannelDevice(Channel, LiveView)) {
// Start section handling: // Start section handling:
if (sectionHandler) { if (sectionHandler) {
if (patFilter)
patFilter->Trigger(Channel->Sid());
sectionHandler->SetChannel(Channel); sectionHandler->SetChannel(Channel);
sectionHandler->SetStatus(true); sectionHandler->SetStatus(true);
} }
@ -942,26 +892,21 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
} }
if (Result == scrOk) { if (Result == scrOk) {
if (LiveView) { if (LiveView && IsPrimaryDevice()) {
if (IsPrimaryDevice(false)) currentChannel = Channel->Number();
currentChannel = Channel->Number(); // Set the available audio tracks:
if (IsPrimaryDevice()) { ClrAvailableTracks();
if (patFilter) // this is only for FF DVB cards! for (int i = 0; i < MAXAPIDS; i++)
patFilter->Request(Channel->Sid()); SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
// Set the available audio tracks: if (Setup.UseDolbyDigital) {
ClrAvailableTracks(); for (int i = 0; i < MAXDPIDS; i++)
for (int i = 0; i < MAXAPIDS; i++) SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
if (Setup.UseDolbyDigital) {
for (int i = 0; i < MAXDPIDS; i++)
SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
}
for (int i = 0; i < MAXSPIDS; i++)
SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i));
if (!NeedsTransferMode)
EnsureAudioTrack(true);
EnsureSubtitleTrack();
} }
for (int i = 0; i < MAXSPIDS; i++)
SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i));
if (!NeedsTransferMode)
EnsureAudioTrack(true);
EnsureSubtitleTrack();
} }
cStatus::MsgChannelSwitch(this, Channel->Number(), LiveView); // only report status if channel switch successful cStatus::MsgChannelSwitch(this, Channel->Number(), LiveView); // only report status if channel switch successful
} }
@ -973,34 +918,21 @@ void cDevice::ForceTransferMode(void)
{ {
if (!cTransferControl::ReceiverDevice()) { if (!cTransferControl::ReceiverDevice()) {
LOCK_CHANNELS_READ; LOCK_CHANNELS_READ;
if (const cChannel *Channel = Channels->GetByNumber(CurrentChannel())) { if (const cChannel *Channel = Channels->GetByNumber(CurrentChannel()))
SetPowerSaveMode(false);
SetChannelDevice(Channel, false); // this implicitly starts Transfer Mode SetChannelDevice(Channel, false); // this implicitly starts Transfer Mode
}
} }
} }
int cDevice::Occupied(int Priority) const int cDevice::Occupied(void) const
{ {
if (Priority > occupiedPriority)
return 0;
int Seconds = occupiedTimeout - time(NULL); int Seconds = occupiedTimeout - time(NULL);
return Seconds > 0 ? Seconds : 0; return Seconds > 0 ? Seconds : 0;
} }
void cDevice::SetOccupied(int Seconds, int Priority, time_t From) void cDevice::SetOccupied(int Seconds)
{ {
if (Seconds < 0) if (Seconds >= 0)
return; occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
if (From == 0)
From = time(NULL);
if (From == occupiedFrom)
occupiedPriority = max(Priority, occupiedPriority);
else {
occupiedPriority = Priority;
occupiedFrom = From;
}
occupiedTimeout = From + min(Seconds, MAXOCCUPIEDTIMEOUT);
} }
bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
@ -1015,7 +947,7 @@ bool cDevice::HasLock(int TimeoutMs) const
bool cDevice::HasProgramme(void) const bool cDevice::HasProgramme(void) const
{ {
cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN and HasProgramme() cMutexLock MutexLock(&mutexReceiver); // to avoid a race between SVDRP CHAN and HasProgramme()
return Replaying() || pidHandles[ptAudio].pid || pidHandles[ptVideo].pid; return Replaying() || pidHandles[ptAudio].pid || pidHandles[ptVideo].pid;
} }
@ -1629,6 +1561,7 @@ int cDevice::PlayTsSubtitle(const uchar *Data, int Length)
return Length; return Length;
} }
//TODO detect and report continuity errors?
int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
{ {
int Played = 0; int Played = 0;
@ -1692,13 +1625,11 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
return Played; return Played;
} }
int cDevice::Priority(bool IgnoreOccupied) const int cDevice::Priority(void) const
{ {
int priority = IDLEPRIORITY; int priority = IDLEPRIORITY;
if (IsPrimaryDevice() && !Replaying() && HasProgramme()) if (IsPrimaryDevice() && !Replaying() && HasProgramme())
priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing priority = TRANSFERPRIORITY; // we use the same value here, no matter whether it's actual Transfer Mode or real live viewing
if (!IgnoreOccupied && time(NULL) <= occupiedTimeout && occupiedPriority > priority)
priority = occupiedPriority - 1; // so timers with occupiedPriority can start
cMutexLock MutexLock(&mutexReceiver); cMutexLock MutexLock(&mutexReceiver);
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i]) if (receiver[i])
@ -1742,7 +1673,6 @@ void cDevice::Action(void)
int Pid = TsPid(b); int Pid = TsPid(b);
bool IsScrambled = TsIsScrambled(b); bool IsScrambled = TsIsScrambled(b);
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
cMutexLock MutexLock(&mutexReceiver);
cReceiver *Receiver = receiver[i]; cReceiver *Receiver = receiver[i];
if (Receiver && Receiver->WantsPid(Pid)) { if (Receiver && Receiver->WantsPid(Pid)) {
Receiver->Receive(b, TS_SIZE); Receiver->Receive(b, TS_SIZE);
@ -1823,7 +1753,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
#ifdef WAIT_FOR_TUNER_LOCK #ifdef WAIT_FOR_TUNER_LOCK
#define TUNER_LOCK_TIMEOUT 5000 // ms #define TUNER_LOCK_TIMEOUT 5000 // ms
if (!HasLock(TUNER_LOCK_TIMEOUT)) { if (!HasLock(TUNER_LOCK_TIMEOUT)) {
esyslog("ERROR: device %d has no lock, can't attach receiver!", DeviceNumber() + 1); esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1);
return false; return false;
} }
#endif #endif
@ -1838,8 +1768,10 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
} }
} }
Receiver->Activate(true); Receiver->Activate(true);
Lock();
Receiver->device = this; Receiver->device = this;
receiver[i] = Receiver; receiver[i] = Receiver;
Unlock();
if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (camSlot->WantsTsData()) { if (camSlot->WantsTsData()) {
@ -1851,13 +1783,11 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT; Receiver->scramblingTimeout = TS_SCRAMBLING_TIMEOUT;
bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber()); bool KnownToDecrypt = ChannelCamRelations.CamDecrypt(Receiver->ChannelID(), camSlot->MasterSlotNumber());
if (KnownToDecrypt) if (KnownToDecrypt)
Receiver->scramblingTimeout *= 9; // give it time to receive ECM/EMM (must be less than MAXBROKENTIMEOUT in recorder.c!) Receiver->scramblingTimeout *= 10; // give it time to receive ECM/EMM
if (Receiver->ChannelID().Valid()) if (Receiver->ChannelID().Valid())
dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout); dsyslog("CAM %d: %sknown to decrypt channel %s (scramblingTimeout = %ds)", camSlot->MasterSlotNumber(), KnownToDecrypt ? "" : "not ", *Receiver->ChannelID().ToString(), Receiver->scramblingTimeout);
} }
} }
if (patFilter && Receiver->ChannelID().Valid())
patFilter->Request(Receiver->ChannelID().Sid());
Start(); Start();
return true; return true;
} }
@ -1866,30 +1796,30 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
return false; return false;
} }
void cDevice::Detach(cReceiver *Receiver, bool ReleaseCam) void cDevice::Detach(cReceiver *Receiver)
{ {
if (!Receiver || Receiver->device != this) if (!Receiver || Receiver->device != this)
return; return;
bool receiversLeft = false; bool receiversLeft = false;
mutexReceiver.Lock(); cMutexLock MutexLock(&mutexReceiver);
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i] == Receiver) if (receiver[i] == Receiver) {
Lock();
receiver[i] = NULL; receiver[i] = NULL;
Receiver->device = NULL;
Unlock();
Receiver->Activate(false);
for (int n = 0; n < Receiver->numPids; n++)
DelPid(Receiver->pids[n]);
}
else if (receiver[i]) else if (receiver[i])
receiversLeft = true; receiversLeft = true;
} }
if (patFilter && Receiver->ChannelID().Valid())
patFilter->Release(Receiver->ChannelID().Sid());
mutexReceiver.Unlock();
Receiver->device = NULL;
Receiver->Activate(false);
for (int n = 0; n < Receiver->numPids; n++)
DelPid(Receiver->pids[n]);
if (camSlot) { if (camSlot) {
if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (ReleaseCam) if (!camSlot->IsDecrypting() && !camSlot->IsActivating())
ReleaseCamSlot(); camSlot->Assign(NULL);
} }
} }
if (!receiversLeft) if (!receiversLeft)
@ -1903,9 +1833,8 @@ void cDevice::DetachAll(int Pid)
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
cReceiver *Receiver = receiver[i]; cReceiver *Receiver = receiver[i];
if (Receiver && Receiver->WantsPid(Pid)) if (Receiver && Receiver->WantsPid(Pid))
Detach(Receiver, false); Detach(Receiver);
} }
ReleaseCamSlot();
} }
} }
@ -1913,17 +1842,16 @@ void cDevice::DetachAllReceivers(void)
{ {
cMutexLock MutexLock(&mutexReceiver); cMutexLock MutexLock(&mutexReceiver);
for (int i = 0; i < MAXRECEIVERS; i++) for (int i = 0; i < MAXRECEIVERS; i++)
Detach(receiver[i], false); Detach(receiver[i]);
ReleaseCamSlot();
} }
// --- cTSBuffer ------------------------------------------------------------- // --- cTSBuffer -------------------------------------------------------------
cTSBuffer::cTSBuffer(int File, int Size, int DeviceNumber) cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
{ {
SetDescription("device %d TS buffer", DeviceNumber); SetDescription("device %d TS buffer", CardIndex);
f = File; f = File;
deviceNumber = DeviceNumber; cardIndex = CardIndex;
delivered = 0; delivered = 0;
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS"); ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
ringBuffer->SetTimeouts(100, 100); ringBuffer->SetTimeouts(100, 100);
@ -1948,7 +1876,7 @@ void cTSBuffer::Action(void)
int r = ringBuffer->Read(f); int r = ringBuffer->Read(f);
if (r < 0 && FATALERRNO) { if (r < 0 && FATALERRNO) {
if (errno == EOVERFLOW) if (errno == EOVERFLOW)
esyslog("ERROR: driver buffer overflow on device %d", deviceNumber); esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
else { else {
LOG_ERROR; LOG_ERROR;
break; break;
@ -1979,7 +1907,7 @@ uchar *cTSBuffer::Get(int *Available, bool CheckAvailable)
} }
} }
ringBuffer->Del(Count); ringBuffer->Del(Count);
esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, deviceNumber); esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, cardIndex);
return NULL; return NULL;
} }
delivered = TS_SIZE; delivered = TS_SIZE;

Some files were not shown because too many files have changed in this diff Show More