Commit f84e734a authored by Tobias Grimm's avatar Tobias Grimm

New upstream version 2.4.1

parent 8d596e3c
......@@ -283,6 +283,8 @@ Uwe Scheffler <linux_dvb@uni.de>
for reporting a problem in handling the PrimaryLimit when requesting a device for
live viewing
for reporting a black screen while a "Recording started" message is displayed
for reporting a problem with the lock on the Channels list in cDisplayChannel still
being held when Flush() was called
Matjaz Thaler <matjaz.thaler@guest.arnes.si>
for improving AC3 decoding when replaying DVDs
......@@ -2270,6 +2272,7 @@ J
in cKbdRemote
for reporting a possible discrepancy of the primary device number in the LSTD and
PRIM commands
for adding support for EAC3 audio from other sources
Christian Wieninger <cwieninger@gmx.de>
for suggesting to add cMenuEditStrItem::InEditMode()
......@@ -2854,6 +2857,7 @@ Johann Friedrichs <johann.friedrichs@web.de>
replay has been stopped, but before the replay control has been destroyed
for reporting a problem in processing SVDRP client responses in case the caller doesn't
want the actual response strings
for reporting a bug in handling the tfRecording flag in the SVDRP commands MODT and UPDT
Timo Helkio <timolavi@mbnet.fi>
for reporting a hangup when replaying a TS recording with subtitles activated
......@@ -3124,6 +3128,7 @@ Chris Mayo <aklhfex@gmail.com>
for updating links in the INSTALL file
for reporting double slashes in file names processed with AddDirectory()
for using the 'example' macro in vdr.5
for fixing the install target in case of multiple jobs
Dominic Evans <oldmanuk@gmail.com>
for making the SVDRP command LSTC accepts channel IDs
......@@ -3315,6 +3320,8 @@ Matthias Senzel <matthias.senzel@t-online.de>
after starting the editing process
for reporting a problem with setting the initial offset of the cursor in a list menu
for reporting a high CPU load during replay with active progress display
for reporting that the lock on the Channels list in cDisplayChannel was still held
when Flush() was called
Marek Nazarko <mnazarko@gmail.com>
for translating OSD texts to the Polish language
......@@ -3539,6 +3546,7 @@ Stefan P
Robert Hannebauer <vdr@hannebauer.org>
for fixing an overflow of PIDs in a receiver
for fixing opening the UDP port in peerdemo
Aitugan Sarbassov <isarbassov@gmail.com>
for adding 'S58.5E Kazsat 3' to sources.conf
......@@ -3558,6 +3566,29 @@ Daniel Scheller <d.scheller@gmx.net>
Onur Sentürk <onur@sentek.org>
for making the MTD mapper avoid immediately reusing unique PIDs when switching channels
for fixing handling shared CA pids
for fixing handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
in "backwards compatibility mode" according to ETSI EN 300 468
Helmut Binder <cco@aon.at>
for improving calculating signal strength and quality
for fixing switching through encrypted channels with the Up/Down keys
for deactivating MTD support if a non MCD capable CAM is inserted after removing
a previously used CAM that is MCD capable
for fixing accessing the actual frontend on multi frontend devices
for fixing processing the last entry in the scan list of the EIT scanner
for fixing processing transponder data in the NIT
for fixing triggering the SDT filter when parsing the NIT
for reporting a bug in processing SI::T2DeliverySystemDescriptor when typecasting it
over an SI::ExtensionDescriptor
for fixing mapping SIDs in MTD
for fixing updating the checksum in the CA table after mapping EMM PIDs for MTD
for fixing a compiler warning in ExchangeChars()
for suggesting to add __attribute__((packed)) to tIndexPes and tIndexTs
Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is
keeping the OSD open
Stian B. Barmen <stian@barmen.nu>
for reporting missing EPG data on channels from Canal Digital Norway
......@@ -9347,3 +9347,75 @@ Video Disk Recorder Revision History
- Fixed a high CPU load during replay with active progress display (reported by Matthias
Senzel).
- Official release.
2019-06-17: Version 2.4.1
- Fixed handling the tfRecording flag in the SVDRP commands MODT and UPDT (reported
by Johann Friedrichs).
- Fixed a possible invalid locking sequence in case a remote timer handling error message
is displayed on the OSD and the skin tries to lock the Recordings or DeletedRecordings
list in its Flush() function (for instance by calling cVideoDiskUsage::HasChanged()).
To do this, the call to Skins.Message() in menu.c's HandleRemoteModifications() has
been changed to Skins.QueueMessage(), and cSkins::ProcessQueuedMessages() is now called
unconditionally in the main loop, and checks whether the current cSkinDisplay object
(if any) implements SetMessage().
- Fixed locking the Channels list in cDisplayChannel, where the lock was still held
when Flush() was called (reported by Matthias Senzel and Uwe Scheffler).
- Fixed shutdown after user inactivity in case a plugin is keeping the OSD open
(reported by Ulrich Eckhardt).
- Fixed switching through encrypted channels with the Up/Down keys (thanks to Helmut
Binder).
- Now deactivating MTD support if a non MCD capable CAM is inserted after removing
a previously used CAM that is MCD capable (thanks to Helmut Binder).
- Added support for DVB devices with more than one frontend that all use the same
dvr and demux. Note that in order for this to work, you must not set symbolic
links like "demux1 -> demux0" and "dvr1 -> dvr0", as is mentioned in some user
manuals of multi frontend DVB cards.
- Reverted the change "The EIT filter no longer parses data from "other TS"...". It led to
missing EPG data on channels from Canal Digital Norway (reported by Stian B. Barmen).
- Fixed accessing the actual frontend on multi frontend devices (thanks to Helmut Binder).
- Fixed opening the UDP port in peerdemo (thanks to Robert Hannebauer).
- Fixed handling PATs that contain no PMTs.
- Fixed processing the last entry in the scan list of the EIT scanner (thanks to
Helmut Binder).
- Fixed processing transponder data in the NIT (thanks to Helmut Binder).
- Fixed triggering the SDT filter when parsing the NIT (thanks to Helmut Binder).
- Added support for EAC3 audio from other sources (thanks to Jürgen Schneider).
- No longer logging tuning timeouts for transponders that are announced in the NIT but
are not currently broadcasting.
- Fixed processing SI::T2DeliverySystemDescriptor when typecasting it over an
SI::ExtensionDescriptor (reported by Helmut Binder).
- Fixed sorting recordings alphabetically.
- Fixed dropping capabilities in case cap_sys_time is not available.
- Fixed updating the cursor position when switching channels with the Channel+/- keys
while the Channels menu is open.
- Fixed handling shared CA pids (thanks to Onur Sentürk).
- Now touching the .update file in the video directory after removing deleted
recordings, so that other VDRs that use the same video directory will update their
list of (deleted) recordings and thus won't display too much empty disk space.
- Fixed the install target in case of multiple jobs (thanks to Chris Mayo).
- Fixed mapping SIDs in MTD (thanks to Helmut Binder).
- Fixed updating the checksum in the CA table after mapping EMM PIDs for MTD (thanks to
Helmut Binder).
- Fixed a compiler warning in ExchangeChars() (thanks to Helmut Binder).
- Fixed a compiler warning and a possible buffer overflow in cCiMMI::SendAnswer().
- Fixed a possible invalid lock sequence if the main menu is open and the user
switches to a channel that is currently not available, using the Channel+/- keys.
- Fixed handling remote timers in case the response to LSTT is '550 No timers defined'.
- Fixed a compiler warning in cIndexFile::ConvertToPes() and added __attribute__((packed))
to tIndexPes and tIndexTs (suggested by Helmut Binder).
- Fixed handling repeat function for keyboards.
- Added a workaround for broadcasters who set an event to status "not running" where
this is inappropriate; implicitly setting events to "not running" is now also logged.
- Fixed asserting free disk space in case there is no local timer currently recording.
- The default maximum size of a cPixmap has been raised to the maximum possible value.
- Increased PLAYERBUFSIZE to (MAXFRAMESIZE * 5) to avoid stuttering replay under heavy
system load, and to better document that this buffer size is related to the maximum
frame size.
- Fixed inconsistent behavior in case only certain devices are used (selected by the '-D'
option).
- Fixed a wrong variable name in cFileName::cFileName().
- If cSkins::Message() is called from a background thread and Type is not mtStatus,
the call is now automatically forwarded to QueueMessage().
- Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk).
......@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
# $Id: Makefile 4.5 2017/05/29 08:48:42 kls Exp $
# $Id: Makefile 4.5.1.1 2019/05/05 13:37:38 kls Exp $
.DELETE_ON_ERROR:
......@@ -271,7 +271,7 @@ clean-plugins: vdr.pc
# Install the files (note that 'install-pc' must be first!):
install: install-pc install-bin install-dirs install-conf install-doc install-plugins install-i18n install-includes
install: install-pc install-bin install-conf install-doc install-plugins install-i18n install-includes
# VDR binary:
......@@ -288,7 +288,7 @@ install-dirs:
@mkdir -p $(DESTDIR)$(CACHEDIR)
@mkdir -p $(DESTDIR)$(RESDIR)
install-conf:
install-conf: install-dirs
@cp -pn *.conf $(DESTDIR)$(CONFDIR)
# Documentation:
......
......@@ -141,3 +141,7 @@ VDR Plugin 'skincurses' Revision History
2018-04-15: Version 2.4.0
- Official release.
2019-03-12: Version 2.4.1
- Changes for ncurses version 6 (thanks to Ulrick Eckhardt).
......@@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
* $Id: skincurses.c 4.3 2018/04/10 13:01:00 kls Exp $
* $Id: skincurses.c 4.3.1.1 2019/03/12 12:28:04 kls Exp $
*/
#include <ncurses.h>
......@@ -12,7 +12,7 @@
#include <vdr/skins.h>
#include <vdr/videodir.h>
static const char *VERSION = "2.4.0";
static const char *VERSION = "2.4.1";
static const char *DESCRIPTION = trNOOP("A text only skin");
static const char *MAINMENUENTRY = NULL;
......@@ -127,8 +127,12 @@ void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
void cCursesOsd::RestoreRegion(void)
{
int begy, begx;
int maxy, maxx;
getmaxyx(savedRegion, maxy,maxx);
getbegyx(savedRegion, begy,begx);
if (savedRegion) {
copywin(savedRegion, window, 0, 0, savedRegion->_begy, savedRegion->_begx, savedRegion->_maxy - savedRegion->_begy, savedRegion->_maxx - savedRegion->_begx, false);
copywin(savedRegion, window, 0, 0, begy, begx, maxy - begy, maxx - begx, false);
delwin(savedRegion);
savedRegion = NULL;
}
......@@ -828,9 +832,13 @@ bool cPluginSkinCurses::Initialize(void)
{
// Initialize any background activities the plugin shall perform.
WINDOW *w = initscr();
int begy, begx;
int maxy, maxx;
getmaxyx(w, maxy,maxx);
getbegyx(w, begy,begx);
if (w) {
ScOsdWidth = w->_maxx - w->_begx + 1;
ScOsdHeight = w->_maxy - w->_begy + 1;
ScOsdWidth = maxx - begx + 1;
ScOsdHeight = maxy - begy + 1;
return true;
}
return false;
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.c 4.21 2018/03/19 16:37:03 kls Exp $
* $Id: ci.c 4.21.1.5 2019/05/28 15:55:44 kls Exp $
*/
#include "ci.h"
......@@ -225,7 +225,7 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length)
}
else {
esyslog("ERROR: buffer overflow in cCaPidReceiver::Receive()");
bufp = 0;
bufp = NULL;
length = 0;
}
}
......@@ -250,12 +250,22 @@ void cCaPidReceiver::Receive(const uchar *Data, int Length)
i += p[i + 1] + 2 - 1; // -1 to compensate for the loop increment
}
}
if (MtdCamSlot) {
if (!bufp && length) {
// update crc32 - but only single packet CAT is handled for now:
uint32_t crc = SI::CRC32::crc32((const char *)p - 8, length + 8 - 4, 0xFFFFFFFF); // <TableIdCAT....>[crc32]
uchar *c = const_cast<uchar *>(p + length - 4);
*c++ = crc >> 24;
*c++ = crc >> 16;
*c++ = crc >> 8;
*c++ = crc;
}
memcpy(mtdCatBuffer, Data, TS_SIZE);
MtdCamSlot->PutCat(mtdCatBuffer, TS_SIZE);
}
p = NULL;
bufp = 0;
bufp = NULL;
length = 0;
memcpy(mtdCatBuffer, Data, TS_SIZE);
if (MtdCamSlot)
MtdCamSlot->PutCat(mtdCatBuffer, TS_SIZE);
}
}
}
......@@ -1213,6 +1223,7 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
}
else {
dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber());
CamSlot()->MtdActivate(false);
state = 4; // normal operation
}
}
......@@ -1580,9 +1591,12 @@ bool cCiMMI::SendAnswer(const char *Text)
struct tAnswer { uint8_t id; char text[256]; };//XXX
tAnswer answer;
answer.id = Text ? AI_ANSWER : AI_CANCEL;
if (Text)
strncpy(answer.text, Text, sizeof(answer.text));
SendData(AOT_ANSW, Text ? strlen(Text) + 1 : 1, (uint8_t *)&answer);
int len = 0;
if (Text) {
len = min(sizeof(answer.text), strlen(Text));
memcpy(answer.text, Text, len);
}
SendData(AOT_ANSW, len + 1, (uint8_t *)&answer);
return true;
}
......@@ -2219,14 +2233,14 @@ bool cCamSlot::Assign(cDevice *Device, bool Query)
return false;
}
bool cCamSlot::Devices(cVector<int> &CardIndexes)
bool cCamSlot::Devices(cVector<int> &DeviceNumbers)
{
cMutexLock MutexLock(&mutex);
if (mtdHandler)
return mtdHandler->Devices(CardIndexes);
return mtdHandler->Devices(DeviceNumbers);
if (assignedDevice)
CardIndexes.Append(assignedDevice->CardIndex());
return CardIndexes.Size() > 0;
DeviceNumbers.Append(assignedDevice->DeviceNumber());
return DeviceNumbers.Size() > 0;
}
void cCamSlot::NewConnection(void)
......@@ -2504,8 +2518,10 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M
if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids) > 0) {
if (Active)
caPidReceiver->AddPids(CaPids);
else
else {
KeepSharedCaPids(p->programNumber, CaSystemIds, CaPids);
caPidReceiver->DelPids(CaPids);
}
}
}
if (RepliesToQuery())
......@@ -2521,6 +2537,43 @@ void cCamSlot::BuildCaPmts(uint8_t CmdId, cCiCaPmtList &CaPmtList, cMtdMapper *M
}
}
void cCamSlot::KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids)
{
int numPids = 0;
int *pCaPids = CaPids;
while (*pCaPids) {
numPids++;
pCaPids++;
}
if (numPids <= 0)
return;
int CaPids2[MAXRECEIVEPIDS + 1];
for (cCiCaProgramData *p = caProgramList.First(); p; p = caProgramList.Next(p)) {
if (p->programNumber != ProgramNumber) {
if (GetCaPids(source, transponder, p->programNumber, CaSystemIds, MAXRECEIVEPIDS + 1, CaPids2) > 0) {
int *pCaPids2 = CaPids2;
while (*pCaPids2) {
pCaPids = CaPids;
while (*pCaPids) {
if (*pCaPids == *pCaPids2) {
dsyslog("CAM %d: keeping shared CA pid %d", SlotNumber(), *pCaPids);
// To remove *pCaPids from CaPids we overwrite it with the last valie in the list, and then strip the last value:
*pCaPids = CaPids[numPids - 1];
numPids--;
CaPids[numPids] = 0;
if (numPids <= 0)
return;
}
else
pCaPids++;
}
pCaPids2++;
}
}
}
}
}
void cCamSlot::SendCaPmts(cCiCaPmtList &CaPmtList)
{
cMutexLock MutexLock(&mutex);
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.h 4.12 2018/03/17 12:17:37 kls Exp $
* $Id: ci.h 4.12.1.2 2019/05/28 15:55:44 kls Exp $
*/
#ifndef __CI_H
......@@ -254,6 +254,7 @@ private:
cList<cCiCaProgramData> caProgramList;
bool mtdAvailable;
cMtdHandler *mtdHandler;
void KeepSharedCaPids(int ProgramNumber, const int *CaSystemIds, int *CaPids);
void NewConnection(void);
void DeleteAllConnections(void);
void Process(cTPDU *TPDU = NULL);
......@@ -330,9 +331,9 @@ public:
///< class function.
cDevice *Device(void) { return assignedDevice; }
///< Returns the device this CAM slot is currently assigned to.
bool Devices(cVector<int> &CardIndexes);
///< Adds the card indexes of any devices that currently use this CAM to
///< the given CardIndexes. This can be more than one in case of MTD.
bool Devices(cVector<int> &DeviceNumbers);
///< Adds the numbers of any devices that currently use this CAM to
///< the given DeviceNumbers. This can be more than one in case of MTD.
///< Returns true if the array is not empty.
bool WantsTsData(void) const { return caPidReceiver != NULL; }
///< Returns true if this CAM slot wants to receive the TS data through
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 4.15 2018/03/19 15:06:46 kls Exp $
* $Id: config.h 4.15.1.1 2019/06/16 09:13:45 kls Exp $
*/
#ifndef __CONFIG_H
......@@ -22,13 +22,13 @@
// VDR's own version number:
#define VDRVERSION "2.4.0"
#define VDRVERSNUM 20400 // Version * 10000 + Major * 100 + Minor
#define VDRVERSION "2.4.1"
#define VDRVERSNUM 20401 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number:
#define APIVERSION "2.4.0"
#define APIVERSNUM 20400 // Version * 10000 + Major * 100 + Minor
#define APIVERSION "2.4.1"
#define APIVERSNUM 20401 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 4.27 2018/03/24 09:49:14 kls Exp $
* $Id: device.c 4.27.1.3 2019/05/28 15:55:44 kls Exp $
*/
#include "device.h"
......@@ -75,9 +75,9 @@ cDevice::cDevice(void)
:patPmtParser(true)
{
cardIndex = nextCardIndex++;
dsyslog("new device number %d", CardIndex() + 1);
dsyslog("new device number %d (card index %d)", numDevices + 1, CardIndex() + 1);
SetDescription("device %d receiver", CardIndex() + 1);
SetDescription("device %d receiver", numDevices + 1);
mute = false;
volume = Setup.CurrentVolume;
......@@ -230,11 +230,11 @@ static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device)
int MaxNumProvidedSystems = (1 << AvailableBits) - 1;
int NumProvidedSystems = Device->NumProvidedSystems();
if (NumProvidedSystems > MaxNumProvidedSystems) {
esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->DeviceNumber() + 1, NumProvidedSystems, MaxNumProvidedSystems);
NumProvidedSystems = MaxNumProvidedSystems;
}
else if (NumProvidedSystems <= 0) {
esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems);
esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->DeviceNumber() + 1, NumProvidedSystems);
NumProvidedSystems = 1;
}
return NumProvidedSystems;
......@@ -272,7 +272,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
continue; // there is no CAM available in this slot
for (int i = 0; i < numDevices; i++) {
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->DeviceNumber() + 1)
continue; // a specific card was requested, but not this one
bool HasInternalCam = device[i]->HasInternalCam();
if (InternalCamNeeded && !HasInternalCam)
......@@ -525,7 +525,7 @@ void cDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
PixelAspect = 1.0;
}
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", CardIndex(), s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); }
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", DeviceNumber() + 1, s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog("%s", b); }
#define PRINTPIDS(s)
bool cDevice::HasPid(int Pid) const
......@@ -560,7 +560,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
// It's a special PID that may have to be switched into "tap" mode
PRINTPIDS("A");
if (!SetPid(&pidHandles[n], n, true)) {
esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1);
if (PidType <= ptTeletext)
DetachAll(Pid);
DelPid(Pid, PidType);
......@@ -581,7 +581,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
n = a;
}
else {
esyslog("ERROR: no free slot for PID %d on device %d", Pid, CardIndex() + 1);
esyslog("ERROR: no free slot for PID %d on device %d", Pid, DeviceNumber() + 1);
return false;
}
if (n >= 0) {
......@@ -590,7 +590,7 @@ bool cDevice::AddPid(int Pid, ePidType PidType, int StreamType)
pidHandles[n].used = 1;
PRINTPIDS("C");
if (!SetPid(&pidHandles[n], n, true)) {
esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1);
esyslog("ERROR: can't set PID %d on device %d", Pid, DeviceNumber() + 1);
if (PidType <= ptTeletext)
DetachAll(Pid);
DelPid(Pid, PidType);
......@@ -787,6 +787,7 @@ bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
if (LiveView) {
isyslog("switching to channel %d %s (%s)", Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
// and, if decrypted, this removes the now superflous PIDs from the CAM, too
}
for (int i = 3; i--;) {
switch (SetChannel(Channel, LiveView)) {
......@@ -809,6 +810,7 @@ bool cDevice::SwitchChannel(int Direction)
Direction = sgn(Direction);
if (Direction) {
cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
// and, if decrypted, this removes the now superflous PIDs from the CAM, too
int n = CurrentChannel() + Direction;
int first = n;
LOCK_CHANNELS_READ;
......@@ -829,7 +831,7 @@ bool cDevice::SwitchChannel(int Direction)
result = true;
}
else if (n != first)
Skins.Message(mtError, tr("Channel not available!"));
Skins.QueueMessage(mtError, tr("Channel not available!"));
}
return result;
}
......@@ -1756,7 +1758,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
#ifdef WAIT_FOR_TUNER_LOCK
#define TUNER_LOCK_TIMEOUT 5000 // ms
if (!HasLock(TUNER_LOCK_TIMEOUT)) {
esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1);
esyslog("ERROR: device %d has no lock, can't attach receiver!", DeviceNumber() + 1);
return false;
}
#endif
......@@ -1847,11 +1849,11 @@ void cDevice::DetachAllReceivers(void)
// --- cTSBuffer -------------------------------------------------------------
cTSBuffer::cTSBuffer(int File, int Size, int CardIndex)
cTSBuffer::cTSBuffer(int File, int Size, int DeviceNumber)
{
SetDescription("device %d TS buffer", CardIndex);
SetDescription("device %d TS buffer", DeviceNumber);
f = File;
cardIndex = CardIndex;
deviceNumber = DeviceNumber;
delivered = 0;
ringBuffer = new cRingBufferLinear(Size, TS_SIZE, true, "TS");
ringBuffer->SetTimeouts(100, 100);
......@@ -1876,7 +1878,7 @@ void cTSBuffer::Action(void)
int r = ringBuffer->Read(f);
if (r < 0 && FATALERRNO) {
if (errno == EOVERFLOW)
esyslog("ERROR: driver buffer overflow on device %d", cardIndex);
esyslog("ERROR: driver buffer overflow on device %d", deviceNumber);
else {
LOG_ERROR;
break;
......@@ -1907,7 +1909,7 @@ uchar *cTSBuffer::Get(int *Available, bool CheckAvailable)
}
}
ringBuffer->Del(Count);
esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, cardIndex);
esyslog("ERROR: skipped %d bytes to sync on TS packet on device %d", Count, deviceNumber);
return NULL;
}
delivered = TS_SIZE;
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.h 4.12 2017/11/02 14:47:33 kls Exp $
* $Id: device.h 4.12.1.1 2019/05/28 15:55:44 kls Exp $
*/
#ifndef __DEVICE_H
......@@ -861,12 +861,12 @@ public:
class cTSBuffer : public cThread {
private:
int f;
int cardIndex;
int deviceNumber;
int delivered;
cRingBufferLinear *ringBuffer;
virtual void Action(void);
public:
cTSBuffer(int File, int Size, int CardIndex);
cTSBuffer(int File, int Size, int DeviceNumber);
virtual ~cTSBuffer();
uchar *Get(int *Available = NULL, bool CheckAvailable = false);
///< Returns a pointer to the first TS packet in the buffer. If Available is given,
......
This diff is collapsed.
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.h 4.4 2017/05/09 11:24:47 kls Exp $
* $Id: dvbdevice.h 4.4.1.2 2019/03/10 12:18:02 kls Exp $
*/
#ifndef __DVBDEVICE_H
......@@ -67,8 +67,6 @@ enum {
// --- End of definitions for older DVB API versions -------------------------
#define MAXDELIVERYSYSTEMS 8
#define DEV_VIDEO "/dev/video"
#define DEV_DVB_BASE "/dev/dvb"
#define DEV_DVB_ADAPTER "adapter"
......@@ -162,12 +160,12 @@ public:
class cDvbTuner;
cString DvbName(const char *Name, int Adapter, int Frontend);
int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false);
/// The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
class cDvbDevice : public cDevice {
protected:
static cString DvbName(const char *Name, int Adapter, int Frontend);
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError = false);
private:
static bool Exists(int Adapter, int Frontend);
///< Checks whether the given adapter/frontend exists.
......@@ -182,21 +180,16 @@ public:
protected:
int adapter, frontend;
private:
dvb_frontend_info frontendInfo;
int deliverySystems[MAXDELIVERYSYSTEMS];
int numDeliverySystems;
int numModulations;
int fd_dvr, fd_ca;
bool checkTsBuffer;
static cMutex bondMutex;
cDvbDevice *bondedDevice;
mutable bool needsDetachBondedReceivers;
bool QueryDeliverySystems(int fd_frontend);
public:
cDvbDevice(int Adapter, int Frontend);
virtual ~cDvbDevice();
int Adapter(void) const { return adapter; }
int Frontend(void) const { return frontend; }
int Frontend(void) const;
virtual cString DeviceType(void) const;
virtual cString DeviceName(void) const;
static bool BondDevices(const char *Bondings);
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbplayer.c 4.5 2017/11/26 14:55:03 kls Exp $
* $Id: dvbplayer.c 4.5.1.1 2019/05/28 09:27:32 kls Exp $
*/
#include "dvbplayer.h"
......@@ -230,7 +230,7 @@ bool cNonBlockingFileReader::WaitForDataMs(int msToWait)
// --- cDvbPlayer ------------------------------------------------------------
#define PLAYERBUFSIZE MEGABYTE(1)
#define PLAYERBUFSIZE (MAXFRAMESIZE * 5)
#define RESUMEBACKUP 10 // number of seconds to back up when resuming an interrupted replay session
#define MAXSTUCKATEOF 3 // max. number of seconds to wait in case the device doesn't play the last frame
......
......@@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
* $Id: eit.c 4.5 2018/03/31 13:40:32 kls Exp $
* $Id: eit.c 4.5.1.2 2019/05/21 21:25:00 kls Exp $
*/
#include "eit.h"
......@@ -20,6 +20,8 @@
#define VALID_TIME (31536000 * 2) // two years
#define DBGEIT 0
// --- cEIT ------------------------------------------------------------------
class cEIT : public SI::EIT {
......@@ -130,8 +132,34 @@ cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const
if (pEvent->TableID() > 0x4E) // for backwards compatibility, table ids less than 0x4E are never overwritten
pEvent->SetTableID(Tid);
if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning)
pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), Channel);
int RunningStatus = SiEitEvent.getRunningStatus();
#if DBGEIT
if (Process)
dsyslog("channel %d (%s) event %s status %d (raw data from '%s' section)", Channel->Number(), Channel->Name(), *pEvent->ToDescr(), RunningStatus, getSectionNumber() ? "following" : "present");
#endif
if (RunningStatus >= SI::RunningStatusNotRunning) {
// Workaround for broadcasters who set an event to status "not running" where
// this is inappropriate:
if (RunningStatus != pEvent->RunningStatus()) { // if the running status of the event has changed...
if (RunningStatus == SI::RunningStatusNotRunning) { // ...and the new status is "not running"...
int OverrideStatus = -1;
if (getSectionNumber() == 0) { // ...and if this the "present" event...
if (pEvent->RunningStatus() == SI::RunningStatusPausing) // ...and if the event has already been set to "pausing"...
OverrideStatus = SI::RunningStatusPausing; // ...then we ignore the faulty new status and stay with "pausing"
}
else // ...and if this is the "following" event...
OverrideStatus = SI::RunningStatusUndefined; // ...then we ignore the faulty new status and fall back to "undefined"
if (OverrideStatus >= 0) {
#if DBGEIT
if (Process)
dsyslog("channel %d (%s) event %s status %d (ignored status %d from '%s' section)", Channel->Number(), Channel->Name(), *pEvent->ToDescr(), OverrideStatus, RunningStatus, getSectionNumber() ? "following" : "present");
#endif
RunningStatus = OverrideStatus;
}
}
}
pSchedule->SetRunningStatus(pEvent, RunningStatus, Channel);
}
if (!Process)
continue;
}
......@@ -388,8 +416,7 @@ time_t cEitFilter::disableUntil = 0;
cEitFilter::cEitFilter(void)
{
//Set(0x12, 0x40, 0xC0); // event info now&next actual/other TS (0x4E/0x4F), future actual/other TS (0x5X/0x6X) // TODO: remove later
Set(0x12, 0x40, 0xE0); // event info now&next actual/other TS (0x4E/0x4F), future actual TS (0x5X)
Set(0x12, 0x40, 0xC0); // event info now&next actual/other TS (0x4E/0x4F), future actual/other TS (0x5X/0x6X)
Set(0x14, 0x70); // TDT
}
......@@ -416,8 +443,7 @@ void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
}
switch (Pid) {
case 0x12: {
//if (Tid >= 0x4E && Tid <= 0x6F) // TODO: remove later
if (Tid == 0x4E || Tid >= 0x50 && Tid <= 0x5F)
if (Tid >= 0x4E && Tid <= 0x6F)
cEIT EIT(sectionSyncerHash, Source(), Tid, Data);
}
break;
......
......@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.