summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS17
-rw-r--r--HISTORY25
-rw-r--r--MANUAL8
-rw-r--r--ca.conf2
-rw-r--r--channels.conf4
-rw-r--r--ci.c15
-rw-r--r--config.h4
-rw-r--r--dvbplayer.c199
-rw-r--r--eit.c23
-rw-r--r--eitscan.c60
-rw-r--r--i18n.c36
-rw-r--r--libdtv/liblx/Makefile4
-rw-r--r--libdtv/libvdr/Makefile3
-rw-r--r--menu.c12
-rw-r--r--menu.h3
-rw-r--r--menuitems.c56
-rw-r--r--menuitems.h13
-rw-r--r--recorder.c18
-rw-r--r--remux.c41
-rw-r--r--ringbuffer.c98
-rw-r--r--ringbuffer.h31
-rw-r--r--transfer.c19
-rw-r--r--vdr.c4
23 files changed, 490 insertions, 205 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 1454c7d..fad747b 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -305,7 +305,7 @@ Mirko Günther <mi.guenther@ib-helms.de>
Achim Lange <Achim_Lange@t-online.de>
for replacing 'killproc' with 'killall' in 'runvdr' to make it work on Debian
for reporting a bug in switching back the replay mode display in time shift mode
- for his help in keeping 'channels.conf.cable' up to date
+ for his help in keeping 'channels.conf.cable' and 'channels.conf' up to date
Klaus Wolf <klaus@wolfsoft.de>
for reporting a bug in restoring the CICAM values for a fourth DVB card
@@ -364,6 +364,7 @@ Simon Dean <linux-dvb@sickhack.com>
Dimitrios Dimitrakos <mail@dimitrios.de>
for translating OSD texts to the Greek language
+ for fixing handling the LOG_LOCALn parameters in the -l option
Marcus Kuba <marcus@kuba4u.de>
for reporting a bug in the unit of the "SVDRP timeout" setup parameter
@@ -457,6 +458,7 @@ Robert Schiele <rschiele@uni-mannheim.de>
for reporting some faulty default parameter initializations
for suggesting to only set the Makefile variables CXX and CXXFLAGS if they are not
yet defined
+ for fixing a problem with user defined CFLAGS in libdtv/libvdr/Makefile
Gerhard Steiner <steiner@mail.austria.com>
for suggesting that the SVDRP command PUTE shall trigger an immediate write of
@@ -502,6 +504,7 @@ Georg Hitsch <georg@hitsch.at>
Clemens Kirchgatterer <clemens@thf.ath.cx>
for suggesting to change source directory name for plugins from 'SRC' to 'src'
+ for reporting a problem with user defined CFLAGS in libdtv/libvdr/Makefile
Emil Naepflein <Emil.Naepflein@philosys.de>
for suggesting to take an active SVDRP connection into account when doing shutdown or
@@ -522,3 +525,15 @@ Jan Rieger <jan@ricomp.de>
Walter Stroebel <walter.stroebel@lifeline.nl>
for introducing "Doxygen" to document the VDR source code
+
+Paul Gohn <pgohn@nexgo.de>
+ for adding 'Hrvatska radiotelevizija' and 'RTV Slovenija' to ca.conf
+
+Teemu Rantanen <tvr@iki.fi>
+ for increased the maximum possible packet size in remux.c to avoid corrupted streams
+ with broadcasters that send extremely large PES packets
+ for adding TS error checking to remux.c
+ for pinpointing a problem with excessive memmove() calls in 'Transfer Mode'
+
+Jan Ekholm <chakie@infa.abo.fi>
+ for adding/improving some Swedish language OSD texts
diff --git a/HISTORY b/HISTORY
index e92eff1..9085936 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1916,3 +1916,28 @@ Video Disk Recorder Revision History
- Since several channels put very long strings into the Subtitle part of their
EPG data, that string is now limited in length when used in a recording's
file name.
+
+2003-01-26: Version 1.1.22
+
+- Added 'Hrvatska radiotelevizija' and 'RTV Slovenija' to ca.conf (thanks to
+ Paul Gohn).
+- Implemented actual user input for CAM enquiry menus.
+- Since disk file systems apparently don't honor the O_NONBLOCK flag to read from
+ a file in non-blocking mode the cDvbPlayer now uses a non blocking file reader
+ class to make sure replay remains smooth even under heavy system load.
+- Increased the maximum possible packet size in remux.c to avoid corrupted streams
+ with broadcasters that send extremely large PES packets (thanks to Teemu Rantanen).
+- Added TS error checking to remux.c (thanks to Teemu Rantanen).
+- Modified cRingBufferLinear to avoid excessive memmove() calls in 'Transfer Mode'
+ and during recordings, which dramatically reduces CPU load. Thanks to Teemu
+ Rantanen for pinpointing the problem with the excessive memmove() calls.
+- Updated 'channels.conf' (thanks to Achim Lange).
+- Added/improved Swedish language texts (thanks to Jan Ekholm).
+- Fixed the description of the "Scroll pages" OSD setup parameter ('yes' and 'no'
+ were mixed up).
+- Fixed handling the LOG_LOCALn parameters in the -l option (thanks to Dimitrios
+ Dimitrakos).
+- Changed EIT processing to always read a full section.
+- Fixed handling user defined CFLAGS in libdtv/libvdr/Makefile (thanks to Clemens
+ Kirchgatterer and Robert Schiele).
+- Fixed skipping unavailable channels in the EPG scanner.
diff --git a/MANUAL b/MANUAL
index 3c0504e..73a1b6e 100644
--- a/MANUAL
+++ b/MANUAL
@@ -23,6 +23,10 @@ Video Disk Recorder User's Manual
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing
+ In a numerical input field (like the response to a CAM enquiry) the keys 0..9
+ are used to enter the data, and the Left key can be used to delete the last
+ entered digit.
+
If your remote control provides additional keys, they can be used for the
following functions:
@@ -411,11 +415,11 @@ Video Disk Recorder User's Manual
always displayed when pressing the "Ok" button in
normal viewing mode.
- Scroll pages = yes yes = when pressing the "Down" ("Up") key while the cursor
+ Scroll pages = yes no = when pressing the "Down" ("Up") key while the cursor
is on the last (first) line of a list page, the
list is advanced by a full page and the cursor will
be at the top (bottom) of that page
- no = dto., but the cursor remains at the bottom (top) of
+ yes = dto., but the cursor remains at the bottom (top) of
the page (this mode allows for faster scrolling
through long lists).
diff --git a/ca.conf b/ca.conf
index 61f1189..fe3d758 100644
--- a/ca.conf
+++ b/ca.conf
@@ -29,6 +29,8 @@
402 NTV Plus
403 Viasat
404 Parabole Reunion
+405 Hrvatska radiotelevizija
+406 RTV Slovenija
# Viaccess 2
diff --git a/channels.conf b/channels.conf
index f01251e..8d7f567 100644
--- a/channels.conf
+++ b/channels.conf
@@ -54,7 +54,7 @@ Premiere 5:11797:h:S19.2E:27500:1279:1280:0:101:29:0:0:0
Premiere 6:11797:h:S19.2E:27500:1535:1536:0:101:41:0:0:0
Premiere 7:11797:h:S19.2E:27500:1023:1024:0:101:20:0:0:0
13th Street:11758:h:S19.2E:27500:2303:2304:0:101:42:0:0:0
-Studio Universal:11758:h:S19.2E:27500:2047:2048:0:101:36:0:0:0
+Studio Universal:12071:h:S19.2E:27500:2047:2048:0:101:36:0:0:0
Premiere Serie:12031:h:S19.2E:27500:1023:1024:0:101:16:0:0:0
Disney Channel:11758:h:S19.2E:27500:2559:2560:0:101:34:0:0:0
Premiere Nostalgie:12031:h:S19.2E:27500:2559:2560:0:101:516:0:0:0
@@ -77,7 +77,7 @@ Premiere Direkt 3B:11719:h:S19.2E:27500:1279:1280;1283:0:101:183:0:0:0
Premiere Direkt 4A:12031:h:S19.2E:27500:2815:2816:0:101:18:0:0:0
:#Premiere Direkt 4B:12070:h:S19.2E:27500:1535:1536:0:101:216:0:0:0
:PW Erotic
-Beate-Uhse.TV:11758:h:S19.2E:27500:1023:1024:0:101:21:0:0:0
+Beate-Uhse.TV:12071:h:S19.2E:27500:1023:1024:0:101:21:0:0:0
Premiere Erotik 1:12031:h:S19.2E:27500:1279:1280:0:101:513:0:0:0
Premiere Erotik 2:11719:h:S19.2E:27500:1535:1536:0:101:778:0:0:0
Premiere Erotik 3:11719:h:S19.2E:27500:1791:1792:0:101:779:0:0:0
diff --git a/ci.c b/ci.c
index d3812d6..61bc748 100644
--- a/ci.c
+++ b/ci.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ci.c 1.1 2003/01/06 13:56:17 kls Exp $
+ * $Id: ci.c 1.2 2003/01/11 11:15:19 kls Exp $
*/
/* XXX TODO
@@ -331,6 +331,7 @@ int cCiTransportConnection::RecvTPDU(void)
struct pollfd pfd[1];
pfd[0].fd = fd;
pfd[0].events = POLLIN;
+ lastResponse = ERROR;
if (poll(pfd, 1, 3500/*XXX*/) && (pfd[0].revents & POLLIN))//XXX
if (tpdu->Read(fd) == OK && tpdu->Tcid() == tcid) {
switch (state) {
@@ -338,7 +339,7 @@ int cCiTransportConnection::RecvTPDU(void)
case stCREATION: if (tpdu->Tag() == T_CTC_REPLY) {
dataAvailable = tpdu->Status() & DATA_INDICATOR;
state = stACTIVE;
- return tpdu->Tag();
+ lastResponse = tpdu->Tag();
}
break;
case stACTIVE: switch (tpdu->Tag()) {
@@ -353,17 +354,17 @@ int cCiTransportConnection::RecvTPDU(void)
default: return ERROR;
}
dataAvailable = tpdu->Status() & DATA_INDICATOR;
- return tpdu->Tag();
+ lastResponse = tpdu->Tag();
break;
case stDELETION: if (tpdu->Tag() == T_DTC_REPLY) {
Init(fd, slot, tcid);
//XXX Status()???
- return tpdu->Tag();
+ lastResponse = tpdu->Tag();
}
break;
}
}
- return ERROR;
+ return lastResponse;
}
int cCiTransportConnection::SendData(int Length, const uint8_t *Data)
@@ -413,7 +414,7 @@ int cCiTransportConnection::Poll(void)
{
if (state == stACTIVE) {
if (SendTPDU(T_DATA_LAST) == OK) {
- return lastResponse = RecvTPDU();
+ return RecvTPDU();
}
}
return ERROR;
@@ -644,7 +645,7 @@ int cCiSession::SendData(int Tag, int Length, const uint8_t *Data)
*p++ = (Tag >> 8) & 0xFF;
*p++ = Tag & 0xFF;
p = SetLength(p, Length);
- if (p - buffer + Length < sizeof(buffer)) {
+ if (p - buffer + Length < int(sizeof(buffer))) {
memcpy(p, Data, Length);
p += Length;
return tc->SendData(p - buffer, buffer);
diff --git a/config.h b/config.h
index 7cf7d91..83045ae 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.145 2002/12/22 15:29:45 kls Exp $
+ * $Id: config.h 1.146 2003/01/12 09:44:28 kls Exp $
*/
#ifndef __CONFIG_H
@@ -19,7 +19,7 @@
#include "device.h"
#include "tools.h"
-#define VDRVERSION "1.1.21"
+#define VDRVERSION "1.1.22"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/dvbplayer.c b/dvbplayer.c
index 2d9cc1c..1d140ea 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.c 1.16 2002/11/03 11:23:47 kls Exp $
+ * $Id: dvbplayer.c 1.17 2003/01/19 15:43:58 kls Exp $
*/
#include "dvbplayer.h"
@@ -69,6 +69,103 @@ int cBackTrace::Get(bool Forward)
return i;
}
+// --- cNonBlockingFileReader ------------------------------------------------
+
+class cNonBlockingFileReader : public cThread {
+private:
+ int f;
+ uchar *buffer;
+ int wanted;
+ int length;
+ bool hasData;
+ bool active;
+ cMutex mutex;
+ cCondVar newSet;
+protected:
+ void Action(void);
+public:
+ cNonBlockingFileReader(void);
+ ~cNonBlockingFileReader();
+ void Clear(void);
+ int Read(int FileHandle, uchar *Buffer, int Length);
+ bool Reading(void) { return buffer; }
+ };
+
+cNonBlockingFileReader::cNonBlockingFileReader(void)
+{
+ f = -1;
+ buffer = NULL;
+ wanted = length = 0;
+ hasData = false;
+ active = false;
+ Start();
+}
+
+cNonBlockingFileReader::~cNonBlockingFileReader()
+{
+ active = false;
+ newSet.Broadcast();
+ Cancel(3);
+ free(buffer);
+}
+
+void cNonBlockingFileReader::Clear(void)
+{
+ cMutexLock MutexLock(&mutex);
+ f = -1;
+ buffer = NULL;
+ wanted = length = 0;
+ hasData = false;
+ newSet.Broadcast();
+}
+
+int cNonBlockingFileReader::Read(int FileHandle, uchar *Buffer, int Length)
+{
+ if (hasData && buffer) {
+ if (buffer != Buffer) {
+ esyslog("ERROR: cNonBlockingFileReader::Read() called with different buffer!");
+ errno = EINVAL;
+ return -1;
+ }
+ buffer = NULL;
+ return length;
+ }
+ if (!buffer) {
+ f = FileHandle;
+ buffer = Buffer;
+ wanted = Length;
+ length = 0;
+ hasData = false;
+ newSet.Broadcast();
+ }
+ errno = EAGAIN;
+ return -1;
+}
+
+void cNonBlockingFileReader::Action(void)
+{
+ dsyslog("non blocking file reader thread started (pid=%d)", getpid());
+ active = true;
+ while (active) {
+ cMutexLock MutexLock(&mutex);
+ if (!hasData && f >= 0 && buffer) {
+ int r = safe_read(f, buffer + length, wanted - length);
+ if (r >= 0) {
+ length += r;
+ if (!r || length == wanted) // r == 0 means EOF
+ hasData = true;
+ }
+ else if (r < 0 && FATALERRNO) {
+ LOG_ERROR;
+ length = r; // this will forward the error status to the caller
+ hasData = true;
+ }
+ }
+ newSet.TimedWait(mutex, 1000);
+ }
+ dsyslog("non blocking file reader thread ended (pid=%d)", getpid());
+}
+
// --- cDvbPlayer ------------------------------------------------------------
//XXX+ also used in recorder.c - find a better place???
@@ -84,6 +181,7 @@ private:
enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
enum ePlayDirs { pdForward, pdBackward };
static int Speeds[];
+ cNonBlockingFileReader *nonBlockingFileReader;
cRingBufferFrame *ringBuffer;
cBackTrace *backTrace;
cFileName *fileName;
@@ -135,6 +233,7 @@ int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 };
cDvbPlayer::cDvbPlayer(const char *FileName)
{
+ nonBlockingFileReader = NULL;
ringBuffer = NULL;
backTrace = NULL;
index = NULL;
@@ -198,7 +297,9 @@ void cDvbPlayer::TrickSpeed(int Increment)
void cDvbPlayer::Empty(void)
{
- Lock();
+ LOCK_THREAD;
+ if (nonBlockingFileReader)
+ nonBlockingFileReader->Clear();
if ((readIndex = backTrace->Get(playDir == pdForward)) < 0)
readIndex = writeIndex;
readFrame = NULL;
@@ -206,7 +307,6 @@ void cDvbPlayer::Empty(void)
ringBuffer->Clear();
backTrace->Clear();
DeviceClear();
- Unlock();
}
void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
@@ -305,7 +405,7 @@ void cDvbPlayer::Action(void)
{
dsyslog("dvbplayer thread started (pid=%d)", getpid());
- uchar b[MAXFRAMESIZE];
+ uchar *b = NULL;
const uchar *p = NULL;
int pc = 0;
@@ -313,6 +413,10 @@ void cDvbPlayer::Action(void)
if (readIndex >= 0)
isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
+ nonBlockingFileReader = new cNonBlockingFileReader;
+ int Length = 0;
+ int AudioTrack = 0; // -1 = any, 0 = none, >0 = audioTrack
+
running = true;
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available())) {
cPoller Poller;
@@ -326,46 +430,59 @@ void cDvbPlayer::Action(void)
if (!readFrame && (replayFile >= 0 || readIndex >= 0)) {
if (playMode != pmStill) {
- int r = 0;
- if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
- uchar FileNumber;
- int FileOffset, Length;
- int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
- if (Index >= 0) {
- if (!NextFile(FileNumber, FileOffset))
+ if (!nonBlockingFileReader->Reading()) {
+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
+ uchar FileNumber;
+ int FileOffset;
+ int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
+ if (Index >= 0) {
+ if (!NextFile(FileNumber, FileOffset))
+ continue;
+ }
+ else {
+ // can't call Play() here, because those functions may only be
+ // called from the foreground thread - and we also don't need
+ // to empty the buffer here
+ DevicePlay();
+ playMode = pmPlay;
+ playDir = pdForward;
continue;
+ }
+ readIndex = Index;
+ AudioTrack = 0;
+ // must clear all audio packets because the buffer is not emptied
+ // when falling back from "fast forward" to "play" (see above)
}
- else {
- // can't call Play() here, because those functions may only be
- // called from the foreground thread - and we also don't need
- // to empty the buffer here
- DevicePlay();
- playMode = pmPlay;
- playDir = pdForward;
- continue;
+ else if (index) {
+ uchar FileNumber;
+ int FileOffset;
+ readIndex++;
+ if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
+ readIndex = -1;
+ eof = true;
+ continue;
+ }
+ AudioTrack = audioTrack;
}
- readIndex = Index;
- r = ReadFrame(replayFile, b, Length, sizeof(b));
- // must call StripAudioPackets() here because the buffer is not emptied
- // when falling back from "fast forward" to "play" (see above)
- StripAudioPackets(b, r);
- }
- else if (index) {
- uchar FileNumber;
- int FileOffset, Length;
- readIndex++;
- if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
- readIndex = -1;
- eof = true;
- continue;
+ else { // allows replay even if the index file is missing
+ Length = MAXFRAMESIZE;
+ AudioTrack = -1;
+ }
+ if (Length == -1)
+ Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
+ else if (Length > MAXFRAMESIZE) {
+ esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE);
+ Length = MAXFRAMESIZE;
}
- r = ReadFrame(replayFile, b, Length, sizeof(b));
- StripAudioPackets(b, r, audioTrack);
+ b = MALLOC(uchar, Length);
+ }
+ int r = nonBlockingFileReader->Read(replayFile, b, Length);
+ if (r > 0) {
+ if (AudioTrack >= 0)
+ StripAudioPackets(b, r, AudioTrack);
+ readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
+ b = NULL;
}
- else // allows replay even if the index file is missing
- r = read(replayFile, b, sizeof(b));
- if (r > 0)
- readFrame = new cFrame(b, r, ftUnknown, readIndex);
else if (r == 0)
eof = true;
else if (r < 0 && FATALERRNO) {
@@ -422,6 +539,10 @@ void cDvbPlayer::Action(void)
}
active = running = false;
+ cNonBlockingFileReader *nbfr = nonBlockingFileReader;
+ nonBlockingFileReader = NULL;
+ delete nbfr;
+
dsyslog("dvbplayer thread ended (pid=%d)", getpid());
}
diff --git a/eit.c b/eit.c
index e2e0fe7..174ad6d 100644
--- a/eit.c
+++ b/eit.c
@@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.c 1.63 2003/01/06 15:05:46 kls Exp $
+ * $Id: eit.c 1.64 2003/01/26 12:21:15 kls Exp $
***************************************************************************/
#include "eit.h"
@@ -1240,17 +1240,16 @@ void cSIProcessor::Action()
{
if (pfd[a].revents & POLLIN)
{
- /* read section */
- unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
- if (safe_read(filters[a].handle, buf, 3) == 3)
+ // read section
+ unsigned char buf[4096]; // max. allowed size for any EIT section
+ int r = safe_read(filters[a].handle, buf, sizeof(buf));
+ if (r > 3) // minimum number of bytes necessary to get section length
{
- int seclen = ((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF);
+ int seclen = ((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF) + 3;
int pid = filters[a].pid;
- int n = safe_read(filters[a].handle, buf + 3, seclen);
- if (n == seclen)
+ if (seclen == r)
{
- seclen += 3;
- //dsyslog("Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen);
+ //dsyslog("Received pid 0x%04X with table ID 0x%02X and length of %4d\n", pid, buf[0], seclen);
switch (pid)
{
case 0x00:
@@ -1335,10 +1334,10 @@ void cSIProcessor::Action()
break;
}
}
- /*XXX this just fills up the log file - shouldn't we rather try to re-sync?
+ /*
else
- dsyslog("read incomplete section - seclen = %d, n = %d", seclen, n);
- XXX*/
+ dsyslog("read incomplete section - seclen = %d, r = %d", seclen, r);
+ */
}
}
}
diff --git a/eitscan.c b/eitscan.c
index fdcd8c3..5768a42 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.10 2002/11/01 11:04:49 kls Exp $
+ * $Id: eitscan.c 1.11 2003/01/26 16:19:24 kls Exp $
*/
#include "eitscan.h"
@@ -51,38 +51,42 @@ void cEITScanner::Process(void)
if (Setup.EPGScanTimeout && Channels.MaxNumber() > 1) {
time_t now = time(NULL);
if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) {
- for (int i = 0; i < cDevice::NumDevices(); i++) {
- cDevice *Device = cDevice::GetDevice(i);
- if (Device && Device->CardIndex() < MAXDVBDEVICES) {
- if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
- if (!(Device->Receiving(true) || Device->Replaying())) {
- int oldCh = lastChannel;
- int ch = oldCh + 1;
- while (ch != oldCh) {
- if (ch > Channels.MaxNumber()) {
- ch = 1;
- numTransponders = 0;
- }
- cChannel *Channel = Channels.GetByNumber(ch, 1);
- if (Channel) {
- if (!Device->ProvidesChannel(Channel))
- break;
- if (Channel->Sid() && !TransponderScanned(Channel)) {
- if (Device == cDevice::PrimaryDevice() && !currentChannel)
- currentChannel = Device->CurrentChannel();
- Device->SwitchChannel(Channel, false);
- lastChannel = ch;
- break;
+ do {
+ int oldLastChannel = lastChannel;
+ for (int i = 0; i < cDevice::NumDevices(); i++) {
+ cDevice *Device = cDevice::GetDevice(i);
+ if (Device && Device->CardIndex() < MAXDVBDEVICES) {
+ if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
+ if (!(Device->Receiving(true) || Device->Replaying())) {
+ int oldCh = lastChannel;
+ int ch = oldCh + 1;
+ while (ch != oldCh) {
+ if (ch > Channels.MaxNumber()) {
+ ch = 1;
+ numTransponders = 0;
+ }
+ cChannel *Channel = Channels.GetByNumber(ch, 1);
+ if (Channel) {
+ if (!Device->ProvidesChannel(Channel))
+ break;
+ if (Channel->Sid() && !TransponderScanned(Channel)) {
+ if (Device == cDevice::PrimaryDevice() && !currentChannel)
+ currentChannel = Device->CurrentChannel();
+ Device->SwitchChannel(Channel, false);
+ lastChannel = ch;
+ break;
+ }
}
+ ch = Channel->Number() + 1;
}
- ch = Channel->Number() + 1;
- }
+ }
}
}
}
- else
- lastChannel++; // avoid hangup in case the last channel in the list is not provided by a DVB card
- }
+ if (lastChannel != oldLastChannel)
+ break;
+ lastChannel++;
+ } while (time(NULL) - now < 2);
lastScan = time(NULL);
}
}
diff --git a/i18n.c b/i18n.c
index aafe0c1..3dc42b0 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.101 2003/01/06 12:16:28 kls Exp $
+ * $Id: i18n.c 1.103 2003/01/26 11:46:46 kls Exp $
*
* Translations provided by:
*
@@ -18,7 +18,7 @@
* Polish Michael Rakowski <mrak@gmx.de>
* Spanish Ruben Nunez Francisco <ruben.nunez@tang-it.com>
* Greek Dimitrios Dimitrakos <mail@dimitrios.de>
- * Swedish Tomas Prybil <tomas@prybil.se>
+ * Swedish Tomas Prybil <tomas@prybil.se> and Jan Ekholm <chakie@infa.abo.fi>
* Romanian Paul Lacatus <paul@campina.iiruc.ro>
* Hungarian Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
*
@@ -211,7 +211,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Inspelningskommandon",
"",// TODO
"",// TODO
},
@@ -950,7 +950,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"",//TODO
"",//TODO
- "",//TODO
+ "Källa",
"",//TODO
"",//TODO
},
@@ -1126,7 +1126,7 @@ const tI18nPhrase Phrases[] = {
"Bandwidth",
"Bandwidth",
"Bandwidth",
- "Bandwidth",
+ "Bandbredd",
"Bandwidth",
"Bandwidth",
},
@@ -1496,7 +1496,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"",//TODO
"",//TODO
- "",//TODO
+ "Kanalen ej tillgänglig!",
"",//TODO
"",//TODO
},
@@ -1512,7 +1512,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"",//TODO
"",//TODO
- "",//TODO
+ "Kanalinställningarna är ej unika!",
"",//TODO
"",//TODO
},
@@ -2042,7 +2042,7 @@ const tI18nPhrase Phrases[] = {
"Transponder do ustawiania czasu",
"Transponder para reloj de sistema",
"Transponder gia sintonismo tis oras",
- "Använd klockan från fransponder",
+ "Använd klockan från transponder",
"Preia ceasul din transponder",
"Idöhöz tartozó Transponder",
},
@@ -2700,7 +2700,7 @@ const tI18nPhrase Phrases[] = {
"Paina 'Ylös' tallettaaksesi ja 'Alas' peruuttaaksesi",
"'Gora' zapamietuje, 'Dol' przerywa",
"Pulse 'Arriba' para guarder, 'Abajo' para anular",
- "'kato' apothikevsi, 'Pano' akirosi",
+ "'Kato' apothikevsi, 'Pano' akirosi",
"Tryck 'Upp' för att spara, 'Ner' för att avsluta",
"Apsati 'Sus' pentru salvare, 'Jos' pentru anulare",
"'Fel' mentés, 'Le´ mégse",
@@ -2894,7 +2894,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Spela upp",
"",// TODO
"",// TODO
},
@@ -2910,7 +2910,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Pausa",
"",// TODO
"",// TODO
},
@@ -2926,7 +2926,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Stoppa",
"",// TODO
"",// TODO
},
@@ -2942,7 +2942,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Spela in",
"",// TODO
"",// TODO
},
@@ -2958,7 +2958,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Spola framåt",
"",// TODO
"",// TODO
},
@@ -2974,7 +2974,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Spola bakåt",
"",// TODO
"",// TODO
},
@@ -3006,7 +3006,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Kanal+",
"",// TODO
"",// TODO
},
@@ -3022,7 +3022,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "Kanal-",
"",// TODO
"",// TODO
},
@@ -3119,7 +3119,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "av",
"",// TODO
"",// TODO
},
diff --git a/libdtv/liblx/Makefile b/libdtv/liblx/Makefile
index 2531708..d06ee09 100644
--- a/libdtv/liblx/Makefile
+++ b/libdtv/liblx/Makefile
@@ -27,8 +27,8 @@
#
#
#
-CC = gcc
-CFLAGS = -O2 -g -pedantic -Wmissing-prototypes -Wstrict-prototypes \
+CC ?= gcc
+CFLAGS ?= -O2 -g -pedantic -Wmissing-prototypes -Wstrict-prototypes \
-Wimplicit -D__USE_FIXED_PROTOTYPES__ # -DDEBUG
diff --git a/libdtv/libvdr/Makefile b/libdtv/libvdr/Makefile
index 0f2ad72..6eebedd 100644
--- a/libdtv/libvdr/Makefile
+++ b/libdtv/libvdr/Makefile
@@ -29,8 +29,9 @@
#
CC ?= gcc
CFLAGS ?= -O2 -g -Wmissing-prototypes -Wstrict-prototypes \
- -Wimplicit -D__USE_FIXED_PROTOTYPES__ -I../include # -DDEBUG
+ -Wimplicit -D__USE_FIXED_PROTOTYPES__ # -DDEBUG
+CFLAGS += -I../include
AR = ar
ARFLAGS = r
diff --git a/menu.c b/menu.c
index e3a4c18..081a4ba 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.231 2003/01/06 16:13:53 kls Exp $
+ * $Id: menu.c 1.232 2003/01/19 14:59:46 kls Exp $
*/
#include "menu.h"
@@ -1572,11 +1572,15 @@ eOSState cMenuCam::ProcessKey(eKeys Key)
//XXX this is just quick and dirty - make this a separate display object
cMenuCamEnquiry::cMenuCamEnquiry(cCiEnquiry *CiEnquiry)
-:cOsdMenu("")
+:cOsdMenu("", 10)
{
ciEnquiry = CiEnquiry;
+ int Length = ciEnquiry->ExpectedLength();
+ input = MALLOC(char, Length + 1);
+ *input = 0;
replied = false;
SetTitle(ciEnquiry->Text() ? ciEnquiry->Text() : "CAM");
+ Add(new cMenuEditNumItem("Input", input, Length, ciEnquiry->Blind()));
Display();
}
@@ -1584,12 +1588,14 @@ cMenuCamEnquiry::~cMenuCamEnquiry()
{
if (!replied)
ciEnquiry->Cancel();
+ free(input);
delete ciEnquiry;
}
eOSState cMenuCamEnquiry::Reply(void)
{
- ciEnquiry->Reply("1234");//XXX implement actual user input
+ //XXX check length???
+ ciEnquiry->Reply(input);
replied = true;
return osEnd;
}
diff --git a/menu.h b/menu.h
index e886f18..43a0d8f 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 1.52 2003/01/06 10:04:05 kls Exp $
+ * $Id: menu.h 1.53 2003/01/12 14:54:05 kls Exp $
*/
#ifndef __MENU_H
@@ -73,6 +73,7 @@ public:
class cMenuCamEnquiry : public cOsdMenu {
private:
cCiEnquiry *ciEnquiry;
+ char *input;
bool replied;
eOSState Reply(void);
public:
diff --git a/menuitems.c b/menuitems.c
index c92d531..56b9199 100644
--- a/menuitems.c
+++ b/menuitems.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menuitems.c 1.11 2002/12/15 11:05:19 kls Exp $
+ * $Id: menuitems.c 1.12 2003/01/18 13:34:40 kls Exp $
*/
#include "menuitems.h"
@@ -109,6 +109,60 @@ void cMenuEditBoolItem::Set(void)
SetValue(buf);
}
+// --- cMenuEditNumItem ------------------------------------------------------
+
+cMenuEditNumItem::cMenuEditNumItem(const char *Name, char *Value, int Length, bool Blind)
+:cMenuEditItem(Name)
+{
+ value = Value;
+ length = Length;
+ blind = Blind;
+ Set();
+}
+
+void cMenuEditNumItem::Set(void)
+{
+ if (blind) {
+ char buf[length + 1];
+ int i;
+ for (i = 0; i < length && value[i]; i++)
+ buf[i] = '*';
+ buf[i] = 0;
+ SetValue(buf);
+ }
+ else
+ SetValue(value);
+}
+
+eOSState cMenuEditNumItem::ProcessKey(eKeys Key)
+{
+ eOSState state = cMenuEditItem::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ Key = NORMALKEY(Key);
+ switch (Key) {
+ case kLeft: {
+ int l = strlen(value);
+ if (l > 0)
+ value[l - 1] = 0;
+ }
+ break;
+ case k0 ... k9: {
+ int l = strlen(value);
+ if (l < length) {
+ value[l] = Key - k0 + '0';
+ value[l + 1] = 0;
+ }
+ }
+ break;
+ default: return state;
+ }
+ Set();
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cMenuEditChrItem ------------------------------------------------------
cMenuEditChrItem::cMenuEditChrItem(const char *Name, char *Value, const char *Allowed)
diff --git a/menuitems.h b/menuitems.h
index 4752d4b..f9b2ff3 100644
--- a/menuitems.h
+++ b/menuitems.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menuitems.h 1.4 2002/08/15 11:28:26 kls Exp $
+ * $Id: menuitems.h 1.5 2003/01/12 15:06:23 kls Exp $
*/
#ifndef __MENUITEMS_H
@@ -42,6 +42,17 @@ public:
cMenuEditBoolItem(const char *Name, int *Value, const char *FalseString = NULL, const char *TrueString = NULL);
};
+class cMenuEditNumItem : public cMenuEditItem {
+protected:
+ char *value;
+ int length;
+ bool blind;
+ virtual void Set(void);
+public:
+ cMenuEditNumItem(const char *Name, char *Value, int Length, bool Blind = false);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
class cMenuEditChrItem : public cMenuEditItem {
private:
char *value;
diff --git a/recorder.c b/recorder.c
index 426b555..15e8646 100644
--- a/recorder.c
+++ b/recorder.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recorder.c 1.4 2002/12/22 11:33:08 kls Exp $
+ * $Id: recorder.c 1.5 2003/01/25 16:23:36 kls Exp $
*/
#include <stdarg.h>
@@ -41,7 +41,7 @@ cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int A
SpinUpDisk(FileName);
- ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true);
+ ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true);
fileName = new cFileName(FileName, true);
recordFile = fileName->Open();
@@ -110,16 +110,14 @@ void cRecorder::Action(void)
{
dsyslog("recording thread started (pid=%d)", getpid());
- uchar b[MINVIDEODATA];
- int r = 0;
active = true;
while (active) {
- int g = ringBuffer->Get(b + r, sizeof(b) - r);
- if (g > 0)
- r += g;
- if (r > 0) {
+ int r;
+ const uchar *b = ringBuffer->Get(r);
+ if (b) {
int Count = r, Result;
uchar *p = remux->Process(b, Count, Result, &pictureType);
+ ringBuffer->Del(Count);
if (p) {
//XXX+ active??? see old version (Busy)
if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame
@@ -136,10 +134,6 @@ void cRecorder::Action(void)
else
break;
}
- if (Count > 0) {
- r -= Count;
- memmove(b, b + Count, r);
- }
}
else
usleep(1); // this keeps the CPU load low
diff --git a/remux.c b/remux.c
index 786bb8f..097b4a5 100644
--- a/remux.c
+++ b/remux.c
@@ -8,7 +8,7 @@
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
* VDR's needs.
*
- * $Id: remux.c 1.12 2002/10/12 13:33:54 kls Exp $
+ * $Id: remux.c 1.14 2003/01/24 17:22:29 kls Exp $
*/
/* The calling interface of the 'cRemux::Process()' function is defined
@@ -97,14 +97,16 @@
#define PTS_ONLY 0x80
#define TS_SIZE 188
-#define PAY_START 0x40
#define PID_MASK_HI 0x1F
-//flags
+#define CONT_CNT_MASK 0x0F
+
+// Flags:
+#define PAY_START 0x40
+#define TS_ERROR 0x80
#define ADAPT_FIELD 0x20
-//XXX TODO
-#define MAX_PLENGTH 0xFFFF
-#define MMAX_PLENGTH (4*MAX_PLENGTH)
+#define MAX_PLENGTH 0xFFFF // the maximum PES packet length (theoretically)
+#define MMAX_PLENGTH (8*MAX_PLENGTH) // some stations send PES packets that are extremely large, e.g. DVB-T in Finland
#define IPACKS 2048
@@ -132,6 +134,9 @@ private:
bool done;
uint8_t *resultBuffer;
int *resultCount;
+ int tsErrors;
+ int ccErrors;
+ int ccCounter;
static uint8_t headr[];
void store(uint8_t *Data, int Count);
void reset_ipack(void);
@@ -154,6 +159,10 @@ cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t Audi
size = Size;
audioCid = AudioCid;
+ tsErrors = 0;
+ ccErrors = 0;
+ ccCounter = -1;
+
if (!(buf = MALLOC(uint8_t, size)))
esyslog("Not enough memory for ts_transform");
@@ -162,6 +171,8 @@ cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t Audi
cTS2PES::~cTS2PES()
{
+ if (tsErrors || ccErrors)
+ dsyslog("cTS2PES got %d TS errors, %d TS continuity errors", tsErrors, ccErrors);
free(buf);
}
@@ -384,6 +395,8 @@ void cTS2PES::instant_repack(const uint8_t *Buf, int Count)
}
if (plength && found == plength + 6) {
+ if (plength == MMAX_PLENGTH - 6)
+ esyslog("ERROR: PES packet length overflow in remuxer (stream corruption)");
send_ipack();
reset_ipack();
if (c < Count)
@@ -398,6 +411,22 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188)
if (!Buf)
return;
+ if (Buf[1] & TS_ERROR)
+ tsErrors++;
+ if ((Buf[3] ^ ccCounter) & CONT_CNT_MASK) {
+ // This should check duplicates and packets which do not increase the counter.
+ // But as the errors usually come in bursts this should be enough to
+ // show you there is something wrong with signal quality.
+ if (ccCounter != -1 && ((Buf[3] ^ (ccCounter + 1)) & CONT_CNT_MASK)) {
+ ccErrors++;
+ // Enable this if you are having problems with signal quality.
+ // These are the errors I used to get with Nova-T when antenna
+ // was not positioned correcly (not transport errors). //tvr
+ //dsyslog("TS continuity error (%d)", ccCounter);
+ }
+ ccCounter = Buf[3] & CONT_CNT_MASK;
+ }
+
if (Buf[1] & PAY_START) {
if (plength == MMAX_PLENGTH - 6 && found > 6) {
plength = found - 6;
diff --git a/ringbuffer.c b/ringbuffer.c
index b57b23e..0734c28 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org).
*
- * $Id: ringbuffer.c 1.10 2002/07/28 12:47:32 kls Exp $
+ * $Id: ringbuffer.c 1.12 2003/01/26 09:39:24 kls Exp $
*/
#include "ringbuffer.h"
@@ -57,13 +57,14 @@ void cRingBuffer::EnableGet(void)
// --- cRingBufferLinear -----------------------------------------------------
-cRingBufferLinear::cRingBufferLinear(int Size, bool Statistics)
+cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics)
:cRingBuffer(Size, Statistics)
{
+ margin = Margin;
buffer = NULL;
getThreadPid = -1;
if (Size > 1) { // 'Size - 1' must not be 0!
- buffer = new uchar[Size];
+ buffer = MALLOC(uchar, Size);
if (!buffer)
esyslog("ERROR: can't allocate ring buffer (size=%d)", Size);
Clear();
@@ -74,7 +75,7 @@ cRingBufferLinear::cRingBufferLinear(int Size, bool Statistics)
cRingBufferLinear::~cRingBufferLinear()
{
- delete buffer;
+ free(buffer);
}
int cRingBufferLinear::Available(void)
@@ -82,13 +83,14 @@ int cRingBufferLinear::Available(void)
Lock();
int diff = head - tail;
Unlock();
- return (diff >= 0) ? diff : Size() + diff;
+ return (diff >= 0) ? diff : Size() + diff - margin;
}
void cRingBufferLinear::Clear(void)
{
Lock();
- head = tail = 0;
+ head = tail = margin;
+ lastGet = -1;
Unlock();
EnablePut();
EnableGet();
@@ -100,7 +102,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
Lock();
int rest = Size() - head;
int diff = tail - head;
- int free = (diff > 0) ? diff - 1 : Size() + diff - 1;
+ int free = (diff > 0) ? diff - 1 : Size() + diff - (tail < margin ? -(margin - tail) : margin) - 1;
if (statistics) {
int fill = Size() - free - 1 + Count;
if (fill >= Size())
@@ -122,8 +124,8 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
if (Count >= rest) {
memcpy(buffer + head, Data, rest);
if (Count - rest)
- memcpy(buffer, Data + rest, Count - rest);
- head = Count - rest;
+ memcpy(buffer + margin, Data + rest, Count - rest);
+ head = margin + Count - rest;
}
else {
memcpy(buffer + head, Data, Count);
@@ -138,50 +140,60 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
return Count;
}
-int cRingBufferLinear::Get(uchar *Data, int Count)
+const uchar *cRingBufferLinear::Get(int &Count)
{
- if (Count > 0) {
- Lock();
- if (getThreadPid < 0)
- getThreadPid = getpid();
- int rest = Size() - tail;
- int diff = head - tail;
- int cont = (diff >= 0) ? diff : Size() + diff;
- if (rest > 0) {
- if (cont < Count)
- Count = cont;
- if (Count >= rest) {
- memcpy(Data, buffer + tail, rest);
- if (Count - rest)
- memcpy(Data + rest, buffer, Count - rest);
- tail = Count - rest;
- }
- else {
- memcpy(Data, buffer + tail, Count);
- tail += Count;
- }
- }
- else
- Count = 0;
- Unlock();
- if (Count == 0)
- WaitForGet();
+ const uchar *p = NULL;
+ Lock();
+ if (getThreadPid < 0)
+ getThreadPid = getpid();
+ int rest = Size() - tail;
+ if (tail > Size() - margin && head < tail) {
+ int t = margin - rest;
+ memcpy(buffer + t, buffer + tail, rest);
+ tail = t;
}
- return Count;
+ int diff = head - tail;
+ int cont = (diff >= 0) ? diff : Size() + diff - margin;
+ if (cont > rest)
+ cont = rest;
+ if (cont >= margin) {
+ p = buffer + tail;
+ Count = lastGet = cont;
+ }
+ Unlock();
+ if (!p)
+ WaitForGet();
+ return p;
+}
+
+void cRingBufferLinear::Del(int Count)
+{
+ if (Count > 0 && Count <= lastGet) {
+ tail += Count;
+ lastGet -= Count;
+ if (tail >= Size())
+ tail = margin;
+ }
+ else
+ esyslog("ERROR: invalid Count in cRingBufferLinear::Del: %d", Count);
}
// --- cFrame ----------------------------------------------------------------
cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
{
- count = Count;
+ count = abs(Count);
type = Type;
index = Index;
- data = new uchar[count];
- if (data)
- memcpy(data, Data, count);
- else
- esyslog("ERROR: can't allocate frame buffer (count=%d)", count);
+ if (Count < 0)
+ data = (uchar *)Data;
+ else {
+ data = new uchar[count];
+ if (data)
+ memcpy(data, Data, count);
+ else
+ esyslog("ERROR: can't allocate frame buffer (count=%d)", count);
+ }
next = NULL;
}
diff --git a/ringbuffer.h b/ringbuffer.h
index 660a08b..9205df7 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ringbuffer.h 1.7 2002/08/04 10:27:30 kls Exp $
+ * $Id: ringbuffer.h 1.9 2003/01/26 09:47:39 kls Exp $
*/
#ifndef __RINGBUFFER_H
@@ -40,21 +40,31 @@ public:
class cRingBufferLinear : public cRingBuffer {
private:
- int head, tail;
+ int margin, head, tail;
+ int lastGet;
uchar *buffer;
pid_t getThreadPid;
public:
- cRingBufferLinear(int Size, bool Statistics = false);
+ cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false);
+ ///< Creates a linear ring buffer.
+ ///< The buffer will be able to hold at most Size bytes of data, and will
+ ///< be guaranteed to return at least Margin bytes in one consecutive block.
virtual ~cRingBufferLinear();
virtual int Available(void);
virtual void Clear(void);
- // Immediately clears the ring buffer.
+ ///< Immediately clears the ring buffer.
int Put(const uchar *Data, int Count);
- // Puts at most Count bytes of Data into the ring buffer.
- // Returns the number of bytes actually stored.
- int Get(uchar *Data, int Count);
- // Gets at most Count bytes of Data from the ring buffer.
- // Returns the number of bytes actually retrieved.
+ ///< Puts at most Count bytes of Data into the ring buffer.
+ ///< \return Returns the number of bytes actually stored.
+ const uchar *Get(int &Count);
+ ///< Gets data from the ring buffer.
+ ///< The data will remain in the buffer until a call to Del() deletes it.
+ ///< \return Returns a pointer to the data, and stores the number of bytes
+ ///< actually retrieved in Count. If the returned pointer is NULL, Count has no meaning.
+ void Del(int Count);
+ ///< Deletes at most Count bytes from the ring buffer.
+ ///< Count must be less or equal to the number that was returned by a previous
+ ///< call to Get().
};
enum eFrameType { ftUnknown, ftVideo, ftAudio, ftDolby };
@@ -69,6 +79,9 @@ private:
int index;
public:
cFrame(const uchar *Data, int Count, eFrameType = ftUnknown, int Index = -1);
+ ///< Creates a new cFrame object.
+ ///< If Count is negative, the cFrame object will take ownership of the given
+ ///< Data. Otherwise it will allocate Count bytes of memory and copy Data.
~cFrame();
const uchar *Data(void) const { return data; }
int Count(void) const { return count; }
diff --git a/transfer.c b/transfer.c
index d8975a9..abcb9d0 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: transfer.c 1.8 2002/12/14 13:14:53 kls Exp $
+ * $Id: transfer.c 1.9 2003/01/26 09:59:35 kls Exp $
*/
#include "transfer.h"
@@ -19,7 +19,7 @@
cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
:cReceiver(0, -1, 5, VPid, APid1, APid2, DPid1, DPid2)
{
- ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true);
+ ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
canToggleAudioTrack = false;
audioTrack = 0xC0;
@@ -60,8 +60,6 @@ void cTransfer::Action(void)
{
dsyslog("transfer thread started (pid=%d)", getpid());
- uchar b[MINVIDEODATA];
- int r = 0;
active = true;
while (active) {
@@ -80,15 +78,15 @@ void cTransfer::Action(void)
// Get data from the buffer:
- int g = ringBuffer->Get(b + r, sizeof(b) - r);
- if (g > 0)
- r += g;
+ int r;
+ const uchar *b = ringBuffer->Get(r);
// Play the data:
- if (r > 0) {
+ if (b) {
int Count = r, Result;
uchar *p = remux->Process(b, Count, Result);
+ ringBuffer->Del(Count);
if (p) {
StripAudioPackets(p, Result, audioTrack);
while (Result > 0 && active) {
@@ -103,11 +101,6 @@ void cTransfer::Action(void)
}
}
}
- if (Count > 0) {
- r -= Count;
- if (r > 0)
- memmove(b, b + Count, r);
- }
}
else
usleep(1); // this keeps the CPU load low
diff --git a/vdr.c b/vdr.c
index 44ed58f..87550de 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.140 2003/01/06 11:14:50 kls Exp $
+ * $Id: vdr.c 1.141 2003/01/26 11:56:31 kls Exp $
*/
#include <getopt.h>
@@ -160,7 +160,7 @@ int main(int argc, char *argv[])
if (!p)
break;
if (isnumber(p + 1)) {
- int l = atoi(optarg);
+ int l = atoi(p + 1);
if (0 <= l && l <= 7) {
int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
SysLogTarget = targets[l];