Compare commits

...

17 Commits

Author SHA1 Message Date
Rolf Ahrenberg ff59839f7d Added signal level units (Thanks to Winfried). 2019-10-27 16:50:01 +02:00
Rolf Ahrenberg d366856c71 Updated for vdr-2.4.0. 2018-04-15 22:54:18 +03:00
Rolf Ahrenberg 28e4fb8de8 Updated German translation (Thanks to Andreas Brachold). 2017-06-25 14:07:10 +03:00
Rolf Ahrenberg c8868748a8 Adapt VDR's Makefile style again. 2017-06-04 23:02:53 +03:00
Rolf Ahrenberg 0dec600842 Adapt VDR's new Makefile style. 2017-05-25 15:12:31 +03:00
Rolf Ahrenberg 6764e356e9 Get rid of ioctls. 2017-05-25 14:55:37 +03:00
Rolf Ahrenberg c6546524cc Reorder headers. 2017-05-25 14:55:16 +03:00
Rolf Ahrenberg 6112484300 Merge pull request #5 from tmn505/polish_language
Add polish language
2017-02-28 21:51:42 +02:00
Tomasz Maciej Nowak b3808d9934 Add polish language 2017-02-28 16:38:07 +01:00
Rolf Ahrenberg cf47ee83b3 Fix OSD information for H.265 codec. 2017-02-27 21:51:59 +02:00
Rolf Ahrenberg 0ed9e37d52 Fix bitstream parsing. 2017-02-26 14:58:07 +02:00
Rolf Ahrenberg 3e78ac0987 Detect H.265 video resolution. 2017-02-24 23:07:09 +02:00
Rolf Ahrenberg ba767e02bf Add preliminary H.265 support. 2017-01-05 17:55:53 +02:00
Rolf Ahrenberg cc586c3eb4 Updated for vdr-2.3.2. 2017-01-05 15:39:52 +02:00
Rolf Ahrenberg 6ea5108395 Don't use cache for a default value. 2017-01-05 15:38:42 +02:00
Rolf Ahrenberg 7bc2ff53bd Fix frontend handling during a device switch. 2016-01-21 22:23:44 +02:00
Rolf Ahrenberg c13f98a622 Updated for vdr-2.3.1. 2015-09-19 17:01:01 +03:00
40 changed files with 2030 additions and 498 deletions

26
HISTORY
View File

@ -525,3 +525,29 @@ VDR Plugin 'femon' Revision History
- Got rid of FEMON_DEBUG.
- Added support for tracing modes.
- Removed the 'femonclient' plugin.
===================================
VDR Plugin 'femon' Revision History
===================================
2017-06-24: Version 2.3.0
- Updated for vdr-2.3.7.
- Added support for H.265 video codec.
- Fixed frontend handling during a device switch.
- Added Polish translation (Thanks to Tomasz Nowak).
- Updated German translation (Thanks to Andreas Brachold).
===================================
VDR Plugin 'femon' Revision History
===================================
2018-04-15: Version 2.4.0
- Updated for vdr-2.4.0.
2019-xx-xx: Version 2.4.1
- Added signal level units (Thanks to Winfried).

View File

@ -61,7 +61,7 @@ all-redirect: all
### The object files (add further files here):
OBJS = $(PLUGIN).o aac.o ac3.o config.o h264.o latm.o mpeg.o osd.o receiver.o setup.o symbol.o tools.o
OBJS = $(PLUGIN).o aac.o ac3.o config.o h264.o h265.o latm.o mpeg.o osd.o receiver.o setup.o symbol.o tools.o
### The main target:
@ -70,14 +70,15 @@ all: $(SOFILE) i18n
### Implicit rules:
%.o: %.c
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
@echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies:
MAKEDEP = $(CXX) -MM -MG
DEPFILE = .dependencies
$(DEPFILE): Makefile
@$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
$(Q)$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
-include $(DEPFILE)
@ -90,17 +91,21 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po
msgfmt -c -o $@ $<
@echo MO $@
$(Q)msgfmt -c -o $@ $<
$(I18Npot): $(wildcard *.c)
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
@echo GT $@
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
%.po: $(I18Npot)
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@echo PO $@
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
@touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
install -D -m644 $< $@
@echo IN $@
$(Q)install -D -m644 $< $@
.PHONY: i18n
i18n: $(I18Nmo) $(I18Npot)
@ -110,11 +115,13 @@ install-i18n: $(I18Nmsgs)
### Targets:
$(SOFILE): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
@$(STRIP) $@
@echo LD $@
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
$(Q)$(STRIP) $@
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
@echo IN $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
$(Q)install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
install: install-lib install-i18n
@ -132,4 +139,4 @@ clean:
.PHONY: cppcheck
cppcheck:
@cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c)
$(Q)cppcheck --language=c++ --enable=all -v -f $(OBJS:%.o=%.c)

11
README
View File

@ -34,15 +34,14 @@ Terminology:
|## Channel Name ################### [SVDRP][AR][VF][A/DD][D]|
|[=====Signal Strength ===================|=================]|
|[=====Signal Quality ================|=====================]|
| STR: #0000 (0%) BER: #00000000 Video: 0 Mbit/s |
| SNR: #0000 (0%) UNC: #00000000 Audio: 0 kbit/s |
| STR: 0 CNR: 0 BER: 0 PER: 0 Video: 0 Audio: 0 |
| [LOCK] [SIGNAL] [CARRIER] [VITERBI] [SYNC] |
--------------------------------------------------------------
STR - Signal strength from driver
SNR - Signal-to-noise ratio from driver
BER - Bit error rate
UNC - Uncorrected blocks
STR - Signal strength in dBm/dBuV/dbV
CNR - Signal-to-noise ratio of the main carrier in dB
BER - Bit error rate after the forward error correction (FEC) done by inner code block
PER - Block error rate after the outer forward error correction coding
Video - Calculated video bitrate in Mbit/s
Audio - Calculated audio / AC-3 bitrate in kbit/s

View File

@ -20,6 +20,7 @@ cFemonConfig::cFemonConfig()
themeM(0),
positionM(1),
downscaleM(0),
signalUnitM(0),
redLimitM(33),
greenLimitM(66),
updateIntervalM(5),

View File

@ -19,6 +19,14 @@ enum eFemonModes
eFemonModeMaxNumber
};
enum eFemonSignalUnit
{
eFemonSignalUnitdBm,
eFemonSignalUnitdBuV,
eFemonSignalUnitdBV,
eFemonSignalUnitMaxNumber
};
class cFemonConfig
{
private:
@ -29,6 +37,7 @@ private:
int themeM;
int positionM;
int downscaleM;
int signalUnitM;
int redLimitM;
int greenLimitM;
int updateIntervalM;
@ -68,6 +77,7 @@ public:
int GetTheme(void) const { return themeM; }
int GetPosition(void) const { return positionM; }
int GetDownscale(void) const { return downscaleM; }
int GetSignalUnit(void) const { return signalUnitM; }
int GetRedLimit(void) const { return redLimitM; }
int GetGreenLimit(void) const { return greenLimitM; }
int GetUpdateInterval(void) const { return updateIntervalM; }
@ -84,6 +94,7 @@ public:
void SetTheme(int themeP) { themeM = themeP; }
void SetPosition(int positionP) { positionM = positionP; }
void SetDownscale(int downscaleP) { downscaleM = downscaleP; }
void SetSignalUnit(int signalUnitP) { signalUnitM = signalUnitP; }
void SetRedLimit(int redLimitP) { redLimitM = redLimitP; }
void SetGreenLimit(int greenLimitP) { greenLimitM = greenLimitP; }
void SetUpdateInterval(int updateIntervalP) { updateIntervalM = updateIntervalP; }

51
femon.c
View File

@ -17,15 +17,15 @@
#include "tools.h"
#include "setup.h"
#if defined(APIVERSNUM) && APIVERSNUM < 20200
#error "VDR-2.2.0 API version or greater is required!"
#if defined(APIVERSNUM) && APIVERSNUM < 20400
#error "VDR-2.4.0 API version or greater is required!"
#endif
#ifndef GITVERSION
#define GITVERSION ""
#endif
static const char VERSION[] = "2.2.1" GITVERSION;
static const char VERSION[] = "2.4.1" GITVERSION;
static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)");
static const char MAINMENUENTRY[] = trNOOP("Signal Information");
@ -120,7 +120,8 @@ cOsdObject *cPluginFemon::MainMenuAction(void)
{
// Perform the action when selected from the main VDR menu.
debug1("%s", __PRETTY_FUNCTION__);
if (cControl::Control() || (Channels.Count() <= 0))
LOCK_CHANNELS_READ;
if (cControl::Control() || (Channels->Count() <= 0))
Skins.Message(mtInfo, tr("Femon not available"));
else
return cFemonOsd::Instance(true);
@ -164,6 +165,8 @@ bool cPluginFemon::SetupParse(const char *nameP, const char *valueP)
FemonConfig.SetSvdrpPort(atoi(valueP));
else if (!strcasecmp(nameP, "ServerIp"))
FemonConfig.SetSvdrpIp(valueP);
else if (!strcasecmp(nameP, "SignalUnit"))
FemonConfig.SetSignalUnit(atoi(valueP));
else
return false;
@ -172,18 +175,18 @@ bool cPluginFemon::SetupParse(const char *nameP, const char *valueP)
bool cPluginFemon::Service(const char *idP, void *dataP)
{
if (strcmp(idP, "FemonService-v1.0") == 0) {
if (strcmp(idP, "FemonService-v1.1") == 0) {
if (dataP) {
FemonService_v1_0 *data = reinterpret_cast<FemonService_v1_0*>(dataP);
if (!cDevice::ActualDevice())
FemonService_v1_1 *data = reinterpret_cast<FemonService_v1_1*>(dataP);
cDevice *dev = cDevice::ActualDevice();
if (!dev)
return false;
cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice());
data->fe_name = getFrontendName(dev);
data->fe_status = getFrontendStatus(dev);
data->fe_snr = getSNR(dev);
data->fe_cnr = getCNR(dev);
data->fe_signal = getSignal(dev);
data->fe_ber = getBER(dev);
data->fe_unc = getUNC(dev);
data->fe_per = getPER(dev);
data->video_bitrate = cFemonOsd::Instance() ? cFemonOsd::Instance()->GetVideoBitrate() : 0.0;
data->audio_bitrate = cFemonOsd::Instance() ? cFemonOsd::Instance()->GetAudioBitrate() : 0.0;
data->dolby_bitrate = cFemonOsd::Instance() ? cFemonOsd::Instance()->GetDolbyBitrate() : 0.0;
@ -217,12 +220,12 @@ const char **cPluginFemon::SVDRPHelpPages(void)
" Print the signal quality.",
"SGNL <card index>\n"
" Print the signal strength from driver.",
"SNRA <card index>\n"
" Print the signal-to-noise ratio from driver.",
"CNRA <card index>\n"
" Print the carrier-to-noise ratio from driver.",
"BERA <card index>\n"
" Print the bit error rate.",
"UNCB <card index>\n"
" Print the uncorrected blocks rate.",
" Print the bit error rate from driver.",
"PERA <card index>\n"
" Print the packet error rate from driver.",
"VIBR\n"
" Print the current video bitrate [Mbit/s].",
"AUBR\n"
@ -238,14 +241,14 @@ const char **cPluginFemon::SVDRPHelpPages(void)
cString cPluginFemon::SVDRPCommand(const char *commandP, const char *optionP, int &replyCodeP)
{
cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice());
cDevice *dev = cDevice::ActualDevice();
if (strcasecmp(commandP, "TRAC") == 0) {
if (optionP && *optionP)
FemonConfig.SetTraceMode(strtol(optionP, NULL, 0));
return cString::sprintf("Tracing mode: 0x%04X\n", FemonConfig.GetTraceMode());
}
if (*optionP && isnumber(optionP)) {
cDvbDevice *dev2 = dynamic_cast<cDvbDevice*>(cDevice::GetDevice(int(strtol(optionP, NULL, 10))));
cDevice *dev2 = cDevice::GetDevice(int(strtol(optionP, NULL, 10)));
if (dev2)
dev = dev2;
}
@ -291,18 +294,16 @@ cString cPluginFemon::SVDRPCommand(const char *commandP, const char *optionP, in
return cString::sprintf("%d on device #%d", dev->SignalQuality(), dev->CardIndex());
}
else if (strcasecmp(commandP, "SGNL") == 0) {
int value = getSignal(dev);
return cString::sprintf("%04X (%02d%%) on device #%d", value, value / 655, dev->CardIndex());
return cString::sprintf("%s on device #%d", *getSignalStrength(getSignal(dev)), dev->CardIndex());
}
else if (strcasecmp(commandP, "SNRA") == 0) {
int value = getSNR(dev);
return cString::sprintf("%04X (%02d%%) on device #%d", value, value / 655, dev->CardIndex());
else if (strcasecmp(commandP, "CNRA") == 0) {
return cString::sprintf("%.2f dB on device #%d", getCNR(dev), dev->CardIndex());
}
else if (strcasecmp(commandP, "BERA") == 0) {
return cString::sprintf("%08X on device #%d", getBER(dev), dev->CardIndex());
return cString::sprintf("%.0f on device #%d", getBER(dev), dev->CardIndex());
}
else if (strcasecmp(commandP, "UNCB") == 0) {
return cString::sprintf("%08X on device #%d", getUNC(dev), dev->CardIndex());
else if (strcasecmp(commandP, "PERA") == 0) {
return cString::sprintf("%.0f on device #%d", getPER(dev), dev->CardIndex());
}
else if (strcasecmp(commandP, "VIBR") == 0) {
if (cFemonOsd::Instance())

View File

@ -8,15 +8,13 @@
#ifndef __FEMONSERVICE_H
#define __FEMONSERVICE_H
#include <linux/dvb/frontend.h>
struct FemonService_v1_0 {
struct FemonService_v1_1 {
cString fe_name;
cString fe_status;
uint16_t fe_snr;
uint16_t fe_signal;
uint32_t fe_ber;
uint32_t fe_unc;
double fe_cnr;
double fe_signal;
double fe_ber;
double fe_per;
double video_bitrate;
double audio_bitrate;
double dolby_bitrate;

34
h264.c
View File

@ -203,21 +203,19 @@ int cFemonH264::nalUnescape(uint8_t *dstP, const uint8_t *srcP, int lenP)
{
int s = 0, d = 0;
while (s < lenP) {
if (!srcP[s] && !srcP[s + 1]) {
// hit 00 00 xx
dstP[d] = dstP[d + 1] = 0;
s += 2;
d += 2;
if (srcP[s] == 3) {
s++; // 00 00 03 xx --> 00 00 xx
if (s >= lenP)
return d;
}
while (s < lenP - 3) {
if (!srcP[s] && !srcP[s + 1] && srcP[s + 2] == 3) {
dstP[d++] = srcP[s++];
dstP[d++] = srcP[s++];
s++; // skip emulation_prevention_three_byte
}
dstP[d++] = srcP[s++];
else
dstP[d++] = srcP[s++];
}
while (s < lenP)
dstP[d++] = srcP[s++];
return d;
}
@ -553,7 +551,7 @@ int cFemonH264::parseSPS(const uint8_t *bufP, int lenP)
if (bs.GetBit()) { // video_signal_type_present_flag
uint32_t video_format;
video_format = bs.GetBits(3); // video_format
if (video_format < sizeof(videoFormatS) / sizeof(videoFormatS[0])) {
if (video_format < ELEMENTS(videoFormatS)) {
format = videoFormatS[video_format];
debug2("%s video_format=%d", __PRETTY_FUNCTION__, format);
}
@ -646,7 +644,7 @@ int cFemonH264::parseSEI(const uint8_t *bufP, int lenP)
eVideoScan scan = scanM;
while ((bs.Index() * 8 + 16) < lenP) { // sei_message
while ((bs.Index() * 8 + 16) < lenP) { // sei_message
int lastByte, payloadSize = 0, payloadType = 0;
do {
@ -661,14 +659,14 @@ int cFemonH264::parseSEI(const uint8_t *bufP, int lenP)
switch (payloadType) { // sei_payload
case 1: // pic_timing
if (cpbDpbDelaysPresentFlagM) { // cpb_dpb_delays_present_flag
if (cpbDpbDelaysPresentFlagM) { // cpb_dpb_delays_present_flag
bs.SkipUeGolomb(); // cpb_removal_delay
bs.SkipUeGolomb(); // dpb_output_delay
}
if (picStructPresentFlagM) { // pic_struct_present_flag
if (picStructPresentFlagM) { // pic_struct_present_flag
uint32_t pic_struct, ct_type = 0, i = 0;
pic_struct = bs.GetBits(4); // pic_struct
if (pic_struct >= (sizeof(seiNumClockTsTableS)) / sizeof(seiNumClockTsTableS[0]))
if (pic_struct >= ELEMENTS(seiNumClockTsTableS))
return 0;
if (frameMbsOnlyFlagM && !mbAdaptiveFrameFieldFlagM)
scan = VIDEO_SCAN_PROGRESSIVE;
@ -720,7 +718,7 @@ int cFemonH264::parseSEI(const uint8_t *bufP, int lenP)
}
}
if (timeOffsetLengthM > 0)
bs.SkipBits(timeOffsetLengthM); // time_offset
bs.SkipBits(timeOffsetLengthM); // time_offset
}
}
if (i > 0)

8
h264.h
View File

@ -49,10 +49,10 @@ private:
int parseSPS(const uint8_t *buf, int len);
int parseSEI(const uint8_t *buf, int len);
static const t_SAR sarS[];
static const t_DAR darS[];
static const eVideoFormat videoFormatS[];
static const uint8_t seiNumClockTsTableS[9];
static const t_SAR sarS[];
static const t_DAR darS[];
static const eVideoFormat videoFormatS[];
static const uint8_t seiNumClockTsTableS[9];
public:
cFemonH264(cFemonVideoIf *videoHandlerP);

715
h265.c Normal file
View File

@ -0,0 +1,715 @@
/*
* h265.c: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include <math.h>
#include "log.h"
#include "tools.h"
#include "h265.h"
const cFemonH265::t_DAR cFemonH265::darS[] =
{
{ VIDEO_ASPECT_RATIO_1_1, 100 },
{ VIDEO_ASPECT_RATIO_4_3, 133 },
{ VIDEO_ASPECT_RATIO_16_9, 177 },
{ VIDEO_ASPECT_RATIO_2_21_1, 221 },
{ VIDEO_ASPECT_RATIO_12_11, 109 },
{ VIDEO_ASPECT_RATIO_10_11, 90 },
{ VIDEO_ASPECT_RATIO_16_11, 145 },
{ VIDEO_ASPECT_RATIO_40_33, 121 },
{ VIDEO_ASPECT_RATIO_24_11, 218 },
{ VIDEO_ASPECT_RATIO_20_11, 181 },
{ VIDEO_ASPECT_RATIO_32_11, 290 },
{ VIDEO_ASPECT_RATIO_80_33, 242 },
{ VIDEO_ASPECT_RATIO_18_11, 163 },
{ VIDEO_ASPECT_RATIO_15_11, 136 },
{ VIDEO_ASPECT_RATIO_64_33, 193 },
{ VIDEO_ASPECT_RATIO_160_99, 161 },
{ VIDEO_ASPECT_RATIO_3_2, 150 },
{ VIDEO_ASPECT_RATIO_2_1, 200 }
};
const cFemonH265::t_SAR cFemonH265::sarS[] =
{
{ 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 cFemonH265::videoFormatS[] =
{
VIDEO_FORMAT_COMPONENT,
VIDEO_FORMAT_PAL,
VIDEO_FORMAT_NTSC,
VIDEO_FORMAT_SECAM,
VIDEO_FORMAT_MAC,
VIDEO_FORMAT_UNKNOWN,
VIDEO_FORMAT_RESERVED,
VIDEO_FORMAT_RESERVED
};
cFemonH265::cFemonH265(cFemonVideoIf *videoHandlerP)
: videoHandlerM(videoHandlerP),
widthM(0),
heightM(0),
aspectRatioM(VIDEO_ASPECT_RATIO_INVALID),
formatM(VIDEO_FORMAT_INVALID),
frameRateM(0),
bitRateM(0),
scanM(VIDEO_SCAN_INVALID),
frameFieldInfoPresentFlagM(false)
{
reset();
}
cFemonH265::~cFemonH265()
{
}
bool cFemonH265::processVideo(const uint8_t *bufP, int lenP)
{
uint8_t nal_data[lenP];
bool aud_found = false, sps_found = false, sei_found = true; // SEI temporarily disabled!
const uint8_t *buf = bufP;
const uint8_t *start = buf;
const uint8_t *end = start + lenP;
if (!videoHandlerM)
return false;
// skip PES header
if (!PesLongEnough(lenP))
return false;
buf += PesPayloadOffset(buf);
start = buf;
reset();
for (;;) {
int consumed = 0;
buf = nextStartCode(buf, end);
if (buf >= end)
break;
switch ((buf[3] >> 1) & 0x3F) {
case NAL_AUD:
if (!aud_found) {
debug2("%s Found NAL AUD at offset %d/%d", __PRETTY_FUNCTION__, int(buf - start), lenP);
aud_found = true;
}
break;
case NAL_SPS:
if (!sps_found) {
debug2("%s Found NAL SPS at offset %d/%d", __PRETTY_FUNCTION__, int(buf - start), lenP);
int nal_len = nalUnescape(nal_data, buf + 5, int(end - buf - 5));
consumed = parseSPS(nal_data, nal_len);
if (consumed > 0)
sps_found = true;
}
break;
case NAL_SEI:
if (!sei_found) {
debug2("%s Found NAL SEI at offset %d/%d", __PRETTY_FUNCTION__, int(buf - start), lenP);
int nal_len = nalUnescape(nal_data, buf + 5, int(end - buf - 5));
consumed = parseSEI(nal_data, nal_len);
if (consumed > 0)
sei_found = true;
}
break;
default:
break;
}
if (aud_found && sps_found && sei_found)
break;
buf += consumed + 4;
}
if (aud_found) {
videoHandlerM->SetVideoCodec(VIDEO_CODEC_H265);
if (sps_found) {
debug2("%s width=%d height=%d, aspect=%d format=%d bitrate=%.0f", __PRETTY_FUNCTION__, widthM, heightM, aspectRatioM, formatM, bitRateM);
videoHandlerM->SetVideoSize(widthM, heightM);
videoHandlerM->SetVideoFormat(formatM);
videoHandlerM->SetVideoAspectRatio(aspectRatioM);
videoHandlerM->SetVideoBitrate(bitRateM);
}
if (sps_found || sei_found) {
debug2("%s scan=%d framerate=%.2f", __PRETTY_FUNCTION__, scanM, frameRateM);
videoHandlerM->SetVideoScan(scanM);
videoHandlerM->SetVideoFramerate(frameRateM);
}
}
return sps_found;
}
void cFemonH265::reset()
{
frameFieldInfoPresentFlagM = false;
}
const uint8_t *cFemonH265::nextStartCode(const uint8_t *startP, const uint8_t *endP)
{
for (endP -= 3; startP < endP; ++startP) {
if ((startP[0] == 0x00) && (startP[1] == 0x00) && (startP[2] == 0x01))
return startP;
}
return (endP + 3);
}
int cFemonH265::nalUnescape(uint8_t *dstP, const uint8_t *srcP, int lenP)
{
int s = 0, d = 0;
while (s < lenP - 3) {
if (!srcP[s] && !srcP[s + 1] && srcP[s + 2] == 3) {
dstP[d++] = srcP[s++];
dstP[d++] = srcP[s++];
s++; // skip emulation_prevention_three_byte
}
else
dstP[d++] = srcP[s++];
}
while (s < lenP)
dstP[d++] = srcP[s++];
return d;
}
int cFemonH265::parseSPS(const uint8_t *bufP, int lenP)
{
cFemonBitStream bs(bufP, lenP);
uint32_t width = widthM;
uint32_t height = heightM;
eVideoFormat format = formatM;
eVideoAspectRatio aspect_ratio = aspectRatioM;
eVideoScan scan = scanM;
double frame_rate = frameRateM;
double bit_rate = bitRateM;
bool frame_field_info_present_flag = frameFieldInfoPresentFlagM;
const char *profile_name = NULL;
bool general_tier_flag, conformance_window_flag, sps_sub_layer_ordering_info_present_flag, profilePresentFlag = true;
bool general_max_12bit_constraint_flag = false, general_max_10bit_constraint_flag = false, general_max_8bit_constraint_flag = false;
bool general_max_422chroma_constraint_flag = false, general_max_420chroma_constraint_flag = false, general_max_monochrome_constraint_flag = false;
bool general_intra_constraint_flag = false, general_one_picture_only_constraint_flag = false, general_lower_bit_rate_constraint_flag = false;
bool general_progressive_source_flag, general_interlaced_source_flag, general_profile_compatibility_flag[32];
uint32_t chroma_format_idc, log2_max_pic_order_cnt_lsb_minus4, num_short_term_ref_pic_sets, num_long_term_ref_pics_sps;
uint8_t sps_max_sub_layers_minus1, sub_layer_profile_present_flag[8], sub_layer_level_present_flag[8], general_profile_idc, general_level_idc;
bs.SkipBits(4); // sps_video_parameter_set_id
sps_max_sub_layers_minus1 = bs.GetBits(3); // sps_max_sub_layers_minus1
bs.SkipBit(); // sps_temporal_id_nesting_flag
// start of profile_tier_level(1, sps_max_sub_layers_minus1)
if (profilePresentFlag) {
bs.SkipBits(2); // general_profile_space
general_tier_flag = bs.GetBit(); // general_tier_flag
general_profile_idc = bs.GetBits(5); // general_profile_idc
for (int i = 0; i < 32; ++i) {
general_profile_compatibility_flag[i] = bs.GetBit(); // general_profile_compatibility_flag[i]
}
general_progressive_source_flag = bs.GetBit(); // general_progressive_source_flag
general_interlaced_source_flag = bs.GetBit(); // general_interlaced_source_flag
if (general_progressive_source_flag && !general_interlaced_source_flag)
scan = VIDEO_SCAN_PROGRESSIVE;
else if (!general_progressive_source_flag && general_interlaced_source_flag)
scan = VIDEO_SCAN_INTERLACED;
else if (!general_progressive_source_flag && !general_interlaced_source_flag)
scan = VIDEO_SCAN_UNKNOWN;
else
scan = VIDEO_SCAN_INVALID;
debug2("%s general_progressive_source_flag=%d general_interlaced_source_flag=%d scan_type=%d", __PRETTY_FUNCTION__, general_progressive_source_flag, general_interlaced_source_flag, scan);
bs.SkipBit(); // general_non_packed_constraint_flag
bs.SkipBit(); // general_frame_only_constraint_flag
if (general_profile_idc == 4 || general_profile_compatibility_flag[4] ||
general_profile_idc == 5 || general_profile_compatibility_flag[5] ||
general_profile_idc == 6 || general_profile_compatibility_flag[6] ||
general_profile_idc == 7 || general_profile_compatibility_flag[7]) {
// the number of bits in this syntax structure is not affected by this condition
general_max_12bit_constraint_flag = bs.GetBit(); // general_max_12bit_constraint_flag
general_max_10bit_constraint_flag = bs.GetBit(); // general_max_10bit_constraint_flag
general_max_8bit_constraint_flag = bs.GetBit(); // general_max_8bit_constraint_flag
debug2("%s general_max_12bit_constraint_flag=%d general_max_10bit_constraint_flag=%d general_max_8bit_constraint_flag=%d", __PRETTY_FUNCTION__, general_max_12bit_constraint_flag, general_max_10bit_constraint_flag, general_max_8bit_constraint_flag);
general_max_422chroma_constraint_flag = bs.GetBit(); // general_max_422chroma_constraint_flag
general_max_420chroma_constraint_flag = bs.GetBit(); // general_max_420chroma_constraint_flag
general_max_monochrome_constraint_flag = bs.GetBit(); // general_max_monochrome_constraint_flag
debug2("%s general_max_422chroma_constraint_flag=%d general_max_420chroma_constraint_flag=%d general_max_monochrome_constraint_flag=%d", __PRETTY_FUNCTION__, general_max_422chroma_constraint_flag, general_max_420chroma_constraint_flag, general_max_monochrome_constraint_flag);
general_intra_constraint_flag = bs.GetBit(); // general_intra_constraint_flag
general_one_picture_only_constraint_flag = bs.GetBit(); // general_one_picture_only_constraint_flag
general_lower_bit_rate_constraint_flag = bs.GetBit(); // general_lower_bit_rate_constraint_flag
debug2("%s general_intra_constraint_flag=%d general_one_picture_only_constraint_flag=%d general_lower_bit_rate_constraint_flag=%d", __PRETTY_FUNCTION__, general_intra_constraint_flag, general_one_picture_only_constraint_flag, general_lower_bit_rate_constraint_flag);
bs.SkipBits(34); // general_reserved_zero_34bits
}
else
bs.SkipBits(43); // general_reserved_zero_43bits
// the number of bits in this syntax structure is not affected by this condition
bs.SkipBit(); // general_reserved_zero_bit
}
general_level_idc = bs.GetBits(8); // general_level_idc
debug2("%s general_profile_idc=%d general_tier_flag=%d general_level_idc=%d", __PRETTY_FUNCTION__, general_profile_idc, general_tier_flag, general_level_idc);
switch (general_profile_idc) {
default:
case 0:
profile_name = "None";
break;
case 1:
profile_name = "Main";
break;
case 2:
profile_name = "Main 10";
break;
case 3:
profile_name = "Main Still Picture";
break;
case 4:
profile_name = "Format Range Extensions";
break;
case 5:
profile_name = "Format Range Extensions High Throughput";
break;
}
if (general_profile_idc == 1 || general_profile_idc == 2)
switch (general_level_idc) {
case 30: // level 1
bit_rate = general_tier_flag ? 0 : 128000;
break;
case 60: // level 2
bit_rate = general_tier_flag ? 0 : 1500000;
break;
case 63: // level 2.1
bit_rate = general_tier_flag ? 0 : 3000000;
break;
case 90: // level 3
bit_rate = general_tier_flag ? 0 : 6000000;
break;
case 93: // level 3
bit_rate = general_tier_flag ? 0 : 10000000;
break;
case 120: // level 4
bit_rate = general_tier_flag ? 30000000 : 12000000;
break;
case 123: // level 4.1
bit_rate = general_tier_flag ? 50000000 : 20000000;
break;
case 150: // level 5
bit_rate = general_tier_flag ? 100000000 : 25000000;
break;
case 153: // level 5.1
bit_rate = general_tier_flag ? 160000000 : 40000000;
break;
case 156: // level 5.2
bit_rate = general_tier_flag ? 240000000 : 60000000;
break;
case 180: // level 6
bit_rate = general_tier_flag ? 240000000 : 60000000;
break;
case 183: // level 6.1
bit_rate = general_tier_flag ? 480000000 : 120000000;
break;
case 186: // level 6.2
bit_rate = general_tier_flag ? 800000000 : 240000000;
break;
default:
bit_rate = 0;
break;
}
else
bit_rate = 0;
debug2("%s profile=\"%s@L%.1f@%s\" bit_rate=%.f", __PRETTY_FUNCTION__, profile_name, (double)general_level_idc / 30, general_tier_flag ? "High" : "Main", bit_rate);
for (int i = 0; i < sps_max_sub_layers_minus1; ++i) {
sub_layer_profile_present_flag[i] = bs.GetBit(); // sub_layer_profile_present_flag[i]
sub_layer_level_present_flag[i] = bs.GetBit(); // sub_layer_level_present_flag[i]
}
if (sps_max_sub_layers_minus1 > 0) {
for (int i = sps_max_sub_layers_minus1; i < 8; ++i)
bs.SkipBits(2); // reserved_zero_2bits[i]
}
for (int i = 0; i < sps_max_sub_layers_minus1; ++i) {
if (sub_layer_profile_present_flag[i]) {
bs.SkipBits(2); // sub_layer_profile_space[i]
bs.SkipBit(); // sub_layer_tier_flag[i]
bs.SkipBits(5); // sub_layer_profile_idc[i]
bs.SkipBits(32); // sub_layer_profile_compatibility_flag[i][0-31]
bs.SkipBit(); // sub_layer_progressive_source_flag[i]
bs.SkipBit(); // sub_layer_interlaced_source_flag[i]
bs.SkipBit(); // sub_layer_non_packed_constraint_flag[i]
bs.SkipBit(); // sub_layer_frame_only_constraint_flag[i]
// the number of bits in this syntax structure is not affected by this condition
bs.SkipBits(43); // sub_layer_reserved_zero_43bits[i]
// the number of bits in this syntax structure is not affected by this condition
bs.SkipBit(); // sub_layer_reserved_zero_bit[i]
}
if (sub_layer_level_present_flag[i])
bs.SkipBits(8); // sub_layer_level_idc[i]
}
// end of profile_tier_level
bs.SkipUeGolomb(); // sps_seq_parameter_set_id
chroma_format_idc = bs.GetUeGolomb(); // chroma_format_idc
if (chroma_format_idc == 3)
bs.SkipBit(); // separate_colour_plane_flag
width = bs.GetUeGolomb(); // pic_width_in_luma_samples
height = bs.GetUeGolomb(); // pic_height_in_luma_samples
conformance_window_flag = bs.GetBit(); // conformance_window_flag
if (conformance_window_flag) {
bs.SkipUeGolomb(); // conf_win_left_offset
bs.SkipUeGolomb(); // conf_win_right_offset
bs.SkipUeGolomb(); // conf_win_top_offset
bs.SkipUeGolomb(); // conf_win_bottom_offset
}
bs.SkipUeGolomb(); // bit_depth_luma_minus8
bs.SkipUeGolomb(); // bit_depth_chroma_minus8
log2_max_pic_order_cnt_lsb_minus4 = bs.GetUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4
sps_sub_layer_ordering_info_present_flag = bs.GetBit(); // sps_sub_layer_ordering_info_present_flag
for (int i = (sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1); i <= sps_max_sub_layers_minus1; ++i) {
bs.SkipUeGolomb(); // sps_max_dec_pic_buffering_minus1[i]
bs.SkipUeGolomb(); // sps_max_num_reorder_pics[i]
bs.SkipUeGolomb(); // sps_max_latency_increase_plus1[i]
}
bs.SkipUeGolomb(); // log2_min_luma_coding_block_size_minus3
bs.SkipUeGolomb(); // log2_diff_max_min_luma_coding_block_size
bs.SkipUeGolomb(); // log2_min_luma_transform_block_size_minus2
bs.SkipUeGolomb(); // log2_diff_max_min_luma_transform_block_size
bs.SkipUeGolomb(); // max_transform_hierarchy_depth_inter
bs.SkipUeGolomb(); // max_transform_hierarchy_depth_intra
if (bs.GetBit()) { // scaling_list_enabled_flag
if (bs.GetBit()) { // sps_scaling_list_data_present_flag
// start of scaling_list_data()
for (int sizeId = 0; sizeId < 4; ++sizeId) {
for (int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
if (!bs.GetBit()) // scaling_list_pred_mode_flag[sizeId][matrixId]
bs.SkipUeGolomb(); // scaling_list_pred_matrix_id_delta[sizeId][matrixId]
else {
int coefNum = min(64, (1 << (4 + (sizeId << 1))));
if (sizeId > 1)
bs.SkipSeGolomb(); // scaling_list_dc_coef_minus8[sizeId2][matrixId]
for (int i = 0; i < coefNum; ++i)
bs.SkipSeGolomb(); // scaling_list_delta_coef
}
}
}
// end of scaling_list_data()
}
}
bs.SkipBit(); // amp_enabled_flag
bs.SkipBit(); // sample_adaptive_offset_enabled_flag
if (bs.GetBit()) { // pcm_enabled_flag
bs.SkipBits(4); // pcm_sample_bit_depth_luma_minus1
bs.SkipBits(4); // pcm_sample_bit_depth_chroma_minus1
bs.SkipUeGolomb(); // log2_min_pcm_luma_coding_block_size_minus3
bs.SkipUeGolomb(); // log2_diff_max_min_pcm_luma_coding_block_size
bs.SkipBit(); // pcm_loop_filter_disabled_flag
}
num_short_term_ref_pic_sets = bs.GetUeGolomb(); // num_short_term_ref_pic_sets
uint32_t NumDeltaPocs[num_short_term_ref_pic_sets];
for (uint32_t stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; ++stRpsIdx) {
// start of st_ref_pic_set(stRpsIdx)
bool inter_ref_pic_set_prediction_flag = false;
if (stRpsIdx != 0)
inter_ref_pic_set_prediction_flag = bs.GetBit(); // inter_ref_pic_set_prediction_flag
if (inter_ref_pic_set_prediction_flag) {
uint32_t RefRpsIdx, delta_idx_minus1 = 0;
if (stRpsIdx == num_short_term_ref_pic_sets)
delta_idx_minus1 = bs.GetUeGolomb(); // delta_idx_minus1
bs.SkipBit(); // delta_rps_sign
bs.SkipUeGolomb(); // abs_delta_rps_minus1
RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
NumDeltaPocs[stRpsIdx] = 0;
for (uint32_t j = 0; j <= NumDeltaPocs[RefRpsIdx]; ++j) {
if (!bs.GetBit()) { // used_by_curr_pic_flag[j]
if (bs.GetBit()) // use_delta_flag[j]
NumDeltaPocs[stRpsIdx]++;
}
else
NumDeltaPocs[stRpsIdx]++;
}
}
else {
uint32_t num_negative_pics = bs.GetUeGolomb(); // num_negative_pics
uint32_t num_positive_pics = bs.GetUeGolomb(); // num_positive_pics
for (uint32_t j = 0; j < num_negative_pics; ++j) {
bs.SkipUeGolomb(); // delta_poc_s0_minus1[i]
bs.SkipBit(); // used_by_curr_pic_s0_flag[i]
}
for (uint32_t j = 0; j < num_positive_pics; ++j) {
bs.SkipUeGolomb(); // delta_poc_s1_minus1[i]
bs.SkipBit(); // delta_poc_s1_minus1[i]
}
NumDeltaPocs[stRpsIdx] = num_negative_pics + num_positive_pics;
}
// end of st_ref_pic_set(stRpsIdx)
}
if (bs.GetBit()) { // long_term_ref_pics_present_flag
num_long_term_ref_pics_sps = bs.GetUeGolomb(); // num_long_term_ref_pics_sps
for (uint32_t i = 0; i < num_long_term_ref_pics_sps; ++i) {
bs.SkipBits(log2_max_pic_order_cnt_lsb_minus4 + 4); // lt_ref_pic_poc_lsb_sps[i]
bs.SkipBit(); // used_by_curr_pic_lt_sps_flag[i]
}
}
bs.SkipBit(); // sps_temporal_mvp_enabled_flag
bs.SkipBit(); // strong_intra_smoothing_enabled_flag
if (bs.GetBit()) { // vui_parameters_present_flag
// start of vui_parameters()
if (bs.GetBit()) { // aspect_ratio_info_present_flag
uint32_t sar_width = 0, sar_height = 0;
uint8_t aspect_ratio_idc = bs.GetBits(8); // aspect_ratio_idc
debug2("%s aspect_ratio_idc=%d", __PRETTY_FUNCTION__, aspect_ratio_idc);
if (aspect_ratio_idc == 255) { // EXTENDED_SAR
sar_width = bs.GetBits(16); // sar_width
sar_height = bs.GetBits(16); // sar_height
}
else if (aspect_ratio_idc < ELEMENTS(sarS)) {
sar_width = sarS[aspect_ratio_idc].w;
sar_height = sarS[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(darS); ++i) {
if (darS[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 = darS[index].dar;
debug2("%s sar_width=%d sar_height=%d aspect_ratio=%d", __PRETTY_FUNCTION__, sar_width, sar_height, aspect_ratio);
}
}
if (bs.GetBit()) // overscan_info_present_flag
bs.SkipBit(); // overscan_appropriate_flag
if (bs.GetBit()) { // video_signal_type_present_flag
uint32_t video_format = bs.GetBits(3); // video_format
if (video_format < ELEMENTS(videoFormatS)) {
format = videoFormatS[video_format];
debug2("%s video_format=%d format=%d", __PRETTY_FUNCTION__, video_format, format);
}
bs.SkipBit(); // video_full_range_flag
if (bs.GetBit()) { // colour_description_present_flag
bs.SkipBits(8); // colour_primaries
bs.SkipBits(8); // transfer_characteristics
bs.SkipBits(8); // matrix_coeffs
}
}
if (bs.GetBit()) { // chroma_loc_info_present_flag
bs.SkipUeGolomb(); // chroma_sample_loc_type_top_field
bs.SkipUeGolomb(); // chroma_sample_loc_type_bottom_field
}
bs.SkipBit(); // neutral_chroma_indication_flag
bs.SkipBit(); // field_seq_flag
frame_field_info_present_flag = bs.GetBit(); // frame_field_info_present_flag
debug2("%s frame_field_info_present_flag=%d", __PRETTY_FUNCTION__, frame_field_info_present_flag);
if (bs.GetBit()) { // default_display_window_flag
bs.SkipUeGolomb(); // def_disp_win_left_offset
bs.SkipUeGolomb(); // def_disp_win_right_offset
bs.SkipUeGolomb(); // def_disp_win_top_offset
bs.SkipUeGolomb(); // def_disp_win_bottom_offset
}
if (bs.GetBit()) { // vui_timing_info_present_flag
uint32_t vui_num_units_in_tick = bs.GetBits(32); // vui_num_units_in_tick
uint32_t vui_time_scale = bs.GetBits(32); // vui_time_scale
if (vui_num_units_in_tick > 0) {
frame_rate = (double)vui_time_scale / vui_num_units_in_tick;
debug2("%s frame_rate = vui_time_scale(%d) / vui_num_units_in_tick(%d) = %.f", __PRETTY_FUNCTION__, vui_time_scale, vui_num_units_in_tick, frame_rate);
}
if (bs.GetBit()) // vui_poc_proportional_to_timing_flag
bs.SkipUeGolomb(); // vui_num_ticks_poc_diff_one_minus1
if (bs.GetBit()) { // vui_hrd_parameters_present_flag
// start of hrd_parameters(1, sps_max_sub_layers_minus1)
uint32_t bit_rate_scale = 0;
bool commonInfPresentFlag = true, nal_hrd_parameters_present_flag = false, vcl_hrd_parameters_present_flag = false, sub_pic_hrd_params_present_flag = false;
if (commonInfPresentFlag) {
nal_hrd_parameters_present_flag = bs.GetBit(); // nal_hrd_parameters_present_flag
vcl_hrd_parameters_present_flag = bs.GetBit(); // vcl_hrd_parameters_present_flag
if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
sub_pic_hrd_params_present_flag = bs.GetBit(); // sub_pic_hrd_params_present_flag
if (sub_pic_hrd_params_present_flag) {
bs.SkipBits(8); // tick_divisor_minus2
bs.SkipBits(5); // du_cpb_removal_delay_increment_length_minus1
bs.SkipBit(); // sub_pic_cpb_params_in_pic_timing_sei_flag
bs.SkipBits(5); // dpb_output_delay_du_length_minus1
}
bit_rate_scale = bs.GetBits(4); // bit_rate_scale
bs.SkipBits(4); // cpb_size_scale
if (sub_pic_hrd_params_present_flag)
bs.SkipBits(4); // cpb_size_du_scale
bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1
bs.SkipBits(5); // au_cpb_removal_delay_length_minus1
bs.SkipBits(5); // dpb_output_delay_length_minus1
}
}
for (uint32_t i = 0; i <= sps_max_sub_layers_minus1; ++i) {
bool fixed_pic_rate_within_cvs_flag = false, low_delay_hrd_flag = false;
uint32_t cpb_cnt_minus1 = 0;
if (!bs.GetBit()) // fixed_pic_rate_general_flag[i]
fixed_pic_rate_within_cvs_flag = bs.GetBit(); // fixed_pic_rate_within_cvs_flag[i]
if (fixed_pic_rate_within_cvs_flag)
bs.SkipUeGolomb(); // elemental_duration_in_tc_minus1[i]
else
low_delay_hrd_flag = bs.GetBit(); // low_delay_hrd_flag[i]
if (!low_delay_hrd_flag)
cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1[i]
if (nal_hrd_parameters_present_flag) {
// start of sub_layer_hrd_parameters(i)
for (uint32_t i = 0; i <= cpb_cnt_minus1; ++i) {
uint32_t bit_rate_value_minus1;
bit_rate_value_minus1 = bs.GetUeGolomb(); // bit_rate_value_minus1[i]
bs.SkipUeGolomb(); // cpb_size_value_minus1[i]
if (sub_pic_hrd_params_present_flag) {
bs.SkipUeGolomb(); // cpb_size_du_value_minus1[i]
bs.SkipUeGolomb(); // bit_rate_du_value_minus1[i]
}
else {
double bitrate = (double)((bit_rate_value_minus1 + 1) * pow(2.0, 6 + bit_rate_scale));
debug2("%s bit_rate_value_minus1(%u) + 1 * 2 ^ (6 + bit_rate_scale(%u)) = %.f", __PRETTY_FUNCTION__, bit_rate_value_minus1, bit_rate_scale, bitrate);
}
bs.SkipBit(); // cbr_flag[i]
}
// end of sub_layer_hrd_parameters(i)
}
if (vcl_hrd_parameters_present_flag) {
// start of sub_layer_hrd_parameters(i)
for (uint32_t i = 0; i <= cpb_cnt_minus1; ++i) {
bs.SkipUeGolomb(); // bit_rate_value_minus1[i]
bs.SkipUeGolomb(); // cpb_size_value_minus1[i]
if (sub_pic_hrd_params_present_flag) {
bs.SkipUeGolomb(); // cpb_size_du_value_minus1[i]
bs.SkipUeGolomb(); // bit_rate_du_value_minus1[i]
}
bs.SkipBit(); // cbr_flag[i]
}
// end of sub_layer_hrd_parameters(i)
}
}
// end of hrd_parameters(1, sps_max_sub_layers_minus1)
}
}
if (bs.GetBit()) { // bitstream_restriction_flag
bs.SkipBit(); // tiles_fixed_structure_flag
bs.SkipBit(); // motion_vectors_over_pic_boundaries_flag
bs.SkipBit(); // restricted_ref_pic_lists_flag
bs.SkipUeGolomb(); // min_spatial_segmentation_idc
bs.SkipUeGolomb(); // max_bytes_per_pic_denom
bs.SkipUeGolomb(); // max_bits_per_min_cu_denom
bs.SkipUeGolomb(); // log2_max_mv_length_horizontal
bs.SkipUeGolomb(); // log2_max_mv_length_vertical
}
// end of vui_parameters()
}
if (bs.GetBit()) { // sps_extension_present_flag
bs.SkipBit(); // sps_range_extension_flag
bs.SkipBit(); // sps_multilayer_extension_flag
bs.SkipBit(); // sps_3d_extension_flag
bs.SkipBits(5); // sps_extension_5bits
}
widthM = width;
heightM = height;
formatM = format;
aspectRatioM = aspect_ratio;
scanM = scan;
frameRateM = frame_rate;
bitRateM = bit_rate;
frameFieldInfoPresentFlagM = frame_field_info_present_flag;
return (bs.Index() / 8);
}
int cFemonH265::parseSEI(const uint8_t *bufP, int lenP)
{
cFemonBitStream bs(bufP, lenP);
eVideoScan scan = scanM;
while ((bs.Index() * 8 + 16) < lenP) { // sei_message
int len, lastByte, payloadSize = 0, payloadType = 0;
do {
lastByte = bs.GetBits(8) & 0xFF;
payloadType += lastByte;
} while (lastByte == 0xFF); // last_payload_type_byte
do {
lastByte = bs.GetBits(8) & 0xFF;
payloadSize += lastByte;
} while (lastByte == 0xFF); // last_payload_size_byte
switch (payloadType) { // sei_payload
case 1: // pic_timing
len = payloadSize * 8;
if (frameFieldInfoPresentFlagM) {
uint8_t pic_struct = bs.GetBits(4); // pic_struct
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
case 9: // top paired with previous bottom
case 10: // bottom paired with previous top
case 11: // top paired with next bottom
case 12: // bottom paired with next top
scan = VIDEO_SCAN_INTERLACED;
break;
default:
scan = VIDEO_SCAN_RESERVED;
break;
}
debug2("%s pic_struct=%d scan_type=%d", __PRETTY_FUNCTION__, pic_struct, scan);
bs.SkipBits(2); // source_scan_type
bs.SkipBit(); // duplicate_flag
len -= 7;
}
bs.SkipBits(len);
break;
default:
bs.SkipBits(payloadSize * 8);
break;
}
// force byte align
bs.ByteAlign();
}
scanM = scan;
return (bs.Index() / 8);
}

62
h265.h Normal file
View File

@ -0,0 +1,62 @@
/*
* h265.h: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef __FEMON_H265_H
#define __FEMON_H265_H
#include "video.h"
class cFemonH265 {
private:
enum {
NAL_VPS = 32, // Video Parameter Set
NAL_SPS = 33, // Sequence Parameter Set
NAL_PPS = 34, // Picture Parameter Set
NAL_AUD = 35, // Access Unit Delimiter
NAL_EOS = 36, // End of Sequence
NAL_EOB = 37, // End of Bitstream
NAL_SEI = 39, // Prefix Supplemental Enchancement Information
};
typedef struct DAR {
eVideoAspectRatio dar;
int ratio;
} t_DAR;
typedef struct SAR {
int w;
int h;
} t_SAR;
cFemonVideoIf *videoHandlerM;
uint32_t widthM;
uint32_t heightM;
eVideoAspectRatio aspectRatioM;
eVideoFormat formatM;
double frameRateM;
double bitRateM;
eVideoScan scanM;
bool frameFieldInfoPresentFlagM;
void reset();
const uint8_t *nextStartCode(const uint8_t *start, const uint8_t *end);
int nalUnescape(uint8_t *dst, const uint8_t *src, int len);
int parseSPS(const uint8_t *buf, int len);
int parseSEI(const uint8_t *buf, int len);
static const t_SAR sarS[];
static const t_DAR darS[];
static const eVideoFormat videoFormatS[];
public:
cFemonH265(cFemonVideoIf *videoHandlerP);
virtual ~cFemonH265();
bool processVideo(const uint8_t *bufP, int lenP);
};
#endif //__FEMON_H265_H

332
osd.c
View File

@ -27,7 +27,7 @@
#define OSDHEIGHT osdHeightM // in pixels
#define OSDROWHEIGHT fontM->Height() // in pixels
#define OSDINFOHEIGHT (OSDROWHEIGHT * 14) // in pixels (14 rows)
#define OSDSTATUSHEIGHT (OSDROWHEIGHT * 6) // in pixels (6 rows)
#define OSDSTATUSHEIGHT (OSDROWHEIGHT * 5) // in pixels (5 rows)
#define OSDSYMBOL(id) femonSymbols.Get(id)
#define OSDSPACING femonSymbols.GetSpacing()
#define OSDROUNDING femonSymbols.GetRounding()
@ -39,12 +39,11 @@
(col == 2) ? int(round(OSDWIDTH * 0.26)) : \
int(round(OSDWIDTH * 0.025)))
#define OSDSTATUSWIN_Y(offset) (FemonConfig.GetPosition() ? offset : (OSDHEIGHT - OSDSTATUSHEIGHT + offset))
#define OSDSTATUSWIN_X(col) ((col == 7) ? int(round(OSDWIDTH * 0.79)) : \
(col == 6) ? int(round(OSDWIDTH * 0.68)) : \
(col == 5) ? int(round(OSDWIDTH * 0.46)) : \
(col == 4) ? int(round(OSDWIDTH * 0.37)) : \
(col == 3) ? int(round(OSDWIDTH * 0.21)) : \
(col == 2) ? int(round(OSDWIDTH * 0.12)) : \
#define OSDSTATUSWIN_X(col) ((col == 6) ? int(round(OSDWIDTH * 0.84)) : \
(col == 5) ? int(round(OSDWIDTH * 0.66)) : \
(col == 4) ? int(round(OSDWIDTH * 0.50)) : \
(col == 3) ? int(round(OSDWIDTH * 0.35)) : \
(col == 2) ? int(round(OSDWIDTH * 0.19)) : \
int(round(OSDWIDTH * 0.025)))
#define OSDSTATUSWIN_XSYMBOL(c,w) (c * ((OSDWIDTH - (5 * w)) / 6) + ((c - 1) * w))
#define OSDBARWIDTH(x) (OSDWIDTH * x / 100)
@ -60,14 +59,13 @@
#define OSDDRAWSTATUSFRONTEND(column, bitmap, status) \
osdM->DrawBitmap(OSDSTATUSWIN_XSYMBOL(column, x), OSDSTATUSWIN_Y(offset) + y, bitmap, (frontendStatusM & status) ? FemonTheme[FemonConfig.GetTheme()].clrActiveText : FemonTheme[FemonConfig.GetTheme()].clrRed, FemonTheme[FemonConfig.GetTheme()].clrBackground)
#define OSDDRAWSTATUSVALUES(label1, label2, label3, label4, label5, label6, label7) \
#define OSDDRAWSTATUSVALUES(label1, label2, label3, label4, label5, label6) \
osdM->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), label1, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), label2, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), label3, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), label4, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), label5, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), label6, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \
osdM->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), label7, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM)
osdM->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), label6, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM)
#define OSDDRAWSTATUSBAR(value) \
if (value > 0) { \
@ -144,6 +142,7 @@
class cFemonDummyFont : public cFont {
public:
virtual int Width(void) const { return 10; }
virtual int Width(uint cP) const { return 10; }
virtual int Width(const char *sP) const { return 50; }
virtual int Height(void) const { return 20; }
@ -167,7 +166,6 @@ cFemonOsd::cFemonOsd()
: cOsdObject(true), cThread("femon osd"),
osdM(NULL),
receiverM(NULL),
frontendM(-1),
svdrpFrontendM(-1),
svdrpVideoBitRateM(-1),
svdrpAudioBitRateM(-1),
@ -178,15 +176,17 @@ cFemonOsd::cFemonOsd()
qualityValidM(false),
strengthM(0),
strengthValidM(false),
snrM(0),
snrValidM(false),
cnrM(0),
cnrValidM(false),
signalM(0),
signalValidM(false),
berM(0),
berValidM(false),
uncM(0),
uncValidM(false),
perM(0),
perValidM(false),
frontendNameM(""),
frontendTypeM(""),
frontendStatusM(DTV_STAT_HAS_NONE),
frontendStatusValidM(false),
deviceSourceM(DEVICESOURCE_DVBAPI),
displayModeM(FemonConfig.GetDisplayMode()),
@ -200,8 +200,6 @@ cFemonOsd::cFemonOsd()
{
int tmp;
debug1("%s", __PRETTY_FUNCTION__);
memset(&frontendStatusM, 0, sizeof(frontendStatusM));
memset(&frontendInfoM, 0, sizeof(frontendInfoM));
svdrpConnectionM.handle = -1;
femonSymbols.Refresh();
fontM = cFont::CreateFont(Setup.FontSml, constrain(Setup.FontSmlSize, MINFONTSIZE, MAXFONTSIZE));
@ -240,17 +238,14 @@ cFemonOsd::~cFemonOsd(void)
DELETENULL(osdM);
if (fontM)
DELETENULL(fontM);
if (frontendM >= 0) {
close(frontendM);
frontendM = -1;
}
pInstanceS = NULL;
}
void cFemonOsd::DrawStatusWindow(void)
{
cMutexLock lock(&mutexM);
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (osdM && channel) {
cBitmap *bm = NULL;
@ -305,7 +300,14 @@ void cFemonOsd::DrawStatusWindow(void)
OSDDRAWSTATUSBM(OSDSPACING);
}
if (receiverM) {
if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 1080)) {
if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 2160)) {
switch (receiverM->VideoScan()) {
case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_2160i); break;
case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_2160p); break;
default: bm = &OSDSYMBOL(SYMBOL_FORMAT_2160); break;
}
}
else if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 1080)) {
switch (receiverM->VideoScan()) {
case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080i); break;
case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080p); break;
@ -339,6 +341,7 @@ void cFemonOsd::DrawStatusWindow(void)
switch (receiverM->VideoCodec()) {
case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break;
case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break;
case VIDEO_CODEC_H265: bm = &OSDSYMBOL(SYMBOL_H265); break;
default: bm = NULL; break;
}
OSDDRAWSTATUSBM(OSDSPACING);
@ -368,23 +371,22 @@ void cFemonOsd::DrawStatusWindow(void)
if (qualityValidM)
OSDDRAWSTATUSBAR(qualityM);
offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("STR:", signalValidM ? *cString::sprintf("%04x", signalM) : "", signalValidM ? *cString::sprintf("(%2d%%)", signalM / 655) : "",
"BER:", berValidM ? *cString::sprintf("%08x", berM) : "", *cString::sprintf("%s:", tr("Video")),
*getBitrateMbits(receiverM ? receiverM->VideoBitrate() : (svdrpFrontendM >= 0 ? svdrpVideoBitRateM : -1.0)));
offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("SNR:", snrValidM ? *cString::sprintf("%04x", snrM) : "", snrValidM ? *cString::sprintf("(%2d%%)", snrM / 655) : "",
"UNC:", uncValidM ? *cString::sprintf("%08x", uncM) : "",
*cString::sprintf("%s:", (receiverM && receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")),
*getBitrateKbits(receiverM ? ((receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) ? receiverM->AC3Bitrate() : receiverM->AudioBitrate()) : (svdrpFrontendM >= 0 ? svdrpAudioBitRateM : -1.0)));
OSDDRAWSTATUSVALUES(signalValidM ? *cString::sprintf("STR: %s", *getSignalStrength(signalM)) : "STR: ---",
cnrValidM ? *cString::sprintf("CNR: %.2f dB", cnrM) : "CNR: ---",
berValidM ? *cString::sprintf("BER: %.0f", berM) : "BER: ---",
perValidM ? *cString::sprintf("PER: %.0f", perM) : "PER: ---",
*cString::sprintf("%s: %s", tr("Video"), *getBitrateMbits(receiverM ? receiverM->VideoBitrate() : (svdrpFrontendM >= 0 ? svdrpVideoBitRateM : -1.0))),
*cString::sprintf("%s: %s", (receiverM && receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio"), *getBitrateKbits(receiverM ? ((receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) ? receiverM->AC3Bitrate() : receiverM->AudioBitrate()) : (svdrpFrontendM >= 0 ? svdrpAudioBitRateM : -1.0)))
);
offset += OSDROWHEIGHT;
x = OSDSYMBOL(SYMBOL_LOCK).Width();
y = (OSDROWHEIGHT - OSDSYMBOL(SYMBOL_LOCK).Height()) / 2;
if (frontendStatusValidM) {
OSDDRAWSTATUSFRONTEND(1, OSDSYMBOL(SYMBOL_LOCK), FE_HAS_LOCK);
OSDDRAWSTATUSFRONTEND(2, OSDSYMBOL(SYMBOL_SIGNAL), FE_HAS_SIGNAL);
OSDDRAWSTATUSFRONTEND(3, OSDSYMBOL(SYMBOL_CARRIER), FE_HAS_CARRIER);
OSDDRAWSTATUSFRONTEND(4, OSDSYMBOL(SYMBOL_VITERBI), FE_HAS_VITERBI);
OSDDRAWSTATUSFRONTEND(5, OSDSYMBOL(SYMBOL_SYNC), FE_HAS_SYNC);
OSDDRAWSTATUSFRONTEND(1, OSDSYMBOL(SYMBOL_LOCK), DTV_STAT_HAS_LOCK);
OSDDRAWSTATUSFRONTEND(2, OSDSYMBOL(SYMBOL_SIGNAL), DTV_STAT_HAS_SIGNAL);
OSDDRAWSTATUSFRONTEND(3, OSDSYMBOL(SYMBOL_CARRIER), DTV_STAT_HAS_CARRIER);
OSDDRAWSTATUSFRONTEND(4, OSDSYMBOL(SYMBOL_VITERBI), DTV_STAT_HAS_VITERBI);
OSDDRAWSTATUSFRONTEND(5, OSDSYMBOL(SYMBOL_SYNC), DTV_STAT_HAS_SYNC);
}
OSDDRAWSTATUSBOTTOMBAR();
osdM->Flush();
@ -394,7 +396,8 @@ void cFemonOsd::DrawStatusWindow(void)
void cFemonOsd::DrawInfoWindow(void)
{
cMutexLock lock(&mutexM);
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (osdM && channel) {
int offset = 0;
@ -590,16 +593,16 @@ void cFemonOsd::Action(void)
strengthM = cDevice::ActualDevice()->SignalStrength();
strengthValidM = (strengthM >= 0);
frontendNameM = cDevice::ActualDevice()->DeviceName();
frontendStatusM = (fe_status_t)(strengthValidM ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0);
frontendStatusM = strengthValidM ? (DTV_STAT_HAS_SIGNAL | DTV_STAT_HAS_CARRIER | DTV_STAT_HAS_VITERBI | DTV_STAT_HAS_SYNC | DTV_STAT_HAS_LOCK) : DTV_STAT_HAS_NONE;
frontendStatusValidM = strengthValidM;
signalM = uint16_t(strengthM * 0xFFFF / 100);
signalM = strengthM;
signalValidM = strengthValidM;
snrM = 0;
snrValidM = false;
cnrM = 0;
cnrValidM = false;
berM = 0;
berValidM = false;
uncM = 0;
uncValidM = false;
perM = 0;
perValidM = false;
break;
case DEVICESOURCE_IPTV:
qualityM = cDevice::ActualDevice()->SignalQuality();
@ -607,49 +610,20 @@ void cFemonOsd::Action(void)
strengthM = cDevice::ActualDevice()->SignalStrength();
strengthValidM = (strengthM >= 0);
frontendNameM = cDevice::ActualDevice()->DeviceName();
frontendStatusM = (fe_status_t)(strengthValidM ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0);
frontendStatusM = strengthValidM ? (DTV_STAT_HAS_SIGNAL | DTV_STAT_HAS_CARRIER | DTV_STAT_HAS_VITERBI | DTV_STAT_HAS_SYNC | DTV_STAT_HAS_LOCK) : DTV_STAT_HAS_NONE;
frontendStatusValidM = strengthValidM;
signalM = uint16_t(strengthM * 0xFFFF / 100);
signalM = strengthM;
signalValidM = strengthValidM;
snrM = uint16_t(qualityM * 0xFFFF / 100);
snrValidM = qualityValidM;
cnrM = qualityM;
cnrValidM = qualityValidM;
berM = 0;
berValidM = false;
uncM = 0;
uncValidM = false;
perM = 0;
perValidM = false;
break;
default:
case DEVICESOURCE_DVBAPI:
if (frontendM != -1) {
qualityM = cDevice::ActualDevice()->SignalQuality();
qualityValidM = (qualityM >= 0);
strengthM = cDevice::ActualDevice()->SignalStrength();
strengthValidM = (strengthM >= 0);
frontendNameM = cDevice::ActualDevice()->DeviceName();
frontendStatusValidM = (ioctl(frontendM, FE_READ_STATUS, &frontendStatusM) >= 0);
signalValidM = (ioctl(frontendM, FE_READ_SIGNAL_STRENGTH, &signalM) >= 0);
snrValidM = (ioctl(frontendM, FE_READ_SNR, &snrM) >= 0);
berValidM = (ioctl(frontendM, FE_READ_BER, &berM) >= 0);
uncValidM = (ioctl(frontendM, FE_READ_UNCORRECTED_BLOCKS, &uncM) >= 0);
}
else if (strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) {
qualityM = cDevice::ActualDevice()->SignalQuality();
qualityValidM = (qualityM >= 0);
strengthM = cDevice::ActualDevice()->SignalStrength();
strengthValidM = (strengthM >= 0);
frontendNameM = cDevice::ActualDevice()->DeviceName();
frontendStatusM = (fe_status_t)(cDevice::ActualDevice()->HasLock() ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0);
frontendStatusValidM = strengthValidM;
signalM = uint16_t(strengthM * 0xFFFF / 100);
signalValidM = strengthValidM;
snrM = uint16_t(qualityM * 0xFFFF / 100);
snrValidM = qualityValidM;
berM = 0;
berValidM = false;
uncM = 0;
uncValidM = false;
}
else if (svdrpConnectionM.handle >= 0) {
if (svdrpConnectionM.handle >= 0) {
cmd.handle = svdrpConnectionM.handle;
svdrpPluginM->Service("SvdrpCommand-v1.0", &cmd);
if (cmd.responseCode == 900) {
@ -657,9 +631,9 @@ void cFemonOsd::Action(void)
qualityValidM = false;
frontendStatusValidM = false;
signalValidM = false;
snrValidM = false;
cnrValidM = false;
berValidM = false;
uncValidM = false;
perValidM = false;
for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) {
const char *s = line->Text();
if (!strncasecmp(s, "CARD:", 5))
@ -672,38 +646,61 @@ void cFemonOsd::Action(void)
qualityM = (int)strtol(s + 5, NULL, 10);
qualityValidM = (qualityM >= 0);
}
else if (!strncasecmp(s, "TYPE:", 5))
frontendInfoM.type = (fe_type_t)strtol(s + 5, NULL, 10);
else if (!strncasecmp(s, "TYPE:", 5)) {
frontendTypeM = s + 5;
}
else if (!strncasecmp(s, "NAME:", 5)) {
frontendNameM = s + 5;
}
else if (!strncasecmp(s, "STAT:", 5)) {
frontendStatusM = (fe_status_t)strtol(s + 5, NULL, 16);
frontendStatusM = strtol(s + 5, NULL, 16);
frontendStatusValidM = true;
}
else if (!strncasecmp(s, "SGNL:", 5)) {
signalM = (uint16_t)strtol(s + 5, NULL, 16);
signalM = atod(s + 5);
signalValidM = true;
}
else if (!strncasecmp(s, "SNRA:", 5)) {
snrM = (uint16_t)strtol(s + 5, NULL, 16);
snrValidM = true;
else if (!strncasecmp(s, "CNRA:", 5)) {
cnrM = atod(s + 5);
cnrValidM = true;
}
else if (!strncasecmp(s, "BERA:", 5)) {
berM = (uint32_t)strtol(s + 5, NULL, 16);
berM = atod(s + 5);
berValidM = true;
}
else if (!strncasecmp(s, "UNCB:", 5)) {
uncM = (uint32_t)strtol(s + 5, NULL, 16);
uncValidM = true;
else if (!strncasecmp(s, "PERA:", 5)) {
perM = atod(s + 5);
perValidM = true;
}
else if (!strncasecmp(s, "VIBR:", 5))
svdrpVideoBitRateM = (double)strtol(s + 5, NULL, 10);
svdrpVideoBitRateM = atod(s + 5);
else if (!strncasecmp(s, "AUBR:", 5))
svdrpAudioBitRateM = (double)strtol(s + 5, NULL, 10);
svdrpAudioBitRateM = atod(s + 5);
}
}
}
else {
int valid;
qualityM = cDevice::ActualDevice()->SignalQuality();
qualityValidM = (qualityM >= 0);
strengthM = cDevice::ActualDevice()->SignalStrength();
strengthValidM = (strengthM >= 0);
frontendNameM = cDevice::ActualDevice()->DeviceName();
if (cDevice::ActualDevice()->SignalStats(valid, &signalM, &cnrM, NULL, &berM, &perM, &frontendStatusM)) {
frontendStatusValidM = valid & DTV_STAT_VALID_STATUS;
signalValidM = valid & DTV_STAT_VALID_STRENGTH;
cnrValidM = valid & DTV_STAT_VALID_CNR;
berValidM = valid & DTV_STAT_VALID_BERPOST;
perValidM = valid & DTV_STAT_VALID_PER;
}
else {
frontendStatusValidM = false;
signalValidM = false;
cnrValidM = false;
berValidM = false;
perValidM = false;
}
}
break;
}
DrawInfoWindow();
@ -716,42 +713,10 @@ void cFemonOsd::Show(void)
{
debug1("%s", __PRETTY_FUNCTION__);
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
deviceSourceM = DEVICESOURCE_DVBAPI;
if (channel) {
if (channel->IsSourceType('I'))
deviceSourceM = DEVICESOURCE_IPTV;
else if (channel->IsSourceType('V'))
deviceSourceM = DEVICESOURCE_PVRINPUT;
}
if (deviceSourceM == DEVICESOURCE_DVBAPI) {
if (!strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) {
cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice());
frontendM = dev ? open(*cString::sprintf(FRONTEND_DEVICE, dev->Adapter(), dev->Frontend()), O_RDONLY | O_NONBLOCK) : -1;
if (frontendM >= 0) {
if (ioctl(frontendM, FE_GET_INFO, &frontendInfoM) < 0) {
if (!FemonConfig.GetUseSvdrp())
error("%s Cannot read frontend info", __PRETTY_FUNCTION__);
close(frontendM);
frontendM = -1;
memset(&frontendInfoM, 0, sizeof(frontendInfoM));
return;
}
}
else if (FemonConfig.GetUseSvdrp()) {
if (!SvdrpConnect() || !SvdrpTune())
return;
}
else {
error("%s Cannot open frontend device", __PRETTY_FUNCTION__);
return;
}
}
}
else
frontendM = -1;
AttachFrontend();
osdM = cOsdProvider::NewOsd(osdLeftM, osdTopM);
if (osdM) {
@ -780,11 +745,38 @@ void cFemonOsd::Show(void)
}
}
bool cFemonOsd::AttachFrontend(void)
{
debug1("%s", __PRETTY_FUNCTION__);
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
deviceSourceM = DEVICESOURCE_DVBAPI;
if (channel) {
if (channel->IsSourceType('I'))
deviceSourceM = DEVICESOURCE_IPTV;
else if (channel->IsSourceType('V'))
deviceSourceM = DEVICESOURCE_PVRINPUT;
}
if (deviceSourceM == DEVICESOURCE_DVBAPI) {
if (!strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) {
if (FemonConfig.GetUseSvdrp()) {
if (!SvdrpConnect() || !SvdrpTune())
return false;
}
}
}
return true;
}
void cFemonOsd::ChannelSwitch(const cDevice * deviceP, int channelNumberP, bool liveViewP)
{
debug1("%s (%d, %d, %d)", __PRETTY_FUNCTION__, deviceP->DeviceNumber(), channelNumberP, liveViewP);
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (!deviceP || !liveViewP)
return;
@ -797,49 +789,13 @@ void cFemonOsd::ChannelSwitch(const cDevice * deviceP, int channelNumberP, bool
return;
}
if (channel && FemonConfig.GetAnalyzeStream()) {
deviceSourceM = DEVICESOURCE_DVBAPI;
if (channel->IsSourceType('I'))
deviceSourceM = DEVICESOURCE_IPTV;
else if (channel->IsSourceType('V'))
deviceSourceM = DEVICESOURCE_PVRINPUT;
if (frontendM >= 0) {
close(frontendM);
frontendM = -1;
}
if (deviceSourceM == DEVICESOURCE_DVBAPI) {
if (!strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) {
cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice());
frontendM = dev ? open(*cString::sprintf(FRONTEND_DEVICE, dev->Adapter(), dev->Frontend()), O_RDONLY | O_NONBLOCK) : -1;
if (frontendM >= 0) {
if (ioctl(frontendM, FE_GET_INFO, &frontendInfoM) < 0) {
if (!FemonConfig.GetUseSvdrp())
error("%s Cannot read frontend info", __PRETTY_FUNCTION__);
close(frontendM);
frontendM = -1;
memset(&frontendInfoM, 0, sizeof(frontendInfoM));
return;
}
}
else if (FemonConfig.GetUseSvdrp()) {
if (!SvdrpConnect() || !SvdrpTune())
return;
}
else {
error("%s Cannot open frontend device", __PRETTY_FUNCTION__);
return;
}
}
if (receiverM) {
receiverM->Deactivate();
DELETENULL(receiverM);
}
receiverM = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
cDevice::ActualDevice()->AttachReceiver(receiverM);
if (channel && FemonConfig.GetAnalyzeStream() && AttachFrontend()) {
if (receiverM) {
receiverM->Deactivate();
DELETENULL(receiverM);
}
receiverM = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
cDevice::ActualDevice()->AttachReceiver(receiverM);
}
}
@ -852,7 +808,8 @@ void cFemonOsd::SetAudioTrack(int indexP, const char * const *tracksP)
DELETENULL(receiverM);
}
if (FemonConfig.GetAnalyzeStream()) {
const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (channel) {
receiverM = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
cDevice::ActualDevice()->AttachReceiver(receiverM);
@ -866,7 +823,8 @@ bool cFemonOsd::DeviceSwitch(int directionP)
int device = cDevice::ActualDevice()->DeviceNumber();
int direction = sgn(directionP);
if (device >= 0) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (channel) {
for (int i = 0; i < cDevice::NumDevices() - 1; i++) {
if (direction >= 0) {
@ -939,12 +897,13 @@ bool cFemonOsd::DeviceSwitch(int directionP)
d->CamSlot()->Assign(NULL);
d->SwitchChannel(channel, false);
cControl::Launch(new cTransferControl(d, channel));
return (true);
AttachFrontend();
return true;
}
}
}
}
return (false);
return false;
}
bool cFemonOsd::SvdrpConnect(void)
@ -978,7 +937,8 @@ bool cFemonOsd::SvdrpConnect(void)
bool cFemonOsd::SvdrpTune(void)
{
if (svdrpPluginM && svdrpConnectionM.handle >= 0) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (channel) {
SvdrpCommand_v1_0 cmd;
cmd.handle = svdrpConnectionM.handle;
@ -1038,7 +998,8 @@ eOSState cFemonOsd::ProcessKey(eKeys keyP)
if ((numberM == 0) && (oldNumberM != 0)) {
numberM = oldNumberM;
oldNumberM = cDevice::CurrentChannel();
Channels.SwitchTo(numberM);
LOCK_CHANNELS_READ;
Channels->SwitchTo(numberM);
numberM = 0;
return osContinue;
}
@ -1047,11 +1008,12 @@ eOSState cFemonOsd::ProcessKey(eKeys keyP)
numberM = numberM * 10 + keyP - k0;
if (numberM > 0) {
DrawStatusWindow();
cChannel *ch = Channels.GetByNumber(numberM);
LOCK_CHANNELS_READ;
const cChannel *ch = Channels->GetByNumber(numberM);
inputTimeM.Set(0);
// Lets see if there can be any useful further input:
int n = ch ? numberM * 10 : 0;
while (ch && (ch = Channels.Next(ch)) != NULL) {
while (ch && (ch = Channels->Next(ch)) != NULL) {
if (!ch->GroupSep()) {
if (n <= ch->Number() && ch->Number() <= n + 9) {
n = 0;
@ -1064,7 +1026,7 @@ eOSState cFemonOsd::ProcessKey(eKeys keyP)
if (n > 0) {
// This channel is the only one that fits the input, so let's take it right away:
oldNumberM = cDevice::CurrentChannel();
Channels.SwitchTo(numberM);
Channels->SwitchTo(numberM);
numberM = 0;
}
}
@ -1124,9 +1086,10 @@ eOSState cFemonOsd::ProcessKey(eKeys keyP)
break;
case kNone:
if (numberM && (inputTimeM.Elapsed() > CHANNELINPUT_TIMEOUT)) {
if (Channels.GetByNumber(numberM)) {
LOCK_CHANNELS_READ;
if (Channels->GetByNumber(numberM)) {
oldNumberM = cDevice::CurrentChannel();
Channels.SwitchTo(numberM);
Channels->SwitchTo(numberM);
numberM = 0;
}
else {
@ -1138,7 +1101,8 @@ eOSState cFemonOsd::ProcessKey(eKeys keyP)
case kOk:
{
// toggle between display modes
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
LOCK_CHANNELS_READ;
const cChannel *channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (++displayModeM == eFemonModeAC3 && channel && !channel->Dpid(0)) displayModeM++;
if (displayModeM >= eFemonModeMaxNumber) displayModeM = 0;
DrawInfoWindow();

19
osd.h
View File

@ -8,9 +8,7 @@
#ifndef __FEMON_OSD_H
#define __FEMON_OSD_H
#include <linux/dvb/frontend.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <vdr/osd.h>
#include <vdr/thread.h>
#include <vdr/status.h>
@ -37,7 +35,6 @@ private:
cOsd *osdM;
cFemonReceiver *receiverM;
int frontendM;
int svdrpFrontendM;
double svdrpVideoBitRateM;
double svdrpAudioBitRateM;
@ -49,16 +46,17 @@ private:
bool qualityValidM;
int strengthM;
bool strengthValidM;
uint16_t snrM;
bool snrValidM;
uint16_t signalM;
double cnrM;
bool cnrValidM;
double signalM;
bool signalValidM;
uint32_t berM;
double berM;
bool berValidM;
uint32_t uncM;
bool uncValidM;
double perM;
bool perValidM;
cString frontendNameM;
fe_status_t frontendStatusM;
cString frontendTypeM;
int frontendStatusM;
bool frontendStatusValidM;
dvb_frontend_info frontendInfoM;
eDeviceSourceType deviceSourceM;
@ -72,6 +70,7 @@ private:
cCondWait sleepM;
cMutex mutexM;
bool AttachFrontend(void);
void DrawStatusWindow(void);
void DrawInfoWindow(void);
bool SvdrpConnect(void);

View File

@ -1,21 +1,22 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Peter Marquardt
# Andreas Brachold
# Christian Wieninger
# Christian Wieninger
# Winfried
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Christian Wieninger\n"
"Language-Team: German <vdr@linuxtv.org>\n"
"Language: de\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"
msgid "DVB Signal Information Monitor (OSD)"
@ -25,7 +26,7 @@ msgid "Signal Information"
msgstr "Signalinformationen"
msgid "Femon not available"
msgstr "Femon nicht verfügbar"
msgstr "Femon nicht verfügbar"
msgid "Video"
msgstr "Video"
@ -61,7 +62,7 @@ msgid "Coderate"
msgstr "Coderate"
msgid "Protocol"
msgstr ""
msgstr "Protokoll"
msgid "Bitrate"
msgstr "Bitrate"
@ -70,28 +71,28 @@ msgid "Stream Information"
msgstr "Streaminformation"
msgid "Video Stream"
msgstr "Video Stream"
msgstr "Videostream"
msgid "Codec"
msgstr ""
msgstr "Codec"
msgid "Aspect Ratio"
msgstr "Seitenverhältnis"
msgstr "Seitenverhältnis"
msgid "Frame Rate"
msgstr "Bildrate"
msgid "Video Format"
msgstr "Bildformat"
msgstr "Videoformat"
msgid "Resolution"
msgstr "Auflösung"
msgstr "Auflösung"
msgid "Audio Stream"
msgstr "Audio Stream"
msgstr "Audiostream"
msgid "Channel Mode"
msgstr ""
msgstr "Kanalmodus"
msgid "Sampling Frequency"
msgstr "Abtastrate"
@ -115,7 +116,7 @@ msgid "Dolby Surround Mode"
msgstr "Dolby Surround Modus"
msgid "Low Frequency Effects"
msgstr "Tieftöner Effekte"
msgstr "Tieftöner Effekte"
msgid "Dialogue Normalization"
msgstr "Dialog Normalisierung"
@ -129,6 +130,15 @@ msgstr "Transponder"
msgid "stream"
msgstr "Stream"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klassischer"
@ -160,82 +170,88 @@ msgid "PearlHD"
msgstr "PearlHD"
msgid "Hide main menu entry"
msgstr "Hauptmenüeintrag verstecken"
msgstr "Hauptmenüeintrag verstecken"
msgid "Define whether the main menu entry is hidden."
msgstr ""
msgstr "Legt fest, ob der Hauptmenüeintrag ausgeblendet ist."
msgid "Default display mode"
msgstr "Standard Anzeigemodus"
msgid "Define the default display mode at startup."
msgstr ""
msgstr "Definiert den Standard-Anzeigemodus beim Start."
msgid "Define the used OSD skin."
msgstr ""
msgstr "Definiert die verwendete OSD-Oberfläche."
msgid "Define the used OSD theme."
msgstr ""
msgstr "Definiert das verwendete OSD-Theme."
msgid "Position"
msgstr "Position"
msgid "Define the position of OSD."
msgstr ""
msgstr "Definiert die Position des OSD."
msgid "Downscale OSD size [%]"
msgstr ""
msgstr "OSD Größe verkleinern [%]"
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgstr "Definiert den Verkleinerungsfaktor der OSD-Größe."
msgid "Signal level unit"
msgstr "Signalpegel Einheiten"
msgid "Define the used signal level unit."
msgstr "Definiert der Einheit für Signalpegel."
msgid "Red limit [%]"
msgstr "Grenze Rot [%]"
msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr ""
msgstr "Definiert einen Grenzwert für den roten Balken, um ein schlechtes Signal zu kennzeichnen."
msgid "Green limit [%]"
msgstr "Grenze Grün [%]"
msgstr "Grenze Grün [%]"
msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr ""
msgstr "Definiert einen Grenzwert für den grünen Balken, um ein gutes Signal zu kennzeichnen."
msgid "OSD update interval [0.1s]"
msgstr "OSD Updateintervall [0.1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr ""
msgstr "Definiert den Intervall für OSD-Updates. Ein kleineres Intervall erzeugt eine höhere CPU-Last."
msgid "Analyze stream"
msgstr "Stream analysieren"
msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr ""
msgstr "Definiert ob der DVB-Stream analysiert und die Bitraten berechnet werden."
msgid "Calculation interval [0.1s]"
msgstr "Berechnungsintervall [0.1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr ""
msgstr "Definiert den Intervall für die Berechnung. Ein größerer Intervall erzeugt stabilere Werte."
msgid "Use SVDRP service"
msgstr "SVDRP Service verwenden"
msgstr "SVDRP-Service verwenden"
msgid "Define whether the SVDRP service is used in client/server setups."
msgstr ""
msgstr "Legt fest, ob der SVDRP-Service in Client/Server-Setups verwendet wird."
msgid "SVDRP service port"
msgstr "SVDRP Service Port"
msgstr "SVDRP-Service Port"
msgid "Define the port number of SVDRP service."
msgstr ""
msgstr "Definiert die Portnummer des SVDRP-Service."
msgid "SVDRP service IP"
msgstr "SVDRP Service IP"
msgstr "SVDRP-Service IP"
msgid "Define the IP address of SVDRP service."
msgstr ""
msgstr "Definiert die IP-Adresse des SVDRP-Service."
msgid "Help"
msgstr "Hilfe"
@ -247,64 +263,67 @@ msgid "Analog"
msgstr "Analog"
msgid "MPEG-2"
msgstr ""
msgstr "MPEG-2"
msgid "H.264"
msgstr ""
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr ""
msgstr "MPEG-1 Layer I"
msgid "MPEG-1 Layer II"
msgstr ""
msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III"
msgstr ""
msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I"
msgstr ""
msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II"
msgstr ""
msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III"
msgstr ""
msgstr "MPEG-2 Layer III"
msgid "HE-AAC"
msgstr ""
msgstr "HE-AAC"
msgid "LATM"
msgstr ""
msgstr "LATM"
msgid "stereo"
msgstr ""
msgstr "Stereo"
msgid "joint Stereo"
msgstr ""
msgstr "Joint-Stereo"
msgid "dual"
msgstr ""
msgstr "Dual"
msgid "mono"
msgstr ""
msgstr "Mono"
msgid "interlaced"
msgstr ""
msgstr "Interlaced"
msgid "progressive"
msgstr ""
msgstr "Progressiv"
msgid "reserved"
msgstr "belegt"
msgid "extended"
msgstr ""
msgstr "erweitert"
msgid "unknown"
msgstr "unbekannt"
msgid "component"
msgstr ""
msgstr "Komponentenvideo"
msgid "PAL"
msgstr "PAL"
@ -313,10 +332,10 @@ msgid "NTSC"
msgstr "NTSC"
msgid "SECAM"
msgstr ""
msgstr "SECAM"
msgid "MAC"
msgstr ""
msgstr "MAC"
msgid "Hz"
msgstr "Hz"
@ -331,7 +350,7 @@ msgid "Visually Impaired (VI)"
msgstr "Sehbehindert (VI)"
msgid "Hearing Impaired (HI)"
msgstr "Hörbehindert (HI)"
msgstr "Hörbehindert (HI)"
msgid "Dialogue (D)"
msgstr "Dialog (D)"
@ -343,7 +362,7 @@ msgid "Emergency (E)"
msgstr "Notfall (E)"
msgid "Voice Over (VO)"
msgstr "Überlagerte Stimme (VO)"
msgstr "Überlagerte Stimme (VO)"
msgid "Karaoke"
msgstr "Karaoke"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Luis Palacios
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Luis Palacios\n"
"Language-Team: Spanish <vdr@linuxtv.org>\n"
"Language: es\n"
@ -127,6 +127,15 @@ msgstr "Transpondedor"
msgid "stream"
msgstr "Flujo"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Clásico"
@ -187,6 +196,12 @@ msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Límite de rojo [%s]"
@ -250,6 +265,9 @@ msgstr ""
msgid "H.264"
msgstr ""
msgid "H.265"
msgstr ""
msgid "MPEG-1 Layer I"
msgstr ""

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Arthur Konovalov
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Arthur Konovalov\n"
"Language-Team: Estonian <vdr@linuxtv.org>\n"
"Language: et\n"
@ -127,6 +127,15 @@ msgstr "transponder"
msgid "stream"
msgstr "voog"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Classic"
@ -187,6 +196,12 @@ msgstr "Ekraanimen
msgid "Define the downscale ratio for OSD size."
msgstr "Ekraanimenüü suuruse vähendamise määritlemine"
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Punase limiit [%]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layet I"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Rolf Ahrenberg
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2019-10-27 16:29+0200\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Rolf Ahrenberg\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n"
"Language: fi\n"
@ -127,8 +127,17 @@ msgstr "transponderi"
msgid "stream"
msgstr "lähete"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klassinen"
msgstr ""
msgid "Elchi"
msgstr "Elchi"
@ -187,6 +196,12 @@ msgstr "Pienennä näytön kokoa [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Määrittele näytön pienennyssuhde."
msgid "Signal level unit"
msgstr "Signaalitason yksikkö"
msgid "Define the used signal level unit."
msgstr "Määrittele yksikkö signaalin tasolle."
msgid "Red limit [%]"
msgstr "Punaisen taso [%]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 kerros I"
@ -387,3 +405,6 @@ msgstr "Mbit/s"
msgid "kbit/s"
msgstr "kbit/s"
#~ msgid "Clasxsic"
#~ msgstr "Klassinen"

View File

@ -1,5 +1,5 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Nicolas Huillard
# Michaël Nival <mnival@club-internet.fr>, 2010
@ -7,10 +7,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Bernard Jaulin <bernard.jaulin@gmail.com>\n"
"Language-Team: French <vdr@linuxtv.org>\n"
"Language: fr\n"
@ -129,6 +129,15 @@ msgstr "transpondeur"
msgid "stream"
msgstr "flux"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Classique"
@ -189,6 +198,12 @@ msgstr "Réduit la taille de l'OSD (%)"
msgid "Define the downscale ratio for OSD size."
msgstr "Définit le ration de réduction de l'OSD."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Limite du rouge (%)"
@ -252,6 +267,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Füley István <ifuley at tigercomp dot ro>, 2011
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Füley István <ifuley at tigercomp dot ro>\n"
"Language-Team: Hungarian <ifuley at tigercomp dot ro>\n"
"Language: hu\n"
@ -130,6 +130,15 @@ msgstr "transponder"
msgid "stream"
msgstr "adatfolyam (stream)"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klasszikus"
@ -190,6 +199,12 @@ msgstr "Az OSD lem
msgid "Define the downscale ratio for OSD size."
msgstr "Az OSD méretének leméretezése százalékban."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Piros színt határa [%]"
@ -253,6 +268,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -1,15 +1,15 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Sean Carlos
# Diego Pierotto <vdr-italian@tiscali.it>
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: Italian <vdr@linuxtv.org>\n"
"Language: it\n"
@ -131,6 +131,15 @@ msgstr "transponder"
msgid "stream"
msgstr "flusso"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Classico"
@ -191,6 +200,12 @@ msgstr "Riduci dimensione OSD [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Definisci il rapporto di riduzione della dimensione OSD."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Limite rosso [%]"
@ -254,6 +269,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Valdemaras Pipiras
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
"Language: lt\n"
@ -127,6 +127,15 @@ msgstr "Siųstuvas"
msgid "stream"
msgstr "Srautas"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klasikinis"
@ -187,6 +196,12 @@ msgstr "Sumažinti ekrano užsklandos (OSD) dydį [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Nustatyti ekrano užsklandos (OSD) mažinimo santykį."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Raudonoji ribą [%]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

408
po/pl_PL.po Normal file
View File

@ -0,0 +1,408 @@
# VDR plugin language source file.
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the vdr-femon package.
# Tomasz Maciej Nowak, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Tomasz Maciej Nowak <tomek_n@o2.pl>\n"
"Language-Team: Polish <vdr@linuxtv.org>\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.11\n"
msgid "DVB Signal Information Monitor (OSD)"
msgstr "Monitor sygnału DVB (OSD)"
msgid "Signal Information"
msgstr "Informacja o sygnale"
msgid "Femon not available"
msgstr "Femon niedostępny"
msgid "Video"
msgstr "Obraz"
msgid "AC-3"
msgstr "AC-3"
msgid "Audio"
msgstr "Dźwięk"
msgid "Transponder Information"
msgstr "Informacje o transponderze"
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 "Sprawność kodowania"
msgid "Protocol"
msgstr "Protokół"
msgid "Bitrate"
msgstr "Przepływność"
msgid "Stream Information"
msgstr "Informacje o strumieniu"
msgid "Video Stream"
msgstr "Strumień obrazu"
msgid "Codec"
msgstr "Kodek"
msgid "Aspect Ratio"
msgstr "Proporcje obrazu"
msgid "Frame Rate"
msgstr "Tempo wyświetlania klatek"
msgid "Video Format"
msgstr "Format obrazu"
msgid "Resolution"
msgstr "Rozdzielczość"
msgid "Audio Stream"
msgstr "Strumień dźwięku"
msgid "Channel Mode"
msgstr "Tryb kanału"
msgid "Sampling Frequency"
msgstr "Częstotliwość próbkowania"
msgid "AC-3 Stream"
msgstr "Strumień AC-3"
msgid "Bit Stream Mode"
msgstr "Tryb strumienia bitów"
msgid "Audio Coding Mode"
msgstr "Tryb kodowania dźwięku"
msgid "Center Mix Level"
msgstr "Poziom Center Mix"
msgid "Surround Mix Level"
msgstr "Poziom Surround Mix"
msgid "Dolby Surround Mode"
msgstr "Tryb Dolby Surround"
msgid "Low Frequency Effects"
msgstr "Efekty niskich frekwencji"
msgid "Dialogue Normalization"
msgstr "Normalizacja dialogów"
msgid "basic"
msgstr "podstawowy"
msgid "transponder"
msgstr "transponder"
msgid "stream"
msgstr "strumień"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klasyczna"
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 "PearlHD"
msgstr "PearlHD"
msgid "Hide main menu entry"
msgstr "Ukryj pozycję w głównym menu"
msgid "Define whether the main menu entry is hidden."
msgstr "Określa czy pozycja w głównym menu jest ukryta."
msgid "Default display mode"
msgstr "Domyślny tryb wyświetlania"
msgid "Define the default display mode at startup."
msgstr "Określa domyślny tryb wyświetlania przy uruchamianiu."
msgid "Define the used OSD skin."
msgstr "Określa używaną skórkę OSD."
msgid "Define the used OSD theme."
msgstr "Określa używany motyw OSD."
msgid "Position"
msgstr "Pozycja"
msgid "Define the position of OSD."
msgstr "Określa pozycję OSD."
msgid "Downscale OSD size [%]"
msgstr "Zmniejsz rozmiar OSD [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Określa procent zmniejszenia OSD."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Czerwony - zakres [%]"
msgid "Define a limit for red bar, which is used to indicate a bad signal."
msgstr "Określa zakres czerwonego paska, pokazującego zły sygnał."
msgid "Green limit [%]"
msgstr "Zielony - zakres [%]"
msgid "Define a limit for green bar, which is used to indicate a good signal."
msgstr "Określa zakres zielonego paska, pokazującego dobry sygnał."
msgid "OSD update interval [0.1s]"
msgstr "Interwał aktualizacji OSD [0,1s]"
msgid "Define an interval for OSD updates. The smaller interval generates higher CPU load."
msgstr "Określa interwał aktualizacji danych w OSD. Mniejszy interwał generuje większe obciążenie CPU."
msgid "Analyze stream"
msgstr "Analiza strumienia"
msgid "Define whether the DVB stream is analyzed and bitrates calculated."
msgstr "Określa czy strumień DVB jest analizowany a przepływność obliczana."
msgid "Calculation interval [0.1s]"
msgstr "Interwał obliczeń [0,1s]"
msgid "Define an interval for calculation. The bigger interval generates more stable values."
msgstr "Określa interwał obliczeń. Większy interwał generuje stabilniejsze wartości."
msgid "Use SVDRP service"
msgstr "Używaj usługi SVDRP"
msgid "Define whether the SVDRP service is used in client/server setups."
msgstr "Określa czy używać usługi SVDRP w kownfiguracjach serwer/klient."
msgid "SVDRP service port"
msgstr "Port usługi SVDRP"
msgid "Define the port number of SVDRP service."
msgstr "Określa numer portu usługi SVDRP."
msgid "SVDRP service IP"
msgstr "IP usługi SVDRP"
msgid "Define the IP address of SVDRP service."
msgstr "Określa adres IP usługi SVDRP."
msgid "Help"
msgstr "Pomoc"
msgid "Fixed"
msgstr "Stały"
msgid "Analog"
msgstr "Analog"
msgid "MPEG-2"
msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
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 "połączone stereo"
msgid "dual"
msgstr "podwójne"
msgid "mono"
msgstr "mono"
msgid "interlaced"
msgstr "z przeplotem"
msgid "progressive"
msgstr "progresywne"
msgid "reserved"
msgstr "zamknięte"
msgid "extended"
msgstr "rozszerzone"
msgid "unknown"
msgstr "nieznane"
msgid "component"
msgstr "komponent"
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 "Complete Main (CM)"
msgid "Music and Effects (ME)"
msgstr "Muzyka i efekty (ME)"
msgid "Visually Impaired (VI)"
msgstr "Upośledzone wzrokowo (VI)"
msgid "Hearing Impaired (HI)"
msgstr "Upośledzone słuchowo (HI)"
msgid "Dialogue (D)"
msgstr "Dialog (D)"
msgid "Commentary (C)"
msgstr "Komentarz (C)"
msgid "Emergency (E)"
msgstr "Nagły wypadek (E)"
msgid "Voice Over (VO)"
msgstr "Naniesiony głos (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 "nie podano"
msgid "MHz"
msgstr "MHz"
msgid "free"
msgstr "wolne"
msgid "Mbit/s"
msgstr "Mbit/s"
msgid "kbit/s"
msgstr "kbit/s"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Vyacheslav Dikonov
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Vyacheslav Dikonov\n"
"Language-Team: Russian <vdr@linuxtv.org>\n"
"Language: ru\n"
@ -127,6 +127,15 @@ msgstr ""
msgid "stream"
msgstr ""
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr ""
@ -187,6 +196,12 @@ msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "ºàÐáÝÐï ×ÞÝÐ áÛÐÑÞÓÞ áØÓÝÐÛÐ ÔÞ (%)"
@ -250,6 +265,9 @@ msgstr ""
msgid "H.264"
msgstr ""
msgid "H.265"
msgstr ""
msgid "MPEG-1 Layer I"
msgstr ""

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 Rolf Ahrenberg
# This file is distributed under the same license as the femon package.
# Milan Hrala
#
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <vdr@linuxtv.org>\n"
"Language: sk\n"
@ -127,6 +127,15 @@ msgstr "Transpond
msgid "stream"
msgstr "dátový tok"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Klasický"
@ -187,6 +196,12 @@ msgstr "Zmen
msgid "Define the downscale ratio for OSD size."
msgstr "Zadajte zmen¹enie pomeru pre OSD veµkosti."
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Èervený limit [%]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 vrstva I"

View File

@ -4,10 +4,10 @@
# Yarema aka Knedlyk <yupadmin@gmail.com>, 2010.
msgid ""
msgstr ""
"Project-Id-Version: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
"Language-Team: Ukrainian <translation@linux.org.ua>\n"
"Language: uk\n"
@ -127,6 +127,15 @@ msgstr "транспондер"
msgid "stream"
msgstr "потік"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "Класичний"
@ -187,6 +196,12 @@ msgstr "Масштаб розміру повідомлень [%]"
msgid "Define the downscale ratio for OSD size."
msgstr "Визначити коефіцієнт масштабування розміру повідомлень"
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "Червона границя [%]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 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: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: NanFeng <nfgx@21cn.com>\n"
"Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n"
"Language: zh_CN\n"
@ -127,6 +127,15 @@ msgstr "转发器"
msgid "stream"
msgstr "数据流"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "经典"
@ -187,6 +196,12 @@ msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "红限制[ ]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -1,14 +1,14 @@
# VDR plugin language source file.
# Copyright (C) 2007-2015 Rolf Ahrenberg
# Copyright (C) 2007-2019 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: vdr-femon 2.2.1\n"
"Project-Id-Version: vdr-femon 2.4.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-04-04 04:04+0300\n"
"PO-Revision-Date: 2015-04-04 04:04+0300\n"
"POT-Creation-Date: 2018-04-15 04:15+0300\n"
"PO-Revision-Date: 2018-04-15 04:15+0300\n"
"Last-Translator: NanFeng <nfgx@21cn.com>\n"
"Language-Team: Chinese (traditional) <vdr@linuxtv.org>\n"
"Language: zh_TW\n"
@ -127,6 +127,15 @@ msgstr "轉發器"
msgid "stream"
msgstr "數據流"
msgid "dBm"
msgstr "dBm"
msgid "dBuV"
msgstr "dBuV"
msgid "dBV"
msgstr "dBV"
msgid "Classic"
msgstr "經典"
@ -187,6 +196,12 @@ msgstr ""
msgid "Define the downscale ratio for OSD size."
msgstr ""
msgid "Signal level unit"
msgstr ""
msgid "Define the used signal level unit."
msgstr ""
msgid "Red limit [%]"
msgstr "紅限制[ ]"
@ -250,6 +265,9 @@ msgstr "MPEG-2"
msgid "H.264"
msgstr "H.264"
msgid "H.265"
msgstr "H.265"
msgid "MPEG-1 Layer I"
msgstr "MPEG-1 Layer I"

View File

@ -19,6 +19,7 @@ cFemonReceiver::cFemonReceiver(const cChannel *channelP, int aTrackP, int dTrack
sleepM(),
activeM(false),
detectH264M(this),
detectH265M(this),
detectMpegM(this, this),
detectAacM(this),
detectLatmM(this),
@ -101,7 +102,7 @@ void cFemonReceiver::Activate(bool onP)
Deactivate();
}
void cFemonReceiver::Receive(uchar *dataP, int lengthP)
void cFemonReceiver::Receive(const uchar *dataP, int lengthP)
{
// TS packet length: TS_SIZE
if (Running() && (*dataP == TS_SYNC_BYTE) && (lengthP == TS_SIZE)) {
@ -163,12 +164,18 @@ void cFemonReceiver::Action(void)
processed = true;
if (TsPayloadStart(Data)) {
while (const uint8_t *p = videoAssemblerM.GetPes(len)) {
if (videoTypeM == 0x1B) { // MPEG4
if (videoTypeM == 0x1B) {
if (detectH264M.processVideo(p, len)) {
videoValidM = true;
break;
}
}
else if (videoTypeM == 0x24) {
if (detectH265M.processVideo(p, len)) {
videoValidM = true;
break;
}
}
else {
if (detectMpegM.processVideo(p, len)) {
videoValidM = true;

View File

@ -15,6 +15,7 @@
#include "ac3.h"
#include "audio.h"
#include "h264.h"
#include "h265.h"
#include "latm.h"
#include "mpeg.h"
#include "tools.h"
@ -27,6 +28,7 @@ private:
bool activeM;
cFemonH264 detectH264M;
cFemonH265 detectH265M;
cFemonMPEG detectMpegM;
cFemonAAC detectAacM;
cFemonLATM detectLatmM;
@ -59,7 +61,7 @@ private:
protected:
virtual void Activate(bool onP);
virtual void Receive(uchar *dataP, int lengthP);
virtual void Receive(const uchar *dataP, int lengthP);
virtual void Action(void);
public:

42
setup.c
View File

@ -19,6 +19,7 @@ cMenuFemonSetup::cMenuFemonSetup()
themeM(FemonConfig.GetTheme()),
positionM(FemonConfig.GetPosition()),
downscaleM(FemonConfig.GetDownscale()),
signalUnitM(FemonConfig.GetSignalUnit()),
redLimitM(FemonConfig.GetRedLimit()),
greenLimitM(FemonConfig.GetGreenLimit()),
updateIntervalM(FemonConfig.GetUpdateInterval()),
@ -30,24 +31,28 @@ cMenuFemonSetup::cMenuFemonSetup()
debug1("%s", __PRETTY_FUNCTION__);
strn0cpy(svdrpIpM, FemonConfig.GetSvdrpIp(), sizeof(svdrpIpM));
dispModesM[eFemonModeBasic] = tr("basic");
dispModesM[eFemonModeTransponder] = tr("transponder");
dispModesM[eFemonModeStream] = tr("stream");
dispModesM[eFemonModeAC3] = tr("AC-3");
dispModesM[eFemonModeBasic] = tr("basic");
dispModesM[eFemonModeTransponder] = tr("transponder");
dispModesM[eFemonModeStream] = tr("stream");
dispModesM[eFemonModeAC3] = tr("AC-3");
skinsM[eFemonSkinClassic] = tr("Classic");
skinsM[eFemonSkinElchi] = tr("Elchi");
signalUnitsM[eFemonSignalUnitdBm] = tr("dBm");
signalUnitsM[eFemonSignalUnitdBuV] = tr("dBuV");
signalUnitsM[eFemonSignalUnitdBV] = tr("dBV");
themesM[eFemonThemeClassic] = tr("Classic");
themesM[eFemonThemeElchi] = tr("Elchi");
themesM[eFemonThemeSTTNG] = tr("ST:TNG");
themesM[eFemonThemeDeepBlue] = tr("DeepBlue");
themesM[eFemonThemeMoronimo] = tr("Moronimo");
themesM[eFemonThemeEnigma] = tr("Enigma");
themesM[eFemonThemeEgalsTry] = tr("EgalsTry");
themesM[eFemonThemeDuotone] = tr("Duotone");
themesM[eFemonThemeSilverGreen] = tr("SilverGreen");
themesM[eFemonThemePearlHD] = tr("PearlHD");
skinsM[eFemonSkinClassic] = tr("Classic");
skinsM[eFemonSkinElchi] = tr("Elchi");
themesM[eFemonThemeClassic] = tr("Classic");
themesM[eFemonThemeElchi] = tr("Elchi");
themesM[eFemonThemeSTTNG] = tr("ST:TNG");
themesM[eFemonThemeDeepBlue] = tr("DeepBlue");
themesM[eFemonThemeMoronimo] = tr("Moronimo");
themesM[eFemonThemeEnigma] = tr("Enigma");
themesM[eFemonThemeEgalsTry] = tr("EgalsTry");
themesM[eFemonThemeDuotone] = tr("Duotone");
themesM[eFemonThemeSilverGreen] = tr("SilverGreen");
themesM[eFemonThemePearlHD] = tr("PearlHD");
SetMenuCategory(mcSetupPlugins);
Setup();
@ -78,6 +83,9 @@ void cMenuFemonSetup::Setup(void)
Add(new cMenuEditIntItem(tr("Downscale OSD size [%]"), &downscaleM, 0, 20));
helpM.Append(tr("Define the downscale ratio for OSD size."));
Add(new cMenuEditStraItem(tr("Signal level unit"), &signalUnitM, eFemonSignalUnitMaxNumber, signalUnitsM));
helpM.Append(tr("Define the used signal level unit."));
Add(new cMenuEditIntItem(tr("Red limit [%]"), &redLimitM, 1, 50));
helpM.Append(tr("Define a limit for red bar, which is used to indicate a bad signal."));
@ -120,6 +128,7 @@ void cMenuFemonSetup::Store(void)
SetupStore("Theme", themeM);
SetupStore("Position", positionM);
SetupStore("Downscale", downscaleM);
SetupStore("SignalUnit", signalUnitM);
SetupStore("RedLimit", redLimitM);
SetupStore("GreenLimit", greenLimitM);
SetupStore("UpdateInterval", updateIntervalM);
@ -135,6 +144,7 @@ void cMenuFemonSetup::Store(void)
FemonConfig.SetTheme(themeM);
FemonConfig.SetPosition(positionM);
FemonConfig.SetDownscale(downscaleM);
FemonConfig.SetSignalUnit(signalUnitM);
FemonConfig.SetRedLimit(redLimitM);
FemonConfig.SetGreenLimit(greenLimitM);
FemonConfig.SetUpdateInterval(updateIntervalM);

View File

@ -11,6 +11,7 @@
class cMenuFemonSetup : public cMenuSetupPage {
private:
const char *dispModesM[eFemonModeMaxNumber];
const char *signalUnitsM[eFemonSignalUnitMaxNumber];
const char *skinsM[eFemonSkinMaxNumber];
const char *themesM[eFemonThemeMaxNumber];
cVector<const char*> helpM;
@ -20,6 +21,7 @@ private:
int themeM;
int positionM;
int downscaleM;
int signalUnitM;
int redLimitM;
int greenLimitM;
int updateIntervalM;

View File

@ -19,6 +19,7 @@
#include "symbols/dolbydigital51.xpm"
#include "symbols/mpeg2.xpm"
#include "symbols/h264.xpm"
#include "symbols/h265.xpm"
#include "symbols/ntsc.xpm"
#include "symbols/pal.xpm"
#include "symbols/encrypted.xpm"
@ -42,6 +43,9 @@
#include "symbols/six.xpm"
#include "symbols/seven.xpm"
#include "symbols/eight.xpm"
#include "symbols/format2160.xpm"
#include "symbols/format2160i.xpm"
#include "symbols/format2160p.xpm"
#include "symbols/format1080.xpm"
#include "symbols/format1080i.xpm"
#include "symbols/format1080p.xpm"
@ -64,6 +68,7 @@ static cBitmap bmDolbyDigital20(dolbydigital20_xpm);
static cBitmap bmDolbyDigital51(dolbydigital51_xpm);
static cBitmap bmMpeg2(mpeg2_xpm);
static cBitmap bmH264(h264_xpm);
static cBitmap bmH265(h265_xpm);
static cBitmap bmPal(pal_xpm);
static cBitmap bmNtsc(ntsc_xpm);
static cBitmap bmEncrypted(encrypted_xpm);
@ -87,6 +92,9 @@ static cBitmap bmFive(five_xpm);
static cBitmap bmSix(six_xpm);
static cBitmap bmSeven(seven_xpm);
static cBitmap bmEight(eight_xpm);
static cBitmap bmFormat2160(format2160_xpm);
static cBitmap bmFormat2160i(format2160i_xpm);
static cBitmap bmFormat2160p(format2160p_xpm);
static cBitmap bmFormat1080(format1080_xpm);
static cBitmap bmFormat1080i(format1080i_xpm);
static cBitmap bmFormat1080p(format1080p_xpm);
@ -146,6 +154,7 @@ bool cFemonSymbolCache::Populate(void)
cacheM.Append(bmDolbyDigital51.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD51
cacheM.Append(bmMpeg2.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MPEG2
cacheM.Append(bmH264.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_H264
cacheM.Append(bmH265.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_H265
cacheM.Append(bmPal.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_PAL
cacheM.Append(bmNtsc.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_NTSC
cacheM.Append(bmEncrypted.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ENCRYPTED
@ -169,6 +178,9 @@ bool cFemonSymbolCache::Populate(void)
cacheM.Append(bmSix.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_SIX
cacheM.Append(bmSeven.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_SEVEN
cacheM.Append(bmEight.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_EIGHT
cacheM.Append(bmFormat2160.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_2160
cacheM.Append(bmFormat2160i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_2160i
cacheM.Append(bmFormat2160p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_2160p
cacheM.Append(bmFormat1080.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_1080
cacheM.Append(bmFormat1080i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_1080i
cacheM.Append(bmFormat1080p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_1080p
@ -201,7 +213,7 @@ bool cFemonSymbolCache::Flush(void)
cBitmap& cFemonSymbolCache::Get(eSymbols symbolP)
{
cBitmap *bitmapM = cacheM[SYMBOL_ONEPIXEL];
cBitmap *bitmapM = &bmOnePixel;
if (symbolP < cacheM.Size())
bitmapM = cacheM[symbolP];

View File

@ -21,6 +21,7 @@ enum eSymbols {
SYMBOL_DD51,
SYMBOL_MPEG2,
SYMBOL_H264,
SYMBOL_H265,
SYMBOL_PAL,
SYMBOL_NTSC,
SYMBOL_ENCRYPTED,
@ -44,6 +45,9 @@ enum eSymbols {
SYMBOL_SIX,
SYMBOL_SEVEN,
SYMBOL_EIGHT,
SYMBOL_FORMAT_2160,
SYMBOL_FORMAT_2160i,
SYMBOL_FORMAT_2160p,
SYMBOL_FORMAT_1080,
SYMBOL_FORMAT_1080i,
SYMBOL_FORMAT_1080p,

23
symbols/format2160.xpm Normal file
View File

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

23
symbols/format2160i.xpm Normal file
View File

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

23
symbols/format2160p.xpm Normal file
View File

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

23
symbols/h265.xpm Normal file
View File

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

169
tools.c
View File

@ -13,9 +13,8 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/dvb/frontend.h>
#include "config.h"
#include "osd.h"
#include "receiver.h"
#include "tools.h"
@ -91,60 +90,42 @@ static const char *getUserString(int valueP, const tDvbParameterMap *mapP)
return "---";
}
cDvbDevice *getDvbDevice(cDevice* deviceP)
cString getFrontendInfo(cDevice *deviceP)
{
cDvbDevice *dev = dynamic_cast<cDvbDevice*>(deviceP);
#ifdef __DYNAMIC_DEVICE_PROBE
if (!dev && deviceP && deviceP->HasSubDevice())
dev = dynamic_cast<cDvbDevice*>(deviceP->SubDevice());
#endif
return dev;
}
cString getFrontendInfo(cDvbDevice *deviceP)
{
struct dvb_frontend_info value;
fe_status_t status;
const cChannel *channel;
int status, valid = DTV_STAT_VALID_NONE;
cString info = "";
uint16_t signal = 0;
uint16_t snr = 0;
uint32_t ber = 0;
uint32_t unc = 0;
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
double signal = 0, cnr = 0, ber = 0, per = 0;
if (!deviceP)
return info;
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return info;
info = cString::sprintf("CARD:%d\nSTRG:%d\nQUAL:%d", deviceP->CardIndex(), deviceP->SignalStrength(), deviceP->SignalQuality());
if (ioctl(fe, FE_GET_INFO, &value) >= 0)
info = cString::sprintf("%s\nTYPE:%d\nNAME:%s", *info, value.type, *deviceP->DeviceName());
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);
info = cString::sprintf("CARD:%d\nSTRG:%d\nQUAL:%d\nTYPE:%s\nNAME:%s", deviceP->CardIndex(), deviceP->SignalStrength(), deviceP->SignalQuality(), *deviceP->DeviceType(), *deviceP->DeviceName());
if (deviceP && deviceP->SignalStats(valid, &signal, &cnr, NULL, &ber, &per, &status)) {
if (valid & DTV_STAT_VALID_STATUS)
info = cString::sprintf("%s\nSTAT:%04X", *info, status);
if (valid & DTV_STAT_VALID_STRENGTH)
info = cString::sprintf("%s\nSGNL:%s", *info, *dtoa(signal, "%.2f"));
if (valid & DTV_STAT_VALID_CNR)
info = cString::sprintf("%s\nCNRA:%s", *info, *dtoa(cnr, "%.2f"));
if (valid & DTV_STAT_VALID_BERPOST)
info = cString::sprintf("%s\nBERA:%s", *info, *dtoa(ber, "%.0f"));
if (valid & DTV_STAT_VALID_PER)
info = cString::sprintf("%s\nPERA:%s", *info, *dtoa(per, "%.0f"));
}
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:%s\nAUBR:%s\nDDBR:%s", *info, *dtoa(cFemonOsd::Instance()->GetVideoBitrate(), "%.0f"), *dtoa(cFemonOsd::Instance()->GetAudioBitrate(), "%.0f"), *dtoa(cFemonOsd::Instance()->GetDolbyBitrate(), "%.0f"));
LOCK_CHANNELS_READ;
channel = Channels->GetByNumber(cDevice::CurrentChannel());
if (channel)
info = cString::sprintf("%s\nCHAN:%s", *info, *channel->ToText());
return info;
}
cString getFrontendName(cDvbDevice *deviceP)
cString getFrontendName(cDevice *deviceP)
{
if (!deviceP)
return NULL;
@ -152,85 +133,80 @@ cString getFrontendName(cDvbDevice *deviceP)
return (cString::sprintf("%s on deviceP #%d", *deviceP->DeviceName(), deviceP->CardIndex()));
}
cString getFrontendStatus(cDvbDevice *deviceP)
cString getFrontendStatus(cDevice *deviceP)
{
fe_status_t value;
int status;
int valid = DTV_STAT_VALID_NONE;
if (!deviceP)
return NULL;
if (deviceP && deviceP->SignalStats(valid, NULL, NULL, NULL, NULL, NULL, &status)) {
if (valid & DTV_STAT_VALID_STATUS)
return (cString::sprintf("Status %s:%s:%s:%s:%s on deviceP #%d", (status & DTV_STAT_HAS_LOCK) ? "LOCKED" : "-", (status & DTV_STAT_HAS_SIGNAL) ? "SIGNAL" : "-", (status & DTV_STAT_HAS_CARRIER) ? "CARRIER" : "-", (status & DTV_STAT_HAS_VITERBI) ? "VITERBI" : "-", (status & DTV_STAT_HAS_SYNC) ? "SYNC" : "-", deviceP->CardIndex()));
}
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return NULL;
memset(&value, 0, sizeof(value));
ioctl(fe, FE_READ_STATUS, &value);
close(fe);
return (cString::sprintf("Status %s:%s:%s:%s:%s on deviceP #%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" : "-", deviceP->CardIndex()));
return NULL;
}
uint16_t getSignal(cDvbDevice *deviceP)
double getSignal(cDevice *deviceP)
{
uint16_t value = 0;
double strength;
int valid = DTV_STAT_VALID_NONE;
if (!deviceP)
return (value);
if (deviceP && deviceP->SignalStats(valid, &strength, NULL, NULL, NULL, NULL, NULL)) {
if (valid & DTV_STAT_VALID_STRENGTH)
return strength;
}
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return (value);
ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value);
close(fe);
return (value);
return 0;
}
uint16_t getSNR(cDvbDevice *deviceP)
double getCNR(cDevice *deviceP)
{
uint16_t value = 0;
double cnr;
int valid = DTV_STAT_VALID_NONE;
if (!deviceP)
return (value);
if (deviceP && deviceP->SignalStats(valid, NULL, &cnr, NULL, NULL, NULL, NULL)) {
if (valid & DTV_STAT_VALID_CNR)
return cnr;
}
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return (value);
ioctl(fe, FE_READ_SNR, &value);
close(fe);
return (value);
return 0;
}
uint32_t getBER(cDvbDevice *deviceP)
double getBER(cDevice *deviceP)
{
uint32_t value = 0;
double ber;
int valid = DTV_STAT_VALID_NONE;
if (!deviceP)
return (value);
if (deviceP && deviceP->SignalStats(valid, NULL, NULL, NULL, &ber, NULL, NULL)) {
if (valid & DTV_STAT_VALID_BERPOST)
return ber;
}
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return (value);
ioctl(fe, FE_READ_BER, &value);
close(fe);
return (value);
return 0;
}
uint32_t getUNC(cDvbDevice *deviceP)
double getPER(cDevice *deviceP)
{
uint32_t value = 0;
double per;
int valid = DTV_STAT_VALID_NONE;
if (!deviceP)
return (value);
if (deviceP && deviceP->SignalStats(valid, NULL, NULL, NULL, NULL, &per, NULL)) {
if (valid & DTV_STAT_VALID_PER)
return per;
}
int fe = open(*cString::sprintf(FRONTEND_DEVICE, deviceP->Adapter(), deviceP->Frontend()), O_RDONLY | O_NONBLOCK);
if (fe < 0)
return (value);
ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &value);
close(fe);
return 0;
}
return (value);
cString getSignalStrength(double strengthP)
{
switch (FemonConfig.GetSignalUnit()) {
case eFemonSignalUnitdBm: return cString::sprintf("%.2f %s", strengthP, tr("dBm"));
case eFemonSignalUnitdBuV: return cString::sprintf("%.2f %s", strengthP + (120 - 11.25), tr("dBuV"));
case eFemonSignalUnitdBV: return cString::sprintf("%.2f %s", strengthP - 11.25, tr("dBV"));
default: break;
}
return cString::sprintf("---");
}
cString getApids(const cChannel *channelP)
@ -309,6 +285,7 @@ cString getVideoCodec(int valueP)
switch (valueP) {
case VIDEO_CODEC_MPEG2: return cString::sprintf("%s", tr("MPEG-2"));
case VIDEO_CODEC_H264: return cString::sprintf("%s", tr("H.264"));
case VIDEO_CODEC_H265: return cString::sprintf("%s", tr("H.265"));
default: break;
}
return cString::sprintf("---");

18
tools.h
View File

@ -20,18 +20,16 @@
#define SATIP_DEVICE "SAT>IP"
cDvbDevice *getDvbDevice(cDevice* deviceP);
cString getFrontendInfo(cDevice *deviceP);
cString getFrontendName(cDevice *deviceP);
cString getFrontendStatus(cDevice *deviceP);
cString getFrontendInfo(cDvbDevice *deviceP);
cString getFrontendName(cDvbDevice *deviceP);
cString getFrontendStatus(cDvbDevice *deviceP);
uint16_t getSNR(cDvbDevice *deviceP);
uint16_t getSignal(cDvbDevice *deviceP);
uint32_t getBER(cDvbDevice *deviceP);
uint32_t getUNC(cDvbDevice *deviceP);
double getCNR(cDevice *deviceP);
double getSignal(cDevice *deviceP);
double getBER(cDevice *deviceP);
double getPER(cDevice *deviceP);
cString getSignalStrength(double strengthP);
cString getApids(const cChannel *channelP);
cString getDpids(const cChannel *channelP);
cString getSpids(const cChannel *channelP);

View File

@ -12,7 +12,8 @@ enum eVideoCodec {
VIDEO_CODEC_INVALID = -1,
VIDEO_CODEC_UNKNOWN,
VIDEO_CODEC_MPEG2,
VIDEO_CODEC_H264
VIDEO_CODEC_H264,
VIDEO_CODEC_H265
};
enum eVideoFormat {