diff options
Diffstat (limited to 'transfer.c')
-rw-r--r-- | transfer.c | 95 |
1 files changed, 19 insertions, 76 deletions
@@ -4,109 +4,52 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: transfer.c 1.34 2007/01/07 14:45:28 kls Exp $ + * $Id: transfer.c 2.1 2008/08/15 14:32:12 kls Exp $ */ #include "transfer.h" -#define TRANSFERBUFSIZE MEGABYTE(2) -#define POLLTIMEOUTS_BEFORE_DEVICECLEAR 6 - // --- cTransfer ------------------------------------------------------------- cTransfer::cTransfer(tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids) :cReceiver(ChannelID, -1, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) -,cThread("transfer") { - ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); + patPmtGenerator.GeneratePmt(ChannelID); } cTransfer::~cTransfer() { cReceiver::Detach(); cPlayer::Detach(); - delete remux; - delete ringBuffer; } void cTransfer::Activate(bool On) { - if (On) - Start(); - else { - Cancel(3); - cPlayer::Detach(); + if (On) { + PlayTs(patPmtGenerator.GetPat(), TS_SIZE); + int Index = 0; + while (uchar *pmt = patPmtGenerator.GetPmt(Index)) + PlayTs(pmt, TS_SIZE); } } void cTransfer::Receive(uchar *Data, int Length) { - if (cPlayer::IsAttached() && Running()) { - int p = ringBuffer->Put(Data, Length); - if (p != Length && Running()) - ringBuffer->ReportOverflow(Length - p); + if (cPlayer::IsAttached()) { + // Transfer Mode means "live tv", so there's no point in doing any additional + // buffering here. The TS packets *must* get through here! However, every + // now and then there may be conditions where the packet just can't be + // handled when offered the first time, so that's why we try several times: + for (int i = 0; i < 100; i++) { + if (PlayTs(Data, Length) > 0) + return; + fprintf(stderr, "-");//XXX just for testing - remove when stable + cCondWait::SleepMs(10); + } + esyslog("ERROR: TS packet not accepted in Transfer Mode"); } } -void cTransfer::Action(void) -{ - int PollTimeouts = 0; - uchar *p = NULL; - int Result = 0; - while (Running()) { - int Count; - uchar *b = ringBuffer->Get(Count); - if (b) { - if (ringBuffer->Available() > TRANSFERBUFSIZE * 9 / 10) { - // If the buffer runs full, we have no chance of ever catching up - // since the data comes in at the same rate as it goes out (it's "live"). - // So let's clear the buffer instead of suffering from permanent - // overflows. - dsyslog("clearing transfer buffer to avoid overflows"); - DeviceClear(); - ringBuffer->Clear(); - remux->Clear(); - PlayPes(NULL, 0); - p = NULL; - continue; - } - Count = remux->Put(b, Count); - if (Count) - ringBuffer->Del(Count); - } - if (!p) - p = remux->Get(Result); - if (p) { - cPoller Poller; - if (DevicePoll(Poller, 100)) { - PollTimeouts = 0; - int w = PlayPes(p, Result); - if (w > 0) { - p += w; - Result -= w; - remux->Del(w); - if (Result <= 0) - p = NULL; - } - else if (w < 0 && FATALERRNO) - LOG_ERROR; - } - else { - PollTimeouts++; - if (PollTimeouts == POLLTIMEOUTS_BEFORE_DEVICECLEAR) { - dsyslog("clearing device because of consecutive poll timeouts"); - DeviceClear(); - ringBuffer->Clear(); - remux->Clear(); - PlayPes(NULL, 0); - p = NULL; - } - } - } - } -} - // --- cTransferControl ------------------------------------------------------ cDevice *cTransferControl::receiverDevice = NULL; |