mirror of
https://github.com/rofafor/vdr-plugin-femon.git
synced 2023-10-10 13:36:53 +02:00
Removed bitstream parsing from Receive() method.
Refactored the error logging from unimplemented ioctl functions.
This commit is contained in:
parent
080f390a75
commit
21d9c20beb
1
HISTORY
1
HISTORY
@ -381,3 +381,4 @@ VDR Plugin 'femon' Revision History
|
|||||||
|
|
||||||
- Changed H.264 parser to show display aspect ratio.
|
- Changed H.264 parser to show display aspect ratio.
|
||||||
- Removed error logging from unimplemented ioctl functions.
|
- Removed error logging from unimplemented ioctl functions.
|
||||||
|
- Removed bitstream parsing from Receive() method.
|
||||||
|
101
femonosd.c
101
femonosd.c
@ -28,6 +28,7 @@
|
|||||||
#define OSDSPACING 5
|
#define OSDSPACING 5
|
||||||
#define OSDROUNDING 10
|
#define OSDROUNDING 10
|
||||||
#define IS_OSDROUNDING (femonConfig.skin == eFemonSkinElchi)
|
#define IS_OSDROUNDING (femonConfig.skin == eFemonSkinElchi)
|
||||||
|
#define IS_OSDRESOLUTION(r1, r2) (abs(r1 - r2) < 20)
|
||||||
#define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset)
|
#define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset)
|
||||||
#define OSDINFOWIN_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \
|
#define OSDINFOWIN_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \
|
||||||
(col == 3) ? int(round(OSDWIDTH * 0.51)) : \
|
(col == 3) ? int(round(OSDWIDTH * 0.51)) : \
|
||||||
@ -66,7 +67,7 @@
|
|||||||
|
|
||||||
#define OSDDRAWSTATUSBAR(value) \
|
#define OSDDRAWSTATUSBAR(value) \
|
||||||
if (value > 0) { \
|
if (value > 0) { \
|
||||||
int32_t barvalue = OSDBARWIDTH(value); \
|
int barvalue = OSDBARWIDTH(value); \
|
||||||
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(femonConfig.redlimit), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrRed); \
|
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(femonConfig.redlimit), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrRed); \
|
||||||
if (barvalue > OSDBARWIDTH(femonConfig.redlimit)) \
|
if (barvalue > OSDBARWIDTH(femonConfig.redlimit)) \
|
||||||
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * femonConfig.greenlimit / 100), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrYellow); \
|
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * femonConfig.greenlimit / 100), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrYellow); \
|
||||||
@ -168,10 +169,15 @@ cFemonOsd::cFemonOsd()
|
|||||||
m_SvdrpPlugin(NULL),
|
m_SvdrpPlugin(NULL),
|
||||||
m_Number(0),
|
m_Number(0),
|
||||||
m_OldNumber(0),
|
m_OldNumber(0),
|
||||||
m_SNR(-1),
|
m_SNR(0),
|
||||||
m_Signal(-1),
|
m_SNRValid(false),
|
||||||
m_BER(-1),
|
m_Signal(0),
|
||||||
m_UNC(-1),
|
m_SignalValid(false),
|
||||||
|
m_BER(0),
|
||||||
|
m_BERValid(false),
|
||||||
|
m_UNC(0),
|
||||||
|
m_UNCValid(false),
|
||||||
|
m_FrontendStatusValid(false),
|
||||||
m_DisplayMode(femonConfig.displaymode),
|
m_DisplayMode(femonConfig.displaymode),
|
||||||
m_OsdWidth(cOsd::OsdWidth()),
|
m_OsdWidth(cOsd::OsdWidth()),
|
||||||
m_OsdHeight(cOsd::OsdHeight()),
|
m_OsdHeight(cOsd::OsdHeight()),
|
||||||
@ -181,8 +187,8 @@ cFemonOsd::cFemonOsd()
|
|||||||
{
|
{
|
||||||
int tmp;
|
int tmp;
|
||||||
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
||||||
memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo));
|
|
||||||
memset(&m_FrontendStatus, 0, sizeof(m_FrontendStatus));
|
memset(&m_FrontendStatus, 0, sizeof(m_FrontendStatus));
|
||||||
|
memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo));
|
||||||
m_SvdrpConnection.handle = -1;
|
m_SvdrpConnection.handle = -1;
|
||||||
m_Font = cFont::CreateFont(Setup.FontSml, min(max(Setup.FontSmlSize, MINFONTSIZE), MAXFONTSIZE));
|
m_Font = cFont::CreateFont(Setup.FontSml, min(max(Setup.FontSmlSize, MINFONTSIZE), MAXFONTSIZE));
|
||||||
if (!m_Font || !m_Font->Height()) {
|
if (!m_Font || !m_Font->Height()) {
|
||||||
@ -284,13 +290,13 @@ void cFemonOsd::DrawStatusWindow(void)
|
|||||||
OSDDRAWSTATUSBM(OSDSPACING);
|
OSDDRAWSTATUSBM(OSDSPACING);
|
||||||
}
|
}
|
||||||
if (m_Receiver) {
|
if (m_Receiver) {
|
||||||
if (abs(m_Receiver->VideoVerticalSize() - 1080) < 20)
|
if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 1080))
|
||||||
bm = &bmSymbol[SYMBOL_FORMAT_1080];
|
bm = &bmSymbol[SYMBOL_FORMAT_1080];
|
||||||
else if (abs(m_Receiver->VideoVerticalSize() - 720) < 20)
|
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 720))
|
||||||
bm = &bmSymbol[SYMBOL_FORMAT_720];
|
bm = &bmSymbol[SYMBOL_FORMAT_720];
|
||||||
else if (abs(m_Receiver->VideoVerticalSize() - 576) < 20)
|
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 576))
|
||||||
bm = &bmSymbol[SYMBOL_FORMAT_576];
|
bm = &bmSymbol[SYMBOL_FORMAT_576];
|
||||||
else if (abs(m_Receiver->VideoVerticalSize() - 480) < 20)
|
else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 480))
|
||||||
bm = &bmSymbol[SYMBOL_FORMAT_480];
|
bm = &bmSymbol[SYMBOL_FORMAT_480];
|
||||||
else
|
else
|
||||||
bm = NULL;
|
bm = NULL;
|
||||||
@ -321,28 +327,30 @@ void cFemonOsd::DrawStatusWindow(void)
|
|||||||
OSDDRAWSTATUSBM(OSDSPACING);
|
OSDDRAWSTATUSBM(OSDSPACING);
|
||||||
}
|
}
|
||||||
offset += OSDROWHEIGHT;
|
offset += OSDROWHEIGHT;
|
||||||
if (m_Signal >= 0)
|
if (m_SignalValid)
|
||||||
OSDDRAWSTATUSBAR(m_Signal / 655);
|
OSDDRAWSTATUSBAR(m_Signal / 655);
|
||||||
offset += OSDROWHEIGHT;
|
offset += OSDROWHEIGHT;
|
||||||
if (m_SNR >= 0)
|
if (m_SNRValid)
|
||||||
OSDDRAWSTATUSBAR(m_SNR / 655);
|
OSDDRAWSTATUSBAR(m_SNR / 655);
|
||||||
offset += OSDROWHEIGHT;
|
offset += OSDROWHEIGHT;
|
||||||
OSDDRAWSTATUSVALUES("STR:", (m_Signal >= 0) ? *cString::sprintf("%04" PRIu32, m_Signal) : "---", (m_Signal >= 0) ? *cString::sprintf("(%2d%%)", m_Signal / 655) : "",
|
OSDDRAWSTATUSVALUES("STR:", m_SignalValid ? *cString::sprintf("%04x", m_Signal) : "", m_SignalValid ? *cString::sprintf("(%2d%%)", m_Signal / 655) : "",
|
||||||
"BER:", (m_BER >= 0) ? *cString::sprintf("%08" PRIx64, m_BER) : "---", *cString::sprintf("%s:", tr("Video")),
|
"BER:", m_BERValid ? *cString::sprintf("%08x", m_BER) : "", *cString::sprintf("%s:", tr("Video")),
|
||||||
*getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0)));
|
*getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0)));
|
||||||
offset += OSDROWHEIGHT;
|
offset += OSDROWHEIGHT;
|
||||||
OSDDRAWSTATUSVALUES("SNR:", (m_SNR >= 0) ? *cString::sprintf("%04" PRIu32, m_SNR) : "---", (m_SNR >= 0) ? *cString::sprintf("(%2d%%)", m_SNR / 655) : "",
|
OSDDRAWSTATUSVALUES("SNR:", m_SNRValid ? *cString::sprintf("%04x", m_SNR) : "", m_SNRValid ? *cString::sprintf("(%2d%%)", m_SNR / 655) : "",
|
||||||
"UNC:", (m_UNC >= 0) ? *cString::sprintf("%08" PRIx64, m_UNC) : "---",
|
"UNC:", m_UNCValid ? *cString::sprintf("%08x", m_UNC) : "",
|
||||||
*cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")),
|
*cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")),
|
||||||
*getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0)));
|
*getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0)));
|
||||||
offset += OSDROWHEIGHT;
|
offset += OSDROWHEIGHT;
|
||||||
x = bmSymbol[SYMBOL_LOCK].Width();
|
x = bmSymbol[SYMBOL_LOCK].Width();
|
||||||
y = (OSDROWHEIGHT - bmSymbol[SYMBOL_LOCK].Height()) / 2;
|
y = (OSDROWHEIGHT - bmSymbol[SYMBOL_LOCK].Height()) / 2;
|
||||||
OSDDRAWSTATUSFRONTEND(1, bmSymbol[SYMBOL_LOCK], FE_HAS_LOCK);
|
if (m_FrontendStatusValid) {
|
||||||
OSDDRAWSTATUSFRONTEND(2, bmSymbol[SYMBOL_SIGNAL], FE_HAS_SIGNAL);
|
OSDDRAWSTATUSFRONTEND(1, bmSymbol[SYMBOL_LOCK], FE_HAS_LOCK);
|
||||||
OSDDRAWSTATUSFRONTEND(3, bmSymbol[SYMBOL_CARRIER], FE_HAS_CARRIER);
|
OSDDRAWSTATUSFRONTEND(2, bmSymbol[SYMBOL_SIGNAL], FE_HAS_SIGNAL);
|
||||||
OSDDRAWSTATUSFRONTEND(4, bmSymbol[SYMBOL_VITERBI], FE_HAS_VITERBI);
|
OSDDRAWSTATUSFRONTEND(3, bmSymbol[SYMBOL_CARRIER], FE_HAS_CARRIER);
|
||||||
OSDDRAWSTATUSFRONTEND(5, bmSymbol[SYMBOL_SYNC], FE_HAS_SYNC);
|
OSDDRAWSTATUSFRONTEND(4, bmSymbol[SYMBOL_VITERBI], FE_HAS_VITERBI);
|
||||||
|
OSDDRAWSTATUSFRONTEND(5, bmSymbol[SYMBOL_SYNC], FE_HAS_SYNC);
|
||||||
|
}
|
||||||
OSDDRAWSTATUSBOTTOMBAR();
|
OSDDRAWSTATUSBOTTOMBAR();
|
||||||
m_Osd->Flush();
|
m_Osd->Flush();
|
||||||
}
|
}
|
||||||
@ -505,16 +513,11 @@ void cFemonOsd::Action(void)
|
|||||||
m_SvdrpVideoBitrate = -1.0;
|
m_SvdrpVideoBitrate = -1.0;
|
||||||
m_SvdrpAudioBitrate = -1.0;
|
m_SvdrpAudioBitrate = -1.0;
|
||||||
if (m_Frontend != -1) {
|
if (m_Frontend != -1) {
|
||||||
if (ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus) < 0)
|
m_FrontendStatusValid = (ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus) >= 0);
|
||||||
memset(&m_FrontendStatus, 0, sizeof(m_FrontendStatus));
|
m_SignalValid = (ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal) >= 0);
|
||||||
if (ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal) < 0)
|
m_SNRValid = (ioctl(m_Frontend, FE_READ_SNR, &m_SNR) >= 0);
|
||||||
m_Signal = -1;
|
m_BERValid = (ioctl(m_Frontend, FE_READ_BER, &m_BER) >= 0);
|
||||||
if (ioctl(m_Frontend, FE_READ_SNR, &m_SNR) < 0)
|
m_UNCValid = (ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC) >= 0);
|
||||||
m_SNR = -1;
|
|
||||||
if (ioctl(m_Frontend, FE_READ_BER, &m_BER) < 0)
|
|
||||||
m_BER = -1;
|
|
||||||
if (ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC) < 0)
|
|
||||||
m_UNC = -1;
|
|
||||||
DrawInfoWindow();
|
DrawInfoWindow();
|
||||||
DrawStatusWindow();
|
DrawStatusWindow();
|
||||||
}
|
}
|
||||||
@ -522,24 +525,40 @@ void cFemonOsd::Action(void)
|
|||||||
cmd.handle = m_SvdrpConnection.handle;
|
cmd.handle = m_SvdrpConnection.handle;
|
||||||
m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd);
|
m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd);
|
||||||
if (cmd.responseCode == 900) {
|
if (cmd.responseCode == 900) {
|
||||||
|
m_FrontendStatusValid = false;
|
||||||
|
m_SignalValid = false;
|
||||||
|
m_SNRValid = false;
|
||||||
|
m_BERValid = false;
|
||||||
|
m_UNCValid = false;
|
||||||
for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) {
|
for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) {
|
||||||
const char *s = line->Text();
|
const char *s = line->Text();
|
||||||
if (!strncasecmp(s, "CARD:", 5))
|
if (!strncasecmp(s, "CARD:", 5))
|
||||||
m_SvdrpFrontend = (int)strtol(s + 5, NULL, 10);
|
m_SvdrpFrontend = (int)strtol(s + 5, NULL, 10);
|
||||||
else if (!strncasecmp(s, "TYPE:", 5))
|
else if (!strncasecmp(s, "TYPE:", 5))
|
||||||
m_FrontendInfo.type = (fe_type_t)strtol(s + 5, NULL, 10);
|
m_FrontendInfo.type = (fe_type_t)strtol(s + 5, NULL, 10);
|
||||||
else if (!strncasecmp(s, "NAME:", 5))
|
else if (!strncasecmp(s, "NAME:", 5)) {
|
||||||
strn0cpy(m_FrontendInfo.name, s + 5, sizeof(m_FrontendInfo.name));
|
strn0cpy(m_FrontendInfo.name, s + 5, sizeof(m_FrontendInfo.name));
|
||||||
else if (!strncasecmp(s, "STAT:", 5))
|
}
|
||||||
|
else if (!strncasecmp(s, "STAT:", 5)) {
|
||||||
m_FrontendStatus = (fe_status_t)strtol(s + 5, NULL, 16);
|
m_FrontendStatus = (fe_status_t)strtol(s + 5, NULL, 16);
|
||||||
else if (!strncasecmp(s, "SGNL:", 5))
|
m_FrontendStatusValid = true;
|
||||||
m_Signal = (int32_t)strtol(s + 5, NULL, 16);
|
}
|
||||||
else if (!strncasecmp(s, "SNRA:", 5))
|
else if (!strncasecmp(s, "SGNL:", 5)) {
|
||||||
m_SNR = (int32_t)strtol(s + 5, NULL, 16);
|
m_Signal = (uint16_t)strtol(s + 5, NULL, 16);
|
||||||
else if (!strncasecmp(s, "BERA:", 5))
|
m_SignalValid = true;
|
||||||
m_BER = (int64_t)strtol(s + 5, NULL, 16);
|
}
|
||||||
else if (!strncasecmp(s, "UNCB:", 5))
|
else if (!strncasecmp(s, "SNRA:", 5)) {
|
||||||
m_UNC = (int64_t)strtol(s + 5, NULL, 16);
|
m_SNR = (uint16_t)strtol(s + 5, NULL, 16);
|
||||||
|
m_SNRValid = true;
|
||||||
|
}
|
||||||
|
else if (!strncasecmp(s, "BERA:", 5)) {
|
||||||
|
m_BER = (uint32_t)strtol(s + 5, NULL, 16);
|
||||||
|
m_BERValid = true;
|
||||||
|
}
|
||||||
|
else if (!strncasecmp(s, "UNCB:", 5)) {
|
||||||
|
m_UNC = (uint32_t)strtol(s + 5, NULL, 16);
|
||||||
|
m_UNCValid = true;
|
||||||
|
}
|
||||||
else if (!strncasecmp(s, "VIBR:", 5))
|
else if (!strncasecmp(s, "VIBR:", 5))
|
||||||
m_SvdrpVideoBitrate = (double)strtol(s + 5, NULL, 10);
|
m_SvdrpVideoBitrate = (double)strtol(s + 5, NULL, 10);
|
||||||
else if (!strncasecmp(s, "AUBR:", 5))
|
else if (!strncasecmp(s, "AUBR:", 5))
|
||||||
|
15
femonosd.h
15
femonosd.h
@ -34,14 +34,19 @@ private:
|
|||||||
double m_SvdrpAudioBitrate;
|
double m_SvdrpAudioBitrate;
|
||||||
SvdrpConnection_v1_0 m_SvdrpConnection;
|
SvdrpConnection_v1_0 m_SvdrpConnection;
|
||||||
cPlugin *m_SvdrpPlugin;
|
cPlugin *m_SvdrpPlugin;
|
||||||
dvb_frontend_info m_FrontendInfo;
|
|
||||||
int m_Number;
|
int m_Number;
|
||||||
int m_OldNumber;
|
int m_OldNumber;
|
||||||
int32_t m_SNR;
|
uint16_t m_SNR;
|
||||||
int32_t m_Signal;
|
bool m_SNRValid;
|
||||||
int64_t m_BER;
|
uint16_t m_Signal;
|
||||||
int64_t m_UNC;
|
bool m_SignalValid;
|
||||||
|
uint32_t m_BER;
|
||||||
|
bool m_BERValid;
|
||||||
|
uint32_t m_UNC;
|
||||||
|
bool m_UNCValid;
|
||||||
fe_status_t m_FrontendStatus;
|
fe_status_t m_FrontendStatus;
|
||||||
|
bool m_FrontendStatusValid;
|
||||||
|
dvb_frontend_info m_FrontendInfo;
|
||||||
int m_DisplayMode;
|
int m_DisplayMode;
|
||||||
int m_OsdWidth;
|
int m_OsdWidth;
|
||||||
int m_OsdHeight;
|
int m_OsdHeight;
|
||||||
|
175
femonreceiver.c
175
femonreceiver.c
@ -20,15 +20,18 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid
|
|||||||
m_DetectMPEG(this, this),
|
m_DetectMPEG(this, this),
|
||||||
m_DetectAAC(this),
|
m_DetectAAC(this),
|
||||||
m_DetectAC3(this),
|
m_DetectAC3(this),
|
||||||
|
m_VideoBuffer(KILOBYTE(256), TS_SIZE, false, "Femon video"),
|
||||||
m_VideoType(Vtype),
|
m_VideoType(Vtype),
|
||||||
m_VideoPid(Vpid),
|
m_VideoPid(Vpid),
|
||||||
m_VideoPacketCount(0),
|
m_VideoPacketCount(0),
|
||||||
m_VideoBitrate(0.0),
|
m_VideoBitrate(0.0),
|
||||||
m_VideoValid(false),
|
m_VideoValid(false),
|
||||||
|
m_AudioBuffer(KILOBYTE(256), TS_SIZE, false, "Femon audio"),
|
||||||
m_AudioPid(Apid[0]),
|
m_AudioPid(Apid[0]),
|
||||||
m_AudioPacketCount(0),
|
m_AudioPacketCount(0),
|
||||||
m_AudioBitrate(0.0),
|
m_AudioBitrate(0.0),
|
||||||
m_AudioValid(false),
|
m_AudioValid(false),
|
||||||
|
m_AC3Buffer(KILOBYTE(256), TS_SIZE, false, "Femon AC3"),
|
||||||
m_AC3Pid(Dpid[0]),
|
m_AC3Pid(Dpid[0]),
|
||||||
m_AC3PacketCount(0),
|
m_AC3PacketCount(0),
|
||||||
m_AC3Bitrate(0),
|
m_AC3Bitrate(0),
|
||||||
@ -36,6 +39,10 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid
|
|||||||
{
|
{
|
||||||
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
m_VideoBuffer.SetTimeouts(0, 0);
|
||||||
|
m_AudioBuffer.SetTimeouts(0, 0);
|
||||||
|
m_AC3Buffer.SetTimeouts(0, 0);
|
||||||
|
|
||||||
m_VideoInfo.codec = VIDEO_CODEC_INVALID;
|
m_VideoInfo.codec = VIDEO_CODEC_INVALID;
|
||||||
m_VideoInfo.format = VIDEO_FORMAT_INVALID;
|
m_VideoInfo.format = VIDEO_FORMAT_INVALID;
|
||||||
m_VideoInfo.scan = VIDEO_SCAN_INVALID;
|
m_VideoInfo.scan = VIDEO_SCAN_INVALID;
|
||||||
@ -89,46 +96,31 @@ void cFemonReceiver::Activate(bool On)
|
|||||||
void cFemonReceiver::Receive(uchar *Data, int Length)
|
void cFemonReceiver::Receive(uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
// TS packet length: TS_SIZE
|
// TS packet length: TS_SIZE
|
||||||
if (Length == TS_SIZE) {
|
if ((*Data == TS_SYNC_BYTE) || (Length == TS_SIZE)) {
|
||||||
int len, pid = TsPid(Data);
|
int len, pid = TsPid(Data);
|
||||||
if (pid == m_VideoPid) {
|
if (pid == m_VideoPid) {
|
||||||
m_VideoPacketCount++;
|
++m_VideoPacketCount;
|
||||||
if (TsPayloadStart(Data)) {
|
len = m_VideoBuffer.Put(Data, Length);
|
||||||
while (const uint8_t *p = m_VideoAssembler.GetPes(len)) {
|
if (len != Length) {
|
||||||
if (m_VideoType == 0x1B) { // MPEG4
|
m_VideoBuffer.ReportOverflow(Length - len);
|
||||||
if (m_DetectH264.processVideo(p, len)) {
|
m_VideoBuffer.Clear();
|
||||||
m_VideoValid = true;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (m_DetectMPEG.processVideo(p, len)) {
|
|
||||||
m_VideoValid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_VideoAssembler.Reset();
|
|
||||||
}
|
|
||||||
m_VideoAssembler.PutTs(Data, Length);
|
|
||||||
}
|
}
|
||||||
else if (pid == m_AudioPid) {
|
else if (pid == m_AudioPid) {
|
||||||
m_AudioPacketCount++;
|
++m_AudioPacketCount;
|
||||||
if (const uint8_t *p = m_AudioAssembler.GetPes(len)) {
|
len = m_AudioBuffer.Put(Data, Length);
|
||||||
if (m_DetectAAC.processAudio(p, len) || m_DetectMPEG.processAudio(p, len))
|
if (len != Length) {
|
||||||
m_AudioValid = true;
|
m_AudioBuffer.ReportOverflow(Length - len);
|
||||||
m_AudioAssembler.Reset();
|
m_AudioBuffer.Clear();
|
||||||
}
|
}
|
||||||
m_AudioAssembler.PutTs(Data, Length);
|
|
||||||
}
|
}
|
||||||
else if (pid == m_AC3Pid) {
|
else if (pid == m_AC3Pid) {
|
||||||
m_AC3PacketCount++;
|
++m_AC3PacketCount;
|
||||||
if (const uint8_t *p = m_AC3Assembler.GetPes(len)) {
|
len = m_AC3Buffer.Put(Data, Length);
|
||||||
if (m_DetectAC3.processAudio(p, len))
|
if (len != Length) {
|
||||||
m_AC3Valid = true;
|
m_AC3Buffer.ReportOverflow(Length - len);
|
||||||
m_AC3Assembler.Reset();
|
m_AC3Buffer.Clear();
|
||||||
}
|
}
|
||||||
m_AC3Assembler.PutTs(Data, Length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,17 +128,116 @@ void cFemonReceiver::Receive(uchar *Data, int Length)
|
|||||||
void cFemonReceiver::Action(void)
|
void cFemonReceiver::Action(void)
|
||||||
{
|
{
|
||||||
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
Dprintf("%s()\n", __PRETTY_FUNCTION__);
|
||||||
cTimeMs t;
|
cTimeMs calcPeriod(0);
|
||||||
m_Active = true;
|
m_Active = true;
|
||||||
|
|
||||||
while (Running() && m_Active) {
|
while (Running() && m_Active) {
|
||||||
t.Set(0);
|
uint8_t *Data;
|
||||||
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
|
double timeout;
|
||||||
m_VideoBitrate = (10.0 * 8.0 * 184.0 * m_VideoPacketCount) / femonConfig.calcinterval;
|
int len, Length;
|
||||||
m_VideoPacketCount = 0;
|
bool processed = false;
|
||||||
m_AudioBitrate = (10.0 * 8.0 * 184.0 * m_AudioPacketCount) / femonConfig.calcinterval;
|
|
||||||
m_AudioPacketCount = 0;
|
// process available video data
|
||||||
m_AC3Bitrate = (10.0 * 8.0 * 184.0 * m_AC3PacketCount) / femonConfig.calcinterval;
|
while (Data = m_VideoBuffer.Get(Length)) {
|
||||||
m_AC3PacketCount = 0;
|
if (!m_Active || (Length < TS_SIZE))
|
||||||
m_Sleep.Wait(max((int)(100 * femonConfig.calcinterval - t.Elapsed()), 3));
|
break;
|
||||||
|
Length = TS_SIZE;
|
||||||
|
if (*Data != TS_SYNC_BYTE) {
|
||||||
|
for (int i = 1; i < Length; ++i) {
|
||||||
|
if (Data[i] == TS_SYNC_BYTE) {
|
||||||
|
Length = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_VideoBuffer.Del(Length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processed = true;
|
||||||
|
if (TsPayloadStart(Data)) {
|
||||||
|
while (const uint8_t *p = m_VideoAssembler.GetPes(len)) {
|
||||||
|
if (m_VideoType == 0x1B) { // MPEG4
|
||||||
|
if (m_DetectH264.processVideo(p, len)) {
|
||||||
|
m_VideoValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m_DetectMPEG.processVideo(p, len)) {
|
||||||
|
m_VideoValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_VideoAssembler.Reset();
|
||||||
|
}
|
||||||
|
m_VideoAssembler.PutTs(Data, Length);
|
||||||
|
m_VideoBuffer.Del(Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process available audio data
|
||||||
|
while (Data = m_AudioBuffer.Get(Length)) {
|
||||||
|
if (!m_Active || (Length < TS_SIZE))
|
||||||
|
break;
|
||||||
|
Length = TS_SIZE;
|
||||||
|
if (*Data != TS_SYNC_BYTE) {
|
||||||
|
for (int i = 1; i < Length; ++i) {
|
||||||
|
if (Data[i] == TS_SYNC_BYTE) {
|
||||||
|
Length = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_AudioBuffer.Del(Length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processed = true;
|
||||||
|
if (const uint8_t *p = m_AudioAssembler.GetPes(len)) {
|
||||||
|
if (m_DetectAAC.processAudio(p, len) || m_DetectMPEG.processAudio(p, len))
|
||||||
|
m_AudioValid = true;
|
||||||
|
m_AudioAssembler.Reset();
|
||||||
|
}
|
||||||
|
m_AudioAssembler.PutTs(Data, Length);
|
||||||
|
m_AudioBuffer.Del(Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process available dolby data
|
||||||
|
while (Data = m_AC3Buffer.Get(Length)) {
|
||||||
|
if (!m_Active || (Length < TS_SIZE))
|
||||||
|
break;
|
||||||
|
Length = TS_SIZE;
|
||||||
|
if (*Data != TS_SYNC_BYTE) {
|
||||||
|
for (int i = 1; i < Length; ++i) {
|
||||||
|
if (Data[i] == TS_SYNC_BYTE) {
|
||||||
|
Length = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_AC3Buffer.Del(Length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processed = true;
|
||||||
|
if (const uint8_t *p = m_AC3Assembler.GetPes(len)) {
|
||||||
|
if (m_DetectAC3.processAudio(p, len))
|
||||||
|
m_AC3Valid = true;
|
||||||
|
m_AC3Assembler.Reset();
|
||||||
|
}
|
||||||
|
m_AC3Assembler.PutTs(Data, Length);
|
||||||
|
m_AudioBuffer.Del(Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate bitrates
|
||||||
|
timeout = double(calcPeriod.Elapsed());
|
||||||
|
if (m_Active && (timeout >= (100.0 * femonConfig.calcinterval))) {
|
||||||
|
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
|
||||||
|
m_VideoBitrate = (1000.0 * 8.0 * 184.0 * m_VideoPacketCount) / timeout;
|
||||||
|
m_VideoPacketCount = 0;
|
||||||
|
m_AudioBitrate = (1000.0 * 8.0 * 184.0 * m_AudioPacketCount) / timeout;
|
||||||
|
m_AudioPacketCount = 0;
|
||||||
|
m_AC3Bitrate = (1000.0 * 8.0 * 184.0 * m_AC3PacketCount) / timeout;
|
||||||
|
m_AC3PacketCount = 0;
|
||||||
|
calcPeriod.Set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processed)
|
||||||
|
m_Sleep.Wait(10); // to avoid busy loop and reduce cpu load
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,36 +21,39 @@
|
|||||||
|
|
||||||
class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If {
|
class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If {
|
||||||
private:
|
private:
|
||||||
cMutex m_Mutex;
|
cMutex m_Mutex;
|
||||||
cCondWait m_Sleep;
|
cCondWait m_Sleep;
|
||||||
bool m_Active;
|
bool m_Active;
|
||||||
|
|
||||||
cFemonH264 m_DetectH264;
|
cFemonH264 m_DetectH264;
|
||||||
cFemonMPEG m_DetectMPEG;
|
cFemonMPEG m_DetectMPEG;
|
||||||
cFemonAAC m_DetectAAC;
|
cFemonAAC m_DetectAAC;
|
||||||
cFemonAC3 m_DetectAC3;
|
cFemonAC3 m_DetectAC3;
|
||||||
|
|
||||||
cTsToPes m_VideoAssembler;
|
cRingBufferLinear m_VideoBuffer;
|
||||||
int m_VideoType;
|
cTsToPes m_VideoAssembler;
|
||||||
int m_VideoPid;
|
int m_VideoType;
|
||||||
int m_VideoPacketCount;
|
int m_VideoPid;
|
||||||
double m_VideoBitrate;
|
int m_VideoPacketCount;
|
||||||
bool m_VideoValid;
|
double m_VideoBitrate;
|
||||||
video_info_t m_VideoInfo;
|
bool m_VideoValid;
|
||||||
|
video_info_t m_VideoInfo;
|
||||||
|
|
||||||
cTsToPes m_AudioAssembler;
|
cRingBufferLinear m_AudioBuffer;
|
||||||
int m_AudioPid;
|
cTsToPes m_AudioAssembler;
|
||||||
int m_AudioPacketCount;
|
int m_AudioPid;
|
||||||
double m_AudioBitrate;
|
int m_AudioPacketCount;
|
||||||
bool m_AudioValid;
|
double m_AudioBitrate;
|
||||||
audio_info_t m_AudioInfo;
|
bool m_AudioValid;
|
||||||
|
audio_info_t m_AudioInfo;
|
||||||
|
|
||||||
cTsToPes m_AC3Assembler;
|
cRingBufferLinear m_AC3Buffer;
|
||||||
int m_AC3Pid;
|
cTsToPes m_AC3Assembler;
|
||||||
int m_AC3PacketCount;
|
int m_AC3Pid;
|
||||||
double m_AC3Bitrate;
|
int m_AC3PacketCount;
|
||||||
bool m_AC3Valid;
|
double m_AC3Bitrate;
|
||||||
ac3_info_t m_AC3Info;
|
bool m_AC3Valid;
|
||||||
|
ac3_info_t m_AC3Info;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Activate(bool On);
|
virtual void Activate(bool On);
|
||||||
|
@ -99,13 +99,13 @@ cString getFrontendInfo(int cardIndex)
|
|||||||
if (ioctl(fe, FE_READ_STATUS, &status) >= 0)
|
if (ioctl(fe, FE_READ_STATUS, &status) >= 0)
|
||||||
info = cString::sprintf("%s\nSTAT:%02X", *info, status);
|
info = cString::sprintf("%s\nSTAT:%02X", *info, status);
|
||||||
if (ioctl(fe, FE_READ_SIGNAL_STRENGTH, &signal) >= 0)
|
if (ioctl(fe, FE_READ_SIGNAL_STRENGTH, &signal) >= 0)
|
||||||
info = cString::sprintf("%s\nSGNL:%04" PRIX16, *info, signal);
|
info = cString::sprintf("%s\nSGNL:%04X", *info, signal);
|
||||||
if (ioctl(fe, FE_READ_SNR, &snr) >= 0)
|
if (ioctl(fe, FE_READ_SNR, &snr) >= 0)
|
||||||
info = cString::sprintf("%s\nSNRA:%04" PRIX16, *info, snr);
|
info = cString::sprintf("%s\nSNRA:%04X", *info, snr);
|
||||||
if (ioctl(fe, FE_READ_BER, &ber) >= 0)
|
if (ioctl(fe, FE_READ_BER, &ber) >= 0)
|
||||||
info = cString::sprintf("%s\nBERA:%08" PRIX32, *info, ber);
|
info = cString::sprintf("%s\nBERA:%08X", *info, ber);
|
||||||
if (ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &unc) >= 0)
|
if (ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &unc) >= 0)
|
||||||
info = cString::sprintf("%s\nUNCB:%08" PRIX32, *info, unc);
|
info = cString::sprintf("%s\nUNCB:%08X", *info, unc);
|
||||||
close(fe);
|
close(fe);
|
||||||
|
|
||||||
if (cFemonOsd::Instance())
|
if (cFemonOsd::Instance())
|
||||||
|
Loading…
Reference in New Issue
Block a user