1
0
mirror of https://github.com/rofafor/vdr-plugin-femon.git synced 2023-10-10 11:36:53 +00:00

Compare commits

..

11 Commits

Author SHA1 Message Date
Rolf Ahrenberg
2340ade6c8 Updated HISTORY. 2008-11-30 15:18:12 +02:00
Rolf Ahrenberg
7db77978b5 Fixed partially H.264 SEI parsing. 2008-11-29 19:33:29 +02:00
Rolf Ahrenberg
ab8f5f3de8 Fixed a deadlock in cFemonReceiver. 2008-11-23 22:26:48 +02:00
Rolf Ahrenberg
427b3023ba Added some OSD tweaks. 2008-11-23 04:45:20 +02:00
Rolf Ahrenberg
8f283f27f5 Removed the FEMON_NTSC option. 2008-11-23 03:12:21 +02:00
Rolf Ahrenberg
c4fda38364 Replaced "Use single area (8bpp)" option with VDR's "Setup/OSD/Anti-alias". 2008-11-23 02:22:13 +02:00
Rolf Ahrenberg
219fc78226 Fixed a crash. 2008-11-23 02:01:27 +02:00
Rolf Ahrenberg
5333a9274d Added getAC3Stream() function. 2008-11-22 23:12:39 +02:00
Rolf Ahrenberg
a8c065639a Fixed a memory leak.
Added a check for the minimum OSD height.
2008-11-12 17:58:32 +02:00
Rolf Ahrenberg
fa41c95b1c Updated Italian translation (Thanks to Diego Pierotto). 2008-11-11 16:30:21 +02:00
Rolf Ahrenberg
6eb4329fff Added getVideoStream() and getAudioStream() functions. 2008-11-11 00:30:00 +02:00
20 changed files with 272 additions and 284 deletions

10
HISTORY
View File

@@ -310,3 +310,13 @@ VDR Plugin 'femon' Revision History
- Added initial support for H.264 and HE-AAC. - Added initial support for H.264 and HE-AAC.
- Fixed detection of false positives in audio/video streams. - Fixed detection of false positives in audio/video streams.
- Refactored source code. - Refactored source code.
2008-11-30: Version 1.6.4
- Added new helper functions.
- Updated Italian translation (Thanks to Diego Pierotto).
- Fixed a memory leak.
- Added a check for the minimum OSD height.
- Replaced "Use single area (8bpp)" option with VDR's "Setup/OSD/Anti-alias".
- Removed the FEMON_NTSC option.
- Fixed a deadlock in cFemonReceiver (Thanks to Antti Seppälä for reporting this one).

View File

@@ -5,9 +5,6 @@
# Debugging on/off # Debugging on/off
#FEMON_DEBUG = 1 #FEMON_DEBUG = 1
# NTSC on/off
#FEMON_NTSC = 1
# Strip debug symbols? Set eg. to /bin/true if not # Strip debug symbols? Set eg. to /bin/true if not
STRIP = strip STRIP = strip
@@ -53,10 +50,6 @@ INCLUDES += -I$(VDRDIR)/include
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
ifdef FEMON_NTSC
DEFINES += -DNTSC
endif
ifdef FEMON_DEBUG ifdef FEMON_DEBUG
DEFINES += -DDEBUG DEFINES += -DDEBUG
endif endif

4
README
View File

@@ -15,7 +15,7 @@ See the file COPYING for license information.
Requirements: Requirements:
VDR & DVB. BMW & Ph.D.. BEER. YARRR! VDR and a DVB card.
Description: Description:
@@ -112,7 +112,7 @@ Notes:
- If the OSD isn't visible, you've configured the OSD height too big or too - If the OSD isn't visible, you've configured the OSD height too big or too
small. Please, try to adjust the variable on the setup page before writing small. Please, try to adjust the variable on the setup page before writing
any bug reports. NTSC users should use a shrinked default OSD height by any bug reports. NTSC users should use a shrinked default OSD height by
compiling the plugin with: make FEMON_NTSC=1 modifying VDR's setup.conf: femon.OSDHeight = 420
- If the SVDRP service is used: femon won't notice if the server is tuned - If the SVDRP service is used: femon won't notice if the server is tuned
to a different channel and tuning the channel on the server might annoy to a different channel and tuning the channel on the server might annoy

View File

@@ -18,7 +18,7 @@
#error "VDR-1.6.0 API version or greater is required!" #error "VDR-1.6.0 API version or greater is required!"
#endif #endif
static const char VERSION[] = "1.6.3"; static const char VERSION[] = "1.6.4";
static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)"); static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)");
static const char MAINMENUENTRY[] = trNOOP("Signal Information"); static const char MAINMENUENTRY[] = trNOOP("Signal Information");
@@ -108,7 +108,6 @@ bool cPluginFemon::SetupParse(const char *Name, const char *Value)
{ {
// Parse your own setup parameters and store their values. // Parse your own setup parameters and store their values.
if (!strcasecmp(Name, "HideMenu")) femonConfig.hidemenu = atoi(Value); if (!strcasecmp(Name, "HideMenu")) femonConfig.hidemenu = atoi(Value);
else if (!strcasecmp(Name, "UseSingleArea")) femonConfig.usesinglearea = atoi(Value);
else if (!strcasecmp(Name, "DisplayMode")) femonConfig.displaymode = atoi(Value); else if (!strcasecmp(Name, "DisplayMode")) femonConfig.displaymode = atoi(Value);
else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value); else if (!strcasecmp(Name, "Position")) femonConfig.position = atoi(Value);
else if (!strcasecmp(Name, "OSDHeight")) femonConfig.osdheight = atoi(Value); else if (!strcasecmp(Name, "OSDHeight")) femonConfig.osdheight = atoi(Value);
@@ -311,9 +310,6 @@ void cMenuFemonSetup::Setup(void)
Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &data.hidemenu)); Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &data.hidemenu));
help.Append(tr("Define whether the main menu entry is hidden.")); help.Append(tr("Define whether the main menu entry is hidden."));
Add(new cMenuEditBoolItem(tr("Use single area (8bpp)"), &data.usesinglearea));
help.Append(tr("Define whether a single 8bpp OSD area is preferred.\n\nRequired by Truetype fonts and anti-aliasing."));
Add(new cMenuEditStraItem(tr("Default display mode"), &data.displaymode, eFemonModeMaxNumber, dispmodes)); Add(new cMenuEditStraItem(tr("Default display mode"), &data.displaymode, eFemonModeMaxNumber, dispmodes));
help.Append(tr("Define the default display mode at startup.")); help.Append(tr("Define the default display mode at startup."));
@@ -372,7 +368,6 @@ void cMenuFemonSetup::Store(void)
Dprintf("%s()\n", __PRETTY_FUNCTION__); Dprintf("%s()\n", __PRETTY_FUNCTION__);
femonConfig = data; femonConfig = data;
SetupStore("HideMenu", femonConfig.hidemenu); SetupStore("HideMenu", femonConfig.hidemenu);
SetupStore("UseSingleArea", femonConfig.usesinglearea);
SetupStore("DisplayMode", femonConfig.displaymode); SetupStore("DisplayMode", femonConfig.displaymode);
SetupStore("Skin", femonConfig.skin); SetupStore("Skin", femonConfig.skin);
SetupStore("Theme", femonConfig.theme); SetupStore("Theme", femonConfig.theme);

View File

@@ -13,7 +13,6 @@ cFemonConfig femonConfig;
cFemonConfig::cFemonConfig(void) cFemonConfig::cFemonConfig(void)
{ {
hidemenu = 0; hidemenu = 0;
usesinglearea = 0;
displaymode = 0; displaymode = 0;
skin = 0; skin = 0;
theme = 0; theme = 0;
@@ -24,11 +23,7 @@ cFemonConfig::cFemonConfig(void)
analyzestream = 1; analyzestream = 1;
calcinterval = 20; calcinterval = 20;
showcasystem = 0; showcasystem = 0;
#ifdef NTSC
osdheight = 420;
#else
osdheight = 480; osdheight = 480;
#endif
osdoffset = 0; osdoffset = 0;
usesvdrp = 0; usesvdrp = 0;
svdrpport = 2001; svdrpport = 2001;

View File

@@ -24,7 +24,6 @@ struct cFemonConfig
public: public:
cFemonConfig(void); cFemonConfig(void);
int hidemenu; int hidemenu;
int usesinglearea;
int displaymode; int displaymode;
int skin; int skin;
int theme; int theme;

View File

@@ -85,7 +85,6 @@ typedef struct {
#define br_skip_ue_golomb(br) br_skip_golomb(br) #define br_skip_ue_golomb(br) br_skip_golomb(br)
#define br_skip_se_golomb(br) br_skip_golomb(br) #define br_skip_se_golomb(br) br_skip_golomb(br)
static inline void br_init(br_state *br, const uint8_t *data, int bytes) static inline void br_init(br_state *br, const uint8_t *data, int bytes)
{ {
br->data = data; br->data = data;
@@ -235,11 +234,11 @@ static bool h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps)
br_skip_bit(&br); // sar_width br_skip_bit(&br); // sar_width
br_skip_bit(&br); // sar_height br_skip_bit(&br); // sar_height
sps->aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED; sps->aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED;
//Dprintf("H.264 SPS: -> sar %dx%d", sar_width, sar_height); //Dprintf("H.264 SPS: aspect ratio extended");
} }
else if (aspect_ratio_idc < sizeof(aspect_ratios) / sizeof(aspect_ratios[0])) { else if (aspect_ratio_idc < sizeof(aspect_ratios) / sizeof(aspect_ratios[0])) {
sps->aspect_ratio = aspect_ratios[aspect_ratio_idc]; sps->aspect_ratio = aspect_ratios[aspect_ratio_idc];
//Dprintf("H.264 SPS: -> aspect ratio %d", sps->aspect); //Dprintf("H.264 SPS: -> aspect ratio %d", sps->aspect_ratio);
} }
} }
if (br_get_bit(&br)) // overscan_info_present_flag if (br_get_bit(&br)) // overscan_info_present_flag
@@ -253,7 +252,7 @@ static bool h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps)
} }
} }
//Dprintf("H.264 SPS: -> video size %dx%d, aspect %d", sps->width, sps->height, sps->aspect); //Dprintf("H.264 SPS: -> video size %dx%d, aspect %d", sps->width, sps->height, sps->aspect_ratio);
if (BR_EOF(&br)) { if (BR_EOF(&br)) {
//Dprintf("H.264 SPS: not enough data ?"); //Dprintf("H.264 SPS: not enough data ?");
@@ -263,76 +262,75 @@ static bool h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps)
return true; return true;
} }
#if 0
static bool h264_parse_sei(const uint8_t *buf, int len, h264_sei_data_t *sei) static bool h264_parse_sei(const uint8_t *buf, int len, h264_sei_data_t *sei)
{ {
int num_referenced_subseqs, i;
br_state br = BR_INIT(buf, len); br_state br = BR_INIT(buf, len);
while (!BR_EOF(&br)) { while (!BR_EOF(&br)) { // sei_message
{ // sei_message int lastByte, payloadSize = 0, payloadType = 0;
int lastByte, payloadSize = 0, payloadType = 0;
// last_payload_type_byte
do {
lastByte = br_get_u8(&br);
payloadType += lastByte;
} while (lastByte != 0xFF);
// last_payload_size_byte // last_payload_type_byte
do { do {
lastByte = br_get_u8(&br); lastByte = br_get_u8(&br) & 0xFF;
payloadSize += lastByte; payloadType += lastByte;
} while (lastByte != 0xFF); } while (lastByte == 0xFF);
{ // sei_payload // last_payload_size_byte
switch (payloadType) { do {
//case 1: // pic_timing lastByte = br_get_u8(&br) & 0xFF;
// ... payloadSize += lastByte;
// switch (br_get_bits(&br, 2)) { // ct_type } while (lastByte == 0xFF);
// case 0:
// sei->scan = VIDEO_SCAN_PROGRESSIVE;
// break;
// case 1: switch (payloadType) { // sei_payload
// sei->scan = VIDEO_SCAN_INTERLACED; //case 1: // pic_timing
// break; // ...
// switch (br_get_bits(&br, 2)) { // ct_type
// case 0:
// sei->scan = VIDEO_SCAN_PROGRESSIVE;
// break;
// case 1:
// sei->scan = VIDEO_SCAN_INTERLACED;
// break;
// case 2:
// sei->scan = VIDEO_SCAN_UNKNOWN;
// break;
// default:
// sei->scan = VIDEO_SCAN_RESERVED;
// break;
// }
// break;
// case 2: case 12: // sub_seq_characteristics
// sei->scan = VIDEO_SCAN_UNKNOWN; br_skip_ue_golomb(&br); // sub_seq_layer_num
// break; br_skip_ue_golomb(&br); // sub_seq_id
if (br_get_bit(&br)) // duration_flag
br_skip_bits(&br, 32); // sub_seq_duration
if (br_get_bit(&br)) { // average_rate_flag
br_skip_bit(&br); // accurate_statistics_flag
sei->bitrate = br_get_u16(&br); // average_bit_rate
sei->frame_rate = br_get_u16(&br); // average_frame_rate
//Dprintf("H.264 SEI: -> stream bitrate %.1f, frame rate %.1f", sei->bitrate, sei->frame_rate);
}
num_referenced_subseqs = br_get_ue_golomb(&br); // num_referenced_subseqs
for (i = 0; i < num_referenced_subseqs; ++i) {
br_skip_ue_golomb(&br); // ref_sub_seq_layer_num
br_skip_ue_golomb(&br); // ref_sub_seq_id
br_get_bit(&br); // ref_sub_seq_direction
}
break;
// default: default:
// sei->scan = VIDEO_SCAN_RESERVED; br_skip_bits(&br, payloadSize);
// break; break;
// } }
// break;
case 12: // sub_seq_characteristics // force byte align
br_skip_ue_golomb(&br); // sub_seq_layer_num br_byte_align(&br);
br_skip_ue_golomb(&br); // sub_seq_id }
if (br_get_bit(&br)) { // duration_flag
br_skip_bits(&br, 32); // sub_seq_duration
if (br_get_bit(&br)) { // average_rate_flag
br_skip_bit(&br); // accurate_statistics_flag
sei->bitrate = br_get_u16(&br); // average_bit_rate
sei->frame_rate = br_get_u16(&br); // average_frame_rate
//Dprintf("H.264 SEI: -> stream bitrate %d, frame rate %d", sei->bitrate, sei->frame_rate);
}
}
break;
default:
br_skip_bits(&br, payloadSize);
break;
}
// force byte align
br_byte_align(&br);
} // sei_payload
} // sei_message
};
return true; return true;
} }
#endif
static int h264_nal_unescape(uint8_t *dst, const uint8_t *src, int len) static int h264_nal_unescape(uint8_t *dst, const uint8_t *src, int len)
{ {
@@ -374,6 +372,8 @@ static int h264_get_picture_type(const uint8_t *buf, int len)
bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info) bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info)
{ {
bool sps_found = false, sei_found = true; // sei currently disabled
// H.264 detection, search for NAL AUD // H.264 detection, search for NAL AUD
if (!IS_NAL_AUD(buf)) if (!IS_NAL_AUD(buf))
return false; return false;
@@ -387,7 +387,7 @@ bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info)
// Scan video packet ... // Scan video packet ...
for (int i = 5; i < len - 4; i++) { for (int i = 5; i < len - 4; i++) {
// ... for sequence parameter set // ... for sequence parameter set
if ((buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SPS) { if (!sps_found && (buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SPS) {
uint8_t nal_data[len]; uint8_t nal_data[len];
int nal_len; int nal_len;
//Dprintf("H.264: Found NAL SPS at offset %d/%d", i, len); //Dprintf("H.264: Found NAL SPS at offset %d/%d", i, len);
@@ -398,13 +398,12 @@ bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info)
info->width = sps.width; info->width = sps.width;
info->height = sps.height; info->height = sps.height;
info->aspectRatio = sps.aspect_ratio; info->aspectRatio = sps.aspect_ratio;
return true; sps_found = true;
} }
} }
} }
#if 0
// ... for supplemental enhancement information // ... for supplemental enhancement information
else if ((buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SEI) { if (!sei_found && (buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SEI) {
uint8_t nal_data[len]; uint8_t nal_data[len];
int nal_len; int nal_len;
//Dprintf("H.264: Found NAL SEI at offset %d/%d", i, len); //Dprintf("H.264: Found NAL SEI at offset %d/%d", i, len);
@@ -414,11 +413,12 @@ bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info)
info->frameRate = sei.frame_rate; info->frameRate = sei.frame_rate;
info->bitrate = sei.bitrate; info->bitrate = sei.bitrate;
info->scan = sei.scan; info->scan = sei.scan;
return true; sei_found = true;
} }
} }
} }
#endif if (sps_found && sei_found)
break;
} }
return true; return true;

View File

@@ -21,8 +21,8 @@
#define OSDINFOHEIGHT (OSDROWHEIGHT * 13) // in pixels (13 rows) #define OSDINFOHEIGHT (OSDROWHEIGHT * 13) // in pixels (13 rows)
#define OSDSTATUSHEIGHT (OSDROWHEIGHT * 6) // in pixels (6 rows) #define OSDSTATUSHEIGHT (OSDROWHEIGHT * 6) // in pixels (6 rows)
#define OSDSPACING 5 #define OSDSPACING 5
#define OSDCORNERING 10 #define OSDROUNDING 10
#define IS_OSDCORNERING (femonConfig.skin == eFemonSkinElchi) #define IS_OSDROUNDING (femonConfig.skin == eFemonSkinElchi)
#define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset) #define OSDINFOWIN_Y(offset) (femonConfig.position ? (OSDHEIGHT - OSDINFOHEIGHT + offset) : offset)
#define OSDINFOWIN_X(col) ((col == 4) ? 455 : (col == 3) ? 305 : (col == 2) ? 155 : 15) #define OSDINFOWIN_X(col) ((col == 4) ? 455 : (col == 3) ? 305 : (col == 2) ? 155 : 15)
@@ -36,11 +36,11 @@
x -= bm->Width() + spacing; \ x -= bm->Width() + spacing; \
y = (OSDROWHEIGHT - bm->Height()) / 2; \ y = (OSDROWHEIGHT - bm->Height()) / 2; \
if (y < 0) y = 0; \ if (y < 0) y = 0; \
m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset + y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); \ m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset) + y, *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); \
} }
#define OSDDRAWSTATUSFRONTEND(column, bitmap, status) \ #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) 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) \ #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(1), OSDSTATUSWIN_Y(offset), label1, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \
@@ -54,28 +54,31 @@
#define OSDDRAWSTATUSBAR(value) \ #define OSDDRAWSTATUSBAR(value) \
if (value > 0) { \ if (value > 0) { \
value = OSDBARWIDTH(value); \ value = OSDBARWIDTH(value); \
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset + 3), min(OSDBARWIDTH(femonConfig.redlimit), value), OSDSTATUSWIN_Y(offset + OSDROWHEIGHT - 3), femonTheme[femonConfig.theme].clrRed); \ m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset) + 3, min(OSDBARWIDTH(femonConfig.redlimit), value), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrRed); \
if (value > OSDBARWIDTH(femonConfig.redlimit)) \ if (value > OSDBARWIDTH(femonConfig.redlimit)) \
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset + 3), min((OSDWIDTH * femonConfig.greenlimit / 100), value), OSDSTATUSWIN_Y(offset + OSDROWHEIGHT - 3), femonTheme[femonConfig.theme].clrYellow); \ m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset) + 3, min((OSDWIDTH * femonConfig.greenlimit / 100), value), OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrYellow); \
if (value > OSDBARWIDTH(femonConfig.greenlimit)) \ if (value > OSDBARWIDTH(femonConfig.greenlimit)) \
m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset + 3), value, OSDSTATUSWIN_Y(offset + OSDROWHEIGHT - 3), femonTheme[femonConfig.theme].clrGreen); \ m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset) + 3, value, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 3, femonTheme[femonConfig.theme].clrGreen); \
} }
#define OSDDRAWSTATUSTITLEBAR(title) \ #define OSDDRAWSTATUSTITLEBAR(title) \
m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), femonTheme[femonConfig.theme].clrBackground); \ m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset), OSDWIDTH, OSDSTATUSWIN_Y(offset) + OSDROWHEIGHT - 1, femonTheme[femonConfig.theme].clrTitleBackground); \
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); \ m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \
if (IS_OSDCORNERING) { \ if (IS_OSDROUNDING) { \
m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDCORNERING, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -2); \ m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDROUNDING, OSDSTATUSWIN_Y(OSDROUNDING), clrTransparent, -2); \
m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -1); \ 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() \ #define OSDDRAWSTATUSBOTTOMBAR() \
if (IS_OSDCORNERING) { \ if (IS_OSDROUNDING) { \
m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDCORNERING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); \ m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT) - OSDROUNDING, OSDROUNDING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); \
m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -4); \ 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) \ #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(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) m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font)
@@ -96,22 +99,22 @@
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(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font)
#define OSDDRAWINFOTITLEBAR(title) \ #define OSDDRAWINFOTITLEBAR(title) \
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), femonTheme[femonConfig.theme].clrBackground); \ m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset) + OSDROWHEIGHT - 1, femonTheme[femonConfig.theme].clrTitleBackground); \
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); \ m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \
if (IS_OSDCORNERING) { \ if (IS_OSDROUNDING) { \
m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDCORNERING, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -2); \ m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDROUNDING, OSDINFOWIN_Y(OSDROUNDING), clrTransparent, -2); \
m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -1); \ 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() \ #define OSDDRAWINFOBOTTOMBAR() \
if (IS_OSDCORNERING) { \ if (IS_OSDROUNDING) { \
m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDCORNERING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); \ m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDROUNDING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); \
m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); \ m_Osd->DrawEllipse((OSDWIDTH - OSDROUNDING), OSDINFOWIN_Y(OSDINFOHEIGHT) - OSDROUNDING, OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); \
} }
#define OSDCLEARINFO() \ #define OSDCLEARINFO() \
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent) m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT) - 1, clrTransparent)
cFemonOsd *cFemonOsd::pInstance = NULL; cFemonOsd *cFemonOsd::pInstance = NULL;
@@ -126,26 +129,27 @@ cFemonOsd *cFemonOsd::Instance(bool create)
} }
cFemonOsd::cFemonOsd() cFemonOsd::cFemonOsd()
:cOsdObject(true), cThread("femon osd") : 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_SNR(0),
m_Signal(0),
m_BER(0),
m_UNC(0),
m_DisplayMode(femonConfig.displaymode),
m_InputTime(0),
m_Sleep(),
m_Mutex()
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); Dprintf("%s()\n", __PRETTY_FUNCTION__);
m_Osd = NULL;
m_Receiver = NULL;
m_Frontend = -1;
m_SvdrpVideoBitrate = -1.0;
m_SvdrpAudioBitrate = -1.0;
m_SvdrpFrontend = -1;
m_SvdrpConnection.handle = -1; m_SvdrpConnection.handle = -1;
m_SvdrpPlugin = NULL;
m_Number = 0;
m_OldNumber = 0;
m_Signal = 0;
m_SNR = 0;
m_BER = 0;
m_UNC = 0;
m_DisplayMode = femonConfig.displaymode;
m_InputTime.Set(0);
m_Mutex = new cMutex();
if (Setup.UseSmallFont == 0) { if (Setup.UseSmallFont == 0) {
// Dirty hack to force the small fonts... // Dirty hack to force the small fonts...
Setup.UseSmallFont = 1; Setup.UseSmallFont = 1;
@@ -154,6 +158,8 @@ cFemonOsd::cFemonOsd()
} }
else else
m_Font = cFont::GetFont(fontSml); m_Font = cFont::GetFont(fontSml);
if (OSDHEIGHT < (OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT))
OSDHEIGHT = (OSDINFOHEIGHT + OSDROWHEIGHT + OSDSTATUSHEIGHT);
} }
cFemonOsd::~cFemonOsd(void) cFemonOsd::~cFemonOsd(void)
@@ -167,21 +173,23 @@ cFemonOsd::~cFemonOsd(void)
if (m_SvdrpPlugin) if (m_SvdrpPlugin)
m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection);
} }
if (m_Receiver) if (m_Receiver) {
delete m_Receiver; m_Receiver->Deactivate();
DELETENULL(m_Receiver);
}
if (m_Osd) if (m_Osd)
delete m_Osd; DELETENULL(m_Osd);
pInstance = NULL; pInstance = NULL;
} }
void cFemonOsd::DrawStatusWindow(void) void cFemonOsd::DrawStatusWindow(void)
{ {
cMutexLock lock(m_Mutex); cMutexLock lock(&m_Mutex);
cBitmap *bm = NULL; cBitmap *bm = NULL;
int snr = m_SNR / 655; int snr = m_SNR / 655;
int signal = m_Signal / 655; int signal = m_Signal / 655;
int offset = 0; int offset = 0;
int x = OSDWIDTH - OSDCORNERING; int x = OSDWIDTH - OSDROUNDING;
int y = 0; int y = 0;
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
@@ -262,7 +270,7 @@ void cFemonOsd::DrawStatusWindow(void)
OSDDRAWSTATUSBAR(snr); OSDDRAWSTATUSBAR(snr);
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("STR:", *cString::sprintf("%04x", m_Signal), *cString::sprintf("(%2d%%)", m_Signal / 655), "BER:", *cString::sprintf("%08x", m_BER), OSDDRAWSTATUSVALUES("STR:", *cString::sprintf("%04x", m_Signal), *cString::sprintf("(%2d%%)", m_Signal / 655), "BER:", *cString::sprintf("%08x", m_BER),
*cString::sprintf("%s:", tr("Video")), *getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0))); *cString::sprintf("%s:", tr("Video")), *getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0)));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWSTATUSVALUES("SNR:", *cString::sprintf("%04x", m_SNR), *cString::sprintf("(%2d%%)", m_SNR / 655), "UNC:", *cString::sprintf("%08x", m_UNC), OSDDRAWSTATUSVALUES("SNR:", *cString::sprintf("%04x", m_SNR), *cString::sprintf("(%2d%%)", m_SNR / 655), "UNC:", *cString::sprintf("%08x", m_UNC),
*cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")), *cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")),
@@ -282,7 +290,7 @@ void cFemonOsd::DrawStatusWindow(void)
void cFemonOsd::DrawInfoWindow(void) void cFemonOsd::DrawInfoWindow(void)
{ {
cMutexLock lock(m_Mutex); cMutexLock lock(&m_Mutex);
int offset = 0; int offset = 0;
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
@@ -367,7 +375,7 @@ void cFemonOsd::DrawInfoWindow(void)
case eFemonModeStream: case eFemonModeStream:
OSDDRAWINFOTITLEBAR(tr("Stream Information")); OSDDRAWINFOTITLEBAR(tr("Stream Information"));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOACTIVE( tr("Video Stream"), *cString::sprintf("#%d", channel->Vpid())); OSDDRAWINFOACTIVE( tr("Video Stream"), *getVideoStream(channel->Vpid()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOINACTIVE(tr("Codec"), *getVideoCodec(m_Receiver ? m_Receiver->VideoCodec() : VIDEO_CODEC_INVALID)); OSDDRAWINFOINACTIVE(tr("Codec"), *getVideoCodec(m_Receiver ? m_Receiver->VideoCodec() : VIDEO_CODEC_INVALID));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
@@ -381,7 +389,7 @@ void cFemonOsd::DrawInfoWindow(void)
offset += OSDROWHEIGHT; 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)); 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; offset += OSDROWHEIGHT;
OSDDRAWINFOACTIVE( tr("Audio Stream"), *cString::sprintf("#%d (%s)", IS_AUDIO_TRACK(track) ? channel->Apid(int(track - ttAudioFirst)) : channel->Apid(0), IS_AUDIO_TRACK(track) ? channel->Alang(int(track - ttAudioFirst)) : channel->Alang(0))); OSDDRAWINFOACTIVE( tr("Audio Stream"), *getAudioStream(track, channel));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOINACTIVE(tr("Codec"), *getAudioCodec(m_Receiver ? m_Receiver->AudioCodec() : AUDIO_CODEC_INVALID)); OSDDRAWINFOINACTIVE(tr("Codec"), *getAudioCodec(m_Receiver ? m_Receiver->AudioCodec() : AUDIO_CODEC_INVALID));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
@@ -397,7 +405,7 @@ void cFemonOsd::DrawInfoWindow(void)
OSDDRAWINFOTITLEBAR(tr("Stream Information")); OSDDRAWINFOTITLEBAR(tr("Stream Information"));
if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) {
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOINACTIVE(tr("AC-3 Stream"), *cString::sprintf("#%d %s", channel->Dpid(int(track - ttDolbyFirst)), channel->Dlang(int(track - ttDolbyFirst)))); OSDDRAWINFOACTIVE( tr("AC-3 Stream"), *getAC3Stream(track, channel));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver->AC3Bitrate(), m_Receiver->AC3StreamBitrate())); OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver->AC3Bitrate(), m_Receiver->AC3StreamBitrate()));
offset += OSDROWHEIGHT; offset += OSDROWHEIGHT;
@@ -510,21 +518,23 @@ void cFemonOsd::Show(void)
m_Osd = cOsdProvider::NewOsd(((cOsd::OsdWidth() - OSDWIDTH) / 2) + cOsd::OsdLeft() + femonConfig.osdoffset, ((cOsd::OsdHeight() - OSDHEIGHT) / 2) + cOsd::OsdTop()); m_Osd = cOsdProvider::NewOsd(((cOsd::OsdWidth() - OSDWIDTH) / 2) + cOsd::OsdLeft() + femonConfig.osdoffset, ((cOsd::OsdHeight() - OSDHEIGHT) / 2) + cOsd::OsdTop());
if (m_Osd) { if (m_Osd) {
// try to use single 8bpp area tArea Areas1[] = { { 0, 0, OSDWIDTH - 1, OSDHEIGHT - 1, 8 } };
tArea Areas1[] = { { 0, 0, OSDWIDTH, OSDHEIGHT, 8 } }; if (Setup.AntiAlias && m_Osd->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) {
if (femonConfig.usesinglearea && m_Osd->CanHandleAreas(Areas1, sizeof(Areas1) / sizeof(tArea)) == oeOk) {
m_Osd->SetAreas(Areas1, sizeof(Areas1) / sizeof(tArea)); m_Osd->SetAreas(Areas1, sizeof(Areas1) / sizeof(tArea));
} }
else { else {
tArea Areas2[] = { { 0, OSDSTATUSWIN_Y(0), (OSDWIDTH - 1), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT - 1), femonTheme[femonConfig.theme].bpp }, 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(OSDROWHEIGHT - 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(OSDINFOHEIGHT - 1), 2 } }; { 0, OSDINFOWIN_Y(OSDROWHEIGHT), OSDWIDTH - 1, OSDINFOWIN_Y(0) + OSDINFOHEIGHT - 1, 2 } };
m_Osd->SetAreas(Areas2, sizeof(Areas2) / sizeof(tArea)); m_Osd->SetAreas(Areas2, sizeof(Areas2) / sizeof(tArea));
} }
m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent); OSDCLEARSTATUS();
OSDCLEARINFO();
m_Osd->Flush(); m_Osd->Flush();
if (m_Receiver) if (m_Receiver) {
delete m_Receiver; m_Receiver->Deactivate();
DELETENULL(m_Receiver);
}
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
@@ -566,8 +576,10 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber)
return; return;
} }
if (m_Receiver) if (m_Receiver) {
delete m_Receiver; m_Receiver->Deactivate();
DELETENULL(m_Receiver);
}
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {
@@ -585,8 +597,10 @@ void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks)
int apid[2] = {0, 0}; int apid[2] = {0, 0};
int dpid[2] = {0, 0}; int dpid[2] = {0, 0};
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
if (m_Receiver) if (m_Receiver) {
delete m_Receiver; m_Receiver->Deactivate();
DELETENULL(m_Receiver);
}
if (femonConfig.analyzestream) { if (femonConfig.analyzestream) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) { if (channel) {

View File

@@ -25,27 +25,29 @@
class cFemonOsd : public cOsdObject, public cThread, public cStatus { class cFemonOsd : public cOsdObject, public cThread, public cStatus {
private: private:
static cFemonOsd *pInstance; static cFemonOsd *pInstance;
cOsd *m_Osd;
cFemonReceiver *m_Receiver; cOsd *m_Osd;
int m_Frontend; cFemonReceiver *m_Receiver;
int m_SvdrpFrontend; int m_Frontend;
double m_SvdrpVideoBitrate; int m_SvdrpFrontend;
double m_SvdrpAudioBitrate; double m_SvdrpVideoBitrate;
double m_SvdrpAudioBitrate;
SvdrpConnection_v1_0 m_SvdrpConnection; SvdrpConnection_v1_0 m_SvdrpConnection;
cPlugin *m_SvdrpPlugin; cPlugin *m_SvdrpPlugin;
struct dvb_frontend_info m_FrontendInfo; struct dvb_frontend_info m_FrontendInfo;
int m_Number; int m_Number;
int m_OldNumber; int m_OldNumber;
uint16_t m_SNR; uint16_t m_SNR;
uint16_t m_Signal; uint16_t m_Signal;
uint32_t m_BER; uint32_t m_BER;
uint32_t m_UNC; uint32_t m_UNC;
fe_status_t m_FrontendStatus; fe_status_t m_FrontendStatus;
int m_DisplayMode; int m_DisplayMode;
const cFont *m_Font; const cFont *m_Font;
cTimeMs m_InputTime; cTimeMs m_InputTime;
cCondWait m_Sleep; cCondWait m_Sleep;
cMutex* m_Mutex; cMutex m_Mutex;
void DrawStatusWindow(void); void DrawStatusWindow(void);
void DrawInfoWindow(void); void DrawInfoWindow(void);
bool SvdrpConnect(void); bool SvdrpConnect(void);
@@ -66,10 +68,10 @@ public:
virtual void Show(void); virtual void Show(void);
virtual eOSState ProcessKey(eKeys Key); virtual eOSState ProcessKey(eKeys Key);
bool DeviceSwitch(int direction); bool DeviceSwitch(int direction);
double GetVideoBitrate(void); double GetVideoBitrate(void);
double GetAudioBitrate(void); double GetAudioBitrate(void);
double GetDolbyBitrate(void); double GetDolbyBitrate(void);
}; };
#endif //__FEMONOSD_H #endif //__FEMONOSD_H

View File

@@ -23,6 +23,8 @@
cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]) cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[])
: cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL), : cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL),
cThread("femon receiver"), cThread("femon receiver"),
m_Sleep(),
m_Active(false),
m_VideoPid(Vpid), m_VideoPid(Vpid),
m_VideoPacketCount(0), m_VideoPacketCount(0),
m_VideoBitrate(0.0), m_VideoBitrate(0.0),
@@ -75,10 +77,19 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[
cFemonReceiver::~cFemonReceiver(void) cFemonReceiver::~cFemonReceiver(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); Dprintf("%s()\n", __PRETTY_FUNCTION__);
m_Sleep.Signal(); Deactivate();
if (Running()) }
Cancel(3);
Detach(); void cFemonReceiver::Deactivate(void)
{
Dprintf("%s()\n", __PRETTY_FUNCTION__);
if (m_Active) {
m_Active = false;
m_Sleep.Signal();
if (Running())
Cancel(3);
Detach();
}
} }
void cFemonReceiver::GetVideoInfo(uint8_t *buf, int len) void cFemonReceiver::GetVideoInfo(uint8_t *buf, int len)
@@ -165,7 +176,7 @@ void cFemonReceiver::Activate(bool On)
if (On) if (On)
Start(); Start();
else else
Cancel(); Deactivate();
} }
void cFemonReceiver::Receive(uchar *Data, int Length) void cFemonReceiver::Receive(uchar *Data, int Length)
@@ -214,7 +225,8 @@ void cFemonReceiver::Action(void)
{ {
Dprintf("%s()\n", __PRETTY_FUNCTION__); Dprintf("%s()\n", __PRETTY_FUNCTION__);
cTimeMs t; cTimeMs t;
while (Running()) { m_Active = true;
while (Running() && m_Active) {
t.Set(0); t.Set(0);
// TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit
m_VideoBitrate = (10.0 * 8.0 * 184.0 * m_VideoPacketCount) / femonConfig.calcinterval; m_VideoBitrate = (10.0 * 8.0 * 184.0 * m_VideoPacketCount) / femonConfig.calcinterval;

View File

@@ -17,6 +17,7 @@
class cFemonReceiver : public cReceiver, public cThread { class cFemonReceiver : public cReceiver, public cThread {
private: private:
cCondWait m_Sleep; cCondWait m_Sleep;
bool m_Active;
int m_VideoPid; int m_VideoPid;
int m_VideoPacketCount; int m_VideoPacketCount;
@@ -54,6 +55,7 @@ protected:
public: public:
cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]); cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]);
virtual ~cFemonReceiver(); virtual ~cFemonReceiver();
void Deactivate(void);
bool VideoValid(void) { return m_VideoValid; }; // boolean bool VideoValid(void) { return m_VideoValid; }; // boolean
double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s

View File

@@ -199,6 +199,41 @@ cString getCA(int value)
return cString::sprintf("%X", value); return cString::sprintf("%X", value);
} }
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) cString getVideoCodec(int value)
{ {
switch (value) { switch (value) {

View File

@@ -37,7 +37,9 @@ cString getDpids(const cChannel *channel);
cString getSpids(const cChannel *channel); cString getSpids(const cChannel *channel);
cString getCAids(const cChannel *channel, bool identify = false); cString getCAids(const cChannel *channel, bool identify = false);
cString getCA(int value); cString getCA(int value);
cString getVideoStream(int value);
cString getVideoCodec(int value); cString getVideoCodec(int value);
cString getAudioStream(int value, const cChannel *channel);
cString getAudioCodec(int value); cString getAudioCodec(int value);
cString getAudioChannelMode(int value); cString getAudioChannelMode(int value);
cString getCoderate(int value); cString getCoderate(int value);
@@ -55,6 +57,7 @@ cString getResolution(int width, int height, int scan);
cString getAspectRatio(int value); cString getAspectRatio(int value);
cString getVideoFormat(int value); cString getVideoFormat(int value);
cString getFrameRate(double value); cString getFrameRate(double value);
cString getAC3Stream(int value, const cChannel *channel);
cString getAC3BitStreamMode(int value, int coding); cString getAC3BitStreamMode(int value, int coding);
cString getAC3AudioCodingMode(int value, int stream); cString getAC3AudioCodingMode(int value, int stream);
cString getAC3CenterMixLevel(int value); cString getAC3CenterMixLevel(int value);

View File

@@ -7,7 +7,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n"
@@ -71,15 +71,6 @@ msgstr "Hauptmen
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "" msgstr ""
msgid "Use single area (8bpp)"
msgstr "Ein Bildbereich benutzen (8bpp)"
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
msgid "Default display mode" msgid "Default display mode"
msgstr "Standard Anzeigemodus" msgstr "Standard Anzeigemodus"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n"
@@ -69,15 +69,6 @@ msgstr "Ocultar en el men
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "" msgstr ""
msgid "Use single area (8bpp)"
msgstr ""
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
msgid "Default display mode" msgid "Default display mode"
msgstr "Modo de visualizaci<63>n estandar" msgstr "Modo de visualizaci<63>n estandar"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n"
@@ -69,15 +69,6 @@ msgstr "Peida valik peamen
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "" msgstr ""
msgid "Use single area (8bpp)"
msgstr ""
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
msgid "Default display mode" msgid "Default display mode"
msgstr "Vaikimisi displei moodus" msgstr "Vaikimisi displei moodus"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n"
@@ -69,18 +69,6 @@ msgstr "Piilota valinta päävalikosta"
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "Määrittele, näytetäänkö laajennoksen valinta päävalikossa." msgstr "Määrittele, näytetäänkö laajennoksen valinta päävalikossa."
msgid "Use single area (8bpp)"
msgstr "Käytä yksittäistä kuva-aluetta (8bpp)"
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
"Määrittele, yritetäänkö käyttää yksittäistä 8bpp kuva-aluetta.\n"
"\n"
"Truetype-kirjasimet ja reunan pehmennys vaativat tämän asetuksen."
msgid "Default display mode" msgid "Default display mode"
msgstr "Oletusnäyttötila" msgstr "Oletusnäyttötila"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2008-01-26 09:59+0100\n" "PO-Revision-Date: 2008-01-26 09:59+0100\n"
@@ -69,18 +69,6 @@ msgstr "Masquer dans le menu principal"
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "D<>finit si l'entr<74>e doit <20>tre masqu<71>e dans le menu principal." msgstr "D<>finit si l'entr<74>e doit <20>tre masqu<71>e dans le menu principal."
msgid "Use single area (8bpp)"
msgstr "Utiliser zone unique (8bpp)"
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
"D<>finit si une seule zone OSD de 8bpp est pr<70>f<EFBFBD>r<EFBFBD>e.\n"
"\n"
"Requis par les polices Truetype et l'anti-aliasing."
msgid "Default display mode" msgid "Default display mode"
msgstr "Affichage par d<>faut" msgstr "Affichage par d<>faut"

View File

@@ -6,10 +6,10 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2008-04-17 00:18+0100\n" "PO-Revision-Date: 2008-11-10 23:37+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: <vdr@linuxtv.org>\n" "Language-Team: <vdr@linuxtv.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -70,18 +70,6 @@ msgstr "Nascondi voce menu principale"
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "Definisci se la voce del menu principale <20> nascosta." msgstr "Definisci se la voce del menu principale <20> nascosta."
msgid "Use single area (8bpp)"
msgstr "Utilizza area singola (8bpp)"
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
"Definisci se <20> preferita un'area OSD singola a 8bpp.\n"
"\n"
"Richiesto dai caratteri Truetype e anti-aliasing."
msgid "Default display mode" msgid "Default display mode"
msgstr "Modalit<69> visualizz. predefinita" msgstr "Modalit<69> visualizz. predefinita"
@@ -212,7 +200,7 @@ msgid "Video Stream"
msgstr "Flusso video" msgstr "Flusso video"
msgid "Codec" msgid "Codec"
msgstr "" msgstr "Codifica"
msgid "Bitrate" msgid "Bitrate"
msgstr "Bitrate" msgstr "Bitrate"
@@ -233,7 +221,7 @@ msgid "Audio Stream"
msgstr "Flusso audio" msgstr "Flusso audio"
msgid "Channel Mode" msgid "Channel Mode"
msgstr "" msgstr "Modalit<EFBFBD> canale"
msgid "Sampling Frequency" msgid "Sampling Frequency"
msgstr "Frequenza campionamento" msgstr "Frequenza campionamento"
@@ -305,43 +293,43 @@ msgid "SkyCrypt"
msgstr "SkyCrypt" msgstr "SkyCrypt"
msgid "MPEG-2" msgid "MPEG-2"
msgstr "" msgstr "MPEG-2"
msgid "H.264" msgid "H.264"
msgstr "" msgstr "H.264"
msgid "MPEG-1 Layer I" msgid "MPEG-1 Layer I"
msgstr "" msgstr "MPEG-1 Layer I"
msgid "MPEG-1 Layer II" msgid "MPEG-1 Layer II"
msgstr "" msgstr "MPEG-1 Layer II"
msgid "MPEG-1 Layer III" msgid "MPEG-1 Layer III"
msgstr "" msgstr "MPEG-1 Layer III"
msgid "MPEG-2 Layer I" msgid "MPEG-2 Layer I"
msgstr "" msgstr "MPEG-2 Layer I"
msgid "MPEG-2 Layer II" msgid "MPEG-2 Layer II"
msgstr "" msgstr "MPEG-2 Layer II"
msgid "MPEG-2 Layer III" msgid "MPEG-2 Layer III"
msgstr "" msgstr "MPEG-2 Layer III"
msgid "HE-AAC" msgid "HE-AAC"
msgstr "" msgstr "HE-AAC"
msgid "stereo" msgid "stereo"
msgstr "" msgstr "stereo"
msgid "joint Stereo" msgid "joint Stereo"
msgstr "" msgstr "joint Stereo"
msgid "dual" msgid "dual"
msgstr "" msgstr "dual"
msgid "mono" msgid "mono"
msgstr "" msgstr "mono"
msgid "none" msgid "none"
msgstr "nessuna" msgstr "nessuna"
@@ -353,22 +341,22 @@ msgid "MHz"
msgstr "MHz" msgstr "MHz"
msgid "interlaced" msgid "interlaced"
msgstr "" msgstr "interlacciato"
msgid "progressive" msgid "progressive"
msgstr "" msgstr "progressivo"
msgid "reserved" msgid "reserved"
msgstr "riservato" msgstr "riservato"
msgid "extended" msgid "extended"
msgstr "" msgstr "esteso"
msgid "unknown" msgid "unknown"
msgstr "sconosciuto" msgstr "sconosciuto"
msgid "component" msgid "component"
msgstr "" msgstr "componente"
msgid "PAL" msgid "PAL"
msgstr "PAL" msgstr "PAL"
@@ -377,10 +365,10 @@ msgid "NTSC"
msgstr "NTSC" msgstr "NTSC"
msgid "SECAM" msgid "SECAM"
msgstr "" msgstr "SECAM"
msgid "MAC" msgid "MAC"
msgstr "" msgstr "MAC"
msgid "Hz" msgid "Hz"
msgstr "Hz" msgstr "Hz"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: femon 1.6.3\n" "Project-Id-Version: femon 1.6.4\n"
"Report-Msgid-Bugs-To: Rolf Ahrenberg\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n"
"POT-Creation-Date: 2008-11-09 13:31+0200\n" "POT-Creation-Date: 2008-11-09 13:31+0200\n"
"PO-Revision-Date: 2007-08-12 23:22+0300\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n"
@@ -69,15 +69,6 @@ msgstr "
msgid "Define whether the main menu entry is hidden." msgid "Define whether the main menu entry is hidden."
msgstr "" msgstr ""
msgid "Use single area (8bpp)"
msgstr ""
msgid ""
"Define whether a single 8bpp OSD area is preferred.\n"
"\n"
"Required by Truetype fonts and anti-aliasing."
msgstr ""
msgid "Default display mode" msgid "Default display mode"
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" msgstr "<22><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"