From patchwork Mon May 14 22:49:56 2007 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: VDRU VDRU X-Patchwork-Id: 12464 Received: from wx-out-0506.google.com ([66.249.82.226]) by www.linuxtv.org with esmtp (Exim 4.50) id 1HnjMc-0005Xr-Cf for vdr@linuxtv.org; Tue, 15 May 2007 00:49:58 +0200 Received: by wx-out-0506.google.com with SMTP id i29so1811796wxd for ; Mon, 14 May 2007 15:49:56 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=hBqGIxhRLU4yXIoP0isPI9/o7gvUpsjd503bCTwqpfA1+7OAxA8NxiIGeWBjwvJTfpOKJxgmtmegFjzNCXNQUxiaail1QNLRQPnD4aPVJuQ2cy7qsZnwdgooJee6kmkHQy1SvADgO65k3e1CGvI3mIlklft6xmHBfAEWgCLQZ9w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=nxMhBaWMDSUpQizYHjs3+zqwD7YUIk3Lhm95ZYxKusKSos7qHH3MPduPpVdzTF14IkevQDWjoQlfhmHHJrVBOOvRIWw7xsj3zdS1igH0QEi+oXEp2ipdTjfhgPqbFcISda6YNbUSwadED1CLZME7QuffKGEOKZTV9MO4dzop3hE= Received: by 10.90.102.20 with SMTP id z20mr5601896agb.1179182996179; Mon, 14 May 2007 15:49:56 -0700 (PDT) Received: by 10.90.31.16 with HTTP; Mon, 14 May 2007 15:49:56 -0700 (PDT) Message-ID: Date: Mon, 14 May 2007 15:49:56 -0700 From: "VDR User" To: "VDR Mailing List" Subject: Re: [vdr] [PATCH] Auto sized ringbuffers v3 In-Reply-To: MIME-Version: 1.0 References: <46477132.9080503@o2.pl> X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 May 2007 22:49:58 -0000 Status: O X-Status: X-Keywords: X-UID: 12902 In case anyone is having trouble, here's an attached patch of v3 for vdr-1.5.2. diff -ruN vdr-1.5.2-orig/dvbdevice.c vdr-1.5.2/dvbdevice.c --- vdr-1.5.2-orig/dvbdevice.c 2007-05-14 14:58:29.000000000 -0700 +++ vdr-1.5.2/dvbdevice.c 2007-05-14 15:22:50.000000000 -0700 @@ -1172,7 +1172,7 @@ CloseDvr(); fd_dvr = DvbOpen(DEV_DVB_DVR, CardIndex(), O_RDONLY | O_NONBLOCK, true); if (fd_dvr >= 0) - tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1); + tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(8), CardIndex() + 1); return fd_dvr >= 0; } diff -ruN vdr-1.5.2-orig/recorder.c vdr-1.5.2/recorder.c --- vdr-1.5.2-orig/recorder.c 2007-05-14 14:58:29.000000000 -0700 +++ vdr-1.5.2/recorder.c 2007-05-14 15:27:12.000000000 -0700 @@ -176,8 +176,22 @@ int Count = remux->Put(b, r); if (Count) ringBuffer->Del(Count); - else - cCondWait::SleepMs(100); // avoid busy loop when resultBuffer is full in cRemux::Put() - } + else { // avoid busy loop when resultBuffer is full in cRemux::Put() + int ms; + for (ms=5; Running() && ms<100; ms+=ms) { + cCondWait::SleepMs(ms); + if (!Running()) + return; + Count = remux->Put(b, r); + if (Count) { + ringBuffer->Del(Count); + dsyslog("cRecorder::Action() ring buffer consumer slept %d ms", ms); + break; + } + } + if (ms>=100) + dsyslog("cRecorder::Action() ring buffer consumer slept >100 ms"); + } + } } } diff -ruN vdr-1.5.2-orig/remux.c vdr-1.5.2/remux.c --- vdr-1.5.2-orig/remux.c 2007-05-14 14:58:29.000000000 -0700 +++ vdr-1.5.2/remux.c 2007-05-14 15:27:45.000000000 -0700 @@ -1851,7 +1851,7 @@ // --- cRemux ---------------------------------------------------------------- -#define RESULTBUFFERSIZE KILOBYTE(256) +#define RESULTBUFFERSIZE MEGABYTE(2) cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) { diff -ruN vdr-1.5.2-orig/ringbuffer.c vdr-1.5.2/ringbuffer.c --- vdr-1.5.2-orig/ringbuffer.c 2007-05-14 14:58:29.000000000 -0700 +++ vdr-1.5.2/ringbuffer.c 2007-05-14 15:33:18.000000000 -0700 @@ -151,13 +151,31 @@ } #endif +// cRingBufferLinear are dynamically sized, or at least we can pretend they are ;) +// We treat 'Size' as the maximum size, but start with a small buffer, which can +// grow later as it fills up. Memory is always allocated for the full buffer, but +// the unused RAM portion remains untouched until (if at all) it is actually needed. +// Note that we can not start with a larger than requested buffer because there are +// ring buffer users that cause crashes then (eg softdevice mpegdecoder absolutely +// needs 32/64k). + +// Startup size. 64k still causes overflows before buffer starts to grow, 128k doesn't. +// The buffers grow to 200..500k anyway, so maybe increasing this a bit more would +// make sense, but let's first see if it's really needed. +// In fact 128k is on the low side, but let's try not going for 256k yet. +#define DEFRBSIZE KILOBYTE(192) + cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics, const char *Description) -:cRingBuffer(Size, Statistics) +:cRingBuffer(min(Size,DEFRBSIZE), Statistics) { description = Description ? strdup(Description) : NULL; tail = head = margin = Margin; gotten = 0; buffer = NULL; + maxsize = Size; + growthresh = size 1) { // 'Size - 1' must not be 0! if (Margin <= Size / 2) { buffer = MALLOC(uchar, Size); @@ -183,6 +201,7 @@ #ifdef DEBUGRINGBUFFERS DelDebugRBL(this); #endif + dsyslog("Deleting ring buffer \"%s\" size: %d / %d (used %g%% of requested size)", description, size, maxsize, size/(double)maxsize*100.0 ); free(buffer); free(description); } @@ -205,8 +224,20 @@ EnablePut(); } +// Must only be called by the producer (ie Read()/Put()), not the consumer (Get()). +void cRingBufferLinear::GrowBuffer(void) +{ + size = min(size+size/2, maxsize); + growthresh = size=tail && size 0) ? diff - 1 : Size() - head; @@ -219,6 +250,10 @@ Count = safe_read(FileHandle, buffer + head, free); if (Count > 0) { int Head = head + Count; + if (Available()+Count >= growthresh) + growbuf = 2; + if (growbuf && head>=tail && size= Size()) Head = margin; head = Head; @@ -245,6 +280,10 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) { if (Count > 0) { + if (Available()+Count >= growthresh) + growbuf = 3; + if (growbuf && head>=tail && size