summaryrefslogtreecommitdiff
path: root/libcore
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2014-10-28 16:39:42 +0100
committerlouis <louis.braun@gmx.de>2014-10-28 16:39:42 +0100
commitabd8fd8db042ae860bb5346ce886ee961a847ae6 (patch)
treeba5f6bfdcf8a899ebf43d32ba4ed3755e39d08c1 /libcore
parentc53dbf7cd63785a4e23b9d85faf6ac8493a7a9c3 (diff)
downloadvdr-plugin-skindesigner-abd8fd8db042ae860bb5346ce886ee961a847ae6.tar.gz
vdr-plugin-skindesigner-abd8fd8db042ae860bb5346ce886ee961a847ae6.tar.bz2
added tokens for current video and audio bitrate in displaychannel
Diffstat (limited to 'libcore')
-rw-r--r--libcore/femonreceiver.c184
-rw-r--r--libcore/femonreceiver.h53
2 files changed, 237 insertions, 0 deletions
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
+