Fixed replaying recordings of radio channels with many audio tracks

This commit is contained in:
Klaus Schmidinger 2006-02-19 14:23:17 +01:00
parent 8409c68e44
commit 8186544e10
3 changed files with 27 additions and 3 deletions

View File

@ -1058,6 +1058,7 @@ Reinhard Nissl <rnissl@gmx.de>
for fixing handling TS packets in cTS2PES for fixing handling TS packets in cTS2PES
for adding a mutex to synchronize cDevice::PlayPesPacket() and SetCurrentAudioTrack() for adding a mutex to synchronize cDevice::PlayPesPacket() and SetCurrentAudioTrack()
for a suggestion that lead to implementing cDevice::Transferring() for a suggestion that lead to implementing cDevice::Transferring()
for fixing replaying recordings of radio channels with many audio tracks
Richard Robson <richard_robson@beeb.net> Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the for reporting freezing replay if a timer starts while in Transfer Mode from the

View File

@ -4355,3 +4355,5 @@ Video Disk Recorder Revision History
information than the EPG's component data, the code from the channel is taken. information than the EPG's component data, the code from the channel is taken.
- Fixed handling DPID when deciding whether to switch to 'Transfer Mode' (thanks - Fixed handling DPID when deciding whether to switch to 'Transfer Mode' (thanks
to Marco Schlüßler). to Marco Schlüßler).
- Fixed replaying recordings of radio channels with many audio tracks (thanks to
Reinhard Nissl).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbplayer.c 1.42 2006/01/08 11:39:41 kls Exp $ * $Id: dvbplayer.c 1.43 2006/02/19 14:20:15 kls Exp $
*/ */
#include "dvbplayer.h" #include "dvbplayer.h"
@ -80,6 +80,8 @@ private:
int length; int length;
bool hasData; bool hasData;
cCondWait newSet; cCondWait newSet;
cCondVar newDataCond;
cMutex newDataMutex;
protected: protected:
void Action(void); void Action(void);
public: public:
@ -88,6 +90,7 @@ public:
void Clear(void); void Clear(void);
int Read(cUnbufferedFile *File, uchar *Buffer, int Length); int Read(cUnbufferedFile *File, uchar *Buffer, int Length);
bool Reading(void) { return buffer; } bool Reading(void) { return buffer; }
bool WaitForDataMs(int msToWait);
}; };
cNonBlockingFileReader::cNonBlockingFileReader(void) cNonBlockingFileReader::cNonBlockingFileReader(void)
@ -150,8 +153,11 @@ void cNonBlockingFileReader::Action(void)
int r = f->Read(buffer + length, wanted - length); int r = f->Read(buffer + length, wanted - length);
if (r >= 0) { if (r >= 0) {
length += r; length += r;
if (!r || length == wanted) // r == 0 means EOF if (!r || length == wanted) { // r == 0 means EOF
cMutexLock NewDataLock(&newDataMutex);
hasData = true; hasData = true;
newDataCond.Broadcast();
}
} }
else if (r < 0 && FATALERRNO) { else if (r < 0 && FATALERRNO) {
LOG_ERROR; LOG_ERROR;
@ -164,6 +170,14 @@ void cNonBlockingFileReader::Action(void)
} }
} }
bool cNonBlockingFileReader::WaitForDataMs(int msToWait)
{
cMutexLock NewDataLock(&newDataMutex);
if (hasData)
return true;
return newDataCond.TimedWait(newDataMutex, msToWait);
}
// --- cDvbPlayer ------------------------------------------------------------ // --- cDvbPlayer ------------------------------------------------------------
#define PLAYERBUFSIZE MEGABYTE(1) #define PLAYERBUFSIZE MEGABYTE(1)
@ -362,10 +376,14 @@ void cDvbPlayer::Action(void)
nonBlockingFileReader = new cNonBlockingFileReader; nonBlockingFileReader = new cNonBlockingFileReader;
int Length = 0; int Length = 0;
bool Sleep = false; bool Sleep = false;
bool WaitingForData = false;
while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) { while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
if (Sleep) { if (Sleep) {
cCondWait::SleepMs(3); // this keeps the CPU load low if (WaitingForData)
nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
else
cCondWait::SleepMs(3); // this keeps the CPU load low
Sleep = false; Sleep = false;
} }
cPoller Poller; cPoller Poller;
@ -423,11 +441,14 @@ void cDvbPlayer::Action(void)
} }
int r = nonBlockingFileReader->Read(replayFile, b, Length); int r = nonBlockingFileReader->Read(replayFile, b, Length);
if (r > 0) { if (r > 0) {
WaitingForData = false;
readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
b = NULL; b = NULL;
} }
else if (r == 0) else if (r == 0)
eof = true; eof = true;
else if (r < 0 && errno == EAGAIN)
WaitingForData = true;
else if (r < 0 && FATALERRNO) { else if (r < 0 && FATALERRNO) {
LOG_ERROR; LOG_ERROR;
break; break;