diff -ruN vdr-1.4.6/CONTRIBUTORS vdr-1.4.7/CONTRIBUTORS
--- vdr-1.4.6/CONTRIBUTORS	2007-02-24 12:13:59.000000000 +0100
+++ vdr-1.4.7/CONTRIBUTORS	2007-04-30 11:50:02.000000000 +0200
@@ -1118,6 +1118,7 @@
  for making cCommand::Execute() use cPipe instead of popen() to avoid problems
  with open file handles when starting background commands
  for fixing handling error status in cDvbTuner::GetFrontendStatus()
+ for fixing a busy loop in fast forward if the next video data file is missing
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1392,6 +1393,7 @@
  for reporting a problem with displaying the replay mode symbol in case of "Multi
  speed mode"
  for removing 'assert(0)' from cDvbSpuDecoder::setTime()
+ for fixing handling ChannelUp/Down keys if there is currently a replay running
 
 Jürgen Schmitz <j.schmitz@web.de>
  for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -2006,6 +2008,7 @@
  for suggesting that cDevice::GetDevice() should prefer any device that's already
  receiving and doesn't require detatching receivers
  for improving handling Transfer Mode devices when selecting a device to receive
+ for fixing handling frequencies in NitFilter::Process()
 
 Antti Hartikainen <ami+vdr@ah.fi>
  for updating 'S13E' in 'sources.conf'
diff -ruN vdr-1.4.6/HISTORY vdr-1.4.7/HISTORY
--- vdr-1.4.6/HISTORY	2007-03-03 16:57:20.000000000 +0100
+++ vdr-1.4.7/HISTORY	2007-05-12 11:03:44.000000000 +0200
@@ -5047,3 +5047,17 @@
 2007-03-03: Version 1.4.6
 
 - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
+
+2007-04-30: Version 1.4.6-1
+
+- Fixed a busy loop in fast forward if the next video data file is missing
+  (thanks to Reinhard Nissl).
+- Fixed handling frequencies in NitFilter::Process() (thanks to Anssi Hannula).
+- Fixed handling ChannelUp/Down keys if there is currently a replay running
+  (thanks to Marco Schlüßler).
+- Increased the maximum number of CA system ids to cope with the AlphaCrypt
+  CAM's version 3.11 firmware.
+
+2007-05-12: Version 1.4.7
+
+- Official release.
diff -ruN vdr-1.4.6/ci.c vdr-1.4.7/ci.c
--- vdr-1.4.6/ci.c	2007-01-05 11:08:46.000000000 +0100
+++ vdr-1.4.7/ci.c	2007-04-30 14:58:41.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 1.46 2007/01/05 10:08:46 kls Exp $
+ * $Id: ci.c 1.46.1.1 2007/04/30 12:58:41 kls Exp $
  */
 
 #include "ci.h"
@@ -943,7 +943,7 @@
 
 // --- cCiConditionalAccessSupport -------------------------------------------
 
-#define MAXCASYSTEMIDS 16
+#define MAXCASYSTEMIDS 64
 
 // CA Enable Ids:
 
diff -ruN vdr-1.4.6/config.h vdr-1.4.7/config.h
--- vdr-1.4.6/config.h	2007-02-25 13:09:29.000000000 +0100
+++ vdr-1.4.7/config.h	2007-05-12 11:07:16.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 1.282.1.3 2007/02/25 12:09:29 kls Exp $
+ * $Id: config.h 1.282.1.5 2007/05/12 09:07:16 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -21,8 +21,8 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "1.4.6"
-#define VDRVERSNUM   10406  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.4.7"
+#define VDRVERSNUM   10407  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
diff -ruN vdr-1.4.6/dvbplayer.c vdr-1.4.7/dvbplayer.c
--- vdr-1.4.6/dvbplayer.c	2006-04-17 14:45:48.000000000 +0200
+++ vdr-1.4.7/dvbplayer.c	2007-04-28 16:55:22.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.c 1.45 2006/04/17 12:45:48 kls Exp $
+ * $Id: dvbplayer.c 1.46 2007/04/28 14:55:22 kls Exp $
  */
 
 #include "dvbplayer.h"
@@ -402,8 +402,10 @@
                        bool TimeShiftMode = index->IsStillRecording();
                        int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode);
                        if (Index >= 0) {
-                          if (!NextFile(FileNumber, FileOffset))
+                          if (!NextFile(FileNumber, FileOffset)) {
+                             readIndex = Index;
                              continue;
+                             }
                           }
                        else {
                           if (!TimeShiftMode && playDir == pdForward) {
diff -ruN vdr-1.4.6/nit.c vdr-1.4.7/nit.c
--- vdr-1.4.6/nit.c	2006-10-28 14:31:04.000000000 +0200
+++ vdr-1.4.7/nit.c	2007-04-29 13:35:33.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: nit.c 1.13 2006/10/28 12:31:04 kls Exp $
+ * $Id: nit.c 1.14 2007/04/29 11:35:33 kls Exp $
  */
 
 #include "nit.h"
@@ -144,17 +144,16 @@
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
                         if (Setup.UpdateChannels >= 5) {
-                           if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) { // only modify channels if we're actually receiving this transponder
-                              if (!ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Channel->Transponder())) {
-                                 for (int n = 0; n < NumFrequencies; n++) {
-                                     if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), Channel->Transponder())) {
-                                        Frequency = Frequencies[n];
-                                        break;
-                                        }
+                           if (!ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
                                      }
-                                 }
-                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
+                                  }
                               }
+                           if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder
+                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
                            }
                         found = true;
                         }
@@ -195,17 +194,16 @@
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
                         if (Setup.UpdateChannels >= 5) {
-                           if (ISTRANSPONDER(Frequency / 1000, Transponder())) { // only modify channels if we're actually receiving this transponder
-                              if (!ISTRANSPONDER(Frequency / 1000, Channel->Transponder())) {
-                                 for (int n = 0; n < NumFrequencies; n++) {
-                                     if (ISTRANSPONDER(Frequencies[n] / 1000, Channel->Transponder())) {
-                                        Frequency = Frequencies[n];
-                                        break;
-                                        }
+                           if (!ISTRANSPONDER(Frequency / 1000, Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(Frequencies[n] / 1000, Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
                                      }
-                                 }
-                              Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate);
+                                  }
                               }
+                           if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder
+                              Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate);
                            }
                         found = true;
                         }
@@ -253,17 +251,16 @@
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
                         if (Setup.UpdateChannels >= 5) {
-                           if (ISTRANSPONDER(Frequency / 1000000, Transponder())) { // only modify channels if we're actually receiving this transponder
-                              if (!ISTRANSPONDER(Frequency / 1000000, Channel->Transponder())) {
-                                 for (int n = 0; n < NumFrequencies; n++) {
-                                     if (ISTRANSPONDER(Frequencies[n] / 1000000, Channel->Transponder())) {
-                                        Frequency = Frequencies[n];
-                                        break;
-                                        }
+                           if (!ISTRANSPONDER(Frequency / 1000000, Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(Frequencies[n] / 1000000, Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
                                      }
-                                 }
-                              Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode);
+                                  }
                               }
+                           if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder
+                              Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode);
                            }
                         found = true;
                         }
diff -ruN vdr-1.4.6/vdr.c vdr-1.4.7/vdr.c
--- vdr-1.4.6/vdr.c	2006-12-02 17:22:12.000000000 +0100
+++ vdr-1.4.7/vdr.c	2007-04-30 11:48:23.000000000 +0200
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.cadsoft.de/vdr
  *
- * $Id: vdr.c 1.282 2006/12/02 16:22:12 kls Exp $
+ * $Id: vdr.c 1.282.1.1 2007/04/30 09:48:23 kls Exp $
  */
 
 #include <getopt.h>
@@ -947,7 +947,7 @@
           case kChanDn:
                if (!Interact)
                   Menu = new cDisplayChannel(NORMALKEY(key));
-               else if (cDisplayChannel::IsOpen()) {
+               else if (cDisplayChannel::IsOpen() || cControl::Control()) {
                   Interact->ProcessKey(key);
                   continue;
                   }
