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

Compare commits

..

45 Commits

Author SHA1 Message Date
Rolf Ahrenberg
d9f977e302 Updated HISTORY. 2010-12-27 10:30:43 +02:00
Rolf Ahrenberg
ebfc153940 Added support for LDFLAGS. 2010-12-14 19:25:09 +02:00
Rolf Ahrenberg
f3c52fab6e Tweaked translation files. 2010-12-08 10:47:24 +02:00
Rolf Ahrenberg
b682dbf0fe Updated translation files. 2010-12-04 19:06:15 +02:00
Rolf Ahrenberg
b4673bdece Fixed detection of replaying. 2010-10-29 21:16:01 +03:00
Rolf Ahrenberg
c3b0254b2e Added Makefile depencency for objects. 2010-10-11 23:27:30 +03:00
Rolf Ahrenberg
b8c7fdddb7 Updated for vdr-1.7.16. 2010-09-19 23:19:33 +03:00
Rolf Ahrenberg
23a8a72c38 Modified LATM parser. 2010-06-23 20:12:35 +03:00
Rolf Ahrenberg
f37f428670 Added preliminary support for LATM. 2010-06-23 12:16:17 +03:00
Rolf Ahrenberg
3235c67256 Fixed a crash in femon service (Thanks to Wolfgang Astleitner). 2010-05-31 16:55:19 +03:00
Rolf Ahrenberg
a21ed98163 Updated Italian translation (Thanks to Diego Pierotto). 2010-03-31 14:44:39 +03:00
Rolf Ahrenberg
0b38358442 Fixed a typo. 2010-03-09 15:31:18 +02:00
Rolf Ahrenberg
9c085fea51 Fixed device switching. 2010-03-06 22:01:42 +02:00
Rolf Ahrenberg
dfc66b3d69 Updated the femonclient plugin. 2010-03-04 22:54:45 +02:00
Rolf Ahrenberg
252bd0e479 Added parsing for a missing setup option. 2010-03-04 22:49:19 +02:00
Rolf Ahrenberg
7657d21d5e Updated CXXFLAGS. 2010-03-04 12:58:25 +02:00
Rolf Ahrenberg
7b004e9427 Updated Estonian translation (Thanks to Arthur Konovalov). 2010-03-04 12:55:18 +02:00
Rolf Ahrenberg
a08f9de9d3 Updated for vdr-1.7.13. 2010-02-28 21:42:06 +02:00
Rolf Ahrenberg
513791d5f1 Added a setup option to downscale the OSD size. 2010-02-25 20:33:20 +02:00
Rolf Ahrenberg
60386835dd Updated for vdr-1.7.12. 2010-02-01 13:48:28 +02:00
Rolf Ahrenberg
38f4d3d9b8 Added Lithuanian translation (Thanks to Valdemaras Pipiras). 2009-12-14 16:47:16 +02:00
Rolf Ahrenberg
078f0552fc Fixed a typo. 2009-11-25 16:03:41 +02:00
Rolf Ahrenberg
1fd7c90c3b Updated Estonian translation (Thanks to Arthur Konovalov).
Updated version number.
2009-11-23 15:11:37 +02:00
Rolf Ahrenberg
44fa48c59f Added debug() and error() macros. 2009-10-01 12:13:35 +03:00
Rolf Ahrenberg
554dac9674 Increased video buffer size, added buffer timeouts and fixed deleting AC3 buffer data. 2009-09-29 15:31:32 +03:00
Rolf Ahrenberg
8267abcc3b Revert "Changed cRingBufferLinear to cRingBufferFrame."
This reverts commit edb8b4090a.
2009-09-27 16:59:42 +03:00
Rolf Ahrenberg
ea4561a874 Silenced a compilation warning. 2009-09-26 12:15:26 +03:00
Rolf Ahrenberg
56b9b89204 Cleaned up translations and warnings. 2009-09-26 11:54:31 +03:00
Rolf Ahrenberg
3d994be0b7 Cosmetics. 2009-09-25 22:31:12 +03:00
Rolf Ahrenberg
b7d44e730e Added Chinese translation (Thanks to NanFeng). 2009-09-24 17:28:02 +03:00
Rolf Ahrenberg
edb8b4090a Changed cRingBufferLinear to cRingBufferFrame. 2009-09-22 20:37:15 +03:00
Rolf Ahrenberg
21d9c20beb Removed bitstream parsing from Receive() method.
Refactored the error logging from unimplemented ioctl functions.
2009-09-22 08:44:30 +03:00
Rolf Ahrenberg
080f390a75 Remove compilation warnings. 2009-09-16 12:05:15 +03:00
Rolf Ahrenberg
fefb7f0fde Removed error logging from unimplemented ioctl functions. 2009-09-16 09:37:51 +03:00
Rolf Ahrenberg
ba133f15f8 Changed H.264 parser to show display aspect ratio. 2009-09-15 10:57:53 +03:00
Rolf Ahrenberg
4e87693de6 Tweaked symbols. 2009-09-05 01:22:27 +03:00
Rolf Ahrenberg
8ea980a60f Fixed symbols. 2009-09-05 01:05:17 +03:00
Rolf Ahrenberg
5635c2dc52 Fixed debug print output. 2009-09-04 10:47:19 +03:00
Rolf Ahrenberg
7551788969 Changed bitrate to bit/s instead of Mbit/s. 2009-09-04 08:44:33 +03:00
Rolf Ahrenberg
6b6169d5f3 Disabled temporarily SEI in H.264 bitstream parser. 2009-09-03 18:24:51 +03:00
Rolf Ahrenberg
22644e6ae4 Header cleanup. 2009-09-03 18:20:31 +03:00
Rolf Ahrenberg
3fc73af3d5 Added non-strict limits for 1080/720/576/480 format symbols. 2009-09-03 18:15:04 +03:00
Rolf Ahrenberg
c07abc7ed5 Added 1080/720/576/480 symbols into status window. 2009-09-02 15:58:30 +03:00
Rolf Ahrenberg
e57b36a151 Fixed H.264 bitstream parser.
Added a mutex to receiver class.
2009-09-01 15:30:48 +03:00
Rolf Ahrenberg
453ca7a2a5 Fixed H.264 bitstream parsing. 2009-08-31 19:12:15 +03:00
36 changed files with 2556 additions and 498 deletions

39
HISTORY
View File

@@ -370,3 +370,42 @@ VDR Plugin 'femon' Revision History
- Removed OSD offset and height options. - Removed OSD offset and height options.
- Added PES assembler. - Added PES assembler.
- Added bitstream parsers for all codecs. - Added bitstream parsers for all codecs.
2009-09-04: Version 1.7.4
- Fixed H.264 bitstream parser.
- Added a mutex to receiver class.
- Added 1080/720/576/480 format symbols into status window.
2009-10-01: Version 1.7.5
- Changed H.264 parser to show display aspect ratio.
- Removed error logging from unimplemented ioctl functions.
- Removed bitstream parsing from Receive() method.
- Added Chinese translation (Thanks to NanFeng).
2010-02-01: Version 1.7.6
- Updated for vdr-1.7.12.
- Updated Estonian translation (Thanks to Arthur Konovalov).
- Added Lithuanian translation (Thanks to Valdemaras Pipiras).
2010-03-05: Version 1.7.7
- Updated for vdr-1.7.13.
- Added a setup option to downscale the OSD size.
- Updated Estonian translation (Thanks to Arthur Konovalov).
2010-06-23: Version 1.7.8
- Fixed device switching.
- Added preliminary support for LATM.
- Updated Italian translation (Thanks to Diego Pierotto).
- Fixed a crash in femon service (Thanks to Wolfgang Astleitner).
2010-12-27: Version 1.7.9
- Updated for vdr-1.7.16.
- Added Makefile depencency for objects.
- Fixed detection of replaying.
- Added support for LDFLAGS.

View File

@@ -24,6 +24,7 @@ VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).c | awk '{ p
CXX ?= g++ CXX ?= g++
CXXFLAGS ?= -fPIC -g -O2 -Wall -Wextra -Wswitch-default -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wcast-align -Wredundant-decls -Wno-unused-parameter -Woverloaded-virtual -Wno-parentheses CXXFLAGS ?= -fPIC -g -O2 -Wall -Wextra -Wswitch-default -Wfloat-equal -Wundef -Wpointer-arith -Wconversion -Wcast-align -Wredundant-decls -Wno-unused-parameter -Woverloaded-virtual -Wno-parentheses
LDFLAGS ?= -Wl,--as-needed
### The directory environment: ### The directory environment:
@@ -31,6 +32,10 @@ VDRDIR = ../../..
LIBDIR = ../../lib LIBDIR = ../../lib
TMPDIR = /tmp TMPDIR = /tmp
### Make sure that necessary options are included:
-include $(VDRDIR)/Make.global
### Allow user defined options to overwrite defaults: ### Allow user defined options to overwrite defaults:
-include $(VDRDIR)/Make.config -include $(VDRDIR)/Make.config
@@ -59,7 +64,7 @@ all-redirect: all
### The object files (add further files here): ### The object files (add further files here):
OBJS = femon.o femonosd.o femonreceiver.o femoncfg.o femontools.o femonmpeg.o femonac3.o femonaac.o femonh264.o femonsymbol.o OBJS = femon.o femonosd.o femonreceiver.o femoncfg.o femontools.o femonmpeg.o femonac3.o femonaac.o femonlatm.o femonh264.o femonsymbol.o
### The main target: ### The main target:
@@ -67,7 +72,7 @@ all: libvdr-$(PLUGIN).so i18n
### Implicit rules: ### Implicit rules:
%.o: %.c %.o: %.c Makefile
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
### Dependencies: ### Dependencies:
@@ -91,7 +96,7 @@ I18Npot = $(PODIR)/$(PLUGIN).pot
msgfmt -c -o $@ $< msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c) $(I18Npot): $(wildcard *.c)
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='Rolf Ahrenberg' -o $@ $^ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<see README>' -o $@ $^
%.po: $(I18Npot) %.po: $(I18Npot)
msgmerge -U --no-wrap --no-location --backup=none -q $@ $< msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@@ -107,7 +112,7 @@ i18n: $(I18Nmsgs) $(I18Npot)
### Targets: ### Targets:
libvdr-$(PLUGIN).so: $(OBJS) libvdr-$(PLUGIN).so: $(OBJS)
$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
ifndef FEMON_DEBUG ifndef FEMON_DEBUG
@$(STRIP) $@ @$(STRIP) $@
endif endif

29
femon.c
View File

@@ -7,18 +7,18 @@
#include <vdr/menu.h> #include <vdr/menu.h>
#include <vdr/remote.h> #include <vdr/remote.h>
#include <vdr/menu.h> #include <vdr/player.h>
#include "femoncfg.h" #include "femoncfg.h"
#include "femonreceiver.h" #include "femonreceiver.h"
#include "femonosd.h" #include "femonosd.h"
#include "femonservice.h" #include "femonservice.h"
#include "femontools.h" #include "femontools.h"
#if defined(APIVERSNUM) && APIVERSNUM < 10700 #if defined(APIVERSNUM) && APIVERSNUM < 10716
#error "VDR-1.7.0 API version or greater is required!" #error "VDR-1.7.16 API version or greater is required!"
#endif #endif
static const char VERSION[] = "1.7.3"; static const char VERSION[] = "1.7.9";
static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)"); static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)");
static const char MAINMENUENTRY[] = trNOOP("Signal Information"); static const char MAINMENUENTRY[] = trNOOP("Signal Information");
@@ -50,13 +50,13 @@ cPluginFemon::cPluginFemon()
// Initialize any member variables here. // Initialize any member variables here.
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
} }
cPluginFemon::~cPluginFemon() cPluginFemon::~cPluginFemon()
{ {
// Clean up after yourself! // Clean up after yourself!
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
} }
const char *cPluginFemon::CommandLineHelp(void) const char *cPluginFemon::CommandLineHelp(void)
@@ -96,8 +96,8 @@ void cPluginFemon::Housekeeping(void)
cOsdObject *cPluginFemon::MainMenuAction(void) cOsdObject *cPluginFemon::MainMenuAction(void)
{ {
// Perform the action when selected from the main VDR menu. // Perform the action when selected from the main VDR menu.
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
if (cReplayControl::NowReplaying() || (Channels.Count() <= 0)) if (cControl::Control() || (Channels.Count() <= 0))
Skins.Message(mtInfo, tr("Femon not available")); Skins.Message(mtInfo, tr("Femon not available"));
else else
return cFemonOsd::Instance(true); return cFemonOsd::Instance(true);
@@ -112,6 +112,7 @@ bool cPluginFemon::SetupParse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value); else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value);
else if (!strcasecmp(Name, "Skin")) femonConfig.skin = atoi(Value); else if (!strcasecmp(Name, "Skin")) femonConfig.skin = atoi(Value);
else if (!strcasecmp(Name, "Theme")) femonConfig.theme = atoi(Value); else if (!strcasecmp(Name, "Theme")) femonConfig.theme = atoi(Value);
else if (!strcasecmp(Name, "Downscale")) femonConfig.downscale = atoi(Value);
else if (!strcasecmp(Name, "RedLimit")) femonConfig.redlimit = atoi(Value); else if (!strcasecmp(Name, "RedLimit")) femonConfig.redlimit = atoi(Value);
else if (!strcasecmp(Name, "GreenLimit")) femonConfig.greenlimit = atoi(Value); else if (!strcasecmp(Name, "GreenLimit")) femonConfig.greenlimit = atoi(Value);
else if (!strcasecmp(Name, "UpdateInterval")) femonConfig.updateinterval = atoi(Value); else if (!strcasecmp(Name, "UpdateInterval")) femonConfig.updateinterval = atoi(Value);
@@ -132,6 +133,8 @@ bool cPluginFemon::Service(const char *Id, void *Data)
if (strcmp(Id,"FemonService-v1.0") == 0) { if (strcmp(Id,"FemonService-v1.0") == 0) {
if (Data) { if (Data) {
FemonService_v1_0 *data = (FemonService_v1_0*)Data; FemonService_v1_0 *data = (FemonService_v1_0*)Data;
if (!cDevice::ActualDevice())
return false;
int ndx = cDevice::ActualDevice()->CardIndex(); int ndx = cDevice::ActualDevice()->CardIndex();
data->fe_name = getFrontendName(ndx); data->fe_name = getFrontendName(ndx);
data->fe_status = getFrontendStatus(ndx); data->fe_status = getFrontendStatus(ndx);
@@ -193,7 +196,7 @@ cString cPluginFemon::SVDRPCommand(const char *Command, const char *Option, int
return cString("Cannot open femon plugin while replaying"); return cString("Cannot open femon plugin while replaying");
} }
if (!cFemonOsd::Instance()) if (!cFemonOsd::Instance())
cRemote::CallPlugin("femon"); cRemote::CallPlugin(Name());
return cString("Opening femon plugin"); return cString("Opening femon plugin");
} }
else if (strcasecmp(Command, "QUIT") == 0) { else if (strcasecmp(Command, "QUIT") == 0) {
@@ -274,7 +277,7 @@ public:
cMenuFemonSetup::cMenuFemonSetup(void) cMenuFemonSetup::cMenuFemonSetup(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
dispmodes[eFemonModeBasic] = tr("basic"); dispmodes[eFemonModeBasic] = tr("basic");
dispmodes[eFemonModeTransponder] = tr("transponder"); dispmodes[eFemonModeTransponder] = tr("transponder");
dispmodes[eFemonModeStream] = tr("stream"); dispmodes[eFemonModeStream] = tr("stream");
@@ -319,6 +322,9 @@ void cMenuFemonSetup::Setup(void)
Add(new cMenuEditBoolItem(tr("Position"), &data.position, trVDR("bottom"), trVDR("top"))); Add(new cMenuEditBoolItem(tr("Position"), &data.position, trVDR("bottom"), trVDR("top")));
help.Append(tr("Define the position of OSD.")); help.Append(tr("Define the position of OSD."));
Add(new cMenuEditIntItem(tr("Downscale OSD size [%]"), &data.downscale, 0, 20));
help.Append(tr("Define the downscale ratio for OSD size."));
Add(new cMenuEditIntItem(tr("Red limit [%]"), &data.redlimit, 1, 50)); Add(new cMenuEditIntItem(tr("Red limit [%]"), &data.redlimit, 1, 50));
help.Append(tr("Define a limit for red bar, which is used to indicate a bad signal.")); help.Append(tr("Define a limit for red bar, which is used to indicate a bad signal."));
@@ -353,13 +359,14 @@ void cMenuFemonSetup::Setup(void)
void cMenuFemonSetup::Store(void) void cMenuFemonSetup::Store(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
femonConfig = data; femonConfig = data;
SetupStore("HideMenu", femonConfig.hidemenu); SetupStore("HideMenu", femonConfig.hidemenu);
SetupStore("DisplayMode", femonConfig.displaymode); SetupStore("DisplayMode", femonConfig.displaymode);
SetupStore("Skin", femonConfig.skin); SetupStore("Skin", femonConfig.skin);
SetupStore("Theme", femonConfig.theme); SetupStore("Theme", femonConfig.theme);
SetupStore("Position", femonConfig.position); SetupStore("Position", femonConfig.position);
SetupStore("Downscale", femonConfig.downscale);
SetupStore("RedLimit", femonConfig.redlimit); SetupStore("RedLimit", femonConfig.redlimit);
SetupStore("GreenLimit", femonConfig.greenlimit); SetupStore("GreenLimit", femonConfig.greenlimit);
SetupStore("UpdateInterval", femonConfig.updateinterval); SetupStore("UpdateInterval", femonConfig.updateinterval);

View File

@@ -17,7 +17,8 @@ enum eAudioCodec {
AUDIO_CODEC_MPEG2_I, AUDIO_CODEC_MPEG2_I,
AUDIO_CODEC_MPEG2_II, AUDIO_CODEC_MPEG2_II,
AUDIO_CODEC_MPEG2_III, AUDIO_CODEC_MPEG2_III,
AUDIO_CODEC_HEAAC AUDIO_CODEC_HEAAC,
AUDIO_CODEC_LATM
}; };
enum eAudioChannelMode { enum eAudioChannelMode {
@@ -89,7 +90,7 @@ enum eAudioCodingMode {
typedef struct audio_info { typedef struct audio_info {
eAudioCodec codec; // enum eAudioCodec codec; // enum
double bitrate; // kbit/s or eAudioBitrate double bitrate; // bit/s or eAudioBitrate
int samplingFrequency; // Hz or eAudioSamplingFrequency int samplingFrequency; // Hz or eAudioSamplingFrequency
int channelMode; // eAudioChannelMode int channelMode; // eAudioChannelMode
} audio_info_t; } audio_info_t;

View File

@@ -17,13 +17,14 @@ cFemonConfig::cFemonConfig(void)
skin = 0; skin = 0;
theme = 0; theme = 0;
position = 1; position = 1;
downscale = 0;
redlimit = 33; redlimit = 33;
greenlimit = 66; greenlimit = 66;
updateinterval = 5; updateinterval = 5;
analyzestream = 1; analyzestream = 1;
calcinterval = 20; calcinterval = 20;
usesvdrp = 0; usesvdrp = 0;
svdrpport = 2001; svdrpport = 6419;
strncpy(svdrpip, "0.0.0.0", sizeof(svdrpip)); strncpy(svdrpip, "0.0.0.0", sizeof(svdrpip));
} }

View File

@@ -28,6 +28,7 @@ public:
int skin; int skin;
int theme; int theme;
int position; int position;
int downscale;
int redlimit; int redlimit;
int greenlimit; int greenlimit;
int updateinterval; int updateinterval;

Binary file not shown.

View File

@@ -3,32 +3,52 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* The original NAL SPS parsing and bitstream functions are taken from
* vdr-xineliboutput plugin by Petri Hintukainen.
*/ */
#include "femontools.h" #include "femontools.h"
#include "femonh264.h" #include "femonh264.h"
const eVideoAspectRatio cFemonH264::s_AspectRatios[] = const cFemonH264::t_DAR cFemonH264::s_DAR[] =
{ {
VIDEO_ASPECT_RATIO_INVALID, { VIDEO_ASPECT_RATIO_1_1, 100 },
VIDEO_ASPECT_RATIO_1_1, { VIDEO_ASPECT_RATIO_4_3, 133 },
VIDEO_ASPECT_RATIO_12_11, { VIDEO_ASPECT_RATIO_16_9, 177 },
VIDEO_ASPECT_RATIO_10_11, { VIDEO_ASPECT_RATIO_2_21_1, 221 },
VIDEO_ASPECT_RATIO_16_11, { VIDEO_ASPECT_RATIO_12_11, 109 },
VIDEO_ASPECT_RATIO_40_33, { VIDEO_ASPECT_RATIO_10_11, 90 },
VIDEO_ASPECT_RATIO_24_11, { VIDEO_ASPECT_RATIO_16_11, 145 },
VIDEO_ASPECT_RATIO_20_11, { VIDEO_ASPECT_RATIO_40_33, 121 },
VIDEO_ASPECT_RATIO_32_11, { VIDEO_ASPECT_RATIO_24_11, 218 },
VIDEO_ASPECT_RATIO_80_33, { VIDEO_ASPECT_RATIO_20_11, 181 },
VIDEO_ASPECT_RATIO_18_11, { VIDEO_ASPECT_RATIO_32_11, 290 },
VIDEO_ASPECT_RATIO_15_11, { VIDEO_ASPECT_RATIO_80_33, 242 },
VIDEO_ASPECT_RATIO_64_33, { VIDEO_ASPECT_RATIO_18_11, 163 },
VIDEO_ASPECT_RATIO_160_99, { VIDEO_ASPECT_RATIO_15_11, 136 },
VIDEO_ASPECT_RATIO_4_3, { VIDEO_ASPECT_RATIO_64_33, 193 },
VIDEO_ASPECT_RATIO_3_2, { VIDEO_ASPECT_RATIO_160_99, 161 },
VIDEO_ASPECT_RATIO_2_1 { VIDEO_ASPECT_RATIO_3_2, 150 },
{ VIDEO_ASPECT_RATIO_2_1, 200 }
};
const cFemonH264::t_SAR cFemonH264::s_SAR[] =
{
{ 0, 0 }, // VIDEO_ASPECT_RATIO_INVALID
{ 1, 1 }, // VIDEO_ASPECT_RATIO_1_1
{ 12, 11 }, // VIDEO_ASPECT_RATIO_12_11
{ 10, 11 }, // VIDEO_ASPECT_RATIO_10_11
{ 16, 11 }, // VIDEO_ASPECT_RATIO_16_11
{ 40, 33 }, // VIDEO_ASPECT_RATIO_40_33
{ 24, 11 }, // VIDEO_ASPECT_RATIO_24_11
{ 20, 11 }, // VIDEO_ASPECT_RATIO_20_11
{ 32, 11 }, // VIDEO_ASPECT_RATIO_32_11
{ 80, 33 }, // VIDEO_ASPECT_RATIO_80_33
{ 18, 11 }, // VIDEO_ASPECT_RATIO_18_11
{ 15, 11 }, // VIDEO_ASPECT_RATIO_15_11
{ 64, 33 }, // VIDEO_ASPECT_RATIO_64_33
{ 160, 99 }, // VIDEO_ASPECT_RATIO_160_99
{ 4, 3 }, // VIDEO_ASPECT_RATIO_4_3
{ 3, 2 }, // VIDEO_ASPECT_RATIO_3_2
{ 2, 1 } // VIDEO_ASPECT_RATIO_2_1
}; };
const eVideoFormat cFemonH264::s_VideoFormats[] = const eVideoFormat cFemonH264::s_VideoFormats[] =
@@ -58,8 +78,11 @@ cFemonH264::cFemonH264(cFemonVideoIf *videohandler)
m_Scan(VIDEO_SCAN_INVALID), m_Scan(VIDEO_SCAN_INVALID),
m_CpbDpbDelaysPresentFlag(false), m_CpbDpbDelaysPresentFlag(false),
m_PicStructPresentFlag(false), m_PicStructPresentFlag(false),
m_FrameMbsOnlyFlag(false),
m_MbAdaptiveFrameFieldFlag(false),
m_TimeOffsetLength(0) m_TimeOffsetLength(0)
{ {
reset();
} }
cFemonH264::~cFemonH264() cFemonH264::~cFemonH264()
@@ -69,7 +92,7 @@ cFemonH264::~cFemonH264()
bool cFemonH264::processVideo(const uint8_t *buf, int len) bool cFemonH264::processVideo(const uint8_t *buf, int len)
{ {
uint8_t nal_data[len]; uint8_t nal_data[len];
bool aud_found = false, sps_found = false, sei_found = false; bool aud_found = false, sps_found = false, sei_found = true; // SEI temporarily disabled!
const uint8_t *start = buf; const uint8_t *start = buf;
const uint8_t *end = start + len; const uint8_t *end = start + len;
@@ -82,6 +105,8 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
buf += PesPayloadOffset(buf); buf += PesPayloadOffset(buf);
start = buf; start = buf;
reset();
for (;;) { for (;;) {
int consumed = 0; int consumed = 0;
@@ -94,7 +119,7 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
if (!aud_found) { if (!aud_found) {
switch (buf[4] >> 5) { switch (buf[4] >> 5) {
case 0: case 3: case 5: // I_FRAME case 0: case 3: case 5: // I_FRAME
//Dprintf("H.264: Found NAL AUD at offset %d/%d", buf - start, len); //debug("H.264: Found NAL AUD at offset %d/%d\n", int(buf - start), len);
aud_found = true; aud_found = true;
break; break;
case 1: case 4: case 6: // P_FRAME; case 1: case 4: case 6: // P_FRAME;
@@ -107,24 +132,24 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
case NAL_SPS: case NAL_SPS:
if (!sps_found) { if (!sps_found) {
//Dprintf("H.264: Found NAL SPS at offset %d/%d", buf - start, len); //debug("H.264: Found NAL SPS at offset %d/%d\n", int(buf - start), len);
int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4)); int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4));
consumed = parseSPS(nal_data, nal_len); consumed = parseSPS(nal_data, nal_len);
if (consumed > 0) if (consumed > 0)
sps_found = true; sps_found = true;
} }
break; break;
#if 0
case NAL_SEI: case NAL_SEI:
if (!sei_found) { if (!sei_found) {
//Dprintf("H.264: Found NAL SEI at offset %d/%d", buf - start, len); //debug("H.264: Found NAL SEI at offset %d/%d\n", int(buf - start), len);
int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4)); int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4));
consumed = parseSEI(nal_data, nal_len); consumed = parseSEI(nal_data, nal_len);
if (consumed > 0) if (consumed > 0)
sei_found = true; sei_found = true;
} }
break; break;
#endif
default: default:
break; break;
} }
@@ -138,15 +163,15 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
if (aud_found) { if (aud_found) {
m_VideoHandler->SetVideoCodec(VIDEO_CODEC_H264); m_VideoHandler->SetVideoCodec(VIDEO_CODEC_H264);
if (sps_found) { if (sps_found) {
//Dprintf("H.264 SPS: -> video size %dx%d, aspect %d format %d", m_Width, m_Height, m_AspectRatio, m_Format); //debug("H.264 SPS: size %dx%d, aspect %d format %d framerate %.2f bitrate %.0f\n", m_Width, m_Height, m_AspectRatio, m_Format, m_FrameRate, m_BitRate);
m_VideoHandler->SetVideoFormat(m_Format); m_VideoHandler->SetVideoFormat(m_Format);
m_VideoHandler->SetVideoSize(m_Width, m_Height); m_VideoHandler->SetVideoSize(m_Width, m_Height);
m_VideoHandler->SetVideoAspectRatio(m_AspectRatio); m_VideoHandler->SetVideoAspectRatio(m_AspectRatio);
}
if (sei_found) {
//Dprintf("H.264 SEI: -> stream bitrate %.1f, frame rate %.1f scan %d", m_BitRate, m_FrameRate, m_Scan);
m_VideoHandler->SetVideoFramerate(m_FrameRate); m_VideoHandler->SetVideoFramerate(m_FrameRate);
m_VideoHandler->SetVideoBitrate(m_BitRate); m_VideoHandler->SetVideoBitrate(m_BitRate);
}
if (sei_found) {
//debug("H.264 SEI: scan %d\n", m_Scan);
m_VideoHandler->SetVideoScan(m_Scan); m_VideoHandler->SetVideoScan(m_Scan);
} }
} }
@@ -154,6 +179,15 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
return aud_found; return aud_found;
} }
void cFemonH264::reset()
{
m_CpbDpbDelaysPresentFlag = false;
m_PicStructPresentFlag = false;
m_FrameMbsOnlyFlag = false;
m_MbAdaptiveFrameFieldFlag = false;
m_TimeOffsetLength = 0;
}
const uint8_t *cFemonH264::nextStartCode(const uint8_t *start, const uint8_t *end) const uint8_t *cFemonH264::nextStartCode(const uint8_t *start, const uint8_t *end)
{ {
for (end -= 3; start < end; ++start) { for (end -= 3; start < end; ++start) {
@@ -187,34 +221,252 @@ int cFemonH264::nalUnescape(uint8_t *dst, const uint8_t *src, int len)
int cFemonH264::parseSPS(const uint8_t *buf, int len) int cFemonH264::parseSPS(const uint8_t *buf, int len)
{ {
int profile_idc, pic_order_cnt_type, frame_mbs_only, i, j; int profile_idc, level_idc, constraint_set3_flag, pic_order_cnt_type, i, j;
cBitStream bs(buf, len); cBitStream bs(buf, len);
unsigned int width = m_Width; uint32_t width = m_Width;
unsigned int height = m_Height; uint32_t height = m_Height;
eVideoAspectRatio aspect_ratio = m_AspectRatio; eVideoAspectRatio aspect_ratio = m_AspectRatio;
eVideoFormat format = m_Format; eVideoFormat format = m_Format;
double frame_rate = m_FrameRate;
double bit_rate = m_BitRate;
bool cpb_dpb_delays_present_flag = m_CpbDpbDelaysPresentFlag; bool cpb_dpb_delays_present_flag = m_CpbDpbDelaysPresentFlag;
bool pic_struct_present_flag = m_PicStructPresentFlag; bool pic_struct_present_flag = m_PicStructPresentFlag;
unsigned int time_offset_length = m_TimeOffsetLength; bool frame_mbs_only_flag = m_FrameMbsOnlyFlag;
bool mb_adaptive_frame_field_flag = m_MbAdaptiveFrameFieldFlag;
uint32_t time_offset_length = m_TimeOffsetLength;
profile_idc = bs.getU8(); profile_idc = bs.getU8(); // profile_idc
bs.skipBit(); // constraint_set0_flag
//Dprintf("H.264 SPS: profile_idc %d", profile_idc); bs.skipBit(); // constraint_set1_flag
bs.skipBit(); // constraint_set2_flag
bs.skipBits(16); constraint_set3_flag = bs.getBit(); // constraint_set3_flag
bs.skipBits(4); // reserved_zero_4bits
level_idc = bs.getU8(); // level_idc
bs.skipUeGolomb(); // seq_parameter_set_id bs.skipUeGolomb(); // seq_parameter_set_id
if (profile_idc >= 100) { //debug("H.264 SPS: profile_idc %d level_idc %d\n", profile_idc, level_idc);
switch (profile_idc) {
case 66: // baseline profile
case 77: // main profile
case 88: // extended profile
switch (level_idc) {
case 10: // level 1.0
bit_rate = 64000;
break;
case 11: // level 1b / 1.1
bit_rate = constraint_set3_flag ? 128000 : 192000;
break;
case 12: // level 1.2
bit_rate = 384000;
break;
case 13: // level 1.3
bit_rate = 768000;
break;
case 20: // level 2.0
bit_rate = 2000000;
break;
case 21: // level 2.1
bit_rate = 4000000;
break;
case 22: // level 2.2
bit_rate = 4000000;
break;
case 30: // level 3.0
bit_rate = 10000000;
break;
case 31: // level 3.1
bit_rate = 14000000;
break;
case 32: // level 3.2
bit_rate = 20000000;
break;
case 40: // level 4.0
bit_rate = 20000000;
break;
case 41: // level 4.1
bit_rate = 50000000;
break;
case 42: // level 4.2
bit_rate = 50000000;
break;
case 50: // level 5.0
bit_rate = 135000000;
break;
case 51: // level 5.1
bit_rate = 240000000;
break;
default:
break;
}
break;
case 100: // high profile
switch (level_idc) {
case 10: // level 1.0
bit_rate = 80000;
break;
case 11: // level 1b / 1.1
bit_rate = constraint_set3_flag ? 160000 : 240000;
break;
case 12: // level 1.2
bit_rate = 480000;
break;
case 13: // level 1.3
bit_rate = 960000;
break;
case 20: // level 2.0
bit_rate = 2500000;
break;
case 21: // level 2.1
bit_rate = 5000000;
break;
case 22: // level 2.2
bit_rate = 5000000;
break;
case 30: // level 3.0
bit_rate = 12500000;
break;
case 31: // level 3.1
bit_rate = 17500000;
break;
case 32: // level 3.2
bit_rate = 25000000;
break;
case 40: // level 4.0
bit_rate = 25000000;
break;
case 41: // level 4.1
bit_rate = 62500000;
break;
case 42: // level 4.2
bit_rate = 62500000;
break;
case 50: // level 5.0
bit_rate = 168750000;
break;
case 51: // level 5.1
bit_rate = 300000000;
break;
default:
break;
}
break;
case 110: // high 10 profile
switch (level_idc) {
case 10: // level 1.0
bit_rate = 192000;
break;
case 11: // level 1b / 1.1
bit_rate = constraint_set3_flag ? 384000 : 576000;
break;
case 12: // level 1.2
bit_rate = 115200;
break;
case 13: // level 1.3
bit_rate = 2304000;
break;
case 20: // level 2.0
bit_rate = 6000000;
break;
case 21: // level 2.1
bit_rate = 12000000;
break;
case 22: // level 2.2
bit_rate = 12000000;
break;
case 30: // level 3.0
bit_rate = 30000000;
break;
case 31: // level 3.1
bit_rate = 42000000;
break;
case 32: // level 3.2
bit_rate = 60000000;
break;
case 40: // level 4.0
bit_rate = 60000000;
break;
case 41: // level 4.1
bit_rate = 150000000;
break;
case 42: // level 4.2
bit_rate = 150000000;
break;
case 50: // level 5.0
bit_rate = 405000000;
break;
case 51: // level 5.1
bit_rate = 720000000;
break;
default:
break;
}
break;
case 122: // high 4:2:2 profile
case 144: // high 4:4:4 profile
switch (level_idc) {
case 10: // level 1.0
bit_rate = 256000;
break;
case 11: // level 1b / 1.1
bit_rate = constraint_set3_flag ? 512000 : 768000;
break;
case 12: // level 1.2
bit_rate = 1536000;
break;
case 13: // level 1.3
bit_rate = 3072000;
break;
case 20: // level 2.0
bit_rate = 8000000;
break;
case 21: // level 2.1
bit_rate = 16000000;
break;
case 22: // level 2.2
bit_rate = 16000000;
break;
case 30: // level 3.0
bit_rate = 40000000;
break;
case 31: // level 3.1
bit_rate = 56000000;
break;
case 32: // level 3.2
bit_rate = 80000000;
break;
case 40: // level 4.0
bit_rate = 80000000;
break;
case 41: // level 4.1
bit_rate = 200000000;
break;
case 42: // level 4.2
bit_rate = 200000000;
break;
case 50: // level 5.0
bit_rate = 540000000;
break;
case 51: // level 5.1
bit_rate = 960000000;
break;
default:
break;
}
break;
default:
break;
}
if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) {
if (bs.getUeGolomb() == 3) // chroma_format_idc if (bs.getUeGolomb() == 3) // chroma_format_idc
bs.skipBit(); // residual_colour_transform_flag bs.skipBit(); // residual_colour_transform_flag
bs.skipUeGolomb(); // bit_depth_luma - 8 bs.skipUeGolomb(); // bit_depth_luma_minus8
bs.skipUeGolomb(); // bit_depth_chroma - 8 bs.skipUeGolomb(); // bit_depth_chroma_minus8
bs.skipBit(); // transform_bypass bs.skipBit(); // qpprime_y_zero_transform_bypass_flag
if (bs.getBit()) { // seq_scaling_matrix_present if (bs.getBit()) { // seq_scaling_matrix_present_flag
for (i = 0; i < 8; i++) { for (i = 0; i < 8; ++i) {
if (bs.getBit()) { // seq_scaling_list_present if (bs.getBit()) { // seq_scaling_list_present_flag[i]
int last = 8, next = 8, size = (i < 6) ? 16 : 64; int last = 8, next = 8, size = (i < 6) ? 16 : 64;
for (j = 0; j < size; j++) { for (j = 0; j < size; ++j) {
if (next) if (next)
next = (last + bs.getSeGolomb()) & 0xff; next = (last + bs.getSeGolomb()) & 0xff;
last = next ?: last; last = next ?: last;
@@ -223,67 +475,75 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
} }
} }
} }
bs.skipUeGolomb(); // log2_max_frame_num_minus4
bs.skipUeGolomb(); // log2_max_frame_num - 4 pic_order_cnt_type = bs.getUeGolomb(); // pic_order_cnt_type
pic_order_cnt_type = bs.getUeGolomb();
if (pic_order_cnt_type == 0) if (pic_order_cnt_type == 0)
bs.skipUeGolomb(); // log2_max_poc_lsb - 4 bs.skipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4
else if (pic_order_cnt_type == 1) { else if (pic_order_cnt_type == 1) {
bs.skipBit(); // delta_pic_order_always_zero bs.skipBit(); // delta_pic_order_always_zero
bs.skipSeGolomb(); // offset_for_non_ref_pic bs.skipSeGolomb(); // offset_for_non_ref_pic
bs.skipSeGolomb(); // offset_for_top_to_bottom_field bs.skipSeGolomb(); // offset_for_top_to_bottom_field
j = bs.getUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle j = bs.getUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle
for (i = 0; i < j; i++) for (i = 0; i < j; ++i)
bs.skipSeGolomb(); // offset_for_ref_frame[i] bs.skipSeGolomb(); // offset_for_ref_frame[i]
} }
bs.skipUeGolomb(); // ref_frames bs.skipUeGolomb(); // num_ref_frames
bs.skipBit(); // gaps_in_frame_num_allowed bs.skipBit(); // gaps_in_frame_num_value_allowed_flag
width = bs.getUeGolomb() + 1; // mbs width = bs.getUeGolomb() + 1; // pic_width_in_mbs_minus1
height = bs.getUeGolomb() + 1; // mbs height = bs.getUeGolomb() + 1; // pic_height_in_mbs_minus1
frame_mbs_only = bs.getBit(); frame_mbs_only_flag = bs.getBit(); // frame_mbs_only_flag
//debug("H.264 SPS: pic_width: %u mbs\n", width);
//Dprintf("H.264 SPS: pic_width: %u mbs", width); //debug("H.264 SPS: pic_height: %u mbs\n", height);
//Dprintf("H.264 SPS: pic_height: %u mbs", height); //debug("H.264 SPS: frame only flag: %d\n", frame_mbs_only_flag);
//Dprintf("H.264 SPS: frame only flag: %d", frame_mbs_only);
width *= 16; width *= 16;
height *= 16 * (2 - frame_mbs_only); height *= 16 * (frame_mbs_only_flag ? 1 : 2);
if (!frame_mbs_only_flag)
if (!frame_mbs_only) { mb_adaptive_frame_field_flag = bs.getBit(); // mb_adaptive_frame_field_flag
if (bs.getBit()) { // mb_adaptive_frame_field_flag
//Dprintf("H.264 SPS: MBAFF");
}
}
bs.skipBit(); // direct_8x8_inference_flag bs.skipBit(); // direct_8x8_inference_flag
if (bs.getBit()) { // frame_cropping_flag if (bs.getBit()) { // frame_cropping_flag
uint32_t crop_left = bs.getUeGolomb(); uint32_t crop_left, crop_right, crop_top, crop_bottom;
uint32_t crop_right = bs.getUeGolomb(); crop_left = bs.getUeGolomb(); // frame_crop_left_offset
uint32_t crop_top = bs.getUeGolomb(); crop_right = bs.getUeGolomb(); // frame_crop_rigth_offset
uint32_t crop_bottom = bs.getUeGolomb(); crop_top = bs.getUeGolomb(); // frame_crop_top_offset
//Dprintf("H.264 SPS: cropping %d %d %d %d", crop_left, crop_top, crop_right, crop_bottom); crop_bottom = bs.getUeGolomb(); // frame_crop_bottom_offset
//debug("H.264 SPS: cropping %d %d %d %d\n", crop_left, crop_top, crop_right, crop_bottom);
width -= 2 * (crop_left + crop_right); width -= 2 * (crop_left + crop_right);
if (frame_mbs_only) if (frame_mbs_only_flag)
height -= 2 * (crop_top + crop_bottom); height -= 2 * (crop_top + crop_bottom);
else else
height -= 4 * (crop_top + crop_bottom); height -= 4 * (crop_top + crop_bottom);
} }
// VUI parameters // VUI parameters
if (bs.getBit()) { // vui_parameters_present_flag if (bs.getBit()) { // vui_parameters_present_flag
if (bs.getBit()) { // aspect_ratio_info_present if (bs.getBit()) { // aspect_ratio_info_present
uint32_t aspect_ratio_idc = bs.getU8(); uint32_t aspect_ratio_idc, sar_width = 0, sar_height = 0;
//Dprintf("H.264 SPS: aspect_ratio_idc %d", aspect_ratio_idc); aspect_ratio_idc = bs.getU8(); // aspect_ratio_idc
//debug("H.264 SPS: aspect_ratio_idc %d\n", aspect_ratio_idc);
if (aspect_ratio_idc == 255) { // extended sar if (aspect_ratio_idc == 255) { // extended sar
bs.skipBit(); // sar_width sar_width = bs.getU16(); // sar_width
bs.skipBit(); // sar_height sar_height = bs.getU16(); // sar_height
aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED;
//Dprintf("H.264 SPS: aspect ratio extended");
} }
else if (aspect_ratio_idc < sizeof(s_AspectRatios) / sizeof(s_AspectRatios[0])) { else if (aspect_ratio_idc < ELEMENTS(s_SAR)) {
aspect_ratio = s_AspectRatios[aspect_ratio_idc]; sar_width = s_SAR[aspect_ratio_idc].w;
//Dprintf("H.264 SPS: -> aspect ratio %d", aspect_ratio); sar_height = s_SAR[aspect_ratio_idc].h;
}
if (sar_width && sar_height) {
int index = -1, ratio = int(100.0L * sar_width * width / sar_height / height);
for (unsigned int i = 0; i < ELEMENTS(s_DAR); ++i) {
if (s_DAR[i].ratio == ratio) {
index = i;
break;
}
}
if (index < 0) {
if (aspect_ratio_idc == 255)
aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED;
else
aspect_ratio = VIDEO_ASPECT_RATIO_INVALID;
}
else
aspect_ratio = s_DAR[index].dar;
//debug("H.264 SPS: DAR %dx%d (%d)\n", sar_width, sar_height, aspect_ratio);
} }
} }
if (bs.getBit()) // overscan_info_present_flag if (bs.getBit()) // overscan_info_present_flag
@@ -293,10 +553,9 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
video_format = bs.getBits(3); // video_format video_format = bs.getBits(3); // video_format
if (video_format < sizeof(s_VideoFormats) / sizeof(s_VideoFormats[0])) { if (video_format < sizeof(s_VideoFormats) / sizeof(s_VideoFormats[0])) {
format = s_VideoFormats[video_format]; format = s_VideoFormats[video_format];
//Dprintf("H.264 SPS: -> video format %d", format); //debug("H.264 SPS: video format %d\n", format);
} }
bs.skipBit(); // video_full_range_flag bs.skipBit(); // video_full_range_flag
bs.skipBit(); // video_full_range_flag
if (bs.getBit()) { // colour_description_present_flag if (bs.getBit()) { // colour_description_present_flag
bs.skipBits(8); // colour_primaries bs.skipBits(8); // colour_primaries
bs.skipBits(8); // transfer_characteristics bs.skipBits(8); // transfer_characteristics
@@ -308,8 +567,11 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
bs.skipUeGolomb(); // chroma_sample_loc_type_bottom_field bs.skipUeGolomb(); // chroma_sample_loc_type_bottom_field
} }
if (bs.getBit()) { // timing_info_present_flag if (bs.getBit()) { // timing_info_present_flag
bs.skipBits(32); // num_units_in_tick uint32_t num_units_in_tick, time_scale;
bs.skipBits(32); // time_scale num_units_in_tick = bs.getU32(); // num_units_in_tick
time_scale = bs.getU32(); // time_scale
if (num_units_in_tick > 0)
frame_rate = time_scale / num_units_in_tick;
bs.skipBit(); // fixed_frame_rate_flag bs.skipBit(); // fixed_frame_rate_flag
} }
int nal_hrd_parameters_present_flag = bs.getBit(); // nal_hrd_parameters_present_flag int nal_hrd_parameters_present_flag = bs.getBit(); // nal_hrd_parameters_present_flag
@@ -331,18 +593,18 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
int vlc_hrd_parameters_present_flag = bs.getBit(); // vlc_hrd_parameters_present_flag int vlc_hrd_parameters_present_flag = bs.getBit(); // vlc_hrd_parameters_present_flag
if (vlc_hrd_parameters_present_flag) { if (vlc_hrd_parameters_present_flag) {
int cpb_cnt_minus1; int cpb_cnt_minus1;
cpb_cnt_minus1 = bs.getUeGolomb(); // cpb_cnt_minus1 cpb_cnt_minus1 = bs.getUeGolomb(); // cpb_cnt_minus1
bs.skipBits(4); // bit_rate_scale bs.skipBits(4); // bit_rate_scale
bs.skipBits(4); // cpb_size_scale bs.skipBits(4); // cpb_size_scale
for (int i = 0; i < cpb_cnt_minus1; ++i) { for (int i = 0; i < cpb_cnt_minus1; ++i) {
bs.skipUeGolomb(); // bit_rate_value_minus1[i] bs.skipUeGolomb(); // bit_rate_value_minus1[i]
bs.skipUeGolomb(); // cpb_size_value_minus1[i] bs.skipUeGolomb(); // cpb_size_value_minus1[i]
bs.skipBit(); // cbr_flag[i] bs.skipBit(); // cbr_flag[i]
} }
bs.skipBits(5); // initial_cpb_removal_delay_length_minus1 bs.skipBits(5); // initial_cpb_removal_delay_length_minus1
bs.skipBits(5); // cpb_removal_delay_length_minus1 bs.skipBits(5); // cpb_removal_delay_length_minus1
bs.skipBits(5); // dpb_output_delay_length_minus1 bs.skipBits(5); // dpb_output_delay_length_minus1
time_offset_length = bs.getBits(5); // time_offset_length time_offset_length = bs.getBits(5);// time_offset_length
} }
cpb_dpb_delays_present_flag = (nal_hrd_parameters_present_flag | vlc_hrd_parameters_present_flag); cpb_dpb_delays_present_flag = (nal_hrd_parameters_present_flag | vlc_hrd_parameters_present_flag);
if (cpb_dpb_delays_present_flag) if (cpb_dpb_delays_present_flag)
@@ -363,8 +625,12 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
m_Height = height; m_Height = height;
m_AspectRatio = aspect_ratio; m_AspectRatio = aspect_ratio;
m_Format = format; m_Format = format;
m_FrameRate = frame_rate;
m_BitRate = bit_rate;
m_CpbDpbDelaysPresentFlag = cpb_dpb_delays_present_flag; m_CpbDpbDelaysPresentFlag = cpb_dpb_delays_present_flag;
m_PicStructPresentFlag = pic_struct_present_flag; m_PicStructPresentFlag = pic_struct_present_flag;
m_FrameMbsOnlyFlag = frame_mbs_only_flag;
m_MbAdaptiveFrameFieldFlag = mb_adaptive_frame_field_flag;
m_TimeOffsetLength = time_offset_length; m_TimeOffsetLength = time_offset_length;
return (bs.getIndex() / 8); return (bs.getIndex() / 8);
@@ -375,24 +641,20 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
int num_referenced_subseqs, i; int num_referenced_subseqs, i;
cBitStream bs(buf, len); cBitStream bs(buf, len);
double frame_rate = m_FrameRate;
double bit_rate = m_BitRate;
eVideoScan scan = m_Scan; eVideoScan scan = m_Scan;
while ((bs.getIndex() * 8 + 16) < len) { // sei_message while ((bs.getIndex() * 8 + 16) < len) { // sei_message
int lastByte, payloadSize = 0, payloadType = 0; int lastByte, payloadSize = 0, payloadType = 0;
// last_payload_type_byte
do { do {
lastByte = bs.getU8() & 0xFF; lastByte = bs.getU8() & 0xFF;
payloadType += lastByte; payloadType += lastByte;
} while (lastByte == 0xFF); } while (lastByte == 0xFF); // last_payload_type_byte
// last_payload_size_byte
do { do {
lastByte = bs.getU8() & 0xFF; lastByte = bs.getU8() & 0xFF;
payloadSize += lastByte; payloadSize += lastByte;
} while (lastByte == 0xFF); } while (lastByte == 0xFF); // last_payload_size_byte
switch (payloadType) { // sei_payload switch (payloadType) { // sei_payload
case 1: // pic_timing case 1: // pic_timing
@@ -400,10 +662,34 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
bs.skipUeGolomb(); // cpb_removal_delay bs.skipUeGolomb(); // cpb_removal_delay
bs.skipUeGolomb(); // dpb_output_delay bs.skipUeGolomb(); // dpb_output_delay
} }
if (m_PicStructPresentFlag) { // pic_struct_present_flag if (m_PicStructPresentFlag) { // pic_struct_present_flag
unsigned int pic_struct = bs.getBits(4); // pic_struct uint32_t pic_struct;
if (pic_struct >= (sizeof(s_SeiNumClockTsTable) ) / sizeof(s_SeiNumClockTsTable[0])) pic_struct = bs.getBits(4); // pic_struct
if (pic_struct >= (sizeof(s_SeiNumClockTsTable)) / sizeof(s_SeiNumClockTsTable[0]))
return 0; return 0;
if (m_FrameMbsOnlyFlag && !m_MbAdaptiveFrameFieldFlag)
scan = VIDEO_SCAN_PROGRESSIVE;
else {
switch (pic_struct) {
case 0: // frame
case 7: // frame doubling
case 8: // frame tripling
scan = VIDEO_SCAN_PROGRESSIVE;
break;
case 1: // top
case 2: // bottom
case 3: // top bottom
case 4: // bottom top
case 5: // top bottom top
case 6: // bottom top bottom
scan = VIDEO_SCAN_INTERLACED;
break;
default:
scan = VIDEO_SCAN_RESERVED;
break;
}
}
//debug("H.264 SEI: pic struct %d scan type %d\n", pic_struct, scan);
for (int i = 0; i < s_SeiNumClockTsTable[pic_struct]; ++i) { for (int i = 0; i < s_SeiNumClockTsTable[pic_struct]; ++i) {
if (bs.getBit()) { // clock_timestamp_flag[i] if (bs.getBit()) { // clock_timestamp_flag[i]
int full_timestamp_flag; int full_timestamp_flag;
@@ -421,7 +707,7 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
scan = VIDEO_SCAN_RESERVED; scan = VIDEO_SCAN_RESERVED;
break; break;
} }
//Dprintf("\nH.264 SEI: -> scan type %d", bit_rate, scan); //debug("H.264 SEI: scan type %d\n", scan);
bs.skipBit(); // nuit_field_based_flag bs.skipBit(); // nuit_field_based_flag
bs.skipBits(5); // counting_type bs.skipBits(5); // counting_type
full_timestamp_flag = bs.getBit(); // full_timestamp_flag full_timestamp_flag = bs.getBit(); // full_timestamp_flag
@@ -450,22 +736,21 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
} }
break; break;
case 12: // sub_seq_characteristics case 12: // sub_seq_characteristics
bs.skipUeGolomb(); // sub_seq_layer_num bs.skipUeGolomb(); // sub_seq_layer_num
bs.skipUeGolomb(); // sub_seq_id bs.skipUeGolomb(); // sub_seq_id
if (bs.getBit()) // duration_flag if (bs.getBit()) // duration_flag
bs.skipBits(32); // sub_seq_duration bs.skipBits(32); // sub_seq_duration
if (bs.getBit()) { // average_rate_flag if (bs.getBit()) { // average_rate_flag
bs.skipBit(); // accurate_statistics_flag bs.skipBit(); // accurate_statistics_flag
bit_rate = bs.getU16() / 1048.51; // average_bit_rate (1000 bit/s -> Mbit/s) bs.skipBits(16); // average_bit_rate (1000 bit/s)
frame_rate = bs.getU16() / 256.0; // average_frame_rate (frames/256s) bs.skipBits(16); // average_frame_rate (frames per 256s)
//Dprintf("\nH.264 SEI: -> stream bitrate %.1f, frame rate %.1f", bit_rate, frame_rate);
} }
num_referenced_subseqs = bs.getUeGolomb(); // num_referenced_subseqs num_referenced_subseqs = bs.getUeGolomb(); // num_referenced_subseqs
for (i = 0; i < num_referenced_subseqs; ++i) { for (i = 0; i < num_referenced_subseqs; ++i) {
bs.skipUeGolomb(); // ref_sub_seq_layer_num bs.skipUeGolomb(); // ref_sub_seq_layer_num
bs.skipUeGolomb(); // ref_sub_seq_id bs.skipUeGolomb(); // ref_sub_seq_id
bs.getBit(); // ref_sub_seq_direction bs.getBit(); // ref_sub_seq_direction
} }
break; break;
@@ -478,8 +763,6 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
bs.byteAlign(); bs.byteAlign();
} }
m_FrameRate = frame_rate;
m_BitRate = bit_rate;
m_Scan = scan; m_Scan = scan;
return (bs.getIndex() / 8); return (bs.getIndex() / 8);

View File

@@ -19,26 +19,40 @@ private:
NAL_END_SEQ = 0x0A // End of Sequence NAL_END_SEQ = 0x0A // End of Sequence
}; };
cFemonVideoIf *m_VideoHandler; typedef struct DAR {
unsigned int m_Width; eVideoAspectRatio dar;
unsigned int m_Height; int ratio;
} t_DAR;
typedef struct SAR {
int w;
int h;
} t_SAR;
cFemonVideoIf *m_VideoHandler;
uint32_t m_Width;
uint32_t m_Height;
eVideoAspectRatio m_AspectRatio; eVideoAspectRatio m_AspectRatio;
eVideoFormat m_Format; eVideoFormat m_Format;
double m_FrameRate; double m_FrameRate;
double m_BitRate; double m_BitRate;
eVideoScan m_Scan; eVideoScan m_Scan;
bool m_CpbDpbDelaysPresentFlag; bool m_CpbDpbDelaysPresentFlag;
bool m_PicStructPresentFlag; bool m_PicStructPresentFlag;
unsigned int m_TimeOffsetLength; bool m_FrameMbsOnlyFlag;
bool m_MbAdaptiveFrameFieldFlag;
uint32_t m_TimeOffsetLength;
void reset();
const uint8_t *nextStartCode(const uint8_t *start, const uint8_t *end); const uint8_t *nextStartCode(const uint8_t *start, const uint8_t *end);
int nalUnescape(uint8_t *dst, const uint8_t *src, int len); int nalUnescape(uint8_t *dst, const uint8_t *src, int len);
int parseSPS(const uint8_t *buf, int len); int parseSPS(const uint8_t *buf, int len);
int parseSEI(const uint8_t *buf, int len); int parseSEI(const uint8_t *buf, int len);
static const eVideoAspectRatio s_AspectRatios[]; static const t_SAR s_SAR[];
static const eVideoFormat s_VideoFormats[]; static const t_DAR s_DAR[];
static const uint8_t s_SeiNumClockTsTable[9]; static const eVideoFormat s_VideoFormats[];
static const uint8_t s_SeiNumClockTsTable[9];
public: public:
cFemonH264(cFemonVideoIf *videohandler); cFemonH264(cFemonVideoIf *videohandler);

112
femonlatm.c Normal file
View File

@@ -0,0 +1,112 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include "femontools.h"
#include "femonlatm.h"
unsigned int cFemonLATM::s_Bitrates[3][16] =
{
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III
};
unsigned int cFemonLATM::s_Samplerates[4] =
{
22050, 24000, 16000, -1
};
cFemonLATM::cFemonLATM(cFemonAudioIf *audiohandler)
: m_AudioHandler(audiohandler)
{
}
cFemonLATM::~cFemonLATM()
{
}
bool cFemonLATM::processAudio(const uint8_t *buf, int len)
{
cBitStream bs(buf, len * 8);
if (!m_AudioHandler)
return false;
// skip PES header
if (!PesLongEnough(len))
return false;
bs.skipBits(8 * PesPayloadOffset(buf));
// MPEG audio detection
if (bs.getBits(12) != 0x56E) // syncword
return false;
m_AudioHandler->SetAudioCodec(AUDIO_CODEC_LATM);
if (bs.getBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0
return true; // @todo: lower sampling frequencies support
int layer = 3 - bs.getBits(2); // layer: I=11, II=10, III=01
bs.skipBit(); // protection bit
int bit_rate_index = bs.getBits(4); // bitrate index
int sampling_frequency = bs.getBits(2); // sampling frequency
bs.skipBit(); // padding bit
bs.skipBit(); // private pid
int mode = bs.getBits(2); // mode
switch (mode) {
case 0:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO);
break;
case 1:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO);
break;
case 2:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL);
break;
case 3:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE);
break;
default:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID);
break;
}
if (layer == 3) {
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE);
}
else {
switch (bit_rate_index) {
case 0:
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE);
break;
case 0xF:
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED);
break;
default:
m_AudioHandler->SetAudioBitrate(1000 * s_Bitrates[layer][bit_rate_index]);
break;
}
}
switch (sampling_frequency) {
case 3:
m_AudioHandler->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED);
break;
default:
m_AudioHandler->SetAudioSamplingFrequency(s_Samplerates[sampling_frequency]);
break;
}
return true;
}

27
femonlatm.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef __FEMONLATM_H
#define __FEMONLATM_H
#include "femonaudio.h"
class cFemonLATM {
private:
cFemonAudioIf *m_AudioHandler;
static unsigned int s_Bitrates[3][16];
static unsigned int s_Samplerates[4];
public:
cFemonLATM(cFemonAudioIf *audiohandler);
virtual ~cFemonLATM();
bool processAudio(const uint8_t *buf, int len);
};
#endif //__FEMONLATM_H

View File

@@ -5,6 +5,10 @@
* *
*/ */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <ctype.h> #include <ctype.h>
#include <math.h> #include <math.h>
#include "femoncfg.h" #include "femoncfg.h"
@@ -24,6 +28,7 @@
#define OSDSPACING 5 #define OSDSPACING 5
#define OSDROUNDING 10 #define OSDROUNDING 10
#define IS_OSDROUNDING (femonConfig.skin == eFemonSkinElchi) #define IS_OSDROUNDING (femonConfig.skin == eFemonSkinElchi)
#define IS_OSDRESOLUTION(r1, r2) (abs(r1 - r2) < 20)
#define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset) #define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset)
#define OSDINFOWIN_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \ #define OSDINFOWIN_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \
(col == 3) ? int(round(OSDWIDTH * 0.51)) : \ (col == 3) ? int(round(OSDWIDTH * 0.51)) : \
@@ -62,12 +67,12 @@
#define OSDDRAWSTATUSBAR(value) \ #define OSDDRAWSTATUSBAR(value) \
if (value > 0) { \ if (value > 0) { \
value = OSDBARWIDTH(value); \ int barvalue = OSDBARWIDTH(value); \
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(femonConfig.redlimit), value), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrRed); \ m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(femonConfig.redlimit), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrRed); \
if (value > OSDBARWIDTH(femonConfig.redlimit)) \ if (barvalue > OSDBARWIDTH(femonConfig.redlimit)) \
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * femonConfig.greenlimit / 100), value), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrYellow); \ m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * femonConfig.greenlimit / 100), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrYellow); \
if (value > OSDBARWIDTH(femonConfig.greenlimit)) \ if (barvalue > OSDBARWIDTH(femonConfig.greenlimit)) \
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset) + 3, value, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrGreen); \ m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset) + 3, barvalue, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrGreen); \
} }
#define OSDDRAWSTATUSTITLEBAR(title) \ #define OSDDRAWSTATUSTITLEBAR(title) \
@@ -145,7 +150,7 @@ cFemonOsd *cFemonOsd::pInstance = NULL;
cFemonOsd *cFemonOsd::Instance(bool create) cFemonOsd *cFemonOsd::Instance(bool create)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
if ((pInstance == NULL) && create) if ((pInstance == NULL) && create)
{ {
pInstance = new cFemonOsd(); pInstance = new cFemonOsd();
@@ -165,39 +170,48 @@ cFemonOsd::cFemonOsd()
m_Number(0), m_Number(0),
m_OldNumber(0), m_OldNumber(0),
m_SNR(0), m_SNR(0),
m_SNRValid(false),
m_Signal(0), m_Signal(0),
m_SignalValid(false),
m_BER(0), m_BER(0),
m_BERValid(false),
m_UNC(0), m_UNC(0),
m_UNCValid(false),
m_FrontendStatusValid(false),
m_DisplayMode(femonConfig.displaymode), m_DisplayMode(femonConfig.displaymode),
m_OsdWidth(cOsd::OsdWidth()), m_OsdWidth(cOsd::OsdWidth() * (100 - femonConfig.downscale) / 100),
m_OsdHeight(cOsd::OsdHeight()), m_OsdHeight(cOsd::OsdHeight() * (100 - femonConfig.downscale) / 100),
m_OsdLeft(cOsd::OsdLeft() + (cOsd::OsdWidth() * femonConfig.downscale / 200)),
m_OsdTop(cOsd::OsdTop() + (cOsd::OsdHeight() * femonConfig.downscale / 200)),
m_InputTime(0), m_InputTime(0),
m_Sleep(), m_Sleep(),
m_Mutex() m_Mutex()
{ {
int tmp; int tmp;
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
memset(&m_FrontendStatus, 0, sizeof(m_FrontendStatus));
memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo));
m_SvdrpConnection.handle = -1; m_SvdrpConnection.handle = -1;
m_Font = cFont::CreateFont(Setup.FontSml, min(max(Setup.FontSmlSize, MINFONTSIZE), MAXFONTSIZE)); m_Font = cFont::CreateFont(Setup.FontSml, min(max(Setup.FontSmlSize, MINFONTSIZE), MAXFONTSIZE));
if (!m_Font || !m_Font->Height()) { if (!m_Font || !m_Font->Height()) {
m_Font = new cFemonDummyFont; m_Font = new cFemonDummyFont;
esyslog("ERROR: cFemonOsd::cFemonOsd() cannot create required font."); error("cFemonOsd::cFemonOsd() cannot create required font.");
} }
tmp = 5 * bmSymbol[SYMBOL_LOCK].Width() + 6 * OSDSPACING; tmp = 5 * bmSymbol[SYMBOL_LOCK].Width() + 6 * OSDSPACING;
if (OSDWIDTH < tmp) { if (OSDWIDTH < tmp) {
esyslog("ERROR: cFemonOsd::cFemonOsd() OSD width (%d) smaller than required (%d).", OSDWIDTH, tmp); error("cFemonOsd::cFemonOsd() OSD width (%d) smaller than required (%d).", OSDWIDTH, tmp);
OSDWIDTH = tmp; OSDWIDTH = tmp;
} }
tmp = OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT; tmp = OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT;
if (OSDHEIGHT < tmp) { if (OSDHEIGHT < tmp) {
esyslog("ERROR: cFemonOsd::cFemonOsd() OSD height (%d) smaller than required (%d).", OSDHEIGHT, tmp); error("cFemonOsd::cFemonOsd() OSD height (%d) smaller than required (%d).", OSDHEIGHT, tmp);
OSDHEIGHT = tmp; OSDHEIGHT = tmp;
} }
} }
cFemonOsd::~cFemonOsd(void) cFemonOsd::~cFemonOsd(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
m_Sleep.Signal(); m_Sleep.Signal();
if (Running()) if (Running())
Cancel(3); Cancel(3);
@@ -225,8 +239,6 @@ void cFemonOsd::DrawStatusWindow(void)
{ {
cMutexLock lock(&m_Mutex); cMutexLock lock(&m_Mutex);
cBitmap *bm = NULL; cBitmap *bm = NULL;
int snr = m_SNR / 655;
int signal = m_Signal / 655;
int offset = 0; int offset = 0;
int x = OSDWIDTH - OSDROUNDING; int x = OSDWIDTH - OSDROUNDING;
int y = 0; int y = 0;
@@ -247,6 +259,7 @@ void cFemonOsd::DrawStatusWindow(void)
case 5: bm = &bmSymbol[SYMBOL_FIVE]; break; case 5: bm = &bmSymbol[SYMBOL_FIVE]; break;
case 6: bm = &bmSymbol[SYMBOL_SIX]; break; case 6: bm = &bmSymbol[SYMBOL_SIX]; break;
case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break; case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break;
case 8: bm = &bmSymbol[SYMBOL_EIGHT]; break;
default: bm = &bmSymbol[SYMBOL_ZERO]; break; default: bm = &bmSymbol[SYMBOL_ZERO]; break;
} }
OSDDRAWSTATUSBM(OSDSPACING); OSDDRAWSTATUSBM(OSDSPACING);
@@ -261,6 +274,7 @@ void cFemonOsd::DrawStatusWindow(void)
case 5: bm = &bmSymbol[SYMBOL_FIVE]; break; case 5: bm = &bmSymbol[SYMBOL_FIVE]; break;
case 6: bm = &bmSymbol[SYMBOL_SIX]; break; case 6: bm = &bmSymbol[SYMBOL_SIX]; break;
case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break; case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break;
case 8: bm = &bmSymbol[SYMBOL_EIGHT]; break;
default: bm = &bmSymbol[SYMBOL_ZERO]; break; default: bm = &bmSymbol[SYMBOL_ZERO]; break;
} }
OSDDRAWSTATUSBM(OSDSPACING); OSDDRAWSTATUSBM(OSDSPACING);
@@ -278,6 +292,17 @@ void cFemonOsd::DrawStatusWindow(void)
OSDDRAWSTATUSBM(OSDSPACING); OSDDRAWSTATUSBM(OSDSPACING);
} }
if (m_Receiver) { if (m_Receiver) {
if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 1080))
bm = &bmSymbol[SYMBOL_FORMAT_1080];
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 720))
bm = &bmSymbol[SYMBOL_FORMAT_720];
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 576))
bm = &bmSymbol[SYMBOL_FORMAT_576];
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 480))
bm = &bmSymbol[SYMBOL_FORMAT_480];
else
bm = NULL;
OSDDRAWSTATUSBM(OSDSPACING);
switch (m_Receiver->VideoCodec()) { switch (m_Receiver->VideoCodec()) {
case VIDEO_CODEC_MPEG2: bm = &bmSymbol[SYMBOL_MPEG2]; break; case VIDEO_CODEC_MPEG2: bm = &bmSymbol[SYMBOL_MPEG2]; break;
case VIDEO_CODEC_H264: bm = &bmSymbol[SYMBOL_H264]; break; case VIDEO_CODEC_H264: bm = &bmSymbol[SYMBOL_H264]; break;
@@ -304,24 +329,30 @@ void cFemonOsd::DrawStatusWindow(void)
OSDDRAWSTATUSBM(OSDSPACING); OSDDRAWSTATUSBM(OSDSPACING);
} }
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSBAR(signal); if (m_SignalValid)
OSDDRAWSTATUSBAR(m_Signal / 655);
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSBAR(snr); if (m_SNRValid)
OSDDRAWSTATUSBAR(m_SNR / 655);
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("STR:", *cString::sprintf("%04x", m_Signal), *cString::sprintf("(%2d%%)", m_Signal / 655), "BER:", *cString::sprintf("%08x", m_BER), OSDDRAWSTATUSVALUES("STR:", m_SignalValid ? *cString::sprintf("%04x", m_Signal) : "", m_SignalValid ? *cString::sprintf("(%2d%%)", m_Signal / 655) : "",
*cString::sprintf("%s:", tr("Video")), *getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0))); "BER:", m_BERValid ? *cString::sprintf("%08x", m_BER) : "", *cString::sprintf("%s:", tr("Video")),
*getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0)));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("SNR:", *cString::sprintf("%04x", m_SNR), *cString::sprintf("(%2d%%)", m_SNR / 655), "UNC:", *cString::sprintf("%08x", m_UNC), OSDDRAWSTATUSVALUES("SNR:", m_SNRValid ? *cString::sprintf("%04x", m_SNR) : "", m_SNRValid ? *cString::sprintf("(%2d%%)", m_SNR / 655) : "",
"UNC:", m_UNCValid ? *cString::sprintf("%08x", m_UNC) : "",
*cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")), *cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")),
*getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0))); *getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0)));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
x = bmSymbol[SYMBOL_LOCK].Width(); x = bmSymbol[SYMBOL_LOCK].Width();
y = (OSDROWHEIGHT - bmSymbol[SYMBOL_LOCK].Height()) / 2; y = (OSDROWHEIGHT - bmSymbol[SYMBOL_LOCK].Height()) / 2;
OSDDRAWSTATUSFRONTEND(1, bmSymbol[SYMBOL_LOCK], FE_HAS_LOCK); if (m_FrontendStatusValid) {
OSDDRAWSTATUSFRONTEND(2, bmSymbol[SYMBOL_SIGNAL], FE_HAS_SIGNAL); OSDDRAWSTATUSFRONTEND(1, bmSymbol[SYMBOL_LOCK], FE_HAS_LOCK);
OSDDRAWSTATUSFRONTEND(3, bmSymbol[SYMBOL_CARRIER], FE_HAS_CARRIER); OSDDRAWSTATUSFRONTEND(2, bmSymbol[SYMBOL_SIGNAL], FE_HAS_SIGNAL);
OSDDRAWSTATUSFRONTEND(4, bmSymbol[SYMBOL_VITERBI], FE_HAS_VITERBI); OSDDRAWSTATUSFRONTEND(3, bmSymbol[SYMBOL_CARRIER], FE_HAS_CARRIER);
OSDDRAWSTATUSFRONTEND(5, bmSymbol[SYMBOL_SYNC], FE_HAS_SYNC); OSDDRAWSTATUSFRONTEND(4, bmSymbol[SYMBOL_VITERBI], FE_HAS_VITERBI);
OSDDRAWSTATUSFRONTEND(5, bmSymbol[SYMBOL_SYNC], FE_HAS_SYNC);
}
OSDDRAWSTATUSBOTTOMBAR(); OSDDRAWSTATUSBOTTOMBAR();
m_Osd->Flush(); m_Osd->Flush();
} }
@@ -335,6 +366,7 @@ void cFemonOsd::DrawInfoWindow(void)
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
if (m_Osd && channel) { if (m_Osd && channel) {
cDvbTransponderParameters dtp(channel->Parameters());
switch (m_DisplayMode) { switch (m_DisplayMode) {
case eFemonModeTransponder: case eFemonModeTransponder:
OSDDRAWINFOTITLEBAR(tr("Transponder Information")); OSDDRAWINFOTITLEBAR(tr("Transponder Information"));
@@ -364,13 +396,13 @@ void cFemonOsd::DrawInfoWindow(void)
OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate()));
OSDDRAWINFORIGHT(trVDR("Polarization"), *cString::sprintf("%c", toupper(channel->Polarization()))); OSDDRAWINFORIGHT(trVDR("Polarization"), *cString::sprintf("%c", toupper(dtp.Polarization())));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion()));
OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(channel->CoderateH())); OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("System"), *getSystem(channel->System())); OSDDRAWINFOLEFT( trVDR("System"), *getSystem(dtp.System()));
OSDDRAWINFORIGHT(trVDR("RollOff"), *getRollOff(channel->RollOff())); OSDDRAWINFORIGHT(trVDR("RollOff"), *getRollOff(dtp.RollOff()));
break; break;
case cSource::stCable: case cSource::stCable:
@@ -380,26 +412,26 @@ void cFemonOsd::DrawInfoWindow(void)
OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate()));
OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(channel->Modulation())); OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion()));
OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(channel->CoderateH())); OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH()));
break; break;
case cSource::stTerr: case cSource::stTerr:
OSDDRAWINFOLINE(*cString::sprintf("DVB-T #%d - %s", (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); OSDDRAWINFOLINE(*cString::sprintf("DVB-T #%d - %s", (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency()));
OSDDRAWINFORIGHT(trVDR("Transmission"), *getTransmission(channel->Transmission())); OSDDRAWINFORIGHT(trVDR("Transmission"), *getTransmission(dtp.Transmission()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Bandwidth"), *getBandwidth(channel->Bandwidth())); OSDDRAWINFOLEFT( trVDR("Bandwidth"), *getBandwidth(dtp.Bandwidth()));
OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(channel->Modulation())); OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion()));
OSDDRAWINFORIGHT(tr ("Coderate"), *cString::sprintf("%s (H) %s (L)", *getCoderate(channel->CoderateH()), *getCoderate(channel->CoderateL()))); OSDDRAWINFORIGHT(tr ("Coderate"), *cString::sprintf("%s (H) %s (L)", *getCoderate(dtp.CoderateH()), *getCoderate(dtp.CoderateL())));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOLEFT( trVDR("Hierarchy"), *getHierarchy(channel->Hierarchy())); OSDDRAWINFOLEFT( trVDR("Hierarchy"), *getHierarchy(dtp.Hierarchy()));
OSDDRAWINFORIGHT(trVDR("Guard"), *getGuard(channel->Guard())); OSDDRAWINFORIGHT(trVDR("Guard"), *getGuard(dtp.Guard()));
break; break;
default: default:
@@ -474,7 +506,7 @@ void cFemonOsd::DrawInfoWindow(void)
void cFemonOsd::Action(void) void cFemonOsd::Action(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
cTimeMs t; cTimeMs t;
SvdrpCommand_v1_0 cmd; SvdrpCommand_v1_0 cmd;
cmd.command = cString::sprintf("PLUG %s INFO\r\n", PLUGIN_NAME_I18N); cmd.command = cString::sprintf("PLUG %s INFO\r\n", PLUGIN_NAME_I18N);
@@ -484,11 +516,11 @@ void cFemonOsd::Action(void)
m_SvdrpVideoBitrate = -1.0; m_SvdrpVideoBitrate = -1.0;
m_SvdrpAudioBitrate = -1.0; m_SvdrpAudioBitrate = -1.0;
if (m_Frontend != -1) { if (m_Frontend != -1) {
CHECK(ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus)); m_FrontendStatusValid = (ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus) >= 0);
CHECK(ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal)); m_SignalValid = (ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal) >= 0);
CHECK(ioctl(m_Frontend, FE_READ_SNR, &m_SNR)); m_SNRValid = (ioctl(m_Frontend, FE_READ_SNR, &m_SNR) >= 0);
CHECK(ioctl(m_Frontend, FE_READ_BER, &m_BER)); m_BERValid = (ioctl(m_Frontend, FE_READ_BER, &m_BER) >= 0);
CHECK(ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC)); m_UNCValid = (ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC) >= 0);
DrawInfoWindow(); DrawInfoWindow();
DrawStatusWindow(); DrawStatusWindow();
} }
@@ -496,24 +528,40 @@ void cFemonOsd::Action(void)
cmd.handle = m_SvdrpConnection.handle; cmd.handle = m_SvdrpConnection.handle;
m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd);
if (cmd.responseCode == 900) { if (cmd.responseCode == 900) {
m_FrontendStatusValid = false;
m_SignalValid = false;
m_SNRValid = false;
m_BERValid = false;
m_UNCValid = false;
for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) { for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) {
const char *s = line->Text(); const char *s = line->Text();
if (!strncasecmp(s, "CARD:", 5)) if (!strncasecmp(s, "CARD:", 5))
m_SvdrpFrontend = (int)strtol(s + 5, NULL, 10); m_SvdrpFrontend = (int)strtol(s + 5, NULL, 10);
else if (!strncasecmp(s, "TYPE:", 5)) else if (!strncasecmp(s, "TYPE:", 5))
m_FrontendInfo.type = (fe_type_t)strtol(s + 5, NULL, 10); m_FrontendInfo.type = (fe_type_t)strtol(s + 5, NULL, 10);
else if (!strncasecmp(s, "NAME:", 5)) else if (!strncasecmp(s, "NAME:", 5)) {
strn0cpy(m_FrontendInfo.name, s + 5, sizeof(m_FrontendInfo.name)); strn0cpy(m_FrontendInfo.name, s + 5, sizeof(m_FrontendInfo.name));
else if (!strncasecmp(s, "STAT:", 5)) }
else if (!strncasecmp(s, "STAT:", 5)) {
m_FrontendStatus = (fe_status_t)strtol(s + 5, NULL, 16); m_FrontendStatus = (fe_status_t)strtol(s + 5, NULL, 16);
else if (!strncasecmp(s, "SGNL:", 5)) m_FrontendStatusValid = true;
}
else if (!strncasecmp(s, "SGNL:", 5)) {
m_Signal = (uint16_t)strtol(s + 5, NULL, 16); m_Signal = (uint16_t)strtol(s + 5, NULL, 16);
else if (!strncasecmp(s, "SNRA:", 5)) m_SignalValid = true;
}
else if (!strncasecmp(s, "SNRA:", 5)) {
m_SNR = (uint16_t)strtol(s + 5, NULL, 16); m_SNR = (uint16_t)strtol(s + 5, NULL, 16);
else if (!strncasecmp(s, "BERA:", 5)) m_SNRValid = true;
}
else if (!strncasecmp(s, "BERA:", 5)) {
m_BER = (uint32_t)strtol(s + 5, NULL, 16); m_BER = (uint32_t)strtol(s + 5, NULL, 16);
else if (!strncasecmp(s, "UNCB:", 5)) m_BERValid = true;
}
else if (!strncasecmp(s, "UNCB:", 5)) {
m_UNC = (uint32_t)strtol(s + 5, NULL, 16); m_UNC = (uint32_t)strtol(s + 5, NULL, 16);
m_UNCValid = true;
}
else if (!strncasecmp(s, "VIBR:", 5)) else if (!strncasecmp(s, "VIBR:", 5))
m_SvdrpVideoBitrate = (double)strtol(s + 5, NULL, 10); m_SvdrpVideoBitrate = (double)strtol(s + 5, NULL, 10);
else if (!strncasecmp(s, "AUBR:", 5)) else if (!strncasecmp(s, "AUBR:", 5))
@@ -529,17 +577,17 @@ void cFemonOsd::Action(void)
void cFemonOsd::Show(void) void cFemonOsd::Show(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
int apid[2] = {0, 0};
int dpid[2] = {0, 0};
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
cString dev = cString::sprintf(FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); cString dev = cString::sprintf(FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0);
m_Frontend = open(dev, O_RDONLY | O_NONBLOCK); m_Frontend = open(dev, O_RDONLY | O_NONBLOCK);
if (m_Frontend >= 0) { if (m_Frontend >= 0) {
if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) { if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) {
esyslog("ERROR: cFemonOsd::Show() cannot read frontend info."); if (!femonConfig.usesvdrp)
error("cFemonOsd::Show() cannot read frontend info.");
close(m_Frontend); close(m_Frontend);
m_Frontend = -1; m_Frontend = -1;
memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo));
return; return;
} }
} }
@@ -548,11 +596,11 @@ void cFemonOsd::Show(void)
return; return;
} }
else { else {
esyslog("ERROR: cFemonOsd::Show() cannot open frontend device."); error("cFemonOsd::Show() cannot open frontend device.");
return; return;
} }
m_Osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop()); m_Osd = cOsdProvider::NewOsd(m_OsdLeft, m_OsdTop);
if (m_Osd) { if (m_Osd) {
tArea Areas1[] = { { 0, 0, OSDWIDTH - 1, OSDHEIGHT - 1, 8 } }; tArea Areas1[] = { { 0, 0, OSDWIDTH - 1, OSDHEIGHT - 1, 8 } };
if (Setup.AntiAlias && m_Osd->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) { if (Setup.AntiAlias && m_Osd->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) {
@@ -574,9 +622,7 @@ void cFemonOsd::Show(void)
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
IS_AUDIO_TRACK(track) ? apid[0] = channel->Apid(int(track - ttAudioFirst)) : apid[0] = channel->Apid(0); m_Receiver = new cFemonReceiver(channel->Vtype(), channel->Vpid(), channel->Apid(IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0), channel->Dpid(IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0));
IS_DOLBY_TRACK(track) ? dpid[0] = channel->Dpid(int(track - ttDolbyFirst)) : dpid[0] = channel->Dpid(0);
m_Receiver = new cFemonReceiver(channel->GetChannelID(), channel->Ca(), channel->Vtype(), channel->Vpid(), apid, dpid);
cDevice::ActualDevice()->AttachReceiver(m_Receiver); cDevice::ActualDevice()->AttachReceiver(m_Receiver);
} }
} }
@@ -586,9 +632,7 @@ void cFemonOsd::Show(void)
void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber) void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
{ {
Dprintf("%s(%d,%d)\n", __PRETTY_FUNCTION__, device->DeviceNumber(), channelNumber); debug("%s(%d,%d)\n", __PRETTY_FUNCTION__, device->DeviceNumber(), channelNumber);
int apid[2] = {0, 0};
int dpid[2] = {0, 0};
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
if (!device->IsPrimaryDevice() || !channelNumber || cDevice::PrimaryDevice()->CurrentChannel() != channelNumber) if (!device->IsPrimaryDevice() || !channelNumber || cDevice::PrimaryDevice()->CurrentChannel() != channelNumber)
return; return;
@@ -597,9 +641,11 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
m_Frontend = open(dev, O_RDONLY | O_NONBLOCK); m_Frontend = open(dev, O_RDONLY | O_NONBLOCK);
if (m_Frontend >= 0) { if (m_Frontend >= 0) {
if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) { if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) {
esyslog("ERROR: cFemonOsd::ChannelSwitch() cannot read frontend info."); if (!femonConfig.usesvdrp)
error("cFemonOsd::ChannelSwitch() cannot read frontend info.");
close(m_Frontend); close(m_Frontend);
m_Frontend = -1; m_Frontend = -1;
memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo));
return; return;
} }
} }
@@ -608,7 +654,7 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
return; return;
} }
else { else {
esyslog("ERROR: cFemonOsd::ChannelSwitch() cannot open frontend device."); error("cFemonOsd::ChannelSwitch() cannot open frontend device.");
return; return;
} }
@@ -619,9 +665,7 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
IS_AUDIO_TRACK(track) ? apid[0] = channel->Apid(int(track - ttAudioFirst)) : apid[0] = channel->Apid(0); m_Receiver = new cFemonReceiver(channel->Vtype(), channel->Vpid(), channel->Apid(IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0), channel->Dpid(IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0));
IS_DOLBY_TRACK(track) ? dpid[0] = channel->Dpid(int(track - ttDolbyFirst)) : dpid[0] = channel->Dpid(0);
m_Receiver = new cFemonReceiver(channel->GetChannelID(), channel->Ca(), channel->Vtype(), channel->Vpid(), apid, dpid);
cDevice::ActualDevice()->AttachReceiver(m_Receiver); cDevice::ActualDevice()->AttachReceiver(m_Receiver);
} }
} }
@@ -629,9 +673,7 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks) void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
int apid[2] = {0, 0};
int dpid[2] = {0, 0};
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
if (m_Receiver) { if (m_Receiver) {
m_Receiver->Deactivate(); m_Receiver->Deactivate();
@@ -640,9 +682,7 @@ void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks)
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
IS_AUDIO_TRACK(track) ? apid[0] = channel->Apid(int(track - ttAudioFirst)) : apid[0] = channel->Apid(0); m_Receiver = new cFemonReceiver(channel->Vtype(), channel->Vpid(), channel->Apid(IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0), channel->Dpid(IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0));
IS_DOLBY_TRACK(track) ? dpid[0] = channel->Dpid(int(track - ttDolbyFirst)) : dpid[0] = channel->Dpid(0);
m_Receiver = new cFemonReceiver(channel->GetChannelID(), channel->Ca(), channel->Vtype(), channel->Vpid(), apid, dpid);
cDevice::ActualDevice()->AttachReceiver(m_Receiver); cDevice::ActualDevice()->AttachReceiver(m_Receiver);
} }
} }
@@ -650,14 +690,14 @@ void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks)
bool cFemonOsd::DeviceSwitch(int direction) bool cFemonOsd::DeviceSwitch(int direction)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
int device = cDevice::ActualDevice()->DeviceNumber(); int device = cDevice::ActualDevice()->DeviceNumber();
direction = sgn(direction); direction = sgn(direction);
if (device >= 0) { if (device >= 0) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
for (int i = 0; i < cDevice::NumDevices() - 1; i++) { for (int i = 0; i < cDevice::NumDevices() - 1; i++) {
if (direction) { if (direction >= 0) {
if (++device >= cDevice::NumDevices()) if (++device >= cDevice::NumDevices())
device = 0; device = 0;
} }
@@ -666,13 +706,13 @@ bool cFemonOsd::DeviceSwitch(int direction)
device = cDevice::NumDevices() - 1; device = cDevice::NumDevices() - 1;
} }
if (cDevice::GetDevice(device)->ProvidesChannel(channel, 0)) { if (cDevice::GetDevice(device)->ProvidesChannel(channel, 0)) {
Dprintf("%s(%d) device(%d)\n", __PRETTY_FUNCTION__, direction, device); debug("%s(%d) device(%d)\n", __PRETTY_FUNCTION__, direction, device);
cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), 0); cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), 0);
cControl::Shutdown(); cControl::Shutdown();
cDevice::GetDevice(device)->SwitchChannel(channel, true); cDevice::GetDevice(device)->SwitchChannel(channel, true);
if (cDevice::GetDevice(device) == cDevice::PrimaryDevice()) if (cDevice::GetDevice(device) == cDevice::PrimaryDevice())
cDevice::GetDevice(device)->ForceTransferMode(); cDevice::GetDevice(device)->ForceTransferMode();
cControl::Launch(new cTransferControl(cDevice::GetDevice(device), channel->GetChannelID(), channel->Vpid(), channel->Apids(), channel->Dpids(), channel->Spids())); cControl::Launch(new cTransferControl(cDevice::GetDevice(device), channel));
cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), channel->Number()); cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), channel->Number());
return (true); return (true);
} }
@@ -698,14 +738,14 @@ bool cFemonOsd::SvdrpConnect(void)
m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd);
if (cmd.responseCode != 214) { if (cmd.responseCode != 214) {
m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); // close connection m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); // close connection
esyslog("ERROR: cFemonOsd::SvdrpConnect() cannot find plugin '%s' on server %s.", PLUGIN_NAME_I18N, *m_SvdrpConnection.serverIp); error("cFemonOsd::SvdrpConnect() cannot find plugin '%s' on server %s.", PLUGIN_NAME_I18N, *m_SvdrpConnection.serverIp);
} }
} }
else else
esyslog("ERROR: cFemonOsd::SvdrpConnect() cannot connect to SVDRP server."); error("cFemonOsd::SvdrpConnect() cannot connect to SVDRP server.");
} }
else else
esyslog("ERROR: cFemonOsd::SvdrpConnect() cannot find plugin '%s'.", SVDRPPLUGIN); error("cFemonOsd::SvdrpConnect() cannot find plugin '%s'.", SVDRPPLUGIN);
} }
return m_SvdrpConnection.handle >= 0; return m_SvdrpConnection.handle >= 0;
} }
@@ -721,19 +761,19 @@ bool cFemonOsd::SvdrpTune(void)
m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd);
if (cmd.responseCode == 250) if (cmd.responseCode == 250)
return true; return true;
esyslog("ERROR: cFemonOsd::SvdrpTune() cannot tune server channel."); error("cFemonOsd::SvdrpTune() cannot tune server channel.");
} }
else else
esyslog("ERROR: cFemonOsd::SvdrpTune() invalid channel."); error("cFemonOsd::SvdrpTune() invalid channel.");
} }
else else
esyslog("ERROR: cFemonOsd::SvdrpTune() unexpected connection state."); error("cFemonOsd::SvdrpTune() unexpected connection state.");
return false; return false;
} }
double cFemonOsd::GetVideoBitrate(void) double cFemonOsd::GetVideoBitrate(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
double value = 0.0; double value = 0.0;
if (m_Receiver) if (m_Receiver)
@@ -744,7 +784,7 @@ double cFemonOsd::GetVideoBitrate(void)
double cFemonOsd::GetAudioBitrate(void) double cFemonOsd::GetAudioBitrate(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
double value = 0.0; double value = 0.0;
if (m_Receiver) if (m_Receiver)
@@ -755,7 +795,7 @@ double cFemonOsd::GetAudioBitrate(void)
double cFemonOsd::GetDolbyBitrate(void) double cFemonOsd::GetDolbyBitrate(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
double value = 0.0; double value = 0.0;
if (m_Receiver) if (m_Receiver)

View File

@@ -34,17 +34,24 @@ private:
double m_SvdrpAudioBitrate; double m_SvdrpAudioBitrate;
SvdrpConnection_v1_0 m_SvdrpConnection; SvdrpConnection_v1_0 m_SvdrpConnection;
cPlugin *m_SvdrpPlugin; cPlugin *m_SvdrpPlugin;
dvb_frontend_info m_FrontendInfo;
int m_Number; int m_Number;
int m_OldNumber; int m_OldNumber;
uint16_t m_SNR; uint16_t m_SNR;
bool m_SNRValid;
uint16_t m_Signal; uint16_t m_Signal;
bool m_SignalValid;
uint32_t m_BER; uint32_t m_BER;
bool m_BERValid;
uint32_t m_UNC; uint32_t m_UNC;
bool m_UNCValid;
fe_status_t m_FrontendStatus; fe_status_t m_FrontendStatus;
bool m_FrontendStatusValid;
dvb_frontend_info m_FrontendInfo;
int m_DisplayMode; int m_DisplayMode;
int m_OsdWidth; int m_OsdWidth;
int m_OsdHeight; int m_OsdHeight;
int m_OsdLeft;
int m_OsdTop;
cFont *m_Font; cFont *m_Font;
cTimeMs m_InputTime; cTimeMs m_InputTime;
cCondWait m_Sleep; cCondWait m_Sleep;

View File

@@ -10,30 +10,42 @@
#include "femoncfg.h" #include "femoncfg.h"
#include "femonreceiver.h" #include "femonreceiver.h"
cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid, int Apid[], int Dpid[]) cFemonReceiver::cFemonReceiver(int Vtype, int Vpid, int Apid, int Dpid)
: cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL), : cThread("femon receiver"),
cThread("femon receiver"), m_Mutex(),
m_Sleep(), m_Sleep(),
m_Active(false), m_Active(false),
m_DetectH264(this), m_DetectH264(this),
m_DetectMPEG(this, this), m_DetectMPEG(this, this),
m_DetectAAC(this), m_DetectAAC(this),
m_DetectLATM(this),
m_DetectAC3(this), m_DetectAC3(this),
m_VideoBuffer(KILOBYTE(512), TS_SIZE, false, "Femon video"),
m_VideoType(Vtype), m_VideoType(Vtype),
m_VideoPid(Vpid), m_VideoPid(Vpid),
m_VideoPacketCount(0), m_VideoPacketCount(0),
m_VideoBitrate(0.0), m_VideoBitrate(0.0),
m_VideoValid(false), m_VideoValid(false),
m_AudioPid(Apid[0]), m_AudioBuffer(KILOBYTE(256), TS_SIZE, false, "Femon audio"),
m_AudioPid(Apid),
m_AudioPacketCount(0), m_AudioPacketCount(0),
m_AudioBitrate(0.0), m_AudioBitrate(0.0),
m_AudioValid(false), m_AudioValid(false),
m_AC3Pid(Dpid[0]), m_AC3Buffer(KILOBYTE(256), TS_SIZE, false, "Femon AC3"),
m_AC3Pid(Dpid),
m_AC3PacketCount(0), m_AC3PacketCount(0),
m_AC3Bitrate(0), m_AC3Bitrate(0),
m_AC3Valid(false) m_AC3Valid(false)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
AddPid(m_VideoPid);
AddPid(m_AudioPid);
AddPid(m_AC3Pid);
m_VideoBuffer.SetTimeouts(0, 100);
m_AudioBuffer.SetTimeouts(0, 100);
m_AC3Buffer.SetTimeouts(0, 100);
m_VideoInfo.codec = VIDEO_CODEC_INVALID; m_VideoInfo.codec = VIDEO_CODEC_INVALID;
m_VideoInfo.format = VIDEO_FORMAT_INVALID; m_VideoInfo.format = VIDEO_FORMAT_INVALID;
@@ -60,13 +72,13 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid
cFemonReceiver::~cFemonReceiver(void) cFemonReceiver::~cFemonReceiver(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
Deactivate(); Deactivate();
} }
void cFemonReceiver::Deactivate(void) void cFemonReceiver::Deactivate(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
if (m_Active) { if (m_Active) {
m_Active = false; m_Active = false;
m_Sleep.Signal(); m_Sleep.Signal();
@@ -78,7 +90,7 @@ void cFemonReceiver::Deactivate(void)
void cFemonReceiver::Activate(bool On) void cFemonReceiver::Activate(bool On)
{ {
Dprintf("%s(%d)\n", __PRETTY_FUNCTION__, On); debug("%s(%d)\n", __PRETTY_FUNCTION__, On);
if (On) if (On)
Start(); Start();
else else
@@ -88,64 +100,149 @@ void cFemonReceiver::Activate(bool On)
void cFemonReceiver::Receive(uchar *Data, int Length) void cFemonReceiver::Receive(uchar *Data, int Length)
{ {
// TS packet length: TS_SIZE // TS packet length: TS_SIZE
if (Length == TS_SIZE) { if (Running() && (*Data == TS_SYNC_BYTE) && (Length == TS_SIZE)) {
int len, pid = TsPid(Data); int len, pid = TsPid(Data);
if (pid == m_VideoPid) { if (pid == m_VideoPid) {
m_VideoPacketCount++; ++m_VideoPacketCount;
if (TsPayloadStart(Data)) { len = m_VideoBuffer.Put(Data, Length);
while (const uint8_t *p = m_VideoAssembler.GetPes(len)) { if (len != Length) {
if (m_VideoType == 0x1B) { // MPEG4 m_VideoBuffer.ReportOverflow(Length - len);
if (m_DetectH264.processVideo(p, len)) { m_VideoBuffer.Clear();
m_VideoValid = true; }
break;
}
}
else {
if (m_DetectMPEG.processVideo(p, len)) {
m_VideoValid = true;
break;
}
}
}
m_VideoAssembler.Reset();
}
m_VideoAssembler.PutTs(Data, Length);
} }
else if (pid == m_AudioPid) { else if (pid == m_AudioPid) {
m_AudioPacketCount++; ++m_AudioPacketCount;
if (const uint8_t *p = m_AudioAssembler.GetPes(len)) { len = m_AudioBuffer.Put(Data, Length);
if (m_DetectAAC.processAudio(p, len) || m_DetectMPEG.processAudio(p, len)) if (len != Length) {
m_AudioValid = true; m_AudioBuffer.ReportOverflow(Length - len);
m_AudioAssembler.Reset(); m_AudioBuffer.Clear();
} }
m_AudioAssembler.PutTs(Data, Length);
} }
else if (pid == m_AC3Pid) { else if (pid == m_AC3Pid) {
m_AC3PacketCount++; ++m_AC3PacketCount;
if (const uint8_t *p = m_AC3Assembler.GetPes(len)) { len = m_AC3Buffer.Put(Data, Length);
if (m_DetectAC3.processAudio(p, len)) if (len != Length) {
m_AC3Valid = true; m_AC3Buffer.ReportOverflow(Length - len);
m_AC3Assembler.Reset(); m_AC3Buffer.Clear();
} }
m_AC3Assembler.PutTs(Data, Length);
} }
} }
} }
void cFemonReceiver::Action(void) void cFemonReceiver::Action(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); debug("%s()\n", __PRETTY_FUNCTION__);
cTimeMs t; cTimeMs calcPeriod(0);
m_Active = true; m_Active = true;
while (Running() && m_Active) { while (Running() && m_Active) {
t.Set(0); uint8_t *Data;
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit double timeout;
m_VideoBitrate = (10.0 * 8.0 * 184.0 * m_VideoPacketCount) / femonConfig.calcinterval; int len, Length;
m_VideoPacketCount = 0; bool processed = false;
m_AudioBitrate = (10.0 * 8.0 * 184.0 * m_AudioPacketCount) / femonConfig.calcinterval;
m_AudioPacketCount = 0; // process available video data
m_AC3Bitrate = (10.0 * 8.0 * 184.0 * m_AC3PacketCount) / femonConfig.calcinterval; while (Data = m_VideoBuffer.Get(Length)) {
m_AC3PacketCount = 0; if (!m_Active || (Length < TS_SIZE))
m_Sleep.Wait(max((int)(100 * femonConfig.calcinterval - t.Elapsed()), 3)); break;
Length = TS_SIZE;
if (*Data != TS_SYNC_BYTE) {
for (int i = 1; i < Length; ++i) {
if (Data[i] == TS_SYNC_BYTE) {
Length = i;
break;
}
}
m_VideoBuffer.Del(Length);
continue;
}
processed = true;
if (TsPayloadStart(Data)) {
while (const uint8_t *p = m_VideoAssembler.GetPes(len)) {
if (m_VideoType == 0x1B) { // MPEG4
if (m_DetectH264.processVideo(p, len)) {
m_VideoValid = true;
break;
}
}
else {
if (m_DetectMPEG.processVideo(p, len)) {
m_VideoValid = true;
break;
}
}
}
m_VideoAssembler.Reset();
}
m_VideoAssembler.PutTs(Data, Length);
m_VideoBuffer.Del(Length);
}
// process available audio data
while (Data = m_AudioBuffer.Get(Length)) {
if (!m_Active || (Length < TS_SIZE))
break;
Length = TS_SIZE;
if (*Data != TS_SYNC_BYTE) {
for (int i = 1; i < Length; ++i) {
if (Data[i] == TS_SYNC_BYTE) {
Length = i;
break;
}
}
m_AudioBuffer.Del(Length);
continue;
}
processed = true;
if (const uint8_t *p = m_AudioAssembler.GetPes(len)) {
if (m_DetectAAC.processAudio(p, len) || m_DetectLATM.processAudio(p, len) || m_DetectMPEG.processAudio(p, len))
m_AudioValid = true;
m_AudioAssembler.Reset();
}
m_AudioAssembler.PutTs(Data, Length);
m_AudioBuffer.Del(Length);
}
// process available dolby data
while (Data = m_AC3Buffer.Get(Length)) {
if (!m_Active || (Length < TS_SIZE))
break;
Length = TS_SIZE;
if (*Data != TS_SYNC_BYTE) {
for (int i = 1; i < Length; ++i) {
if (Data[i] == TS_SYNC_BYTE) {
Length = i;
break;
}
}
m_AC3Buffer.Del(Length);
continue;
}
processed = true;
if (const uint8_t *p = m_AC3Assembler.GetPes(len)) {
if (m_DetectAC3.processAudio(p, len))
m_AC3Valid = true;
m_AC3Assembler.Reset();
}
m_AC3Assembler.PutTs(Data, Length);
m_AC3Buffer.Del(Length);
}
// calculate bitrates
timeout = double(calcPeriod.Elapsed());
if (m_Active && (timeout >= (100.0 * femonConfig.calcinterval))) {
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
// PES headers should be compensated!
m_VideoBitrate = (1000.0 * 8.0 * 184.0 * m_VideoPacketCount) / timeout;
m_VideoPacketCount = 0;
m_AudioBitrate = (1000.0 * 8.0 * 184.0 * m_AudioPacketCount) / timeout;
m_AudioPacketCount = 0;
m_AC3Bitrate = (1000.0 * 8.0 * 184.0 * m_AC3PacketCount) / timeout;
m_AC3PacketCount = 0;
calcPeriod.Set(0);
}
if (!processed)
m_Sleep.Wait(10); // to avoid busy loop and reduce cpu load
} }
} }

View File

@@ -14,6 +14,7 @@
#include "femonh264.h" #include "femonh264.h"
#include "femonmpeg.h" #include "femonmpeg.h"
#include "femonaac.h" #include "femonaac.h"
#include "femonlatm.h"
#include "femonac3.h" #include "femonac3.h"
#include "femonaudio.h" #include "femonaudio.h"
#include "femonvideo.h" #include "femonvideo.h"
@@ -21,35 +22,40 @@
class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If { class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If {
private: private:
cCondWait m_Sleep; cMutex m_Mutex;
bool m_Active; cCondWait m_Sleep;
bool m_Active;
cFemonH264 m_DetectH264; cFemonH264 m_DetectH264;
cFemonMPEG m_DetectMPEG; cFemonMPEG m_DetectMPEG;
cFemonAAC m_DetectAAC; cFemonAAC m_DetectAAC;
cFemonAC3 m_DetectAC3; cFemonLATM m_DetectLATM;
cFemonAC3 m_DetectAC3;
cTsToPes m_VideoAssembler; cRingBufferLinear m_VideoBuffer;
int m_VideoType; cTsToPes m_VideoAssembler;
int m_VideoPid; int m_VideoType;
int m_VideoPacketCount; int m_VideoPid;
double m_VideoBitrate; int m_VideoPacketCount;
bool m_VideoValid; double m_VideoBitrate;
video_info_t m_VideoInfo; bool m_VideoValid;
video_info_t m_VideoInfo;
cTsToPes m_AudioAssembler; cRingBufferLinear m_AudioBuffer;
int m_AudioPid; cTsToPes m_AudioAssembler;
int m_AudioPacketCount; int m_AudioPid;
double m_AudioBitrate; int m_AudioPacketCount;
bool m_AudioValid; double m_AudioBitrate;
audio_info_t m_AudioInfo; bool m_AudioValid;
audio_info_t m_AudioInfo;
cTsToPes m_AC3Assembler; cRingBufferLinear m_AC3Buffer;
int m_AC3Pid; cTsToPes m_AC3Assembler;
int m_AC3PacketCount; int m_AC3Pid;
double m_AC3Bitrate; int m_AC3PacketCount;
bool m_AC3Valid; double m_AC3Bitrate;
ac3_info_t m_AC3Info; bool m_AC3Valid;
ac3_info_t m_AC3Info;
protected: protected:
virtual void Activate(bool On); virtual void Activate(bool On);
@@ -57,66 +63,115 @@ protected:
virtual void Action(void); virtual void Action(void);
public: public:
virtual void SetVideoCodec(eVideoCodec codec) { m_VideoInfo.codec = codec; } virtual void SetVideoCodec(eVideoCodec codec) { cMutexLock MutexLock(&m_Mutex);
virtual void SetVideoFormat(eVideoFormat format) { m_VideoInfo.format = format; } m_VideoInfo.codec = codec; }
virtual void SetVideoScan(eVideoScan scan) { m_VideoInfo.scan = scan; } virtual void SetVideoFormat(eVideoFormat format) { cMutexLock MutexLock(&m_Mutex);
virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) { m_VideoInfo.aspectRatio = aspectratio; } m_VideoInfo.format = format; }
virtual void SetVideoSize(int width, int height) { m_VideoInfo.width = width; virtual void SetVideoScan(eVideoScan scan) { cMutexLock MutexLock(&m_Mutex);
m_VideoInfo.height = height; } m_VideoInfo.scan = scan; }
virtual void SetVideoFramerate(double framerate) { m_VideoInfo.frameRate = framerate; } virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) { cMutexLock MutexLock(&m_Mutex);
virtual void SetVideoBitrate(double bitrate) { m_VideoInfo.bitrate = bitrate; } m_VideoInfo.aspectRatio = aspectratio; }
virtual void SetVideoSize(int width, int height) { cMutexLock MutexLock(&m_Mutex);
m_VideoInfo.width = width;
m_VideoInfo.height = height; }
virtual void SetVideoFramerate(double framerate) { cMutexLock MutexLock(&m_Mutex);
m_VideoInfo.frameRate = framerate; }
virtual void SetVideoBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex);
m_VideoInfo.bitrate = bitrate; }
virtual void SetAudioCodec(eAudioCodec codec) { m_AudioInfo.codec = codec; } virtual void SetAudioCodec(eAudioCodec codec) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAudioBitrate(double bitrate) { m_AudioInfo.bitrate = bitrate; } m_AudioInfo.codec = codec; }
virtual void SetAudioSamplingFrequency(int sampling) { m_AudioInfo.samplingFrequency = sampling; } virtual void SetAudioBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAudioChannel(eAudioChannelMode mode) { m_AudioInfo.channelMode = mode; } m_AudioInfo.bitrate = bitrate; }
virtual void SetAudioSamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex);
m_AudioInfo.samplingFrequency = sampling; }
virtual void SetAudioChannel(eAudioChannelMode mode) { cMutexLock MutexLock(&m_Mutex);
m_AudioInfo.channelMode = mode; }
virtual void SetAC3Bitrate(int bitrate) { m_AC3Info.bitrate = bitrate; } virtual void SetAC3Bitrate(int bitrate) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAC3SamplingFrequency(int sampling) { m_AC3Info.samplingFrequency = sampling; } m_AC3Info.bitrate = bitrate; }
virtual void SetAC3Bitstream(int mode) { m_AC3Info.bitstreamMode = mode; } virtual void SetAC3SamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAC3AudioCoding(int mode) { m_AC3Info.audioCodingMode = mode; } m_AC3Info.samplingFrequency = sampling; }
virtual void SetAC3DolbySurround(int mode) { m_AC3Info.dolbySurroundMode = mode; } virtual void SetAC3Bitstream(int mode) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAC3CenterMix(int level) { m_AC3Info.centerMixLevel = level; } m_AC3Info.bitstreamMode = mode; }
virtual void SetAC3SurroundMix(int level) { m_AC3Info.surroundMixLevel = level; } virtual void SetAC3AudioCoding(int mode) { cMutexLock MutexLock(&m_Mutex);
virtual void SetAC3Dialog(int level) { m_AC3Info.dialogLevel = level; } m_AC3Info.audioCodingMode = mode; }
virtual void SetAC3LFE(bool onoff) { m_AC3Info.lfe = onoff; } virtual void SetAC3DolbySurround(int mode) { cMutexLock MutexLock(&m_Mutex);
m_AC3Info.dolbySurroundMode = mode; }
virtual void SetAC3CenterMix(int level) { cMutexLock MutexLock(&m_Mutex);
m_AC3Info.centerMixLevel = level; }
virtual void SetAC3SurroundMix(int level) { cMutexLock MutexLock(&m_Mutex);
m_AC3Info.surroundMixLevel = level; }
virtual void SetAC3Dialog(int level) { cMutexLock MutexLock(&m_Mutex);
m_AC3Info.dialogLevel = level; }
virtual void SetAC3LFE(bool onoff) { cMutexLock MutexLock(&m_Mutex);
m_AC3Info.lfe = onoff; }
public: public:
cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid, int Apid[], int Dpid[]); cFemonReceiver(int Vtype, int Vpid, int Apid, int Dpid);
virtual ~cFemonReceiver(); virtual ~cFemonReceiver();
void Deactivate(void); void Deactivate(void);
bool VideoValid(void) { return m_VideoValid; }; // boolean bool VideoValid(void) { cMutexLock MutexLock(&m_Mutex);
double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s return m_VideoValid; }; // boolean
int VideoCodec(void) { return m_VideoInfo.codec; }; // eVideoCodec double VideoBitrate(void) { cMutexLock MutexLock(&m_Mutex);
int VideoFormat(void) { return m_VideoInfo.format; }; // eVideoFormat return m_VideoBitrate; }; // bit/s
int VideoScan(void) { return m_VideoInfo.scan; }; // eVideoScan int VideoCodec(void) { cMutexLock MutexLock(&m_Mutex);
int VideoAspectRatio(void) { return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio return m_VideoInfo.codec; }; // eVideoCodec
int VideoHorizontalSize(void) { return m_VideoInfo.width; }; // pixels int VideoFormat(void) { cMutexLock MutexLock(&m_Mutex);
int VideoVerticalSize(void) { return m_VideoInfo.height; }; // pixels return m_VideoInfo.format; }; // eVideoFormat
double VideoFrameRate(void) { return m_VideoInfo.frameRate; }; // Hz int VideoScan(void) { cMutexLock MutexLock(&m_Mutex);
double VideoStreamBitrate(void) { return m_VideoInfo.bitrate; }; // bit/s return m_VideoInfo.scan; }; // eVideoScan
int VideoAspectRatio(void) { cMutexLock MutexLock(&m_Mutex);
return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio
int VideoHorizontalSize(void) { cMutexLock MutexLock(&m_Mutex);
return m_VideoInfo.width; }; // pixels
int VideoVerticalSize(void) { cMutexLock MutexLock(&m_Mutex);
return m_VideoInfo.height; }; // pixels
double VideoFrameRate(void) { cMutexLock MutexLock(&m_Mutex);
return m_VideoInfo.frameRate; }; // Hz
double VideoStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
return m_VideoInfo.bitrate; }; // bit/s
bool AudioValid(void) { return m_AudioValid; }; // boolean bool AudioValid(void) { cMutexLock MutexLock(&m_Mutex);
double AudioBitrate(void) { return m_AudioBitrate; }; // bit/s return m_AudioValid; }; // boolean
int AudioCodec(void) { return m_AudioInfo.codec; }; // eAudioCodec double AudioBitrate(void) { cMutexLock MutexLock(&m_Mutex);
int AudioChannelMode(void) { return m_AudioInfo.channelMode; }; // eAudioChannelMode return m_AudioBitrate; }; // bit/s
double AudioStreamBitrate(void) { return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate int AudioCodec(void) { cMutexLock MutexLock(&m_Mutex);
int AudioSamplingFreq(void) { return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency return m_AudioInfo.codec; }; // eAudioCodec
int AudioChannelMode(void) { cMutexLock MutexLock(&m_Mutex);
return m_AudioInfo.channelMode; }; // eAudioChannelMode
double AudioStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate
int AudioSamplingFreq(void) { cMutexLock MutexLock(&m_Mutex);
return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency
bool AC3Valid(void) { return m_AC3Valid; }; // boolean bool AC3Valid(void) { cMutexLock MutexLock(&m_Mutex);
double AC3Bitrate(void) { return m_AC3Bitrate; }; // bit/s return m_AC3Valid; }; // boolean
double AC3StreamBitrate(void) { return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate double AC3Bitrate(void) { cMutexLock MutexLock(&m_Mutex);
int AC3SamplingFreq(void) { return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency return m_AC3Bitrate; }; // bit/s
int AC3BitStreamMode(void) { return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode double AC3StreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
int AC3AudioCodingMode(void) { return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate
bool AC3_2_0(void) { return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean int AC3SamplingFreq(void) { cMutexLock MutexLock(&m_Mutex);
bool AC3_5_1(void) { return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency
int AC3DolbySurroundMode(void) { return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode int AC3BitStreamMode(void) { cMutexLock MutexLock(&m_Mutex);
int AC3CenterMixLevel(void) { return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode
int AC3SurroundMixLevel(void) { return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel int AC3AudioCodingMode(void) { cMutexLock MutexLock(&m_Mutex);
int AC3DialogLevel(void) { return m_AC3Info.dialogLevel; }; // -dB return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode
bool AC3Lfe(void) { return m_AC3Info.lfe; }; // boolean bool AC3_2_0(void) { cMutexLock MutexLock(&m_Mutex);
return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean
bool AC3_5_1(void) { cMutexLock MutexLock(&m_Mutex);
return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean
int AC3DolbySurroundMode(void) { cMutexLock MutexLock(&m_Mutex);
return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode
int AC3CenterMixLevel(void) { cMutexLock MutexLock(&m_Mutex);
return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel
int AC3SurroundMixLevel(void) { cMutexLock MutexLock(&m_Mutex);
return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel
int AC3DialogLevel(void) { cMutexLock MutexLock(&m_Mutex);
return m_AC3Info.dialogLevel; }; // -dB
bool AC3Lfe(void) { cMutexLock MutexLock(&m_Mutex);
return m_AC3Info.lfe; }; // boolean
}; };
#endif //__FEMONRECEIVER_H #endif //__FEMONRECEIVER_H

View File

@@ -37,6 +37,11 @@
#include "symbols/five.xpm" #include "symbols/five.xpm"
#include "symbols/six.xpm" #include "symbols/six.xpm"
#include "symbols/seven.xpm" #include "symbols/seven.xpm"
#include "symbols/eight.xpm"
#include "symbols/format1080.xpm"
#include "symbols/format720.xpm"
#include "symbols/format576.xpm"
#include "symbols/format480.xpm"
cBitmap bmSymbol[SYMBOL_MAX_COUNT] = cBitmap bmSymbol[SYMBOL_MAX_COUNT] =
{ {
@@ -69,5 +74,10 @@ cBitmap bmSymbol[SYMBOL_MAX_COUNT] =
cBitmap(four_xpm), // SYMBOL_FOUR cBitmap(four_xpm), // SYMBOL_FOUR
cBitmap(five_xpm), // SYMBOL_FIVE cBitmap(five_xpm), // SYMBOL_FIVE
cBitmap(six_xpm), // SYMBOL_SIX cBitmap(six_xpm), // SYMBOL_SIX
cBitmap(seven_xpm) // SYMBOL_SEVEN cBitmap(seven_xpm), // SYMBOL_SEVEN
cBitmap(eight_xpm), // SYMBOL_EIGHT
cBitmap(format1080_xpm), // SYMBOL_FORMAT_1080
cBitmap(format720_xpm), // SYMBOL_FORMAT_720
cBitmap(format576_xpm), // SYMBOL_FORMAT_576
cBitmap(format480_xpm) // SYMBOL_FORMAT_480
}; };

View File

@@ -41,6 +41,11 @@ enum eSymbols {
SYMBOL_FIVE, SYMBOL_FIVE,
SYMBOL_SIX, SYMBOL_SIX,
SYMBOL_SEVEN, SYMBOL_SEVEN,
SYMBOL_EIGHT,
SYMBOL_FORMAT_1080,
SYMBOL_FORMAT_720,
SYMBOL_FORMAT_576,
SYMBOL_FORMAT_480,
SYMBOL_MAX_COUNT SYMBOL_MAX_COUNT
}; };

View File

@@ -5,6 +5,11 @@
* *
*/ */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -60,9 +65,9 @@ static cString getCA(int value)
return cString::sprintf("%X", value); return cString::sprintf("%X", value);
} }
static const char *getUserString(int Value, const tChannelParameterMap *Map) static const char *getUserString(int Value, const tDvbParameterMap *Map)
{ {
const tChannelParameterMap *map = Map; const tDvbParameterMap *map = Map;
while (map && map->userValue != -1) { while (map && map->userValue != -1) {
if (map->driverValue == Value) if (map->driverValue == Value)
return map->userString ? trVDR(map->userString) : "---"; return map->userString ? trVDR(map->userString) : "---";
@@ -86,15 +91,22 @@ cString getFrontendInfo(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return NULL; return NULL;
CHECK(ioctl(fe, FE_GET_INFO, &value));
CHECK(ioctl(fe, FE_READ_STATUS, &status));
CHECK(ioctl(fe, FE_READ_SIGNAL_STRENGTH, &signal));
CHECK(ioctl(fe, FE_READ_SNR, &snr));
CHECK(ioctl(fe, FE_READ_BER, &ber));
CHECK(ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &unc));
close(fe);
info = cString::sprintf("CARD:%d\nTYPE:%d\nNAME:%s\nSTAT:%02X\nSGNL:%04X\nSNRA:%04X\nBERA:%08X\nUNCB:%08X", cardIndex, value.type, value.name, status, signal, snr, ber, unc); info = cString::sprintf("CARD:%d", cardIndex);
if (ioctl(fe, FE_GET_INFO, &value) >= 0)
info = cString::sprintf("%s\nTYPE:%d\nNAME:%s", *info, value.type, value.name);
if (ioctl(fe, FE_READ_STATUS, &status) >= 0)
info = cString::sprintf("%s\nSTAT:%02X", *info, status);
if (ioctl(fe, FE_READ_SIGNAL_STRENGTH, &signal) >= 0)
info = cString::sprintf("%s\nSGNL:%04X", *info, signal);
if (ioctl(fe, FE_READ_SNR, &snr) >= 0)
info = cString::sprintf("%s\nSNRA:%04X", *info, snr);
if (ioctl(fe, FE_READ_BER, &ber) >= 0)
info = cString::sprintf("%s\nBERA:%08X", *info, ber);
if (ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &unc) >= 0)
info = cString::sprintf("%s\nUNCB:%08X", *info, unc);
close(fe);
if (cFemonOsd::Instance()) if (cFemonOsd::Instance())
info = cString::sprintf("%s\nVIBR:%.0f\nAUBR:%.0f\nDDBR:%.0f", *info, cFemonOsd::Instance()->GetVideoBitrate(), cFemonOsd::Instance()->GetAudioBitrate(), cFemonOsd::Instance()->GetDolbyBitrate()); info = cString::sprintf("%s\nVIBR:%.0f\nAUBR:%.0f\nDDBR:%.0f", *info, cFemonOsd::Instance()->GetVideoBitrate(), cFemonOsd::Instance()->GetAudioBitrate(), cFemonOsd::Instance()->GetDolbyBitrate());
@@ -113,7 +125,8 @@ cString getFrontendName(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return NULL; return NULL;
CHECK(ioctl(fe, FE_GET_INFO, &value)); memset(&value, 0, sizeof(value));
ioctl(fe, FE_GET_INFO, &value);
close(fe); close(fe);
return (cString::sprintf("%s on device #%d", value.name, cardIndex)); return (cString::sprintf("%s on device #%d", value.name, cardIndex));
@@ -127,7 +140,8 @@ cString getFrontendStatus(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return NULL; return NULL;
CHECK(ioctl(fe, FE_READ_STATUS, &value)); memset(&value, 0, sizeof(value));
ioctl(fe, FE_READ_STATUS, &value);
close(fe); close(fe);
return (cString::sprintf("Status %s:%s:%s:%s:%s on device #%d", (value & FE_HAS_LOCK) ? "LOCKED" : "-", (value & FE_HAS_SIGNAL) ? "SIGNAL" : "-", (value & FE_HAS_CARRIER) ? "CARRIER" : "-", (value & FE_HAS_VITERBI) ? "VITERBI" : "-", (value & FE_HAS_SYNC) ? "SYNC" : "-", cardIndex)); return (cString::sprintf("Status %s:%s:%s:%s:%s on device #%d", (value & FE_HAS_LOCK) ? "LOCKED" : "-", (value & FE_HAS_SIGNAL) ? "SIGNAL" : "-", (value & FE_HAS_CARRIER) ? "CARRIER" : "-", (value & FE_HAS_VITERBI) ? "VITERBI" : "-", (value & FE_HAS_SYNC) ? "SYNC" : "-", cardIndex));
@@ -141,7 +155,7 @@ uint16_t getSignal(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return (value); return (value);
CHECK(ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value)); ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value);
close(fe); close(fe);
return (value); return (value);
@@ -155,7 +169,7 @@ uint16_t getSNR(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return (value); return (value);
CHECK(ioctl(fe, FE_READ_SNR, &value)); ioctl(fe, FE_READ_SNR, &value);
close(fe); close(fe);
return (value); return (value);
@@ -169,7 +183,7 @@ uint32_t getBER(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return (value); return (value);
CHECK(ioctl(fe, FE_READ_BER, &value)); ioctl(fe, FE_READ_BER, &value);
close(fe); close(fe);
return (value); return (value);
@@ -183,7 +197,7 @@ uint32_t getUNC(int cardIndex)
int fe = open(dev, O_RDONLY | O_NONBLOCK); int fe = open(dev, O_RDONLY | O_NONBLOCK);
if (fe < 0) if (fe < 0)
return (value); return (value);
CHECK(ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &value)); ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &value);
close(fe); close(fe);
return (value); return (value);
@@ -280,6 +294,7 @@ cString getAudioCodec(int value)
case AUDIO_CODEC_MPEG2_II: return cString::sprintf("%s", tr("MPEG-2 Layer II")); case AUDIO_CODEC_MPEG2_II: return cString::sprintf("%s", tr("MPEG-2 Layer II"));
case AUDIO_CODEC_MPEG2_III: return cString::sprintf("%s", tr("MPEG-2 Layer III")); case AUDIO_CODEC_MPEG2_III: return cString::sprintf("%s", tr("MPEG-2 Layer III"));
case AUDIO_CODEC_HEAAC: return cString::sprintf("%s", tr("HE-AAC")); case AUDIO_CODEC_HEAAC: return cString::sprintf("%s", tr("HE-AAC"));
case AUDIO_CODEC_LATM: return cString::sprintf("%s", tr("LATM"));
default: break; default: break;
} }
return cString::sprintf("---"); return cString::sprintf("---");

View File

@@ -14,9 +14,11 @@
#include <vdr/tools.h> #include <vdr/tools.h>
#ifdef DEBUG #ifdef DEBUG
#define Dprintf(x...) printf(x); #define debug(x...) dsyslog("FEMON: " x);
#define error(x...) esyslog("ERROR: " x);
#else #else
#define Dprintf(x...) ; #define debug(x...) ;
#define error(x...) esyslog("ERROR: " x);
#endif #endif
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) #define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))

View File

@@ -66,7 +66,7 @@ typedef struct video_info {
int width; // pixels int width; // pixels
int height; // pixels int height; // pixels
double frameRate; // Hz double frameRate; // Hz
double bitrate; // Mbit/s double bitrate; // bit/s
} video_info_t; } video_info_t;
class cFemonVideoIf { class cFemonVideoIf {

View File

@@ -7,12 +7,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Christian Wieninger\n" "Last-Translator: Christian Wieninger\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: German <vdr@linuxtv.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -89,6 +90,12 @@ msgstr "Position"
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "" msgstr ""
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "Grenze Rot [%]" msgstr "Grenze Rot [%]"
@@ -260,6 +267,9 @@ msgstr ""
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr ""
msgid "LATM"
msgstr ""
msgid "stereo" msgid "stereo"
msgstr "" msgstr ""

View File

@@ -5,12 +5,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Luis Palacios\n" "Last-Translator: Luis Palacios\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: Spanish <vdr@linuxtv.org>\n"
"Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -87,6 +88,12 @@ msgstr "Posici
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "" msgstr ""
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "L<>mite de rojo [%s]" msgstr "L<>mite de rojo [%s]"
@@ -258,6 +265,9 @@ msgstr ""
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr ""
msgid "LATM"
msgstr ""
msgid "stereo" msgid "stereo"
msgstr "" msgstr ""

View File

@@ -5,12 +5,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Arthur Konovalov\n" "Last-Translator: Arthur Konovalov\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: Estonian <vdr@linuxtv.org>\n"
"Language: et\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-13\n" "Content-Type: text/plain; charset=ISO-8859-13\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -22,7 +23,7 @@ msgid "Signal Information"
msgstr "Signaaliinfo" msgstr "Signaaliinfo"
msgid "Femon not available" msgid "Femon not available"
msgstr "" msgstr "Femon ei ole k<>ttesaadav"
msgid "basic" msgid "basic"
msgstr "standard" msgstr "standard"
@@ -37,7 +38,7 @@ msgid "AC-3"
msgstr "AC-3" msgstr "AC-3"
msgid "Classic" msgid "Classic"
msgstr "Klassikaline" msgstr "Classic"
msgid "Elchi" msgid "Elchi"
msgstr "Elchi" msgstr "Elchi"
@@ -64,79 +65,85 @@ msgid "SilverGreen"
msgstr "SilverGreen" msgstr "SilverGreen"
msgid "Hide main menu entry" msgid "Hide main menu entry"
msgstr "Peida valik peamen<65><6E>s" msgstr "Peita valik peamen<65><6E>s"
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "" msgstr "Valiku peamen<65><6E>s peitmise m<><6D>ritlemine."
msgid "Default display mode" msgid "Default display mode"
msgstr "Vaikimisi displei moodus" msgstr "Vaikemoodus"
msgid "Define the default display mode at startup." msgid "Define the default display mode at startup."
msgstr "" msgstr "K<EFBFBD>ivitamisel vaikemooduse m<><6D>ritlemine."
msgid "Define the used OSD skin." msgid "Define the used OSD skin."
msgstr "" msgstr "Kasutatava ekraanikesta m<><6D>ritlemine."
msgid "Define the used OSD theme." msgid "Define the used OSD theme."
msgstr "" msgstr "Kasutatava teema m<><6D>ritlemine."
msgid "Position" msgid "Position"
msgstr "Positsioon" msgstr "Positsioon"
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "" msgstr "Ekraaniinfo positsiooni m<><6D>ritlemine."
msgid "Downscale OSD size [%]"
msgstr "Ekraanimen<65><6E> v<>hendamine [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Ekraanimen<65><6E> suuruse v<>hendamise m<><6D>ritlemine"
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "Punase limiit [%]" msgstr "Punase limiit [%]"
msgid "Define a limit for red bar, which is used to indicate a bad signal." msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr "" msgstr "Seaded punasele limiidile. Iseloomustab kehva signaali."
msgid "Green limit [%]" msgid "Green limit [%]"
msgstr "Rohelise limiit [%]" msgstr "Rohelise limiit [%]"
msgid "Define a limit for green bar, which is used to indicate a good signal." msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr "" msgstr "Seaded rohelisele limiidile. Iseloomustab head signaali."
msgid "OSD update interval [0.1s]" msgid "OSD update interval [0.1s]"
msgstr "Uuendusintervall [0,1s]" msgstr "Uuendusintervall [0,1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load." msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "" msgstr "Ekraaniinfo uuendamise intervalli m<><6D>ritlemine. V<>iksem intervall- suurem CPU koormus."
msgid "Analyze stream" msgid "Analyze stream"
msgstr "Voo anal<61><6C>s" msgstr "Voo anal<61><6C>s"
msgid "Define whether the DVB stream is analyzed and bitrates calculated." msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "" msgstr "DVB voo bitikiiruse rehkendamise m<><6D>ritlemine."
msgid "Calculation interval [0.1s]" msgid "Calculation interval [0.1s]"
msgstr "Kalkulatsiooni intervall [0,1s]" msgstr "Arvutamise intervall [0,1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values." msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "" msgstr "Arvutamise intervalli m<><6D>ritlemine. Suurem intervall annab stabiilsemaid tulemusi."
msgid "Use SVDRP service" msgid "Use SVDRP service"
msgstr "" msgstr "SVDRP teenus"
msgid "Define whether the SVDRP service is used in client/server setups." msgid "Define whether the SVDRP service is used in client/server setups."
msgstr "" msgstr "SVDRP teenuse klient/server seadete m<><6D>ritlemine."
msgid "SVDRP service port" msgid "SVDRP service port"
msgstr "" msgstr "SVDRP port"
msgid "Define the port number of SVDRP service." msgid "Define the port number of SVDRP service."
msgstr "" msgstr "SVDRP teenuse pordi m<><6D>ritlemine."
msgid "SVDRP service IP" msgid "SVDRP service IP"
msgstr "" msgstr "SVDRP IP"
msgid "Define the IP address of SVDRP service." msgid "Define the IP address of SVDRP service."
msgstr "" msgstr "SVDRP teenuse IP aadressi m<><6D>ritlemine."
msgid "Help" msgid "Help"
msgstr "" msgstr "Abi"
msgid "Video" msgid "Video"
msgstr "Video" msgstr "Video"
@@ -169,13 +176,13 @@ msgid "Coderate"
msgstr "Coderate" msgstr "Coderate"
msgid "Stream Information" msgid "Stream Information"
msgstr "Voo info" msgstr "Vooinfo"
msgid "Video Stream" msgid "Video Stream"
msgstr "Videovoog" msgstr "Videovoog"
msgid "Codec" msgid "Codec"
msgstr "" msgstr "Koodek"
msgid "Bitrate" msgid "Bitrate"
msgstr "Bitikiirus" msgstr "Bitikiirus"
@@ -196,7 +203,7 @@ msgid "Audio Stream"
msgstr "Audiovoog" msgstr "Audiovoog"
msgid "Channel Mode" msgid "Channel Mode"
msgstr "" msgstr "Kanalimoodus"
msgid "Sampling Frequency" msgid "Sampling Frequency"
msgstr "S<>mplimissagedus" msgstr "S<>mplimissagedus"
@@ -229,64 +236,67 @@ msgid "Fixed"
msgstr "Fikseeritud" msgstr "Fikseeritud"
msgid "Analog" msgid "Analog"
msgstr "" msgstr "Analoog"
msgid "MPEG-2" msgid "MPEG-2"
msgstr "" msgstr "MPEG-2"
msgid "H.264" msgid "H.264"
msgstr "" msgstr "H.264"
msgid "MPEG-1 Layer I" msgid "MPEG-1 Layer I"
msgstr "" msgstr "MPEG-1 Layet I"
msgid "MPEG-1 Layer II" msgid "MPEG-1 Layer II"
msgstr "" msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III" msgid "MPEG-1 Layer III"
msgstr "" msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I" msgid "MPEG-2 Layer I"
msgstr "" msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II" msgid "MPEG-2 Layer II"
msgstr "" msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III" msgid "MPEG-2 Layer III"
msgstr "" msgstr "MPEG-2 Layer III"
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo" msgid "stereo"
msgstr "" msgstr "stereo"
msgid "joint Stereo" msgid "joint Stereo"
msgstr "" msgstr "joint stereo"
msgid "dual" msgid "dual"
msgstr "" msgstr "duaalne"
msgid "mono" msgid "mono"
msgstr "" msgstr "mono"
msgid "interlaced" msgid "interlaced"
msgstr "" msgstr "<EFBFBD>lerealaotus"
msgid "progressive" msgid "progressive"
msgstr "" msgstr "progressiivne"
msgid "reserved" msgid "reserved"
msgstr "reserveeritud" msgstr "reserv."
msgid "extended" msgid "extended"
msgstr "" msgstr "laiendatud"
msgid "unknown" msgid "unknown"
msgstr "tundmatu" msgstr "tundmatu"
msgid "component" msgid "component"
msgstr "" msgstr "komponentne"
msgid "PAL" msgid "PAL"
msgstr "PAL" msgstr "PAL"
@@ -295,10 +305,10 @@ msgid "NTSC"
msgstr "NTSC" msgstr "NTSC"
msgid "SECAM" msgid "SECAM"
msgstr "" msgstr "SECAM"
msgid "MAC" msgid "MAC"
msgstr "" msgstr "MAC"
msgid "Hz" msgid "Hz"
msgstr "Hz" msgstr "Hz"
@@ -331,10 +341,10 @@ msgid "Karaoke"
msgstr "Karaoke" msgstr "Karaoke"
msgid "Ch1" msgid "Ch1"
msgstr "Kan. 1" msgstr "Kan.1"
msgid "Ch2" msgid "Ch2"
msgstr "Kan. 2" msgstr "Kan.2"
msgid "C" msgid "C"
msgstr "C" msgstr "C"

View File

@@ -5,12 +5,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Rolf Ahrenberg\n" "Last-Translator: Rolf Ahrenberg\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: Finnish <vdr@linuxtv.org>\n"
"Language: fi\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -87,6 +88,12 @@ msgstr "Sijainti"
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "Määrittele näytön sijainti." msgstr "Määrittele näytön sijainti."
msgid "Downscale OSD size [%]"
msgstr "Pienennä näytön kokoa [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Määrittele näytön pienennyssuhde."
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "Punaisen taso [%]" msgstr "Punaisen taso [%]"
@@ -258,6 +265,9 @@ msgstr "MPEG-2 kerros III"
msgid "HE-AAC" msgid "HE-AAC"
msgstr "HE-AAC" msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo" msgid "stereo"
msgstr "stereo" msgstr "stereo"

View File

@@ -5,12 +5,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2008-01-26 09:59+0100\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: NIVAL Micha<68>l <mnival@club-internet.fr>\n" "Last-Translator: NIVAL Micha<68>l <mnival@club-internet.fr>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: French <vdr@linuxtv.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -87,6 +88,12 @@ msgstr "Position"
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "D<>finit la position de l'OSD." msgstr "D<>finit la position de l'OSD."
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "Limite du rouge (%)" msgstr "Limite du rouge (%)"
@@ -258,6 +265,9 @@ msgstr ""
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr ""
msgid "LATM"
msgstr ""
msgid "stereo" msgid "stereo"
msgstr "" msgstr ""

View File

@@ -6,15 +6,19 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2008-11-10 23:37+0100\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: Italian <vdr@linuxtv.org>\n"
"Language: it\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Italian\n"
"X-Poedit-Country: ITALY\n"
"X-Poedit-SourceCharset: utf-8\n"
msgid "DVB Signal Information Monitor (OSD)" msgid "DVB Signal Information Monitor (OSD)"
msgstr "Mostra info segnale DVB (OSD)" msgstr "Mostra info segnale DVB (OSD)"
@@ -68,13 +72,13 @@ msgid "Hide main menu entry"
msgstr "Nascondi voce menu principale" msgstr "Nascondi voce menu principale"
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "Definisci se la voce del menu principale <EFBFBD> nascosta." msgstr "Definisci se la voce del menu principale è nascosta."
msgid "Default display mode" msgid "Default display mode"
msgstr "Modalit<EFBFBD> visualizz. predefinita" msgstr "Modalità visualizz. predefinita"
msgid "Define the default display mode at startup." msgid "Define the default display mode at startup."
msgstr "Definisci la modalit<EFBFBD> di visualizz. predefinita all'avvio." msgstr "Definisci la modalità di visualizz. predefinita all'avvio."
msgid "Define the used OSD skin." msgid "Define the used OSD skin."
msgstr "Definisci lo stile interfaccia OSD utilizzato." msgstr "Definisci lo stile interfaccia OSD utilizzato."
@@ -88,6 +92,12 @@ msgstr "Posizione"
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "Definisci la posizione dell'OSD." msgstr "Definisci la posizione dell'OSD."
msgid "Downscale OSD size [%]"
msgstr "Riduci dimensione OSD [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Definisci il rapporto di riduzione della dimensione OSD."
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "Limite rosso [%]" msgstr "Limite rosso [%]"
@@ -104,19 +114,19 @@ msgid "OSD update interval [0.1s]"
msgstr "Intervallo agg. OSD [0.1s]" msgstr "Intervallo agg. OSD [0.1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load." msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "Definisci un intervallo per gli agg. OSD. Pi<EFBFBD> piccolo <EFBFBD> l'intervallo maggiore sar<EFBFBD> l'uso di CPU." msgstr "Definisci un intervallo per gli agg. OSD. Più piccolo è l'intervallo maggiore sarà l'uso di CPU."
msgid "Analyze stream" msgid "Analyze stream"
msgstr "Analizza flusso" msgstr "Analizza flusso"
msgid "Define whether the DVB stream is analyzed and bitrates calculated." msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "Definisci se il flusso DVB <EFBFBD> analizzato e i bitrate calcolati." msgstr "Definisci se il flusso DVB è analizzato e i bitrate calcolati."
msgid "Calculation interval [0.1s]" msgid "Calculation interval [0.1s]"
msgstr "Intervallo di calcolo [0.1s]" msgstr "Intervallo di calcolo [0.1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values." msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "Definisci un intervallo di calcolo. L'intervallo pi<EFBFBD> grande genera valori pi<EFBFBD> stabili." msgstr "Definisci un intervallo di calcolo. L'intervallo più grande genera valori più stabili."
msgid "Use SVDRP service" msgid "Use SVDRP service"
msgstr "Utilizza servizio SVDRP" msgstr "Utilizza servizio SVDRP"
@@ -197,7 +207,7 @@ msgid "Audio Stream"
msgstr "Flusso audio" msgstr "Flusso audio"
msgid "Channel Mode" msgid "Channel Mode"
msgstr "Modalit<EFBFBD> canale" msgstr "Modalità canale"
msgid "Sampling Frequency" msgid "Sampling Frequency"
msgstr "Frequenza campionamento" msgstr "Frequenza campionamento"
@@ -206,10 +216,10 @@ msgid "AC-3 Stream"
msgstr "Flusso AC-3" msgstr "Flusso AC-3"
msgid "Bit Stream Mode" msgid "Bit Stream Mode"
msgstr "Modalit<EFBFBD> bitstream" msgstr "Modalità bitstream"
msgid "Audio Coding Mode" msgid "Audio Coding Mode"
msgstr "Modalit<EFBFBD> codifica audio" msgstr "Modalità codifica audio"
msgid "Center Mix Level" msgid "Center Mix Level"
msgstr "Livello sonoro centrale" msgstr "Livello sonoro centrale"
@@ -218,7 +228,7 @@ msgid "Surround Mix Level"
msgstr "Livello sonoro surround" msgstr "Livello sonoro surround"
msgid "Dolby Surround Mode" msgid "Dolby Surround Mode"
msgstr "Modalit<EFBFBD> Dolby Surround" msgstr "Modalità Dolby Surround"
msgid "Low Frequency Effects" msgid "Low Frequency Effects"
msgstr "Effetti bassa frequenza" msgstr "Effetti bassa frequenza"
@@ -259,6 +269,9 @@ msgstr "MPEG-2 Layer III"
msgid "HE-AAC" msgid "HE-AAC"
msgstr "HE-AAC" msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo" msgid "stereo"
msgstr "stereo" msgstr "stereo"

383
po/lt_LT.po Normal file
View File

@@ -0,0 +1,383 @@
# VDR plugin language source file.
# Copyright (C) 2007 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Valdemaras Pipiras
#
msgid ""
msgstr ""
"Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
"Language: lt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "DVB Signal Information Monitor (OSD)"
msgstr "DVB signalo informacijos stebėjimas (OSD)"
msgid "Signal Information"
msgstr "Signalo informacija"
msgid "Femon not available"
msgstr "Femon įskiepas nepasiekiamas"
msgid "basic"
msgstr "Standartinis"
msgid "transponder"
msgstr "Siųstuvas"
msgid "stream"
msgstr "Srautas"
msgid "AC-3"
msgstr "AC-3"
msgid "Classic"
msgstr "Klasikinis"
msgid "Elchi"
msgstr "Elchi"
msgid "ST:TNG"
msgstr "ST:TNG"
msgid "DeepBlue"
msgstr "DeepBlue"
msgid "Moronimo"
msgstr "Moronimo"
msgid "Enigma"
msgstr "Enigma"
msgid "EgalsTry"
msgstr "EgalsTry"
msgid "Duotone"
msgstr "Duotone"
msgid "SilverGreen"
msgstr "SilverGreen"
msgid "Hide main menu entry"
msgstr "Paslėpti pagrindinio meniu įrašus"
msgid "Define whether the main menu entry is hidden."
msgstr "Nustatyti pagrindinio meniu įrašų paslėpimą."
msgid "Default display mode"
msgstr "Numatytasis rodymo būdas"
msgid "Define the default display mode at startup."
msgstr "Nustatyti numatytąjį rodymo būdą paleidžiant."
msgid "Define the used OSD skin."
msgstr "Nustatyti naudojamą ekrano apvalkalą."
msgid "Define the used OSD theme."
msgstr "Nustatyti naudojamą ekrano temą."
msgid "Position"
msgstr "Pozicija"
msgid "Define the position of OSD."
msgstr "Nustatyti ekrano užsklandos poziciją."
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]"
msgstr "Raudonoji ribą [%]"
msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr "Nustatyti raudonos juostos ribą, kuri naudojama blogo signalo indikacijai."
msgid "Green limit [%]"
msgstr "Žalioji riba [%]"
msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr "Nustatyti žalios juostos ribą, kuri naudojama gero signalo indikacijai."
msgid "OSD update interval [0.1s]"
msgstr "Ekrano užsklandos atnaujinimo intervalas [0.1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "Nustatyti ekrano užsklandos atnaujinimo intervalą. Mažesnis intervalas labiau apkrauna centrinį procesorių (CPU)."
msgid "Analyze stream"
msgstr "Analizuoti srautą"
msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "Nurodyti ar DVB srautas turi būti analizuojamas bei jo kokybė išskaičiuojama."
msgid "Calculation interval [0.1s]"
msgstr "Apskaitos intervalos [0.1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "Nustatyti apskaitos intervalą. Kuo didesnis intervalas, tuo tikslesni duomenys."
msgid "Use SVDRP service"
msgstr "Naudoti SVDRP paslaugą"
msgid "Define whether the SVDRP service is used in client/server setups."
msgstr "Nurodyti ar SVDRP paslauga naudojama kliento/serverio nustatymuose."
msgid "SVDRP service port"
msgstr "SVDRP įrenginio portas"
msgid "Define the port number of SVDRP service."
msgstr "Nustatyti SVDRP įrenginio prievadą."
msgid "SVDRP service IP"
msgstr "SVDRP įrenginio IP"
msgid "Define the IP address of SVDRP service."
msgstr "Nustatyti SVDRP įrenginio IP adresą."
msgid "Help"
msgstr "Pagalba"
msgid "Video"
msgstr "Video"
msgid "Audio"
msgstr "Audio"
msgid "Transponder Information"
msgstr "Siųstuvo informacija"
msgid "Apid"
msgstr "Apid"
msgid "Dpid"
msgstr "Dpid"
msgid "Spid"
msgstr "Spid"
msgid "Nid"
msgstr "Nid"
msgid "Tid"
msgstr "Tid"
msgid "Rid"
msgstr "Rid"
msgid "Coderate"
msgstr "Kodavimo dažnis"
msgid "Stream Information"
msgstr "Srauto informacija"
msgid "Video Stream"
msgstr "Video srautas"
msgid "Codec"
msgstr "Kodekas"
msgid "Bitrate"
msgstr "Kokybė"
msgid "Aspect Ratio"
msgstr "Proporcijos"
msgid "Frame Rate"
msgstr "Kadrų dažnis"
msgid "Video Format"
msgstr "Video formatas"
msgid "Resolution"
msgstr "Rezoliucija"
msgid "Audio Stream"
msgstr "Audio srautas"
msgid "Channel Mode"
msgstr "kanalo būsena"
msgid "Sampling Frequency"
msgstr "Parodomasis dažnis"
msgid "AC-3 Stream"
msgstr "AC-3 srautas"
msgid "Bit Stream Mode"
msgstr "Bitstream būsena"
msgid "Audio Coding Mode"
msgstr "Audio kodavimas"
msgid "Center Mix Level"
msgstr "Centerinis Mix lygis"
msgid "Surround Mix Level"
msgstr "Surround Mix lygis"
msgid "Dolby Surround Mode"
msgstr "Dolby Surround būklė"
msgid "Low Frequency Effects"
msgstr "Žemo dažnio efektai"
msgid "Dialogue Normalization"
msgstr "Dialogo normalizacija"
msgid "Fixed"
msgstr "Fest"
msgid "Analog"
msgstr "Analog"
msgid "MPEG-2"
msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"
msgid "MPEG-1 Layer II"
msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III"
msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I"
msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II"
msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III"
msgstr "MPEG-2 Layer III"
msgid "HE-AAC"
msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo"
msgstr "stereo"
msgid "joint Stereo"
msgstr "jungtinis stereo"
msgid "dual"
msgstr "dvigubas"
msgid "mono"
msgstr "mono"
msgid "interlaced"
msgstr "persipynęs (interlaced)"
msgid "progressive"
msgstr "progresyvinis"
msgid "reserved"
msgstr "belegt"
msgid "extended"
msgstr "išplėstas"
msgid "unknown"
msgstr "nežinomas"
msgid "component"
msgstr "komponentas"
msgid "PAL"
msgstr "PAL"
msgid "NTSC"
msgstr "NTSC"
msgid "SECAM"
msgstr "SECAM"
msgid "MAC"
msgstr "MAC"
msgid "Hz"
msgstr "Hz"
msgid "Complete Main (CM)"
msgstr "Pilnai pagrindinis (CM)"
msgid "Music and Effects (ME)"
msgstr "Muzika ir efektai (ME)"
msgid "Visually Impaired (VI)"
msgstr " (VI)"
msgid "Hearing Impaired (HI)"
msgstr " (HI)"
msgid "Dialogue (D)"
msgstr "Dialogas (D)"
msgid "Commentary (C)"
msgstr "Komentavimas (C)"
msgid "Emergency (E)"
msgstr "Avarinis (E)"
msgid "Voice Over (VO)"
msgstr "Voice over (VO)"
msgid "Karaoke"
msgstr "Karaoke"
msgid "Ch1"
msgstr "Kan1"
msgid "Ch2"
msgstr "Kan2"
msgid "C"
msgstr "C"
msgid "L"
msgstr "L"
msgid "R"
msgstr "R"
msgid "S"
msgstr "S"
msgid "SL"
msgstr "SL"
msgid "SR"
msgstr "SR"
msgid "dB"
msgstr "dB"
msgid "not indicated"
msgstr "nerasta"
msgid "MHz"
msgstr "MHz"
msgid "free"
msgstr "frei"
msgid "Mbit/s"
msgstr "Mbit/s"
msgid "kbit/s"
msgstr "kbit/s"

View File

@@ -5,12 +5,13 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.7.3\n" "Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2009-08-29 20:57+0300\n" "POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: Vyacheslav Dikonov\n" "Last-Translator: Vyacheslav Dikonov\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: Russian <vdr@linuxtv.org>\n"
"Language: ru\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-5\n" "Content-Type: text/plain; charset=ISO-8859-5\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@@ -87,6 +88,12 @@ msgstr "
msgid "Define the position of OSD." msgid "Define the position of OSD."
msgstr "" msgstr ""
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]" msgid "Red limit [%]"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> (%)" msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> (%)"
@@ -258,6 +265,9 @@ msgstr ""
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr ""
msgid "LATM"
msgstr ""
msgid "stereo" msgid "stereo"
msgstr "" msgstr ""

383
po/zh_CN.po Normal file
View File

@@ -0,0 +1,383 @@
# VDR plugin language source file.
# Copyright (C) 2007 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Nan Feng VDR <nfgx@21cn.com>, 2009.2
#
msgid ""
msgstr ""
"Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: NanFeng <nfgx@21cn.com>\n"
"Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "DVB Signal Information Monitor (OSD)"
msgstr "卫星信号信息显示(OSD)"
msgid "Signal Information"
msgstr "频道信息浏览"
msgid "Femon not available"
msgstr "Femon插件无法使用"
msgid "basic"
msgstr "基本"
msgid "transponder"
msgstr "转发器"
msgid "stream"
msgstr "数据流"
msgid "AC-3"
msgstr "AC-3"
msgid "Classic"
msgstr "经典"
msgid "Elchi"
msgstr "Elchi"
msgid "ST:TNG"
msgstr "ST:TNG"
msgid "DeepBlue"
msgstr "DeepBlue"
msgid "Moronimo"
msgstr "Moronimo"
msgid "Enigma"
msgstr "Enigma"
msgid "EgalsTry"
msgstr "EgalsTry"
msgid "Duotone"
msgstr "双色调"
msgid "SilverGreen"
msgstr "银绿"
msgid "Hide main menu entry"
msgstr "隐藏主菜单条目."
msgid "Define whether the main menu entry is hidden."
msgstr "确定是否进入主菜单是隐藏的."
msgid "Default display mode"
msgstr "默认启动时显示模式."
msgid "Define the default display mode at startup."
msgstr "定义默认启动时显示模式."
msgid "Define the used OSD skin."
msgstr "确定使用的菜单皮肤."
msgid "Define the used OSD theme."
msgstr "确定使用的菜单主题."
msgid "Position"
msgstr "位置"
msgid "Define the position of OSD."
msgstr "确定菜单的位置."
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]"
msgstr "红限制[ ]"
msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr "定义一个限制红键,这是用来表示一个坏的信号."
msgid "Green limit [%]"
msgstr "绿限制[ ]"
msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr "定义一个限制的绿色键,这是用来表示一个良好的信号."
msgid "OSD update interval [0.1s]"
msgstr "菜单更新间隔时间 [0.1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "确定一个OSD的更新时间间隔.较小的间隔产生较高的CPU负载."
msgid "Analyze stream"
msgstr "分析流"
msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "确定是否DVB流分析和比特率计算."
msgid "Calculation interval [0.1s]"
msgstr "计算时间间隔 [0.1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "定义一个时间间隔来计算.更大的时间价格产生将更稳定."
msgid "Use SVDRP service"
msgstr "使用SVDRP服务"
msgid "Define whether the SVDRP service is used in client/server setups."
msgstr "定义是否SVDRP服务是用来在客户机/服务器的设置."
msgid "SVDRP service port"
msgstr "SVDRP服务端口"
msgid "Define the port number of SVDRP service."
msgstr "定义SVDRP服务的端口号."
msgid "SVDRP service IP"
msgstr "SVDRP服务的IP地址"
msgid "Define the IP address of SVDRP service."
msgstr "定义SVDRP服务的IP地址."
msgid "Help"
msgstr "帮助"
msgid "Video"
msgstr "视频"
msgid "Audio"
msgstr "音频"
msgid "Transponder Information"
msgstr "转发器信息"
msgid "Apid"
msgstr "Apid"
msgid "Dpid"
msgstr "Dpid"
msgid "Spid"
msgstr "Spid"
msgid "Nid"
msgstr "Nid"
msgid "Tid"
msgstr "Tid"
msgid "Rid"
msgstr "Rid"
msgid "Coderate"
msgstr "码速率"
msgid "Stream Information"
msgstr "流信息"
msgid "Video Stream"
msgstr "视频流"
msgid "Codec"
msgstr "解码模式"
msgid "Bitrate"
msgstr "比特率"
msgid "Aspect Ratio"
msgstr "纵横比"
msgid "Frame Rate"
msgstr "帧速率"
msgid "Video Format"
msgstr "视频制式"
msgid "Resolution"
msgstr "分辨率"
msgid "Audio Stream"
msgstr "音频流"
msgid "Channel Mode"
msgstr "声道模式"
msgid "Sampling Frequency"
msgstr "采样频率"
msgid "AC-3 Stream"
msgstr "AC-3流"
msgid "Bit Stream Mode"
msgstr "比特流模式"
msgid "Audio Coding Mode"
msgstr "音频编码模式"
msgid "Center Mix Level"
msgstr "中心混合级别"
msgid "Surround Mix Level"
msgstr "环绕混合级别"
msgid "Dolby Surround Mode"
msgstr "杜比环绕声模式"
msgid "Low Frequency Effects"
msgstr "低频效果"
msgid "Dialogue Normalization"
msgstr "对话正常化"
msgid "Fixed"
msgstr "固定"
msgid "Analog"
msgstr "模拟"
msgid "MPEG-2"
msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"
msgid "MPEG-1 Layer II"
msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III"
msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I"
msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II"
msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III"
msgstr "MPEG-2 Layer III"
msgid "HE-AAC"
msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo"
msgstr "立体声"
msgid "joint Stereo"
msgstr "联合立体声"
msgid "dual"
msgstr "双重"
msgid "mono"
msgstr "单声道"
msgid "interlaced"
msgstr "隔行扫描"
msgid "progressive"
msgstr "进步"
msgid "reserved"
msgstr "保留"
msgid "extended"
msgstr "扩展"
msgid "unknown"
msgstr "未知"
msgid "component"
msgstr "组件"
msgid "PAL"
msgstr "PAL"
msgid "NTSC"
msgstr "NTSC"
msgid "SECAM"
msgstr "SECAM"
msgid "MAC"
msgstr "MAC"
msgid "Hz"
msgstr "赫兹"
msgid "Complete Main (CM)"
msgstr "完成主要 (CM)"
msgid "Music and Effects (ME)"
msgstr "音乐和效果 (ME)"
msgid "Visually Impaired (VI)"
msgstr "视障 (VI)"
msgid "Hearing Impaired (HI)"
msgstr "听障 (HI)"
msgid "Dialogue (D)"
msgstr "对话 (D)"
msgid "Commentary (C)"
msgstr "评论 (C)"
msgid "Emergency (E)"
msgstr "紧急 (E)"
msgid "Voice Over (VO)"
msgstr "旁白 (VO)"
msgid "Karaoke"
msgstr "卡拉OK"
msgid "Ch1"
msgstr "Ch1"
msgid "Ch2"
msgstr "Ch2"
msgid "C"
msgstr "C"
msgid "L"
msgstr "L"
msgid "R"
msgstr "R"
msgid "S"
msgstr "S"
msgid "SL"
msgstr "SL"
msgid "SR"
msgstr "SR"
msgid "dB"
msgstr "dB"
msgid "not indicated"
msgstr "没有说明"
msgid "MHz"
msgstr "兆赫兹"
msgid "free"
msgstr "免费"
msgid "Mbit/s"
msgstr "兆位/秒"
msgid "kbit/s"
msgstr "千字节/秒"

383
po/zh_TW.po Normal file
View File

@@ -0,0 +1,383 @@
# VDR plugin language source file.
# Copyright (C) 2007 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Nan Feng VDR <nfgx@21cn.com>, 2009.2
#
msgid ""
msgstr ""
"Project-Id-Version: femon 1.7.8\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2010-10-10 10:10+0300\n"
"PO-Revision-Date: 2010-10-10 10:10+0300\n"
"Last-Translator: NanFeng <nfgx@21cn.com>\n"
"Language-Team: Chinese (traditional) <vdr@linuxtv.org>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "DVB Signal Information Monitor (OSD)"
msgstr "衛星信號信息顯示(OSD)"
msgid "Signal Information"
msgstr "頻道信息瀏覽"
msgid "Femon not available"
msgstr "Femon插件無法使用"
msgid "basic"
msgstr "基本"
msgid "transponder"
msgstr "轉發器"
msgid "stream"
msgstr "數據流"
msgid "AC-3"
msgstr "AC-3"
msgid "Classic"
msgstr "經典"
msgid "Elchi"
msgstr "Elchi"
msgid "ST:TNG"
msgstr "ST:TNG"
msgid "DeepBlue"
msgstr "DeepBlue"
msgid "Moronimo"
msgstr "Moronimo"
msgid "Enigma"
msgstr "Enigma"
msgid "EgalsTry"
msgstr "EgalsTry"
msgid "Duotone"
msgstr "雙色調"
msgid "SilverGreen"
msgstr "銀綠"
msgid "Hide main menu entry"
msgstr "隱藏主菜單條目."
msgid "Define whether the main menu entry is hidden."
msgstr "確定是否進入主菜單是隱藏的."
msgid "Default display mode"
msgstr "默認啟動時顯示模式."
msgid "Define the default display mode at startup."
msgstr "定義默認啟動時顯示模式."
msgid "Define the used OSD skin."
msgstr "確定使用的菜單皮膚."
msgid "Define the used OSD theme."
msgstr "確定使用的菜單主題."
msgid "Position"
msgstr "位置"
msgid "Define the position of OSD."
msgstr "確定菜單的位置."
msgid "Downscale OSD size [%]"
msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Red limit [%]"
msgstr "紅限制[ ]"
msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr "定義一個限制紅鍵,這是用來表示一個壞的信號."
msgid "Green limit [%]"
msgstr "綠限制[ ]"
msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr "定義一個限制的綠色鍵,這是用來表示一個良好的信號."
msgid "OSD update interval [0.1s]"
msgstr "菜單更新間隔時間[0.1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "確定一個OSD的更新時間間隔.較小的間隔產生較高的CPU負載."
msgid "Analyze stream"
msgstr "分析流"
msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "確定是否DVB流分析和比特率計算."
msgid "Calculation interval [0.1s]"
msgstr "計算時間間隔[0.1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "定義一個時間間隔來計算.更大的時間價格產生將更穩定."
msgid "Use SVDRP service"
msgstr "使用SVDRP服務"
msgid "Define whether the SVDRP service is used in client/server setups."
msgstr "定義是否SVDRP服務是用來在客戶機/服務器的設置."
msgid "SVDRP service port"
msgstr "SVDRP服務端口"
msgid "Define the port number of SVDRP service."
msgstr "定義SVDRP服務的端口號."
msgid "SVDRP service IP"
msgstr "SVDRP服務的IP地址"
msgid "Define the IP address of SVDRP service."
msgstr "定義SVDRP服務的IP地址."
msgid "Help"
msgstr "幫助"
msgid "Video"
msgstr "視頻"
msgid "Audio"
msgstr "音頻"
msgid "Transponder Information"
msgstr "轉發器信息"
msgid "Apid"
msgstr "Apid"
msgid "Dpid"
msgstr "Dpid"
msgid "Spid"
msgstr "Spid"
msgid "Nid"
msgstr "Nid"
msgid "Tid"
msgstr "Tid"
msgid "Rid"
msgstr "Rid"
msgid "Coderate"
msgstr "碼速率"
msgid "Stream Information"
msgstr "流信息"
msgid "Video Stream"
msgstr "視頻流"
msgid "Codec"
msgstr "解碼模式"
msgid "Bitrate"
msgstr "比特率"
msgid "Aspect Ratio"
msgstr "縱橫比"
msgid "Frame Rate"
msgstr "幀速率"
msgid "Video Format"
msgstr "視頻制式"
msgid "Resolution"
msgstr "分辨率"
msgid "Audio Stream"
msgstr "音頻流"
msgid "Channel Mode"
msgstr "聲道模式"
msgid "Sampling Frequency"
msgstr "採樣頻率"
msgid "AC-3 Stream"
msgstr "AC-3流"
msgid "Bit Stream Mode"
msgstr "比特流模式"
msgid "Audio Coding Mode"
msgstr "音頻編碼模式"
msgid "Center Mix Level"
msgstr "中心混合級別"
msgid "Surround Mix Level"
msgstr "環繞混合級別"
msgid "Dolby Surround Mode"
msgstr "杜比環繞聲模式"
msgid "Low Frequency Effects"
msgstr "低頻效果"
msgid "Dialogue Normalization"
msgstr "對話正常化"
msgid "Fixed"
msgstr "固定"
msgid "Analog"
msgstr "模擬"
msgid "MPEG-2"
msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"
msgid "MPEG-1 Layer II"
msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III"
msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I"
msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II"
msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III"
msgstr "MPEG-2 Layer III"
msgid "HE-AAC"
msgstr "HE-AAC"
msgid "LATM"
msgstr "LATM"
msgid "stereo"
msgstr "立體聲"
msgid "joint Stereo"
msgstr "聯合立體聲"
msgid "dual"
msgstr "雙重"
msgid "mono"
msgstr "單聲道"
msgid "interlaced"
msgstr "隔行掃描"
msgid "progressive"
msgstr "進步"
msgid "reserved"
msgstr "保留"
msgid "extended"
msgstr "擴展"
msgid "unknown"
msgstr "未知"
msgid "component"
msgstr "組件"
msgid "PAL"
msgstr "PAL"
msgid "NTSC"
msgstr "NTSC"
msgid "SECAM"
msgstr "SECAM"
msgid "MAC"
msgstr "MAC"
msgid "Hz"
msgstr "赫茲"
msgid "Complete Main (CM)"
msgstr "完成主要(CM)"
msgid "Music and Effects (ME)"
msgstr "音樂和效果(ME)"
msgid "Visually Impaired (VI)"
msgstr "視障(VI)"
msgid "Hearing Impaired (HI)"
msgstr "聽障(HI)"
msgid "Dialogue (D)"
msgstr "對話(D)"
msgid "Commentary (C)"
msgstr "評論(C)"
msgid "Emergency (E)"
msgstr "緊急(E)"
msgid "Voice Over (VO)"
msgstr "旁白(VO)"
msgid "Karaoke"
msgstr "卡拉OK"
msgid "Ch1"
msgstr "Ch1"
msgid "Ch2"
msgstr "Ch2"
msgid "C"
msgstr "C"
msgid "L"
msgstr "L"
msgid "R"
msgstr "R"
msgid "S"
msgstr "S"
msgid "SL"
msgstr "SL"
msgid "SR"
msgstr "SR"
msgid "dB"
msgstr "dB"
msgid "not indicated"
msgstr "沒有說明"
msgid "MHz"
msgstr "兆赫茲"
msgid "free"
msgstr "免費"
msgid "Mbit/s"
msgstr "兆位/秒"
msgid "kbit/s"
msgstr "千字節/秒"

23
symbols/eight.xpm Normal file
View File

@@ -0,0 +1,23 @@
/* XPM */
static const char *const eight_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",
"+++++++++++++++",
"..............+",
".....++++.....+",
"....++++++....+",
"....++..++....+",
"...++....++...+",
"...++....++...+",
"....++..++....+",
".....++++.....+",
".....++++.....+",
"....++..++....+",
"...++....++...+",
"...++....++...+",
"....++..++....+",
"....++++++....+",
".....++++.....+",
"..............+",
"+++++++++++++++"};

23
symbols/format1080.xpm Normal file
View File

@@ -0,0 +1,23 @@
/* XPM */
static const char *const format1080_xpm[] = {
"40 18 2 1",
". c #FFFFFF",
"+ c #000000",
"++++++++++++++++++++++++++++++++++++++++",
"+......................................+",
"+......++...++++.....++++.....++++.....+",
"+...+++++..++++++...++++++...++++++....+",
"+...+++++..++..++...++..++...++..++....+",
"+......++.++....++.++....++.++....++...+",
"+......++.++....++.++....++.++....++...+",
"+......++.++....++..++..++..++....++...+",
"+......++.++....++...++++...++....++...+",
"+......++.++....++...++++...++....++...+",
"+......++.++....++..++..++..++....++...+",
"+......++.++....++.++....++.++....++...+",
"+......++.++....++.++....++.++....++...+",
"+......++..++..++...++..++...++..++....+",
"+......++..++++++...++++++...++++++....+",
"+......++...++++.....++++.....++++.....+",
"+......................................+",
"++++++++++++++++++++++++++++++++++++++++"};

23
symbols/format480.xpm Normal file
View File

@@ -0,0 +1,23 @@
/* XPM */
static const char *const format480_xpm[] = {
"35 18 2 1",
". c #FFFFFF",
"+ c #000000",
"+++++++++++++++++++++++++++++++++++",
"+.................................+",
"+.........++....++++.....++++.....+",
"+........+++...++++++...++++++....+",
"+.......++++...++..++...++..++....+",
"+......++.++..++....++.++....++...+",
"+.....++..++..++....++.++....++...+",
"+.....++..++...++..++..++....++...+",
"+....++...++....++++...++....++...+",
"+...++....++....++++...++....++...+",
"+...+++++++++..++..++..++....++...+",
"+...+++++++++.++....++.++....++...+",
"+.........++..++....++.++....++...+",
"+.........++...++..++...++..++....+",
"+.........++...++++++...++++++....+",
"+.........++....++++.....++++.....+",
"+.................................+",
"+++++++++++++++++++++++++++++++++++"};

23
symbols/format576.xpm Normal file
View File

@@ -0,0 +1,23 @@
/* XPM */
static const char *const format576_xpm[] = {
"33 18 2 1",
". c #FFFFFF",
"+ c #000000",
"+++++++++++++++++++++++++++++++++",
"+...............................+",
"+...+++++++.++++++++..++++++....+",
"+...+++++++.++++++++.++++++++...+",
"+...++......++....++.+++...++...+",
"+...++............++.++.........+",
"+...++...........+++.++.........+",
"+...++++++.......++..++.+++.....+",
"+...+++++++......++..+++++++....+",
"+...++...+++....+++..+++..+++...+",
"+.........++....++...++....++...+",
"+.........++....++...++....++...+",
"+...++....++...+++...++....++...+",
"+...++...+++...++....+++..+++...+",
"+...+++++++....++....+++++++....+",
"+....+++++.....++.....+++++.....+",
"+...............................+",
"+++++++++++++++++++++++++++++++++"};

23
symbols/format720.xpm Normal file
View File

@@ -0,0 +1,23 @@
/* XPM */
static const char *const format720_xpm[] = {
"34 18 2 1",
". c #FFFFFF",
"+ c #000000",
"++++++++++++++++++++++++++++++++++",
"+................................+",
"+...++++++++...++++.....++++.....+",
"+...++++++++.+++++++...++++++....+",
"+...++....++.++....++..++..++....+",
"+.........++.......++.++....++...+",
"+.........++.......++.++....++...+",
"+.........++.......++.++....++...+",
"+........++......+++..++....++...+",
"+.......+++.....+++...++....++...+",
"+.......++.....+++....++....++...+",
"+.......++....+++.....++....++...+",
"+......+++...+++......++....++...+",
"+......++....++........++..++....+",
"+......++....++++++++..++++++....+",
"+......++....++++++++...++++.....+",
"+................................+",
"++++++++++++++++++++++++++++++++++"};