mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented signal strength and quality handling
This commit is contained in:
parent
40278ec121
commit
e572cbda47
@ -1104,6 +1104,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi>
|
|||||||
for adding support for "registration descriptor" to 'libsi' and using it in pat.c
|
for adding support for "registration descriptor" to 'libsi' and using it in pat.c
|
||||||
for adding an include of VDR's 'Make.global' to libsi's Makefile
|
for adding an include of VDR's 'Make.global' to libsi's Makefile
|
||||||
for adding handling of "ANSI/SCTE 57" descriptors
|
for adding handling of "ANSI/SCTE 57" descriptors
|
||||||
|
for some input on how to use BER and UNC values to generate a "quality" value
|
||||||
|
|
||||||
Ralf Klueber <ralf.klueber@vodafone.com>
|
Ralf Klueber <ralf.klueber@vodafone.com>
|
||||||
for reporting a bug in cutting a recording if there is only a single editing mark
|
for reporting a bug in cutting a recording if there is only a single editing mark
|
||||||
|
10
HISTORY
10
HISTORY
@ -6607,7 +6607,7 @@ Video Disk Recorder Revision History
|
|||||||
- Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard
|
- Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard
|
||||||
Nissl).
|
Nissl).
|
||||||
|
|
||||||
2011-05-22: Version 1.7.19
|
2011-06-02: Version 1.7.19
|
||||||
|
|
||||||
- Fixed cString's operator=(const char *String) in case the given string is the
|
- Fixed cString's operator=(const char *String) in case the given string is the
|
||||||
same as the existing one (thanks to Dirk Leber).
|
same as the existing one (thanks to Dirk Leber).
|
||||||
@ -6624,3 +6624,11 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed a possible race condition in cDiseqc::Execute() (reported by Marco Göbenich).
|
- Fixed a possible race condition in cDiseqc::Execute() (reported by Marco Göbenich).
|
||||||
The return value of cDiseqcs::Get() is now const, so plugin authors may need to
|
The return value of cDiseqcs::Get() is now const, so plugin authors may need to
|
||||||
adjust their code if they use this function.
|
adjust their code if they use this function.
|
||||||
|
- The new functions cDevice::SignalStrength() and cDevice::SignalQuality() can be
|
||||||
|
used to determine the signal strength and quality of a given device (thanks to
|
||||||
|
Rolf Ahrenberg for some input on how to use BER and UNC values to generate a
|
||||||
|
"quality" value).
|
||||||
|
- The 'sttng' skin now displays two colored bars at the bottom of the channel display,
|
||||||
|
indicating the strength (upper bar) and quality (lower bar) of the received signal.
|
||||||
|
The number to the left of these bars indicates the actual device the current
|
||||||
|
channel is being received with.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbsdffdevice.c 2.28 2011/05/21 13:24:35 kls Exp $
|
* $Id: dvbsdffdevice.c 2.29 2011/05/22 15:22:14 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbsdffdevice.h"
|
#include "dvbsdffdevice.h"
|
||||||
@ -777,22 +777,7 @@ bool cDvbSdFfDeviceProbe::Probe(int Adapter, int Frontend)
|
|||||||
0x13C21002, // Technotrend/Hauppauge WinTV DVB-S rev1.3 SE
|
0x13C21002, // Technotrend/Hauppauge WinTV DVB-S rev1.3 SE
|
||||||
0x00000000
|
0x00000000
|
||||||
};
|
};
|
||||||
cString FileName;
|
uint32_t SubsystemId = GetSubsystemId(Adapter, Frontend);
|
||||||
cReadLine ReadLine;
|
|
||||||
FILE *f = NULL;
|
|
||||||
uint32_t SubsystemId = 0;
|
|
||||||
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
|
|
||||||
if ((f = fopen(FileName, "r")) != NULL) {
|
|
||||||
if (char *s = ReadLine.Read(f))
|
|
||||||
SubsystemId = strtoul(s, NULL, 0) << 16;
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
|
|
||||||
if ((f = fopen(FileName, "r")) != NULL) {
|
|
||||||
if (char *s = ReadLine.Read(f))
|
|
||||||
SubsystemId |= strtoul(s, NULL, 0);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
for (uint32_t *sid = SubsystemIds; *sid; sid++) {
|
for (uint32_t *sid = SubsystemIds; *sid; sid++) {
|
||||||
if (*sid == SubsystemId) {
|
if (*sid == SubsystemId) {
|
||||||
dsyslog("creating cDvbSdFfDevice");
|
dsyslog("creating cDvbSdFfDevice");
|
||||||
|
12
device.c
12
device.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: device.c 2.40 2011/05/22 09:42:57 kls Exp $
|
* $Id: device.c 2.41 2011/06/02 13:14:16 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -618,6 +618,16 @@ int cDevice::NumProvidedSystems(void) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDevice::SignalStrength(void) const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cDevice::SignalQuality(void) const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
const cChannel *cDevice::GetCurrentlyTunedTransponder(void) const
|
const cChannel *cDevice::GetCurrentlyTunedTransponder(void) const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
12
device.h
12
device.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: device.h 2.25 2011/05/21 12:54:43 kls Exp $
|
* $Id: device.h 2.26 2011/06/02 13:15:31 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DEVICE_H
|
#ifndef __DEVICE_H
|
||||||
@ -253,6 +253,16 @@ public:
|
|||||||
///< actually provide channels must implement this function.
|
///< actually provide channels must implement this function.
|
||||||
///< The result of this function is used when selecting a device, in order
|
///< The result of this function is used when selecting a device, in order
|
||||||
///< to avoid devices that provide more than one system.
|
///< to avoid devices that provide more than one system.
|
||||||
|
virtual int SignalStrength(void) const;
|
||||||
|
///< Returns the "strength" of the currently received signal.
|
||||||
|
///< This is a value in the range 0 (no signal at all) through
|
||||||
|
///< 100 (best possible signal). A value of -1 indicates that this
|
||||||
|
///< device has no concept of a "signal strength".
|
||||||
|
virtual int SignalQuality(void) const;
|
||||||
|
///< Returns the "quality" of the currently received signal.
|
||||||
|
///< This is a value in the range 0 (worst quality) through
|
||||||
|
///< 100 (best possible quality). A value of -1 indicates that this
|
||||||
|
///< device has no concept of a "signal quality".
|
||||||
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
||||||
///< Returns a pointer to the currently tuned transponder.
|
///< Returns a pointer to the currently tuned transponder.
|
||||||
///< This is not one of the channels in the global cChannels list, but rather
|
///< This is not one of the channels in the global cChannels list, but rather
|
||||||
|
159
dvbdevice.c
159
dvbdevice.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: dvbdevice.c 2.39 2011/05/22 10:34:49 kls Exp $
|
* $Id: dvbdevice.c 2.40 2011/06/02 13:28:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -253,12 +253,15 @@ bool cDvbTransponderParameters::Parse(const char *s)
|
|||||||
|
|
||||||
// --- cDvbTuner -------------------------------------------------------------
|
// --- cDvbTuner -------------------------------------------------------------
|
||||||
|
|
||||||
|
#define TUNER_POLL_TIMEOUT 10 // ms
|
||||||
|
|
||||||
class cDvbTuner : public cThread {
|
class cDvbTuner : public cThread {
|
||||||
private:
|
private:
|
||||||
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
|
||||||
int device;
|
int device;
|
||||||
int fd_frontend;
|
int fd_frontend;
|
||||||
int adapter, frontend;
|
int adapter, frontend;
|
||||||
|
uint32_t subsystemId;
|
||||||
int tuneTimeout;
|
int tuneTimeout;
|
||||||
int lockTimeout;
|
int lockTimeout;
|
||||||
time_t lastTimeoutReport;
|
time_t lastTimeoutReport;
|
||||||
@ -269,16 +272,20 @@ private:
|
|||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
cCondVar locked;
|
cCondVar locked;
|
||||||
cCondVar newSet;
|
cCondVar newSet;
|
||||||
bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0);
|
void ClearEventQueue(void) const;
|
||||||
|
bool GetFrontendStatus(fe_status_t &Status) const;
|
||||||
bool SetFrontend(void);
|
bool SetFrontend(void);
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType);
|
cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType);
|
||||||
virtual ~cDvbTuner();
|
virtual ~cDvbTuner();
|
||||||
const cChannel *GetTransponder(void) const { return &channel; }
|
const cChannel *GetTransponder(void) const { return &channel; }
|
||||||
|
uint32_t SubsystemId(void) const { return subsystemId; }
|
||||||
bool IsTunedTo(const cChannel *Channel) const;
|
bool IsTunedTo(const cChannel *Channel) const;
|
||||||
void Set(const cChannel *Channel);
|
void Set(const cChannel *Channel);
|
||||||
bool Locked(int TimeoutMs = 0);
|
bool Locked(int TimeoutMs = 0);
|
||||||
|
int GetSignalStrength(void) const;
|
||||||
|
int GetSignalQuality(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType)
|
cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType)
|
||||||
@ -288,6 +295,7 @@ cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_
|
|||||||
adapter = Adapter;
|
adapter = Adapter;
|
||||||
frontend = Frontend;
|
frontend = Frontend;
|
||||||
frontendType = FrontendType;
|
frontendType = FrontendType;
|
||||||
|
subsystemId = cDvbDeviceProbe::GetSubsystemId(adapter, frontend);
|
||||||
tuneTimeout = 0;
|
tuneTimeout = 0;
|
||||||
lockTimeout = 0;
|
lockTimeout = 0;
|
||||||
lastTimeoutReport = 0;
|
lastTimeoutReport = 0;
|
||||||
@ -339,16 +347,19 @@ bool cDvbTuner::Locked(int TimeoutMs)
|
|||||||
return tunerStatus >= tsLocked;
|
return tunerStatus >= tsLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs)
|
void cDvbTuner::ClearEventQueue(void) const
|
||||||
{
|
{
|
||||||
if (TimeoutMs) {
|
|
||||||
cPoller Poller(fd_frontend);
|
cPoller Poller(fd_frontend);
|
||||||
if (Poller.Poll(TimeoutMs)) {
|
if (Poller.Poll(TUNER_POLL_TIMEOUT)) {
|
||||||
dvb_frontend_event Event;
|
dvb_frontend_event Event;
|
||||||
while (ioctl(fd_frontend, FE_GET_EVENT, &Event) == 0)
|
while (ioctl(fd_frontend, FE_GET_EVENT, &Event) == 0)
|
||||||
; // just to clear the event queue - we'll read the actual status below
|
; // just to clear the event queue - we'll read the actual status below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
|
||||||
|
{
|
||||||
|
ClearEventQueue();
|
||||||
while (1) {
|
while (1) {
|
||||||
if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1)
|
if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1)
|
||||||
return true;
|
return true;
|
||||||
@ -358,6 +369,104 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define DEBUG_SIGNALSTRENGTH
|
||||||
|
//#define DEBUG_SIGNALQUALITY
|
||||||
|
|
||||||
|
int cDvbTuner::GetSignalStrength(void) const
|
||||||
|
{
|
||||||
|
ClearEventQueue();
|
||||||
|
uint16_t Signal;
|
||||||
|
while (1) {
|
||||||
|
if (ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
|
||||||
|
break;
|
||||||
|
if (errno != EINTR)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint16_t MaxSignal = 0xFFFF; // Let's assume the default is using the entire range.
|
||||||
|
// Use the subsystemId to identify individual devices in case they need
|
||||||
|
// special treatment to map their Signal value into the range 0...0xFFFF.
|
||||||
|
int s = int(Signal) * 100 / MaxSignal;
|
||||||
|
if (s > 100)
|
||||||
|
s = 100;
|
||||||
|
#ifdef DEBUG_SIGNALSTRENGTH
|
||||||
|
fprintf(stderr, "FE %d/%d: %08X S = %04X %04X %3d%%\n", adapter, frontend, subsystemId, MaxSignal, Signal, s);
|
||||||
|
#endif
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCK_THRESHOLD 10
|
||||||
|
|
||||||
|
int cDvbTuner::GetSignalQuality(void) const
|
||||||
|
{
|
||||||
|
fe_status_t Status;
|
||||||
|
if (GetFrontendStatus(Status)) {
|
||||||
|
if ((Status & FE_HAS_SIGNAL) == 0)
|
||||||
|
return 0;
|
||||||
|
if ((Status & FE_HAS_CARRIER) == 0)
|
||||||
|
return LOCK_THRESHOLD / 4;
|
||||||
|
if ((Status & FE_HAS_VITERBI) == 0)
|
||||||
|
return LOCK_THRESHOLD / 3;
|
||||||
|
if ((Status & FE_HAS_SYNC) == 0)
|
||||||
|
return LOCK_THRESHOLD / 2;
|
||||||
|
if ((Status & FE_HAS_LOCK) == 0)
|
||||||
|
return LOCK_THRESHOLD;
|
||||||
|
bool HasSnr = true;
|
||||||
|
uint16_t Snr;
|
||||||
|
while (1) {
|
||||||
|
if (ioctl(fd_frontend, FE_READ_SNR, &Snr) != -1)
|
||||||
|
break;
|
||||||
|
if (errno == EOPNOTSUPP) {
|
||||||
|
Snr = 0xFFFF;
|
||||||
|
HasSnr = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno != EINTR)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bool HasBer = true;
|
||||||
|
uint32_t Ber;
|
||||||
|
while (1) {
|
||||||
|
if (ioctl(fd_frontend, FE_READ_BER, &Ber) != -1)
|
||||||
|
break;
|
||||||
|
if (errno == EOPNOTSUPP) {
|
||||||
|
Ber = 0;
|
||||||
|
HasBer = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno != EINTR)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bool HasUnc = true;
|
||||||
|
uint32_t Unc;
|
||||||
|
while (1) {
|
||||||
|
if (ioctl(fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1)
|
||||||
|
break;
|
||||||
|
if (errno == EOPNOTSUPP) {
|
||||||
|
Unc = 0;
|
||||||
|
HasUnc = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno != EINTR)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint16_t MaxSnr = 0xFFFF; // Let's assume the default is using the entire range.
|
||||||
|
// Use the subsystemId to identify individual devices in case they need
|
||||||
|
// special treatment to map their Snr value into the range 0...0xFFFF.
|
||||||
|
int a = int(Snr) * 100 / MaxSnr;
|
||||||
|
int b = 100 - (Unc * 10 + (Ber / 256) * 5);
|
||||||
|
if (b < 0)
|
||||||
|
b = 0;
|
||||||
|
int q = LOCK_THRESHOLD + a * b * (100 - LOCK_THRESHOLD) / 100 / 100;
|
||||||
|
if (q > 100)
|
||||||
|
q = 100;
|
||||||
|
#ifdef DEBUG_SIGNALQUALITY
|
||||||
|
fprintf(stderr, "FE %d/%d: %08X Q = %04X %04X %5d %5d %3d%%\n", adapter, frontend, subsystemId, MaxSnr, Snr, HasBer ? int(Ber) : -1, HasUnc ? int(Unc) : -1, q);
|
||||||
|
#endif
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int FrequencyToHz(unsigned int f)
|
static unsigned int FrequencyToHz(unsigned int f)
|
||||||
{
|
{
|
||||||
while (f && f < 1000000)
|
while (f && f < 1000000)
|
||||||
@ -527,7 +636,7 @@ void cDvbTuner::Action(void)
|
|||||||
fe_status_t Status = (fe_status_t)0;
|
fe_status_t Status = (fe_status_t)0;
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
fe_status_t NewStatus;
|
fe_status_t NewStatus;
|
||||||
if (GetFrontendStatus(NewStatus, 10))
|
if (GetFrontendStatus(NewStatus))
|
||||||
Status = NewStatus;
|
Status = NewStatus;
|
||||||
cMutexLock MutexLock(&mutex);
|
cMutexLock MutexLock(&mutex);
|
||||||
switch (tunerStatus) {
|
switch (tunerStatus) {
|
||||||
@ -936,7 +1045,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
|||||||
bool hasPriority = Priority < 0 || Priority > this->Priority();
|
bool hasPriority = Priority < 0 || Priority > this->Priority();
|
||||||
bool needsDetachReceivers = false;
|
bool needsDetachReceivers = false;
|
||||||
|
|
||||||
if (ProvidesTransponder(Channel)) {
|
if (dvbTuner && ProvidesTransponder(Channel)) {
|
||||||
result = hasPriority;
|
result = hasPriority;
|
||||||
if (Priority >= 0 && Receiving(true)) {
|
if (Priority >= 0 && Receiving(true)) {
|
||||||
if (dvbTuner->IsTunedTo(Channel)) {
|
if (dvbTuner->IsTunedTo(Channel)) {
|
||||||
@ -969,18 +1078,29 @@ int cDvbDevice::NumProvidedSystems(void) const
|
|||||||
return numProvidedSystems;
|
return numProvidedSystems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDvbDevice::SignalStrength(void) const
|
||||||
|
{
|
||||||
|
return dvbTuner ? dvbTuner->GetSignalStrength() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cDvbDevice::SignalQuality(void) const
|
||||||
|
{
|
||||||
|
return dvbTuner ? dvbTuner->GetSignalQuality() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
const cChannel *cDvbDevice::GetCurrentlyTunedTransponder(void) const
|
const cChannel *cDvbDevice::GetCurrentlyTunedTransponder(void) const
|
||||||
{
|
{
|
||||||
return dvbTuner->GetTransponder();
|
return dvbTuner ? dvbTuner->GetTransponder() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel)
|
bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel)
|
||||||
{
|
{
|
||||||
return dvbTuner->IsTunedTo(Channel);
|
return dvbTuner ? dvbTuner->IsTunedTo(Channel) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
||||||
{
|
{
|
||||||
|
if (dvbTuner)
|
||||||
dvbTuner->Set(Channel);
|
dvbTuner->Set(Channel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1036,3 +1156,24 @@ cDvbDeviceProbe::~cDvbDeviceProbe()
|
|||||||
{
|
{
|
||||||
DvbDeviceProbes.Del(this, false);
|
DvbDeviceProbes.Del(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t cDvbDeviceProbe::GetSubsystemId(int Adapter, int Frontend)
|
||||||
|
{
|
||||||
|
cString FileName;
|
||||||
|
cReadLine ReadLine;
|
||||||
|
FILE *f = NULL;
|
||||||
|
uint32_t SubsystemId = 0;
|
||||||
|
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
|
||||||
|
if ((f = fopen(FileName, "r")) != NULL) {
|
||||||
|
if (char *s = ReadLine.Read(f))
|
||||||
|
SubsystemId = strtoul(s, NULL, 0) << 16;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
|
||||||
|
if ((f = fopen(FileName, "r")) != NULL) {
|
||||||
|
if (char *s = ReadLine.Read(f))
|
||||||
|
SubsystemId |= strtoul(s, NULL, 0);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
return SubsystemId;
|
||||||
|
}
|
||||||
|
@ -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: dvbdevice.h 2.14 2010/04/11 10:29:37 kls Exp $
|
* $Id: dvbdevice.h 2.15 2011/06/02 13:20:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBDEVICE_H
|
#ifndef __DVBDEVICE_H
|
||||||
@ -141,6 +141,8 @@ public:
|
|||||||
virtual bool ProvidesTransponder(const cChannel *Channel) const;
|
virtual bool ProvidesTransponder(const cChannel *Channel) const;
|
||||||
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
|
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
|
||||||
virtual int NumProvidedSystems(void) const;
|
virtual int NumProvidedSystems(void) const;
|
||||||
|
virtual int SignalStrength(void) const;
|
||||||
|
virtual int SignalQuality(void) const;
|
||||||
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
||||||
virtual bool IsTunedToTransponder(const cChannel *Channel);
|
virtual bool IsTunedToTransponder(const cChannel *Channel);
|
||||||
protected:
|
protected:
|
||||||
@ -196,6 +198,7 @@ class cDvbDeviceProbe : public cListObject {
|
|||||||
public:
|
public:
|
||||||
cDvbDeviceProbe(void);
|
cDvbDeviceProbe(void);
|
||||||
virtual ~cDvbDeviceProbe();
|
virtual ~cDvbDeviceProbe();
|
||||||
|
static uint32_t GetSubsystemId(int Adapter, int Frontend);
|
||||||
virtual bool Probe(int Adapter, int Frontend) = 0;
|
virtual bool Probe(int Adapter, int Frontend) = 0;
|
||||||
///< Probes for a DVB device at the given Adapter and creates the appropriate
|
///< Probes for a DVB device at the given Adapter and creates the appropriate
|
||||||
///< object derived from cDvbDevice if applicable.
|
///< object derived from cDvbDevice if applicable.
|
||||||
|
40
skinsttng.c
40
skinsttng.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: skinsttng.c 2.7 2011/02/20 13:02:49 kls Exp $
|
* $Id: skinsttng.c 2.8 2011/06/02 12:54:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
||||||
@ -92,6 +92,8 @@ THEME_CLR(Theme, clrChannelEpgTitle, clrCyan);
|
|||||||
THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
|
THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
|
||||||
THEME_CLR(Theme, clrChannelTimebarSeen, clrYellow);
|
THEME_CLR(Theme, clrChannelTimebarSeen, clrYellow);
|
||||||
THEME_CLR(Theme, clrChannelTimebarRest, clrGray50);
|
THEME_CLR(Theme, clrChannelTimebarRest, clrGray50);
|
||||||
|
THEME_CLR(Theme, clrChannelSignalValue, clrGreen);
|
||||||
|
THEME_CLR(Theme, clrChannelSignalRest, clrRed);
|
||||||
THEME_CLR(Theme, clrMenuFrame, clrYellow);
|
THEME_CLR(Theme, clrMenuFrame, clrYellow);
|
||||||
THEME_CLR(Theme, clrMenuTitle, clrBlack);
|
THEME_CLR(Theme, clrMenuTitle, clrBlack);
|
||||||
THEME_CLR(Theme, clrMenuDate, clrBlack);
|
THEME_CLR(Theme, clrMenuDate, clrBlack);
|
||||||
@ -134,6 +136,9 @@ private:
|
|||||||
const cEvent *present;
|
const cEvent *present;
|
||||||
cString lastDate;
|
cString lastDate;
|
||||||
int lastSeen;
|
int lastSeen;
|
||||||
|
int lastDeviceNumber;
|
||||||
|
int lastSignalStrength;
|
||||||
|
int lastSignalQuality;
|
||||||
tTrackId lastTrackId;
|
tTrackId lastTrackId;
|
||||||
static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
|
static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
|
||||||
public:
|
public:
|
||||||
@ -156,6 +161,9 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo)
|
|||||||
{
|
{
|
||||||
present = NULL;
|
present = NULL;
|
||||||
lastSeen = -1;
|
lastSeen = -1;
|
||||||
|
lastDeviceNumber = -1;
|
||||||
|
lastSignalStrength = -1;
|
||||||
|
lastSignalQuality = -1;
|
||||||
memset(&lastTrackId, 0, sizeof(lastTrackId));
|
memset(&lastTrackId, 0, sizeof(lastTrackId));
|
||||||
const cFont *font = cFont::GetFont(fontOsd);
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
withInfo = WithInfo;
|
withInfo = WithInfo;
|
||||||
@ -344,6 +352,36 @@ void cSkinSTTNGDisplayChannel::Flush(void)
|
|||||||
osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
|
osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
|
||||||
lastSeen = seen;
|
lastSeen = seen;
|
||||||
}
|
}
|
||||||
|
int DeviceNumber = cDevice::ActualDevice()->DeviceNumber() + 1;
|
||||||
|
int SignalStrength = cDevice::ActualDevice()->SignalStrength();
|
||||||
|
int SignalQuality = cDevice::ActualDevice()->SignalQuality();
|
||||||
|
if (DeviceNumber != lastDeviceNumber || SignalStrength != lastSignalStrength || SignalQuality != lastSignalQuality) {
|
||||||
|
int d = 3;
|
||||||
|
int h = ((y7 - y6 + 1) - 3 * d) / 2;
|
||||||
|
int w = (x4 - x3) / 5;
|
||||||
|
int x = (x3 + x4) / 2 - w / 2;
|
||||||
|
if (SignalStrength >= 0) {
|
||||||
|
int s = SignalStrength * w / 100;
|
||||||
|
osd->DrawRectangle(x, y6 + d, x + s - 1, y6 + d + h - 1, Theme.Color(clrChannelSignalValue));
|
||||||
|
osd->DrawRectangle(x + s, y6 + d, x + w - 1, y6 + d + h - 1, Theme.Color(clrChannelSignalRest));
|
||||||
|
}
|
||||||
|
else if (DeviceNumber != lastDeviceNumber)
|
||||||
|
osd->DrawRectangle(x, y6 + d, x + w - 1, y6 + d + h - 1, Theme.Color(clrChannelFrame));
|
||||||
|
if (SignalQuality >= 0) {
|
||||||
|
int q = SignalQuality * w / 100;
|
||||||
|
osd->DrawRectangle(x, y7 - d - h + 1, x + q - 1, y7 - d, Theme.Color(clrChannelSignalValue));
|
||||||
|
osd->DrawRectangle(x + q, y7 - d - h + 1, x + w - 1, y7 - d, Theme.Color(clrChannelSignalRest));
|
||||||
|
}
|
||||||
|
else if (DeviceNumber != lastDeviceNumber)
|
||||||
|
osd->DrawRectangle(x, y7 - d - h + 1, x + w - 1, y7 - d, Theme.Color(clrChannelFrame));
|
||||||
|
cString dn = cString::sprintf(" %d ", DeviceNumber);
|
||||||
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
|
int dw = font->Width(dn);
|
||||||
|
osd->DrawText(x - 2 * d - dw, y6, dn, Theme.Color(clrChannelDate), frameColor, font, dw);
|
||||||
|
lastDeviceNumber = DeviceNumber;
|
||||||
|
lastSignalStrength = SignalStrength;
|
||||||
|
lastSignalQuality = SignalQuality;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user