summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY4
-rw-r--r--Makefile1
-rw-r--r--config.c2
-rw-r--r--config.h1
-rw-r--r--displaychannel.c2
-rw-r--r--dtd/displaychannel.dtd7
-rw-r--r--libcore/femonreceiver.c184
-rw-r--r--libcore/femonreceiver.h53
-rw-r--r--libtemplate/templateview.c6
-rw-r--r--libtemplate/templateviewelement.h1
-rw-r--r--skindesigner.c2
-rw-r--r--skins/metrixhd/xmlfiles/displaychannel.xml18
-rw-r--r--skinskeleton/xmlfiles/displaychannel.xml9
-rw-r--r--views/displaychannelview.c29
-rw-r--r--views/displaychannelview.h2
-rw-r--r--views/viewhelpers.c74
-rw-r--r--views/viewhelpers.h17
17 files changed, 402 insertions, 10 deletions
diff --git a/HISTORY b/HISTORY
index e458949..e918aea 100644
--- a/HISTORY
+++ b/HISTORY
@@ -42,6 +42,8 @@ Version 0.0.2
Version 0.0.3
-
+- added tokens for current video and audio bitrate in displaychannel. Thx @rofafor for the original code
+ in the femon plugin and _Martin_ for extracting the code in skinflatplus
+- changed skin metrixHD to display bitrate infos
diff --git a/Makefile b/Makefile
index 2be7976..2160ae6 100644
--- a/Makefile
+++ b/Makefile
@@ -78,6 +78,7 @@ OBJS = $(PLUGIN).o \
libcore/recfolderinfo.o \
libcore/extrecinfo.o \
libcore/timers.o \
+ libcore/femonreceiver.o \
libtemplate/globals.o \
libtemplate/parameter.o \
libtemplate/template.o \
diff --git a/config.c b/config.c
index 4ef6964..a3ec23d 100644
--- a/config.c
+++ b/config.c
@@ -23,6 +23,8 @@ cDesignerConfig::cDesignerConfig() {
//menu display style, display menu items
//one after each other or in one step
blockFlush = 1;
+ //interval for femon receiver to recalculate bitrates in tenth of a second
+ bitrateCalcInterval = 10;
//remember current skin and theme, osd size and osd fonts
SetSkin();
SetOSDSize();
diff --git a/config.h b/config.h
index 7773208..9c5429e 100644
--- a/config.h
+++ b/config.h
@@ -61,6 +61,7 @@ public:
int rerunDistance;
int rerunMaxChannel;
int blockFlush;
+ int bitrateCalcInterval;
};
#ifdef DEFINE_CONFIG
diff --git a/displaychannel.c b/displaychannel.c
index 97013bb..0ddb514 100644
--- a/displaychannel.c
+++ b/displaychannel.c
@@ -186,12 +186,14 @@ void cSDDisplayChannel::Flush(void) {
channelView->DrawSignal();
channelView->DrawAudioInfo();
channelView->DrawDevices(initial);
+ channelView->DrawBitrates();
} else {
channelView->ClearStatusIcons();
channelView->ClearScreenResolution();
channelView->ClearSignal();
channelView->ClearSignalBackground();
channelView->ClearDevices();
+ channelView->DrawBitrates();
}
if (initial) {
diff --git a/dtd/displaychannel.dtd b/dtd/displaychannel.dtd
index a99e87e..f3b76ab 100644
--- a/dtd/displaychannel.dtd
+++ b/dtd/displaychannel.dtd
@@ -4,7 +4,7 @@
<!ELEMENT displaychannel (background | channelinfo | epginfo | progressbar | progressbarback |
statusinfo | audioinfo | screenresolution | channelgroup |
- signalquality | signalqualityback | devices | scrapercontent |
+ signalquality | signalqualityback | devices | bitrate | scrapercontent |
datetime | message | customtokens)* >
<!ATTLIST displaychannel
x CDATA #REQUIRED
@@ -78,6 +78,11 @@
debug CDATA #IMPLIED
>
+<!ELEMENT bitrate (area|areascroll)*>
+<!ATTLIST bitrate
+ debug CDATA #IMPLIED
+>
+
<!ELEMENT scrapercontent (area|areascroll)*>
<!ATTLIST scrapercontent
debug CDATA #IMPLIED
diff --git a/libcore/femonreceiver.c b/libcore/femonreceiver.c
new file mode 100644
index 0000000..56a362c
--- /dev/null
+++ b/libcore/femonreceiver.c
@@ -0,0 +1,184 @@
+#include <unistd.h>
+#include "../config.h"
+#include "femonreceiver.h"
+
+cFemonReceiver::cFemonReceiver(const cChannel *Channel, int ATrack, int DTrack)
+ : cReceiver(Channel),
+ cThread("femon receiver"),
+ m_Mutex(),
+ m_Sleep(),
+ m_Active(false),
+ m_VideoBuffer(KILOBYTE(512), TS_SIZE, false, "Femon video"),
+ m_VideoType(Channel ? Channel->Vtype(): 0),
+ m_VideoPid(Channel ? Channel->Vpid() : 0),
+ m_VideoPacketCount(0),
+ m_AudioBuffer(KILOBYTE(256), TS_SIZE, false, "Femon audio"),
+ m_AudioPid(Channel ? Channel->Apid(ATrack) : 0),
+ m_AudioPacketCount(0),
+ m_AC3Buffer(KILOBYTE(256), TS_SIZE, false, "Femon AC3"),
+ m_AC3Pid(Channel ? Channel->Dpid(DTrack) : 0),
+ m_AC3PacketCount(0)
+{
+ SetPids(NULL);
+ AddPid(m_VideoPid);
+ AddPid(m_AudioPid);
+ AddPid(m_AC3Pid);
+
+ m_VideoBuffer.SetTimeouts(0, 100);
+ m_AudioBuffer.SetTimeouts(0, 100);
+ m_AC3Buffer.SetTimeouts(0, 100);
+
+ m_VideoBitrate = 0.0;
+ m_AudioBitrate = 0.0;
+ m_AC3Bitrate = 0.0;
+}
+
+cFemonReceiver::~cFemonReceiver(void)
+{
+ Deactivate();
+}
+
+void cFemonReceiver::Deactivate(void)
+{
+ Detach();
+ if (m_Active) {
+ m_Active = false;
+ m_Sleep.Signal();
+ if (Running())
+ Cancel(3);
+ }
+}
+
+void cFemonReceiver::Activate(bool On)
+{
+ if (On)
+ Start();
+ else
+ Deactivate();
+}
+
+void cFemonReceiver::Receive(uchar *Data, int Length)
+{
+ // TS packet length: TS_SIZE
+ if (Running() && (*Data == TS_SYNC_BYTE) && (Length == TS_SIZE)) {
+ int len, pid = TsPid(Data);
+ if (pid == m_VideoPid) {
+ ++m_VideoPacketCount;
+ len = m_VideoBuffer.Put(Data, Length);
+ if (len != Length) {
+ m_VideoBuffer.ReportOverflow(Length - len);
+ m_VideoBuffer.Clear();
+ }
+ }
+ else if (pid == m_AudioPid) {
+ ++m_AudioPacketCount;
+ len = m_AudioBuffer.Put(Data, Length);
+ if (len != Length) {
+ m_AudioBuffer.ReportOverflow(Length - len);
+ m_AudioBuffer.Clear();
+ }
+ }
+ else if (pid == m_AC3Pid) {
+ ++m_AC3PacketCount;
+ len = m_AC3Buffer.Put(Data, Length);
+ if (len != Length) {
+ m_AC3Buffer.ReportOverflow(Length - len);
+ m_AC3Buffer.Clear();
+ }
+ }
+ }
+}
+
+void cFemonReceiver::Action(void)
+{
+ cTimeMs calcPeriod(0);
+ m_Active = true;
+ bool init = true;
+ while (Running() && m_Active) {
+ uint8_t *Data;
+ double timeout;
+ int Length;
+ bool processed = false;
+
+ // process available video data
+ while ((Data = m_VideoBuffer.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_VideoBuffer.Del(Length);
+ continue;
+ }
+ processed = true;
+ if (TsPayloadStart(Data)) {
+ 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;
+ 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;
+ m_AC3Assembler.PutTs(Data, Length);
+ m_AC3Buffer.Del(Length);
+ }
+
+ // calculate bitrates
+ timeout = double(calcPeriod.Elapsed());
+ if (m_Active && (init || (timeout >= (100.0 * config.bitrateCalcInterval )))) {
+ // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
+ // PES headers should be compensated!
+ m_VideoBitrate = (1000.0 * 8.0 * 184.0 * m_VideoPacketCount) / timeout;
+ m_VideoPacketCount = 0;
+ m_AudioBitrate = (1000.0 * 8.0 * 184.0 * m_AudioPacketCount) / timeout;
+ m_AudioPacketCount = 0;
+ m_AC3Bitrate = (1000.0 * 8.0 * 184.0 * m_AC3PacketCount) / timeout;
+ m_AC3PacketCount = 0;
+ calcPeriod.Set(0);
+ init = false;
+ }
+
+ if (!processed)
+ m_Sleep.Wait(10); // to avoid busy loop and reduce cpu load
+ }
+}
diff --git a/libcore/femonreceiver.h b/libcore/femonreceiver.h
new file mode 100644
index 0000000..2720ff1
--- /dev/null
+++ b/libcore/femonreceiver.h
@@ -0,0 +1,53 @@
+#ifndef __FEMONRECEIVER_H
+#define __FEMONRECEIVER_H
+
+#include <vdr/thread.h>
+#include <vdr/receiver.h>
+
+class cFemonReceiver : public cReceiver, public cThread {
+ private:
+ cMutex m_Mutex;
+ cCondWait m_Sleep;
+ bool m_Active;
+
+ cRingBufferLinear m_VideoBuffer;
+ cTsToPes m_VideoAssembler;
+ int m_VideoType;
+ int m_VideoPid;
+ int m_VideoPacketCount;
+ double m_VideoBitrate;
+
+ cRingBufferLinear m_AudioBuffer;
+ cTsToPes m_AudioAssembler;
+ int m_AudioPid;
+ int m_AudioPacketCount;
+ double m_AudioBitrate;
+ bool m_AudioValid;
+
+ cRingBufferLinear m_AC3Buffer;
+ cTsToPes m_AC3Assembler;
+ int m_AC3Pid;
+ int m_AC3PacketCount;
+ double m_AC3Bitrate;
+ bool m_AC3Valid;
+
+ protected:
+ virtual void Activate(bool On);
+ virtual void Receive(uchar *Data, int Length);
+ virtual void Action(void);
+
+ public:
+ cFemonReceiver(const cChannel* Channel, int ATrack, int DTrack);
+ virtual ~cFemonReceiver();
+ void Deactivate(void);
+
+ double VideoBitrate(void) { cMutexLock MutexLock(&m_Mutex);
+ return m_VideoBitrate; }; // bit/s
+ double AudioBitrate(void) { cMutexLock MutexLock(&m_Mutex);
+ return m_AudioBitrate; }; // bit/s
+ double AC3Bitrate(void) { cMutexLock MutexLock(&m_Mutex);
+ return m_AC3Bitrate; }; // bit/s
+};
+
+#endif //__FEMONRECEIVER_H
+
diff --git a/libtemplate/templateview.c b/libtemplate/templateview.c
index f122732..a032349 100644
--- a/libtemplate/templateview.c
+++ b/libtemplate/templateview.c
@@ -613,6 +613,7 @@ void cTemplateViewChannel::SetViewElements(void) {
viewElementsAllowed.insert("signalquality");
viewElementsAllowed.insert("signalqualityback");
viewElementsAllowed.insert("devices");
+ viewElementsAllowed.insert("bitrate");
viewElementsAllowed.insert("scrapercontent");
viewElementsAllowed.insert("datetime");
viewElementsAllowed.insert("message");
@@ -655,6 +656,9 @@ string cTemplateViewChannel::GetViewElementName(eViewElement ve) {
case veSignalQualityBack:
name = "Signal Quality Background";
break;
+ case veBitRate:
+ name = "Bit Rate";
+ break;
case veDevices:
name = "Devices";
break;
@@ -702,6 +706,8 @@ void cTemplateViewChannel::AddPixmap(string sViewElement, cTemplatePixmap *pix,
ve = veSignalQuality;
} else if (!sViewElement.compare("signalqualityback")) {
ve = veSignalQualityBack;
+ } else if (!sViewElement.compare("bitrate")) {
+ ve = veBitRate;
} else if (!sViewElement.compare("devices")) {
ve = veDevices;
} else if (!sViewElement.compare("scrapercontent")) {
diff --git a/libtemplate/templateviewelement.h b/libtemplate/templateviewelement.h
index 7fe78b9..a2605ca 100644
--- a/libtemplate/templateviewelement.h
+++ b/libtemplate/templateviewelement.h
@@ -37,6 +37,7 @@ enum eViewElement {
veScreenResolution,
veSignalQuality,
veSignalQualityBack,
+ veBitRate,
veScraperContent,
//DisplayMenu ViewElements
veHeader,
diff --git a/skindesigner.c b/skindesigner.c
index d6e8168..c2f499a 100644
--- a/skindesigner.c
+++ b/skindesigner.c
@@ -19,7 +19,7 @@
#endif
-static const char *VERSION = "0.0.3";
+static const char *VERSION = "0.0.4dev";
static const char *DESCRIPTION = "SkinDesigner";
static const char *MAINMENUENTRY = "Skin Designer";
diff --git a/skins/metrixhd/xmlfiles/displaychannel.xml b/skins/metrixhd/xmlfiles/displaychannel.xml
index 030e937..1e087d7 100644
--- a/skins/metrixhd/xmlfiles/displaychannel.xml
+++ b/skins/metrixhd/xmlfiles/displaychannel.xml
@@ -164,8 +164,9 @@
{signalquality} SNR value of currently displayed channel
-->
<signalquality>
- <area x="22%" y="94%" width="76%" height="6%" layer="3">
- <drawtext x="0" valign="center" font="{light}" fontsize="70%" color="{clrWhite}" text="STR: {signalstrength}% SNR: {signalquality}%" />
+ <area x="22%" y="94%" width="10%" height="6%" layer="3">
+ <drawtext x="0" y="0" font="{light}" fontsize="50%" color="{clrWhite}" text="STR: {signalstrength}%" />
+ <drawtext x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="SNR: {signalquality}%" />
</area>
</signalquality>
@@ -209,6 +210,19 @@
</devices>
<!-- Available Variables scrapercontent:
+ {bitratevideo} bitrate of currently displayed video track in MBit/s (with two decimal places)
+ {bitrateaudio} bitrate of currently displayed stereo audio track in KBit/s
+ {bitratedolby} bitrate of currently displayed ac3 audio track in KBit/s
+ {isdolby} true if bitrate of ac3 stream is > 0
+ -->
+ <bitrate>
+ <area x="32%" y="94%" width="15%" height="6%" layer="3">
+ <drawtext x="0" y="0" font="{light}" fontsize="50%" color="{clrWhite}" text="Video: {bitratevideo} MBit/s" />
+ <drawtext condition="not{isdolby}" x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="Stereo: {bitrateaudio} KBit/s" />
+ <drawtext condition="{isdolby}" x="0" y="50%" font="{light}" fontsize="50%" color="{clrWhite}" text="AC3: {bitratedolby} KBit/s" />
+ </area>
+ </bitrate>
+ <!-- Available Variables scrapercontent:
{mediapath} Full Path of Poster or Banner to use in image path attribute
{mediawidth} width of image in pixel
{mediaheight} height of image in pixel
diff --git a/skinskeleton/xmlfiles/displaychannel.xml b/skinskeleton/xmlfiles/displaychannel.xml
index 49a1630..1a9b459 100644
--- a/skinskeleton/xmlfiles/displaychannel.xml
+++ b/skinskeleton/xmlfiles/displaychannel.xml
@@ -126,6 +126,15 @@
</devices>
<!-- Available Variables scrapercontent:
+ {bitratevideo} bitrate of currently displayed video track in MBit/s (with two decimal places)
+ {bitrateaudio} bitrate of currently displayed stereo audio track in KBit/s
+ {bitratedolby} bitrate of currently displayed ac3 audio track in KBit/s
+ {isdolby} true if bitrate of ac3 stream is > 0
+ -->
+ <bitrate>
+ </bitrate>
+
+ <!-- Available Variables scrapercontent:
{mediapath} Full Path of Poster or Banner to use in image path attribute
{mediawidth} width of image in pixel
{mediaheight} height of image in pixel
diff --git a/views/displaychannelview.c b/views/displaychannelview.c
index e8b5177..486218a 100644
--- a/views/displaychannelview.c
+++ b/views/displaychannelview.c
@@ -5,7 +5,6 @@
#include "../libcore/timers.h"
#include "../libcore/helpers.h"
-
cDisplayChannelView::cDisplayChannelView(cTemplateView *tmplView) : cView(tmplView) {
lastDate = "";
lastScreenWidth = 0;
@@ -18,6 +17,7 @@ cDisplayChannelView::cDisplayChannelView(cTemplateView *tmplView) : cView(tmplVi
lastTracDesc = "";
lastTrackLang = "";
InitDevices();
+ InitFemonReceiver();
DeleteOsdOnExit();
SetFadeTime(tmplView->GetNumericParameter(ptFadeTime));
}
@@ -424,6 +424,33 @@ void cDisplayChannelView::ClearDevices(void) {
ClearViewElement(veDevices);
}
+void cDisplayChannelView::DrawBitrates(void) {
+ if (!ViewElementImplemented(veBitRate)) {
+ return;
+ }
+ double bitrateVideo;
+ double bitrateAudio;
+ double bitrateDolby;
+
+ bool changed = GetBitrates(bitrateVideo, bitrateAudio, bitrateDolby);
+ if (!changed) {
+ return;
+ }
+ map < string, string > stringTokens;
+ map < string, int > intTokens;
+ stringTokens.insert(pair<string,string>("bitratevideo", *cString::sprintf("%.2f", bitrateVideo)));
+ intTokens.insert(pair<string,int>("bitrateaudio", bitrateAudio));
+ intTokens.insert(pair<string,int>("bitratedolby", bitrateDolby));
+ intTokens.insert(pair<string,int>("isdolby", (bitrateDolby > 0) ? true : false));
+
+ ClearBitrates();
+ DrawViewElement(veBitRate, &stringTokens, &intTokens);
+}
+
+void cDisplayChannelView::ClearBitrates(void) {
+ ClearViewElement(veBitRate);
+}
+
void cDisplayChannelView::DrawChannelGroups(const cChannel *Channel, cString ChannelName) {
if (!ViewElementImplemented(veChannelGroup)) {
return;
diff --git a/views/displaychannelview.h b/views/displaychannelview.h
index 4cb0be4..f1167d8 100644
--- a/views/displaychannelview.h
+++ b/views/displaychannelview.h
@@ -47,6 +47,8 @@ public:
void ClearSignalBackground(void);
void DrawDevices(bool initial);
void ClearDevices(void);
+ void DrawBitrates(void);
+ void ClearBitrates(void);
void DrawChannelGroups(const cChannel *Channel, cString ChannelName);
void ClearChannelGroups(void);
void DisplayMessage(eMessageType Type, const char *Text);
diff --git a/views/viewhelpers.c b/views/viewhelpers.c
index d08d6f2..f4d86c7 100644
--- a/views/viewhelpers.c
+++ b/views/viewhelpers.c
@@ -4,6 +4,8 @@
cViewHelpers::cViewHelpers(void) {
devicesInit = false;
+ femonReceiver = NULL;
+ bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0;
}
cViewHelpers::~cViewHelpers() {
@@ -12,6 +14,10 @@ cViewHelpers::~cViewHelpers() {
delete[] lastSignalQuality;
delete[] recDevices;
}
+ if (femonReceiver) {
+ femonReceiver->Deactivate();
+ delete femonReceiver;
+ }
}
void cViewHelpers::InitDevices(void) {
@@ -131,4 +137,70 @@ bool cViewHelpers::SetDevices(bool initial, map<string,int> *intTokens, vector<m
intTokens->insert(pair<string, int>("numdevices", actualNumDevices));
return true;
-} \ No newline at end of file
+}
+
+void cViewHelpers::InitFemonReceiver(void) {
+ const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
+ eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
+ if (channel) {
+ femonReceiver = new cFemonReceiver(channel,
+ IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,
+ IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
+ cDevice::ActualDevice()->AttachReceiver(femonReceiver);
+ }
+}
+
+void cViewHelpers::ChannelSwitch(const cDevice * device, int channelNumber, bool liveView) {
+ if (!femonReceiver)
+ return;
+ bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0;
+ eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
+ const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
+
+ if (!liveView || !channelNumber || !channel || channel->Number() != channelNumber)
+ return;
+
+ if (femonReceiver) {
+ femonReceiver->Deactivate();
+ delete femonReceiver;
+ femonReceiver = NULL;
+ }
+ if (channel) {
+ femonReceiver = new cFemonReceiver(channel,
+ IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,
+ IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
+ cDevice::ActualDevice()->AttachReceiver(femonReceiver);
+ }
+}
+
+void cViewHelpers::SetAudioTrack(int Index, const char * const *Tracks) {
+ if (!femonReceiver)
+ return;
+ bitrateVideoLast = bitrateAudioLast = bitrateDolbyLast = 0.0;
+ eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
+ if (femonReceiver) {
+ femonReceiver->Deactivate();
+ delete femonReceiver;
+ femonReceiver = NULL;
+ }
+ const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
+ if (channel) {
+ femonReceiver = new cFemonReceiver(channel,
+ IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0,
+ IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0);
+ cDevice::ActualDevice()->AttachReceiver(femonReceiver);
+ }
+}
+
+bool cViewHelpers::GetBitrates(double &bitrateVideo, double &bitrateAudio, double &bitrateDolby) {
+ bitrateVideo = (int)(femonReceiver->VideoBitrate() / 1024 / 1024 * 100 + 0.5) / 100.0;
+ bitrateAudio = (int)(femonReceiver->AudioBitrate() / 1024 * 100 + 0.5) / 100.0;
+ bitrateDolby = (int)(femonReceiver->AC3Bitrate() / 1024 * 100 + 0.5) / 100.0;
+ if (bitrateVideo != bitrateVideoLast || bitrateAudio != bitrateAudioLast || bitrateDolby != bitrateDolbyLast) {
+ bitrateVideoLast = bitrateVideo;
+ bitrateAudioLast = bitrateAudio;
+ bitrateDolbyLast = bitrateDolby;
+ return true;
+ }
+ return false;
+}
diff --git a/views/viewhelpers.h b/views/viewhelpers.h
index d88651c..676a2d1 100644
--- a/views/viewhelpers.h
+++ b/views/viewhelpers.h
@@ -1,18 +1,29 @@
#ifndef __VIEWHELPERS_H
#define __VIEWHELPERS_H
-class cViewHelpers {
+#include <vdr/status.h>
+#include "../libcore/femonreceiver.h"
+
+class cViewHelpers : public cStatus {
private:
bool devicesInit;
int* lastSignalStrength;
int* lastSignalQuality;
bool* recDevices;
+ cFemonReceiver *femonReceiver;
+ double bitrateVideoLast;
+ double bitrateAudioLast;
+ double bitrateDolbyLast;
protected:
+ virtual void ChannelSwitch(const cDevice *device, int channelNumber, bool liveView);
+ virtual void SetAudioTrack(int Index, const char * const *Tracks);
+ void InitDevices(void);
+ bool SetDevices(bool initial, map<string,int> *intTokens, vector<map<string,string> > *devices);
+ void InitFemonReceiver(void);
+ bool GetBitrates(double &bitrateVideo, double &bitrateAudio, double &bitrateDolby);
public:
cViewHelpers(void);
virtual ~cViewHelpers(void);
- void InitDevices(void);
- bool SetDevices(bool initial, map<string,int> *intTokens, vector<map<string,string> > *devices);
};
#endif //__VIEWHELPERS_H \ No newline at end of file