diff -Nru vdr-1.5.12/config.c vdr-1.5.12-syncearly/config.c --- vdr-1.5.12/config.c 2007-11-18 17:54:58.000000000 +0100 +++ vdr-1.5.12-syncearly/config.c 2007-11-18 17:56:31.000000000 +0100 @@ -267,6 +267,7 @@ UpdateChannels = 5; RecordDolbyDigital = 1; UseDolbyDigital = 1; + UseSyncEarlyPatch = 1; ChannelInfoPos = 0; ChannelInfoTime = 5; OSDLeft = 54; @@ -454,6 +455,7 @@ else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value); else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value); else if (!strcasecmp(Name, "UseDolbyDigital")) UseDolbyDigital = atoi(Value); + else if (!strcasecmp(Name, "UseSyncEarlyPatch")) UseSyncEarlyPatch = atoi(Value); else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); else if (!strcasecmp(Name, "ChannelInfoTime")) ChannelInfoTime = atoi(Value); else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value); @@ -559,6 +561,7 @@ Store("UpdateChannels", UpdateChannels); Store("RecordDolbyDigital", RecordDolbyDigital); Store("UseDolbyDigital", UseDolbyDigital); + Store("UseSyncEarlyPatch", UseSyncEarlyPatch); Store("ChannelInfoPos", ChannelInfoPos); Store("ChannelInfoTime", ChannelInfoTime); Store("OSDLeft", OSDLeft); diff -Nru vdr-1.5.12/config.h vdr-1.5.12-syncearly/config.h --- vdr-1.5.12/config.h 2007-11-18 17:54:58.000000000 +0100 +++ vdr-1.5.12-syncearly/config.h 2007-11-18 17:56:43.000000000 +0100 @@ -253,6 +253,7 @@ int UpdateChannels; int RecordDolbyDigital; int UseDolbyDigital; + int UseSyncEarlyPatch; int ChannelInfoPos; int ChannelInfoTime; int OSDLeft, OSDTop, OSDWidth, OSDHeight; diff -Nru vdr-1.5.12/device.c vdr-1.5.12-syncearly/device.c --- vdr-1.5.12/device.c 2007-11-18 17:54:58.000000000 +0100 +++ vdr-1.5.12-syncearly/device.c 2007-11-18 17:57:14.000000000 +0100 @@ -988,7 +988,7 @@ } for (int i = 0; i < MAXSPIDS; i++) SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i)); - if (!NeedsTransferMode) + if ((Setup.UseSyncEarlyPatch && (!NeedsTransferMode || GetCurrentAudioTrack() == ttNone)) || (!Setup.UseSyncEarlyPatch && !NeedsTransferMode)) EnsureAudioTrack(true); EnsureSubtitleTrack(); } diff -Nru vdr-1.5.12/menu.c vdr-1.5.12-syncearly/menu.c --- vdr-1.5.12/menu.c 2007-11-18 17:55:05.000000000 +0100 +++ vdr-1.5.12-syncearly/menu.c 2007-11-18 17:57:42.000000000 +0100 @@ -2781,6 +2781,7 @@ Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); } + Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Sync Early Patch"), &data.UseSyncEarlyPatch)); SetCurrent(Get(current)); Display(); diff -Nru vdr-1.5.12/remux.c vdr-1.5.12-syncearly/remux.c --- vdr-1.5.12/remux.c 2007-11-18 17:55:01.000000000 +0100 +++ vdr-1.5.12-syncearly/remux.c 2007-11-18 18:01:35.000000000 +0100 @@ -1998,12 +1998,13 @@ #define RESULTBUFFERSIZE KILOBYTE(256) -cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) +cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure, bool SyncEarly) { exitOnFailure = ExitOnFailure; noVideo = VPid == 0 || VPid == 1 || VPid == 0x1FFF; numUPTerrors = 0; synced = false; + syncEarly = SyncEarly; skipped = 0; numTracks = 0; resultSkipped = 0; @@ -2218,12 +2219,18 @@ ShutdownHandler.RequestEmergencyExit(); } else if (!synced) { - if (pt == I_FRAME) { + if (pt == I_FRAME || syncEarly) { if (PictureType) *PictureType = pt; resultSkipped = i; // will drop everything before this position + if (!syncEarly) SetBrokenLink(data + i, l); synced = true; + if (syncEarly) { + if (pt == I_FRAME) // syncEarly: it's ok but there is no need to call SetBrokenLink() + SetBrokenLink(data + i, l); + else fprintf(stderr, "video: synced early\n"); + } } } else if (Count) @@ -2236,15 +2243,16 @@ l = GetPacketLength(data, resultCount, i); if (l < 0) return resultData; - if (noVideo) { + if (noVideo || !synced && syncEarly) { uchar pt = NO_PICTURE; if (audioIndexer && !Count) audioIndexer->PrepareFrame(data, resultCount, i, pt); if (!synced) { - if (PictureType) + if (PictureType && noVideo) *PictureType = pt; resultSkipped = i; // will drop everything before this position synced = true; + if (!noVideo && syncEarly) fprintf(stderr, "audio: synced early\n"); } else if (Count) return resultData; diff -Nru vdr-1.5.12/remux.h vdr-1.5.12-syncearly/remux.h --- vdr-1.5.12/remux.h 2007-11-18 17:55:01.000000000 +0100 +++ vdr-1.5.12-syncearly/remux.h 2007-11-18 18:02:23.000000000 +0100 @@ -41,6 +41,7 @@ bool noVideo; int numUPTerrors; bool synced; + bool syncEarly; int skipped; cTS2PES *ts2pes[MAXTRACKS]; int numTracks; @@ -49,12 +50,13 @@ cAudioIndexer *audioIndexer; int GetPid(const uchar *Data); public: - cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); + cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false, bool SyncEarly = false); ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while ///< APids, DPids and SPids are pointers to zero terminated lists of audio, ///< dolby and subtitle PIDs (the pointers may be NULL if there is no such ///< PID). If ExitOnFailure is true, the remuxer will initiate an "emergency ///< exit" in case of problems with the data stream. + ///< SyncEarly causes cRemux to sync as soon as a video or audio frame is seen. ~cRemux(); void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } ///< By default cRemux assumes that Put() and Get() are called from different diff -Nru vdr-1.5.12/transfer.c vdr-1.5.12-syncearly/transfer.c --- vdr-1.5.12/transfer.c 2007-01-05 11:45:28.000000000 +0100 +++ vdr-1.5.12-syncearly/transfer.c 2007-11-18 18:02:39.000000000 +0100 @@ -19,7 +19,7 @@ ,cThread("transfer") { ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); + remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, false, Setup.UseSyncEarlyPatch); } cTransfer::~cTransfer()