diff --git a/HISTORY b/HISTORY index 63e4bf6..6b108d8 100644 --- a/HISTORY +++ b/HISTORY @@ -54,6 +54,10 @@ VDR Plugin 'femon' Revision History - Backported changes and fixes from version 0.1.2. +2004-06-11: Version 0.0.6 + +- Backported the "AC3 Stream Information" feature from version 0.1.3. + ------------------------- 2004-05-18: Version 0.1.0 @@ -73,3 +77,7 @@ VDR Plugin 'femon' Revision History - Fixed the channel switch bug (reported by Stefan Lucke). - Nid/Tid/Rid are now included in translations. - Added video format and aspect ratio symbols into status window. + +2004-06-11: Version 0.1.3 + +- Added "AC-3 Stream Information" display mode (Thanks to Lothar Englisch). diff --git a/README b/README index ae6611e..52369cc 100644 --- a/README +++ b/README @@ -10,9 +10,7 @@ See the file COPYING for license information. Requirements: -Ph.D. in Astro Physics and preferably a six-pack waiting in a fridge. -Never trust a Klingon. "Qu'vaD lI' De'vam". Beam me up, Scotty! -You're number six! I'm number two. YARRR! +VDR & DVB. BMW & Ph.D.. BEER. YARRR! Description: @@ -30,7 +28,41 @@ bitrate calculation algorithm originates from the 'dvbstream' application by Dave Chapman and the stream information routines from the 'libdvb' library by Metzler Brothers. -Shortcomings / Todo list / Important Notes: +Terminology: + +-------------------------------------------------------------- +|## Channel Name ############################# DD 16:9 PAL ##| +|[=====Signal Strength in % =============|=================]| +|[=====Signal-to-Noise Ratio in % ========|=================]| +| STR: #0000 (0%) BER: #00000000 Video: 0 Mbit/s | +| SNR: #0000 (0%) UNC: #00000000 Audio: 0 kbit/s | +| [LOCK] [SIGNAL] [CARRIER] [VITERBI] [SYNC] | +-------------------------------------------------------------- + +STR - Signal strength +SNR - Signal-to-noise ratio +BER - Bit error rate +UNC - Uncorrected blocks +Video - Calculated video bitrate in Mbit/s +Audio - Calculated audio / AC-3 bitrate in kbit/s (only first PID) + +LOCK - Everything's working... +SIGNAL - Found something above the noise level +CARRIER - Found a DVB signal +VITERBI - FEC (forward error correction) is stable +SYNC - Found sync bytes + +Installation: + +cd /put/your/path/here/VDR/PLUGINS/src +tar -xzf /put/your/path/here/vdr-femon-X.Y.Z.tar.gz +ln -s femon-X.Y.Z femon +cd /put/your/path/here/VDR +make +make plugins +./vdr -Pfemon + +Notes: - The plugin supports only those DVB cards with _one_ frontend (do any cards with multiple frontends even exist?), because I haven't yet figured howto do diff --git a/femon.c b/femon.c index f73cfb6..83e42f4 100644 --- a/femon.c +++ b/femon.c @@ -85,9 +85,10 @@ bool cPluginFemon::SetupParse(const char *Name, const char *Value) cMenuFemonSetup::cMenuFemonSetup(void) { - dispmodes[0] = tr("basic"); - dispmodes[1] = tr("transponder"); - dispmodes[2] = tr("stream"); + dispmodes[modeBasic] = tr("basic"); + dispmodes[modeTransponder] = tr("transponder"); + dispmodes[modeStream] = tr("stream"); + dispmodes[modeAC3] = tr("AC-3"); Setup(); } diff --git a/femon.h b/femon.h index 0cad3a3..d63957b 100644 --- a/femon.h +++ b/femon.h @@ -11,7 +11,7 @@ #include -static const char *VERSION = "0.1.2"; +static const char *VERSION = "0.1.3"; static const char *DESCRIPTION = "DVB Signal Information Monitor (OSD)"; static const char *MAINMENUENTRY = "Signal Information"; diff --git a/femoncfg.h b/femoncfg.h index b8a9407..cf5f5b3 100644 --- a/femoncfg.h +++ b/femoncfg.h @@ -13,6 +13,7 @@ enum dispModes { modeBasic, modeTransponder, modeStream, + modeAC3, modeMaxNumber }; diff --git a/femoni18n.c b/femoni18n.c index aaeddaa..0961ce9 100644 --- a/femoni18n.c +++ b/femoni18n.c @@ -940,25 +940,6 @@ const tI18nPhrase Phrases[] = { "Ú³æ", // ÀãááÚØÙ (Russian) "kHz", // Hrvatski (Croatian) }, - { "MPEG Layer", // English - "MPEG Layer", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "MPEG-kerros", // suomi - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Romaneste - "", // Magyar - "", // Català - "", // ÀãááÚØÙ (Russian) - "", // Hrvatski (Croatian) - }, { "Nid", // English "Nid", // Deutsch "Nid", // Slovenski @@ -1016,5 +997,556 @@ const tI18nPhrase Phrases[] = { "Rid", // ÀãááÚØÙ (Russian) "Rid", // Hrvatski (Croatian) }, + { "dB", // English + "dB", // Deutsch + "dB", // Slovenski + "dB", // Italiano + "dB", // Nederlands + "dB", // Português + "dB", // Français + "dB", // Norsk + "dB", // suomi + "dB", // Polski + "dB", // Español + "dB", // ÅëëçíéêÜ (Greek) + "dB", // Svenska + "dB", // Romaneste + "dB", // Magyar + "dB", // Català + "dB", // ÀãááÚØÙ (Russian) + "dB", // Hrvatski (Croatian) + }, + { "not indicated", // English + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "ei ilmaistu", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "AC-3", // English + "AC-3", // Deutsch + "AC-3", // Slovenski + "AC-3", // Italiano + "AC-3", // Nederlands + "AC-3", // Português + "AC-3", // Français + "AC-3", // Norsk + "AC-3", // suomi + "AC-3", // Polski + "AC-3", // Español + "AC-3", // ÅëëçíéêÜ (Greek) + "AC-3", // Svenska + "AC-3", // Romaneste + "AC-3", // Magyar + "AC-3", // Català + "AC-3", // ÀãááÚØÙ (Russian) + "AC-3", // Hrvatski (Croatian) + }, + { "AC-3 Stream", // English + "AC-3 Stream", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "AC-3 ääniraita", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Frame Size", // English + "Frame Größe", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kehyksen koko", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Bit Stream Mode", // English + "Bitstream Modus", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Lähetteen tyyppi", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Audio Coding Mode", // English + "Audio Coding Modus", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Äänikoodaus", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Center Mix Level", // English + "Center Mix Pegel", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Keskikanavan taso", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Surround Mix Level", // English + "Surround Mix Pegel", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Tehostekanavien taso", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Dolby Surround Mode", // English + "Dolby Surround Modus", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Dolby Surround -moodi", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Low Frequency Effects", // English + "Tieftöner Effekte", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "LFE-kanava", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Dialogue Normalization", // English + "Dialog Normalisierung", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Dialogin normalisointi", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Complete Main (CM)", // English + "Complete Main (CM)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Pääasiallinen (CM)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Music and Effects (ME)", // English + "Musik und Effekte (ME)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Musiikki ja tehosteet (ME)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Visually Impaired (VI)", // English + "Sehbehindert (VI)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Näkörajoitteinen (VI)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Hearing Impaired (HI)", // English + "Hörbehindert (HI)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kuulorajoitteinen (HI)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Dialogue (D)", // English + "Dialog (D)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Vuoropuhelu (D)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Commentary (C)", // English + "Kommentar (C)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kommentointi (C)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Emergency (E)", // English + "Notfall (E)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Hätätiedote (E)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Voice Over (VO)", // English + "überlagerte Stimme (VO)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Päälle puhuttu (VO)", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Karaoke", // English + "Karaoke", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Karaoke", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Ch1", // English "Channel 1" + "Kan1", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "kan. 1", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "Ch2", // English "Channel 2" + "Kan2", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "kan. 2", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "C", // English "Center" + "C", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "K", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "L", // English "Left" + "L", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "V", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "R", // English "Right" + "R", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "O", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "S", // English "Surround" + "S", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "T", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "SL", // English "Surround Left" + "SL", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "TV", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, + { "SR", // English "Surround Right" + "SR", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "TO", // suomi + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català + "", // ÀãááÚØÙ (Russian) + "", // Hrvatski (Croatian) + }, { NULL } }; diff --git a/femonosd.c b/femonosd.c index ed3425a..72aa27b 100644 --- a/femonosd.c +++ b/femonosd.c @@ -18,6 +18,9 @@ #include "symbols/ar43.xpm" #include "symbols/ntsc.xpm" #include "symbols/pal.xpm" +#include "symbols/dolbydigital.xpm" +#include "symbols/dolbydigital20.xpm" +#include "symbols/dolbydigital51.xpm" #define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" #define CHANNELINPUT_TIMEOUT 1000 @@ -45,6 +48,9 @@ cBitmap cFemonOsd::bmAspectRatio_2_21_1(ar2211_xpm); cBitmap cFemonOsd::bmAspectRatio_4_3(ar43_xpm); cBitmap cFemonOsd::bmPAL(pal_xpm); cBitmap cFemonOsd::bmNTSC(ntsc_xpm); +cBitmap cFemonOsd::bmDD(dolbydigital_xpm); +cBitmap cFemonOsd::bmDD20(dolbydigital20_xpm); +cBitmap cFemonOsd::bmDD51(dolbydigital51_xpm); cFemonOsd::cFemonOsd(void) :cOsdObject(true), cThread("femon osd") @@ -135,6 +141,26 @@ void cFemonOsd::DrawStatusWindow(void) if (y < 0) y = 0; m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmAspectRatio_2_21_1, clrBlack, clrWhite); } + if (m_Receiver && m_Receiver->AC3Valid()) { + if (m_Receiver->AC3_5_1()) { + x -= bmDD51.Width() + SPACING; + y = (m_Font->Height() - bmDD51.Height()) / 2; + if (y < 0) y = 0; + m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmDD51, clrBlack, clrWhite); + } + else if (m_Receiver->AC3_2_0()) { + x -= bmDD20.Width() + SPACING; + y = (m_Font->Height() - bmDD20.Height()) / 2; + if (y < 0) y = 0; + m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmDD20, clrBlack, clrWhite); + } + else { + x -= bmDD.Width() + SPACING; + y = (m_Font->Height() - bmDD.Height()) / 2; + if (y < 0) y = 0; + m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmDD, clrBlack, clrWhite); + } + } } offset += m_Font->Height(); if (signal > 0) { @@ -181,9 +207,9 @@ void cFemonOsd::DrawStatusWindow(void) m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), "UNC:", clrWhite, clrBackground, m_Font); snprintf(buf, sizeof(buf), "%08x", m_UNC); m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font); - snprintf(buf, sizeof(buf), "%s:", tr("Audio")); + snprintf(buf, sizeof(buf), "%s:", (m_Receiver && m_Receiver->AC3Valid()) ? tr("AC-3") : tr("Audio")); m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font); - if (m_Receiver) snprintf(buf, sizeof(buf), "%.0f %s", m_Receiver->AudioBitrate(), tr("kbit/s")); + if (m_Receiver) snprintf(buf, sizeof(buf), "%.0f %s", m_Receiver->AC3Valid() ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate(), tr("kbit/s")); else snprintf(buf, sizeof(buf), "--- %s", tr("kbit/s")); m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), buf, clrWhite, clrBackground, m_Font); offset += m_Font->Height(); @@ -500,6 +526,99 @@ void cFemonOsd::DrawInfoWindow(void) } else snprintf(buf, sizeof(buf), "---"); m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + } + else if (m_DisplayMode == modeAC3) { + m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrBackground); + m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset+m_Font->Height()-1), clrWhite); + snprintf(buf, sizeof(buf), "%s - %s #%d", tr("Stream Information"), tr("AC-3 Stream"), channel->Dpid1()); + m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, clrBackground, clrWhite, m_Font); + offset += m_Font->Height(); + if (m_Receiver && m_Receiver->AC3Valid()) { + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), clrWhite, clrBackground, m_Font); + snprintf(buf, sizeof(buf), "%.0f %s (%0.f %s)", m_Receiver->AC3StreamBitrate(), tr("kbit/s"), m_Receiver->AC3Bitrate(), tr("kbit/s")); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Sampling Frequency"), clrWhite, clrBackground, m_Font); + snprintf(buf, sizeof(buf), "%.1f %s", m_Receiver->AC3SamplingFreq() / 1000., tr("kHz")); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frame Size"), clrWhite, clrBackground, m_Font); + snprintf(buf, sizeof(buf), "%d", m_Receiver->AC3FrameSize()); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bit Stream Mode"), clrWhite, clrBackground, m_Font); + switch (m_Receiver->AC3BitStreamMode()) { + case 0: snprintf(buf, sizeof(buf), tr("Complete Main (CM)")); break; + case 1: snprintf(buf, sizeof(buf), tr("Music and Effects (ME)")); break; + case 2: snprintf(buf, sizeof(buf), tr("Visually Impaired (VI)")); break; + case 3: snprintf(buf, sizeof(buf), tr("Hearing Impaired (HI)")); break; + case 4: snprintf(buf, sizeof(buf), tr("Dialogue (D)")); break; + case 5: snprintf(buf, sizeof(buf), tr("Commentary (C)")); break; + case 6: snprintf(buf, sizeof(buf), tr("Emergency (E)")); break; + case 7: (m_Receiver->AC3AudioCodingMode() == 1) ? snprintf(buf, sizeof(buf), tr("Voice Over (VO)")) : snprintf(buf, sizeof(buf), tr("Karaoke")); break; + default: snprintf(buf, sizeof(buf), "---"); + } + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Audio Coding Mode"), clrWhite, clrBackground, m_Font); + if (m_Receiver->AC3BitStreamMode() != 7) { + switch (m_Receiver->AC3AudioCodingMode()) { + case 0: snprintf(buf, sizeof(buf), "1+1 - %s, %s", tr("Ch1"), tr("Ch2")); break; + case 1: snprintf(buf, sizeof(buf), "1/0 - %s", tr("C")); break; + case 2: snprintf(buf, sizeof(buf), "2/0 - %s, %s", tr("L"), tr("R")); break; + case 3: snprintf(buf, sizeof(buf), "3/0 - %s, %s, %s", tr("L"), tr("C"), tr("R")); break; + case 4: snprintf(buf, sizeof(buf), "2/1 - %s, %s, %s", tr("L"), tr("R"), tr("S")); break; + case 5: snprintf(buf, sizeof(buf), "3/1 - %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("S")); break; + case 6: snprintf(buf, sizeof(buf), "2/2 - %s, %s, %s, %s", tr("L"), tr("R"), tr("SL"), tr("SR")); break; + case 7: snprintf(buf, sizeof(buf), "3/2 - %s, %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("SL"), tr("SR")); break; + default: snprintf(buf, sizeof(buf), "---"); + } + } + else snprintf(buf, sizeof(buf), "---"); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Center Mix Level"), clrWhite, clrBackground, m_Font); + switch (m_Receiver->AC3CenterMixLevel()) { + case CML_MINUS_3dB: snprintf(buf, sizeof(buf), "-3.0 %s", tr("dB")); break; + case CML_MINUS_4_5dB: snprintf(buf, sizeof(buf), "-4.5 %s", tr("dB")); break; + case CML_MINUS_6dB: snprintf(buf, sizeof(buf), "-6.0 %s", tr("dB")); break; + case CML_RESERVED: snprintf(buf, sizeof(buf), "%s", tr("reserved")); break; + default: snprintf(buf, sizeof(buf), "---"); + } + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Surround Mix Level"), clrWhite, clrBackground, m_Font); + switch (m_Receiver->AC3SurroundMixLevel()) { + case SML_MINUS_3dB: snprintf(buf, sizeof(buf), "-3 %s", tr("dB")); break; + case SML_MINUS_6dB: snprintf(buf, sizeof(buf), "-6 %s", tr("dB")); break; + case SML_0_dB: snprintf(buf, sizeof(buf), "0 %s", tr("dB")); break; + case SML_RESERVED: snprintf(buf, sizeof(buf), "%s", tr("reserved")); break; + default: snprintf(buf, sizeof(buf), "---"); + } + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Dolby Surround Mode"), clrWhite, clrBackground, m_Font); + switch (m_Receiver->AC3DolbySurroundMode()) { + case DSM_NOT_INDICATED: snprintf(buf, sizeof(buf), "%s", tr("not indicated")); break; + case DSM_NOT_DOLBYSURROUND: snprintf(buf, sizeof(buf), "%s", tr("no")); break; + case DSM_DOLBYSURROUND: snprintf(buf, sizeof(buf), "%s", tr("yes")); break; + case DSM_RESERVED: snprintf(buf, sizeof(buf), "%s", tr("reserved")); break; + default: snprintf(buf, sizeof(buf), "---"); + } + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Low Frequency Effects"), clrWhite, clrBackground, m_Font); + snprintf(buf, sizeof(buf), "%s", m_Receiver->AC3LfeOn() ? tr("On") : tr("Off")); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Dialogue Normalization"), clrWhite, clrBackground, m_Font); + value = m_Receiver->AC3DialogLevel(); + if (value > 0) snprintf(buf, sizeof(buf), "-%d %s", value, tr("dB")); + else snprintf(buf, sizeof(buf), "---"); + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font); + offset += m_Font->Height(); + } } else /* modeBasic */ { m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent); @@ -564,8 +683,8 @@ void cFemonOsd::Show(void) if (m_Receiver) delete m_Receiver; if (femonConfig.analyzestream) { - int channelNumber = cDevice::CurrentChannel(); - m_Receiver = new cFemonReceiver(Channels.GetByNumber(channelNumber)->Ca(), Channels.GetByNumber(channelNumber)->Vpid(), Channels.GetByNumber(channelNumber)->Apid1()); + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid1(), channel->Dpid1()); cDevice::ActualDevice()->AttachReceiver(m_Receiver); } Start(); @@ -596,8 +715,8 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber) if (m_Receiver) delete m_Receiver; if (femonConfig.analyzestream) { - channelNumber = cDevice::CurrentChannel(); - m_Receiver = new cFemonReceiver(Channels.GetByNumber(channelNumber)->Ca(), Channels.GetByNumber(channelNumber)->Vpid(), Channels.GetByNumber(channelNumber)->Apid1()); + cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); + m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid1(), channel->Dpid1()); cDevice::ActualDevice()->AttachReceiver(m_Receiver); } } @@ -668,7 +787,9 @@ eOSState cFemonOsd::ProcessKey(eKeys Key) } break; case kOk: - if (++m_DisplayMode >= modeMaxNumber) m_DisplayMode = 0; // toggle between display modes + // toggle between display modes + if (++m_DisplayMode == modeAC3 && !Channels.GetByNumber(cDevice::CurrentChannel())->Dpid1()) m_DisplayMode++; + if (m_DisplayMode >= modeMaxNumber) m_DisplayMode = 0; DrawInfoWindow(); break; default: diff --git a/femonosd.h b/femonosd.h index 2828e05..feea4f6 100644 --- a/femonosd.h +++ b/femonosd.h @@ -35,7 +35,7 @@ private: int m_DisplayMode; const cFont *m_Font; cMutex* m_Mutex; - static cBitmap bmPAL, bmNTSC, bmAspectRatio_1_1, bmAspectRatio_16_9, bmAspectRatio_2_21_1, bmAspectRatio_4_3; + static cBitmap bmDD, bmDD20, bmDD51, bmPAL, bmNTSC, bmAspectRatio_1_1, bmAspectRatio_16_9, bmAspectRatio_2_21_1, bmAspectRatio_4_3; void DrawStatusWindow(void); void DrawInfoWindow(void); diff --git a/femonreceiver.c b/femonreceiver.c index ec71bfd..1f1f3d1 100644 --- a/femonreceiver.c +++ b/femonreceiver.c @@ -16,13 +16,15 @@ #define PAYLOAD 0x10 #define PTS_DTS_FLAGS 0xC0 -cFemonReceiver::cFemonReceiver(int Ca, int Vpid, int Apid) -:cReceiver(Ca, -1, 2, Vpid, Apid), cThread("femon receiver") +cFemonReceiver::cFemonReceiver(int Ca, int Vpid, int Apid, int Dpid) +:cReceiver(Ca, -1, 3, Vpid, Apid, Dpid), cThread("femon receiver") { //printf("cFemonReceiver::cFemonReceiver()\n"); m_Active = false; m_VideoPid = Vpid; m_AudioPid = Apid; + m_AC3Pid = Dpid; + m_VideoValid = false; m_VideoPacketCount = 0; m_VideoHorizontalSize = 0; m_VideoVerticalSize = 0; @@ -31,13 +33,26 @@ cFemonReceiver::cFemonReceiver(int Ca, int Vpid, int Apid) m_VideoFrameRate = 0.0; m_VideoStreamBitrate = 0.0; m_VideoBitrate = 0.0; + m_AudioValid = false; m_AudioPacketCount = 0; m_AudioStreamBitrate = -2.0; m_AudioBitrate = 0.0; m_AudioSamplingFreq = -1; m_AudioMPEGLayer = 0; m_AudioBitrate = 0.0; - + m_AC3Valid = false; + m_AC3PacketCount = 0; + m_AC3StreamBitrate = 0; + m_AC3SamplingFreq = 0; + m_AC3Bitrate = 0; + m_AC3FrameSize = 0; + m_AC3BitStreamMode = FR_NOTVALID; + m_AC3AudioCodingMode = FR_NOTVALID; + m_AC3CenterMixLevel = FR_NOTVALID; + m_AC3SurroundMixLevel = FR_NOTVALID; + m_AC3DolbySurroundMode = FR_NOTVALID; + m_AC3LfeOn = false; + m_AC3DialogLevel = FR_NOTVALID; } cFemonReceiver::~cFemonReceiver(void) @@ -49,29 +64,29 @@ cFemonReceiver::~cFemonReceiver(void) } } -/* the following function originates from libdvbmpeg: */ +/* The following function originates from libdvbmpeg: */ void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count) { //printf("cFemonReceiver::GetVideoInfo()\n"); uint8_t *headr; int found = 0; int c = 0; - while (found < 4 && c + 4 < count) { + m_VideoValid = false; + while ((found < 4) && ((c + 4) < count)) { uint8_t *b; b = mbuf + c; - if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 && b[3] == 0xb3) + if ((b[0] == 0x00) && (b[1] == 0x00) && (b[2] == 0x01) && (b[3] == 0xb3)) found = 4; else c++; } - if (!found) return; - c += 4; - if (c + 12 >= count) return; - headr = mbuf + c; - m_VideoHorizontalSize = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - m_VideoVerticalSize = ((headr[1] &0x0F) << 8) | (headr[2]); + if ((!found) || ((c + 16) >= count)) return; + m_VideoValid = true; + headr = mbuf + c + 4; + m_VideoHorizontalSize = ((headr[1] & 0xF0) >> 4) | (headr[0] << 4); + m_VideoVerticalSize = ((headr[1] & 0x0F) << 8) | (headr[2]); int sw = (int)((headr[3] & 0xF0) >> 4); - switch( sw ){ + switch ( sw ){ case 1: m_VideoAspectRatio = AR_1_1; break; @@ -85,15 +100,14 @@ void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count) m_VideoAspectRatio = AR_2_21_1; break; case 5 ... 15: + default: m_VideoAspectRatio = AR_RESERVED; break; - default: - return; } sw = (int)(headr[3] & 0x0F); switch ( sw ) { case 1: - m_VideoFrameRate = 24000/1001.0; + m_VideoFrameRate = 24000 / 1001.0; m_VideoFormat = VF_UNKNOWN; break; case 2: @@ -105,7 +119,7 @@ void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count) m_VideoFormat = VF_PAL; break; case 4: - m_VideoFrameRate = 30000/1001.0; + m_VideoFrameRate = 30000 / 1001.0; m_VideoFormat = VF_NTSC; break; case 5: @@ -120,6 +134,15 @@ void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count) m_VideoFrameRate = 60.0; m_VideoFormat = VF_NTSC; break; + case 8: + m_VideoFrameRate = 60000 / 1001.0; + m_VideoFormat = VF_NTSC; + break; + case 9 ... 15: + default: + m_VideoFrameRate = 0; + m_VideoFormat = VF_UNKNOWN; + break; } m_VideoStreamBitrate = 400 * (((headr[4] << 10) & 0x0003FC00UL) | ((headr[5] << 2) & 0x000003FCUL) | (((headr[6] & 0xC0) >> 6) & 0x00000003UL)) / 1000000.0; } @@ -131,9 +154,10 @@ static unsigned int bitrates[3][16] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0} }; -static unsigned int samplerates[4] = {441, 480, 320, 0}; +static unsigned int samplerates[4] = +{441, 480, 320, 0}; -/* the following function originates from libdvbmpeg: */ +/* The following function originates from libdvbmpeg: */ void cFemonReceiver::GetAudioInfo(uint8_t *mbuf, int count) { //printf("cFemonReceiver::GetAudioInfo()\n"); @@ -141,15 +165,16 @@ void cFemonReceiver::GetAudioInfo(uint8_t *mbuf, int count) int found = 0; int c = 0; int tmp = 0; - while (!found && c < count) { + m_AudioValid = false; + while (!found && (c < count)) { uint8_t *b = mbuf + c; - if (b[0] == 0xff && (b[1] & 0xf8) == 0xf8) + if ((b[0] == 0xff) && ((b[1] & 0xf8) == 0xf8)) found = 1; else c++; } - if (!found) return; - if (c + 3 >= count) return; + if ((!found) || ((c + 3) >= count)) return; + m_AudioValid = true; headr = mbuf + c; m_AudioMPEGLayer = 4 - ((headr[1] & 0x06) >> 1); tmp = bitrates[(3 - ((headr[1] & 0x06) >> 1))][(headr[2] >> 4)] * 1000; @@ -166,6 +191,65 @@ void cFemonReceiver::GetAudioInfo(uint8_t *mbuf, int count) m_AudioSamplingFreq = tmp; } +static unsigned int ac3_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}; + +static unsigned int ac3_freq[4] = +{480, 441, 320, 0}; + +static unsigned int ac3_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} +}; + +/* +** AC3 Audio Header: http://www.atsc.org/standards/a_52a.pdf +** The following function originates from libdvbmpeg: +*/ +void cFemonReceiver::GetAC3Info(uint8_t *mbuf, int count) +{ + uint8_t *headr; + int found = 0; + int c = 0; + uint8_t frame; + m_AC3Valid = false; + while (!found && (c < count)) { + uint8_t *b = mbuf + c; + if ((b[0] == 0x0b) && (b[1] == 0x77)) + found = 1; + else + c++; + } + if ((!found) || ((c + 5) >= count)) return; + m_AC3Valid = true; + headr = mbuf + c + 2; + frame = (headr[2] & 0x3f); + m_AC3StreamBitrate = ac3_bitrates[frame >> 1]; + int fr = (headr[2] & 0xc0 ) >> 6; + m_AC3SamplingFreq = ac3_freq[fr] * 100; + m_AC3FrameSize = ac3_frames[fr][frame >> 1]; + if ((frame & 1) && (fr == 1)) m_AC3FrameSize++; + m_AC3FrameSize <<= 1; + m_AC3BitStreamMode = (headr[3] & 7); + m_AC3AudioCodingMode = (headr[4] & 0xE0) >> 5; + if ((m_AC3AudioCodingMode & 0x01) && (m_AC3AudioCodingMode != 0x01)) // if 3 front channels + m_AC3CenterMixLevel = (headr[4] & 0x18) >> 3; + else + m_AC3CenterMixLevel = FR_NOTVALID; + if (m_AC3AudioCodingMode & 0x04) // if a surround channel exists + m_AC3SurroundMixLevel = (headr[4] & 0x06) >> 1; + else + m_AC3SurroundMixLevel = FR_NOTVALID; + if (m_AC3AudioCodingMode == 0x02) // if in 2/0 mode + m_AC3DolbySurroundMode = ((headr[4] & 1) << 1) | ((headr[5] & 0x80) >> 7); + else + m_AC3DolbySurroundMode = FR_NOTVALID; + m_AC3LfeOn = (headr[5] & 0x40) >> 6; + m_AC3DialogLevel = (headr[5] & 0x3e) >> 1; +} + void cFemonReceiver::Activate(bool On) { //printf("cFemonReceiver::Activate()\n"); @@ -184,6 +268,9 @@ void cFemonReceiver::Receive(uchar *Data, int Length) else if (pid == m_AudioPid) { m_AudioPacketCount++; } + else if (pid == m_AC3Pid) { + m_AC3PacketCount++; + } /* the following originates from libdvbmpeg: */ if (!(Data[3] & PAYLOAD)) { return; @@ -200,9 +287,12 @@ void cFemonReceiver::Receive(uchar *Data, int Length) if (pid == m_VideoPid) { GetVideoInfo(pay, l); } - if (pid == m_AudioPid) { + else if (pid == m_AudioPid) { GetAudioInfo(pay, l); } + else if (pid == m_AC3Pid) { + GetAC3Info(pay, l); + } } } /* end */ @@ -219,6 +309,8 @@ void cFemonReceiver::Action(void) m_VideoPacketCount = 0; m_AudioBitrate = (8.0 * 184.0 * m_AudioPacketCount) / (femonConfig.calcinterval * 100.0); m_AudioPacketCount = 0; + m_AC3Bitrate = (8.0 * 184.0 * m_AC3PacketCount) / (femonConfig.calcinterval * 100.0); + m_AC3PacketCount = 0; usleep(100000L * femonConfig.calcinterval); } } diff --git a/femonreceiver.h b/femonreceiver.h index 5d2bdd9..1b0b117 100644 --- a/femonreceiver.h +++ b/femonreceiver.h @@ -26,29 +26,68 @@ enum eAspectRatio { AR_2_21_1 = 233, }; -#define FR_RESERVED -1 -#define FR_FREE -2 +enum eCenterMixLevel { + CML_MINUS_3dB = 0, + CML_MINUS_4_5dB = 1, + CML_MINUS_6dB = 2, + CML_RESERVED = 3, + }; + +enum eSurroundMixLevel { + SML_MINUS_3dB = 0, + SML_MINUS_6dB = 1, + SML_0_dB = 2, + SML_RESERVED = 3, + }; + +enum eDolbySurroundMode { + DSM_NOT_INDICATED = 0, + DSM_NOT_DOLBYSURROUND = 1, + DSM_DOLBYSURROUND = 2, + DSM_RESERVED = 3, + }; + +#define FR_RESERVED -1 +#define FR_FREE -2 +#define FR_NOTVALID -3 class cFemonReceiver : public cReceiver, public cThread { private: - bool m_Active; - int m_VideoPid; - int m_AudioPid; - int m_VideoPacketCount; - int m_VideoHorizontalSize; - int m_VideoVerticalSize; - int m_VideoAspectRatio; - int m_VideoFormat; + bool m_Active; + int m_VideoPid; + int m_AudioPid; + int m_AC3Pid; + bool m_VideoValid; + int m_VideoPacketCount; + int m_VideoHorizontalSize; + int m_VideoVerticalSize; + int m_VideoAspectRatio; + int m_VideoFormat; double m_VideoFrameRate; double m_VideoStreamBitrate; double m_VideoBitrate; - int m_AudioPacketCount; + bool m_AudioValid; + int m_AudioPacketCount; double m_AudioStreamBitrate; double m_AudioBitrate; - int m_AudioSamplingFreq; - int m_AudioMPEGLayer; - void GetVideoInfo(uint8_t *mbuf, int count); - void GetAudioInfo(uint8_t *mbuf, int count); + int m_AudioSamplingFreq; + int m_AudioMPEGLayer; + bool m_AC3Valid; + int m_AC3PacketCount; + double m_AC3Bitrate; + int m_AC3FrameSize; + int m_AC3SamplingFreq; + int m_AC3StreamBitrate; + int m_AC3BitStreamMode; + int m_AC3AudioCodingMode; + int m_AC3CenterMixLevel; + int m_AC3SurroundMixLevel; + int m_AC3DolbySurroundMode; + bool m_AC3LfeOn; + int m_AC3DialogLevel; + void GetVideoInfo(uint8_t *mbuf, int count); + void GetAudioInfo(uint8_t *mbuf, int count); + void GetAC3Info(uint8_t *mbuf, int count); protected: virtual void Activate(bool On); @@ -56,9 +95,10 @@ protected: virtual void Action(void); public: - cFemonReceiver(int Ca, int Vpid, int Apid); + cFemonReceiver(int Ca, int Vpid, int Apid, int Dpid); virtual ~cFemonReceiver(); + bool VideoValid(void) { return m_VideoValid; }; // boolean int VideoHorizontalSize(void) { return m_VideoHorizontalSize; }; // pixels int VideoVerticalSize(void) { return m_VideoVerticalSize; }; // pixels int VideoAspectRatio(void) { return m_VideoAspectRatio; }; // eAspectRatio @@ -67,10 +107,26 @@ public: double VideoStreamBitrate(void) { return m_VideoStreamBitrate; }; // Mbit/s double VideoBitrate(void) { return m_VideoBitrate; }; // Mbit/s + bool AudioValid(void) { return m_AudioValid; }; // boolean int AudioMPEGLayer(void) { return m_AudioMPEGLayer; }; // layer number int AudioSamplingFreq(void) { return m_AudioSamplingFreq; }; // Hz double AudioStreamBitrate(void) { return m_AudioStreamBitrate; }; // kbit/s double AudioBitrate(void) { return m_AudioBitrate; }; // kbit/s + + bool AC3Valid(void) { return m_AC3Valid; }; // boolean + int AC3SamplingFreq(void) { return m_AC3SamplingFreq; }; // Hz + double AC3StreamBitrate(void) { return m_AC3StreamBitrate; }; // kbit/s + double AC3Bitrate(void) { return m_AC3Bitrate; }; // kbit/s + int AC3FrameSize(void) { return m_AC3FrameSize; }; // Bytes + int AC3BitStreamMode(void) { return m_AC3BitStreamMode; }; // 0..7 + int AC3AudioCodingMode(void) { return m_AC3AudioCodingMode; }; // 0..7 + bool AC3_2_0(void) { return m_AC3AudioCodingMode == 2; }; // DD 2.0 + bool AC3_5_1(void) { return m_AC3AudioCodingMode == 7; }; // DD 5.1 + int AC3CenterMixLevel(void) { return m_AC3CenterMixLevel; }; // eCenterMixLevel + int AC3SurroundMixLevel(void) { return m_AC3SurroundMixLevel; }; // eSurroundMixLevel + int AC3DolbySurroundMode(void) { return m_AC3DolbySurroundMode; }; // eDolbySurroundMode + bool AC3LfeOn(void) { return m_AC3LfeOn; }; // boolean + int AC3DialogLevel(void) { return m_AC3DialogLevel; }; // -dB }; #endif //__FEMONRECEIVER_H diff --git a/symbols/dolbydigital.xpm b/symbols/dolbydigital.xpm new file mode 100644 index 0000000..e51709e --- /dev/null +++ b/symbols/dolbydigital.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * dolbydigital_xpm[] = { +"27 18 2 1", +". c #FFFFFF", +"+ c #000000", +"...........................", +"...........................", +"..+++++++++++.+++++++++++..", +"..++.++++++++.++++++++.++..", +"..++...++++++.++++++...++..", +"..++.....++++.++++.....++..", +"..++......+++.+++......++..", +"..++.......++.++.......++..", +"..++.......++.++.......++..", +"..++.......++.++.......++..", +"..++.......++.++.......++..", +"..++......+++.+++......++..", +"..++.....++++.++++.....++..", +"..++...++++++.++++++...++..", +"..++.++++++++.++++++++.++..", +"..+++++++++++.+++++++++++..", +"...........................", +"..........................."}; diff --git a/symbols/dolbydigital20.xpm b/symbols/dolbydigital20.xpm new file mode 100644 index 0000000..dcc96dc --- /dev/null +++ b/symbols/dolbydigital20.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * dolbydigital20_xpm[] = { +"49 18 2 1", +". c #FFFFFF", +"+ c #000000", +".................................................", +".................................................", +"..+++++++++++.+++++++++++....++++.......++++++...", +"..++.++++++++.++++++++.++...++++++.....++++++++..", +"..++...++++++.++++++...++..+++..+++....+++..+++..", +"..++.....++++.++++.....++..++....++....++....++..", +"..++......+++.+++......++..++....++....++....++..", +"..++.......++.++.......++.......+++....++....++..", +"..++.......++.++.......++......+++.....++....++..", +"..++.......++.++.......++.....+++......++....++..", +"..++.......++.++.......++....+++.......++....++..", +"..++......+++.+++......++...+++........++....++..", +"..++.....++++.++++.....++..+++.........++....++..", +"..++...++++++.++++++...++..++....++.++.+++..+++..", +"..++.++++++++.++++++++.++..++++++++.++.++++++++..", +"..+++++++++++.+++++++++++..++++++++.++..++++++...", +".................................................", +"................................................."}; diff --git a/symbols/dolbydigital51.xpm b/symbols/dolbydigital51.xpm new file mode 100644 index 0000000..ec60527 --- /dev/null +++ b/symbols/dolbydigital51.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * dolbydigital51_xpm[] = { +"44 18 2 1", +". c #FFFFFF", +"+ c #000000", +"............................................", +"............................................", +"..+++++++++++.+++++++++++..++++++++.....++..", +"..++.++++++++.++++++++.++..++++++++....+++..", +"..++...++++++.++++++...++..++.........++++..", +"..++.....++++.++++.....++..++.........++++..", +"..++......+++.+++......++..++...........++..", +"..++.......++.++.......++..++++++.......++..", +"..++.......++.++.......++..+++++++......++..", +"..++.......++.++.......++.......+++.....++..", +"..++.......++.++.......++........++.....++..", +"..++......+++.+++......++..++....++.....++..", +"..++.....++++.++++.....++..++....++.....++..", +"..++...++++++.++++++...++..+++..+++.++..++..", +"..++.++++++++.++++++++.++...++++++..++..++..", +"..+++++++++++.+++++++++++....++++...++..++..", +"............................................", +"............................................"};