From 05402c740765e6e0ca2aaf1760c77d9e3d3ed5a5 Mon Sep 17 00:00:00 2001
From: Klaus Schmidinger <kls (at) cadsoft (dot) de>
Date: Sun, 27 Feb 2005 18:00:00 +0100
Subject: [PATCH] =?UTF-8?q?Version=201.3.22=20-=20Removed=20some=20unneede?=
 =?UTF-8?q?d=20code=20and=20fixed=20access=20to=20unallocated=20memory=20i?=
 =?UTF-8?q?n=20=20=20cEvent::FixEpgBugs()=20(thanks=20to=20Wolfgang=20Rohd?=
 =?UTF-8?q?ewald).=20-=20Avoiding=20unnecessary=20calls=20to=20SetPid()=20?=
 =?UTF-8?q?in=20cDvbDevice::SetAudioTrackDevice()=20=20=20(thanks=20to=20M?=
 =?UTF-8?q?arco=20Schl=C3=BC=C3=9Fler).=20-=20No=20longer=20calling=20Ensu?=
 =?UTF-8?q?reAudioTrack()=20in=20cDevice::SetChannel()=20if=20a=20Transfer?=
 =?UTF-8?q?=20Mode=20is=20=20=20started,=20to=20avoid=20setting=20the=20au?=
 =?UTF-8?q?dio=20PID=20on=20the=20primary=20device=20(thanks=20to=20Marco?=
 =?UTF-8?q?=20=20=20Schl=C3=BC=C3=9Fler=20for=20pointing=20this=20out).=20?=
 =?UTF-8?q?-=20Replaced=20the=20call=20to=20system("sync")=20in=20SpinUpDi?=
 =?UTF-8?q?sk()=20with=20fdatasync(f)=20to=20avoid=20=20=20problems=20on?=
 =?UTF-8?q?=20NPTL=20systems=20(thanks=20to=20Chris=20Warren=20for=20point?=
 =?UTF-8?q?ing=20this=20out).=20-=20Increased=20POLLTIMEOUTS=5FBEFORE=5FDE?=
 =?UTF-8?q?VICECLEAR=20in=20transfer.c=20to=206=20to=20avoid=20problems=20?=
 =?UTF-8?q?=20=20with=20the=20larger=20buffer=20reserve=20(thanks=20to=20M?=
 =?UTF-8?q?arco=20Schl=C3=BC=C3=9Fler).=20-=20Fixed=20the=20call=20to=20Se?=
 =?UTF-8?q?tVideoFormat()=20in=20cDvbDevice::cDvbDevice()=20(parameter=20i?=
 =?UTF-8?q?s=20=5Fbool=5F).=20-=20Added=20support=20for=20setting=20the=20?=
 =?UTF-8?q?video=20display=20mode=20(thanks=20to=20Marco=20Schl=C3=BC?=
 =?UTF-8?q?=C3=9Fler).=20-=20The=20new=20setup=20option=20"DVB/Video=20dis?=
 =?UTF-8?q?play=20format"=20can=20be=20used=20to=20define=20which=20displa?=
 =?UTF-8?q?y=20=20=20format=20to=20use=20for=20playing=20wide=20screen=20v?=
 =?UTF-8?q?ideo=20on=20a=204:3=20tv=20set.=20-=20Changed=20MAXDPIDS=20to?=
 =?UTF-8?q?=2016=20(8xAC3=20+=208xDTS)=20(thanks=20to=20Werner=20Fink=20fo?=
 =?UTF-8?q?r=20pointing=20this=20out).=20-=20Completed=20Dutch=20language?=
 =?UTF-8?q?=20texts=20(thanks=20to=20Hans=20Dingemans).=20-=20Added=20'smi?=
 =?UTF-8?q?'=20to=20the=20Finnish=20language=20codes=20(thanks=20to=20Rolf?=
 =?UTF-8?q?=20Ahrenberg).=20-=20Fixed=20ensuring=20there=20is=20a=20curren?=
 =?UTF-8?q?t=20audio=20track=20in=20case=20there=20is=20only=20one=20track?=
 =?UTF-8?q?=20=20=20(thanks=20to=20Werner=20Fink=20for=20reporting=20this?=
 =?UTF-8?q?=20one).=20-=20Improved=20automatic=20audio=20track=20selection?=
 =?UTF-8?q?.=20-=20Keeping=20the=20track=20language=20codes=20and=20descri?=
 =?UTF-8?q?ptions=20in=20Transfer=20Mode=20(thanks=20to=20=20=20Luca=20Oli?=
 =?UTF-8?q?vetti).=20-=20Fixed=20handling=20repeated=20kAudio=20keys.=20-?=
 =?UTF-8?q?=20Improved=20displaying=20the=20the=20current=20audio=20track?=
 =?UTF-8?q?=20in=20the=20ST:TNG=20channel=20display.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CONTRIBUTORS  |  21 ++++++++
 HISTORY       |  28 ++++++++++
 INSTALL       |   4 +-
 MANUAL        |   4 ++
 channels.conf |  16 +++---
 channels.h    |   4 +-
 config.c      |   5 +-
 config.h      |   7 +--
 device.c      |  53 +++++++++++++-----
 device.h      |  17 ++++--
 dvbdevice.c   |  33 ++++++++++--
 dvbdevice.h   |   3 +-
 dvbspu.h      |   3 +-
 epg.c         |   4 +-
 i18n.c        | 146 +++++++++++++++++++++++++++++++++++++++-----------
 menu.c        |  11 +++-
 skins.h       |   4 +-
 skinsttng.c   |  13 ++---
 spu.h         |   5 +-
 tools.c       |   5 +-
 transfer.c    |   4 +-
 21 files changed, 304 insertions(+), 86 deletions(-)

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 94258a46..52d52244 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -274,6 +274,9 @@ Werner Fink <werner@suse.de>
  for pointing out that pesAssembler->Reset() needs to be called between subsequent
  Transfer Modes
  for suggestions that led to the addition of the 'Id' parameter to cAudio::Play().
+ for pointing out that MAXDPIDS needs to be to 16 (8xAC3 + 8xDTS)
+ for reporting a problem with ensuring there is a current audio track in case there
+ is only one track
 
 Rolf Hakenes <hakenes@hippomi.de>
  for providing 'libdtv' and adapting the EIT mechanisms to it
@@ -1147,6 +1150,14 @@ Marco Schl
  for adding DeviceClrAvailableTracks() and DeviceSetCurrentAudioTrack() to cPlayer
  for reporting a missing 'resultSkipped = 0' in cRemux::Clear()
  for reporting a missing reset of the 'repacker' in cTS2PES::Clear()
+ for avoiding unnecessary calls to SetPid() in cDvbDevice::SetAudioTrackDevice()
+ for pointing out that EnsureAudioTrack() in cDevice::SetChannel() should not be
+ called if a Transfer Mode is started, to avoid setting the audio PID on the primary
+ device
+ for fixing calling cStatus::MsgChannelSwitch() in cDevice::SetChannel()
+ for increasing POLLTIMEOUTS_BEFORE_DEVICECLEAR in transfer.c to 6 to avoid problems
+ with the larger buffer reserve
+ for adding support for setting the video display mode
 
 J�rgen Schmitz <j.schmitz@web.de>
  for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -1268,6 +1279,16 @@ Rolf Groppe <rolf@groppe.de>
 Wolfgang Rohdewald <wolfgang@rohdewald.de>
  for pointing out that primaryDevice = NULL should be done before deleting the devices
  in cDevice::Shutdown()
+ for removing some unneeded code and fixing access to unallocated memory in
+ cEvent::FixEpgBugs()
 
 Chad Flynt <hoochster@sofnet.com>
  for suggestions and experiments regarding the buffer reserve in cTransfer
+
+Chris Warren <dvb@ixalon.net>
+ for pointing out that the call to system("sync") in SpinUpDisk() should be
+ replaced with fsync(f) to avoid problems on NPTL systems
+
+Luca Olivetti <luca@ventoso.org>
+ for making cDevice::AttachPlayer() keep the track language codes and descriptions
+ in Transfer Mode
diff --git a/HISTORY b/HISTORY
index 41b36ebd..a8099c4f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3415,3 +3415,31 @@ Video Disk Recorder Revision History
   from starting Transfer Mode in order to replay DD over the DVB device.
 - Added missing reset of the 'repacker' to cTS2PES::Clear() (thanks to Marco
   Schl��ler for reporting this one).
+
+2005-02-27: Version 1.3.22
+
+- Removed some unneeded code and fixed access to unallocated memory in
+  cEvent::FixEpgBugs() (thanks to Wolfgang Rohdewald).
+- Avoiding unnecessary calls to SetPid() in cDvbDevice::SetAudioTrackDevice()
+  (thanks to Marco Schl��ler).
+- No longer calling EnsureAudioTrack() in cDevice::SetChannel() if a Transfer Mode is
+  started, to avoid setting the audio PID on the primary device (thanks to Marco
+  Schl��ler for pointing this out).
+- Replaced the call to system("sync") in SpinUpDisk() with fdatasync(f) to avoid
+  problems on NPTL systems (thanks to Chris Warren for pointing this out).
+- Increased POLLTIMEOUTS_BEFORE_DEVICECLEAR in transfer.c to 6 to avoid problems
+  with the larger buffer reserve (thanks to Marco Schl��ler).
+- Fixed the call to SetVideoFormat() in cDvbDevice::cDvbDevice() (parameter is _bool_).
+- Added support for setting the video display mode (thanks to Marco Schl��ler).
+- The new setup option "DVB/Video display format" can be used to define which display
+  format to use for playing wide screen video on a 4:3 tv set.
+- Changed MAXDPIDS to 16 (8xAC3 + 8xDTS) (thanks to Werner Fink for pointing this out).
+- Completed dutch language texts (thanks to Hans Dingemans).
+- Added 'smi' to the Finnish language codes (thanks to Rolf Ahrenberg).
+- Fixed ensuring there is a current audio track in case there is only one track
+  (thanks to Werner Fink for reporting this one).
+- Improved automatic audio track selection.
+- Keeping the track language codes and descriptions in Transfer Mode (thanks to
+  Luca Olivetti).
+- Fixed handling repeated kAudio keys.
+- Improved displaying the the current audio track in the ST:TNG channel display.
diff --git a/INSTALL b/INSTALL
index df57170c..e894e8db 100644
--- a/INSTALL
+++ b/INSTALL
@@ -250,7 +250,9 @@ Use "vdr --help" for a list of available command line options.
 Replaying Dolby Digital audio:
 ------------------------------
 
-To replay Dolby Digital audio you need a program that reads the DD data
+If you have a "full featured" DVB card with SPDIF output you can replay
+Dolby Digital audio directly through the DVB card.
+You can also use an external program that reads the DD data
 from stdin and processes it in a way suitable for your audio hardware.
 This program must be given to VDR with the '-a' option, as in
 
diff --git a/MANUAL b/MANUAL
index a03f72cb..e95b94fa 100644
--- a/MANUAL
+++ b/MANUAL
@@ -588,6 +588,10 @@ Version 1.2
                          from the primary DVB interface, so that the viewer will
                          be disturbed as little as possible.
 
+  Video display format = letterbox
+                         The display format to use for playing wide screen video on
+                         a 4:3 tv set ("pan & scan", "letterbox" or "center cut out").
+
   Video format = 4:3     The video format (or aspect ratio) of the tv set in use
                          (4:3 or 16:9).
 
diff --git a/channels.conf b/channels.conf
index d05e2521..e0fc70fa 100644
--- a/channels.conf
+++ b/channels.conf
@@ -29,7 +29,7 @@ Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:11
 EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
 rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0
 Sky News;BSkyB:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
-Veronica/FoxKids;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0
+Veronica/JETIX;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0
 BVN;CANAL+:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
 n-tv;RTL World:12187:hC34:S19.2E:27500:169:73=deu:80:0:12090:1:1089:0
 Al Jazeera;CANALSATELLITE:11567:vC56:S19.2E:22000:55:56=ara:0:0:9021:1:1024:0
@@ -44,14 +44,14 @@ MDR FERNSEHEN;ARD:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0
 rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
 :Premiere World
 PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0
-PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1702,1801:10:133:2:0
-PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1702,1722,1801:11:133:2:0
+PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1801,1702:10:133:2:0
+PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1722,1801,1702:11:133:2:0
 PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0
 PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0
-PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1702,1801:29:133:2:0
-PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1801,1722:41:133:2:0
-PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1801,1702:20:133:2:0
-DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1702,1801:34:133:17:0
+PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1801,1722,1702:29:133:2:0
+PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0
+PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0
+DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1801,1702:34:133:17:0
 :Premiere Direkt
 PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0
 :PW Erotic
@@ -110,7 +110,7 @@ Chelsea TV;BskyB:11778:vC23:S28.2E:27500:2308+2304:2309=eng:0:960,961:9307:2:200
 WDR M�nster;ARD:12421:hC34:S19.2E:27500:101:102=deu:104:0:28310:1:1201:0
 Going Places:10920:hC56:S28.2E:22000:2310+2304:2311=eng:2312:0:5008:2:2055:0
 Animal Plnt+;BSkyB:12070:hC23:S28.2E:27500:2314+2307:2315=eng:0:960,961:50002:2:2019:0
-S1T;BSkyB:12285:vC23:S28.2E:27500:2311+2304:2312=eng,2313=NAR:2307:960,961:4409:2:2030:0
+S1T;BSkyB:12285:vC23:S28.2E:27500:513+8190:641=eng,661=NAR:577:960,961:4409:2:2030:0
 CNN;BSkyB:12051:vC23:S28.2E:27500:2313:2315=eng:2314:0:7140:2:2018:0
 BBC PARL'MNT:12129:vC23:S28.2E:27500:2304:2306=eng,2307=eng:2305:0:7300:2:2022:0
 JOLLY FILM;T-Systems/MTI:11200:vC56:S13.0E:27500:413:414=ita:0:0:4733:318:13400:0
diff --git a/channels.h b/channels.h
index 472003f4..e94be176 100644
--- a/channels.h
+++ b/channels.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.h 1.25 2005/01/16 13:46:41 kls Exp $
+ * $Id: channels.h 1.26 2005/02/20 14:05:24 kls Exp $
  */
 
 #ifndef __CHANNELS_H
@@ -31,7 +31,7 @@
 #define CHANNELSMOD_USER    2
 
 #define MAXAPIDS 32 // audio
-#define MAXDPIDS  8 // dolby
+#define MAXDPIDS 16 // dolby (AC3 + DTS)
 #define MAXSPIDS  8 // subtitles
 #define MAXCAIDS  8 // conditional access
 
diff --git a/config.c b/config.c
index 900d039d..971f1671 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.c 1.132 2005/02/05 10:43:04 kls Exp $
+ * $Id: config.c 1.133 2005/02/20 12:52:59 kls Exp $
  */
 
 #include "config.h"
@@ -279,6 +279,7 @@ cSetup::cSetup(void)
   UseVps = 0;
   VpsMargin = 120;
   RecordingDirs = 1;
+  VideoDisplayFormat = 1;
   VideoFormat = 0;
   UpdateChannels = 4;
   UseDolbyDigital = 1;
@@ -435,6 +436,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
   else if (!strcasecmp(Name, "UseVps"))              UseVps             = atoi(Value);
   else if (!strcasecmp(Name, "VpsMargin"))           VpsMargin          = atoi(Value);
   else if (!strcasecmp(Name, "RecordingDirs"))       RecordingDirs      = atoi(Value);
+  else if (!strcasecmp(Name, "VideoDisplayFormat"))  VideoDisplayFormat = atoi(Value);
   else if (!strcasecmp(Name, "VideoFormat"))         VideoFormat        = atoi(Value);
   else if (!strcasecmp(Name, "UpdateChannels"))      UpdateChannels     = atoi(Value);
   else if (!strcasecmp(Name, "UseDolbyDigital"))     UseDolbyDigital    = atoi(Value);
@@ -498,6 +500,7 @@ bool cSetup::Save(void)
   Store("UseVps",             UseVps);
   Store("VpsMargin",          VpsMargin);
   Store("RecordingDirs",      RecordingDirs);
+  Store("VideoDisplayFormat", VideoDisplayFormat);
   Store("VideoFormat",        VideoFormat);
   Store("UpdateChannels",     UpdateChannels);
   Store("UseDolbyDigital",    UseDolbyDigital);
diff --git a/config.h b/config.h
index 7dffe140..a94f9066 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 1.213 2005/02/08 11:22:14 kls Exp $
+ * $Id: config.h 1.215 2005/02/20 12:50:37 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -20,8 +20,8 @@
 #include "i18n.h"
 #include "tools.h"
 
-#define VDRVERSION  "1.3.21"
-#define VDRVERSNUM   10321  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.3.22"
+#define VDRVERSNUM   10322  // Version * 10000 + Major * 100 + Minor
 
 #define MAXPRIORITY 99
 #define MAXLIFETIME 99
@@ -237,6 +237,7 @@ public:
   int UseVps;
   int VpsMargin;
   int RecordingDirs;
+  int VideoDisplayFormat;
   int VideoFormat;
   int UpdateChannels;
   int UseDolbyDigital;
diff --git a/device.c b/device.c
index f270b5a4..d6ab8911 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 1.92 2005/02/13 09:51:48 kls Exp $
+ * $Id: device.c 1.99 2005/02/27 13:55:15 kls Exp $
  */
 
 #include "device.h"
@@ -169,7 +169,7 @@ cDevice::cDevice(void)
   player = NULL;
   pesAssembler = new cPesAssembler;
   ClrAvailableTracks();
-  currentAudioTrack = ttAudioFirst;
+  currentAudioTrack = ttNone;
   currentAudioTrackMissingCount = 0;
 
   for (int i = 0; i < MAXRECEIVERS; i++)
@@ -235,6 +235,7 @@ bool cDevice::SetPrimaryDevice(int n)
         primaryDevice->MakePrimaryDevice(false);
      primaryDevice = device[n];
      primaryDevice->MakePrimaryDevice(true);
+     primaryDevice->SetVideoFormat(Setup.VideoFormat);
      return true;
      }
   esyslog("ERROR: invalid primary device number: %d", n + 1);
@@ -327,6 +328,28 @@ bool cDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX,
   return false;
 }
 
+void cDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
+{
+  cSpuDecoder *spuDecoder = GetSpuDecoder();
+  if (spuDecoder) {
+     if (Setup.VideoFormat)
+        spuDecoder->setScaleMode(cSpuDecoder::eSpuNormal);
+     else {
+        switch (VideoDisplayFormat) {
+               case vdfPanAndScan:
+                    spuDecoder->setScaleMode(cSpuDecoder::eSpuPanAndScan);
+                    break;
+               case vdfLetterBox:
+                    spuDecoder->setScaleMode(cSpuDecoder::eSpuLetterBox);
+                    break;
+               case vdfCenterCutOut:
+                    spuDecoder->setScaleMode(cSpuDecoder::eSpuNormal);
+                    break;
+               }
+        }
+     }
+}
+
 void cDevice::SetVideoFormat(bool VideoFormat16_9)
 {
 }
@@ -578,14 +601,14 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
         currentChannel = Channel->Number();
         // Set the available audio tracks:
         ClrAvailableTracks();
-        currentAudioTrack = ttAudioFirst;
         for (int i = 0; i < MAXAPIDS; i++)
             SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
         if (Setup.UseDolbyDigital) {
            for (int i = 0; i < MAXDPIDS; i++)
                SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
            }
-        EnsureAudioTrack(true);
+        if (!NeedsTransferMode)
+           EnsureAudioTrack(true);
         }
      cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
      }
@@ -680,6 +703,7 @@ void cDevice::ClrAvailableTracks(bool DescriptionsOnly)
      pre_1_3_19_PrivateStream = false;
      SetAudioChannel(0); // fall back to stereo
      currentAudioTrackMissingCount = 0;
+     currentAudioTrack = ttNone;
      }
 }
 
@@ -692,12 +716,14 @@ bool cDevice::SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const c
         strn0cpy(availableTracks[t].language, Language, sizeof(availableTracks[t].language));
      if (Description)
         strn0cpy(availableTracks[t].description, Description, sizeof(availableTracks[t].description));
-     if (Id)
+     if (Id) {
         availableTracks[t].id = Id; // setting 'id' last to avoid the need for extensive locking
-     if (t == currentAudioTrack)
-        currentAudioTrackMissingCount = 0;
-     else if (!availableTracks[currentAudioTrack].id && currentAudioTrackMissingCount++ > NumAudioTracks() * 10)
-        EnsureAudioTrack();
+        int numAudioTracks = NumAudioTracks();
+        if (!availableTracks[currentAudioTrack].id && numAudioTracks && currentAudioTrackMissingCount++ > numAudioTracks * 10)
+           EnsureAudioTrack();
+        else if (t == currentAudioTrack)
+           currentAudioTrackMissingCount = 0;
+        }
      return true;
      }
   else
@@ -816,7 +842,8 @@ bool cDevice::AttachPlayer(cPlayer *Player)
   if (CanReplay()) {
      if (player)
         Detach(player);
-     ClrAvailableTracks();
+     if (!dynamic_cast<cTransfer *>(Player))
+        ClrAvailableTracks();
      pesAssembler->Reset();
      player = Player;
      SetPlayMode(player->playMode);
@@ -834,6 +861,7 @@ void cDevice::Detach(cPlayer *Player)
      player->device = NULL;
      player = NULL;
      SetPlayMode(pmNone);
+     SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
      Audios.ClearAudio();
      }
 }
@@ -894,7 +922,7 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly)
                uchar SubStreamId = Data[PayloadOffset];
                uchar SubStreamType = SubStreamId & 0xF0;
                uchar SubStreamIndex = SubStreamId & 0x1F;
-
+        
                // Compatibility mode for old VDR recordings, where 0xBD was only AC3:
 pre_1_3_19_PrivateStreamDeteced:
                if (pre_1_3_19_PrivateStream) {
@@ -902,7 +930,6 @@ pre_1_3_19_PrivateStreamDeteced:
                   SubStreamType = 0x80;
                   SubStreamIndex = 0;
                   }
-
                switch (SubStreamType) {
                  case 0x20: // SPU
                  case 0x30: // SPU
@@ -1002,7 +1029,7 @@ int cDevice::PlayPes(const uchar *Data, int Length, bool VideoOnly)
   if (i < Length)
      pesAssembler->Put(Data + i, Length - i);
   return Length;
- }
+}
 
 int cDevice::Ca(void) const
 {
diff --git a/device.h b/device.h
index 80587992..02fa35cc 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.h 1.55 2005/02/06 11:43:04 kls Exp $
+ * $Id: device.h 1.57 2005/02/20 14:06:28 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -18,6 +18,7 @@
 #include "ringbuffer.h"
 #include "sdt.h"
 #include "sections.h"
+#include "spu.h"
 #include "thread.h"
 #include "tools.h"
 
@@ -56,17 +57,22 @@ enum eVideoSystem { vsPAL,
                     vsNTSC
                   };
 
+enum eVideoDisplayFormat { vdfPanAndScan,
+                           vdfLetterBox,
+                           vdfCenterCutOut
+                         };
+
 enum eTrackType { ttNone,
                   ttAudio,
                   ttAudioFirst = ttAudio,
                   ttAudioLast  = ttAudioFirst + 31, // MAXAPIDS - 1
                   ttDolby,
                   ttDolbyFirst = ttDolby,
-                  ttDolbyLast  = ttDolbyFirst + 8, // MAXDPIDS - 1
+                  ttDolbyLast  = ttDolbyFirst + 15, // MAXDPIDS - 1
                   /* future...
                   ttSubtitle,
                   ttSubtitleFirst = ttSubtitle,
-                  ttSubtitleLast  = ttSubtitleFirst + 8, // MAXSPIDS - 1
+                  ttSubtitleLast  = ttSubtitleFirst + 7, // MAXSPIDS - 1
                   */
                   ttMaxTrackTypes
                 };
@@ -83,7 +89,6 @@ struct tTrackId {
 class cChannel;
 class cPlayer;
 class cReceiver;
-class cSpuDecoder;
 class cPesAssembler;
 
 /// The cDevice class is the base from which actual devices can be derived.
@@ -301,6 +306,10 @@ public:
 // Video format facilities
 
 public:
+  virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat);
+         ///< Sets the video display format to the given one (only useful
+         ///< if this device has an MPEG decoder).
+         ///< A derived class must first call the base class function!
   virtual void SetVideoFormat(bool VideoFormat16_9);
          ///< Sets the output video format to either 16:9 or 4:3 (only useful
          ///< if this device has an MPEG decoder).
diff --git a/dvbdevice.c b/dvbdevice.c
index 741848a8..c2311229 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 1.120 2005/02/13 14:26:37 kls Exp $
+ * $Id: dvbdevice.c 1.124 2005/02/20 13:35:28 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -402,7 +402,7 @@ cDvbDevice::cDvbDevice(int n)
 
   // Video format:
 
-  SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
+  SetVideoFormat(Setup.VideoFormat);
 
   // We only check the devices that must be present - the others will be checked before accessing them://XXX
 
@@ -599,10 +599,35 @@ bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int Siz
   return false;
 }
 
+void cDvbDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
+{
+  cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
+  if (HasDecoder()) {
+     if (Setup.VideoFormat) {
+        CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_CENTER_CUT_OUT));
+        }
+     else {
+        switch (VideoDisplayFormat) {
+          case vdfPanAndScan:
+               CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_PAN_SCAN));
+               break;
+          case vdfLetterBox:
+               CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX));
+               break;
+          case vdfCenterCutOut:
+               CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_CENTER_CUT_OUT));
+               break;
+          }
+        }
+     }
+}
+
 void cDvbDevice::SetVideoFormat(bool VideoFormat16_9)
 {
-  if (HasDecoder())
+  if (HasDecoder()) {
      CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, VideoFormat16_9 ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3));
+     SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
+     }
 }
 
 eVideoSystem cDvbDevice::GetVideoSystem(void)
@@ -872,7 +897,7 @@ void cDvbDevice::SetAudioTrackDevice(eTrackType Type)
   const tTrackId *TrackId = GetTrack(Type);
   if (TrackId && TrackId->id) {
      if (IS_AUDIO_TRACK(Type)) {
-        if (pidHandles[ptAudio].pid) {
+        if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) {
            pidHandles[ptAudio].pid = TrackId->id;
            SetPid(&pidHandles[ptAudio], ptAudio, true);
            }
diff --git a/dvbdevice.h b/dvbdevice.h
index 99456e73..4a705367 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.h 1.33 2005/02/13 14:14:31 kls Exp $
+ * $Id: dvbdevice.h 1.34 2005/02/20 11:17:07 kls Exp $
  */
 
 #ifndef __DVBDEVICE_H
@@ -87,6 +87,7 @@ public:
 // Video format facilities
 
 public:
+  virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat);
   virtual void SetVideoFormat(bool VideoFormat16_9);
   virtual eVideoSystem GetVideoSystem(void);
 
diff --git a/dvbspu.h b/dvbspu.h
index 88812347..c60567a3 100644
--- a/dvbspu.h
+++ b/dvbspu.h
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.h 1.7 2005/01/08 09:59:44 kls Exp $
+ * $Id: dvbspu.h 1.8 2005/02/20 11:20:43 kls Exp $
  */
 
 #ifndef __DVBSPU_H
@@ -139,6 +139,7 @@ class cDvbSpuDecoder:public cSpuDecoder {
 
     int setTime(uint32_t pts);
 
+    cSpuDecoder::eScaleMode getScaleMode(void) { return scaleMode; }
     void setScaleMode(cSpuDecoder::eScaleMode ScaleMode);
     void setPalette(uint32_t * pal);
     void setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey,
diff --git a/epg.c b/epg.c
index 5539ab04..df267f63 100644
--- a/epg.c
+++ b/epg.c
@@ -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 1.24 2005/01/02 11:25:25 kls Exp $
+ * $Id: epg.c 1.25 2005/02/19 11:35:00 kls Exp $
  */
 
 #include "epg.h"
@@ -525,7 +525,7 @@ void cEvent::FixEpgBugs(void)
      if (description) {
         char *p = description;
         while (*p && *(p + 1) && *(p + 2)) {
-              if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
+              if (*p == '-' && *(p + 1) == ' ' && p != description && islower(*(p - 1)) && islower(*(p + 2))) {
                  if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten"
                     memmove(p, p + 2, strlen(p + 2) + 1);
                     EpgBugFixStat(5, ChannelID());
diff --git a/i18n.c b/i18n.c
index 9d7417c0..a265cd0e 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: i18n.c 1.177 2005/02/12 10:26:51 kls Exp $
+ * $Id: i18n.c 1.181 2005/02/27 09:45:57 kls Exp $
  *
  * Translations provided by:
  *
@@ -133,7 +133,7 @@ const tI18nPhrase Phrases[] = {
     "por",
     "fra,fre",
     "nor",
-    "fin",
+    "fin,smi",
     "pol",
     "esl,spa",
     "ell,gre",
@@ -950,7 +950,7 @@ const tI18nPhrase Phrases[] = {
     "Scan",
     "",//TODO
     "Scansione",
-    "",//TODO
+    "Scan",
     "",//TODO
     "Scan",
     "",//TODO
@@ -1793,7 +1793,7 @@ const tI18nPhrase Phrases[] = {
     "VPS",
     "",// TODO
     "VPS",
-    "",// TODO
+    "VPS",
     "",// TODO
     "VPS",
     "",// TODO
@@ -2298,7 +2298,7 @@ const tI18nPhrase Phrases[] = {
     "Kein Audio verf�gbar!",
     "",//TODO
     "",//TODO
-    "",//TODO
+    "Geen audio beschikbaar!",
     "",//TODO
     "",//TODO
     "",//TODO
@@ -2573,7 +2573,7 @@ const tI18nPhrase Phrases[] = {
     "Oberfl�che",
     "",// TODO
     "Superficie Skin",
-    "",// TODO
+    "Skin",
     "",// TODO
     "Skin",
     "",// TODO
@@ -2594,7 +2594,7 @@ const tI18nPhrase Phrases[] = {
     "Thema",
     "",// TODO
     "Tema",
-    "",// TODO
+    "Thema",
     "",// TODO
     "Th�me",
     "",// TODO
@@ -2615,7 +2615,7 @@ const tI18nPhrase Phrases[] = {
     "Links",
     "",// TODO
     "Sinistra",
-    "",// TODO
+    "Links",
     "",// TODO
     "Gauche",
     "",// TODO
@@ -2636,7 +2636,7 @@ const tI18nPhrase Phrases[] = {
     "Oben",
     "",// TODO
     "Cima",
-    "",// TODO
+    "Boven",
     "",// TODO
     "Haut",
     "",// TODO
@@ -2720,7 +2720,7 @@ const tI18nPhrase Phrases[] = {
     "Kleine Schrift benutzen",
     "",// TODO
     "Utilizzare caratteri piccoli",
-    "",// TODO
+    "Klein lettertype gebruiken",
     "",// TODO
     "Utiliser les petits caract�res",
     "",// TODO
@@ -2741,7 +2741,7 @@ const tI18nPhrase Phrases[] = {
     "nie",
     "",// TODO
     "mai",
-    "",// TODO
+    "nooit",
     "",// TODO
     "jamais",
     "",// TODO
@@ -2762,7 +2762,7 @@ const tI18nPhrase Phrases[] = {
     "je nach Oberfl�che",
     "",// TODO
     "in base alla superficie",
-    "",// TODO
+    "skin afhankelijk",
     "",// TODO
     "D�pend du skin",
     "",// TODO
@@ -2783,7 +2783,7 @@ const tI18nPhrase Phrases[] = {
     "immer",
     "",// TODO
     "sempre",
-    "",// TODO
+    "altijd",
     "",// TODO
     "toujours",
     "",// TODO
@@ -2825,7 +2825,7 @@ const tI18nPhrase Phrases[] = {
     "Anzeigedauer f�r Kanal-Info (s)",
     "",// TODO
     "",// TODO
-    "",// TODO
+    "Duur tonen kanaal-informatie (s)",
     "",// TODO
     "Dur�e affichage infos cha�nes (s)",
     "",// TODO
@@ -2972,7 +2972,7 @@ const tI18nPhrase Phrases[] = {
     "Alte EPG-Daten anzeigen (min)",// TODO
     "",// TODO
     "Visualizzazione dati vecchi (min)",
-    "",// TODO
+    "Oude EPG data tonen (min)",
     "",// TODO
     "Montrer l'EPG plus vieux de m min",
     "",// TODO
@@ -3035,7 +3035,7 @@ const tI18nPhrase Phrases[] = {
     "Bevorzugte Sprachen",
     "",// TODO
     "Lingue preferite",
-    "",// TODO
+    "Voorkeurstalen",
     "",// TODO
     "Langues pr�f�r�es",
     "",// TODO
@@ -3056,7 +3056,7 @@ const tI18nPhrase Phrases[] = {
     "Bevorzugte Sprache",
     "",// TODO
     "Lingua preferita",
-    "",// TODO
+    "Voorkeurstaal",
     "",// TODO
     "Langue pr�f�r�e",
     "",// TODO
@@ -3094,6 +3094,90 @@ const tI18nPhrase Phrases[] = {
     "Esmane DVB seade",
     "Prim�r DVB enhed",
   },
+  { "Setup.DVB$Video display format",
+    "Video Anzeige-Format",
+    "",//TODO
+    "",//TODO
+    "Video display format",
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+    "",//TODO
+  },
+  { "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+    "pan&scan",
+  },
+  { "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+    "letterbox",
+  },
+  { "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+    "center cut out",
+  },
   { "Setup.DVB$Video format",
     "Video Format",
     "Video format",
@@ -3119,7 +3203,7 @@ const tI18nPhrase Phrases[] = {
     "Dolby Digital Ton benutzen",
     "",//TODO
     "",//TODO
-    "",//TODO
+    "Dolby Digital gebruiken",
     "",//TODO
     "",//TODO
     "",//TODO
@@ -3140,7 +3224,7 @@ const tI18nPhrase Phrases[] = {
     "Kan�le aktualisieren",
     "",// TODO
     "Aggiornare i canali",
-    "",// TODO
+    "Kanalen actualiseren",
     "",// TODO
     "Mettre � jour les cha�nes",
     "",// TODO
@@ -3161,7 +3245,7 @@ const tI18nPhrase Phrases[] = {
     "nur Namen",
     "",// TODO
     "solo nomi",
-    "",// TODO
+    "alleen namen",
     "",// TODO
     "Seulement les noms",
     "",// TODO
@@ -3182,7 +3266,7 @@ const tI18nPhrase Phrases[] = {
     "Namen und PIDs",
     "",// TODO
     "nomi e PIDs",
-    "",// TODO
+    "namen en PIDs",
     "",// TODO
     "Noms et PIDs",
     "",// TODO
@@ -3203,7 +3287,7 @@ const tI18nPhrase Phrases[] = {
     "neue Kan�le hinzuf�gen",
     "",// TODO
     "aggiungere canali nuovi",
-    "",// TODO
+    "nieuwe kanalen toevoegen",
     "",// TODO
     "Ajouter les nouvelles cha�nes",
     "",// TODO
@@ -3224,7 +3308,7 @@ const tI18nPhrase Phrases[] = {
     "neue Transponder hinzuf�gen",
     "",// TODO
     "aggiungere transponder nuovi",
-    "",// TODO
+    "nieuwe transponders toevoegen",
     "",// TODO
     "Ajouter les nouveaux transpondeurs",
     "",// TODO
@@ -3245,7 +3329,7 @@ const tI18nPhrase Phrases[] = {
     "",//TODO
     "",//TODO
     "",//TODO
-    "",//TODO
+    "Audio talen",
     "",//TODO
     "",//TODO
     "",//TODO
@@ -3266,7 +3350,7 @@ const tI18nPhrase Phrases[] = {
     "",//TODO
     "",//TODO
     "",//TODO
-    "",//TODO
+    "Audio taal",
     "",//TODO
     "",//TODO
     "",//TODO
@@ -3560,7 +3644,7 @@ const tI18nPhrase Phrases[] = {
     "VPS benutzen",
     "",// TODO
     "Utilizzare VPS",
-    "",// TODO
+    "VPS gebruiken",
     "",// TODO
     "Utiliser le VPS",
     "",// TODO
@@ -3581,7 +3665,7 @@ const tI18nPhrase Phrases[] = {
     "Zeitpuffer bei VPS (s)",
     "",// TODO
     "Margine VPS",
-    "",// TODO
+    "Marge VPS (s)",
     "",// TODO
     "Marge VPS",
     "",// TODO
@@ -3898,7 +3982,7 @@ const tI18nPhrase Phrases[] = {
     " a�bcdefghijklmno�pqrstu�vwxyz0123456789-.#~",
     " abcdefghijklmnopqrstuvwxyz0123456789-.#~",
     " a�bcde��fghi�jklmnopqrstu�vwxyz0123456789-.#~",
-    "",// TODO
+    " abcdefghijklmnopqrstuvwxyz0123456789-.#~����������",
     "",// TODO
     " a�bc�de���fghi�jklmno�pqrstu��vwxyz0123456789-.#~",
     "",// TODO
@@ -4698,7 +4782,7 @@ const tI18nPhrase Phrases[] = {
     "Audio",
     "",// TODO
     "",// TODO
-    "",// TODO
+    "Audio",
     "",// TODO
     "",// TODO
     "",// TODO
@@ -5182,7 +5266,7 @@ const tI18nPhrase Phrases[] = {
     "Klassischer VDR",
     "",// TODO
     "VDR Classico",
-    "",// TODO
+    "VDR Klassiek",
     "",// TODO
     "",// TODO
     "",// TODO
@@ -5203,7 +5287,7 @@ const tI18nPhrase Phrases[] = {
     "ST:TNG Konsolen",
     "",// TODO
     "Consolles ST:TNG",
-    "",// TODO
+    "ST:TNG Consoles",
     "",// TODO
     "",// TODO
     "",// TODO
diff --git a/menu.c b/menu.c
index a438b799..e3168633 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 1.340 2005/02/06 11:33:13 kls Exp $
+ * $Id: menu.c 1.342 2005/02/27 14:09:00 kls Exp $
  */
 
 #include "menu.h"
@@ -1915,6 +1915,7 @@ private:
   int originalNumAudioLanguages;
   int numAudioLanguages;
   void Setup(void);
+  const char *videoDisplayFormatTexts[3];
   const char *updateChannelsTexts[5];
 public:
   cMenuSetupDVB(void);
@@ -1926,6 +1927,9 @@ cMenuSetupDVB::cMenuSetupDVB(void)
   for (numAudioLanguages = 0; numAudioLanguages < I18nNumLanguages && data.AudioLanguages[numAudioLanguages] >= 0; numAudioLanguages++)
       ;
   originalNumAudioLanguages = numAudioLanguages;
+  videoDisplayFormatTexts[0] = tr("pan&scan");
+  videoDisplayFormatTexts[1] = tr("letterbox");
+  videoDisplayFormatTexts[2] = tr("center cut out");
   updateChannelsTexts[0] = tr("no");
   updateChannelsTexts[1] = tr("names only");
   updateChannelsTexts[2] = tr("names and PIDs");
@@ -1943,6 +1947,7 @@ void cMenuSetupDVB::Setup(void)
   Clear();
 
   Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices()));
+  Add(new cMenuEditStraItem(tr("Setup.DVB$Video display format"),  &data.VideoDisplayFormat, 3, videoDisplayFormatTexts));
   Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"),          &data.VideoFormat, "4:3", "16:9"));
   Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Dolby Digital"),     &data.UseDolbyDigital));
   Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"),       &data.UpdateChannels, 5, updateChannelsTexts));
@@ -1957,6 +1962,7 @@ void cMenuSetupDVB::Setup(void)
 eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
 {
   int oldPrimaryDVB = ::Setup.PrimaryDVB;
+  int oldVideoDisplayFormat = ::Setup.VideoDisplayFormat;
   bool oldVideoFormat = ::Setup.VideoFormat;
   int oldnumAudioLanguages = numAudioLanguages;
   eOSState state = cMenuSetupBase::ProcessKey(Key);
@@ -1984,6 +1990,8 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
   if (state == osBack && Key == kOk) {
      if (::Setup.PrimaryDVB != oldPrimaryDVB)
         state = osSwitchDvb;
+     if (::Setup.VideoDisplayFormat != oldVideoDisplayFormat)
+        cDevice::PrimaryDevice()->SetVideoDisplayFormat(eVideoDisplayFormat(::Setup.VideoDisplayFormat));
      if (::Setup.VideoFormat != oldVideoFormat)
         cDevice::PrimaryDevice()->SetVideoFormat(::Setup.VideoFormat);
      }
@@ -2938,6 +2946,7 @@ eOSState cDisplayTracks::ProcessKey(eKeys Key)
                     timeout.Set(TRACKTIMEOUT);
                     }
          break;
+    case kAudio|k_Repeat:
     case kAudio:
          if (++track >= numTracks)
             track = 0;
diff --git a/skins.h b/skins.h
index ae2733c4..add8d56a 100644
--- a/skins.h
+++ b/skins.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.h 1.6 2005/01/09 11:49:37 kls Exp $
+ * $Id: skins.h 1.7 2005/02/27 14:37:37 kls Exp $
  */
 
 #ifndef __SKINS_H
@@ -54,7 +54,7 @@ public:
        ///< user is in the process of entering a channel number, which must
        ///< be displayed accordingly.
   virtual void SetEvents(const cEvent *Present, const cEvent *Following) = 0;
-       ///< Sets the Present and Following EPG events. It either of these
+       ///< Sets the Present and Following EPG events. If either of these
        ///< is not available, NULL will be given.
   virtual void SetMessage(eMessageType Type, const char *Text) = 0;
        ///< Sets a one line message Text, with the given Type. Type can be used
diff --git a/skinsttng.c b/skinsttng.c
index 94a4b66f..3760ad4d 100644
--- a/skinsttng.c
+++ b/skinsttng.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinsttng.c 1.12 2005/01/08 15:37:55 kls Exp $
+ * $Id: skinsttng.c 1.13 2005/02/27 14:45:19 kls Exp $
  */
 
 // Star Trek: The Next Generation� is a registered trademark of Paramount Pictures
@@ -268,9 +268,6 @@ void cSkinSTTNGDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Fo
          osd->DrawText(x3 + 2, y3 + (2 * i + 1) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), x4 - x3 - 2);
          }
       }
-  cDevice *Device = cDevice::PrimaryDevice();
-  const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
-  osd->DrawText(x3 + 2, y6, Track ? Track->description : "", Theme.Color(clrChannelName), frameColor, cFont::GetFont(fontSml), x4 - x3 - 2);
 }
 
 void cSkinSTTNGDisplayChannel::SetMessage(eMessageType Type, const char *Text)
@@ -295,9 +292,13 @@ void cSkinSTTNGDisplayChannel::Flush(void)
 {
   if (withInfo) {
      if (!message) {
-        cString date = DayDateTime();
         const cFont *font = cFont::GetFont(fontSml);
-        osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
+        cString date = DayDateTime();
+        int w = font->Width(date);
+        osd->DrawText(x4 - w - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
+        cDevice *Device = cDevice::PrimaryDevice();
+        const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
+        osd->DrawText(x3 + 2, y6, Track ? Track->description : "", Theme.Color(clrChannelName), frameColor, font, x4 - x3 - w - 4);
         }
 
      int seen = 0;
diff --git a/spu.h b/spu.h
index 9ab4da5b..0437a322 100644
--- a/spu.h
+++ b/spu.h
@@ -6,7 +6,7 @@
  * This code is distributed under the terms and conditions of the
  * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
  *
- * $Id: spu.h 1.3 2005/01/08 09:58:35 kls Exp $
+ * $Id: spu.h 1.4 2005/02/20 11:21:31 kls Exp $
  */
 
 #ifndef __SPU_VDR_H
@@ -21,10 +21,11 @@ class cSpuDecoder {
     typedef enum { eSpuNormal, eSpuLetterBox, eSpuPanAndScan } eScaleMode;
   public:
     //    cSpuDecoder();
-     virtual ~ cSpuDecoder();
+    virtual ~cSpuDecoder();
 
     virtual int setTime(uint32_t pts) = 0;
 
+    virtual cSpuDecoder::eScaleMode getScaleMode(void) = 0;
     virtual void setScaleMode(cSpuDecoder::eScaleMode ScaleMode) = 0;
     virtual void setPalette(uint32_t * pal) = 0;
     virtual void setHighlight(uint16_t sx, uint16_t sy,
diff --git a/tools.c b/tools.c
index 0501d76d..aee71ecf 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 1.89 2005/02/05 10:10:30 kls Exp $
+ * $Id: tools.c 1.90 2005/02/19 13:43:03 kls Exp $
  */
 
 #include "tools.h"
@@ -454,8 +454,9 @@ bool SpinUpDisk(const char *FileName)
          int f = open(buf, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
          // O_SYNC doesn't work on all file systems
          if (f >= 0) {
+            if (fdatasync(f) < 0)
+               LOG_ERROR_STR(buf);
             close(f);
-            system("sync");
             remove(buf);
             gettimeofday(&tp2, NULL);
             double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
diff --git a/transfer.c b/transfer.c
index 331ac62b..c214b88f 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,13 +4,13 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: transfer.c 1.27 2005/02/12 15:54:06 kls Exp $
+ * $Id: transfer.c 1.28 2005/02/19 14:38:55 kls Exp $
  */
 
 #include "transfer.h"
 
 #define TRANSFERBUFSIZE  MEGABYTE(2)
-#define POLLTIMEOUTS_BEFORE_DEVICECLEAR 3
+#define POLLTIMEOUTS_BEFORE_DEVICECLEAR 6
 
 // --- cTransfer -------------------------------------------------------------