diff options
Diffstat (limited to 'dvbplayer.c')
-rw-r--r-- | dvbplayer.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/dvbplayer.c b/dvbplayer.c index 017df6d..b0adac4 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 2.21 2010/03/07 14:24:26 kls Exp $ + * $Id: dvbplayer.c 2.23 2012/02/19 10:48:02 kls Exp $ */ #include "dvbplayer.h" @@ -87,6 +87,7 @@ class cNonBlockingFileReader : public cThread { private: cUnbufferedFile *f; uchar *buffer; + uchar *result; int wanted; int length; cCondWait newSet; @@ -100,7 +101,7 @@ public: void Clear(void); void Request(cUnbufferedFile *File, int Length); int Result(uchar **Buffer); - bool Reading(void) { return buffer; } + bool Reading(void) { return result; } bool WaitForDataMs(int msToWait); }; @@ -109,6 +110,7 @@ cNonBlockingFileReader::cNonBlockingFileReader(void) { f = NULL; buffer = NULL; + result = NULL; wanted = length = 0; Start(); } @@ -118,6 +120,7 @@ cNonBlockingFileReader::~cNonBlockingFileReader() newSet.Signal(); Cancel(3); free(buffer); + free(result); } void cNonBlockingFileReader::Clear(void) @@ -126,6 +129,8 @@ void cNonBlockingFileReader::Clear(void) f = NULL; free(buffer); buffer = NULL; + free(result); + result = NULL; wanted = length = 0; Unlock(); } @@ -137,18 +142,18 @@ void cNonBlockingFileReader::Request(cUnbufferedFile *File, int Length) wanted = Length; buffer = MALLOC(uchar, wanted); f = File; - Unlock(); newSet.Signal(); + Unlock(); } int cNonBlockingFileReader::Result(uchar **Buffer) { LOCK_THREAD; - if (buffer && length == wanted) { - *Buffer = buffer; - buffer = NULL; + if (result && length == wanted) { + *Buffer = result; + result = NULL; return wanted; - } + } errno = EAGAIN; return -1; } @@ -172,6 +177,8 @@ void cNonBlockingFileReader::Action(void) length = wanted = r; // this will forward the error status to the caller } if (length == wanted) { + result = buffer; + buffer = NULL; cMutexLock NewDataLock(&newDataMutex); newDataCond.Broadcast(); } @@ -183,9 +190,9 @@ void cNonBlockingFileReader::Action(void) bool cNonBlockingFileReader::WaitForDataMs(int msToWait) { - cMutexLock NewDataLock(&newDataMutex); - if (buffer && length == wanted) + if (result && length == wanted) return true; + cMutexLock NewDataLock(&newDataMutex); return newDataCond.TimedWait(newDataMutex, msToWait); } @@ -209,6 +216,7 @@ private: cUnbufferedFile *replayFile; double framesPerSecond; bool isPesRecording; + bool pauseLive; bool eof; bool firstPacket; ePlayModes playMode; @@ -228,7 +236,7 @@ protected: virtual void Activate(bool On); virtual void Action(void); public: - cDvbPlayer(const char *FileName); + cDvbPlayer(const char *FileName, bool PauseLive); virtual ~cDvbPlayer(); bool Active(void) { return cThread::Running(); } void Pause(void); @@ -249,7 +257,7 @@ public: #define SPEED_MULT 12 // the speed multiplier int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 }; -cDvbPlayer::cDvbPlayer(const char *FileName) +cDvbPlayer::cDvbPlayer(const char *FileName, bool PauseLive) :cThread("dvbplayer") { nonBlockingFileReader = NULL; @@ -258,6 +266,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName) cRecording Recording(FileName); framesPerSecond = Recording.FramesPerSecond(); isPesRecording = Recording.IsPesRecording(); + pauseLive = PauseLive; eof = false; firstPacket = true; playMode = pmPlay; @@ -275,7 +284,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName) return; ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE); // Create the index file: - index = new cIndexFile(FileName, false, isPesRecording); + index = new cIndexFile(FileName, false, isPesRecording, pauseLive); if (!index) esyslog("ERROR: can't allocate index"); else if (!index->Ok()) { @@ -400,15 +409,17 @@ void cDvbPlayer::Action(void) int LastReadIFrame = -1; int SwitchToPlayFrame = 0; + if (pauseLive) + Goto(0, true); while (Running()) { if (WaitingForData) - nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data + nonBlockingFileReader->WaitForDataMs(10); // this keeps the CPU load low, but reacts immediately on new data else if (Sleep) { cPoller Poller; DevicePoll(Poller, 10); Sleep = false; - if (playMode == pmStill || playMode==pmPause) - cCondWait::SleepMs(3); + if (playMode == pmStill || playMode == pmPause) + cCondWait::SleepMs(10); } { LOCK_THREAD; @@ -470,7 +481,15 @@ void cDvbPlayer::Action(void) } if (!eof) { uchar *b = NULL; - int r = nonBlockingFileReader->Result(&b); + int Retries = 5; + int r; + while (true) { + r = nonBlockingFileReader->Result(&b); + if (r == -1 && errno == EAGAIN && --Retries) + nonBlockingFileReader->WaitForDataMs(10); + else + break; + } if (r > 0) { WaitingForData = false; uint32_t Pts = 0; @@ -821,8 +840,8 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed) // --- cDvbPlayerControl ----------------------------------------------------- -cDvbPlayerControl::cDvbPlayerControl(const char *FileName) -:cControl(player = new cDvbPlayer(FileName)) +cDvbPlayerControl::cDvbPlayerControl(const char *FileName, bool PauseLive) +:cControl(player = new cDvbPlayer(FileName, PauseLive)) { } |