diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/aac.c vdr-plugin-femon-2.2.1.git20150307.2205/aac.c --- vdr-plugin-femon-2.2.0.git20150222.1714/aac.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/aac.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * aac.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "tools.h" +#include "aac.h" + +#define IS_HEAAC_AUDIO(buf) (((buf)[0] == 0xFF) && (((buf)[1] & 0xF6) == 0xF0)) + +int cFemonAAC::sampleRateS[16] = +{ + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, -1, -1, -1, -1 +}; + +cFemonAAC::cFemonAAC(cFemonAudioIf *audioHandlerP) +: audioHandlerM(audioHandlerP) +{ +} + +cFemonAAC::~cFemonAAC() +{ +} + +bool cFemonAAC::processAudio(const uint8_t *bufP, int lenP) +{ + cFemonBitStream bs(bufP, lenP * 8); + + if (!audioHandlerM) + return false; + + /* ADTS Fixed Header: + * syncword 12b always: '111111111111' + * id 1b 0: MPEG-4, 1: MPEG-2 + * layer 2b always: '00' + * protection_absent 1b + * profile 2b 0: Main profile AAC MAIN 1: Low Complexity profile (LC) AAC LC 2: Scalable Sample Rate profile (SSR) AAC SSR 3: (reserved) AAC LTP + * sampling_frequency_index 4b + * private_bit 1b + * channel_configuration 3b + * original/copy 1b + * home 1b + * emphasis 2b only if ID == 0 (ie MPEG-4) + */ + + // skip PES header + if (!PesLongEnough(lenP)) + return false; + bs.SkipBits(8 * PesPayloadOffset(bufP)); + + // HE-AAC audio detection + if (bs.GetBits(12) != 0xFFF) // syncword + return false; + + bs.SkipBit(); // id + + // layer must be 0 + if (bs.GetBits(2)) // layer + return false; + + bs.SkipBit(); // protection_absent + bs.SkipBits(2); // profile + int sampling_frequency_index = bs.GetBits(4); // sampling_frequency_index + bs.SkipBit(); // private pid + int channel_configuration = bs.GetBits(3); // channel_configuration + + audioHandlerM->SetAudioCodec(AUDIO_CODEC_HEAAC); + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_RESERVED); + + switch (channel_configuration) { + case 0: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); + break; + + case 1: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); + break; + + case 2: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); + break; + + case 3: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); + break; + + default: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); + break; + } + + switch (sampling_frequency_index) { + case 0xC ... 0xF: + audioHandlerM->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); + break; + + default: + audioHandlerM->SetAudioSamplingFrequency(sampleRateS[sampling_frequency_index]); + break; + } + + return true; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/aac.h vdr-plugin-femon-2.2.1.git20150307.2205/aac.h --- vdr-plugin-femon-2.2.0.git20150222.1714/aac.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/aac.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * aac.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_AAC_H +#define __FEMON_AAC_H + +#include "audio.h" + +class cFemonAAC { +private: + cFemonAudioIf *audioHandlerM; + + static int sampleRateS[16]; + +public: + cFemonAAC(cFemonAudioIf *audioHandlerP); + virtual ~cFemonAAC(); + + bool processAudio(const uint8_t *bufP, int lenP); + }; + +#endif //__FEMON_AAC_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/ac3.c vdr-plugin-femon-2.2.1.git20150307.2205/ac3.c --- vdr-plugin-femon-2.2.0.git20150222.1714/ac3.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/ac3.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * ac3.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * AC3 Audio Header: http://www.atsc.org/standards/a_52a.pdf + */ + +#include "tools.h" +#include "ac3.h" + +int cFemonAC3::bitrateS[32] = +{ + 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int cFemonAC3::frequencieS[4] = +{ + 480, 441, 320, 0 +}; + +int cFemonAC3::frameS[3][32] = +{ + {64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024, 1152, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114, 1253, 1393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +cFemonAC3::cFemonAC3(cFemonAC3If *audioHandlerP) +: audioHandlerM(audioHandlerP) +{ +} + +cFemonAC3::~cFemonAC3() +{ +} + +bool cFemonAC3::processAudio(const uint8_t *bufP, int lenP) +{ + int fscod, frmsizcod, bsmod, acmod; + int centermixlevel = AUDIO_CENTER_MIX_LEVEL_INVALID; + int surroundmixlevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; + int dolbysurroundmode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + cFemonBitStream bs(bufP, lenP * 8); + + if (!audioHandlerM) + return false; + + // skip PES header + if (!PesLongEnough(lenP)) + return false; + bs.SkipBits(8 * PesPayloadOffset(bufP)); + + // http://rmworkshop.com/dvd_info/related_info/ac3hdr.htm + + // AC3 audio detection + if (bs.GetBits(16) != 0x0B77) // syncword + return false; + + bs.SkipBits(16); // CRC1 + + fscod = bs.GetBits(2); // sampling rate values + frmsizcod = bs.GetBits(6); // frame size code + + bs.SkipBits(5); // bitstream id + bsmod = bs.GetBits(3); // bitstream mode + acmod = bs.GetBits(3); // audio coding mode + + // 3 front channels + if ((acmod & 0x01) && (acmod != 0x01)) + centermixlevel = bs.GetBits(2); + + // if a surround channel exists + if (acmod & 0x04) + surroundmixlevel = bs.GetBits(2); + + // if in 2/0 mode + if (acmod == 0x02) + dolbysurroundmode = bs.GetBits(2); + + audioHandlerM->SetAC3Bitrate(1000 * bitrateS[frmsizcod >> 1]); + audioHandlerM->SetAC3SamplingFrequency(100 * frequencieS[fscod]); + audioHandlerM->SetAC3Bitstream(bsmod); + audioHandlerM->SetAC3AudioCoding(acmod); + audioHandlerM->SetAC3CenterMix(centermixlevel); + audioHandlerM->SetAC3SurroundMix(surroundmixlevel); + audioHandlerM->SetAC3DolbySurround(dolbysurroundmode); + + audioHandlerM->SetAC3LFE(bs.GetBit()); // low frequency effects on + audioHandlerM->SetAC3Dialog(bs.GetBits(5)); // dialog normalization + + return true; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/ac3.h vdr-plugin-femon-2.2.1.git20150307.2205/ac3.h --- vdr-plugin-femon-2.2.0.git20150222.1714/ac3.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/ac3.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,28 @@ +/* + * ac3.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_AC3_H +#define __FEMON_AC3_H + +#include "audio.h" + +class cFemonAC3 { +private: + cFemonAC3If *audioHandlerM; + + static int bitrateS[32]; + static int frequencieS[4]; + static int frameS[3][32]; + +public: + cFemonAC3(cFemonAC3If *audioHandlerP); + virtual ~cFemonAC3(); + + bool processAudio(const uint8_t *bufP, int lenP); + }; + +#endif //__FEMON_AC3_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/audio.h vdr-plugin-femon-2.2.1.git20150307.2205/audio.h --- vdr-plugin-femon-2.2.0.git20150222.1714/audio.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/audio.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,150 @@ +/* + * audio.h: Frontend Status Monitor plugin for the AUDIO Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMON_AUDIO_H +#define __FEMON_AUDIO_H + +enum eAudioCodec { + AUDIO_CODEC_INVALID = -1, + AUDIO_CODEC_UNKNOWN, + AUDIO_CODEC_MPEG1_I, + AUDIO_CODEC_MPEG1_II, + AUDIO_CODEC_MPEG1_III, + AUDIO_CODEC_MPEG2_I, + AUDIO_CODEC_MPEG2_II, + AUDIO_CODEC_MPEG2_III, + AUDIO_CODEC_HEAAC, + AUDIO_CODEC_LATM + }; + +enum eAudioChannelMode { + AUDIO_CHANNEL_MODE_INVALID = -1, + AUDIO_CHANNEL_MODE_STEREO, + AUDIO_CHANNEL_MODE_JOINT_STEREO, + AUDIO_CHANNEL_MODE_DUAL, + AUDIO_CHANNEL_MODE_SINGLE + }; + +enum eAudioBitrate { + AUDIO_BITRATE_RESERVED = -3, + AUDIO_BITRATE_FREE = -2, + AUDIO_BITRATE_INVALID = -1 + }; + +enum eAudioSamplingFrequency { + AUDIO_SAMPLING_FREQUENCY_RESERVED = -2, + AUDIO_SAMPLING_FREQUENCY_INVALID = -1 + }; + +enum eAudioCenterMixLevel { + AUDIO_CENTER_MIX_LEVEL_INVALID = -1, + AUDIO_CENTER_MIX_LEVEL_MINUS_3dB, + AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB, + AUDIO_CENTER_MIX_LEVEL_MINUS_6dB, + AUDIO_CENTER_MIX_LEVEL_RESERVED + }; + +enum eAudioSurroundMixLevel { + AUDIO_SURROUND_MIX_LEVEL_INVALID = -1, + AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB, + AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB, + AUDIO_SURROUND_MIX_LEVEL_0_dB, + AUDIO_SURROUND_MIX_LEVEL_RESERVED + }; + +enum eAudioDolbySurroundMode { + AUDIO_DOLBY_SURROUND_MODE_INVALID = -1, + AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED, + AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND, + AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND, + AUDIO_DOLBY_SURROUND_MODE_RESERVED + }; + +enum eAudioBitstreamMode { + AUDIO_BITSTREAM_MODE_INVALID = -1, + AUDIO_BITSTREAM_MODE_CM, + AUDIO_BITSTREAM_MODE_ME, + AUDIO_BITSTREAM_MODE_VI, + AUDIO_BITSTREAM_MODE_HI, + AUDIO_BITSTREAM_MODE_D, + AUDIO_BITSTREAM_MODE_C, + AUDIO_BITSTREAM_MODE_E, + AUDIO_BITSTREAM_MODE_VO_KAR + }; + +enum eAudioCodingMode { + AUDIO_CODING_MODE_INVALID = -1, + AUDIO_CODING_MODE_1_1, + AUDIO_CODING_MODE_1_0, + AUDIO_CODING_MODE_2_0, + AUDIO_CODING_MODE_3_0, + AUDIO_CODING_MODE_2_1, + AUDIO_CODING_MODE_3_1, + AUDIO_CODING_MODE_2_2, + AUDIO_CODING_MODE_3_2, + }; + +typedef struct audio_info { + eAudioCodec codec; // enum + double bitrate; // bit/s or eAudioBitrate + int samplingFrequency; // Hz or eAudioSamplingFrequency + int channelMode; // eAudioChannelMode +} audio_info_t; + +typedef struct ac3_info { + int bitrate; // bit/s or eAudioBitrate + int samplingFrequency; // Hz or eAudioSamplingFrequency + int bitstreamMode; // 0..7 or eAudioBitstreamMode + int audioCodingMode; // 0..7 or eAudioCodingMode + int dolbySurroundMode; // eAudioDolbySurroundMode + int centerMixLevel; // eAudioCenterMixLevel + int surroundMixLevel; // eAudioSurroundMixLevel + int dialogLevel; // -dB + bool lfe; // boolean +} ac3_info_t; + +class cFemonAudioIf { +public: + cFemonAudioIf() {} + virtual ~cFemonAudioIf() {} + + // enum + virtual void SetAudioCodec(eAudioCodec codecP) = 0; + // kbit/s or eAudioBitrate + virtual void SetAudioBitrate(double bitRateP) = 0; + // Hz or eAudioSamplingFrequency + virtual void SetAudioSamplingFrequency(int samplingP) = 0; + // eAudioChannelMode + virtual void SetAudioChannel(eAudioChannelMode modeP) = 0; + }; + +class cFemonAC3If { +public: + cFemonAC3If() {} + virtual ~cFemonAC3If() {} + + // bit/s or eAudioBitrate + virtual void SetAC3Bitrate(int bitRateP) = 0; + // Hz or eAudioSamplingFrequency + virtual void SetAC3SamplingFrequency(int samplingP) = 0; + // 0..7 or eAudioBitstreamMode + virtual void SetAC3Bitstream(int modeP) = 0; + // 0..7 or eAudioCodingMode + virtual void SetAC3AudioCoding(int modeP) = 0; + // eAudioDolbySurroundMode + virtual void SetAC3DolbySurround(int modeP) = 0; + // eAudioCenterMixLevel + virtual void SetAC3CenterMix(int levelP) = 0; + // eAudioSurroundMixLevel + virtual void SetAC3SurroundMix(int levelP) = 0; + // -dB + virtual void SetAC3Dialog(int levelP) = 0; + // boolean + virtual void SetAC3LFE(bool onoffP) = 0; + }; + +#endif //__FEMON_AUDIO_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/config.c vdr-plugin-femon-2.2.1.git20150307.2205/config.c --- vdr-plugin-femon-2.2.0.git20150222.1714/config.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/config.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * config.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include + +#include "tools.h" +#include "config.h" + +cFemonConfig FemonConfig; + +cFemonConfig::cFemonConfig() +: traceModeM(eTraceModeNormal), + hideMenuM(0), + displayModeM(0), + skinM(0), + themeM(0), + positionM(1), + downscaleM(0), + redLimitM(33), + greenLimitM(66), + updateIntervalM(5), + analyzeStreamM(1), + calcIntervalM(20), + useSvdrpM(0), + svdrpPortM(6419) +{ + SetSvdrpIp("0.0.0.0"); +} + +void cFemonConfig::SetSvdrpIp(const char *strP) +{ + strn0cpy(svdrpIpM, strP, sizeof(svdrpIpM)); +} + +const cFemonTheme FemonTheme[eFemonThemeMaxNumber] = +{ + { + // eFemonThemeClassic + 4, // bpp + 0x7F000000, // clrBackground + 0xFFFCFCFC, // clrTitleBackground + 0xFF000000, // clrTitleText + 0xFFFCC024, // clrActiveText + 0xFFFCFCFC, // clrInactiveText + 0xFFFC1414, // clrRed + 0xFFFCC024, // clrYellow + 0xFF24FC24, // clrGreen + }, + { + // eFemonThemeElchi + 4, // bpp + 0xC8000066, // clrBackground + 0xC833AAEE, // clrTitleBackground + 0xFF000000, // clrTitleText + 0xFFCCBB22, // clrActiveText + 0xFFFFFFFF, // clrInactiveText + 0xFFFF0000, // clrRed + 0xFFFFEE00, // clrYellow + 0xFF33CC33, // clrGreen + }, + { + // eFemonThemeSTTNG + 4, // bpp + 0x7F000000, // clrBackground + 0xFFFCC024, // clrTitleBackground + 0xFF000000, // clrTitleText + 0xFF00FCFC, // clrActiveText + 0xFFFCC024, // clrInactiveText + 0xFFFC1414, // clrRed + 0xFFFCC024, // clrYellow + 0xFF24FC24, // clrGreen + }, + { + // eFemonThemeDeepBlue + 4, // bpp + 0xC80C0C0C, // clrBackground + 0xC832557A, // clrTitleBackground + 0xFF000000, // clrTitleText + 0xFFCE7B00, // clrActiveText + 0xFF9A9A9A, // clrInactiveText + 0xFF992900, // clrRed + 0xFFCE7B00, // clrYellow + 0xFF336600, // clrGreen + }, + { + // eFemonThemeMoronimo + 4, // bpp + 0xDF294A6B, // clrBackground + 0xDF3E5578, // clrTitleBackground + 0xFF9BBAD7, // clrTitleText + 0xFFCE7B00, // clrActiveText + 0xFF9A9A9A, // clrInactiveText + 0xFF992900, // clrRed + 0xFFCE7B00, // clrYellow + 0xFF336600, // clrGreen + }, + { + // eFemonThemeEnigma + 4, // bpp + 0xB8DEE5FA, // clrBackground + 0xB84158BC, // clrTitleBackground + 0xFFFFFFFF, // clrTitleText + 0xFF000000, // clrActiveText + 0xFF000000, // clrInactiveText + 0xB8C40000, // clrRed + 0xB8C4C400, // clrYellow + 0xB800C400, // clrGreen + }, + { + // eFemonThemeEgalsTry + 4, // bpp + 0xCA2B1B9E, // clrBackground + 0xDFBEBAC3, // clrTitleBackground + 0xFF280249, // clrTitleText + 0xFFD4D7DB, // clrActiveText + 0xDFCFCFCF, // clrInactiveText + 0xFFFF0000, // clrRed + 0xFFFCC024, // clrYellow + 0xFF20980B, // clrGreen + }, + { + // eFemonThemeDuotone + 2, // bpp + 0x7F000000, // clrBackground + 0xFFFCFCFC, // clrTitleBackground + 0x7F000000, // clrTitleText + 0xFFFCFCFC, // clrActiveText + 0xFFFCFCFC, // clrInactiveText + 0xFFFC1414, // clrRed + 0xFFFCFCFC, // clrYellow + 0xFFFCFCFC, // clrGreen + }, + { + // eFemonThemeSilverGreen + 4, // bpp + 0xD9526470, // clrBackground + 0xD9293841, // clrTitleBackground + 0xFFB3BDCA, // clrTitleText + 0xFFCE7B00, // clrActiveText + 0xFFB3BDCA, // clrInactiveText + 0xFF992900, // clrRed + 0xFFCE7B00, // clrYellow + 0xFF336600, // clrGreen + }, + { + // eFemonThemePearlHD + 4, // bpp + 0x90000000, // clrBackground + 0xCC000000, // clrTitleBackground + 0xFFBEBEBE, // clrTitleText + 0xFF4E78B1, // clrActiveText + 0xFFBEBEBE, // clrInactiveText + 0xAAFF0000, // clrRed + 0xAAF8F800, // clrYellow + 0x6000ff00, // clrGreen + }, +}; diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/config.h vdr-plugin-femon-2.2.1.git20150307.2205/config.h --- vdr-plugin-femon-2.2.0.git20150222.1714/config.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/config.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,136 @@ +/* + * config.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_CONFIG_H +#define __FEMON_CONFIG_H + +#define MaxSvdrpIp 15 // xxx.xxx.xxx.xxx + +enum eFemonModes +{ + eFemonModeBasic, + eFemonModeTransponder, + eFemonModeStream, + eFemonModeAC3, + eFemonModeMaxNumber +}; + +class cFemonConfig +{ +private: + unsigned int traceModeM; + int hideMenuM; + int displayModeM; + int skinM; + int themeM; + int positionM; + int downscaleM; + int redLimitM; + int greenLimitM; + int updateIntervalM; + int analyzeStreamM; + int calcIntervalM; + int useSvdrpM; + int svdrpPortM; + char svdrpIpM[MaxSvdrpIp + 1]; // must end with additional null + +public: + enum eTraceMode { + eTraceModeNormal = 0x0000, + eTraceModeDebug1 = 0x0001, + eTraceModeDebug2 = 0x0002, + eTraceModeDebug3 = 0x0004, + eTraceModeDebug4 = 0x0008, + eTraceModeDebug5 = 0x0010, + eTraceModeDebug6 = 0x0020, + eTraceModeDebug7 = 0x0040, + eTraceModeDebug8 = 0x0080, + eTraceModeDebug9 = 0x0100, + eTraceModeDebug10 = 0x0200, + eTraceModeDebug11 = 0x0400, + eTraceModeDebug12 = 0x0800, + eTraceModeDebug13 = 0x1000, + eTraceModeDebug14 = 0x2000, + eTraceModeDebug15 = 0x4000, + eTraceModeDebug16 = 0x8000, + eTraceModeMask = 0xFFFF + }; + cFemonConfig(); + unsigned int GetTraceMode(void) const { return traceModeM; } + bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); } + int GetHideMenu(void) const { return hideMenuM; } + int GetDisplayMode(void) const { return displayModeM; } + int GetSkin(void) const { return skinM; } + int GetTheme(void) const { return themeM; } + int GetPosition(void) const { return positionM; } + int GetDownscale(void) const { return downscaleM; } + int GetRedLimit(void) const { return redLimitM; } + int GetGreenLimit(void) const { return greenLimitM; } + int GetUpdateInterval(void) const { return updateIntervalM; } + int GetAnalyzeStream(void) const { return analyzeStreamM; } + int GetCalcInterval(void) const { return calcIntervalM; } + int GetUseSvdrp(void) const { return useSvdrpM; } + int GetSvdrpPort(void) const { return svdrpPortM; } + const char *GetSvdrpIp(void) const { return svdrpIpM; } + + void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); } + void SetHideMenu(int hideMenuP) { hideMenuM = hideMenuP; } + void SetDisplayMode(int displayModeP) { if (displayModeM < 0 || displayModeM >= eFemonModeMaxNumber) displayModeM = 0; else displayModeM = displayModeP; } + void SetSkin(int skinP) { skinM = skinP; } + void SetTheme(int themeP) { themeM = themeP; } + void SetPosition(int positionP) { positionM = positionP; } + void SetDownscale(int downscaleP) { downscaleM = downscaleP; } + void SetRedLimit(int redLimitP) { redLimitM = redLimitP; } + void SetGreenLimit(int greenLimitP) { greenLimitM = greenLimitP; } + void SetUpdateInterval(int updateIntervalP) { updateIntervalM = updateIntervalP; } + void SetAnalyzeStream(int analyzeStreamP) { analyzeStreamM = analyzeStreamP; } + void SetCalcInterval(int calcIntervalP) { calcIntervalM = calcIntervalP; } + void SetUseSvdrp(int useSvdrpP) { useSvdrpM = useSvdrpP; } + void SetSvdrpPort(int svdrpPortP) { svdrpPortM = svdrpPortP; } + void SetSvdrpIp(const char *strP); +}; + +extern cFemonConfig FemonConfig; + +enum eFemonSkins +{ + eFemonSkinClassic, + eFemonSkinElchi, + eFemonSkinMaxNumber +}; + +enum eFemonThemes +{ + eFemonThemeClassic, + eFemonThemeElchi, + eFemonThemeSTTNG, + eFemonThemeDeepBlue, + eFemonThemeMoronimo, + eFemonThemeEnigma, + eFemonThemeEgalsTry, + eFemonThemeDuotone, + eFemonThemeSilverGreen, + eFemonThemePearlHD, + eFemonThemeMaxNumber +}; + +struct cFemonTheme +{ + int bpp; + unsigned int clrBackground; + unsigned int clrTitleBackground; + unsigned int clrTitleText; + unsigned int clrActiveText; + unsigned int clrInactiveText; + unsigned int clrRed; + unsigned int clrYellow; + unsigned int clrGreen; +}; + +extern const cFemonTheme FemonTheme[eFemonThemeMaxNumber]; + +#endif // __FEMON_CONFIG_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog --- vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog 2015-02-22 17:15:03.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog 2015-03-07 22:05:35.000000000 +0000 @@ -1,3 +1,10 @@ +vdr-plugin-femon (2.2.1.git20150307.2205-0yavdr0~precise) precise; urgency=low + + * 37be623: Merge branch 'master' of https://github.com/rofafor/vdr- + plugin-femon + + -- Frodo Sat, 07 Mar 2015 23:05:35 +0100 + vdr-plugin-femon (2.2.0.git20150222.1714-0yavdr0~precise) precise; urgency=low * aaaf0ee: Merge branch 'master' of https://github.com/rofafor/vdr- diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog.precise vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog.precise --- vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog.precise 2015-02-15 20:24:38.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog.precise 2015-02-22 17:15:15.000000000 +0000 @@ -1,3 +1,10 @@ +vdr-plugin-femon (2.2.0.git20150222.1714-0yavdr0~precise) precise; urgency=low + + * aaaf0ee: Merge branch 'master' of https://github.com/rofafor/vdr- + plugin-femon + + -- Frodo Sun, 22 Feb 2015 18:15:03 +0100 + vdr-plugin-femon (2.2.0.git20150215.2024-0yavdr0~precise) precise; urgency=low * c4602d2: Merge branch 'master' of https://github.com/rofafor/vdr- diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog.trusty vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog.trusty --- vdr-plugin-femon-2.2.0.git20150222.1714/debian/changelog.trusty 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/debian/changelog.trusty 2015-03-07 22:05:34.000000000 +0000 @@ -1,3 +1,10 @@ +vdr-plugin-femon (2.2.0.git20150222.1715-0yavdr0~trusty) trusty; urgency=low + + * aaaf0ee: Merge branch 'master' of https://github.com/rofafor/vdr- + plugin-femon + + -- Frodo Sun, 22 Feb 2015 18:15:15 +0100 + vdr-plugin-femon (2.2.0.git20150215.2024-0yavdr0~trusty) trusty; urgency=low * c4602d2: Merge branch 'master' of https://github.com/rofafor/vdr- diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonaac.c vdr-plugin-femon-2.2.1.git20150307.2205/femonaac.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonaac.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonaac.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include "femontools.h" -#include "femonaac.h" - -#define IS_HEAAC_AUDIO(buf) (((buf)[0] == 0xFF) && (((buf)[1] & 0xF6) == 0xF0)) - -int cFemonAAC::s_Samplerates[16] = -{ - 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, -1, -1, -1, -1 -}; - -cFemonAAC::cFemonAAC(cFemonAudioIf *audiohandler) -: m_AudioHandler(audiohandler) -{ -} - -cFemonAAC::~cFemonAAC() -{ -} - -bool cFemonAAC::processAudio(const uint8_t *buf, int len) -{ - cFemonBitStream bs(buf, len * 8); - - if (!m_AudioHandler) - return false; - - /* ADTS Fixed Header: - * syncword 12b always: '111111111111' - * id 1b 0: MPEG-4, 1: MPEG-2 - * layer 2b always: '00' - * protection_absent 1b - * profile 2b 0: Main profile AAC MAIN 1: Low Complexity profile (LC) AAC LC 2: Scalable Sample Rate profile (SSR) AAC SSR 3: (reserved) AAC LTP - * sampling_frequency_index 4b - * private_bit 1b - * channel_configuration 3b - * original/copy 1b - * home 1b - * emphasis 2b only if ID == 0 (ie MPEG-4) - */ - - // skip PES header - if (!PesLongEnough(len)) - return false; - bs.SkipBits(8 * PesPayloadOffset(buf)); - - // HE-AAC audio detection - if (bs.GetBits(12) != 0xFFF) // syncword - return false; - - bs.SkipBit(); // id - - // layer must be 0 - if (bs.GetBits(2)) // layer - return false; - - bs.SkipBit(); // protection_absent - bs.SkipBits(2); // profile - int sampling_frequency_index = bs.GetBits(4); // sampling_frequency_index - bs.SkipBit(); // private pid - int channel_configuration = bs.GetBits(3); // channel_configuration - - m_AudioHandler->SetAudioCodec(AUDIO_CODEC_HEAAC); - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED); - - switch (channel_configuration) { - case 0: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); - break; - - case 1: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); - break; - - case 2: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); - break; - - case 3: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); - break; - - default: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); - break; - } - - switch (sampling_frequency_index) { - case 0xC ... 0xF: - m_AudioHandler->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); - break; - - default: - m_AudioHandler->SetAudioSamplingFrequency(s_Samplerates[sampling_frequency_index]); - break; - } - - return true; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonaac.h vdr-plugin-femon-2.2.1.git20150307.2205/femonaac.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonaac.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonaac.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONAAC_H -#define __FEMONAAC_H - -#include "femonaudio.h" - -class cFemonAAC { -private: - cFemonAudioIf *m_AudioHandler; - - static int s_Samplerates[16]; - -public: - cFemonAAC(cFemonAudioIf *audiohandler); - virtual ~cFemonAAC(); - - bool processAudio(const uint8_t *buf, int len); - }; - -#endif //__FEMONAAC_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonac3.c vdr-plugin-femon-2.2.1.git20150307.2205/femonac3.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonac3.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonac3.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * AC3 Audio Header: http://www.atsc.org/standards/a_52a.pdf - */ - -#include "femontools.h" -#include "femonac3.h" - -int cFemonAC3::s_Bitrates[32] = -{ - 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -int cFemonAC3::s_Frequencies[4] = -{ - 480, 441, 320, 0 -}; - -int cFemonAC3::s_Frames[3][32] = -{ - {64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024, 1152, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114, 1253, 1393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -cFemonAC3::cFemonAC3(cFemonAC3If *audiohandler) -: m_AudioHandler(audiohandler) -{ -} - -cFemonAC3::~cFemonAC3() -{ -} - -bool cFemonAC3::processAudio(const uint8_t *buf, int len) -{ - int fscod, frmsizcod, bsmod, acmod; - int centermixlevel = AUDIO_CENTER_MIX_LEVEL_INVALID; - int surroundmixlevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; - int dolbysurroundmode = AUDIO_DOLBY_SURROUND_MODE_INVALID; - cFemonBitStream bs(buf, len * 8); - - if (!m_AudioHandler) - return false; - - // skip PES header - if (!PesLongEnough(len)) - return false; - bs.SkipBits(8 * PesPayloadOffset(buf)); - - // http://rmworkshop.com/dvd_info/related_info/ac3hdr.htm - - // AC3 audio detection - if (bs.GetBits(16) != 0x0B77) // syncword - return false; - - bs.SkipBits(16); // CRC1 - - fscod = bs.GetBits(2); // sampling rate values - frmsizcod = bs.GetBits(6); // frame size code - - bs.SkipBits(5); // bitstream id - bsmod = bs.GetBits(3); // bitstream mode - acmod = bs.GetBits(3); // audio coding mode - - // 3 front channels - if ((acmod & 0x01) && (acmod != 0x01)) - centermixlevel = bs.GetBits(2); - - // if a surround channel exists - if (acmod & 0x04) - surroundmixlevel = bs.GetBits(2); - - // if in 2/0 mode - if (acmod == 0x02) - dolbysurroundmode = bs.GetBits(2); - - m_AudioHandler->SetAC3Bitrate(1000 * s_Bitrates[frmsizcod >> 1]); - m_AudioHandler->SetAC3SamplingFrequency(100 * s_Frequencies[fscod]); - m_AudioHandler->SetAC3Bitstream(bsmod); - m_AudioHandler->SetAC3AudioCoding(acmod); - m_AudioHandler->SetAC3CenterMix(centermixlevel); - m_AudioHandler->SetAC3SurroundMix(surroundmixlevel); - m_AudioHandler->SetAC3DolbySurround(dolbysurroundmode); - - m_AudioHandler->SetAC3LFE(bs.GetBit()); // low frequency effects on - m_AudioHandler->SetAC3Dialog(bs.GetBits(5)); // dialog normalization - - return true; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonac3.h vdr-plugin-femon-2.2.1.git20150307.2205/femonac3.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonac3.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonac3.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONAC3_H -#define __FEMONAC3_H - -#include "femonaudio.h" - -class cFemonAC3 { -private: - cFemonAC3If *m_AudioHandler; - - static int s_Bitrates[32]; - static int s_Frequencies[4]; - static int s_Frames[3][32]; - -public: - cFemonAC3(cFemonAC3If *audiohandler); - virtual ~cFemonAC3(); - - bool processAudio(const uint8_t *buf, int len); - }; - -#endif //__FEMONAC3_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonaudio.h vdr-plugin-femon-2.2.1.git20150307.2205/femonaudio.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonaudio.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonaudio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -/* - * Frontend Status Monitor plugin for the AUDIO Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONAUDIO_H -#define __FEMONAUDIO_H - -enum eAudioCodec { - AUDIO_CODEC_INVALID = -1, - AUDIO_CODEC_UNKNOWN, - AUDIO_CODEC_MPEG1_I, - AUDIO_CODEC_MPEG1_II, - AUDIO_CODEC_MPEG1_III, - AUDIO_CODEC_MPEG2_I, - AUDIO_CODEC_MPEG2_II, - AUDIO_CODEC_MPEG2_III, - AUDIO_CODEC_HEAAC, - AUDIO_CODEC_LATM - }; - -enum eAudioChannelMode { - AUDIO_CHANNEL_MODE_INVALID = -1, - AUDIO_CHANNEL_MODE_STEREO, - AUDIO_CHANNEL_MODE_JOINT_STEREO, - AUDIO_CHANNEL_MODE_DUAL, - AUDIO_CHANNEL_MODE_SINGLE - }; - -enum eAudioBitrate { - AUDIO_BITRATE_RESERVED = -3, - AUDIO_BITRATE_FREE = -2, - AUDIO_BITRATE_INVALID = -1 - }; - -enum eAudioSamplingFrequency { - AUDIO_SAMPLING_FREQUENCY_RESERVED = -2, - AUDIO_SAMPLING_FREQUENCY_INVALID = -1 - }; - -enum eAudioCenterMixLevel { - AUDIO_CENTER_MIX_LEVEL_INVALID = -1, - AUDIO_CENTER_MIX_LEVEL_MINUS_3dB, - AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB, - AUDIO_CENTER_MIX_LEVEL_MINUS_6dB, - AUDIO_CENTER_MIX_LEVEL_RESERVED - }; - -enum eAudioSurroundMixLevel { - AUDIO_SURROUND_MIX_LEVEL_INVALID = -1, - AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB, - AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB, - AUDIO_SURROUND_MIX_LEVEL_0_dB, - AUDIO_SURROUND_MIX_LEVEL_RESERVED - }; - -enum eAudioDolbySurroundMode { - AUDIO_DOLBY_SURROUND_MODE_INVALID = -1, - AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED, - AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND, - AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND, - AUDIO_DOLBY_SURROUND_MODE_RESERVED - }; - -enum eAudioBitstreamMode { - AUDIO_BITSTREAM_MODE_INVALID = -1, - AUDIO_BITSTREAM_MODE_CM, - AUDIO_BITSTREAM_MODE_ME, - AUDIO_BITSTREAM_MODE_VI, - AUDIO_BITSTREAM_MODE_HI, - AUDIO_BITSTREAM_MODE_D, - AUDIO_BITSTREAM_MODE_C, - AUDIO_BITSTREAM_MODE_E, - AUDIO_BITSTREAM_MODE_VO_KAR - }; - -enum eAudioCodingMode { - AUDIO_CODING_MODE_INVALID = -1, - AUDIO_CODING_MODE_1_1, - AUDIO_CODING_MODE_1_0, - AUDIO_CODING_MODE_2_0, - AUDIO_CODING_MODE_3_0, - AUDIO_CODING_MODE_2_1, - AUDIO_CODING_MODE_3_1, - AUDIO_CODING_MODE_2_2, - AUDIO_CODING_MODE_3_2, - }; - -typedef struct audio_info { - eAudioCodec codec; // enum - double bitrate; // bit/s or eAudioBitrate - int samplingFrequency; // Hz or eAudioSamplingFrequency - int channelMode; // eAudioChannelMode -} audio_info_t; - -typedef struct ac3_info { - int bitrate; // bit/s or eAudioBitrate - int samplingFrequency; // Hz or eAudioSamplingFrequency - int bitstreamMode; // 0..7 or eAudioBitstreamMode - int audioCodingMode; // 0..7 or eAudioCodingMode - int dolbySurroundMode; // eAudioDolbySurroundMode - int centerMixLevel; // eAudioCenterMixLevel - int surroundMixLevel; // eAudioSurroundMixLevel - int dialogLevel; // -dB - bool lfe; // boolean -} ac3_info_t; - -class cFemonAudioIf { -public: - cFemonAudioIf() {} - virtual ~cFemonAudioIf() {} - - // enum - virtual void SetAudioCodec(eAudioCodec codec) = 0; - // kbit/s or eAudioBitrate - virtual void SetAudioBitrate(double bitrate) = 0; - // Hz or eAudioSamplingFrequency - virtual void SetAudioSamplingFrequency(int sampling) = 0; - // eAudioChannelMode - virtual void SetAudioChannel(eAudioChannelMode mode) = 0; - }; - -class cFemonAC3If { -public: - cFemonAC3If() {} - virtual ~cFemonAC3If() {} - - // bit/s or eAudioBitrate - virtual void SetAC3Bitrate(int bitrate) = 0; - // Hz or eAudioSamplingFrequency - virtual void SetAC3SamplingFrequency(int sampling) = 0; - // 0..7 or eAudioBitstreamMode - virtual void SetAC3Bitstream(int mode) = 0; - // 0..7 or eAudioCodingMode - virtual void SetAC3AudioCoding(int mode) = 0; - // eAudioDolbySurroundMode - virtual void SetAC3DolbySurround(int mode) = 0; - // eAudioCenterMixLevel - virtual void SetAC3CenterMix(int level) = 0; - // eAudioSurroundMixLevel - virtual void SetAC3SurroundMix(int level) = 0; - // -dB - virtual void SetAC3Dialog(int level) = 0; - // boolean - virtual void SetAC3LFE(bool onoff) = 0; - }; - -#endif //__FEMONAUDIO_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femon.c vdr-plugin-femon-2.2.1.git20150307.2205/femon.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femon.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femon.c 2015-03-07 22:05:34.000000000 +0000 @@ -1,18 +1,21 @@ /* - * Frontend Status Monitor plugin for the Video Disk Recorder + * femon.c: Frontend Status Monitor plugin for the Video Disk Recorder * * See the README file for copyright information and how to reach the author. * */ +#include #include #include #include -#include "femoncfg.h" -#include "femonreceiver.h" -#include "femonosd.h" + +#include "config.h" #include "femonservice.h" -#include "femontools.h" +#include "log.h" +#include "osd.h" +#include "tools.h" +#include "setup.h" #if defined(APIVERSNUM) && APIVERSNUM < 20200 #error "VDR-2.2.0 API version or greater is required!" @@ -22,7 +25,7 @@ #define GITVERSION "" #endif -static const char VERSION[] = "2.2.0" GITVERSION; +static const char VERSION[] = "2.2.1" GITVERSION; static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)"); static const char MAINMENUENTRY[] = trNOOP("Signal Information"); @@ -40,13 +43,13 @@ virtual void Housekeeping(void); virtual void MainThreadHook(void) {} virtual cString Active(void) { return NULL; } - virtual const char *MainMenuEntry(void) { return (femonConfig.hidemenu ? NULL : tr(MAINMENUENTRY)); } + virtual const char *MainMenuEntry(void) { return (FemonConfig.GetHideMenu() ? NULL : tr(MAINMENUENTRY)); } virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); - virtual bool SetupParse(const char *Name, const char *Value); - virtual bool Service(const char *Id, void *Data); + virtual bool SetupParse(const char *nameP, const char *valueP); + virtual bool Service(const char *idP, void *dataP); virtual const char **SVDRPHelpPages(void); - virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode); + virtual cString SVDRPCommand(const char *commandP, const char *optionP, int &replyCodeP); }; cPluginFemon::cPluginFemon() @@ -54,24 +57,40 @@ // Initialize any member variables here. // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! - debug("%s()\n", __PRETTY_FUNCTION__); + debug1("%s", __PRETTY_FUNCTION__); } cPluginFemon::~cPluginFemon() { // Clean up after yourself! - debug("%s()\n", __PRETTY_FUNCTION__); + debug1("%s", __PRETTY_FUNCTION__); } const char *cPluginFemon::CommandLineHelp(void) { // Return a string that describes all known command line options. - return NULL; + return " -t , --trace= set the tracing mode\n"; } bool cPluginFemon::ProcessArgs(int argc, char *argv[]) { // Implement command line argument processing here if applicable. + static const struct option long_options[] = { + { "trace", required_argument, NULL, 't' }, + { NULL, no_argument, NULL, 0 } + }; + + cString server; + int c; + while ((c = getopt_long(argc, argv, "t:", long_options, NULL)) != -1) { + switch (c) { + case 't': + FemonConfig.SetTraceMode(strtol(optarg, NULL, 0)); + break; + default: + return false; + } + } return true; } @@ -100,7 +119,7 @@ cOsdObject *cPluginFemon::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. - debug("%s()\n", __PRETTY_FUNCTION__); + debug1("%s", __PRETTY_FUNCTION__); if (cControl::Control() || (Channels.Count() <= 0)) Skins.Message(mtInfo, tr("Femon not available")); else @@ -108,35 +127,54 @@ return NULL; } -bool cPluginFemon::SetupParse(const char *Name, const char *Value) +cMenuSetupPage *cPluginFemon::SetupMenu(void) +{ + // Return a setup menu in case the plugin supports one. + return new cMenuFemonSetup; +} + +bool cPluginFemon::SetupParse(const char *nameP, const char *valueP) { // Parse your own setup parameters and store their values. - if (!strcasecmp(Name, "HideMenu")) femonConfig.hidemenu = atoi(Value); - else if (!strcasecmp(Name, "DisplayMode")) femonConfig.displaymode = atoi(Value); - else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value); - else if (!strcasecmp(Name, "Skin")) femonConfig.skin = atoi(Value); - else if (!strcasecmp(Name, "Theme")) femonConfig.theme = atoi(Value); - else if (!strcasecmp(Name, "Downscale")) femonConfig.downscale = atoi(Value); - else if (!strcasecmp(Name, "RedLimit")) femonConfig.redlimit = atoi(Value); - else if (!strcasecmp(Name, "GreenLimit")) femonConfig.greenlimit = atoi(Value); - else if (!strcasecmp(Name, "UpdateInterval")) femonConfig.updateinterval = atoi(Value); - else if (!strcasecmp(Name, "AnalStream")) femonConfig.analyzestream = atoi(Value); - else if (!strcasecmp(Name, "CalcInterval")) femonConfig.calcinterval = atoi(Value); - else if (!strcasecmp(Name, "UseSvdrp")) femonConfig.usesvdrp = atoi(Value); - else if (!strcasecmp(Name, "ServerPort")) femonConfig.svdrpport = atoi(Value); - else if (!strcasecmp(Name, "ServerIp")) strn0cpy(femonConfig.svdrpip, Value, sizeof(femonConfig.svdrpip)); + if (!strcasecmp(nameP, "HideMenu")) + FemonConfig.SetHideMenu(atoi(valueP)); + else if (!strcasecmp(nameP, "DisplayMode")) + FemonConfig.SetDisplayMode(atoi(valueP)); + else if (!strcasecmp(nameP, "Position")) + FemonConfig.SetPosition(atoi(valueP)); + else if (!strcasecmp(nameP, "Skin")) + FemonConfig.SetSkin(atoi(valueP)); + else if (!strcasecmp(nameP, "Theme")) + FemonConfig.SetTheme(atoi(valueP)); + else if (!strcasecmp(nameP, "Downscale")) + FemonConfig.SetDownscale(atoi(valueP)); + else if (!strcasecmp(nameP, "RedLimit")) + FemonConfig.SetRedLimit(atoi(valueP)); + else if (!strcasecmp(nameP, "GreenLimit")) + FemonConfig.SetGreenLimit(atoi(valueP)); + else if (!strcasecmp(nameP, "UpdateInterval")) + FemonConfig.SetUpdateInterval(atoi(valueP)); + else if (!strcasecmp(nameP, "AnalStream")) + FemonConfig.SetAnalyzeStream(atoi(valueP)); + else if (!strcasecmp(nameP, "CalcInterval")) + FemonConfig.SetCalcInterval(atoi(valueP)); + else if (!strcasecmp(nameP, "UseSvdrp")) + FemonConfig.SetUseSvdrp(atoi(valueP)); + else if (!strcasecmp(nameP, "ServerPort")) + FemonConfig.SetSvdrpPort(atoi(valueP)); + else if (!strcasecmp(nameP, "ServerIp")) + FemonConfig.SetSvdrpIp(valueP); else return false; - if (femonConfig.displaymode < 0 || femonConfig.displaymode >= eFemonModeMaxNumber) femonConfig.displaymode = 0; return true; } -bool cPluginFemon::Service(const char *Id, void *Data) +bool cPluginFemon::Service(const char *idP, void *dataP) { - if (strcmp(Id,"FemonService-v1.0") == 0) { - if (Data) { - FemonService_v1_0 *data = reinterpret_cast(Data); + if (strcmp(idP, "FemonService-v1.0") == 0) { + if (dataP) { + FemonService_v1_0 *data = reinterpret_cast(dataP); if (!cDevice::ActualDevice()) return false; cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice()); @@ -191,87 +229,94 @@ " Print the current audio bitrate [kbit/s].", "DDBR\n" " Print the current dolby bitrate [kbit/s].", + "TRAC [ ]\n" + " Gets and/or sets used tracing mode.\n", NULL }; return HelpPages; } -cString cPluginFemon::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) +cString cPluginFemon::SVDRPCommand(const char *commandP, const char *optionP, int &replyCodeP) { cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice()); - if (*Option && isnumber(Option)) { - cDvbDevice *dev2 = dynamic_cast(cDevice::GetDevice(int(strtol(Option, NULL, 10)))); + 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(cDevice::GetDevice(int(strtol(optionP, NULL, 10)))); if (dev2) dev = dev2; } if (cReplayControl::NowReplaying() || !dev) { - ReplyCode = 550; // Requested action not taken + replyCodeP = 550; // Requested action not taken return cString("Cannot open femon plugin while replaying"); } - if (strcasecmp(Command, "OPEN") == 0) { + if (strcasecmp(commandP, "OPEN") == 0) { if (!cFemonOsd::Instance()) cRemote::CallPlugin(Name()); return cString("Opening femon plugin"); } - else if (strcasecmp(Command, "QUIT") == 0) { + else if (strcasecmp(commandP, "QUIT") == 0) { if (cFemonOsd::Instance()) cRemote::Put(kBack); return cString("Closing femon plugin"); } - else if (strcasecmp(Command, "NEXT") == 0) { + else if (strcasecmp(commandP, "NEXT") == 0) { if (cFemonOsd::Instance()) return cString::sprintf("Switching to next device: %s", cFemonOsd::Instance()->DeviceSwitch(1) ? "ok" : "failed"); else return cString("Cannot switch device"); } - else if (strcasecmp(Command, "PREV") == 0) { + else if (strcasecmp(commandP, "PREV") == 0) { if (cFemonOsd::Instance()) return cString::sprintf("Switching to previous device: %s", cFemonOsd::Instance()->DeviceSwitch(-1) ? "ok" : "failed"); else return cString("Cannot switch device"); } - else if (strcasecmp(Command, "INFO") == 0) { + else if (strcasecmp(commandP, "INFO") == 0) { return getFrontendInfo(dev); } - else if (strcasecmp(Command, "NAME") == 0) { + else if (strcasecmp(commandP, "NAME") == 0) { return getFrontendName(dev); } - else if (strcasecmp(Command, "STAT") == 0) { + else if (strcasecmp(commandP, "STAT") == 0) { return getFrontendStatus(dev); } - else if (strcasecmp(Command, "STRG") == 0) { + else if (strcasecmp(commandP, "STRG") == 0) { return cString::sprintf("%d on device #%d", dev->SignalStrength(), dev->CardIndex()); } - else if (strcasecmp(Command, "QUAL") == 0) { + else if (strcasecmp(commandP, "QUAL") == 0) { return cString::sprintf("%d on device #%d", dev->SignalQuality(), dev->CardIndex()); } - else if (strcasecmp(Command, "SGNL") == 0) { + else if (strcasecmp(commandP, "SGNL") == 0) { int value = getSignal(dev); return cString::sprintf("%04X (%02d%%) on device #%d", value, value / 655, dev->CardIndex()); } - else if (strcasecmp(Command, "SNRA") == 0) { + 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(Command, "BERA") == 0) { + else if (strcasecmp(commandP, "BERA") == 0) { return cString::sprintf("%08X on device #%d", getBER(dev), dev->CardIndex()); } - else if (strcasecmp(Command, "UNCB") == 0) { + else if (strcasecmp(commandP, "UNCB") == 0) { return cString::sprintf("%08X on device #%d", getUNC(dev), dev->CardIndex()); } - else if (strcasecmp(Command, "VIBR") == 0) { + else if (strcasecmp(commandP, "VIBR") == 0) { if (cFemonOsd::Instance()) return cString::sprintf("%s on device #%d", *getBitrateMbits(cFemonOsd::Instance()->GetVideoBitrate()), cDevice::ActualDevice()->CardIndex()); else return cString::sprintf("--- Mbit/s on device #%d", cDevice::ActualDevice()->CardIndex()); } - else if (strcasecmp(Command, "AUBR") == 0) { + else if (strcasecmp(commandP, "AUBR") == 0) { if (cFemonOsd::Instance()) return cString::sprintf("%s on device #%d", *getBitrateKbits(cFemonOsd::Instance()->GetAudioBitrate()), cDevice::ActualDevice()->CardIndex()); else return cString::sprintf("--- kbit/s on device #%d", cDevice::ActualDevice()->CardIndex()); } - else if (strcasecmp(Command, "DDBR") == 0) { + else if (strcasecmp(commandP, "DDBR") == 0) { if (cFemonOsd::Instance()) return cString::sprintf("%s on device #%d", *getBitrateKbits(cFemonOsd::Instance()->GetDolbyBitrate()), cDevice::ActualDevice()->CardIndex()); else @@ -280,145 +325,4 @@ return NULL; } -class cMenuFemonSetup : public cMenuSetupPage { -private: - const char *dispmodes[eFemonModeMaxNumber]; - const char *skins[eFemonSkinMaxNumber]; - const char *themes[eFemonThemeMaxNumber]; - cFemonConfig data; - cVector help; - void Setup(void); -protected: - virtual eOSState ProcessKey(eKeys Key); - virtual void Store(void); -public: - cMenuFemonSetup(void); - }; - -cMenuFemonSetup::cMenuFemonSetup(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - dispmodes[eFemonModeBasic] = tr("basic"); - dispmodes[eFemonModeTransponder] = tr("transponder"); - dispmodes[eFemonModeStream] = tr("stream"); - dispmodes[eFemonModeAC3] = tr("AC-3"); - - skins[eFemonSkinClassic] = tr("Classic"); - skins[eFemonSkinElchi] = tr("Elchi"); - - themes[eFemonThemeClassic] = tr("Classic"); - themes[eFemonThemeElchi] = tr("Elchi"); - themes[eFemonThemeSTTNG] = tr("ST:TNG"); - themes[eFemonThemeDeepBlue] = tr("DeepBlue"); - themes[eFemonThemeMoronimo] = tr("Moronimo"); - themes[eFemonThemeEnigma] = tr("Enigma"); - themes[eFemonThemeEgalsTry] = tr("EgalsTry"); - themes[eFemonThemeDuotone] = tr("Duotone"); - themes[eFemonThemeSilverGreen] = tr("SilverGreen"); - themes[eFemonThemePearlHD] = tr("PearlHD"); - - data = femonConfig; - SetMenuCategory(mcSetupPlugins); - Setup(); -} - -void cMenuFemonSetup::Setup(void) -{ - int current = Current(); - - Clear(); - help.Clear(); - - Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &data.hidemenu)); - help.Append(tr("Define whether the main menu entry is hidden.")); - - Add(new cMenuEditStraItem(tr("Default display mode"), &data.displaymode, eFemonModeMaxNumber, dispmodes)); - help.Append(tr("Define the default display mode at startup.")); - - Add(new cMenuEditStraItem(trVDR("Setup.OSD$Skin"), &data.skin, eFemonSkinMaxNumber, skins)); - help.Append(tr("Define the used OSD skin.")); - - Add(new cMenuEditStraItem(trVDR("Setup.OSD$Theme"), &data.theme, eFemonThemeMaxNumber,themes)); - help.Append(tr("Define the used OSD theme.")); - - Add(new cMenuEditBoolItem(tr("Position"), &data.position, trVDR("bottom"), trVDR("top"))); - help.Append(tr("Define the position of OSD.")); - - Add(new cMenuEditIntItem(tr("Downscale OSD size [%]"), &data.downscale, 0, 20)); - help.Append(tr("Define the downscale ratio for OSD size.")); - - Add(new cMenuEditIntItem(tr("Red limit [%]"), &data.redlimit, 1, 50)); - help.Append(tr("Define a limit for red bar, which is used to indicate a bad signal.")); - - Add(new cMenuEditIntItem(tr("Green limit [%]"), &data.greenlimit, 51, 100)); - help.Append(tr("Define a limit for green bar, which is used to indicate a good signal.")); - - Add(new cMenuEditIntItem(tr("OSD update interval [0.1s]"), &data.updateinterval, 1, 100)); - help.Append(tr("Define an interval for OSD updates. The smaller interval generates higher CPU load.")); - - Add(new cMenuEditBoolItem(tr("Analyze stream"), &data.analyzestream)); - help.Append(tr("Define whether the DVB stream is analyzed and bitrates calculated.")); - - if (femonConfig.analyzestream) { - Add(new cMenuEditIntItem(tr("Calculation interval [0.1s]"), &data.calcinterval, 1, 100)); - help.Append(tr("Define an interval for calculation. The bigger interval generates more stable values.")); - } - - Add(new cMenuEditBoolItem(tr("Use SVDRP service"), &data.usesvdrp)); - help.Append(tr("Define whether the SVDRP service is used in client/server setups.")); - - if (data.usesvdrp) { - Add(new cMenuEditIntItem(tr("SVDRP service port"), &data.svdrpport, 1, 65535)); - help.Append(tr("Define the port number of SVDRP service.")); - - Add(new cMenuEditStrItem(tr("SVDRP service IP"), data.svdrpip, sizeof(data.svdrpip), ".1234567890")); - help.Append(tr("Define the IP address of SVDRP service.")); - } - - SetCurrent(Get(current)); - Display(); -} - -void cMenuFemonSetup::Store(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - femonConfig = data; - SetupStore("HideMenu", femonConfig.hidemenu); - SetupStore("DisplayMode", femonConfig.displaymode); - SetupStore("Skin", femonConfig.skin); - SetupStore("Theme", femonConfig.theme); - SetupStore("Position", femonConfig.position); - SetupStore("Downscale", femonConfig.downscale); - SetupStore("RedLimit", femonConfig.redlimit); - SetupStore("GreenLimit", femonConfig.greenlimit); - SetupStore("UpdateInterval", femonConfig.updateinterval); - SetupStore("AnalStream", femonConfig.analyzestream); - SetupStore("CalcInterval", femonConfig.calcinterval); - SetupStore("UseSvdrp", femonConfig.usesvdrp); - SetupStore("ServerPort", femonConfig.svdrpport); - SetupStore("ServerIp", femonConfig.svdrpip); -} - -eOSState cMenuFemonSetup::ProcessKey(eKeys Key) -{ - int oldUsesvdrp = data.usesvdrp; - int oldAnalyzestream = data.analyzestream; - - eOSState state = cMenuSetupPage::ProcessKey(Key); - - if (Key != kNone && (data.analyzestream != oldAnalyzestream || data.usesvdrp != oldUsesvdrp)) - Setup(); - - if ((Key == kInfo) && (state == osUnknown) && (Current() < help.Size())) - return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), help[Current()])); - - return state; -} - -cMenuSetupPage *cPluginFemon::SetupMenu(void) -{ - // Return a setup menu in case the plugin supports one. - return new cMenuFemonSetup; -} - VDRPLUGINCREATOR(cPluginFemon); // Don't touch this! diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femoncfg.c vdr-plugin-femon-2.2.1.git20150307.2205/femoncfg.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femoncfg.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femoncfg.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include -#include "femoncfg.h" - -cFemonConfig femonConfig; - -cFemonConfig::cFemonConfig(void) -{ - hidemenu = 0; - displaymode = 0; - skin = 0; - theme = 0; - position = 1; - downscale = 0; - redlimit = 33; - greenlimit = 66; - updateinterval = 5; - analyzestream = 1; - calcinterval = 20; - usesvdrp = 0; - svdrpport = 6419; - strncpy(svdrpip, "0.0.0.0", sizeof(svdrpip)); -} - -const cFemonTheme femonTheme[eFemonThemeMaxNumber] = -{ - { - // eFemonThemeClassic - 4, // bpp - 0x7F000000, // clrBackground - 0xFFFCFCFC, // clrTitleBackground - 0xFF000000, // clrTitleText - 0xFFFCC024, // clrActiveText - 0xFFFCFCFC, // clrInactiveText - 0xFFFC1414, // clrRed - 0xFFFCC024, // clrYellow - 0xFF24FC24, // clrGreen - }, - { - // eFemonThemeElchi - 4, // bpp - 0xC8000066, // clrBackground - 0xC833AAEE, // clrTitleBackground - 0xFF000000, // clrTitleText - 0xFFCCBB22, // clrActiveText - 0xFFFFFFFF, // clrInactiveText - 0xFFFF0000, // clrRed - 0xFFFFEE00, // clrYellow - 0xFF33CC33, // clrGreen - }, - { - // eFemonThemeSTTNG - 4, // bpp - 0x7F000000, // clrBackground - 0xFFFCC024, // clrTitleBackground - 0xFF000000, // clrTitleText - 0xFF00FCFC, // clrActiveText - 0xFFFCC024, // clrInactiveText - 0xFFFC1414, // clrRed - 0xFFFCC024, // clrYellow - 0xFF24FC24, // clrGreen - }, - { - // eFemonThemeDeepBlue - 4, // bpp - 0xC80C0C0C, // clrBackground - 0xC832557A, // clrTitleBackground - 0xFF000000, // clrTitleText - 0xFFCE7B00, // clrActiveText - 0xFF9A9A9A, // clrInactiveText - 0xFF992900, // clrRed - 0xFFCE7B00, // clrYellow - 0xFF336600, // clrGreen - }, - { - // eFemonThemeMoronimo - 4, // bpp - 0xDF294A6B, // clrBackground - 0xDF3E5578, // clrTitleBackground - 0xFF9BBAD7, // clrTitleText - 0xFFCE7B00, // clrActiveText - 0xFF9A9A9A, // clrInactiveText - 0xFF992900, // clrRed - 0xFFCE7B00, // clrYellow - 0xFF336600, // clrGreen - }, - { - // eFemonThemeEnigma - 4, // bpp - 0xB8DEE5FA, // clrBackground - 0xB84158BC, // clrTitleBackground - 0xFFFFFFFF, // clrTitleText - 0xFF000000, // clrActiveText - 0xFF000000, // clrInactiveText - 0xB8C40000, // clrRed - 0xB8C4C400, // clrYellow - 0xB800C400, // clrGreen - }, - { - // eFemonThemeEgalsTry - 4, // bpp - 0xCA2B1B9E, // clrBackground - 0xDFBEBAC3, // clrTitleBackground - 0xFF280249, // clrTitleText - 0xFFD4D7DB, // clrActiveText - 0xDFCFCFCF, // clrInactiveText - 0xFFFF0000, // clrRed - 0xFFFCC024, // clrYellow - 0xFF20980B, // clrGreen - }, - { - // eFemonThemeDuotone - 2, // bpp - 0x7F000000, // clrBackground - 0xFFFCFCFC, // clrTitleBackground - 0x7F000000, // clrTitleText - 0xFFFCFCFC, // clrActiveText - 0xFFFCFCFC, // clrInactiveText - 0xFFFC1414, // clrRed - 0xFFFCFCFC, // clrYellow - 0xFFFCFCFC, // clrGreen - }, - { - // eFemonThemeSilverGreen - 4, // bpp - 0xD9526470, // clrBackground - 0xD9293841, // clrTitleBackground - 0xFFB3BDCA, // clrTitleText - 0xFFCE7B00, // clrActiveText - 0xFFB3BDCA, // clrInactiveText - 0xFF992900, // clrRed - 0xFFCE7B00, // clrYellow - 0xFF336600, // clrGreen - }, - { - // eFemonThemePearlHD - 4, // bpp - 0x90000000, // clrBackground - 0xCC000000, // clrTitleBackground - 0xFFBEBEBE, // clrTitleText - 0xFF4E78B1, // clrActiveText - 0xFFBEBEBE, // clrInactiveText - 0xAAFF0000, // clrRed - 0xAAF8F800, // clrYellow - 0x6000ff00, // clrGreen - }, -}; diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femoncfg.h vdr-plugin-femon-2.2.1.git20150307.2205/femoncfg.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femoncfg.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femoncfg.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONCFG_H -#define __FEMONCFG_H - -#define MaxSvdrpIp 15 // xxx.xxx.xxx.xxx - -enum eFemonModes -{ - eFemonModeBasic, - eFemonModeTransponder, - eFemonModeStream, - eFemonModeAC3, - eFemonModeMaxNumber -}; - -struct cFemonConfig -{ -public: - cFemonConfig(void); - int hidemenu; - int displaymode; - int skin; - int theme; - int position; - int downscale; - int redlimit; - int greenlimit; - int updateinterval; - int analyzestream; - int calcinterval; - int usesvdrp; - int svdrpport; - char svdrpip[MaxSvdrpIp + 1]; // must end with additional null -}; - -extern cFemonConfig femonConfig; - -enum eFemonSkins -{ - eFemonSkinClassic, - eFemonSkinElchi, - eFemonSkinMaxNumber -}; - -enum eFemonThemes -{ - eFemonThemeClassic, - eFemonThemeElchi, - eFemonThemeSTTNG, - eFemonThemeDeepBlue, - eFemonThemeMoronimo, - eFemonThemeEnigma, - eFemonThemeEgalsTry, - eFemonThemeDuotone, - eFemonThemeSilverGreen, - eFemonThemePearlHD, - eFemonThemeMaxNumber -}; - -struct cFemonTheme -{ - int bpp; - unsigned int clrBackground; - unsigned int clrTitleBackground; - unsigned int clrTitleText; - unsigned int clrActiveText; - unsigned int clrInactiveText; - unsigned int clrRed; - unsigned int clrYellow; - unsigned int clrGreen; -}; - -extern const cFemonTheme femonTheme[eFemonThemeMaxNumber]; - -#endif // __FEMONCFG_H Binary files /tmp/IjaXcJPE_8/vdr-plugin-femon-2.2.0.git20150222.1714/femonclient/vdr-femonclient-0.0.6.tgz and /tmp/aouD85uOUP/vdr-plugin-femon-2.2.1.git20150307.2205/femonclient/vdr-femonclient-0.0.6.tgz differ diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonh264.c vdr-plugin-femon-2.2.1.git20150307.2205/femonh264.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonh264.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonh264.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,759 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include "femontools.h" -#include "femonh264.h" - -const cFemonH264::t_DAR cFemonH264::s_DAR[] = -{ - { 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 cFemonH264::t_SAR cFemonH264::s_SAR[] = -{ - { 0, 0 }, // VIDEO_ASPECT_RATIO_INVALID - { 1, 1 }, // VIDEO_ASPECT_RATIO_1_1 - { 12, 11 }, // VIDEO_ASPECT_RATIO_12_11 - { 10, 11 }, // VIDEO_ASPECT_RATIO_10_11 - { 16, 11 }, // VIDEO_ASPECT_RATIO_16_11 - { 40, 33 }, // VIDEO_ASPECT_RATIO_40_33 - { 24, 11 }, // VIDEO_ASPECT_RATIO_24_11 - { 20, 11 }, // VIDEO_ASPECT_RATIO_20_11 - { 32, 11 }, // VIDEO_ASPECT_RATIO_32_11 - { 80, 33 }, // VIDEO_ASPECT_RATIO_80_33 - { 18, 11 }, // VIDEO_ASPECT_RATIO_18_11 - { 15, 11 }, // VIDEO_ASPECT_RATIO_15_11 - { 64, 33 }, // VIDEO_ASPECT_RATIO_64_33 - { 160, 99 }, // VIDEO_ASPECT_RATIO_160_99 - { 4, 3 }, // VIDEO_ASPECT_RATIO_4_3 - { 3, 2 }, // VIDEO_ASPECT_RATIO_3_2 - { 2, 1 } // VIDEO_ASPECT_RATIO_2_1 -}; - -const eVideoFormat cFemonH264::s_VideoFormats[] = -{ - VIDEO_FORMAT_COMPONENT, - VIDEO_FORMAT_PAL, - VIDEO_FORMAT_NTSC, - VIDEO_FORMAT_SECAM, - VIDEO_FORMAT_MAC, - VIDEO_FORMAT_UNKNOWN, - VIDEO_FORMAT_RESERVED -}; - -const uint8_t cFemonH264::s_SeiNumClockTsTable[9] = -{ - 1, 1, 1, 2, 2, 3, 3, 2, 3 -}; - -cFemonH264::cFemonH264(cFemonVideoIf *videohandler) -: m_VideoHandler(videohandler), - m_Width(0), - m_Height(0), - m_AspectRatio(VIDEO_ASPECT_RATIO_INVALID), - m_Format(VIDEO_FORMAT_INVALID), - m_FrameRate(0), - m_BitRate(0), - m_Scan(VIDEO_SCAN_INVALID), - m_CpbDpbDelaysPresentFlag(false), - m_PicStructPresentFlag(false), - m_FrameMbsOnlyFlag(false), - m_MbAdaptiveFrameFieldFlag(false), - m_TimeOffsetLength(0) -{ - reset(); -} - -cFemonH264::~cFemonH264() -{ -} - -bool cFemonH264::processVideo(const uint8_t *buf, int len) -{ - uint8_t nal_data[len]; - bool aud_found = false, sps_found = false, sei_found = true; // SEI temporarily disabled! - const uint8_t *start = buf; - const uint8_t *end = start + len; - - if (!m_VideoHandler) - return false; - - // skip PES header - if (!PesLongEnough(len)) - return false; - buf += PesPayloadOffset(buf); - start = buf; - - reset(); - - for (;;) { - int consumed = 0; - - buf = nextStartCode(buf, end); - if (buf >= end) - break; - - switch (buf[3] & 0x1F) { - case NAL_AUD: - if (!aud_found) { - switch (buf[4] >> 5) { - case 0: case 3: case 5: // I_FRAME - //debug("H.264: Found NAL AUD at offset %d/%d\n", int(buf - start), len); - aud_found = true; - break; - case 1: case 4: case 6: // P_FRAME; - case 2: case 7: // B_FRAME; - default: // NO_PICTURE; - break; - } - } - break; - - case NAL_SPS: - if (!sps_found) { - //debug("H.264: Found NAL SPS at offset %d/%d\n", int(buf - start), len); - int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4)); - consumed = parseSPS(nal_data, nal_len); - if (consumed > 0) - sps_found = true; - } - break; - - case NAL_SEI: - if (!sei_found) { - //debug("H.264: Found NAL SEI at offset %d/%d\n", int(buf - start), len); - int nal_len = nalUnescape(nal_data, buf + 4, int(end - buf - 4)); - 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) { - m_VideoHandler->SetVideoCodec(VIDEO_CODEC_H264); - if (sps_found) { - //debug("H.264: size %dx%d, aspect %d format %d bitrate %.0f\n", m_Width, m_Height, m_AspectRatio, m_Format, m_BitRate); - m_VideoHandler->SetVideoFormat(m_Format); - m_VideoHandler->SetVideoSize(m_Width, m_Height); - m_VideoHandler->SetVideoAspectRatio(m_AspectRatio); - m_VideoHandler->SetVideoBitrate(m_BitRate); - } - if (sps_found || sei_found) { - //debug("H.264: scan %d framerate %.2f\n", m_Scan, (m_Scan == VIDEO_SCAN_PROGRESSIVE) ? (m_FrameRate / 2) : m_FrameRate); - m_VideoHandler->SetVideoScan(m_Scan); - m_VideoHandler->SetVideoFramerate((m_Scan == VIDEO_SCAN_PROGRESSIVE) ? (m_FrameRate / 2) : m_FrameRate); - } - } - - return aud_found; -} - -void cFemonH264::reset() -{ - m_CpbDpbDelaysPresentFlag = false; - m_PicStructPresentFlag = false; - m_FrameMbsOnlyFlag = false; - m_MbAdaptiveFrameFieldFlag = false; - m_TimeOffsetLength = 0; -} - -const uint8_t *cFemonH264::nextStartCode(const uint8_t *start, const uint8_t *end) -{ - for (end -= 3; start < end; ++start) { - if ((start[0] == 0x00) && (start[1] == 0x00) && (start[2] == 0x01)) - return start; - } - return (end + 3); -} - -int cFemonH264::nalUnescape(uint8_t *dst, const uint8_t *src, int len) -{ - int s = 0, d = 0; - - while (s < len) { - if (!src[s] && !src[s + 1]) { - // hit 00 00 xx - dst[d] = dst[d + 1] = 0; - s += 2; - d += 2; - if (src[s] == 3) { - s++; // 00 00 03 xx --> 00 00 xx - if (s >= len) - return d; - } - } - dst[d++] = src[s++]; - } - - return d; -} - -int cFemonH264::parseSPS(const uint8_t *buf, int len) -{ - int profile_idc, level_idc, constraint_set3_flag, pic_order_cnt_type, i, j; - cFemonBitStream bs(buf, len); - - uint32_t width = m_Width; - uint32_t height = m_Height; - eVideoAspectRatio aspect_ratio = m_AspectRatio; - eVideoFormat format = m_Format; - double frame_rate = m_FrameRate; - double bit_rate = m_BitRate; - bool cpb_dpb_delays_present_flag = m_CpbDpbDelaysPresentFlag; - bool pic_struct_present_flag = m_PicStructPresentFlag; - bool frame_mbs_only_flag = m_FrameMbsOnlyFlag; - bool mb_adaptive_frame_field_flag = m_MbAdaptiveFrameFieldFlag; - uint32_t time_offset_length = m_TimeOffsetLength; - - profile_idc = bs.GetBits(8); // profile_idc - bs.SkipBit(); // constraint_set0_flag - bs.SkipBit(); // constraint_set1_flag - bs.SkipBit(); // constraint_set2_flag - constraint_set3_flag = bs.GetBit(); // constraint_set3_flag - bs.SkipBits(4); // reserved_zero_4bits - level_idc = bs.GetBits(8); // level_idc - bs.SkipUeGolomb(); // seq_parameter_set_id - //debug("H.264 SPS: profile_idc %d level_idc %d\n", profile_idc, level_idc); - switch (profile_idc) { - case 66: // baseline profile - case 77: // main profile - case 88: // extended profile - switch (level_idc) { - case 10: // level 1.0 - bit_rate = 64000; - break; - case 11: // level 1b / 1.1 - bit_rate = constraint_set3_flag ? 128000 : 192000; - break; - case 12: // level 1.2 - bit_rate = 384000; - break; - case 13: // level 1.3 - bit_rate = 768000; - break; - case 20: // level 2.0 - bit_rate = 2000000; - break; - case 21: // level 2.1 - bit_rate = 4000000; - break; - case 22: // level 2.2 - bit_rate = 4000000; - break; - case 30: // level 3.0 - bit_rate = 10000000; - break; - case 31: // level 3.1 - bit_rate = 14000000; - break; - case 32: // level 3.2 - bit_rate = 20000000; - break; - case 40: // level 4.0 - bit_rate = 20000000; - break; - case 41: // level 4.1 - bit_rate = 50000000; - break; - case 42: // level 4.2 - bit_rate = 50000000; - break; - case 50: // level 5.0 - bit_rate = 135000000; - break; - case 51: // level 5.1 - bit_rate = 240000000; - break; - default: - break; - } - break; - case 100: // high profile - switch (level_idc) { - case 10: // level 1.0 - bit_rate = 80000; - break; - case 11: // level 1b / 1.1 - bit_rate = constraint_set3_flag ? 160000 : 240000; - break; - case 12: // level 1.2 - bit_rate = 480000; - break; - case 13: // level 1.3 - bit_rate = 960000; - break; - case 20: // level 2.0 - bit_rate = 2500000; - break; - case 21: // level 2.1 - bit_rate = 5000000; - break; - case 22: // level 2.2 - bit_rate = 5000000; - break; - case 30: // level 3.0 - bit_rate = 12500000; - break; - case 31: // level 3.1 - bit_rate = 17500000; - break; - case 32: // level 3.2 - bit_rate = 25000000; - break; - case 40: // level 4.0 - bit_rate = 25000000; - break; - case 41: // level 4.1 - bit_rate = 62500000; - break; - case 42: // level 4.2 - bit_rate = 62500000; - break; - case 50: // level 5.0 - bit_rate = 168750000; - break; - case 51: // level 5.1 - bit_rate = 300000000; - break; - default: - break; - } - break; - case 110: // high 10 profile - switch (level_idc) { - case 10: // level 1.0 - bit_rate = 192000; - break; - case 11: // level 1b / 1.1 - bit_rate = constraint_set3_flag ? 384000 : 576000; - break; - case 12: // level 1.2 - bit_rate = 115200; - break; - case 13: // level 1.3 - bit_rate = 2304000; - break; - case 20: // level 2.0 - bit_rate = 6000000; - break; - case 21: // level 2.1 - bit_rate = 12000000; - break; - case 22: // level 2.2 - bit_rate = 12000000; - break; - case 30: // level 3.0 - bit_rate = 30000000; - break; - case 31: // level 3.1 - bit_rate = 42000000; - break; - case 32: // level 3.2 - bit_rate = 60000000; - break; - case 40: // level 4.0 - bit_rate = 60000000; - break; - case 41: // level 4.1 - bit_rate = 150000000; - break; - case 42: // level 4.2 - bit_rate = 150000000; - break; - case 50: // level 5.0 - bit_rate = 405000000; - break; - case 51: // level 5.1 - bit_rate = 720000000; - break; - default: - break; - } - break; - case 122: // high 4:2:2 profile - case 144: // high 4:4:4 profile - switch (level_idc) { - case 10: // level 1.0 - bit_rate = 256000; - break; - case 11: // level 1b / 1.1 - bit_rate = constraint_set3_flag ? 512000 : 768000; - break; - case 12: // level 1.2 - bit_rate = 1536000; - break; - case 13: // level 1.3 - bit_rate = 3072000; - break; - case 20: // level 2.0 - bit_rate = 8000000; - break; - case 21: // level 2.1 - bit_rate = 16000000; - break; - case 22: // level 2.2 - bit_rate = 16000000; - break; - case 30: // level 3.0 - bit_rate = 40000000; - break; - case 31: // level 3.1 - bit_rate = 56000000; - break; - case 32: // level 3.2 - bit_rate = 80000000; - break; - case 40: // level 4.0 - bit_rate = 80000000; - break; - case 41: // level 4.1 - bit_rate = 200000000; - break; - case 42: // level 4.2 - bit_rate = 200000000; - break; - case 50: // level 5.0 - bit_rate = 540000000; - break; - case 51: // level 5.1 - bit_rate = 960000000; - break; - default: - break; - } - break; - default: - break; - } - if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) { - if (bs.GetUeGolomb() == 3) // chroma_format_idc - bs.SkipBit(); // residual_colour_transform_flag - bs.SkipUeGolomb(); // bit_depth_luma_minus8 - bs.SkipUeGolomb(); // bit_depth_chroma_minus8 - bs.SkipBit(); // qpprime_y_zero_transform_bypass_flag - if (bs.GetBit()) { // seq_scaling_matrix_present_flag - for (i = 0; i < 8; ++i) { - if (bs.GetBit()) { // seq_scaling_list_present_flag[i] - int last = 8, next = 8, size = (i < 6) ? 16 : 64; - for (j = 0; j < size; ++j) { - if (next) - next = (last + bs.GetSeGolomb()) & 0xff; - last = next ?: last; - } - } - } - } - } - bs.SkipUeGolomb(); // log2_max_frame_num_minus4 - pic_order_cnt_type = bs.GetUeGolomb(); // pic_order_cnt_type - if (pic_order_cnt_type == 0) - bs.SkipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4 - else if (pic_order_cnt_type == 1) { - bs.SkipBit(); // delta_pic_order_always_zero - bs.SkipSeGolomb(); // offset_for_non_ref_pic - bs.SkipSeGolomb(); // offset_for_top_to_bottom_field - j = bs.GetUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle - for (i = 0; i < j; ++i) - bs.SkipSeGolomb(); // offset_for_ref_frame[i] - } - bs.SkipUeGolomb(); // num_ref_frames - bs.SkipBit(); // gaps_in_frame_num_value_allowed_flag - width = bs.GetUeGolomb() + 1; // pic_width_in_mbs_minus1 - height = bs.GetUeGolomb() + 1; // pic_height_in_mbs_minus1 - frame_mbs_only_flag = bs.GetBit(); // frame_mbs_only_flag - //debug("H.264 SPS: pic_width: %u mbs\n", width); - //debug("H.264 SPS: pic_height: %u mbs\n", height); - //debug("H.264 SPS: frame only flag: %d\n", frame_mbs_only_flag); - width *= 16; - height *= 16 * (frame_mbs_only_flag ? 1 : 2); - if (!frame_mbs_only_flag) - mb_adaptive_frame_field_flag = bs.GetBit(); // mb_adaptive_frame_field_flag - bs.SkipBit(); // direct_8x8_inference_flag - if (bs.GetBit()) { // frame_cropping_flag - uint32_t crop_left, crop_right, crop_top, crop_bottom; - crop_left = bs.GetUeGolomb(); // frame_crop_left_offset - crop_right = bs.GetUeGolomb(); // frame_crop_rigth_offset - crop_top = bs.GetUeGolomb(); // frame_crop_top_offset - crop_bottom = bs.GetUeGolomb(); // frame_crop_bottom_offset - //debug("H.264 SPS: cropping %d %d %d %d\n", crop_left, crop_top, crop_right, crop_bottom); - width -= 2 * (crop_left + crop_right); - if (frame_mbs_only_flag) - height -= 2 * (crop_top + crop_bottom); - else - height -= 4 * (crop_top + crop_bottom); - } - // VUI parameters - if (bs.GetBit()) { // vui_parameters_present_flag - if (bs.GetBit()) { // aspect_ratio_info_present - uint32_t aspect_ratio_idc, sar_width = 0, sar_height = 0; - aspect_ratio_idc = bs.GetBits(8); // aspect_ratio_idc - //debug("H.264 SPS: aspect_ratio_idc %d\n", 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(s_SAR)) { - sar_width = s_SAR[aspect_ratio_idc].w; - sar_height = s_SAR[aspect_ratio_idc].h; - } - if (sar_width && sar_height) { - int index = -1, ratio = int(100.0L * sar_width * width / sar_height / height); - for (unsigned int i = 0; i < ELEMENTS(s_DAR); ++i) { - if (s_DAR[i].ratio == ratio) { - index = i; - break; - } - } - if (index < 0) { - if (aspect_ratio_idc == 255) - aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED; - else - aspect_ratio = VIDEO_ASPECT_RATIO_INVALID; - } - else - aspect_ratio = s_DAR[index].dar; - //debug("H.264 SPS: DAR %dx%d (%d)\n", sar_width, sar_height, aspect_ratio); - } - } - if (bs.GetBit()) // overscan_info_present_flag - bs.SkipBit(); // overscan_approriate_flag - if (bs.GetBit()) { // video_signal_type_present_flag - uint32_t video_format; - video_format = bs.GetBits(3); // video_format - if (video_format < sizeof(s_VideoFormats) / sizeof(s_VideoFormats[0])) { - format = s_VideoFormats[video_format]; - //debug("H.264 SPS: video format %d\n", 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_coefficients - } - } - if (bs.GetBit()) { // chroma_loc_info_present_flag - bs.SkipUeGolomb(); // chroma_sample_loc_type_top_field - bs.SkipUeGolomb(); // chroma_sample_loc_type_bottom_field - } - if (bs.GetBit()) { // timing_info_present_flag - uint32_t num_units_in_tick, time_scale; - num_units_in_tick = bs.GetBits(32); // num_units_in_tick - time_scale = bs.GetBits(32); // time_scale - if (num_units_in_tick > 0) - frame_rate = time_scale / num_units_in_tick; - bs.SkipBit(); // fixed_frame_rate_flag - } - int nal_hrd_parameters_present_flag = bs.GetBit(); // nal_hrd_parameters_present_flag - if (nal_hrd_parameters_present_flag) { - int cpb_cnt_minus1; - cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1 - bs.SkipBits(4); // bit_rate_scale - bs.SkipBits(4); // cpb_size_scale - for (int i = 0; i < cpb_cnt_minus1; ++i) { - bs.SkipUeGolomb(); // bit_rate_value_minus1[i] - bs.SkipUeGolomb(); // cpb_size_value_minus1[i] - bs.SkipBit(); // cbr_flag[i] - } - bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1 - bs.SkipBits(5); // cpb_removal_delay_length_minus1 - bs.SkipBits(5); // dpb_output_delay_length_minus1 - time_offset_length = bs.GetBits(5); // time_offset_length - } - int vlc_hrd_parameters_present_flag = bs.GetBit(); // vlc_hrd_parameters_present_flag - if (vlc_hrd_parameters_present_flag) { - int cpb_cnt_minus1; - cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1 - bs.SkipBits(4); // bit_rate_scale - bs.SkipBits(4); // cpb_size_scale - for (int i = 0; i < cpb_cnt_minus1; ++i) { - bs.SkipUeGolomb(); // bit_rate_value_minus1[i] - bs.SkipUeGolomb(); // cpb_size_value_minus1[i] - bs.SkipBit(); // cbr_flag[i] - } - bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1 - bs.SkipBits(5); // cpb_removal_delay_length_minus1 - bs.SkipBits(5); // dpb_output_delay_length_minus1 - time_offset_length = bs.GetBits(5);// time_offset_length - } - cpb_dpb_delays_present_flag = (nal_hrd_parameters_present_flag | vlc_hrd_parameters_present_flag); - if (cpb_dpb_delays_present_flag) - bs.SkipBit(); // low_delay_hrd_flag - pic_struct_present_flag = bs.GetBit(); // pic_struct_present_flag - if (bs.GetBit()) { // bitstream_restriction_flag - bs.SkipBit(); // motion_vectors_over_pic_boundaries_flag - bs.SkipUeGolomb(); // max_bytes_per_pic_denom - bs.SkipUeGolomb(); // max_bits_per_mb_denom - bs.SkipUeGolomb(); // log2_max_mv_length_horizontal - bs.SkipUeGolomb(); // log2_max_mv_length_vertical - bs.SkipUeGolomb(); // num_reorder_frames - bs.SkipUeGolomb(); // max_dec_frame_buffering - } - } - - m_Width = width; - m_Height = height; - m_AspectRatio = aspect_ratio; - m_Format = format; - m_Scan = frame_mbs_only_flag ? VIDEO_SCAN_PROGRESSIVE : VIDEO_SCAN_INTERLACED; - m_FrameRate = frame_rate; - m_BitRate = bit_rate; - m_CpbDpbDelaysPresentFlag = cpb_dpb_delays_present_flag; - m_PicStructPresentFlag = pic_struct_present_flag; - m_FrameMbsOnlyFlag = frame_mbs_only_flag; - m_MbAdaptiveFrameFieldFlag = mb_adaptive_frame_field_flag; - m_TimeOffsetLength = time_offset_length; - - return (bs.Index() / 8); -} - -int cFemonH264::parseSEI(const uint8_t *buf, int len) -{ - int num_referenced_subseqs, i; - cFemonBitStream bs(buf, len); - - eVideoScan scan = m_Scan; - - while ((bs.Index() * 8 + 16) < len) { // sei_message - int 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 - if (m_CpbDpbDelaysPresentFlag) { // cpb_dpb_delays_present_flag - bs.SkipUeGolomb(); // cpb_removal_delay - bs.SkipUeGolomb(); // dpb_output_delay - } - if (m_PicStructPresentFlag) { // pic_struct_present_flag - uint32_t pic_struct, ct_type = 0, i = 0; - pic_struct = bs.GetBits(4); // pic_struct - if (pic_struct >= (sizeof(s_SeiNumClockTsTable)) / sizeof(s_SeiNumClockTsTable[0])) - return 0; - if (m_FrameMbsOnlyFlag && !m_MbAdaptiveFrameFieldFlag) - scan = VIDEO_SCAN_PROGRESSIVE; - else { - switch (pic_struct) { - case 0: // frame - case 7: // frame doubling - case 8: // frame tripling - scan = VIDEO_SCAN_PROGRESSIVE; - break; - case 1: // top - case 2: // bottom - case 3: // top bottom - case 4: // bottom top - case 5: // top bottom top - case 6: // bottom top bottom - scan = VIDEO_SCAN_INTERLACED; - break; - default: - scan = VIDEO_SCAN_RESERVED; - break; - } - } - //debug("H.264 SEI: pic struct %d scan type %d\n", pic_struct, scan); - for (i = 0; i < s_SeiNumClockTsTable[pic_struct]; ++i) { - if (bs.GetBit()) { // clock_timestamp_flag[i] - int full_timestamp_flag; - ct_type |= (1 << bs.GetBits(2)); // ct_type - //debug("H.264 SEI: ct type %04X\n", ct_type); - bs.SkipBit(); // nuit_field_based_flag - bs.SkipBits(5); // counting_type - full_timestamp_flag = bs.GetBit(); // full_timestamp_flag - bs.SkipBit(); // discontinuity_flag - bs.SkipBit(); // cnt_dropped_flag - bs.SkipBits(8); // n_frames - if (full_timestamp_flag) { - bs.SkipBits(6); // seconds_value - bs.SkipBits(6); // minutes_value - bs.SkipBits(5); // hours_value - } - else { - if (bs.GetBit()) { // seconds_flag - bs.SkipBits(6); // seconds_value - if (bs.GetBit()) { // minutes_flag - bs.SkipBits(6); // minutes_value - if (bs.GetBit()) // hours_flag - bs.SkipBits(5); // hours_value - } - } - } - if (m_TimeOffsetLength > 0) - bs.SkipBits(m_TimeOffsetLength); // time_offset - } - } - if (i > 0) - scan = (ct_type & (1 << 1)) ? VIDEO_SCAN_INTERLACED : VIDEO_SCAN_PROGRESSIVE; - } - break; - - case 12: // sub_seq_characteristics - bs.SkipUeGolomb(); // sub_seq_layer_num - bs.SkipUeGolomb(); // sub_seq_id - if (bs.GetBit()) // duration_flag - bs.SkipBits(32); // sub_seq_duration - if (bs.GetBit()) { // average_rate_flag - bs.SkipBit(); // accurate_statistics_flag - bs.SkipBits(16); // average_bit_rate (1000 bit/s) - bs.SkipBits(16); // average_frame_rate (frames per 256s) - } - num_referenced_subseqs = bs.GetUeGolomb(); // num_referenced_subseqs - for (i = 0; i < num_referenced_subseqs; ++i) { - bs.SkipUeGolomb(); // ref_sub_seq_layer_num - bs.SkipUeGolomb(); // ref_sub_seq_id - bs.GetBit(); // ref_sub_seq_direction - } - break; - - default: - bs.SkipBits(payloadSize * 8); - break; - } - - // force byte align - bs.ByteAlign(); - } - - m_Scan = scan; - - return (bs.Index() / 8); -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonh264.h vdr-plugin-femon-2.2.1.git20150307.2205/femonh264.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonh264.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonh264.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONH264_H -#define __FEMONH264_H - -#include "femonvideo.h" - -class cFemonH264 { -private: - enum { - NAL_SEI = 0x06, // Supplemental Enhancement Information - NAL_SPS = 0x07, // Sequence Parameter Set - NAL_AUD = 0x09, // Access Unit Delimiter - NAL_END_SEQ = 0x0A // End of Sequence - }; - - typedef struct DAR { - eVideoAspectRatio dar; - int ratio; - } t_DAR; - - typedef struct SAR { - int w; - int h; - } t_SAR; - - cFemonVideoIf *m_VideoHandler; - uint32_t m_Width; - uint32_t m_Height; - eVideoAspectRatio m_AspectRatio; - eVideoFormat m_Format; - double m_FrameRate; - double m_BitRate; - eVideoScan m_Scan; - bool m_CpbDpbDelaysPresentFlag; - bool m_PicStructPresentFlag; - bool m_FrameMbsOnlyFlag; - bool m_MbAdaptiveFrameFieldFlag; - uint32_t m_TimeOffsetLength; - - 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 s_SAR[]; - static const t_DAR s_DAR[]; - static const eVideoFormat s_VideoFormats[]; - static const uint8_t s_SeiNumClockTsTable[9]; - -public: - cFemonH264(cFemonVideoIf *videohandler); - virtual ~cFemonH264(); - - bool processVideo(const uint8_t *buf, int len); - }; - -#endif //__FEMONH264_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonlatm.c vdr-plugin-femon-2.2.1.git20150307.2205/femonlatm.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonlatm.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonlatm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include "femontools.h" -#include "femonlatm.h" - -int cFemonLATM::s_Bitrates[3][16] = -{ - {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III -}; - -int cFemonLATM::s_Samplerates[4] = -{ - 22050, 24000, 16000, -1 -}; - -cFemonLATM::cFemonLATM(cFemonAudioIf *audiohandler) -: m_AudioHandler(audiohandler) -{ -} - -cFemonLATM::~cFemonLATM() -{ -} - -bool cFemonLATM::processAudio(const uint8_t *buf, int len) -{ - cFemonBitStream bs(buf, len * 8); - - if (!m_AudioHandler) - return false; - - // skip PES header - if (!PesLongEnough(len)) - return false; - bs.SkipBits(8 * PesPayloadOffset(buf)); - - // MPEG audio detection - if (bs.GetBits(12) != 0x56E) // syncword - return false; - - m_AudioHandler->SetAudioCodec(AUDIO_CODEC_LATM); - - if (bs.GetBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0 - return true; // @todo: lower sampling frequencies support - int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01 - bs.SkipBit(); // protection bit - int bit_rate_index = bs.GetBits(4); // bitrate index - int sampling_frequency = bs.GetBits(2); // sampling frequency - bs.SkipBit(); // padding bit - bs.SkipBit(); // private pid - int mode = bs.GetBits(2); // mode - - switch (mode) { - case 0: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); - break; - - case 1: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); - break; - - case 2: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); - break; - - case 3: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); - break; - - default: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); - break; - } - - if (layer == 3) { - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE); - } - else { - switch (bit_rate_index) { - case 0: - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE); - break; - - case 0xF: - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED); - break; - - default: - m_AudioHandler->SetAudioBitrate(1000 * s_Bitrates[layer][bit_rate_index]); - break; - } - } - - switch (sampling_frequency) { - case 3: - m_AudioHandler->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); - break; - - default: - m_AudioHandler->SetAudioSamplingFrequency(s_Samplerates[sampling_frequency]); - break; - } - - return true; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonlatm.h vdr-plugin-femon-2.2.1.git20150307.2205/femonlatm.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonlatm.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonlatm.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONLATM_H -#define __FEMONLATM_H - -#include "femonaudio.h" - -class cFemonLATM { -private: - cFemonAudioIf *m_AudioHandler; - - static int s_Bitrates[3][16]; - static int s_Samplerates[4]; - -public: - cFemonLATM(cFemonAudioIf *audiohandler); - virtual ~cFemonLATM(); - - bool processAudio(const uint8_t *buf, int len); - }; - -#endif //__FEMONLATM_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonmpeg.c vdr-plugin-femon-2.2.1.git20150307.2205/femonmpeg.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonmpeg.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonmpeg.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include "femontools.h" -#include "femonmpeg.h" - -#define IS_EXTENSION_START(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == 0xB5)) - -int cFemonMPEG::s_Bitrates[2][3][16] = -{ - { - {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III - }, - { - {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1}, // MPEG-1 Layer I - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1}, // MPEG-1 Layer II - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1} // MPEG-1 Layer III - } -}; - -int cFemonMPEG::s_Samplerates[2][4] = -{ - {22050, 24000, 16000, -1}, // MPEG-2 - {44100, 48000, 32000, -1} // MPEG-1 -}; - -eAudioCodec cFemonMPEG::s_Formats[2][4] = -{ - {AUDIO_CODEC_MPEG2_I, AUDIO_CODEC_MPEG2_II, AUDIO_CODEC_MPEG2_III, AUDIO_CODEC_UNKNOWN}, // MPEG-2 - {AUDIO_CODEC_MPEG1_I, AUDIO_CODEC_MPEG1_II, AUDIO_CODEC_MPEG1_III, AUDIO_CODEC_UNKNOWN} // MPEG-1 -}; - -cFemonMPEG::cFemonMPEG(cFemonVideoIf *videohandler, cFemonAudioIf *audiohandler) -: m_VideoHandler(videohandler), - m_AudioHandler(audiohandler) -{ -} - -cFemonMPEG::~cFemonMPEG() -{ -} - -bool cFemonMPEG::processAudio(const uint8_t *buf, int len) -{ - cFemonBitStream bs(buf, len * 8); - - if (!m_AudioHandler) - return false; - - // skip PES header - if (!PesLongEnough(len)) - return false; - bs.SkipBits(8 * PesPayloadOffset(buf)); - - // MPEG audio detection - if (bs.GetBits(12) != 0xFFF) // syncword - return false; - - int id = bs.GetBit(); // id: MPEG-2=0, MPEG-1=1 - int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01 - bs.SkipBit(); // protection bit - int bit_rate_index = bs.GetBits(4); // bitrate index - int sampling_frequency = bs.GetBits(2); // sampling frequency - bs.SkipBit(); // padding bit - bs.SkipBit(); // private pid - int mode = bs.GetBits(2); // mode - - m_AudioHandler->SetAudioCodec(s_Formats[id][layer]); - - switch (mode) { - case 0: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); - break; - - case 1: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); - break; - - case 2: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); - break; - - case 3: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); - break; - - default: - m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); - break; - } - - switch (bit_rate_index) { - case 0: - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE); - break; - - case 0xF: - m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED); - break; - - default: - m_AudioHandler->SetAudioBitrate(1000 * s_Bitrates[id][layer][bit_rate_index]); - break; - } - - switch (sampling_frequency) { - case 3: - m_AudioHandler->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); - break; - - default: - m_AudioHandler->SetAudioSamplingFrequency(s_Samplerates[id][sampling_frequency]); - break; - } - - return true; -} - -bool cFemonMPEG::processVideo(const uint8_t *buf, int len) -{ - cFemonBitStream bs(buf, len * 8); - - if (!m_VideoHandler) - return false; - - // skip PES header - if (!PesLongEnough(len)) - return false; - bs.SkipBits(8 * PesPayloadOffset(buf)); - - // MPEG-2 video detection, search for start code - if (bs.GetBits(32) != 0x000001B3) // sequence header - return false; - - int scan = VIDEO_SCAN_UNKNOWN; - int format = VIDEO_FORMAT_UNKNOWN; - int aspect = VIDEO_ASPECT_RATIO_RESERVED; - - int horizontal_size = bs.GetBits(12); // horizontal size value - int vertical_size = bs.GetBits(12); // vertical size value - - switch (bs.GetBits(4)) { // aspect ratio information - case 1: - aspect = VIDEO_ASPECT_RATIO_1_1; - break; - - case 2: - aspect = VIDEO_ASPECT_RATIO_4_3; - break; - - case 3: - aspect = VIDEO_ASPECT_RATIO_16_9; - break; - - case 4: - aspect = VIDEO_ASPECT_RATIO_2_21_1; - break; - - case 5 ... 15: - default: - aspect = VIDEO_ASPECT_RATIO_RESERVED; - break; - } - - double frame_rate = 0; - switch (bs.GetBits(4)) { // frame rate code - case 1: - frame_rate = 24000 / 1001.0; - format = VIDEO_FORMAT_UNKNOWN; - break; - - case 2: - frame_rate = 24.0; - format = VIDEO_FORMAT_UNKNOWN; - break; - - case 3: - frame_rate = 25.0; - format = VIDEO_FORMAT_PAL; - break; - - case 4: - frame_rate = 30000 / 1001.0; - format = VIDEO_FORMAT_NTSC; - break; - - case 5: - frame_rate = 30.0; - format = VIDEO_FORMAT_NTSC; - break; - - case 6: - frame_rate = 50.0; - format = VIDEO_FORMAT_PAL; - break; - - case 7: - frame_rate = 60.0; - format = VIDEO_FORMAT_NTSC; - break; - - case 8: - frame_rate = 60000 / 1001.0; - format = VIDEO_FORMAT_NTSC; - break; - - case 9 ... 15: - default: - frame_rate = 0; - format = VIDEO_FORMAT_UNKNOWN; - break; - } - - int bit_rate = bs.GetBits(18); // bit rate value - - bs.SkipBit(); // marker bit - bs.SkipBits(10); // vbv buffer size value - bs.SkipBit(); // constrained parameters value - if (bs.GetBit()) // load intra quantizer matrix - bs.SkipBits(8 * 64); // intra quantizer matrix - if (bs.GetBit()) // load non-intra quantizer matrix - bs.SkipBits(8 * 64); // non-intra quantizer matrix - - if (bs.GetBits(32) != 0x000001B5) { // extension start - bs.SkipBits(4); // extension start code identifier - bs.SkipBits(8); // profile and level indicator - scan = bs.GetBit() ? VIDEO_SCAN_PROGRESSIVE : - VIDEO_SCAN_INTERLACED; // progressive sequence - bs.SkipBits(2); // chroma format - horizontal_size |= (bs.GetBits(2) << 12); // horizontal size extension - vertical_size |= (bs.GetBits(2) << 12); // vertical size extension - bit_rate |= (bs.GetBits(12) << 18); // bit rate extension - bs.SkipBit(); // marker bit - bs.SkipBits(8); // vpv buffer size extension - bs.SkipBit(); // low delay - bs.SkipBits(2); // frame rate extension n - bs.SkipBits(5); // frame rate extension d - - if ((bs.GetBits(32) != 0x000001B5) && // extension start code - (bs.GetBits(4) == 0x0010)) { // sequence display extension id - switch (bs.GetBits(3)) { // video format - case 0x000: - format = VIDEO_FORMAT_COMPONENT; - break; - case 0x001: - format = VIDEO_FORMAT_PAL; - break; - case 0x010: - format = VIDEO_FORMAT_NTSC; - break; - case 0x011: - format = VIDEO_FORMAT_SECAM; - break; - case 0x100: - format = VIDEO_FORMAT_MAC; - break; - case 0x101: - format = VIDEO_FORMAT_UNKNOWN; - break; - case 0x110: - case 0x111: - format = VIDEO_FORMAT_RESERVED; - break; - default: - format = VIDEO_FORMAT_INVALID; - break; - } - } - } - - m_VideoHandler->SetVideoCodec(VIDEO_CODEC_MPEG2); - m_VideoHandler->SetVideoSize(horizontal_size, vertical_size); - m_VideoHandler->SetVideoBitrate(400.0 * (double)(bit_rate)); - m_VideoHandler->SetVideoFramerate(frame_rate); - m_VideoHandler->SetVideoScan(eVideoScan(scan)); - m_VideoHandler->SetVideoAspectRatio(eVideoAspectRatio(aspect)); - m_VideoHandler->SetVideoFormat(eVideoFormat(format)); - - return true; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonmpeg.h vdr-plugin-femon-2.2.1.git20150307.2205/femonmpeg.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonmpeg.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonmpeg.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONMPEG_H -#define __FEMONMPEG_H - -#include "femonvideo.h" -#include "femonaudio.h" - -class cFemonMPEG { -private: - cFemonVideoIf *m_VideoHandler; - cFemonAudioIf *m_AudioHandler; - - static int s_Bitrates[2][3][16]; - static int s_Samplerates[2][4]; - static eAudioCodec s_Formats[2][4]; - -public: - cFemonMPEG(cFemonVideoIf *videohandler, cFemonAudioIf *audiohandler); - virtual ~cFemonMPEG(); - - bool processVideo(const uint8_t *buf, int len); - bool processAudio(const uint8_t *buf, int len); - }; - -#endif //__FEMONMPEG_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonosd.c vdr-plugin-femon-2.2.1.git20150307.2205/femonosd.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonosd.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonosd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1151 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif - -#include -#include -#include "iptvservice.h" -#include "femoncfg.h" -#include "femonreceiver.h" -#include "femontools.h" -#include "femonsymbol.h" -#include "femonosd.h" - -#define CHANNELINPUT_TIMEOUT 1000 -#define SVDRPPLUGIN "svdrpservice" - -#define OSDWIDTH m_OsdWidth // in pixels -#define OSDHEIGHT m_OsdHeight // in pixels -#define OSDROWHEIGHT m_Font->Height() // in pixels -#define OSDINFOHEIGHT (OSDROWHEIGHT * 14) // in pixels (14 rows) -#define OSDSTATUSHEIGHT (OSDROWHEIGHT * 6) // in pixels (6 rows) -#define OSDSYMBOL(id) femonSymbols.Get(id) -#define OSDSPACING femonSymbols.GetSpacing() -#define OSDROUNDING femonSymbols.GetRounding() -#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_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \ - (col == 3) ? int(round(OSDWIDTH * 0.51)) : \ - (col == 2) ? int(round(OSDWIDTH * 0.26)) : \ - int(round(OSDWIDTH * 0.025))) -#define OSDSTATUSWIN_Y(offset) (femonConfig.position ? 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)) : \ - int(round(OSDWIDTH * 0.025))) -#define OSDSTATUSWIN_XSYMBOL(c,w) (c * ((OSDWIDTH - (5 * w)) / 6) + ((c - 1) * w)) -#define OSDBARWIDTH(x) (OSDWIDTH * x / 100) - -#define OSDDRAWSTATUSBM(spacing) \ - if (bm) { \ - x -= bm->Width() + spacing; \ - y = (OSDROWHEIGHT - bm->Height()) / 2; \ - if (y < 0) y = 0; \ - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset) + y, *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); \ - } - -#define OSDDRAWSTATUSFRONTEND(column, bitmap, status) \ - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(column, x), OSDSTATUSWIN_Y(offset) + y, bitmap, (m_FrontendStatus & status) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground) - -#define OSDDRAWSTATUSVALUES(label1, label2, label3, label4, label5, label6, label7) \ - m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), label1, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), label2, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), label3, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), label4, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), label5, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), label6, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), label7, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWSTATUSBAR(value) \ - if (value > 0) { \ - 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); \ - 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); \ - if (barvalue > OSDBARWIDTH(femonConfig.greenlimit)) \ - m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset) + 3, barvalue, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrGreen); \ - } - -#define OSDDRAWSTATUSTITLEBAR(title) \ - m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset), OSDWIDTH, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 1, femonTheme[femonConfig.theme].clrTitleBackground); \ - m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \ - if (IS_OSDROUNDING) { \ - m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDROUNDING, OSDSTATUSWIN_Y(OSDROUNDING), clrTransparent, -2); \ - m_Osd->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDROUNDING), clrTransparent, -1); \ - } \ - m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT, OSDWIDTH, OSDSTATUSWIN_Y(offset) + OSDSTATUSHEIGHT - 1, femonTheme[femonConfig.theme].clrBackground) - -#define OSDDRAWSTATUSBOTTOMBAR() \ - if (IS_OSDROUNDING) { \ - m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - OSDROUNDING, OSDROUNDING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); \ - m_Osd->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - OSDROUNDING, OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -4); \ - } - -#define OSDCLEARSTATUS() \ - m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - 1, clrTransparent) - -#define OSDDRAWINFOLEFT(label, value) \ - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWINFORIGHT(label, value) \ - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWINFOACTIVE(label, value) \ - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWINFOINACTIVE(label, value) \ - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWINFOLINE(label) \ - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) - -#define OSDDRAWINFOTITLEBAR(title) \ - m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset) + OSDROWHEIGHT - 1, femonTheme[femonConfig.theme].clrTitleBackground); \ - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \ - if (IS_OSDROUNDING) { \ - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDROUNDING, OSDINFOWIN_Y(OSDROUNDING), clrTransparent, -2); \ - m_Osd->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDROUNDING), clrTransparent, -1); \ - } \ - m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset) + OSDROWHEIGHT, OSDWIDTH, OSDINFOWIN_Y(offset) + OSDINFOHEIGHT - 1, femonTheme[femonConfig.theme].clrBackground) - -#define OSDDRAWINFOBOTTOMBAR() \ - if (IS_OSDROUNDING) { \ - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDROUNDING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); \ - m_Osd->DrawEllipse((OSDWIDTH - OSDROUNDING), OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); \ - } - -#define OSDCLEARINFO() \ - m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT) - 1, clrTransparent) - -#ifndef MINFONTSIZE -#define MINFONTSIZE 10 -#endif - -#ifndef MAXFONTSIZE -#define MAXFONTSIZE 64 -#endif - -class cFemonDummyFont : public cFont { -public: - virtual int Width(uint c) const { return 10; } - virtual int Width(const char *s) const { return 50; } - virtual int Height(void) const { return 20; } - virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} - virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} -}; - -cFemonOsd *cFemonOsd::pInstance = NULL; - -cFemonOsd *cFemonOsd::Instance(bool create) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - if ((pInstance == NULL) && create) - { - pInstance = new cFemonOsd(); - } - return (pInstance); -} - -cFemonOsd::cFemonOsd() -: cOsdObject(true), cThread("femon osd"), - m_Osd(NULL), - m_Receiver(NULL), - m_Frontend(-1), - m_SvdrpFrontend(-1), - m_SvdrpVideoBitrate(-1), - m_SvdrpAudioBitrate(-1), - m_SvdrpPlugin(NULL), - m_Number(0), - m_OldNumber(0), - m_Quality(0), - m_QualityValid(false), - m_Strength(0), - m_StrengthValid(false), - m_SNR(0), - m_SNRValid(false), - m_Signal(0), - m_SignalValid(false), - m_BER(0), - m_BERValid(false), - m_UNC(0), - m_UNCValid(false), - m_FrontendName(""), - m_FrontendStatusValid(false), - m_DeviceSource(DEVICESOURCE_DVBAPI), - m_DisplayMode(femonConfig.displaymode), - m_OsdWidth(cOsd::OsdWidth() * (100 - femonConfig.downscale) / 100), - m_OsdHeight(cOsd::OsdHeight() * (100 - femonConfig.downscale) / 100), - m_OsdLeft(cOsd::OsdLeft() + (cOsd::OsdWidth() * femonConfig.downscale / 200)), - m_OsdTop(cOsd::OsdTop() + (cOsd::OsdHeight() * femonConfig.downscale / 200)), - m_InputTime(0), - m_Sleep(), - m_Mutex() -{ - int tmp; - debug("%s()\n", __PRETTY_FUNCTION__); - memset(&m_FrontendStatus, 0, sizeof(m_FrontendStatus)); - memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo)); - m_SvdrpConnection.handle = -1; - femonSymbols.Refresh(); - m_Font = cFont::CreateFont(Setup.FontSml, constrain(Setup.FontSmlSize, MINFONTSIZE, MAXFONTSIZE)); - if (!m_Font || !m_Font->Height()) { - m_Font = new cFemonDummyFont; - error("cFemonOsd::cFemonOsd() cannot create required font."); - } - tmp = 5 * OSDSYMBOL(SYMBOL_LOCK).Width() + 6 * OSDSPACING; - if (OSDWIDTH < tmp) { - error("cFemonOsd::cFemonOsd() OSD width (%d) smaller than required (%d).", OSDWIDTH, tmp); - OSDWIDTH = tmp; - } - tmp = OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT; - if (OSDHEIGHT < tmp) { - error("cFemonOsd::cFemonOsd() OSD height (%d) smaller than required (%d).", OSDHEIGHT, tmp); - OSDHEIGHT = tmp; - } -} - -cFemonOsd::~cFemonOsd(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - m_Sleep.Signal(); - if (Running()) - Cancel(3); - if (m_SvdrpConnection.handle >= 0) { - m_SvdrpPlugin = cPluginManager::GetPlugin(SVDRPPLUGIN); - if (m_SvdrpPlugin) - m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); - } - if (m_Receiver) { - m_Receiver->Deactivate(); - DELETENULL(m_Receiver); - } - if (m_Osd) - DELETENULL(m_Osd); - if (m_Font) - DELETENULL(m_Font); - if (m_Frontend >= 0) { - close(m_Frontend); - m_Frontend = -1; - } - pInstance = NULL; -} - -void cFemonOsd::DrawStatusWindow(void) -{ - cMutexLock lock(&m_Mutex); - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - - if (m_Osd && channel) { - cBitmap *bm = NULL; - int offset = 0; - int x = OSDWIDTH - OSDROUNDING; - int y = 0; - eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - - OSDDRAWSTATUSTITLEBAR(*cString::sprintf("%d%s %s", m_Number ? m_Number : channel->Number(), m_Number ? "-" : "", channel->ShortName(true))); - if (m_SvdrpFrontend >= 0) { - bm = &OSDSYMBOL(SYMBOL_SVDRP); - OSDDRAWSTATUSBM(OSDSPACING); - } - switch (cDevice::ActualDevice()->CardIndex()) { - case 1: bm = &OSDSYMBOL(SYMBOL_ONE); break; - case 2: bm = &OSDSYMBOL(SYMBOL_TWO); break; - case 3: bm = &OSDSYMBOL(SYMBOL_THREE); break; - case 4: bm = &OSDSYMBOL(SYMBOL_FOUR); break; - case 5: bm = &OSDSYMBOL(SYMBOL_FIVE); break; - case 6: bm = &OSDSYMBOL(SYMBOL_SIX); break; - case 7: bm = &OSDSYMBOL(SYMBOL_SEVEN); break; - case 8: bm = &OSDSYMBOL(SYMBOL_EIGHT); break; - default: bm = &OSDSYMBOL(SYMBOL_ZERO); break; - } - OSDDRAWSTATUSBM(OSDSPACING); - bm = &OSDSYMBOL(SYMBOL_DEVICE); - OSDDRAWSTATUSBM(0); - if (IS_AUDIO_TRACK(track)) { - switch (int(track - ttAudioFirst)) { - case 1: bm = &OSDSYMBOL(SYMBOL_ONE); break; - case 2: bm = &OSDSYMBOL(SYMBOL_TWO); break; - case 3: bm = &OSDSYMBOL(SYMBOL_THREE); break; - case 4: bm = &OSDSYMBOL(SYMBOL_FOUR); break; - case 5: bm = &OSDSYMBOL(SYMBOL_FIVE); break; - case 6: bm = &OSDSYMBOL(SYMBOL_SIX); break; - case 7: bm = &OSDSYMBOL(SYMBOL_SEVEN); break; - case 8: bm = &OSDSYMBOL(SYMBOL_EIGHT); break; - default: bm = &OSDSYMBOL(SYMBOL_ZERO); break; - } - OSDDRAWSTATUSBM(OSDSPACING); - switch (cDevice::PrimaryDevice()->GetAudioChannel()) { - case 1: bm = &OSDSYMBOL(SYMBOL_MONO_LEFT); break; - case 2: bm = &OSDSYMBOL(SYMBOL_MONO_RIGHT); break; - default: bm = &OSDSYMBOL(SYMBOL_STEREO); break; - } - OSDDRAWSTATUSBM(0); - } - else if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { - if (m_Receiver->AC3_5_1()) bm = &OSDSYMBOL(SYMBOL_DD51); - else if (m_Receiver->AC3_2_0()) bm = &OSDSYMBOL(SYMBOL_DD20); - else bm = &OSDSYMBOL(SYMBOL_DD); - OSDDRAWSTATUSBM(OSDSPACING); - } - if (m_Receiver) { - if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 1080)) { - switch (m_Receiver->VideoScan()) { - case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080i); break; - case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080p); break; - default: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080); break; - } - } - else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 720)) { - switch (m_Receiver->VideoScan()) { - case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_720i); break; - case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_720p); break; - default: bm = &OSDSYMBOL(SYMBOL_FORMAT_720); break; - } - } - else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 576)) { - switch (m_Receiver->VideoScan()) { - case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_576i); break; - case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_576p); break; - default: bm = &OSDSYMBOL(SYMBOL_FORMAT_576); break; - } - } - else if (IS_OSDRESOLUTION(m_Receiver->VideoVerticalSize(), 480)) { - switch (m_Receiver->VideoScan()) { - case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_480i); break; - case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_480p); break; - default: bm = &OSDSYMBOL(SYMBOL_FORMAT_480); break; - } - } - else - bm = NULL; - OSDDRAWSTATUSBM(OSDSPACING); - switch (m_Receiver->VideoCodec()) { - case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break; - case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break; - default: bm = NULL; break; - } - OSDDRAWSTATUSBM(OSDSPACING); - switch (m_Receiver->VideoFormat()) { - case VIDEO_FORMAT_PAL: bm = &OSDSYMBOL(SYMBOL_PAL); break; - case VIDEO_FORMAT_NTSC: bm = &OSDSYMBOL(SYMBOL_NTSC); break; - default: bm = NULL; break; - } - OSDDRAWSTATUSBM(OSDSPACING); - switch (m_Receiver->VideoAspectRatio()) { - case VIDEO_ASPECT_RATIO_1_1: bm = &OSDSYMBOL(SYMBOL_AR_1_1); break; - case VIDEO_ASPECT_RATIO_4_3: bm = &OSDSYMBOL(SYMBOL_AR_4_3); break; - case VIDEO_ASPECT_RATIO_16_9: bm = &OSDSYMBOL(SYMBOL_AR_16_9); break; - case VIDEO_ASPECT_RATIO_2_21_1: bm = &OSDSYMBOL(SYMBOL_AR_2_21_1); break; - default: bm = NULL; break; - } - OSDDRAWSTATUSBM(OSDSPACING); - } - if (channel->Ca() > 0xFF) { - bm = &OSDSYMBOL(SYMBOL_ENCRYPTED); - OSDDRAWSTATUSBM(OSDSPACING); - } - offset += OSDROWHEIGHT; - if (m_StrengthValid) - OSDDRAWSTATUSBAR(m_Strength); - offset += OSDROWHEIGHT; - if (m_QualityValid) - OSDDRAWSTATUSBAR(m_Quality); - offset += OSDROWHEIGHT; - OSDDRAWSTATUSVALUES("STR:", m_SignalValid ? *cString::sprintf("%04x", m_Signal) : "", m_SignalValid ? *cString::sprintf("(%2d%%)", m_Signal / 655) : "", - "BER:", m_BERValid ? *cString::sprintf("%08x", m_BER) : "", *cString::sprintf("%s:", tr("Video")), - *getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0))); - offset += OSDROWHEIGHT; - OSDDRAWSTATUSVALUES("SNR:", m_SNRValid ? *cString::sprintf("%04x", m_SNR) : "", m_SNRValid ? *cString::sprintf("(%2d%%)", m_SNR / 655) : "", - "UNC:", m_UNCValid ? *cString::sprintf("%08x", m_UNC) : "", - *cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")), - *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; - x = OSDSYMBOL(SYMBOL_LOCK).Width(); - y = (OSDROWHEIGHT - OSDSYMBOL(SYMBOL_LOCK).Height()) / 2; - if (m_FrontendStatusValid) { - 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); - } - OSDDRAWSTATUSBOTTOMBAR(); - m_Osd->Flush(); - } -} - -void cFemonOsd::DrawInfoWindow(void) -{ - cMutexLock lock(&m_Mutex); - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - - if (m_Osd && channel) { - int offset = 0; - eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - - switch (m_DisplayMode) { - case eFemonModeTransponder: - OSDDRAWINFOTITLEBAR(tr("Transponder Information")); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Vpid"), *cString::sprintf("%d", channel->Vpid())); - OSDDRAWINFORIGHT(trVDR("Ppid"), *cString::sprintf("%d", channel->Ppid())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( tr("Apid"), *getApids(channel)); - OSDDRAWINFORIGHT( tr("Dpid"), *getDpids(channel)); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( tr("Spid"), *getSpids(channel)); - OSDDRAWINFORIGHT(trVDR("Tpid"), *cString::sprintf("%d", channel->Tpid())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Sid"), *cString::sprintf("%d", channel->Sid())); - OSDDRAWINFORIGHT( tr("Nid"), *cString::sprintf("%d", channel->Nid())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( tr("Tid"), *cString::sprintf("%d", channel->Tid())); - OSDDRAWINFORIGHT( tr("Rid"), *cString::sprintf("%d", channel->Rid())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("CA"), *getCAids(channel)); - offset += OSDROWHEIGHT; - switch (channel->Source() & cSource::st_Mask) { - case cSource::stSat: { - cDvbTransponderParameters dtp(channel->Parameters()); - OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", *getSatelliteSystem(dtp.System()), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), *m_FrontendName)); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); - OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); - OSDDRAWINFORIGHT(trVDR("Polarization"), *cString::sprintf("%c", toupper(dtp.Polarization()))); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); - OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("System"), *getSatelliteSystem(dtp.System())); - if (dtp.System()) { - OSDDRAWINFORIGHT(trVDR("RollOff"), *getRollOff(dtp.RollOff())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Pilot"), *getPilot(dtp.Pilot())); - } - } - break; - - case cSource::stCable: { - cDvbTransponderParameters dtp(channel->Parameters()); - OSDDRAWINFOLINE(*cString::sprintf("DVB-C #%d - %s", (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), *m_FrontendName)); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); - OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); - OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); - OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH())); - } - break; - - case cSource::stTerr: { - cDvbTransponderParameters dtp(channel->Parameters()); - OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", *getTerrestrialSystem(dtp.System()), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), *m_FrontendName)); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); - OSDDRAWINFORIGHT(trVDR("Transmission"), *getTransmission(dtp.Transmission())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Bandwidth"), *getBandwidth(dtp.Bandwidth())); - OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); - OSDDRAWINFORIGHT(tr ("Coderate"), *cString::sprintf("%s (H) %s (L)", *getCoderate(dtp.CoderateH()), *getCoderate(dtp.CoderateL()))); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("Hierarchy"), *getHierarchy(dtp.Hierarchy())); - OSDDRAWINFORIGHT(trVDR("Guard"), *getGuard(dtp.Guard())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("System"), *getTerrestrialSystem(dtp.System())); - if (dtp.System()) { - OSDDRAWINFORIGHT(trVDR("StreamId"), *cString::sprintf("%d", dtp.StreamId())); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT( trVDR("T2SystemId"),*cString::sprintf("%d", dtp.T2SystemId())); - OSDDRAWINFORIGHT(trVDR("SISO/MISO"), *cString::sprintf("%d", dtp.SisoMiso())); - } - } - break; - - case stIptv: { - OSDDRAWINFOLINE(*cString::sprintf("IPTV #%d - %s", (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), *m_FrontendName)); - offset += OSDROWHEIGHT; - if (m_SvdrpFrontend < 0) { - cPlugin *p; - IptvService_v1_0 data; - data.cardIndex = cDevice::ActualDevice()->CardIndex(); - p = cPluginManager::CallFirstService("IptvService-v1.0", &data); - if (p) { - OSDDRAWINFOLEFT(tr("Protocol"), *data.protocol); - offset += OSDROWHEIGHT; - OSDDRAWINFOLEFT(tr("Bitrate"), *data.bitrate); - } - } - } - break; - - default: - break; - } - OSDDRAWINFOBOTTOMBAR(); - break; - - case eFemonModeStream: - OSDDRAWINFOTITLEBAR(tr("Stream Information")); - offset += OSDROWHEIGHT; - OSDDRAWINFOACTIVE( tr("Video Stream"), *getVideoStream(channel->Vpid())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Codec"), *getVideoCodec(m_Receiver ? m_Receiver->VideoCodec() : VIDEO_CODEC_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Bitrate"), *getVideoBitrate(m_Receiver ? m_Receiver->VideoBitrate() : 0, m_Receiver ? m_Receiver->VideoStreamBitrate() : 0)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Aspect Ratio"), *getAspectRatio(m_Receiver ? m_Receiver->VideoAspectRatio() : VIDEO_ASPECT_RATIO_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Frame Rate"), *getFrameRate(m_Receiver ? m_Receiver->VideoFrameRate() : 0)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Video Format"), *getVideoFormat(m_Receiver ? m_Receiver->VideoFormat() : VIDEO_CODEC_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Resolution"), *getResolution(m_Receiver ? m_Receiver->VideoHorizontalSize() : 0, m_Receiver ? m_Receiver->VideoVerticalSize() : 0, m_Receiver ? m_Receiver->VideoScan() : VIDEO_SCAN_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOACTIVE( tr("Audio Stream"), *getAudioStream(track, channel)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Codec"), *getAudioCodec(m_Receiver ? m_Receiver->AudioCodec() : AUDIO_CODEC_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Channel Mode"), *getAudioChannelMode(m_Receiver ? m_Receiver->AudioChannelMode() : AUDIO_CHANNEL_MODE_INVALID)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver ? m_Receiver->AudioBitrate() : 0, m_Receiver ? m_Receiver->AudioStreamBitrate() : 0)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(m_Receiver ? m_Receiver->AudioSamplingFreq() : AUDIO_SAMPLING_FREQUENCY_INVALID)); - OSDDRAWINFOBOTTOMBAR(); - break; - - case eFemonModeAC3: - OSDDRAWINFOTITLEBAR(tr("Stream Information")); - if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { - offset += OSDROWHEIGHT; - OSDDRAWINFOACTIVE( tr("AC-3 Stream"), *getAC3Stream(track, channel)); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver->AC3Bitrate(), m_Receiver->AC3StreamBitrate())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(m_Receiver->AC3SamplingFreq())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Bit Stream Mode"), *getAC3BitStreamMode(m_Receiver->AC3BitStreamMode(), m_Receiver->AC3AudioCodingMode())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Audio Coding Mode"), *getAC3AudioCodingMode(m_Receiver->AC3AudioCodingMode(), m_Receiver->AC3BitStreamMode())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Center Mix Level"), *getAC3CenterMixLevel(m_Receiver->AC3CenterMixLevel())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Surround Mix Level"), *getAC3SurroundMixLevel(m_Receiver->AC3SurroundMixLevel())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Dolby Surround Mode"), *getAC3DolbySurroundMode(m_Receiver->AC3DolbySurroundMode())); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Low Frequency Effects"), *cString::sprintf("%s", m_Receiver->AC3Lfe() ? trVDR("on") : trVDR("off"))); - offset += OSDROWHEIGHT; - OSDDRAWINFOINACTIVE(tr("Dialogue Normalization"), *getAC3DialogLevel(m_Receiver->AC3DialogLevel())); - } - OSDDRAWINFOBOTTOMBAR(); - break; - - default: - OSDCLEARINFO(); - break; - } - m_Osd->Flush(); - } -} - -void cFemonOsd::Action(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - cTimeMs t; - SvdrpCommand_v1_0 cmd; - cmd.command = cString::sprintf("PLUG %s INFO\r\n", PLUGIN_NAME_I18N); - while (Running()) { - t.Set(0); - m_SvdrpFrontend = -1; - m_SvdrpVideoBitrate = -1.0; - m_SvdrpAudioBitrate = -1.0; - switch (m_DeviceSource) { - case DEVICESOURCE_PVRINPUT: - m_Quality = cDevice::ActualDevice()->SignalStrength(); - m_QualityValid = (m_Quality >= 0); - m_Strength = cDevice::ActualDevice()->SignalStrength(); - m_StrengthValid = (m_Strength >= 0); - m_FrontendName = cDevice::ActualDevice()->DeviceName(); - m_FrontendStatus = (fe_status_t)(m_StrengthValid ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0); - m_FrontendStatusValid = m_StrengthValid; - m_Signal = uint16_t(m_Strength * 0xFFFF / 100); - m_SignalValid = m_StrengthValid; - m_SNR = 0; - m_SNRValid = false; - m_BER = 0; - m_BERValid = false; - m_UNC = 0; - m_UNCValid = false; - break; - case DEVICESOURCE_IPTV: - m_Quality = cDevice::ActualDevice()->SignalQuality(); - m_QualityValid = (m_Quality >= 0); - m_Strength = cDevice::ActualDevice()->SignalStrength(); - m_StrengthValid = (m_Strength >= 0); - m_FrontendName = cDevice::ActualDevice()->DeviceName(); - m_FrontendStatus = (fe_status_t)(m_StrengthValid ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0); - m_FrontendStatusValid = m_StrengthValid; - m_Signal = uint16_t(m_Strength * 0xFFFF / 100); - m_SignalValid = m_StrengthValid; - m_SNR = uint16_t(m_Quality * 0xFFFF / 100); - m_SNRValid = m_QualityValid; - m_BER = 0; - m_BERValid = false; - m_UNC = 0; - m_UNCValid = false; - break; - default: - case DEVICESOURCE_DVBAPI: - if (m_Frontend != -1) { - m_Quality = cDevice::ActualDevice()->SignalQuality(); - m_QualityValid = (m_Quality >= 0); - m_Strength = cDevice::ActualDevice()->SignalStrength(); - m_StrengthValid = (m_Strength >= 0); - m_FrontendName = cDevice::ActualDevice()->DeviceName(); - m_FrontendStatusValid = (ioctl(m_Frontend, FE_READ_STATUS, &m_FrontendStatus) >= 0); - m_SignalValid = (ioctl(m_Frontend, FE_READ_SIGNAL_STRENGTH, &m_Signal) >= 0); - m_SNRValid = (ioctl(m_Frontend, FE_READ_SNR, &m_SNR) >= 0); - m_BERValid = (ioctl(m_Frontend, FE_READ_BER, &m_BER) >= 0); - m_UNCValid = (ioctl(m_Frontend, FE_READ_UNCORRECTED_BLOCKS, &m_UNC) >= 0); - } - else if (strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) { - m_Quality = cDevice::ActualDevice()->SignalQuality(); - m_QualityValid = (m_Quality >= 0); - m_Strength = cDevice::ActualDevice()->SignalStrength(); - m_StrengthValid = (m_Strength >= 0); - m_FrontendName = cDevice::ActualDevice()->DeviceName(); - m_FrontendStatus = (fe_status_t)(cDevice::ActualDevice()->HasLock() ? (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC) : 0); - m_FrontendStatusValid = m_StrengthValid; - m_Signal = uint16_t(m_Strength * 0xFFFF / 100); - m_SignalValid = m_StrengthValid; - m_SNR = uint16_t(m_Quality * 0xFFFF / 100); - m_SNRValid = m_QualityValid; - m_BER = 0; - m_BERValid = false; - m_UNC = 0; - m_UNCValid = false; - } - else if (m_SvdrpConnection.handle >= 0) { - cmd.handle = m_SvdrpConnection.handle; - m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); - if (cmd.responseCode == 900) { - m_StrengthValid = false; - m_QualityValid = false; - 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)) { - const char *s = line->Text(); - if (!strncasecmp(s, "CARD:", 5)) - m_SvdrpFrontend = (int)strtol(s + 5, NULL, 10); - else if (!strncasecmp(s, "STRG:", 5)) { - m_Strength = (int)strtol(s + 5, NULL, 10); - m_StrengthValid = (m_Strength >= 0); - } - else if (!strncasecmp(s, "QUAL:", 5)) { - m_Quality = (int)strtol(s + 5, NULL, 10); - m_QualityValid = (m_Quality >= 0); - } - else if (!strncasecmp(s, "TYPE:", 5)) - m_FrontendInfo.type = (fe_type_t)strtol(s + 5, NULL, 10); - else if (!strncasecmp(s, "NAME:", 5)) { - m_FrontendName = s + 5; - } - else if (!strncasecmp(s, "STAT:", 5)) { - m_FrontendStatus = (fe_status_t)strtol(s + 5, NULL, 16); - m_FrontendStatusValid = true; - } - else if (!strncasecmp(s, "SGNL:", 5)) { - m_Signal = (uint16_t)strtol(s + 5, NULL, 16); - m_SignalValid = true; - } - else if (!strncasecmp(s, "SNRA:", 5)) { - 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)) - m_SvdrpVideoBitrate = (double)strtol(s + 5, NULL, 10); - else if (!strncasecmp(s, "AUBR:", 5)) - m_SvdrpAudioBitrate = (double)strtol(s + 5, NULL, 10); - } - } - } - break; - } - DrawInfoWindow(); - DrawStatusWindow(); - m_Sleep.Wait(max((int)(100 * femonConfig.updateinterval - t.Elapsed()), 3)); - } -} - -void cFemonOsd::Show(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - - m_DeviceSource = DEVICESOURCE_DVBAPI; - if (channel) { - if (channel->IsSourceType('I')) - m_DeviceSource = DEVICESOURCE_IPTV; - else if (channel->IsSourceType('V')) - m_DeviceSource = DEVICESOURCE_PVRINPUT; - } - - if (m_DeviceSource == DEVICESOURCE_DVBAPI) { - if (!strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) { - cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice()); - m_Frontend = dev ? open(*cString::sprintf(FRONTEND_DEVICE, dev->Adapter(), dev->Frontend()), O_RDONLY | O_NONBLOCK) : -1; - if (m_Frontend >= 0) { - if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) { - if (!femonConfig.usesvdrp) - error("cFemonOsd::Show() cannot read frontend info."); - close(m_Frontend); - m_Frontend = -1; - memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo)); - return; - } - } - else if (femonConfig.usesvdrp) { - if (!SvdrpConnect() || !SvdrpTune()) - return; - } - else { - error("cFemonOsd::Show() cannot open frontend device."); - return; - } - } - } - else - m_Frontend = -1; - - m_Osd = cOsdProvider::NewOsd(m_OsdLeft, m_OsdTop); - if (m_Osd) { - tArea Areas1[] = { { 0, 0, OSDWIDTH - 1, OSDHEIGHT - 1, 8 } }; - if (Setup.AntiAlias && m_Osd->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) { - m_Osd->SetAreas(Areas1, sizeof(Areas1) / sizeof(tArea)); - } - else { - tArea Areas2[] = { { 0, OSDSTATUSWIN_Y(0), OSDWIDTH - 1, OSDSTATUSWIN_Y(0) + OSDSTATUSHEIGHT - 1, femonTheme[femonConfig.theme].bpp }, - { 0, OSDINFOWIN_Y(0), OSDWIDTH - 1, OSDINFOWIN_Y(0) + OSDROWHEIGHT - 1, femonTheme[femonConfig.theme].bpp }, - { 0, OSDINFOWIN_Y(OSDROWHEIGHT), OSDWIDTH - 1, OSDINFOWIN_Y(0) + OSDINFOHEIGHT - 1, 2 } }; - m_Osd->SetAreas(Areas2, sizeof(Areas2) / sizeof(tArea)); - } - OSDCLEARSTATUS(); - OSDCLEARINFO(); - m_Osd->Flush(); - if (m_Receiver) { - m_Receiver->Deactivate(); - DELETENULL(m_Receiver); - } - if (femonConfig.analyzestream && channel) { - m_Receiver = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); - cDevice::ActualDevice()->AttachReceiver(m_Receiver); - } - Start(); - } -} - -void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber, bool liveView) -{ - debug("%s(%d,%d)\n", __PRETTY_FUNCTION__, device->DeviceNumber(), channelNumber); - eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - - if (!device || !liveView) - return; - - if (!channelNumber) { - if (m_Receiver) { - m_Receiver->Deactivate(); - DELETENULL(m_Receiver); - } - return; - } - - if (channel && femonConfig.analyzestream) { - m_DeviceSource = DEVICESOURCE_DVBAPI; - if (channel->IsSourceType('I')) - m_DeviceSource = DEVICESOURCE_IPTV; - else if (channel->IsSourceType('V')) - m_DeviceSource = DEVICESOURCE_PVRINPUT; - - if (m_Frontend >= 0) { - close(m_Frontend); - m_Frontend = -1; - } - - if (m_DeviceSource == DEVICESOURCE_DVBAPI) { - if (!strstr(*cDevice::ActualDevice()->DeviceType(), SATIP_DEVICE)) { - cDvbDevice *dev = getDvbDevice(cDevice::ActualDevice()); - m_Frontend = dev ? open(*cString::sprintf(FRONTEND_DEVICE, dev->Adapter(), dev->Frontend()), O_RDONLY | O_NONBLOCK) : -1; - if (m_Frontend >= 0) { - if (ioctl(m_Frontend, FE_GET_INFO, &m_FrontendInfo) < 0) { - if (!femonConfig.usesvdrp) - error("cFemonOsd::ChannelSwitch() cannot read frontend info."); - close(m_Frontend); - m_Frontend = -1; - memset(&m_FrontendInfo, 0, sizeof(m_FrontendInfo)); - return; - } - } - else if (femonConfig.usesvdrp) { - if (!SvdrpConnect() || !SvdrpTune()) - return; - } - else { - error("cFemonOsd::ChannelSwitch() cannot open frontend device."); - return; - } - } - - if (m_Receiver) { - m_Receiver->Deactivate(); - DELETENULL(m_Receiver); - } - m_Receiver = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); - cDevice::ActualDevice()->AttachReceiver(m_Receiver); - } - } -} - -void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - if (m_Receiver) { - m_Receiver->Deactivate(); - DELETENULL(m_Receiver); - } - if (femonConfig.analyzestream) { - const cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (channel) { - m_Receiver = new cFemonReceiver(channel, IS_AUDIO_TRACK(track) ? int(track - ttAudioFirst) : 0, IS_DOLBY_TRACK(track) ? int(track - ttDolbyFirst) : 0); - cDevice::ActualDevice()->AttachReceiver(m_Receiver); - } - } -} - -bool cFemonOsd::DeviceSwitch(int direction) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - int device = cDevice::ActualDevice()->DeviceNumber(); - direction = sgn(direction); - if (device >= 0) { - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (channel) { - for (int i = 0; i < cDevice::NumDevices() - 1; i++) { - if (direction >= 0) { - if (++device >= cDevice::NumDevices()) - device = 0; - } - else { - if (--device < 0) - device = cDevice::NumDevices() - 1; - } - // Collect the current priorities of all CAM slots that can decrypt the channel: - int NumCamSlots = CamSlots.Count(); - int SlotPriority[NumCamSlots]; - int NumUsableSlots = 0; - bool NeedsDetachAllReceivers = false; - bool InternalCamNeeded = false; - bool ValidDevice = false; - cCamSlot *s = NULL; - cDevice *d = cDevice::GetDevice(device); - if (channel->Ca() >= CA_ENCRYPTED_MIN) { - for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { - SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used - if (CamSlot->ModuleStatus() == msReady) { - if (CamSlot->ProvidesCa(channel->Caids())) { - if (!ChannelCamRelations.CamChecked(channel->GetChannelID(), CamSlot->SlotNumber())) { - SlotPriority[CamSlot->Index()] = CamSlot->Priority(); - NumUsableSlots++; - } - } - } - } - if (!NumUsableSlots) - InternalCamNeeded = true; // no CAM is able to decrypt this channel - } - for (int j = 0; j < NumCamSlots || !NumUsableSlots; ++j) { - if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) - continue; // there is no CAM available in this slot - bool HasInternalCam = d->HasInternalCam(); - if (InternalCamNeeded && !HasInternalCam) - continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs - if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(d, true)) - continue; // CAM slot can't be used with this device - if (d->ProvidesChannel(channel, 0, &NeedsDetachAllReceivers)) { // this device is basically able to do the job - debug("%s(%d) device(%d)\n", __PRETTY_FUNCTION__, direction, device); - if (NumUsableSlots && !HasInternalCam && d->CamSlot() && d->CamSlot() != CamSlots.Get(j)) - NeedsDetachAllReceivers = true; // using a different CAM slot requires detaching receivers - if (NumUsableSlots && !HasInternalCam) - s = CamSlots.Get(j); - ValidDevice = true; - break; - } - if (!NumUsableSlots) - break; // no CAM necessary, so just one loop over the devices - } - // Do the actual switch if valid device found - if (d && ValidDevice) { - cControl::Shutdown(); - if (NeedsDetachAllReceivers) - d->DetachAllReceivers(); - if (s) { - if (s->Device() != d) { - if (s->Device()) - s->Device()->DetachAllReceivers(); - if (d->CamSlot()) - d->CamSlot()->Assign(NULL); - s->Assign(d); - } - } - else if (d->CamSlot() && !d->CamSlot()->IsDecrypting()) - d->CamSlot()->Assign(NULL); - d->SwitchChannel(channel, false); - cControl::Launch(new cTransferControl(d, channel)); - return (true); - } - } - } - } - return (false); -} - -bool cFemonOsd::SvdrpConnect(void) -{ - if (m_SvdrpConnection.handle < 0) { - m_SvdrpPlugin = cPluginManager::GetPlugin(SVDRPPLUGIN); - if (m_SvdrpPlugin) { - m_SvdrpConnection.serverIp = femonConfig.svdrpip; - m_SvdrpConnection.serverPort = (unsigned short)femonConfig.svdrpport; - m_SvdrpConnection.shared = true; - m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); - if (m_SvdrpConnection.handle >= 0) { - SvdrpCommand_v1_0 cmd; - cmd.handle = m_SvdrpConnection.handle; - cmd.command = cString::sprintf("PLUG %s\r\n", PLUGIN_NAME_I18N); - m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); - if (cmd.responseCode != 214) { - m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); // close connection - error("cFemonOsd::SvdrpConnect() cannot find plugin '%s' on server %s.", PLUGIN_NAME_I18N, *m_SvdrpConnection.serverIp); - } - } - else - error("cFemonOsd::SvdrpConnect() cannot connect to SVDRP server."); - } - else - error("cFemonOsd::SvdrpConnect() cannot find plugin '%s'.", SVDRPPLUGIN); - } - return m_SvdrpConnection.handle >= 0; -} - -bool cFemonOsd::SvdrpTune(void) -{ - if (m_SvdrpPlugin && m_SvdrpConnection.handle >= 0) { - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (channel) { - SvdrpCommand_v1_0 cmd; - cmd.handle = m_SvdrpConnection.handle; - cmd.command = cString::sprintf("CHAN %s\r\n", *channel->GetChannelID().ToString()); - m_SvdrpPlugin->Service("SvdrpCommand-v1.0", &cmd); - if (cmd.responseCode == 250) - return true; - error("cFemonOsd::SvdrpTune() cannot tune server channel."); - } - else - error("cFemonOsd::SvdrpTune() invalid channel."); - } - else - error("cFemonOsd::SvdrpTune() unexpected connection state."); - return false; -} - -double cFemonOsd::GetVideoBitrate(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - double value = 0.0; - - if (m_Receiver) - value = m_Receiver->VideoBitrate(); - - return (value); -} - -double cFemonOsd::GetAudioBitrate(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - double value = 0.0; - - if (m_Receiver) - value = m_Receiver->AudioBitrate(); - - return (value); -} - -double cFemonOsd::GetDolbyBitrate(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - double value = 0.0; - - if (m_Receiver) - value = m_Receiver->AC3Bitrate(); - - return (value); -} - -eOSState cFemonOsd::ProcessKey(eKeys Key) -{ - eOSState state = cOsdObject::ProcessKey(Key); - if (state == osUnknown) { - switch (int(Key)) { - case k0: - if ((m_Number == 0) && (m_OldNumber != 0)) { - m_Number = m_OldNumber; - m_OldNumber = cDevice::CurrentChannel(); - Channels.SwitchTo(m_Number); - m_Number = 0; - return osContinue; - } - case k1 ... k9: - if (m_Number >= 0) { - m_Number = m_Number * 10 + Key - k0; - if (m_Number > 0) { - DrawStatusWindow(); - cChannel *ch = Channels.GetByNumber(m_Number); - m_InputTime.Set(0); - // Lets see if there can be any useful further input: - int n = ch ? m_Number * 10 : 0; - while (ch && (ch = Channels.Next(ch)) != NULL) { - if (!ch->GroupSep()) { - if (n <= ch->Number() && ch->Number() <= n + 9) { - n = 0; - break; - } - if (ch->Number() > n) - n *= 10; - } - } - if (n > 0) { - // This channel is the only one that fits the input, so let's take it right away: - m_OldNumber = cDevice::CurrentChannel(); - Channels.SwitchTo(m_Number); - m_Number = 0; - } - } - } - break; - case kBack: - return osEnd; - case kGreen: - { - eTrackType types[ttMaxTrackTypes]; - eTrackType CurrentAudioTrack = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - int numTracks = 0; - int oldTrack = 0; - int track = 0; - for (int i = ttAudioFirst; i <= ttDolbyLast; i++) { - const tTrackId *TrackId = cDevice::PrimaryDevice()->GetTrack(eTrackType(i)); - if (TrackId && TrackId->id) { - types[numTracks] = eTrackType(i); - if (i == CurrentAudioTrack) - track = numTracks; - numTracks++; - } - } - oldTrack = track; - if (++track >= numTracks) - track = 0; - if (track != oldTrack) { - cDevice::PrimaryDevice()->SetCurrentAudioTrack(types[track]); - Setup.CurrentDolby = IS_DOLBY_TRACK(types[track]); - } - } - break; - case kYellow: - if (IS_AUDIO_TRACK(cDevice::PrimaryDevice()->GetCurrentAudioTrack())) { - int audioChannel = cDevice::PrimaryDevice()->GetAudioChannel(); - int oldAudioChannel = audioChannel; - if (++audioChannel > 2) - audioChannel = 0; - if (audioChannel != oldAudioChannel) { - cDevice::PrimaryDevice()->SetAudioChannel(audioChannel); - } - } - break; - case kRight: - DeviceSwitch(1); - break; - case kLeft: - DeviceSwitch(-1); - break; - case kUp|k_Repeat: - case kUp: - case kDown|k_Repeat: - case kDown: - m_OldNumber = cDevice::CurrentChannel(); - cDevice::SwitchChannel(NORMALKEY(Key) == kUp ? 1 : -1); - m_Number = 0; - break; - case kNone: - if (m_Number && (m_InputTime.Elapsed() > CHANNELINPUT_TIMEOUT)) { - if (Channels.GetByNumber(m_Number)) { - m_OldNumber = cDevice::CurrentChannel(); - Channels.SwitchTo(m_Number); - m_Number = 0; - } - else { - m_InputTime.Set(0); - m_Number = 0; - } - } - break; - case kOk: - { - // toggle between display modes - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (++m_DisplayMode == eFemonModeAC3 && channel && !channel->Dpid(0)) m_DisplayMode++; - if (m_DisplayMode >= eFemonModeMaxNumber) m_DisplayMode = 0; - DrawInfoWindow(); - } - break; - default: - break; - } - state = osContinue; - } - return state; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonosd.h vdr-plugin-femon-2.2.1.git20150307.2205/femonosd.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonosd.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonosd.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONOSD_H -#define __FEMONOSD_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "svdrpservice.h" - -#define MAX_BM_NUMBER 8 - -class cFemonOsd : public cOsdObject, public cThread, public cStatus { -private: - enum eDeviceSourceType { - DEVICESOURCE_DVBAPI = 0, - DEVICESOURCE_IPTV, - DEVICESOURCE_PVRINPUT, - DEVICESOURCE_COUNT - }; - - static cFemonOsd *pInstance; - - cOsd *m_Osd; - cFemonReceiver *m_Receiver; - int m_Frontend; - int m_SvdrpFrontend; - double m_SvdrpVideoBitrate; - double m_SvdrpAudioBitrate; - SvdrpConnection_v1_0 m_SvdrpConnection; - cPlugin *m_SvdrpPlugin; - int m_Number; - int m_OldNumber; - int m_Quality; - bool m_QualityValid; - int m_Strength; - bool m_StrengthValid; - uint16_t m_SNR; - bool m_SNRValid; - uint16_t m_Signal; - bool m_SignalValid; - uint32_t m_BER; - bool m_BERValid; - uint32_t m_UNC; - bool m_UNCValid; - cString m_FrontendName; - fe_status_t m_FrontendStatus; - bool m_FrontendStatusValid; - dvb_frontend_info m_FrontendInfo; - eDeviceSourceType m_DeviceSource; - int m_DisplayMode; - int m_OsdWidth; - int m_OsdHeight; - int m_OsdLeft; - int m_OsdTop; - cFont *m_Font; - cTimeMs m_InputTime; - cCondWait m_Sleep; - cMutex m_Mutex; - - void DrawStatusWindow(void); - void DrawInfoWindow(void); - bool SvdrpConnect(void); - bool SvdrpTune(void); - -protected: - cFemonOsd(); - cFemonOsd(const cFemonOsd&); - cFemonOsd& operator= (const cFemonOsd&); - virtual void Action(void); - virtual void ChannelSwitch(const cDevice *device, int channelNumber, bool liveView); - virtual void SetAudioTrack(int Index, const char * const *Tracks); - -public: - static cFemonOsd *Instance(bool create = false); - ~cFemonOsd(); - - virtual void Show(void); - virtual eOSState ProcessKey(eKeys Key); - - bool DeviceSwitch(int direction); - double GetVideoBitrate(void); - double GetAudioBitrate(void); - double GetDolbyBitrate(void); -}; - -#endif //__FEMONOSD_H - diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonreceiver.c vdr-plugin-femon-2.2.1.git20150307.2205/femonreceiver.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonreceiver.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonreceiver.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,250 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include -#include "femontools.h" -#include "femoncfg.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_DetectH264(this), - m_DetectMPEG(this, this), - m_DetectAAC(this), - m_DetectLATM(this), - m_DetectAC3(this), - 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_VideoBitrate(0.0), - m_VideoValid(false), - m_AudioBuffer(KILOBYTE(256), TS_SIZE, false, "Femon audio"), - m_AudioPid(Channel ? Channel->Apid(ATrack) : 0), - m_AudioPacketCount(0), - m_AudioBitrate(0.0), - m_AudioValid(false), - m_AC3Buffer(KILOBYTE(256), TS_SIZE, false, "Femon AC3"), - m_AC3Pid(Channel ? Channel->Dpid(DTrack) : 0), - m_AC3PacketCount(0), - m_AC3Bitrate(0), - m_AC3Valid(false) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - - 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_VideoInfo.codec = VIDEO_CODEC_INVALID; - m_VideoInfo.format = VIDEO_FORMAT_INVALID; - m_VideoInfo.scan = VIDEO_SCAN_INVALID; - m_VideoInfo.aspectRatio = VIDEO_ASPECT_RATIO_INVALID; - m_VideoInfo.width = 0; - m_VideoInfo.height = 0; - m_VideoInfo.frameRate = 0; - m_VideoInfo.bitrate = AUDIO_BITRATE_INVALID; - m_AudioInfo.codec = AUDIO_CODEC_UNKNOWN; - m_AudioInfo.bitrate = AUDIO_BITRATE_INVALID; - m_AudioInfo.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; - m_AudioInfo.channelMode = AUDIO_CHANNEL_MODE_INVALID; - m_AC3Info.bitrate = AUDIO_BITRATE_INVALID; - m_AC3Info.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; - m_AC3Info.bitstreamMode = AUDIO_BITSTREAM_MODE_INVALID; - m_AC3Info.audioCodingMode = AUDIO_CODING_MODE_INVALID; - m_AC3Info.dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; - m_AC3Info.centerMixLevel = AUDIO_CENTER_MIX_LEVEL_INVALID; - m_AC3Info.surroundMixLevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; - m_AC3Info.dialogLevel = 0; - m_AC3Info.lfe = false; -} - -cFemonReceiver::~cFemonReceiver(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - Deactivate(); -} - -void cFemonReceiver::Deactivate(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - Detach(); - if (m_Active) { - m_Active = false; - m_Sleep.Signal(); - if (Running()) - Cancel(3); - } -} - -void cFemonReceiver::Activate(bool On) -{ - debug("%s(%d)\n", __PRETTY_FUNCTION__, 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) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - cTimeMs calcPeriod(0); - m_Active = true; - - while (Running() && m_Active) { - uint8_t *Data; - double timeout; - int len, 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)) { - while (const uint8_t *p = m_VideoAssembler.GetPes(len)) { - if (m_VideoType == 0x1B) { // MPEG4 - if (m_DetectH264.processVideo(p, len)) { - m_VideoValid = true; - break; - } - } - else { - if (m_DetectMPEG.processVideo(p, len)) { - m_VideoValid = true; - break; - } - } - } - m_VideoAssembler.Reset(); - } - m_VideoAssembler.PutTs(Data, Length); - m_VideoBuffer.Del(Length); - } - - // process available audio data - while ((Data = m_AudioBuffer.Get(Length))) { - if (!m_Active || (Length < TS_SIZE)) - break; - Length = TS_SIZE; - if (*Data != TS_SYNC_BYTE) { - for (int i = 1; i < Length; ++i) { - if (Data[i] == TS_SYNC_BYTE) { - Length = i; - break; - } - } - m_AudioBuffer.Del(Length); - continue; - } - processed = true; - if (const uint8_t *p = m_AudioAssembler.GetPes(len)) { - if (m_DetectAAC.processAudio(p, len) || m_DetectLATM.processAudio(p, len) || m_DetectMPEG.processAudio(p, len)) - m_AudioValid = true; - m_AudioAssembler.Reset(); - } - m_AudioAssembler.PutTs(Data, Length); - m_AudioBuffer.Del(Length); - } - - // process available dolby data - while ((Data = m_AC3Buffer.Get(Length))) { - if (!m_Active || (Length < TS_SIZE)) - break; - Length = TS_SIZE; - if (*Data != TS_SYNC_BYTE) { - for (int i = 1; i < Length; ++i) { - if (Data[i] == TS_SYNC_BYTE) { - Length = i; - break; - } - } - m_AC3Buffer.Del(Length); - continue; - } - processed = true; - if (const uint8_t *p = m_AC3Assembler.GetPes(len)) { - if (m_DetectAC3.processAudio(p, len)) - m_AC3Valid = true; - m_AC3Assembler.Reset(); - } - m_AC3Assembler.PutTs(Data, Length); - m_AC3Buffer.Del(Length); - } - - // calculate bitrates - timeout = double(calcPeriod.Elapsed()); - if (m_Active && (timeout >= (100.0 * femonConfig.calcinterval))) { - // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit - // PES headers should be compensated! - m_VideoBitrate = (1000.0 * 8.0 * 184.0 * m_VideoPacketCount) / timeout; - m_VideoPacketCount = 0; - m_AudioBitrate = (1000.0 * 8.0 * 184.0 * m_AudioPacketCount) / timeout; - m_AudioPacketCount = 0; - m_AC3Bitrate = (1000.0 * 8.0 * 184.0 * m_AC3PacketCount) / timeout; - m_AC3PacketCount = 0; - calcPeriod.Set(0); - } - - if (!processed) - m_Sleep.Wait(10); // to avoid busy loop and reduce cpu load - } -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonreceiver.h vdr-plugin-femon-2.2.1.git20150307.2205/femonreceiver.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonreceiver.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonreceiver.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONRECEIVER_H -#define __FEMONRECEIVER_H - -#include -#include - -#include "femonh264.h" -#include "femonmpeg.h" -#include "femonaac.h" -#include "femonlatm.h" -#include "femonac3.h" -#include "femonaudio.h" -#include "femonvideo.h" -#include "femontools.h" - -class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If { -private: - cMutex m_Mutex; - cCondWait m_Sleep; - bool m_Active; - - cFemonH264 m_DetectH264; - cFemonMPEG m_DetectMPEG; - cFemonAAC m_DetectAAC; - cFemonLATM m_DetectLATM; - cFemonAC3 m_DetectAC3; - - cRingBufferLinear m_VideoBuffer; - cTsToPes m_VideoAssembler; - int m_VideoType; - int m_VideoPid; - int m_VideoPacketCount; - double m_VideoBitrate; - bool m_VideoValid; - video_info_t m_VideoInfo; - - cRingBufferLinear m_AudioBuffer; - cTsToPes m_AudioAssembler; - int m_AudioPid; - int m_AudioPacketCount; - double m_AudioBitrate; - bool m_AudioValid; - audio_info_t m_AudioInfo; - - cRingBufferLinear m_AC3Buffer; - cTsToPes m_AC3Assembler; - int m_AC3Pid; - int m_AC3PacketCount; - double m_AC3Bitrate; - bool m_AC3Valid; - ac3_info_t m_AC3Info; - -protected: - virtual void Activate(bool On); - virtual void Receive(uchar *Data, int Length); - virtual void Action(void); - -public: - virtual void SetVideoCodec(eVideoCodec codec) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.codec = codec; } - virtual void SetVideoFormat(eVideoFormat format) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.format = format; } - virtual void SetVideoScan(eVideoScan scan) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.scan = scan; } - virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.aspectRatio = aspectratio; } - virtual void SetVideoSize(int width, int height) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.width = width; - m_VideoInfo.height = height; } - virtual void SetVideoFramerate(double framerate) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.frameRate = framerate; } - virtual void SetVideoBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex); - m_VideoInfo.bitrate = bitrate; } - - virtual void SetAudioCodec(eAudioCodec codec) { cMutexLock MutexLock(&m_Mutex); - m_AudioInfo.codec = codec; } - virtual void SetAudioBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex); - m_AudioInfo.bitrate = bitrate; } - virtual void SetAudioSamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex); - m_AudioInfo.samplingFrequency = sampling; } - virtual void SetAudioChannel(eAudioChannelMode mode) { cMutexLock MutexLock(&m_Mutex); - m_AudioInfo.channelMode = mode; } - - virtual void SetAC3Bitrate(int bitrate) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.bitrate = bitrate; } - virtual void SetAC3SamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.samplingFrequency = sampling; } - virtual void SetAC3Bitstream(int mode) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.bitstreamMode = mode; } - virtual void SetAC3AudioCoding(int mode) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.audioCodingMode = mode; } - virtual void SetAC3DolbySurround(int mode) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.dolbySurroundMode = mode; } - virtual void SetAC3CenterMix(int level) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.centerMixLevel = level; } - virtual void SetAC3SurroundMix(int level) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.surroundMixLevel = level; } - virtual void SetAC3Dialog(int level) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.dialogLevel = level; } - virtual void SetAC3LFE(bool onoff) { cMutexLock MutexLock(&m_Mutex); - m_AC3Info.lfe = onoff; } - -public: - cFemonReceiver(const cChannel* Channel, int ATrack, int DTrack); - virtual ~cFemonReceiver(); - void Deactivate(void); - - bool VideoValid(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoValid; }; // boolean - double VideoBitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoBitrate; }; // bit/s - int VideoCodec(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.codec; }; // eVideoCodec - int VideoFormat(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.format; }; // eVideoFormat - int VideoScan(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.scan; }; // eVideoScan - int VideoAspectRatio(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio - int VideoHorizontalSize(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.width; }; // pixels - int VideoVerticalSize(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.height; }; // pixels - double VideoFrameRate(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.frameRate; }; // Hz - double VideoStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_VideoInfo.bitrate; }; // bit/s - - bool AudioValid(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioValid; }; // boolean - double AudioBitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioBitrate; }; // bit/s - int AudioCodec(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioInfo.codec; }; // eAudioCodec - int AudioChannelMode(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioInfo.channelMode; }; // eAudioChannelMode - double AudioStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate - int AudioSamplingFreq(void) { cMutexLock MutexLock(&m_Mutex); - return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency - - bool AC3Valid(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Valid; }; // boolean - double AC3Bitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Bitrate; }; // bit/s - double AC3StreamBitrate(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate - int AC3SamplingFreq(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency - int AC3BitStreamMode(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode - int AC3AudioCodingMode(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode - bool AC3_2_0(void) { cMutexLock MutexLock(&m_Mutex); - return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean - bool AC3_5_1(void) { cMutexLock MutexLock(&m_Mutex); - return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean - int AC3DolbySurroundMode(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode - int AC3CenterMixLevel(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel - int AC3SurroundMixLevel(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel - int AC3DialogLevel(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.dialogLevel; }; // -dB - bool AC3Lfe(void) { cMutexLock MutexLock(&m_Mutex); - return m_AC3Info.lfe; }; // boolean - }; - -#endif //__FEMONRECEIVER_H - diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonsymbol.c vdr-plugin-femon-2.2.1.git20150307.2205/femonsymbol.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femonsymbol.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonsymbol.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#include -#include "femontools.h" -#include "femonsymbol.h" - -#include "symbols/stereo.xpm" -#include "symbols/monoleft.xpm" -#include "symbols/monoright.xpm" -#include "symbols/dolbydigital.xpm" -#include "symbols/dolbydigital20.xpm" -#include "symbols/dolbydigital51.xpm" -#include "symbols/mpeg2.xpm" -#include "symbols/h264.xpm" -#include "symbols/ntsc.xpm" -#include "symbols/pal.xpm" -#include "symbols/encrypted.xpm" -#include "symbols/svdrp.xpm" -#include "symbols/lock.xpm" -#include "symbols/signal.xpm" -#include "symbols/carrier.xpm" -#include "symbols/viterbi.xpm" -#include "symbols/sync.xpm" -#include "symbols/ar11.xpm" -#include "symbols/ar169.xpm" -#include "symbols/ar2211.xpm" -#include "symbols/ar43.xpm" -#include "symbols/device.xpm" -#include "symbols/zero.xpm" -#include "symbols/one.xpm" -#include "symbols/two.xpm" -#include "symbols/three.xpm" -#include "symbols/four.xpm" -#include "symbols/five.xpm" -#include "symbols/six.xpm" -#include "symbols/seven.xpm" -#include "symbols/eight.xpm" -#include "symbols/format1080.xpm" -#include "symbols/format1080i.xpm" -#include "symbols/format1080p.xpm" -#include "symbols/format720.xpm" -#include "symbols/format720i.xpm" -#include "symbols/format720p.xpm" -#include "symbols/format576.xpm" -#include "symbols/format576i.xpm" -#include "symbols/format576p.xpm" -#include "symbols/format480.xpm" -#include "symbols/format480i.xpm" -#include "symbols/format480p.xpm" - -static cBitmap bmOnePixel(1, 1, 1); -static cBitmap bmStereo(stereo_xpm); -static cBitmap bmMonoLeft(monoleft_xpm); -static cBitmap bmMonoRight(monoright_xpm); -static cBitmap bmDolbyDigital(dolbydigital_xpm); -static cBitmap bmDolbyDigital20(dolbydigital20_xpm); -static cBitmap bmDolbyDigital51(dolbydigital51_xpm); -static cBitmap bmMpeg2(mpeg2_xpm); -static cBitmap bmH264(h264_xpm); -static cBitmap bmPal(pal_xpm); -static cBitmap bmNtsc(ntsc_xpm); -static cBitmap bmEncrypted(encrypted_xpm); -static cBitmap bmSvdrp(svdrp_xpm); -static cBitmap bmLock(lock_xpm); -static cBitmap bmSignal(signal_xpm); -static cBitmap bmCarrier(carrier_xpm); -static cBitmap bmViterbi(viterbi_xpm); -static cBitmap bmSync(sync_xpm); -static cBitmap bmAspectRatio11(ar11_xpm); -static cBitmap bmAspectRatio169(ar169_xpm); -static cBitmap bmAspectRatio2211(ar2211_xpm); -static cBitmap bmAspectRatio43(ar43_xpm); -static cBitmap bmDevice(device_xpm); -static cBitmap bmZero(zero_xpm); -static cBitmap bmOne(one_xpm); -static cBitmap bmTwo(two_xpm); -static cBitmap bmThree(three_xpm); -static cBitmap bmFour(four_xpm); -static cBitmap bmFive(five_xpm); -static cBitmap bmSix(six_xpm); -static cBitmap bmSeven(seven_xpm); -static cBitmap bmEight(eight_xpm); -static cBitmap bmFormat1080(format1080_xpm); -static cBitmap bmFormat1080i(format1080i_xpm); -static cBitmap bmFormat1080p(format1080p_xpm); -static cBitmap bmFormat720(format720_xpm); -static cBitmap bmFormat720i(format720i_xpm); -static cBitmap bmFormat720p(format720p_xpm); -static cBitmap bmFormat576(format576_xpm); -static cBitmap bmFormat576i(format576i_xpm); -static cBitmap bmFormat576p(format576p_xpm); -static cBitmap bmFormat480(format480_xpm); -static cBitmap bmFormat480i(format480i_xpm); -static cBitmap bmFormat480p(format480p_xpm); - -cFemonSymbolCache femonSymbols; - -cFemonSymbolCache::cFemonSymbolCache() -: xFactorM(1.0), - yFactorM(1.0), - antiAliasM(false) -{ - Populate(); -} - -cFemonSymbolCache::~cFemonSymbolCache() -{ - Flush(); -} - -void cFemonSymbolCache::Refresh() -{ - int width, height; - double aspect, xfactor, yfactor; - cDevice::PrimaryDevice()->GetOsdSize(width, height, aspect); - debug("%s(): %dx%d\n", __PRETTY_FUNCTION__, width, height); - xfactor = (double)width / DEFAULT_WIDTH; - yfactor = (double)height / DEFAULT_HEIGHT; - if (!DoubleEqual(xfactor, xFactorM) || !DoubleEqual(yfactor, yFactorM)) { - xFactorM = xfactor; - yFactorM = yfactor; - Populate(); - } -} - -bool cFemonSymbolCache::Populate(void) -{ - debug("%s(): %.02fx%.02f\n", __PRETTY_FUNCTION__, xFactorM, yFactorM); - if (!DoubleEqual(0.0, xFactorM) || !DoubleEqual(0.0, yFactorM)) { - Flush(); - - // pushing order must follow the enumeration - keep original proportions except for frontend status ones - cacheM.Append(bmOnePixel.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ONEPIXEL - cacheM.Append(bmStereo.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_STEREO - cacheM.Append(bmMonoLeft.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MONO_LEFT - cacheM.Append(bmMonoRight.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MONO_RIGHT - cacheM.Append(bmDolbyDigital.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD - cacheM.Append(bmDolbyDigital20.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD20 - 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(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 - cacheM.Append(bmSvdrp.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_SVDRP - cacheM.Append(bmLock.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_LOCK - cacheM.Append(bmSignal.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_SIGNAL - cacheM.Append(bmCarrier.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_CARRIER - cacheM.Append(bmViterbi.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_VITERBI - cacheM.Append(bmSync.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_SYNC - cacheM.Append(bmAspectRatio11.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_1_1 - cacheM.Append(bmAspectRatio169.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_16_9 - cacheM.Append(bmAspectRatio2211.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_2_21_1 - cacheM.Append(bmAspectRatio43.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_4_3 - cacheM.Append(bmDevice.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DEVICE - cacheM.Append(bmZero.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ZERO - cacheM.Append(bmOne.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ONE - cacheM.Append(bmTwo.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_TWO - cacheM.Append(bmThree.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_THREE - cacheM.Append(bmFour.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FOUR - cacheM.Append(bmFive.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FIVE - 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(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 - cacheM.Append(bmFormat720.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720 - cacheM.Append(bmFormat720i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720i - cacheM.Append(bmFormat720p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720p - cacheM.Append(bmFormat576.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576 - cacheM.Append(bmFormat576i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576i - cacheM.Append(bmFormat576p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576p - cacheM.Append(bmFormat480.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480 - cacheM.Append(bmFormat480i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480i - cacheM.Append(bmFormat480p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480p - - return true; - } - - return false; -} - -bool cFemonSymbolCache::Flush(void) -{ - debug("%s()\n", __PRETTY_FUNCTION__); - for (int i = 0; i < cacheM.Size(); ++i) { - cBitmap *bmp = cacheM[i]; - DELETENULL(bmp); - } - cacheM.Clear(); - return true; -} - -cBitmap& cFemonSymbolCache::Get(eSymbols symbolP) -{ - cBitmap *bitmapM = cacheM[SYMBOL_ONEPIXEL]; - - if (symbolP < cacheM.Size()) - bitmapM = cacheM[symbolP]; - else - error("%s(): Invalid symbol %d\n", __PRETTY_FUNCTION__, symbolP); - - return *bitmapM; -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonsymbol.h vdr-plugin-femon-2.2.1.git20150307.2205/femonsymbol.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonsymbol.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonsymbol.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONSYMBOL_H -#define __FEMONSYMBOL_H - -#include -#include - -enum eSymbols { - SYMBOL_ONEPIXEL, - SYMBOL_STEREO, - SYMBOL_MONO_LEFT, - SYMBOL_MONO_RIGHT, - SYMBOL_DD, - SYMBOL_DD20, - SYMBOL_DD51, - SYMBOL_MPEG2, - SYMBOL_H264, - SYMBOL_PAL, - SYMBOL_NTSC, - SYMBOL_ENCRYPTED, - SYMBOL_SVDRP, - SYMBOL_LOCK, - SYMBOL_SIGNAL, - SYMBOL_CARRIER, - SYMBOL_VITERBI, - SYMBOL_SYNC, - SYMBOL_AR_1_1, - SYMBOL_AR_16_9, - SYMBOL_AR_2_21_1, - SYMBOL_AR_4_3, - SYMBOL_DEVICE, - SYMBOL_ZERO, - SYMBOL_ONE, - SYMBOL_TWO, - SYMBOL_THREE, - SYMBOL_FOUR, - SYMBOL_FIVE, - SYMBOL_SIX, - SYMBOL_SEVEN, - SYMBOL_EIGHT, - SYMBOL_FORMAT_1080, - SYMBOL_FORMAT_1080i, - SYMBOL_FORMAT_1080p, - SYMBOL_FORMAT_720, - SYMBOL_FORMAT_720i, - SYMBOL_FORMAT_720p, - SYMBOL_FORMAT_576, - SYMBOL_FORMAT_576i, - SYMBOL_FORMAT_576p, - SYMBOL_FORMAT_480, - SYMBOL_FORMAT_480i, - SYMBOL_FORMAT_480p, - SYMBOL_MAX_COUNT - }; - -class cFemonSymbolCache { -private: - enum { - DEFAULT_SPACING = 5, - DEFAULT_ROUNDING = 10, - DEFAULT_HEIGHT = 576, - DEFAULT_WIDTH = 720 - }; - double xFactorM; - double yFactorM; - bool antiAliasM; - cVector cacheM; - bool Populate(void); - bool Flush(void); -public: - cFemonSymbolCache(); - ~cFemonSymbolCache(); - void Refresh(); - cBitmap& Get(eSymbols symbolP); - int GetSpacing() { return int(yFactorM * cFemonSymbolCache::DEFAULT_SPACING); } - int GetRounding() { return int(yFactorM * cFemonSymbolCache::DEFAULT_ROUNDING); } -}; - -extern cFemonSymbolCache femonSymbols; - -#endif // __FEMONSYMBOL_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femontools.c vdr-plugin-femon-2.2.1.git20150307.2205/femontools.c --- vdr-plugin-femon-2.2.0.git20150222.1714/femontools.c 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femontools.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,612 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif - -#include -#include -#include -#include -#include -#include -#include "femonreceiver.h" -#include "femonosd.h" -#include "femontools.h" - -static cString getCA(int value) -{ - // http://www.dvb.org/index.php?id=174 - // http://en.wikipedia.org/wiki/Conditional_access_system - switch (value) { - case 0x0000: return cString::sprintf("%s (%X)", trVDR("Free To Air"), value); // Reserved - case 0x0001 ... 0x009F: - case 0x00A2 ... 0x00FF: return cString::sprintf("%s (%X)", tr("Fixed"), value); // Standardized systems - case 0x00A0 ... 0x00A1: return cString::sprintf("%s (%X)", tr("Analog"), value); // Analog signals - case 0x0100 ... 0x01FF: return cString::sprintf("SECA Mediaguard (%X)", value); // Canal Plus - case 0x0464: return cString::sprintf("EuroDec (%X)", value); // EuroDec - case 0x0500 ... 0x05FF: return cString::sprintf("Viaccess (%X)", value); // France Telecom - case 0x0600 ... 0x06FF: return cString::sprintf("Irdeto (%X)", value); // Irdeto - case 0x0700 ... 0x07FF: return cString::sprintf("DigiCipher 2 (%X)", value); // Jerrold/GI/Motorola 4DTV - case 0x0900 ... 0x09FF: return cString::sprintf("NDS Videoguard (%X)", value); // NDS - case 0x0B00 ... 0x0BFF: return cString::sprintf("Conax (%X)", value); // Norwegian Telekom - case 0x0D00 ... 0x0DFF: return cString::sprintf("CryptoWorks (%X)", value); // Philips CryptoTec - case 0x0E00 ... 0x0EFF: return cString::sprintf("PowerVu (%X)", value); // Scientific Atlanta - case 0x1000: return cString::sprintf("RAS (%X)", value); // Tandberg Television - case 0x1200 ... 0x12FF: return cString::sprintf("NagraVision (%X)", value); // BellVu Express - case 0x1700 ... 0x17FF: return cString::sprintf("VCAS (%X)", value); // Verimatrix Inc. former BetaTechnik - case 0x1800 ... 0x18FF: return cString::sprintf("NagraVision (%X)", value); // Kudelski SA - case 0x22F0: return cString::sprintf("Codicrypt (%X)", value); // Scopus Network Technologies - case 0x2600: return cString::sprintf("BISS (%X)", value); // European Broadcasting Union - case 0x2719: return cString::sprintf("VanyaCas (%X)", value); // S-Curious Research & Technology Pvt. Ltd. - case 0x4347: return cString::sprintf("CryptOn (%X)", value); // CryptOn - case 0x4800: return cString::sprintf("Accessgate (%X)", value); // Telemann - case 0x4900: return cString::sprintf("China Crypt (%X)", value); // CryptoWorks - case 0x4A02: return cString::sprintf("Tongfang (%X)", value); // Tsinghua Tongfang Company - case 0x4A10: return cString::sprintf("EasyCas (%X)", value); // EasyCas - case 0x4A20: return cString::sprintf("AlphaCrypt (%X)", value); // AlphaCrypt - case 0x4A60: return cString::sprintf("SkyCrypt (%X)", value); // @Sky - case 0x4A61: return cString::sprintf("Neotioncrypt (%X)", value); // Neotion - case 0x4A62: return cString::sprintf("SkyCrypt (%X)", value); // @Sky - case 0x4A63: return cString::sprintf("Neotion SHL (%X)", value); // Neotion - case 0x4A64 ... 0x4A6F: return cString::sprintf("SkyCrypt (%X)", value); // @Sky - case 0x4A70: return cString::sprintf("DreamCrypt (%X)", value); // Dream Multimedia - case 0x4A80: return cString::sprintf("ThalesCrypt (%X)", value); // Thales Broadcast & Multimedia - case 0x4AA1: return cString::sprintf("KeyFly (%X)", value); // SIDSA - case 0x4ABF: return cString::sprintf("CTI-CAS (%X)", value); // Beijing Compunicate Technology Inc. - case 0x4AC1: return cString::sprintf("Latens (%X)", value); // Latens Systems - case 0x4AD0 ... 0x4AD1: return cString::sprintf("X-Crypt (%X)", value); // XCrypt Inc. - case 0x4AD4: return cString::sprintf("OmniCrypt (%X)", value); // Widevine Technologies, Inc. - case 0x4AE0 ... 0x4AE1: return cString::sprintf("Z-Crypt (%X)", value); // Digi Raum Electronics Co. Ltd. - case 0x4AE4: return cString::sprintf("CoreCrypt (%X)", value); // CoreTrust - case 0x4AE5: return cString::sprintf("PRO-Crypt (%X)", value); // IK SATPROF - case 0x4AEA: return cString::sprintf("Cryptoguard (%X)", value); // Gryptoguard AB - case 0x4AEB: return cString::sprintf("Abel Quintic (%X)", value); // Abel DRM Systems - case 0x4AF0: return cString::sprintf("ABV (%X)", value); // Alliance Broadcast Vision - case 0x5500: return cString::sprintf("Z-Crypt (%X)", value); // Digi Raum Electronics Co. Ltd. - case 0x5501: return cString::sprintf("Griffin (%X)", value); // Nucleus Systems Ltd. - case 0x5581: return cString::sprintf("Bulcrypt (%X)", value); // Bulcrypt - case 0x7BE1: return cString::sprintf("DRE-Crypt (%X)", value); // DRE-Crypt - case 0xA101: return cString::sprintf("RosCrypt-M (%X)", value); // NIIR - case 0xEAD0: return cString::sprintf("VanyaCas (%X)", value); // S-Curious Research & Technology Pvt. Ltd. - default: break; - } - return cString::sprintf("%X", value); -} - -static const char *getUserString(int Value, const tDvbParameterMap *Map) -{ - const tDvbParameterMap *map = Map; - while (map && map->userValue != -1) { - if (map->driverValue == Value) - return map->userString ? trVDR(map->userString) : "---"; - map++; - } - return "---"; -} - -cDvbDevice *getDvbDevice(cDevice* device) -{ - cDvbDevice *dev = dynamic_cast(device); -#ifdef __DYNAMIC_DEVICE_PROBE - if (!dev && device && device->HasSubDevice()) - dev = dynamic_cast(device->SubDevice()); -#endif - return dev; -} - -cString getFrontendInfo(cDvbDevice *device) -{ - struct dvb_frontend_info value; - fe_status_t status; - cString info = ""; - uint16_t signal = 0; - uint16_t snr = 0; - uint32_t ber = 0; - uint32_t unc = 0; - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - - if (!device) - return info; - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->Frontend()), O_RDONLY | O_NONBLOCK); - if (fe < 0) - return info; - - info = cString::sprintf("CARD:%d\nSTRG:%d\nQUAL:%d", device->CardIndex(), device->SignalStrength(), device->SignalQuality()); - - if (ioctl(fe, FE_GET_INFO, &value) >= 0) - info = cString::sprintf("%s\nTYPE:%d\nNAME:%s", *info, value.type, *device->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); - - if (cFemonOsd::Instance()) - info = cString::sprintf("%s\nVIBR:%.0f\nAUBR:%.0f\nDDBR:%.0f", *info, cFemonOsd::Instance()->GetVideoBitrate(), cFemonOsd::Instance()->GetAudioBitrate(), cFemonOsd::Instance()->GetDolbyBitrate()); - - if (channel) - info = cString::sprintf("%s\nCHAN:%s", *info, *channel->ToText()); - - return info; -} - -cString getFrontendName(cDvbDevice *device) -{ - if (!device) - return NULL; - - return (cString::sprintf("%s on device #%d", *device->DeviceName(), device->CardIndex())); -} - -cString getFrontendStatus(cDvbDevice *device) -{ - fe_status_t value; - - if (!device) - return NULL; - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->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 device #%d", (value & FE_HAS_LOCK) ? "LOCKED" : "-", (value & FE_HAS_SIGNAL) ? "SIGNAL" : "-", (value & FE_HAS_CARRIER) ? "CARRIER" : "-", (value & FE_HAS_VITERBI) ? "VITERBI" : "-", (value & FE_HAS_SYNC) ? "SYNC" : "-", device->CardIndex())); -} - -uint16_t getSignal(cDvbDevice *device) -{ - uint16_t value = 0; - - if (!device) - return (value); - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->Frontend()), O_RDONLY | O_NONBLOCK); - if (fe < 0) - return (value); - ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value); - close(fe); - - return (value); -} - -uint16_t getSNR(cDvbDevice *device) -{ - uint16_t value = 0; - - if (!device) - return (value); - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->Frontend()), O_RDONLY | O_NONBLOCK); - if (fe < 0) - return (value); - ioctl(fe, FE_READ_SNR, &value); - close(fe); - - return (value); -} - -uint32_t getBER(cDvbDevice *device) -{ - uint32_t value = 0; - - if (!device) - return (value); - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->Frontend()), O_RDONLY | O_NONBLOCK); - if (fe < 0) - return (value); - ioctl(fe, FE_READ_BER, &value); - close(fe); - - return (value); -} - -uint32_t getUNC(cDvbDevice *device) -{ - uint32_t value = 0; - - if (!device) - return (value); - - int fe = open(*cString::sprintf(FRONTEND_DEVICE, device->Adapter(), device->Frontend()), O_RDONLY | O_NONBLOCK); - if (fe < 0) - return (value); - ioctl(fe, FE_READ_UNCORRECTED_BLOCKS, &value); - close(fe); - - return (value); -} - -cString getApids(const cChannel *channel) -{ - int value = 0; - cString apids = cString::sprintf("%d", channel->Apid(value)); - while (channel->Apid(++value) && (value < MAXAPIDS)) - apids = cString::sprintf("%s, %d", *apids, channel->Apid(value)); - return apids; -} - -cString getDpids(const cChannel *channel) -{ - int value = 0; - cString dpids = cString::sprintf("%d", channel->Dpid(value)); - while (channel->Dpid(++value) && (value < MAXDPIDS)) - dpids = cString::sprintf("%s, %d", *dpids, channel->Dpid(value)); - return dpids; -} - -cString getSpids(const cChannel *channel) -{ - int value = 0; - cString spids = cString::sprintf("%d", channel->Spid(value)); - while (channel->Spid(++value) && (value < MAXSPIDS)) - spids = cString::sprintf("%s, %d", *spids, channel->Spid(value)); - return spids; -} - -cString getCAids(const cChannel *channel) -{ - int value = 0; - cString caids = cString::sprintf("%s", *getCA(channel->Ca(value))); - while (channel->Ca(++value) && (value < MAXCAIDS)) - caids = cString::sprintf("%s, %s", *caids, *getCA(channel->Ca(value))); - return caids; -} - -cString getVideoStream(int value) -{ - if (value != 0) - return cString::sprintf("#%d", value); - return cString::sprintf("---"); -} - -cString getAudioStream(int value, const cChannel *channel) -{ - int pid = 0; - if (IS_AUDIO_TRACK(value)) - pid = int(value - ttAudioFirst); - if (channel && channel->Apid(pid)) { - if (channel->Alang(pid)) - return cString::sprintf("#%d (%s)", channel->Apid(pid), channel->Alang(pid)); - else - return cString::sprintf("#%d", channel->Apid(pid)); - } - return cString::sprintf("---"); -} - -cString getAC3Stream(int value, const cChannel *channel) -{ - int pid = 0; - if (IS_DOLBY_TRACK(value)) - pid = int(value - ttDolbyFirst); - if (channel && channel->Dpid(pid)) { - if (channel->Dlang(pid)) - return cString::sprintf("#%d (%s)", channel->Dpid(pid), channel->Dlang(pid)); - else - return cString::sprintf("#%d", channel->Dpid(pid)); - } - return cString::sprintf("---"); -} - -cString getVideoCodec(int value) -{ - switch (value) { - case VIDEO_CODEC_MPEG2: return cString::sprintf("%s", tr("MPEG-2")); - case VIDEO_CODEC_H264: return cString::sprintf("%s", tr("H.264")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAudioCodec(int value) -{ - switch (value) { - case AUDIO_CODEC_MPEG1_I: return cString::sprintf("%s", tr("MPEG-1 Layer I")); - case AUDIO_CODEC_MPEG1_II: return cString::sprintf("%s", tr("MPEG-1 Layer II")); - case AUDIO_CODEC_MPEG1_III: return cString::sprintf("%s", tr("MPEG-1 Layer III")); - case AUDIO_CODEC_MPEG2_I: return cString::sprintf("%s", tr("MPEG-2 Layer I")); - case AUDIO_CODEC_MPEG2_II: return cString::sprintf("%s", tr("MPEG-2 Layer II")); - case AUDIO_CODEC_MPEG2_III: return cString::sprintf("%s", tr("MPEG-2 Layer III")); - case AUDIO_CODEC_HEAAC: return cString::sprintf("%s", tr("HE-AAC")); - case AUDIO_CODEC_LATM: return cString::sprintf("%s", tr("LATM")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAudioChannelMode(int value) -{ - switch (value) { - case AUDIO_CHANNEL_MODE_STEREO: return cString::sprintf("%s", tr("stereo")); - case AUDIO_CHANNEL_MODE_JOINT_STEREO: return cString::sprintf("%s", tr("joint Stereo")); - case AUDIO_CHANNEL_MODE_DUAL: return cString::sprintf("%s", tr("dual")); - case AUDIO_CHANNEL_MODE_SINGLE: return cString::sprintf("%s", tr("mono")); - default: break; - } - return cString::sprintf("---"); -} - -cString getCoderate(int value) -{ - return cString::sprintf("%s", getUserString(value, CoderateValues)); -} - -cString getTransmission(int value) -{ - return cString::sprintf("%s", getUserString(value, TransmissionValues)); -} - -cString getBandwidth(int value) -{ - return cString::sprintf("%s", getUserString(value, BandwidthValues)); -} - -cString getInversion(int value) -{ - return cString::sprintf("%s", getUserString(value, InversionValues)); -} - -cString getHierarchy(int value) -{ - return cString::sprintf("%s", getUserString(value, HierarchyValues)); -} - -cString getGuard(int value) -{ - return cString::sprintf("%s", getUserString(value, GuardValues)); -} - -cString getModulation(int value) -{ - return cString::sprintf("%s", getUserString(value, ModulationValues)); -} - -cString getTerrestrialSystem(int value) -{ - return cString::sprintf("%s", getUserString(value, SystemValuesTerr)); -} - -cString getSatelliteSystem(int value) -{ - return cString::sprintf("%s", getUserString(value, SystemValuesSat)); -} - -cString getRollOff(int value) -{ - return cString::sprintf("%s", getUserString(value, RollOffValues)); -} - -cString getPilot(int value) -{ - return cString::sprintf("%s", getUserString(value, PilotValues)); -} - -cString getResolution(int width, int height, int scan) -{ - if ((width > 0) && (height > 0)) { - switch (scan) { - case VIDEO_SCAN_INTERLACED: return cString::sprintf("%dx%d %s", width, height, tr("interlaced")); - case VIDEO_SCAN_PROGRESSIVE: return cString::sprintf("%dx%d %s", width, height, tr("progressive")); - default: return cString::sprintf("%dx%d", width, height); - } - } - return cString::sprintf("---"); -} - -cString getAspectRatio(int value) -{ - switch (value) { - case VIDEO_ASPECT_RATIO_RESERVED: return cString::sprintf("%s", tr("reserved")); - case VIDEO_ASPECT_RATIO_EXTENDED: return cString::sprintf("%s", tr("extended")); - case VIDEO_ASPECT_RATIO_1_1: return cString::sprintf("1:1"); - case VIDEO_ASPECT_RATIO_4_3: return cString::sprintf("4:3"); - case VIDEO_ASPECT_RATIO_16_9: return cString::sprintf("16:9"); - case VIDEO_ASPECT_RATIO_2_21_1: return cString::sprintf("2.21:1"); - case VIDEO_ASPECT_RATIO_12_11: return cString::sprintf("12:11"); - case VIDEO_ASPECT_RATIO_10_11: return cString::sprintf("10:11"); - case VIDEO_ASPECT_RATIO_16_11: return cString::sprintf("16:11"); - case VIDEO_ASPECT_RATIO_40_33: return cString::sprintf("40:33"); - case VIDEO_ASPECT_RATIO_24_11: return cString::sprintf("24:11"); - case VIDEO_ASPECT_RATIO_20_11: return cString::sprintf("20:11"); - case VIDEO_ASPECT_RATIO_32_11: return cString::sprintf("32:11"); - case VIDEO_ASPECT_RATIO_80_33: return cString::sprintf("80:33"); - case VIDEO_ASPECT_RATIO_18_11: return cString::sprintf("18:11"); - case VIDEO_ASPECT_RATIO_15_11: return cString::sprintf("15:11"); - case VIDEO_ASPECT_RATIO_64_33: return cString::sprintf("64:33"); - case VIDEO_ASPECT_RATIO_160_99: return cString::sprintf("160:99"); - case VIDEO_ASPECT_RATIO_3_2: return cString::sprintf("3:2"); - case VIDEO_ASPECT_RATIO_2_1: return cString::sprintf("2:1"); - default: break; - } - return cString::sprintf("---"); -} - -cString getVideoFormat(int value) -{ - switch (value) { - case VIDEO_FORMAT_UNKNOWN: return cString::sprintf("%s", tr("unknown")); - case VIDEO_FORMAT_RESERVED: return cString::sprintf("%s", tr("reserved")); - case VIDEO_FORMAT_COMPONENT: return cString::sprintf("%s", tr("component")); - case VIDEO_FORMAT_PAL: return cString::sprintf("%s", tr("PAL")); - case VIDEO_FORMAT_NTSC: return cString::sprintf("%s", tr("NTSC")); - case VIDEO_FORMAT_SECAM: return cString::sprintf("%s", tr("SECAM")); - case VIDEO_FORMAT_MAC: return cString::sprintf("%s", tr("MAC")); - default: break; - } - return cString::sprintf("---"); -} - -cString getFrameRate(double value) -{ - if (value > 0) - return cString::sprintf("%.2f %s", value, tr("Hz")); - return cString::sprintf("---"); -} - -cString getAC3BitStreamMode(int value, int coding) -{ - switch (value) { - case AUDIO_BITSTREAM_MODE_CM: return cString::sprintf("%s", tr("Complete Main (CM)")); - case AUDIO_BITSTREAM_MODE_ME: return cString::sprintf("%s", tr("Music and Effects (ME)")); - case AUDIO_BITSTREAM_MODE_VI: return cString::sprintf("%s", tr("Visually Impaired (VI)")); - case AUDIO_BITSTREAM_MODE_HI: return cString::sprintf("%s", tr("Hearing Impaired (HI)")); - case AUDIO_BITSTREAM_MODE_D: return cString::sprintf("%s", tr("Dialogue (D)")); - case AUDIO_BITSTREAM_MODE_C: return cString::sprintf("%s", tr("Commentary (C)")); - case AUDIO_BITSTREAM_MODE_E: return cString::sprintf("%s", tr("Emergency (E)")); - case AUDIO_BITSTREAM_MODE_VO_KAR: return cString::sprintf("%s", (coding == 1) ? tr("Voice Over (VO)") : tr("Karaoke")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAC3AudioCodingMode(int value, int stream) -{ - if (stream != 7) { - switch (value) { - case AUDIO_CODING_MODE_1_1: return cString::sprintf("1+1 - %s, %s", tr("Ch1"), tr("Ch2")); - case AUDIO_CODING_MODE_1_0: return cString::sprintf("1/0 - %s", tr("C")); - case AUDIO_CODING_MODE_2_0: return cString::sprintf("2/0 - %s, %s", tr("L"), tr("R")); - case AUDIO_CODING_MODE_3_0: return cString::sprintf("3/0 - %s, %s, %s", tr("L"), tr("C"), tr("R")); - case AUDIO_CODING_MODE_2_1: return cString::sprintf("2/1 - %s, %s, %s", tr("L"), tr("R"), tr("S")); - case AUDIO_CODING_MODE_3_1: return cString::sprintf("3/1 - %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("S")); - case AUDIO_CODING_MODE_2_2: return cString::sprintf("2/2 - %s, %s, %s, %s", tr("L"), tr("R"), tr("SL"), tr("SR")); - case AUDIO_CODING_MODE_3_2: return cString::sprintf("3/2 - %s, %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("SL"), tr("SR")); - default: break; - } - } - return cString::sprintf("---"); -} - -cString getAC3CenterMixLevel(int value) -{ - switch (value) { - case AUDIO_CENTER_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3.0 %s", tr("dB")); - case AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB: return cString::sprintf("-4.5 %s", tr("dB")); - case AUDIO_CENTER_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6.0 %s", tr("dB")); - case AUDIO_CENTER_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAC3SurroundMixLevel(int value) -{ - switch (value) { - case AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3 %s", tr("dB")); - case AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6 %s", tr("dB")); - case AUDIO_SURROUND_MIX_LEVEL_0_dB: return cString::sprintf("0 %s", tr("dB")); - case AUDIO_SURROUND_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAC3DolbySurroundMode(int value) -{ - switch (value) { - case AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED: return cString::sprintf("%s", tr("not indicated")); - case AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND: return cString::sprintf("%s", trVDR("no")); - case AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND: return cString::sprintf("%s", trVDR("yes")); - case AUDIO_DOLBY_SURROUND_MODE_RESERVED: return cString::sprintf("%s", tr("reserved")); - default: break; - } - return cString::sprintf("---"); -} - -cString getAC3DialogLevel(int value) -{ - if (value > 0) - return cString::sprintf("-%d %s", value, tr("dB")); - return cString::sprintf("---"); -} - -cString getFrequencyMHz(int value) -{ - double freq = value; - while (freq > 20000.0) freq /= 1000.0; - return cString::sprintf("%s %s", *dtoa(freq, "%lg"), tr("MHz")); -} - -cString getAudioSamplingFreq(int value) -{ - switch (value) { - case AUDIO_SAMPLING_FREQUENCY_INVALID: return cString::sprintf("---"); - case AUDIO_SAMPLING_FREQUENCY_RESERVED: return cString::sprintf("%s", tr("reserved")); - default: break; - } - return cString::sprintf("%d %s", value, tr("Hz")); -} - -cString getAudioBitrate(double value, double stream) -{ - switch ((int)stream) { - case AUDIO_BITRATE_INVALID: return cString::sprintf("---"); - case AUDIO_BITRATE_RESERVED: return cString::sprintf("%s (%s)", tr("reserved"), *getBitrateKbits(value)); - case AUDIO_BITRATE_FREE: return cString::sprintf("%s (%s)", tr("free"), *getBitrateKbits(value)); - default: break; - } - return cString::sprintf("%s (%s)", *getBitrateKbits(stream), *getBitrateKbits(value)); -} - -cString getVideoBitrate(double value, double stream) -{ - return cString::sprintf("%s (%s)", *getBitrateMbits(stream), *getBitrateMbits(value)); -} - -cString getBitrateMbits(double value) -{ - if (value > 0) - return cString::sprintf("%.2f %s", value / 1000000.0, tr("Mbit/s")); - return cString::sprintf("---"); -} - -cString getBitrateKbits(double value) -{ - if (value > 0) - return cString::sprintf("%.0f %s", value / 1000.0, tr("kbit/s")); - return cString::sprintf("---"); -} - -// --- cFemonBitStream ------------------------------------------------------- - -uint32_t cFemonBitStream::GetUeGolomb() -{ - int n = 0; - - while (!GetBit() && (n < 32)) - n++; - - return (n ? ((1 << n) - 1) + GetBits(n) : 0); -} - -int32_t cFemonBitStream::GetSeGolomb() -{ - uint32_t r = GetUeGolomb() + 1; - - return ((r & 1) ? -(r >> 1) : (r >> 1)); -} - -void cFemonBitStream::SkipGolomb() -{ - int n = 0; - - while (!GetBit() && (n < 32)) - n++; - - SkipBits(n); -} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femontools.h vdr-plugin-femon-2.2.1.git20150307.2205/femontools.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femontools.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femontools.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONTOOLS_H -#define __FEMONTOOLS_H - -#include -#include -#include -#include -#include - -#ifdef DEBUG -#define debug(x...) dsyslog("FEMON: " x); -#define error(x...) esyslog("ERROR: " x); -#else -#define debug(x...) ; -#define error(x...) esyslog("ERROR: " x); -#endif - -#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) - -#define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" - -#define SATIP_DEVICE "SAT>IP" - -cDvbDevice *getDvbDevice(cDevice* device); - -cString getFrontendInfo(cDvbDevice *device); -cString getFrontendName(cDvbDevice *device); -cString getFrontendStatus(cDvbDevice *device); - -uint16_t getSNR(cDvbDevice *device); -uint16_t getSignal(cDvbDevice *device); - -uint32_t getBER(cDvbDevice *device); -uint32_t getUNC(cDvbDevice *device); - -cString getApids(const cChannel *channel); -cString getDpids(const cChannel *channel); -cString getSpids(const cChannel *channel); -cString getCAids(const cChannel *channel); -cString getVideoStream(int value); -cString getVideoCodec(int value); -cString getAudioStream(int value, const cChannel *channel); -cString getAudioCodec(int value); -cString getAudioChannelMode(int value); -cString getCoderate(int value); -cString getTransmission(int value); -cString getBandwidth(int value); -cString getInversion(int value); -cString getHierarchy(int value); -cString getGuard(int value); -cString getModulation(int value); -cString getTerrestrialSystem(int value); -cString getSatelliteSystem(int value); -cString getRollOff(int value); -cString getPilot(int value); -cString getResolution(int width, int height, int scan); -cString getAspectRatio(int value); -cString getVideoFormat(int value); -cString getFrameRate(double value); -cString getAC3Stream(int value, const cChannel *channel); -cString getAC3BitStreamMode(int value, int coding); -cString getAC3AudioCodingMode(int value, int stream); -cString getAC3CenterMixLevel(int value); -cString getAC3SurroundMixLevel(int value); -cString getAC3DolbySurroundMode(int value); -cString getAC3DialogLevel(int value); -cString getFrequencyMHz(int value); -cString getAudioSamplingFreq(int value); -cString getAudioBitrate(double value, double stream); -cString getVideoBitrate(double value, double stream); -cString getBitrateMbits(double value); -cString getBitrateKbits(double value); - -class cFemonBitStream : public cBitStream { -public: - cFemonBitStream(const uint8_t *Data, const int Length) : cBitStream(Data, Length) {} - uint32_t GetUeGolomb(); - int32_t GetSeGolomb(); - void SkipGolomb(); - void SkipUeGolomb() { SkipGolomb(); } - void SkipSeGolomb() { SkipGolomb(); } - }; - -#endif // __FEMONTOOLS_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/femonvideo.h vdr-plugin-femon-2.2.1.git20150307.2205/femonvideo.h --- vdr-plugin-femon-2.2.0.git20150222.1714/femonvideo.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/femonvideo.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* - * Frontend Status Monitor plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - */ - -#ifndef __FEMONVIDEO_H -#define __FEMONVIDEO_H - -enum eVideoCodec { - VIDEO_CODEC_INVALID = -1, - VIDEO_CODEC_UNKNOWN, - VIDEO_CODEC_MPEG2, - VIDEO_CODEC_H264 - }; - -enum eVideoFormat { - VIDEO_FORMAT_INVALID = -1, - VIDEO_FORMAT_UNKNOWN, - VIDEO_FORMAT_RESERVED, - VIDEO_FORMAT_COMPONENT, - VIDEO_FORMAT_PAL, - VIDEO_FORMAT_NTSC, - VIDEO_FORMAT_SECAM, - VIDEO_FORMAT_MAC - }; - -enum eVideoScan { - VIDEO_SCAN_INVALID = -1, - VIDEO_SCAN_UNKNOWN, - VIDEO_SCAN_RESERVED, - VIDEO_SCAN_INTERLACED, - VIDEO_SCAN_PROGRESSIVE - }; - -enum eVideoAspectRatio { - VIDEO_ASPECT_RATIO_INVALID = -1, - VIDEO_ASPECT_RATIO_RESERVED, - VIDEO_ASPECT_RATIO_EXTENDED, - VIDEO_ASPECT_RATIO_1_1, - VIDEO_ASPECT_RATIO_4_3, - VIDEO_ASPECT_RATIO_16_9, - VIDEO_ASPECT_RATIO_2_21_1, - VIDEO_ASPECT_RATIO_12_11, - VIDEO_ASPECT_RATIO_10_11, - VIDEO_ASPECT_RATIO_16_11, - VIDEO_ASPECT_RATIO_40_33, - VIDEO_ASPECT_RATIO_24_11, - VIDEO_ASPECT_RATIO_20_11, - VIDEO_ASPECT_RATIO_32_11, - VIDEO_ASPECT_RATIO_80_33, - VIDEO_ASPECT_RATIO_18_11, - VIDEO_ASPECT_RATIO_15_11, - VIDEO_ASPECT_RATIO_64_33, - VIDEO_ASPECT_RATIO_160_99, - VIDEO_ASPECT_RATIO_3_2, - VIDEO_ASPECT_RATIO_2_1 - }; - -typedef struct video_info { - eVideoCodec codec; // enum - eVideoFormat format; // enum - eVideoScan scan; // enum - eVideoAspectRatio aspectRatio; // enum - int width; // pixels - int height; // pixels - double frameRate; // Hz - double bitrate; // bit/s -} video_info_t; - -class cFemonVideoIf { -public: - cFemonVideoIf() {} - virtual ~cFemonVideoIf() {} - - // eVideoCodec - virtual void SetVideoCodec(eVideoCodec codec) = 0; - // eVideoFormat - virtual void SetVideoFormat(eVideoFormat format) = 0; - // eVideoScan - virtual void SetVideoScan(eVideoScan scan) = 0; - // eVideoAspectRatio - virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) = 0; - // pixels - virtual void SetVideoSize(int width, int height) = 0; - // Hz - virtual void SetVideoFramerate(double framerate) = 0; - // Mbit/s - virtual void SetVideoBitrate(double bitrate) = 0; - }; - -#endif //__FEMONVIDEO_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/h264.c vdr-plugin-femon-2.2.1.git20150307.2205/h264.c --- vdr-plugin-femon-2.2.0.git20150222.1714/h264.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/h264.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,761 @@ +/* + * h264.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "log.h" +#include "tools.h" +#include "h264.h" + +const cFemonH264::t_DAR cFemonH264::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 cFemonH264::t_SAR cFemonH264::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 cFemonH264::videoFormatS[] = +{ + VIDEO_FORMAT_COMPONENT, + VIDEO_FORMAT_PAL, + VIDEO_FORMAT_NTSC, + VIDEO_FORMAT_SECAM, + VIDEO_FORMAT_MAC, + VIDEO_FORMAT_UNKNOWN, + VIDEO_FORMAT_RESERVED +}; + +const uint8_t cFemonH264::seiNumClockTsTableS[9] = +{ + 1, 1, 1, 2, 2, 3, 3, 2, 3 +}; + +cFemonH264::cFemonH264(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), + cpbDpbDelaysPresentFlagM(false), + picStructPresentFlagM(false), + frameMbsOnlyFlagM(false), + mbAdaptiveFrameFieldFlagM(false), + timeOffsetLengthM(0) +{ + reset(); +} + +cFemonH264::~cFemonH264() +{ +} + +bool cFemonH264::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] & 0x1F) { + case NAL_AUD: + if (!aud_found) { + switch (buf[4] >> 5) { + case 0: case 3: case 5: // I_FRAME + debug2("%s Found NAL AUD at offset %d/%d", __PRETTY_FUNCTION__, int(buf - start), lenP); + aud_found = true; + break; + case 1: case 4: case 6: // P_FRAME; + case 2: case 7: // B_FRAME; + default: // NO_PICTURE; + break; + } + } + 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 + 4, int(end - buf - 4)); + 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 + 4, int(end - buf - 4)); + 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_H264); + if (sps_found) { + debug2("%s width=%d height=%d, aspect=%d format=%d bitrate=%.0f", __PRETTY_FUNCTION__, widthM, heightM, aspectRatioM, formatM, bitRateM); + videoHandlerM->SetVideoFormat(formatM); + videoHandlerM->SetVideoSize(widthM, heightM); + videoHandlerM->SetVideoAspectRatio(aspectRatioM); + videoHandlerM->SetVideoBitrate(bitRateM); + } + if (sps_found || sei_found) { + debug2("%s scan=%d framerate=%.2f", __PRETTY_FUNCTION__, scanM, (scanM == VIDEO_SCAN_PROGRESSIVE) ? (frameRateM / 2) : frameRateM); + videoHandlerM->SetVideoScan(scanM); + videoHandlerM->SetVideoFramerate((scanM == VIDEO_SCAN_PROGRESSIVE) ? (frameRateM / 2) : frameRateM); + } + } + + return aud_found; +} + +void cFemonH264::reset() +{ + cpbDpbDelaysPresentFlagM = false; + picStructPresentFlagM = false; + frameMbsOnlyFlagM = false; + mbAdaptiveFrameFieldFlagM = false; + timeOffsetLengthM = 0; +} + +const uint8_t *cFemonH264::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 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; + } + } + dstP[d++] = srcP[s++]; + } + + return d; +} + +int cFemonH264::parseSPS(const uint8_t *bufP, int lenP) +{ + int profile_idc, level_idc, constraint_set3_flag, pic_order_cnt_type, i, j; + cFemonBitStream bs(bufP, lenP); + + uint32_t width = widthM; + uint32_t height = heightM; + eVideoAspectRatio aspect_ratio = aspectRatioM; + eVideoFormat format = formatM; + double frame_rate = frameRateM; + double bit_rate = bitRateM; + bool cpb_dpb_delays_present_flag = cpbDpbDelaysPresentFlagM; + bool pic_struct_present_flag = picStructPresentFlagM; + bool frame_mbs_only_flag = frameMbsOnlyFlagM; + bool mb_adaptive_frame_field_flag = mbAdaptiveFrameFieldFlagM; + uint32_t time_offset_length = timeOffsetLengthM; + + profile_idc = bs.GetBits(8); // profile_idc + bs.SkipBit(); // constraint_set0_flag + bs.SkipBit(); // constraint_set1_flag + bs.SkipBit(); // constraint_set2_flag + constraint_set3_flag = bs.GetBit(); // constraint_set3_flag + bs.SkipBits(4); // reserved_zero_4bits + level_idc = bs.GetBits(8); // level_idc + bs.SkipUeGolomb(); // seq_parameter_set_id + debug2("%s profile_idc=%d level_idc=%d", __PRETTY_FUNCTION__, profile_idc, level_idc); + switch (profile_idc) { + case 66: // baseline profile + case 77: // main profile + case 88: // extended profile + switch (level_idc) { + case 10: // level 1.0 + bit_rate = 64000; + break; + case 11: // level 1b / 1.1 + bit_rate = constraint_set3_flag ? 128000 : 192000; + break; + case 12: // level 1.2 + bit_rate = 384000; + break; + case 13: // level 1.3 + bit_rate = 768000; + break; + case 20: // level 2.0 + bit_rate = 2000000; + break; + case 21: // level 2.1 + bit_rate = 4000000; + break; + case 22: // level 2.2 + bit_rate = 4000000; + break; + case 30: // level 3.0 + bit_rate = 10000000; + break; + case 31: // level 3.1 + bit_rate = 14000000; + break; + case 32: // level 3.2 + bit_rate = 20000000; + break; + case 40: // level 4.0 + bit_rate = 20000000; + break; + case 41: // level 4.1 + bit_rate = 50000000; + break; + case 42: // level 4.2 + bit_rate = 50000000; + break; + case 50: // level 5.0 + bit_rate = 135000000; + break; + case 51: // level 5.1 + bit_rate = 240000000; + break; + default: + break; + } + break; + case 100: // high profile + switch (level_idc) { + case 10: // level 1.0 + bit_rate = 80000; + break; + case 11: // level 1b / 1.1 + bit_rate = constraint_set3_flag ? 160000 : 240000; + break; + case 12: // level 1.2 + bit_rate = 480000; + break; + case 13: // level 1.3 + bit_rate = 960000; + break; + case 20: // level 2.0 + bit_rate = 2500000; + break; + case 21: // level 2.1 + bit_rate = 5000000; + break; + case 22: // level 2.2 + bit_rate = 5000000; + break; + case 30: // level 3.0 + bit_rate = 12500000; + break; + case 31: // level 3.1 + bit_rate = 17500000; + break; + case 32: // level 3.2 + bit_rate = 25000000; + break; + case 40: // level 4.0 + bit_rate = 25000000; + break; + case 41: // level 4.1 + bit_rate = 62500000; + break; + case 42: // level 4.2 + bit_rate = 62500000; + break; + case 50: // level 5.0 + bit_rate = 168750000; + break; + case 51: // level 5.1 + bit_rate = 300000000; + break; + default: + break; + } + break; + case 110: // high 10 profile + switch (level_idc) { + case 10: // level 1.0 + bit_rate = 192000; + break; + case 11: // level 1b / 1.1 + bit_rate = constraint_set3_flag ? 384000 : 576000; + break; + case 12: // level 1.2 + bit_rate = 115200; + break; + case 13: // level 1.3 + bit_rate = 2304000; + break; + case 20: // level 2.0 + bit_rate = 6000000; + break; + case 21: // level 2.1 + bit_rate = 12000000; + break; + case 22: // level 2.2 + bit_rate = 12000000; + break; + case 30: // level 3.0 + bit_rate = 30000000; + break; + case 31: // level 3.1 + bit_rate = 42000000; + break; + case 32: // level 3.2 + bit_rate = 60000000; + break; + case 40: // level 4.0 + bit_rate = 60000000; + break; + case 41: // level 4.1 + bit_rate = 150000000; + break; + case 42: // level 4.2 + bit_rate = 150000000; + break; + case 50: // level 5.0 + bit_rate = 405000000; + break; + case 51: // level 5.1 + bit_rate = 720000000; + break; + default: + break; + } + break; + case 122: // high 4:2:2 profile + case 144: // high 4:4:4 profile + switch (level_idc) { + case 10: // level 1.0 + bit_rate = 256000; + break; + case 11: // level 1b / 1.1 + bit_rate = constraint_set3_flag ? 512000 : 768000; + break; + case 12: // level 1.2 + bit_rate = 1536000; + break; + case 13: // level 1.3 + bit_rate = 3072000; + break; + case 20: // level 2.0 + bit_rate = 8000000; + break; + case 21: // level 2.1 + bit_rate = 16000000; + break; + case 22: // level 2.2 + bit_rate = 16000000; + break; + case 30: // level 3.0 + bit_rate = 40000000; + break; + case 31: // level 3.1 + bit_rate = 56000000; + break; + case 32: // level 3.2 + bit_rate = 80000000; + break; + case 40: // level 4.0 + bit_rate = 80000000; + break; + case 41: // level 4.1 + bit_rate = 200000000; + break; + case 42: // level 4.2 + bit_rate = 200000000; + break; + case 50: // level 5.0 + bit_rate = 540000000; + break; + case 51: // level 5.1 + bit_rate = 960000000; + break; + default: + break; + } + break; + default: + break; + } + if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) { + if (bs.GetUeGolomb() == 3) // chroma_format_idc + bs.SkipBit(); // residual_colour_transform_flag + bs.SkipUeGolomb(); // bit_depth_luma_minus8 + bs.SkipUeGolomb(); // bit_depth_chroma_minus8 + bs.SkipBit(); // qpprime_y_zero_transform_bypass_flag + if (bs.GetBit()) { // seq_scaling_matrix_present_flag + for (i = 0; i < 8; ++i) { + if (bs.GetBit()) { // seq_scaling_list_present_flag[i] + int last = 8, next = 8, size = (i < 6) ? 16 : 64; + for (j = 0; j < size; ++j) { + if (next) + next = (last + bs.GetSeGolomb()) & 0xff; + last = next ?: last; + } + } + } + } + } + bs.SkipUeGolomb(); // log2_max_frame_num_minus4 + pic_order_cnt_type = bs.GetUeGolomb(); // pic_order_cnt_type + if (pic_order_cnt_type == 0) + bs.SkipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4 + else if (pic_order_cnt_type == 1) { + bs.SkipBit(); // delta_pic_order_always_zero + bs.SkipSeGolomb(); // offset_for_non_ref_pic + bs.SkipSeGolomb(); // offset_for_top_to_bottom_field + j = bs.GetUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle + for (i = 0; i < j; ++i) + bs.SkipSeGolomb(); // offset_for_ref_frame[i] + } + bs.SkipUeGolomb(); // num_ref_frames + bs.SkipBit(); // gaps_in_frame_num_value_allowed_flag + width = bs.GetUeGolomb() + 1; // pic_width_in_mbs_minus1 + height = bs.GetUeGolomb() + 1; // pic_height_in_mbs_minus1 + frame_mbs_only_flag = bs.GetBit(); // frame_mbs_only_flag + debug2("%s pic_width=%u", __PRETTY_FUNCTION__, width); + debug2("%s pic_height=%u", __PRETTY_FUNCTION__, height); + debug2("%s frame_mbs_only_flag=%d", __PRETTY_FUNCTION__, frame_mbs_only_flag); + width *= 16; + height *= 16 * (frame_mbs_only_flag ? 1 : 2); + if (!frame_mbs_only_flag) + mb_adaptive_frame_field_flag = bs.GetBit(); // mb_adaptive_frame_field_flag + bs.SkipBit(); // direct_8x8_inference_flag + if (bs.GetBit()) { // frame_cropping_flag + uint32_t crop_left, crop_right, crop_top, crop_bottom; + crop_left = bs.GetUeGolomb(); // frame_crop_left_offset + crop_right = bs.GetUeGolomb(); // frame_crop_rigth_offset + crop_top = bs.GetUeGolomb(); // frame_crop_top_offset + crop_bottom = bs.GetUeGolomb(); // frame_crop_bottom_offset + debug2("%s crop_left=%d crop_top=%d crop_right=%d crop_bottom=%d", __PRETTY_FUNCTION__, crop_left, crop_top, crop_right, crop_bottom); + width -= 2 * (crop_left + crop_right); + if (frame_mbs_only_flag) + height -= 2 * (crop_top + crop_bottom); + else + height -= 4 * (crop_top + crop_bottom); + } + // VUI parameters + if (bs.GetBit()) { // vui_parameters_present_flag + if (bs.GetBit()) { // aspect_ratio_info_present + uint32_t aspect_ratio_idc, sar_width = 0, sar_height = 0; + 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_approriate_flag + 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])) { + format = videoFormatS[video_format]; + debug2("%s video_format=%d", __PRETTY_FUNCTION__, 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_coefficients + } + } + if (bs.GetBit()) { // chroma_loc_info_present_flag + bs.SkipUeGolomb(); // chroma_sample_loc_type_top_field + bs.SkipUeGolomb(); // chroma_sample_loc_type_bottom_field + } + if (bs.GetBit()) { // timing_info_present_flag + uint32_t num_units_in_tick, time_scale; + num_units_in_tick = bs.GetBits(32); // num_units_in_tick + time_scale = bs.GetBits(32); // time_scale + if (num_units_in_tick > 0) + frame_rate = time_scale / num_units_in_tick; + bs.SkipBit(); // fixed_frame_rate_flag + } + int nal_hrd_parameters_present_flag = bs.GetBit(); // nal_hrd_parameters_present_flag + if (nal_hrd_parameters_present_flag) { + int cpb_cnt_minus1; + cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1 + bs.SkipBits(4); // bit_rate_scale + bs.SkipBits(4); // cpb_size_scale + for (int i = 0; i < cpb_cnt_minus1; ++i) { + bs.SkipUeGolomb(); // bit_rate_value_minus1[i] + bs.SkipUeGolomb(); // cpb_size_value_minus1[i] + bs.SkipBit(); // cbr_flag[i] + } + bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1 + bs.SkipBits(5); // cpb_removal_delay_length_minus1 + bs.SkipBits(5); // dpb_output_delay_length_minus1 + time_offset_length = bs.GetBits(5); // time_offset_length + } + int vlc_hrd_parameters_present_flag = bs.GetBit(); // vlc_hrd_parameters_present_flag + if (vlc_hrd_parameters_present_flag) { + int cpb_cnt_minus1; + cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1 + bs.SkipBits(4); // bit_rate_scale + bs.SkipBits(4); // cpb_size_scale + for (int i = 0; i < cpb_cnt_minus1; ++i) { + bs.SkipUeGolomb(); // bit_rate_value_minus1[i] + bs.SkipUeGolomb(); // cpb_size_value_minus1[i] + bs.SkipBit(); // cbr_flag[i] + } + bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1 + bs.SkipBits(5); // cpb_removal_delay_length_minus1 + bs.SkipBits(5); // dpb_output_delay_length_minus1 + time_offset_length = bs.GetBits(5);// time_offset_length + } + cpb_dpb_delays_present_flag = (nal_hrd_parameters_present_flag | vlc_hrd_parameters_present_flag); + if (cpb_dpb_delays_present_flag) + bs.SkipBit(); // low_delay_hrd_flag + pic_struct_present_flag = bs.GetBit(); // pic_struct_present_flag + if (bs.GetBit()) { // bitstream_restriction_flag + bs.SkipBit(); // motion_vectors_over_pic_boundaries_flag + bs.SkipUeGolomb(); // max_bytes_per_pic_denom + bs.SkipUeGolomb(); // max_bits_per_mb_denom + bs.SkipUeGolomb(); // log2_max_mv_length_horizontal + bs.SkipUeGolomb(); // log2_max_mv_length_vertical + bs.SkipUeGolomb(); // num_reorder_frames + bs.SkipUeGolomb(); // max_dec_frame_buffering + } + } + + widthM = width; + heightM = height; + aspectRatioM = aspect_ratio; + formatM = format; + scanM = frame_mbs_only_flag ? VIDEO_SCAN_PROGRESSIVE : VIDEO_SCAN_INTERLACED; + frameRateM = frame_rate; + bitRateM = bit_rate; + cpbDpbDelaysPresentFlagM = cpb_dpb_delays_present_flag; + picStructPresentFlagM = pic_struct_present_flag; + frameMbsOnlyFlagM = frame_mbs_only_flag; + mbAdaptiveFrameFieldFlagM = mb_adaptive_frame_field_flag; + timeOffsetLengthM = time_offset_length; + + return (bs.Index() / 8); +} + +int cFemonH264::parseSEI(const uint8_t *bufP, int lenP) +{ + int num_referenced_subseqs, i; + cFemonBitStream bs(bufP, lenP); + + eVideoScan scan = scanM; + + while ((bs.Index() * 8 + 16) < lenP) { // sei_message + int 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 + if (cpbDpbDelaysPresentFlagM) { // cpb_dpb_delays_present_flag + bs.SkipUeGolomb(); // cpb_removal_delay + bs.SkipUeGolomb(); // dpb_output_delay + } + 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])) + return 0; + if (frameMbsOnlyFlagM && !mbAdaptiveFrameFieldFlagM) + scan = VIDEO_SCAN_PROGRESSIVE; + else { + switch (pic_struct) { + case 0: // frame + case 7: // frame doubling + case 8: // frame tripling + scan = VIDEO_SCAN_PROGRESSIVE; + break; + case 1: // top + case 2: // bottom + case 3: // top bottom + case 4: // bottom top + case 5: // top bottom top + case 6: // bottom top bottom + scan = VIDEO_SCAN_INTERLACED; + break; + default: + scan = VIDEO_SCAN_RESERVED; + break; + } + } + debug2("%s pic_struct=%d scan_type=%d", __PRETTY_FUNCTION__, pic_struct, scan); + for (i = 0; i < seiNumClockTsTableS[pic_struct]; ++i) { + if (bs.GetBit()) { // clock_timestamp_flag[i] + int full_timestamp_flag; + ct_type |= (1 << bs.GetBits(2)); // ct_type + debug2("%s ct_type=%04X", __PRETTY_FUNCTION__, ct_type); + bs.SkipBit(); // nuit_field_based_flag + bs.SkipBits(5); // counting_type + full_timestamp_flag = bs.GetBit(); // full_timestamp_flag + bs.SkipBit(); // discontinuity_flag + bs.SkipBit(); // cnt_dropped_flag + bs.SkipBits(8); // n_frames + if (full_timestamp_flag) { + bs.SkipBits(6); // seconds_value + bs.SkipBits(6); // minutes_value + bs.SkipBits(5); // hours_value + } + else { + if (bs.GetBit()) { // seconds_flag + bs.SkipBits(6); // seconds_value + if (bs.GetBit()) { // minutes_flag + bs.SkipBits(6); // minutes_value + if (bs.GetBit()) // hours_flag + bs.SkipBits(5); // hours_value + } + } + } + if (timeOffsetLengthM > 0) + bs.SkipBits(timeOffsetLengthM); // time_offset + } + } + if (i > 0) + scan = (ct_type & (1 << 1)) ? VIDEO_SCAN_INTERLACED : VIDEO_SCAN_PROGRESSIVE; + } + break; + + case 12: // sub_seq_characteristics + bs.SkipUeGolomb(); // sub_seq_layer_num + bs.SkipUeGolomb(); // sub_seq_id + if (bs.GetBit()) // duration_flag + bs.SkipBits(32); // sub_seq_duration + if (bs.GetBit()) { // average_rate_flag + bs.SkipBit(); // accurate_statistics_flag + bs.SkipBits(16); // average_bit_rate (1000 bit/s) + bs.SkipBits(16); // average_frame_rate (frames per 256s) + } + num_referenced_subseqs = bs.GetUeGolomb(); // num_referenced_subseqs + for (i = 0; i < num_referenced_subseqs; ++i) { + bs.SkipUeGolomb(); // ref_sub_seq_layer_num + bs.SkipUeGolomb(); // ref_sub_seq_id + bs.GetBit(); // ref_sub_seq_direction + } + break; + + default: + bs.SkipBits(payloadSize * 8); + break; + } + + // force byte align + bs.ByteAlign(); + } + + scanM = scan; + + return (bs.Index() / 8); +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/h264.h vdr-plugin-femon-2.2.1.git20150307.2205/h264.h --- vdr-plugin-femon-2.2.0.git20150222.1714/h264.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/h264.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * h264.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_H264_H +#define __FEMON_H264_H + +#include "video.h" + +class cFemonH264 { +private: + enum { + NAL_SEI = 0x06, // Supplemental Enhancement Information + NAL_SPS = 0x07, // Sequence Parameter Set + NAL_AUD = 0x09, // Access Unit Delimiter + NAL_END_SEQ = 0x0A // End of Sequence + }; + + 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 cpbDpbDelaysPresentFlagM; + bool picStructPresentFlagM; + bool frameMbsOnlyFlagM; + bool mbAdaptiveFrameFieldFlagM; + uint32_t timeOffsetLengthM; + + 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[]; + static const uint8_t seiNumClockTsTableS[9]; + +public: + cFemonH264(cFemonVideoIf *videoHandlerP); + virtual ~cFemonH264(); + + bool processVideo(const uint8_t *bufP, int lenP); + }; + +#endif //__FEMON_H264_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/HISTORY vdr-plugin-femon-2.2.1.git20150307.2205/HISTORY --- vdr-plugin-femon-2.2.0.git20150222.1714/HISTORY 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/HISTORY 2015-03-07 22:05:34.000000000 +0000 @@ -519,3 +519,7 @@ - Updated CA definitions. - Fixed the SVDRP service IP menu item (Thanks to Toerless Eckert). - Fixed the detaching of receiver during a channel switch. + +2015-XX-XX: Version 2.2.1 + +- diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/latm.c vdr-plugin-femon-2.2.1.git20150307.2205/latm.c --- vdr-plugin-femon-2.2.0.git20150222.1714/latm.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/latm.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * latm.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "tools.h" +#include "latm.h" + +int cFemonLATM::bitrateS[3][16] = +{ + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III +}; + +int cFemonLATM::sampleRateS[4] = +{ + 22050, 24000, 16000, -1 +}; + +cFemonLATM::cFemonLATM(cFemonAudioIf *audioHandlerP) +: audioHandlerM(audioHandlerP) +{ +} + +cFemonLATM::~cFemonLATM() +{ +} + +bool cFemonLATM::processAudio(const uint8_t *bufP, int lenP) +{ + cFemonBitStream bs(bufP, lenP * 8); + + if (!audioHandlerM) + return false; + + // skip PES header + if (!PesLongEnough(lenP)) + return false; + bs.SkipBits(8 * PesPayloadOffset(bufP)); + + // MPEG audio detection + if (bs.GetBits(12) != 0x56E) // syncword + return false; + + audioHandlerM->SetAudioCodec(AUDIO_CODEC_LATM); + + if (bs.GetBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0 + return true; // @todo: lower sampling frequencies support + int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01 + bs.SkipBit(); // protection bit + int bit_rate_index = bs.GetBits(4); // bitrate index + int sampling_frequency = bs.GetBits(2); // sampling frequency + bs.SkipBit(); // padding bit + bs.SkipBit(); // private pid + int mode = bs.GetBits(2); // mode + + switch (mode) { + case 0: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); + break; + + case 1: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); + break; + + case 2: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); + break; + + case 3: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); + break; + + default: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); + break; + } + + if (layer == 3) { + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_FREE); + } + else { + switch (bit_rate_index) { + case 0: + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_FREE); + break; + + case 0xF: + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_RESERVED); + break; + + default: + audioHandlerM->SetAudioBitrate(1000 * bitrateS[layer][bit_rate_index]); + break; + } + } + + switch (sampling_frequency) { + case 3: + audioHandlerM->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); + break; + + default: + audioHandlerM->SetAudioSamplingFrequency(sampleRateS[sampling_frequency]); + break; + } + + return true; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/latm.h vdr-plugin-femon-2.2.1.git20150307.2205/latm.h --- vdr-plugin-femon-2.2.0.git20150222.1714/latm.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/latm.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * latm.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_LATM_H +#define __FEMON_LATM_H + +#include "audio.h" + +class cFemonLATM { +private: + cFemonAudioIf *audioHandlerM; + + static int bitrateS[3][16]; + static int sampleRateS[4]; + +public: + cFemonLATM(cFemonAudioIf *audioHandlerP); + virtual ~cFemonLATM(); + + bool processAudio(const uint8_t *bufP, int lenP); + }; + +#endif //__FEMON_LATM_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/log.h vdr-plugin-femon-2.2.1.git20150307.2205/log.h --- vdr-plugin-femon-2.2.0.git20150222.1714/log.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/log.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * log.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_LOG_H +#define __FEMON_LOG_H + +#include "config.h" + +#define error(x...) esyslog("FEMON-ERROR: " x) +#define info(x...) isyslog("FEMON: " x) +// 0x0001: Generic call stack +#define debug1(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug1) ? dsyslog("FEMON1: " x) : void() ) +// 0x0002: H.264 +#define debug2(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug2) ? dsyslog("FEMON2: " x) : void() ) +// 0x0004: TBD +#define debug3(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug3) ? dsyslog("FEMON3: " x) : void() ) +// 0x0008: TBD +#define debug4(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug4) ? dsyslog("FEMON4: " x) : void() ) +// 0x0010: TBD +#define debug5(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug5) ? dsyslog("FEMON5: " x) : void() ) +// 0x0020: TBD +#define debug6(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug6) ? dsyslog("FEMON6: " x) : void() ) +// 0x0040: TBD +#define debug7(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug7) ? dsyslog("FEMON7: " x) : void() ) +// 0x0080: TBD +#define debug8(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug8) ? dsyslog("FEMON8: " x) : void() ) +// 0x0100: TBD +#define debug9(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug9) ? dsyslog("FEMON9: " x) : void() ) +// 0x0200: TBD +#define debug10(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug10) ? dsyslog("FEMON10: " x) : void() ) +// 0x0400: TBD +#define debug11(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug11) ? dsyslog("FEMON11: " x) : void() ) +// 0x0800: TBD +#define debug12(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug12) ? dsyslog("FEMON12: " x) : void() ) +// 0x1000: TBD +#define debug13(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug13) ? dsyslog("FEMON13: " x) : void() ) +// 0x2000: TBD +#define debug14(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug14) ? dsyslog("FEMON14: " x) : void() ) +// 0x4000: TBD +#define debug15(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug15) ? dsyslog("FEMON15: " x) : void() ) +// 0x8000; Extra call stack +#define debug16(x...) void( FemonConfig.IsTraceMode(cFemonConfig::eTraceModeDebug16) ? dsyslog("FEMON16: " x) : void() ) + +#endif // __FEMON_LOG_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/Makefile vdr-plugin-femon-2.2.1.git20150307.2205/Makefile --- vdr-plugin-femon-2.2.0.git20150222.1714/Makefile 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/Makefile 2015-03-07 22:05:34.000000000 +0000 @@ -2,14 +2,6 @@ # Makefile for Frontend Status Monitor plugin # -# Debugging on/off - -#FEMON_DEBUG = 1 - -# Strip debug symbols? Set eg. to /bin/true if not - -STRIP = strip - # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. # By default the main source file also carries this name. @@ -35,6 +27,7 @@ export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) +STRIP ?= /bin/true ### The version number of VDR's plugin API: @@ -59,10 +52,6 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -ifdef FEMON_DEBUG -DEFINES += -DDEBUG -endif - ifneq ($(strip $(GITTAG)),) DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"' endif @@ -72,7 +61,7 @@ ### The object files (add further files here): -OBJS = $(PLUGIN).o femonosd.o femonreceiver.o femoncfg.o femontools.o femonmpeg.o femonac3.o femonaac.o femonlatm.o femonh264.o femonsymbol.o +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 ### The main target: @@ -122,9 +111,7 @@ $(SOFILE): $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ -ifndef FEMON_DEBUG @$(STRIP) $@ -endif install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/mpeg.c vdr-plugin-femon-2.2.1.git20150307.2205/mpeg.c --- vdr-plugin-femon-2.2.0.git20150222.1714/mpeg.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/mpeg.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,286 @@ +/* + * mpeg.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "tools.h" +#include "mpeg.h" + +#define IS_EXTENSION_START(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == 0xB5)) + +int cFemonMPEG::bitrateS[2][3][16] = +{ + { + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III + }, + { + {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1}, // MPEG-1 Layer I + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1}, // MPEG-1 Layer II + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1} // MPEG-1 Layer III + } +}; + +int cFemonMPEG::sampleRateS[2][4] = +{ + {22050, 24000, 16000, -1}, // MPEG-2 + {44100, 48000, 32000, -1} // MPEG-1 +}; + +eAudioCodec cFemonMPEG::formatS[2][4] = +{ + {AUDIO_CODEC_MPEG2_I, AUDIO_CODEC_MPEG2_II, AUDIO_CODEC_MPEG2_III, AUDIO_CODEC_UNKNOWN}, // MPEG-2 + {AUDIO_CODEC_MPEG1_I, AUDIO_CODEC_MPEG1_II, AUDIO_CODEC_MPEG1_III, AUDIO_CODEC_UNKNOWN} // MPEG-1 +}; + +cFemonMPEG::cFemonMPEG(cFemonVideoIf *videoHandlerP, cFemonAudioIf *audioHandlerP) +: videoHandlerM(videoHandlerP), + audioHandlerM(audioHandlerP) +{ +} + +cFemonMPEG::~cFemonMPEG() +{ +} + +bool cFemonMPEG::processAudio(const uint8_t *bufP, int lenP) +{ + cFemonBitStream bs(bufP, lenP * 8); + + if (!audioHandlerM) + return false; + + // skip PES header + if (!PesLongEnough(lenP)) + return false; + bs.SkipBits(8 * PesPayloadOffset(bufP)); + + // MPEG audio detection + if (bs.GetBits(12) != 0xFFF) // syncword + return false; + + int id = bs.GetBit(); // id: MPEG-2=0, MPEG-1=1 + int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01 + bs.SkipBit(); // protection bit + int bit_rate_index = bs.GetBits(4); // bitrate index + int sampling_frequency = bs.GetBits(2); // sampling frequency + bs.SkipBit(); // padding bit + bs.SkipBit(); // private pid + int mode = bs.GetBits(2); // mode + + audioHandlerM->SetAudioCodec(formatS[id][layer]); + + switch (mode) { + case 0: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO); + break; + + case 1: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO); + break; + + case 2: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL); + break; + + case 3: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE); + break; + + default: + audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID); + break; + } + + switch (bit_rate_index) { + case 0: + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_FREE); + break; + + case 0xF: + audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_RESERVED); + break; + + default: + audioHandlerM->SetAudioBitrate(1000 * bitrateS[id][layer][bit_rate_index]); + break; + } + + switch (sampling_frequency) { + case 3: + audioHandlerM->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED); + break; + + default: + audioHandlerM->SetAudioSamplingFrequency(sampleRateS[id][sampling_frequency]); + break; + } + + return true; +} + +bool cFemonMPEG::processVideo(const uint8_t *bufP, int lenP) +{ + cFemonBitStream bs(bufP, lenP * 8); + + if (!videoHandlerM) + return false; + + // skip PES header + if (!PesLongEnough(lenP)) + return false; + bs.SkipBits(8 * PesPayloadOffset(bufP)); + + // MPEG-2 video detection, search for start code + if (bs.GetBits(32) != 0x000001B3) // sequence header + return false; + + int scan = VIDEO_SCAN_UNKNOWN; + int format = VIDEO_FORMAT_UNKNOWN; + int aspect = VIDEO_ASPECT_RATIO_RESERVED; + + int horizontal_size = bs.GetBits(12); // horizontal size value + int vertical_size = bs.GetBits(12); // vertical size value + + switch (bs.GetBits(4)) { // aspect ratio information + case 1: + aspect = VIDEO_ASPECT_RATIO_1_1; + break; + + case 2: + aspect = VIDEO_ASPECT_RATIO_4_3; + break; + + case 3: + aspect = VIDEO_ASPECT_RATIO_16_9; + break; + + case 4: + aspect = VIDEO_ASPECT_RATIO_2_21_1; + break; + + case 5 ... 15: + default: + aspect = VIDEO_ASPECT_RATIO_RESERVED; + break; + } + + double frame_rate = 0; + switch (bs.GetBits(4)) { // frame rate code + case 1: + frame_rate = 24000 / 1001.0; + format = VIDEO_FORMAT_UNKNOWN; + break; + + case 2: + frame_rate = 24.0; + format = VIDEO_FORMAT_UNKNOWN; + break; + + case 3: + frame_rate = 25.0; + format = VIDEO_FORMAT_PAL; + break; + + case 4: + frame_rate = 30000 / 1001.0; + format = VIDEO_FORMAT_NTSC; + break; + + case 5: + frame_rate = 30.0; + format = VIDEO_FORMAT_NTSC; + break; + + case 6: + frame_rate = 50.0; + format = VIDEO_FORMAT_PAL; + break; + + case 7: + frame_rate = 60.0; + format = VIDEO_FORMAT_NTSC; + break; + + case 8: + frame_rate = 60000 / 1001.0; + format = VIDEO_FORMAT_NTSC; + break; + + case 9 ... 15: + default: + frame_rate = 0; + format = VIDEO_FORMAT_UNKNOWN; + break; + } + + int bit_rate = bs.GetBits(18); // bit rate value + + bs.SkipBit(); // marker bit + bs.SkipBits(10); // vbv buffer size value + bs.SkipBit(); // constrained parameters value + if (bs.GetBit()) // load intra quantizer matrix + bs.SkipBits(8 * 64); // intra quantizer matrix + if (bs.GetBit()) // load non-intra quantizer matrix + bs.SkipBits(8 * 64); // non-intra quantizer matrix + + if (bs.GetBits(32) != 0x000001B5) { // extension start + bs.SkipBits(4); // extension start code identifier + bs.SkipBits(8); // profile and level indicator + scan = bs.GetBit() ? VIDEO_SCAN_PROGRESSIVE : + VIDEO_SCAN_INTERLACED; // progressive sequence + bs.SkipBits(2); // chroma format + horizontal_size |= (bs.GetBits(2) << 12); // horizontal size extension + vertical_size |= (bs.GetBits(2) << 12); // vertical size extension + bit_rate |= (bs.GetBits(12) << 18); // bit rate extension + bs.SkipBit(); // marker bit + bs.SkipBits(8); // vpv buffer size extension + bs.SkipBit(); // low delay + bs.SkipBits(2); // frame rate extension n + bs.SkipBits(5); // frame rate extension d + + if ((bs.GetBits(32) != 0x000001B5) && // extension start code + (bs.GetBits(4) == 0x0010)) { // sequence display extension id + switch (bs.GetBits(3)) { // video format + case 0x000: + format = VIDEO_FORMAT_COMPONENT; + break; + case 0x001: + format = VIDEO_FORMAT_PAL; + break; + case 0x010: + format = VIDEO_FORMAT_NTSC; + break; + case 0x011: + format = VIDEO_FORMAT_SECAM; + break; + case 0x100: + format = VIDEO_FORMAT_MAC; + break; + case 0x101: + format = VIDEO_FORMAT_UNKNOWN; + break; + case 0x110: + case 0x111: + format = VIDEO_FORMAT_RESERVED; + break; + default: + format = VIDEO_FORMAT_INVALID; + break; + } + } + } + + videoHandlerM->SetVideoCodec(VIDEO_CODEC_MPEG2); + videoHandlerM->SetVideoSize(horizontal_size, vertical_size); + videoHandlerM->SetVideoBitrate(400.0 * (double)(bit_rate)); + videoHandlerM->SetVideoFramerate(frame_rate); + videoHandlerM->SetVideoScan(eVideoScan(scan)); + videoHandlerM->SetVideoAspectRatio(eVideoAspectRatio(aspect)); + videoHandlerM->SetVideoFormat(eVideoFormat(format)); + + return true; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/mpeg.h vdr-plugin-femon-2.2.1.git20150307.2205/mpeg.h --- vdr-plugin-femon-2.2.0.git20150222.1714/mpeg.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/mpeg.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * mpeg.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_MPEG_H +#define __FEMON_MPEG_H + +#include "video.h" +#include "audio.h" + +class cFemonMPEG { +private: + cFemonVideoIf *videoHandlerM; + cFemonAudioIf *audioHandlerM; + + static int bitrateS[2][3][16]; + static int sampleRateS[2][4]; + static eAudioCodec formatS[2][4]; + +public: + cFemonMPEG(cFemonVideoIf *videoHandlerP, cFemonAudioIf *audioHandlerP); + virtual ~cFemonMPEG(); + + bool processVideo(const uint8_t *bufP, int lenP); + bool processAudio(const uint8_t *bufP, int lenP); + }; + +#endif //__FEMON_MPEG_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/osd.c vdr-plugin-femon-2.2.1.git20150307.2205/osd.c --- vdr-plugin-femon-2.2.0.git20150222.1714/osd.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/osd.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,1153 @@ +/* + * osd.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include +#include + +#include "config.h" +#include "iptvservice.h" +#include "log.h" +#include "receiver.h" +#include "symbol.h" +#include "tools.h" +#include "osd.h" + +#define CHANNELINPUT_TIMEOUT 1000 +#define SVDRPPLUGIN "svdrpservice" + +#define OSDWIDTH osdWidthM // in pixels +#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 OSDSYMBOL(id) femonSymbols.Get(id) +#define OSDSPACING femonSymbols.GetSpacing() +#define OSDROUNDING femonSymbols.GetRounding() +#define IS_OSDROUNDING (FemonConfig.GetSkin() == eFemonSkinElchi) +#define IS_OSDRESOLUTION(r1, r2) (abs(r1 - r2) < 20) +#define OSDINFOWIN_Y(offset) (FemonConfig.GetPosition() ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset) +#define OSDINFOWIN_X(col) ((col == 4) ? int(round(OSDWIDTH * 0.76)) : \ + (col == 3) ? int(round(OSDWIDTH * 0.51)) : \ + (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)) : \ + int(round(OSDWIDTH * 0.025))) +#define OSDSTATUSWIN_XSYMBOL(c,w) (c * ((OSDWIDTH - (5 * w)) / 6) + ((c - 1) * w)) +#define OSDBARWIDTH(x) (OSDWIDTH * x / 100) + +#define OSDDRAWSTATUSBM(spacing) \ + if (bm) { \ + x -= bm->Width() + spacing; \ + y = (OSDROWHEIGHT - bm->Height()) / 2; \ + if (y < 0) y = 0; \ + osdM->DrawBitmap(x, OSDSTATUSWIN_Y(offset) + y, *bm, FemonTheme[FemonConfig.GetTheme()].clrTitleText, FemonTheme[FemonConfig.GetTheme()].clrTitleBackground); \ + } + +#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) \ + 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) + +#define OSDDRAWSTATUSBAR(value) \ + if (value > 0) { \ + int barvalue = OSDBARWIDTH(value); \ + osdM->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(FemonConfig.GetRedLimit()), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, FemonTheme[FemonConfig.GetTheme()].clrRed); \ + if (barvalue > OSDBARWIDTH(FemonConfig.GetRedLimit())) \ + osdM->DrawRectangle(OSDBARWIDTH(FemonConfig.GetRedLimit()), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * FemonConfig.GetGreenLimit() / 100), barvalue), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, FemonTheme[FemonConfig.GetTheme()].clrYellow); \ + if (barvalue > OSDBARWIDTH(FemonConfig.GetGreenLimit())) \ + osdM->DrawRectangle(OSDBARWIDTH(FemonConfig.GetGreenLimit()), OSDSTATUSWIN_Y(offset) + 3, barvalue, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, FemonTheme[FemonConfig.GetTheme()].clrGreen); \ + } + +#define OSDDRAWSTATUSTITLEBAR(title) \ + osdM->DrawRectangle(0, OSDSTATUSWIN_Y(offset), OSDWIDTH, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].clrTitleBackground); \ + osdM->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), title, FemonTheme[FemonConfig.GetTheme()].clrTitleText, FemonTheme[FemonConfig.GetTheme()].clrTitleBackground, fontM); \ + if (IS_OSDROUNDING) { \ + osdM->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDROUNDING, OSDSTATUSWIN_Y(OSDROUNDING), clrTransparent, -2); \ + osdM->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDROUNDING), clrTransparent, -1); \ + } \ + osdM->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT, OSDWIDTH, OSDSTATUSWIN_Y(offset) + OSDSTATUSHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].clrBackground) + +#define OSDDRAWSTATUSBOTTOMBAR() \ + if (IS_OSDROUNDING) { \ + osdM->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - OSDROUNDING, OSDROUNDING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); \ + osdM->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - OSDROUNDING, OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -4); \ + } + +#define OSDCLEARSTATUS() \ + osdM->DrawRectangle(0, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - 1, clrTransparent) + +#define OSDDRAWINFOLEFT(label, value) \ + osdM->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \ + osdM->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), value, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM) + +#define OSDDRAWINFORIGHT(label, value) \ + osdM->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), label, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \ + osdM->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), value, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM) + +#define OSDDRAWINFOACTIVE(label, value) \ + osdM->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \ + osdM->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM) + +#define OSDDRAWINFOINACTIVE(label, value) \ + osdM->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, FemonTheme[FemonConfig.GetTheme()].clrInactiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM); \ + osdM->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM) + +#define OSDDRAWINFOLINE(label) \ + osdM->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, FemonTheme[FemonConfig.GetTheme()].clrActiveText, FemonTheme[FemonConfig.GetTheme()].clrBackground, fontM) + +#define OSDDRAWINFOTITLEBAR(title) \ + osdM->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset) + OSDROWHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].clrTitleBackground); \ + osdM->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), title, FemonTheme[FemonConfig.GetTheme()].clrTitleText, FemonTheme[FemonConfig.GetTheme()].clrTitleBackground, fontM); \ + if (IS_OSDROUNDING) { \ + osdM->DrawEllipse(0, OSDINFOWIN_Y(0), OSDROUNDING, OSDINFOWIN_Y(OSDROUNDING), clrTransparent, -2); \ + osdM->DrawEllipse(OSDWIDTH - OSDROUNDING, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDROUNDING), clrTransparent, -1); \ + } \ + osdM->DrawRectangle(0, OSDINFOWIN_Y(offset) + OSDROWHEIGHT, OSDWIDTH, OSDINFOWIN_Y(offset) + OSDINFOHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].clrBackground) + +#define OSDDRAWINFOBOTTOMBAR() \ + if (IS_OSDROUNDING) { \ + osdM->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDROUNDING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); \ + osdM->DrawEllipse((OSDWIDTH - OSDROUNDING), OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); \ + } + +#define OSDCLEARINFO() \ + osdM->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT) - 1, clrTransparent) + +#ifndef MINFONTSIZE +#define MINFONTSIZE 10 +#endif + +#ifndef MAXFONTSIZE +#define MAXFONTSIZE 64 +#endif + +class cFemonDummyFont : public cFont { +public: + virtual int Width(uint cP) const { return 10; } + virtual int Width(const char *sP) const { return 50; } + virtual int Height(void) const { return 20; } + virtual void DrawText(cBitmap *bitmapP, int xP, int yP, const char *sP, tColor colorFgP, tColor colorBgP, int widthP) const {} + virtual void DrawText(cPixmap *pixmapP, int xP, int yP, const char *sP, tColor colorFgP, tColor colorBgP, int widthP) const {} +}; + +cFemonOsd *cFemonOsd::pInstanceS = NULL; + +cFemonOsd *cFemonOsd::Instance(bool createP) +{ + debug1("%s (%d)", __PRETTY_FUNCTION__, createP); + if ((pInstanceS == NULL) && createP) + { + pInstanceS = new cFemonOsd(); + } + return (pInstanceS); +} + +cFemonOsd::cFemonOsd() +: cOsdObject(true), cThread("femon osd"), + osdM(NULL), + receiverM(NULL), + frontendM(-1), + svdrpFrontendM(-1), + svdrpVideoBitRateM(-1), + svdrpAudioBitRateM(-1), + svdrpPluginM(NULL), + numberM(0), + oldNumberM(0), + qualityM(0), + qualityValidM(false), + strengthM(0), + strengthValidM(false), + snrM(0), + snrValidM(false), + signalM(0), + signalValidM(false), + berM(0), + berValidM(false), + uncM(0), + uncValidM(false), + frontendNameM(""), + frontendStatusValidM(false), + deviceSourceM(DEVICESOURCE_DVBAPI), + displayModeM(FemonConfig.GetDisplayMode()), + osdWidthM(cOsd::OsdWidth() * (100 - FemonConfig.GetDownscale()) / 100), + osdHeightM(cOsd::OsdHeight() * (100 - FemonConfig.GetDownscale()) / 100), + osdLeftM(cOsd::OsdLeft() + (cOsd::OsdWidth() * FemonConfig.GetDownscale() / 200)), + osdTopM(cOsd::OsdTop() + (cOsd::OsdHeight() * FemonConfig.GetDownscale() / 200)), + inputTimeM(0), + sleepM(), + mutexM() +{ + 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)); + if (!fontM || !fontM->Height()) { + fontM = new cFemonDummyFont; + error("%s Cannot create required font", __PRETTY_FUNCTION__); + } + tmp = 5 * OSDSYMBOL(SYMBOL_LOCK).Width() + 6 * OSDSPACING; + if (OSDWIDTH < tmp) { + error("%s OSD width (%d) smaller than required (%d).", __PRETTY_FUNCTION__, OSDWIDTH, tmp); + OSDWIDTH = tmp; + } + tmp = OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT; + if (OSDHEIGHT < tmp) { + error("%s OSD height (%d) smaller than required (%d).", __PRETTY_FUNCTION__, OSDHEIGHT, tmp); + OSDHEIGHT = tmp; + } +} + +cFemonOsd::~cFemonOsd(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + sleepM.Signal(); + if (Running()) + Cancel(3); + if (svdrpConnectionM.handle >= 0) { + svdrpPluginM = cPluginManager::GetPlugin(SVDRPPLUGIN); + if (svdrpPluginM) + svdrpPluginM->Service("SvdrpConnection-v1.0", &svdrpConnectionM); + } + if (receiverM) { + receiverM->Deactivate(); + DELETENULL(receiverM); + } + if (osdM) + 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()); + + if (osdM && channel) { + cBitmap *bm = NULL; + int offset = 0; + int x = OSDWIDTH - OSDROUNDING; + int y = 0; + eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); + + OSDDRAWSTATUSTITLEBAR(*cString::sprintf("%d%s %s", numberM ? numberM : channel->Number(), numberM ? "-" : "", channel->ShortName(true))); + if (svdrpFrontendM >= 0) { + bm = &OSDSYMBOL(SYMBOL_SVDRP); + OSDDRAWSTATUSBM(OSDSPACING); + } + switch (cDevice::ActualDevice()->CardIndex()) { + case 1: bm = &OSDSYMBOL(SYMBOL_ONE); break; + case 2: bm = &OSDSYMBOL(SYMBOL_TWO); break; + case 3: bm = &OSDSYMBOL(SYMBOL_THREE); break; + case 4: bm = &OSDSYMBOL(SYMBOL_FOUR); break; + case 5: bm = &OSDSYMBOL(SYMBOL_FIVE); break; + case 6: bm = &OSDSYMBOL(SYMBOL_SIX); break; + case 7: bm = &OSDSYMBOL(SYMBOL_SEVEN); break; + case 8: bm = &OSDSYMBOL(SYMBOL_EIGHT); break; + default: bm = &OSDSYMBOL(SYMBOL_ZERO); break; + } + OSDDRAWSTATUSBM(OSDSPACING); + bm = &OSDSYMBOL(SYMBOL_DEVICE); + OSDDRAWSTATUSBM(0); + if (IS_AUDIO_TRACK(track)) { + switch (int(track - ttAudioFirst)) { + case 1: bm = &OSDSYMBOL(SYMBOL_ONE); break; + case 2: bm = &OSDSYMBOL(SYMBOL_TWO); break; + case 3: bm = &OSDSYMBOL(SYMBOL_THREE); break; + case 4: bm = &OSDSYMBOL(SYMBOL_FOUR); break; + case 5: bm = &OSDSYMBOL(SYMBOL_FIVE); break; + case 6: bm = &OSDSYMBOL(SYMBOL_SIX); break; + case 7: bm = &OSDSYMBOL(SYMBOL_SEVEN); break; + case 8: bm = &OSDSYMBOL(SYMBOL_EIGHT); break; + default: bm = &OSDSYMBOL(SYMBOL_ZERO); break; + } + OSDDRAWSTATUSBM(OSDSPACING); + switch (cDevice::PrimaryDevice()->GetAudioChannel()) { + case 1: bm = &OSDSYMBOL(SYMBOL_MONO_LEFT); break; + case 2: bm = &OSDSYMBOL(SYMBOL_MONO_RIGHT); break; + default: bm = &OSDSYMBOL(SYMBOL_STEREO); break; + } + OSDDRAWSTATUSBM(0); + } + else if (receiverM && receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) { + if (receiverM->AC3_5_1()) bm = &OSDSYMBOL(SYMBOL_DD51); + else if (receiverM->AC3_2_0()) bm = &OSDSYMBOL(SYMBOL_DD20); + else bm = &OSDSYMBOL(SYMBOL_DD); + OSDDRAWSTATUSBM(OSDSPACING); + } + if (receiverM) { + 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; + default: bm = &OSDSYMBOL(SYMBOL_FORMAT_1080); break; + } + } + else if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 720)) { + switch (receiverM->VideoScan()) { + case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_720i); break; + case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_720p); break; + default: bm = &OSDSYMBOL(SYMBOL_FORMAT_720); break; + } + } + else if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 576)) { + switch (receiverM->VideoScan()) { + case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_576i); break; + case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_576p); break; + default: bm = &OSDSYMBOL(SYMBOL_FORMAT_576); break; + } + } + else if (IS_OSDRESOLUTION(receiverM->VideoVerticalSize(), 480)) { + switch (receiverM->VideoScan()) { + case VIDEO_SCAN_INTERLACED: bm = &OSDSYMBOL(SYMBOL_FORMAT_480i); break; + case VIDEO_SCAN_PROGRESSIVE: bm = &OSDSYMBOL(SYMBOL_FORMAT_480p); break; + default: bm = &OSDSYMBOL(SYMBOL_FORMAT_480); break; + } + } + else + bm = NULL; + OSDDRAWSTATUSBM(OSDSPACING); + switch (receiverM->VideoCodec()) { + case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break; + case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break; + default: bm = NULL; break; + } + OSDDRAWSTATUSBM(OSDSPACING); + switch (receiverM->VideoFormat()) { + case VIDEO_FORMAT_PAL: bm = &OSDSYMBOL(SYMBOL_PAL); break; + case VIDEO_FORMAT_NTSC: bm = &OSDSYMBOL(SYMBOL_NTSC); break; + default: bm = NULL; break; + } + OSDDRAWSTATUSBM(OSDSPACING); + switch (receiverM->VideoAspectRatio()) { + case VIDEO_ASPECT_RATIO_1_1: bm = &OSDSYMBOL(SYMBOL_AR_1_1); break; + case VIDEO_ASPECT_RATIO_4_3: bm = &OSDSYMBOL(SYMBOL_AR_4_3); break; + case VIDEO_ASPECT_RATIO_16_9: bm = &OSDSYMBOL(SYMBOL_AR_16_9); break; + case VIDEO_ASPECT_RATIO_2_21_1: bm = &OSDSYMBOL(SYMBOL_AR_2_21_1); break; + default: bm = NULL; break; + } + OSDDRAWSTATUSBM(OSDSPACING); + } + if (channel->Ca() > 0xFF) { + bm = &OSDSYMBOL(SYMBOL_ENCRYPTED); + OSDDRAWSTATUSBM(OSDSPACING); + } + offset += OSDROWHEIGHT; + if (strengthValidM) + OSDDRAWSTATUSBAR(strengthM); + offset += OSDROWHEIGHT; + 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))); + 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); + } + OSDDRAWSTATUSBOTTOMBAR(); + osdM->Flush(); + } +} + +void cFemonOsd::DrawInfoWindow(void) +{ + cMutexLock lock(&mutexM); + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + + if (osdM && channel) { + int offset = 0; + eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); + + switch (displayModeM) { + case eFemonModeTransponder: + OSDDRAWINFOTITLEBAR(tr("Transponder Information")); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Vpid"), *cString::sprintf("%d", channel->Vpid())); + OSDDRAWINFORIGHT(trVDR("Ppid"), *cString::sprintf("%d", channel->Ppid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Apid"), *getApids(channel)); + OSDDRAWINFORIGHT( tr("Dpid"), *getDpids(channel)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Spid"), *getSpids(channel)); + OSDDRAWINFORIGHT(trVDR("Tpid"), *cString::sprintf("%d", channel->Tpid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Sid"), *cString::sprintf("%d", channel->Sid())); + OSDDRAWINFORIGHT( tr("Nid"), *cString::sprintf("%d", channel->Nid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Tid"), *cString::sprintf("%d", channel->Tid())); + OSDDRAWINFORIGHT( tr("Rid"), *cString::sprintf("%d", channel->Rid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("CA"), *getCAids(channel)); + offset += OSDROWHEIGHT; + switch (channel->Source() & cSource::st_Mask) { + case cSource::stSat: { + cDvbTransponderParameters dtp(channel->Parameters()); + OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", *getSatelliteSystem(dtp.System()), (svdrpFrontendM >= 0) ? svdrpFrontendM : cDevice::ActualDevice()->CardIndex(), *frontendNameM)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); + OSDDRAWINFORIGHT(trVDR("Polarization"), *cString::sprintf("%c", toupper(dtp.Polarization()))); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); + OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("System"), *getSatelliteSystem(dtp.System())); + if (dtp.System()) { + OSDDRAWINFORIGHT(trVDR("RollOff"), *getRollOff(dtp.RollOff())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Pilot"), *getPilot(dtp.Pilot())); + } + } + break; + + case cSource::stCable: { + cDvbTransponderParameters dtp(channel->Parameters()); + OSDDRAWINFOLINE(*cString::sprintf("DVB-C #%d - %s", (svdrpFrontendM >= 0) ? svdrpFrontendM : cDevice::ActualDevice()->CardIndex(), *frontendNameM)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); + OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); + OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(dtp.CoderateH())); + } + break; + + case cSource::stTerr: { + cDvbTransponderParameters dtp(channel->Parameters()); + OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", *getTerrestrialSystem(dtp.System()), (svdrpFrontendM >= 0) ? svdrpFrontendM : cDevice::ActualDevice()->CardIndex(), *frontendNameM)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Transmission"), *getTransmission(dtp.Transmission())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Bandwidth"), *getBandwidth(dtp.Bandwidth())); + OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(dtp.Modulation())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(dtp.Inversion())); + OSDDRAWINFORIGHT(tr ("Coderate"), *cString::sprintf("%s (H) %s (L)", *getCoderate(dtp.CoderateH()), *getCoderate(dtp.CoderateL()))); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Hierarchy"), *getHierarchy(dtp.Hierarchy())); + OSDDRAWINFORIGHT(trVDR("Guard"), *getGuard(dtp.Guard())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("System"), *getTerrestrialSystem(dtp.System())); + if (dtp.System()) { + OSDDRAWINFORIGHT(trVDR("StreamId"), *cString::sprintf("%d", dtp.StreamId())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("T2SystemId"),*cString::sprintf("%d", dtp.T2SystemId())); + OSDDRAWINFORIGHT(trVDR("SISO/MISO"), *cString::sprintf("%d", dtp.SisoMiso())); + } + } + break; + + case stIptv: { + OSDDRAWINFOLINE(*cString::sprintf("IPTV #%d - %s", (svdrpFrontendM >= 0) ? svdrpFrontendM : cDevice::ActualDevice()->CardIndex(), *frontendNameM)); + offset += OSDROWHEIGHT; + if (svdrpFrontendM < 0) { + cPlugin *p; + IptvService_v1_0 data; + data.cardIndex = cDevice::ActualDevice()->CardIndex(); + p = cPluginManager::CallFirstService("IptvService-v1.0", &data); + if (p) { + OSDDRAWINFOLEFT(tr("Protocol"), *data.protocol); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT(tr("Bitrate"), *data.bitrate); + } + } + } + break; + + default: + break; + } + OSDDRAWINFOBOTTOMBAR(); + break; + + case eFemonModeStream: + OSDDRAWINFOTITLEBAR(tr("Stream Information")); + offset += OSDROWHEIGHT; + OSDDRAWINFOACTIVE( tr("Video Stream"), *getVideoStream(channel->Vpid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Codec"), *getVideoCodec(receiverM ? receiverM->VideoCodec() : VIDEO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getVideoBitrate(receiverM ? receiverM->VideoBitrate() : 0, receiverM ? receiverM->VideoStreamBitrate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Aspect Ratio"), *getAspectRatio(receiverM ? receiverM->VideoAspectRatio() : VIDEO_ASPECT_RATIO_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Frame Rate"), *getFrameRate(receiverM ? receiverM->VideoFrameRate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Video Format"), *getVideoFormat(receiverM ? receiverM->VideoFormat() : VIDEO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Resolution"), *getResolution(receiverM ? receiverM->VideoHorizontalSize() : 0, receiverM ? receiverM->VideoVerticalSize() : 0, receiverM ? receiverM->VideoScan() : VIDEO_SCAN_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOACTIVE( tr("Audio Stream"), *getAudioStream(track, channel)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Codec"), *getAudioCodec(receiverM ? receiverM->AudioCodec() : AUDIO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Channel Mode"), *getAudioChannelMode(receiverM ? receiverM->AudioChannelMode() : AUDIO_CHANNEL_MODE_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(receiverM ? receiverM->AudioBitrate() : 0, receiverM ? receiverM->AudioStreamBitrate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(receiverM ? receiverM->AudioSamplingFreq() : AUDIO_SAMPLING_FREQUENCY_INVALID)); + OSDDRAWINFOBOTTOMBAR(); + break; + + case eFemonModeAC3: + OSDDRAWINFOTITLEBAR(tr("Stream Information")); + if (receiverM && receiverM->AC3Valid() && IS_DOLBY_TRACK(track)) { + offset += OSDROWHEIGHT; + OSDDRAWINFOACTIVE( tr("AC-3 Stream"), *getAC3Stream(track, channel)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(receiverM->AC3Bitrate(), receiverM->AC3StreamBitrate())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(receiverM->AC3SamplingFreq())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bit Stream Mode"), *getAC3BitStreamMode(receiverM->AC3BitStreamMode(), receiverM->AC3AudioCodingMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Audio Coding Mode"), *getAC3AudioCodingMode(receiverM->AC3AudioCodingMode(), receiverM->AC3BitStreamMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Center Mix Level"), *getAC3CenterMixLevel(receiverM->AC3CenterMixLevel())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Surround Mix Level"), *getAC3SurroundMixLevel(receiverM->AC3SurroundMixLevel())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Dolby Surround Mode"), *getAC3DolbySurroundMode(receiverM->AC3DolbySurroundMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Low Frequency Effects"), *cString::sprintf("%s", receiverM->AC3Lfe() ? trVDR("on") : trVDR("off"))); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Dialogue Normalization"), *getAC3DialogLevel(receiverM->AC3DialogLevel())); + } + OSDDRAWINFOBOTTOMBAR(); + break; + + default: + OSDCLEARINFO(); + break; + } + osdM->Flush(); + } +} + +void cFemonOsd::Action(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + cTimeMs t; + SvdrpCommand_v1_0 cmd; + cmd.command = cString::sprintf("PLUG %s INFO\r\n", PLUGIN_NAME_I18N); + while (Running()) { + t.Set(0); + svdrpFrontendM = -1; + svdrpVideoBitRateM = -1.0; + svdrpAudioBitRateM = -1.0; + switch (deviceSourceM) { + case DEVICESOURCE_PVRINPUT: + qualityM = cDevice::ActualDevice()->SignalStrength(); + qualityValidM = (qualityM >= 0); + 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); + frontendStatusValidM = strengthValidM; + signalM = uint16_t(strengthM * 0xFFFF / 100); + signalValidM = strengthValidM; + snrM = 0; + snrValidM = false; + berM = 0; + berValidM = false; + uncM = 0; + uncValidM = false; + break; + case DEVICESOURCE_IPTV: + qualityM = cDevice::ActualDevice()->SignalQuality(); + qualityValidM = (qualityM >= 0); + 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); + 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; + 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) { + cmd.handle = svdrpConnectionM.handle; + svdrpPluginM->Service("SvdrpCommand-v1.0", &cmd); + if (cmd.responseCode == 900) { + strengthValidM = false; + qualityValidM = false; + frontendStatusValidM = false; + signalValidM = false; + snrValidM = false; + berValidM = false; + uncValidM = false; + for (cLine *line = cmd.reply.First(); line; line = cmd.reply.Next(line)) { + const char *s = line->Text(); + if (!strncasecmp(s, "CARD:", 5)) + svdrpFrontendM = (int)strtol(s + 5, NULL, 10); + else if (!strncasecmp(s, "STRG:", 5)) { + strengthM = (int)strtol(s + 5, NULL, 10); + strengthValidM = (strengthM >= 0); + } + else if (!strncasecmp(s, "QUAL:", 5)) { + 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, "NAME:", 5)) { + frontendNameM = s + 5; + } + else if (!strncasecmp(s, "STAT:", 5)) { + frontendStatusM = (fe_status_t)strtol(s + 5, NULL, 16); + frontendStatusValidM = true; + } + else if (!strncasecmp(s, "SGNL:", 5)) { + signalM = (uint16_t)strtol(s + 5, NULL, 16); + signalValidM = true; + } + else if (!strncasecmp(s, "SNRA:", 5)) { + snrM = (uint16_t)strtol(s + 5, NULL, 16); + snrValidM = true; + } + else if (!strncasecmp(s, "BERA:", 5)) { + berM = (uint32_t)strtol(s + 5, NULL, 16); + berValidM = true; + } + else if (!strncasecmp(s, "UNCB:", 5)) { + uncM = (uint32_t)strtol(s + 5, NULL, 16); + uncValidM = true; + } + else if (!strncasecmp(s, "VIBR:", 5)) + svdrpVideoBitRateM = (double)strtol(s + 5, NULL, 10); + else if (!strncasecmp(s, "AUBR:", 5)) + svdrpAudioBitRateM = (double)strtol(s + 5, NULL, 10); + } + } + } + break; + } + DrawInfoWindow(); + DrawStatusWindow(); + sleepM.Wait(max((int)(100 * FemonConfig.GetUpdateInterval() - t.Elapsed()), 3)); + } +} + +void cFemonOsd::Show(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); + 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; + + osdM = cOsdProvider::NewOsd(osdLeftM, osdTopM); + if (osdM) { + tArea Areas1[] = { { 0, 0, OSDWIDTH - 1, OSDHEIGHT - 1, 8 } }; + if (Setup.AntiAlias && osdM->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) { + osdM->SetAreas(Areas1, sizeof(Areas1) / sizeof(tArea)); + } + else { + tArea Areas2[] = { { 0, OSDSTATUSWIN_Y(0), OSDWIDTH - 1, OSDSTATUSWIN_Y(0) + OSDSTATUSHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].bpp }, + { 0, OSDINFOWIN_Y(0), OSDWIDTH - 1, OSDINFOWIN_Y(0) + OSDROWHEIGHT - 1, FemonTheme[FemonConfig.GetTheme()].bpp }, + { 0, OSDINFOWIN_Y(OSDROWHEIGHT), OSDWIDTH - 1, OSDINFOWIN_Y(0) + OSDINFOHEIGHT - 1, 2 } }; + osdM->SetAreas(Areas2, sizeof(Areas2) / sizeof(tArea)); + } + OSDCLEARSTATUS(); + OSDCLEARINFO(); + osdM->Flush(); + if (receiverM) { + receiverM->Deactivate(); + DELETENULL(receiverM); + } + if (FemonConfig.GetAnalyzeStream() && 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); + } + Start(); + } +} + +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()); + + if (!deviceP || !liveViewP) + return; + + if (!channelNumberP) { + if (receiverM) { + receiverM->Deactivate(); + DELETENULL(receiverM); + } + 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); + } + } +} + +void cFemonOsd::SetAudioTrack(int indexP, const char * const *tracksP) +{ + debug1("%s (%d, )", __PRETTY_FUNCTION__, indexP); + eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); + if (receiverM) { + receiverM->Deactivate(); + DELETENULL(receiverM); + } + if (FemonConfig.GetAnalyzeStream()) { + 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); + } + } +} + +bool cFemonOsd::DeviceSwitch(int directionP) +{ + debug1("%s (%d)", __PRETTY_FUNCTION__, directionP); + int device = cDevice::ActualDevice()->DeviceNumber(); + int direction = sgn(directionP); + if (device >= 0) { + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + if (channel) { + for (int i = 0; i < cDevice::NumDevices() - 1; i++) { + if (direction >= 0) { + if (++device >= cDevice::NumDevices()) + device = 0; + } + else { + if (--device < 0) + device = cDevice::NumDevices() - 1; + } + // Collect the current priorities of all CAM slots that can decrypt the channel: + int NumCamSlots = CamSlots.Count(); + int SlotPriority[NumCamSlots]; + int NumUsableSlots = 0; + bool NeedsDetachAllReceivers = false; + bool InternalCamNeeded = false; + bool ValidDevice = false; + cCamSlot *s = NULL; + cDevice *d = cDevice::GetDevice(device); + if (channel->Ca() >= CA_ENCRYPTED_MIN) { + for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { + SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used + if (CamSlot->ModuleStatus() == msReady) { + if (CamSlot->ProvidesCa(channel->Caids())) { + if (!ChannelCamRelations.CamChecked(channel->GetChannelID(), CamSlot->SlotNumber())) { + SlotPriority[CamSlot->Index()] = CamSlot->Priority(); + NumUsableSlots++; + } + } + } + } + if (!NumUsableSlots) + InternalCamNeeded = true; // no CAM is able to decrypt this channel + } + for (int j = 0; j < NumCamSlots || !NumUsableSlots; ++j) { + if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) + continue; // there is no CAM available in this slot + bool HasInternalCam = d->HasInternalCam(); + if (InternalCamNeeded && !HasInternalCam) + continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs + if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(d, true)) + continue; // CAM slot can't be used with this device + if (d->ProvidesChannel(channel, 0, &NeedsDetachAllReceivers)) { // this device is basically able to do the job + debug1("%s (%d) device=%d", __PRETTY_FUNCTION__, direction, device); + if (NumUsableSlots && !HasInternalCam && d->CamSlot() && d->CamSlot() != CamSlots.Get(j)) + NeedsDetachAllReceivers = true; // using a different CAM slot requires detaching receivers + if (NumUsableSlots && !HasInternalCam) + s = CamSlots.Get(j); + ValidDevice = true; + break; + } + if (!NumUsableSlots) + break; // no CAM necessary, so just one loop over the devices + } + // Do the actual switch if valid device found + if (d && ValidDevice) { + cControl::Shutdown(); + if (NeedsDetachAllReceivers) + d->DetachAllReceivers(); + if (s) { + if (s->Device() != d) { + if (s->Device()) + s->Device()->DetachAllReceivers(); + if (d->CamSlot()) + d->CamSlot()->Assign(NULL); + s->Assign(d); + } + } + else if (d->CamSlot() && !d->CamSlot()->IsDecrypting()) + d->CamSlot()->Assign(NULL); + d->SwitchChannel(channel, false); + cControl::Launch(new cTransferControl(d, channel)); + return (true); + } + } + } + } + return (false); +} + +bool cFemonOsd::SvdrpConnect(void) +{ + if (svdrpConnectionM.handle < 0) { + svdrpPluginM = cPluginManager::GetPlugin(SVDRPPLUGIN); + if (svdrpPluginM) { + svdrpConnectionM.serverIp = FemonConfig.GetSvdrpIp(); + svdrpConnectionM.serverPort = (unsigned short)FemonConfig.GetSvdrpPort(); + svdrpConnectionM.shared = true; + svdrpPluginM->Service("SvdrpConnection-v1.0", &svdrpConnectionM); + if (svdrpConnectionM.handle >= 0) { + SvdrpCommand_v1_0 cmd; + cmd.handle = svdrpConnectionM.handle; + cmd.command = cString::sprintf("PLUG %s\r\n", PLUGIN_NAME_I18N); + svdrpPluginM->Service("SvdrpCommand-v1.0", &cmd); + if (cmd.responseCode != 214) { + svdrpPluginM->Service("SvdrpConnection-v1.0", &svdrpConnectionM); // close connection + error("%s Cannot find plugin '%s' on server %s", __PRETTY_FUNCTION__, PLUGIN_NAME_I18N, *svdrpConnectionM.serverIp); + } + } + else + error("%s Cannot connect to SVDRP server", __PRETTY_FUNCTION__); + } + else + error("%s Cannot find plugin '%s'", __PRETTY_FUNCTION__, SVDRPPLUGIN); + } + return svdrpConnectionM.handle >= 0; +} + +bool cFemonOsd::SvdrpTune(void) +{ + if (svdrpPluginM && svdrpConnectionM.handle >= 0) { + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + if (channel) { + SvdrpCommand_v1_0 cmd; + cmd.handle = svdrpConnectionM.handle; + cmd.command = cString::sprintf("CHAN %s\r\n", *channel->GetChannelID().ToString()); + svdrpPluginM->Service("SvdrpCommand-v1.0", &cmd); + if (cmd.responseCode == 250) + return true; + error("%s Cannot tune server channel", __PRETTY_FUNCTION__); + } + else + error("%s Invalid channel", __PRETTY_FUNCTION__); + } + else + error("%s Unexpected connection state", __PRETTY_FUNCTION__); + return false; +} + +double cFemonOsd::GetVideoBitrate(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + double value = 0.0; + + if (receiverM) + value = receiverM->VideoBitrate(); + + return (value); +} + +double cFemonOsd::GetAudioBitrate(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + double value = 0.0; + + if (receiverM) + value = receiverM->AudioBitrate(); + + return (value); +} + +double cFemonOsd::GetDolbyBitrate(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + double value = 0.0; + + if (receiverM) + value = receiverM->AC3Bitrate(); + + return (value); +} + +eOSState cFemonOsd::ProcessKey(eKeys keyP) +{ + eOSState state = cOsdObject::ProcessKey(keyP); + if (state == osUnknown) { + switch (int(keyP)) { + case k0: + if ((numberM == 0) && (oldNumberM != 0)) { + numberM = oldNumberM; + oldNumberM = cDevice::CurrentChannel(); + Channels.SwitchTo(numberM); + numberM = 0; + return osContinue; + } + case k1 ... k9: + if (numberM >= 0) { + numberM = numberM * 10 + keyP - k0; + if (numberM > 0) { + DrawStatusWindow(); + 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) { + if (!ch->GroupSep()) { + if (n <= ch->Number() && ch->Number() <= n + 9) { + n = 0; + break; + } + if (ch->Number() > n) + n *= 10; + } + } + 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); + numberM = 0; + } + } + } + break; + case kBack: + return osEnd; + case kGreen: + { + eTrackType types[ttMaxTrackTypes]; + eTrackType CurrentAudioTrack = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); + int numTracks = 0; + int oldTrack = 0; + int track = 0; + for (int i = ttAudioFirst; i <= ttDolbyLast; i++) { + const tTrackId *TrackId = cDevice::PrimaryDevice()->GetTrack(eTrackType(i)); + if (TrackId && TrackId->id) { + types[numTracks] = eTrackType(i); + if (i == CurrentAudioTrack) + track = numTracks; + numTracks++; + } + } + oldTrack = track; + if (++track >= numTracks) + track = 0; + if (track != oldTrack) { + cDevice::PrimaryDevice()->SetCurrentAudioTrack(types[track]); + Setup.CurrentDolby = IS_DOLBY_TRACK(types[track]); + } + } + break; + case kYellow: + if (IS_AUDIO_TRACK(cDevice::PrimaryDevice()->GetCurrentAudioTrack())) { + int audioChannel = cDevice::PrimaryDevice()->GetAudioChannel(); + int oldAudioChannel = audioChannel; + if (++audioChannel > 2) + audioChannel = 0; + if (audioChannel != oldAudioChannel) { + cDevice::PrimaryDevice()->SetAudioChannel(audioChannel); + } + } + break; + case kRight: + DeviceSwitch(1); + break; + case kLeft: + DeviceSwitch(-1); + break; + case kUp|k_Repeat: + case kUp: + case kDown|k_Repeat: + case kDown: + oldNumberM = cDevice::CurrentChannel(); + cDevice::SwitchChannel(NORMALKEY(keyP) == kUp ? 1 : -1); + numberM = 0; + break; + case kNone: + if (numberM && (inputTimeM.Elapsed() > CHANNELINPUT_TIMEOUT)) { + if (Channels.GetByNumber(numberM)) { + oldNumberM = cDevice::CurrentChannel(); + Channels.SwitchTo(numberM); + numberM = 0; + } + else { + inputTimeM.Set(0); + numberM = 0; + } + } + break; + case kOk: + { + // toggle between display modes + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + if (++displayModeM == eFemonModeAC3 && channel && !channel->Dpid(0)) displayModeM++; + if (displayModeM >= eFemonModeMaxNumber) displayModeM = 0; + DrawInfoWindow(); + } + break; + default: + break; + } + state = osContinue; + } + return state; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/osd.h vdr-plugin-femon-2.2.1.git20150307.2205/osd.h --- vdr-plugin-femon-2.2.0.git20150222.1714/osd.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/osd.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * osd.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_OSD_H +#define __FEMON_OSD_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "receiver.h" +#include "svdrpservice.h" + +#define MAX_BM_NUMBER 8 + +class cFemonOsd : public cOsdObject, public cThread, public cStatus { +private: + enum eDeviceSourceType { + DEVICESOURCE_DVBAPI = 0, + DEVICESOURCE_IPTV, + DEVICESOURCE_PVRINPUT, + DEVICESOURCE_COUNT + }; + + static cFemonOsd *pInstanceS; + + cOsd *osdM; + cFemonReceiver *receiverM; + int frontendM; + int svdrpFrontendM; + double svdrpVideoBitRateM; + double svdrpAudioBitRateM; + SvdrpConnection_v1_0 svdrpConnectionM; + cPlugin *svdrpPluginM; + int numberM; + int oldNumberM; + int qualityM; + bool qualityValidM; + int strengthM; + bool strengthValidM; + uint16_t snrM; + bool snrValidM; + uint16_t signalM; + bool signalValidM; + uint32_t berM; + bool berValidM; + uint32_t uncM; + bool uncValidM; + cString frontendNameM; + fe_status_t frontendStatusM; + bool frontendStatusValidM; + dvb_frontend_info frontendInfoM; + eDeviceSourceType deviceSourceM; + int displayModeM; + int osdWidthM; + int osdHeightM; + int osdLeftM; + int osdTopM; + cFont *fontM; + cTimeMs inputTimeM; + cCondWait sleepM; + cMutex mutexM; + + void DrawStatusWindow(void); + void DrawInfoWindow(void); + bool SvdrpConnect(void); + bool SvdrpTune(void); + +protected: + cFemonOsd(); + cFemonOsd(const cFemonOsd&); + cFemonOsd& operator= (const cFemonOsd&); + virtual void Action(void); + virtual void ChannelSwitch(const cDevice *deviceP, int channelNumberP, bool liveViewP); + virtual void SetAudioTrack(int indexP, const char * const *tracksP); + +public: + static cFemonOsd *Instance(bool createP = false); + ~cFemonOsd(); + + virtual void Show(void); + virtual eOSState ProcessKey(eKeys keyP); + + bool DeviceSwitch(int directionP); + double GetVideoBitrate(void); + double GetAudioBitrate(void); + double GetDolbyBitrate(void); +}; + +#endif //__FEMON_OSD_H + diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/de_DE.po vdr-plugin-femon-2.2.1.git20150307.2205/po/de_DE.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/de_DE.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/de_DE.po 2015-03-07 22:05:34.000000000 +0000 @@ -27,6 +27,99 @@ msgid "Femon not available" msgstr "Femon nicht verfügbar" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Transponderinformation" + +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 "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "Bitrate" + +msgid "Stream Information" +msgstr "Streaminformation" + +msgid "Video Stream" +msgstr "Video Stream" + +msgid "Codec" +msgstr "" + +msgid "Aspect Ratio" +msgstr "Seitenverhältnis" + +msgid "Frame Rate" +msgstr "Bildrate" + +msgid "Video Format" +msgstr "Bildformat" + +msgid "Resolution" +msgstr "Auflösung" + +msgid "Audio Stream" +msgstr "Audio Stream" + +msgid "Channel Mode" +msgstr "" + +msgid "Sampling Frequency" +msgstr "Abtastrate" + +msgid "AC-3 Stream" +msgstr "AC-3 Stream" + +msgid "Bit Stream Mode" +msgstr "Bitstream Modus" + +msgid "Audio Coding Mode" +msgstr "Audiokodierung" + +msgid "Center Mix Level" +msgstr "Center Mix Pegel" + +msgid "Surround Mix Level" +msgstr "Surround Mix Pegel" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround Modus" + +msgid "Low Frequency Effects" +msgstr "Tieftöner Effekte" + +msgid "Dialogue Normalization" +msgstr "Dialog Normalisierung" + msgid "basic" msgstr "Standard" @@ -36,9 +129,6 @@ msgid "stream" msgstr "Stream" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Klassischer" @@ -150,96 +240,6 @@ msgid "Help" msgstr "Hilfe" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Transponderinformation" - -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 "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "Bitrate" - -msgid "Stream Information" -msgstr "Streaminformation" - -msgid "Video Stream" -msgstr "Video Stream" - -msgid "Codec" -msgstr "" - -msgid "Aspect Ratio" -msgstr "Seitenverhältnis" - -msgid "Frame Rate" -msgstr "Bildrate" - -msgid "Video Format" -msgstr "Bildformat" - -msgid "Resolution" -msgstr "Auflösung" - -msgid "Audio Stream" -msgstr "Audio Stream" - -msgid "Channel Mode" -msgstr "" - -msgid "Sampling Frequency" -msgstr "Abtastrate" - -msgid "AC-3 Stream" -msgstr "AC-3 Stream" - -msgid "Bit Stream Mode" -msgstr "Bitstream Modus" - -msgid "Audio Coding Mode" -msgstr "Audiokodierung" - -msgid "Center Mix Level" -msgstr "Center Mix Pegel" - -msgid "Surround Mix Level" -msgstr "Surround Mix Pegel" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround Modus" - -msgid "Low Frequency Effects" -msgstr "Tieftöner Effekte" - -msgid "Dialogue Normalization" -msgstr "Dialog Normalisierung" - msgid "Fixed" msgstr "Fest" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/es_ES.po vdr-plugin-femon-2.2.1.git20150307.2205/po/es_ES.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/es_ES.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/es_ES.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Información del transpondedor" + +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 "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "Tasa de bits" + +msgid "Stream Information" +msgstr "Información del flujo" + +msgid "Video Stream" +msgstr "Flujo de video" + +msgid "Codec" +msgstr "" + +msgid "Aspect Ratio" +msgstr "Proporciones de la imagen" + +msgid "Frame Rate" +msgstr "Tasa de frames" + +msgid "Video Format" +msgstr "Formato de video" + +msgid "Resolution" +msgstr "Resolución" + +msgid "Audio Stream" +msgstr "Flujo de audio" + +msgid "Channel Mode" +msgstr "" + +msgid "Sampling Frequency" +msgstr "Frecuencia de muestreo" + +msgid "AC-3 Stream" +msgstr "Flujo AC-3" + +msgid "Bit Stream Mode" +msgstr "Modo bitstream" + +msgid "Audio Coding Mode" +msgstr "Modo de codificación de audio" + +msgid "Center Mix Level" +msgstr "Nivel sonoro central" + +msgid "Surround Mix Level" +msgstr "Nivel sonoro surround" + +msgid "Dolby Surround Mode" +msgstr "Nivel sonoro Dolby Surround" + +msgid "Low Frequency Effects" +msgstr "Efectos de baja frecuencia" + +msgid "Dialogue Normalization" +msgstr "Normalización del diálogo" + msgid "basic" msgstr "Básico" @@ -34,9 +127,6 @@ msgid "stream" msgstr "Flujo" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Clásico" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Ayuda" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Información del transpondedor" - -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 "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "Tasa de bits" - -msgid "Stream Information" -msgstr "Información del flujo" - -msgid "Video Stream" -msgstr "Flujo de video" - -msgid "Codec" -msgstr "" - -msgid "Aspect Ratio" -msgstr "Proporciones de la imagen" - -msgid "Frame Rate" -msgstr "Tasa de frames" - -msgid "Video Format" -msgstr "Formato de video" - -msgid "Resolution" -msgstr "Resolución" - -msgid "Audio Stream" -msgstr "Flujo de audio" - -msgid "Channel Mode" -msgstr "" - -msgid "Sampling Frequency" -msgstr "Frecuencia de muestreo" - -msgid "AC-3 Stream" -msgstr "Flujo AC-3" - -msgid "Bit Stream Mode" -msgstr "Modo bitstream" - -msgid "Audio Coding Mode" -msgstr "Modo de codificación de audio" - -msgid "Center Mix Level" -msgstr "Nivel sonoro central" - -msgid "Surround Mix Level" -msgstr "Nivel sonoro surround" - -msgid "Dolby Surround Mode" -msgstr "Nivel sonoro Dolby Surround" - -msgid "Low Frequency Effects" -msgstr "Efectos de baja frecuencia" - -msgid "Dialogue Normalization" -msgstr "Normalización del diálogo" - msgid "Fixed" msgstr "Fijo" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/et_EE.po vdr-plugin-femon-2.2.1.git20150307.2205/po/et_EE.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/et_EE.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/et_EE.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femon ei ole kättesaadav" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Transponderi info" + +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 "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "Bitikiirus" + +msgid "Stream Information" +msgstr "Vooinfo" + +msgid "Video Stream" +msgstr "Videovoog" + +msgid "Codec" +msgstr "Koodek" + +msgid "Aspect Ratio" +msgstr "Külgsuhe" + +msgid "Frame Rate" +msgstr "Kaadrisagedus" + +msgid "Video Format" +msgstr "Videoformaat" + +msgid "Resolution" +msgstr "Resolutsioon" + +msgid "Audio Stream" +msgstr "Audiovoog" + +msgid "Channel Mode" +msgstr "Kanalimoodus" + +msgid "Sampling Frequency" +msgstr "Sämplimissagedus" + +msgid "AC-3 Stream" +msgstr "AC-3 voog" + +msgid "Bit Stream Mode" +msgstr "Bitivoo tüüp" + +msgid "Audio Coding Mode" +msgstr "Audiokodeering" + +msgid "Center Mix Level" +msgstr "Keskmise kanali tase" + +msgid "Surround Mix Level" +msgstr "Surround kanali tase" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround'i tüüp" + +msgid "Low Frequency Effects" +msgstr "LFE kanal" + +msgid "Dialogue Normalization" +msgstr "Dialoogi normalisatsioon" + msgid "basic" msgstr "standard" @@ -34,9 +127,6 @@ msgid "stream" msgstr "voog" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Classic" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Abi" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Transponderi info" - -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 "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "Bitikiirus" - -msgid "Stream Information" -msgstr "Vooinfo" - -msgid "Video Stream" -msgstr "Videovoog" - -msgid "Codec" -msgstr "Koodek" - -msgid "Aspect Ratio" -msgstr "Külgsuhe" - -msgid "Frame Rate" -msgstr "Kaadrisagedus" - -msgid "Video Format" -msgstr "Videoformaat" - -msgid "Resolution" -msgstr "Resolutsioon" - -msgid "Audio Stream" -msgstr "Audiovoog" - -msgid "Channel Mode" -msgstr "Kanalimoodus" - -msgid "Sampling Frequency" -msgstr "Sämplimissagedus" - -msgid "AC-3 Stream" -msgstr "AC-3 voog" - -msgid "Bit Stream Mode" -msgstr "Bitivoo tüüp" - -msgid "Audio Coding Mode" -msgstr "Audiokodeering" - -msgid "Center Mix Level" -msgstr "Keskmise kanali tase" - -msgid "Surround Mix Level" -msgstr "Surround kanali tase" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround'i tüüp" - -msgid "Low Frequency Effects" -msgstr "LFE kanal" - -msgid "Dialogue Normalization" -msgstr "Dialoogi normalisatsioon" - msgid "Fixed" msgstr "Fikseeritud" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/fi_FI.po vdr-plugin-femon-2.2.1.git20150307.2205/po/fi_FI.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/fi_FI.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/fi_FI.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Signaalimittari ei ole käytettävissä" +msgid "Video" +msgstr "Kuva" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Ääni" + +msgid "Transponder Information" +msgstr "Transponderin tiedot" + +msgid "Apid" +msgstr "Ääni-PID" + +msgid "Dpid" +msgstr "Dolby-PID" + +msgid "Spid" +msgstr "Tekstitys-PID" + +msgid "Nid" +msgstr "Verkko-ID" + +msgid "Tid" +msgstr "TS-ID" + +msgid "Rid" +msgstr "Radio-ID" + +msgid "Coderate" +msgstr "Suojaustaso" + +msgid "Protocol" +msgstr "Protokolla" + +msgid "Bitrate" +msgstr "Bittinopeus" + +msgid "Stream Information" +msgstr "Lähetteen tiedot" + +msgid "Video Stream" +msgstr "Kuvaraita" + +msgid "Codec" +msgstr "Koodekki" + +msgid "Aspect Ratio" +msgstr "Kuvasuhde" + +msgid "Frame Rate" +msgstr "Ruudunpäivitystaajuus" + +msgid "Video Format" +msgstr "Kuvaformaatti" + +msgid "Resolution" +msgstr "Resoluutio" + +msgid "Audio Stream" +msgstr "Ääniraita" + +msgid "Channel Mode" +msgstr "Kanavatila" + +msgid "Sampling Frequency" +msgstr "Näytteenottotaajuus" + +msgid "AC-3 Stream" +msgstr "AC-3-ääniraita" + +msgid "Bit Stream Mode" +msgstr "Lähetteen tyyppi" + +msgid "Audio Coding Mode" +msgstr "Äänikoodaus" + +msgid "Center Mix Level" +msgstr "Keskikanavan taso" + +msgid "Surround Mix Level" +msgstr "Tehostekanavien taso" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround -tehoste" + +msgid "Low Frequency Effects" +msgstr "LFE-kanava" + +msgid "Dialogue Normalization" +msgstr "Dialogin normalisointi" + msgid "basic" msgstr "perus" @@ -34,9 +127,6 @@ msgid "stream" msgstr "lähete" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Klassinen" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Opaste" -msgid "Video" -msgstr "Kuva" - -msgid "Audio" -msgstr "Ääni" - -msgid "Transponder Information" -msgstr "Transponderin tiedot" - -msgid "Apid" -msgstr "Ääni-PID" - -msgid "Dpid" -msgstr "Dolby-PID" - -msgid "Spid" -msgstr "Tekstitys-PID" - -msgid "Nid" -msgstr "Verkko-ID" - -msgid "Tid" -msgstr "TS-ID" - -msgid "Rid" -msgstr "Radio-ID" - -msgid "Coderate" -msgstr "Suojaustaso" - -msgid "Protocol" -msgstr "Protokolla" - -msgid "Bitrate" -msgstr "Bittinopeus" - -msgid "Stream Information" -msgstr "Lähetteen tiedot" - -msgid "Video Stream" -msgstr "Kuvaraita" - -msgid "Codec" -msgstr "Koodekki" - -msgid "Aspect Ratio" -msgstr "Kuvasuhde" - -msgid "Frame Rate" -msgstr "Ruudunpäivitystaajuus" - -msgid "Video Format" -msgstr "Kuvaformaatti" - -msgid "Resolution" -msgstr "Resoluutio" - -msgid "Audio Stream" -msgstr "Ääniraita" - -msgid "Channel Mode" -msgstr "Kanavatila" - -msgid "Sampling Frequency" -msgstr "Näytteenottotaajuus" - -msgid "AC-3 Stream" -msgstr "AC-3-ääniraita" - -msgid "Bit Stream Mode" -msgstr "Lähetteen tyyppi" - -msgid "Audio Coding Mode" -msgstr "Äänikoodaus" - -msgid "Center Mix Level" -msgstr "Keskikanavan taso" - -msgid "Surround Mix Level" -msgstr "Tehostekanavien taso" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround -tehoste" - -msgid "Low Frequency Effects" -msgstr "LFE-kanava" - -msgid "Dialogue Normalization" -msgstr "Dialogin normalisointi" - msgid "Fixed" msgstr "kiinteä" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/fr_FR.po vdr-plugin-femon-2.2.1.git20150307.2205/po/fr_FR.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/fr_FR.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/fr_FR.po 2015-03-07 22:05:34.000000000 +0000 @@ -27,6 +27,99 @@ msgid "Femon not available" msgstr "Femon n'est pas disponible" +msgid "Video" +msgstr "Vidéo" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Information du transpondeur" + +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 "Coderate" + +msgid "Protocol" +msgstr "Protocole" + +msgid "Bitrate" +msgstr "Taux d'échantillonnage fixe" + +msgid "Stream Information" +msgstr "Information sur le flux" + +msgid "Video Stream" +msgstr "Flux vidéo" + +msgid "Codec" +msgstr "Codec" + +msgid "Aspect Ratio" +msgstr "Format de l'image" + +msgid "Frame Rate" +msgstr "Rafraîchissement" + +msgid "Video Format" +msgstr "Standard vidéo" + +msgid "Resolution" +msgstr "Résolution" + +msgid "Audio Stream" +msgstr "Flux audio" + +msgid "Channel Mode" +msgstr "Mode chaîne" + +msgid "Sampling Frequency" +msgstr "Fréquence d'échantillonage" + +msgid "AC-3 Stream" +msgstr "Flux AC-3" + +msgid "Bit Stream Mode" +msgstr "Mode bitstream" + +msgid "Audio Coding Mode" +msgstr "Mode de codage audio" + +msgid "Center Mix Level" +msgstr "Niveau sonore milieu" + +msgid "Surround Mix Level" +msgstr "Niveau sonore surround" + +msgid "Dolby Surround Mode" +msgstr "Mode Dolby Surround" + +msgid "Low Frequency Effects" +msgstr "Effets de basses" + +msgid "Dialogue Normalization" +msgstr "Normalisation des dialogues" + msgid "basic" msgstr "basique" @@ -36,9 +129,6 @@ msgid "stream" msgstr "flux" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Classique" @@ -150,96 +240,6 @@ msgid "Help" msgstr "Aide" -msgid "Video" -msgstr "Vidéo" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Information du transpondeur" - -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 "Coderate" - -msgid "Protocol" -msgstr "Protocole" - -msgid "Bitrate" -msgstr "Taux d'échantillonnage fixe" - -msgid "Stream Information" -msgstr "Information sur le flux" - -msgid "Video Stream" -msgstr "Flux vidéo" - -msgid "Codec" -msgstr "Codec" - -msgid "Aspect Ratio" -msgstr "Format de l'image" - -msgid "Frame Rate" -msgstr "Rafraîchissement" - -msgid "Video Format" -msgstr "Standard vidéo" - -msgid "Resolution" -msgstr "Résolution" - -msgid "Audio Stream" -msgstr "Flux audio" - -msgid "Channel Mode" -msgstr "Mode chaîne" - -msgid "Sampling Frequency" -msgstr "Fréquence d'échantillonage" - -msgid "AC-3 Stream" -msgstr "Flux AC-3" - -msgid "Bit Stream Mode" -msgstr "Mode bitstream" - -msgid "Audio Coding Mode" -msgstr "Mode de codage audio" - -msgid "Center Mix Level" -msgstr "Niveau sonore milieu" - -msgid "Surround Mix Level" -msgstr "Niveau sonore surround" - -msgid "Dolby Surround Mode" -msgstr "Mode Dolby Surround" - -msgid "Low Frequency Effects" -msgstr "Effets de basses" - -msgid "Dialogue Normalization" -msgstr "Normalisation des dialogues" - msgid "Fixed" msgstr "Fixe" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/hu_HU.po vdr-plugin-femon-2.2.1.git20150307.2205/po/hu_HU.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/hu_HU.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/hu_HU.po 2015-03-07 22:05:34.000000000 +0000 @@ -28,6 +28,99 @@ msgid "Femon not available" msgstr "Femon nem elérhetõ" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Transponder infó" + +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 "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "Bitráta" + +msgid "Stream Information" +msgstr "Adatfolyam infó" + +msgid "Video Stream" +msgstr "Videó adatfolyam" + +msgid "Codec" +msgstr "Kodek" + +msgid "Aspect Ratio" +msgstr "Méretarány" + +msgid "Frame Rate" +msgstr "Képfrissítés" + +msgid "Video Format" +msgstr "Videó formátum" + +msgid "Resolution" +msgstr "Felbontás" + +msgid "Audio Stream" +msgstr "Hang adatfolyam" + +msgid "Channel Mode" +msgstr "Hangsáv mód" + +msgid "Sampling Frequency" +msgstr "Mintavételezési frekvencia" + +msgid "AC-3 Stream" +msgstr "AC-3 adatfolyam" + +msgid "Bit Stream Mode" +msgstr "Bit Stream mód" + +msgid "Audio Coding Mode" +msgstr "Hang kódolási mód" + +msgid "Center Mix Level" +msgstr "Középcsatorna keverési jelszintje" + +msgid "Surround Mix Level" +msgstr "Térhatás csatorna keverési szintje" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround mód" + +msgid "Low Frequency Effects" +msgstr "LFE - alacsony frekvenciás effektek" + +msgid "Dialogue Normalization" +msgstr "Párbeszéd jelszint normalizálása" + msgid "basic" msgstr "alap" @@ -37,9 +130,6 @@ msgid "stream" msgstr "adatfolyam (stream)" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Klasszikus" @@ -151,96 +241,6 @@ msgid "Help" msgstr "Segítség" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Transponder infó" - -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 "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "Bitráta" - -msgid "Stream Information" -msgstr "Adatfolyam infó" - -msgid "Video Stream" -msgstr "Videó adatfolyam" - -msgid "Codec" -msgstr "Kodek" - -msgid "Aspect Ratio" -msgstr "Méretarány" - -msgid "Frame Rate" -msgstr "Képfrissítés" - -msgid "Video Format" -msgstr "Videó formátum" - -msgid "Resolution" -msgstr "Felbontás" - -msgid "Audio Stream" -msgstr "Hang adatfolyam" - -msgid "Channel Mode" -msgstr "Hangsáv mód" - -msgid "Sampling Frequency" -msgstr "Mintavételezési frekvencia" - -msgid "AC-3 Stream" -msgstr "AC-3 adatfolyam" - -msgid "Bit Stream Mode" -msgstr "Bit Stream mód" - -msgid "Audio Coding Mode" -msgstr "Hang kódolási mód" - -msgid "Center Mix Level" -msgstr "Középcsatorna keverési jelszintje" - -msgid "Surround Mix Level" -msgstr "Térhatás csatorna keverési szintje" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround mód" - -msgid "Low Frequency Effects" -msgstr "LFE - alacsony frekvenciás effektek" - -msgid "Dialogue Normalization" -msgstr "Párbeszéd jelszint normalizálása" - msgid "Fixed" msgstr "Állandó" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/it_IT.po vdr-plugin-femon-2.2.1.git20150307.2205/po/it_IT.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/it_IT.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/it_IT.po 2015-03-07 22:05:34.000000000 +0000 @@ -29,6 +29,99 @@ msgid "Femon not available" msgstr "Femon non disponibile" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Informazioni transponder" + +msgid "Apid" +msgstr "PID Audio" + +msgid "Dpid" +msgstr "PID AC3" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "Bitrate" + +msgid "Stream Information" +msgstr "Informazioni flusso" + +msgid "Video Stream" +msgstr "Flusso video" + +msgid "Codec" +msgstr "Codifica" + +msgid "Aspect Ratio" +msgstr "Formato immagine" + +msgid "Frame Rate" +msgstr "Frame rate" + +msgid "Video Format" +msgstr "Formato video" + +msgid "Resolution" +msgstr "Risoluzione" + +msgid "Audio Stream" +msgstr "Flusso audio" + +msgid "Channel Mode" +msgstr "Modalità canale" + +msgid "Sampling Frequency" +msgstr "Frequenza campionamento" + +msgid "AC-3 Stream" +msgstr "Flusso AC-3" + +msgid "Bit Stream Mode" +msgstr "Modalità bitstream" + +msgid "Audio Coding Mode" +msgstr "Modalità codifica audio" + +msgid "Center Mix Level" +msgstr "Livello sonoro centrale" + +msgid "Surround Mix Level" +msgstr "Livello sonoro surround" + +msgid "Dolby Surround Mode" +msgstr "Modalità Dolby Surround" + +msgid "Low Frequency Effects" +msgstr "Effetti bassa frequenza" + +msgid "Dialogue Normalization" +msgstr "Normalizzazione dialoghi" + msgid "basic" msgstr "base" @@ -38,9 +131,6 @@ msgid "stream" msgstr "flusso" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Classico" @@ -152,96 +242,6 @@ msgid "Help" msgstr "Aiuto" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Informazioni transponder" - -msgid "Apid" -msgstr "PID Audio" - -msgid "Dpid" -msgstr "PID AC3" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "Bitrate" - -msgid "Stream Information" -msgstr "Informazioni flusso" - -msgid "Video Stream" -msgstr "Flusso video" - -msgid "Codec" -msgstr "Codifica" - -msgid "Aspect Ratio" -msgstr "Formato immagine" - -msgid "Frame Rate" -msgstr "Frame rate" - -msgid "Video Format" -msgstr "Formato video" - -msgid "Resolution" -msgstr "Risoluzione" - -msgid "Audio Stream" -msgstr "Flusso audio" - -msgid "Channel Mode" -msgstr "Modalità canale" - -msgid "Sampling Frequency" -msgstr "Frequenza campionamento" - -msgid "AC-3 Stream" -msgstr "Flusso AC-3" - -msgid "Bit Stream Mode" -msgstr "Modalità bitstream" - -msgid "Audio Coding Mode" -msgstr "Modalità codifica audio" - -msgid "Center Mix Level" -msgstr "Livello sonoro centrale" - -msgid "Surround Mix Level" -msgstr "Livello sonoro surround" - -msgid "Dolby Surround Mode" -msgstr "Modalità Dolby Surround" - -msgid "Low Frequency Effects" -msgstr "Effetti bassa frequenza" - -msgid "Dialogue Normalization" -msgstr "Normalizzazione dialoghi" - msgid "Fixed" msgstr "Fisso" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/lt_LT.po vdr-plugin-femon-2.2.1.git20150307.2205/po/lt_LT.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/lt_LT.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/lt_LT.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femon įskiepas nepasiekiamas" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Audio" + +msgid "Transponder Information" +msgstr "Siųstuvo informacija" + +msgid "Apid" +msgstr "Apid" + +msgid "Dpid" +msgstr "Dpid" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "Kodavimo dažnis" + +msgid "Protocol" +msgstr "Protokolas" + +msgid "Bitrate" +msgstr "KokybÄ—" + +msgid "Stream Information" +msgstr "Srauto informacija" + +msgid "Video Stream" +msgstr "Video srautas" + +msgid "Codec" +msgstr "Kodekas" + +msgid "Aspect Ratio" +msgstr "Proporcijos" + +msgid "Frame Rate" +msgstr "Kadrų dažnis" + +msgid "Video Format" +msgstr "Video formatas" + +msgid "Resolution" +msgstr "Rezoliucija" + +msgid "Audio Stream" +msgstr "Audio srautas" + +msgid "Channel Mode" +msgstr "Kanalo bÅ«sena" + +msgid "Sampling Frequency" +msgstr "Parodomasis dažnis" + +msgid "AC-3 Stream" +msgstr "AC-3 srautas" + +msgid "Bit Stream Mode" +msgstr "Srauto bÅ«sena" + +msgid "Audio Coding Mode" +msgstr "Audio kodavimas" + +msgid "Center Mix Level" +msgstr "Centrinis mikserio lygis" + +msgid "Surround Mix Level" +msgstr "Surround Mix lygis" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround bÅ«klÄ—" + +msgid "Low Frequency Effects" +msgstr "Žemo dažnio efektai" + +msgid "Dialogue Normalization" +msgstr "Dialogo normalizacija" + msgid "basic" msgstr "Standartinis" @@ -34,9 +127,6 @@ msgid "stream" msgstr "Srautas" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Klasikinis" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Pagalba" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Audio" - -msgid "Transponder Information" -msgstr "Siųstuvo informacija" - -msgid "Apid" -msgstr "Apid" - -msgid "Dpid" -msgstr "Dpid" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "Kodavimo dažnis" - -msgid "Protocol" -msgstr "Protokolas" - -msgid "Bitrate" -msgstr "KokybÄ—" - -msgid "Stream Information" -msgstr "Srauto informacija" - -msgid "Video Stream" -msgstr "Video srautas" - -msgid "Codec" -msgstr "Kodekas" - -msgid "Aspect Ratio" -msgstr "Proporcijos" - -msgid "Frame Rate" -msgstr "Kadrų dažnis" - -msgid "Video Format" -msgstr "Video formatas" - -msgid "Resolution" -msgstr "Rezoliucija" - -msgid "Audio Stream" -msgstr "Audio srautas" - -msgid "Channel Mode" -msgstr "Kanalo bÅ«sena" - -msgid "Sampling Frequency" -msgstr "Parodomasis dažnis" - -msgid "AC-3 Stream" -msgstr "AC-3 srautas" - -msgid "Bit Stream Mode" -msgstr "Srauto bÅ«sena" - -msgid "Audio Coding Mode" -msgstr "Audio kodavimas" - -msgid "Center Mix Level" -msgstr "Centrinis mikserio lygis" - -msgid "Surround Mix Level" -msgstr "Surround Mix lygis" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround bÅ«klÄ—" - -msgid "Low Frequency Effects" -msgstr "Žemo dažnio efektai" - -msgid "Dialogue Normalization" -msgstr "Dialogo normalizacija" - msgid "Fixed" msgstr "Sutvarkyta" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/ru_RU.po vdr-plugin-femon-2.2.1.git20150307.2205/po/ru_RU.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/ru_RU.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/ru_RU.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "" +msgid "Video" +msgstr "²ØÔÕÞ" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "°ãÔØÞ" + +msgid "Transponder Information" +msgstr "ÁÒÕÔÕÝØï Þ ÚÐÝÐÛÕ" + +msgid "Apid" +msgstr "Apid" + +msgid "Dpid" +msgstr "Dpid" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "Coderate" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "" + +msgid "Stream Information" +msgstr "" + +msgid "Video Stream" +msgstr "" + +msgid "Codec" +msgstr "" + +msgid "Aspect Ratio" +msgstr "" + +msgid "Frame Rate" +msgstr "" + +msgid "Video Format" +msgstr "" + +msgid "Resolution" +msgstr "" + +msgid "Audio Stream" +msgstr "" + +msgid "Channel Mode" +msgstr "" + +msgid "Sampling Frequency" +msgstr "" + +msgid "AC-3 Stream" +msgstr "" + +msgid "Bit Stream Mode" +msgstr "" + +msgid "Audio Coding Mode" +msgstr "" + +msgid "Center Mix Level" +msgstr "" + +msgid "Surround Mix Level" +msgstr "" + +msgid "Dolby Surround Mode" +msgstr "" + +msgid "Low Frequency Effects" +msgstr "" + +msgid "Dialogue Normalization" +msgstr "" + msgid "basic" msgstr "" @@ -34,9 +127,6 @@ msgid "stream" msgstr "" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "" @@ -148,96 +238,6 @@ msgid "Help" msgstr "" -msgid "Video" -msgstr "²ØÔÕÞ" - -msgid "Audio" -msgstr "°ãÔØÞ" - -msgid "Transponder Information" -msgstr "ÁÒÕÔÕÝØï Þ ÚÐÝÐÛÕ" - -msgid "Apid" -msgstr "Apid" - -msgid "Dpid" -msgstr "Dpid" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "Coderate" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "" - -msgid "Stream Information" -msgstr "" - -msgid "Video Stream" -msgstr "" - -msgid "Codec" -msgstr "" - -msgid "Aspect Ratio" -msgstr "" - -msgid "Frame Rate" -msgstr "" - -msgid "Video Format" -msgstr "" - -msgid "Resolution" -msgstr "" - -msgid "Audio Stream" -msgstr "" - -msgid "Channel Mode" -msgstr "" - -msgid "Sampling Frequency" -msgstr "" - -msgid "AC-3 Stream" -msgstr "" - -msgid "Bit Stream Mode" -msgstr "" - -msgid "Audio Coding Mode" -msgstr "" - -msgid "Center Mix Level" -msgstr "" - -msgid "Surround Mix Level" -msgstr "" - -msgid "Dolby Surround Mode" -msgstr "" - -msgid "Low Frequency Effects" -msgstr "" - -msgid "Dialogue Normalization" -msgstr "" - msgid "Fixed" msgstr "" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/sk_SK.po vdr-plugin-femon-2.2.1.git20150307.2205/po/sk_SK.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/sk_SK.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/sk_SK.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femon nie je k dispozícii" +msgid "Video" +msgstr "Video" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Zvuk" + +msgid "Transponder Information" +msgstr "Informácie transpondéra" + +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 "rýchlos» kódovania" + +msgid "Protocol" +msgstr "Protokol" + +msgid "Bitrate" +msgstr "Dátový tok" + +msgid "Stream Information" +msgstr "Informácie o dátovom toku" + +msgid "Video Stream" +msgstr "Video stopa" + +msgid "Codec" +msgstr "kodek" + +msgid "Aspect Ratio" +msgstr "Pomer strán" + +msgid "Frame Rate" +msgstr "Poèet snímkov" + +msgid "Video Format" +msgstr "Video formát" + +msgid "Resolution" +msgstr "Rozlí¹enie" + +msgid "Audio Stream" +msgstr "Zvuková stopa" + +msgid "Channel Mode" +msgstr "re¾im kanála" + +msgid "Sampling Frequency" +msgstr "Vzorkovacia frekvencia" + +msgid "AC-3 Stream" +msgstr "AC-3 dátový tok" + +msgid "Bit Stream Mode" +msgstr "re¾im bitového toku" + +msgid "Audio Coding Mode" +msgstr "Re¾ím kódovania zvuku" + +msgid "Center Mix Level" +msgstr "Úroveò Center mix" + +msgid "Surround Mix Level" +msgstr "Úroveò Surround mix" + +msgid "Dolby Surround Mode" +msgstr "Dolby Surround re¾ím" + +msgid "Low Frequency Effects" +msgstr "Basové efekty" + +msgid "Dialogue Normalization" +msgstr "©tandartný dialóg" + msgid "basic" msgstr "©tandardtný" @@ -34,9 +127,6 @@ msgid "stream" msgstr "dátový tok" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "Klasický" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Pomoc" -msgid "Video" -msgstr "Video" - -msgid "Audio" -msgstr "Zvuk" - -msgid "Transponder Information" -msgstr "Informácie transpondéra" - -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 "rýchlos» kódovania" - -msgid "Protocol" -msgstr "Protokol" - -msgid "Bitrate" -msgstr "Dátový tok" - -msgid "Stream Information" -msgstr "Informácie o dátovom toku" - -msgid "Video Stream" -msgstr "Video stopa" - -msgid "Codec" -msgstr "kodek" - -msgid "Aspect Ratio" -msgstr "Pomer strán" - -msgid "Frame Rate" -msgstr "Poèet snímkov" - -msgid "Video Format" -msgstr "Video formát" - -msgid "Resolution" -msgstr "Rozlí¹enie" - -msgid "Audio Stream" -msgstr "Zvuková stopa" - -msgid "Channel Mode" -msgstr "re¾im kanála" - -msgid "Sampling Frequency" -msgstr "Vzorkovacia frekvencia" - -msgid "AC-3 Stream" -msgstr "AC-3 dátový tok" - -msgid "Bit Stream Mode" -msgstr "re¾im bitového toku" - -msgid "Audio Coding Mode" -msgstr "Re¾ím kódovania zvuku" - -msgid "Center Mix Level" -msgstr "Úroveò Center mix" - -msgid "Surround Mix Level" -msgstr "Úroveò Surround mix" - -msgid "Dolby Surround Mode" -msgstr "Dolby Surround re¾ím" - -msgid "Low Frequency Effects" -msgstr "Basové efekty" - -msgid "Dialogue Normalization" -msgstr "©tandartný dialóg" - msgid "Fixed" msgstr "Pevné" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/uk_UA.po vdr-plugin-femon-2.2.1.git20150307.2205/po/uk_UA.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/uk_UA.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/uk_UA.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femon не доÑтупний" +msgid "Video" +msgstr "Відео" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "Ðудіо" + +msgid "Transponder Information" +msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ транÑпондер" + +msgid "Apid" +msgstr "Apid" + +msgid "Dpid" +msgstr "Dpid" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "Шв. кодуваннÑ" + +msgid "Protocol" +msgstr "Протокол" + +msgid "Bitrate" +msgstr "Бітрейт" + +msgid "Stream Information" +msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ потік" + +msgid "Video Stream" +msgstr "Відео потік" + +msgid "Codec" +msgstr "Кодек" + +msgid "Aspect Ratio" +msgstr "Ð¡Ð¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ñторін" + +msgid "Frame Rate" +msgstr "ЧаÑтота кадрів" + +msgid "Video Format" +msgstr "Формат відео" + +msgid "Resolution" +msgstr "Роздільна здатніÑÑ‚ÑŒ" + +msgid "Audio Stream" +msgstr "Ðудіо потік" + +msgid "Channel Mode" +msgstr "Режим каналу" + +msgid "Sampling Frequency" +msgstr "ЧаÑтота" + +msgid "AC-3 Stream" +msgstr "AC-3 потік" + +msgid "Bit Stream Mode" +msgstr "Режим бітового потоку:" + +msgid "Audio Coding Mode" +msgstr "Режим ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ð»ÑŽÐ½ÐºÐ°" + +msgid "Center Mix Level" +msgstr "Рівень мікÑÑƒÐ²Ð°Ð½Ð½Ñ Ð² центрі" + +msgid "Surround Mix Level" +msgstr "Рівень мікÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ" + +msgid "Dolby Surround Mode" +msgstr "Режим Dolby Surround" + +msgid "Low Frequency Effects" +msgstr "Ефекти низької чаÑтоти" + +msgid "Dialogue Normalization" +msgstr "ÐÐ¾Ñ€Ð¼Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ–" + msgid "basic" msgstr "оÑновне" @@ -34,9 +127,6 @@ msgid "stream" msgstr "потік" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "КлаÑичний" @@ -148,96 +238,6 @@ msgid "Help" msgstr "Допомога" -msgid "Video" -msgstr "Відео" - -msgid "Audio" -msgstr "Ðудіо" - -msgid "Transponder Information" -msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ транÑпондер" - -msgid "Apid" -msgstr "Apid" - -msgid "Dpid" -msgstr "Dpid" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "Шв. кодуваннÑ" - -msgid "Protocol" -msgstr "Протокол" - -msgid "Bitrate" -msgstr "Бітрейт" - -msgid "Stream Information" -msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ потік" - -msgid "Video Stream" -msgstr "Відео потік" - -msgid "Codec" -msgstr "Кодек" - -msgid "Aspect Ratio" -msgstr "Ð¡Ð¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ñторін" - -msgid "Frame Rate" -msgstr "ЧаÑтота кадрів" - -msgid "Video Format" -msgstr "Формат відео" - -msgid "Resolution" -msgstr "Роздільна здатніÑÑ‚ÑŒ" - -msgid "Audio Stream" -msgstr "Ðудіо потік" - -msgid "Channel Mode" -msgstr "Режим каналу" - -msgid "Sampling Frequency" -msgstr "ЧаÑтота" - -msgid "AC-3 Stream" -msgstr "AC-3 потік" - -msgid "Bit Stream Mode" -msgstr "Режим бітового потоку:" - -msgid "Audio Coding Mode" -msgstr "Режим ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ð»ÑŽÐ½ÐºÐ°" - -msgid "Center Mix Level" -msgstr "Рівень мікÑÑƒÐ²Ð°Ð½Ð½Ñ Ð² центрі" - -msgid "Surround Mix Level" -msgstr "Рівень мікÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ" - -msgid "Dolby Surround Mode" -msgstr "Режим Dolby Surround" - -msgid "Low Frequency Effects" -msgstr "Ефекти низької чаÑтоти" - -msgid "Dialogue Normalization" -msgstr "ÐÐ¾Ñ€Ð¼Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð³ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ–" - msgid "Fixed" msgstr "ФікÑовано" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/zh_CN.po vdr-plugin-femon-2.2.1.git20150307.2205/po/zh_CN.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/zh_CN.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/zh_CN.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femonæ’件无法使用" +msgid "Video" +msgstr "视频" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "音频" + +msgid "Transponder Information" +msgstr "转å‘器信æ¯" + +msgid "Apid" +msgstr "Apid" + +msgid "Dpid" +msgstr "Dpid" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "ç é€ŸçŽ‡" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "比特率" + +msgid "Stream Information" +msgstr "æµä¿¡æ¯" + +msgid "Video Stream" +msgstr "视频æµ" + +msgid "Codec" +msgstr "解ç æ¨¡å¼" + +msgid "Aspect Ratio" +msgstr "纵横比" + +msgid "Frame Rate" +msgstr "帧速率" + +msgid "Video Format" +msgstr "视频制å¼" + +msgid "Resolution" +msgstr "分辨率" + +msgid "Audio Stream" +msgstr "音频æµ" + +msgid "Channel Mode" +msgstr "声é“模å¼" + +msgid "Sampling Frequency" +msgstr "采样频率" + +msgid "AC-3 Stream" +msgstr "AC-3æµ" + +msgid "Bit Stream Mode" +msgstr "比特æµæ¨¡å¼" + +msgid "Audio Coding Mode" +msgstr "音频编ç æ¨¡å¼" + +msgid "Center Mix Level" +msgstr "中心混åˆçº§åˆ«" + +msgid "Surround Mix Level" +msgstr "环绕混åˆçº§åˆ«" + +msgid "Dolby Surround Mode" +msgstr "æœæ¯”环绕声模å¼" + +msgid "Low Frequency Effects" +msgstr "低频效果" + +msgid "Dialogue Normalization" +msgstr "对è¯æ­£å¸¸åŒ–" + msgid "basic" msgstr "基本" @@ -34,9 +127,6 @@ msgid "stream" msgstr "æ•°æ®æµ" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "ç»å…¸" @@ -148,96 +238,6 @@ msgid "Help" msgstr "帮助" -msgid "Video" -msgstr "视频" - -msgid "Audio" -msgstr "音频" - -msgid "Transponder Information" -msgstr "转å‘器信æ¯" - -msgid "Apid" -msgstr "Apid" - -msgid "Dpid" -msgstr "Dpid" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "ç é€ŸçŽ‡" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "比特率" - -msgid "Stream Information" -msgstr "æµä¿¡æ¯" - -msgid "Video Stream" -msgstr "视频æµ" - -msgid "Codec" -msgstr "解ç æ¨¡å¼" - -msgid "Aspect Ratio" -msgstr "纵横比" - -msgid "Frame Rate" -msgstr "帧速率" - -msgid "Video Format" -msgstr "视频制å¼" - -msgid "Resolution" -msgstr "分辨率" - -msgid "Audio Stream" -msgstr "音频æµ" - -msgid "Channel Mode" -msgstr "声é“模å¼" - -msgid "Sampling Frequency" -msgstr "采样频率" - -msgid "AC-3 Stream" -msgstr "AC-3æµ" - -msgid "Bit Stream Mode" -msgstr "比特æµæ¨¡å¼" - -msgid "Audio Coding Mode" -msgstr "音频编ç æ¨¡å¼" - -msgid "Center Mix Level" -msgstr "中心混åˆçº§åˆ«" - -msgid "Surround Mix Level" -msgstr "环绕混åˆçº§åˆ«" - -msgid "Dolby Surround Mode" -msgstr "æœæ¯”环绕声模å¼" - -msgid "Low Frequency Effects" -msgstr "低频效果" - -msgid "Dialogue Normalization" -msgstr "对è¯æ­£å¸¸åŒ–" - msgid "Fixed" msgstr "固定" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/po/zh_TW.po vdr-plugin-femon-2.2.1.git20150307.2205/po/zh_TW.po --- vdr-plugin-femon-2.2.0.git20150222.1714/po/zh_TW.po 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/po/zh_TW.po 2015-03-07 22:05:34.000000000 +0000 @@ -25,6 +25,99 @@ msgid "Femon not available" msgstr "Femonæ’件無法使用" +msgid "Video" +msgstr "視頻" + +msgid "AC-3" +msgstr "AC-3" + +msgid "Audio" +msgstr "音頻" + +msgid "Transponder Information" +msgstr "轉發器信æ¯" + +msgid "Apid" +msgstr "Apid" + +msgid "Dpid" +msgstr "Dpid" + +msgid "Spid" +msgstr "Spid" + +msgid "Nid" +msgstr "Nid" + +msgid "Tid" +msgstr "Tid" + +msgid "Rid" +msgstr "Rid" + +msgid "Coderate" +msgstr "碼速率" + +msgid "Protocol" +msgstr "" + +msgid "Bitrate" +msgstr "比特率" + +msgid "Stream Information" +msgstr "æµä¿¡æ¯" + +msgid "Video Stream" +msgstr "視頻æµ" + +msgid "Codec" +msgstr "解碼模å¼" + +msgid "Aspect Ratio" +msgstr "縱橫比" + +msgid "Frame Rate" +msgstr "幀速率" + +msgid "Video Format" +msgstr "視頻制å¼" + +msgid "Resolution" +msgstr "分辨率" + +msgid "Audio Stream" +msgstr "音頻æµ" + +msgid "Channel Mode" +msgstr "è²é“模å¼" + +msgid "Sampling Frequency" +msgstr "採樣頻率" + +msgid "AC-3 Stream" +msgstr "AC-3æµ" + +msgid "Bit Stream Mode" +msgstr "比特æµæ¨¡å¼" + +msgid "Audio Coding Mode" +msgstr "音頻編碼模å¼" + +msgid "Center Mix Level" +msgstr "中心混åˆç´šåˆ¥" + +msgid "Surround Mix Level" +msgstr "環繞混åˆç´šåˆ¥" + +msgid "Dolby Surround Mode" +msgstr "æœæ¯”環繞è²æ¨¡å¼" + +msgid "Low Frequency Effects" +msgstr "低頻效果" + +msgid "Dialogue Normalization" +msgstr "å°è©±æ­£å¸¸åŒ–" + msgid "basic" msgstr "基本" @@ -34,9 +127,6 @@ msgid "stream" msgstr "數據æµ" -msgid "AC-3" -msgstr "AC-3" - msgid "Classic" msgstr "經典" @@ -148,96 +238,6 @@ msgid "Help" msgstr "幫助" -msgid "Video" -msgstr "視頻" - -msgid "Audio" -msgstr "音頻" - -msgid "Transponder Information" -msgstr "轉發器信æ¯" - -msgid "Apid" -msgstr "Apid" - -msgid "Dpid" -msgstr "Dpid" - -msgid "Spid" -msgstr "Spid" - -msgid "Nid" -msgstr "Nid" - -msgid "Tid" -msgstr "Tid" - -msgid "Rid" -msgstr "Rid" - -msgid "Coderate" -msgstr "碼速率" - -msgid "Protocol" -msgstr "" - -msgid "Bitrate" -msgstr "比特率" - -msgid "Stream Information" -msgstr "æµä¿¡æ¯" - -msgid "Video Stream" -msgstr "視頻æµ" - -msgid "Codec" -msgstr "解碼模å¼" - -msgid "Aspect Ratio" -msgstr "縱橫比" - -msgid "Frame Rate" -msgstr "幀速率" - -msgid "Video Format" -msgstr "視頻制å¼" - -msgid "Resolution" -msgstr "分辨率" - -msgid "Audio Stream" -msgstr "音頻æµ" - -msgid "Channel Mode" -msgstr "è²é“模å¼" - -msgid "Sampling Frequency" -msgstr "採樣頻率" - -msgid "AC-3 Stream" -msgstr "AC-3æµ" - -msgid "Bit Stream Mode" -msgstr "比特æµæ¨¡å¼" - -msgid "Audio Coding Mode" -msgstr "音頻編碼模å¼" - -msgid "Center Mix Level" -msgstr "中心混åˆç´šåˆ¥" - -msgid "Surround Mix Level" -msgstr "環繞混åˆç´šåˆ¥" - -msgid "Dolby Surround Mode" -msgstr "æœæ¯”環繞è²æ¨¡å¼" - -msgid "Low Frequency Effects" -msgstr "低頻效果" - -msgid "Dialogue Normalization" -msgstr "å°è©±æ­£å¸¸åŒ–" - msgid "Fixed" msgstr "固定" diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/receiver.c vdr-plugin-femon-2.2.1.git20150307.2205/receiver.c --- vdr-plugin-femon-2.2.0.git20150222.1714/receiver.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/receiver.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,252 @@ +/* + * receiver.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include + +#include "config.h" +#include "log.h" +#include "tools.h" +#include "receiver.h" + +cFemonReceiver::cFemonReceiver(const cChannel *channelP, int aTrackP, int dTrackP) +: cReceiver(channelP), + cThread("femon receiver"), + mutexM(), + sleepM(), + activeM(false), + detectH264M(this), + detectMpegM(this, this), + detectAacM(this), + detectLatmM(this), + detectAc3M(this), + videoBufferM(KILOBYTE(512), TS_SIZE, false, "Femon video"), + videoTypeM(channelP ? channelP->Vtype(): 0), + videoPidM(channelP ? channelP->Vpid() : 0), + videoPacketCountM(0), + videoBitRateM(0.0), + videoValidM(false), + audioBufferM(KILOBYTE(256), TS_SIZE, false, "Femon audio"), + audioPidM(channelP ? channelP->Apid(aTrackP) : 0), + audioPacketCountM(0), + audioBitRateM(0.0), + audioValidM(false), + ac3BufferM(KILOBYTE(256), TS_SIZE, false, "Femon AC3"), + ac3PidM(channelP ? channelP->Dpid(dTrackP) : 0), + ac3PacketCountM(0), + ac3BitRateM(0), + ac3ValidM(false) +{ + debug1("%s (, %d, %d)", __PRETTY_FUNCTION__, aTrackP, dTrackP); + + SetPids(NULL); + AddPid(videoPidM); + AddPid(audioPidM); + AddPid(ac3PidM); + + videoBufferM.SetTimeouts(0, 100); + audioBufferM.SetTimeouts(0, 100); + ac3BufferM.SetTimeouts(0, 100); + + videoInfoM.codec = VIDEO_CODEC_INVALID; + videoInfoM.format = VIDEO_FORMAT_INVALID; + videoInfoM.scan = VIDEO_SCAN_INVALID; + videoInfoM.aspectRatio = VIDEO_ASPECT_RATIO_INVALID; + videoInfoM.width = 0; + videoInfoM.height = 0; + videoInfoM.frameRate = 0; + videoInfoM.bitrate = AUDIO_BITRATE_INVALID; + audioInfoM.codec = AUDIO_CODEC_UNKNOWN; + audioInfoM.bitrate = AUDIO_BITRATE_INVALID; + audioInfoM.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; + audioInfoM.channelMode = AUDIO_CHANNEL_MODE_INVALID; + ac3InfoM.bitrate = AUDIO_BITRATE_INVALID; + ac3InfoM.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; + ac3InfoM.bitstreamMode = AUDIO_BITSTREAM_MODE_INVALID; + ac3InfoM.audioCodingMode = AUDIO_CODING_MODE_INVALID; + ac3InfoM.dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + ac3InfoM.centerMixLevel = AUDIO_CENTER_MIX_LEVEL_INVALID; + ac3InfoM.surroundMixLevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; + ac3InfoM.dialogLevel = 0; + ac3InfoM.lfe = false; +} + +cFemonReceiver::~cFemonReceiver(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + Deactivate(); +} + +void cFemonReceiver::Deactivate(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + Detach(); + if (activeM) { + activeM = false; + sleepM.Signal(); + if (Running()) + Cancel(3); + } +} + +void cFemonReceiver::Activate(bool onP) +{ + debug1("%s (%d)", __PRETTY_FUNCTION__, onP); + if (onP) + Start(); + else + Deactivate(); +} + +void cFemonReceiver::Receive(uchar *dataP, int lengthP) +{ + // TS packet length: TS_SIZE + if (Running() && (*dataP == TS_SYNC_BYTE) && (lengthP == TS_SIZE)) { + int len, pid = TsPid(dataP); + if (pid == videoPidM) { + ++videoPacketCountM; + len = videoBufferM.Put(dataP, lengthP); + if (len != lengthP) { + videoBufferM.ReportOverflow(lengthP - len); + videoBufferM.Clear(); + } + } + else if (pid == audioPidM) { + ++audioPacketCountM; + len = audioBufferM.Put(dataP, lengthP); + if (len != lengthP) { + audioBufferM.ReportOverflow(lengthP - len); + audioBufferM.Clear(); + } + } + else if (pid == ac3PidM) { + ++ac3PacketCountM; + len = ac3BufferM.Put(dataP, lengthP); + if (len != lengthP) { + ac3BufferM.ReportOverflow(lengthP - len); + ac3BufferM.Clear(); + } + } + } +} + +void cFemonReceiver::Action(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + cTimeMs calcPeriod(0); + activeM = true; + + while (Running() && activeM) { + uint8_t *Data; + double timeout; + int len, Length; + bool processed = false; + + // process available video data + while ((Data = videoBufferM.Get(Length))) { + if (!activeM || (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; + } + } + videoBufferM.Del(Length); + continue; + } + processed = true; + if (TsPayloadStart(Data)) { + while (const uint8_t *p = videoAssemblerM.GetPes(len)) { + if (videoTypeM == 0x1B) { // MPEG4 + if (detectH264M.processVideo(p, len)) { + videoValidM = true; + break; + } + } + else { + if (detectMpegM.processVideo(p, len)) { + videoValidM = true; + break; + } + } + } + videoAssemblerM.Reset(); + } + videoAssemblerM.PutTs(Data, Length); + videoBufferM.Del(Length); + } + + // process available audio data + while ((Data = audioBufferM.Get(Length))) { + if (!activeM || (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; + } + } + audioBufferM.Del(Length); + continue; + } + processed = true; + if (const uint8_t *p = audioAssemblerM.GetPes(len)) { + if (detectAacM.processAudio(p, len) || detectLatmM.processAudio(p, len) || detectMpegM.processAudio(p, len)) + audioValidM = true; + audioAssemblerM.Reset(); + } + audioAssemblerM.PutTs(Data, Length); + audioBufferM.Del(Length); + } + + // process available dolby data + while ((Data = ac3BufferM.Get(Length))) { + if (!activeM || (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; + } + } + ac3BufferM.Del(Length); + continue; + } + processed = true; + if (const uint8_t *p = ac3AssemblerM.GetPes(len)) { + if (detectAc3M.processAudio(p, len)) + ac3ValidM = true; + ac3AssemblerM.Reset(); + } + ac3AssemblerM.PutTs(Data, Length); + ac3BufferM.Del(Length); + } + + // calculate bitrates + timeout = double(calcPeriod.Elapsed()); + if (activeM && (timeout >= (100.0 * FemonConfig.GetCalcInterval()))) { + // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit + // PES headers should be compensated! + videoBitRateM = (1000.0 * 8.0 * 184.0 * videoPacketCountM) / timeout; + videoPacketCountM = 0; + audioBitRateM = (1000.0 * 8.0 * 184.0 * audioPacketCountM) / timeout; + audioPacketCountM = 0; + ac3BitRateM = (1000.0 * 8.0 * 184.0 * ac3PacketCountM) / timeout; + ac3PacketCountM = 0; + calcPeriod.Set(0); + } + + if (!processed) + sleepM.Wait(10); // to avoid busy loop and reduce cpu load + } +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/receiver.h vdr-plugin-femon-2.2.1.git20150307.2205/receiver.h --- vdr-plugin-femon-2.2.0.git20150222.1714/receiver.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/receiver.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,178 @@ +/* + * receiver.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_RECEIVER_H +#define __FEMON_RECEIVER_H + +#include +#include + +#include "aac.h" +#include "ac3.h" +#include "audio.h" +#include "h264.h" +#include "latm.h" +#include "mpeg.h" +#include "tools.h" +#include "video.h" + +class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If { +private: + cMutex mutexM; + cCondWait sleepM; + bool activeM; + + cFemonH264 detectH264M; + cFemonMPEG detectMpegM; + cFemonAAC detectAacM; + cFemonLATM detectLatmM; + cFemonAC3 detectAc3M; + + cRingBufferLinear videoBufferM; + cTsToPes videoAssemblerM; + int videoTypeM; + int videoPidM; + int videoPacketCountM; + double videoBitRateM; + bool videoValidM; + video_info_t videoInfoM; + + cRingBufferLinear audioBufferM; + cTsToPes audioAssemblerM; + int audioPidM; + int audioPacketCountM; + double audioBitRateM; + bool audioValidM; + audio_info_t audioInfoM; + + cRingBufferLinear ac3BufferM; + cTsToPes ac3AssemblerM; + int ac3PidM; + int ac3PacketCountM; + double ac3BitRateM; + bool ac3ValidM; + ac3_info_t ac3InfoM; + +protected: + virtual void Activate(bool onP); + virtual void Receive(uchar *dataP, int lengthP); + virtual void Action(void); + +public: + virtual void SetVideoCodec(eVideoCodec codecP) { cMutexLock MutexLock(&mutexM); + videoInfoM.codec = codecP; } + virtual void SetVideoFormat(eVideoFormat formatP) { cMutexLock MutexLock(&mutexM); + videoInfoM.format = formatP; } + virtual void SetVideoScan(eVideoScan scanP) { cMutexLock MutexLock(&mutexM); + videoInfoM.scan = scanP; } + virtual void SetVideoAspectRatio(eVideoAspectRatio aspectRatioP) { cMutexLock MutexLock(&mutexM); + videoInfoM.aspectRatio = aspectRatioP; } + virtual void SetVideoSize(int widthP, int heightP) { cMutexLock MutexLock(&mutexM); + videoInfoM.width = widthP; + videoInfoM.height = heightP; } + virtual void SetVideoFramerate(double frameRateP) { cMutexLock MutexLock(&mutexM); + videoInfoM.frameRate = frameRateP; } + virtual void SetVideoBitrate(double bitRateP) { cMutexLock MutexLock(&mutexM); + videoInfoM.bitrate = bitRateP; } + + virtual void SetAudioCodec(eAudioCodec codecP) { cMutexLock MutexLock(&mutexM); + audioInfoM.codec = codecP; } + virtual void SetAudioBitrate(double bitRateP) { cMutexLock MutexLock(&mutexM); + audioInfoM.bitrate = bitRateP; } + virtual void SetAudioSamplingFrequency(int samplingP) { cMutexLock MutexLock(&mutexM); + audioInfoM.samplingFrequency = samplingP; } + virtual void SetAudioChannel(eAudioChannelMode modeP) { cMutexLock MutexLock(&mutexM); + audioInfoM.channelMode = modeP; } + + virtual void SetAC3Bitrate(int bitRateP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.bitrate = bitRateP; } + virtual void SetAC3SamplingFrequency(int samplingP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.samplingFrequency = samplingP; } + virtual void SetAC3Bitstream(int modeP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.bitstreamMode = modeP; } + virtual void SetAC3AudioCoding(int modeP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.audioCodingMode = modeP; } + virtual void SetAC3DolbySurround(int modeP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.dolbySurroundMode = modeP; } + virtual void SetAC3CenterMix(int levelP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.centerMixLevel = levelP; } + virtual void SetAC3SurroundMix(int levelP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.surroundMixLevel = levelP; } + virtual void SetAC3Dialog(int levelP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.dialogLevel = levelP; } + virtual void SetAC3LFE(bool onoffP) { cMutexLock MutexLock(&mutexM); + ac3InfoM.lfe = onoffP; } + +public: + cFemonReceiver(const cChannel* channelP, int aTrackp, int dTrackP); + virtual ~cFemonReceiver(); + void Deactivate(void); + + bool VideoValid(void) { cMutexLock MutexLock(&mutexM); + return videoValidM; }; // boolean + double VideoBitrate(void) { cMutexLock MutexLock(&mutexM); + return videoBitRateM; }; // bit/s + int VideoCodec(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.codec; }; // eVideoCodec + int VideoFormat(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.format; }; // eVideoFormat + int VideoScan(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.scan; }; // eVideoScan + int VideoAspectRatio(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.aspectRatio; }; // eVideoAspectRatio + int VideoHorizontalSize(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.width; }; // pixels + int VideoVerticalSize(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.height; }; // pixels + double VideoFrameRate(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.frameRate; }; // Hz + double VideoStreamBitrate(void) { cMutexLock MutexLock(&mutexM); + return videoInfoM.bitrate; }; // bit/s + + bool AudioValid(void) { cMutexLock MutexLock(&mutexM); + return audioValidM; }; // boolean + double AudioBitrate(void) { cMutexLock MutexLock(&mutexM); + return audioBitRateM; }; // bit/s + int AudioCodec(void) { cMutexLock MutexLock(&mutexM); + return audioInfoM.codec; }; // eAudioCodec + int AudioChannelMode(void) { cMutexLock MutexLock(&mutexM); + return audioInfoM.channelMode; }; // eAudioChannelMode + double AudioStreamBitrate(void) { cMutexLock MutexLock(&mutexM); + return audioInfoM.bitrate; }; // bit/s or eAudioBitrate + int AudioSamplingFreq(void) { cMutexLock MutexLock(&mutexM); + return audioInfoM.samplingFrequency; }; // Hz or eAudioSamplingFrequency + + bool AC3Valid(void) { cMutexLock MutexLock(&mutexM); + return ac3ValidM; }; // boolean + double AC3Bitrate(void) { cMutexLock MutexLock(&mutexM); + return ac3BitRateM; }; // bit/s + double AC3StreamBitrate(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.bitrate; }; // bit/s or eAudioBitrate + int AC3SamplingFreq(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.samplingFrequency; }; // Hz or eAudioSamplingFrequency + int AC3BitStreamMode(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.bitstreamMode; }; // 0..7 or eAudioBitstreamMode + int AC3AudioCodingMode(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.audioCodingMode; }; // 0..7 or eAudioCodingMode + bool AC3_2_0(void) { cMutexLock MutexLock(&mutexM); + return (ac3InfoM.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean + bool AC3_5_1(void) { cMutexLock MutexLock(&mutexM); + return (ac3InfoM.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean + int AC3DolbySurroundMode(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.dolbySurroundMode; }; // eAudioDolbySurroundMode + int AC3CenterMixLevel(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.centerMixLevel; }; // eAudioCenterMixLevel + int AC3SurroundMixLevel(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.surroundMixLevel; }; // eAudioSurroundMixLevel + int AC3DialogLevel(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.dialogLevel; }; // -dB + bool AC3Lfe(void) { cMutexLock MutexLock(&mutexM); + return ac3InfoM.lfe; }; // boolean + }; + +#endif //__FEMON_RECEIVER_H + diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/setup.c vdr-plugin-femon-2.2.1.git20150307.2205/setup.c --- vdr-plugin-femon-2.2.0.git20150222.1714/setup.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/setup.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,162 @@ +/* + * setup.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include + +#include "config.h" +#include "log.h" +#include "tools.h" +#include "setup.h" + +cMenuFemonSetup::cMenuFemonSetup() +: hideMenuM(FemonConfig.GetHideMenu()), + displayModeM(FemonConfig.GetDisplayMode()), + skinM(FemonConfig.GetSkin()), + themeM(FemonConfig.GetTheme()), + positionM(FemonConfig.GetPosition()), + downscaleM(FemonConfig.GetDownscale()), + redLimitM(FemonConfig.GetRedLimit()), + greenLimitM(FemonConfig.GetGreenLimit()), + updateIntervalM(FemonConfig.GetUpdateInterval()), + analyzeStreamM(FemonConfig.GetAnalyzeStream()), + calcIntervalM(FemonConfig.GetCalcInterval()), + useSvdrpM(FemonConfig.GetUseSvdrp()), + svdrpPortM(FemonConfig.GetSvdrpPort()) +{ + 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"); + + 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(); +} + +void cMenuFemonSetup::Setup(void) +{ + int current = Current(); + + Clear(); + helpM.Clear(); + + Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &hideMenuM)); + helpM.Append(tr("Define whether the main menu entry is hidden.")); + + Add(new cMenuEditStraItem(tr("Default display mode"), &displayModeM, eFemonModeMaxNumber, dispModesM)); + helpM.Append(tr("Define the default display mode at startup.")); + + Add(new cMenuEditStraItem(trVDR("Setup.OSD$Skin"), &skinM, eFemonSkinMaxNumber, skinsM)); + helpM.Append(tr("Define the used OSD skin.")); + + Add(new cMenuEditStraItem(trVDR("Setup.OSD$Theme"), &themeM, eFemonThemeMaxNumber, themesM)); + helpM.Append(tr("Define the used OSD theme.")); + + Add(new cMenuEditBoolItem(tr("Position"), &positionM, trVDR("bottom"), trVDR("top"))); + helpM.Append(tr("Define the position of OSD.")); + + Add(new cMenuEditIntItem(tr("Downscale OSD size [%]"), &downscaleM, 0, 20)); + helpM.Append(tr("Define the downscale ratio for OSD size.")); + + 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.")); + + Add(new cMenuEditIntItem(tr("Green limit [%]"), &greenLimitM, 51, 100)); + helpM.Append(tr("Define a limit for green bar, which is used to indicate a good signal.")); + + Add(new cMenuEditIntItem(tr("OSD update interval [0.1s]"), &updateIntervalM, 1, 100)); + helpM.Append(tr("Define an interval for OSD updates. The smaller interval generates higher CPU load.")); + + Add(new cMenuEditBoolItem(tr("Analyze stream"), &analyzeStreamM)); + helpM.Append(tr("Define whether the DVB stream is analyzed and bitrates calculated.")); + + if (analyzeStreamM) { + Add(new cMenuEditIntItem(tr("Calculation interval [0.1s]"), &calcIntervalM, 1, 100)); + helpM.Append(tr("Define an interval for calculation. The bigger interval generates more stable values.")); + } + + Add(new cMenuEditBoolItem(tr("Use SVDRP service"), &useSvdrpM)); + helpM.Append(tr("Define whether the SVDRP service is used in client/server setups.")); + + if (useSvdrpM) { + Add(new cMenuEditIntItem(tr("SVDRP service port"), &svdrpPortM, 1, 65535)); + helpM.Append(tr("Define the port number of SVDRP service.")); + + Add(new cMenuEditStrItem(tr("SVDRP service IP"), svdrpIpM, sizeof(svdrpIpM), ".1234567890")); + helpM.Append(tr("Define the IP address of SVDRP service.")); + } + + SetCurrent(Get(current)); + Display(); +} + +void cMenuFemonSetup::Store(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + // Store values into setup.conf + SetupStore("HideMenu", hideMenuM); + SetupStore("DisplayMode", displayModeM); + SetupStore("Skin", skinM); + SetupStore("Theme", themeM); + SetupStore("Position", positionM); + SetupStore("Downscale", downscaleM); + SetupStore("RedLimit", redLimitM); + SetupStore("GreenLimit", greenLimitM); + SetupStore("UpdateInterval", updateIntervalM); + SetupStore("AnalStream", analyzeStreamM); + SetupStore("CalcInterval", calcIntervalM); + SetupStore("UseSvdrp", useSvdrpM); + SetupStore("ServerPort", svdrpPortM); + SetupStore("ServerIp", svdrpIpM); + // Update global config + FemonConfig.SetHideMenu(hideMenuM); + FemonConfig.SetDisplayMode(displayModeM); + FemonConfig.SetSkin(skinM); + FemonConfig.SetTheme(themeM); + FemonConfig.SetPosition(positionM); + FemonConfig.SetDownscale(downscaleM); + FemonConfig.SetRedLimit(redLimitM); + FemonConfig.SetGreenLimit(greenLimitM); + FemonConfig.SetUpdateInterval(updateIntervalM); + FemonConfig.SetAnalyzeStream(analyzeStreamM); + FemonConfig.SetCalcInterval(calcIntervalM); + FemonConfig.SetUseSvdrp(useSvdrpM); + FemonConfig.SetSvdrpPort(svdrpPortM); + FemonConfig.SetSvdrpIp(svdrpIpM); +} + +eOSState cMenuFemonSetup::ProcessKey(eKeys keyP) +{ + int oldUseSvdrp = useSvdrpM; + int oldAnalyzeStream = analyzeStreamM; + + eOSState state = cMenuSetupPage::ProcessKey(keyP); + + if (keyP != kNone && (analyzeStreamM != oldAnalyzeStream || useSvdrpM != oldUseSvdrp)) + Setup(); + + if ((keyP == kInfo) && (state == osUnknown) && (Current() < helpM.Size())) + return AddSubMenu(new cMenuText(cString::sprintf("%s - %s '%s'", tr("Help"), trVDR("Plugin"), PLUGIN_NAME_I18N), helpM[Current()])); + + return state; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/setup.h vdr-plugin-femon-2.2.1.git20150307.2205/setup.h --- vdr-plugin-femon-2.2.0.git20150222.1714/setup.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/setup.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * setup.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_SETUP_H +#define __FEMON_SETUP_H + +class cMenuFemonSetup : public cMenuSetupPage { +private: + const char *dispModesM[eFemonModeMaxNumber]; + const char *skinsM[eFemonSkinMaxNumber]; + const char *themesM[eFemonThemeMaxNumber]; + cVector helpM; + int hideMenuM; + int displayModeM; + int skinM; + int themeM; + int positionM; + int downscaleM; + int redLimitM; + int greenLimitM; + int updateIntervalM; + int analyzeStreamM; + int calcIntervalM; + int useSvdrpM; + int svdrpPortM; + char svdrpIpM[MaxSvdrpIp + 1]; // must end with additional null + void Setup(void); + +protected: + virtual eOSState ProcessKey(eKeys Key); + virtual void Store(void); + +public: + cMenuFemonSetup(); +}; + +#endif // __FEMON_SETUP_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/svdrpservice.h vdr-plugin-femon-2.2.1.git20150307.2205/svdrpservice.h --- vdr-plugin-femon-2.2.0.git20150222.1714/svdrpservice.h 2015-02-22 17:15:02.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/svdrpservice.h 2015-03-07 22:05:34.000000000 +0000 @@ -11,11 +11,11 @@ class cLine: public cListObject { private: - char *Line; + char *lineM; public: - const char *Text() { return Line; } - cLine(const char *s) { Line = s ? strdup(s) : NULL; }; - virtual ~cLine() { if (Line) free(Line); }; + const char *Text() { return lineM; } + cLine(const char *strP) { lineM = strP ? strdup(strP) : NULL; }; + virtual ~cLine() { if (lineM) free(lineM); }; }; struct SvdrpConnection_v1_0 { diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/symbol.c vdr-plugin-femon-2.2.1.git20150307.2205/symbol.c --- vdr-plugin-femon-2.2.0.git20150222.1714/symbol.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/symbol.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,212 @@ +/* + * symbol.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include + +#include "log.h" +#include "tools.h" +#include "symbol.h" + +#include "symbols/stereo.xpm" +#include "symbols/monoleft.xpm" +#include "symbols/monoright.xpm" +#include "symbols/dolbydigital.xpm" +#include "symbols/dolbydigital20.xpm" +#include "symbols/dolbydigital51.xpm" +#include "symbols/mpeg2.xpm" +#include "symbols/h264.xpm" +#include "symbols/ntsc.xpm" +#include "symbols/pal.xpm" +#include "symbols/encrypted.xpm" +#include "symbols/svdrp.xpm" +#include "symbols/lock.xpm" +#include "symbols/signal.xpm" +#include "symbols/carrier.xpm" +#include "symbols/viterbi.xpm" +#include "symbols/sync.xpm" +#include "symbols/ar11.xpm" +#include "symbols/ar169.xpm" +#include "symbols/ar2211.xpm" +#include "symbols/ar43.xpm" +#include "symbols/device.xpm" +#include "symbols/zero.xpm" +#include "symbols/one.xpm" +#include "symbols/two.xpm" +#include "symbols/three.xpm" +#include "symbols/four.xpm" +#include "symbols/five.xpm" +#include "symbols/six.xpm" +#include "symbols/seven.xpm" +#include "symbols/eight.xpm" +#include "symbols/format1080.xpm" +#include "symbols/format1080i.xpm" +#include "symbols/format1080p.xpm" +#include "symbols/format720.xpm" +#include "symbols/format720i.xpm" +#include "symbols/format720p.xpm" +#include "symbols/format576.xpm" +#include "symbols/format576i.xpm" +#include "symbols/format576p.xpm" +#include "symbols/format480.xpm" +#include "symbols/format480i.xpm" +#include "symbols/format480p.xpm" + +static cBitmap bmOnePixel(1, 1, 1); +static cBitmap bmStereo(stereo_xpm); +static cBitmap bmMonoLeft(monoleft_xpm); +static cBitmap bmMonoRight(monoright_xpm); +static cBitmap bmDolbyDigital(dolbydigital_xpm); +static cBitmap bmDolbyDigital20(dolbydigital20_xpm); +static cBitmap bmDolbyDigital51(dolbydigital51_xpm); +static cBitmap bmMpeg2(mpeg2_xpm); +static cBitmap bmH264(h264_xpm); +static cBitmap bmPal(pal_xpm); +static cBitmap bmNtsc(ntsc_xpm); +static cBitmap bmEncrypted(encrypted_xpm); +static cBitmap bmSvdrp(svdrp_xpm); +static cBitmap bmLock(lock_xpm); +static cBitmap bmSignal(signal_xpm); +static cBitmap bmCarrier(carrier_xpm); +static cBitmap bmViterbi(viterbi_xpm); +static cBitmap bmSync(sync_xpm); +static cBitmap bmAspectRatio11(ar11_xpm); +static cBitmap bmAspectRatio169(ar169_xpm); +static cBitmap bmAspectRatio2211(ar2211_xpm); +static cBitmap bmAspectRatio43(ar43_xpm); +static cBitmap bmDevice(device_xpm); +static cBitmap bmZero(zero_xpm); +static cBitmap bmOne(one_xpm); +static cBitmap bmTwo(two_xpm); +static cBitmap bmThree(three_xpm); +static cBitmap bmFour(four_xpm); +static cBitmap bmFive(five_xpm); +static cBitmap bmSix(six_xpm); +static cBitmap bmSeven(seven_xpm); +static cBitmap bmEight(eight_xpm); +static cBitmap bmFormat1080(format1080_xpm); +static cBitmap bmFormat1080i(format1080i_xpm); +static cBitmap bmFormat1080p(format1080p_xpm); +static cBitmap bmFormat720(format720_xpm); +static cBitmap bmFormat720i(format720i_xpm); +static cBitmap bmFormat720p(format720p_xpm); +static cBitmap bmFormat576(format576_xpm); +static cBitmap bmFormat576i(format576i_xpm); +static cBitmap bmFormat576p(format576p_xpm); +static cBitmap bmFormat480(format480_xpm); +static cBitmap bmFormat480i(format480i_xpm); +static cBitmap bmFormat480p(format480p_xpm); + +cFemonSymbolCache femonSymbols; + +cFemonSymbolCache::cFemonSymbolCache() +: xFactorM(1.0), + yFactorM(1.0), + antiAliasM(false) +{ + Populate(); +} + +cFemonSymbolCache::~cFemonSymbolCache() +{ + Flush(); +} + +void cFemonSymbolCache::Refresh() +{ + int width, height; + double aspect, xfactor, yfactor; + cDevice::PrimaryDevice()->GetOsdSize(width, height, aspect); + debug1("%s width=%d height=%d", __PRETTY_FUNCTION__, width, height); + xfactor = (double)width / DEFAULT_WIDTH; + yfactor = (double)height / DEFAULT_HEIGHT; + if (!DoubleEqual(xfactor, xFactorM) || !DoubleEqual(yfactor, yFactorM)) { + xFactorM = xfactor; + yFactorM = yfactor; + Populate(); + } +} + +bool cFemonSymbolCache::Populate(void) +{ + debug1("%s xFactor=%.02f yFactor=%.02f", __PRETTY_FUNCTION__, xFactorM, yFactorM); + if (!DoubleEqual(0.0, xFactorM) || !DoubleEqual(0.0, yFactorM)) { + Flush(); + + // pushing order must follow the enumeration - keep original proportions except for frontend status ones + cacheM.Append(bmOnePixel.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ONEPIXEL + cacheM.Append(bmStereo.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_STEREO + cacheM.Append(bmMonoLeft.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MONO_LEFT + cacheM.Append(bmMonoRight.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MONO_RIGHT + cacheM.Append(bmDolbyDigital.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD + cacheM.Append(bmDolbyDigital20.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD20 + 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(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 + cacheM.Append(bmSvdrp.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_SVDRP + cacheM.Append(bmLock.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_LOCK + cacheM.Append(bmSignal.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_SIGNAL + cacheM.Append(bmCarrier.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_CARRIER + cacheM.Append(bmViterbi.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_VITERBI + cacheM.Append(bmSync.Scaled(xFactorM, yFactorM, antiAliasM)); // SYMBOL_SYNC + cacheM.Append(bmAspectRatio11.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_1_1 + cacheM.Append(bmAspectRatio169.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_16_9 + cacheM.Append(bmAspectRatio2211.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_2_21_1 + cacheM.Append(bmAspectRatio43.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_AR_4_3 + cacheM.Append(bmDevice.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DEVICE + cacheM.Append(bmZero.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ZERO + cacheM.Append(bmOne.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ONE + cacheM.Append(bmTwo.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_TWO + cacheM.Append(bmThree.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_THREE + cacheM.Append(bmFour.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FOUR + cacheM.Append(bmFive.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FIVE + 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(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 + cacheM.Append(bmFormat720.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720 + cacheM.Append(bmFormat720i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720i + cacheM.Append(bmFormat720p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_720p + cacheM.Append(bmFormat576.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576 + cacheM.Append(bmFormat576i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576i + cacheM.Append(bmFormat576p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_576p + cacheM.Append(bmFormat480.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480 + cacheM.Append(bmFormat480i.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480i + cacheM.Append(bmFormat480p.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_FORMAT_480p + + return true; + } + + return false; +} + +bool cFemonSymbolCache::Flush(void) +{ + debug1("%s", __PRETTY_FUNCTION__); + for (int i = 0; i < cacheM.Size(); ++i) { + cBitmap *bmp = cacheM[i]; + DELETENULL(bmp); + } + cacheM.Clear(); + return true; +} + +cBitmap& cFemonSymbolCache::Get(eSymbols symbolP) +{ + cBitmap *bitmapM = cacheM[SYMBOL_ONEPIXEL]; + + if (symbolP < cacheM.Size()) + bitmapM = cacheM[symbolP]; + else + error("%s (%d) Invalid symbol", __PRETTY_FUNCTION__, symbolP); + + return *bitmapM; +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/symbol.h vdr-plugin-femon-2.2.1.git20150307.2205/symbol.h --- vdr-plugin-femon-2.2.0.git20150222.1714/symbol.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/symbol.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * symbol.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_SYMBOL_H +#define __FEMON_SYMBOL_H + +#include +#include + +enum eSymbols { + SYMBOL_ONEPIXEL, + SYMBOL_STEREO, + SYMBOL_MONO_LEFT, + SYMBOL_MONO_RIGHT, + SYMBOL_DD, + SYMBOL_DD20, + SYMBOL_DD51, + SYMBOL_MPEG2, + SYMBOL_H264, + SYMBOL_PAL, + SYMBOL_NTSC, + SYMBOL_ENCRYPTED, + SYMBOL_SVDRP, + SYMBOL_LOCK, + SYMBOL_SIGNAL, + SYMBOL_CARRIER, + SYMBOL_VITERBI, + SYMBOL_SYNC, + SYMBOL_AR_1_1, + SYMBOL_AR_16_9, + SYMBOL_AR_2_21_1, + SYMBOL_AR_4_3, + SYMBOL_DEVICE, + SYMBOL_ZERO, + SYMBOL_ONE, + SYMBOL_TWO, + SYMBOL_THREE, + SYMBOL_FOUR, + SYMBOL_FIVE, + SYMBOL_SIX, + SYMBOL_SEVEN, + SYMBOL_EIGHT, + SYMBOL_FORMAT_1080, + SYMBOL_FORMAT_1080i, + SYMBOL_FORMAT_1080p, + SYMBOL_FORMAT_720, + SYMBOL_FORMAT_720i, + SYMBOL_FORMAT_720p, + SYMBOL_FORMAT_576, + SYMBOL_FORMAT_576i, + SYMBOL_FORMAT_576p, + SYMBOL_FORMAT_480, + SYMBOL_FORMAT_480i, + SYMBOL_FORMAT_480p, + SYMBOL_MAX_COUNT + }; + +class cFemonSymbolCache { +private: + enum { + DEFAULT_SPACING = 5, + DEFAULT_ROUNDING = 10, + DEFAULT_HEIGHT = 576, + DEFAULT_WIDTH = 720 + }; + double xFactorM; + double yFactorM; + bool antiAliasM; + cVector cacheM; + bool Populate(void); + bool Flush(void); +public: + cFemonSymbolCache(); + ~cFemonSymbolCache(); + void Refresh(); + cBitmap& Get(eSymbols symbolP); + int GetSpacing() { return int(yFactorM * cFemonSymbolCache::DEFAULT_SPACING); } + int GetRounding() { return int(yFactorM * cFemonSymbolCache::DEFAULT_ROUNDING); } +}; + +extern cFemonSymbolCache femonSymbols; + +#endif // __FEMON_SYMBOL_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/tools.c vdr-plugin-femon-2.2.1.git20150307.2205/tools.c --- vdr-plugin-femon-2.2.0.git20150222.1714/tools.c 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/tools.c 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,613 @@ +/* + * tools.c: Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include +#include +#include +#include + +#include "osd.h" +#include "receiver.h" +#include "tools.h" + +static cString getCA(int valueP) +{ + // http://www.dvb.org/index.php?id=174 + // http://en.wikipedia.org/wiki/Conditional_access_system + switch (valueP) { + case 0x0000: return cString::sprintf("%s (%X)", trVDR("Free To Air"), valueP); // Reserved + case 0x0001 ... 0x009F: + case 0x00A2 ... 0x00FF: return cString::sprintf("%s (%X)", tr("Fixed"), valueP); // Standardized systems + case 0x00A0 ... 0x00A1: return cString::sprintf("%s (%X)", tr("Analog"), valueP); // Analog signals + case 0x0100 ... 0x01FF: return cString::sprintf("SECA Mediaguard (%X)", valueP); // Canal Plus + case 0x0464: return cString::sprintf("EuroDec (%X)", valueP); // EuroDec + case 0x0500 ... 0x05FF: return cString::sprintf("Viaccess (%X)", valueP); // France Telecom + case 0x0600 ... 0x06FF: return cString::sprintf("Irdeto (%X)", valueP); // Irdeto + case 0x0700 ... 0x07FF: return cString::sprintf("DigiCipher 2 (%X)", valueP); // Jerrold/GI/Motorola 4DTV + case 0x0900 ... 0x09FF: return cString::sprintf("NDS Videoguard (%X)", valueP); // NDS + case 0x0B00 ... 0x0BFF: return cString::sprintf("Conax (%X)", valueP); // Norwegian Telekom + case 0x0D00 ... 0x0DFF: return cString::sprintf("CryptoWorks (%X)", valueP); // Philips CryptoTec + case 0x0E00 ... 0x0EFF: return cString::sprintf("PowerVu (%X)", valueP); // Scientific Atlanta + case 0x1000: return cString::sprintf("RAS (%X)", valueP); // Tandberg Television + case 0x1200 ... 0x12FF: return cString::sprintf("NagraVision (%X)", valueP); // BellVu Express + case 0x1700 ... 0x17FF: return cString::sprintf("VCAS (%X)", valueP); // Verimatrix Inc. former BetaTechnik + case 0x1800 ... 0x18FF: return cString::sprintf("NagraVision (%X)", valueP); // Kudelski SA + case 0x22F0: return cString::sprintf("Codicrypt (%X)", valueP); // Scopus Network Technologies + case 0x2600: return cString::sprintf("BISS (%X)", valueP); // European Broadcasting Union + case 0x2719: return cString::sprintf("VanyaCas (%X)", valueP); // S-Curious Research & Technology Pvt. Ltd. + case 0x4347: return cString::sprintf("CryptOn (%X)", valueP); // CryptOn + case 0x4800: return cString::sprintf("Accessgate (%X)", valueP); // Telemann + case 0x4900: return cString::sprintf("China Crypt (%X)", valueP); // CryptoWorks + case 0x4A02: return cString::sprintf("Tongfang (%X)", valueP); // Tsinghua Tongfang Company + case 0x4A10: return cString::sprintf("EasyCas (%X)", valueP); // EasyCas + case 0x4A20: return cString::sprintf("AlphaCrypt (%X)", valueP); // AlphaCrypt + case 0x4A60: return cString::sprintf("SkyCrypt (%X)", valueP); // @Sky + case 0x4A61: return cString::sprintf("Neotioncrypt (%X)", valueP); // Neotion + case 0x4A62: return cString::sprintf("SkyCrypt (%X)", valueP); // @Sky + case 0x4A63: return cString::sprintf("Neotion SHL (%X)", valueP); // Neotion + case 0x4A64 ... 0x4A6F: return cString::sprintf("SkyCrypt (%X)", valueP); // @Sky + case 0x4A70: return cString::sprintf("DreamCrypt (%X)", valueP); // Dream Multimedia + case 0x4A80: return cString::sprintf("ThalesCrypt (%X)", valueP); // Thales Broadcast & Multimedia + case 0x4AA1: return cString::sprintf("KeyFly (%X)", valueP); // SIDSA + case 0x4ABF: return cString::sprintf("CTI-CAS (%X)", valueP); // Beijing Compunicate Technology Inc. + case 0x4AC1: return cString::sprintf("Latens (%X)", valueP); // Latens Systems + case 0x4AD0 ... 0x4AD1: return cString::sprintf("X-Crypt (%X)", valueP); // XCrypt Inc. + case 0x4AD4: return cString::sprintf("OmniCrypt (%X)", valueP); // Widevine Technologies, Inc. + case 0x4AE0 ... 0x4AE1: return cString::sprintf("Z-Crypt (%X)", valueP); // Digi Raum Electronics Co. Ltd. + case 0x4AE4: return cString::sprintf("CoreCrypt (%X)", valueP); // CoreTrust + case 0x4AE5: return cString::sprintf("PRO-Crypt (%X)", valueP); // IK SATPROF + case 0x4AEA: return cString::sprintf("Cryptoguard (%X)", valueP); // Gryptoguard AB + case 0x4AEB: return cString::sprintf("Abel Quintic (%X)", valueP); // Abel DRM Systems + case 0x4AF0: return cString::sprintf("ABV (%X)", valueP); // Alliance Broadcast Vision + case 0x5500: return cString::sprintf("Z-Crypt (%X)", valueP); // Digi Raum Electronics Co. Ltd. + case 0x5501: return cString::sprintf("Griffin (%X)", valueP); // Nucleus Systems Ltd. + case 0x5581: return cString::sprintf("Bulcrypt (%X)", valueP); // Bulcrypt + case 0x7BE1: return cString::sprintf("DRE-Crypt (%X)", valueP); // DRE-Crypt + case 0xA101: return cString::sprintf("RosCrypt-M (%X)", valueP); // NIIR + case 0xEAD0: return cString::sprintf("VanyaCas (%X)", valueP); // S-Curious Research & Technology Pvt. Ltd. + default: break; + } + return cString::sprintf("%X", valueP); +} + +static const char *getUserString(int valueP, const tDvbParameterMap *mapP) +{ + const tDvbParameterMap *map = mapP; + while (map && map->userValue != -1) { + if (map->driverValue == valueP) + return map->userString ? trVDR(map->userString) : "---"; + map++; + } + return "---"; +} + +cDvbDevice *getDvbDevice(cDevice* deviceP) +{ + cDvbDevice *dev = dynamic_cast(deviceP); +#ifdef __DYNAMIC_DEVICE_PROBE + if (!dev && deviceP && deviceP->HasSubDevice()) + dev = dynamic_cast(deviceP->SubDevice()); +#endif + return dev; +} + +cString getFrontendInfo(cDvbDevice *deviceP) +{ + struct dvb_frontend_info value; + fe_status_t status; + cString info = ""; + uint16_t signal = 0; + uint16_t snr = 0; + uint32_t ber = 0; + uint32_t unc = 0; + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + + 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); + + if (cFemonOsd::Instance()) + info = cString::sprintf("%s\nVIBR:%.0f\nAUBR:%.0f\nDDBR:%.0f", *info, cFemonOsd::Instance()->GetVideoBitrate(), cFemonOsd::Instance()->GetAudioBitrate(), cFemonOsd::Instance()->GetDolbyBitrate()); + + if (channel) + info = cString::sprintf("%s\nCHAN:%s", *info, *channel->ToText()); + + return info; +} + +cString getFrontendName(cDvbDevice *deviceP) +{ + if (!deviceP) + return NULL; + + return (cString::sprintf("%s on deviceP #%d", *deviceP->DeviceName(), deviceP->CardIndex())); +} + +cString getFrontendStatus(cDvbDevice *deviceP) +{ + fe_status_t value; + + if (!deviceP) + return NULL; + + 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())); +} + +uint16_t getSignal(cDvbDevice *deviceP) +{ + uint16_t value = 0; + + if (!deviceP) + return (value); + + 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); +} + +uint16_t getSNR(cDvbDevice *deviceP) +{ + uint16_t value = 0; + + if (!deviceP) + return (value); + + 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); +} + +uint32_t getBER(cDvbDevice *deviceP) +{ + uint32_t value = 0; + + if (!deviceP) + return (value); + + 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); +} + +uint32_t getUNC(cDvbDevice *deviceP) +{ + uint32_t value = 0; + + if (!deviceP) + return (value); + + 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 (value); +} + +cString getApids(const cChannel *channelP) +{ + int value = 0; + cString apids = cString::sprintf("%d", channelP->Apid(value)); + while (channelP->Apid(++value) && (value < MAXAPIDS)) + apids = cString::sprintf("%s, %d", *apids, channelP->Apid(value)); + return apids; +} + +cString getDpids(const cChannel *channelP) +{ + int value = 0; + cString dpids = cString::sprintf("%d", channelP->Dpid(value)); + while (channelP->Dpid(++value) && (value < MAXDPIDS)) + dpids = cString::sprintf("%s, %d", *dpids, channelP->Dpid(value)); + return dpids; +} + +cString getSpids(const cChannel *channelP) +{ + int value = 0; + cString spids = cString::sprintf("%d", channelP->Spid(value)); + while (channelP->Spid(++value) && (value < MAXSPIDS)) + spids = cString::sprintf("%s, %d", *spids, channelP->Spid(value)); + return spids; +} + +cString getCAids(const cChannel *channelP) +{ + int value = 0; + cString caids = cString::sprintf("%s", *getCA(channelP->Ca(value))); + while (channelP->Ca(++value) && (value < MAXCAIDS)) + caids = cString::sprintf("%s, %s", *caids, *getCA(channelP->Ca(value))); + return caids; +} + +cString getVideoStream(int value) +{ + if (value != 0) + return cString::sprintf("#%d", value); + return cString::sprintf("---"); +} + +cString getAudioStream(int valueP, const cChannel *channelP) +{ + int pid = 0; + if (IS_AUDIO_TRACK(valueP)) + pid = int(valueP - ttAudioFirst); + if (channelP && channelP->Apid(pid)) { + if (channelP->Alang(pid)) + return cString::sprintf("#%d (%s)", channelP->Apid(pid), channelP->Alang(pid)); + else + return cString::sprintf("#%d", channelP->Apid(pid)); + } + return cString::sprintf("---"); +} + +cString getAC3Stream(int valueP, const cChannel *channelP) +{ + int pid = 0; + if (IS_DOLBY_TRACK(valueP)) + pid = int(valueP - ttDolbyFirst); + if (channelP && channelP->Dpid(pid)) { + if (channelP->Dlang(pid)) + return cString::sprintf("#%d (%s)", channelP->Dpid(pid), channelP->Dlang(pid)); + else + return cString::sprintf("#%d", channelP->Dpid(pid)); + } + return cString::sprintf("---"); +} + +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")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAudioCodec(int valueP) +{ + switch (valueP) { + case AUDIO_CODEC_MPEG1_I: return cString::sprintf("%s", tr("MPEG-1 Layer I")); + case AUDIO_CODEC_MPEG1_II: return cString::sprintf("%s", tr("MPEG-1 Layer II")); + case AUDIO_CODEC_MPEG1_III: return cString::sprintf("%s", tr("MPEG-1 Layer III")); + case AUDIO_CODEC_MPEG2_I: return cString::sprintf("%s", tr("MPEG-2 Layer I")); + case AUDIO_CODEC_MPEG2_II: return cString::sprintf("%s", tr("MPEG-2 Layer II")); + case AUDIO_CODEC_MPEG2_III: return cString::sprintf("%s", tr("MPEG-2 Layer III")); + case AUDIO_CODEC_HEAAC: return cString::sprintf("%s", tr("HE-AAC")); + case AUDIO_CODEC_LATM: return cString::sprintf("%s", tr("LATM")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAudioChannelMode(int valueP) +{ + switch (valueP) { + case AUDIO_CHANNEL_MODE_STEREO: return cString::sprintf("%s", tr("stereo")); + case AUDIO_CHANNEL_MODE_JOINT_STEREO: return cString::sprintf("%s", tr("joint Stereo")); + case AUDIO_CHANNEL_MODE_DUAL: return cString::sprintf("%s", tr("dual")); + case AUDIO_CHANNEL_MODE_SINGLE: return cString::sprintf("%s", tr("mono")); + default: break; + } + return cString::sprintf("---"); +} + +cString getCoderate(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, CoderateValues)); +} + +cString getTransmission(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, TransmissionValues)); +} + +cString getBandwidth(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, BandwidthValues)); +} + +cString getInversion(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, InversionValues)); +} + +cString getHierarchy(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, HierarchyValues)); +} + +cString getGuard(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, GuardValues)); +} + +cString getModulation(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, ModulationValues)); +} + +cString getTerrestrialSystem(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, SystemValuesTerr)); +} + +cString getSatelliteSystem(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, SystemValuesSat)); +} + +cString getRollOff(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, RollOffValues)); +} + +cString getPilot(int valueP) +{ + return cString::sprintf("%s", getUserString(valueP, PilotValues)); +} + +cString getResolution(int widthP, int heightP, int scanP) +{ + if ((widthP > 0) && (heightP > 0)) { + switch (scanP) { + case VIDEO_SCAN_INTERLACED: return cString::sprintf("%dx%d %s", widthP, heightP, tr("interlaced")); + case VIDEO_SCAN_PROGRESSIVE: return cString::sprintf("%dx%d %s", widthP, heightP, tr("progressive")); + default: return cString::sprintf("%dx%d", widthP, heightP); + } + } + return cString::sprintf("---"); +} + +cString getAspectRatio(int valueP) +{ + switch (valueP) { + case VIDEO_ASPECT_RATIO_RESERVED: return cString::sprintf("%s", tr("reserved")); + case VIDEO_ASPECT_RATIO_EXTENDED: return cString::sprintf("%s", tr("extended")); + case VIDEO_ASPECT_RATIO_1_1: return cString::sprintf("1:1"); + case VIDEO_ASPECT_RATIO_4_3: return cString::sprintf("4:3"); + case VIDEO_ASPECT_RATIO_16_9: return cString::sprintf("16:9"); + case VIDEO_ASPECT_RATIO_2_21_1: return cString::sprintf("2.21:1"); + case VIDEO_ASPECT_RATIO_12_11: return cString::sprintf("12:11"); + case VIDEO_ASPECT_RATIO_10_11: return cString::sprintf("10:11"); + case VIDEO_ASPECT_RATIO_16_11: return cString::sprintf("16:11"); + case VIDEO_ASPECT_RATIO_40_33: return cString::sprintf("40:33"); + case VIDEO_ASPECT_RATIO_24_11: return cString::sprintf("24:11"); + case VIDEO_ASPECT_RATIO_20_11: return cString::sprintf("20:11"); + case VIDEO_ASPECT_RATIO_32_11: return cString::sprintf("32:11"); + case VIDEO_ASPECT_RATIO_80_33: return cString::sprintf("80:33"); + case VIDEO_ASPECT_RATIO_18_11: return cString::sprintf("18:11"); + case VIDEO_ASPECT_RATIO_15_11: return cString::sprintf("15:11"); + case VIDEO_ASPECT_RATIO_64_33: return cString::sprintf("64:33"); + case VIDEO_ASPECT_RATIO_160_99: return cString::sprintf("160:99"); + case VIDEO_ASPECT_RATIO_3_2: return cString::sprintf("3:2"); + case VIDEO_ASPECT_RATIO_2_1: return cString::sprintf("2:1"); + default: break; + } + return cString::sprintf("---"); +} + +cString getVideoFormat(int valueP) +{ + switch (valueP) { + case VIDEO_FORMAT_UNKNOWN: return cString::sprintf("%s", tr("unknown")); + case VIDEO_FORMAT_RESERVED: return cString::sprintf("%s", tr("reserved")); + case VIDEO_FORMAT_COMPONENT: return cString::sprintf("%s", tr("component")); + case VIDEO_FORMAT_PAL: return cString::sprintf("%s", tr("PAL")); + case VIDEO_FORMAT_NTSC: return cString::sprintf("%s", tr("NTSC")); + case VIDEO_FORMAT_SECAM: return cString::sprintf("%s", tr("SECAM")); + case VIDEO_FORMAT_MAC: return cString::sprintf("%s", tr("MAC")); + default: break; + } + return cString::sprintf("---"); +} + +cString getFrameRate(double valueP) +{ + if (valueP > 0) + return cString::sprintf("%.2f %s", valueP, tr("Hz")); + return cString::sprintf("---"); +} + +cString getAC3BitStreamMode(int valueP, int codingP) +{ + switch (valueP) { + case AUDIO_BITSTREAM_MODE_CM: return cString::sprintf("%s", tr("Complete Main (CM)")); + case AUDIO_BITSTREAM_MODE_ME: return cString::sprintf("%s", tr("Music and Effects (ME)")); + case AUDIO_BITSTREAM_MODE_VI: return cString::sprintf("%s", tr("Visually Impaired (VI)")); + case AUDIO_BITSTREAM_MODE_HI: return cString::sprintf("%s", tr("Hearing Impaired (HI)")); + case AUDIO_BITSTREAM_MODE_D: return cString::sprintf("%s", tr("Dialogue (D)")); + case AUDIO_BITSTREAM_MODE_C: return cString::sprintf("%s", tr("Commentary (C)")); + case AUDIO_BITSTREAM_MODE_E: return cString::sprintf("%s", tr("Emergency (E)")); + case AUDIO_BITSTREAM_MODE_VO_KAR: return cString::sprintf("%s", (codingP == 1) ? tr("Voice Over (VO)") : tr("Karaoke")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAC3AudioCodingMode(int valueP, int streamP) +{ + if (streamP != 7) { + switch (valueP) { + case AUDIO_CODING_MODE_1_1: return cString::sprintf("1+1 - %s, %s", tr("Ch1"), tr("Ch2")); + case AUDIO_CODING_MODE_1_0: return cString::sprintf("1/0 - %s", tr("C")); + case AUDIO_CODING_MODE_2_0: return cString::sprintf("2/0 - %s, %s", tr("L"), tr("R")); + case AUDIO_CODING_MODE_3_0: return cString::sprintf("3/0 - %s, %s, %s", tr("L"), tr("C"), tr("R")); + case AUDIO_CODING_MODE_2_1: return cString::sprintf("2/1 - %s, %s, %s", tr("L"), tr("R"), tr("S")); + case AUDIO_CODING_MODE_3_1: return cString::sprintf("3/1 - %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("S")); + case AUDIO_CODING_MODE_2_2: return cString::sprintf("2/2 - %s, %s, %s, %s", tr("L"), tr("R"), tr("SL"), tr("SR")); + case AUDIO_CODING_MODE_3_2: return cString::sprintf("3/2 - %s, %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("SL"), tr("SR")); + default: break; + } + } + return cString::sprintf("---"); +} + +cString getAC3CenterMixLevel(int valueP) +{ + switch (valueP) { + case AUDIO_CENTER_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3.0 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB: return cString::sprintf("-4.5 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6.0 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAC3SurroundMixLevel(int valueP) +{ + switch (valueP) { + case AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_0_dB: return cString::sprintf("0 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAC3DolbySurroundMode(int valueP) +{ + switch (valueP) { + case AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED: return cString::sprintf("%s", tr("not indicated")); + case AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND: return cString::sprintf("%s", trVDR("no")); + case AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND: return cString::sprintf("%s", trVDR("yes")); + case AUDIO_DOLBY_SURROUND_MODE_RESERVED: return cString::sprintf("%s", tr("reserved")); + default: break; + } + return cString::sprintf("---"); +} + +cString getAC3DialogLevel(int valueP) +{ + if (valueP > 0) + return cString::sprintf("-%d %s", valueP, tr("dB")); + return cString::sprintf("---"); +} + +cString getFrequencyMHz(int valueP) +{ + double freq = valueP; + while (freq > 20000.0) freq /= 1000.0; + return cString::sprintf("%s %s", *dtoa(freq, "%lg"), tr("MHz")); +} + +cString getAudioSamplingFreq(int valueP) +{ + switch (valueP) { + case AUDIO_SAMPLING_FREQUENCY_INVALID: return cString::sprintf("---"); + case AUDIO_SAMPLING_FREQUENCY_RESERVED: return cString::sprintf("%s", tr("reserved")); + default: break; + } + return cString::sprintf("%d %s", valueP, tr("Hz")); +} + +cString getAudioBitrate(double valueP, double streamP) +{ + switch ((int)streamP) { + case AUDIO_BITRATE_INVALID: return cString::sprintf("---"); + case AUDIO_BITRATE_RESERVED: return cString::sprintf("%s (%s)", tr("reserved"), *getBitrateKbits(valueP)); + case AUDIO_BITRATE_FREE: return cString::sprintf("%s (%s)", tr("free"), *getBitrateKbits(valueP)); + default: break; + } + return cString::sprintf("%s (%s)", *getBitrateKbits(streamP), *getBitrateKbits(valueP)); +} + +cString getVideoBitrate(double valueP, double streamP) +{ + return cString::sprintf("%s (%s)", *getBitrateMbits(streamP), *getBitrateMbits(valueP)); +} + +cString getBitrateMbits(double valueP) +{ + if (valueP > 0) + return cString::sprintf("%.2f %s", valueP / 1000000.0, tr("Mbit/s")); + return cString::sprintf("---"); +} + +cString getBitrateKbits(double valueP) +{ + if (valueP > 0) + return cString::sprintf("%.0f %s", valueP / 1000.0, tr("kbit/s")); + return cString::sprintf("---"); +} + +// --- cFemonBitStream ------------------------------------------------------- + +uint32_t cFemonBitStream::GetUeGolomb() +{ + int n = 0; + + while (!GetBit() && (n < 32)) + n++; + + return (n ? ((1 << n) - 1) + GetBits(n) : 0); +} + +int32_t cFemonBitStream::GetSeGolomb() +{ + uint32_t r = GetUeGolomb() + 1; + + return ((r & 1) ? -(r >> 1) : (r >> 1)); +} + +void cFemonBitStream::SkipGolomb() +{ + int n = 0; + + while (!GetBit() && (n < 32)) + n++; + + SkipBits(n); +} diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/tools.h vdr-plugin-femon-2.2.1.git20150307.2205/tools.h --- vdr-plugin-femon-2.2.0.git20150222.1714/tools.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/tools.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,83 @@ +/* + * tools.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_COMMON_H +#define __FEMON_COMMON_H + +#include +#include +#include +#include +#include + +#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) + +#define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" + +#define SATIP_DEVICE "SAT>IP" + +cDvbDevice *getDvbDevice(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); + +cString getApids(const cChannel *channelP); +cString getDpids(const cChannel *channelP); +cString getSpids(const cChannel *channelP); +cString getCAids(const cChannel *channelP); +cString getVideoStream(int valueP); +cString getVideoCodec(int valueP); +cString getAudioStream(int valueP, const cChannel *channelP); +cString getAudioCodec(int valueP); +cString getAudioChannelMode(int valueP); +cString getCoderate(int valueP); +cString getTransmission(int valueP); +cString getBandwidth(int valueP); +cString getInversion(int valueP); +cString getHierarchy(int valueP); +cString getGuard(int valueP); +cString getModulation(int valueP); +cString getTerrestrialSystem(int valueP); +cString getSatelliteSystem(int valueP); +cString getRollOff(int valueP); +cString getPilot(int valueP); +cString getResolution(int widthP, int heightP, int scanP); +cString getAspectRatio(int valueP); +cString getVideoFormat(int valueP); +cString getFrameRate(double valueP); +cString getAC3Stream(int valueP, const cChannel *channelP); +cString getAC3BitStreamMode(int valueP, int codingP); +cString getAC3AudioCodingMode(int valueP, int streamP); +cString getAC3CenterMixLevel(int valueP); +cString getAC3SurroundMixLevel(int valueP); +cString getAC3DolbySurroundMode(int valueP); +cString getAC3DialogLevel(int valueP); +cString getFrequencyMHz(int valueP); +cString getAudioSamplingFreq(int valueP); +cString getAudioBitrate(double valueP, double streamP); +cString getVideoBitrate(double valueP, double streamP); +cString getBitrateMbits(double valueP); +cString getBitrateKbits(double valueP); + +class cFemonBitStream : public cBitStream { +public: + cFemonBitStream(const uint8_t *dataP, const int lengthP) : cBitStream(dataP, lengthP) {} + uint32_t GetUeGolomb(); + int32_t GetSeGolomb(); + void SkipGolomb(); + void SkipUeGolomb() { SkipGolomb(); } + void SkipSeGolomb() { SkipGolomb(); } + }; + +#endif // __FEMON_COMMON_H diff -Nru vdr-plugin-femon-2.2.0.git20150222.1714/video.h vdr-plugin-femon-2.2.1.git20150307.2205/video.h --- vdr-plugin-femon-2.2.0.git20150222.1714/video.h 1970-01-01 00:00:00.000000000 +0000 +++ vdr-plugin-femon-2.2.1.git20150307.2205/video.h 2015-03-07 22:05:34.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * video.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_VIDEO_H +#define __FEMON_VIDEO_H + +enum eVideoCodec { + VIDEO_CODEC_INVALID = -1, + VIDEO_CODEC_UNKNOWN, + VIDEO_CODEC_MPEG2, + VIDEO_CODEC_H264 + }; + +enum eVideoFormat { + VIDEO_FORMAT_INVALID = -1, + VIDEO_FORMAT_UNKNOWN, + VIDEO_FORMAT_RESERVED, + VIDEO_FORMAT_COMPONENT, + VIDEO_FORMAT_PAL, + VIDEO_FORMAT_NTSC, + VIDEO_FORMAT_SECAM, + VIDEO_FORMAT_MAC + }; + +enum eVideoScan { + VIDEO_SCAN_INVALID = -1, + VIDEO_SCAN_UNKNOWN, + VIDEO_SCAN_RESERVED, + VIDEO_SCAN_INTERLACED, + VIDEO_SCAN_PROGRESSIVE + }; + +enum eVideoAspectRatio { + VIDEO_ASPECT_RATIO_INVALID = -1, + VIDEO_ASPECT_RATIO_RESERVED, + VIDEO_ASPECT_RATIO_EXTENDED, + VIDEO_ASPECT_RATIO_1_1, + VIDEO_ASPECT_RATIO_4_3, + VIDEO_ASPECT_RATIO_16_9, + VIDEO_ASPECT_RATIO_2_21_1, + VIDEO_ASPECT_RATIO_12_11, + VIDEO_ASPECT_RATIO_10_11, + VIDEO_ASPECT_RATIO_16_11, + VIDEO_ASPECT_RATIO_40_33, + VIDEO_ASPECT_RATIO_24_11, + VIDEO_ASPECT_RATIO_20_11, + VIDEO_ASPECT_RATIO_32_11, + VIDEO_ASPECT_RATIO_80_33, + VIDEO_ASPECT_RATIO_18_11, + VIDEO_ASPECT_RATIO_15_11, + VIDEO_ASPECT_RATIO_64_33, + VIDEO_ASPECT_RATIO_160_99, + VIDEO_ASPECT_RATIO_3_2, + VIDEO_ASPECT_RATIO_2_1 + }; + +typedef struct video_info { + eVideoCodec codec; // enum + eVideoFormat format; // enum + eVideoScan scan; // enum + eVideoAspectRatio aspectRatio; // enum + int width; // pixels + int height; // pixels + double frameRate; // Hz + double bitrate; // bit/s +} video_info_t; + +class cFemonVideoIf { +public: + cFemonVideoIf() {} + virtual ~cFemonVideoIf() {} + + // eVideoCodec + virtual void SetVideoCodec(eVideoCodec codecP) = 0; + // eVideoFormat + virtual void SetVideoFormat(eVideoFormat formatP) = 0; + // eVideoScan + virtual void SetVideoScan(eVideoScan scanP) = 0; + // eVideoAspectRatio + virtual void SetVideoAspectRatio(eVideoAspectRatio aspectRatioP) = 0; + // pixels + virtual void SetVideoSize(int widthP, int heightP) = 0; + // Hz + virtual void SetVideoFramerate(double frameRateP) = 0; + // Mbit/s + virtual void SetVideoBitrate(double bitRateP) = 0; + }; + +#endif //__FEMON_VIDEO_H