mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented getting and logging DVB API 5 signal statistics
This commit is contained in:
parent
1f541487e0
commit
6132a46768
@ -3388,6 +3388,8 @@ Dietmar Spingler <d_spingler@gmx.de>
|
|||||||
for suggesting that the -V and -h options should list the plugins in alphabetical order
|
for suggesting that the -V and -h options should list the plugins in alphabetical order
|
||||||
for suggesting to implement the setup option "Recording/Record key handling"
|
for suggesting to implement the setup option "Recording/Record key handling"
|
||||||
for suggesting to cache the channel/CAM relations in the file 'cam.data'
|
for suggesting to cache the channel/CAM relations in the file 'cam.data'
|
||||||
|
for suggesting to log signal statistics whenever the tuner of a cDvbDevice acquires
|
||||||
|
a lock, and DVB API 5 signal statistics are available
|
||||||
|
|
||||||
Stefan Schallenberg <infos@nafets.de>
|
Stefan Schallenberg <infos@nafets.de>
|
||||||
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
|
for adding the functions IndexOf(), InsertUnique(), AppendUnique() and RemoveElement()
|
||||||
|
6
HISTORY
6
HISTORY
@ -8925,7 +8925,7 @@ Video Disk Recorder Revision History
|
|||||||
- Now stopping any ongoing recordings before stopping the plugins, to avoid
|
- Now stopping any ongoing recordings before stopping the plugins, to avoid
|
||||||
a crash when stopping VDR while recording.
|
a crash when stopping VDR while recording.
|
||||||
|
|
||||||
2017-04-15: Version 2.3.4
|
2017-04-17: Version 2.3.4
|
||||||
|
|
||||||
- The functionality of HandleRemoteModifications(), which synchronizes changes to
|
- The functionality of HandleRemoteModifications(), which synchronizes changes to
|
||||||
timers between peer VDR machines, has been moved to timers.[ch] and renamed to
|
timers between peer VDR machines, has been moved to timers.[ch] and renamed to
|
||||||
@ -8978,3 +8978,7 @@ Video Disk Recorder Revision History
|
|||||||
is called, but the actual TS packet returned (pointed to by Data) may well be
|
is called, but the actual TS packet returned (pointed to by Data) may well be
|
||||||
(and typically is, unless the CAM copies the data) in the area of the buffer that
|
(and typically is, unless the CAM copies the data) in the area of the buffer that
|
||||||
would be deleted by Skip().
|
would be deleted by Skip().
|
||||||
|
- The new function cDevice::SignalStats() (if implemented by an actual device) returns
|
||||||
|
statistics about the currently received signal.
|
||||||
|
- If DVB API 5 signal statistics are available for a cDvbDevice, it now logs them
|
||||||
|
whenever the tuner acquires a lock (suggested by Dietmar Spingler).
|
||||||
|
7
device.c
7
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 4.14 2017/04/15 09:44:50 kls Exp $
|
* $Id: device.c 4.15 2017/04/17 14:47:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -749,6 +749,11 @@ const cPositioner *cDevice::Positioner(void) const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDevice::SignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int cDevice::SignalStrength(void) const
|
int cDevice::SignalStrength(void) const
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
25
device.h
25
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 4.7 2017/04/15 09:41:34 kls Exp $
|
* $Id: device.h 4.8 2017/04/17 14:46:57 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DEVICE_H
|
#ifndef __DEVICE_H
|
||||||
@ -106,6 +106,13 @@ public:
|
|||||||
|
|
||||||
/// The cDevice class is the base from which actual devices can be derived.
|
/// The cDevice class is the base from which actual devices can be derived.
|
||||||
|
|
||||||
|
#define DTV_STAT_VALID_NONE 0x0000
|
||||||
|
#define DTV_STAT_VALID_STRENGTH 0x0001
|
||||||
|
#define DTV_STAT_VALID_CNR 0x0002
|
||||||
|
#define DTV_STAT_VALID_BERPRE 0x0004
|
||||||
|
#define DTV_STAT_VALID_BERPOST 0x0008
|
||||||
|
#define DTV_STAT_VALID_PER 0x0010
|
||||||
|
|
||||||
class cDevice : public cThread {
|
class cDevice : public cThread {
|
||||||
friend class cLiveSubtitle;
|
friend class cLiveSubtitle;
|
||||||
friend class cDeviceHook;
|
friend class cDeviceHook;
|
||||||
@ -284,6 +291,22 @@ public:
|
|||||||
///< move the satellite dish to the requested position (only applies to DVB-S
|
///< move the satellite dish to the requested position (only applies to DVB-S
|
||||||
///< devices). If no positioner is involved, or this is not a DVB-S device,
|
///< devices). If no positioner is involved, or this is not a DVB-S device,
|
||||||
///< NULL will be returned.
|
///< NULL will be returned.
|
||||||
|
virtual bool SignalStats(int &Valid, double *Strength = NULL, double *Cnr = NULL, double *BerPre = NULL, double *BerPost = NULL, double *Per = NULL) const;
|
||||||
|
///< Returns statistics about the currently received signal (if available).
|
||||||
|
///< Strength is the signal strength in dBm (typical range -100dBm...0dBm).
|
||||||
|
///< Cnr is the carrier to noise ratio in dB (typical range 0dB...40dB).
|
||||||
|
///< BerPre is the bit error rate before the forward error correction (FEC).
|
||||||
|
///< BerPost is the bit error rate after the forward error correction (FEC).
|
||||||
|
///< Per is the block error rate after the forward error correction (FEC).
|
||||||
|
///< Typical range for BerPre, BerPost and Per is 0...1.
|
||||||
|
///< If any of the given pointers is not NULL, the value of the respective signal
|
||||||
|
///< statistic is returned in it. Upon return, Valid holds a combination of
|
||||||
|
///< DTV_STAT_VALID_* flags, indicating which of the returned values are actually
|
||||||
|
///< valid. If the flag for a particular parameter in Valid is 0, the returned
|
||||||
|
///< value is undefined. It depends on the device which of these parameters
|
||||||
|
///< (if any) are available.
|
||||||
|
///< Returns true if any of the requested parameters is valid.
|
||||||
|
///< If false is returned, the value in Valid is undefined.
|
||||||
virtual int SignalStrength(void) const;
|
virtual int SignalStrength(void) const;
|
||||||
///< Returns the "strength" of the currently received signal.
|
///< Returns the "strength" of the currently received signal.
|
||||||
///< This is a value in the range 0 (no signal at all) through
|
///< This is a value in the range 0 (no signal at all) through
|
||||||
|
116
dvbdevice.c
116
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 4.6 2017/04/14 10:05:15 kls Exp $
|
* $Id: dvbdevice.c 4.7 2017/04/17 15:02:44 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -346,6 +346,7 @@ public:
|
|||||||
void SetChannel(const cChannel *Channel);
|
void SetChannel(const cChannel *Channel);
|
||||||
bool Locked(int TimeoutMs = 0);
|
bool Locked(int TimeoutMs = 0);
|
||||||
const cPositioner *Positioner(void) const { return positioner; }
|
const cPositioner *Positioner(void) const { return positioner; }
|
||||||
|
bool GetSignalStats(int &Valid, double *Strength = NULL, double *Cnr = NULL, double *BerPre = NULL, double *BerPost = NULL, double *Per = NULL) const;
|
||||||
int GetSignalStrength(void) const;
|
int GetSignalStrength(void) const;
|
||||||
int GetSignalQuality(void) const;
|
int GetSignalQuality(void) const;
|
||||||
};
|
};
|
||||||
@ -554,6 +555,7 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define DEBUG_SIGNALSTATS
|
||||||
//#define DEBUG_SIGNALSTRENGTH
|
//#define DEBUG_SIGNALSTRENGTH
|
||||||
//#define DEBUG_SIGNALQUALITY
|
//#define DEBUG_SIGNALQUALITY
|
||||||
|
|
||||||
@ -566,6 +568,101 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDvbTuner::GetSignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per) const
|
||||||
|
{
|
||||||
|
ClearEventQueue();
|
||||||
|
dtv_property Props[MAXFRONTENDCMDS];
|
||||||
|
dtv_properties CmdSeq;
|
||||||
|
memset(&Props, 0, sizeof(Props));
|
||||||
|
memset(&CmdSeq, 0, sizeof(CmdSeq));
|
||||||
|
CmdSeq.props = Props;
|
||||||
|
if (Strength) SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
|
||||||
|
if (Cnr) SETCMD(DTV_STAT_CNR, 0);
|
||||||
|
if (BerPre) { SETCMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0);
|
||||||
|
SETCMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0); }
|
||||||
|
if (BerPost) { SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
|
||||||
|
SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0); }
|
||||||
|
if (Per) { SETCMD(DTV_STAT_ERROR_BLOCK_COUNT, 0);
|
||||||
|
SETCMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0); }
|
||||||
|
if (ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
|
||||||
|
esyslog("ERROR: frontend %d/%d: %m", adapter, frontend);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Valid = DTV_STAT_VALID_NONE;
|
||||||
|
int i = 0;
|
||||||
|
if (Strength) {
|
||||||
|
if (Props[i].u.st.len > 0) {
|
||||||
|
switch (Props[i].u.st.stat[0].scale) {
|
||||||
|
case FE_SCALE_DECIBEL: *Strength = double(Props[i].u.st.stat[0].svalue) / 1000;
|
||||||
|
Valid |= DTV_STAT_VALID_STRENGTH;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (Cnr) {
|
||||||
|
if (Props[i].u.st.len > 0) {
|
||||||
|
switch (Props[i].u.st.stat[0].scale) {
|
||||||
|
case FE_SCALE_DECIBEL: *Cnr = double(Props[i].u.st.stat[0].svalue) / 1000;
|
||||||
|
Valid |= DTV_STAT_VALID_CNR;
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (BerPre) {
|
||||||
|
if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
|
||||||
|
if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||||
|
uint64_t ebc = Props[i].u.st.stat[0].uvalue; // error bit count
|
||||||
|
uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue; // total bit count
|
||||||
|
if (tbc > 0) {
|
||||||
|
*BerPre = double(ebc) / tbc;
|
||||||
|
Valid |= DTV_STAT_VALID_BERPRE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
if (BerPost) {
|
||||||
|
if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
|
||||||
|
if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||||
|
uint64_t ebc = Props[i].u.st.stat[0].uvalue; // error bit count
|
||||||
|
uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue; // total bit count
|
||||||
|
if (tbc > 0) {
|
||||||
|
*BerPost = double(ebc) / tbc;
|
||||||
|
Valid |= DTV_STAT_VALID_BERPOST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
if (Per) {
|
||||||
|
if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
|
||||||
|
if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
|
||||||
|
uint64_t ebc = Props[i].u.st.stat[0].uvalue; // error block count
|
||||||
|
uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue; // total block count
|
||||||
|
if (tbc > 0) {
|
||||||
|
*Per = double(ebc) / tbc;
|
||||||
|
Valid |= DTV_STAT_VALID_PER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_SIGNALSTATS
|
||||||
|
fprintf(stderr, "FE %d/%d: API5 %04X", adapter, frontend, Valid);
|
||||||
|
if ((Valid & DTV_STAT_VALID_STRENGTH) != 0) fprintf(stderr, " STR=%1.1fdBm", *Strength);
|
||||||
|
if ((Valid & DTV_STAT_VALID_CNR) != 0) fprintf(stderr, " CNR=%1.1fdB", *Cnr);
|
||||||
|
if ((Valid & DTV_STAT_VALID_BERPRE) != 0) fprintf(stderr, " BERPRE=%1.1e", *BerPre);
|
||||||
|
if ((Valid & DTV_STAT_VALID_BERPOST) != 0) fprintf(stderr, " BERPOST=%1.1e", *BerPost);
|
||||||
|
if ((Valid & DTV_STAT_VALID_PER) != 0) fprintf(stderr, " PER=%1.1e", *Per);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
#endif
|
||||||
|
return Valid != DTV_STAT_VALID_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
int dB1000toPercent(int dB1000, int Low, int High)
|
int dB1000toPercent(int dB1000, int Low, int High)
|
||||||
{
|
{
|
||||||
// Convert the given value, which is in 1/1000 dBm, to a percentage in the
|
// Convert the given value, which is in 1/1000 dBm, to a percentage in the
|
||||||
@ -1058,6 +1155,18 @@ void cDvbTuner::Action(void)
|
|||||||
isyslog("frontend %d/%d regained lock on channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder());
|
isyslog("frontend %d/%d regained lock on channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder());
|
||||||
LostLock = false;
|
LostLock = false;
|
||||||
}
|
}
|
||||||
|
if (tunerStatus == tsTuned) {
|
||||||
|
if (SysLogLevel >= 3) {
|
||||||
|
int Valid;
|
||||||
|
double Strength, Cnr;
|
||||||
|
if (GetSignalStats(Valid, &Strength, &Cnr)) {
|
||||||
|
cString s = cString::sprintf("frontend %d/%d locked with signal", adapter, frontend);
|
||||||
|
if ((Valid & DTV_STAT_VALID_STRENGTH) != 0) s = cString::sprintf("%s STR=%1.1fdBm", *s, Strength);
|
||||||
|
if ((Valid & DTV_STAT_VALID_CNR) != 0) s = cString::sprintf("%s CNR=%1.1fdB", *s, Cnr);
|
||||||
|
dsyslog("%s", *s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
tunerStatus = tsLocked;
|
tunerStatus = tsLocked;
|
||||||
locked.Broadcast();
|
locked.Broadcast();
|
||||||
lastTimeoutReport = 0;
|
lastTimeoutReport = 0;
|
||||||
@ -1697,6 +1806,11 @@ const cPositioner *cDvbDevice::Positioner(void) const
|
|||||||
return dvbTuner ? dvbTuner->Positioner() : NULL;
|
return dvbTuner ? dvbTuner->Positioner() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDvbDevice::SignalStats(int &Valid, double *Strength, double *Cnr, double *BerPre, double *BerPost, double *Per) const
|
||||||
|
{
|
||||||
|
return dvbTuner ? dvbTuner->GetSignalStats(Valid, Strength, Cnr, BerPre, BerPost, Per) : false;
|
||||||
|
}
|
||||||
|
|
||||||
int cDvbDevice::SignalStrength(void) const
|
int cDvbDevice::SignalStrength(void) const
|
||||||
{
|
{
|
||||||
return dvbTuner ? dvbTuner->GetSignalStrength() : -1;
|
return dvbTuner ? dvbTuner->GetSignalStrength() : -1;
|
||||||
|
@ -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 4.2 2017/04/14 09:31:29 kls Exp $
|
* $Id: dvbdevice.h 4.3 2017/04/17 14:44:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBDEVICE_H
|
#ifndef __DVBDEVICE_H
|
||||||
@ -244,6 +244,7 @@ public:
|
|||||||
virtual bool ProvidesEIT(void) const;
|
virtual bool ProvidesEIT(void) const;
|
||||||
virtual int NumProvidedSystems(void) const;
|
virtual int NumProvidedSystems(void) const;
|
||||||
virtual const cPositioner *Positioner(void) const;
|
virtual const cPositioner *Positioner(void) const;
|
||||||
|
virtual bool SignalStats(int &Valid, double *Strength = NULL, double *Cnr = NULL, double *BerPre = NULL, double *BerPost = NULL, double *Per = NULL) const;
|
||||||
virtual int SignalStrength(void) const;
|
virtual int SignalStrength(void) const;
|
||||||
virtual int SignalQuality(void) const;
|
virtual int SignalQuality(void) const;
|
||||||
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user