Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] workaround for ring buffer overflow
Hi,
as i'm also harmed by these bloody ring buffer overflows, especailly when
doing multiple recordings on my single-card system, i've tried to find a way
to let my vdr run more stable under these conditions. Adding some more
logging output shows me, that these errors could be detected in the 'Action'
function of cTransfer: if the driver has a problem, the call to DevicePoll
returns with 0 and errno also 0, which means there was a timeout. Counting
consecutive poll-timeouts and doing a DeviceClear after some consecutive
timeouts helps the driver to switch back to a usable state. In the last
resort, there will be initiated an emergency exit on more consecutive
timeouts (never happend on my system).
The number of consecutive timeouts could be adjusted by changing the value of
the define of POLLTIMEOUTS_BEFORE_DEVICECLEAR, the emergency exit is
initiated by detecting twice of POLLTIMEOUTS_BEFORE_DEVICECLEAR timeouts. To
avoid the emergency exit, just comment out the line with the define of
EMERGENCY_EXIT_ON_CONSECUTIVE_POLLTIMEOUTS in transfer.c.
With this patch, i can do up to three recordings on different channels and
switch between them without any problem.
Greetings
--- vdr-1.2.1/transfer.c 2003-06-14 10:40:43.000000000 +0200
+++ vdr-1.2.1patch/transfer.c 2003-06-26 22:04:20.000000000 +0200
@@ -13,6 +13,8 @@
// The size of the array used to buffer video data:
// (must be larger than MINVIDEODATA - see remux.h)
#define VIDEOBUFSIZE MEGABYTE(1)
+#define POLLTIMEOUTS_BEFORE_DEVICECLEAR 3
+#define EMERGENCY_EXIT_ON_CONSECUTIVE_POLLTIMEOUTS
// --- cTransfer -------------------------------------------------------------
@@ -53,7 +55,7 @@
int i = 0;
while (active && Length > 0) {
if (i++ > 10) {
- esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length);
+ esyslog("ERROR: ring buffer overflow in cTransfer (%d bytes dropped)", Length);
break;
}
int p = ringBuffer->Put(Data, Length);
@@ -68,6 +70,7 @@
dsyslog("transfer thread started (pid=%d)", getpid());
active = true;
+ int iPollErr = 0;
while (active) {
//XXX+ Maybe we need this to avoid buffer underruns in driver.
@@ -99,6 +102,7 @@
while (Result > 0 && active) {
cPoller Poller;
if (DevicePoll(Poller, 100)) {
+ iPollErr = 0;
int w = PlayVideo(p, Result);
if (w > 0) {
p += w;
@@ -109,6 +113,20 @@
break;
}
}
+ else {
+ iPollErr++;
+ if( iPollErr == POLLTIMEOUTS_BEFORE_DEVICECLEAR ) {
+ dsyslog("clear device because of consecutive poll-errors");
+ DeviceClear();
+ }
+ #ifdef EMERGENCY_EXIT_ON_CONSECUTIVE_POLLERRORS
+ if( iPollErr == POLLTIMEOUTS_BEFORE_DEVICECLEAR*2 ) {
+ dsyslog("more consecutive poll-errors");
+ cThread::EmergencyExit(true);
+ }
+ #endif
+ }
+
}
}
}
Home |
Main Index |
Thread Index