summaryrefslogtreecommitdiff
path: root/device.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2004-10-16 09:36:28 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2004-10-16 09:36:28 +0200
commit6415cc900de3361925d22f879077be687fce3858 (patch)
tree98ab10cda016e125e33966e371ccfe01e5fd9bd1 /device.c
parent15030f6acece1060f9736f875fe3abbcf9392263 (diff)
downloadvdr-6415cc900de3361925d22f879077be687fce3858.tar.gz
vdr-6415cc900de3361925d22f879077be687fce3858.tar.bz2
Improved buffer handling
Diffstat (limited to 'device.c')
-rw-r--r--device.c104
1 files changed, 46 insertions, 58 deletions
diff --git a/device.c b/device.c
index d62b4563..1813df8a 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.56 2004/06/19 08:51:05 kls Exp $
+ * $Id: device.c 1.57 2004/10/09 12:53:02 kls Exp $
*/
#include "device.h"
@@ -801,79 +801,67 @@ void cDevice::Detach(cReceiver *Receiver)
cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
{
+ SetDescription("TS buffer on device %d", CardIndex);
f = File;
- size = Size / TS_SIZE * TS_SIZE;
cardIndex = CardIndex;
- tsRead = tsWrite = 0;
- buf = (f >= 0 && size >= TS_SIZE) ? MALLOC(uchar, size + TS_SIZE) : NULL;
- // the '+ TS_SIZE' allocates some extra space for handling packets that got split by a buffer roll-over
- firstRead = true;
+ active = false;
+ delivered = false;
+ ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
+ ringBuffer->SetTimeouts(100, 100);
+ Start();
}
cTSBuffer::~cTSBuffer()
{
- free(buf);
-}
-
-int cTSBuffer::Read(void)
-{
- if (buf) {
- cPoller Poller(f, false);
- bool repeat;
- int total = 0;
- do {
- repeat = false;
- if (firstRead || Used() > TS_SIZE || Poller.Poll(100)) { // only wait if there's not enough data in the buffer
- firstRead = false;
- if (tsRead == tsWrite)
- tsRead = tsWrite = 0; // keep the maximum buffer space available
- if (tsWrite >= size && tsRead > 0)
- tsWrite = 0;
- int free = tsRead <= tsWrite ? size - tsWrite : tsRead - tsWrite - 1;
- if (free > 0) {
- int r = read(f, buf + tsWrite, free);
- if (r > 0) {
- total += r;
- tsWrite += r;
- if (tsWrite >= size && tsRead > 0) {
- tsWrite = 0;
- repeat = true; // read again after a boundary roll-over
- }
- }
- }
- }
- } while (repeat);
- return total;
+ active = false;
+ Cancel(3);
+ delete ringBuffer;
+}
+
+void cTSBuffer::Action(void)
+{
+ if (ringBuffer) {
+ bool firstRead = true;
+ cPoller Poller(f);
+ active = true;
+ for (; active;) {
+ if (firstRead || Poller.Poll(100)) {
+ firstRead = false;
+ int r = ringBuffer->Read(f);
+ if (r < 0 && FATALERRNO) {
+ if (errno == EOVERFLOW)
+ esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
+ else {
+ LOG_ERROR;
+ break;
+ }
+ }
+ }
+ }
}
- return -1;
}
uchar *cTSBuffer::Get(void)
{
- if (Used() >= TS_SIZE) {
- uchar *p = buf + tsRead;
+ int Count = 0;
+ if (delivered) {
+ ringBuffer->Del(TS_SIZE);
+ delivered = false;
+ }
+ uchar *p = ringBuffer->Get(Count);
+ if (p && Count >= TS_SIZE) {
if (*p != TS_SYNC_BYTE) {
- esyslog("ERROR: not sync'ed to TS packet on device %d", cardIndex);
- int tsMax = tsRead < tsWrite ? tsWrite : size;
- for (int i = tsRead; i < tsMax; i++) {
- if (buf[i] == TS_SYNC_BYTE) {
- esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", i - tsRead, cardIndex);
- tsRead = i;
- return NULL;
+ for (int i = 1; i < Count; i++) {
+ if (p[i] == TS_SYNC_BYTE) {
+ Count = i;
+ break;
}
}
- if ((tsRead = tsMax) >= size)
- tsRead = 0;
+ ringBuffer->Del(Count);
+ esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, cardIndex);
return NULL;
}
- if (tsRead + TS_SIZE > size) {
- // the packet rolled over the buffer boundary, so let's fetch the rest from the beginning (which MUST be there, since Used() >= TS_SIZE)
- int rest = TS_SIZE - (size - tsRead);
- memcpy(buf + size, buf, rest);
- tsRead = rest;
- }
- else if ((tsRead += TS_SIZE) >= size)
- tsRead = 0;
+ delivered = true;
return p;
}
return NULL;