Redesigned the user interface.

Transponder information is now available in advanced display mode: Press 'OK' key to switch between the simple and the advanced display mode.
Moved bitrate calculation to it's own thread for improved accurancy.
This commit is contained in:
Rolf Ahrenberg 2004-03-03 04:20:00 +02:00
parent 52b9653b42
commit 23487c5972
12 changed files with 762 additions and 212 deletions

View File

@ -7,7 +7,7 @@ VDR Plugin 'femon' Revision History
2004-02-23: Version 0.0.1b
- Fixed cThread to work under vdr-1.2.6.
- Fixed cThread initialization to work under vdr-1.2.6.
2004-02-26: Version 0.0.2
@ -22,3 +22,10 @@ VDR Plugin 'femon' Revision History
- Translation only update:
Fixed 'Deutsch' (Thanks to Olaf Henkel @ VDRPortal).
Added 'Italiano' (Thanks to Sean Carlos).
2004-03-03: Version 0.0.3
- Redesigned the user interface.
- Transponder information is now available in advanced display mode:
Press 'OK' key to switch between the simple and the advanced display mode.
- Moved bitrate calculation to it's own thread for improved accurancy.

43
README
View File

@ -11,34 +11,33 @@ See the file COPYING for license information.
Requirements:
Ph.D. in Astro Physics and preferably a six-pack waiting in a fridge.
Never trust a Klingon.
Description:
DVB Frontend Status Monitor is a plugin that displays a few signal quality parameters
of the tuned channel on your screen. You can zap through all your channels and the
plugin should be monitoring always the right frontend *fingers crossed*. A short
message is shown at the bottom line to help the DVB card identification after each
channel switch and OK press.
DVB Frontend Status Monitor is a plugin that displays some signal information
parameters of the current tuned channel on OSD. You can zap through all your
channels and the plugin should be monitoring always the right frontend. The
transponder information is also available in advanced display mode. User can
switch between simple and advanced display modes by pressing 'OK' key.
The plugin is based on a neat console frontend status monitor application called
'femon' by Johannes Stezenbach <js@convergence.de> (see DVB-apps/szap/femon.c for
further information). The other parts of plugin code are borrowed from the
excellent OSD Picture-In-Picture plugin by Sascha Volkenandt <sascha@akv-soft.de>
and Andreas Regel <andreas.regel@powarman.de>. Props to Sascha for being brave
enough to test this piece of junk and ofcourse for german translations. The bitrate
calculation algorithm is originally copied from dvbstream application by Dave Chapman
<dave@dchapman.com>.
The plugin is based on a neat console frontend status monitor application called
'femon' by Johannes Stezenbach <js@convergence.de> (see DVB-apps/szap/femon.c
for further information). The other parts of plugin code are borrowed from the
excellent 'OSD Picture-In-Picture' plugin by Sascha Volkenandt <sascha@akv-soft.de>
and Andreas Regel <andreas.regel@powarman.de>. The bitrate calculation algorithm
originates from the 'dvbstream' application by Dave Chapman <dave@dchapman.com>.
Shortcomings / Todo list:
- The current version is a kind of Proof In Concept to replace the old 'tech
patch', so the internals will be eventually rewritten... if I'll find some
spare time.
- The plugin supports only those DVB cards with _one_ frontend (do any cards with
multiple frontends even exist?), because I haven't yet figured howto do it without
patching the VDR core.
patch', and it's now eating many unnecessary cpu clock cycles - this will be
fixed later...
- The plugin supports only those DVB cards with _one_ frontend (do any cards
with multiple frontends even exist?), because I haven't yet figured howto do
it without patching the VDR core.
- Sometimes (read always) ttxtsubs plugin messes up the OSD - user should disable
ttxtsubs, but closing and reopening the femon plugin might help temporarily as well.
Btw., this same thing happens with OSDTeletext plugin too :)
- The plugin GUI is designed for small fonts, so stable vdr-1.2.6 users should consider
the ElchiAIO4a+ patch to maximize the *wow* effect :)
ttxtsubs, but closing and reopening the femon plugin might help temporarily as
well. Btw., this same thing happens with OSDTeletext plugin too :)
- The plugin GUI is designed for _small fonts_, so stable vdr-1.2.6 users should
consider a small font patch (e.g. ElchiAIO4a) to maximize the visual effect :)

66
femon.c
View File

@ -1,5 +1,5 @@
/*
* A Frontend Monitor plugin for the Video Disk Recorder
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
@ -63,11 +63,14 @@ cOsdObject *cPluginFemon::MainMenuAction(void)
bool cPluginFemon::SetupParse(const char *Name, const char *Value)
{
// Parse your own setup parameters and store their values.
if (!strcasecmp(Name, "HideMenu")) femonConfig.hidemenu = atoi(Value);
else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value);
else if (!strcasecmp(Name, "Interval")) femonConfig.interval = atoi(Value);
else if (!strcasecmp(Name, "RedLimit")) femonConfig.redlimit = atoi(Value);
else if (!strcasecmp(Name, "GreenLimit")) femonConfig.greenlimit = atoi(Value);
if (!strcasecmp(Name, "HideMenu")) femonConfig.hidemenu = atoi(Value);
else if (!strcasecmp(Name, "DisplayMode")) femonConfig.displaymode = atoi(Value);
else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value);
else if (!strcasecmp(Name, "RedLimit")) femonConfig.redlimit = atoi(Value);
else if (!strcasecmp(Name, "GreenLimit")) femonConfig.greenlimit = atoi(Value);
else if (!strcasecmp(Name, "UpdateInterval")) femonConfig.updateinterval = atoi(Value);
else if (!strcasecmp(Name, "ShowBitRate")) femonConfig.showbitrate = atoi(Value);
else if (!strcasecmp(Name, "CalcInterval")) femonConfig.calcinterval = atoi(Value);
else
return false;
@ -76,20 +79,51 @@ bool cPluginFemon::SetupParse(const char *Name, const char *Value)
cMenuFemonSetup::cMenuFemonSetup(void)
{
Add(new cMenuEditBoolItem(tr("Hide Mainmenu Entry"), &femonConfig.hidemenu, tr("no"), tr("yes")));
Add(new cMenuEditBoolItem(tr("Position"), &femonConfig.position, tr("bottom"), tr("top")));
Add(new cMenuEditIntItem( tr("Update Interval [0.1s]"), &femonConfig.interval, 5, 50));
Add(new cMenuEditIntItem( tr("Red Limit [%]"), &femonConfig.redlimit, 1, 50));
Add(new cMenuEditIntItem( tr("Green Limit [%]"), &femonConfig.greenlimit, 51, 100));
Setup();
}
void cMenuFemonSetup::Setup(void)
{
int current = Current();
Clear();
Add(new cMenuEditBoolItem( tr("Hide Mainmenu Entry"), &femonConfig.hidemenu, tr("no"), tr("yes")));
Add(new cMenuEditBoolItem( tr("Default Display Mode"), &femonConfig.displaymode, tr("simple"), tr("advanced")));
Add(new cMenuEditBoolItem( tr("Position"), &femonConfig.position, tr("bottom"), tr("top")));
Add(new cMenuEditIntItem( tr("Red Limit [%]"), &femonConfig.redlimit, 1, 50));
Add(new cMenuEditIntItem( tr("Green Limit [%]"), &femonConfig.greenlimit, 51, 100));
Add(new cMenuEditIntItem( tr("OSD Update Interval [0.1s]"), &femonConfig.updateinterval, 1, 100));
Add(new cMenuEditBoolItem( tr("Bitrate Calculation"), &femonConfig.showbitrate, tr("no"), tr("yes")));
if (femonConfig.showbitrate)
Add(new cMenuEditIntItem(tr("Calculation Interval [0.1s]"), &femonConfig.calcinterval, 1, 100));
SetCurrent(Get(current));
Display();
}
void cMenuFemonSetup::Store(void)
{
SetupStore("HideMenu", femonConfig.hidemenu);
SetupStore("Position", femonConfig.position);
SetupStore("Interval", femonConfig.interval);
SetupStore("RedLimit", femonConfig.redlimit);
SetupStore("GreenLimit", femonConfig.greenlimit);
SetupStore("HideMenu", femonConfig.hidemenu);
SetupStore("Position", femonConfig.position);
SetupStore("DisplayMode", femonConfig.displaymode);
SetupStore("RedLimit", femonConfig.redlimit);
SetupStore("GreenLimit", femonConfig.greenlimit);
SetupStore("UpdateInterval", femonConfig.updateinterval);
SetupStore("ShowBitRate", femonConfig.showbitrate);
SetupStore("CalcInterval", femonConfig.calcinterval);
}
eOSState cMenuFemonSetup::ProcessKey(eKeys Key)
{
int oldShowbitrate = femonConfig.showbitrate;
eOSState state = cMenuSetupPage::ProcessKey(Key);
if (Key != kNone && (femonConfig.showbitrate != oldShowbitrate)) {
Setup();
}
return state;
}
cMenuSetupPage *cPluginFemon::SetupMenu(void)

23
femon.h
View File

@ -1,11 +1,19 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef __FEMON_H
#define __FEMON_H
#include <vdr/plugin.h>
static const char *VERSION = "0.0.2c";
static const char *DESCRIPTION = "DVB Signal Quality Monitor (OSD)";
static const char *MAINMENUENTRY = "Signal Quality";
static const char *VERSION = "0.0.3";
static const char *DESCRIPTION = "DVB Signal Information Monitor (OSD)";
static const char *MAINMENUENTRY = "Signal Information";
class cPluginFemon : public cPlugin {
private:
@ -27,11 +35,14 @@ public:
};
class cMenuFemonSetup : public cMenuSetupPage {
private:
virtual void Setup(void);
protected:
virtual eOSState ProcessKey(eKeys Key);
virtual void Store(void);
public:
cMenuFemonSetup(void);
protected:
virtual void Store(void);
};
};
#endif //__FEMON_H

View File

@ -1,5 +1,5 @@
/*
* A Frontend Monitor plugin for the Video Disk Recorder
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
@ -12,9 +12,12 @@ cFemonConfig femonConfig;
cFemonConfig::cFemonConfig(void)
{
hidemenu = 0;
position = 1;
interval = 10;
redlimit = 33;
greenlimit = 66;
hidemenu = 0;
displaymode = 0;
position = 1;
redlimit = 33;
greenlimit = 66;
updateinterval = 5;
showbitrate = 1;
calcinterval = 20;
}

View File

@ -1,3 +1,11 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef __FEMONCFG_H
#define __FEMONCFG_H
@ -6,10 +14,13 @@ struct cFemonConfig
public:
cFemonConfig(void);
int hidemenu;
int displaymode;
int position;
int interval;
int redlimit;
int greenlimit;
int updateinterval;
int showbitrate;
int calcinterval;
};
extern cFemonConfig femonConfig;

View File

@ -1,5 +1,5 @@
/*
* A Frontend Monitor plugin for the Video Disk Recorder
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
@ -9,10 +9,10 @@
#include "femoni18n.h"
const tI18nPhrase Phrases[] = {
{ "DVB Signal Quality Monitor (OSD)", // English
"DVB Signalqualitäts-Anzeige (OSD)", // Deutsch
{ "DVB Signal Information Monitor (OSD)", // English
"DVB Signal Informationsanzeige (OSD)", // Deutsch
"", // Slovenski
"Visualizzazione della qualita' del segnale DVB (OSD)", // Italiano
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
@ -29,10 +29,10 @@ const tI18nPhrase Phrases[] = {
"" // ÀãááÚØÙ
#endif
},
{ "Signal Quality", // English
"Signalqualität", // Deutsch
{ "Signal Information", // English
"Signalinformationen", // Deutsch
"", // Slovenski
"Qualita' del segnale", // Italiano
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
@ -67,6 +67,66 @@ const tI18nPhrase Phrases[] = {
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Default Display Mode", // English
"Standard Anzeigemodus", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Oletus näyttömoodi", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "simple", // English
"einfach", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"suppea", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "advanced", // English
"fortgeschritten", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"laaja", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Hide Mainmenu Entry", // English
@ -89,15 +149,55 @@ const tI18nPhrase Phrases[] = {
"" // ÀãááÚØÙ
#endif
},
{ "Update Interval [0.1s]", // English
"Aktualisierung alle [0.1s]", // Deutsch
{ "OSD Update Interval [0.1s]", // English
"OSD Updateintervall [0.1s]", // Deutsch
"", // Slovenski
"Intervallo di aggiornamento [0.1s]", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Päivitystaajuus [0.1s]", // suomi
"Näytön päivitysväli [0.1s]", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Bitrate Calculation", // English
"Bitratenberechnung", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Bittinopeuden laskenta", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Calculation Interval [0.1s]", // English
"Berechnungsintervall [0.1s]", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Laskennan päivitysväli [0.1s]", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
@ -147,6 +247,86 @@ const tI18nPhrase Phrases[] = {
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Transponder Information", // English
"Transponderinformation", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Transponderin tiedot", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Satellite Card", // English
"Satellitenkarte", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Satelliittikortti", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Cable Card", // English
"Kabelkarte", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Kaapelikortti", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ "Terrestial Card", // English
"Terrestrische Karte", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Português
"", // Français
"", // Norsk
"Terrestiaalikortti", // suomi
"", // Polski
"", // Español
"", // ÅëëçíéêÜ
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Català
#if VDRVERSNUM >= 10300
"" // ÀãááÚØÙ
#endif
},
{ NULL }

View File

@ -1,3 +1,11 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef __FEMONI18N_H
#define __FEMONI18N_H

View File

@ -1,48 +1,75 @@
/*
* A Frontend Monitor plugin for the Video Disk Recorder
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#include <ctype.h>
#include "femoncfg.h"
#include "femoni18n.h"
#include "femonreceiver.h"
#include "femonosd.h"
#define FE_DEVICE "/dev/dvb/adapter%d/frontend%d"
#if (VDRVERSNUM < 10300) && !defined(ELCHIAIOVERSION)
#warning You should consider using the small fonts!
#endif
#define FE_DEVICE "/dev/dvb/adapter%d/frontend%d"
#define CHANNELINPUT_TIMEOUT 1000
#define CHANNELINFO_TIMEOUT 5000
#define OSDHEIGHT 5
#define OSDWIDTH 46
#define OSDINFOHEIGHT 11
#define OSDGAPHEIGHT 1
#define OSDSTATUSHEIGHT 6
#define OSDSTATUSCOL1 1
#define OSDSTATUSCOL2 10
#define OSDSTATUSCOL3 17
#define OSDSTATUSCOL4 32
#define OSDSTATUSLOCK 1
#define OSDSTATUSSIGN 9
#define OSDSTATUSCARR 19
#define OSDSTATUSVITE 30
#define OSDSTATUSSYNC 40
#define OSDINFOLCOL1 1
#define OSDINFOLCOL2 14
#define OSDINFOLCOL3 23
#define OSDINFOLCOL4 36
cFemonOsd::cFemonOsd(void)
#if VDRVERSNUM >= 10300
:cOsdObject(true), cThread("femon plugin")
#else
:cOsdObject(true), cThread()
:cOsdObject(true)
#endif
{
//printf("cFemonOsd::cFemonOsd()\n");
m_Osd = NULL;
m_Window = -1;
m_InfoWindow = -1;
m_StatusWindow = -1;
m_Receiver = NULL;
m_Frontend = -1;
m_Active = false;
m_Number = 0;
m_InputTime = 0;
m_InfoTime = 0;
m_Width = Setup.OSDwidth * cOsd::CellWidth();
m_Height = OSDHEIGHT * cOsd::LineHeight();
m_Xpos = (720 - m_Width) / 2;
m_Ypos = (576 - Setup.OSDheight * cOsd::LineHeight()) / 2 + ( femonConfig.position ? 0 : (Setup.OSDheight - OSDHEIGHT) * cOsd::LineHeight());
m_Signal = 0;
m_SNR = 0;
m_BER = 0;
m_UNC = 0;
m_DisplayMode = femonConfig.displaymode;
m_Mutex = new cMutex();
}
cFemonOsd::~cFemonOsd(void)
{
//printf("cFemonOsd::~cFemonOsd()\n");
if (m_Active) {
m_Active = false;
Cancel(3);
Cancel(5);
}
if (m_Receiver)
delete m_Receiver;
@ -50,97 +77,326 @@ cFemonOsd::~cFemonOsd(void)
delete m_Osd;
}
void cFemonOsd::DrawStatusWindow(void)
{
cMutexLock lock(m_Mutex);
//printf("cFemonOsd::DrawStatusWindow()\n");
char buf[128];
int snr = m_SNR / 655;
int signal = m_Signal / 655;
int lines = 0;
if (m_Osd) {
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
eDvbFont OldFont = m_Osd->SetFont(fontSml);
#endif
m_Osd->Clear(m_StatusWindow);
snprintf(buf, sizeof(buf), "%d%s %s", m_Number ? m_Number : Channels.GetByNumber(cDevice::CurrentChannel())->Number(), m_Number ? "-" : "", Channels.GetByNumber(cDevice::CurrentChannel())->Name());
m_Osd->Fill(0, femonConfig.position ? 0 : (OSDINFOHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight(), OSDWIDTH * cOsd::CellWidth(), femonConfig.position ? cOsd::LineHeight() - 1 : (OSDINFOHEIGHT + OSDGAPHEIGHT + 1) * cOsd::LineHeight() - 1, clrWhite, m_StatusWindow);
m_Osd->Text(OSDSTATUSCOL1 * cOsd::CellWidth(), femonConfig.position ? 0 : (OSDINFOHEIGHT + OSDGAPHEIGHT + 0) * cOsd::LineHeight(), buf, clrBlack, clrWhite, m_StatusWindow);
lines++;
if (signal > 0) {
signal = (OSDWIDTH * cOsd::CellWidth()) * signal / 100;
m_Osd->Fill(0, femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, min(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100), signal), femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrRed, m_StatusWindow);
if (signal > ((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100)) {
m_Osd->Fill(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100), femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, min(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100), signal), femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrYellow, m_StatusWindow);
}
if (signal > ((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100)) {
m_Osd->Fill(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100), femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, signal, femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrGreen, m_StatusWindow);
}
}
lines++;
if (snr > 0) {
snr = (OSDWIDTH * cOsd::CellWidth()) * snr / 100;
m_Osd->Fill(0, femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, min(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100), snr), femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrRed, m_StatusWindow);
if (snr > ((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100)) {
m_Osd->Fill(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.redlimit / 100), femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, min(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100), snr), femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrYellow, m_StatusWindow);
}
if (snr > ((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100)) {
m_Osd->Fill(((OSDWIDTH * cOsd::CellWidth()) * femonConfig.greenlimit / 100), femonConfig.position ? lines * cOsd::LineHeight() + 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() + 3, snr, femonConfig.position ? (lines + 1) * cOsd::LineHeight() - 3 : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 3, clrGreen, m_StatusWindow);
}
}
lines++;
snprintf(buf, sizeof(buf), "STR: %04x", m_Signal);
m_Osd->Text(OSDSTATUSCOL1 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
snprintf(buf, sizeof(buf), "(%2d%%)", m_Signal / 655);
m_Osd->Text(OSDSTATUSCOL2 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite /*signal < femonConfig.redlimit ? clrRed : signal < femonConfig.greenlimit ? clrYellow : clrGreen*/, clrBackground, m_StatusWindow);
snprintf(buf, sizeof(buf), "BER: %08x", m_BER);
m_Osd->Text(OSDSTATUSCOL3 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
if (m_Receiver) snprintf(buf, sizeof(buf), "Video: %.2f Mbit/s",m_Receiver->VideoBitrate());
else snprintf(buf, sizeof(buf), "Video: --- Mbit/s");
m_Osd->Text(OSDSTATUSCOL4 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
lines++;
snprintf(buf, sizeof(buf), "SNR: %04x", m_SNR);
m_Osd->Text(OSDSTATUSCOL1 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
snprintf(buf, sizeof(buf), "(%2d%%)", m_SNR / 655);
m_Osd->Text(OSDSTATUSCOL2 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite /*snr < femonConfig.redlimit ? clrRed : snr < femonConfig.greenlimit ? clrYellow : clrGreen*/, clrBackground, m_StatusWindow);
snprintf(buf, sizeof(buf), "UNC: %08x", m_UNC);
m_Osd->Text(OSDSTATUSCOL3 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
if (m_Receiver) snprintf(buf, sizeof(buf), "Audio: %.0f kbit/s",m_Receiver->AudioBitrate());
else snprintf(buf, sizeof(buf), "Audio: --- kbit/s");
m_Osd->Text(OSDSTATUSCOL4 * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_StatusWindow);
lines++;
m_Osd->Text(OSDSTATUSLOCK * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), "LOCK", (m_FrontendStatus & FE_HAS_LOCK) ? clrYellow : clrBlack, clrBackground, m_StatusWindow);
m_Osd->Text(OSDSTATUSSIGN * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), "SIGNAL", (m_FrontendStatus & FE_HAS_SIGNAL) ? clrYellow : clrBlack, clrBackground, m_StatusWindow);
m_Osd->Text(OSDSTATUSCARR * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), "CARRIER",(m_FrontendStatus & FE_HAS_CARRIER)? clrYellow : clrBlack, clrBackground, m_StatusWindow);
m_Osd->Text(OSDSTATUSVITE * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), "VITERBI",(m_FrontendStatus & FE_HAS_VITERBI)? clrYellow : clrBlack, clrBackground, m_StatusWindow);
m_Osd->Text(OSDSTATUSSYNC * cOsd::CellWidth(), femonConfig.position ? lines * cOsd::LineHeight() : (OSDINFOHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight(), "SYNC", (m_FrontendStatus & FE_HAS_SYNC) ? clrYellow : clrBlack, clrBackground, m_StatusWindow);
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
m_Osd->SetFont(OldFont);
#endif
m_Osd->Flush();
}
}
void cFemonOsd::DrawInfoWindow(void)
{
cMutexLock lock(m_Mutex);
//printf("cFemonOsd::DrawInfoWindow()\n");
char buf[128];
char buf2[20];
int lines = 0;
int value = 0;
if (m_Osd) {
if (m_DisplayMode) {
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
eDvbFont OldFont = m_Osd->SetFont(fontSml);
#endif
m_Osd->Clear(m_InfoWindow);
m_Osd->Fill(0, femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), OSDWIDTH * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines + 1) * cOsd::LineHeight() - 1 : (lines + 1) * cOsd::LineHeight() - 1, clrWhite, m_InfoWindow);
m_Osd->Text( OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines, tr("Transponder Information"), clrBackground, clrWhite, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Vpid"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Vpid());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Ppid"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Ppid());
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Apid1"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Apid1());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Tpid"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Tpid());
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("CA"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Ca());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Sid"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Sid());
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
#if (VDRVERSNUM >= 10300)
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), "Nid", clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Nid());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), "Tid" /*tr("Tid")*/, clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Tid());
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), "Rid" /*tr("Rid")*/, clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Rid());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
#endif
switch (m_FrontendInfo.type) {
case FE_QPSK:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Satellite Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Frequency"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d kHz", Channels.GetByNumber(cDevice::CurrentChannel())->Frequency());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Source"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%s", cSource::ToString(Channels.GetByNumber(cDevice::CurrentChannel())->Source()));
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Srate"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Srate());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Polarization"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%c", toupper(Channels.GetByNumber(cDevice::CurrentChannel())->Polarization()));
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Inversion"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Inversion();
if (value == 0) snprintf(buf, sizeof(buf), "Off");
else if (value == 1) snprintf(buf, sizeof(buf), "On");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("CoderateH"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->CoderateH();
if (value == 0) snprintf(buf, sizeof(buf), "None");
else if (value == 1) snprintf(buf, sizeof(buf), "1/2");
else if (value == 2) snprintf(buf, sizeof(buf), "2/3");
else if (value == 3) snprintf(buf, sizeof(buf), "3/4");
else if (value == 4) snprintf(buf, sizeof(buf), "4/5");
else if (value == 5) snprintf(buf, sizeof(buf), "5/6");
else if (value == 6) snprintf(buf, sizeof(buf), "6/7");
else if (value == 7) snprintf(buf, sizeof(buf), "7/8");
else if (value == 8) snprintf(buf, sizeof(buf), "8/9");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
break;
case FE_QAM:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Cable Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Frequency"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d kHz", Channels.GetByNumber(cDevice::CurrentChannel())->Frequency());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Source"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%s", cSource::ToString(Channels.GetByNumber(cDevice::CurrentChannel())->Source()));
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Srate"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d", Channels.GetByNumber(cDevice::CurrentChannel())->Srate());
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Modulation"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Modulation();
if (value == 0) snprintf(buf, sizeof(buf), "QPSK");
else if (value == 1) snprintf(buf, sizeof(buf), "QAM 16");
else if (value == 2) snprintf(buf, sizeof(buf), "QAM 32");
else if (value == 3) snprintf(buf, sizeof(buf), "QAM 64");
else if (value == 4) snprintf(buf, sizeof(buf), "QAM 128");
else if (value == 5) snprintf(buf, sizeof(buf), "QAM 256");
else snprintf(buf, sizeof(buf), "QAM Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Inversion"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Inversion();
if (value == 0) snprintf(buf, sizeof(buf), "Off");
else if (value == 1) snprintf(buf, sizeof(buf), "On");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("CoderateH"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->CoderateH();
if (value == 0) snprintf(buf, sizeof(buf), "None");
else if (value == 1) snprintf(buf, sizeof(buf), "1/2");
else if (value == 2) snprintf(buf, sizeof(buf), "2/3");
else if (value == 3) snprintf(buf, sizeof(buf), "3/4");
else if (value == 4) snprintf(buf, sizeof(buf), "4/5");
else if (value == 5) snprintf(buf, sizeof(buf), "5/6");
else if (value == 6) snprintf(buf, sizeof(buf), "6/7");
else if (value == 7) snprintf(buf, sizeof(buf), "7/8");
else if (value == 8) snprintf(buf, sizeof(buf), "8/9");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
break;
default:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Terrestial Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Frequency"), clrWhite, clrBackground, m_InfoWindow);
snprintf(buf, sizeof(buf), "%d kHz", Channels.GetByNumber(cDevice::CurrentChannel())->Frequency() / 1000);
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Transmission"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Transmission();
if (value == 0) snprintf(buf, sizeof(buf), "2K");
else if (value == 1) snprintf(buf, sizeof(buf), "8K");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text( OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Bandwidth"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Bandwidth();
if (value == 0) snprintf(buf, sizeof(buf), "6 MHz");
else if (value == 1) snprintf(buf, sizeof(buf), "7 MHz");
else if (value == 2) snprintf(buf, sizeof(buf), "8 MHz");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Modulation"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Modulation();
if (value == 0) snprintf(buf, sizeof(buf), "QPSK");
else if (value == 1) snprintf(buf, sizeof(buf), "QAM 16");
else if (value == 2) snprintf(buf, sizeof(buf), "QAM 32");
else if (value == 3) snprintf(buf, sizeof(buf), "QAM 64");
else if (value == 4) snprintf(buf, sizeof(buf), "QAM 128");
else if (value == 5) snprintf(buf, sizeof(buf), "QAM 256");
else snprintf(buf, sizeof(buf), "QAM Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Inversion"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Inversion();
if (value == 0) snprintf(buf, sizeof(buf), "Off");
else if (value == 1) snprintf(buf, sizeof(buf), "On");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("CoderateH"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->CoderateH();
if (value == 0) snprintf(buf, sizeof(buf), "None");
else if (value == 1) snprintf(buf, sizeof(buf), "1/2");
else if (value == 2) snprintf(buf, sizeof(buf), "2/3");
else if (value == 3) snprintf(buf, sizeof(buf), "3/4");
else if (value == 4) snprintf(buf, sizeof(buf), "4/5");
else if (value == 5) snprintf(buf, sizeof(buf), "5/6");
else if (value == 6) snprintf(buf, sizeof(buf), "6/7");
else if (value == 7) snprintf(buf, sizeof(buf), "7/8");
else if (value == 8) snprintf(buf, sizeof(buf), "8/9");
else snprintf(buf, sizeof(buf), "Auto");
value = Channels.GetByNumber(cDevice::CurrentChannel())->CoderateL();
if (value == 0) snprintf(buf2, sizeof(buf2), " - None");
else if (value == 1) snprintf(buf2, sizeof(buf2), " - 1/2");
else if (value == 2) snprintf(buf2, sizeof(buf2), " - 2/3");
else if (value == 3) snprintf(buf2, sizeof(buf2), " - 3/4");
else if (value == 4) snprintf(buf2, sizeof(buf2), " - 4/5");
else if (value == 5) snprintf(buf2, sizeof(buf2), " - 5/6");
else if (value == 6) snprintf(buf2, sizeof(buf2), " - 6/7");
else if (value == 7) snprintf(buf2, sizeof(buf2), " - 7/8");
else if (value == 8) snprintf(buf2, sizeof(buf2), " - 8/9");
else snprintf(buf2, sizeof(buf2), " - Auto");
strncat(buf, buf2, sizeof(buf));
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
lines++;
m_Osd->Text(OSDINFOLCOL1 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Hierarchy"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Hierarchy();
if (value == 0) snprintf(buf, sizeof(buf), "None");
else if (value == 1) snprintf(buf, sizeof(buf), "1");
else if (value == 2) snprintf(buf, sizeof(buf), "2");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL2 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
m_Osd->Text(OSDINFOLCOL3 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), tr("Guard"), clrWhite, clrBackground, m_InfoWindow);
value = Channels.GetByNumber(cDevice::CurrentChannel())->Guard();
if (value == 0) snprintf(buf, sizeof(buf), "1/4");
else if (value == 1) snprintf(buf, sizeof(buf), "1/8");
else if (value == 2) snprintf(buf, sizeof(buf), "1/16");
else if (value == 3) snprintf(buf, sizeof(buf), "1/32");
else snprintf(buf, sizeof(buf), "Auto");
m_Osd->Text(OSDINFOLCOL4 * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT + lines) * cOsd::LineHeight() : lines * cOsd::LineHeight(), buf, clrYellow, clrBackground, m_InfoWindow);
break;
}
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
m_Osd->SetFont(OldFont);
#endif
}
else {
m_Osd->Fill(0, femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight() : 0, OSDWIDTH * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDINFOHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight() : OSDINFOHEIGHT * cOsd::LineHeight(), clrTransparent, m_InfoWindow);
}
m_Osd->Flush();
}
}
void cFemonOsd::Action(void)
{
//printf("cFemonOsd::Action()\n");
int snr_o, signal_o;
uint16_t snr, signal;
uint32_t ber, unc;
fe_status_t fe_status;
char buf[128];
double VRate = 0.0;
double ARate = 0.0;
#if (VDRVERSNUM < 10300)
isyslog("femon plugin: thread started (pid = %d)", getpid());
#endif
m_Active = true;
while (m_Active) {
if (m_Frontend != -1) {
CHECK(ioctl(m_Frontend, FE_READ_STATUS, &fe_status));
CHECK(ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &signal));
CHECK(ioctl(m_Frontend, FE_READ_SNR, &snr));
CHECK(ioctl(m_Frontend, FE_READ_BER, &ber));
CHECK(ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &unc));
if (m_Osd) {
m_Osd->Clear(m_Window);
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
eDvbFont OldFont = m_Osd->SetFont(fontSml);
#endif
sprintf(buf, "%d%s%s", m_Number ? m_Number : cDevice::CurrentChannel(), m_Number ? "- " : " ", Channels.GetByNumber(cDevice::CurrentChannel())->Name());
m_Osd->Fill(0, 0, m_Width, cOsd::LineHeight() - 1, clrWhite, m_Window);
m_Osd->Text(cOsd::CellWidth(), 0, buf, clrBlack, clrWhite, m_Window);
if (m_Receiver) {
// do some averaging to smooth the value
VRate = (VRate + (8.0 * TS_SIZE * m_Receiver->VideoPacketCount()) / (femonConfig.interval * 102.4 * 1024.0)) / 2.0;
ARate = (ARate + (8.0 * TS_SIZE * m_Receiver->AudioPacketCount()) / (femonConfig.interval * 102.4)) / 2.0;
sprintf(buf, "V: %.2f Mbit/s", VRate);
m_Osd->Text((m_Width - 22 * cOsd::CellWidth()), 0, buf, clrBlack, clrWhite, m_Window);
sprintf(buf, "A: %.0f kbit/s", ARate);
m_Osd->Text((m_Width - 10 * cOsd::CellWidth()), 0, buf, clrBlack, clrWhite, m_Window);
}
sprintf(buf, "STR: %04x", signal);
m_Osd->Text(cOsd::CellWidth(), 3 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
sprintf(buf, "SNR: %04x", snr);
m_Osd->Text(11 * cOsd::CellWidth(), 3 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
sprintf(buf, "BER: %08x", ber);
m_Osd->Text(21 * cOsd::CellWidth(), 3 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
sprintf(buf, "UNC: %08x", unc);
m_Osd->Text(35 * cOsd::CellWidth(), 3 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
signal_o = signal / 655;
sprintf(buf, "STR: %2d%%", signal_o);
if (signal_o > 0) {
signal_o = (m_Width - 8 * cOsd::CellWidth()) * signal_o / 100;
m_Osd->Fill(0, cOsd::LineHeight() + 3, min(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100), signal_o), 2 * cOsd::LineHeight() - 3, clrRed, m_Window);
if (signal_o > ((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100)) {
m_Osd->Fill(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100), cOsd::LineHeight() + 3, min(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100), signal_o), 2 * cOsd::LineHeight() - 3, clrYellow, m_Window);
}
if (signal_o > ((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100)) {
m_Osd->Fill(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100), cOsd::LineHeight() + 3, signal_o, 2 * cOsd::LineHeight() - 3, clrGreen, m_Window);
}
m_Osd->Text(m_Width - 8 * cOsd::CellWidth(), cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
}
snr_o = snr / 655;
sprintf(buf, "SNR: %2d%%", snr_o);
if (snr_o > 0) {
snr_o = (m_Width - 8 * cOsd::CellWidth()) * snr_o / 100;
m_Osd->Fill(0, 2 * cOsd::LineHeight() + 3, min(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100), snr_o), 3 * cOsd::LineHeight() - 3, clrRed, m_Window);
if (snr_o > ((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100)) {
m_Osd->Fill(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.redlimit / 100), 2 * cOsd::LineHeight() + 3, min(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100), snr_o), 3 * cOsd::LineHeight() - 3, clrYellow, m_Window);
}
if (snr_o > ((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100)) {
m_Osd->Fill(((m_Width - 8 * cOsd::CellWidth()) * femonConfig.greenlimit / 100), 2 * cOsd::LineHeight() + 3, snr_o, 3 * cOsd::LineHeight() - 3, clrGreen, m_Window);
}
m_Osd->Text(m_Width - 8 * cOsd::CellWidth(), 2 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
}
if (time_ms() - m_InfoTime < CHANNELINFO_TIMEOUT) {
sprintf(buf, "%s Card #%d - %s", m_FrontendInfo.type == FE_QPSK ? "Satellite" : m_FrontendInfo.type == FE_QAM ? "Cable" : "Terrestial", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->Text(cOsd::CellWidth(), 4 * cOsd::LineHeight(), buf, clrWhite, clrBackground, m_Window);
}
else {
m_Osd->Text( 1 * cOsd::CellWidth(), 4 * cOsd::LineHeight(), "LOCK", (fe_status & FE_HAS_LOCK) ? clrYellow : clrBlack, clrBackground, m_Window);
m_Osd->Text( 9 * cOsd::CellWidth(), 4 * cOsd::LineHeight(), "SIGNAL", (fe_status & FE_HAS_SIGNAL) ? clrYellow : clrBlack, clrBackground, m_Window);
m_Osd->Text( 19 * cOsd::CellWidth(), 4 * cOsd::LineHeight(), "CARRIER",(fe_status & FE_HAS_CARRIER) ? clrYellow : clrBlack, clrBackground, m_Window);
m_Osd->Text( 30 * cOsd::CellWidth(), 4 * cOsd::LineHeight(), "VITERBI",(fe_status & FE_HAS_VITERBI) ? clrYellow : clrBlack, clrBackground, m_Window);
m_Osd->Text( 40 * cOsd::CellWidth(), 4 * cOsd::LineHeight(), "SYNC", (fe_status & FE_HAS_SYNC) ? clrYellow : clrBlack, clrBackground, m_Window);
}
#if (VDRVERSNUM >= 10300) || defined(ELCHIAIOVERSION)
m_Osd->SetFont(OldFont);
#endif
m_Osd->Flush();
}
CHECK(ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus));
CHECK(ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal));
CHECK(ioctl(m_Frontend, FE_READ_SNR, &m_SNR));
CHECK(ioctl(m_Frontend, FE_READ_BER, &m_BER));
CHECK(ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC));
DrawInfoWindow();
DrawStatusWindow();
}
usleep(100000L * femonConfig.interval);
usleep(100000L * femonConfig.updateinterval);
}
#if (VDRVERSNUM < 10300)
isyslog("femon plugin: thread stopped (pid = %d)", getpid());
@ -165,24 +421,19 @@ void cFemonOsd::Show(void)
close(m_Frontend);
return;
}
m_InfoTime = time_ms();
m_Osd = cOsd::OpenRaw(m_Xpos, m_Ypos);
m_Osd = cOsd::OpenRaw((720 - OSDWIDTH * cOsd::CellWidth()) / 2, (576 - (OSDSTATUSHEIGHT + OSDINFOHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight()) / 2);
if (m_Osd) {
//printf("X: %d - Y: %d - W: %d - H: %d\n", m_Xpos, m_Ypos, m_Width, m_Height);
m_Window = m_Osd->Create(0, 0, m_Width, m_Height, 4);
m_Osd->AddColor(clrBackground, m_Window);
m_Osd->AddColor(clrRed, m_Window);
m_Osd->AddColor(clrGreen, m_Window);
m_Osd->AddColor(clrYellow, m_Window);
m_Osd->AddColor(clrWhite, m_Window);
m_Osd->AddColor(clrBlack, m_Window);
m_Osd->AddColor(clrTransparent, m_Window);
m_Osd->Clear(m_Window);
m_StatusWindow = m_Osd->Create(0, femonConfig.position ? 0 : (OSDINFOHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight(), OSDWIDTH * cOsd::CellWidth(), OSDSTATUSHEIGHT * cOsd::LineHeight(), 4);
m_InfoWindow = m_Osd->Create(0, femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight() : 0, OSDWIDTH * cOsd::CellWidth(), OSDINFOHEIGHT * cOsd::LineHeight(), 2);
m_Osd->Clear();
m_Osd->Fill(0, femonConfig.position ? (OSDSTATUSHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight() : 0, OSDWIDTH * cOsd::CellWidth(), femonConfig.position ? (OSDSTATUSHEIGHT + OSDINFOHEIGHT + OSDGAPHEIGHT) * cOsd::LineHeight() : OSDINFOHEIGHT * cOsd::LineHeight(), clrTransparent, m_InfoWindow);
m_Osd->Flush();
if (m_Receiver)
delete m_Receiver;
m_Receiver = new cFemonReceiver(Channels.GetByNumber(cDevice::CurrentChannel())->Ca(), Channels.GetByNumber(cDevice::CurrentChannel())->Vpid(), Channels.GetByNumber(cDevice::CurrentChannel())->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
if (femonConfig.showbitrate) {
m_Receiver = new cFemonReceiver(Channels.GetByNumber(cDevice::CurrentChannel())->Ca(), Channels.GetByNumber(cDevice::CurrentChannel())->Vpid(), Channels.GetByNumber(cDevice::CurrentChannel())->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
}
Start();
}
}
@ -208,9 +459,10 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
}
if (m_Receiver)
delete m_Receiver;
m_Receiver = new cFemonReceiver(Channels.GetByNumber(cDevice::CurrentChannel())->Ca(), Channels.GetByNumber(cDevice::CurrentChannel())->Vpid(), Channels.GetByNumber(cDevice::CurrentChannel())->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
m_InfoTime = time_ms();
if (femonConfig.showbitrate) {
m_Receiver = new cFemonReceiver(Channels.GetByNumber(cDevice::CurrentChannel())->Ca(), Channels.GetByNumber(cDevice::CurrentChannel())->Vpid(), Channels.GetByNumber(cDevice::CurrentChannel())->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
}
}
eOSState cFemonOsd::ProcessKey(eKeys Key)
@ -221,7 +473,7 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
switch (Key & ~k_Repeat) {
case k0:
if (m_Number == 0) {
// keep the "Toggle channels" function working
// keep the "Toggle channels" function working - however it isn't working now :)
cRemote::Put(Key);
return osContinue;
}
@ -229,6 +481,7 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
if (m_Number >= 0) {
m_Number = m_Number * 10 + Key - k0;
if (m_Number > 0) {
DrawStatusWindow();
cChannel *ch = Channels.GetByNumber(m_Number);
m_InputTime = time_ms();
// Lets see if there can be any useful further input:
@ -264,13 +517,14 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
m_Number = 0;
}
else {
m_Number = 0;
m_InputTime = time_ms();
m_Number = 0;
}
}
break;
case kOk:
m_InfoTime = time_ms();
m_DisplayMode ^= 1; // toggle between advanced and simple display mode
DrawInfoWindow();
break;
default:
break;

View File

@ -1,3 +1,11 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef __FEMONOSD_H
#define __FEMONOSD_H
@ -9,23 +17,27 @@
#include <vdr/status.h>
#include <vdr/channels.h>
#include <vdr/font.h>
#include <vdr/device.h> // only for TS_SIZE
class cFemonOsd : public cOsdObject, public cThread, public cStatus {
private:
bool m_Active;
cOsdBase *m_Osd;
tWindowHandle m_Window;
tWindowHandle m_InfoWindow;
tWindowHandle m_StatusWindow;
cFemonReceiver *m_Receiver;
int m_Frontend;
struct dvb_frontend_info m_FrontendInfo;
int m_Number;
int m_InputTime;
int m_InfoTime;
int m_Width;
int m_Height;
int m_Xpos;
int m_Ypos;
uint16_t m_SNR;
uint16_t m_Signal;
uint32_t m_BER;
uint32_t m_UNC;
fe_status_t m_FrontendStatus;
int m_DisplayMode;
cMutex* m_Mutex;
void DrawStatusWindow(void);
void DrawInfoWindow(void);
protected:
virtual void Action(void);

View File

@ -1,31 +1,45 @@
/*
* A Frontend Monitor plugin for the Video Disk Recorder
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#include <unistd.h>
#include "femoncfg.h"
#include "femonreceiver.h"
cFemonReceiver::cFemonReceiver(int Ca, int Vpid, int Apid)
#if VDRVERSNUM >= 10300
:cReceiver(Ca, -1, 2, Vpid, Apid), cThread("femon receiver")
#else
:cReceiver(Ca, -1, 2, Vpid, Apid)
#endif
{
//printf("cFemonReceiver::cFemonReceiver()\n");
m_VPid = Vpid;
m_APid = Apid;
m_VideoCount = 0;
m_AudioCount = 0;
m_Active = false;
m_VideoPid = Vpid;
m_AudioPid = Apid;
m_VideoPacketCount = 0;
m_AudioPacketCount = 0;
m_VideoBitrate = 0.0;
m_AudioBitrate = 0.0;
}
cFemonReceiver::~cFemonReceiver(void)
{
//printf("cFemonReceiver::~cFemonReceiver()\n");
if (m_Active) {
m_Active = false;
Cancel(5);
}
}
void cFemonReceiver::Activate(bool On)
{
//printf("cFemonReceiver::Activate()\n");
Start();
}
void cFemonReceiver::Receive(uchar *Data, int Length)
@ -33,27 +47,31 @@ void cFemonReceiver::Receive(uchar *Data, int Length)
//printf("cFemonReceiver::Receive()\n");
if (Length == TS_SIZE) {
int pid = ((Data[1] & 0x1f) << 8) | (Data[2]);
if (pid == m_VPid) {
m_VideoCount++;
if (pid == m_VideoPid) {
m_VideoPacketCount++;
}
else if (pid == m_APid) {
m_AudioCount++;
else if (pid == m_AudioPid) {
m_AudioPacketCount++;
}
}
}
int cFemonReceiver::VideoPacketCount(void)
void cFemonReceiver::Action(void)
{
//printf("cFemonReceiver::VideoPacketCount()\n");
int count = m_VideoCount;
m_VideoCount = 0;
return count;
}
int cFemonReceiver::AudioPacketCount(void)
{
//printf("cFemonReceiver::AudioPacketCount()\n");
int count = m_AudioCount;
m_AudioCount = 0;
return count;
//printf("cFemonReceiver::Action()\n");
#if (VDRVERSNUM < 10300)
isyslog("femon receiver: thread started (pid = %d)", getpid());
#endif
m_Active = true;
while (m_Active) {
// should we do some averaging to smooth the bitrates ?
m_VideoBitrate = (8.0 * TS_SIZE * m_VideoPacketCount) / (femonConfig.calcinterval * 102.4 * 1024.0);
m_VideoPacketCount = 0;
m_AudioBitrate = (8.0 * TS_SIZE * m_AudioPacketCount) / (femonConfig.calcinterval * 102.4);
m_AudioPacketCount = 0;
usleep(100000L * femonConfig.calcinterval);
}
#if (VDRVERSNUM < 10300)
isyslog("femon receiver: thread stopped (pid = %d)", getpid());
#endif
}

View File

@ -1,26 +1,39 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef __FEMONRECEIVER_H
#define __FEMONRECEIVER_H
#include <vdr/device.h> // only for TS_SIZE
#include <vdr/thread.h>
#include <vdr/receiver.h>
class cFemonReceiver : public cReceiver {
class cFemonReceiver : public cReceiver, public cThread {
private:
int m_VPid;
int m_APid;
int m_VideoCount;
int m_AudioCount;
bool m_Active;
int m_VideoPid;
int m_AudioPid;
int m_VideoPacketCount;
int m_AudioPacketCount;
double m_VideoBitrate;
double m_AudioBitrate;
protected:
virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length);
virtual void Action(void);
public:
cFemonReceiver(int Ca, int Vpid, int Apid);
virtual ~cFemonReceiver();
int VideoPacketCount(void);
int AudioPacketCount(void);
double VideoBitrate(void) { return m_VideoBitrate; };
double AudioBitrate(void) { return m_AudioBitrate; };
};
#endif //__FEMONRECEIVER_H