1
0
mirror of https://github.com/rofafor/vdr-plugin-femon.git synced 2023-10-10 11:36:53 +00:00

Compare commits

..

9 Commits

Author SHA1 Message Date
Rolf Ahrenberg
74ed4d8490 Added "Stream Information" display mode.
Toggle between different modes with 'OK' key:
 .-> basic -> transponder -> stream -.
 `-----------------------------------´
Added missing german translations (Thanks to Peter Marquardt).
2004-05-30 04:20:00 +03:00
Rolf Ahrenberg
8c7c110cf2 Updated for vdr-1.3.7 and removed compability with older versions. 2004-05-18 04:20:00 +03:00
Rolf Ahrenberg
ba7896b59a Fixed minor bitrate calculation errors.
Added russian translation (Thanks to Vyacheslav Dikonov).
2004-04-04 04:20:00 +03:00
Rolf Ahrenberg
43c68bcf23 Fixed channel toggling with '0' key.
Bitrate calculation thread is now canceled immediately to speed up channel switching.
2004-03-16 04:20:00 +02:00
Rolf Ahrenberg
954f09182f Fixed frequency, guard and bandwidth units in transponder information.
Added Apid2, Dpid1, Dpid2 information.
Added option to write signal information into system log.
2004-03-07 04:20:00 +02:00
Rolf Ahrenberg
23487c5972 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.
2004-03-03 04:20:00 +02:00
Rolf Ahrenberg
52b9653b42 Translation only update:
Fixed 'Deutsch' (Thanks to Olaf Henkel @ VDRPortal).
Added 'Italiano' (Thanks to Sean Carlos).
2004-02-28 04:20:00 +02:00
Rolf Ahrenberg
c6ac49bfed Some minor cosmetic changes. 2004-02-27 04:20:00 +02:00
Rolf Ahrenberg
2d06d2c6c1 Added preliminary video (VPID) and audio (APID1) bitrate calculations. 2004-02-26 04:20:00 +02:00
13 changed files with 1845 additions and 224 deletions

57
HISTORY
View File

@@ -7,4 +7,59 @@ 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
- Added preliminary video (VPID) and audio (APID1) bitrate calculations.
2004-02-27: Version 0.0.2b
- Some minor cosmetic changes.
2004-02-28: Version 0.0.2c
- 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.
2004-03-07: Version 0.0.3a
- Fixed frequency, guard and bandwidth units in transponder information.
- Added Apid2, Dpid1, Dpid2 information.
- Added option to write signal information into system log.
2004-03-16: Version 0.0.3b
- Fixed channel toggling with '0' key.
- Bitrate calculation thread is now canceled immediately to speed up channel switching.
2004-04-04: Version 0.0.3c
- Fixed minor bitrate calculation errors.
- Added russian translation (Thanks to Vyacheslav Dikonov).
2004-05-31: Version 0.0.4
- Backported "stream information" feature (from version 0.1.1).
-------------------------
2004-05-18: Version 0.1.0
- Updated for vdr-1.3.7 and removed compability with older versions.
2004-05-30: Version 0.1.1
- Added "Stream Information" display mode.
Toggle between different modes with 'OK' key:
.-> basic -> transponder -> stream -.
`-----------------------------------<2D>
- Added missing german translations (Thanks to Peter Marquardt).

View File

@@ -46,7 +46,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
OBJS = femon.o femonosd.o femoncfg.o femoni18n.o
OBJS = femon.o femonosd.o femonreceiver.o femoncfg.o femoni18n.o
### Implicit rules:

43
README
View File

@@ -11,31 +11,32 @@ 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. "Qu'vaD lI' De'vam". Beam me up, Scotty!
You're number six! I'm number two.
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 and stream information are also available in advanced display modes.
User can switch between different 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 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 and Andreas Regel.
The bitrate calculation algorithm originates from the 'dvbstream' application by
Dave Chapman and the stream information routines from the 'libdvb' library by
Metzler Brothers.
Shortcomings / Todo list:
Shortcomings / Todo list / Important Notes:
- 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.
- 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 as well. BTW. the
same things happens with OSDTeletext plugin too :)
- Where's the bitrate!?
ttxtsubs, but closing and reopening the femon plugin might help temporarily as
well. Btw., this same thing happens with OSDTeletext plugin too :)
- Disable the stream analyze to speed up heavy zapping sessions.
- If you're using VDR version 1.3.6 or older, you'll have to stick with femon-0.0.4!

83
femon.c
View File

@@ -1,14 +1,20 @@
/*
* 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 "femon.h"
#include "femonosd.h"
#include "femoncfg.h"
#include "femoni18n.h"
#include "femonreceiver.h"
#include "femonosd.h"
#include "femon.h"
#if VDRVERSNUM < 10307
#error "You don't exist! Go away!"
#endif
cPluginFemon::cPluginFemon(void)
{
@@ -61,33 +67,74 @@ 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, "SyslogOutput")) femonConfig.syslogoutput = 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, "AnalStream")) femonConfig.analyzestream = atoi(Value);
else if (!strcasecmp(Name, "CalcInterval")) femonConfig.calcinterval = atoi(Value);
else
return false;
if (femonConfig.displaymode < 0 || femonConfig.displaymode >= modeMaxNumber) femonConfig.displaymode = 0;
return true;
}
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, 1, 20));
Add(new cMenuEditIntItem( tr("Red Limit [%]"), &femonConfig.redlimit, 1, 50));
Add(new cMenuEditIntItem( tr("Green Limit [%]"), &femonConfig.greenlimit, 51, 100));
dispmodes[0] = tr("basic");
dispmodes[1] = tr("transponder");
dispmodes[2] = tr("stream");
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("Use Syslog Output"), &femonConfig.syslogoutput, tr("no"), tr("yes")));
Add(new cMenuEditStraItem( tr("Default Display Mode"), &femonConfig.displaymode, modeMaxNumber, dispmodes));
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("Analyze Stream"), &femonConfig.analyzestream, tr("no"), tr("yes")));
if (femonConfig.analyzestream)
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("SyslogOutput", femonConfig.syslogoutput);
SetupStore("Position", femonConfig.position);
SetupStore("DisplayMode", femonConfig.displaymode);
SetupStore("RedLimit", femonConfig.redlimit);
SetupStore("GreenLimit", femonConfig.greenlimit);
SetupStore("UpdateInterval", femonConfig.updateinterval);
SetupStore("AnalStream", femonConfig.analyzestream);
SetupStore("CalcInterval", femonConfig.calcinterval);
}
eOSState cMenuFemonSetup::ProcessKey(eKeys Key)
{
int oldAnalyzestream = femonConfig.analyzestream;
eOSState state = cMenuSetupPage::ProcessKey(Key);
if (Key != kNone && (femonConfig.analyzestream != oldAnalyzestream)) {
Setup();
}
return state;
}
cMenuSetupPage *cPluginFemon::SetupMenu(void)

25
femon.h
View File

@@ -1,12 +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>
#include "femoncfg.h"
static const char *VERSION = "0.0.1b";
static const char *DESCRIPTION = "DVB Signal Quality Monitor (OSD)";
static const char *MAINMENUENTRY = "Signal Quality";
static const char *VERSION = "0.1.1";
static const char *DESCRIPTION = "DVB Signal Information Monitor (OSD)";
static const char *MAINMENUENTRY = "Signal Information";
class cPluginFemon : public cPlugin {
private:
@@ -28,11 +35,15 @@ public:
};
class cMenuFemonSetup : public cMenuSetupPage {
private:
const char *dispmodes[modeMaxNumber];
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,13 @@ cFemonConfig femonConfig;
cFemonConfig::cFemonConfig(void)
{
hidemenu = 0;
position = 1;
interval = 5;
redlimit = 33;
greenlimit = 66;
hidemenu = 0;
displaymode = 0;
position = 1;
redlimit = 33;
greenlimit = 66;
updateinterval = 5;
analyzestream = 1;
calcinterval = 20;
syslogoutput = 0;
}

View File

@@ -1,15 +1,34 @@
/*
* 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
enum dispModes {
modeBasic,
modeTransponder,
modeStream,
modeMaxNumber
};
struct cFemonConfig
{
public:
cFemonConfig(void);
int hidemenu;
int position;
int interval;
int redlimit;
int greenlimit;
int hidemenu;
int displaymode;
int position;
int redlimit;
int greenlimit;
int updateinterval;
int analyzestream;
int calcinterval;
int syslogoutput;
};
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<EFBFBD>ts-Anzeige (OSD)", // Deutsch
{ "DVB Signal Information Monitor (OSD)", // English
"DVB Signal Informationsanzeige (OSD)", // Deutsch
"", // Slovenski
"", // Italiano
"Visualizza le informazioni sul segnale DVB", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -20,19 +20,18 @@ const tI18nPhrase Phrases[] = {
"DVB signaalimittari (OSD)", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Signal Quality", // English
"SIgnalqualit<EFBFBD>t", // Deutsch
{ "Signal Information", // English
"Signalinformationen", // Deutsch
"", // Slovenski
"", // Italiano
"Informazioni sul segnale", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -40,19 +39,18 @@ const tI18nPhrase Phrases[] = {
"Signaalimittari", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Position", // English
"Position", // Deutsch
"", // Slovenski
"", // Italiano
"Posizione", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -60,19 +58,94 @@ const tI18nPhrase Phrases[] = {
"Sijainti", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Default Display Mode", // English
"Standard Anzeigemodus", // Deutsch
"", // Slovenski
"Modo di visualizzazione standard", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Oletus n<>ytt<74>moodi", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "basic", // English
"Standard", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"perus", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "transponder", // English
"Transponder", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"transponderi", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "stream", // English
"Stream", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"l<EFBFBD>hete", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Hide Mainmenu Entry", // English
"Hauptmen<EFBFBD>eintrag verstecken", // Deutsch
"", // Slovenski
"", // Italiano
"Nascondi voce men<65>", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -80,39 +153,75 @@ const tI18nPhrase Phrases[] = {
"Piilota valinta p<><70>valikosta", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "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<67>s
"", // Fran<61>ais
"", // Norsk
"N<EFBFBD>yt<EFBFBD>n p<>ivitysv<73>li [0.1s]", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (0,1 <20><><EFBFBD>)", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Analyze Stream", // English
"Stream analysieren", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"P<EFBFBD>ivitystaajuus [0.1s]", // suomi
"L<EFBFBD>hetteen analysointi", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Calculation Interval [0.1s]", // English
"Berechnungsintervall [0.1s]", // Deutsch
"", // Slovenski
"Intervallo di calcolo [0.1s]", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Laskennan p<>ivitysv<73>li [0.1s]", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (0,1 <20><><EFBFBD>)", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Red Limit [%]", // English
"Grenze Rot [%]", // Deutsch
"", // Slovenski
"", // Italiano
"Limite rosso [%]", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -120,19 +229,18 @@ const tI18nPhrase Phrases[] = {
"Punaisen taso [%]", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> (%)", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Green Limit [%]", // English
"Grenze Gr<47>n [%]", // Deutsch
"", // Slovenski
"", // Italiano
"Limite verde [%]", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
@@ -140,15 +248,716 @@ const tI18nPhrase Phrases[] = {
"Vihre<EFBFBD>n taso [%]", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
#if VDRVERSNUM >= 10300
"" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> (%)", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Transponder Information", // English
"Transponderinformation", // Deutsch
"", // Slovenski
"Informazioni transponder", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Transponderin tiedot", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Satellite Card", // English
"Satellitenkarte", // Deutsch
"", // Slovenski
"Scheda satellitare", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Satelliittikortti", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Cable Card", // English
"Kabelkarte", // Deutsch
"", // Slovenski
"Scheda via cavo", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Kaapelikortti", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Terrestial Card", // English
"Terrestrische Karte", // Deutsch
"", // Slovenski
"Scheda terrestre", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Terrestiaalikortti", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Use Syslog Output", // English
"Benutze syslog Ausgabe", // Deutsch
"", // Slovenski
"Registra su syslog", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Kirjaa systeemilokiin", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> syslog", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "LOCK", // English
"LOCK", // Deutsch
"LOCK", // Slovenski
"LOCK", // Italiano
"LOCK", // Nederlands
"LOCK", // Portugu<67>s
"LOCK", // Fran<61>ais
"LOCK", // Norsk
"LOCK", // suomi
"LOCK", // Polski
"LOCK", // Espa<70>ol
"LOCK", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"LOCK", // Svenska
"LOCK", // Romaneste
"LOCK", // Magyar
"LOCK", // Catal<61>
"<EFBFBD><EFBFBD>Ų<EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"LOCK", // Hrvatski (Croatian)
},
{ "SIGNAL", // English
"SIGNAL", // Deutsch
"SIGNAL", // Slovenski
"SIGNAL", // Italiano
"SIGNAL", // Nederlands
"SIGNAL", // Portugu<67>s
"SIGNAL", // Fran<61>ais
"SIGNAL", // Norsk
"SIGNAL", // suomi
"SIGNAL", // Polski
"SIGNAL", // Espa<70>ol
"SIGNAL", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"SIGNAL", // Svenska
"SIGNAL", // Romaneste
"SIGNAL", // Magyar
"SIGNAL", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"SIGNAL", // Hrvatski (Croatian)
},
{ "CARRIER", // English
"CARRIER", // Deutsch
"CARRIER", // Slovenski
"CARRIER", // Italiano
"CARRIER", // Nederlands
"CARRIER", // Portugu<67>s
"CARRIER", // Fran<61>ais
"CARRIER", // Norsk
"CARRIER", // suomi
"CARRIER", // Polski
"CARRIER", // Espa<70>ol
"CARRIER", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"CARRIER", // Svenska
"CARRIER", // Romaneste
"CARRIER", // Magyar
"CARRIER", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɰ<EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"CARRIER", // Hrvatski (Croatian)
},
{ "VITERBI", // English
"VITERBI", // Deutsch
"VITERBI", // Slovenski
"VITERBI", // Italiano
"VITERBI", // Nederlands
"VITERBI", // Portugu<67>s
"VITERBI", // Fran<61>ais
"VITERBI", // Norsk
"VITERBI", // suomi
"VITERBI", // Polski
"VITERBI", // Espa<70>ol
"VITERBI", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"VITERBI", // Svenska
"VITERBI", // Romaneste
"VITERBI", // Magyar
"VITERBI", // Catal<61>
"<EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"VITERBI", // Hrvatski (Croatian)
},
{ "SYNC", // English
"SYNC", // Deutsch
"SYNC", // Slovenski
"SYNC", // Italiano
"SYNC", // Nederlands
"SYNC", // Portugu<67>s
"SYNC", // Fran<61>ais
"SYNC", // Norsk
"SYNC", // suomi
"SYNC", // Polski
"SYNC", // Espa<70>ol
"SYNC", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"SYNC", // Svenska
"SYNC", // Romaneste
"SYNC", // Magyar
"SYNC", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"SYNC", // Hrvatski (Croatian)
},
{ "Audio", // English
"Audio", // Deutsch
"Audio", // Slovenski
"Audio", // Italiano
"Audio", // Nederlands
"Audio", // Portugu<67>s
"Audio", // Fran<61>ais
"Audio", // Norsk
"<EFBFBD><EFBFBD>ni", // suomi
"Audio", // Polski
"Audio", // Espa<70>ol
"Audio", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Audio", // Svenska
"Audio", // Romaneste
"Audio", // Magyar
"Audio", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Audio", // Hrvatski (Croatian)
},
{ "Video", // English
"Video", // Deutsch
"Video", // Slovenski
"Video", // Italiano
"Video", // Nederlands
"Video", // Portugu<67>s
"Video", // Fran<61>ais
"Video", // Norsk
"Kuva", // suomi
"Video", // Polski
"Video", // Espa<70>ol
"Video", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Video", // Svenska
"Video", // Romaneste
"Video", // Magyar
"Video", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Video", // Hrvatski (Croatian)
},
{ "Auto", // English
"Auto", // Deutsch
"Auto", // Slovenski
"Auto", // Italiano
"Auto", // Nederlands
"Auto", // Portugu<67>s
"Auto", // Fran<61>ais
"Auto", // Norsk
"Auto", // suomi
"Auto", // Polski
"Auto", // Espa<70>ol
"Auto", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Auto", // Svenska
"Auto", // Romaneste
"Auto", // Magyar
"Auto", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Auto", // Hrvatski (Croatian)
},
{ "None", // English
"None", // Deutsch
"None", // Slovenski
"None", // Italiano
"None", // Nederlands
"None", // Portugu<67>s
"None", // Fran<61>ais
"None", // Norsk
"None", // suomi
"None", // Polski
"None", // Espa<70>ol
"None", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"None", // Svenska
"None", // Romaneste
"None", // Magyar
"None", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"None", // Hrvatski (Croatian)
},
{ "Off", // English
"Off", // Deutsch
"Off", // Slovenski
"Off", // Italiano
"Off", // Nederlands
"Off", // Portugu<67>s
"Off", // Fran<61>ais
"Off", // Norsk
"Off", // suomi
"Off", // Polski
"Off", // Espa<70>ol
"Off", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Off", // Svenska
"Off", // Romaneste
"Off", // Magyar
"Off", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Off", // Hrvatski (Croatian)
},
{ "On", // English
"On", // Deutsch
"On", // Slovenski
"On", // Italiano
"On", // Nederlands
"On", // Portugu<67>s
"On", // Fran<61>ais
"On", // Norsk
"On", // suomi
"On", // Polski
"On", // Espa<70>ol
"On", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"On", // Svenska
"On", // Romaneste
"On", // Magyar
"On", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"On", // Hrvatski (Croatian)
},
{ "MHz", // English
"MHz", // Deutsch
"MHz", // Slovenski
"MHz", // Italiano
"MHz", // Nederlands
"MHz", // Portugu<67>s
"MHz", // Fran<61>ais
"MHz", // Norsk
"MHz", // suomi
"MHz", // Polski
"MHz", // Espa<70>ol
"MHz", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"MHz", // Svenska
"MHz", // Romaneste
"MHz", // Magyar
"MHz", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"MHz", // Hrvatski (Croatian)
},
{ "Mbit/s", // English
"Mbit/s", // Deutsch
"Mbit/s", // Slovenski
"Mbit/s", // Italiano
"Mbit/s", // Nederlands
"Mbit/s", // Portugu<67>s
"Mbit/s", // Fran<61>ais
"Mbit/s", // Norsk
"Mbit/s", // suomi
"Mbit/s", // Polski
"Mbit/s", // Espa<70>ol
"Mbit/s", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Mbit/s", // Svenska
"Mbit/s", // Romaneste
"Mbit/s", // Magyar
"Mbit/s", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Mbit/s", // Hrvatski (Croatian)
},
{ "kbit/s", // English
"kbit/s", // Deutsch
"kbit/s", // Slovenski
"kbit/s", // Italiano
"kbit/s", // Nederlands
"kbit/s", // Portugu<67>s
"kbit/s", // Fran<61>ais
"kbit/s", // Norsk
"kbit/s", // suomi
"kbit/s", // Polski
"kbit/s", // Espa<70>ol
"kbit/s", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"kbit/s", // Svenska
"kbit/s", // Romaneste
"kbit/s", // Magyar
"kbit/s", // Catal<61>
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"kbit/s", // Hrvatski (Croatian)
},
{ "Stream Information", // English
"Streaminformation", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"L<EFBFBD>hetteen tiedot", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "MPEG Layer", // English
"MPEG Layer", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"MPEG-taso", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Video Stream", // English
"Video Stream", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Kuvaraita", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Bitrate", // English
"Bitrate", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Bittinopeus", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Frame Rate", // English
"Bildrate", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Ruudunp<EFBFBD>ivitysnopeus", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Hz", // English
"Hz", // Deutsch
"Hz", // Slovenski
"Hz", // Italiano
"Hz", // Nederlands
"Hz", // Portugu<67>s
"Hz", // Fran<61>ais
"Hz", // Norsk
"Hz", // suomi
"Hz", // Polski
"Hz", // Espa<70>ol
"Hz", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"Hz", // Svenska
"Hz", // Romaneste
"Hz", // Magyar
"Hz", // Catal<61>
"Hz", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"Hz", // Hrvatski (Croatian)
},
{ "Aspect Ratio", // English
"Seitenverh<EFBFBD>ltnis", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Kuvasuhde", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "reserved", // English
"belegt", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"varattu", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "free", // English
"frei", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"vapaa", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Video Format", // English
"Bildformat", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Kuvaformaatti", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "PAL", // English
"PAL", // Deutsch
"PAL", // Slovenski
"PAL", // Italiano
"PAL", // Nederlands
"PAL", // Portugu<67>s
"PAL", // Fran<61>ais
"PAL", // Norsk
"PAL", // suomi
"PAL", // Polski
"PAL", // Espa<70>ol
"PAL", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"PAL", // Svenska
"PAL", // Romaneste
"PAL", // Magyar
"PAL", // Catal<61>
"PAL", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"PAL", // Hrvatski (Croatian)
},
{ "NTSC", // English
"NTSC", // Deutsch
"NTSC", // Slovenski
"NTSC", // Italiano
"NTSC", // Nederlands
"NTSC", // Portugu<67>s
"NTSC", // Fran<61>ais
"NTSC", // Norsk
"NTSC", // suomi
"NTSC", // Polski
"NTSC", // Espa<70>ol
"NTSC", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"NTSC", // Svenska
"NTSC", // Romaneste
"NTSC", // Magyar
"NTSC", // Catal<61>
"NTSC", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"NTSC", // Hrvatski (Croatian)
},
{ "unknown", // English
"unbekannt", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"tuntematon", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Resolution", // English
"Aufl<EFBFBD>sung", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"Resoluutio", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Audio Stream", // English
"Audio Stream", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"<EFBFBD><EFBFBD>niraita", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "Sampling Frequency", // English
"Abtastrate", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"N<EFBFBD>ytteenottotaajuus", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ "kHz", // English
"kHz", // Deutsch
"kHz", // Slovenski
"kHz", // Italiano
"kHz", // Nederlands
"kHz", // Portugu<67>s
"kHz", // Fran<61>ais
"kHz", // Norsk
"kHz", // suomi
"kHz", // Polski
"kHz", // Espa<70>ol
"kHz", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"kHz", // Svenska
"kHz", // Romaneste
"kHz", // Magyar
"kHz", // Catal<61>
"kHz", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"kHz", // Hrvatski (Croatian)
},
{ "MPEG Layer", // English
"MPEG Layer", // Deutsch
"", // Slovenski
"", // Italiano
"", // Nederlands
"", // Portugu<67>s
"", // Fran<61>ais
"", // Norsk
"MPEG-kerros", // suomi
"", // Polski
"", // Espa<70>ol
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Greek)
"", // Svenska
"", // Romaneste
"", // Magyar
"", // Catal<61>
"", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Russian)
"", // Hrvatski (Croatian)
},
{ 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,40 +1,56 @@
/*
* 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 "femonosd.h"
#include <ctype.h>
#include "femoncfg.h"
#include "femoni18n.h"
#include "femonreceiver.h"
#include "femonosd.h"
#define FEMON_DEVICE "/dev/dvb/adapter%d/frontend%d"
#define CHANNELINPUT_TIMEOUT 1000
#define CHANNELINFO_TIMEOUT 5000
#define OSDHEIGHT 5
#define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d"
#define CHANNELINPUT_TIMEOUT 1000
#define SCREENWIDTH 720 // in pixels
#define SCREENHEIGHT 576 // in pixels
#define OSDWIDTH 600 // in pixels
#define OSDHEIGHT 480 // in pixels
#define OSDINFOHEIGHT (m_Font->Height() * 11) // in pixels (11 rows)
#define OSDSTATUSHEIGHT (m_Font->Height() * 6) // in pixels (6 rows)
#define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset)
#define OSDINFOWIN_X(col) ((col == 4) ? 470 : (col == 3) ? 300 : (col==2) ? 180 : 15)
#define OSDSTATUSWIN_Y(offset) (femonConfig.position ? offset : (OSDHEIGHT - OSDSTATUSHEIGHT + offset))
#define OSDSTATUSWIN_X(col) ((col == 7) ? 475 : (col == 6) ? 410 : (col == 5) ? 275 : (col == 4) ? 220 : (col == 3) ? 125 : (col==2) ? 70 : 15)
#define OSDSTATUSWIN_XC(col,txt) (((col - 1) * SCREENWIDTH / 6) + ((SCREENWIDTH / 6 - m_Font->Width(txt)) / 2))
#define BARWIDTH(x) (OSDWIDTH * x / 100)
#define clrBackground clrGray50 // this should be tied somehow into current theme
cFemonOsd::cFemonOsd(void)
#if VDRVERSNUM >= 10300
:cOsdObject(true), cThread("femon plugin")
#else
:cOsdObject(true), cThread()
#endif
:cOsdObject(true), cThread("femon osd")
{
//printf("cFemonOsd::cFemonOsd()\n");
m_Osd = NULL;
m_Window = -1;
m_Receiver = NULL;
m_Frontend = -1;
m_Active = false;
m_Number = 0;
m_OldNumber = 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_Font = cFont::GetFont(fontSml);
m_Mutex = new cMutex();
}
cFemonOsd::~cFemonOsd(void)
{
//printf("cFemonOsd::~cFemonOsd()\n");
@@ -42,97 +58,427 @@ cFemonOsd::~cFemonOsd(void)
m_Active = false;
Cancel(3);
}
if (m_Receiver)
delete m_Receiver;
if (m_Osd)
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 offset = 0;
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (m_Osd) {
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrBackground);
snprintf(buf, sizeof(buf), "%d%s %s", m_Number ? m_Number : channel->Number(), m_Number ? "-" : "", channel->Name());
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset), OSDWIDTH, OSDSTATUSWIN_Y(offset+m_Font->Height()-1), clrWhite);
m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), buf, clrBlack, clrWhite, m_Font);
offset += m_Font->Height();
if (signal > 0) {
signal = BARWIDTH(signal);
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset+3), min(BARWIDTH(femonConfig.redlimit), signal), OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrRed);
if (signal > BARWIDTH(femonConfig.redlimit)) {
m_Osd->DrawRectangle(BARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset+3), min((OSDWIDTH * femonConfig.greenlimit / 100), signal), OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrYellow);
}
if (signal > BARWIDTH(femonConfig.greenlimit)) {
m_Osd->DrawRectangle(BARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset+3), signal, OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrGreen);
}
}
offset += m_Font->Height();
if (snr > 0) {
snr = BARWIDTH(snr);
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset+3), min(BARWIDTH(femonConfig.redlimit), snr), OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrRed);
if (snr > BARWIDTH(femonConfig.redlimit)) {
m_Osd->DrawRectangle(BARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset+3), min(BARWIDTH(femonConfig.greenlimit), snr), OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrYellow);
}
if (snr > BARWIDTH(femonConfig.greenlimit)) {
m_Osd->DrawRectangle(BARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset+3), snr, OSDSTATUSWIN_Y(offset+m_Font->Height()-3), clrGreen);
}
}
offset += m_Font->Height();
m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), "STR:", clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%04x", m_Signal);
m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "(%2d%%)", m_Signal / 655);
m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), "BER:", clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%08x", m_BER);
m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%s:", tr("Video"));
m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%.2f %s", m_Receiver->VideoBitrate(), tr("Mbit/s"));
else snprintf(buf, sizeof(buf), "--- %s", tr("Mbit/s"));
m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), "SNR:", clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%04x", m_SNR);
m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "(%2d%%)", m_SNR / 655);
m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), "UNC:", clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%08x", m_UNC);
m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%s:", tr("Audio"));
m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%.0f %s", m_Receiver->AudioBitrate(), tr("kbit/s"));
else snprintf(buf, sizeof(buf), "--- %s", tr("kbit/s"));
m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDSTATUSWIN_XC(1,tr("LOCK")), OSDSTATUSWIN_Y(offset), tr("LOCK"), (m_FrontendStatus & FE_HAS_LOCK) ? clrYellow : clrBlack, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_XC(2,tr("SIGNAL")), OSDSTATUSWIN_Y(offset), tr("SIGNAL"), (m_FrontendStatus & FE_HAS_SIGNAL) ? clrYellow : clrBlack, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_XC(3,tr("CARRIER")), OSDSTATUSWIN_Y(offset), tr("CARRIER"),(m_FrontendStatus & FE_HAS_CARRIER)? clrYellow : clrBlack, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_XC(4,tr("VITERBI")), OSDSTATUSWIN_Y(offset), tr("VITERBI"),(m_FrontendStatus & FE_HAS_VITERBI)? clrYellow : clrBlack, clrBackground, m_Font);
m_Osd->DrawText(OSDSTATUSWIN_XC(5,tr("SYNC")), OSDSTATUSWIN_Y(offset), tr("SYNC"), (m_FrontendStatus & FE_HAS_SYNC) ? clrYellow : clrBlack, clrBackground, m_Font);
m_Osd->Flush();
}
}
void cFemonOsd::DrawInfoWindow(void)
{
cMutexLock lock(m_Mutex);
//printf("cFemonOsd::DrawInfoWindow()\n");
char buf[128];
char buf2[20];
int offset = 0;
int value = 0;
double dvalue = 0.0;
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (m_Osd) {
if (m_DisplayMode == modeTransponder) {
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrBackground);
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset+m_Font->Height()-1), clrWhite);
m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Transponder Information"), clrBackground, clrWhite, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Vpid"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Vpid());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Ppid"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Ppid());
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Apid1"), clrWhite, clrBackground, m_Font);
value = channel->Apid2();
if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Apid1(), value);
else snprintf(buf, sizeof(buf), "%d", channel->Apid1());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Dpid1"), clrWhite, clrBackground, m_Font);
value = channel->Dpid2();
if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Dpid1(), value);
else snprintf(buf, sizeof(buf), "%d", channel->Dpid1());
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("CA"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Ca());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Tpid"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Tpid());
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Sid"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Sid());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), "Nid", clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Nid());
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), "Tid" /*tr("Tid")*/, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Tid());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), "Rid" /*tr("Rid")*/, clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Rid());
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
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->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frequency"), clrWhite, clrBackground, m_Font);
value = channel->Frequency();
while (value > 20000) value /= 1000;
snprintf(buf, sizeof(buf), "%d %s", value, tr("MHz"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Source"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%s", cSource::ToString(channel->Source()));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Srate"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Srate());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Polarization"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%c", toupper(channel->Polarization()));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Inversion"), clrWhite, clrBackground, m_Font);
value = channel->Inversion();
if (value == INVERSION_OFF) snprintf(buf, sizeof(buf), tr("Off"));
else if (value == INVERSION_ON) snprintf(buf, sizeof(buf), tr("On"));
else /*INVERSION_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("CoderateH"), clrWhite, clrBackground, m_Font);
value = channel->CoderateH();
if (value == FEC_NONE) snprintf(buf, sizeof(buf), tr("None"));
else if (value == FEC_1_2) snprintf(buf, sizeof(buf), "1/2");
else if (value == FEC_2_3) snprintf(buf, sizeof(buf), "2/3");
else if (value == FEC_3_4) snprintf(buf, sizeof(buf), "3/4");
else if (value == FEC_4_5) snprintf(buf, sizeof(buf), "4/5");
else if (value == FEC_5_6) snprintf(buf, sizeof(buf), "5/6");
else if (value == FEC_6_7) snprintf(buf, sizeof(buf), "6/7");
else if (value == FEC_7_8) snprintf(buf, sizeof(buf), "7/8");
else if (value == FEC_8_9) snprintf(buf, sizeof(buf), "8/9");
else /*FEC_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
break;
case FE_QAM:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Cable Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frequency"), clrWhite, clrBackground, m_Font);
value = channel->Frequency();
while (value > 20000) value /= 1000;
snprintf(buf, sizeof(buf), "%d %s", value, tr("MHz"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Source"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%s", cSource::ToString(channel->Source()));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Srate"), clrWhite, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "%d", channel->Srate());
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Modulation"), clrWhite, clrBackground, m_Font);
value = channel->Modulation();
if (value == QPSK) snprintf(buf, sizeof(buf), "QPSK");
else if (value == QAM_16) snprintf(buf, sizeof(buf), "QAM 16");
else if (value == QAM_32) snprintf(buf, sizeof(buf), "QAM 32");
else if (value == QAM_64) snprintf(buf, sizeof(buf), "QAM 64");
else if (value == QAM_128) snprintf(buf, sizeof(buf), "QAM 128");
else if (value == QAM_256) snprintf(buf, sizeof(buf), "QAM 256");
else /*QAM_AUTO*/ snprintf(buf, sizeof(buf), "QAM %s", tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Inversion"), clrWhite, clrBackground, m_Font);
value = channel->Inversion();
if (value == INVERSION_OFF) snprintf(buf, sizeof(buf), tr("Off"));
else if (value == INVERSION_ON) snprintf(buf, sizeof(buf), tr("On"));
else /*INVERSION_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("CoderateH"), clrWhite, clrBackground, m_Font);
value = channel->CoderateH();
if (value == FEC_NONE) snprintf(buf, sizeof(buf), tr("None"));
else if (value == FEC_1_2) snprintf(buf, sizeof(buf), "1/2");
else if (value == FEC_2_3) snprintf(buf, sizeof(buf), "2/3");
else if (value == FEC_3_4) snprintf(buf, sizeof(buf), "3/4");
else if (value == FEC_4_5) snprintf(buf, sizeof(buf), "4/5");
else if (value == FEC_5_6) snprintf(buf, sizeof(buf), "5/6");
else if (value == FEC_6_7) snprintf(buf, sizeof(buf), "6/7");
else if (value == FEC_7_8) snprintf(buf, sizeof(buf), "7/8");
else if (value == FEC_8_9) snprintf(buf, sizeof(buf), "8/9");
else /*FEC_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
break;
default:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Terrestial Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frequency"), clrWhite, clrBackground, m_Font);
value = channel->Frequency();
while (value > 20000) value /= 1000;
snprintf(buf, sizeof(buf), "%d %s", value, tr("MHz"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Transmission"), clrWhite, clrBackground, m_Font);
value = channel->Transmission();
if (value == TRANSMISSION_MODE_2K) snprintf(buf, sizeof(buf), "2K");
else if (value == TRANSMISSION_MODE_8K) snprintf(buf, sizeof(buf), "8K");
else /*TRANSMISSION_MODE_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bandwidth"), clrWhite, clrBackground, m_Font);
value = channel->Bandwidth();
if (value == BANDWIDTH_8_MHZ) snprintf(buf, sizeof(buf), "8 %s", tr("MHz"));
else if (value == BANDWIDTH_7_MHZ) snprintf(buf, sizeof(buf), "7 %s", tr("MHz"));
else if (value == BANDWIDTH_6_MHZ) snprintf(buf, sizeof(buf), "6 %s", tr("MHz"));
else /*BANDWIDTH_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Modulation"), clrWhite, clrBackground, m_Font);
value = channel->Modulation();
if (value == QPSK) snprintf(buf, sizeof(buf), "QPSK");
else if (value == QAM_16) snprintf(buf, sizeof(buf), "QAM 16");
else if (value == QAM_32) snprintf(buf, sizeof(buf), "QAM 32");
else if (value == QAM_64) snprintf(buf, sizeof(buf), "QAM 64");
else if (value == QAM_128) snprintf(buf, sizeof(buf), "QAM 128");
else if (value == QAM_256) snprintf(buf, sizeof(buf), "QAM 256");
else /*QAM_AUTO*/ snprintf(buf, sizeof(buf), "QAM %s", tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Inversion"), clrWhite, clrBackground, m_Font);
value = channel->Inversion();
if (value == INVERSION_OFF) snprintf(buf, sizeof(buf), tr("Off"));
else if (value == INVERSION_ON) snprintf(buf, sizeof(buf), tr("On"));
else /*INVERSION_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("CoderateH"), clrWhite, clrBackground, m_Font);
value = channel->CoderateH();
if (value == FEC_NONE) snprintf(buf, sizeof(buf), tr("None"));
else if (value == FEC_1_2) snprintf(buf, sizeof(buf), "1/2");
else if (value == FEC_2_3) snprintf(buf, sizeof(buf), "2/3");
else if (value == FEC_3_4) snprintf(buf, sizeof(buf), "3/4");
else if (value == FEC_4_5) snprintf(buf, sizeof(buf), "4/5");
else if (value == FEC_5_6) snprintf(buf, sizeof(buf), "5/6");
else if (value == FEC_6_7) snprintf(buf, sizeof(buf), "6/7");
else if (value == FEC_7_8) snprintf(buf, sizeof(buf), "7/8");
else if (value == FEC_8_9) snprintf(buf, sizeof(buf), "8/9");
else /*FEC_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
value = channel->CoderateL();
if (value == FEC_NONE) snprintf(buf2, sizeof(buf2), " - %s", tr("None"));
else if (value == FEC_1_2) snprintf(buf2, sizeof(buf2), " - 1/2");
else if (value == FEC_2_3) snprintf(buf2, sizeof(buf2), " - 2/3");
else if (value == FEC_3_4) snprintf(buf2, sizeof(buf2), " - 3/4");
else if (value == FEC_4_5) snprintf(buf2, sizeof(buf2), " - 4/5");
else if (value == FEC_5_6) snprintf(buf2, sizeof(buf2), " - 5/6");
else if (value == FEC_6_7) snprintf(buf2, sizeof(buf2), " - 6/7");
else if (value == FEC_7_8) snprintf(buf2, sizeof(buf2), " - 7/8");
else if (value == FEC_8_9) snprintf(buf2, sizeof(buf2), " - 8/9");
else /*FEC_AUTO*/ snprintf(buf2, sizeof(buf2), " - %s", tr("Auto"));
strncat(buf, buf2, sizeof(buf));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Hierarchy"), clrWhite, clrBackground, m_Font);
value = channel->Hierarchy();
if (value == HIERARCHY_NONE) snprintf(buf, sizeof(buf), tr("None"));
else if (value == HIERARCHY_1) snprintf(buf, sizeof(buf), "1");
else if (value == HIERARCHY_2) snprintf(buf, sizeof(buf), "2");
else if (value == HIERARCHY_4) snprintf(buf, sizeof(buf), "4");
else /*HIERARCHY_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Guard"), clrWhite, clrBackground, m_Font);
value = channel->Guard();
if (value == GUARD_INTERVAL_1_32) snprintf(buf, sizeof(buf), "1/32");
else if (value == GUARD_INTERVAL_1_16) snprintf(buf, sizeof(buf), "1/16");
else if (value == GUARD_INTERVAL_1_8) snprintf(buf, sizeof(buf), "1/8");
else if (value == GUARD_INTERVAL_1_4) snprintf(buf, sizeof(buf), "1/4");
else /*GUARD_INTERVAL_AUTO*/ snprintf(buf, sizeof(buf), tr("Auto"));
m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
break;
}
}
else if (m_DisplayMode == modeStream) {
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrBackground);
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset+m_Font->Height()-1), clrWhite);
m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Stream Information"), clrBackground, clrWhite, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Video Stream"), clrYellow, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "#%d", channel->Vpid());
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%.2f %s (%.2f %s)", m_Receiver->VideoStreamBitrate(), tr("Mbit/s"), m_Receiver->VideoBitrate(), tr("Mbit/s"));
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Aspect Ratio"), clrWhite, clrBackground, m_Font);
if (m_Receiver) {
value = m_Receiver->VideoAspectRatio();
if (value == 100) snprintf(buf, sizeof(buf), "1:1");
else if (value == 133) snprintf(buf, sizeof(buf), "4:3");
else if (value == 177) snprintf(buf, sizeof(buf), "16:9");
else if (value == 233) snprintf(buf, sizeof(buf), "2.21:1");
else snprintf(buf, sizeof(buf), "%s", tr("reserved"));
}
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frame Rate"), clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%.2f %s", m_Receiver->VideoFrameRate(), tr("Hz"));
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Video Format"), clrWhite, clrBackground, m_Font);
if (m_Receiver) {
value = m_Receiver->VideoFormat();
if (value == 1) snprintf(buf, sizeof(buf), "%s", tr("PAL"));
else if (value == 2) snprintf(buf, sizeof(buf), "%s", tr("NTSC"));
else snprintf(buf, sizeof(buf), "%s", tr("unknown"));
}
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Resolution"), clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%d x %d", m_Receiver->VideoHorizontalSize(), m_Receiver->VideoVerticalSize());
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Audio Stream"), clrYellow, clrBackground, m_Font);
snprintf(buf, sizeof(buf), "#%d", channel->Apid1());
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), clrWhite, clrBackground, m_Font);
dvalue = m_Receiver->AudioStreamBitrate();
if (m_Receiver) {
if (dvalue == -1.0) snprintf(buf, sizeof(buf), "%s (%.0f %s)", tr("reserved"), m_Receiver->AudioBitrate(), tr("kbit/s"));
else if (dvalue == -2.0) snprintf(buf, sizeof(buf), "%s (%.0f %s)", tr("free"), m_Receiver->AudioBitrate(), tr("kbit/s"));
else snprintf(buf, sizeof(buf), "%.0f %s (%.0f %s)", dvalue, tr("kbit/s"), m_Receiver->AudioBitrate(), tr("kbit/s"));
}
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("MPEG Layer"), clrWhite, clrBackground, m_Font);
if (m_Receiver) snprintf(buf, sizeof(buf), "%d", m_Receiver->AudioMPEGLayer());
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
offset += m_Font->Height();
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Sampling Frequency"), clrWhite, clrBackground, m_Font);
if (m_Receiver) {
value = m_Receiver->AudioSamplingFreq();
if (value == -1) snprintf(buf, sizeof(buf), "%s", tr("reserved"));
else snprintf(buf, sizeof(buf), "%.1f %s", (value / 1000.0), tr("kHz"));
}
else snprintf(buf, sizeof(buf), "---");
m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
}
else /* modeBasic */ {
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent);
}
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];
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", cDevice::CurrentChannel(), 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);
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();
if (femonConfig.syslogoutput) {
isyslog("Card #%d (%s) STR: %04x SNR: %04x BER: %08x UNC: %08x |%c|%c|%c|%c|%c|", cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name, m_Signal, m_SNR, m_BER, m_UNC, (m_FrontendStatus & FE_HAS_LOCK) ? 'L' : ' ', (m_FrontendStatus & FE_HAS_SIGNAL) ? 'S' : ' ', (m_FrontendStatus & FE_HAS_CARRIER) ? 'C' : ' ', (m_FrontendStatus & FE_HAS_VITERBI) ? 'V' : ' ', (m_FrontendStatus & FE_HAS_SYNC) ? 'Z' : ' ');
}
}
usleep(100000L * femonConfig.interval);
usleep(100000L * femonConfig.updateinterval);
}
}
void cFemonOsd::Show(void)
{
//printf("cFemonOsd::Show()\n");
char *fedev = NULL;
asprintf(&fedev, FEMON_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); // only the first frontend supported
m_Frontend = open(fedev, O_RDONLY | O_NONBLOCK);
free(fedev);
char *dev = NULL;
asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0);
m_Frontend = open(dev, O_RDONLY | O_NONBLOCK);
free(dev);
if (m_Frontend < 0) {
isyslog("cFemonOsd::Show() cannot open frontend device.");
m_Frontend = -1;
@@ -142,21 +488,29 @@ void cFemonOsd::Show(void)
isyslog("cFemonOsd::Show() cannot read frontend info.");
m_Frontend = -1;
close(m_Frontend);
return;
}
m_InfoTime = time_ms();
m_Osd = cOsd::OpenRaw(m_Xpos, m_Ypos);
m_Osd = cOsdProvider::NewOsd(((Setup.OSDWidth - OSDWIDTH) / 2) + Setup.OSDLeft, ((Setup.OSDHeight - OSDHEIGHT) / 2) + Setup.OSDTop);
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);
tArea Areas[] = { { 0, 0, OSDWIDTH, OSDHEIGHT, 4 } };
if (m_Osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) {
m_Osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
}
else {
tArea Areas[] = { { 0, OSDSTATUSWIN_Y(0), (OSDWIDTH-1), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-1), 4 },
{ 0, OSDINFOWIN_Y(0), (OSDWIDTH-1), OSDINFOWIN_Y(OSDINFOHEIGHT-1), 2 }
};
m_Osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
}
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent);
m_Osd->Flush();
if (m_Receiver)
delete m_Receiver;
if (femonConfig.analyzestream) {
int channelNumber = cDevice::CurrentChannel();
m_Receiver = new cFemonReceiver(Channels.GetByNumber(channelNumber)->Ca(), Channels.GetByNumber(channelNumber)->Vpid(), Channels.GetByNumber(channelNumber)->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
}
Start();
}
}
@@ -164,12 +518,11 @@ void cFemonOsd::Show(void)
void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
{
//printf("cFemonOsd::ChannelSwitch()\n");
char *fedev = NULL;
char *dev = NULL;
close(m_Frontend);
asprintf(&fedev, FEMON_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); // only the first frontend$
m_Frontend = open(fedev, O_RDONLY | O_NONBLOCK);
free(fedev);
asprintf(&dev, FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0);
m_Frontend = open(dev, O_RDONLY | O_NONBLOCK);
free(dev);
if (m_Frontend < 0) {
isyslog("cFemonOsd::ChannelSwitch() cannot open frontend device.");
m_Frontend = -1;
@@ -179,8 +532,15 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
isyslog("cFemonOsd::ChannelSwitch() cannot read frontend info.");
m_Frontend = -1;
close(m_Frontend);
return;
}
if (m_Receiver)
delete m_Receiver;
if (femonConfig.analyzestream) {
channelNumber = cDevice::CurrentChannel();
m_Receiver = new cFemonReceiver(Channels.GetByNumber(channelNumber)->Ca(), Channels.GetByNumber(channelNumber)->Vpid(), Channels.GetByNumber(channelNumber)->Apid1());
cDevice::ActualDevice()->AttachReceiver(m_Receiver);
}
m_InfoTime = time_ms();
}
eOSState cFemonOsd::ProcessKey(eKeys Key)
@@ -190,15 +550,18 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
if (state == osUnknown) {
switch (Key & ~k_Repeat) {
case k0:
if (m_Number == 0) {
// keep the "Toggle channels" function working
cRemote::Put(Key);
if ((m_Number == 0) && (m_OldNumber != 0)) {
m_Number = m_OldNumber;
m_OldNumber = cDevice::CurrentChannel();
Channels.SwitchTo(m_Number);
m_Number = 0;
return osContinue;
}
case k1 ... k9:
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:
@@ -215,6 +578,7 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
}
if (n > 0) {
// This channel is the only one that fits the input, so let's take it right away:
m_OldNumber = cDevice::CurrentChannel();
Channels.SwitchTo(m_Number);
m_Number = 0;
}
@@ -223,24 +587,30 @@ eOSState cFemonOsd::ProcessKey(eKeys Key)
break;
case kBack:
return osEnd;
case kUp|k_Repeat:
case kUp:
case kDown|k_Repeat:
case kDown:
m_OldNumber = cDevice::CurrentChannel();
cDevice::SwitchChannel(NORMALKEY(Key) == kUp ? 1 : -1);
m_Number = 0;
break;
case kNone:
if (m_Number && (time_ms() - m_InputTime > CHANNELINPUT_TIMEOUT)) {
if (Channels.GetByNumber(m_Number)) {
m_OldNumber = cDevice::CurrentChannel();
Channels.SwitchTo(m_Number);
m_Number = 0;
}
else {
m_Number = 0;
m_InputTime = time_ms();
m_Number = 0;
}
}
break;
case kOk:
m_InfoTime = time_ms();
if (++m_DisplayMode >= modeMaxNumber) m_DisplayMode = 0; // toggle between display modes
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
@@ -8,22 +16,27 @@
#include <vdr/thread.h>
#include <vdr/status.h>
#include <vdr/channels.h>
#include <vdr/font.h>
class cFemonOsd : public cOsdObject, public cThread, public cStatus {
private:
bool m_Active;
cOsdBase *m_Osd;
tWindowHandle m_Window;
cOsd *m_Osd;
cFemonReceiver *m_Receiver;
int m_Frontend;
struct dvb_frontend_info m_FrontendInfo;
int m_Number;
int m_OldNumber;
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;
const cFont *m_Font;
cMutex* m_Mutex;
void DrawStatusWindow(void);
void DrawInfoWindow(void);
protected:
virtual void Action(void);

224
femonreceiver.c Normal file
View File

@@ -0,0 +1,224 @@
/*
* 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"
#define TS_SIZE 188
#define PAY_START 0x40
#define ADAPT_FIELD 0x20
#define PAYLOAD 0x10
#define PTS_DTS_FLAGS 0xC0
cFemonReceiver::cFemonReceiver(int Ca, int Vpid, int Apid)
:cReceiver(Ca, -1, 2, Vpid, Apid), cThread("femon receiver")
{
//printf("cFemonReceiver::cFemonReceiver()\n");
m_Active = false;
m_VideoPid = Vpid;
m_AudioPid = Apid;
m_VideoPacketCount = 0;
m_VideoHorizontalSize = 0;
m_VideoVerticalSize = 0;
m_VideoAspectRatio = 0;
m_VideoFormat = 0;
m_VideoFrameRate = 0.0;
m_VideoStreamBitrate = 0.0;
m_VideoBitrate = 0.0;
m_AudioPacketCount = 0;
m_AudioStreamBitrate = -2.0;
m_AudioBitrate = 0.0;
m_AudioSamplingFreq = -1;
m_AudioMPEGLayer = 0;
m_AudioBitrate = 0.0;
}
cFemonReceiver::~cFemonReceiver(void)
{
//printf("cFemonReceiver::~cFemonReceiver()\n");
if (m_Active) {
m_Active = false;
Cancel(0);
}
}
/* the following function originates from libdvbmpeg: */
void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count)
{
//printf("cFemonReceiver::GetVideoInfo()\n");
uint8_t *headr;
int found = 0;
int c = 0;
while (found < 4 && c + 4 < count) {
uint8_t *b;
b = mbuf + c;
if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 && b[3] == 0xb3)
found = 4;
else
c++;
}
if (!found) return;
c += 4;
if (c + 12 >= count) return;
headr = mbuf + c;
m_VideoHorizontalSize = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
m_VideoVerticalSize = ((headr[1] &0x0F) << 8) | (headr[2]);
int sw = (int)((headr[3] & 0xF0) >> 4);
switch( sw ){
case 1:
m_VideoAspectRatio = 100;
break;
case 2:
m_VideoAspectRatio = 133;
break;
case 3:
m_VideoAspectRatio = 177;
break;
case 4:
m_VideoAspectRatio = 221;
break;
case 5 ... 15:
m_VideoAspectRatio = 0;
break;
default:
return;
}
sw = (int)(headr[3] & 0x0F);
switch ( sw ) {
case 1:
m_VideoFrameRate = 24000/1001.0;
m_VideoFormat = 0;
break;
case 2:
m_VideoFrameRate = 24.0;
m_VideoFormat = 0;
break;
case 3:
m_VideoFrameRate = 25.0;
m_VideoFormat = 1;
break;
case 4:
m_VideoFrameRate = 30000/1001.0;
m_VideoFormat = 2;
break;
case 5:
m_VideoFrameRate = 30.0;
m_VideoFormat = 2;
break;
case 6:
m_VideoFrameRate = 50.0;
m_VideoFormat = 1;
break;
case 7:
m_VideoFrameRate = 60.0;
m_VideoFormat = 2;
break;
}
m_VideoStreamBitrate = 400 * (((headr[4] << 10) & 0x0003FC00UL) | ((headr[5] << 2) & 0x000003FCUL) | (((headr[6] & 0xC0) >> 6) & 0x00000003UL)) / 1000000.0;
}
static unsigned int bitrates[3][16] =
{
{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}
};
static unsigned int samplerates[4] = {441, 480, 320, 0};
/* the following function originates from libdvbmpeg: */
void cFemonReceiver::GetAudioInfo(uint8_t *mbuf, int count)
{
//printf("cFemonReceiver::GetAudioInfo()\n");
uint8_t *headr;
int found = 0;
int c = 0;
int tmp = 0;
while (!found && c < count) {
uint8_t *b = mbuf + c;
if (b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
found = 1;
else
c++;
}
if (!found) return;
if (c + 3 >= count) return;
headr = mbuf + c;
m_AudioMPEGLayer = 4 - ((headr[1] & 0x06) >> 1);
tmp = bitrates[(3 - ((headr[1] & 0x06) >> 1))][(headr[2] >> 4)] * 1000;
if (tmp == 0)
m_AudioStreamBitrate = -2.0; // free
else if (tmp == 0xf)
m_AudioStreamBitrate = -1.0; // reserved
else
m_AudioStreamBitrate = tmp / 1000.0;
tmp = samplerates[((headr[2] & 0x0c) >> 2)] * 100;
if (tmp == 3)
m_AudioSamplingFreq = -1; // reserved
else
m_AudioSamplingFreq = tmp;
}
void cFemonReceiver::Activate(bool On)
{
//printf("cFemonReceiver::Activate()\n");
Start();
}
void cFemonReceiver::Receive(uchar *Data, int Length)
{
//printf("cFemonReceiver::Receive()\n");
// TS packet length: TS_SIZE
if (Length == TS_SIZE) {
int pid = ((Data[1] & 0x1f) << 8) | (Data[2]);
if (pid == m_VideoPid) {
m_VideoPacketCount++;
}
else if (pid == m_AudioPid) {
m_AudioPacketCount++;
}
/* the following originates from libdvbmpeg: */
if (!(Data[3] & PAYLOAD)) {
return;
}
uint8_t off = 0;
if (Data[3] & ADAPT_FIELD) {
off = Data[4] + 1;
}
if (Data[1] & PAY_START) {
uint8_t *sb = Data + 4 + off;
if (sb[7] & PTS_DTS_FLAGS) {
uint8_t *pay = sb + sb[8] + 9;
int l = TS_SIZE - 13 - off - sb[8];
if (pid == m_VideoPid) {
GetVideoInfo(pay, l);
}
if (pid == m_AudioPid) {
GetAudioInfo(pay, l);
}
}
}
/* end */
}
}
void cFemonReceiver::Action(void)
{
//printf("cFemonReceiver::Action()\n");
m_Active = true;
while (m_Active) {
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
m_VideoBitrate = (8.0 * 184.0 * m_VideoPacketCount) / (femonConfig.calcinterval * 100000.0);
m_VideoPacketCount = 0;
m_AudioBitrate = (8.0 * 184.0 * m_AudioPacketCount) / (femonConfig.calcinterval * 100.0);
m_AudioPacketCount = 0;
usleep(100000L * femonConfig.calcinterval);
}
}

60
femonreceiver.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* 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/thread.h>
#include <vdr/receiver.h>
class cFemonReceiver : public cReceiver, public cThread {
private:
bool m_Active;
int m_VideoPid;
int m_AudioPid;
int m_VideoPacketCount;
int m_VideoHorizontalSize;
int m_VideoVerticalSize;
int m_VideoAspectRatio;
int m_VideoFormat;
double m_VideoFrameRate;
double m_VideoStreamBitrate;
double m_VideoBitrate;
int m_AudioPacketCount;
double m_AudioStreamBitrate;
double m_AudioBitrate;
int m_AudioSamplingFreq;
int m_AudioMPEGLayer;
void GetVideoInfo(uint8_t *mbuf, int count);
void GetAudioInfo(uint8_t *mbuf, int count);
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 VideoHorizontalSize(void) { return m_VideoHorizontalSize; }; // pixels
int VideoVerticalSize(void) { return m_VideoVerticalSize; }; // pixels
int VideoAspectRatio(void) { return m_VideoAspectRatio; }; // 4:3 == 133, ...
int VideoFormat(void) { return m_VideoFormat; }; // 0 == unknown, 1 == PAL, 2 == NTSC
double VideoFrameRate(void) { return m_VideoFrameRate; }; // Hz
double VideoStreamBitrate(void) { return m_VideoStreamBitrate; }; // Mbit/s
double VideoBitrate(void) { return m_VideoBitrate; }; // Mbit/s
int AudioMPEGLayer(void) { return m_AudioMPEGLayer; }; // number
int AudioSamplingFreq(void) { return m_AudioSamplingFreq; }; // Hz
double AudioStreamBitrate(void) { return m_AudioStreamBitrate; }; // kbit/s
double AudioBitrate(void) { return m_AudioBitrate; }; // kbit/s
};
#endif //__FEMONRECEIVER_H