diff -ruN vdr-1.7.31/CONTRIBUTORS vdr-1.7.32/CONTRIBUTORS
--- vdr-1.7.31/CONTRIBUTORS	2012-09-29 12:05:49.000000000 +0200
+++ vdr-1.7.32/CONTRIBUTORS	2012-11-18 14:12:31.000000000 +0100
@@ -1757,6 +1757,9 @@
  for adding the option --outputonly to the dvbsddevice plugin
  for adding a missing template specification to the c'tor of cSortedTimers
  for contributing to a patch that implements FHS support
+ for suggesting to check cIoThrottle::Engaged() in cRemoveDeletedRecordingsThread::Action()
+ for suggesting to shift editing marks that don't point to an I-frame towards the next I-frame
+ when a recording is played
 
 Sven Kreiensen <svenk@kammer.uni-hannover.de>
  for his help in keeping 'channels.conf.terr' up to date
@@ -2305,6 +2308,8 @@
  for fixing cRecording::LengthInSeconds(), which wrongfully rounded the result to full
  minutes
  for suggesting to check for NULL in cOsd::AddPixmap()
+ for making modified editing marks be written to disk whenever the replay progress
+ display gets hidden
 
 Pekka Mauno <pekka.mauno@iki.fi>
  for fixing cSchedule::GetFollowingEvent() in case there is currently no present
@@ -2314,6 +2319,8 @@
  for fixing the shutdown timeout
  for making the script given to VDR with the '-r' option be also called whenever a
  recording is deleted
+ for making pressing the Play key during normal live viewing mode open the Recordings
+ menu if there is no "last viewed" recording
 
 Jan Lenz <email@JanLenz.de>
  for reporting a bug in deleting recordings that have been removed externally when
@@ -2618,6 +2625,7 @@
  for reporting a problem with the function cString::sprintf(const char *fmt, va_list &ap),
  that might inadvertently be called with a 'char *' as the second argument on some
  compilers and cause a crash
+ for reporting a possible memory leak in SI::StructureLoop::getNextAsPointer()
 
 Ales Jurik <ajurik@quick.cz>
  for reporting broken SI data on Czech/Slovak channels after changing the default
@@ -2692,6 +2700,7 @@
  several payloads
  for reporting a problem with getting the maximum short channel name length in case there
  are no short names at all
+ for reporting an incompatible change from DTV_DVBT2_PLP_ID to DTV_STREAM_ID in DVB API 5.8
 
 Marcel Unbehaun <frostworks@gmx.de>
  for adding cRecordingInfo::GetEvent()
@@ -2895,6 +2904,7 @@
  in case buffers run full
  for suggesting to increase the size of the TS buffer to 5MB and that of the Recorder
  buffer to 20MB to better handle HD recordings
+ for fixing setting the video format in the dvbhdffdevice
 
 Christian Ruppert <idl0r@gentoo.org>
  for some improvements to the Makefiles
@@ -2960,3 +2970,6 @@
  for a patch that was used to move cleaning up the EPG data and writing the epg.data
  file into a separate thread to avoid sluggish response to user input on slow systems
  for fixing sorting folders before recordings in case of UTF-8
+
+Peter Münster <pmlists@free.fr>
+ for fixing 'make install' to not overwrite existing configuration files
diff -ruN vdr-1.7.31/HISTORY vdr-1.7.32/HISTORY
--- vdr-1.7.31/HISTORY	2012-09-30 13:07:48.000000000 +0200
+++ vdr-1.7.32/HISTORY	2012-11-18 14:11:56.000000000 +0100
@@ -7271,3 +7271,70 @@
   whether a directory is empty. This allows users to continue to use files such as
   ".keep" to prevent a directory from being deleted when it is empty. Currently the
   only file name that is ignored is ".sort".
+
+2012-11-18: Version 1.7.32
+
+- Pressing the Play key during normal live viewing mode now opens the Recordings menu
+  if there is no "last viewed" recording (thanks to Alexander Wenzel).
+  The same behavior has been implemented for the Blue key in the main menu.
+- cIoThrottle::Engaged() is now also checked in cRemoveDeletedRecordingsThread::Action(),
+  to suspend removing deleted recordings in case this is necessary to make room for
+  new, ongoing recordings (suggested by Udo Richter).
+- The cThread constructor now has an additional boolean parameter that can be set to
+  true to have this thread run at a lower priority. Plugin authors that use low
+  priority threads may want to use this instead of the calls to SetPriority(19) and
+  SetIOPriority(7). The priority of a thread ("low" or "high") is now logged when the
+  thread starts.
+- Changed DTV_DVBT2_PLP_ID to DTV_STREAM_ID in dvbdevice.c to adapt to an incompatible
+  change in DVB API 5.8 (reported by Derek Kelly).
+  Removed the meanwhile obsolete definition of FE_CAN_TURBO_FEC.
+- Fixed some compiler warnings under gcc version 4.7.1.
+- Fixed setting the video format in the dvbhdffdevice (thanks to Torsten Lang).
+- Fixed 'make install' to not overwrite existing configuration files (thanks to Peter
+  Münster).
+- Added including the Make.global and Make.config files to the dvbdhffdevice's
+  libhdffcmd/Makefile.
+- Added options to build a 32-bit version of VDR on a 64-bit machine to
+  Make.config.template.
+- Fixed handling VPS timers in case the running status of an event goes to '1' (not
+  running) and later goes to '4' (running).
+- If a frame position in the 'marks' file of a recording doesn't point to an I-frame,
+  it will now be shifted towards the next I-frame, either up or down, whichever is
+  closer (suggested by Udo Richter).
+- Fixed a possible memory leak in SI::StructureLoop::getNextAsPointer() (reported by
+  Sundararaj Reel).
+- Fixed handling timers in case an event is modified and "phased out" while the timer
+  is recording.
+- Improved frame detection by parsing just far enough into the MPEG-4 NAL units to get
+  the necessary information about frames and slices.
+- The initial syncing of the frame detector is now done immediately after the first
+  complete GOP has been seen. This makes recordings and especially pausing live video
+  start up to twice as fast as before.
+- Updated the Romanian OSD texts (thanks to Lucian Muresan).
+- Fixed handling the very last entry in a recording index.
+- The return type of cMarks::Add() has been changed to void, since due to the sorting
+  of the list of marks the returned pointer might have pointed to a totally different
+  mark. Besides, the return value was never actually used.
+- Improved editing TS recordings by
+  + stripping dangling TS packets from the beginning of a sequence
+  + including pending TS packets at the end of a sequence
+  + fixing all timestamps and continuity counters
+  + generating editing marks for the edited version in such a way that each cutting
+    point is marked by an "end" and "begin" mark with the same offset
+  + no longer generating an editing mark at the "end" of the edited recording (this
+    was actually generated at the beginning of the last GOP, so that a subsequent
+    edit would have cut off the last GOP)
+  + no longer generating any editing marks if the edited recording results on just
+    one single sequence
+  + ignoring pairs of editing marks that are placed at exactly the same position of
+    a recording when actually cutting the recording
+  + not doing anything if the editing marks in place would result in the edited
+    version being the same as the original recording
+- Editing marks can now be placed directly on top of each other, in which case they
+  simply mark a position, but have no effect on the actual cutting process.
+- When positioned at an offset where two (or more) editing marks are placed on top
+  of each other, the '4' key moves the first one of them to the left, while the '6'
+  key moves the last one of them to the right. The '7' and '9' key handle multiple
+  marks at the same place as if it were one single mark.
+- Modified editing marks are now written to disk whenever the replay progress display
+  gets hidden (thanks to Christoph Haubrich).
diff -ruN vdr-1.7.31/INSTALL vdr-1.7.32/INSTALL
--- vdr-1.7.31/INSTALL	2012-09-17 11:00:43.000000000 +0200
+++ vdr-1.7.32/INSTALL	2012-10-09 12:43:28.000000000 +0200
@@ -36,6 +36,10 @@
 named 'vdr', which can be run after the DVB driver has been
 installed.
 
+If you want to build a 32-bit version of VDR on a 64-bit machine, you can
+use 'make M32=1' to do so. Note that you also need to have a Make.config file
+(derived from Make.config.template) to make this work.
+
 IMPORTANT: See "Configuration files" below for information on how
 =========  to set up the configuration files at the proper location!
 
diff -ruN vdr-1.7.31/MANUAL vdr-1.7.32/MANUAL
--- vdr-1.7.31/MANUAL	2012-09-15 15:50:06.000000000 +0200
+++ vdr-1.7.32/MANUAL	2012-11-13 13:09:38.000000000 +0100
@@ -367,13 +367,13 @@
   - 7, 9    Jump back and forward between editing marks. Replay goes into still
             mode after jumping to a mark.
   - 8       Positions replay at a point 3 seconds before the current or next
-            "start" mark and starts replay.
+            "begin" mark and starts replay.
   - 2       Start the actual cutting process.
 
   Editing marks are represented by black, vertical lines in the progress display.
-  A small black triangle at the top of the mark means that this is a "start"
+  A small black triangle at the top of the mark means that this is a "begin"
   mark, and a triangle at the bottom means that this is an "end" mark.
-  The cutting process will save all video data between "start" and "end" marks
+  The cutting process will save all video data between "begin" and "end" marks
   into a new file (the original recording remains untouched). The new file will
   have the same name as the original recording, preceded with a '%' character
   (imagine the '%' somehow looking like a pair of scissors ;-). Red bars in the
@@ -382,7 +382,7 @@
 
   The video sequences to be saved by the cutting process are determined by an
   "even/odd" algorithm. This means that every odd numbered editing mark (i.e.
-  1, 3, 5,...) represents a "start" mark, while every even numbered mark (2, 4,
+  1, 3, 5,...) represents a "begin" mark, while every even numbered mark (2, 4,
   6,...) is an "end" mark. Inserting or toggling a mark on or off automatically
   adjusts the sequence to the right side of that mark.
 
@@ -395,11 +395,13 @@
   version of the recording you can use the '8' key to jump to a point just
   before the next cut and have a look at the resulting sequence.
 
-  Currently editing marks can only be set at I-frames, which typically is
-  every 12th frame. So editing can be done with a resolution of roughly half
-  a second. A "start" mark marks the first frame of a resulting video
-  sequence, and an "end" mark marks the last frame of that sequence.
-
+  Currently editing marks can only be set at I-frames, which typically appear
+  every half of a second to a second.  A "begin" mark marks the first frame of
+  a resulting video sequence, and an "end" mark marks the last frame of that
+  sequence.  Note that the actual frame indicated by the an "end" mark will
+  not be included in the edited version of the recording. That's because every
+  recording (and every sequence of an edited recording) begins with an I-frame
+  and ends right before the next I-frame.
   An edited recording (indicated by the '%' character) will never be deleted
   automatically in case the disk runs full (no matter what "lifetime" it has).
 
diff -ruN vdr-1.7.31/Make.config.template vdr-1.7.32/Make.config.template
--- vdr-1.7.31/Make.config.template	2012-09-01 12:31:33.000000000 +0200
+++ vdr-1.7.32/Make.config.template	2012-10-09 12:32:32.000000000 +0200
@@ -6,7 +6,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Make.config.template 2.9 2012/09/01 10:31:33 kls Exp $
+# $Id: Make.config.template 2.10 2012/10/09 10:32:32 kls Exp $
 
 ### The C compiler and options:
 
@@ -21,6 +21,12 @@
 CXXFLAGS += -fPIC
 endif
 
+# Use 'make M32=1 ...' to build a 32-bit version of VDR on a 64-bit machine:
+ifdef M32
+CFLAGS   += -m32
+CXXFLAGS += -m32
+endif
+
 ### The directory environment:
 
 PREFIX   = $(DESTDIR)/usr/local
diff -ruN vdr-1.7.31/Makefile vdr-1.7.32/Makefile
--- vdr-1.7.31/Makefile	2012-09-07 16:11:37.000000000 +0200
+++ vdr-1.7.32/Makefile	2012-10-09 10:32:25.000000000 +0200
@@ -4,7 +4,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Makefile 2.29 2012/09/07 14:11:37 kls Exp $
+# $Id: Makefile 2.30 2012/10/09 08:32:25 kls Exp $
 
 .DELETE_ON_ERROR:
 
@@ -211,7 +211,7 @@
 	@mkdir -p $(DESTDIR)$(RESDIRDEF)
 
 install-conf:
-	@cp *.conf $(DESTDIR)$(CONFDIRDEF)
+	@cp -n *.conf $(DESTDIR)$(CONFDIRDEF)
 
 
 # Documentation:
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/dvbhdffdevice.c vdr-1.7.32/PLUGINS/src/dvbhddevice/dvbhdffdevice.c
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/dvbhdffdevice.c	2012-05-08 13:40:32.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/dvbhdffdevice.c	2012-11-15 10:19:10.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbhdffdevice.c 1.43 2012/05/08 11:40:32 kls Exp $
+ * $Id: dvbhdffdevice.c 1.46 2012/11/15 09:19:10 kls Exp $
  */
 
 #include <stdint.h>
@@ -69,6 +69,7 @@
 
      mHdffCmdIf->CmdAvSetAudioDelay(gHdffSetup.AudioDelay);
      mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) gHdffSetup.AudioDownmix);
+     mHdffCmdIf->CmdAvSetSyncShift(gHdffSetup.AvSyncShift);
      mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) gHdffSetup.AnalogueVideo);
      mHdffCmdIf->CmdHdmiSetVideoMode(gHdffSetup.GetVideoMode());
 
@@ -136,7 +137,7 @@
 {
   HdffVideoFormat_t videoFormat;
   videoFormat.AutomaticEnabled = true;
-  videoFormat.AfdEnabled = true;
+  videoFormat.AfdEnabled = false;
   videoFormat.TvFormat = (HdffTvFormat_t) gHdffSetup.TvFormat;
   videoFormat.VideoConversion = (HdffVideoConversion_t) gHdffSetup.VideoConversion;
   mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat);
@@ -375,62 +376,86 @@
 
 bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode)
 {
-  if (PlayMode == pmNone) {
-     mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
-     mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
-
-     mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
-     mHdffCmdIf->CmdAvSetPcrPid(0, 0);
-     mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
-     mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
-
-     ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
-     mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
-     mHdffCmdIf->CmdAvEnableSync(0, true);
-     mHdffCmdIf->CmdAvSetPlayMode(0, true);
-     }
-  else {
-     if (playMode == pmNone)
-        TurnOffLiveMode(true);
+    if (PlayMode == pmNone) {
+        if (fd_video == -1)
+            fd_video = DvbOpen(DEV_DVB_VIDEO,  adapter, frontend, O_RDWR | O_NONBLOCK);
+        if (fd_audio == -1)
+            fd_audio = DvbOpen(DEV_DVB_AUDIO,  adapter, frontend, O_RDWR | O_NONBLOCK);
+
+        mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+        mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+
+        mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
+        mHdffCmdIf->CmdAvSetPcrPid(0, 0);
+        mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
+        mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+
+        ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
+        mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
+        mHdffCmdIf->CmdAvEnableSync(0, true);
+        mHdffCmdIf->CmdAvSetPlayMode(0, true);
+    }
+    else {
+        if (playMode == pmNone)
+            TurnOffLiveMode(true);
 
-     mHdffCmdIf->CmdAvSetPlayMode(1, Transferring() || (cTransferControl::ReceiverDevice() == this));
-     mHdffCmdIf->CmdAvSetStc(0, 100000);
-     mHdffCmdIf->CmdAvEnableSync(0, true);
-     mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);
-
-     playVideoPid = -1;
-     playAudioPid = -1;
-     audioCounter = 0;
-     videoCounter = 0;
-     freezed = false;
-     trickMode = false;
-
-     mHdffCmdIf->CmdAvSetDecoderInput(0, 2);
-     ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
-     }
-  playMode = PlayMode;
-  return true;
+        if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
+        {
+            close(fd_video);
+            fd_video = -1;
+            close(fd_audio);
+            fd_audio = -1;
+        }
+        else
+        {
+            mHdffCmdIf->CmdAvSetPlayMode(1, Transferring() || (cTransferControl::ReceiverDevice() == this));
+            mHdffCmdIf->CmdAvSetStc(0, 100000);
+            mHdffCmdIf->CmdAvEnableSync(0, false);
+            mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);
+
+            playVideoPid = -1;
+            playAudioPid = -1;
+            audioCounter = 0;
+            videoCounter = 0;
+            freezed = false;
+            trickMode = false;
+            isPlayingVideo = false;
+
+            mHdffCmdIf->CmdAvSetDecoderInput(0, 2);
+            ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
+	}
+    }
+    playMode = PlayMode;
+    return true;
 }
 
 int64_t cDvbHdFfDevice::GetSTC(void)
 {
-  if (fd_video >= 0) {
-     uint64_t pts;
-     if (ioctl(fd_video, VIDEO_GET_PTS, &pts) == -1) {
-        esyslog("ERROR: pts %d: %m", CardIndex() + 1);
-        return -1;
+    if (isPlayingVideo)
+    {
+        if (fd_video >= 0) {
+            uint64_t pts;
+            if (ioctl(fd_video, VIDEO_GET_PTS, &pts) == -1) {
+                esyslog("ERROR: pts %d: %m", CardIndex() + 1);
+                return -1;
+            }
+            //printf("video PTS %lld\n", pts);
+            return pts;
         }
-     return pts;
-     }
-  if (fd_audio >= 0) {
-     uint64_t pts;
-     if (ioctl(fd_audio, AUDIO_GET_PTS, &pts) == -1) {
-        esyslog("ERROR: pts %d: %m", CardIndex() + 1);
-        return -1;
+    }
+    else
+    {
+        if (fd_audio >= 0) {
+            uint64_t pts;
+            if (ioctl(fd_audio, AUDIO_GET_PTS, &pts) == -1) {
+                esyslog("ERROR: pts %d: %m", CardIndex() + 1);
+                return -1;
+            }
+            //printf("audio PTS %lld\n", pts);
+            return pts;
         }
-     return pts;
-     }
-  return -1;
+    }
+    return -1;
 }
 
 void cDvbHdFfDevice::TrickSpeed(int Speed)
@@ -456,12 +481,13 @@
 
 void cDvbHdFfDevice::Play(void)
 {
-  freezed = false;
-  trickMode = false;
-  mHdffCmdIf->CmdAvEnableSync(0, true);
-  mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
-  mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
-  cDevice::Play();
+    freezed = false;
+    trickMode = false;
+    if (isPlayingVideo)
+        mHdffCmdIf->CmdAvEnableSync(0, true);
+    mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+    mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+    cDevice::Play();
 }
 
 void cDvbHdFfDevice::Freeze(void)
@@ -631,6 +657,11 @@
 {
     if (freezed)
         return -1;
+    if (!isPlayingVideo)
+    {
+        mHdffCmdIf->CmdAvEnableSync(0, true);
+        isPlayingVideo = true;
+    }
     //TODO: support greater Length
     uint8_t tsBuffer[188 * 16];
     uint32_t tsLength;
@@ -651,8 +682,6 @@
 {
     if (freezed)
         return -1;
-    if (trickMode)
-        return Length;
     uint8_t streamId;
     uint8_t tsBuffer[188 * 16];
     uint32_t tsLength;
@@ -702,17 +731,23 @@
 
 int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length)
 {
-  if (freezed)
-    return -1;
-  int pid = TsPid(Data);
-  if (pid != playVideoPid) {
-     PatPmtParser();
-     if (pid == PatPmtParser()->Vpid()) {
-        playVideoPid = pid;
-        mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true);
+    if (freezed)
+        return -1;
+    if (!isPlayingVideo)
+    {
+        mHdffCmdIf->CmdAvEnableSync(0, true);
+        isPlayingVideo = true;
+    }
+
+    int pid = TsPid(Data);
+    if (pid != playVideoPid) {
+        PatPmtParser();
+        if (pid == PatPmtParser()->Vpid()) {
+            playVideoPid = pid;
+            mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true);
         }
-     }
-  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+    }
+    return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
 }
 
 static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
@@ -732,8 +767,6 @@
 {
   if (freezed)
     return -1;
-  if (trickMode)
-    return Length;
   int pid = TsPid(Data);
   if (pid != playAudioPid) {
      playAudioPid = pid;
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/dvbhdffdevice.h vdr-1.7.32/PLUGINS/src/dvbhddevice/dvbhdffdevice.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/dvbhdffdevice.h	2011-09-10 12:17:32.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/dvbhdffdevice.h	2012-11-05 09:49:29.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbhdffdevice.h 1.7 2011/09/10 10:17:32 kls Exp $
+ * $Id: dvbhdffdevice.h 1.8 2012/11/05 08:49:29 kls Exp $
  */
 
 #ifndef __DVBHDFFDEVICE_H
@@ -81,6 +81,7 @@
   int playAudioPid;
   bool freezed;
   bool trickMode;
+  bool isPlayingVideo;
 
   // Pes2Ts conversion stuff
   uint8_t videoCounter;
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffcmd.c vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffcmd.c
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffcmd.c	2012-06-16 13:16:38.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffcmd.c	2012-11-15 10:19:47.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: hdffcmd.c 1.25 2012/06/16 11:16:38 kls Exp $
+ * $Id: hdffcmd.c 1.26 2012/11/15 09:19:47 kls Exp $
  */
 
 #include <stdint.h>
@@ -170,6 +170,11 @@
     HdffCmdAvSetAudioChannel(mOsdDev, AudioChannel);
 }
 
+void cHdffCmdIf::CmdAvSetSyncShift(int16_t SyncShift)
+{
+    HdffCmdAvSetSyncShift(mOsdDev, SyncShift);
+}
+
 
 void cHdffCmdIf::CmdOsdConfigure(const HdffOsdConfig_t * pConfig)
 {
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffcmd.h vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffcmd.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffcmd.h	2012-06-16 13:16:52.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffcmd.h	2012-11-15 10:20:05.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: hdffcmd.h 1.20 2012/06/16 11:16:52 kls Exp $
+ * $Id: hdffcmd.h 1.21 2012/11/15 09:20:05 kls Exp $
  */
 
 #ifndef _HDFF_CMD_H_
@@ -47,6 +47,7 @@
     void CmdAvSetAudioDelay(int16_t Delay);
     void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode);
     void CmdAvSetAudioChannel(uint8_t AudioChannel);
+    void CmdAvSetSyncShift(int16_t SyncShift);
 
     void CmdOsdConfigure(const HdffOsdConfig_t * pConfig);
     void CmdOsdReset(void);
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffmsgdef.h vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffmsgdef.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffmsgdef.h	2011-08-27 11:34:43.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffmsgdef.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,313 +0,0 @@
-/*
- * hdffmsgdef.h: TODO(short description)
- *
- * See the README file for copyright information and how to reach the author.
- *
- * $Id: hdffmsgdef.h 1.13 2011/08/27 09:34:43 kls Exp $
- */
-
-#ifndef _HDFF_MSGDEF_H_
-#define _HDFF_MSGDEF_H_
-
-#define MAX_CMD_LEN 1536
-
-namespace HDFF
-{
-
-typedef enum _eMessageType
-{
-    msgTypeCommand,
-    msgTypeAnswer,
-    msgTypeResult,
-    msgTypeEvent
-} eMessageType;
-
-typedef enum _eMessageGroup
-{
-    msgGroupGeneric,
-    msgGroupAvDec,
-    msgGroupAvMux,
-    msgGroupFrontend,
-    msgGroupOsd,
-    msgGroupHdmi,
-    msgGroupRemoteControl
-} eMessageGroup;
-
-typedef enum _eMessageId
-{
-    msgGenGetFirmwareVersion = 0,
-    msgGenGetInterfaceVersion,
-    msgGenGetCopyrights,
-
-    msgAvSetAudioPid = 0,
-    msgAvSetVideoPid,
-    msgAvSetPcrPid,
-    msgAvSetTeletextPid,
-    msgAvShowStillImage,
-    msgAvSetVideoWindow,
-    msgAvSetDecoderInput,
-    msgAvSetDemultiplexerInput,
-    msgAvSetVideoFormat,
-    msgAvSetVideoOutputMode,
-    msgAvSetStc,
-    msgAvFlushBuffer,
-    msgAvEnableSync,
-    msgAvSetVideoSpeed,
-    msgAvSetAudioSpeed,
-    msgAvEnableVideoAfterStop,
-    msgAvGetVideoFormatInfo,
-    msgAvSetAudioDelay,
-    msgAvSetAudioDownmix,
-    msgAvSetAudioChannel,
-    msgAvSetPlayMode,
-
-    msgMuxSetVideoOut = 0,
-    msgMuxSetSlowBlank,
-    msgMuxSetFastBlank,
-    msgMuxSetVolume,
-    msgMuxSetAudioMute,
-
-    msgOsdConfigure = 0,
-    msgOsdReset,
-    msgOsdCreateDisplay = 10,
-    msgOsdDeleteDisplay,
-    msgOsdEnableDisplay,
-    msgOsdSetDisplayOutputRectangle,
-    msgOsdSetDisplayClippingArea,
-    msgOsdRenderDisplay,
-    msgOsdSaveRegion,
-    msgOsdRestoreRegion,
-    msgOsdCreatePalette = 30,
-    msgOsdDeletePalette,
-    msgOsdSetDisplayPalette,
-    msgOsdSetPaletteColors,
-    msgOsdCreateFontFace = 50,
-    msgOsdDeleteFontFace,
-    msgOsdCreateFont,
-    msgOsdDeleteFont,
-    msgOsdDrawPixel = 70,
-    msgOsdDrawRectangle,
-    msgOsdDrawCircle,
-    msgOsdDrawEllipse,
-    msgOsdDrawSlope,
-    msgOsdDrawText,
-    msgOsdDrawTextW,
-    msgOsdDrawBitmap,
-
-    msgHdmiEnableOutput = 0,
-    msgHdmiSetVideoMode,
-    msgHdmiConfigure,
-    msgHdmiIsDisplayConnected,
-    msgHdmiGetDisplayInfo,
-    msgHdmiGetVideoMode,
-    msgHdmiSendCecCommand,
-
-    msgRemoteSetProtocol = 0,
-    msgRemoteSetAddressFilter,
-    msgRemoteKeyEvent
-} eMessageId;
-
-
-// AvDec definitions
-
-typedef enum _eAVContainerType
-{
-    avContainerPes,
-    avContainerPesDvd,
-    avContainerMaxValue
-} eAVContainerType;
-
-typedef enum _eAudioStreamType
-{
-    audioStreamMpeg1,
-    audioStreamMpeg2,
-    audioStreamAc3,
-    audioStreamAac,
-    audioStreamHeAac,
-    audioStreamPcm,
-    audioStreamEAc3,
-    audioStreamDts,
-    audioStreamMaxValue
-} eAudioStreamType;
-
-typedef enum _eVideoStreamType
-{
-    videoStreamMpeg1,
-    videoStreamMpeg2,
-    videoStreamH264,
-    videoStreamMpeg4Asp,
-    videoStreamVc1,
-    videoStreamMaxValue
-} eVideoStreamType;
-
-
-typedef enum _eTvFormat
-{
-    tvFormat4by3,
-    tvFormat16by9,
-    tvFormatMaxValue
-} eTvFormat;
-
-typedef enum _eVideoConversion
-{
-    videoConversionAutomatic,
-    videoConversionLetterbox16by9,
-    videoConversionLetterbox14by9,
-    videoConversionPillarbox,
-    videoConversionCentreCutOut,
-    videoConversionAlways16by9,
-    videoConversionMaxValue
-} eVideoConversion;
-
-typedef struct _tVideoFormat
-{
-    bool AutomaticEnabled;
-    bool AfdEnabled;
-    eTvFormat TvFormat;
-    eVideoConversion VideoConversion;
-} tVideoFormat;
-
-typedef enum _eVideoOutputMode
-{
-    videoOutputClone,
-    videoOutputDualView,
-    videoOutputMaxValue
-} eVideoOutputMode;
-
-typedef enum _eDownmixMode
-{
-    downmixOff,
-    downmixAnalog,
-    downmixAlways,
-    downmixAutomatic,
-    downmixHdmi
-} eDownmixMode;
-
-// AvMux definitions
-
-typedef enum _eVideoOut
-{
-    videoOutDisabled,
-    videoOutRgb,
-    videoOutCvbsYuv,
-    videoOutYc,
-    videoOutMaxValue
-} eVideoOut;
-
-typedef enum _eSlowBlank
-{
-    slowBlankOff,
-    slowBlank16by9,
-    slowBlank4by3,
-    slowBlankMaxValue
-} eSlowBlank;
-
-typedef enum _eFastBlank
-{
-    fastBlankCvbs,
-    fastBlankRgb,
-    fastBlankMaxValue
-} eFastBlank;
-
-
-// OSD definitions
-
-#define InvalidHandle           0xFFFFFFFF
-#define ScreenDisplayHandle     0xFFFFFFFE
-
-#define PositionScreenCentered  0xFFFF
-
-#define SizeFullScreen    0xFFFF
-#define SizeSameAsSource  0xFFFE
-
-#define FontFaceTiresias  0x00000000
-
-typedef enum _eColorType
-{
-    colorTypeClut1,
-    colorTypeClut2,
-    colorTypeClut4,
-    colorTypeClut8,
-    colorTypeARGB8888,
-    colorTypeARGB8565,
-    colorTypeARGB4444,
-    colorTypeARGB1555,
-} eColorType;
-
-typedef enum _eColorFormat
-{
-    colorFormatARGB,
-    colorFormatACbYCr,
-} eColorFormat;
-
-typedef enum _eDrawingFlags
-{
-    drawFull,
-    drawHalfTop,
-    drawHalfLeft,
-    drawHalfBottom,
-    drawHalfRight,
-    drawQuarterTopLeft,
-    drawQuarterTopRight,
-    drawQuarterBottomLeft,
-    drawQuarterBottomRight,
-    drawQuarterTopLeftInverted,
-    drawQuarterTopRightInverted,
-    drawQuarterBottomLeftInverted,
-    drawQuarterBottomRightInverted
-} eDrawingFlags;
-
-typedef struct _tOsdConfig
-{
-    bool FontAntialiasing;
-    bool FontKerning;
-} tOsdConfig;
-
-// HDMI definitions
-
-typedef enum _eHdmiVideoMode
-{
-    videoMode576p50 = 18,
-    videoMode720p50 = 19,
-    videoMode1080i50 = 20,
-    videoMode576i50 = 22,
-    videoModeMaxValue
-} eHdmiVideoMode;
-
-typedef enum _eVideoModeAdaption
-{
-    videoModeAdaptOff,
-    videoModeAdaptFrameRate,
-    videoModeAdaptOnlyForHd,
-    videoModeAdaptAlways
-} eVideoModeAdaption;
-
-typedef enum _eCecCommand
-{
-    cecCommandTvOn,
-    cecCommandTvOff,
-    cecCommandActiveSource,
-    cecCommandInactiveSource
-} eCecCommand;
-
-typedef struct _tHdmiConfig
-{
-    bool TransmitAudio;
-    bool ForceDviMode;
-    bool CecEnabled;
-    eVideoModeAdaption VideoModeAdaption;
-} tHdmiConfig;
-
-// Remote control definitions
-
-typedef enum _eRemoteProtocol
-{
-    remoteProtocolNone,
-    remoteProtocolRc5,
-    remoteProtocolRc6,
-    remoteProtocolMaxValue
-} eRemoteProtocol;
-
-} // end of namespace
-
-#endif
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffosd.c vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffosd.c
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/hdffosd.c	2012-06-16 13:17:11.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/hdffosd.c	2012-11-15 10:20:24.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: hdffosd.c 1.17 2012/06/16 11:17:11 kls Exp $
+ * $Id: hdffosd.c 1.18 2012/11/15 09:20:24 kls Exp $
  */
 
 #include "hdffosd.h"
@@ -390,11 +390,13 @@
             }
         }
     }
+#if 0
     if (mSupportsUtf8Text)
     {
         mHdffCmdIf->CmdOsdDrawUtf8Text(mDisplay, pFont->Handle, x + mLeft, y + mTop + h, s, ColorFg);
     }
     else
+#endif
     {
         uint16_t tmp[1000];
         uint16_t len = 0;
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile	2012-01-18 13:25:20.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile	2012-10-09 11:54:26.000000000 +0200
@@ -24,6 +24,18 @@
 AR      ?= ar
 ARFLAGS ?= r
 
+### The directory environment:
+
+VDRDIR ?= ../../../..
+
+### Make sure that necessary options are included:
+
+include $(VDRDIR)/Make.global
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
 ### Implicit rules:
 
 %.o: %.c
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c	2011-10-16 17:12:49.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c	2012-11-13 21:19:39.000000000 +0100
@@ -449,3 +449,22 @@
     osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
     return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
 }
+
+int HdffCmdAvSetSyncShift(int OsdDevice, int16_t SyncShift)
+{
+    uint8_t cmdData[16];
+    BitBuffer_t cmdBuf;
+    osd_raw_cmd_t osd_cmd;
+
+    BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+    memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+    osd_cmd.cmd_data = cmdData;
+    HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+                       HDFF_MSG_GROUP_AV_DECODER,
+                       HDFF_MSG_AV_SET_OPTIONS);
+    BitBuffer_SetBits(&cmdBuf, 1, 1);
+    BitBuffer_SetBits(&cmdBuf, 31, 0); // reserved
+    BitBuffer_SetBits(&cmdBuf, 16, SyncShift);
+    osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+    return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h	2012-02-05 20:25:33.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h	2012-11-13 21:19:39.000000000 +0100
@@ -149,4 +149,6 @@
 
 int HdffCmdAvSetAudioChannel(int OsdDevice, uint8_t AudioChannel);
 
+int HdffCmdAvSetSyncShift(int OsdDevice, int16_t SyncShift);
+
 #endif /* HDFFCMD_AV_H */
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h	2012-06-14 20:59:28.000000000 +0200
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h	2012-11-13 21:19:39.000000000 +0100
@@ -70,6 +70,7 @@
     HDFF_MSG_AV_SET_AUDIO_DOWNMIX,
     HDFF_MSG_AV_SET_AUDIO_CHANNEL,
     HDFF_MSG_AV_SET_PLAY_MODE,
+    HDFF_MSG_AV_SET_OPTIONS,
 
     HDFF_MSG_MUX_SET_VIDEO_OUT = 0,
     HDFF_MSG_MUX_SET_SLOW_BLANK,
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/po/de_DE.po vdr-1.7.32/PLUGINS/src/dvbhddevice/po/de_DE.po
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/po/de_DE.po	2012-02-08 16:15:13.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/po/de_DE.po	2012-11-15 10:23:02.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR \n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-02-07 20:13+0100\n"
+"POT-Creation-Date: 2012-11-13 20:08+0100\n"
 "PO-Revision-Date: 2011-04-25 21:44+0200\n"
 "Last-Translator: Christoph Haubrich\n"
 "Language-Team: <see README>\n"
@@ -91,6 +91,9 @@
 msgid "Audio Downmix"
 msgstr "Audio Downmix"
 
+msgid "A/V Sync Shift (ms)"
+msgstr "A/V-Sync Verschiebung (ms)"
+
 msgid "OSD Size"
 msgstr "OSD GrÃ¶ÃŸe"
 
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/po/fi_FI.po vdr-1.7.32/PLUGINS/src/dvbhddevice/po/fi_FI.po
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/po/fi_FI.po	2012-03-18 16:30:03.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/po/fi_FI.po	2012-11-15 10:23:02.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR \n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-02-07 20:13+0100\n"
+"POT-Creation-Date: 2012-11-13 20:08+0100\n"
 "PO-Revision-Date: 2011-04-25 21:44+0200\n"
 "Last-Translator: Rolf Ahrenberg\n"
 "Language-Team: Finnish <vdr@linuxtv.org>\n"
@@ -91,6 +91,9 @@
 msgid "Audio Downmix"
 msgstr "Ã„Ã¤nen alasmiksaus"
 
+msgid "A/V Sync Shift (ms)"
+msgstr ""
+
 msgid "OSD Size"
 msgstr "KuvaruutunÃ¤ytÃ¶n koko"
 
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/po/it_IT.po vdr-1.7.32/PLUGINS/src/dvbhddevice/po/it_IT.po
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/po/it_IT.po	2012-02-08 16:15:13.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/po/it_IT.po	2012-11-15 10:23:02.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-02-07 20:13+0100\n"
+"POT-Creation-Date: 2012-11-13 20:08+0100\n"
 "PO-Revision-Date: 2011-07-10 00:23+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
 "Language-Team:  <see README>\n"
@@ -94,6 +94,9 @@
 msgid "Audio Downmix"
 msgstr "Scala Audio"
 
+msgid "A/V Sync Shift (ms)"
+msgstr ""
+
 msgid "OSD Size"
 msgstr "Dimensione OSD"
 
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/setup.c vdr-1.7.32/PLUGINS/src/dvbhddevice/setup.c
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/setup.c	2012-02-08 16:14:01.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/setup.c	2012-11-15 10:20:50.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: setup.c 1.17 2012/02/08 15:14:01 kls Exp $
+ * $Id: setup.c 1.18 2012/11/15 09:20:50 kls Exp $
  */
 
 #include "setup.h"
@@ -26,6 +26,7 @@
     AnalogueVideo = HDFF_VIDEO_OUT_CVBS_YUV;
     AudioDelay = 0;
     AudioDownmix = HDFF_AUDIO_DOWNMIX_AUTOMATIC;
+    AvSyncShift = 0;
     OsdSize = 0;
     CecEnabled = 1;
     CecTvOn = 1;
@@ -46,6 +47,7 @@
     else if (strcmp(Name, "AnalogueVideo")     == 0) AnalogueVideo     = atoi(Value);
     else if (strcmp(Name, "AudioDelay")        == 0) AudioDelay        = atoi(Value);
     else if (strcmp(Name, "AudioDownmix")      == 0) AudioDownmix      = atoi(Value);
+    else if (strcmp(Name, "AvSyncShift")       == 0) AvSyncShift       = atoi(Value);
     else if (strcmp(Name, "OsdSize")           == 0) OsdSize           = atoi(Value);
     else if (strcmp(Name, "CecEnabled")        == 0) CecEnabled        = atoi(Value);
     else if (strcmp(Name, "CecTvOn")           == 0) CecTvOn           = atoi(Value);
@@ -256,6 +258,7 @@
     Add(new cMenuEditStraItem(tr("Analogue Video"), &mNewHdffSetup.AnalogueVideo, kAnalogueVideos, AnalogueVideoItems));
     Add(new cMenuEditIntItem(tr("Audio Delay (ms)"), &mNewHdffSetup.AudioDelay, 0, 500));
     Add(new cMenuEditStraItem(tr("Audio Downmix"), &mNewHdffSetup.AudioDownmix, kAudioDownmixes, AudioDownmixItems));
+    Add(new cMenuEditIntItem(tr("A/V Sync Shift (ms)"), &mNewHdffSetup.AvSyncShift, -500, 500));
     Add(new cMenuEditStraItem(tr("OSD Size"), &mNewHdffSetup.OsdSize, kOsdSizes, OsdSizeItems));
     Add(new cMenuEditBoolItem(tr("HDMI CEC"), &mNewHdffSetup.CecEnabled));
     Add(new cMenuEditBoolItem(tr("CEC: Switch TV on"), &mNewHdffSetup.CecTvOn));
@@ -385,6 +388,7 @@
     SetupStore("AnalogueVideo", mNewHdffSetup.AnalogueVideo);
     SetupStore("AudioDelay", mNewHdffSetup.AudioDelay);
     SetupStore("AudioDownmix", mNewHdffSetup.AudioDownmix);
+    SetupStore("AvSyncShift", mNewHdffSetup.AvSyncShift);
     SetupStore("OsdSize", mNewHdffSetup.OsdSize);
     SetupStore("CecEnabled", mNewHdffSetup.CecEnabled);
     SetupStore("CecTvOn", mNewHdffSetup.CecTvOn);
@@ -412,6 +416,7 @@
 
         mHdffCmdIf->CmdAvSetAudioDelay(mNewHdffSetup.AudioDelay);
         mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) mNewHdffSetup.AudioDownmix);
+        mHdffCmdIf->CmdAvSetSyncShift(mNewHdffSetup.AvSyncShift);
 
         mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) mNewHdffSetup.AnalogueVideo);
 
diff -ruN vdr-1.7.31/PLUGINS/src/dvbhddevice/setup.h vdr-1.7.32/PLUGINS/src/dvbhddevice/setup.h
--- vdr-1.7.31/PLUGINS/src/dvbhddevice/setup.h	2012-02-08 16:14:56.000000000 +0100
+++ vdr-1.7.32/PLUGINS/src/dvbhddevice/setup.h	2012-11-15 10:21:07.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: setup.h 1.12 2012/02/08 15:14:56 kls Exp $
+ * $Id: setup.h 1.13 2012/11/15 09:21:07 kls Exp $
  */
 
 #ifndef _HDFF_SETUP_H_
@@ -28,6 +28,7 @@
     int AnalogueVideo;
     int AudioDelay;
     int AudioDownmix;
+    int AvSyncShift;
     int OsdSize;
     int CecEnabled;
     int CecTvOn;
diff -ruN vdr-1.7.31/ci.c vdr-1.7.32/ci.c
--- vdr-1.7.31/ci.c	2012-05-29 13:13:40.000000000 +0200
+++ vdr-1.7.32/ci.c	2012-10-07 13:11: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 2.9 2012/05/29 11:13:40 kls Exp $
+ * $Id: ci.c 2.10 2012/10/07 11:11:18 kls Exp $
  */
 
 #include "ci.h"
@@ -845,9 +845,9 @@
      int D = tm_gmt.tm_mday;
      int L = (M == 1 || M == 2) ? 1 : 0;
      int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
-#define DEC2BCD(d) (((d / 10) << 4) + (d % 10))
+#define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10))
      struct tTime { uint16_t mjd; uint8_t h, m, s; short offset; };
-     tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : htons(tm_loc.tm_gmtoff / 60) };
+     tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) };
      bool OldDumpTPDUDataTransfer = DumpTPDUDataTransfer;
      DumpTPDUDataTransfer &= DumpDateTime;
      if (DumpDateTime)
diff -ruN vdr-1.7.31/config.h vdr-1.7.32/config.h
--- vdr-1.7.31/config.h	2012-09-15 13:51:54.000000000 +0200
+++ vdr-1.7.32/config.h	2012-10-03 11:59:34.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 2.53 2012/09/15 11:51:54 kls Exp $
+ * $Id: config.h 2.54 2012/10/03 09:59:34 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "1.7.31"
-#define VDRVERSNUM   10731  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.7.32"
+#define VDRVERSNUM   10732  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "1.7.31"
-#define APIVERSNUM   10731  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "1.7.32"
+#define APIVERSNUM   10732  // 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-1.7.31/cutter.c vdr-1.7.32/cutter.c
--- vdr-1.7.31/cutter.c	2012-09-20 11:12:47.000000000 +0200
+++ vdr-1.7.32/cutter.c	2012-11-18 13:09:00.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: cutter.c 2.14 2012/09/20 09:12:47 kls Exp $
+ * $Id: cutter.c 2.16 2012/11/18 12:09:00 kls Exp $
  */
 
 #include "cutter.h"
@@ -13,17 +13,261 @@
 #include "remux.h"
 #include "videodir.h"
 
+// --- cPacketBuffer ---------------------------------------------------------
+
+class cPacketBuffer {
+private:
+  uchar *data;
+  int size;
+  int length;
+public:
+  cPacketBuffer(void);
+  ~cPacketBuffer();
+  void Append(uchar *Data, int Length);
+       ///< Appends Length bytes of Data to this packet buffer.
+  void Flush(uchar *Data, int &Length, int MaxLength);
+       ///< Flushes the content of this packet buffer into the given Data, starting
+       ///< at position Length, and clears the buffer afterwards. Length will be
+       ///< incremented accordingly. If Length plus the total length of the stored
+       ///< packets would exceed MaxLength, nothing is copied.
+  };
+
+cPacketBuffer::cPacketBuffer(void)
+{
+  data = NULL;
+  size = length = 0;
+}
+
+cPacketBuffer::~cPacketBuffer()
+{
+  free(data);
+}
+
+void cPacketBuffer::Append(uchar *Data, int Length)
+{
+  if (length + Length >= size) {
+     int NewSize = (length + Length) * 3 / 2;
+     if (uchar *p = (uchar *)realloc(data, NewSize)) {
+        data = p;
+        size = NewSize;
+        }
+     else
+        return; // out of memory
+     }
+  memcpy(data + length, Data, Length);
+  length += Length;
+}
+
+void cPacketBuffer::Flush(uchar *Data, int &Length, int MaxLength)
+{
+  if (Data && length > 0 && Length + length <= MaxLength) {
+     memcpy(Data + Length, data, length);
+     Length += length;
+     }
+  length = 0;
+}
+
+// --- cPacketStorage --------------------------------------------------------
+
+class cPacketStorage {
+private:
+  cPacketBuffer *buffers[MAXPID];
+public:
+  cPacketStorage(void);
+  ~cPacketStorage();
+  void Append(int Pid, uchar *Data, int Length);
+  void Flush(int Pid, uchar *Data, int &Length, int MaxLength);
+  };
+
+cPacketStorage::cPacketStorage(void)
+{
+  for (int i = 0; i < MAXPID; i++)
+      buffers[i] = NULL;
+}
+
+cPacketStorage::~cPacketStorage()
+{
+  for (int i = 0; i < MAXPID; i++)
+      delete buffers[i];
+}
+
+void cPacketStorage::Append(int Pid, uchar *Data, int Length)
+{
+  if (!buffers[Pid])
+     buffers[Pid] = new cPacketBuffer;
+  buffers[Pid]->Append(Data, Length);
+}
+
+void cPacketStorage::Flush(int Pid, uchar *Data, int &Length, int MaxLength)
+{
+  if (buffers[Pid])
+     buffers[Pid]->Flush(Data, Length, MaxLength);
+}
+
+// --- cDanglingPacketStripper -----------------------------------------------
+
+class cDanglingPacketStripper {
+private:
+  bool processed[MAXPID];
+  cPatPmtParser patPmtParser;
+public:
+  cDanglingPacketStripper(void);
+  bool Process(uchar *Data, int Length, int64_t FirstPts);
+       ///< Scans the frame given in Data and hides the payloads of any TS packets
+       ///< that either didn't start within this frame, or have a PTS that is
+       ///< before FirstPts. The TS packets in question are not physically removed
+       ///< from Data in order to keep any frame counts and PCR timestamps intact.
+       ///< Returns true if any dangling packets have been found.
+  };
+
+cDanglingPacketStripper::cDanglingPacketStripper(void)
+{
+  memset(processed, 0x00, sizeof(processed));
+}
+
+bool cDanglingPacketStripper::Process(uchar *Data, int Length, int64_t FirstPts)
+{
+  bool Found = false;
+  while (Length >= TS_SIZE && *Data == TS_SYNC_BYTE) {
+        int Pid = TsPid(Data);
+        if (Pid == PATPID)
+           patPmtParser.ParsePat(Data, TS_SIZE);
+        else if (Pid == patPmtParser.PmtPid())
+           patPmtParser.ParsePmt(Data, TS_SIZE);
+        else {
+           int64_t Pts = TsGetPts(Data, TS_SIZE);
+           if (Pts >= 0)
+              processed[Pid] = PtsDiff(FirstPts, Pts) >= 0; // Pts is at or after FirstPts
+           if (!processed[Pid]) {
+              TsHidePayload(Data);
+              Found = true;
+              }
+           }
+        Length -= TS_SIZE;
+        Data += TS_SIZE;
+        }
+  return Found;
+}
+
+// --- cPtsFixer -------------------------------------------------------------
+
+class cPtsFixer {
+private:
+  int delta; // time between two frames
+  int64_t last; // the last (i.e. highest) video PTS value seen
+  int64_t offset; // offset to add to PTS values
+  bool fixCounters; // controls fixing the TS continuity counters (only from the second CutIn up)
+  uchar counter[MAXPID]; // the TS continuity counter for each PID
+  cPatPmtParser patPmtParser;
+public:
+  cPtsFixer(void);
+  void Setup(double FramesPerSecond);
+  void Fix(uchar *Data, int Length, bool CutIn);
+  };
+
+cPtsFixer::cPtsFixer(void)
+{
+  delta = 0;
+  last = -1;
+  offset = -1;
+  fixCounters = false;
+  memset(counter, 0x00, sizeof(counter));
+}
+
+void cPtsFixer::Setup(double FramesPerSecond)
+{
+  delta = int(round(PTSTICKS / FramesPerSecond));
+}
+
+void cPtsFixer::Fix(uchar *Data, int Length, bool CutIn)
+{
+  if (!patPmtParser.Vpid()) {
+     if (!patPmtParser.ParsePatPmt(Data, Length))
+        return;
+     }
+  // Determine the PTS offset at the beginning of each sequence (except the first one):
+  if (CutIn && last >= 0) {
+     int64_t Pts = TsGetPts(Data, Length);
+     if (Pts >= 0) {
+        // offset is calculated so that Pts + offset results in last + delta:
+        offset = Pts - PtsAdd(last, delta);
+        if (offset <= 0)
+           offset = -offset;
+        else
+           offset = MAX33BIT + 1 - offset;
+        }
+     fixCounters = true;
+     }
+  // Keep track of the highest video PTS:
+  uchar *p = Data;
+  int len = Length;
+  while (len >= TS_SIZE && *p == TS_SYNC_BYTE) {
+        int Pid = TsPid(p);
+        if (Pid == patPmtParser.Vpid()) {
+           int64_t Pts = PtsAdd(TsGetPts(p, TS_SIZE), offset); // offset is taken into account here, to make last have the "new" value already!
+           if (Pts >= 0 && (last < 0 || PtsDiff(last, Pts) > 0))
+              last = Pts;
+           }
+        // Adjust the TS continuity counter:
+        if (fixCounters) {
+           counter[Pid] = (counter[Pid] + 1) & TS_CONT_CNT_MASK;
+           TsSetContinuityCounter(p, counter[Pid]);
+           }
+        else
+           counter[Pid] = TsGetContinuityCounter(p); // collect initial counters
+        p += TS_SIZE;
+        len -= TS_SIZE;
+        }
+  // Apply the PTS offset:
+  if (offset > 0) {
+     uchar *p = Data;
+     int len = Length;
+     while (len >= TS_SIZE && *p == TS_SYNC_BYTE) {
+           // Adjust the various timestamps:
+           int64_t Pts = TsGetPts(p, TS_SIZE);
+           if (Pts >= 0)
+              TsSetPts(p, TS_SIZE, PtsAdd(Pts, offset));
+           int64_t Dts = TsGetDts(p, TS_SIZE);
+           if (Dts >= 0)
+              TsSetDts(p, TS_SIZE, PtsAdd(Dts, offset));
+           int64_t Pcr = TsGetPcr(p);
+           if (Pcr >= 0) {
+              int64_t NewPcr = Pcr + offset * PCRFACTOR;
+              if (NewPcr >= MAX27MHZ)
+                 NewPcr -= MAX27MHZ + 1;
+              TsSetPcr(p, NewPcr);
+              }
+           p += TS_SIZE;
+           len -= TS_SIZE;
+           }
+     }
+}
+
 // --- cCuttingThread --------------------------------------------------------
 
 class cCuttingThread : public cThread {
 private:
   const char *error;
   bool isPesRecording;
+  double framesPerSecond;
   cUnbufferedFile *fromFile, *toFile;
   cFileName *fromFileName, *toFileName;
   cIndexFile *fromIndex, *toIndex;
   cMarks fromMarks, toMarks;
+  int numSequences;
   off_t maxVideoFileSize;
+  off_t fileSize;
+  cPtsFixer ptsFixer;
+  bool suspensionLogged;
+  bool Throttled(void);
+  bool SwitchFile(bool Force = false);
+  bool LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length);
+  bool FramesAreEqual(int Index1, int Index2);
+  void GetPendingPackets(uchar *Buffer, int &Length, int Index, int64_t LastPts);
+       // Gather all non-video TS packets from Index upward that either belong to
+       // payloads that started before Index, or have a PTS that is before LastPts,
+       // and add them to the end of the given Data.
+  bool ProcessSequence(int LastEndIndex, int BeginIndex, int EndIndex, int NextBeginIndex);
 protected:
   virtual void Action(void);
 public:
@@ -33,7 +277,7 @@
   };
 
 cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
-:cThread("video cutting")
+:cThread("video cutting", true)
 {
   error = NULL;
   fromFile = toFile = NULL;
@@ -41,16 +285,25 @@
   fromIndex = toIndex = NULL;
   cRecording Recording(FromFileName);
   isPesRecording = Recording.IsPesRecording();
-  if (fromMarks.Load(FromFileName, Recording.FramesPerSecond(), isPesRecording) && fromMarks.Count()) {
-     fromFileName = new cFileName(FromFileName, false, true, isPesRecording);
-     toFileName = new cFileName(ToFileName, true, true, isPesRecording);
-     fromIndex = new cIndexFile(FromFileName, false, isPesRecording);
-     toIndex = new cIndexFile(ToFileName, true, isPesRecording);
-     toMarks.Load(ToFileName, Recording.FramesPerSecond(), isPesRecording); // doesn't actually load marks, just sets the file name
-     maxVideoFileSize = MEGABYTE(Setup.MaxVideoFileSize);
-     if (isPesRecording && maxVideoFileSize > MEGABYTE(MAXVIDEOFILESIZEPES))
-        maxVideoFileSize = MEGABYTE(MAXVIDEOFILESIZEPES);
-     Start();
+  framesPerSecond = Recording.FramesPerSecond();
+  suspensionLogged = false;
+  fileSize = 0;
+  ptsFixer.Setup(framesPerSecond);
+  if (fromMarks.Load(FromFileName, framesPerSecond, isPesRecording) && fromMarks.Count()) {
+     numSequences = fromMarks.GetNumSequences();
+     if (numSequences > 0) {
+        fromFileName = new cFileName(FromFileName, false, true, isPesRecording);
+        toFileName = new cFileName(ToFileName, true, true, isPesRecording);
+        fromIndex = new cIndexFile(FromFileName, false, isPesRecording);
+        toIndex = new cIndexFile(ToFileName, true, isPesRecording);
+        toMarks.Load(ToFileName, framesPerSecond, isPesRecording); // doesn't actually load marks, just sets the file name
+        maxVideoFileSize = MEGABYTE(Setup.MaxVideoFileSize);
+        if (isPesRecording && maxVideoFileSize > MEGABYTE(MAXVIDEOFILESIZEPES))
+           maxVideoFileSize = MEGABYTE(MAXVIDEOFILESIZEPES);
+        Start();
+        }
+     else
+        esyslog("no editing sequences found for %s", FromFileName);
      }
   else
      esyslog("no editing marks found for %s", FromFileName);
@@ -65,171 +318,236 @@
   delete toIndex;
 }
 
+bool cCuttingThread::Throttled(void)
+{
+  if (cIoThrottle::Engaged()) {
+     if (!suspensionLogged) {
+        dsyslog("suspending cutter thread");
+        suspensionLogged = true;
+        }
+     return true;
+     }
+  else if (suspensionLogged) {
+     dsyslog("resuming cutter thread");
+     suspensionLogged = false;
+     }
+  return false;
+}
+
+bool cCuttingThread::LoadFrame(int Index, uchar *Buffer, bool &Independent, int &Length)
+{
+  uint16_t FileNumber;
+  off_t FileOffset;
+  if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length)) {
+     fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
+     if (fromFile) {
+        fromFile->SetReadAhead(MEGABYTE(20));
+        int len = ReadFrame(fromFile, Buffer,  Length, MAXFRAMESIZE);
+        if (len < 0)
+           error = "ReadFrame";
+        else if (len != Length)
+           Length = len;
+        return error == NULL;
+        }
+     else
+        error = "fromFile";
+     }
+  return false;
+}
+
+bool cCuttingThread::SwitchFile(bool Force)
+{
+  if (fileSize > maxVideoFileSize || Force) {
+     toFile = toFileName->NextFile();
+     if (!toFile) {
+        error = "toFile";
+        return false;
+        }
+     fileSize = 0;
+     }
+  return true;
+}
+
+bool cCuttingThread::FramesAreEqual(int Index1, int Index2)
+{
+  bool Independent;
+  uchar Buffer1[MAXFRAMESIZE];
+  uchar Buffer2[MAXFRAMESIZE];
+  int Length1;
+  int Length2;
+  if (LoadFrame(Index1, Buffer1, Independent, Length1) && LoadFrame(Index2, Buffer2, Independent, Length2)) {
+     if (Length1 == Length2) {
+        int Diffs = 0;
+        for (int i = 0; i < Length1; i++) {
+            if (Buffer1[i] != Buffer2[i]) {
+               if (Diffs++ > 10) // the continuity counters of the PAT/PMT packets may differ
+                  return false;
+               }
+            }
+        return true;
+        }
+     }
+  return false;
+}
+
+void cCuttingThread::GetPendingPackets(uchar *Data, int &Length, int Index, int64_t LastPts)
+{
+  bool Processed[MAXPID] = { false };
+  int NumIndependentFrames = 0;
+  cPatPmtParser PatPmtParser;
+  cPacketStorage PacketStorage;
+  for (; NumIndependentFrames < 2; Index++) {
+      uchar Buffer[MAXFRAMESIZE];
+      bool Independent;
+      int len;
+      if (LoadFrame(Index, Buffer, Independent, len)) {
+         if (Independent)
+            NumIndependentFrames++;
+         uchar *p = Buffer;
+         while (len >= TS_SIZE && *p == TS_SYNC_BYTE) {
+               int Pid = TsPid(p);
+               if (Pid == PATPID)
+                  PatPmtParser.ParsePat(p, TS_SIZE);
+               else if (Pid == PatPmtParser.PmtPid())
+                  PatPmtParser.ParsePmt(p, TS_SIZE);
+               else if (!Processed[Pid]) {
+                  int64_t Pts = TsGetPts(p, TS_SIZE);
+                  if (Pts >= 0) {
+                     int64_t d = PtsDiff(LastPts, Pts);
+                     if (d <= 0) // Pts is before or at LastPts
+                        PacketStorage.Flush(Pid, Data, Length, MAXFRAMESIZE);
+                     if (d >= 0) { // Pts is at or after LastPts
+                        NumIndependentFrames = 0; // we search until we find two consecutive I-frames without any more pending packets
+                        Processed[Pid] = true;
+                        }
+                     }
+                  if (!Processed[Pid])
+                     PacketStorage.Append(Pid, p, TS_SIZE);
+                  }
+               len -= TS_SIZE;
+               p += TS_SIZE;
+               }
+         }
+      else
+         break;
+      }
+}
+
+bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIndex, int NextBeginIndex)
+{
+  // Check for seamless connections:
+  bool SeamlessBegin = LastEndIndex >= 0 && FramesAreEqual(LastEndIndex, BeginIndex);
+  bool SeamlessEnd = NextBeginIndex >= 0 && FramesAreEqual(EndIndex, NextBeginIndex);
+  // Process all frames from BeginIndex (included) to EndIndex (excluded):
+  cDanglingPacketStripper DanglingPacketStripper;
+  int NumIndependentFrames = 0;
+  int64_t FirstPts = -1;
+  int64_t LastPts = -1;
+  for (int Index = BeginIndex; Running() && Index < EndIndex; Index++) {
+      uchar Buffer[MAXFRAMESIZE];
+      bool Independent;
+      int Length;
+      if (LoadFrame(Index, Buffer, Independent, Length)) {
+         if (!isPesRecording) {
+            int64_t Pts = TsGetPts(Buffer, Length);
+            if (FirstPts < 0)
+               FirstPts = Pts; // the PTS of the first frame in the sequence
+            else if (LastPts < 0 || PtsDiff(LastPts, Pts) > 0)
+               LastPts = Pts; // the PTS of the frame that is displayed as the very last one of the sequence
+            }
+         // Fixup data at the beginning of the sequence:
+         if (!SeamlessBegin) {
+            if (isPesRecording) {
+               if (Index == BeginIndex)
+                  cRemux::SetBrokenLink(Buffer, Length);
+               }
+            else if (NumIndependentFrames < 2) {
+               if (DanglingPacketStripper.Process(Buffer, Length, FirstPts))
+                  NumIndependentFrames = 0; // we search until we find two consecutive I-frames without any more dangling packets
+               }
+            }
+         // Fixup data at the end of the sequence:
+         if (!SeamlessEnd) {
+            if (Index == EndIndex - 1) {
+               if (!isPesRecording)
+                  GetPendingPackets(Buffer, Length, EndIndex, LastPts + int(round(PTSTICKS / framesPerSecond))); // adding one frame length to fully cover the very last frame
+               }
+            }
+         // Fixup timestamps and continuity counters:
+         if (!isPesRecording) {
+            if (numSequences > 1)
+              ptsFixer.Fix(Buffer, Length, !SeamlessBegin && Index == BeginIndex);
+            }
+         // Every file shall start with an independent frame:
+         if (Independent) {
+            NumIndependentFrames++;
+            if (!SwitchFile())
+               return false;
+            }
+         // Write index:
+         if (!toIndex->Write(Independent, toFileName->Number(), fileSize)) {
+            error = "toIndex";
+            return false;
+            }
+         // Write data:
+         if (toFile->Write(Buffer, Length) < 0) {
+            error = "safe_write";
+            return false;
+            }
+         fileSize += Length;
+         // Generate marks at the editing points in the edited recording:
+         if (numSequences > 0 && Index == BeginIndex) {
+            if (toMarks.Count() > 0)
+               toMarks.Add(toIndex->Last());
+            toMarks.Add(toIndex->Last());
+            toMarks.Save();
+            }
+         }
+      else
+         return false;
+      }
+  return true;
+}
+
 void cCuttingThread::Action(void)
 {
-  cMark *Mark = fromMarks.First();
-  if (Mark) {
-     SetPriority(19);
-     SetIOPriority(7);
+  if (cMark *BeginMark = fromMarks.GetNextBegin()) {
      fromFile = fromFileName->Open();
      toFile = toFileName->Open();
      if (!fromFile || !toFile)
         return;
-     fromFile->SetReadAhead(MEGABYTE(20));
-     int Index = Mark->Position();
-     Mark = fromMarks.Next(Mark);
-     off_t FileSize = 0;
-     int CurrentFileNumber = 0;
-     int LastIFrame = 0;
-     toMarks.Add(0);
-     toMarks.Save();
-     uchar buffer[MAXFRAMESIZE], buffer2[MAXFRAMESIZE];
-     int Length2;
-     bool CheckForSeamlessStream = false;
-     bool LastMark = false;
-     bool cutIn = true;
-     bool suspensionLogged = false;
-     while (Running()) {
-           uint16_t FileNumber;
-           off_t FileOffset;
-           int Length;
-           bool Independent;
-
+     int LastEndIndex = -1;
+     while (BeginMark && Running()) {
            // Suspend cutting if we have severe throughput problems:
-
-           if (cIoThrottle::Engaged()) {
-              if (!suspensionLogged) {
-                 dsyslog("suspending cutter thread");
-                 suspensionLogged = true;
-                 }
+           if (Throttled()) {
               cCondWait::SleepMs(100);
               continue;
               }
-           else if (suspensionLogged) {
-              dsyslog("resuming cutter thread");
-              suspensionLogged = false;
-              }
-
            // Make sure there is enough disk space:
-
            AssertFreeDiskSpace(-1);
-
-           // Read one frame:
-
-           if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) {
-              if (FileNumber != CurrentFileNumber) {
-                 fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
-                 if (fromFile)
-                    fromFile->SetReadAhead(MEGABYTE(20));
-                 CurrentFileNumber = FileNumber;
-                 }
-              if (fromFile) {
-                 int len = ReadFrame(fromFile, buffer,  Length, sizeof(buffer));
-                 if (len < 0) {
-                    error = "ReadFrame";
-                    break;
-                    }
-                 if (len != Length) {
-                    CurrentFileNumber = 0; // this re-syncs in case the frame was larger than the buffer
-                    Length = len;
-                    }
-                 }
-              else {
-                 error = "fromFile";
-                 break;
-                 }
+           // Determine the actual begin and end marks, skipping any marks at the same position:
+           cMark *EndMark = fromMarks.GetNextEnd(BeginMark);
+           // Process the current sequence:
+           int EndIndex = EndMark ? EndMark->Position() : fromIndex->Last() + 1;
+           int NextBeginIndex = -1;
+           if (EndMark) {
+              if (cMark *NextBeginMark = fromMarks.GetNextBegin(EndMark))
+                 NextBeginIndex = NextBeginMark->Position();
               }
-           else {
-              // Error, unless we're past the last cut-in and there's no cut-out
-              if (Mark || LastMark)
-                 error = "index";
+           if (!ProcessSequence(LastEndIndex, BeginMark->Position(), EndIndex, NextBeginIndex))
               break;
-              }
-
-           // Write one frame:
-
-           if (Independent) { // every file shall start with an independent frame
-              if (LastMark) // edited version shall end before next I-frame
-                 break;
-              if (FileSize > maxVideoFileSize) {
-                 toFile = toFileName->NextFile();
-                 if (!toFile) {
-                    error = "toFile 1";
+           if (!EndMark)
+              break; // reached EOF
+           LastEndIndex = EndIndex;
+           // Switch to the next sequence:
+           BeginMark = fromMarks.GetNextBegin(EndMark);
+           if (BeginMark) {
+              // Split edited files:
+              if (Setup.SplitEditedFiles) {
+                 if (!SwitchFile(true))
                     break;
-                    }
-                 FileSize = 0;
-                 }
-              LastIFrame = 0;
-              // Compare the current frame with the previously stored one, to see if this is a seamlessly merged recording of the same stream:
-              if (CheckForSeamlessStream) {
-                 if (Length == Length2) {
-                    int diffs = 0;
-                    for (int i = 0; i < Length; i++) {
-                        if (buffer[i] != buffer2[i]) {
-                           if (diffs++ > 10)
-                              break;
-                           }
-                        }
-                    if (diffs < 10) // the continuity counters of the PAT/PMT packets may differ
-                       cutIn = false; // it's apparently a seamless stream, so no need for "broken" handling
-                    }
-                 CheckForSeamlessStream = false;
-                 }
-              if (cutIn) {
-                 if (isPesRecording)
-                    cRemux::SetBrokenLink(buffer, Length);
-                 else
-                    TsSetTeiOnBrokenPackets(buffer, Length);
-                 cutIn = false;
                  }
               }
-           if (toFile->Write(buffer, Length) < 0) {
-              error = "safe_write";
-              break;
-              }
-           if (!toIndex->Write(Independent, toFileName->Number(), FileSize)) {
-              error = "toIndex";
-              break;
-              }
-           FileSize += Length;
-           if (!LastIFrame)
-              LastIFrame = toIndex->Last();
-
-           // Check editing marks:
-
-           if (Mark && Index >= Mark->Position()) {
-              Mark = fromMarks.Next(Mark);
-              toMarks.Add(LastIFrame);
-              if (Mark)
-                 toMarks.Add(toIndex->Last() + 1);
-              toMarks.Save();
-              if (Mark) {
-                 // Read the next frame, for later comparison with the first frame at this mark:
-                 if (fromIndex->Get(Index, &FileNumber, &FileOffset, &Independent, &Length2)) {
-                    if (FileNumber != CurrentFileNumber)
-                       fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
-                    if (fromFile) {
-                       int len = ReadFrame(fromFile, buffer2, Length2, sizeof(buffer2));
-                       if (len >= 0 && len == Length2)
-                          CheckForSeamlessStream = true;
-                       }
-                    }
-                 Index = Mark->Position();
-                 Mark = fromMarks.Next(Mark);
-                 CurrentFileNumber = 0; // triggers SetOffset before reading next frame
-                 cutIn = true;
-                 if (Setup.SplitEditedFiles) {
-                    toFile = toFileName->NextFile();
-                    if (!toFile) {
-                       error = "toFile 2";
-                       break;
-                       }
-                    FileSize = 0;
-                    }
-                 }
-              else
-                 LastMark = true;
-              }
            }
      Recordings.TouchUpdate();
      }
@@ -257,7 +575,7 @@
 
      cMarks FromMarks;
      FromMarks.Load(FileName, Recording.FramesPerSecond(), Recording.IsPesRecording());
-     if (cMark *First = FromMarks.First())
+     if (cMark *First = FromMarks.GetNextBegin())
         Recording.SetStartTime(Recording.Start() + (int(First->Position() / Recording.FramesPerSecond() + 30) / 60) * 60);
 
      const char *evn = Recording.PrefixFileName('%');
@@ -345,13 +663,17 @@
      if (Recording.Name()) {
         cMarks Marks;
         if (Marks.Load(FileName, Recording.FramesPerSecond(), Recording.IsPesRecording()) && Marks.Count()) {
-           if (cCutter::Start(FileName)) {
-              while (cCutter::Active())
-                    cCondWait::SleepMs(CUTTINGCHECKINTERVAL);
-              return true;
+           if (Marks.GetNumSequences()) {
+              if (cCutter::Start(FileName)) {
+                 while (cCutter::Active())
+                       cCondWait::SleepMs(CUTTINGCHECKINTERVAL);
+                 return true;
+                 }
+              else
+                 fprintf(stderr, "can't start editing process\n");
               }
            else
-              fprintf(stderr, "can't start editing process\n");
+              fprintf(stderr, "'%s' has no editing sequences\n", FileName);
            }
         else
            fprintf(stderr, "'%s' has no editing marks\n", FileName);
diff -ruN vdr-1.7.31/device.c vdr-1.7.32/device.c
--- vdr-1.7.31/device.c	2012-09-20 11:32:26.000000000 +0200
+++ vdr-1.7.32/device.c	2012-11-13 10:11:43.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 2.68 2012/09/20 09:32:26 kls Exp $
+ * $Id: device.c 2.69 2012/11/13 09:11:43 kls Exp $
  */
 
 #include "device.h"
@@ -1147,7 +1147,7 @@
      int Size = 0;
      while (Length >= TS_SIZE) {
            int Pid = TsPid(Data);
-           if (Pid == 0)
+           if (Pid == PATPID)
               patPmtParser.ParsePat(Data, TS_SIZE);
            else if (Pid == patPmtParser.PmtPid())
               patPmtParser.ParsePmt(Data, TS_SIZE);
@@ -1484,7 +1484,7 @@
            if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
               int PayloadOffset = TsPayloadOffset(Data);
               if (PayloadOffset < TS_SIZE) {
-                 if (Pid == 0)
+                 if (Pid == PATPID)
                     patPmtParser.ParsePat(Data, TS_SIZE);
                  else if (Pid == patPmtParser.PmtPid())
                     patPmtParser.ParsePmt(Data, TS_SIZE);
diff -ruN vdr-1.7.31/dvbdevice.c vdr-1.7.32/dvbdevice.c
--- vdr-1.7.31/dvbdevice.c	2012-09-20 12:07:54.000000000 +0200
+++ vdr-1.7.32/dvbdevice.c	2012-10-07 13:11:30.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 2.72 2012/09/20 10:07:54 kls Exp $
+ * $Id: dvbdevice.c 2.74 2012/10/07 11:11:30 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -21,7 +21,9 @@
 #include "menuitems.h"
 #include "sourceparams.h"
 
-#define FE_CAN_TURBO_FEC  0x8000000 // TODO: remove this once it is defined in the driver
+#if (DVB_API_VERSION << 8 | DVB_API_VERSION_MINOR) < 0x0508
+#define DTV_STREAM_ID DTV_DVBT2_PLP_ID
+#endif
 
 #define DVBS_TUNE_TIMEOUT  9000 //ms
 #define DVBS_LOCK_TIMEOUT  2000 //ms
@@ -408,7 +410,7 @@
         return diseqc->Commands();
      }
   else {
-     bool ToneOff = Channel->Frequency() < (unsigned int)Setup.LnbSLOF;
+     bool ToneOff = Channel->Frequency() < Setup.LnbSLOF;
      bool VoltOff = dtp.Polarization() == 'V' || dtp.Polarization() == 'R';
      return cString::sprintf("%c %c", ToneOff ? 't' : 'T', VoltOff ? 'v' : 'V');
      }
@@ -574,40 +576,52 @@
            return 3;
         return 4;
         }
+#ifdef DEBUG_SIGNALQUALITY
      bool HasSnr = true;
+#endif
      uint16_t Snr;
      while (1) {
            if (ioctl(fd_frontend, FE_READ_SNR, &Snr) != -1)
               break;
            if (errno == EOPNOTSUPP) {
               Snr = 0xFFFF;
+#ifdef DEBUG_SIGNALQUALITY
               HasSnr = false;
+#endif
               break;
               }
            if (errno != EINTR)
               return -1;
            }
+#ifdef DEBUG_SIGNALQUALITY
      bool HasBer = true;
+#endif
      uint32_t Ber;
      while (1) {
            if (ioctl(fd_frontend, FE_READ_BER, &Ber) != -1)
               break;
            if (errno == EOPNOTSUPP) {
               Ber = 0;
+#ifdef DEBUG_SIGNALQUALITY
               HasBer = false;
+#endif
               break;
               }
            if (errno != EINTR)
               return -1;
            }
+#ifdef DEBUG_SIGNALQUALITY
      bool HasUnc = true;
+#endif
      uint32_t Unc;
      while (1) {
            if (ioctl(fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1)
               break;
            if (errno == EOPNOTSUPP) {
               Unc = 0;
+#ifdef DEBUG_SIGNALQUALITY
               HasUnc = false;
+#endif
               break;
               }
            if (errno != EINTR)
@@ -810,7 +824,7 @@
      SETCMD(DTV_HIERARCHY, dtp.Hierarchy());
      if (frontendType == SYS_DVBT2) {
         // DVB-T2
-        SETCMD(DTV_DVBT2_PLP_ID, dtp.PlpId());
+        SETCMD(DTV_STREAM_ID, dtp.PlpId());
         }
 
      tuneTimeout = DVBT_TUNE_TIMEOUT;
diff -ruN vdr-1.7.31/epg.c vdr-1.7.32/epg.c
--- vdr-1.7.31/epg.c	2012-09-29 16:29:49.000000000 +0200
+++ vdr-1.7.32/epg.c	2012-10-04 14:21:24.000000000 +0200
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.c 2.21 2012/09/29 14:29:49 kls Exp $
+ * $Id: epg.c 2.22 2012/10/04 12:21:24 kls Exp $
  */
 
 #include "epg.h"
@@ -1148,14 +1148,12 @@
   };
 
 cEpgDataWriter::cEpgDataWriter(void)
-:cThread("epg data writer")
+:cThread("epg data writer", true)
 {
 }
 
 void cEpgDataWriter::Action(void)
 {
-  SetPriority(19);
-  SetIOPriority(7);
   Perform();
 }
 
diff -ruN vdr-1.7.31/libsi/si.h vdr-1.7.32/libsi/si.h
--- vdr-1.7.31/libsi/si.h	2012-01-11 12:35:17.000000000 +0100
+++ vdr-1.7.32/libsi/si.h	2012-10-15 13:56:06.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.h 2.5 2012/01/11 11:35:17 kls Exp $
+ *   $Id: si.h 2.6 2012/10/15 11:56:06 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -347,8 +347,10 @@
          T *ret=new T();
          ret->setData(d);
          ret->CheckParse();
-         if (!checkSize(ret->getLength()))
+         if (!checkSize(ret->getLength())) {
+            delete ret;
             return 0;
+         }
          it.i+=ret->getLength();
          return ret;
       }
diff -ruN vdr-1.7.31/menu.c vdr-1.7.32/menu.c
--- vdr-1.7.31/menu.c	2012-09-15 13:45:28.000000000 +0200
+++ vdr-1.7.32/menu.c	2012-11-18 14:07:53.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 2.61 2012/09/15 11:45:28 kls Exp $
+ * $Id: menu.c 2.65 2012/11/18 13:07:53 kls Exp $
  */
 
 #include "menu.h"
@@ -3418,7 +3418,7 @@
         stopReplayItem = NULL;
         }
      // Color buttons:
-     SetHelp(!replaying ? tr("Button$Record") : NULL, tr("Button$Audio"), replaying ? NULL : tr("Button$Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Button$Resume") : NULL);
+     SetHelp(!replaying ? tr("Button$Record") : NULL, tr("Button$Audio"), replaying ? NULL : tr("Button$Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Button$Resume") : tr("Button$Play"));
      result = true;
      }
 
@@ -3516,7 +3516,7 @@
                                 state = replaying ? osContinue : osPause;
                              break;
                case kBlue:   if (!HadSubMenu)
-                                state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue;
+                                state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osRecordings;
                              break;
                default:      break;
                }
@@ -4482,10 +4482,6 @@
   Hide();
   cStatus::MsgReplaying(this, NULL, fileName, false);
   Stop();
-  if (marksModified) {
-     marks.Save();
-     marksModified = false;
-     }
   if (currentReplayControl == this)
      currentReplayControl = NULL;
 }
@@ -4573,6 +4569,10 @@
      timeSearchActive = false;
      timeoutShow = 0;
      }
+  if (marksModified) {
+     marks.Save();
+     marksModified = false;
+     }
 }
 
 void cReplayControl::ShowMode(void)
@@ -4771,12 +4771,12 @@
         int p = SkipFrames(Forward ? 1 : -1);
         cMark *m2;
         if (Forward) {
-           if ((m2 = marks.Next(m)) != NULL && m2->Position() <= p)
-              return;
+           while ((m2 = marks.Next(m)) != NULL && m2->Position() == m->Position())
+                 m = m2;
            }
         else {
-           if ((m2 = marks.Prev(m)) != NULL && m2->Position() >= p)
-              return;
+           while ((m2 = marks.Prev(m)) != NULL && m2->Position() == m->Position())
+                 m = m2;
            }
         m->SetPosition(p);
         Goto(m->Position(), true);
@@ -4789,13 +4789,11 @@
 {
   if (*fileName) {
      Hide();
-     if (marksModified) {
-        marks.Save();
-        marksModified = false;
-        }
      if (!cCutter::Active()) {
         if (!marks.Count())
            Skins.Message(mtError, tr("No editing marks defined!"));
+        else if (!marks.GetNumSequences())
+           Skins.Message(mtError, tr("No editing sequences defined!"));
         else if (!cCutter::Start(fileName))
            Skins.Message(mtError, tr("Can't start editing process!"));
         else
diff -ruN vdr-1.7.31/po/ar.po vdr-1.7.32/po/ar.po
--- vdr-1.7.31/po/ar.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/ar.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-10-16 11:16-0400\n"
 "Last-Translator: Osama Alrawab <alrawab@hotmail.com>\n"
 "Language-Team: Arabic <ar@li.org>\n"
@@ -1241,6 +1241,9 @@
 msgid "No editing marks defined!"
 msgstr "Ù„Ø§ØªÙˆØ¬Ø¯ Ø¹Ù„Ø§Ù…Ø§Øª ØªØ¹Ø¯ÙŠÙ„ Ù…Ø¹Ø±Ù�Ø©"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù„Ø¨Ø¯Ø¡ Ù�Ù‰ Ø¹Ù…Ù„ÙŠØ© Ø§Ù„ØªØ¹Ø¯ÙŠÙ„"
 
diff -ruN vdr-1.7.31/po/ca_ES.po vdr-1.7.32/po/ca_ES.po
--- vdr-1.7.31/po/ca_ES.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/ca_ES.po	2012-11-18 14:31:53.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
 "Language-Team: Catalan <vdr@linuxtv.org>\n"
@@ -1216,6 +1216,9 @@
 msgid "No editing marks defined!"
 msgstr "No hi ha marques d'edició definides"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "No puc iniciar el procés d'edició!"
 
diff -ruN vdr-1.7.31/po/cs_CZ.po vdr-1.7.32/po/cs_CZ.po
--- vdr-1.7.31/po/cs_CZ.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/cs_CZ.po	2012-11-18 14:31:53.000000000 +0100
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.14\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-05-06 11:00+0200\n"
 "Last-Translator: Radek Å Å¥astnÃ½ <dedkus@gmail.com>\n"
 "Language-Team: Czech <vdr@linuxtv.org>\n"
@@ -1215,6 +1215,9 @@
 msgid "No editing marks defined!"
 msgstr "Nejsou definovÃ¡ny editaÄ�nÃ­ znaÄ�ky!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Nelze zaÄ�Ã­t editaÄ�nÃ­ proces!"
 
diff -ruN vdr-1.7.31/po/da_DK.po vdr-1.7.32/po/da_DK.po
--- vdr-1.7.31/po/da_DK.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/da_DK.po	2012-11-18 14:31:53.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
 "Language-Team: Danish <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Der er ikke sat nogen redigeringsmærker!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Kan ikke starte redigeringsprocessen!"
 
diff -ruN vdr-1.7.31/po/de_DE.po vdr-1.7.32/po/de_DE.po
--- vdr-1.7.31/po/de_DE.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/de_DE.po	2012-11-18 14:33:16.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-01-16 16:46+0100\n"
 "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
 "Language-Team: German <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Keine Schnittmarken gesetzt!"
 
+msgid "No editing sequences defined!"
+msgstr "Keine Schnittsequenzen definiert!"
+
 msgid "Can't start editing process!"
 msgstr "Schnitt kann nicht gestartet werden!"
 
diff -ruN vdr-1.7.31/po/el_GR.po vdr-1.7.32/po/el_GR.po
--- vdr-1.7.31/po/el_GR.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/el_GR.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
 "Language-Team: Greek <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "ÄÝí Ý÷ïõí ïñéóôåß óçìåßá åðåîåñãáóßáò"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Áäõíáìßá åêêßíçóçò ôçò åðåîåñãáóßáò!"
 
diff -ruN vdr-1.7.31/po/es_ES.po vdr-1.7.32/po/es_ES.po
--- vdr-1.7.31/po/es_ES.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/es_ES.po	2012-11-18 14:31:53.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
 "Language-Team: Spanish <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "¡No se definieron marcas de edición!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "¡No se puede iniciar el proceso de edición!"
 
diff -ruN vdr-1.7.31/po/et_EE.po vdr-1.7.32/po/et_EE.po
--- vdr-1.7.31/po/et_EE.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/et_EE.po	2012-11-18 14:31:53.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
 "Language-Team: Estonian <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Redigeerimise markerid puuduvad!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Redigeerimise start nurjus!"
 
diff -ruN vdr-1.7.31/po/fi_FI.po vdr-1.7.32/po/fi_FI.po
--- vdr-1.7.31/po/fi_FI.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/fi_FI.po	2012-11-18 14:31:53.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-13 13:15+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2007-08-15 15:52+0200\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
 "Language-Team: Finnish <vdr@linuxtv.org>\n"
@@ -1216,6 +1216,9 @@
 msgid "No editing marks defined!"
 msgstr "MuokkausmerkinnÃ¤t puuttuvat!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Muokkauksen aloitus epÃ¤onnistui!"
 
diff -ruN vdr-1.7.31/po/fr_FR.po vdr-1.7.32/po/fr_FR.po
--- vdr-1.7.31/po/fr_FR.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/fr_FR.po	2012-11-18 14:31:54.000000000 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-02-27 18:14+0100\n"
 "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n"
 "Language-Team: French <vdr@linuxtv.org>\n"
@@ -1219,6 +1219,9 @@
 msgid "No editing marks defined!"
 msgstr "Pas de marques d'édition définies !"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Impossible de commencer le montage !"
 
diff -ruN vdr-1.7.31/po/hr_HR.po vdr-1.7.32/po/hr_HR.po
--- vdr-1.7.31/po/hr_HR.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/hr_HR.po	2012-11-18 14:31:55.000000000 +0100
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-03-17 19:00+0100\n"
 "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
 "Language-Team: Croatian <vdr@linuxtv.org>\n"
@@ -1215,6 +1215,9 @@
 msgid "No editing marks defined!"
 msgstr "Nijedna toèka rezanja nije odreðena!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ne mogu zapoèeti ureðivanje!"
 
diff -ruN vdr-1.7.31/po/hu_HU.po vdr-1.7.32/po/hu_HU.po
--- vdr-1.7.31/po/hu_HU.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/hu_HU.po	2012-11-18 14:31:53.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2012-01-02 11:54+0200\n"
 "Last-Translator: István Füley <ifuley@tigercomp.ro>\n"
 "Language-Team: Hungarian <vdr@linuxtv.org>\n"
@@ -1217,6 +1217,9 @@
 msgid "No editing marks defined!"
 msgstr "Nincs vágópont kijelölve"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "A vágás nem indítható!"
 
diff -ruN vdr-1.7.31/po/it_IT.po vdr-1.7.32/po/it_IT.po
--- vdr-1.7.31/po/it_IT.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/it_IT.po	2012-11-18 14:31:53.000000000 +0100
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2012-06-06 22:50+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
 "Language-Team: Italian <vdr@linuxtv.org>\n"
@@ -1220,6 +1220,9 @@
 msgid "No editing marks defined!"
 msgstr "Nessun marcatore di modifica definito!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Impossibile avviare il processo di modifica!"
 
diff -ruN vdr-1.7.31/po/lt_LT.po vdr-1.7.32/po/lt_LT.po
--- vdr-1.7.31/po/lt_LT.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/lt_LT.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.16\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-10-30 11:55+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
 "Language-Team: Lithuanian <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Nenustatytos koregavimo Å¾ymÄ—s!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Negali pradÄ—ti koregavimo!"
 
diff -ruN vdr-1.7.31/po/mk_MK.po vdr-1.7.32/po/mk_MK.po
--- vdr-1.7.31/po/mk_MK.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/mk_MK.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR-1.7.14\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-03-11 00:54+0100\n"
 "Last-Translator: Dimitar Petrovski <dimeptr@gmail.com>\n"
 "Language-Team: Macedonian <en@li.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "Ð�ÐµÐ¼Ð° Ð¾Ð´Ñ€ÐµÐ´ÐµÐ½Ð¾ Ð¾Ð·Ð½Ð°ÐºÐ¸ Ð·Ð° Ñ�ÐµÑ‡ÐµÑšÐµ!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ð�Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¿Ð¾Ñ‡Ð½Ðµ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐµ!"
 
diff -ruN vdr-1.7.31/po/nl_NL.po vdr-1.7.32/po/nl_NL.po
--- vdr-1.7.31/po/nl_NL.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/nl_NL.po	2012-11-18 14:31:54.000000000 +0100
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-02-26 17:20+0100\n"
 "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n"
 "Language-Team: Dutch <vdr@linuxtv.org>\n"
@@ -1217,6 +1217,9 @@
 msgid "No editing marks defined!"
 msgstr "Geen bewerkingsmarkeringen gedefinieerd!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Kan niet beginnen met bewerken!"
 
diff -ruN vdr-1.7.31/po/nn_NO.po vdr-1.7.32/po/nn_NO.po
--- vdr-1.7.31/po/nn_NO.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/nn_NO.po	2012-11-18 14:31:54.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
 "Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr ""
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Kan ikke starte redigeringsprosessen!"
 
diff -ruN vdr-1.7.31/po/pl_PL.po vdr-1.7.32/po/pl_PL.po
--- vdr-1.7.31/po/pl_PL.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/pl_PL.po	2012-11-18 14:31:53.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-03-09 12:59+0100\n"
 "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
 "Language-Team: Polish <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "Nie zdefiniowano znaczników monta¿u!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Nie mo¿na uruchomiæ procesu edycji!"
 
diff -ruN vdr-1.7.31/po/pt_PT.po vdr-1.7.32/po/pt_PT.po
--- vdr-1.7.31/po/pt_PT.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/pt_PT.po	2012-11-18 14:31:53.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.15\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-03-28 22:49+0100\n"
 "Last-Translator: Cris Silva <hudokkow@gmail.com>\n"
 "Language-Team: Portuguese <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "Marcas de edição não foram definidas!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Impossível iniciar processo de edição!"
 
diff -ruN vdr-1.7.31/po/ro_RO.po vdr-1.7.32/po/ro_RO.po
--- vdr-1.7.31/po/ro_RO.po	2012-09-15 15:57:37.000000000 +0200
+++ vdr-1.7.32/po/ro_RO.po	2012-11-18 14:31:53.000000000 +0100
@@ -2,19 +2,19 @@
 # Copyright (C) 2008 Klaus Schmidinger <kls@tvdr.de>
 # This file is distributed under the same license as the VDR package.
 # Paul Lacatus <paul@campina.iiruc.ro>, 2002
-# Lucian Muresan <lucianm@users.sourceforge.net>, 2004, 2005, 2006, 2008, 2010, 2011
+# Lucian Muresan <lucianm@users.sourceforge.net>, 2004, 2005, 2006, 2008, 2010, 2011, 2012
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: VDR 1.7.12\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
-"PO-Revision-Date: 2011-03-10 23:52+0100\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
+"PO-Revision-Date: 2012-11-05 01:28+0100\n"
 "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
 "Language-Team: Romanian <vdr@linuxtv.org>\n"
 "Language: ro\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Poedit-Language: Romanian\n"
 "X-Poedit-Country: ROMANIA\n"
@@ -47,7 +47,7 @@
 msgstr "Sistem"
 
 msgid "Srate"
-msgstr "Ratã simboluri"
+msgstr "RatÄƒ simboluri"
 
 msgid "Inversion"
 msgstr "Inversiune"
@@ -59,10 +59,10 @@
 msgstr "CoderateL"
 
 msgid "Modulation"
-msgstr "Modulaþie"
+msgstr "ModulaÅ£ie"
 
 msgid "Bandwidth"
-msgstr "Lãrgime de bandã"
+msgstr "LÄƒrgime de bandÄƒ"
 
 msgid "Transmission"
 msgstr "Transmisie"
@@ -77,52 +77,52 @@
 msgstr "Rolloff"
 
 msgid "PlpId"
-msgstr ""
+msgstr "Identificator PLP"
 
 msgid "Starting EPG scan"
-msgstr "Pornesc achiziþia EPG"
+msgstr "Pornesc achiziÅ£ia EPG"
 
 msgid "Content$Movie/Drama"
-msgstr "Film/Dramã"
+msgstr "Film/DramÄƒ"
 
 msgid "Content$Detective/Thriller"
-msgstr "Poliþist/Suspense"
+msgstr "PoliÅ£ist/Suspense"
 
 msgid "Content$Adventure/Western/War"
-msgstr "Aventuri/Western/Rãzboi"
+msgstr "Aventuri/Western/RÄƒzboi"
 
 msgid "Content$Science Fiction/Fantasy/Horror"
-msgstr "Science-Fiction/Fantastic/Groazã"
+msgstr "Science-Fiction/Fantastic/GroazÄƒ"
 
 msgid "Content$Comedy"
 msgstr "Comedie"
 
 msgid "Content$Soap/Melodrama/Folkloric"
-msgstr "Telenovelã/Melodramã/Folclor"
+msgstr "TelenovelÄƒ/MelodramÄƒ/Folclor"
 
 msgid "Content$Romance"
 msgstr "Film romantic"
 
 msgid "Content$Serious/Classical/Religious/Historical Movie/Drama"
-msgstr "Film serios/clasic/religios/istoric/Dramã"
+msgstr "Film serios/clasic/religios/istoric/DramÄƒ"
 
 msgid "Content$Adult Movie/Drama"
-msgstr "Film pentru adulþi/Dramã"
+msgstr "Film pentru adulÅ£i/DramÄƒ"
 
 msgid "Content$News/Current Affairs"
-msgstr "ªtiri/Actualitãþi"
+msgstr "Åžtiri/ActualitÄƒÅ£i"
 
 msgid "Content$News/Weather Report"
-msgstr "ªtiri/Buletin meteorologic"
+msgstr "Åžtiri/Buletin meteorologic"
 
 msgid "Content$News Magazine"
-msgstr "Magazin de ºtiri"
+msgstr "Magazin de ÅŸtiri"
 
 msgid "Content$Documentary"
 msgstr "Documentar"
 
 msgid "Content$Discussion/Inverview/Debate"
-msgstr "Discuþie/Interviu/Dezbatere"
+msgstr "DiscuÅ£ie/Interviu/Dezbatere"
 
 msgid "Content$Show/Game Show"
 msgstr "Show/Jocuri"
@@ -131,7 +131,7 @@
 msgstr "Emisiune jocuri/quiz/concurs"
 
 msgid "Content$Variety Show"
-msgstr "Varietãþi"
+msgstr "VarietÄƒÅ£i"
 
 msgid "Content$Talk Show"
 msgstr "Talk Show"
@@ -152,7 +152,7 @@
 msgstr "Tenis/Squash"
 
 msgid "Content$Team Sports"
-msgstr "Sporturi de echipã"
+msgstr "Sporturi de echipÄƒ"
 
 msgid "Content$Athletics"
 msgstr "Atletism"
@@ -164,19 +164,19 @@
 msgstr "Sporturi acvatice"
 
 msgid "Content$Winter Sports"
-msgstr "Sporturi de iarnã"
+msgstr "Sporturi de iarnÄƒ"
 
 msgid "Content$Equestrian"
-msgstr "Echitaþie"
+msgstr "EchitaÅ£ie"
 
 msgid "Content$Martial Sports"
-msgstr "Arte marþiale"
+msgstr "Arte marÅ£iale"
 
 msgid "Content$Children's/Youth Programme"
 msgstr "Emisiune pentru copii/tineret"
 
 msgid "Content$Pre-school Children's Programme"
-msgstr "Emisiune pentru copii preºcolari"
+msgstr "Emisiune pentru copii preÅŸcolari"
 
 msgid "Content$Entertainment Programme for 6 to 14"
 msgstr "Divertisment pentru copii intre 6 - 16 ani"
@@ -185,34 +185,34 @@
 msgstr "Divertisment pentru copii intre 10 - 16 ani"
 
 msgid "Content$Informational/Educational/School Programme"
-msgstr "Informaþional/Educaþional/Emisiune ºcoalã"
+msgstr "InformaÅ£ional/EducaÅ£ional/Emisiune ÅŸcoalÄƒ"
 
 msgid "Content$Cartoons/Puppets"
-msgstr "Desene animate/Teatru de pãpuºi"
+msgstr "Desene animate/Teatru de pÄƒpuÅŸi"
 
 msgid "Content$Music/Ballet/Dance"
-msgstr "Muzicã/Balet/Dans"
+msgstr "MuzicÄƒ/Balet/Dans"
 
 msgid "Content$Rock/Pop"
 msgstr "Rock/Pop"
 
 msgid "Content$Serious/Classical Music"
-msgstr "Muzicã clasicã/serioasã"
+msgstr "MuzicÄƒ clasicÄƒ/serioasÄƒ"
 
 msgid "Content$Folk/Tradional Music"
-msgstr "Muzicã folk/tradiþionalã"
+msgstr "MuzicÄƒ folk/tradiÅ£ionalÄƒ"
 
 msgid "Content$Jazz"
 msgstr "Jazz"
 
 msgid "Content$Musical/Opera"
-msgstr "Teatru muzical/Operã/Operetã"
+msgstr "Teatru muzical/OperÄƒ/OperetÄƒ"
 
 msgid "Content$Ballet"
 msgstr "Balet"
 
 msgid "Content$Arts/Culture"
-msgstr "Artã/Culturã"
+msgstr "ArtÄƒ/CulturÄƒ"
 
 msgid "Content$Performing Arts"
 msgstr "Spectacole"
@@ -224,10 +224,10 @@
 msgstr "Religie"
 
 msgid "Content$Popular Culture/Traditional Arts"
-msgstr "Culturã Pop/Arte tradiþionale"
+msgstr "CulturÄƒ Pop/Arte tradiÅ£ionale"
 
 msgid "Content$Literature"
-msgstr "Literaturã"
+msgstr "LiteraturÄƒ"
 
 msgid "Content$Film/Cinema"
 msgstr "Film/Cinema"
@@ -236,16 +236,16 @@
 msgstr "Film experimental/Video"
 
 msgid "Content$Broadcasting/Press"
-msgstr "Radiodifuziune/Presã"
+msgstr "Radiodifuziune/PresÄƒ"
 
 msgid "Content$New Media"
 msgstr "Medii noi"
 
 msgid "Content$Arts/Culture Magazine"
-msgstr "Artã/Magazin cultural"
+msgstr "ArtÄƒ/Magazin cultural"
 
 msgid "Content$Fashion"
-msgstr "Modã"
+msgstr "ModÄƒ"
 
 msgid "Content$Social/Political/Economics"
 msgstr "Social/Politic/Economie"
@@ -254,28 +254,28 @@
 msgstr "Magazin/Reportaj/Documentar"
 
 msgid "Content$Economics/Social Advisory"
-msgstr "Economie/Consiliere socialã"
+msgstr "Economie/Consiliere socialÄƒ"
 
 msgid "Content$Remarkable People"
 msgstr "Oameni remarcabili"
 
 msgid "Content$Education/Science/Factual"
-msgstr "Educaþie/ªtiinþã/Practic"
+msgstr "EducaÅ£ie/ÅžtiinÅ£Äƒ/Practic"
 
 msgid "Content$Nature/Animals/Environment"
-msgstr "Naturã/Animale/Mediu"
+msgstr "NaturÄƒ/Animale/Mediu"
 
 msgid "Content$Technology/Natural Sciences"
-msgstr "Tehnologie/ªtiinþe naturale"
+msgstr "Tehnologie/ÅžtiinÅ£e naturale"
 
 msgid "Content$Medicine/Physiology/Psychology"
-msgstr "Medicinã/Fiziologie/Psihologie"
+msgstr "MedicinÄƒ/Fiziologie/Psihologie"
 
 msgid "Content$Foreign Countries/Expeditions"
-msgstr "Þãri strãine/Expediþii"
+msgstr "Å¢Äƒri strÄƒine/ExpediÅ£ii"
 
 msgid "Content$Social/Spiritual Sciences"
-msgstr "Social/ªtiinþe spirituale"
+msgstr "Social/ÅžtiinÅ£e spirituale"
 
 msgid "Content$Further Education"
 msgstr "Cursuri de aprofundare"
@@ -287,28 +287,28 @@
 msgstr "Timp liber/Hobby"
 
 msgid "Content$Tourism/Travel"
-msgstr "Turism/Cãlãtorie"
+msgstr "Turism/CÄƒlÄƒtorie"
 
 msgid "Content$Handicraft"
-msgstr "Meºteºug"
+msgstr "MeÅŸteÅŸug"
 
 msgid "Content$Motoring"
 msgstr "Motoare"
 
 msgid "Content$Fitness & Health"
-msgstr "Miºcare & Sãnãtate"
+msgstr "MiÅŸcare & SÄƒnÄƒtate"
 
 msgid "Content$Cooking"
-msgstr "Gãtit"
+msgstr "GÄƒtit"
 
 msgid "Content$Advertisement/Shopping"
-msgstr "Publicitate/Cumpãrãturi"
+msgstr "Publicitate/CumpÄƒrÄƒturi"
 
 msgid "Content$Gardening"
-msgstr "Grãdinãrit"
+msgstr "GrÄƒdinÄƒrit"
 
 msgid "Content$Original Language"
-msgstr "Limba originalã"
+msgstr "Limba originalÄƒ"
 
 msgid "Content$Black & White"
 msgstr "Alb-Negru"
@@ -317,65 +317,65 @@
 msgstr "Nepublicat"
 
 msgid "Content$Live Broadcast"
-msgstr "Transmisie în direct"
+msgstr "Transmisie Ã®n direct"
 
 #, c-format
 msgid "ParentalRating$from %d"
 msgstr "de la %d ani"
 
 msgid "No title"
-msgstr "Fãrã titlu"
+msgstr "FÄƒrÄƒ titlu"
 
 #. TRANSLATORS: The name of the language, as written natively
 msgid "LanguageName$English"
-msgstr "Românã"
+msgstr "RomÃ¢nÄƒ"
 
 #. TRANSLATORS: The 3-letter code of the language
 msgid "LanguageCode$eng"
 msgstr "rom"
 
 msgid "Phase 1: Detecting RC code type"
-msgstr "Faza 1: Detecþia tipului telecomenzii"
+msgstr "Faza 1: DetecÅ£ia tipului telecomenzii"
 
 msgid "Press any key on the RC unit"
-msgstr "Apãsaþi o tastã pe telecomandã"
+msgstr "ApÄƒsaÅ£i o tastÄƒ pe telecomandÄƒ"
 
 msgid "RC code detected!"
 msgstr "S-a detectat tipul telecomenzii!"
 
 msgid "Do not press any key..."
-msgstr "Nu apãsaþi nici o tastã..."
+msgstr "Nu apÄƒsaÅ£i nici o tastÄƒ..."
 
 msgid "Phase 2: Learning specific key codes"
-msgstr "Faza 2: Învãþarea codurilor anumitor taste"
+msgstr "Faza 2: ÃŽnvÄƒÅ£area codurilor anumitor taste"
 
 #, c-format
 msgid "Press key for '%s'"
-msgstr "Apãsaþi tasta pentru '%s'"
+msgstr "ApÄƒsaÅ£i tasta pentru '%s'"
 
 msgid "Press 'Up' to confirm"
-msgstr "Apãsaþi 'Sus' pentru confirmare"
+msgstr "ApÄƒsaÅ£i 'Sus' pentru confirmare"
 
 msgid "Press 'Down' to continue"
-msgstr "Apãsaþi 'Jos' pentru continuare"
+msgstr "ApÄƒsaÅ£i 'Jos' pentru continuare"
 
 msgid "(press 'Up' to go back)"
-msgstr "(Apãsaþi 'Sus' pentru revenire)"
+msgstr "(ApÄƒsaÅ£i 'Sus' pentru revenire)"
 
 msgid "(press 'Down' to end key definition)"
-msgstr "(Apãsaþi 'Jos' pentru terminare)"
+msgstr "(ApÄƒsaÅ£i 'Jos' pentru terminare)"
 
 msgid "(press 'Menu' to skip this key)"
-msgstr "Apãsaþi 'Meniu' pentru a sãri peste aceastã tastã"
+msgstr "ApÄƒsaÅ£i 'Meniu' pentru a sÄƒri peste aceastÄƒ tastÄƒ"
 
 msgid "Learning Remote Control Keys"
-msgstr "Învãþare taste telecomandã"
+msgstr "ÃŽnvÄƒÅ£are taste telecomandÄƒ"
 
 msgid "Phase 3: Saving key codes"
 msgstr "Faza 3: Salvarea codurilor de taste"
 
 msgid "Press 'Up' to save, 'Down' to cancel"
-msgstr "Apãsaþi 'Sus' pentru salvare, 'Jos' pentru anulare"
+msgstr "ApÄƒsaÅ£i 'Sus' pentru salvare, 'Jos' pentru anulare"
 
 msgid "Key$Up"
 msgstr "Sus"
@@ -390,16 +390,16 @@
 msgstr "OK"
 
 msgid "Key$Back"
-msgstr "Înapoi"
+msgstr "ÃŽnapoi"
 
 msgid "Key$Left"
-msgstr "Stânga"
+msgstr "StÃ¢nga"
 
 msgid "Key$Right"
 msgstr "Dreapta"
 
 msgid "Key$Red"
-msgstr "Roºu"
+msgstr "RoÅŸu"
 
 msgid "Key$Green"
 msgstr "Verde"
@@ -417,28 +417,28 @@
 msgstr "Redare"
 
 msgid "Key$Pause"
-msgstr "Pauzã"
+msgstr "PauzÄƒ"
 
 msgid "Key$Stop"
 msgstr "Stop"
 
 msgid "Key$Record"
-msgstr "Înregistrare"
+msgstr "ÃŽnregistrare"
 
 msgid "Key$FastFwd"
-msgstr "Derulare înainte"
+msgstr "Derulare Ã®nainte"
 
 msgid "Key$FastRew"
-msgstr "Derulare înapoi"
+msgstr "Derulare Ã®napoi"
 
 msgid "Key$Next"
-msgstr "Urmãtor"
+msgstr "UrmÄƒtor"
 
 msgid "Key$Prev"
 msgstr "Anterior"
 
 msgid "Key$Power"
-msgstr "Închidere"
+msgstr "ÃŽnchidere"
 
 msgid "Key$Channel+"
 msgstr "Canal+"
@@ -456,7 +456,7 @@
 msgstr "Volum-"
 
 msgid "Key$Mute"
-msgstr "Fãrã sunet"
+msgstr "FÄƒrÄƒ sunet"
 
 msgid "Key$Audio"
 msgstr "Sunet"
@@ -474,10 +474,10 @@
 msgstr "Timer-e"
 
 msgid "Key$Recordings"
-msgstr "Înregistrãri"
+msgstr "ÃŽnregistrÄƒri"
 
 msgid "Key$Setup"
-msgstr "Configuraþie"
+msgstr "ConfiguraÅ£ie"
 
 msgid "Key$Commands"
 msgstr "Comenzi"
@@ -525,10 +525,10 @@
 msgstr "Nume"
 
 msgid "Source"
-msgstr "Sursã"
+msgstr "SursÄƒ"
 
 msgid "Frequency"
-msgstr "Frecvenþã"
+msgstr "FrecvenÅ£Äƒ"
 
 msgid "Vpid"
 msgstr "PID Video"
@@ -558,7 +558,7 @@
 msgstr "PID Teletext"
 
 msgid "CA"
-msgstr "CA (Acces Condiþional)"
+msgstr "CA (Acces CondiÅ£ional)"
 
 msgid "Sid"
 msgstr "Sid"
@@ -570,25 +570,25 @@
 msgstr "Canale"
 
 msgid "Button$Edit"
-msgstr "Modificã"
+msgstr "ModificÄƒ"
 
 msgid "Button$New"
 msgstr "Nou"
 
 msgid "Button$Delete"
-msgstr "ªterge"
+msgstr "Åžterge"
 
 msgid "Button$Mark"
-msgstr "Marcheazã"
+msgstr "MarcheazÄƒ"
 
 msgid "Channel is being used by a timer!"
 msgstr "Canalul este utilizat de un timer!"
 
 msgid "Delete channel?"
-msgstr "ªterg canalul?"
+msgstr "Åžterg canalul?"
 
 msgid "Edit folder"
-msgstr "Editeazã directorul"
+msgstr "EditeazÄƒ directorul"
 
 msgid "New folder"
 msgstr "Director nou"
@@ -597,20 +597,20 @@
 msgstr "Sub-director"
 
 msgid "Folder name already exists!"
-msgstr "Un director cu acelaºi nume existã!"
+msgstr "Un director cu acelaÅŸi nume existÄƒ!"
 
 #, c-format
 msgid "Folder name must not contain '%c'!"
-msgstr "Numele directorului nu poate sã conþinã '%c'!"
+msgstr "Numele directorului nu poate sÄƒ conÅ£inÄƒ '%c'!"
 
 msgid "Button$Select"
-msgstr "Selecteazã"
+msgstr "SelecteazÄƒ"
 
 msgid "Delete folder and all sub folders?"
-msgstr "ªterg directorul ºi toate sub-directoarele?"
+msgstr "Åžterg directorul ÅŸi toate sub-directoarele?"
 
 msgid "Delete folder?"
-msgstr "ªterg directorul?"
+msgstr "Åžterg directorul?"
 
 msgid "Edit timer"
 msgstr "Modificare timer"
@@ -625,10 +625,10 @@
 msgstr "Ziua"
 
 msgid "Start"
-msgstr "Început"
+msgstr "ÃŽnceput"
 
 msgid "Stop"
-msgstr "Sfârºit"
+msgstr "SfÃ¢rÅŸit"
 
 msgid "VPS"
 msgstr "VPS"
@@ -637,25 +637,25 @@
 msgstr "Prioritate"
 
 msgid "Lifetime"
-msgstr "Timp de pãstrare"
+msgstr "Timp de pÄƒstrare"
 
 msgid "File"
-msgstr "Fiºier"
+msgstr "FiÅŸier"
 
 msgid "Button$Folder"
 msgstr "Director"
 
 msgid "Button$Single"
-msgstr ""
+msgstr "OdatÄƒ"
 
 msgid "Button$Repeating"
-msgstr ""
+msgstr "Repetitiv"
 
 msgid "First day"
 msgstr "Prima zi"
 
 msgid "Select folder"
-msgstr "Selecteazã directorul"
+msgstr "SelecteazÄƒ directorul"
 
 msgid "Timers"
 msgstr "Timer-e"
@@ -667,10 +667,10 @@
 msgstr "Info"
 
 msgid "Delete timer?"
-msgstr "ªterg timer-ul?"
+msgstr "Åžterg timer-ul?"
 
 msgid "Timer still recording - really delete?"
-msgstr "Timer-ul tocmai înregistreazã - ºterg, totuºi?"
+msgstr "Timer-ul tocmai Ã®nregistreazÄƒ - ÅŸterg, totuÅŸi?"
 
 msgid "Event"
 msgstr "Emisiune"
@@ -679,19 +679,19 @@
 msgstr "Timer"
 
 msgid "Button$Record"
-msgstr "Înregistr."
+msgstr "ÃŽnregistr."
 
 msgid "Button$Switch"
-msgstr "Comutã"
+msgstr "ComutÄƒ"
 
 msgid "What's on now?"
 msgstr "Ce emisiuni sunt acum?"
 
 msgid "What's on next?"
-msgstr "Ce emisiuni urmeazã?"
+msgstr "Ce emisiuni urmeazÄƒ?"
 
 msgid "Button$Next"
-msgstr "Urmãtor"
+msgstr "UrmÄƒtor"
 
 msgid "Button$Now"
 msgstr "Acum"
@@ -708,32 +708,32 @@
 
 #, c-format
 msgid "This event - %s"
-msgstr "Aceastã emisiune - %s"
+msgstr "AceastÄƒ emisiune - %s"
 
 msgid "This event - all channels"
-msgstr "Aceastã emisiune - toate canalele"
+msgstr "AceastÄƒ emisiune - toate canalele"
 
 msgid "All events - all channels"
 msgstr "Toate emisiunile - toate canalele"
 
 #, c-format
 msgid "Please enter %d digits!"
-msgstr "Vã rog introduceþi %d cifre!"
+msgstr "VÄƒ rog introduceÅ£i %d cifre!"
 
 msgid "CAM not responding!"
-msgstr "CAM-ul nu reacþioneazã!"
+msgstr "CAM-ul nu reacÅ£ioneazÄƒ!"
 
 msgid "Recording info"
-msgstr "Detaliile înregistrãrii"
+msgstr "Detaliile Ã®nregistrÄƒrii"
 
 msgid "Button$Play"
 msgstr "Redare"
 
 msgid "Button$Rewind"
-msgstr "Înapoi"
+msgstr "ÃŽnapoi"
 
 msgid "Recordings"
-msgstr "Înregistrãri"
+msgstr "ÃŽnregistrÄƒri"
 
 msgid "Button$Open"
 msgstr "Deschide"
@@ -742,28 +742,28 @@
 msgstr "Comenzi"
 
 msgid "Error while accessing recording!"
-msgstr "Eroare la accesarea înregistrãrii"
+msgstr "Eroare la accesarea Ã®nregistrÄƒrii"
 
 msgid "Delete recording?"
-msgstr "ªterg înregistrarea?"
+msgstr "Åžterg Ã®nregistrarea?"
 
 msgid "Recording is being edited - really delete?"
-msgstr ""
+msgstr "Montajul Ã®nregistrÄƒrii e Ã®n curs de desfÄƒÈ™urare - È™terg totuÈ™i?"
 
 msgid "Error while deleting recording!"
-msgstr "Eroare la ºtergerea înregistrãrii!"
+msgstr "Eroare la ÅŸtergerea Ã®nregistrÄƒrii!"
 
 msgid "Recording commands"
-msgstr "Comenzi pentru înregistrãri"
+msgstr "Comenzi pentru Ã®nregistrÄƒri"
 
 msgid "never"
-msgstr "niciodatã"
+msgstr "niciodatÄƒ"
 
 msgid "skin dependent"
 msgstr "dep. de skin"
 
 msgid "always"
-msgstr "întotdeauna"
+msgstr "Ã®ntotdeauna"
 
 msgid "OSD"
 msgstr "OSD"
@@ -775,22 +775,22 @@
 msgstr "Skin"
 
 msgid "Setup.OSD$Theme"
-msgstr "Temã"
+msgstr "TemÄƒ"
 
 msgid "Setup.OSD$Left (%)"
-msgstr "Stânga (%)"
+msgstr "StÃ¢nga (%)"
 
 msgid "Setup.OSD$Top (%)"
 msgstr "Sus (%)"
 
 msgid "Setup.OSD$Width (%)"
-msgstr "Lãþime OSD (%)"
+msgstr "LÄƒÅ£ime OSD (%)"
 
 msgid "Setup.OSD$Height (%)"
-msgstr "Înãlþime OSD (%)"
+msgstr "ÃŽnÄƒlÅ£ime OSD (%)"
 
 msgid "Setup.OSD$Message time (s)"
-msgstr "Timp afiºare mesaje (sec)"
+msgstr "Timp afiÅŸare mesaje (sec)"
 
 msgid "Setup.OSD$Use small font"
 msgstr "Utilizare fonturi mici"
@@ -805,19 +805,19 @@
 msgstr "Font mic"
 
 msgid "Setup.OSD$Fixed font"
-msgstr "Font cu lãþime fixã"
+msgstr "Font cu lÄƒÅ£ime fixÄƒ"
 
 msgid "Setup.OSD$Default font size (%)"
-msgstr "Mãrimea implicitã a fontului (%)"
+msgstr "MÄƒrimea implicitÄƒ a fontului (%)"
 
 msgid "Setup.OSD$Small font size (%)"
-msgstr "Mãrimea 'micã' a fontului (%)"
+msgstr "MÄƒrimea 'micÄƒ' a fontului (%)"
 
 msgid "Setup.OSD$Fixed font size (%)"
-msgstr "Mãrimea 'fixã' a fontului (%)"
+msgstr "MÄƒrimea 'fixÄƒ' a fontului (%)"
 
 msgid "Setup.OSD$Channel info position"
-msgstr "Poziþia informaþiilor despre canal"
+msgstr "PoziÅ£ia informaÅ£iilor despre canal"
 
 msgid "bottom"
 msgstr "jos"
@@ -826,61 +826,61 @@
 msgstr "sus"
 
 msgid "Setup.OSD$Channel info time (s)"
-msgstr "Durata afiºãrii info-canal (s)"
+msgstr "Durata afiÅŸÄƒrii info-canal (s)"
 
 msgid "Setup.OSD$Info on channel switch"
-msgstr "Informaþii la comutarea canalului"
+msgstr "InformaÅ£ii la comutarea canalului"
 
 msgid "Setup.OSD$Timeout requested channel info"
-msgstr "Durata afiºãrii informaþii canal"
+msgstr "Durata afiÅŸÄƒrii informaÅ£ii canal"
 
 msgid "Setup.OSD$Scroll pages"
-msgstr "Deruleazã pagini"
+msgstr "DeruleazÄƒ pagini"
 
 msgid "Setup.OSD$Scroll wraps"
-msgstr "Derulare circularã"
+msgstr "Derulare circularÄƒ"
 
 msgid "Setup.OSD$Menu key closes"
-msgstr "Tasta 'Meniu' închide"
+msgstr "Tasta 'Meniu' Ã®nchide"
 
 msgid "Setup.OSD$Recording directories"
-msgstr "Directoare înregistrãri"
+msgstr "Directoare Ã®nregistrÄƒri"
 
 msgid "Setup.OSD$Folders in timer menu"
-msgstr "Directoare în meniul de timer-e"
+msgstr "Directoare Ã®n meniul de timer-e"
 
 msgid "Setup.OSD$Number keys for characters"
 msgstr "Caractere pe tastele numerice"
 
 msgid "Setup.OSD$Color key 0"
-msgstr ""
+msgstr "Primul buton colorat"
 
 msgid "Setup.OSD$Color key 1"
-msgstr ""
+msgstr "Al 2-lea buton colorat"
 
 msgid "Setup.OSD$Color key 2"
-msgstr ""
+msgstr "Al 3-lea buton colorat"
 
 msgid "Setup.OSD$Color key 3"
-msgstr ""
+msgstr "Al 4-lea buton colorat"
 
 msgid "EPG"
 msgstr "EPG"
 
 msgid "Button$Scan"
-msgstr "Cãutare canale"
+msgstr "CÄƒutare canale"
 
 msgid "Setup.EPG$EPG scan timeout (h)"
-msgstr "Interval achiziþie EPG (h)"
+msgstr "Interval achiziÅ£ie EPG (h)"
 
 msgid "Setup.EPG$EPG bugfix level"
-msgstr "Nivel corecþie EPG"
+msgstr "Nivel corecÅ£ie EPG"
 
 msgid "Setup.EPG$EPG linger time (min)"
 msgstr "Date EPG expirate cel mult (min)"
 
 msgid "Setup.EPG$Set system time"
-msgstr "Potriveºte ceasul sistem"
+msgstr "PotriveÅŸte ceasul sistem"
 
 msgid "Setup.EPG$Use time from transponder"
 msgstr "Preia ora din transponder"
@@ -891,7 +891,7 @@
 
 #. TRANSLATORS: note the singular!
 msgid "Setup.EPG$Preferred language"
-msgstr "Limba preferatã"
+msgstr "Limba preferatÄƒ"
 
 msgid "pan&scan"
 msgstr "pan&scan"
@@ -915,10 +915,10 @@
 msgstr "nume si PID-uri"
 
 msgid "add new channels"
-msgstr "adãugare canale noi"
+msgstr "adÄƒugare canale noi"
 
 msgid "add new transponders"
-msgstr "adãugare transpondere noi"
+msgstr "adÄƒugare transpondere noi"
 
 msgid "DVB"
 msgstr "Dispozitiv DVB"
@@ -930,16 +930,16 @@
 msgstr "Subtitrare"
 
 msgid "Setup.DVB$Primary DVB interface"
-msgstr "Dispozitiv DVB primar"
+msgstr "InterfaÈ›Äƒ DVB primarÄƒ"
 
 msgid "Setup.DVB$Standard compliance"
-msgstr ""
+msgstr "Standard de recepÈ›ie"
 
 msgid "Setup.DVB$Video format"
 msgstr "Format video"
 
 msgid "Setup.DVB$Video display format"
-msgstr "Formatul redãrii video"
+msgstr "Formatul redÄƒrii video"
 
 msgid "Setup.DVB$Use Dolby Digital"
 msgstr "Sunet Dolby Digital"
@@ -954,22 +954,22 @@
 msgstr "Limba sunetului"
 
 msgid "Setup.DVB$Display subtitles"
-msgstr "Afiºeazã subtitrare"
+msgstr "AfiÅŸeazÄƒ subtitrare"
 
 msgid "Setup.DVB$Subtitle languages"
 msgstr "Limbi subtitrare"
 
 msgid "Setup.DVB$Subtitle language"
-msgstr "Limbã subtitrare"
+msgstr "LimbÄƒ subtitrare"
 
 msgid "Setup.DVB$Subtitle offset"
 msgstr "Offset subtitrare"
 
 msgid "Setup.DVB$Subtitle foreground transparency"
-msgstr "Transparenþa prim-planului subtitrãrii"
+msgstr "TransparenÅ£a prim-planului subtitrÄƒrii"
 
 msgid "Setup.DVB$Subtitle background transparency"
-msgstr "Transparenþa fundalului subtitrãrii"
+msgstr "TransparenÅ£a fundalului subtitrÄƒrii"
 
 msgid "LNB"
 msgstr "LNB"
@@ -978,20 +978,20 @@
 msgstr "Utilizare DiSEqC"
 
 msgid "Setup.LNB$SLOF (MHz)"
-msgstr "Frecvenþã comutare bandã, SLOF (MHz)"
+msgstr "FrecvenÅ£Äƒ comutare bandÄƒ, SLOF (MHz)"
 
 msgid "Setup.LNB$Low LNB frequency (MHz)"
-msgstr "Frecvnþã LNB inferioarã (Mhz)"
+msgstr "FrecvnÅ£Äƒ LNB inferioarÄƒ (Mhz)"
 
 msgid "Setup.LNB$High LNB frequency (MHz)"
-msgstr "Frecvnþã LNB superioarã (MHz)"
+msgstr "FrecvnÅ£Äƒ LNB superioarÄƒ (MHz)"
 
 #, c-format
 msgid "Setup.LNB$Device %d connected to sat cable"
-msgstr ""
+msgstr "Receptorul %d conectat la cablul de satelit"
 
 msgid "Setup.LNB$own"
-msgstr ""
+msgstr "propriu"
 
 msgid "CAM reset"
 msgstr "Resetare CAM"
@@ -1000,7 +1000,7 @@
 msgstr "CAM prezent"
 
 msgid "CAM ready"
-msgstr "CAM pregãtit"
+msgstr "CAM pregÄƒtit"
 
 msgid "CAM"
 msgstr "CAM"
@@ -1018,19 +1018,19 @@
 msgstr "Nu pot deschide meniul CAM"
 
 msgid "CAM is in use - really reset?"
-msgstr "CAM-ul este in folosinþã - totuºi resetez?"
+msgstr "CAM-ul este in folosinÅ£Äƒ - totuÅŸi resetez?"
 
 msgid "Can't reset CAM!"
 msgstr "Nu pot reseta CAM"
 
 msgid "do not pause live video"
-msgstr "nu înregistra emisiunea"
+msgstr "nu Ã®nregistra emisiunea"
 
 msgid "confirm pause live video"
-msgstr "confirmã înregistrarea emisiunii"
+msgstr "confirmÄƒ Ã®nregistrarea emisiunii"
 
 msgid "pause live video"
-msgstr "înregistreazã emisiunea"
+msgstr "Ã®nregistreazÄƒ emisiunea"
 
 msgid "confirm"
 msgstr "confirmare"
@@ -1039,70 +1039,70 @@
 msgstr "da"
 
 msgid "Recording"
-msgstr "Înregistrare"
+msgstr "ÃŽnregistrare"
 
 msgid "Setup.Recording$Margin at start (min)"
-msgstr "Marjã la pornire (min)"
+msgstr "MarjÄƒ la pornire (min)"
 
 msgid "Setup.Recording$Margin at stop (min)"
-msgstr "Marjã la oprire (min)"
+msgstr "MarjÄƒ la oprire (min)"
 
 msgid "Setup.Recording$Default priority"
-msgstr "Prioritate implicitã"
+msgstr "Prioritate implicitÄƒ"
 
 msgid "Setup.Recording$Default lifetime (d)"
-msgstr "Timp de pãstrare predefinit (zile)"
+msgstr "Timp de pÄƒstrare predefinit (zile)"
 
 msgid "Setup.Recording$Pause key handling"
-msgstr "Funcþia tastei 'pauzã'"
+msgstr "FuncÅ£ia tastei 'pauzÄƒ'"
 
 msgid "Setup.Recording$Pause priority"
-msgstr "Prioritate pauzã"
+msgstr "Prioritate pauzÄƒ"
 
 msgid "Setup.Recording$Pause lifetime (d)"
-msgstr "Pãstrarea emisiunilor 'pauzate' (zile)"
+msgstr "PÄƒstrarea emisiunilor 'pauzate' (zile)"
 
 msgid "Setup.Recording$Use episode name"
-msgstr "Utilizeazã numele episodului"
+msgstr "UtilizeazÄƒ numele episodului"
 
 msgid "Setup.Recording$Use VPS"
-msgstr "Utilizeazã VPS"
+msgstr "UtilizeazÄƒ VPS"
 
 msgid "Setup.Recording$VPS margin (s)"
-msgstr "Marjã de timp la utilizare VPS (s)"
+msgstr "MarjÄƒ de timp la utilizare VPS (s)"
 
 msgid "Setup.Recording$Mark instant recording"
-msgstr "Marcheazã înregistrare imediatã"
+msgstr "MarcheazÄƒ Ã®nregistrare imediatÄƒ"
 
 msgid "Setup.Recording$Name instant recording"
-msgstr "Nume înregistrare imediatã"
+msgstr "Nume Ã®nregistrare imediatÄƒ"
 
 msgid "Setup.Recording$Instant rec. time (min)"
-msgstr "Timpul de înregistare imediatã (min)"
+msgstr "Timpul de Ã®nregistare imediatÄƒ (min)"
 
 msgid "Setup.Recording$present event"
-msgstr ""
+msgstr "eveniment curent"
 
 msgid "Setup.Recording$Max. video file size (MB)"
-msgstr "Dimensiune maximã a fiºierului video (MB)"
+msgstr "Dimensiune maximÄƒ a fiÅŸierului video (MB)"
 
 msgid "Setup.Recording$Split edited files"
-msgstr "Separare fiºiere montate"
+msgstr "Separare fiÅŸiere montate"
 
 msgid "Setup.Recording$Delete timeshift recording"
-msgstr "ªterge înregistrarea pentru vizionare decalatã"
+msgstr "Åžterge Ã®nregistrarea pentru vizionare decalatÄƒ"
 
 msgid "Replay"
 msgstr "Redare"
 
 msgid "Setup.Replay$Multi speed mode"
-msgstr "Mod multi-vitezã"
+msgstr "Mod multi-vitezÄƒ"
 
 msgid "Setup.Replay$Show replay mode"
-msgstr "Afiºeazã redarea"
+msgstr "AfiÅŸeazÄƒ redarea"
 
 msgid "Setup.Replay$Show remaining time"
-msgstr ""
+msgstr "AratÄƒ timpul rÄƒmas"
 
 msgid "Setup.Replay$Resume ID"
 msgstr "Identificator continuare"
@@ -1111,10 +1111,10 @@
 msgstr "Diverse"
 
 msgid "Setup.Miscellaneous$Min. event timeout (min)"
-msgstr "Duratã minimã emisiuni (min)"
+msgstr "DuratÄƒ minimÄƒ emisiuni (min)"
 
 msgid "Setup.Miscellaneous$Min. user inactivity (min)"
-msgstr "Durata minimã de inactivitate (min)"
+msgstr "Durata minimÄƒ de inactivitate (min)"
 
 msgid "Setup.Miscellaneous$SVDRP timeout (s)"
 msgstr "Timeout SVDRP (sec)"
@@ -1129,28 +1129,28 @@
 msgstr "Canalul de pornire"
 
 msgid "Setup.Miscellaneous$as before"
-msgstr "ca mai înainte"
+msgstr "ca mai Ã®nainte"
 
 msgid "Setup.Miscellaneous$Initial volume"
 msgstr "Volumul la pornire"
 
 msgid "Setup.Miscellaneous$Channels wrap"
-msgstr "Lista de canale în buclã"
+msgstr "Lista de canale Ã®n buclÄƒ"
 
 msgid "Setup.Miscellaneous$Show channel names with source"
-msgstr ""
+msgstr "AratÄƒ numele canalelor cu sursa"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr "Oprire de urgenþã"
+msgstr "Oprire de urgenÅ£Äƒ"
 
 msgid "Plugins"
 msgstr "Plugin-uri"
 
 msgid "This plugin has no setup parameters!"
-msgstr "Acest plugin nu se configureazã!"
+msgstr "Acest plugin nu se configureazÄƒ!"
 
 msgid "Setup"
-msgstr "Configuraþie"
+msgstr "ConfiguraÅ£ie"
 
 msgid "Restart"
 msgstr "Repornire"
@@ -1160,17 +1160,17 @@
 
 #. TRANSLATORS: note the leading and trailing blanks!
 msgid " Stop recording "
-msgstr " Opreºte înregistrarea "
+msgstr " OpreÅŸte Ã®nregistrarea "
 
 msgid "Schedule"
 msgstr "Program (EPG)"
 
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
-msgstr " Opreºte redarea"
+msgstr " OpreÅŸte redarea"
 
 msgid "Button$Pause"
-msgstr "Pauzã"
+msgstr "PauzÄƒ"
 
 msgid "Button$Stop"
 msgstr "Stop"
@@ -1180,56 +1180,59 @@
 
 #. TRANSLATORS: note the leading blank!
 msgid " Cancel editing"
-msgstr " Opreºte montajul înregistrãrii"
+msgstr " OpreÅŸte montajul Ã®nregistrÄƒrii"
 
 msgid "Stop recording?"
-msgstr "Opresc înregistrarea?"
+msgstr "Opresc Ã®nregistrarea?"
 
 msgid "Cancel editing?"
-msgstr "Opresc montajul înregistrãrii?"
+msgstr "Opresc montajul Ã®nregistrÄƒrii?"
 
 msgid "No audio available!"
-msgstr "Lipseºte sunetul!"
+msgstr "LipseÅŸte sunetul!"
 
 msgid "No subtitles"
-msgstr "Nu afiºeazã subtirare"
+msgstr "Nu afiÅŸeazÄƒ subtirare"
 
 msgid "No subtitles available!"
-msgstr "Subtitrare indisponibilã!"
+msgstr "Subtitrare indisponibilÄƒ!"
 
 msgid "Not enough disk space to start recording!"
-msgstr "Insuficient spaþiul pe disc pentru înregistrare!"
+msgstr "Insuficient spaÅ£iul pe disc pentru Ã®nregistrare!"
 
 msgid "No free DVB device to record!"
-msgstr "Nu mai sunt dispozitive DVB disponibile pentru înregistrare!"
+msgstr "Nu mai sunt receptoare DVB disponibile pentru Ã®nregistrare!"
 
 msgid "Pausing live video..."
-msgstr "Trec în pauzã emisiunea transmisã..."
+msgstr "Trec Ã®n pauzÄƒ emisiunea transmisÄƒ..."
 
 msgid "Delete timeshift recording?"
-msgstr "ªterg înregistrarea pentru vizionare decalatã?"
+msgstr "Åžterg Ã®nregistrarea pentru vizionare decalatÄƒ?"
 
 #. TRANSLATORS: note the trailing blank!
 msgid "Jump: "
 msgstr "Salt la: "
 
 msgid "No editing marks defined!"
-msgstr "Nu s-au pus marcaje de montaj pentru aceastã înregistrare"
+msgstr "Nu s-au pus marcaje de montaj pentru aceastÄƒ Ã®nregistrare"
+
+msgid "No editing sequences defined!"
+msgstr ""
 
 msgid "Can't start editing process!"
-msgstr "Nu pot porni montajul înregistrãrii!"
+msgstr "Nu pot porni montajul Ã®nregistrÄƒrii!"
 
 msgid "Editing process started"
-msgstr "Montajul înregistrãrii a început"
+msgstr "Montajul Ã®nregistrÄƒrii a Ã®nceput"
 
 msgid "Editing process already active!"
-msgstr "Montajul înregistrãrii este deja activ!"
+msgstr "Montajul Ã®nregistrÄƒrii este deja activ!"
 
 msgid "FileNameChars$ abcdefghijklmnopqrstuvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&"
-msgstr " aãâbcdefghiîjklmnopqrsºtþuvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&"
+msgstr " aÄƒÃ¢bcdefghiÃ®jklmnopqrsÅŸtÅ£uvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&"
 
 msgid "CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9"
-msgstr " 0\t-.,1#~\\^$[]|()*+?{}/:%@&\taãâbc2\tdef3\tghiî4\tjkl5\tmno6\tpqrsº7\ttþuv8\twxyz9"
+msgstr " 0\t-.,1#~\\^$[]|()*+?{}/:%@&\taÄƒÃ¢bc2\tdef3\tghiÃ®4\tjkl5\tmno6\tpqrsÅŸ7\ttÅ£uv8\twxyz9"
 
 msgid "Button$ABC/abc"
 msgstr "ABC/abc"
@@ -1238,19 +1241,19 @@
 msgstr "Suprascrie"
 
 msgid "Button$Insert"
-msgstr "Insereazã"
+msgstr "InsereazÄƒ"
 
 msgid "Plugin"
-msgstr "Plugin (modul adiþional)"
+msgstr "Plugin (modul adiÅ£ional)"
 
 msgid "Up/Dn for new location - OK to move"
-msgstr "Sus/Jos pentru noua locaþie - OK pentru a muta"
+msgstr "Sus/Jos pentru noua locaÅ£ie - OK pentru a muta"
 
 msgid "Channel locked (recording)!"
-msgstr "Canal blocat (înregistrare)!"
+msgstr "Canal blocat (Ã®nregistrare)!"
 
 msgid "Low disk space!"
-msgstr "Spaþiul pe disc e foarte scãzut!"
+msgstr "SpaÅ£iul pe disc e foarte scÄƒzut!"
 
 msgid "Regenerating index file"
 msgstr "Generez index"
@@ -1259,36 +1262,36 @@
 msgstr "Generarea indexului s-a incheiat"
 
 msgid "Index file regeneration failed!"
-msgstr ""
+msgstr "Generarea indexului a eÈ™uat!"
 
 msgid "Can't shutdown - option '-s' not given!"
-msgstr "Nu pot închide - vezi opþiunea '-s'"
+msgstr "Nu pot Ã®nchide - vezi opÅ£iunea '-s'"
 
 msgid "Editing - shut down anyway?"
-msgstr "Montajul tocmai se efectueazã - închid, totuºi?"
+msgstr "Montajul tocmai se efectueazÄƒ - Ã®nchid, totuÅŸi?"
 
 msgid "Recording - shut down anyway?"
-msgstr "Tocmai se înregistreazã - închid, totuºi?"
+msgstr "Tocmai se Ã®nregistreazÄƒ - Ã®nchid, totuÅŸi?"
 
 #, c-format
 msgid "Recording in %ld minutes, shut down anyway?"
-msgstr "Înregistrez peste %ld minute - închid, totuºi?"
+msgstr "ÃŽnregistrez peste %ld minute - Ã®nchid, totuÅŸi?"
 
 msgid "shut down anyway?"
-msgstr "închid, totuºi?"
+msgstr "Ã®nchid, totuÅŸi?"
 
 #, c-format
 msgid "Plugin %s wakes up in %ld min, continue?"
 msgstr "Plugin-ul %s se va trezi +n %ld min, continui?"
 
 msgid "Editing - restart anyway?"
-msgstr "Montajul tocmai se efectueazã - repornesc, totuºi?"
+msgstr "Montajul tocmai se efectueazÄƒ - repornesc, totuÅŸi?"
 
 msgid "Recording - restart anyway?"
-msgstr "Tocmai se înregistreazã - repornesc, totuºi?"
+msgstr "Tocmai se Ã®nregistreazÄƒ - repornesc, totuÅŸi?"
 
 msgid "restart anyway?"
-msgstr "repornesc, totuºi?"
+msgstr "repornesc, totuÅŸi?"
 
 #. TRANSLATORS: note the trailing blank!
 msgid "Volume "
@@ -1298,22 +1301,22 @@
 msgstr "VDR clasic"
 
 msgid "DISK"
-msgstr ""
+msgstr "HARD-DISC"
 
 msgid "LOAD"
-msgstr ""
+msgstr "SARCINÄ‚"
 
 msgid "TIMERS"
-msgstr ""
+msgstr "TIMER-E"
 
 msgid "DEVICES"
-msgstr ""
+msgstr "RECEPTOARE"
 
 msgid "LIVE"
-msgstr ""
+msgstr "LIVE"
 
 msgid "PLAY"
-msgstr ""
+msgstr "REDARE"
 
 msgid "ST:TNG Panels"
 msgstr "Cons. ST:TNG"
@@ -1324,13 +1327,13 @@
 
 #. TRANSLATORS: abbreviated weekdays, beginning with monday (must all be 3 letters!)
 msgid "MonTueWedThuFriSatSun"
-msgstr "LunMarMieJoiVinSâmDum"
+msgstr "LunMarMieJoiVinSÃ¢mDum"
 
 msgid "Monday"
 msgstr "Luni"
 
 msgid "Tuesday"
-msgstr "Marþi"
+msgstr "MarÅ£i"
 
 msgid "Wednesday"
 msgstr "Miercuri"
@@ -1342,41 +1345,41 @@
 msgstr "Vineri"
 
 msgid "Saturday"
-msgstr "Sâmbãtã"
+msgstr "SÃ¢mbÄƒtÄƒ"
 
 msgid "Sunday"
-msgstr "Duminicã"
+msgstr "DuminicÄƒ"
 
 msgid "Upcoming recording!"
-msgstr "Urmeazã o înregistrare!"
+msgstr "UrmeazÄƒ o Ã®nregistrare!"
 
 msgid "Pause live video?"
-msgstr "Înregistrez emisiunea?"
+msgstr "ÃŽnregistrez emisiunea?"
 
 msgid "Recording started"
-msgstr "A început înregistrarea"
+msgstr "A Ã®nceput Ã®nregistrarea"
 
 msgid "VDR will shut down later - press Power to force"
-msgstr "VDR se va închide mai târziu - apãsaþi 'Power' pentru a forþa"
+msgstr "VDR se va Ã®nchide mai tÃ¢rziu - apÄƒsaÅ£i 'Power' pentru a forÅ£a"
 
 msgid "Press any key to cancel shutdown"
-msgstr "Apasã orice tastã pentru a anula închiderea"
+msgstr "ApasÄƒ orice tastÄƒ pentru a anula Ã®nchiderea"
 
 msgid "Switching primary DVB..."
 msgstr "Comut dispozitiv DVB primar..."
 
 msgid "Editing process failed!"
-msgstr "Montajul înregistrãrii a eºuat"
+msgstr "Montajul Ã®nregistrÄƒrii a eÅŸuat"
 
 msgid "Editing process finished"
-msgstr "Montajul înregistrãrii s-a terminat"
+msgstr "Montajul Ã®nregistrÄƒrii s-a terminat"
 
 msgid "Press any key to cancel restart"
-msgstr "Apãsaþi orice tastã pentru a anula repornirea"
+msgstr "ApÄƒsaÅ£i orice tastÄƒ pentru a anula repornirea"
 
 #, c-format
 msgid "VDR will shut down in %s minutes"
-msgstr "VDR se va închide în %s minute"
+msgstr "VDR se va Ã®nchide Ã®n %s minute"
 
 msgid "Disk"
 msgstr "Disc"
diff -ruN vdr-1.7.31/po/ru_RU.po vdr-1.7.32/po/ru_RU.po
--- vdr-1.7.31/po/ru_RU.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/ru_RU.po	2012-11-18 14:31:55.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-12-15 14:37+0100\n"
 "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
 "Language-Team: Russian <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "½Õ ×ÐÔÐÝë ÜÕâÚØ ÔÛï ÜÞÝâÐÖÐ!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "½ÕÒÞ×ÜÞÖÝÞ ÝÐçÐâì ÜÞÝâÐÖ ×ÐßØáØ!"
 
diff -ruN vdr-1.7.31/po/sk_SK.po vdr-1.7.32/po/sk_SK.po
--- vdr-1.7.31/po/sk_SK.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/sk_SK.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.16\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2011-02-15 16:29+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
 "Language-Team: Slovak <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Nie sú urèené znaèky úprav!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Nemô¾e zaèa» spracovanie úprav!"
 
diff -ruN vdr-1.7.31/po/sl_SI.po vdr-1.7.32/po/sl_SI.po
--- vdr-1.7.31/po/sl_SI.po	2012-09-15 15:57:39.000000000 +0200
+++ vdr-1.7.32/po/sl_SI.po	2012-11-18 14:31:55.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-02-28 19:44+0100\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
 "Language-Team: Slovenian <vdr@linuxtv.org>\n"
@@ -1214,6 +1214,9 @@
 msgid "No editing marks defined!"
 msgstr "Nobena prekinitvena toèka ni definirana!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ne morem zaèeti urejanja!"
 
diff -ruN vdr-1.7.31/po/sr_SR.po vdr-1.7.32/po/sr_SR.po
--- vdr-1.7.31/po/sr_SR.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/sr_SR.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.1\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2011-01-09 15:57+0100\n"
 "Last-Translator: Milan Cvijanoviæ <elcom_cvijo@hotmail.com>\n"
 "Language-Team: Serbian <vdr@linuxtv.org>\n"
@@ -1239,6 +1239,9 @@
 msgid "No editing marks defined!"
 msgstr "Nijedna taèka rezanja nije odreðena!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ne mogu zapoèeti ureðivanje!"
 
diff -ruN vdr-1.7.31/po/sv_SE.po vdr-1.7.32/po/sv_SE.po
--- vdr-1.7.31/po/sv_SE.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/sv_SE.po	2012-11-18 14:31:54.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-03-12 18:25+0100\n"
 "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n"
 "Language-Team: Swedish <vdr@linuxtv.org>\n"
@@ -1216,6 +1216,9 @@
 msgid "No editing marks defined!"
 msgstr "Det finns inga redigeringsmärken"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Kan inte starta redigering!"
 
diff -ruN vdr-1.7.31/po/tr_TR.po vdr-1.7.32/po/tr_TR.po
--- vdr-1.7.31/po/tr_TR.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/tr_TR.po	2012-11-18 14:31:55.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2008-02-28 00:33+0100\n"
 "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
 "Language-Team: Turkish <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Kesim iþaretleri belirtilmemiþ!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Kesim baþlatýlamýyor!"
 
diff -ruN vdr-1.7.31/po/uk_UA.po vdr-1.7.32/po/uk_UA.po
--- vdr-1.7.31/po/uk_UA.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/uk_UA.po	2012-11-18 14:31:54.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2010-04-25 16:35+0200\n"
 "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
 "Language-Team: Ukrainian <vdr@linuxtv.org>\n"
@@ -1213,6 +1213,9 @@
 msgid "No editing marks defined!"
 msgstr "Ð�Ðµ Ð·Ð°Ð´Ð°Ð½Ð¾ Ð¼Ñ–Ñ‚Ð¾Ðº Ð´Ð»Ñ� Ð¼Ð¾Ð½Ñ‚Ð°Ð¶Ñƒ!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "Ð�ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ Ð¿Ð¾Ñ‡Ð°Ñ‚Ð¸ Ð¼Ð¾Ð½Ñ‚Ð°Ð¶ Ð·Ð°Ð¿Ð¸Ñ�Ñƒ!"
 
diff -ruN vdr-1.7.31/po/zh_CN.po vdr-1.7.32/po/zh_CN.po
--- vdr-1.7.31/po/zh_CN.po	2012-09-15 15:57:38.000000000 +0200
+++ vdr-1.7.32/po/zh_CN.po	2012-11-18 14:31:53.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2012-09-15 14:04+0200\n"
+"POT-Creation-Date: 2012-11-18 14:31+0100\n"
 "PO-Revision-Date: 2009-09-23 23:50+0800\n"
 "Last-Translator: Nan Feng <nfgx@21cn.com>\n"
 "Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n"
@@ -1216,6 +1216,9 @@
 msgid "No editing marks defined!"
 msgstr "æ— ç¼–è¾‘æ ‡è®°å®šä¹‰!"
 
+msgid "No editing sequences defined!"
+msgstr ""
+
 msgid "Can't start editing process!"
 msgstr "ä¸�èƒ½å¼€å§‹ç¼–è¾‘å¤„ç�†"
 
diff -ruN vdr-1.7.31/recording.c vdr-1.7.32/recording.c
--- vdr-1.7.31/recording.c	2012-09-30 15:05:14.000000000 +0200
+++ vdr-1.7.32/recording.c	2012-11-13 14:46:49.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 2.64 2012/09/30 13:05:14 kls Exp $
+ * $Id: recording.c 2.73 2012/11/13 13:46:49 kls Exp $
  */
 
 #include "recording.h"
@@ -83,20 +83,20 @@
   };
 
 cRemoveDeletedRecordingsThread::cRemoveDeletedRecordingsThread(void)
-:cThread("remove deleted recordings")
+:cThread("remove deleted recordings", true)
 {
 }
 
 void cRemoveDeletedRecordingsThread::Action(void)
 {
-  SetPriority(19);
-  SetIOPriority(7);
   // Make sure only one instance of VDR does this:
   cLockFile LockFile(VideoDirectory);
   if (LockFile.Lock()) {
      bool deleted = false;
      cThreadLock DeletedRecordingsLock(&DeletedRecordings);
      for (cRecording *r = DeletedRecordings.First(); r; ) {
+         if (cIoThrottle::Engaged())
+            return;
          if (r->Deleted() && time(NULL) - r->Deleted() > DELETEDLIFETIME) {
             cRecording *next = DeletedRecordings.Next(r);
             r->Remove();
@@ -1358,8 +1358,10 @@
 
 bool cMarks::Load(const char *RecordingFileName, double FramesPerSecond, bool IsPesRecording)
 {
+  recordingFileName = RecordingFileName;
   fileName = AddDirectory(RecordingFileName, IsPesRecording ? MARKSFILESUFFIX ".vdr" : MARKSFILESUFFIX);
   framesPerSecond = FramesPerSecond;
+  isPesRecording = IsPesRecording;
   nextUpdate = 0;
   lastFileTime = -1; // the first call to Load() must take place!
   lastChange = 0;
@@ -1388,6 +1390,7 @@
         cMutexLock MutexLock(&MutexMarkFramesPerSecond);
         MarkFramesPerSecond = framesPerSecond;
         if (cConfig<cMark>::Load(fileName)) {
+           Align();
            Sort();
            return true;
            }
@@ -1396,6 +1399,18 @@
   return false;
 }
 
+void cMarks::Align(void)
+{
+  cIndexFile IndexFile(recordingFileName, false, isPesRecording);
+  for (cMark *m = First(); m; m = Next(m)) {
+      int p = IndexFile.GetClosestIFrame(m->Position());
+      if (int d = m->Position() - p) {
+         isyslog("aligned editing mark %s to %s (off by %d frame%s)", *IndexToHMSF(m->Position(), true, framesPerSecond), *IndexToHMSF(p, true, framesPerSecond), d, abs(d) > 1 ? "s" : "");
+         m->SetPosition(p);
+         }
+      }
+}
+
 void cMarks::Sort(void)
 {
   for (cMark *m1 = First(); m1; m1 = Next(m1)) {
@@ -1408,14 +1423,10 @@
       }
 }
 
-cMark *cMarks::Add(int Position)
+void cMarks::Add(int Position)
 {
-  cMark *m = Get(Position);
-  if (!m) {
-     cConfig<cMark>::Add(m = new cMark(Position, NULL, framesPerSecond));
-     Sort();
-     }
-  return m;
+  cConfig<cMark>::Add(new cMark(Position, NULL, framesPerSecond));
+  Sort();
 }
 
 cMark *cMarks::Get(int Position)
@@ -1445,6 +1456,54 @@
   return NULL;
 }
 
+cMark *cMarks::GetNextBegin(cMark *EndMark)
+{
+  cMark *BeginMark = EndMark ? Next(EndMark) : First();
+  if (BeginMark) {
+     while (cMark *NextMark = Next(BeginMark)) {
+           if (BeginMark->Position() == NextMark->Position()) { // skip Begin/End at the same position
+              if (!(BeginMark = Next(NextMark)))
+                 break;
+              }
+           else
+              break;
+           }
+     }
+  return BeginMark;
+}
+
+cMark *cMarks::GetNextEnd(cMark *BeginMark)
+{
+  if (!BeginMark)
+     return NULL;
+  cMark *EndMark = Next(BeginMark);
+  if (EndMark) {
+     while (cMark *NextMark = Next(EndMark)) {
+           if (EndMark->Position() == NextMark->Position()) { // skip End/Begin at the same position
+              if (!(EndMark = Next(NextMark)))
+                 break;
+              }
+           else
+              break;
+           }
+     }
+  return EndMark;
+}
+
+int cMarks::GetNumSequences(void)
+{
+  int NumSequences = 0;
+  if (cMark *BeginMark = GetNextBegin()) {
+     while (cMark *EndMark = GetNextEnd(BeginMark)) {
+           NumSequences++;
+           BeginMark = GetNextBegin(EndMark);
+           }
+     if (NumSequences == 0 && BeginMark->Position() > 0)
+        NumSequences = 1; // there is only one actual "begin" mark at a non-zero offset, and no actual "end" mark
+     }
+  return NumSequences;
+}
+
 // --- cRecordingUserCommand -------------------------------------------------
 
 const char *cRecordingUserCommand::command = NULL;
@@ -1535,7 +1594,6 @@
               if (Processed > 0) {
                  if (FrameDetector.Synced()) {
                     // Synced FrameDetector, so rewind for actual processing:
-                    FrameDetector.Reset();
                     Rewind = true;
                     }
                  Buffer.Del(Processed);
@@ -1546,7 +1604,7 @@
               uchar *p = Data;
               while (Length >= TS_SIZE) {
                     int Pid = TsPid(p);
-                    if (Pid == 0)
+                    if (Pid == PATPID)
                        PatPmtParser.ParsePat(p, TS_SIZE);
                     else if (Pid == PatPmtParser.PmtPid())
                        PatPmtParser.ParsePmt(p, TS_SIZE);
@@ -1570,6 +1628,7 @@
               ReplayFile = FileName.NextFile();
               FileSize = 0;
               FrameOffset = -1;
+              Buffer.Clear();
               }
            }
         // Recording has been processed:
@@ -1753,7 +1812,7 @@
   // returns true unless something really goes wrong, so that 'index' becomes NULL
   if (index && f >= 0) {
      cMutexLock MutexLock(&mutex);
-     for (int i = 0; i <= MAXINDEXCATCHUP && (Index < 0 || Index >= last); i++) {
+     for (int i = 0; i <= MAXINDEXCATCHUP && (Index < 0 || Index > last); i++) {
          struct stat buf;
          if (fstat(f, &buf) == 0) {
             if (!IsInIndexList(this)) {
@@ -1798,7 +1857,7 @@
             }
          else
             LOG_ERROR_STR(*fileName);
-         if (Index < last)
+         if (Index <= last)
             break;
          cCondWait::SleepMs(1000);
          }
@@ -1826,18 +1885,22 @@
 bool cIndexFile::Get(int Index, uint16_t *FileNumber, off_t *FileOffset, bool *Independent, int *Length)
 {
   if (CatchUp(Index)) {
-     if (Index >= 0 && Index < last) {
+     if (Index >= 0 && Index <= last) {
         *FileNumber = index[Index].number;
         *FileOffset = index[Index].offset;
         if (Independent)
            *Independent = index[Index].independent;
         if (Length) {
-           uint16_t fn = index[Index + 1].number;
-           off_t fo = index[Index + 1].offset;
-           if (fn == *FileNumber)
-              *Length = int(fo - *FileOffset);
+           if (Index < last) {
+              uint16_t fn = index[Index + 1].number;
+              off_t fo = index[Index + 1].offset;
+              if (fn == *FileNumber)
+                 *Length = int(fo - *FileOffset);
+              else
+                 *Length = -1; // this means "everything up to EOF" (the buffer's Read function will act accordingly)
+              }
            else
-              *Length = -1; // this means "everything up to EOF" (the buffer's Read function will act accordingly)
+              *Length = -1;
            }
         return true;
         }
@@ -1851,7 +1914,7 @@
      int d = Forward ? 1 : -1;
      for (;;) {
          Index += d;
-         if (Index >= 0 && Index < last) {
+         if (Index >= 0 && Index <= last) {
             if (index[Index].independent) {
                uint16_t fn;
                if (!FileNumber)
@@ -1882,12 +1945,40 @@
   return -1;
 }
 
+int cIndexFile::GetClosestIFrame(int Index)
+{
+  if (last > 0) {
+     Index = constrain(Index, 0, last);
+     if (index[Index].independent)
+        return Index;
+     int il = Index - 1;
+     int ih = Index + 1;
+     for (;;) {
+         if (il >= 0) {
+            if (index[il].independent)
+               return il;
+            il--;
+            }
+         else if (ih > last)
+            break;
+         if (ih <= last) {
+            if (index[ih].independent)
+               return ih;
+            ih++;
+            }
+         else if (il < 0)
+            break;
+         }
+     }
+  return 0;
+}
+
 int cIndexFile::Get(uint16_t FileNumber, off_t FileOffset)
 {
   if (CatchUp()) {
      //TODO implement binary search!
      int i;
-     for (i = 0; i < last; i++) {
+     for (i = 0; i <= last; i++) {
          if (index[i].number > FileNumber || (index[i].number == FileNumber) && off_t(index[i].offset) >= FileOffset)
             break;
          }
@@ -2039,7 +2130,7 @@
                   while (read(fd, buf, sizeof(buf)) == sizeof(buf)) {
                         if (buf[0] == TS_SYNC_BYTE) {
                            int Pid = TsPid(buf);
-                           if (Pid == 0)
+                           if (Pid == PATPID)
                               PatPmtParser.ParsePat(buf, sizeof(buf));
                            else if (Pid == PatPmtParser.PmtPid()) {
                               PatPmtParser.ParsePmt(buf, sizeof(buf));
diff -ruN vdr-1.7.31/recording.h vdr-1.7.32/recording.h
--- vdr-1.7.31/recording.h	2012-09-17 10:53:23.000000000 +0200
+++ vdr-1.7.32/recording.h	2012-11-13 12:43:59.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.h 2.37 2012/09/17 08:53:23 kls Exp $
+ * $Id: recording.h 2.40 2012/11/13 11:43:59 kls Exp $
  */
 
 #ifndef __RECORDING_H
@@ -222,19 +222,35 @@
 
 class cMarks : public cConfig<cMark> {
 private:
+  cString recordingFileName;
   cString fileName;
   double framesPerSecond;
+  bool isPesRecording;
   time_t nextUpdate;
   time_t lastFileTime;
   time_t lastChange;
 public:
   bool Load(const char *RecordingFileName, double FramesPerSecond = DEFAULTFRAMESPERSECOND, bool IsPesRecording = false);
   bool Update(void);
+  void Align(void);
   void Sort(void);
-  cMark *Add(int Position);
+  void Add(int Position);
   cMark *Get(int Position);
   cMark *GetPrev(int Position);
   cMark *GetNext(int Position);
+  cMark *GetNextBegin(cMark *EndMark = NULL);
+       ///< Returns the next "begin" mark after EndMark, skipping any marks at the
+       ///< same position as EndMark. If EndMark is NULL, the first actual "begin"
+       ///< will be returned (if any).
+  cMark *GetNextEnd(cMark *BeginMark);
+       ///< Returns the next "end" mark after BeginMark, skipping any marks at the
+       ///< same position as BeginMark.
+  int GetNumSequences(void);
+       ///< Returns the actual number of sequences to be cut from the recording.
+       ///< If there is only one actual "begin" mark, and it is positioned at index
+       ///< 0 (the beginning of the recording), and there is no "end" mark, the
+       ///< return value is 0, which means that the result is the same as the original
+       ///< recording.
   };
 
 #define RUC_BEFORERECORDING "before"
@@ -291,8 +307,14 @@
   bool Write(bool Independent, uint16_t FileNumber, off_t FileOffset);
   bool Get(int Index, uint16_t *FileNumber, off_t *FileOffset, bool *Independent = NULL, int *Length = NULL);
   int GetNextIFrame(int Index, bool Forward, uint16_t *FileNumber = NULL, off_t *FileOffset = NULL, int *Length = NULL);
+  int GetClosestIFrame(int Index);
+       ///< Returns the index of the I-frame that is closest to the given Index (or Index itself,
+       ///< if it already points to an I-frame). Index may be any value, even outside the current
+       ///< range of frame indexes.
+       ///< If there is no actual index data available, 0 is returned.
   int Get(uint16_t FileNumber, off_t FileOffset);
   int Last(void) { CatchUp(); return last; }
+       ///< Returns the index of the last entry in this file, or -1 if the file is empty.
   int GetResume(void) { return resumeFile.Read(); }
   bool StoreResume(int Index) { return resumeFile.Save(Index); }
   bool IsStillRecording(void);
diff -ruN vdr-1.7.31/remux.c vdr-1.7.32/remux.c
--- vdr-1.7.31/remux.c	2012-09-19 12:28:42.000000000 +0200
+++ vdr-1.7.32/remux.c	2012-11-18 13:18:08.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.c 2.67 2012/09/19 10:28:42 kls Exp $
+ * $Id: remux.c 2.71 2012/11/18 12:18:08 kls Exp $
  */
 
 #include "remux.h"
@@ -23,6 +23,8 @@
 #define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
 #define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
 
+#define EMPTY_SCANNER (0xFFFFFFFF)
+
 ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
 {
   if (Count < 7)
@@ -112,6 +114,32 @@
 
 // --- Some TS handling tools ------------------------------------------------
 
+void TsHidePayload(uchar *p)
+{
+  p[1] &= ~TS_PAYLOAD_START;
+  p[3] |=  TS_ADAPT_FIELD_EXISTS;
+  p[3] &= ~TS_PAYLOAD_EXISTS;
+  p[4] = TS_SIZE - 5;
+  p[5] = 0x00;
+  memset(p + 6, 0xFF, TS_SIZE - 6);
+}
+
+void TsSetPcr(uchar *p, int64_t Pcr)
+{
+  if (TsHasAdaptationField(p)) {
+     if (p[4] >= 7 && (p[5] & TS_ADAPT_PCR)) {
+        int64_t b = Pcr / PCRFACTOR;
+        int e = Pcr % PCRFACTOR;
+        p[ 6] =  b >> 25;
+        p[ 7] =  b >> 17;
+        p[ 8] =  b >>  9;
+        p[ 9] =  b >>  1;
+        p[10] = (b <<  7) | (p[10] & 0x7E) | ((e >> 8) & 0x01);
+        p[11] =  e;
+        }
+     }
+}
+
 int64_t TsGetPts(const uchar *p, int l)
 {
   // Find the first packet with a PTS and use it:
@@ -125,27 +153,165 @@
   return -1;
 }
 
-void TsSetTeiOnBrokenPackets(uchar *p, int l)
+int64_t TsGetDts(const uchar *p, int l)
 {
-  bool Processed[MAXPID] = { false };
-  while (l >= TS_SIZE) {
-        if (*p != TS_SYNC_BYTE)
-           break;
-        int Pid = TsPid(p);
-        if (!Processed[Pid]) {
-           if (!TsPayloadStart(p))
-              p[1] |= TS_ERROR;
-           else {
-              Processed[Pid] = true;
-              int offs = TsPayloadOffset(p);
-              cRemux::SetBrokenLink(p + offs, TS_SIZE - offs);
-              }
+  // Find the first packet with a DTS and use it:
+  while (l > 0) {
+        const uchar *d = p;
+        if (TsPayloadStart(d) && TsGetPayload(&d) && PesHasDts(d))
+           return PesGetDts(d);
+        p += TS_SIZE;
+        l -= TS_SIZE;
+        }
+  return -1;
+}
+
+void TsSetPts(uchar *p, int l, int64_t Pts)
+{
+  // Find the first packet with a PTS and use it:
+  while (l > 0) {
+        const uchar *d = p;
+        if (TsPayloadStart(d) && TsGetPayload(&d) && PesHasPts(d)) {
+           PesSetPts(const_cast<uchar *>(d), Pts);
+           return;
            }
+        p += TS_SIZE;
         l -= TS_SIZE;
+        }
+}
+
+void TsSetDts(uchar *p, int l, int64_t Dts)
+{
+  // Find the first packet with a DTS and use it:
+  while (l > 0) {
+        const uchar *d = p;
+        if (TsPayloadStart(d) && TsGetPayload(&d) && PesHasDts(d)) {
+           PesSetDts(const_cast<uchar *>(d), Dts);
+           return;
+           }
         p += TS_SIZE;
+        l -= TS_SIZE;
         }
 }
 
+// --- Some PES handling tools -----------------------------------------------
+
+void PesSetPts(uchar *p, int64_t Pts)
+{
+  p[ 9] = ((Pts >> 29) & 0x0E) | (p[9] & 0xF1);
+  p[10] =   Pts >> 22;
+  p[11] = ((Pts >> 14) & 0xFE) | 0x01;
+  p[12] =   Pts >>  7;
+  p[13] = ((Pts <<  1) & 0xFE) | 0x01;
+}
+
+void PesSetDts(uchar *p, int64_t Dts)
+{
+  p[14] = ((Dts >> 29) & 0x0E) | (p[14] & 0xF1);
+  p[15] =   Dts >> 22;
+  p[16] = ((Dts >> 14) & 0xFE) | 0x01;
+  p[17] =   Dts >>  7;
+  p[18] = ((Dts <<  1) & 0xFE) | 0x01;
+}
+
+int64_t PtsDiff(int64_t Pts1, int64_t Pts2)
+{
+  int64_t d = Pts2 - Pts1;
+  if (d > MAX33BIT / 2)
+     return d - (MAX33BIT + 1);
+  if (d < -MAX33BIT / 2)
+     return d + (MAX33BIT + 1);
+  return d;
+}
+
+// --- cTsPayload ------------------------------------------------------------
+
+cTsPayload::cTsPayload(void)
+{
+  data = NULL;
+  length = 0;
+  pid = -1;
+  index = 0;
+}
+
+cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
+{
+  Setup(Data, Length, Pid);
+}
+
+void cTsPayload::Setup(uchar *Data, int Length, int Pid)
+{
+  data = Data;
+  length = Length;
+  pid = Pid >= 0 ? Pid : TsPid(Data);
+  index = 0;
+}
+
+uchar cTsPayload::GetByte(void)
+{
+  if (!Eof()) {
+     if (index % TS_SIZE == 0) { // encountered the next TS header
+        for (;; index += TS_SIZE) {
+            if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end
+               uchar *p = data + index;
+               if (TsPid(p) == pid) { // only handle TS packets for the initial PID
+                  if (TsHasPayload(p)) {
+                     if (index > 0 && TsPayloadStart(p)) { // checking index to not skip the very first TS packet
+                        length = index; // triggers EOF
+                        return 0x00;
+                        }
+                     index += TsPayloadOffset(p);
+                     break;
+                     }
+                  }
+               }
+            else {
+               length = index; // triggers EOF
+               return 0x00;
+               }
+           }
+        }
+     return data[index++];
+     }
+  return 0x00;
+}
+
+bool cTsPayload::SkipBytes(int Bytes)
+{
+  while (Bytes-- > 0)
+        GetByte();
+  return !Eof();
+}
+
+bool cTsPayload::SkipPesHeader(void)
+{
+  return SkipBytes(PesPayloadOffset(data + TsPayloadOffset(data)));
+}
+
+int cTsPayload::GetLastIndex(void)
+{
+  return index - 1;
+}
+
+void cTsPayload::SetByte(uchar Byte, int Index)
+{
+  if (Index >= 0 && Index < length)
+     data[Index] = Byte;
+}
+
+bool cTsPayload::Find(uint32_t Code)
+{
+  int OldIndex = index;
+  uint32_t Scanner = EMPTY_SCANNER;
+  while (!Eof()) {
+        Scanner = (Scanner << 8) | GetByte();
+        if (Scanner == Code)
+           return true;
+        }
+  index = OldIndex;
+  return false;
+}
+
 // --- cPatPmtGenerator ------------------------------------------------------
 
 cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
@@ -665,6 +831,25 @@
   pmtSize = 0;
 }
 
+bool cPatPmtParser::ParsePatPmt(const uchar *Data, int Length)
+{
+  while (Length >= TS_SIZE) {
+        if (*Data != TS_SYNC_BYTE)
+           break; // just for safety
+        int Pid = TsPid(Data);
+        if (Pid == PATPID)
+           ParsePat(Data, TS_SIZE);
+        else if (Pid == PmtPid()) {
+           ParsePmt(Data, TS_SIZE);
+           if (patVersion >= 0 && pmtVersion >= 0)
+              return true;
+           }
+        Data += TS_SIZE;
+        Length -= TS_SIZE;
+        }
+  return false;
+}
+
 bool cPatPmtParser::GetVersions(int &PatVersion, int &PmtVersion) const
 {
   PatVersion = patVersion;
@@ -809,23 +994,365 @@
   TsDump(Name, Data, Length);
 }
 
-// --- cFrameDetector --------------------------------------------------------
+// --- cFrameParser ----------------------------------------------------------
 
-#define EMPTY_SCANNER (0xFFFFFFFF)
+class cFrameParser {
+protected:
+  bool debug;
+  bool newFrame;
+  bool independentFrame;
+public:
+  cFrameParser(void);
+  virtual ~cFrameParser() {};
+  virtual int Parse(const uchar *Data, int Length, int Pid) = 0;
+       ///< Parses the given Data, which is a sequence of Length bytes of TS packets.
+       ///< The payload in the TS packets with the given Pid is searched for just
+       ///< enough information to determine the beginning and type of the next video
+       ///< frame.
+       ///< Returns the number of bytes parsed. Upon return, the functions NewFrame()
+       ///< and IndependentFrame() can be called to retrieve the required information.
+  void SetDebug(bool Debug) { debug = Debug; }
+  bool NewFrame(void) { return newFrame; }
+  bool IndependentFrame(void) { return independentFrame; }
+  };
+
+cFrameParser::cFrameParser(void)
+{
+  debug = true;
+  newFrame = false;
+  independentFrame = false;
+}
+
+// --- cAudioParser ----------------------------------------------------------
+
+class cAudioParser : public cFrameParser {
+public:
+  cAudioParser(void);
+  virtual int Parse(const uchar *Data, int Length, int Pid);
+  };
+
+cAudioParser::cAudioParser(void)
+{
+}
+
+int cAudioParser::Parse(const uchar *Data, int Length, int Pid)
+{
+  if (TsPayloadStart(Data)) {
+     newFrame = independentFrame = true;
+     if (debug)
+        dbgframes("/");
+     }
+  else
+     newFrame = independentFrame = false;
+  return TS_SIZE;
+}
+
+// --- cMpeg2Parser ----------------------------------------------------------
+
+class cMpeg2Parser : public cFrameParser {
+private:
+  uint32_t scanner;
+  bool seenIndependentFrame;
+public:
+  cMpeg2Parser(void);
+  virtual int Parse(const uchar *Data, int Length, int Pid);
+  };
+
+cMpeg2Parser::cMpeg2Parser(void)
+{
+  scanner = EMPTY_SCANNER;
+  seenIndependentFrame = false;
+}
+
+int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
+{
+  newFrame = independentFrame = false;
+  bool SeenPayloadStart = false;
+  cTsPayload tsPayload(const_cast<uchar *>(Data), Length, Pid);
+  if (TsPayloadStart(Data)) {
+     SeenPayloadStart = true;
+     tsPayload.SkipPesHeader();
+     scanner = EMPTY_SCANNER;
+     if (debug && seenIndependentFrame)
+        dbgframes("/");
+     }
+  uint32_t OldScanner = scanner; // need to remember it in case of multiple frames per payload
+  for (;;) {
+      if (!SeenPayloadStart && tsPayload.AtTsStart())
+         OldScanner = scanner;
+      scanner = (scanner << 8) | tsPayload.GetByte();
+      if (scanner == 0x00000100) { // Picture Start Code
+         if (!SeenPayloadStart && tsPayload.GetLastIndex() > TS_SIZE) {
+            scanner = OldScanner;
+            return tsPayload.Used() - TS_SIZE;
+            }
+         newFrame = true;
+         tsPayload.GetByte();
+         uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07;
+         independentFrame = FrameType == 1; // I-Frame
+         if (debug) {
+            seenIndependentFrame |= independentFrame;
+            if (seenIndependentFrame) {
+               static const char FrameTypes[] = "?IPBD???";
+               dbgframes("%c", FrameTypes[FrameType]);
+               }
+            }
+         break;
+         }
+      if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
+         || (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
+            && (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
+         break;
+      }
+  return tsPayload.Used();
+}
+
+// --- cMpeg4Parser ----------------------------------------------------------
+
+class cMpeg4Parser : public cFrameParser {
+private:
+  enum eNalUnitType {
+    nutCodedSliceNonIdr     = 1,
+    nutCodedSliceIdr        = 5,
+    nutSequenceParameterSet = 7,
+    nutAccessUnitDelimiter  = 9,
+    };
+  cTsPayload tsPayload;
+  uchar byte; // holds the current byte value in case of bitwise access
+  int bit; // the bit index into the current byte (-1 if we're not in bit reading mode)
+  int zeroBytes; // the number of consecutive zero bytes (to detect 0x000003)
+  uint32_t scanner;
+  // Identifiers written in '_' notation as in "ITU-T H.264":
+  bool separate_colour_plane_flag;
+  int log2_max_frame_num;
+  bool frame_mbs_only_flag;
+  //
+  bool gotAccessUnitDelimiter;
+  bool gotSequenceParameterSet;
+  uchar GetByte(bool Raw = false);
+       ///< Gets the next data byte. If Raw is true, no filtering will be done.
+       ///< With Raw set to false, if the byte sequence 0x000003 is encountered,
+       ///< the byte with 0x03 will be skipped.
+  uchar GetBit(void);
+  uint32_t GetBits(int Bits);
+  uint32_t GetGolombUe(void);
+  int32_t GetGolombSe(void);
+  void ParseAccessUnitDelimiter(void);
+  void ParseSequenceParameterSet(void);
+  void ParseSliceHeader(void);
+public:
+  cMpeg4Parser(void);
+       ///< Sets up a new MPEG-4 parser.
+       ///< This class parses only the data absolutely necessary to determine the
+       ///< frame borders and field count of the given H264 material.
+  virtual int Parse(const uchar *Data, int Length, int Pid);
+  };
+
+cMpeg4Parser::cMpeg4Parser(void)
+{
+  byte = 0;
+  bit = -1;
+  zeroBytes = 0;
+  scanner = EMPTY_SCANNER;
+  separate_colour_plane_flag = false;
+  log2_max_frame_num = 0;
+  frame_mbs_only_flag = false;
+  gotAccessUnitDelimiter = false;
+  gotSequenceParameterSet = false;
+}
+
+uchar cMpeg4Parser::GetByte(bool Raw)
+{
+  uchar b = tsPayload.GetByte();
+  if (!Raw) {
+     // If we encounter the byte sequence 0x000003, we need to skip the 0x03:
+     if (b == 0x00)
+        zeroBytes++;
+     else {
+        if (b == 0x03 && zeroBytes >= 2)
+           b = tsPayload.GetByte();
+        zeroBytes = 0;
+        }
+     }
+  else
+     zeroBytes = 0;
+  bit = -1;
+  return b;
+}
+
+uchar cMpeg4Parser::GetBit(void)
+{
+  if (bit < 0) {
+     byte = GetByte();
+     bit = 7;
+     }
+  return (byte & (1 << bit--)) ? 1 : 0;
+}
+
+uint32_t cMpeg4Parser::GetBits(int Bits)
+{
+  uint32_t b = 0;
+  while (Bits--)
+        b |= GetBit() << Bits;
+  return b;
+}
+
+uint32_t cMpeg4Parser::GetGolombUe(void)
+{
+  int z = -1;
+  for (int b = 0; !b; z++)
+      b = GetBit();
+  return (1 << z) - 1 + GetBits(z);
+}
+
+int32_t cMpeg4Parser::GetGolombSe(void)
+{
+  uint32_t v = GetGolombUe();
+  if (v) {
+     if ((v & 0x01) != 0)
+        return (v + 1) / 2; // fails for v == 0xFFFFFFFF, but that will probably never happen
+     else
+        return -int32_t(v / 2);
+     }
+  return v;
+}
+
+int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid)
+{
+  newFrame = independentFrame = false;
+  tsPayload.Setup(const_cast<uchar *>(Data), Length, Pid);
+  if (TsPayloadStart(Data)) {
+     tsPayload.SkipPesHeader();
+     scanner = EMPTY_SCANNER;
+     if (debug && gotSequenceParameterSet) {
+        dbgframes("/");
+        }
+     }
+  for (;;) {
+      scanner = (scanner << 8) | GetByte(true);
+      if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start
+         uchar NalUnitType = scanner & 0x1F;
+         switch (NalUnitType) {
+           case nutAccessUnitDelimiter:  ParseAccessUnitDelimiter();
+                                         gotAccessUnitDelimiter = true;
+                                         break;
+           case nutSequenceParameterSet: ParseSequenceParameterSet();
+                                         gotSequenceParameterSet = true;
+                                         break;
+           case nutCodedSliceNonIdr:
+           case nutCodedSliceIdr:        if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
+                                            ParseSliceHeader(); 
+                                            gotAccessUnitDelimiter = false;
+                                            return tsPayload.Used();
+                                            }
+                                         break;
+           default: ;
+           }
+         }
+      if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
+         || (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
+            && (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
+         break;
+      }
+  return tsPayload.Used();
+}
+
+void cMpeg4Parser::ParseAccessUnitDelimiter(void)
+{
+  if (debug && gotSequenceParameterSet)
+     dbgframes("A");
+  GetByte(); // primary_pic_type
+}
+
+void cMpeg4Parser::ParseSequenceParameterSet(void)
+{
+  uchar profile_idc = GetByte(); // profile_idc
+  GetByte(); // constraint_set[0-5]_flags, reserved_zero_2bits
+  GetByte(); // level_idc
+  GetGolombUe(); // seq_parameter_set_id
+  if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc ==118 || profile_idc == 128) {
+     int chroma_format_idc = GetGolombUe(); // chroma_format_idc
+     if (chroma_format_idc == 3)
+        separate_colour_plane_flag = GetBit();
+     GetGolombUe(); // bit_depth_luma_minus8
+     GetGolombUe(); // bit_depth_chroma_minus8
+     GetBit(); // qpprime_y_zero_transform_bypass_flag
+     if (GetBit()) { // seq_scaling_matrix_present_flag
+        for (int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); i++) {
+            if (GetBit()) { // seq_scaling_list_present_flag
+               int SizeOfScalingList = (i < 6) ? 16 : 64;
+               int LastScale = 8;
+               int NextScale = 8;
+               for (int j = 0; j < SizeOfScalingList; j++) {
+                   if (NextScale)
+                      NextScale = (LastScale + GetGolombSe() + 256) % 256; // delta_scale
+                   if (NextScale)
+                      LastScale = NextScale;
+                   }
+               }
+            }
+        }
+     }
+  log2_max_frame_num = GetGolombUe() + 4; // log2_max_frame_num_minus4
+  int pic_order_cnt_type = GetGolombUe(); // pic_order_cnt_type
+  if (pic_order_cnt_type == 0)
+     GetGolombUe(); // log2_max_pic_order_cnt_lsb_minus4
+  else if (pic_order_cnt_type == 1) {
+     GetBit(); // delta_pic_order_always_zero_flag
+     GetGolombSe(); // offset_for_non_ref_pic
+     GetGolombSe(); // offset_for_top_to_bottom_field
+     for (int i = GetGolombUe(); i--; ) // num_ref_frames_in_pic_order_cnt_cycle
+         GetGolombSe(); // offset_for_ref_frame
+     }
+  GetGolombUe(); // max_num_ref_frames
+  GetBit(); // gaps_in_frame_num_value_allowed_flag
+  GetGolombUe(); // pic_width_in_mbs_minus1
+  GetGolombUe(); // pic_height_in_map_units_minus1
+  frame_mbs_only_flag = GetBit(); // frame_mbs_only_flag
+  if (debug) {
+     if (gotAccessUnitDelimiter && !gotSequenceParameterSet)
+        dbgframes("A"); // just for completeness
+     dbgframes(frame_mbs_only_flag ? "S" : "s");
+     }
+}
+
+void cMpeg4Parser::ParseSliceHeader(void)
+{
+  newFrame = true;
+  GetGolombUe(); // first_mb_in_slice
+  int slice_type = GetGolombUe(); // slice_type, 0 = P, 1 = B, 2 = I, 3 = SP, 4 = SI
+  independentFrame = (slice_type % 5) == 2;
+  if (debug) {
+     static const char SliceTypes[] = "PBIpi";
+     dbgframes("%c", SliceTypes[slice_type % 5]);
+     }
+  if (frame_mbs_only_flag)
+     return; // don't need the rest - a frame is complete
+  GetGolombUe(); // pic_parameter_set_id
+  if (separate_colour_plane_flag)
+     GetBits(2); // colour_plane_id
+  GetBits(log2_max_frame_num); // frame_num
+  if (!frame_mbs_only_flag) {
+     if (GetBit()) // field_pic_flag
+        newFrame = !GetBit(); // bottom_field_flag
+     if (debug)
+        dbgframes(newFrame ? "t" : "b");
+     }
+}
+
+// --- cFrameDetector --------------------------------------------------------
 
 cFrameDetector::cFrameDetector(int Pid, int Type)
 {
+  parser = NULL;
   SetPid(Pid, Type);
   synced = false;
   newFrame = independentFrame = false;
   numPtsValues = 0;
-  numFrames = 0;
   numIFrames = 0;
   framesPerSecond = 0;
   framesInPayloadUnit = framesPerPayloadUnit = 0;
-  payloadUnitOfFrame = 0;
   scanning = false;
-  scanner = EMPTY_SCANNER;
 }
 
 static int CmpUint32(const void *p1, const void *p2)
@@ -840,42 +1367,26 @@
   pid = Pid;
   type = Type;
   isVideo = type == 0x01 || type == 0x02 || type == 0x1B; // MPEG 1, 2 or 4
-}
-
-void cFrameDetector::Reset(void)
-{
-  newFrame = independentFrame = false;
-  payloadUnitOfFrame = 0;
-  scanning = false;
-  scanner = EMPTY_SCANNER;
-}
-
-int cFrameDetector::SkipPackets(const uchar *&Data, int &Length, int &Processed, int &FrameTypeOffset)
-{
-  if (!synced)
-     dbgframes("%d>", FrameTypeOffset);
-  while (Length >= TS_SIZE) {
-        // switch to the next TS packet, but skip those that have a different PID:
-        Data += TS_SIZE;
-        Length -= TS_SIZE;
-        Processed += TS_SIZE;
-        if (TsPid(Data) == pid)
-           break;
-        else if (Length < TS_SIZE)
-           esyslog("ERROR: out of data while skipping TS packets in cFrameDetector");
-        }
-  FrameTypeOffset -= TS_SIZE;
-  FrameTypeOffset += TsPayloadOffset(Data);
-  return FrameTypeOffset;
+  delete parser;
+  parser = NULL;
+  if (type == 0x01 || type == 0x02)
+     parser = new cMpeg2Parser;
+  else if (type == 0x1B)
+     parser = new cMpeg4Parser;
+  else if (type == 0x04 || type == 0x06) // MPEG audio or AC3 audio
+     parser = new cAudioParser;
+  else if (type != 0)
+     esyslog("ERROR: unknown stream type %d (PID %d) in frame detector", type, pid);
 }
 
 int cFrameDetector::Analyze(const uchar *Data, int Length)
 {
-  bool SeenPayloadStart = false;
-  bool SeenAccessUnitDelimiter = false;
+  if (!parser)
+     return 0;
   int Processed = 0;
   newFrame = independentFrame = false;
-  while (Length >= TS_SIZE) {
+  while (Length >= MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) { // makes sure we are looking at enough data, in case the frame type is not stored in the first TS packet
+        // Sync on TS packet borders:
         if (Data[0] != TS_SYNC_BYTE) {
            int Skipped = 1;
            while (Skipped < Length && (Data[Skipped] != TS_SYNC_BYTE || Length - Skipped > TS_SIZE && Data[Skipped + TS_SIZE] != TS_SYNC_BYTE))
@@ -883,186 +1394,99 @@
            esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
            return Processed + Skipped;
            }
+        // Handle one TS packet:
+        int Handled = TS_SIZE;
         if (TsHasPayload(Data) && !TsIsScrambled(Data)) {
            int Pid = TsPid(Data);
            if (Pid == pid) {
+              if (Processed)
+                 return Processed;
+              if (TsPayloadStart(Data))
+                 scanning = true;
+              if (scanning) {
+                 // Detect the beginning of a new frame:
+                 if (TsPayloadStart(Data)) {
+                    if (!framesPerPayloadUnit)
+                       framesPerPayloadUnit = framesInPayloadUnit;
+                    }
+                 int n = parser->Parse(Data, Length, pid);
+                 if (n > 0) {
+                    if (parser->NewFrame()) {
+                       newFrame = true;
+                       independentFrame = parser->IndependentFrame();
+                       if (synced) {
+                          if (framesPerPayloadUnit <= 1)
+                             scanning = false;
+                          }
+                       else {
+                          framesInPayloadUnit++;
+                          if (independentFrame)
+                             numIFrames++;
+                          }
+                       }
+                    Handled = n;
+                    }
+                 }
               if (TsPayloadStart(Data)) {
-                 SeenPayloadStart = true;
-                 if (synced && Processed)
-                    return Processed;
-                 if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
-                    return Processed; // need more data, in case the frame type is not stored in the first TS packet
+                 // Determine the frame rate from the PTS values in the PES headers:
                  if (framesPerSecond <= 0.0) {
                     // frame rate unknown, so collect a sequence of PTS values:
                     if (numPtsValues < 2 || numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames
-                       const uchar *Pes = Data + TsPayloadOffset(Data);
-                       if (numIFrames && PesHasPts(Pes)) {
-                          ptsValues[numPtsValues] = PesGetPts(Pes);
-                          // check for rollover:
-                          if (numPtsValues && ptsValues[numPtsValues - 1] > 0xF0000000 && ptsValues[numPtsValues] < 0x10000000) {
-                             dbgframes("#");
-                             numPtsValues = 0;
-                             numIFrames = 0;
-                             numFrames = 0;
+                       if (newFrame) { // only take PTS values at the beginning of a frame (in case if fields!)
+                          const uchar *Pes = Data + TsPayloadOffset(Data);
+                          if (numIFrames && PesHasPts(Pes)) {
+                             ptsValues[numPtsValues] = PesGetPts(Pes);
+                             // check for rollover:
+                             if (numPtsValues && ptsValues[numPtsValues - 1] > 0xF0000000 && ptsValues[numPtsValues] < 0x10000000) {
+                                dbgframes("#");
+                                numPtsValues = 0;
+                                numIFrames = 0;
+                                }
+                             else
+                                numPtsValues++;
                              }
-                          else
-                             numPtsValues++;
                           }
                        }
-                    else {
+                    if (numPtsValues >= 2 && numIFrames >= 2) {
                        // find the smallest PTS delta:
                        qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32);
                        numPtsValues--;
                        for (int i = 0; i < numPtsValues; i++)
                            ptsValues[i] = ptsValues[i + 1] - ptsValues[i];
                        qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32);
-                       uint32_t Delta = ptsValues[0];
+                       uint32_t Delta = ptsValues[0] / framesPerPayloadUnit;
                        // determine frame info:
                        if (isVideo) {
                           if (abs(Delta - 3600) <= 1)
                              framesPerSecond = 25.0;
                           else if (Delta % 3003 == 0)
                              framesPerSecond = 30.0 / 1.001;
-                          else if (abs(Delta - 1800) <= 1) {
-                             if (numFrames > 50) {
-                                // this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
-                                framesPerSecond = 25.0;
-                                framesPerPayloadUnit = -2;
-                                }
-                             else
-                                framesPerSecond = 50.0;
-                             }
+                          else if (abs(Delta - 1800) <= 1)
+                             framesPerSecond = 50.0;
                           else if (Delta == 1501)
-                             if (numFrames > 50) {
-                                // this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
-                                framesPerSecond = 30.0 / 1.001;
-                                framesPerPayloadUnit = -2;
-                                }
-                             else
-                                framesPerSecond = 60.0 / 1.001;
+                             framesPerSecond = 60.0 / 1.001;
                           else {
                              framesPerSecond = DEFAULTFRAMESPERSECOND;
                              dsyslog("unknown frame delta (%d), assuming %5.2f fps", Delta, DEFAULTFRAMESPERSECOND);
                              }
                           }
                        else // audio
-                          framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
-                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numFrames);
-                       }
-                    }
-                 scanner = EMPTY_SCANNER;
-                 scanning = true;
-                 }
-              if (scanning) {
-                 int PayloadOffset = TsPayloadOffset(Data);
-                 if (TsPayloadStart(Data)) {
-                    PayloadOffset += PesPayloadOffset(Data + PayloadOffset);
-                    if (!framesPerPayloadUnit)
-                       framesPerPayloadUnit = framesInPayloadUnit;
-                    if (DebugFrames && !synced)
-                       dbgframes("/");
-                    }
-                 for (int i = PayloadOffset; scanning && i < TS_SIZE; i++) {
-                     scanner <<= 8;
-                     scanner |= Data[i];
-                     switch (type) {
-                       case 0x01: // MPEG 1 video
-                       case 0x02: // MPEG 2 video
-                            if (scanner == 0x00000100) { // Picture Start Code
-                               scanner = EMPTY_SCANNER;
-                               if (synced && !SeenPayloadStart && Processed)
-                                  return Processed; // flush everything before this new frame
-                               int FrameTypeOffset = i + 2;
-                               if (FrameTypeOffset >= TS_SIZE) // the byte to check is in the next TS packet
-                                  i = SkipPackets(Data, Length, Processed, FrameTypeOffset);
-                               newFrame = true;
-                               uchar FrameType = (Data[FrameTypeOffset] >> 3) & 0x07;
-                               independentFrame = FrameType == 1; // I-Frame
-                               if (synced) {
-                                  if (framesPerPayloadUnit <= 1)
-                                     scanning = false;
-                                  }
-                               else {
-                                  framesInPayloadUnit++;
-                                  if (independentFrame)
-                                     numIFrames++;
-                                  if (numIFrames == 1)
-                                     numFrames++;
-                                  dbgframes("%u ", FrameType);
-                                  }
-                               if (synced)
-                                  return Processed + TS_SIZE; // flag this new frame
-                               }
-                            break;
-                       case 0x1B: // MPEG 4 video
-                            if (scanner == 0x00000109) { // Access Unit Delimiter
-                               scanner = EMPTY_SCANNER;
-                               if (synced && !SeenPayloadStart && Processed)
-                                  return Processed; // flush everything before this new frame
-                               SeenAccessUnitDelimiter = true;
-                               }
-                            else if (SeenAccessUnitDelimiter && scanner == 0x00000001) { // NALU start
-                               SeenAccessUnitDelimiter = false;
-                               int FrameTypeOffset = i + 1;
-                               if (FrameTypeOffset >= TS_SIZE) // the byte to check is in the next TS packet
-                                  i = SkipPackets(Data, Length, Processed, FrameTypeOffset);
-                               newFrame = true;
-                               uchar FrameType = Data[FrameTypeOffset] & 0x1F;
-                               independentFrame = FrameType == 0x07;
-                               if (synced) {
-                                  if (framesPerPayloadUnit < 0) {
-                                     payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;
-                                     if (payloadUnitOfFrame != 0 && independentFrame)
-                                        payloadUnitOfFrame = 0;
-                                     if (payloadUnitOfFrame)
-                                        newFrame = false;
-                                     }
-                                  if (framesPerPayloadUnit <= 1)
-                                     scanning = false;
-                                  }
-                               else {
-                                  framesInPayloadUnit++;
-                                  if (independentFrame)
-                                     numIFrames++;
-                                  if (numIFrames == 1)
-                                     numFrames++;
-                                  dbgframes("%02X ", FrameType);
-                                  }
-                               if (synced)
-                                  return Processed + TS_SIZE; // flag this new frame
-                               }
-                            break;
-                       case 0x04: // MPEG audio
-                       case 0x06: // AC3 audio
-                            if (synced && Processed)
-                               return Processed;
-                            newFrame = true;
-                            independentFrame = true;
-                            if (!synced) {
-                               framesInPayloadUnit = 1;
-                               if (TsPayloadStart(Data))
-                                  numIFrames++;
-                               }
-                            scanning = false;
-                            break;
-                       default: esyslog("ERROR: unknown stream type %d (PID %d) in frame detector", type, pid);
-                                pid = 0; // let's just ignore any further data
+                          framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing
+                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1);
+                       synced = true;
+                       parser->SetDebug(false);
                        }
-                     }
-                 if (!synced && framesPerSecond > 0.0 && independentFrame) {
-                    synced = true;
-                    dbgframes("*\n");
-                    Reset();
-                    return Processed + TS_SIZE;
                     }
                  }
               }
            else if (Pid == PATPID && synced && Processed)
               return Processed; // allow the caller to see any PAT packets
            }
-        Data += TS_SIZE;
-        Length -= TS_SIZE;
-        Processed += TS_SIZE;
+        Data += Handled;
+        Length -= Handled;
+        Processed += Handled;
+        if (newFrame)
+           break;
         }
   return Processed;
 }
diff -ruN vdr-1.7.31/remux.h vdr-1.7.32/remux.h
--- vdr-1.7.31/remux.h	2011-09-04 14:48:26.000000000 +0200
+++ vdr-1.7.32/remux.h	2012-11-18 13:17:23.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.h 2.32 2011/09/04 12:48:26 kls Exp $
+ * $Id: remux.h 2.35 2012/11/18 12:17:23 kls Exp $
  */
 
 #ifndef __REMUX_H
@@ -52,6 +52,11 @@
 #define PATPID 0x0000 // PAT PID (constant 0)
 #define MAXPID 0x2000 // for arrays that use a PID as the index
 
+#define PTSTICKS  90000 // number of PTS ticks per second
+#define PCRFACTOR 300 // conversion from 27MHz PCR extension to 90kHz PCR base
+#define MAX33BIT  0x00000001FFFFFFFFLL // max. possible value with 33 bit
+#define MAX27MHZ  ((MAX33BIT + 1) * PCRFACTOR - 1) // max. possible PCR value
+
 inline bool TsHasPayload(const uchar *p)
 {
   return p[3] & TS_PAYLOAD_EXISTS;
@@ -82,6 +87,16 @@
   return p[3] & TS_SCRAMBLING_CONTROL;
 }
 
+inline uchar TsGetContinuityCounter(const uchar *p)
+{
+  return p[3] & TS_CONT_CNT_MASK;
+}
+
+inline void TsSetContinuityCounter(uchar *p, uchar Counter)
+{
+  p[3] = (p[3] & ~TS_CONT_CNT_MASK) | (Counter & TS_CONT_CNT_MASK);
+}
+
 inline int TsPayloadOffset(const uchar *p)
 {
   int o = TsHasAdaptationField(p) ? p[4] + 5 : 4;
@@ -103,15 +118,31 @@
   return p[3] & TS_CONT_CNT_MASK;
 }
 
-inline int TsGetAdaptationField(const uchar *p)
+inline int64_t TsGetPcr(const uchar *p)
 {
-  return TsHasAdaptationField(p) ? p[5] : 0x00;
+  if (TsHasAdaptationField(p)) {
+     if (p[4] >= 7 && (p[5] & TS_ADAPT_PCR)) {
+        return ((((int64_t)p[ 6]) << 25) |
+                (((int64_t)p[ 7]) << 17) |
+                (((int64_t)p[ 8]) <<  9) |
+                (((int64_t)p[ 9]) <<  1) |
+                (((int64_t)p[10]) >>  7)) * PCRFACTOR +
+               (((((int)p[10]) & 0x01) << 8) |
+                ( ((int)p[11])));
+        }
+     }
+  return -1;
 }
 
+void TsHidePayload(uchar *p);
+void TsSetPcr(uchar *p, int64_t Pcr);
+
 // The following functions all take a pointer to a sequence of complete TS packets.
 
 int64_t TsGetPts(const uchar *p, int l);
-void TsSetTeiOnBrokenPackets(uchar *p, int l);
+int64_t TsGetDts(const uchar *p, int l);
+void TsSetPts(uchar *p, int l, int64_t Pts);
+void TsSetDts(uchar *p, int l, int64_t Dts);
 
 // Some PES handling tools:
 // The following functions that take a pointer to PES data all assume that
@@ -142,6 +173,11 @@
   return (p[7] & 0x80) && p[8] >= 5;
 }
 
+inline bool PesHasDts(const uchar *p)
+{
+  return (p[7] & 0x40) && p[8] >= 10;
+}
+
 inline int64_t PesGetPts(const uchar *p)
 {
   return ((((int64_t)p[ 9]) & 0x0E) << 29) |
@@ -151,6 +187,88 @@
          ((((int64_t)p[13]) & 0xFE) >>  1);
 }
 
+inline int64_t PesGetDts(const uchar *p)
+{
+  return ((((int64_t)p[14]) & 0x0E) << 29) |
+         (( (int64_t)p[15])         << 22) |
+         ((((int64_t)p[16]) & 0xFE) << 14) |
+         (( (int64_t)p[17])         <<  7) |
+         ((((int64_t)p[18]) & 0xFE) >>  1);
+}
+
+void PesSetPts(uchar *p, int64_t Pts);
+void PesSetDts(uchar *p, int64_t Dts);
+
+// PTS handling:
+
+inline int64_t PtsAdd(int64_t Pts1, int64_t Pts2) { return (Pts1 + Pts2) & MAX33BIT; }
+       ///< Adds the given PTS values, taking into account the 33bit wrap around.
+int64_t PtsDiff(int64_t Pts1, int64_t Pts2);
+       ///< Returns the difference between two PTS values. The result of Pts2 - Pts1
+       ///< is the actual number of 90kHz time ticks that pass from Pts1 to Pts2,
+       ///< properly taking into account the 33bit wrap around. If Pts2 is "before"
+       ///< Pts1, the result is negative.
+
+// A transprent TS payload handler:
+
+class cTsPayload {
+private:
+  uchar *data;
+  int length;
+  int pid;
+  int index; // points to the next byte to process
+public:
+  cTsPayload(void);
+  cTsPayload(uchar *Data, int Length, int Pid = -1);
+       ///< Creates a new TS payload handler and calls Setup() with the given Data.
+  void Setup(uchar *Data, int Length, int Pid = -1);
+       ///< Sets up this TS payload handler with the given Data, which points to a
+       ///< sequence of Length bytes of complete TS packets. Any incomplete TS
+       ///< packet at the end will be ignored.
+       ///< If Pid is given, only TS packets with data for that PID will be processed.
+       ///< Otherwise the PID of the first TS packet defines which payload will be
+       ///< delivered.
+       ///< Any intermediate TS packets with different PIDs will be skipped.
+  bool AtTsStart(void) { return index < length && (index % TS_SIZE) == 0; }
+       ///< Returns true if this payload handler is currently pointing to first byte
+       ///< of a TS packet.
+  bool AtPayloadStart(void) { return AtTsStart() && TsPayloadStart(data + index); }
+       ///< Returns true if this payload handler is currently pointing to the first byte
+       ///< of a TS packet that starts a new payload.
+  int Available(void) { return length - index; }
+       ///< Returns the number of raw bytes (including any TS headers) still available
+       ///< in the TS payload handler.
+  int Used(void) { return (index + TS_SIZE - 1) / TS_SIZE * TS_SIZE; }
+       ///< Returns the number of raw bytes that have already been used (e.g. by calling
+       ///< GetByte()). Any TS packet of which at least a single byte has been delivered
+       ///< is counted with its full size.
+  bool Eof(void) const { return index >= length; }
+       ///< Returns true if all available bytes of the TS payload have been processed.
+  uchar GetByte(void);
+       ///< Gets the next byte of the TS payload, skipping any intermediate TS header data.
+  bool SkipBytes(int Bytes);
+       ///< Skips the given number of bytes in the payload and returns true if there
+       ///< is still data left to read.
+  bool SkipPesHeader(void);
+       ///< Skips all bytes belonging to the PES header of the payload.
+  int GetLastIndex(void);
+       ///< Returns the index into the TS data of the payload byte that has most recently
+       ///< been read. If no byte has been read yet, -1 will be returned.
+  void SetByte(uchar Byte, int Index);
+       ///< Sets the TS data byte at the given Index to the value Byte.
+       ///< Index should be one that has been retrieved by a previous call to GetIndex(),
+       ///< otherwise the behaviour is undefined. The current read index will not be
+       ///< altered by a call to this function.
+  bool Find(uint32_t Code);
+       ///< Searches for the four byte sequence given in Code and returns true if it
+       ///< was found within the payload data. The next call to GetByte() will return the
+       ///< value immediately following the Code. If the code was not found, the read
+       ///< index will remain the same as before this call, so that several calls to
+       ///< Find() can be performed starting at the same index..
+       ///< The special code 0xFFFFFFFF can not be searched, because this value is used
+       ///< to initialize the scanner.
+  };
+
 // PAT/PMT Generator:
 
 #define MAX_SECTION_SIZE 4096 // maximum size of an SI section
@@ -248,6 +366,10 @@
        ///< are delivered to the parser through several subsequent calls to
        ///< ParsePmt(). The whole PMT data will be processed once the last packet
        ///< has been received.
+  bool ParsePatPmt(const uchar *Data, int Length);
+       ///< Parses the given Data (which may consist of several TS packets, typically
+       ///< an entire frame) and extracts the PAT and PMT.
+       ///< Returns true if a valid PAT/PMT has been detected.
   bool GetVersions(int &PatVersion, int &PmtVersion) const;
        ///< Returns true if a valid PAT/PMT has been parsed and stores
        ///< the current version numbers in the given variables.
@@ -338,6 +460,8 @@
 
 #define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 5
 
+class cFrameParser;
+
 class cFrameDetector {
 private:
   enum { MaxPtsValues = 150 };
@@ -354,12 +478,9 @@
   double framesPerSecond;
   int framesInPayloadUnit;
   int framesPerPayloadUnit; // Some broadcasters send one frame per payload unit (== 1),
-                            // some put an entire GOP into one payload unit (> 1), and
-                            // some spread a single frame over several payload units (< 0).
-  int payloadUnitOfFrame;
+                            // while others put an entire GOP into one payload unit (> 1).
   bool scanning;
-  uint32_t scanner;
-  int SkipPackets(const uchar *&Data, int &Length, int &Processed, int &FrameTypeOffset);
+  cFrameParser *parser;
 public:
   cFrameDetector(int Pid = 0, int Type = 0);
       ///< Sets up a frame detector for the given Pid and stream Type.
@@ -367,9 +488,6 @@
       ///< call to SetPid().
   void SetPid(int Pid, int Type);
       ///< Sets the Pid and stream Type to detect frames for.
-  void Reset(void);
-      ///< Resets any counters and flags used while syncing and prepares
-      ///< the frame detector for actual work.
   int Analyze(const uchar *Data, int Length);
       ///< Analyzes the TS packets pointed to by Data. Length is the number of
       ///< bytes Data points to, and must be a multiple of TS_SIZE.
diff -ruN vdr-1.7.31/sections.c vdr-1.7.32/sections.c
--- vdr-1.7.31/sections.c	2012-08-26 14:53:39.000000000 +0200
+++ vdr-1.7.32/sections.c	2012-10-04 14:21:59.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sections.c 2.1 2012/08/26 12:53:39 kls Exp $
+ * $Id: sections.c 2.2 2012/10/04 12:21:59 kls Exp $
  */
 
 #include "sections.h"
@@ -40,7 +40,7 @@
 // --- cSectionHandler -------------------------------------------------------
 
 cSectionHandler::cSectionHandler(cDevice *Device)
-:cThread("section handler")
+:cThread("section handler", true)
 {
   shp = new cSectionHandlerPrivate;
   device = Device;
@@ -164,7 +164,6 @@
 
 void cSectionHandler::Action(void)
 {
-  SetPriority(19);
   while (Running()) {
 
         Lock();
diff -ruN vdr-1.7.31/skinlcars.h vdr-1.7.32/skinlcars.h
--- vdr-1.7.31/skinlcars.h	2012-04-15 15:17:35.000000000 +0200
+++ vdr-1.7.32/skinlcars.h	2012-04-15 15:17:35.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinlcars.h 2.1 2012/04/15 13:17:35 kls Exp $
+ * $Id: skinlcars.h 1.1 2012/04/15 13:17:35 kls Exp $
  */
 
 #ifndef __SKINLCARS_H
diff -ruN vdr-1.7.31/themes.h vdr-1.7.32/themes.h
--- vdr-1.7.31/themes.h	2007-08-05 16:10:22.000000000 +0200
+++ vdr-1.7.32/themes.h	2012-10-07 13:11:43.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: themes.h 2.0 2007/08/05 14:10:22 kls Exp $
+ * $Id: themes.h 2.1 2012/10/07 11:11:43 kls Exp $
  */
 
 #ifndef __THEMES_H
@@ -56,7 +56,7 @@
   };
 
 // A helper macro that simplifies defining theme colors.
-#define THEME_CLR(Theme, Subject, Color) static const int Subject = Theme.AddColor(#Subject, Color)
+#define THEME_CLR(Theme, Subject, Color) static const tColor Subject = Theme.AddColor(#Subject, Color)
 
 class cThemes {
 private:
diff -ruN vdr-1.7.31/thread.c vdr-1.7.32/thread.c
--- vdr-1.7.31/thread.c	2012-09-20 11:05:50.000000000 +0200
+++ vdr-1.7.32/thread.c	2012-10-04 14:20:43.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 2.5 2012/09/20 09:05:50 kls Exp $
+ * $Id: thread.c 2.6 2012/10/04 12:20:43 kls Exp $
  */
 
 #include "thread.h"
@@ -204,7 +204,7 @@
 
 tThreadId cThread::mainThreadId = 0;
 
-cThread::cThread(const char *Description)
+cThread::cThread(const char *Description, bool LowPriority)
 {
   active = running = false;
   childTid = 0;
@@ -212,6 +212,7 @@
   description = NULL;
   if (Description)
      SetDescription("%s", Description);
+  lowPriority = LowPriority;
 }
 
 cThread::~cThread()
@@ -248,12 +249,16 @@
 {
   Thread->childThreadId = ThreadId();
   if (Thread->description) {
-     dsyslog("%s thread started (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+     dsyslog("%s thread started (pid=%d, tid=%d, prio=%s)", Thread->description, getpid(), Thread->childThreadId, Thread->lowPriority ? "low" : "high");
 #ifdef PR_SET_NAME
      if (prctl(PR_SET_NAME, Thread->description, 0, 0, 0) < 0)
         esyslog("%s thread naming failed (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
 #endif
      }
+  if (Thread->lowPriority) {
+     Thread->SetPriority(19);
+     Thread->SetIOPriority(7);
+     }
   Thread->Action();
   if (Thread->description)
      dsyslog("%s thread ended (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
diff -ruN vdr-1.7.31/thread.h vdr-1.7.32/thread.h
--- vdr-1.7.31/thread.h	2012-09-20 10:46:27.000000000 +0200
+++ vdr-1.7.32/thread.h	2012-10-04 14:15:39.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 2.2 2012/09/20 08:46:27 kls Exp $
+ * $Id: thread.h 2.3 2012/10/04 12:15:39 kls Exp $
  */
 
 #ifndef __THREAD_H
@@ -83,6 +83,7 @@
   tThreadId childThreadId;
   cMutex mutex;
   char *description;
+  bool lowPriority;
   static tThreadId mainThreadId;
   static void *StartThread(cThread *Thread);
 protected:
@@ -106,11 +107,13 @@
        ///< If WaitSeconds is -1, only 'running' is set to false and Cancel()
        ///< returns immediately, without killing the thread.
 public:
-  cThread(const char *Description = NULL);
+  cThread(const char *Description = NULL, bool LowPriority = false);
        ///< Creates a new thread.
        ///< If Description is present, a log file entry will be made when
        ///< the thread starts and stops. The Start() function must be called
        ///< to actually start the thread.
+       ///< LowPriority can be set to true to make this thread run at a lower
+       ///< priority.
   virtual ~cThread();
   void SetDescription(const char *Description, ...) __attribute__ ((format (printf, 2, 3)));
   bool Start(void);
diff -ruN vdr-1.7.31/timers.c vdr-1.7.32/timers.c
--- vdr-1.7.31/timers.c	2012-09-15 15:34:03.000000000 +0200
+++ vdr-1.7.32/timers.c	2012-10-16 10:22:39.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 2.12 2012/09/15 13:34:03 kls Exp $
+ * $Id: timers.c 2.14 2012/10/16 08:22:39 kls Exp $
  */
 
 #include "timers.h"
@@ -465,10 +465,11 @@
            startTime = event->StartTime();
            stopTime = event->EndTime();
            if (!Margin) { // this is an actual check
-              if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) // VPS control can only work with up-to-date events...
-                 return event->IsRunning(true);
-              else
-                 return startTime <= t && t < stopTime; // ...otherwise we fall back to normal timer handling
+              if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) { // VPS control can only work with up-to-date events...
+                 if (event->StartTime() > 0) // checks for "phased out" events
+                    return event->IsRunning(true);
+                 }
+              return startTime <= t && t < stopTime; // ...otherwise we fall back to normal timer handling
               }
            }
         }
@@ -549,8 +550,12 @@
         lastSetEvent = now;
         const cEvent *Event = NULL;
         if (HasFlags(tfVps) && Schedule->Events()->First()->Vps()) {
-           if (event && Recording())
-              return; // let the recording end first
+           if (event && event->StartTime() > 0) { // checks for "phased out" events
+              if (Recording())
+                 return; // let the recording end first
+              if (now <= event->EndTime() || Matches(0, true))
+                 return; // stay with the old event until the timer has completely expired
+              }
            // VPS timers only match if their start time exactly matches the event's VPS time:
            for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) {
                if (e->StartTime() && e->RunningStatus() != SI::RunningStatusNotRunning) { // skip outdated events
@@ -562,8 +567,6 @@
                      }
                   }
                }
-           if (!Event && event && (now <= event->EndTime() || Matches(0, true)))
-              return; // stay with the old event until the timer has completely expired
            }
         else {
            // Normal timers match the event they have the most overlap with:
diff -ruN vdr-1.7.31/vdr.5 vdr-1.7.32/vdr.5
--- vdr-1.7.31/vdr.5	2012-03-10 15:56:01.000000000 +0100
+++ vdr-1.7.32/vdr.5	2012-10-15 12:50:23.000000000 +0200
@@ -8,7 +8,7 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.5 2.29 2012/03/10 14:56:01 kls Exp $
+.\" $Id: vdr.5 2.30 2012/10/15 10:50:23 kls Exp $
 .\"
 .TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
 .SH NAME
@@ -815,13 +815,13 @@
 The lines in this file need not necessarily appear in the correct temporal
 sequence, they will be automatically sorted by time index.
 
+If a frame position doesn't point to an I-frame of the corresponding recording,
+it will be shifted towards the next I-frame (either up or down, whichever is
+closer).
+
 \fBCURRENT RESTRICTIONS:\fR
 
 -\ the comment is currently not used by VDR
-.br
--\ marks must have a frame number, and that frame MUST be an I-frame (this
-means that only marks generated by VDR itself can be used, since they
-will always be guaranteed to mark I-frames).
 .SS EPG DATA
 The file \fIepg.data\fR contains the EPG data in an easily parsable format.
 The first character of each line defines what kind of data this line contains.
diff -ruN vdr-1.7.31/vdr.c vdr-1.7.32/vdr.c
--- vdr-1.7.31/vdr.c	2012-09-24 14:43:04.000000000 +0200
+++ vdr-1.7.32/vdr.c	2012-10-13 14:48:56.000000000 +0200
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.tvdr.de
  *
- * $Id: vdr.c 2.40 2012/09/24 12:43:04 kls Exp $
+ * $Id: vdr.c 2.42 2012/10/13 12:48:56 kls Exp $
  */
 
 #include <getopt.h>
@@ -892,7 +892,7 @@
                            Timer->SetInVpsMargin(InVpsMargin);
                            }
                         else if (Timer->Event()) {
-                           InVpsMargin = Timer->Event()->StartTime() <= Now && Timer->Event()->RunningStatus() == SI::RunningStatusUndefined;
+                           InVpsMargin = Timer->Event()->StartTime() <= Now && Now < Timer->Event()->EndTime();
                            NeedsTransponder = Timer->Event()->StartTime() - Now < VPSLOOKAHEADTIME * 3600 && !Timer->Event()->SeenWithin(VPSUPTODATETIME);
                            }
                         else {
@@ -1238,6 +1238,8 @@
                      cControl::Shutdown();
                      cControl::Launch(new cReplayControl);
                      }
+                  else
+                     DirectMainFunction(osRecordings); // no last viewed recording, so enter the Recordings menu
                   break;
              default:    break;
              }
