@@ -735,7 +735,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
@@ -2166,14 +2166,15 @@ 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)
{
h264 = VPID_IS_H264(VPid);
VPid = VPID_FROM_ANY(VPid);
exitOnFailure = ExitOnFailure;
isRadio = VPid == 0 || VPid == 1 || VPid == 0x1FFF;
numUPTerrors = 0;
synced = false;
+ syncEarly = SyncEarly;
skipped = 0;
numTracks = 0;
resultSkipped = 0;
@@ -2438,12 +2439,14 @@ uchar *cRemux::Get(int &Count, uchar *Pi
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
- 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)
@@ -2456,12 +2459,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;
@@ -41,6 +41,7 @@ private:
bool h264;
int numUPTerrors;
bool synced;
+ bool syncEarly;
int skipped;
cTS2PES *ts2pes[MAXTRACKS];
int numTracks;
@@ -49,12 +50,13 @@ private:
int GetPid(const uchar *Data);
int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
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.
+ ///< 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
@@ -19,7 +19,7 @@ cTransfer::cTransfer(tChannelID ChannelI
,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, true);
}
cTransfer::~cTransfer()