Hi,
the motivation for this patch was to speed up zapping channels when
using vdr-xine, i. e. to shorten the time from pressing the remote
button till audio and video appear.
FF card users may only see the effect of this patch when the FF card is
running in transfer mode.
The idea is to not wait for the first I frame in transfer mode. Although
output devices can't decode any frames before the first I frame, the
contained PTS in the PES packets allows the device to synchronize audio
and video even before the first video frame appears on screen.
Another issue which is addressed by this patch is that audio packets
were not delivered to the device immediately after switching the
channel, so the above change didn't have any effect. Calling
EnsureAudioTrack() fixes this.
How much speed up can be expected? Well, it varies from zap to zap as it
depends on a couple of parameters like the offset of audio and video
PTS, whether a PTS is available per frame, the number of frames till the
next I frame arrives, etc. But a speed up should be noticeable.
BTW: Testers of plugin ** should comment out the following line in
cTSBuffer::Get() in file device.c, like that:
//if(!device-***) device-***=new c***;
This change is highly recommended if you experience buffer overflows
while switching channels, though they are not related to the sync early
patch.
Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:[EMAIL PROTECTED]
diff -Nurp ../vdr-1.4.6-1-orig/device.c ./device.c
--- ../vdr-1.4.6-1-orig/device.c 2006-09-03 12:13:25.0 +0200
+++ ./device.c 2007-05-06 21:22:52.0 +0200
@@ -691,7 +691,7 @@ eSetChannelResult cDevice::SetChannel(co
for (int i = 0; i MAXDPIDS; i++)
SetAvailableTrack(ttDolby, i, Channel-Dpid(i), Channel-Dlang(i));
}
-if (!NeedsTransferMode)
+if (!NeedsTransferMode || GetCurrentAudioTrack() == ttNone)
EnsureAudioTrack(true);
}
cStatus::MsgChannelSwitch(this, Channel-Number()); // only report status if channel switch successfull
diff -Nurp ../vdr-1.4.6-1-orig/remux.c ./remux.c
--- ../vdr-1.4.6-1-orig/remux.c 2006-12-01 15:46:25.0 +0100
+++ ./remux.c 2007-05-06 21:22:52.0 +0200
@@ -1853,12 +1853,13 @@ void cTS2PES::ts_to_pes(const uint8_t *B
#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;
isRadio = VPid == 0 || VPid == 1 || VPid == 0x1FFF;
numUPTerrors = 0;
synced = false;
+ syncEarly = SyncEarly;
skipped = 0;
numTracks = 0;
resultSkipped = 0;
@@ -2062,12 +2063,14 @@ uchar *cRemux::Get(int Count, uchar *Pi
cThread::EmergencyExit(true);
}
else if (!synced) {
- if (pt == I_FRAME) {
+ if (pt == I_FRAME || syncEarly) {
if (PictureType)
*PictureType = pt;
resultSkipped = i; // will drop everything before this position
-SetBrokenLink(data + i, l);
synced = true;
+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)
@@ -2080,12 +2083,13 @@ uchar *cRemux::Get(int Count, uchar *Pi
l = GetPacketLength(data, resultCount, i);
if (l 0)
return resultData;
- if (isRadio) {
+ if (isRadio || !synced syncEarly) {
if (!synced) {
- if (PictureType)
+ if (PictureType isRadio)
*PictureType = I_FRAME;
resultSkipped = i; // will drop everything before this position
synced = true;
+if (!isRadio) fprintf(stderr, audio: synced early\n);
}
else if (Count)
return resultData;
diff -Nurp ../vdr-1.4.6-1-orig/remux.h ./remux.h
--- ../vdr-1.4.6-1-orig/remux.h 2006-03-25 13:27:30.0 +0100
+++ ./remux.h 2007-05-06 21:22:52.0 +0200
@@ -40,6 +40,7 @@ private:
bool isRadio;
int numUPTerrors;
bool synced;
+ bool syncEarly;
int skipped;
cTS2PES *ts2pes[MAXTRACKS];
int numTracks;
@@ -47,12 +48,13 @@ private:
int resultSkipped;
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 =