mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
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.
This commit is contained in:
parent
3e1d34f392
commit
a3942b4d17
17
CONTRIBUTORS
17
CONTRIBUTORS
@ -305,7 +305,7 @@ Mirko G
|
|||||||
Achim Lange <Achim_Lange@t-online.de>
|
Achim Lange <Achim_Lange@t-online.de>
|
||||||
for replacing 'killproc' with 'killall' in 'runvdr' to make it work on Debian
|
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 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>
|
Klaus Wolf <klaus@wolfsoft.de>
|
||||||
for reporting a bug in restoring the CICAM values for a fourth DVB card
|
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>
|
Dimitrios Dimitrakos <mail@dimitrios.de>
|
||||||
for translating OSD texts to the Greek language
|
for translating OSD texts to the Greek language
|
||||||
|
for fixing handling the LOG_LOCALn parameters in the -l option
|
||||||
|
|
||||||
Marcus Kuba <marcus@kuba4u.de>
|
Marcus Kuba <marcus@kuba4u.de>
|
||||||
for reporting a bug in the unit of the "SVDRP timeout" setup parameter
|
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 reporting some faulty default parameter initializations
|
||||||
for suggesting to only set the Makefile variables CXX and CXXFLAGS if they are not
|
for suggesting to only set the Makefile variables CXX and CXXFLAGS if they are not
|
||||||
yet defined
|
yet defined
|
||||||
|
for fixing a problem with user defined CFLAGS in libdtv/libvdr/Makefile
|
||||||
|
|
||||||
Gerhard Steiner <steiner@mail.austria.com>
|
Gerhard Steiner <steiner@mail.austria.com>
|
||||||
for suggesting that the SVDRP command PUTE shall trigger an immediate write of
|
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>
|
Clemens Kirchgatterer <clemens@thf.ath.cx>
|
||||||
for suggesting to change source directory name for plugins from 'SRC' to 'src'
|
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>
|
Emil Naepflein <Emil.Naepflein@philosys.de>
|
||||||
for suggesting to take an active SVDRP connection into account when doing shutdown or
|
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>
|
Walter Stroebel <walter.stroebel@lifeline.nl>
|
||||||
for introducing "Doxygen" to document the VDR source code
|
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
|
||||||
|
25
HISTORY
25
HISTORY
@ -1916,3 +1916,28 @@ Video Disk Recorder Revision History
|
|||||||
- Since several channels put very long strings into the Subtitle part of their
|
- 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
|
EPG data, that string is now limited in length when used in a recording's
|
||||||
file name.
|
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.
|
||||||
|
8
MANUAL
8
MANUAL
@ -23,6 +23,10 @@ Video Disk Recorder User's Manual
|
|||||||
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
|
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
|
||||||
0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing
|
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
|
If your remote control provides additional keys, they can be used for the
|
||||||
following functions:
|
following functions:
|
||||||
|
|
||||||
@ -411,11 +415,11 @@ Video Disk Recorder User's Manual
|
|||||||
always displayed when pressing the "Ok" button in
|
always displayed when pressing the "Ok" button in
|
||||||
normal viewing mode.
|
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
|
is on the last (first) line of a list page, the
|
||||||
list is advanced by a full page and the cursor will
|
list is advanced by a full page and the cursor will
|
||||||
be at the top (bottom) of that page
|
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
|
the page (this mode allows for faster scrolling
|
||||||
through long lists).
|
through long lists).
|
||||||
|
|
||||||
|
2
ca.conf
2
ca.conf
@ -29,6 +29,8 @@
|
|||||||
402 NTV Plus
|
402 NTV Plus
|
||||||
403 Viasat
|
403 Viasat
|
||||||
404 Parabole Reunion
|
404 Parabole Reunion
|
||||||
|
405 Hrvatska radiotelevizija
|
||||||
|
406 RTV Slovenija
|
||||||
|
|
||||||
# Viaccess 2
|
# Viaccess 2
|
||||||
|
|
||||||
|
@ -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 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
|
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
|
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
|
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
|
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
|
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 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
|
:#Premiere Direkt 4B:12070:h:S19.2E:27500:1535:1536:0:101:216:0:0:0
|
||||||
:PW Erotic
|
: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 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 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
|
Premiere Erotik 3:11719:h:S19.2E:27500:1791:1792:0:101:779:0:0:0
|
||||||
|
15
ci.c
15
ci.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
/* XXX TODO
|
||||||
@ -331,6 +331,7 @@ int cCiTransportConnection::RecvTPDU(void)
|
|||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
pfd[0].fd = fd;
|
pfd[0].fd = fd;
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
|
lastResponse = ERROR;
|
||||||
if (poll(pfd, 1, 3500/*XXX*/) && (pfd[0].revents & POLLIN))//XXX
|
if (poll(pfd, 1, 3500/*XXX*/) && (pfd[0].revents & POLLIN))//XXX
|
||||||
if (tpdu->Read(fd) == OK && tpdu->Tcid() == tcid) {
|
if (tpdu->Read(fd) == OK && tpdu->Tcid() == tcid) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -338,7 +339,7 @@ int cCiTransportConnection::RecvTPDU(void)
|
|||||||
case stCREATION: if (tpdu->Tag() == T_CTC_REPLY) {
|
case stCREATION: if (tpdu->Tag() == T_CTC_REPLY) {
|
||||||
dataAvailable = tpdu->Status() & DATA_INDICATOR;
|
dataAvailable = tpdu->Status() & DATA_INDICATOR;
|
||||||
state = stACTIVE;
|
state = stACTIVE;
|
||||||
return tpdu->Tag();
|
lastResponse = tpdu->Tag();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case stACTIVE: switch (tpdu->Tag()) {
|
case stACTIVE: switch (tpdu->Tag()) {
|
||||||
@ -353,17 +354,17 @@ int cCiTransportConnection::RecvTPDU(void)
|
|||||||
default: return ERROR;
|
default: return ERROR;
|
||||||
}
|
}
|
||||||
dataAvailable = tpdu->Status() & DATA_INDICATOR;
|
dataAvailable = tpdu->Status() & DATA_INDICATOR;
|
||||||
return tpdu->Tag();
|
lastResponse = tpdu->Tag();
|
||||||
break;
|
break;
|
||||||
case stDELETION: if (tpdu->Tag() == T_DTC_REPLY) {
|
case stDELETION: if (tpdu->Tag() == T_DTC_REPLY) {
|
||||||
Init(fd, slot, tcid);
|
Init(fd, slot, tcid);
|
||||||
//XXX Status()???
|
//XXX Status()???
|
||||||
return tpdu->Tag();
|
lastResponse = tpdu->Tag();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ERROR;
|
return lastResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cCiTransportConnection::SendData(int Length, const uint8_t *Data)
|
int cCiTransportConnection::SendData(int Length, const uint8_t *Data)
|
||||||
@ -413,7 +414,7 @@ int cCiTransportConnection::Poll(void)
|
|||||||
{
|
{
|
||||||
if (state == stACTIVE) {
|
if (state == stACTIVE) {
|
||||||
if (SendTPDU(T_DATA_LAST) == OK) {
|
if (SendTPDU(T_DATA_LAST) == OK) {
|
||||||
return lastResponse = RecvTPDU();
|
return RecvTPDU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ERROR;
|
return ERROR;
|
||||||
@ -644,7 +645,7 @@ int cCiSession::SendData(int Tag, int Length, const uint8_t *Data)
|
|||||||
*p++ = (Tag >> 8) & 0xFF;
|
*p++ = (Tag >> 8) & 0xFF;
|
||||||
*p++ = Tag & 0xFF;
|
*p++ = Tag & 0xFF;
|
||||||
p = SetLength(p, Length);
|
p = SetLength(p, Length);
|
||||||
if (p - buffer + Length < sizeof(buffer)) {
|
if (p - buffer + Length < int(sizeof(buffer))) {
|
||||||
memcpy(p, Data, Length);
|
memcpy(p, Data, Length);
|
||||||
p += Length;
|
p += Length;
|
||||||
return tc->SendData(p - buffer, buffer);
|
return tc->SendData(p - buffer, buffer);
|
||||||
|
4
config.h
4
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __CONFIG_H
|
||||||
@ -19,7 +19,7 @@
|
|||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "1.1.21"
|
#define VDRVERSION "1.1.22"
|
||||||
|
|
||||||
#define MAXPRIORITY 99
|
#define MAXPRIORITY 99
|
||||||
#define MAXLIFETIME 99
|
#define MAXLIFETIME 99
|
||||||
|
199
dvbplayer.c
199
dvbplayer.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "dvbplayer.h"
|
||||||
@ -69,6 +69,103 @@ int cBackTrace::Get(bool Forward)
|
|||||||
return i;
|
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 ------------------------------------------------------------
|
// --- cDvbPlayer ------------------------------------------------------------
|
||||||
|
|
||||||
//XXX+ also used in recorder.c - find a better place???
|
//XXX+ also used in recorder.c - find a better place???
|
||||||
@ -84,6 +181,7 @@ private:
|
|||||||
enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
|
enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
|
||||||
enum ePlayDirs { pdForward, pdBackward };
|
enum ePlayDirs { pdForward, pdBackward };
|
||||||
static int Speeds[];
|
static int Speeds[];
|
||||||
|
cNonBlockingFileReader *nonBlockingFileReader;
|
||||||
cRingBufferFrame *ringBuffer;
|
cRingBufferFrame *ringBuffer;
|
||||||
cBackTrace *backTrace;
|
cBackTrace *backTrace;
|
||||||
cFileName *fileName;
|
cFileName *fileName;
|
||||||
@ -135,6 +233,7 @@ int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 };
|
|||||||
|
|
||||||
cDvbPlayer::cDvbPlayer(const char *FileName)
|
cDvbPlayer::cDvbPlayer(const char *FileName)
|
||||||
{
|
{
|
||||||
|
nonBlockingFileReader = NULL;
|
||||||
ringBuffer = NULL;
|
ringBuffer = NULL;
|
||||||
backTrace = NULL;
|
backTrace = NULL;
|
||||||
index = NULL;
|
index = NULL;
|
||||||
@ -198,7 +297,9 @@ void cDvbPlayer::TrickSpeed(int Increment)
|
|||||||
|
|
||||||
void cDvbPlayer::Empty(void)
|
void cDvbPlayer::Empty(void)
|
||||||
{
|
{
|
||||||
Lock();
|
LOCK_THREAD;
|
||||||
|
if (nonBlockingFileReader)
|
||||||
|
nonBlockingFileReader->Clear();
|
||||||
if ((readIndex = backTrace->Get(playDir == pdForward)) < 0)
|
if ((readIndex = backTrace->Get(playDir == pdForward)) < 0)
|
||||||
readIndex = writeIndex;
|
readIndex = writeIndex;
|
||||||
readFrame = NULL;
|
readFrame = NULL;
|
||||||
@ -206,7 +307,6 @@ void cDvbPlayer::Empty(void)
|
|||||||
ringBuffer->Clear();
|
ringBuffer->Clear();
|
||||||
backTrace->Clear();
|
backTrace->Clear();
|
||||||
DeviceClear();
|
DeviceClear();
|
||||||
Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
|
void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
|
||||||
@ -305,7 +405,7 @@ void cDvbPlayer::Action(void)
|
|||||||
{
|
{
|
||||||
dsyslog("dvbplayer thread started (pid=%d)", getpid());
|
dsyslog("dvbplayer thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
uchar b[MAXFRAMESIZE];
|
uchar *b = NULL;
|
||||||
const uchar *p = NULL;
|
const uchar *p = NULL;
|
||||||
int pc = 0;
|
int pc = 0;
|
||||||
|
|
||||||
@ -313,6 +413,10 @@ void cDvbPlayer::Action(void)
|
|||||||
if (readIndex >= 0)
|
if (readIndex >= 0)
|
||||||
isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
|
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;
|
running = true;
|
||||||
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available())) {
|
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available())) {
|
||||||
cPoller Poller;
|
cPoller Poller;
|
||||||
@ -326,46 +430,59 @@ void cDvbPlayer::Action(void)
|
|||||||
|
|
||||||
if (!readFrame && (replayFile >= 0 || readIndex >= 0)) {
|
if (!readFrame && (replayFile >= 0 || readIndex >= 0)) {
|
||||||
if (playMode != pmStill) {
|
if (playMode != pmStill) {
|
||||||
int r = 0;
|
if (!nonBlockingFileReader->Reading()) {
|
||||||
if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
|
if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
|
||||||
uchar FileNumber;
|
uchar FileNumber;
|
||||||
int FileOffset, Length;
|
int FileOffset;
|
||||||
int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
|
int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
|
||||||
if (Index >= 0) {
|
if (Index >= 0) {
|
||||||
if (!NextFile(FileNumber, FileOffset))
|
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;
|
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 {
|
else if (index) {
|
||||||
// can't call Play() here, because those functions may only be
|
uchar FileNumber;
|
||||||
// called from the foreground thread - and we also don't need
|
int FileOffset;
|
||||||
// to empty the buffer here
|
readIndex++;
|
||||||
DevicePlay();
|
if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
|
||||||
playMode = pmPlay;
|
readIndex = -1;
|
||||||
playDir = pdForward;
|
eof = true;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
AudioTrack = audioTrack;
|
||||||
}
|
}
|
||||||
readIndex = Index;
|
else { // allows replay even if the index file is missing
|
||||||
r = ReadFrame(replayFile, b, Length, sizeof(b));
|
Length = MAXFRAMESIZE;
|
||||||
// must call StripAudioPackets() here because the buffer is not emptied
|
AudioTrack = -1;
|
||||||
// when falling back from "fast forward" to "play" (see above)
|
}
|
||||||
StripAudioPackets(b, r);
|
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;
|
||||||
|
}
|
||||||
|
b = MALLOC(uchar, Length);
|
||||||
}
|
}
|
||||||
else if (index) {
|
int r = nonBlockingFileReader->Read(replayFile, b, Length);
|
||||||
uchar FileNumber;
|
if (r > 0) {
|
||||||
int FileOffset, Length;
|
if (AudioTrack >= 0)
|
||||||
readIndex++;
|
StripAudioPackets(b, r, AudioTrack);
|
||||||
if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
|
readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
|
||||||
readIndex = -1;
|
b = NULL;
|
||||||
eof = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
r = ReadFrame(replayFile, b, Length, sizeof(b));
|
|
||||||
StripAudioPackets(b, r, audioTrack);
|
|
||||||
}
|
}
|
||||||
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)
|
else if (r == 0)
|
||||||
eof = true;
|
eof = true;
|
||||||
else if (r < 0 && FATALERRNO) {
|
else if (r < 0 && FATALERRNO) {
|
||||||
@ -422,6 +539,10 @@ void cDvbPlayer::Action(void)
|
|||||||
}
|
}
|
||||||
active = running = false;
|
active = running = false;
|
||||||
|
|
||||||
|
cNonBlockingFileReader *nbfr = nonBlockingFileReader;
|
||||||
|
nonBlockingFileReader = NULL;
|
||||||
|
delete nbfr;
|
||||||
|
|
||||||
dsyslog("dvbplayer thread ended (pid=%d)", getpid());
|
dsyslog("dvbplayer thread ended (pid=%d)", getpid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
eit.c
23
eit.c
@ -16,7 +16,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (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"
|
#include "eit.h"
|
||||||
@ -1240,17 +1240,16 @@ void cSIProcessor::Action()
|
|||||||
{
|
{
|
||||||
if (pfd[a].revents & POLLIN)
|
if (pfd[a].revents & POLLIN)
|
||||||
{
|
{
|
||||||
/* read section */
|
// read section
|
||||||
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
unsigned char buf[4096]; // max. allowed size for any EIT section
|
||||||
if (safe_read(filters[a].handle, buf, 3) == 3)
|
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 pid = filters[a].pid;
|
||||||
int n = safe_read(filters[a].handle, buf + 3, seclen);
|
if (seclen == r)
|
||||||
if (n == seclen)
|
|
||||||
{
|
{
|
||||||
seclen += 3;
|
//dsyslog("Received pid 0x%04X with table ID 0x%02X and length of %4d\n", pid, buf[0], seclen);
|
||||||
//dsyslog("Received pid 0x%02x with table ID 0x%02x and length of %04d\n", pid, buf[0], seclen);
|
|
||||||
switch (pid)
|
switch (pid)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
@ -1335,10 +1334,10 @@ void cSIProcessor::Action()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*XXX this just fills up the log file - shouldn't we rather try to re-sync?
|
/*
|
||||||
else
|
else
|
||||||
dsyslog("read incomplete section - seclen = %d, n = %d", seclen, n);
|
dsyslog("read incomplete section - seclen = %d, r = %d", seclen, r);
|
||||||
XXX*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
eitscan.c
60
eitscan.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "eitscan.h"
|
||||||
@ -51,38 +51,42 @@ void cEITScanner::Process(void)
|
|||||||
if (Setup.EPGScanTimeout && Channels.MaxNumber() > 1) {
|
if (Setup.EPGScanTimeout && Channels.MaxNumber() > 1) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) {
|
if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) {
|
||||||
for (int i = 0; i < cDevice::NumDevices(); i++) {
|
do {
|
||||||
cDevice *Device = cDevice::GetDevice(i);
|
int oldLastChannel = lastChannel;
|
||||||
if (Device && Device->CardIndex() < MAXDVBDEVICES) {
|
for (int i = 0; i < cDevice::NumDevices(); i++) {
|
||||||
if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
|
cDevice *Device = cDevice::GetDevice(i);
|
||||||
if (!(Device->Receiving(true) || Device->Replaying())) {
|
if (Device && Device->CardIndex() < MAXDVBDEVICES) {
|
||||||
int oldCh = lastChannel;
|
if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
|
||||||
int ch = oldCh + 1;
|
if (!(Device->Receiving(true) || Device->Replaying())) {
|
||||||
while (ch != oldCh) {
|
int oldCh = lastChannel;
|
||||||
if (ch > Channels.MaxNumber()) {
|
int ch = oldCh + 1;
|
||||||
ch = 1;
|
while (ch != oldCh) {
|
||||||
numTransponders = 0;
|
if (ch > Channels.MaxNumber()) {
|
||||||
}
|
ch = 1;
|
||||||
cChannel *Channel = Channels.GetByNumber(ch, 1);
|
numTransponders = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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
|
if (lastChannel != oldLastChannel)
|
||||||
lastChannel++; // avoid hangup in case the last channel in the list is not provided by a DVB card
|
break;
|
||||||
}
|
lastChannel++;
|
||||||
|
} while (time(NULL) - now < 2);
|
||||||
lastScan = time(NULL);
|
lastScan = time(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
i18n.c
36
i18n.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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:
|
* Translations provided by:
|
||||||
*
|
*
|
||||||
@ -18,7 +18,7 @@
|
|||||||
* Polish Michael Rakowski <mrak@gmx.de>
|
* Polish Michael Rakowski <mrak@gmx.de>
|
||||||
* Spanish Ruben Nunez Francisco <ruben.nunez@tang-it.com>
|
* Spanish Ruben Nunez Francisco <ruben.nunez@tang-it.com>
|
||||||
* Greek Dimitrios Dimitrakos <mail@dimitrios.de>
|
* 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>
|
* Romanian Paul Lacatus <paul@campina.iiruc.ro>
|
||||||
* Hungarian Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
|
* 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
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Inspelningskommandon",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -950,7 +950,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"Källa",
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
},
|
},
|
||||||
@ -1126,7 +1126,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Bandwidth",
|
"Bandwidth",
|
||||||
"Bandwidth",
|
"Bandwidth",
|
||||||
"Bandwidth",
|
"Bandwidth",
|
||||||
"Bandwidth",
|
"Bandbredd",
|
||||||
"Bandwidth",
|
"Bandwidth",
|
||||||
"Bandwidth",
|
"Bandwidth",
|
||||||
},
|
},
|
||||||
@ -1496,7 +1496,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"Kanalen ej tillgänglig!",
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
},
|
},
|
||||||
@ -1512,7 +1512,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"Kanalinställningarna är ej unika!",
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
},
|
},
|
||||||
@ -2042,7 +2042,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Transponder do ustawiania czasu",
|
"Transponder do ustawiania czasu",
|
||||||
"Transponder para reloj de sistema",
|
"Transponder para reloj de sistema",
|
||||||
"Transponder gia sintonismo tis oras",
|
"Transponder gia sintonismo tis oras",
|
||||||
"Använd klockan från fransponder",
|
"Använd klockan från transponder",
|
||||||
"Preia ceasul din transponder",
|
"Preia ceasul din transponder",
|
||||||
"Idöhöz tartozó Transponder",
|
"Idöhöz tartozó Transponder",
|
||||||
},
|
},
|
||||||
@ -2700,7 +2700,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Paina 'Ylös' tallettaaksesi ja 'Alas' peruuttaaksesi",
|
"Paina 'Ylös' tallettaaksesi ja 'Alas' peruuttaaksesi",
|
||||||
"'Gora' zapamietuje, 'Dol' przerywa",
|
"'Gora' zapamietuje, 'Dol' przerywa",
|
||||||
"Pulse 'Arriba' para guarder, 'Abajo' para anular",
|
"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",
|
"Tryck 'Upp' för att spara, 'Ner' för att avsluta",
|
||||||
"Apsati 'Sus' pentru salvare, 'Jos' pentru anulare",
|
"Apsati 'Sus' pentru salvare, 'Jos' pentru anulare",
|
||||||
"'Fel' mentés, 'Le´ mégse",
|
"'Fel' mentés, 'Le´ mégse",
|
||||||
@ -2894,7 +2894,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Spela upp",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -2910,7 +2910,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Pausa",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -2926,7 +2926,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Stoppa",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -2942,7 +2942,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Spela in",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -2958,7 +2958,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Spola framåt",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -2974,7 +2974,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Spola bakåt",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -3006,7 +3006,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Kanal+",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -3022,7 +3022,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Kanal-",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
@ -3119,7 +3119,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"av",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
},
|
},
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
CC = gcc
|
CC ?= gcc
|
||||||
CFLAGS = -O2 -g -pedantic -Wmissing-prototypes -Wstrict-prototypes \
|
CFLAGS ?= -O2 -g -pedantic -Wmissing-prototypes -Wstrict-prototypes \
|
||||||
-Wimplicit -D__USE_FIXED_PROTOTYPES__ # -DDEBUG
|
-Wimplicit -D__USE_FIXED_PROTOTYPES__ # -DDEBUG
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,8 +29,9 @@
|
|||||||
#
|
#
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS ?= -O2 -g -Wmissing-prototypes -Wstrict-prototypes \
|
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
|
AR = ar
|
||||||
ARFLAGS = r
|
ARFLAGS = r
|
||||||
|
12
menu.c
12
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#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
|
//XXX this is just quick and dirty - make this a separate display object
|
||||||
cMenuCamEnquiry::cMenuCamEnquiry(cCiEnquiry *CiEnquiry)
|
cMenuCamEnquiry::cMenuCamEnquiry(cCiEnquiry *CiEnquiry)
|
||||||
:cOsdMenu("")
|
:cOsdMenu("", 10)
|
||||||
{
|
{
|
||||||
ciEnquiry = CiEnquiry;
|
ciEnquiry = CiEnquiry;
|
||||||
|
int Length = ciEnquiry->ExpectedLength();
|
||||||
|
input = MALLOC(char, Length + 1);
|
||||||
|
*input = 0;
|
||||||
replied = false;
|
replied = false;
|
||||||
SetTitle(ciEnquiry->Text() ? ciEnquiry->Text() : "CAM");
|
SetTitle(ciEnquiry->Text() ? ciEnquiry->Text() : "CAM");
|
||||||
|
Add(new cMenuEditNumItem("Input", input, Length, ciEnquiry->Blind()));
|
||||||
Display();
|
Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,12 +1588,14 @@ cMenuCamEnquiry::~cMenuCamEnquiry()
|
|||||||
{
|
{
|
||||||
if (!replied)
|
if (!replied)
|
||||||
ciEnquiry->Cancel();
|
ciEnquiry->Cancel();
|
||||||
|
free(input);
|
||||||
delete ciEnquiry;
|
delete ciEnquiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuCamEnquiry::Reply(void)
|
eOSState cMenuCamEnquiry::Reply(void)
|
||||||
{
|
{
|
||||||
ciEnquiry->Reply("1234");//XXX implement actual user input
|
//XXX check length???
|
||||||
|
ciEnquiry->Reply(input);
|
||||||
replied = true;
|
replied = true;
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
|
3
menu.h
3
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __MENU_H
|
||||||
@ -73,6 +73,7 @@ public:
|
|||||||
class cMenuCamEnquiry : public cOsdMenu {
|
class cMenuCamEnquiry : public cOsdMenu {
|
||||||
private:
|
private:
|
||||||
cCiEnquiry *ciEnquiry;
|
cCiEnquiry *ciEnquiry;
|
||||||
|
char *input;
|
||||||
bool replied;
|
bool replied;
|
||||||
eOSState Reply(void);
|
eOSState Reply(void);
|
||||||
public:
|
public:
|
||||||
|
56
menuitems.c
56
menuitems.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menuitems.h"
|
||||||
@ -109,6 +109,60 @@ void cMenuEditBoolItem::Set(void)
|
|||||||
SetValue(buf);
|
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::cMenuEditChrItem(const char *Name, char *Value, const char *Allowed)
|
cMenuEditChrItem::cMenuEditChrItem(const char *Name, char *Value, const char *Allowed)
|
||||||
|
13
menuitems.h
13
menuitems.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __MENUITEMS_H
|
||||||
@ -42,6 +42,17 @@ public:
|
|||||||
cMenuEditBoolItem(const char *Name, int *Value, const char *FalseString = NULL, const char *TrueString = NULL);
|
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 {
|
class cMenuEditChrItem : public cMenuEditItem {
|
||||||
private:
|
private:
|
||||||
char *value;
|
char *value;
|
||||||
|
18
recorder.c
18
recorder.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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>
|
#include <stdarg.h>
|
||||||
@ -41,7 +41,7 @@ cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int A
|
|||||||
|
|
||||||
SpinUpDisk(FileName);
|
SpinUpDisk(FileName);
|
||||||
|
|
||||||
ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true);
|
ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
|
||||||
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true);
|
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true);
|
||||||
fileName = new cFileName(FileName, true);
|
fileName = new cFileName(FileName, true);
|
||||||
recordFile = fileName->Open();
|
recordFile = fileName->Open();
|
||||||
@ -110,16 +110,14 @@ void cRecorder::Action(void)
|
|||||||
{
|
{
|
||||||
dsyslog("recording thread started (pid=%d)", getpid());
|
dsyslog("recording thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
uchar b[MINVIDEODATA];
|
|
||||||
int r = 0;
|
|
||||||
active = true;
|
active = true;
|
||||||
while (active) {
|
while (active) {
|
||||||
int g = ringBuffer->Get(b + r, sizeof(b) - r);
|
int r;
|
||||||
if (g > 0)
|
const uchar *b = ringBuffer->Get(r);
|
||||||
r += g;
|
if (b) {
|
||||||
if (r > 0) {
|
|
||||||
int Count = r, Result;
|
int Count = r, Result;
|
||||||
uchar *p = remux->Process(b, Count, Result, &pictureType);
|
uchar *p = remux->Process(b, Count, Result, &pictureType);
|
||||||
|
ringBuffer->Del(Count);
|
||||||
if (p) {
|
if (p) {
|
||||||
//XXX+ active??? see old version (Busy)
|
//XXX+ active??? see old version (Busy)
|
||||||
if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame
|
if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame
|
||||||
@ -136,10 +134,6 @@ void cRecorder::Action(void)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Count > 0) {
|
|
||||||
r -= Count;
|
|
||||||
memmove(b, b + Count, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usleep(1); // this keeps the CPU load low
|
usleep(1); // this keeps the CPU load low
|
||||||
|
43
remux.c
43
remux.c
@ -8,7 +8,7 @@
|
|||||||
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
|
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
|
||||||
* VDR's needs.
|
* 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
|
/* The calling interface of the 'cRemux::Process()' function is defined
|
||||||
@ -97,14 +97,16 @@
|
|||||||
#define PTS_ONLY 0x80
|
#define PTS_ONLY 0x80
|
||||||
|
|
||||||
#define TS_SIZE 188
|
#define TS_SIZE 188
|
||||||
#define PAY_START 0x40
|
|
||||||
#define PID_MASK_HI 0x1F
|
#define PID_MASK_HI 0x1F
|
||||||
//flags
|
#define CONT_CNT_MASK 0x0F
|
||||||
#define ADAPT_FIELD 0x20
|
|
||||||
//XXX TODO
|
|
||||||
|
|
||||||
#define MAX_PLENGTH 0xFFFF
|
// Flags:
|
||||||
#define MMAX_PLENGTH (4*MAX_PLENGTH)
|
#define PAY_START 0x40
|
||||||
|
#define TS_ERROR 0x80
|
||||||
|
#define ADAPT_FIELD 0x20
|
||||||
|
|
||||||
|
#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
|
#define IPACKS 2048
|
||||||
|
|
||||||
@ -132,6 +134,9 @@ private:
|
|||||||
bool done;
|
bool done;
|
||||||
uint8_t *resultBuffer;
|
uint8_t *resultBuffer;
|
||||||
int *resultCount;
|
int *resultCount;
|
||||||
|
int tsErrors;
|
||||||
|
int ccErrors;
|
||||||
|
int ccCounter;
|
||||||
static uint8_t headr[];
|
static uint8_t headr[];
|
||||||
void store(uint8_t *Data, int Count);
|
void store(uint8_t *Data, int Count);
|
||||||
void reset_ipack(void);
|
void reset_ipack(void);
|
||||||
@ -154,6 +159,10 @@ cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t Audi
|
|||||||
size = Size;
|
size = Size;
|
||||||
audioCid = AudioCid;
|
audioCid = AudioCid;
|
||||||
|
|
||||||
|
tsErrors = 0;
|
||||||
|
ccErrors = 0;
|
||||||
|
ccCounter = -1;
|
||||||
|
|
||||||
if (!(buf = MALLOC(uint8_t, size)))
|
if (!(buf = MALLOC(uint8_t, size)))
|
||||||
esyslog("Not enough memory for ts_transform");
|
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()
|
cTS2PES::~cTS2PES()
|
||||||
{
|
{
|
||||||
|
if (tsErrors || ccErrors)
|
||||||
|
dsyslog("cTS2PES got %d TS errors, %d TS continuity errors", tsErrors, ccErrors);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +395,8 @@ void cTS2PES::instant_repack(const uint8_t *Buf, int Count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (plength && found == plength + 6) {
|
if (plength && found == plength + 6) {
|
||||||
|
if (plength == MMAX_PLENGTH - 6)
|
||||||
|
esyslog("ERROR: PES packet length overflow in remuxer (stream corruption)");
|
||||||
send_ipack();
|
send_ipack();
|
||||||
reset_ipack();
|
reset_ipack();
|
||||||
if (c < Count)
|
if (c < Count)
|
||||||
@ -398,6 +411,22 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188)
|
|||||||
if (!Buf)
|
if (!Buf)
|
||||||
return;
|
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 (Buf[1] & PAY_START) {
|
||||||
if (plength == MMAX_PLENGTH - 6 && found > 6) {
|
if (plength == MMAX_PLENGTH - 6 && found > 6) {
|
||||||
plength = found - 6;
|
plength = found - 6;
|
||||||
|
98
ringbuffer.c
98
ringbuffer.c
@ -7,7 +7,7 @@
|
|||||||
* Parts of this file were inspired by the 'ringbuffy.c' from the
|
* Parts of this file were inspired by the 'ringbuffy.c' from the
|
||||||
* LinuxDVB driver (see linuxtv.org).
|
* 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"
|
#include "ringbuffer.h"
|
||||||
@ -57,13 +57,14 @@ void cRingBuffer::EnableGet(void)
|
|||||||
|
|
||||||
// --- cRingBufferLinear -----------------------------------------------------
|
// --- cRingBufferLinear -----------------------------------------------------
|
||||||
|
|
||||||
cRingBufferLinear::cRingBufferLinear(int Size, bool Statistics)
|
cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics)
|
||||||
:cRingBuffer(Size, Statistics)
|
:cRingBuffer(Size, Statistics)
|
||||||
{
|
{
|
||||||
|
margin = Margin;
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
getThreadPid = -1;
|
getThreadPid = -1;
|
||||||
if (Size > 1) { // 'Size - 1' must not be 0!
|
if (Size > 1) { // 'Size - 1' must not be 0!
|
||||||
buffer = new uchar[Size];
|
buffer = MALLOC(uchar, Size);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
esyslog("ERROR: can't allocate ring buffer (size=%d)", Size);
|
esyslog("ERROR: can't allocate ring buffer (size=%d)", Size);
|
||||||
Clear();
|
Clear();
|
||||||
@ -74,7 +75,7 @@ cRingBufferLinear::cRingBufferLinear(int Size, bool Statistics)
|
|||||||
|
|
||||||
cRingBufferLinear::~cRingBufferLinear()
|
cRingBufferLinear::~cRingBufferLinear()
|
||||||
{
|
{
|
||||||
delete buffer;
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRingBufferLinear::Available(void)
|
int cRingBufferLinear::Available(void)
|
||||||
@ -82,13 +83,14 @@ int cRingBufferLinear::Available(void)
|
|||||||
Lock();
|
Lock();
|
||||||
int diff = head - tail;
|
int diff = head - tail;
|
||||||
Unlock();
|
Unlock();
|
||||||
return (diff >= 0) ? diff : Size() + diff;
|
return (diff >= 0) ? diff : Size() + diff - margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRingBufferLinear::Clear(void)
|
void cRingBufferLinear::Clear(void)
|
||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
head = tail = 0;
|
head = tail = margin;
|
||||||
|
lastGet = -1;
|
||||||
Unlock();
|
Unlock();
|
||||||
EnablePut();
|
EnablePut();
|
||||||
EnableGet();
|
EnableGet();
|
||||||
@ -100,7 +102,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
|
|||||||
Lock();
|
Lock();
|
||||||
int rest = Size() - head;
|
int rest = Size() - head;
|
||||||
int diff = tail - 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) {
|
if (statistics) {
|
||||||
int fill = Size() - free - 1 + Count;
|
int fill = Size() - free - 1 + Count;
|
||||||
if (fill >= Size())
|
if (fill >= Size())
|
||||||
@ -122,8 +124,8 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
|
|||||||
if (Count >= rest) {
|
if (Count >= rest) {
|
||||||
memcpy(buffer + head, Data, rest);
|
memcpy(buffer + head, Data, rest);
|
||||||
if (Count - rest)
|
if (Count - rest)
|
||||||
memcpy(buffer, Data + rest, Count - rest);
|
memcpy(buffer + margin, Data + rest, Count - rest);
|
||||||
head = Count - rest;
|
head = margin + Count - rest;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(buffer + head, Data, Count);
|
memcpy(buffer + head, Data, Count);
|
||||||
@ -138,50 +140,60 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
|
|||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRingBufferLinear::Get(uchar *Data, int Count)
|
const uchar *cRingBufferLinear::Get(int &Count)
|
||||||
{
|
{
|
||||||
if (Count > 0) {
|
const uchar *p = NULL;
|
||||||
Lock();
|
Lock();
|
||||||
if (getThreadPid < 0)
|
if (getThreadPid < 0)
|
||||||
getThreadPid = getpid();
|
getThreadPid = getpid();
|
||||||
int rest = Size() - tail;
|
int rest = Size() - tail;
|
||||||
int diff = head - tail;
|
if (tail > Size() - margin && head < tail) {
|
||||||
int cont = (diff >= 0) ? diff : Size() + diff;
|
int t = margin - rest;
|
||||||
if (rest > 0) {
|
memcpy(buffer + t, buffer + tail, rest);
|
||||||
if (cont < Count)
|
tail = t;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
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::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
|
cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
|
||||||
{
|
{
|
||||||
count = Count;
|
count = abs(Count);
|
||||||
type = Type;
|
type = Type;
|
||||||
index = Index;
|
index = Index;
|
||||||
data = new uchar[count];
|
if (Count < 0)
|
||||||
if (data)
|
data = (uchar *)Data;
|
||||||
memcpy(data, Data, count);
|
else {
|
||||||
else
|
data = new uchar[count];
|
||||||
esyslog("ERROR: can't allocate frame buffer (count=%d)", count);
|
if (data)
|
||||||
|
memcpy(data, Data, count);
|
||||||
|
else
|
||||||
|
esyslog("ERROR: can't allocate frame buffer (count=%d)", count);
|
||||||
|
}
|
||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
ringbuffer.h
31
ringbuffer.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __RINGBUFFER_H
|
||||||
@ -40,21 +40,31 @@ public:
|
|||||||
|
|
||||||
class cRingBufferLinear : public cRingBuffer {
|
class cRingBufferLinear : public cRingBuffer {
|
||||||
private:
|
private:
|
||||||
int head, tail;
|
int margin, head, tail;
|
||||||
|
int lastGet;
|
||||||
uchar *buffer;
|
uchar *buffer;
|
||||||
pid_t getThreadPid;
|
pid_t getThreadPid;
|
||||||
public:
|
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 ~cRingBufferLinear();
|
||||||
virtual int Available(void);
|
virtual int Available(void);
|
||||||
virtual void Clear(void);
|
virtual void Clear(void);
|
||||||
// Immediately clears the ring buffer.
|
///< Immediately clears the ring buffer.
|
||||||
int Put(const uchar *Data, int Count);
|
int Put(const uchar *Data, int Count);
|
||||||
// Puts at most Count bytes of Data into the ring buffer.
|
///< Puts at most Count bytes of Data into the ring buffer.
|
||||||
// Returns the number of bytes actually stored.
|
///< \return Returns the number of bytes actually stored.
|
||||||
int Get(uchar *Data, int Count);
|
const uchar *Get(int &Count);
|
||||||
// Gets at most Count bytes of Data from the ring buffer.
|
///< Gets data from the ring buffer.
|
||||||
// Returns the number of bytes actually retrieved.
|
///< 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 };
|
enum eFrameType { ftUnknown, ftVideo, ftAudio, ftDolby };
|
||||||
@ -69,6 +79,9 @@ private:
|
|||||||
int index;
|
int index;
|
||||||
public:
|
public:
|
||||||
cFrame(const uchar *Data, int Count, eFrameType = ftUnknown, int Index = -1);
|
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();
|
~cFrame();
|
||||||
const uchar *Data(void) const { return data; }
|
const uchar *Data(void) const { return data; }
|
||||||
int Count(void) const { return count; }
|
int Count(void) const { return count; }
|
||||||
|
19
transfer.c
19
transfer.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "transfer.h"
|
||||||
@ -19,7 +19,7 @@
|
|||||||
cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
|
cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
|
||||||
:cReceiver(0, -1, 5, VPid, APid1, APid2, DPid1, 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);
|
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
|
||||||
canToggleAudioTrack = false;
|
canToggleAudioTrack = false;
|
||||||
audioTrack = 0xC0;
|
audioTrack = 0xC0;
|
||||||
@ -60,8 +60,6 @@ void cTransfer::Action(void)
|
|||||||
{
|
{
|
||||||
dsyslog("transfer thread started (pid=%d)", getpid());
|
dsyslog("transfer thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
uchar b[MINVIDEODATA];
|
|
||||||
int r = 0;
|
|
||||||
active = true;
|
active = true;
|
||||||
while (active) {
|
while (active) {
|
||||||
|
|
||||||
@ -80,15 +78,15 @@ void cTransfer::Action(void)
|
|||||||
|
|
||||||
// Get data from the buffer:
|
// Get data from the buffer:
|
||||||
|
|
||||||
int g = ringBuffer->Get(b + r, sizeof(b) - r);
|
int r;
|
||||||
if (g > 0)
|
const uchar *b = ringBuffer->Get(r);
|
||||||
r += g;
|
|
||||||
|
|
||||||
// Play the data:
|
// Play the data:
|
||||||
|
|
||||||
if (r > 0) {
|
if (b) {
|
||||||
int Count = r, Result;
|
int Count = r, Result;
|
||||||
uchar *p = remux->Process(b, Count, Result);
|
uchar *p = remux->Process(b, Count, Result);
|
||||||
|
ringBuffer->Del(Count);
|
||||||
if (p) {
|
if (p) {
|
||||||
StripAudioPackets(p, Result, audioTrack);
|
StripAudioPackets(p, Result, audioTrack);
|
||||||
while (Result > 0 && active) {
|
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
|
else
|
||||||
usleep(1); // this keeps the CPU load low
|
usleep(1); // this keeps the CPU load low
|
||||||
|
4
vdr.c
4
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
* 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>
|
#include <getopt.h>
|
||||||
@ -160,7 +160,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!p)
|
if (!p)
|
||||||
break;
|
break;
|
||||||
if (isnumber(p + 1)) {
|
if (isnumber(p + 1)) {
|
||||||
int l = atoi(optarg);
|
int l = atoi(p + 1);
|
||||||
if (0 <= l && l <= 7) {
|
if (0 <= l && l <= 7) {
|
||||||
int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
|
int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
|
||||||
SysLogTarget = targets[l];
|
SysLogTarget = targets[l];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user