1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Moved buffer handling into cNonBlockingFileReader

This commit is contained in:
Klaus Schmidinger 2009-05-31 14:12:42 +02:00
parent 81cc592c33
commit e92739086e

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 2.16 2009/05/31 09:59:43 kls Exp $ * $Id: dvbplayer.c 2.17 2009/05/31 14:12:42 kls Exp $
*/ */
#include "dvbplayer.h" #include "dvbplayer.h"
@ -89,7 +89,6 @@ private:
uchar *buffer; uchar *buffer;
int wanted; int wanted;
int length; int length;
bool hasData;
cCondWait newSet; cCondWait newSet;
cCondVar newDataCond; cCondVar newDataCond;
cMutex newDataMutex; cMutex newDataMutex;
@ -99,7 +98,8 @@ public:
cNonBlockingFileReader(void); cNonBlockingFileReader(void);
~cNonBlockingFileReader(); ~cNonBlockingFileReader();
void Clear(void); void Clear(void);
int Read(cUnbufferedFile *File, uchar *Buffer, int Length); void Request(cUnbufferedFile *File, int Length);
int Result(uchar **Buffer);
bool Reading(void) { return buffer; } bool Reading(void) { return buffer; }
bool WaitForDataMs(int msToWait); bool WaitForDataMs(int msToWait);
}; };
@ -110,7 +110,6 @@ cNonBlockingFileReader::cNonBlockingFileReader(void)
f = NULL; f = NULL;
buffer = NULL; buffer = NULL;
wanted = length = 0; wanted = length = 0;
hasData = false;
Start(); Start();
} }
@ -128,29 +127,27 @@ void cNonBlockingFileReader::Clear(void)
free(buffer); free(buffer);
buffer = NULL; buffer = NULL;
wanted = length = 0; wanted = length = 0;
hasData = false; Unlock();
}
void cNonBlockingFileReader::Request(cUnbufferedFile *File, int Length)
{
Lock();
Clear();
wanted = Length;
buffer = MALLOC(uchar, wanted);
f = File;
Unlock(); Unlock();
newSet.Signal(); newSet.Signal();
} }
int cNonBlockingFileReader::Read(cUnbufferedFile *File, uchar *Buffer, int Length) int cNonBlockingFileReader::Result(uchar **Buffer)
{ {
if (hasData && buffer) { LOCK_THREAD;
if (buffer != Buffer) { if (buffer && length == wanted) {
esyslog("ERROR: cNonBlockingFileReader::Read() called with different buffer!"); *Buffer = buffer;
errno = EINVAL;
return -1;
}
buffer = NULL; buffer = NULL;
return length; return wanted;
}
if (!buffer) {
f = File;
buffer = Buffer;
wanted = Length;
length = 0;
hasData = false;
newSet.Signal();
} }
errno = EAGAIN; errno = EAGAIN;
return -1; return -1;
@ -160,20 +157,23 @@ void cNonBlockingFileReader::Action(void)
{ {
while (Running()) { while (Running()) {
Lock(); Lock();
if (!hasData && f && buffer) { if (f && buffer && length < wanted) {
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 else if (r == 0) { // r == 0 means EOF
cMutexLock NewDataLock(&newDataMutex); if (length > 0)
hasData = true; wanted = length; // already read something, so return the rest
newDataCond.Broadcast(); else
} length = wanted = 0; // report EOF
} }
else if (r < 0 && FATALERRNO) { else if (FATALERRNO) {
LOG_ERROR; LOG_ERROR;
length = r; // this will forward the error status to the caller length = wanted = r; // this will forward the error status to the caller
hasData = true; }
if (length == wanted) {
cMutexLock NewDataLock(&newDataMutex);
newDataCond.Broadcast();
} }
} }
Unlock(); Unlock();
@ -184,7 +184,7 @@ void cNonBlockingFileReader::Action(void)
bool cNonBlockingFileReader::WaitForDataMs(int msToWait) bool cNonBlockingFileReader::WaitForDataMs(int msToWait)
{ {
cMutexLock NewDataLock(&newDataMutex); cMutexLock NewDataLock(&newDataMutex);
if (hasData) if (buffer && length == wanted)
return true; return true;
return newDataCond.TimedWait(newDataMutex, msToWait); return newDataCond.TimedWait(newDataMutex, msToWait);
} }
@ -381,7 +381,6 @@ void cDvbPlayer::Activate(bool On)
void cDvbPlayer::Action(void) void cDvbPlayer::Action(void)
{ {
uchar *b = NULL;
uchar *p = NULL; uchar *p = NULL;
int pc = 0; int pc = 0;
@ -461,12 +460,12 @@ void cDvbPlayer::Action(void)
esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE); esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE);
Length = MAXFRAMESIZE; Length = MAXFRAMESIZE;
} }
b = NULL; if (!eof)
nonBlockingFileReader->Request(replayFile, Length);
} }
if (!eof && Length > 0) { if (!eof) {
if (!b) uchar *b = NULL;
b = MALLOC(uchar, Length); int r = nonBlockingFileReader->Result(&b);
int r = nonBlockingFileReader->Read(replayFile, b, Length);
if (r > 0) { if (r > 0) {
WaitingForData = false; WaitingForData = false;
uint32_t Pts = 0; uint32_t Pts = 0;
@ -475,13 +474,10 @@ void cDvbPlayer::Action(void)
LastReadIFrame = readIndex; LastReadIFrame = readIndex;
} }
readFrame = new cFrame(b, -r, ftUnknown, readIndex, Pts); // hands over b to the ringBuffer readFrame = new cFrame(b, -r, ftUnknown, readIndex, Pts); // hands over b to the ringBuffer
b = NULL;
} }
else if (r < 0 && errno == EAGAIN) else if (r < 0 && errno == EAGAIN)
WaitingForData = true; WaitingForData = true;
else { else {
free(b);
b = NULL;
if (r == 0) if (r == 0)
eof = true; eof = true;
else if (r < 0 && FATALERRNO) { else if (r < 0 && FATALERRNO) {