diff options
-rw-r--r-- | CONTRIBUTORS | 17 | ||||
-rw-r--r-- | HISTORY | 25 | ||||
-rw-r--r-- | MANUAL | 8 | ||||
-rw-r--r-- | ca.conf | 2 | ||||
-rw-r--r-- | channels.conf | 4 | ||||
-rw-r--r-- | ci.c | 15 | ||||
-rw-r--r-- | config.h | 4 | ||||
-rw-r--r-- | dvbplayer.c | 199 | ||||
-rw-r--r-- | eit.c | 23 | ||||
-rw-r--r-- | eitscan.c | 60 | ||||
-rw-r--r-- | i18n.c | 36 | ||||
-rw-r--r-- | libdtv/liblx/Makefile | 4 | ||||
-rw-r--r-- | libdtv/libvdr/Makefile | 3 | ||||
-rw-r--r-- | menu.c | 12 | ||||
-rw-r--r-- | menu.h | 3 | ||||
-rw-r--r-- | menuitems.c | 56 | ||||
-rw-r--r-- | menuitems.h | 13 | ||||
-rw-r--r-- | recorder.c | 18 | ||||
-rw-r--r-- | remux.c | 41 | ||||
-rw-r--r-- | ringbuffer.c | 98 | ||||
-rw-r--r-- | ringbuffer.h | 31 | ||||
-rw-r--r-- | transfer.c | 19 | ||||
-rw-r--r-- | vdr.c | 4 |
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 @@ -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. @@ -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). @@ -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 @@ -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); @@ -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()); } @@ -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); + */ } } } @@ -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); } } @@ -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 @@ -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; } @@ -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; @@ -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 @@ -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; } @@ -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 @@ -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]; |