diff -ruN vdr-2.4.4/CONTRIBUTORS vdr-2.4.6/CONTRIBUTORS
--- vdr-2.4.4/CONTRIBUTORS	2020-07-10 11:06:21.000000000 +0200
+++ vdr-2.4.6/CONTRIBUTORS	2020-12-18 15:51:57.000000000 +0100
@@ -2184,6 +2184,7 @@
 
 Harald Milz <hm@seneca.muc.de>
  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@hut.fi>
  for making repeat keys be ignored when waiting for a keypress to cancel an operation
@@ -2441,6 +2442,9 @@
  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 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
 
 Pekka Mauno <pekka.mauno@iki.fi>
  for fixing cSchedule::GetFollowingEvent() in case there is currently no present
@@ -2519,6 +2523,7 @@
 Markus Ehrnsperger <markus.ehrnsperger@googlemail.com>
  for reporting a problem with missing 'INCLUDES += -I$(DVBDIR)/include' in an existing
  Make.config
+ for reporting a bug in error handling when loading a plugin
 
 Werner Färber <w.faerber@gmx.de>
  for reporting a bug in handling the cPluginManager::Active() result when pressing
@@ -2762,6 +2767,12 @@
  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
 
 Hans-Werner Hilse <hilse@web.de>
  for adding the command line option --userdump to enable core dumps in case VDR
@@ -3480,6 +3491,8 @@
 Claus Muus <email@clausmuus.de>
  for adding the new parameters "Setup/Miscellaneous/Volume steps" and
  ".../Volume linearize"
+ for reporting multiple recording entries in case a recording is started during the
+ initial reading of the video directory
 
 Dieter Ferdinand <dieter.ferdinand@gmx.de>
  for reporting a problem with jumping to an absolute position via the Red key in
@@ -3618,6 +3631,18 @@
  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
 
 Ulrich Eckhardt <uli@uli-eckhardt.de>
  for reporting a problem with shutdown after user inactivity in case a plugin is
@@ -3633,3 +3658,9 @@
 
 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
diff -ruN vdr-2.4.4/HISTORY vdr-2.4.6/HISTORY
--- vdr-2.4.4/HISTORY	2020-08-02 10:55:08.000000000 +0200
+++ vdr-2.4.6/HISTORY	2020-12-22 18:23:51.000000000 +0100
@@ -9512,3 +9512,53 @@
 - Fixed a possible 'invalid lock sequence' when switching to an unavailable channel
   with the main menu open.
 - Official release.
+
+2020-10-16: Version 2.4.5
+
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- Fixed handling newline characters in ci.c's CopyString() (reported by Winfried Köhler).
+- Fixed checking the return value of the Open() call in cFileName::SetOffset() (reported
+  by Winfried Köhler).
+- Fixed a possible invalid lock sequence in cMenuTimers::OnOff().
+- Fixed several typos (reported by Jens Schleusener).
+- Implemented anti-aliasing for cPixmap::DrawSlope() and cPixmap::DrawEllipse() (thanks
+  to Christoph Haubrich).
+  The version numbers (both VDRVERSNUM and APIVERSNUM) have been bumped to 2.4.5 to
+  indicate this change.
+- Fixed alignment of semi-circles in case of odd sizes.
+- Increased the size of the TS buffer to 16MB, to have more reserve when recording
+  several HD programmes.
+- Added checking the symbol rate to cDvbTuner::IsTunedTo(), which apparently got lost
+  in version 1.7.13 (thanks to Helmut Binder).
+- Now checking for an empty command in cDvbTuner::GetSignalStats() to avoid a possible
+  error message (thanks to Helmut Binder).
+- Now initializing the status variable in cDvbTuner::GetFrontendStatus() and
+  cDvbTuner::GetSignalStats() to avoid problems with drivers that don't do this
+  (thanks to Helmut Binder).
+
+2020-12-22: Version 2.4.6
+
+- Fixed multiple recording entries in case a recording is started during the initial
+  reading of the video directory (reported by Claus Muus).
+- Fixed an unnecessary double call to Display() in cMenuRecording::RefreshRecording()
+  (reported by Christoph Haubrich).
+- Fixed a crash in case an error occurs when setting a remote timer.
+- Fixed allocating memory for cImage (reported by Christoph Haubrich).
+- Fixed parsing the '-l' command line option (reported by Harald Milz).
+- Fixed possible compilation errors with libjpeg (thanks to Bernd Kuhls).
+- Fixed "read incomplete section" errors (thanks to Helmut Binder).
+- Fixed generating the HashId in cEIT::cEIT() (thanks to Helmut Binder).
+- Added initialization of cDvbFrontend::frontendInfo (thanks to Winfried Köhler).
+- Fixed a bug in handling shared PMTs, where after the first pass not all SIDs of a
+  PMT pid were checked any more (thanks to Helmut Binder).
+- Fixed PMT handling in case locking the Channels list times out (reported by Helmut
+  Binder).
+- Avoiding a lengthy lock on the Channels list when starting a recording (thanks to
+  Helmut Binder).
+- Fixed error handling when loading a plugin (reported by Markus Ehrnsperger).
+- Improved handling missing VDRPluginDestroyer() (thanks to Winfried Köhler).
+- Fixed initializing tmpbuf in ExtendedEventDescriptors::getText() (thanks to Helmut
+  Binder).
+- Fixed a compiler warning (thanks to Winfried Köhler).
+- Fixed convertCharacterTable() in case iconv_open() fails (thanks to Helmut Binder).
+- Official release.
diff -ruN vdr-2.4.4/PLUGINS/src/osddemo/HISTORY vdr-2.4.6/PLUGINS/src/osddemo/HISTORY
--- vdr-2.4.4/PLUGINS/src/osddemo/HISTORY	2018-04-10 14:58:53.000000000 +0200
+++ vdr-2.4.6/PLUGINS/src/osddemo/HISTORY	2020-10-14 22:32:41.000000000 +0200
@@ -83,3 +83,7 @@
 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').
diff -ruN vdr-2.4.4/PLUGINS/src/osddemo/osddemo.c vdr-2.4.6/PLUGINS/src/osddemo/osddemo.c
--- vdr-2.4.4/PLUGINS/src/osddemo/osddemo.c	2018-04-10 15:00:27.000000000 +0200
+++ vdr-2.4.6/PLUGINS/src/osddemo/osddemo.c	2020-10-14 22:32:41.000000000 +0200
@@ -3,13 +3,13 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: osddemo.c 4.4 2018/04/10 13:00:27 kls Exp $
+ * $Id: osddemo.c 4.5 2020/10/14 20:32:41 kls Exp $
  */
 
 #include <vdr/osd.h>
 #include <vdr/plugin.h>
 
-static const char *VERSION        = "2.4.0";
+static const char *VERSION        = "2.4.1";
 static const char *DESCRIPTION    = "Demo of arbitrary OSD setup";
 static const char *MAINMENUENTRY  = "Osd Demo";
 
@@ -136,6 +136,91 @@
   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 -------------------------------------------------------------
 
 class cLineGame : public cOsdObject {
@@ -590,6 +675,10 @@
                      SetArea();
                      DrawImages(osd);
                      break;
+       case k4:      Cancel(3);
+                     SetArea();
+                     DrawEllipseAlignments(osd);
+                     return osContinue;
        case kBack:
        case kOk:     return osEnd;
        default: return state;
diff -ruN vdr-2.4.4/PLUGINS.html vdr-2.4.6/PLUGINS.html
--- vdr-2.4.4/PLUGINS.html	2020-06-10 16:52:43.000000000 +0200
+++ vdr-2.4.6/PLUGINS.html	2020-09-16 15:48:33.000000000 +0200
@@ -1710,7 +1710,7 @@
 function, or any of the skin classes a plugin might implement.
 <p>
 If a plugin runs a separate thread and wants to issue a message directly from
-within that tread, it can call
+within that thread, it can call
 
 <p><table><tr><td class="code"><pre>
 int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0);
diff -ruN vdr-2.4.4/UPDATE-2.0.0 vdr-2.4.6/UPDATE-2.0.0
--- vdr-2.4.4/UPDATE-2.0.0	2013-03-18 11:31:12.000000000 +0100
+++ vdr-2.4.6/UPDATE-2.0.0	2020-09-16 15:48:33.000000000 +0200
@@ -224,7 +224,7 @@
 - The OSD size is now automatically adjusted to the actual video display
   (provided the output device implements the GetOsdSize() function).
 - The OSD now has full TrueColor support. There can be several "pixmaps" that can
-  be overlayed with alpha blending. All existing skins should work out of the box
+  be overlaid with alpha blending. All existing skins should work out of the box
   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
   may not be what the plugin expects. As long as this bitmap is only used for setting
diff -ruN vdr-2.4.4/UPDATE-2.2.0 vdr-2.4.6/UPDATE-2.2.0
--- vdr-2.4.4/UPDATE-2.2.0	2015-02-11 10:48:02.000000000 +0100
+++ vdr-2.4.6/UPDATE-2.2.0	2020-09-16 15:48:33.000000000 +0200
@@ -408,7 +408,7 @@
 - Updated sources.conf to reflect the fact that Astra 4A and SES5 are actually in
   two separate positions.
 - Fixed cMarks::GetNextBegin() and cMarks::GetNextEnd(). The behavior of these two
-  functions is now exacly as described in the header file. Editing marks that are
+  functions is now exactly 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
   process.
 - The new command line option --chartab can be used to set the default character
diff -ruN vdr-2.4.4/UPDATE-2.4.0 vdr-2.4.6/UPDATE-2.4.0
--- vdr-2.4.4/UPDATE-2.4.0	2018-03-31 15:39:53.000000000 +0200
+++ vdr-2.4.6/UPDATE-2.4.0	2020-09-16 15:48:33.000000000 +0200
@@ -56,7 +56,7 @@
   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 acually is more than one CAM in the system.
+  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
@@ -79,7 +79,7 @@
 - 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 prefering the
+  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
@@ -402,7 +402,7 @@
   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 preceeding
+  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.
diff -ruN vdr-2.4.4/ci.c vdr-2.4.6/ci.c
--- vdr-2.4.4/ci.c	2020-07-10 11:06:21.000000000 +0200
+++ vdr-2.4.6/ci.c	2020-08-17 12:26:18.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ci.c 4.31 2020/07/10 09:06:21 kls Exp $
+ * $Id: ci.c 4.32 2020/08/17 10:26:18 kls Exp $
  */
 
 #include "ci.h"
@@ -81,7 +81,7 @@
   char *s = MALLOC(char, Length + 1);
   char *p = s;
   while (Length > 0) {
-        char c = *Data;
+        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
diff -ruN vdr-2.4.4/config.h vdr-2.4.6/config.h
--- vdr-2.4.4/config.h	2020-07-15 17:13:08.000000000 +0200
+++ vdr-2.4.6/config.h	2020-12-22 18:23:51.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 4.19 2020/07/15 15:13:08 kls Exp $
+ * $Id: config.h 4.21 2020/12/22 17:23:51 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "2.4.4"
-#define VDRVERSNUM   20404  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "2.4.6"
+#define VDRVERSNUM   20406  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "2.4.3"
-#define APIVERSNUM   20403  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "2.4.6"
+#define APIVERSNUM   20406  // Version * 10000 + Major * 100 + Minor
 
 // When loading plugins, VDR searches them by their APIVERSION, which
 // may be smaller than VDRVERSION in case there have been no changes to
diff -ruN vdr-2.4.4/device.c vdr-2.4.6/device.c
--- vdr-2.4.4/device.c	2020-07-13 10:16:41.000000000 +0200
+++ vdr-2.4.6/device.c	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 4.35 2020/07/13 08:16:41 kls Exp $
+ * $Id: device.c 4.36 2020/09/16 13:48:33 kls Exp $
  */
 
 #include "device.h"
@@ -803,7 +803,7 @@
   if (LiveView) {
      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
-                           // and, if decrypted, this removes the now superflous PIDs from the CAM, too
+                           // and, if decrypted, this removes the now superfluous PIDs from the CAM, too
      }
   for (int i = 3; i--;) {
       switch (SetChannel(Channel, LiveView)) {
@@ -826,7 +826,7 @@
   Direction = sgn(Direction);
   if (Direction) {
      cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
-                           // and, if decrypted, this removes the now superflous PIDs from the CAM, too
+                           // and, if decrypted, this removes the now superfluous PIDs from the CAM, too
      int n = CurrentChannel() + Direction;
      int first = n;
      LOCK_CHANNELS_READ;
diff -ruN vdr-2.4.4/dvbdevice.c vdr-2.4.6/dvbdevice.c
--- vdr-2.4.4/dvbdevice.c	2020-06-10 16:52:43.000000000 +0200
+++ vdr-2.4.6/dvbdevice.c	2020-12-05 16:48:40.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 4.23 2020/06/10 14:52:43 kls Exp $
+ * $Id: dvbdevice.c 4.29 2020/12/05 15:48:40 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -34,6 +34,8 @@
 
 #define SCR_RANDOM_TIMEOUT  500 // ms (add random value up to this when tuning SCR device to avoid lockups)
 
+#define TSBUFFERSIZE MEGABYTE(16)
+
 // --- DVB Parameter Maps ----------------------------------------------------
 
 const tDvbParameterMap PilotValues[] = {
@@ -365,6 +367,8 @@
   frontend = Frontend;
   fd_frontend = -1;
   subsystemId = cDvbDeviceProbe::GetSubsystemId(adapter, frontend);
+  memset(&frontendInfo, 0, sizeof(frontendInfo));
+  strn0cpy(frontendInfo.name, "???", sizeof(frontendInfo.name));
   numModulations = 0;
   Open();
   QueryDeliverySystems();
@@ -790,7 +794,7 @@
 {
   if (tunerStatus == tsIdle)
      return false; // not tuned to
-  if (channel.Source() != Channel->Source() || channel.Transponder() != Channel->Transponder())
+  if (channel.Source() != Channel->Source() || channel.Transponder() != Channel->Transponder() || channel.Srate() != Channel->Srate())
      return false; // sufficient mismatch
   // Polarization is already checked as part of the Transponder.
   return strcmp(channel.Parameters(), Channel->Parameters()) == 0;
@@ -854,6 +858,7 @@
 bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
 {
   ClearEventQueue();
+  Status = (fe_status_t)0; // initialize here to fix buggy drivers
   while (1) {
         if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1)
            return true;
@@ -870,7 +875,7 @@
 bool cDvbTuner::GetSignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per, int *Status) const
 {
   ClearEventQueue();
-  fe_status_t FeStatus;
+  fe_status_t FeStatus = (fe_status_t)0; // initialize here to fix buggy drivers
   dtv_property Props[MAXFRONTENDCMDS];
   dtv_properties CmdSeq;
   memset(&Props, 0, sizeof(Props));
@@ -898,7 +903,7 @@
                   SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0); }
   if (Per)      { SETCMD(DTV_STAT_ERROR_BLOCK_COUNT, 0);
                   SETCMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0); }
-  if (ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
+  if (CmdSeq.num && ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
      esyslog("ERROR: frontend %d/%d: %m (%s:%d)", adapter, frontend, __FILE__, __LINE__);
      return false;
      }
@@ -2135,11 +2140,17 @@
   return true;
 }
 
+#define RB_NUM_SECTIONS 8 // default: 2 sections = 8192 bytes
+
 int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
 {
   cString FileName = DvbName(DEV_DVB_DEMUX, adapter, frontend);
   int f = open(FileName, O_RDWR | O_NONBLOCK);
   if (f >= 0) {
+     if (Pid == EITPID) { // increase ringbuffer size for EIT
+        if (ioctl(f, DMX_SET_BUFFER_SIZE, MAX_SECTION_SIZE * RB_NUM_SECTIONS) < 0)
+           dsyslog("OpenFilter (pid=%d, tid=%02X): ioctl DMX_SET_BUFFER_SIZE failed", Pid, Tid);
+        }
      dmx_sct_filter_params sctFilterParams;
      memset(&sctFilterParams, 0, sizeof(sctFilterParams));
      sctFilterParams.pid = Pid;
@@ -2311,7 +2322,7 @@
   CloseDvr();
   fd_dvr = DvbOpen(DEV_DVB_DVR, adapter, frontend, O_RDONLY | O_NONBLOCK, true);
   if (fd_dvr >= 0)
-     tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(5), DeviceNumber() + 1);
+     tsBuffer = new cTSBuffer(fd_dvr, TSBUFFERSIZE, DeviceNumber() + 1);
   return fd_dvr >= 0;
 }
 
diff -ruN vdr-2.4.4/dvbspu.c vdr-2.4.6/dvbspu.c
--- vdr-2.4.4/dvbspu.c	2013-02-22 16:25:16.000000000 +0100
+++ vdr-2.4.6/dvbspu.c	2020-12-18 15:51:57.000000000 +0100
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.c 4.0 2013/02/22 15:25:16 kls Exp $
+ * $Id: dvbspu.c 4.1 2020/12/18 14:51:57 kls Exp $
  */
 
 #include "dvbspu.h"
@@ -38,7 +38,7 @@
 #ifdef SPUDEBUG
 #define DEBUG(format, args...) printf (format, ## args)
 #else
-#define DEBUG(format, args...)
+#define DEBUG(format, args...) void()
 #endif
 
 // --- cDvbSpuPalette---------------------------------------------------------
diff -ruN vdr-2.4.4/eit.c vdr-2.4.6/eit.c
--- vdr-2.4.4/eit.c	2020-06-23 11:27:09.000000000 +0200
+++ vdr-2.4.6/eit.c	2020-11-28 22:45:05.000000000 +0100
@@ -8,7 +8,7 @@
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
  *
- * $Id: eit.c 4.10 2020/06/23 09:27:09 kls Exp $
+ * $Id: eit.c 4.11 2020/11/28 21:45:05 kls Exp $
  */
 
 #include "eit.h"
@@ -34,7 +34,7 @@
 {
   if (!CheckCRCAndParse())
      return;
-  int HashId = Tid * getServiceId();
+  int HashId = Tid + (getServiceId() << 8);
   cSectionSyncerEntry *SectionSyncerEntry = SectionSyncerHash.Get(HashId);
   if (!SectionSyncerEntry) {
      SectionSyncerEntry = new cSectionSyncerEntry;
diff -ruN vdr-2.4.4/libsi/descriptor.c vdr-2.4.6/libsi/descriptor.c
--- vdr-2.4.4/libsi/descriptor.c	2020-06-23 11:27:09.000000000 +0200
+++ vdr-2.4.6/libsi/descriptor.c	2020-12-17 13:52:57.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.c 4.3 2020/06/23 09:27:09 kls Exp $
+ *   $Id: descriptor.c 4.4 2020/12/17 12:52:57 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -94,6 +94,7 @@
    char tmpbuf[tmpsize];
    const char *fromCode = NULL;
    int index=0, len;
+   *tmpbuf = 0; // just in case length is 0
    for (int i=0;i<length;i++) {
       ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
       if (!d)
diff -ruN vdr-2.4.4/libsi/headers.h vdr-2.4.6/libsi/headers.h
--- vdr-2.4.4/libsi/headers.h	2020-06-23 11:27:09.000000000 +0200
+++ vdr-2.4.6/libsi/headers.h	2020-09-16 15:48:33.000000000 +0200
@@ -10,7 +10,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: headers.h 4.1 2020/06/23 09:27:09 kls Exp $
+ *   $Id: headers.h 4.2 2020/09/16 13:48:33 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -2081,7 +2081,7 @@
    u_char icon_flags_lo                          :8;
 };
 
-/* 0x15 simple application location descrptor */
+/* 0x15 simple application location descriptor */
 
 #define DESCR_SIMPLE_APPLICATION_LOCATION_LEN 3
 
diff -ruN vdr-2.4.4/libsi/si.c vdr-2.4.6/libsi/si.c
--- vdr-2.4.4/libsi/si.c	2020-05-15 13:31:40.000000000 +0200
+++ vdr-2.4.6/libsi/si.c	2020-12-19 15:41:41.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.c 4.2 2020/05/15 11:31:40 kls Exp $
+ *   $Id: si.c 4.3 2020/12/19 14:41:41 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -413,6 +413,7 @@
 
 size_t convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode)
 {
+  bool converted = false;
   char *result = to;
   if (SystemCharacterTable && fromCode) {
      iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
@@ -433,9 +434,10 @@
         }
         *to = 0;
         iconv_close(cd);
+        converted = true;
      }
   }
-  else {
+  if (!converted) {
      size_t len = fromLength;
      if (len >= toLength)
         len = toLength - 1;
diff -ruN vdr-2.4.4/lirc.c vdr-2.4.6/lirc.c
--- vdr-2.4.4/lirc.c	2017-05-30 13:02:17.000000000 +0200
+++ vdr-2.4.6/lirc.c	2020-09-16 15:48:33.000000000 +0200
@@ -6,7 +6,7 @@
  *
  * LIRC support added by Carsten Koch <Carsten.Koch@icem.de>  2000-06-16.
  *
- * $Id: lirc.c 4.1 2017/05/30 11:02:17 kls Exp $
+ * $Id: lirc.c 4.2 2020/09/16 13:48:33 kls Exp $
  */
 
 #include "lirc.h"
@@ -89,7 +89,7 @@
            int count;
            char KeyName[LIRC_KEY_BUF];
            if (sscanf(buf, "%*x %x %29s", &count, KeyName) != 2) { // '29' in '%29s' is LIRC_KEY_BUF-1!
-              esyslog("ERROR: unparseable lirc command: %s", buf);
+              esyslog("ERROR: unparsable lirc command: %s", buf);
               continue;
               }
            int Delta = ThisTime.Elapsed(); // the time between two subsequent LIRC events
diff -ruN vdr-2.4.4/menu.c vdr-2.4.6/menu.c
--- vdr-2.4.4/menu.c	2020-07-01 17:05:17.000000000 +0200
+++ vdr-2.4.6/menu.c	2020-12-12 23:01:01.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 4.83 2020/07/01 15:05:17 kls Exp $
+ * $Id: menu.c 4.88 2020/12/12 22:01:01 kls Exp $
  */
 
 #include "menu.h"
@@ -1130,7 +1130,7 @@
                            addedTimer = timer;
                            if (!HandleRemoteModifications(timer)) {
                               // must add the timer before HandleRemoteModifications to get proper log messages with timer ids
-                              Timers->Del(timer);
+                              Timers->Del(timer, false);
                               addedTimer = NULL;
                               return osContinue;
                               }
@@ -1326,8 +1326,10 @@
         if (!ExecSVDRPCommand(Timer->Remote(), cString::sprintf("MODT %d %s", Timer->Id(), *Timer->ToText(true)), &Response) || SVDRPCode(Response[0]) != 250)
            RemoteTimerError(Timer);
         }
-     LOCK_SCHEDULES_READ;
-     Timer->SetEventFromSchedule(Schedules);
+     {
+       LOCK_SCHEDULES_READ;
+       Timer->SetEventFromSchedule(Schedules);
+     }
      RefreshCurrent();
      DisplayCurrent(true);
      if (Timer->FirstDay())
@@ -2832,6 +2834,8 @@
 :cOsdMenu(tr("Recording info"))
 {
   SetMenuCategory(mcRecordingInfo);
+  if (cRecordings::GetRecordingsRead(recordingsStateKey)) // initializes recordingsStateKey, so we don't call Display() unnecessarily
+     recordingsStateKey.Remove();
   recording = Recording;
   originalFileName = recording->FileName();
   withButtons = WithButtons;
@@ -4727,7 +4731,7 @@
 {
   if (Direction) {
      cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
-                           // and, if decrypted, this removes the now superflous PIDs from the CAM, too
+                           // and, if decrypted, this removes the now superfluous PIDs from the CAM, too
      LOCK_CHANNELS_READ;
      while (Channel) {
            Channel = Direction > 0 ? Channels->Next(Channel) : Channels->Prev(Channel);
@@ -5225,6 +5229,11 @@
   const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules!
   // Whatever happens here, the timers will be modified in some way...
   Timers->SetModified();
+  cStateKey ChannelsStateKey;
+  // To create a new timer, we need to make shure there is
+  // a lock on Channels prior to the Schedules locking below
+  if (!Timer)
+     cChannels::GetChannelsRead(ChannelsStateKey);
   // We're going to work with an event here, so we need to prevent
   // others from modifying any EPG data:
   cStateKey SchedulesStateKey;
@@ -5240,6 +5249,7 @@
      timer = new cTimer(true, Pause);
      Timers->Add(timer);
      instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->DeviceNumber() + 1);
+     ChannelsStateKey.Remove();
      }
   timer->SetPending(true);
   timer->SetRecording(true);
@@ -5376,7 +5386,8 @@
   LastNoDiskSpaceMessage = 0;
 
   ChangeState();
-  LOCK_CHANNELS_READ;
+  cStateKey StateKey;
+  const cChannels *Channels = cChannels::GetChannelsRead(StateKey);
   int ch = Timer ? Timer->Channel()->Number() : cDevice::CurrentChannel();
   if (const cChannel *Channel = Channels->GetByNumber(ch)) {
      int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority;
@@ -5384,9 +5395,12 @@
      if (device) {
         dsyslog("switching device %d to channel %d %s (%s)", device->DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
         if (!device->SwitchChannel(Channel, false)) {
+           StateKey.Remove();
            ShutdownHandler.RequestEmergencyExit();
            return false;
            }
+        StateKey.Remove();
+        Channels = NULL;
         if (!Timer || Timer->Matches()) {
            for (int i = 0; i < MAXRECORDCONTROLS; i++) {
                if (!RecordControls[i]) {
@@ -5403,6 +5417,8 @@
      }
   else
      esyslog("ERROR: channel %d not defined!", ch);
+  if (Channels)
+     StateKey.Remove();
   return false;
 }
 
diff -ruN vdr-2.4.4/osd.c vdr-2.4.6/osd.c
--- vdr-2.4.4/osd.c	2019-05-24 23:28:35.000000000 +0200
+++ vdr-2.4.6/osd.c	2020-12-19 00:02:47.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.c 4.6 2019/05/24 21:28:35 kls Exp $
+ * $Id: osd.c 4.11 2020/12/18 23:02:47 kls Exp $
  */
 
 #include "osd.h"
@@ -633,7 +633,7 @@
 {
   if (!Intersects(x1, y1, x2, y2))
      return;
-  // Algorithm based on http://homepage.smc.edu/kennedy_john/BELIPSE.PDF
+  // Algorithm based on https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf
   int rx = x2 - x1;
   int ry = y2 - y1;
   int cx = (x1 + x2) / 2;
@@ -1109,18 +1109,18 @@
 cImage::cImage(const cImage &Image)
 {
   size = Image.Size();
-  int l = size.Width() * size.Height() * sizeof(tColor);
+  int l = size.Width() * size.Height();
   data = MALLOC(tColor, l);
-  memcpy(data, Image.Data(), l);
+  memcpy(data, Image.Data(), l * sizeof(tColor));
 }
 
 cImage::cImage(const cSize &Size, const tColor *Data)
 {
   size = Size;
-  int l = size.Width() * size.Height() * sizeof(tColor);
+  int l = size.Width() * size.Height();
   data = MALLOC(tColor, l);
   if (Data)
-     memcpy(data, Data, l);
+     memcpy(data, Data, l * sizeof(tColor));
 }
 
 cImage::~cImage()
@@ -1273,6 +1273,24 @@
   Unlock();
 }
 
+void cPixmapMemory::DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t Alpha)
+{
+  Lock();
+  if (DrawPort().Size().Contains(Point)) {
+     int p = Point.Y() * DrawPort().Width() + Point.X();
+     if (Alpha != ALPHA_OPAQUE) {
+        if (Color == clrTransparent)
+           data[p] = (data[p] & 0x00FFFFFF) | ((((data[p] >> 24) * (255 - Alpha)) << 16) & 0xFF000000);
+        else
+           data[p] = AlphaBlend(Color, data[p], Alpha);
+        }
+     else
+        data[p] = Color;
+     MarkDrawPortDirty(Point);
+     }
+  Unlock();
+}
+
 void cPixmapMemory::DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay)
 {
   Lock();
@@ -1378,16 +1396,16 @@
 
 void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants)
 {
-//TODO use anti-aliasing?
-//TODO fix alignment
   Lock();
-  // Algorithm based on http://homepage.smc.edu/kennedy_john/BELIPSE.PDF
+  // Algorithm based on https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf
   int x1 = Rect.Left();
   int y1 = Rect.Top();
   int x2 = Rect.Right();
   int y2 = Rect.Bottom();
   int rx = x2 - x1;
   int ry = y2 - y1;
+  int ax = rx & 0x01; // alignment to make semi-circles match rectangles of same size
+  int ay = ry & 0x01;
   int cx = (x1 + x2) / 2;
   int cy = (y1 + y2) / 2;
   switch (abs(Quadrants)) {
@@ -1411,23 +1429,79 @@
   int EllipseError = 0;
   int StoppingX = TwoBSquare * rx;
   int StoppingY = 0;
+  int Delta = 0;
+  bool AntiAliased = Setup.AntiAlias;
   while (StoppingX >= StoppingY) {
-        switch (Quadrants) {
-          case  5: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); // no break
-          case  1: DrawRectangle(cRect(cx,     cy - y, x + 1, 1), Color); break;
-          case  7: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); // no break
-          case  2: DrawRectangle(cRect(cx - x, cy - y, x + 1, 1), Color); break;
-          case  3: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); break;
-          case  4: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); break;
-          case  0:
-          case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1,       1), Color); if (Quadrants == 6) break;
-          case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1,       1), Color); break;
-          case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1,      1), Color); break;
-          case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
-          case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
-          case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1,      1), Color); break;
-          default: ;
-          }
+        if (!AntiAliased) {
+           switch (Quadrants) {
+             case  5: DrawRectangle(cRect(cx,     cy + y + ay, x + 1, 1), Color); // no break
+             case  1: DrawRectangle(cRect(cx,     cy - y,      x + 1, 1), Color); break;
+             case  7: DrawRectangle(cRect(cx - x, cy + y + ay, x + 1, 1), Color); // no break
+             case  2: DrawRectangle(cRect(cx - x, cy - y,      x + 1, 1), Color); break;
+             case  3: DrawRectangle(cRect(cx - x, cy + y,      x + 1, 1), Color); break;
+             case  4: DrawRectangle(cRect(cx,     cy + y,      x + 1, 1), Color); break;
+             case  0:
+             case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + ax + 1,  1), Color); if (Quadrants == 6) break;
+             case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + ax + 1,  1), Color); break;
+             case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1,      1), Color); break;
+             case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
+             case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
+             case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1,      1), Color); break;
+             default: ;
+             }
+           }
+        else {
+           uint8_t intensity = abs(255 * (long int)EllipseError / XChange);
+           if (EllipseError >= 0) {
+              intensity = 255 - intensity;
+              Delta = 0;
+              }
+           else
+              Delta = 1;
+           switch (Quadrants) {
+             case  5: DrawRectangle(   cRect( cx,             cy + y + ay, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx + x + Delta, cy + y + ay),               Color, intensity);
+                      // no break
+             case  1: DrawRectangle(   cRect( cx,             cy - y, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx + x + Delta, cy - y),               Color, intensity);
+                      break;
+             case  7: DrawRectangle(   cRect( cx - x + 1 - Delta, cy + ay + y, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta,     cy + ay + y),               Color, intensity);
+                      // no break
+             case  2: DrawRectangle(   cRect( cx - x + 1 - Delta, cy - y, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta,     cy - y),               Color, intensity);
+                      break;
+             case  3: DrawRectangle(   cRect( cx - x + 1 - Delta, cy + y, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta,     cy + y),               Color, intensity);
+                      break;
+             case  4: DrawRectangle(   cRect( cx,             cy + y, x + Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx + x + Delta, cy + y),               Color, intensity);
+                      break;
+             case  0:
+             case  6: DrawRectangle(   cRect( cx - x - Delta + 1,  cy - y, 2 * (x + Delta) + ax - 1, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta,      cy - y),                              Color, intensity);
+                      DrawBlendedPixel(cPoint(cx + x + Delta + ax, cy - y),                              Color, intensity);
+                      if (Quadrants == 6)
+                         break;
+             case  8: DrawRectangle(   cRect( cx - x - Delta + 1,  cy + y, 2 * (x + Delta) + ax - 1 , 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta,      cy + y),                               Color, intensity);
+                      DrawBlendedPixel(cPoint(cx + x + Delta + ax, cy + y),                               Color, intensity);
+                      break;
+             case -1: DrawRectangle(   cRect( cx + x + 1 + Delta, cy - y, rx - (x + Delta), 1), Color);
+                      DrawBlendedPixel(cPoint(cx + x + Delta,     cy - y),                      Color, 255-intensity);
+                      break;
+             case -2: DrawRectangle(   cRect( x1,             cy - y, rx - x - Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta, cy - y),                    Color, 255-intensity);
+                      break;
+             case -3: DrawRectangle(   cRect( x1,             cy + y, rx - x - Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx - x - Delta, cy + y),                    Color, 255-intensity);
+                      break;
+             case -4: DrawRectangle(   cRect( cx + x + 1 + Delta, cy + y, rx - x - Delta, 1), Color);
+                      DrawBlendedPixel(cPoint(cx + x + Delta,     cy + y),                    Color, 255-intensity);
+                      break;
+             default: ;
+             }
+           }
         y++;
         StoppingY += TwoASquare;
         EllipseError += YChange;
@@ -1439,6 +1513,7 @@
            XChange += TwoBSquare;
            }
         }
+  int ymax = y - 1;
   x = 0;
   y = ry;
   XChange = ry * ry;
@@ -1447,22 +1522,78 @@
   StoppingX = 0;
   StoppingY = TwoASquare * ry;
   while (StoppingX <= StoppingY) {
-        switch (Quadrants) {
-          case  5: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); // no break
-          case  1: DrawRectangle(cRect(cx,     cy - y, x + 1, 1), Color); break;
-          case  7: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); // no break
-          case  2: DrawRectangle(cRect(cx - x, cy - y, x + 1, 1), Color); break;
-          case  3: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); break;
-          case  4: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); break;
-          case  0:
-          case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1,       1), Color); if (Quadrants == 6) break;
-          case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1,       1), Color); break;
-          case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1,      1), Color); break;
-          case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
-          case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
-          case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1,      1), Color); break;
-          default: ;
-          }
+        if (!AntiAliased) {
+           switch (Quadrants) {
+             case  5: DrawRectangle(cRect(cx,     cy + y + ay, x + 1, 1), Color); // no break
+             case  1: DrawRectangle(cRect(cx,     cy - y,      x + 1, 1), Color); break;
+             case  7: DrawRectangle(cRect(cx - x, cy + y + ay, x + 1, 1), Color); // no break
+             case  2: DrawRectangle(cRect(cx - x, cy - y,      x + 1, 1), Color); break;
+             case  3: DrawRectangle(cRect(cx - x, cy + y,      x + 1, 1), Color); break;
+             case  4: DrawRectangle(cRect(cx,     cy + y,      x + 1, 1), Color); break;
+             case  0:
+             case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + ax + 1,  1), Color); if (Quadrants == 6) break;
+             case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + ax + 1,  1), Color); break;
+             case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1,      1), Color); break;
+             case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
+             case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
+             case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1,      1), Color); break;
+             default: ;
+             }
+           }
+        else {
+           uint8_t intensity = abs(255 * (long int)EllipseError / YChange);
+           if (EllipseError >= 0) {
+              intensity = 255 - intensity;
+              Delta = 1;
+              }
+           else
+              Delta = 0;
+           switch (Quadrants) {
+             case  5: DrawRectangle(   cRect( cx + x, cy + ay + 1 + ymax,  1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx + x, cy + ay + y + 1 - Delta),                  Color, intensity);
+                      // no break
+             case  1: DrawRectangle(   cRect( cx + x, cy - y + Delta, 1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx + x, cy - y - 1 + Delta),                  Color, intensity);
+                      break;
+             case  7: DrawRectangle(   cRect( cx - x, cy + ay + 1 + ymax,  1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x, cy + ay + y + 1 - Delta),                  Color, intensity);
+                      // no break
+             case  2: DrawRectangle(   cRect( cx - x, cy - y + Delta, 1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x, cy - y - 1 + Delta),                  Color, intensity);
+                      break;
+             case  3: DrawRectangle(   cRect( cx - x, cy + 1 + ymax, 1, y - ymax - Delta),  Color);
+                      DrawBlendedPixel(cPoint(cx - x, cy + y + 1 - Delta),                  Color, intensity);
+                      break;
+             case  4: DrawRectangle(   cRect( cx + x, cy + 1 + ymax, 1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx + x, cy + y + 1 - Delta),                  Color, intensity);
+                      break;
+             case  0:
+             case  6: DrawRectangle(   cRect( cx + x + ax, cy - y + Delta, 1, y - ymax - Delta), Color);
+                      DrawRectangle(   cRect( cx - x,      cy - y + Delta, 1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x,      cy - y + Delta - 1),                  Color, intensity);
+                      DrawBlendedPixel(cPoint(cx + x + ax, cy - y + Delta - 1),                  Color, intensity);
+                      if (Quadrants == 6)
+                         break;
+             case  8: DrawRectangle(   cRect( cx - x,      cy + 1 + ymax, 1, y - ymax - Delta), Color);
+                      DrawRectangle(   cRect( cx + x + ax, cy + 1 + ymax, 1, y - ymax - Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x,      cy + y + 1 - Delta),                 Color, intensity);
+                      DrawBlendedPixel(cPoint(cx + x + ax, cy + y + 1 - Delta),                 Color, intensity);
+                      break;
+             case -1: DrawRectangle(   cRect( cx + x, cy - ry, 1, ry - y - 1 + Delta), Color);
+                      DrawBlendedPixel(cPoint(cx + x, cy - y - 1 + Delta),             Color, 255-intensity);
+                      break;
+             case -2: DrawRectangle(   cRect( cx - x, cy - ry, 1, ry - y - 1 + Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x, cy - y - 1 + Delta),             Color, 255-intensity);
+                      break;
+             case -3: DrawRectangle(   cRect( cx - x, cy + y + 2 - Delta, 1, ry - y - 1 + Delta), Color);
+                      DrawBlendedPixel(cPoint(cx - x, cy + y + 1 - Delta),                        Color, 255-intensity);
+                      break;
+             case -4: DrawRectangle(   cRect( cx + x, cy + y + 2 - Delta, 1, ry - y - 1 + Delta), Color);
+                      DrawBlendedPixel(cPoint(cx + x, cy + y + 1 - Delta),                        Color, 255-intensity);
+                      break;
+             default: ;
+             }
+           }
         x++;
         StoppingX += TwoBSquare;
         EllipseError += XChange;
@@ -1474,13 +1605,21 @@
            YChange += TwoASquare;
            }
         }
+  if (AntiAliased && Quadrants < 0 ) {
+     switch (Quadrants) {
+        case -1: DrawRectangle(cRect(cx + x, cy - ry,    rx - x + 1, ry - y), Color); break;
+        case -2: DrawRectangle(cRect(x1,     cy - ry,    rx - x + 1, ry - y), Color); break;
+        case -3: DrawRectangle(cRect(x1,     cy + y + 1, rx - x + 1, ry - y), Color); break;
+        case -4: DrawRectangle(cRect(cx + x, cy + y + 1, rx - x + 1, ry - y), Color); break;
+        default: ;
+        }
+     }
   MarkDrawPortDirty(Rect);
   Unlock();
 }
 
 void cPixmapMemory::DrawSlope(const cRect &Rect, tColor Color, int Type)
 {
-  //TODO anti-aliasing?
   //TODO also simplify cBitmap::DrawSlope()
   Lock();
   bool upper    = Type & 0x01;
@@ -1492,28 +1631,87 @@
   int y2 = Rect.Bottom();
   int w  = Rect.Width();
   int h  = Rect.Height();
+  bool AntiAliased = Setup.AntiAlias;
+  uint8_t intensity = 0;
+
   if (vertical) {
-     for (int y = y1; y <= y2; y++) {
-         double c = cos((y - y1) * M_PI / h);
+     if (upper)
+        DrawRectangle(cRect(x1, y1, w, 1), Color);
+     else
+        DrawRectangle(cRect(x1, y2, w, 1), Color);
+     for (int y = 1; y <= (y2 - y1) / 2; y++) {
+         double c = cos(y * M_PI / (y2 - y1));
+         if (AntiAliased) {
+            double wc = (w * c + (w & 1)) / 2;
+            intensity = 255 * fabs(wc - floor(wc));
+            }
          if (falling)
             c = -c;
-         int x = (x1 + x2) / 2 + int(w * c / 2);
-         if (upper && !falling || !upper && falling)
-            DrawRectangle(cRect(x1, y, x - x1 + 1, 1), Color);
-         else
-            DrawRectangle(cRect(x, y, x2 - x + 1, 1), Color);
+         int x = (x1 + x2 + w * c + 1) / 2;
+         if (upper && !falling || !upper && falling) {
+            if (AntiAliased) {
+               DrawRectangle(cRect(x1, y1 + y, x - x1, 1), Color);
+               DrawBlendedPixel(cPoint(x, y1 + y), Color, upper ? intensity : 255 - intensity);
+               DrawRectangle(cRect(x1, y2 - y, x2 - x, 1), Color);
+               DrawBlendedPixel(cPoint(x1 + x2 - x, y2 - y), Color, upper ? 255 - intensity : intensity);
+               }
+            else {
+               DrawRectangle(cRect(x1, y1 + y, x - x1 + 1, 1), Color);
+               DrawRectangle(cRect(x1, y2 - y, x2 - x + 1, 1), Color);
+               }
+            }
+         else {
+            if (AntiAliased) {
+               DrawRectangle(cRect(x + 1, y1 + y, x2 - x, 1), Color);
+               DrawBlendedPixel(cPoint(x, y1 + y), Color, falling ? intensity : 255 - intensity);
+               DrawRectangle(cRect(x1 + x2 - x + 1, y2 - y, x - x1, 1), Color);
+               DrawBlendedPixel(cPoint(x1 + x2 - x, y2 - y), Color, falling ? 255 - intensity : intensity);
+               }
+            else {
+               DrawRectangle(cRect(x, y1 + y, x2 - x + 1, 1), Color);
+               DrawRectangle(cRect(x1 + x2 - x, y2 - y, x - x1 + 1, 1), Color);
+               }
+            }
          }
      }
   else {
-     for (int x = x1; x <= x2; x++) {
-         double c = cos((x - x1) * M_PI / w);
+     if ((upper && !falling) || (!upper && falling))
+        DrawRectangle(cRect(x1, y1, 1, h), Color);
+     else
+        DrawRectangle(cRect(x2, y1, 1, h), Color);
+     for (int x = 1; x <= (x2 - x1) / 2; x++) {
+         double c = cos(x * M_PI / (x2 - x1));
+         if (AntiAliased) {
+            double hc = (h * c + (h & 1)) / 2;
+            intensity = 255 * fabs(hc - floor(hc));
+            }
          if (falling)
             c = -c;
-         int y = (y1 + y2) / 2 + int(h * c / 2);
-         if (upper)
-            DrawRectangle(cRect(x, y1, 1, y - y1 + 1), Color);
-         else
-            DrawRectangle(cRect(x, y, 1, y2 - y + 1), Color);
+         int y = (y1 + y2 + h * c + 1) / 2;
+         if (upper) {
+            if (AntiAliased) {
+               DrawRectangle(cRect(x1 + x, y1, 1, y - y1), Color);
+               DrawBlendedPixel(cPoint(x1 + x, y), Color, falling ? 255 - intensity : intensity);
+               DrawRectangle(cRect(x2 - x, y1, 1, y2 - y), Color);
+               DrawBlendedPixel(cPoint(x2 - x, y1 + y2 - y), Color, falling ? intensity : 255 - intensity);
+               }
+            else {
+               DrawRectangle(cRect(x1 + x, y1, 1, y - y1 + 1), Color);
+               DrawRectangle(cRect(x2 - x, y1, 1, y2 - y + 1), Color);
+               }
+            }
+         else {
+            if (AntiAliased) {
+               DrawRectangle(cRect(x1 + x, y + 1, 1, y2 - y), Color);
+               DrawBlendedPixel(cPoint(x1 + x, y), Color, falling ? intensity : 255 - intensity);
+               DrawRectangle(cRect(x2 - x, y1 + y2 - y + 1, 1, y - y1), Color);
+               DrawBlendedPixel(cPoint(x2 - x, y1 + y2 - y), Color, falling ? 255 - intensity : intensity);
+               }
+            else {
+               DrawRectangle(cRect(x1 + x, y, 1, y2 - y + 1), Color);
+               DrawRectangle(cRect(x2 - x, y1 + y2 - y, 1, y - y1 + 1), Color);
+               }
+            }
          }
      }
   MarkDrawPortDirty(Rect);
diff -ruN vdr-2.4.4/osd.h vdr-2.4.6/osd.h
--- vdr-2.4.4/osd.h	2019-05-24 23:28:35.000000000 +0200
+++ vdr-2.4.6/osd.h	2020-09-29 16:09:26.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.h 4.6 2019/05/24 21:28:35 kls Exp $
+ * $Id: osd.h 4.7 2020/09/29 14:09:26 kls Exp $
  */
 
 #ifndef __OSD_H
@@ -607,6 +607,10 @@
        ///< a full 32 bit ARGB value. If the alpha value of Color is not 0xFF
        ///< (fully opaque), and this is the background pixmap (layer 0), the pixel is
        ///< alpha blended with the existing color at the given position in this pixmap.
+  virtual void DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t AlphaLayer = ALPHA_OPAQUE) { DrawPixel(Point, Color); }
+       ///< Like DrawPixel(), but with an additional AlphaLayer, and works on any
+       ///< pixmap, not only the background. The default implementation just calls
+       ///< DrawPixel(), ignoring AlphaLayer.
   virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) = 0;
        ///< Sets the pixels in the OSD with the data from the given
        ///< Bitmap, putting the upper left corner of the Bitmap at Point.
@@ -697,6 +701,7 @@
   virtual void DrawImage(const cPoint &Point, const cImage &Image);
   virtual void DrawImage(const cPoint &Point, int ImageHandle);
   virtual void DrawPixel(const cPoint &Point, tColor Color);
+  virtual void DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t AlphaLayer = ALPHA_OPAQUE);
   virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false);
   virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
   virtual void DrawRectangle(const cRect &Rect, tColor Color);
diff -ruN vdr-2.4.4/pat.c vdr-2.4.6/pat.c
--- vdr-2.4.4/pat.c	2020-06-19 14:19:15.000000000 +0200
+++ vdr-2.4.6/pat.c	2020-12-18 15:51:57.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: pat.c 4.6 2020/06/19 12:19:15 kls Exp $
+ * $Id: pat.c 4.9 2020/12/18 14:51:57 kls Exp $
  */
 
 #include "pat.h"
@@ -334,7 +334,7 @@
 #ifdef DEBUG_PAT_PMT
 #define DBGLOG(a...) { cString s = cString::sprintf(a); fprintf(stderr, "%s\n", *s); dsyslog("%s", *s); }
 #else
-#define DBGLOG(a...)
+#define DBGLOG(a...) void()
 #endif
 
 cPatFilter::cPatFilter(void)
@@ -389,13 +389,13 @@
       if (se->Sid() == Sid && se->Pid() == PmtPid) {
          if (!se->Received()) {
             se->SetReceived(true);
-            if (PmtPidComplete(PmtPid))
-               se->PidEntry()->SetComplete(true);
+            se->PidEntry()->SetComplete(PmtPidComplete(PmtPid));
             }
          if (se->Version() != Version) {
-            DBGLOG("PMT %d  %2d %5d/%d %2d -> %2d", Transponder(), i, PmtPid, Sid, se->Version(), Version);
             if (SetNewVersion)
                se->SetVersion(Version);
+            else
+               DBGLOG("PMT %d  %2d %5d/%d %2d -> %2d", Transponder(), i, PmtPid, Sid, se->Version(), Version);
             return true;
             }
          break;
@@ -411,6 +411,7 @@
      if (!(activePmt = pmtPidList.Next(activePmt)))
         activePmt = pmtPidList.First();
      PmtPidReset(activePmt->Pid());
+     activePmt->SetComplete(false);
      Add(activePmt->Pid(), SI::TableIdPMT);
      }
 }
@@ -473,7 +474,7 @@
      SI::PMT pmt(Data, false);
      if (!pmt.CheckCRCAndParse())
         return;
-     if (!PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber(), true)) {
+     if (!PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber(), false)) {
         if (activePmt && activePmt->Complete())
            SwitchToNextPmtPid();
         return;
@@ -482,6 +483,7 @@
      cChannels *Channels = cChannels::GetChannelsWrite(StateKey, 10);
      if (!Channels)
         return;
+     PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber(), true);
      bool ChannelsModified = false;
      if (activePmt && activePmt->Complete())
         SwitchToNextPmtPid();
diff -ruN vdr-2.4.4/plugin.c vdr-2.4.6/plugin.c
--- vdr-2.4.4/plugin.c	2020-06-29 11:29:06.000000000 +0200
+++ vdr-2.4.6/plugin.c	2020-12-16 12:54:06.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.c 4.2 2020/06/29 09:29:06 kls Exp $
+ * $Id: plugin.c 4.4 2020/12/16 11:54:06 kls Exp $
  */
 
 #include "plugin.h"
@@ -229,9 +229,16 @@
   if (!error) {
      typedef cPlugin *create_t(void);
      create_t *create = (create_t *)dlsym(handle, "VDRPluginCreator");
-     if (!(error = dlerror()))
+     error = dlerror();
+     if (!error && create) {
         plugin = create();
-     destroy = (destroy_t *)dlsym(handle, "VDRPluginDestroyer");
+        destroy = (destroy_t *)dlsym(handle, "VDRPluginDestroyer");
+        error = dlerror();
+        if (error) {
+           error = NULL;
+           isyslog("plugin %s: missing symbol VDRPluginDestroyer(), please rebuild", fileName);
+           }
+        }
      }
   if (!error) {
      if (plugin && args) {
diff -ruN vdr-2.4.4/po/it_IT.po vdr-2.4.6/po/it_IT.po
--- vdr-2.4.4/po/it_IT.po	2020-06-15 17:57:32.000000000 +0200
+++ vdr-2.4.6/po/it_IT.po	2020-08-11 11:46:34.000000000 +0200
@@ -350,22 +350,22 @@
 msgstr "ita"
 
 msgid "LanguageName$original language (qaa)"
-msgstr ""
+msgstr "lingua originale (qaa)"
 
 msgid "LanguageName$uncoded languages (mis)"
-msgstr ""
+msgstr "lingue non codificate (mis)"
 
 msgid "LanguageName$multiple languages (mul)"
-msgstr ""
+msgstr "lingue multiple (mul)"
 
 msgid "LanguageName$narrative (nar)"
-msgstr ""
+msgstr "narrativa (nar)"
 
 msgid "LanguageName$undetermined (und)"
-msgstr ""
+msgstr "indeterminata (und)"
 
 msgid "LanguageName$no linguistic content (zxx)"
-msgstr ""
+msgstr "nessun contenuto linguistico (zxx)"
 
 msgid "Phase 1: Detecting RC code type"
 msgstr "Fase 1: Rilevamento tipo codice RC"
diff -ruN vdr-2.4.4/recording.c vdr-2.4.6/recording.c
--- vdr-2.4.4/recording.c	2019-05-28 23:47:32.000000000 +0200
+++ vdr-2.4.6/recording.c	2020-10-30 17:08:29.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 4.27 2019/05/28 21:47:32 kls Exp $
+ * $Id: recording.c 4.29 2020/10/30 16:08:29 kls Exp $
  */
 
 #include "recording.h"
@@ -1375,6 +1375,7 @@
 private:
   cRecordings *recordings;
   cRecordings *deletedRecordings;
+  int count;
   bool initial;
   void ScanVideoDir(const char *DirName, int LinkLevel = 0, int DirLevel = 0);
 protected:
@@ -1389,6 +1390,7 @@
 {
   recordings = Recordings;
   deletedRecordings = DeletedRecordings;
+  count = 0;
   initial = true;
 }
 
@@ -1401,7 +1403,8 @@
 {
   cStateKey StateKey;
   recordings->Lock(StateKey);
-  initial = recordings->Count() == 0; // no name checking if the list is initially empty
+  count = recordings->Count();
+  initial = count == 0; // no name checking if the list is initially empty
   StateKey.Remove();
   deletedRecordings->Lock(StateKey, true);
   deletedRecordings->Clear();
@@ -1439,6 +1442,10 @@
               if (Recordings) {
                  cStateKey StateKey;
                  Recordings->Lock(StateKey, true);
+                 if (initial && count != recordings->Count()) {
+                    dsyslog("activated name checking for initial read of video directory");
+                    initial = false;
+                    }
                  if (Recordings == deletedRecordings || initial || !Recordings->GetByName(buffer)) {
                     cRecording *r = new cRecording(buffer);
                     if (r->Name()) {
@@ -1448,6 +1455,7 @@
                        if (Recordings == deletedRecordings)
                           r->SetDeleted();
                        Recordings->Add(r);
+                       count = recordings->Count();
                        }
                     else
                        delete r;
@@ -3025,8 +3033,8 @@
            }
         // found a non existing file suffix
         }
-     if (Open() >= 0) {
-        if (!record && Offset >= 0 && file && file->Seek(Offset, SEEK_SET) != Offset) {
+     if (Open()) {
+        if (!record && Offset >= 0 && file->Seek(Offset, SEEK_SET) != Offset) {
            LOG_ERROR_STR(fileName);
            return NULL;
            }
diff -ruN vdr-2.4.4/recording.h vdr-2.4.6/recording.h
--- vdr-2.4.4/recording.h	2020-03-29 17:50:22.000000000 +0200
+++ vdr-2.4.6/recording.h	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.h 4.9 2020/03/29 15:50:22 kls Exp $
+ * $Id: recording.h 4.10 2020/09/16 13:48:33 kls Exp $
  */
 
 #ifndef __RECORDING_H
@@ -390,7 +390,7 @@
        ///< If this cMarks object is used by multiple threads, the caller must Lock()
        ///< it before calling Add() and Unlock() it afterwards. The same applies to
        ///< calls to Del(), or any of the functions that return a "cMark *", in case
-       ///< an other thread might modifiy the list while the returned pointer is
+       ///< an other thread might modify the list while the returned pointer is
        ///< considered valid.
   const cMark *Get(int Position) const;
   const cMark *GetPrev(int Position) const;
diff -ruN vdr-2.4.4/remux.h vdr-2.4.6/remux.h
--- vdr-2.4.4/remux.h	2017-05-21 11:44:52.000000000 +0200
+++ vdr-2.4.6/remux.h	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.h 4.5 2017/05/21 09:44:52 kls Exp $
+ * $Id: remux.h 4.6 2020/09/16 13:48:33 kls Exp $
  */
 
 #ifndef __REMUX_H
@@ -221,7 +221,7 @@
        ///< properly taking into account the 33bit wrap around. If Pts2 is "before"
        ///< Pts1, the result is negative.
 
-// A transprent TS payload handler:
+// A transparent TS payload handler:
 
 class cTsPayload {
 private:
diff -ruN vdr-2.4.4/sections.c vdr-2.4.6/sections.c
--- vdr-2.4.4/sections.c	2019-05-28 16:09:04.000000000 +0200
+++ vdr-2.4.6/sections.c	2020-11-24 22:19:49.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sections.c 4.1 2019/05/28 14:09:04 kls Exp $
+ * $Id: sections.c 4.2 2020/11/24 21:19:49 kls Exp $
  */
 
 #include "sections.h"
@@ -48,7 +48,6 @@
   statusCount = 0;
   on = false;
   waitForLock = false;
-  lastIncompleteSection = 0;
   Start();
 }
 
@@ -212,10 +211,8 @@
                                   fi->Process(pid, tid, buf, len);
                                }
                            }
-                        else if (time(NULL) - lastIncompleteSection > 10) { // log them only every 10 seconds
-                           dsyslog("read incomplete section - len = %d, r = %d", len, r);
-                           lastIncompleteSection = time(NULL);
-                           }
+                        else
+                           dsyslog("tp %d (%d/%02X) read incomplete section - len = %d, r = %d", Transponder(), fh->filterData.pid, buf[0], len, r);
                         }
                      }
                   }
diff -ruN vdr-2.4.4/sections.h vdr-2.4.6/sections.h
--- vdr-2.4.4/sections.h	2005-08-13 13:23:55.000000000 +0200
+++ vdr-2.4.6/sections.h	2020-11-24 22:19:49.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sections.h 4.0 2005/08/13 11:23:55 kls Exp $
+ * $Id: sections.h 4.1 2020/11/24 21:19:49 kls Exp $
  */
 
 #ifndef __SECTIONS_H
@@ -27,7 +27,6 @@
   cDevice *device;
   int statusCount;
   bool on, waitForLock;
-  time_t lastIncompleteSection;
   cList<cFilter> filters;
   cList<cFilterHandle> filterHandles;
   void Add(const cFilterData *FilterData);
diff -ruN vdr-2.4.4/thread.c vdr-2.4.6/thread.c
--- vdr-2.4.4/thread.c	2018-03-05 23:38:10.000000000 +0100
+++ vdr-2.4.6/thread.c	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.c 4.14 2018/03/05 22:38:10 kls Exp $
+ * $Id: thread.c 4.15 2020/09/16 13:48:33 kls Exp $
  */
 
 #include "thread.h"
@@ -184,7 +184,7 @@
      }
   else if (writeLockThreadId == cThread::ThreadId()) {
      locked++; // there can be any number of stacked read locks, so we keep track here
-     Result = 0; // aquiring a read lock while holding a write lock within the same thread is OK
+     Result = 0; // acquiring a read lock while holding a write lock within the same thread is OK
      }
   else
      Result = TimeoutMs ? pthread_rwlock_timedrdlock(&rwlock, &abstime) : pthread_rwlock_rdlock(&rwlock);
diff -ruN vdr-2.4.4/thread.h vdr-2.4.6/thread.h
--- vdr-2.4.4/thread.h	2020-03-29 17:53:48.000000000 +0200
+++ vdr-2.4.6/thread.h	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.h 4.5 2020/03/29 15:53:48 kls Exp $
+ * $Id: thread.h 4.6 2020/09/16 13:48:33 kls Exp $
  */
 
 #ifndef __THREAD_H
@@ -215,7 +215,7 @@
        ///< a write lock.
   void SetSyncStateKey(cStateKey &StateKey);
        ///< Sets the given StateKey to be synchronized to the state of this lock.
-       ///< The caller must currenty hold a write lock on this lock, with a cStateKey
+       ///< The caller must currently hold a write lock on this lock, with a cStateKey
        ///< that is different from the given StateKey. If, when removing the key that
        ///< is holding the write lock, the StateKey's current state is the same as that
        ///< of the lock, it will be increased together with the lock's state.
diff -ruN vdr-2.4.4/timers.c vdr-2.4.6/timers.c
--- vdr-2.4.4/timers.c	2019-05-23 11:46:32.000000000 +0200
+++ vdr-2.4.6/timers.c	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.c 4.19 2019/05/23 09:46:32 kls Exp $
+ * $Id: timers.c 4.20 2020/09/16 13:48:33 kls Exp $
  */
 
 #include "timers.h"
@@ -313,7 +313,7 @@
   //XXX results in an empty string (this first occurred when the EIT gathering
   //XXX was put into a separate thread - don't know why this happens...
   //XXX As a cure we copy the original string and add a blank.
-  //XXX If anybody can shed some light on why sscanf() failes here, I'd love
+  //XXX If anybody can shed some light on why sscanf() fails here, I'd love
   //XXX to hear about that!
   char *s2 = NULL;
   int l2 = strlen(s);
diff -ruN vdr-2.4.4/tools.c vdr-2.4.6/tools.c
--- vdr-2.4.4/tools.c	2020-06-10 22:52:10.000000000 +0200
+++ vdr-2.4.6/tools.c	2020-11-22 14:32:05.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 4.12 2020/06/10 20:52:10 kls Exp $
+ * $Id: tools.c 4.13 2020/11/22 13:32:05 kls Exp $
  */
 
 #include "tools.h"
@@ -1272,15 +1272,15 @@
         }
      else {
         esyslog("ERROR: out of memory");
-        return false;
+        return FALSE;
         }
      if (jcd->mem) {
         cinfo->dest->next_output_byte = jcd->mem + Used;
         cinfo->dest->free_in_buffer = jcd->size - Used;
-        return true;
+        return TRUE;
         }
      }
-  return false;
+  return FALSE;
 }
 
 static void JpegCompressTermDestination(j_compress_ptr cinfo)
@@ -1325,8 +1325,8 @@
   cinfo.in_color_space = JCS_RGB;
 
   jpeg_set_defaults(&cinfo);
-  jpeg_set_quality(&cinfo, Quality, true);
-  jpeg_start_compress(&cinfo, true);
+  jpeg_set_quality(&cinfo, Quality, TRUE);
+  jpeg_start_compress(&cinfo, TRUE);
 
   int rs = Width * 3;
   JSAMPROW rp[Height];
diff -ruN vdr-2.4.4/tools.h vdr-2.4.6/tools.h
--- vdr-2.4.4/tools.h	2020-06-23 17:52:29.000000000 +0200
+++ vdr-2.4.6/tools.h	2020-09-16 15:48:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 4.17 2020/06/23 15:52:29 kls Exp $
+ * $Id: tools.h 4.18 2020/09/16 13:48:33 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -222,7 +222,7 @@
     ///< Returns the value part of a 'name=value' pair in s.
     ///< name must either be at the beginning of s, or has to be preceded by white space.
     ///< There may be any number of white space around the '=' sign. The value is
-    ///< everyting up to (and excluding) the next white space, or the end of s.
+    ///< everything up to (and excluding) the next white space, or the end of s.
     ///< If an other delimiter shall be used (like, e.g., ':'), it can be given
     ///< as the third parameter.
     ///< If name occurs more than once in s, only the first occurrence is taken.
diff -ruN vdr-2.4.4/vdr.c vdr-2.4.6/vdr.c
--- vdr-2.4.4/vdr.c	2020-05-18 18:47:29.000000000 +0200
+++ vdr-2.4.6/vdr.c	2020-11-20 14:49:58.000000000 +0100
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.tvdr.de
  *
- * $Id: vdr.c 4.33 2020/05/18 16:47:29 kls Exp $
+ * $Id: vdr.c 4.34 2020/11/20 13:49:58 kls Exp $
  */
 
 #include <getopt.h>
@@ -422,6 +422,7 @@
                           SysLogLevel = l;
                           if (!p)
                              break;
+                          *p = '.';
                           if (isnumber(p + 1)) {
                              int l = atoi(p + 1);
                              if (0 <= l && l <= 7) {
