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:
parent
81cc592c33
commit
e92739086e
78
dvbplayer.c
78
dvbplayer.c
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user