diff --git a/HISTORY b/HISTORY index 2c7ecef..edea479 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,4 @@ + =================================== VDR Plugin 'femon' Revision History =================================== @@ -303,3 +304,9 @@ VDR Plugin 'femon' Revision History - Converted HISTORY and fi_FI.po to UTF-8. - Optimized receiver and OSD thread termination. + +2008-11-09: Version 1.6.3 + +- Added initial support for H.264 and HE-AAC. +- Fixed detection of false positives in audio/video streams. +- Refactored source code. diff --git a/Makefile b/Makefile index c98311b..9b4d90d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ # -# Makefile for a Video Disk Recorder plugin +# Makefile for Frontend Status Monitor plugin # -# $Id$ # Debugging on/off #FEMON_DEBUG = 1 @@ -67,7 +66,7 @@ all-redirect: all ### The object files (add further files here): -OBJS = femon.o femonosd.o femonreceiver.o femoncfg.o femontools.o +OBJS = femon.o femonosd.o femonreceiver.o femoncfg.o femontools.o femonmpeg.o femonac3.o femonaac.o femonh264.o femonsymbol.o ### The main target: diff --git a/README b/README index 4daf0c2..e9e42ed 100644 --- a/README +++ b/README @@ -28,7 +28,8 @@ The plugin is based on a neat console frontend status monitor application called 'femon' by Johannes Stezenbach (see DVB-apps/szap/femon.c for further information). The bitrate calculation trick originates from the 'dvbstream' application by Dave Chapman and the stream information routines are taken from -the 'libdvb' library by Metzler Brothers. +the 'libdvb' library by Metzler Brothers. The H.264 parsing routines are taken +from vdr-xineliboutput plugin by Petri Hintukainen. Terminology: diff --git a/femon.c b/femon.c index 1512d14..d1632ab 100644 --- a/femon.c +++ b/femon.c @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #include @@ -19,7 +18,7 @@ #error "VDR-1.6.0 API version or greater is required!" #endif -static const char VERSION[] = "1.6.2"; +static const char VERSION[] = "1.6.3"; static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)"); static const char MAINMENUENTRY[] = trNOOP("Signal Information"); diff --git a/femonaac.c b/femonaac.c new file mode 100644 index 0000000..8f6fcd0 --- /dev/null +++ b/femonaac.c @@ -0,0 +1,77 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "femontools.h" +#include "femonaac.h" + +#define IS_HEAAC_AUDIO(buf) (((buf)[0] == 0xFF) && (((buf)[1] & 0xF6) == 0xF0)) + +static unsigned int samplerates[16] = +{ + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, -1, -1, -1, -1 +}; + +bool getAACAudioInfo(uint8_t *buf, int len, audio_info_t *info) +{ + // HE-AAC audio detection, search for syncword with layer set to 0 + if ((len < 4) || !IS_HEAAC_AUDIO(buf)) + return false; + + /* ADTS Fixed Header: + * syncword 12b always: '111111111111' + * id 1b 0: MPEG-4, 1: MPEG-2 + * layer 2b always: '00' + * protection_absent 1b + * profile 2b 0: Main profile AAC MAIN 1: Low Complexity profile (LC) AAC LC 2: Scalable Sample Rate profile (SSR) AAC SSR 3: (reserved) AAC LTP + * sampling_frequency_index 4b + * private_bit 1b + * channel_configuration 3b + * original/copy 1b + * home 1b + * emphasis 2b only if ID == 0 (ie MPEG-4) + */ + + int sampling_frequency_index = (buf[2] & 0x03C) >> 2; + int channel_configuration = ((buf[2] & 0x01) << 2) | ((buf[3] & 0xC0) >> 6); + + info->codec = AUDIO_CODEC_HEAAC; + info->bitrate = AUDIO_BITRATE_RESERVED; + + switch (channel_configuration) { + case 0: + info->channelMode = AUDIO_CHANNEL_MODE_STEREO; + break; + + case 1: + info->channelMode = AUDIO_CHANNEL_MODE_JOINT_STEREO; + break; + + case 2: + info->channelMode = AUDIO_CHANNEL_MODE_DUAL; + break; + + case 3: + info->channelMode = AUDIO_CHANNEL_MODE_SINGLE; + break; + + default: + info->channelMode = AUDIO_CHANNEL_MODE_INVALID; + break; + } + + switch (sampling_frequency_index) { + case 0xC ... 0xF: + info->samplingFrequency = AUDIO_SAMPLING_FREQUENCY_RESERVED; + break; + + default: + info->samplingFrequency = samplerates[sampling_frequency_index]; + break; + } + + return true; +} diff --git a/femonaac.h b/femonaac.h new file mode 100644 index 0000000..7a1c6b6 --- /dev/null +++ b/femonaac.h @@ -0,0 +1,15 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONAAC_H +#define __FEMONAAC_H + +#include "femonaudio.h" + +bool getAACAudioInfo(uint8_t *buf, int len, audio_info_t *info); + +#endif //__FEMONAAC_H diff --git a/femonac3.c b/femonac3.c new file mode 100644 index 0000000..095e2c5 --- /dev/null +++ b/femonac3.c @@ -0,0 +1,115 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * AC3 Audio Header: http://www.atsc.org/standards/a_52a.pdf + */ + +#include "femontools.h" +#include "femonac3.h" + +#define IS_AC3_DATA(buf) (((buf)[0] == 0x0b) && ((buf)[1] == 0x77)) + +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} +//}; + +bool getAC3AudioInfo(uint8_t *buf, int len, ac3_info_t *info) +{ + if (!IS_AC3_DATA(buf) || (len < 8)) + return false; + + uint8_t *data = buf + 2; + uint8_t frame = (data[2] & 0x3f); + info->bitrate = 1000 * ac3_bitrates[frame >> 1]; + uint8_t fr = (data[2] & 0xc0 ) >> 6; + //uint8_t sz = ac3_frames[fr][frame >> 1]; + //if ((frame & 1) && (fr == 1)) + // sz++; + //sz <<= 1; + info->samplingFrequency = 100 * ac3_freq[fr]; + info->bitstreamMode = (data[3] & 7); + int acm = (data[4] & 0xE0) >> 5; + info->audioCodingMode = acm; + if ((acm & 0x01) && (acm != 0x01)) { + // 3 front channels + info->centerMixLevel = (data[4] & 0x18) >> 3; + if (acm & 0x04) { + // a surround channel exists + info->surroundMixLevel = (data[4] & 0x06) >> 1; + if (acm == 0x02) { + // if in 2/0 mode + info->dolbySurroundMode = ((data[4] & 0x01) << 1) | ((data[5] & 0x80) >> 7); + info->lfe = (data[5] & 0x40) >> 6; + info->dialogLevel = (data[5] & 0x3e) >> 1; + } + else { + info->dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + info->lfe = (data[4] & 0x01); + info->dialogLevel = (data[5] & 0xF8) >> 3; + } + } + else { + info->surroundMixLevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; + if (acm == 0x02) { + // if in 2/0 mode + info->dolbySurroundMode = (data[4] & 0x06) >> 1; + info->lfe = (data[4] & 0x01); + info->dialogLevel = (data[5] & 0xF8) >> 3; + } + else { + info->dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + info->lfe = (data[4] & 0x04) >> 2; + info->dialogLevel = (data[4] & 0x03) << 3 | ((data[5] & 0xE0) >> 5); + } + } + } + else { + info->centerMixLevel = AUDIO_CENTER_MIX_LEVEL_INVALID; + if (acm & 0x04) { + // a surround channel exists + info->surroundMixLevel = (data[4] & 0x18) >> 3; + if (acm == 0x02) { + // if in 2/0 mode + info->dolbySurroundMode = (data[4] & 0x06) >> 1; + info->lfe = (data[4] & 0x01); + info->dialogLevel = (data[5] & 0xF8) >> 3; + } + else { + info->dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + info->lfe = (data[4] & 0x04) >> 2; + info->dialogLevel = (data[4] & 0x03) << 3 | ((data[5] & 0xE0) >> 5); + } + } + else { + info->surroundMixLevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; + if (acm == 0x02) { + // if in 2/0 mode + info->dolbySurroundMode = (data[4] & 0x18) >> 3; + info->lfe = (data[4] & 0x04) >> 2; + info->dialogLevel = (data[4] & 0x03) << 3 | ((data[5] & 0xE0) >> 5); + } + else { + info->dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + info->lfe = (data[4] & 0x10) >> 4; + info->dialogLevel = ((data[4] & 0x0F) << 1) | ((data[5] & 0x80) >> 7); + } + } + } + + return true; +} diff --git a/femonac3.h b/femonac3.h new file mode 100644 index 0000000..93dd0c1 --- /dev/null +++ b/femonac3.h @@ -0,0 +1,15 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONAC3_H +#define __FEMONAC3_H + +#include "femonaudio.h" + +bool getAC3AudioInfo(uint8_t *buf, int len, ac3_info_t *info); + +#endif //__FEMONAC3_H diff --git a/femonaudio.h b/femonaudio.h new file mode 100644 index 0000000..d1b673b --- /dev/null +++ b/femonaudio.h @@ -0,0 +1,109 @@ +/* + * Frontend Status Monitor plugin for the AUDIO Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONAUDIO_H +#define __FEMONAUDIO_H + +enum eAudioCodec { + AUDIO_CODEC_INVALID = -1, + AUDIO_CODEC_UNKNOWN, + AUDIO_CODEC_MPEG1_I, + AUDIO_CODEC_MPEG1_II, + AUDIO_CODEC_MPEG1_III, + AUDIO_CODEC_MPEG2_I, + AUDIO_CODEC_MPEG2_II, + AUDIO_CODEC_MPEG2_III, + AUDIO_CODEC_HEAAC + }; + +enum eAudioChannelMode { + AUDIO_CHANNEL_MODE_INVALID = -1, + AUDIO_CHANNEL_MODE_STEREO, + AUDIO_CHANNEL_MODE_JOINT_STEREO, + AUDIO_CHANNEL_MODE_DUAL, + AUDIO_CHANNEL_MODE_SINGLE + }; + +enum eAudioBitrate { + AUDIO_BITRATE_RESERVED = -3, + AUDIO_BITRATE_FREE = -2, + AUDIO_BITRATE_INVALID = -1 + }; + +enum eAudioSamplingFrequency { + AUDIO_SAMPLING_FREQUENCY_RESERVED = -2, + AUDIO_SAMPLING_FREQUENCY_INVALID = -1 + }; + +enum eAudioCenterMixLevel { + AUDIO_CENTER_MIX_LEVEL_INVALID = -1, + AUDIO_CENTER_MIX_LEVEL_MINUS_3dB, + AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB, + AUDIO_CENTER_MIX_LEVEL_MINUS_6dB, + AUDIO_CENTER_MIX_LEVEL_RESERVED + }; + +enum eAudioSurroundMixLevel { + AUDIO_SURROUND_MIX_LEVEL_INVALID = -1, + AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB, + AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB, + AUDIO_SURROUND_MIX_LEVEL_0_dB, + AUDIO_SURROUND_MIX_LEVEL_RESERVED + }; + +enum eAudioDolbySurroundMode { + AUDIO_DOLBY_SURROUND_MODE_INVALID = -1, + AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED, + AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND, + AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND, + AUDIO_DOLBY_SURROUND_MODE_RESERVED + }; + +enum eAudioBitstreamMode { + AUDIO_BITSTREAM_MODE_INVALID = -1, + AUDIO_BITSTREAM_MODE_CM, + AUDIO_BITSTREAM_MODE_ME, + AUDIO_BITSTREAM_MODE_VI, + AUDIO_BITSTREAM_MODE_HI, + AUDIO_BITSTREAM_MODE_D, + AUDIO_BITSTREAM_MODE_C, + AUDIO_BITSTREAM_MODE_E, + AUDIO_BITSTREAM_MODE_VO_KAR + }; + +enum eAudioCodingMode { + AUDIO_CODING_MODE_INVALID = -1, + AUDIO_CODING_MODE_1_1, + AUDIO_CODING_MODE_1_0, + AUDIO_CODING_MODE_2_0, + AUDIO_CODING_MODE_3_0, + AUDIO_CODING_MODE_2_1, + AUDIO_CODING_MODE_3_1, + AUDIO_CODING_MODE_2_2, + AUDIO_CODING_MODE_3_2, + }; + +typedef struct audio_info { + eAudioCodec codec; // enum + double bitrate; // kbit/s or eAudioBitrate + int samplingFrequency; // Hz or eAudioSamplingFrequency + int channelMode; // eAudioChannelMode +} audio_info_t; + +typedef struct ac3_info { + int bitrate; // bit/s or eAudioBitrate + int samplingFrequency; // Hz or eAudioSamplingFrequency + int bitstreamMode; // 0..7 or eAudioBitstreamMode + int audioCodingMode; // 0..7 or eAudioCodingMode + int dolbySurroundMode; // eAudioDolbySurroundMode + int centerMixLevel; // eAudioCenterMixLevel + int surroundMixLevel; // eAudioSurroundMixLevel + int dialogLevel; // -dB + bool lfe; // boolean +} ac3_info_t; + +#endif //__FEMONAUDIO_H diff --git a/femoncfg.c b/femoncfg.c index 0b82979..efe74c1 100644 --- a/femoncfg.c +++ b/femoncfg.c @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #include diff --git a/femoncfg.h b/femoncfg.h index 51f1fb8..08e1560 100644 --- a/femoncfg.h +++ b/femoncfg.h @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #ifndef __FEMONCFG_H diff --git a/femonh264.c b/femonh264.c new file mode 100644 index 0000000..80321bf --- /dev/null +++ b/femonh264.c @@ -0,0 +1,425 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * The original NAL SPS parsing and bitstream functions are taken from + * vdr-xineliboutput plugin by Petri Hintukainen. + */ + +#include "femontools.h" +#include "femonh264.h" + +#define NAL_SEI 0x06 // Supplemental Enhancement Information +#define NAL_SPS 0x07 // Sequence Parameter Set +#define NAL_AUD 0x09 // Access Unit Delimiter +#define NAL_END_SEQ 0x10 // End of Sequence + +#define IS_NAL_SEI(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == NAL_SEI)) +#define IS_NAL_SPS(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == NAL_SPS)) +#define IS_NAL_AUD(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == NAL_AUD)) +#define IS_NAL_END_SEQ(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == NAL_END_SEQ)) + +// Picture types +#define NO_PICTURE 0 +#define I_FRAME 1 +#define P_FRAME 2 +#define B_FRAME 3 + +static const eVideoAspectRatio aspect_ratios[] = +{ + VIDEO_ASPECT_RATIO_INVALID, + VIDEO_ASPECT_RATIO_1_1, + VIDEO_ASPECT_RATIO_12_11, + VIDEO_ASPECT_RATIO_10_11, + VIDEO_ASPECT_RATIO_16_11, + VIDEO_ASPECT_RATIO_40_33, + VIDEO_ASPECT_RATIO_24_11, + VIDEO_ASPECT_RATIO_20_11, + VIDEO_ASPECT_RATIO_32_11, + VIDEO_ASPECT_RATIO_80_33, + VIDEO_ASPECT_RATIO_18_11, + VIDEO_ASPECT_RATIO_15_11, + VIDEO_ASPECT_RATIO_64_33, + VIDEO_ASPECT_RATIO_160_99, + VIDEO_ASPECT_RATIO_4_3, + VIDEO_ASPECT_RATIO_3_2, + VIDEO_ASPECT_RATIO_2_1 +}; + +static const eVideoFormat video_formats[] = +{ + VIDEO_FORMAT_COMPONENT, + VIDEO_FORMAT_PAL, + VIDEO_FORMAT_NTSC, + VIDEO_FORMAT_SECAM, + VIDEO_FORMAT_MAC, + VIDEO_FORMAT_UNKNOWN, + VIDEO_FORMAT_RESERVED +}; + +typedef struct { + int width; + int height; + eVideoAspectRatio aspect_ratio; + eVideoFormat format; +} h264_sps_data_t; + +typedef struct { + double frame_rate; + double bitrate; + eVideoScan scan; +} h264_sei_data_t; + +typedef struct { + const uint8_t *data; + int count; // bits + int index; // bits +} br_state; + +#define BR_INIT(data, bytes) { (data), 8 * (bytes), 0 } +#define BR_EOF(br) ((br)->index >= (br)->count) +#define br_skip_bit(br) br_skip_bits(br,1) +#define br_get_u8(br) br_get_bits(br, 8) +#define br_get_u16(br) ((br_get_bits(br, 8) << 8) | br_get_bits(br, 8)) +#define br_skip_ue_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) +{ + br->data = data; + br->count = 8 * bytes; + br->index = 0; +} + +static inline int br_get_bit(br_state *br) +{ + if (br->index >= br->count) + return 1; // -> no infinite colomb's ... + + int r = (br->data[br->index >> 3] >> (7 - (br->index & 7))) & 1; + br->index++; + return r; +} + +static inline uint32_t br_get_bits(br_state *br, uint32_t n) +{ + uint32_t r = 0; + while (n--) + r = r | (br_get_bit(br) << n); + return r; +} + +static inline void br_skip_bits(br_state *br, int n) +{ + br->index += n; +} + +static inline uint32_t br_get_ue_golomb(br_state *br) +{ + int n = 0; + while (!br_get_bit(br) && (n < 32)) + n++; + return n ? ((1 << n) - 1) + br_get_bits(br, n) : 0; +} + +static inline int32_t br_get_se_golomb(br_state *br) +{ + uint32_t r = br_get_ue_golomb(br) + 1; + return (r & 1) ? -(r >> 1) : (r >> 1); +} + +static inline void br_skip_golomb(br_state *br) +{ + int n = 0; + while (!br_get_bit(br) && (n < 32)) + n++; + br_skip_bits(br, n); +} + +static inline void br_byte_align(br_state *br) +{ + int n = br->index % 8; + if (n > 0) + br_skip_bits(br, 8 - n); +} + +static bool h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps) +{ + br_state br = BR_INIT(buf, len); + int profile_idc, pic_order_cnt_type; + int frame_mbs_only; + int i, j; + + profile_idc = br_get_u8(&br); + + //Dprintf("H.264 SPS: profile_idc %d", profile_idc); + + br_skip_bits(&br, 16); + br_skip_ue_golomb(&br); // seq_parameter_set_id + if (profile_idc >= 100) { + if (br_get_ue_golomb(&br) == 3) // chroma_format_idc + br_skip_bit(&br); // residual_colour_transform_flag + br_skip_ue_golomb(&br); // bit_depth_luma - 8 + br_skip_ue_golomb(&br); // bit_depth_chroma - 8 + br_skip_bit(&br); // transform_bypass + if (br_get_bit(&br)) { // seq_scaling_matrix_present + for (i = 0; i < 8; i++) { + if (br_get_bit(&br)) { // seq_scaling_list_present + int last = 8, next = 8, size = (i < 6) ? 16 : 64; + for (j = 0; j < size; j++) { + if (next) + next = (last + br_get_se_golomb(&br)) & 0xff; + last = next ?: last; + } + } + } + } + } + + br_skip_ue_golomb(&br); // log2_max_frame_num - 4 + pic_order_cnt_type = br_get_ue_golomb(&br); + if (pic_order_cnt_type == 0) + br_skip_ue_golomb(&br); // log2_max_poc_lsb - 4 + else if (pic_order_cnt_type == 1) { + br_skip_bit(&br); // delta_pic_order_always_zero + br_skip_se_golomb(&br); // offset_for_non_ref_pic + br_skip_se_golomb(&br); // offset_for_top_to_bottom_field + j = br_get_ue_golomb(&br); // num_ref_frames_in_pic_order_cnt_cycle + for (i = 0; i < j; i++) + br_skip_se_golomb(&br); // offset_for_ref_frame[i] + } + br_skip_ue_golomb(&br); // ref_frames + br_skip_bit(&br); // gaps_in_frame_num_allowed + sps->width = br_get_ue_golomb(&br) + 1; // mbs + sps->height = br_get_ue_golomb(&br) + 1; // mbs + frame_mbs_only = br_get_bit(&br); + + //Dprintf("H.264 SPS: pic_width: %u mbs", (unsigned int)sps->width); + //Dprintf("H.264 SPS: pic_height: %u mbs", (unsigned int)sps->height); + //Dprintf("H.264 SPS: frame only flag: %d", frame_mbs_only); + + sps->width *= 16; + sps->height *= 16 * (2 - frame_mbs_only); + + if (!frame_mbs_only) { + if (br_get_bit(&br)) { // mb_adaptive_frame_field_flag + //Dprintf("H.264 SPS: MBAFF"); + } + } + + br_skip_bit(&br); // direct_8x8_inference_flag + if (br_get_bit(&br)) { // frame_cropping_flag + uint32_t crop_left = br_get_ue_golomb(&br); + uint32_t crop_right = br_get_ue_golomb(&br); + uint32_t crop_top = br_get_ue_golomb(&br); + uint32_t crop_bottom = br_get_ue_golomb(&br); + //Dprintf("H.264 SPS: cropping %d %d %d %d", crop_left, crop_top, crop_right, crop_bottom); + + sps->width -= 2 * (crop_left + crop_right); + if (frame_mbs_only) + sps->height -= 2 * (crop_top + crop_bottom); + else + sps->height -= 4 * (crop_top + crop_bottom); + } + + // VUI parameters + sps->aspect_ratio = VIDEO_ASPECT_RATIO_INVALID; + sps->format = VIDEO_FORMAT_INVALID; + if (br_get_bit(&br)) { // vui_parameters_present_flag + if (br_get_bit(&br)) { // aspect_ratio_info_present + uint32_t aspect_ratio_idc = br_get_u8(&br); + //Dprintf("H.264 SPS: aspect_ratio_idc %d", aspect_ratio_idc); + if (aspect_ratio_idc == 255) { // extended sar + br_skip_bit(&br); // sar_width + br_skip_bit(&br); // sar_height + sps->aspect_ratio = VIDEO_ASPECT_RATIO_EXTENDED; + //Dprintf("H.264 SPS: -> sar %dx%d", sar_width, sar_height); + } + else if (aspect_ratio_idc < sizeof(aspect_ratios) / sizeof(aspect_ratios[0])) { + sps->aspect_ratio = aspect_ratios[aspect_ratio_idc]; + //Dprintf("H.264 SPS: -> aspect ratio %d", sps->aspect); + } + } + if (br_get_bit(&br)) // overscan_info_present_flag + br_skip_bit(&br); // overscan_approriate_flag + if (br_get_bit(&br)) { // video_signal_type_present_flag + uint32_t video_format = br_get_bits(&br, 3); + if (video_format < sizeof(video_formats) / sizeof(video_formats[0])) { + sps->format = video_formats[video_format]; + //Dprintf("H.264 SPS: -> video format %d", sps->format); + } + } + } + + //Dprintf("H.264 SPS: -> video size %dx%d, aspect %d", sps->width, sps->height, sps->aspect); + + if (BR_EOF(&br)) { + //Dprintf("H.264 SPS: not enough data ?"); + return false; + } + + return true; +} + +#if 0 +static bool h264_parse_sei(const uint8_t *buf, int len, h264_sei_data_t *sei) +{ + br_state br = BR_INIT(buf, len); + + while (!BR_EOF(&br)) { + { // sei_message + 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 + do { + lastByte = br_get_u8(&br); + payloadSize += lastByte; + } while (lastByte != 0xFF); + + { // sei_payload + switch (payloadType) { + //case 1: // pic_timing + // ... + // 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 12: // sub_seq_characteristics + br_skip_ue_golomb(&br); // sub_seq_layer_num + 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; +} +#endif + +static int h264_nal_unescape(uint8_t *dst, const uint8_t *src, int len) +{ + int s = 0, d = 0; + + while (s < len) { + if (!src[s] && !src[s + 1]) { + // hit 00 00 xx + dst[d] = dst[d + 1] = 0; + s += 2; + d += 2; + if (src[s] == 3) { + s++; // 00 00 03 xx --> 00 00 xx + if (s >= len) + return d; + } + } + dst[d++] = src[s++]; + } + + return d; +} + +static int h264_get_picture_type(const uint8_t *buf, int len) +{ + for (int i = 0; i < (len - 5); ++i) { + if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && buf[i + 3] == NAL_AUD) { + uint8_t type = (buf[i + 4] >> 5); + switch (type) { + case 0: case 3: case 5: return I_FRAME; + case 1: case 4: case 6: return P_FRAME; + case 2: case 7: return B_FRAME; + default:; + } + } + } + return NO_PICTURE; +} + +bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info) +{ + // H.264 detection, search for NAL AUD + if (!IS_NAL_AUD(buf)) + return false; + + // If I-frame, search for NAL SPS + if (h264_get_picture_type(buf, len) != I_FRAME) + return false; + + info->codec = VIDEO_CODEC_H264; + + // Scan video packet ... + for (int i = 5; i < len - 4; i++) { + // ... for sequence parameter set + if ((buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SPS) { + uint8_t nal_data[len]; + int nal_len; + //Dprintf("H.264: Found NAL SPS at offset %d/%d", i, len); + if (0 < (nal_len = h264_nal_unescape(nal_data, buf + i + 4, len - i - 4))) { + h264_sps_data_t sps = { 0 }; + if (h264_parse_sps(nal_data, nal_len, &sps)) { + info->format = sps.format; + info->width = sps.width; + info->height = sps.height; + info->aspectRatio = sps.aspect_ratio; + return true; + } + } + } +#if 0 + // ... for supplemental enhancement information + else if ((buf[i] == 0x00) && (buf[i + 1] == 0x00) && (buf[i + 2] == 0x01) && (buf[i + 3] & 0x1f) == NAL_SEI) { + uint8_t nal_data[len]; + int nal_len; + //Dprintf("H.264: Found NAL SEI at offset %d/%d", i, len); + if (0 < (nal_len = h264_nal_unescape(nal_data, buf + i + 4, len - i - 4))) { + h264_sei_data_t sei = { 0 }; + if (h264_parse_sei(nal_data, nal_len, &sei)) { + info->frameRate = sei.frame_rate; + info->bitrate = sei.bitrate; + info->scan = sei.scan; + return true; + } + } + } +#endif + } + + return true; +} diff --git a/femonh264.h b/femonh264.h new file mode 100644 index 0000000..b821d8f --- /dev/null +++ b/femonh264.h @@ -0,0 +1,15 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONH264_H +#define __FEMONH264_H + +#include "femonvideo.h" + +bool getH264VideoInfo(uint8_t *buf, int len, video_info_t *info); + +#endif //__FEMONH264_H diff --git a/femonmpeg.c b/femonmpeg.c new file mode 100644 index 0000000..25b6f53 --- /dev/null +++ b/femonmpeg.c @@ -0,0 +1,184 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "femontools.h" +#include "femonmpeg.h" + +#define IS_MPEG_AUDIO(buf) (((buf)[0] == 0xFF) && ((buf)[1] & 0xF0)) +#define IS_SEQUENCE_HEADER(buf) (((buf)[0] == 0x00) && ((buf)[1] == 0x00) && ((buf)[2] == 0x01) && ((buf)[3] == 0xB3)) + +static unsigned int bitrates[2][3][16] = +{ + { + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III + }, + { + {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1}, // MPEG-1 Layer I + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1}, // MPEG-1 Layer II + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1} // MPEG-1 Layer III + } +}; + +static unsigned int samplerates[2][4] = +{ + {22050, 24000, 16000, -1}, // MPEG-2 + {44100, 48000, 32000, -1} // MPEG-1 +}; + +static eAudioCodec formats[2][4] = +{ + {AUDIO_CODEC_MPEG2_I, AUDIO_CODEC_MPEG2_II, AUDIO_CODEC_MPEG2_III, AUDIO_CODEC_UNKNOWN}, // MPEG-2 + {AUDIO_CODEC_MPEG1_I, AUDIO_CODEC_MPEG1_II, AUDIO_CODEC_MPEG1_III, AUDIO_CODEC_UNKNOWN} // MPEG-1 +}; + +bool getMPEGAudioInfo(uint8_t *buf, int len, audio_info_t *info) +{ + // MPEG audio detection, search for syncword + if ((len < 4) || !IS_MPEG_AUDIO(buf)) + return false; + + int mpegIndex = (buf[1] & 0x08) >> 3; // MPEG-2=0, MPEG-1=1 + int layerIndex = 3 - ((buf[1] & 0x06) >> 1); // I=11, II=10, III=01 + int bitrateIndex = (buf[2] & 0xF0) >> 4; + int frequency = (buf[2] & 0x0C) >> 2; + int channelMode = (buf[3] & 0xC0) >> 6; + + info->codec = formats[mpegIndex][layerIndex]; + + switch (channelMode) { + case 0: + info->channelMode = AUDIO_CHANNEL_MODE_STEREO; + break; + + case 1: + info->channelMode = AUDIO_CHANNEL_MODE_JOINT_STEREO; + break; + + case 2: + info->channelMode = AUDIO_CHANNEL_MODE_DUAL; + break; + + case 3: + info->channelMode = AUDIO_CHANNEL_MODE_SINGLE; + break; + + default: + info->channelMode = AUDIO_CHANNEL_MODE_INVALID; + break; + } + + switch (bitrateIndex) { + case 0: + info->bitrate = AUDIO_BITRATE_FREE; + break; + + case 0xF: + info->bitrate = AUDIO_BITRATE_RESERVED; + break; + + default: + info->bitrate = 1000 * bitrates[mpegIndex][layerIndex][bitrateIndex]; + break; + } + + switch (frequency) { + case 3: + info->samplingFrequency = AUDIO_SAMPLING_FREQUENCY_RESERVED; + break; + + default: + info->samplingFrequency = samplerates[mpegIndex][frequency]; + break; + } + + return true; +} + +bool getMPEGVideoInfo(uint8_t *buf, int len, video_info_t *info) +{ + // MPEG-2 video detection, search for sequence header + if ((len < 7) || !IS_SEQUENCE_HEADER(buf)) + return false; + + // Parse header + uint8_t *data = buf + 4; + info->codec = VIDEO_CODEC_MPEG2; + info->width = ((data[1] & 0xF0) >> 4) | (data[0] << 4); + info->height = ((data[1] & 0x0F) << 8) | (data[2]); + switch ((data[3] & 0xF0) >> 4) { + case 1: + info->aspectRatio = VIDEO_ASPECT_RATIO_1_1; + break; + case 2: + info->aspectRatio = VIDEO_ASPECT_RATIO_4_3; + break; + case 3: + info->aspectRatio = VIDEO_ASPECT_RATIO_16_9; + break; + case 4: + info->aspectRatio = VIDEO_ASPECT_RATIO_2_21_1; + break; + case 5 ... 15: + default: + info->aspectRatio = VIDEO_ASPECT_RATIO_RESERVED; + break; + } + // Video scan should be read from progressive_sequence field in sequence extension + switch (data[3] & 0x0F) { + case 1: + info->frameRate = 24000 / 1001.0; + info->scan = VIDEO_SCAN_PROGRESSIVE; + info->format = VIDEO_FORMAT_UNKNOWN; + break; + case 2: + info->frameRate = 24.0; + info->scan = VIDEO_SCAN_PROGRESSIVE; + info->format = VIDEO_FORMAT_UNKNOWN; + break; + case 3: + info->frameRate = 25.0; + info->scan = VIDEO_SCAN_UNKNOWN; // interlaced or progressive + info->format = VIDEO_FORMAT_PAL; + break; + case 4: + info->frameRate = 30000 / 1001.0; + info->scan = VIDEO_SCAN_UNKNOWN; // interlaced or progressive + info->format = VIDEO_FORMAT_NTSC; + break; + case 5: + info->frameRate = 30.0; + info->scan = VIDEO_SCAN_UNKNOWN; // interlaced or progressive + info->format = VIDEO_FORMAT_NTSC; + break; + case 6: + info->frameRate = 50.0; + info->scan = VIDEO_SCAN_PROGRESSIVE; + info->format = VIDEO_FORMAT_PAL; + break; + case 7: + info->frameRate = 60.0; + info->scan = VIDEO_SCAN_PROGRESSIVE; + info->format = VIDEO_FORMAT_NTSC; + break; + case 8: + info->frameRate = 60000 / 1001.0; + info->scan = VIDEO_SCAN_PROGRESSIVE; + info->format = VIDEO_FORMAT_NTSC; + break; + case 9 ... 15: + default: + info->frameRate = 0; + info->scan = VIDEO_SCAN_UNKNOWN; + info->format = VIDEO_FORMAT_UNKNOWN; + break; + } + info->bitrate = 400.0 * (((data[4] << 10) & 0x0003FC00UL) | ((data[5] << 2) & 0x000003FCUL) | (((data[6] & 0xC0) >> 6) & 0x00000003UL)); + + return true; +} diff --git a/femonmpeg.h b/femonmpeg.h new file mode 100644 index 0000000..fdc9492 --- /dev/null +++ b/femonmpeg.h @@ -0,0 +1,17 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONMPEG_H +#define __FEMONMPEG_H + +#include "femonaudio.h" +#include "femonvideo.h" + +bool getMPEGAudioInfo(uint8_t *buf, int len, audio_info_t *info); +bool getMPEGVideoInfo(uint8_t *buf, int len, video_info_t *info); + +#endif //__FEMONMPEG_H diff --git a/femonosd.c b/femonosd.c index 57a5e58..a9805c3 100644 --- a/femonosd.c +++ b/femonosd.c @@ -3,47 +3,22 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #include #include "femoncfg.h" #include "femonreceiver.h" #include "femontools.h" +#include "femonsymbol.h" #include "femonosd.h" -#include "symbols/device.xpm" -#include "symbols/stereo.xpm" -#include "symbols/monoleft.xpm" -#include "symbols/monoright.xpm" -#include "symbols/zero.xpm" -#include "symbols/one.xpm" -#include "symbols/two.xpm" -#include "symbols/three.xpm" -#include "symbols/four.xpm" -#include "symbols/five.xpm" -#include "symbols/svdrp.xpm" -#include "symbols/ar11.xpm" -#include "symbols/ar169.xpm" -#include "symbols/ar2211.xpm" -#include "symbols/ar43.xpm" -#include "symbols/ntsc.xpm" -#include "symbols/pal.xpm" -#include "symbols/dolbydigital.xpm" -#include "symbols/dolbydigital20.xpm" -#include "symbols/dolbydigital51.xpm" -#include "symbols/lock.xpm" -#include "symbols/signal.xpm" -#include "symbols/carrier.xpm" -#include "symbols/viterbi.xpm" -#include "symbols/sync.xpm" - #define CHANNELINPUT_TIMEOUT 1000 +#define SVDRPPLUGIN "svdrpservice" #define OSDHEIGHT femonConfig.osdheight // in pixels #define OSDWIDTH 600 // in pixels #define OSDROWHEIGHT m_Font->Height() // in pixels -#define OSDINFOHEIGHT (OSDROWHEIGHT * 12) // in pixels (12 rows) +#define OSDINFOHEIGHT (OSDROWHEIGHT * 13) // in pixels (13 rows) #define OSDSTATUSHEIGHT (OSDROWHEIGHT * 6) // in pixels (6 rows) #define OSDSPACING 5 #define OSDCORNERING 10 @@ -56,31 +31,87 @@ #define OSDSTATUSWIN_XSYMBOL(c,w) (c * ((OSDWIDTH - (5 * w)) / 6) + ((c - 1) * w)) #define OSDBARWIDTH(x) (OSDWIDTH * x / 100) -#define SVDRPPLUGIN "svdrpservice" +#define OSDDRAWSTATUSBM(spacing) \ + if (bm) { \ + x -= bm->Width() + spacing; \ + y = (OSDROWHEIGHT - bm->Height()) / 2; \ + if (y < 0) y = 0; \ + m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset + y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); \ + } -cBitmap cFemonOsd::bmDevice(device_xpm); -cBitmap cFemonOsd::bmStereo(stereo_xpm); -cBitmap cFemonOsd::bmMonoLeft(monoleft_xpm); -cBitmap cFemonOsd::bmMonoRight(monoright_xpm); -cBitmap cFemonOsd::bmNumbers[MAX_BMNUMBERS] = { - cBitmap(zero_xpm), cBitmap(one_xpm), cBitmap(two_xpm), - cBitmap(three_xpm), cBitmap(four_xpm), cBitmap(five_xpm) -}; -cBitmap cFemonOsd::bmSVDRP(svdrp_xpm); -cBitmap cFemonOsd::bmAspectRatio_1_1(ar11_xpm); -cBitmap cFemonOsd::bmAspectRatio_16_9(ar169_xpm); -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); -cBitmap cFemonOsd::bmLock(lock_xpm); -cBitmap cFemonOsd::bmSignal(signal_xpm); -cBitmap cFemonOsd::bmCarrier(carrier_xpm); -cBitmap cFemonOsd::bmViterbi(viterbi_xpm); -cBitmap cFemonOsd::bmSync(sync_xpm); +#define OSDDRAWSTATUSFRONTEND(column, bitmap, status) \ + m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(column, x), OSDSTATUSWIN_Y(offset + y), bitmap, (m_FrontendStatus & status) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground) + +#define OSDDRAWSTATUSVALUES(label1, label2, label3, label4, label5, label6, label7) \ + m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), label1, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), label2, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), label3, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), label4, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), label5, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), label6, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), label7, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWSTATUSBAR(value) \ + if (value > 0) { \ + 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); \ + 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); \ + 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); \ + } + +#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->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \ + if (IS_OSDCORNERING) { \ + m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDCORNERING, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -2); \ + m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -1); \ + } + +#define OSDDRAWSTATUSBOTTOMBAR() \ + if (IS_OSDCORNERING) { \ + m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDCORNERING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); \ + m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -4); \ + } + +#define OSDDRAWINFOLEFT(label, value) \ + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWINFORIGHT(label, value) \ + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWINFOACTIVE(label, value) \ + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWINFOINACTIVE(label, value) \ + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); \ + m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), value, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWINFOLINE(label) \ + m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), label, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font) + +#define OSDDRAWINFOTITLEBAR(title) \ + m_Osd->DrawRectangle(0, OSDINFOWIN_Y(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->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), title, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); \ + if (IS_OSDCORNERING) { \ + m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDCORNERING, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -2); \ + m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -1); \ + } + +#define OSDDRAWINFOBOTTOMBAR() \ + if (IS_OSDCORNERING) { \ + m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDCORNERING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); \ + m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); \ + } + +#define OSDCLEARINFO() \ + m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent) cFemonOsd *cFemonOsd::pInstance = NULL; @@ -146,7 +177,6 @@ cFemonOsd::~cFemonOsd(void) void cFemonOsd::DrawStatusWindow(void) { cMutexLock lock(m_Mutex); - unsigned int number = 0; cBitmap *bm = NULL; int snr = m_SNR / 655; int signal = m_Signal / 655; @@ -157,137 +187,91 @@ void cFemonOsd::DrawStatusWindow(void) cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (m_Osd && channel) { - 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->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), *cString::sprintf("%d%s %s", m_Number ? m_Number : channel->Number(), m_Number ? "-" : "", channel->ShortName(true)), femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(0), OSDCORNERING, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -2); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(0), OSDWIDTH, OSDSTATUSWIN_Y(OSDCORNERING), clrTransparent, -1); - } + OSDDRAWSTATUSTITLEBAR(*cString::sprintf("%d%s %s", m_Number ? m_Number : channel->Number(), m_Number ? "-" : "", channel->ShortName(true))); if (m_SvdrpFrontend >= 0) { - x -= bmSVDRP.Width() + OSDSPACING; - y = (OSDROWHEIGHT - bmSVDRP.Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmSVDRP, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + bm = &bmSymbol[SYMBOL_SVDRP]; + OSDDRAWSTATUSBM(OSDSPACING); } - number = cDevice::ActualDevice()->CardIndex(); - if (number < MAX_BMNUMBERS) { - x -= bmNumbers[number].Width() + OSDSPACING; - y = (OSDROWHEIGHT - bmNumbers[number].Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmNumbers[number], femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); - x -= bmDevice.Width(); - y = (OSDROWHEIGHT - bmDevice.Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmDevice, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + switch (cDevice::ActualDevice()->CardIndex()) { + case 1: bm = &bmSymbol[SYMBOL_ONE]; break; + case 2: bm = &bmSymbol[SYMBOL_TWO]; break; + case 3: bm = &bmSymbol[SYMBOL_THREE]; break; + case 4: bm = &bmSymbol[SYMBOL_FOUR]; break; + case 5: bm = &bmSymbol[SYMBOL_FIVE]; break; + case 6: bm = &bmSymbol[SYMBOL_SIX]; break; + case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break; + default: bm = &bmSymbol[SYMBOL_ZERO]; break; } + OSDDRAWSTATUSBM(OSDSPACING); + bm = &bmSymbol[SYMBOL_DEVICE]; + OSDDRAWSTATUSBM(0); if (IS_AUDIO_TRACK(track)) { - number = int(track - ttAudioFirst); - if (number < MAX_BMNUMBERS) { - x -= bmNumbers[number].Width() + OSDSPACING; - y = (OSDROWHEIGHT - bmNumbers[number].Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmNumbers[number], femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + switch (int(track - ttAudioFirst)) { + case 1: bm = &bmSymbol[SYMBOL_ONE]; break; + case 2: bm = &bmSymbol[SYMBOL_TWO]; break; + case 3: bm = &bmSymbol[SYMBOL_THREE]; break; + case 4: bm = &bmSymbol[SYMBOL_FOUR]; break; + case 5: bm = &bmSymbol[SYMBOL_FIVE]; break; + case 6: bm = &bmSymbol[SYMBOL_SIX]; break; + case 7: bm = &bmSymbol[SYMBOL_SEVEN]; break; + default: bm = &bmSymbol[SYMBOL_ZERO]; break; } + OSDDRAWSTATUSBM(OSDSPACING); switch (cDevice::PrimaryDevice()->GetAudioChannel()) { - case 1: bm = &bmMonoLeft; break; - case 2: bm = &bmMonoRight; break; - default: bm = &bmStereo; break; - } - if (bm) { - x -= bm->Width(); - y = (OSDROWHEIGHT - bm->Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + case 1: bm = &bmSymbol[SYMBOL_MONO_LEFT]; break; + case 2: bm = &bmSymbol[SYMBOL_MONO_RIGHT]; break; + default: bm = &bmSymbol[SYMBOL_STEREO]; break; } + OSDDRAWSTATUSBM(0); } else if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { - if (m_Receiver->AC3_5_1()) bm = &bmDD51; - else if (m_Receiver->AC3_2_0()) bm = &bmDD20; - else bm = &bmDD; - if (bm) { - x -= bm->Width() + OSDSPACING; - y = (OSDROWHEIGHT - bm->Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); - } + if (m_Receiver->AC3_5_1()) bm = &bmSymbol[SYMBOL_DD51]; + else if (m_Receiver->AC3_2_0()) bm = &bmSymbol[SYMBOL_DD20]; + else bm = &bmSymbol[SYMBOL_DD]; + OSDDRAWSTATUSBM(OSDSPACING); } if (m_Receiver) { + switch (m_Receiver->VideoCodec()) { + case VIDEO_CODEC_MPEG2: bm = &bmSymbol[SYMBOL_MPEG2]; break; + case VIDEO_CODEC_H264: bm = &bmSymbol[SYMBOL_H264]; break; + default: bm = NULL; break; + } + OSDDRAWSTATUSBM(OSDSPACING); switch (m_Receiver->VideoFormat()) { - case VF_PAL: bm = &bmPAL; break; - case VF_NTSC: bm = &bmNTSC; break; - default: bm = NULL; break; - } - if (bm) { - x -= bm->Width() + OSDSPACING; - y = (OSDROWHEIGHT - bm->Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + case VIDEO_FORMAT_PAL: bm = &bmSymbol[SYMBOL_PAL]; break; + case VIDEO_FORMAT_NTSC: bm = &bmSymbol[SYMBOL_NTSC]; break; + default: bm = NULL; break; } + OSDDRAWSTATUSBM(OSDSPACING); switch (m_Receiver->VideoAspectRatio()) { - case AR_1_1: bm = &bmAspectRatio_1_1; break; - case AR_4_3: bm = &bmAspectRatio_4_3; break; - case AR_16_9: bm = &bmAspectRatio_16_9; break; - case AR_2_21_1: bm = &bmAspectRatio_2_21_1; break; - default: bm = NULL; break; - } - if (bm) { - x -= bm->Width() + OSDSPACING; - y = (OSDROWHEIGHT - bm->Height()) / 2; - if (y < 0) y = 0; - m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), *bm, femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground); + case VIDEO_ASPECT_RATIO_1_1: bm = &bmSymbol[SYMBOL_AR_1_1]; break; + case VIDEO_ASPECT_RATIO_4_3: bm = &bmSymbol[SYMBOL_AR_4_3]; break; + case VIDEO_ASPECT_RATIO_16_9: bm = &bmSymbol[SYMBOL_AR_16_9]; break; + case VIDEO_ASPECT_RATIO_2_21_1: bm = &bmSymbol[SYMBOL_AR_2_21_1]; break; + default: bm = NULL; break; } + OSDDRAWSTATUSBM(OSDSPACING); } offset += OSDROWHEIGHT; - if (signal > 0) { - signal = OSDBARWIDTH(signal); - m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset+3), min(OSDBARWIDTH(femonConfig.redlimit), signal), OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrRed); - if (signal > OSDBARWIDTH(femonConfig.redlimit)) { - m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset+3), min((OSDWIDTH * femonConfig.greenlimit / 100), signal), OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrYellow); - } - if (signal > OSDBARWIDTH(femonConfig.greenlimit)) { - m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset+3), signal, OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrGreen); - } - } + OSDDRAWSTATUSBAR(signal); offset += OSDROWHEIGHT; - if (snr > 0) { - snr = OSDBARWIDTH(snr); - m_Osd->DrawRectangle(0, OSDSTATUSWIN_Y(offset+3), min(OSDBARWIDTH(femonConfig.redlimit), snr), OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrRed); - if (snr > OSDBARWIDTH(femonConfig.redlimit)) { - m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.redlimit), OSDSTATUSWIN_Y(offset+3), min(OSDBARWIDTH(femonConfig.greenlimit), snr), OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrYellow); - } - if (snr > OSDBARWIDTH(femonConfig.greenlimit)) { - m_Osd->DrawRectangle(OSDBARWIDTH(femonConfig.greenlimit), OSDSTATUSWIN_Y(offset+3), snr, OSDSTATUSWIN_Y(offset+OSDROWHEIGHT-3), femonTheme[femonConfig.theme].clrGreen); - } - } + OSDDRAWSTATUSBAR(snr); offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), "STR:", femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), *cString::sprintf("%04x", m_Signal), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), *cString::sprintf("(%2d%%)", m_Signal / 655), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), "BER:", femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), *cString::sprintf("%08x", m_BER), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), *cString::sprintf("%s:", tr("Video")), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), *getBitrateMbits(m_Receiver ? m_Receiver->VideoBitrate() : (m_SvdrpFrontend >= 0 ? m_SvdrpVideoBitrate : -1.0)), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); + 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))); offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDSTATUSWIN_X(1), OSDSTATUSWIN_Y(offset), "SNR:", femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(2), OSDSTATUSWIN_Y(offset), *cString::sprintf("%04x", m_SNR), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(3), OSDSTATUSWIN_Y(offset), *cString::sprintf("(%2d%%)", m_SNR / 655), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(4), OSDSTATUSWIN_Y(offset), "UNC:", femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(5), OSDSTATUSWIN_Y(offset), *cString::sprintf("%08x", m_UNC), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(6), OSDSTATUSWIN_Y(offset), *cString::sprintf("%s:", (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? tr("AC-3") : tr("Audio")), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDSTATUSWIN_X(7), OSDSTATUSWIN_Y(offset), *getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0)), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); + 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")), + *getBitrateKbits(m_Receiver ? ((m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) ? m_Receiver->AC3Bitrate() : m_Receiver->AudioBitrate()) : (m_SvdrpFrontend >= 0 ? m_SvdrpAudioBitrate : -1.0))); offset += OSDROWHEIGHT; - x = bmLock.Width(); - y = (OSDROWHEIGHT - bmLock.Height()) / 2; - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(1, x), OSDSTATUSWIN_Y(offset + y), bmLock, (m_FrontendStatus & FE_HAS_LOCK) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground); - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(2, x), OSDSTATUSWIN_Y(offset + y), bmSignal, (m_FrontendStatus & FE_HAS_SIGNAL) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground); - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(3, x), OSDSTATUSWIN_Y(offset + y), bmCarrier, (m_FrontendStatus & FE_HAS_CARRIER) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground); - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(4, x), OSDSTATUSWIN_Y(offset + y), bmViterbi, (m_FrontendStatus & FE_HAS_VITERBI) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground); - m_Osd->DrawBitmap(OSDSTATUSWIN_XSYMBOL(5, x), OSDSTATUSWIN_Y(offset + y), bmSync, (m_FrontendStatus & FE_HAS_SYNC) ? femonTheme[femonConfig.theme].clrActiveText : femonTheme[femonConfig.theme].clrRed, femonTheme[femonConfig.theme].clrBackground); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDCORNERING, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -3); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-OSDCORNERING), OSDWIDTH, OSDSTATUSWIN_Y(OSDSTATUSHEIGHT), clrTransparent, -4); - } + x = bmSymbol[SYMBOL_LOCK].Width(); + y = (OSDROWHEIGHT - bmSymbol[SYMBOL_LOCK].Height()) / 2; + OSDDRAWSTATUSFRONTEND(1, bmSymbol[SYMBOL_LOCK], FE_HAS_LOCK); + OSDDRAWSTATUSFRONTEND(2, bmSymbol[SYMBOL_SIGNAL], FE_HAS_SIGNAL); + OSDDRAWSTATUSFRONTEND(3, bmSymbol[SYMBOL_CARRIER], FE_HAS_CARRIER); + OSDDRAWSTATUSFRONTEND(4, bmSymbol[SYMBOL_VITERBI], FE_HAS_VITERBI); + OSDDRAWSTATUSFRONTEND(5, bmSymbol[SYMBOL_SYNC], FE_HAS_SYNC); + OSDDRAWSTATUSBOTTOMBAR(); m_Osd->Flush(); } } @@ -300,209 +284,142 @@ void cFemonOsd::DrawInfoWindow(void) eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); if (m_Osd && channel) { - if (m_DisplayMode == eFemonModeTransponder) { - 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->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Transponder Information"), femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDCORNERING, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -2); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -1); - } - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Vpid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Vpid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Ppid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Ppid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Apid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getApids(channel), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Dpid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getDpids(channel), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Spid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getSpids(channel), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Tpid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Tpid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Sid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Sid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Nid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Nid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Tid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Tid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Rid"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Rid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("CA"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getCAids(channel, femonConfig.showcasystem), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - switch (m_FrontendInfo.type) { - case FE_QPSK: - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), *cString::sprintf("%s #%d - %s", tr("Satellite Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getFrequencyMHz(channel->Frequency()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Source"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cSource::ToString(channel->Source()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Srate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Srate()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Polarization"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%c", toupper(channel->Polarization())), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Inversion"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getInversion(channel->Inversion()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("CoderateH"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getCoderate(channel->CoderateH()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - break; + switch (m_DisplayMode) { + case eFemonModeTransponder: + OSDDRAWINFOTITLEBAR(tr("Transponder Information")); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Vpid"), *cString::sprintf("%d", channel->Vpid())); + OSDDRAWINFORIGHT(trVDR("Ppid"), *cString::sprintf("%d", channel->Ppid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Apid"), *getApids(channel)); + OSDDRAWINFORIGHT( tr("Dpid"), *getDpids(channel)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Spid"), *getSpids(channel)); + OSDDRAWINFORIGHT(trVDR("Tpid"), *cString::sprintf("%d", channel->Tpid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Sid"), *cString::sprintf("%d", channel->Sid())); + OSDDRAWINFORIGHT( tr("Nid"), *cString::sprintf("%d", channel->Nid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( tr("Tid"), *cString::sprintf("%d", channel->Tid())); + OSDDRAWINFORIGHT( tr("Rid"), *cString::sprintf("%d", channel->Rid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("CA"), *getCAids(channel, femonConfig.showcasystem)); + offset += OSDROWHEIGHT; + switch (m_FrontendInfo.type) { + case FE_QPSK: + OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", tr("Satellite Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); + OSDDRAWINFORIGHT(trVDR("Polarization"), *cString::sprintf("%c", toupper(channel->Polarization()))); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); + OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(channel->CoderateH())); + //offset += OSDROWHEIGHT; + //OSDDRAWINFOLEFT( trVDR("System"), *getSystem(channel->System())); + //OSDDRAWINFORIGHT(trVDR("RollOff"), *getRollOff(channel->RollOff())); + break; - case FE_QAM: - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), *cString::sprintf("%s #%d - %s", tr("Cable Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getFrequencyMHz(channel->Frequency()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Source"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cSource::ToString(channel->Source()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Srate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *cString::sprintf("%d", channel->Srate()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Modulation"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getModulation(channel->Modulation()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Inversion"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getInversion(channel->Inversion()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("CoderateH"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getCoderate(channel->CoderateH()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - break; + case FE_QAM: + OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", tr("Cable Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Source"), *cSource::ToString(channel->Source())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Srate"), *cString::sprintf("%d", channel->Srate())); + OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(channel->Modulation())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); + OSDDRAWINFORIGHT(trVDR("CoderateH"), *getCoderate(channel->CoderateH())); + break; - case FE_OFDM: - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), *cString::sprintf("%s #%d - %s", tr("Terrestrial Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getFrequencyMHz(channel->Frequency()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Transmission"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getTransmission(channel->Transmission()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Bandwidth"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getBandwidth(channel->Bandwidth()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Modulation"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getModulation(channel->Modulation()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Inversion"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getInversion(channel->Inversion()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Coderate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *cString::sprintf("%s (H) %s (L)", *getCoderate(channel->CoderateH()), *getCoderate(channel->CoderateL())), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), trVDR("Hierarchy"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), *getHierarchy(channel->Hierarchy()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), trVDR("Guard"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), *getGuard(channel->Guard()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - break; + case FE_OFDM: + OSDDRAWINFOLINE(*cString::sprintf("%s #%d - %s", tr("Terrestrial Card"), (m_SvdrpFrontend >= 0) ? m_SvdrpFrontend : cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name)); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Frequency"), *getFrequencyMHz(channel->Frequency())); + OSDDRAWINFORIGHT(trVDR("Transmission"), *getTransmission(channel->Transmission())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Bandwidth"), *getBandwidth(channel->Bandwidth())); + OSDDRAWINFORIGHT(trVDR("Modulation"), *getModulation(channel->Modulation())); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Inversion"), *getInversion(channel->Inversion())); + OSDDRAWINFORIGHT(tr ("Coderate"), *cString::sprintf("%s (H) %s (L)", *getCoderate(channel->CoderateH()), *getCoderate(channel->CoderateL()))); + offset += OSDROWHEIGHT; + OSDDRAWINFOLEFT( trVDR("Hierarchy"), *getHierarchy(channel->Hierarchy())); + OSDDRAWINFORIGHT(trVDR("Guard"), *getGuard(channel->Guard())); + //offset += OSDROWHEIGHT; + //OSDDRAWINFOLEFT( trVDR("Alpha"), *getAlpha(channel->Alpha())); + //OSDDRAWINFORIGHT(trVDR("Priority"), *getPriority(channel->Priority())); + break; - default: - break; - } - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDCORNERING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); - } - } - else if (m_DisplayMode == eFemonModeStream) { - 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->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Stream Information"), femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDCORNERING, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -2); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -1); - } - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Video Stream"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("#%d", channel->Vpid()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), m_Receiver ? *cString::sprintf("%s (%s)", *getBitrateMbits(m_Receiver->VideoStreamBitrate()), *getBitrateMbits(m_Receiver->VideoBitrate())) : *cString::sprintf("---"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Aspect Ratio"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAspectRatio(m_Receiver ? m_Receiver->VideoAspectRatio() : -1), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frame Rate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), m_Receiver ? *cString::sprintf("%.2f %s", m_Receiver->VideoFrameRate(), tr("Hz")) : *cString::sprintf("---"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Video Format"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getVideoFormat(m_Receiver ? m_Receiver->VideoFormat() : -1), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Resolution"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), m_Receiver ? *cString::sprintf("%d x %d", m_Receiver->VideoHorizontalSize(), m_Receiver->VideoVerticalSize()) : *cString::sprintf("---"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Audio Stream"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *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)), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAudioBitrate(m_Receiver ? m_Receiver->AudioBitrate() : (double)FR_NOTVALID, m_Receiver ? m_Receiver->AudioStreamBitrate() : (double)FR_NOTVALID), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("MPEG Layer"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), m_Receiver ? *cString::sprintf("%d", m_Receiver->AudioMPEGLayer()) : *cString::sprintf("---"), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Sampling Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAudioSamplingFreq(m_Receiver ? m_Receiver->AudioSamplingFreq() : FR_NOTVALID), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDCORNERING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); - } - } - else if (m_DisplayMode == eFemonModeAC3) { - 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->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Stream Information"), femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(0), OSDCORNERING, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -2); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDCORNERING), clrTransparent, -1); - } - offset += OSDROWHEIGHT; - if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("AC-3 Stream"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("#%d %s", channel->Dpid(int(track - ttDolbyFirst)), channel->Dlang(int(track - ttDolbyFirst))), femonTheme[femonConfig.theme].clrTitleText, femonTheme[femonConfig.theme].clrTitleBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("%s (%s)", *getBitrateKbits(m_Receiver->AC3StreamBitrate()), *getBitrateKbits(m_Receiver->AC3Bitrate())), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Sampling Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("%.1f %s", m_Receiver->AC3SamplingFreq() / 1000., tr("kHz")), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frame Size"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("%d", m_Receiver->AC3FrameSize()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bit Stream Mode"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3BitStreamMode(m_Receiver->AC3BitStreamMode(), m_Receiver->AC3AudioCodingMode()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Audio Coding Mode"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3AudioCodingMode(m_Receiver->AC3AudioCodingMode(), m_Receiver->AC3BitStreamMode()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Center Mix Level"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3CenterMixLevel(m_Receiver->AC3CenterMixLevel()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Surround Mix Level"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3SurroundMixLevel(m_Receiver->AC3SurroundMixLevel()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Dolby Surround Mode"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3DolbySurroundMode(m_Receiver->AC3DolbySurroundMode()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Low Frequency Effects"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *cString::sprintf("%s", m_Receiver->AC3LfeOn() ? tr("on") : tr("off")), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - offset += OSDROWHEIGHT; - m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Dialogue Normalization"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), *getAC3DialogLevel(m_Receiver->AC3DialogLevel()), femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font); - } - if (IS_OSDCORNERING) { - m_Osd->DrawEllipse(0, OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDCORNERING, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -3); - m_Osd->DrawEllipse((OSDWIDTH-OSDCORNERING), OSDINFOWIN_Y(OSDINFOHEIGHT-OSDCORNERING), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent, -4); - } - } - else /* eFemonModeBasic */ { - m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent); - } + default: + break; + } + OSDDRAWINFOBOTTOMBAR(); + break; + + case eFemonModeStream: + OSDDRAWINFOTITLEBAR(tr("Stream Information")); + offset += OSDROWHEIGHT; + OSDDRAWINFOACTIVE( tr("Video Stream"), *cString::sprintf("#%d", channel->Vpid())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Codec"), *getVideoCodec(m_Receiver ? m_Receiver->VideoCodec() : VIDEO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getVideoBitrate(m_Receiver ? m_Receiver->VideoBitrate() : 0, m_Receiver ? m_Receiver->VideoStreamBitrate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Aspect Ratio"), *getAspectRatio(m_Receiver ? m_Receiver->VideoAspectRatio() : VIDEO_ASPECT_RATIO_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Frame Rate"), *getFrameRate(m_Receiver ? m_Receiver->VideoFrameRate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Video Format"), *getVideoFormat(m_Receiver ? m_Receiver->VideoFormat() : VIDEO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Resolution"), *getResolution(m_Receiver ? m_Receiver->VideoHorizontalSize() : 0, m_Receiver ? m_Receiver->VideoVerticalSize() : 0, m_Receiver ? m_Receiver->VideoScan() : VIDEO_SCAN_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOACTIVE( tr("Audio Stream"), *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))); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Codec"), *getAudioCodec(m_Receiver ? m_Receiver->AudioCodec() : AUDIO_CODEC_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Channel Mode"), *getAudioChannelMode(m_Receiver ? m_Receiver->AudioChannelMode() : AUDIO_CHANNEL_MODE_INVALID)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver ? m_Receiver->AudioBitrate() : 0, m_Receiver ? m_Receiver->AudioStreamBitrate() : 0)); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(m_Receiver ? m_Receiver->AudioSamplingFreq() : AUDIO_SAMPLING_FREQUENCY_INVALID)); + OSDDRAWINFOBOTTOMBAR(); + break; + + case eFemonModeAC3: + OSDDRAWINFOTITLEBAR(tr("Stream Information")); + if (m_Receiver && m_Receiver->AC3Valid() && IS_DOLBY_TRACK(track)) { + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("AC-3 Stream"), *cString::sprintf("#%d %s", channel->Dpid(int(track - ttDolbyFirst)), channel->Dlang(int(track - ttDolbyFirst)))); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bitrate"), *getAudioBitrate(m_Receiver->AC3Bitrate(), m_Receiver->AC3StreamBitrate())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Sampling Frequency"), *getAudioSamplingFreq(m_Receiver->AC3SamplingFreq())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Bit Stream Mode"), *getAC3BitStreamMode(m_Receiver->AC3BitStreamMode(), m_Receiver->AC3AudioCodingMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Audio Coding Mode"), *getAC3AudioCodingMode(m_Receiver->AC3AudioCodingMode(), m_Receiver->AC3BitStreamMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Center Mix Level"), *getAC3CenterMixLevel(m_Receiver->AC3CenterMixLevel())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Surround Mix Level"), *getAC3SurroundMixLevel(m_Receiver->AC3SurroundMixLevel())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Dolby Surround Mode"), *getAC3DolbySurroundMode(m_Receiver->AC3DolbySurroundMode())); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Low Frequency Effects"), *cString::sprintf("%s", m_Receiver->AC3Lfe() ? tr("on") : tr("off"))); + offset += OSDROWHEIGHT; + OSDDRAWINFOINACTIVE(tr("Dialogue Normalization"), *getAC3DialogLevel(m_Receiver->AC3DialogLevel())); + } + OSDDRAWINFOBOTTOMBAR(); + break; + + default: + OSDCLEARINFO(); + break; + } m_Osd->Flush(); } } @@ -595,9 +512,9 @@ void cFemonOsd::Show(void) m_Osd->SetAreas(Areas1, sizeof(Areas1) / sizeof(tArea)); } else { - tArea Areas2[] = { { 0, OSDSTATUSWIN_Y(0), (OSDWIDTH-1), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT-1), femonTheme[femonConfig.theme].bpp }, - { 0, OSDINFOWIN_Y(0), (OSDWIDTH-1), OSDINFOWIN_Y(OSDROWHEIGHT-1), femonTheme[femonConfig.theme].bpp }, - { 0, OSDINFOWIN_Y(OSDROWHEIGHT), (OSDWIDTH-1), OSDINFOWIN_Y(OSDINFOHEIGHT-1), 2 } }; + tArea Areas2[] = { { 0, OSDSTATUSWIN_Y(0), (OSDWIDTH - 1), OSDSTATUSWIN_Y(OSDSTATUSHEIGHT - 1), femonTheme[femonConfig.theme].bpp }, + { 0, OSDINFOWIN_Y(0), (OSDWIDTH - 1), OSDINFOWIN_Y(OSDROWHEIGHT - 1), femonTheme[femonConfig.theme].bpp }, + { 0, OSDINFOWIN_Y(OSDROWHEIGHT), (OSDWIDTH - 1), OSDINFOWIN_Y(OSDINFOHEIGHT - 1), 2 } }; m_Osd->SetAreas(Areas2, sizeof(Areas2) / sizeof(tArea)); } m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrTransparent); diff --git a/femonosd.h b/femonosd.h index 2f6dce0..fdd2b67 100644 --- a/femonosd.h +++ b/femonosd.h @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #ifndef __FEMONOSD_H @@ -21,11 +20,10 @@ #include #include "svdrpservice.h" -#define MAX_BM_NUMBER 5 +#define MAX_BM_NUMBER 8 class cFemonOsd : public cOsdObject, public cThread, public cStatus { private: - enum { MAX_BMNUMBERS = 6 }; static cFemonOsd *pInstance; cOsd *m_Osd; cFemonReceiver *m_Receiver; @@ -48,11 +46,6 @@ private: cTimeMs m_InputTime; cCondWait m_Sleep; cMutex* m_Mutex; - static cBitmap bmStereo, bmMonoLeft, bmMonoRight, bmDD, bmDD20, bmDD51; - static cBitmap bmNumbers[MAX_BMNUMBERS]; - static cBitmap bmDevice, bmPAL, bmNTSC, bmSVDRP; - static cBitmap bmAspectRatio_1_1, bmAspectRatio_16_9, bmAspectRatio_2_21_1, bmAspectRatio_4_3; - static cBitmap bmLock, bmSignal, bmCarrier, bmViterbi, bmSync; void DrawStatusWindow(void); void DrawInfoWindow(void); bool SvdrpConnect(void); diff --git a/femonreceiver.c b/femonreceiver.c index 036250e..65cf421 100644 --- a/femonreceiver.c +++ b/femonreceiver.c @@ -3,12 +3,15 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #include #include "femontools.h" #include "femoncfg.h" +#include "femonmpeg.h" +#include "femonaac.h" +#include "femonac3.h" +#include "femonh264.h" #include "femonreceiver.h" #define TS_SIZE 188 @@ -18,43 +21,57 @@ #define PTS_DTS_FLAGS 0xC0 cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]) -:cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL), cThread("femon receiver") +: cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL), + cThread("femon receiver"), + m_VideoPid(Vpid), + m_VideoPacketCount(0), + m_VideoBitrate(0.0), + m_VideoValid(false), + m_VideoInfoBufferIndex(0), + m_AudioPid(Apid[0]), + m_AudioPacketCount(0), + m_AudioBitrate(0.0), + m_AudioValid(false), + m_AudioInfoBufferIndex(0), + m_AC3Pid(Dpid[0]), + m_AC3PacketCount(0), + m_AC3Bitrate(0), + m_AC3Valid(false), + m_AC3InfoBufferIndex(0) { Dprintf("%s()\n", __PRETTY_FUNCTION__); - m_VideoPid = Vpid; - m_AudioPid = Apid[0]; - m_AC3Pid = Dpid[0]; - m_VideoValid = false; - m_VideoPacketCount = 0; - m_VideoHorizontalSize = 0; - m_VideoVerticalSize = 0; - m_VideoAspectRatio = AR_RESERVED; - m_VideoFormat = VF_UNKNOWN; - 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; + + m_VideoInfo.codec = VIDEO_CODEC_INVALID; + m_VideoInfo.format = VIDEO_FORMAT_INVALID; + m_VideoInfo.scan = VIDEO_SCAN_INVALID; + m_VideoInfo.aspectRatio = VIDEO_ASPECT_RATIO_INVALID; + m_VideoInfo.width = 0; + m_VideoInfo.height = 0; + m_VideoInfo.frameRate = 0; + m_VideoInfo.bitrate = AUDIO_BITRATE_INVALID; + for (unsigned int i = 0; i < ELEMENTS(m_VideoInfoBuffer); ++i) + memcpy(&m_VideoInfoBuffer[i], &m_VideoInfo, sizeof(video_info_t)); + + m_AudioInfo.codec = AUDIO_CODEC_UNKNOWN; + m_AudioInfo.bitrate = AUDIO_BITRATE_INVALID; + m_AudioInfo.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; + m_AudioInfo.channelMode = AUDIO_CHANNEL_MODE_INVALID; + for (unsigned int i = 0; i < ELEMENTS(m_AudioInfoBuffer); ++i) + memcpy(&m_AudioInfoBuffer[i], &m_AudioInfo, sizeof(audio_info_t)); + + m_AC3Info.bitrate = AUDIO_BITRATE_INVALID; + m_AC3Info.samplingFrequency = AUDIO_SAMPLING_FREQUENCY_INVALID; + m_AC3Info.bitstreamMode = AUDIO_BITSTREAM_MODE_INVALID; + m_AC3Info.audioCodingMode = AUDIO_CODING_MODE_INVALID; + m_AC3Info.dolbySurroundMode = AUDIO_DOLBY_SURROUND_MODE_INVALID; + m_AC3Info.centerMixLevel = AUDIO_CENTER_MIX_LEVEL_INVALID; + m_AC3Info.surroundMixLevel = AUDIO_SURROUND_MIX_LEVEL_INVALID; + m_AC3Info.dialogLevel = 0; + m_AC3Info.lfe = false; + for (unsigned int i = 0; i < ELEMENTS(m_AC3InfoBuffer); ++i) + memcpy(&m_AC3InfoBuffer[i], &m_AC3Info, sizeof(ac3_info_t)); } - + cFemonReceiver::~cFemonReceiver(void) { Dprintf("%s()\n", __PRETTY_FUNCTION__); @@ -64,239 +81,82 @@ cFemonReceiver::~cFemonReceiver(void) Detach(); } -/* The following function originates from libdvbmpeg: */ -void cFemonReceiver::GetVideoInfo(uint8_t *mbuf, int count) +void cFemonReceiver::GetVideoInfo(uint8_t *buf, int len) { - uint8_t *headr; - int found = 0; int c = 0; - //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)) - found = 4; - else - c++; + + while (c < len) { + video_info_t tmp; + uint8_t *b = buf + c; + if (getMPEGVideoInfo(b, len - c, &tmp) || getH264VideoInfo(b, len - c, &tmp)) { + bool coherent = true; + memcpy(&m_VideoInfoBuffer[m_VideoInfoBufferIndex], &tmp, sizeof(video_info_t)); + m_VideoInfoBufferIndex = (m_VideoInfoBufferIndex + 1) % ELEMENTS(m_VideoInfoBuffer); + for (unsigned int i = 1; i < ELEMENTS(m_VideoInfoBuffer); ++i) { + if (memcmp(&m_VideoInfoBuffer[0], &m_VideoInfoBuffer[i], sizeof(video_info_t))) + coherent = false; + break; + } + if (!m_VideoValid || coherent) { + m_VideoValid = true; + memcpy(&m_VideoInfo, &m_VideoInfoBuffer[0], sizeof(video_info_t)); + } + return; + } + c++; } - 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 ){ - case 1: - m_VideoAspectRatio = AR_1_1; - break; - case 2: - m_VideoAspectRatio = AR_4_3; - break; - case 3: - m_VideoAspectRatio = AR_16_9; - break; - case 4: - m_VideoAspectRatio = AR_2_21_1; - break; - case 5 ... 15: - default: - m_VideoAspectRatio = AR_RESERVED; - break; - } - sw = (int)(headr[3] & 0x0F); - switch ( sw ) { - case 1: - m_VideoFrameRate = 24000 / 1001.0; - m_VideoFormat = VF_UNKNOWN; - break; - case 2: - m_VideoFrameRate = 24.0; - m_VideoFormat = VF_UNKNOWN; - break; - case 3: - m_VideoFrameRate = 25.0; - m_VideoFormat = VF_PAL; - break; - case 4: - m_VideoFrameRate = 30000 / 1001.0; - m_VideoFormat = VF_NTSC; - break; - case 5: - m_VideoFrameRate = 30.0; - m_VideoFormat = VF_NTSC; - break; - case 6: - m_VideoFrameRate = 50.0; - m_VideoFormat = VF_PAL; - break; - case 7: - 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.0 * (((headr[4] << 10) & 0x0003FC00UL) | ((headr[5] << 2) & 0x000003FCUL) | (((headr[6] & 0xC0) >> 6) & 0x00000003UL)); } -static unsigned int bitrates[3][16] = +void cFemonReceiver::GetAudioInfo(uint8_t *buf, int len) { - {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, - {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}; - -/* The following function originates from libdvbmpeg: */ -void cFemonReceiver::GetAudioInfo(uint8_t *mbuf, int count) -{ - uint8_t *headr; - int found = 0; int c = 0; - int tmp = 0; - //m_AudioValid = false; - while (!found && (c < count)) { - uint8_t *b = mbuf + c; - if ((b[0] == 0xff) && ((b[1] & 0xf8) == 0xf8)) - found = 1; - else - c++; + + while (c < len) { + audio_info_t tmp; + uint8_t *b = buf + c; + if (getAACAudioInfo(b, len - c, &tmp) || getMPEGAudioInfo(b, len - c, &tmp)) { + bool coherent = true; + memcpy(&m_AudioInfoBuffer[m_AudioInfoBufferIndex], &tmp, sizeof(audio_info_t)); + m_AudioInfoBufferIndex = (m_AudioInfoBufferIndex + 1) % ELEMENTS(m_AudioInfoBuffer); + for (unsigned int i = 1; i < ELEMENTS(m_AudioInfoBuffer); ++i) { + if (memcmp(&m_AudioInfoBuffer[0], &m_AudioInfoBuffer[i], sizeof(audio_info_t))) + coherent = false; + break; + } + if (!m_AudioValid || coherent) { + m_AudioValid = true; + memcpy(&m_AudioInfo, &m_AudioInfoBuffer[0], sizeof(audio_info_t)); + } + return; + } + c++; } - 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; - if (tmp == 0) - m_AudioStreamBitrate = (double)FR_FREE; - else if (tmp == 0xf) - m_AudioStreamBitrate = (double)FR_RESERVED; - else - m_AudioStreamBitrate = tmp; - tmp = samplerates[((headr[2] & 0x0c) >> 2)] * 100; - if (tmp == 3) - m_AudioSamplingFreq = FR_RESERVED; - else - 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] = +void cFemonReceiver::GetAC3Info(uint8_t *buf, int len) { - {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++; + + while (c < len) { + ac3_info_t tmp; + uint8_t *b = buf + c; + if (getAC3AudioInfo(b, len - c, &tmp)) { + bool coherent = true; + memcpy(&m_AC3InfoBuffer[m_AC3InfoBufferIndex], &tmp, sizeof(ac3_info_t)); + m_AC3InfoBufferIndex = (m_AC3InfoBufferIndex + 1) % ELEMENTS(m_AC3InfoBuffer); + for (unsigned int i = 1; i < ELEMENTS(m_AC3InfoBuffer); ++i) { + if (memcmp(&m_AC3InfoBuffer[0], &m_AC3InfoBuffer[i], sizeof(ac3_info_t))) + coherent = false; + break; + } + if (!m_AC3Valid || coherent) { + m_AC3Valid = true; + memcpy(&m_AC3Info, &m_AC3InfoBuffer[0], sizeof(ac3_info_t)); + } + return; + } + c++; } - if ((!found) || ((c + 5) >= count)) return; - m_AC3Valid = true; - headr = mbuf + c + 2; - frame = (headr[2] & 0x3f); - m_AC3StreamBitrate = ac3_bitrates[frame >> 1] * 1000; - 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)) { - // 3 front channels - m_AC3CenterMixLevel = (headr[4] & 0x18) >> 3; - if (m_AC3AudioCodingMode & 0x04) { - // a surround channel exists - m_AC3SurroundMixLevel = (headr[4] & 0x06) >> 1; - if (m_AC3AudioCodingMode == 0x02) { - // if in 2/0 mode - m_AC3DolbySurroundMode = ((headr[4] & 0x01) << 1) | ((headr[5] & 0x80) >> 7); - m_AC3LfeOn = (headr[5] & 0x40) >> 6; - m_AC3DialogLevel = (headr[5] & 0x3e) >> 1; - } - else { - m_AC3DolbySurroundMode = FR_NOTVALID; - m_AC3LfeOn = (headr[4] & 0x01); - m_AC3DialogLevel = (headr[5] & 0xF8) >> 3; - } - } - else { - m_AC3SurroundMixLevel = FR_NOTVALID; - if (m_AC3AudioCodingMode == 0x02) { - // if in 2/0 mode - m_AC3DolbySurroundMode = (headr[4] & 0x06) >> 1; - m_AC3LfeOn = (headr[4] & 0x01); - m_AC3DialogLevel = (headr[5] & 0xF8) >> 3; - } - else { - m_AC3DolbySurroundMode = FR_NOTVALID; - m_AC3LfeOn = (headr[4] & 0x04) >> 2; - m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5); - } - } - } - else { - m_AC3CenterMixLevel = FR_NOTVALID; - if (m_AC3AudioCodingMode & 0x04) { - // a surround channel exists - m_AC3SurroundMixLevel = (headr[4] & 0x18) >> 3; - if (m_AC3AudioCodingMode == 0x02) { - // if in 2/0 mode - m_AC3DolbySurroundMode = (headr[4] & 0x06) >> 1; - m_AC3LfeOn = (headr[4] & 0x01); - m_AC3DialogLevel = (headr[5] & 0xF8) >> 3; - } - else { - m_AC3DolbySurroundMode = FR_NOTVALID; - m_AC3LfeOn = (headr[4] & 0x04) >> 2; - m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5); - } - } - else { - m_AC3SurroundMixLevel = FR_NOTVALID; - if (m_AC3AudioCodingMode == 0x02) { - // if in 2/0 mode - m_AC3DolbySurroundMode = (headr[4] & 0x18) >> 3; - m_AC3LfeOn = (headr[4] & 0x04) >> 2; - m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5); - } - else { - m_AC3DolbySurroundMode = FR_NOTVALID; - m_AC3LfeOn = (headr[4] & 0x10) >> 4; - m_AC3DialogLevel = ((headr[4] & 0x0F) << 1) | ((headr[5] & 0x80) >> 7); - } - } - } } void cFemonReceiver::Activate(bool On) diff --git a/femonreceiver.h b/femonreceiver.h index 93b13c6..b6bdcca 100644 --- a/femonreceiver.h +++ b/femonreceiver.h @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #ifndef __FEMONRECEIVER_H @@ -12,84 +11,40 @@ #include #include -enum eVideoFormat { - VF_UNKNOWN = 0, - VF_PAL = 1, - VF_NTSC = 2, - }; - -enum eAspectRatio { - AR_RESERVED = 0, - AR_1_1 = 100, - AR_4_3 = 133, - AR_16_9 = 177, - AR_2_21_1 = 233, - }; - -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, - }; - -enum eReceiverCodes { - FR_RESERVED = -1, - FR_FREE = -2, - FR_NOTVALID = -3 - }; +#include "femonaudio.h" +#include "femonvideo.h" class cFemonReceiver : public cReceiver, public cThread { private: - cCondWait m_Sleep; - 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; - bool m_AudioValid; - int m_AudioPacketCount; - double m_AudioStreamBitrate; - double m_AudioBitrate; - 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); + cCondWait m_Sleep; + + int m_VideoPid; + int m_VideoPacketCount; + double m_VideoBitrate; + bool m_VideoValid; + video_info_t m_VideoInfo; + video_info_t m_VideoInfoBuffer[3]; + unsigned int m_VideoInfoBufferIndex; + + int m_AudioPid; + int m_AudioPacketCount; + double m_AudioBitrate; + bool m_AudioValid; + audio_info_t m_AudioInfo; + audio_info_t m_AudioInfoBuffer[3]; + unsigned int m_AudioInfoBufferIndex; + + int m_AC3Pid; + int m_AC3PacketCount; + double m_AC3Bitrate; + bool m_AC3Valid; + ac3_info_t m_AC3Info; + ac3_info_t m_AC3InfoBuffer[3]; + unsigned int m_AC3InfoBufferIndex; + + void GetVideoInfo(uint8_t *buf, int len); + void GetAudioInfo(uint8_t *buf, int len); + void GetAC3Info(uint8_t *buf, int len); protected: virtual void Activate(bool On); @@ -100,35 +55,37 @@ public: cFemonReceiver(tChannelID ChannelID, 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 - int VideoFormat(void) { return m_VideoFormat; }; // eVideoFormat - double VideoFrameRate(void) { return m_VideoFrameRate; }; // Hz - double VideoStreamBitrate(void) { return m_VideoStreamBitrate; }; // bit/s - double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s + bool VideoValid(void) { return m_VideoValid; }; // boolean + double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s + int VideoCodec(void) { return m_VideoInfo.codec; }; // eVideoCodec + int VideoFormat(void) { return m_VideoInfo.format; }; // eVideoFormat + int VideoScan(void) { return m_VideoInfo.scan; }; // eVideoScan + int VideoAspectRatio(void) { return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio + int VideoHorizontalSize(void) { return m_VideoInfo.width; }; // pixels + int VideoVerticalSize(void) { return m_VideoInfo.height; }; // pixels + double VideoFrameRate(void) { return m_VideoInfo.frameRate; }; // Hz + double VideoStreamBitrate(void) { return m_VideoInfo.bitrate; }; // bit/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; }; // bit/s - double AudioBitrate(void) { return m_AudioBitrate; }; // bit/s + bool AudioValid(void) { return m_AudioValid; }; // boolean + double AudioBitrate(void) { return m_AudioBitrate; }; // bit/s + int AudioCodec(void) { return m_AudioInfo.codec; }; // eAudioCodec + int AudioChannelMode(void) { return m_AudioInfo.channelMode; }; // eAudioChannelMode + double AudioStreamBitrate(void) { return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate + int AudioSamplingFreq(void) { return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency - bool AC3Valid(void) { return m_AC3Valid; }; // boolean - int AC3SamplingFreq(void) { return m_AC3SamplingFreq; }; // Hz - double AC3StreamBitrate(void) { return m_AC3StreamBitrate; }; // bit/s - double AC3Bitrate(void) { return m_AC3Bitrate; }; // bit/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 + bool AC3Valid(void) { return m_AC3Valid; }; // boolean + double AC3Bitrate(void) { return m_AC3Bitrate; }; // bit/s + double AC3StreamBitrate(void) { return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate + int AC3SamplingFreq(void) { return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency + int AC3BitStreamMode(void) { return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode + int AC3AudioCodingMode(void) { return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode + bool AC3_2_0(void) { return m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0; }; // boolean + bool AC3_5_1(void) { return m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2; }; // boolean + int AC3DolbySurroundMode(void) { return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode + int AC3CenterMixLevel(void) { return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel + int AC3SurroundMixLevel(void) { return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel + int AC3DialogLevel(void) { return m_AC3Info.dialogLevel; }; // -dB + bool AC3Lfe(void) { return m_AC3Info.lfe; }; // boolean }; #endif //__FEMONRECEIVER_H diff --git a/femonservice.h b/femonservice.h index d596ca5..a960b0a 100644 --- a/femonservice.h +++ b/femonservice.h @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #ifndef __FEMONSERVICE_H diff --git a/femonsymbol.c b/femonsymbol.c new file mode 100644 index 0000000..bdc7e79 --- /dev/null +++ b/femonsymbol.c @@ -0,0 +1,71 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "femonsymbol.h" + +#include "symbols/stereo.xpm" +#include "symbols/monoleft.xpm" +#include "symbols/monoright.xpm" +#include "symbols/dolbydigital.xpm" +#include "symbols/dolbydigital20.xpm" +#include "symbols/dolbydigital51.xpm" +#include "symbols/mpeg2.xpm" +#include "symbols/h264.xpm" +#include "symbols/ntsc.xpm" +#include "symbols/pal.xpm" +#include "symbols/svdrp.xpm" +#include "symbols/lock.xpm" +#include "symbols/signal.xpm" +#include "symbols/carrier.xpm" +#include "symbols/viterbi.xpm" +#include "symbols/sync.xpm" +#include "symbols/ar11.xpm" +#include "symbols/ar169.xpm" +#include "symbols/ar2211.xpm" +#include "symbols/ar43.xpm" +#include "symbols/device.xpm" +#include "symbols/zero.xpm" +#include "symbols/one.xpm" +#include "symbols/two.xpm" +#include "symbols/three.xpm" +#include "symbols/four.xpm" +#include "symbols/five.xpm" +#include "symbols/six.xpm" +#include "symbols/seven.xpm" + +cBitmap bmSymbol[SYMBOL_MAX_COUNT] = +{ + cBitmap(stereo_xpm), // SYMBOL_STEREO + cBitmap(monoleft_xpm), // SYMBOL_MONO_LEFT + cBitmap(monoright_xpm), // SYMBOL_MONO_RIGHT + cBitmap(dolbydigital_xpm), // SYMBOL_DD + cBitmap(dolbydigital20_xpm), // SYMBOL_DD20 + cBitmap(dolbydigital51_xpm), // SYMBOL_DD51 + cBitmap(mpeg2_xpm), // SYMBOL_MPEG2 + cBitmap(h264_xpm), // SYMBOL_H264 + cBitmap(pal_xpm), // SYMBOL_PAL + cBitmap(ntsc_xpm), // SYMBOL_NTSC + cBitmap(svdrp_xpm), // SYMBOL_SVDRP + cBitmap(lock_xpm), // SYMBOL_LOCK + cBitmap(signal_xpm), // SYMBOL_SIGNAL + cBitmap(carrier_xpm), // SYMBOL_CARRIER + cBitmap(viterbi_xpm), // SYMBOL_VITERBI + cBitmap(sync_xpm), // SYMBOL_SYNC + cBitmap(ar11_xpm), // SYMBOL_AR_1_1 + cBitmap(ar169_xpm), // SYMBOL_AR_16_9 + cBitmap(ar2211_xpm), // SYMBOL_AR_2_21_1 + cBitmap(ar43_xpm), // SYMBOL_AR_4_3 + cBitmap(device_xpm), // SYMBOL_DEVICE + cBitmap(zero_xpm), // SYMBOL_ZERO + cBitmap(one_xpm), // SYMBOL_ONE + cBitmap(two_xpm), // SYMBOL_TWO + cBitmap(three_xpm), // SYMBOL_THREE + cBitmap(four_xpm), // SYMBOL_FOUR + cBitmap(five_xpm), // SYMBOL_FIVE + cBitmap(six_xpm), // SYMBOL_SIX + cBitmap(seven_xpm) // SYMBOL_SEVEN +}; diff --git a/femonsymbol.h b/femonsymbol.h new file mode 100644 index 0000000..68f5475 --- /dev/null +++ b/femonsymbol.h @@ -0,0 +1,48 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONSYMBOL_H +#define __FEMONSYMBOL_H + +#include + +enum eSymbols { + SYMBOL_STEREO, + SYMBOL_MONO_LEFT, + SYMBOL_MONO_RIGHT, + SYMBOL_DD, + SYMBOL_DD20, + SYMBOL_DD51, + SYMBOL_MPEG2, + SYMBOL_H264, + SYMBOL_PAL, + SYMBOL_NTSC, + SYMBOL_SVDRP, + SYMBOL_LOCK, + SYMBOL_SIGNAL, + SYMBOL_CARRIER, + SYMBOL_VITERBI, + SYMBOL_SYNC, + SYMBOL_AR_1_1, + SYMBOL_AR_16_9, + SYMBOL_AR_2_21_1, + SYMBOL_AR_4_3, + SYMBOL_DEVICE, + SYMBOL_ZERO, + SYMBOL_ONE, + SYMBOL_TWO, + SYMBOL_THREE, + SYMBOL_FOUR, + SYMBOL_FIVE, + SYMBOL_SIX, + SYMBOL_SEVEN, + SYMBOL_MAX_COUNT + }; + +extern cBitmap bmSymbol[SYMBOL_MAX_COUNT]; + +#endif // __FEMONSYMBOL_H diff --git a/femontools.c b/femontools.c index 332145b..2a6c1ff 100644 --- a/femontools.c +++ b/femontools.c @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #include @@ -181,25 +180,59 @@ cString getCA(int value) { /* http://www.dvb.org/index.php?id=174 */ switch (value) { - case 0x0000: return cString::sprintf("%s", trVDR("Free To Air")); /* Reserved */ + case 0x0000: return cString::sprintf("%s", trVDR("Free To Air")); // Reserved case 0x0001 ... 0x009F: - case 0x00A2 ... 0x00FF: return cString::sprintf("%s", tr("Fixed")); /* Standardized systems */ - case 0x00A0 ... 0x00A1: return cString::sprintf("%s", tr("Analog")); /* Analog signals */ - case 0x0100 ... 0x01FF: return cString::sprintf("%s", tr("SECA/Mediaguard")); /* Canal Plus */ - case 0x0500 ... 0x05FF: return cString::sprintf("%s", tr("Viaccess")); /* France Telecom */ - case 0x0600 ... 0x06FF: return cString::sprintf("%s", tr("Irdeto")); /* Irdeto */ - case 0x0900 ... 0x09FF: return cString::sprintf("%s", tr("NDS/Videoguard")); /* News Datacom */ - case 0x0B00 ... 0x0BFF: return cString::sprintf("%s", tr("Conax")); /* Norwegian Telekom */ - case 0x0D00 ... 0x0DFF: return cString::sprintf("%s", tr("CryptoWorks")); /* Philips */ - case 0x0E00 ... 0x0EFF: return cString::sprintf("%s", tr("PowerVu")); /* Scientific Atlanta */ - case 0x1200 ... 0x12FF: return cString::sprintf("%s", tr("NagraVision")); /* BellVu Express */ - case 0x1700 ... 0x17FF: return cString::sprintf("%s", tr("BetaCrypt")); /* BetaTechnik */ - case 0x1800 ... 0x18FF: return cString::sprintf("%s", tr("NagraVision")); /* Kudelski SA */ - case 0x4A60 ... 0x4A6F: return cString::sprintf("%s", tr("SkyCrypt")); /* @Sky */ + case 0x00A2 ... 0x00FF: return cString::sprintf("%s", tr("Fixed")); // Standardized systems + case 0x00A0 ... 0x00A1: return cString::sprintf("%s", tr("Analog")); // Analog signals + case 0x0100 ... 0x01FF: return cString::sprintf("%s", tr("SECA/Mediaguard")); // Canal Plus + case 0x0500 ... 0x05FF: return cString::sprintf("%s", tr("Viaccess")); // France Telecom + case 0x0600 ... 0x06FF: return cString::sprintf("%s", tr("Irdeto")); // Irdeto + case 0x0900 ... 0x09FF: return cString::sprintf("%s", tr("NDS/Videoguard")); // News Datacom + case 0x0B00 ... 0x0BFF: return cString::sprintf("%s", tr("Conax")); // Norwegian Telekom + case 0x0D00 ... 0x0DFF: return cString::sprintf("%s", tr("CryptoWorks")); // Philips + case 0x0E00 ... 0x0EFF: return cString::sprintf("%s", tr("PowerVu")); // Scientific Atlanta + case 0x1200 ... 0x12FF: return cString::sprintf("%s", tr("NagraVision")); // BellVu Express + case 0x1700 ... 0x17FF: return cString::sprintf("%s", tr("BetaCrypt")); // BetaTechnik + case 0x1800 ... 0x18FF: return cString::sprintf("%s", tr("NagraVision")); // Kudelski SA + case 0x4A60 ... 0x4A6F: return cString::sprintf("%s", tr("SkyCrypt")); // @Sky } return cString::sprintf("%X", value); } +cString getVideoCodec(int value) +{ + switch (value) { + case VIDEO_CODEC_MPEG2: return cString::sprintf("%s", tr("MPEG-2")); + case VIDEO_CODEC_H264: return cString::sprintf("%s", tr("H.264")); + } + return cString::sprintf("---"); +} + +cString getAudioCodec(int value) +{ + switch (value) { + case AUDIO_CODEC_MPEG1_I: return cString::sprintf("%s", tr("MPEG-1 Layer I")); + case AUDIO_CODEC_MPEG1_II: return cString::sprintf("%s", tr("MPEG-1 Layer II")); + case AUDIO_CODEC_MPEG1_III: return cString::sprintf("%s", tr("MPEG-1 Layer III")); + case AUDIO_CODEC_MPEG2_I: return cString::sprintf("%s", tr("MPEG-2 Layer I")); + case AUDIO_CODEC_MPEG2_II: return cString::sprintf("%s", tr("MPEG-2 Layer II")); + case AUDIO_CODEC_MPEG2_III: return cString::sprintf("%s", tr("MPEG-2 Layer III")); + case AUDIO_CODEC_HEAAC: return cString::sprintf("%s", tr("HE-AAC")); + } + return cString::sprintf("---"); +} + +cString getAudioChannelMode(int value) +{ + switch (value) { + case AUDIO_CHANNEL_MODE_STEREO: return cString::sprintf("%s", tr("stereo")); + case AUDIO_CHANNEL_MODE_JOINT_STEREO: return cString::sprintf("%s", tr("joint Stereo")); + case AUDIO_CHANNEL_MODE_DUAL: return cString::sprintf("%s", tr("dual")); + case AUDIO_CHANNEL_MODE_SINGLE: return cString::sprintf("%s", tr("mono")); + } + return cString::sprintf("---"); +} + cString getCoderate(int value) { switch (value) { @@ -286,14 +319,61 @@ cString getModulation(int value) return cString::sprintf("---"); } +cString getAlpha(int value) +{ + return cString::sprintf("---"); +} + +cString getPriority(int value) +{ + return cString::sprintf("---"); +} + +cString getSystem(int value) +{ + return cString::sprintf("---"); +} + +cString getRollOff(int value) +{ + return cString::sprintf("---"); +} + +cString getResolution(int width, int height, int scan) +{ + if ((width > 0) && (height > 0)) { + switch (scan) { + case VIDEO_SCAN_INTERLACED: return cString::sprintf("%dx%d %s", width, height, tr("interlaced")); + case VIDEO_SCAN_PROGRESSIVE: return cString::sprintf("%dx%d %s", width, height, tr("progressive")); + default: return cString::sprintf("%dx%d", width, height); + } + } + return cString::sprintf("---"); +} + cString getAspectRatio(int value) { switch (value) { - case AR_RESERVED: return cString::sprintf("%s", tr("reserved")); - case AR_1_1: return cString::sprintf("1:1"); - case AR_4_3: return cString::sprintf("4:3"); - case AR_16_9: return cString::sprintf("16:9"); - case AR_2_21_1: return cString::sprintf("2.21:1"); + case VIDEO_ASPECT_RATIO_RESERVED: return cString::sprintf("%s", tr("reserved")); + case VIDEO_ASPECT_RATIO_EXTENDED: return cString::sprintf("%s", tr("extended")); + case VIDEO_ASPECT_RATIO_1_1: return cString::sprintf("1:1"); + case VIDEO_ASPECT_RATIO_4_3: return cString::sprintf("4:3"); + case VIDEO_ASPECT_RATIO_16_9: return cString::sprintf("16:9"); + case VIDEO_ASPECT_RATIO_2_21_1: return cString::sprintf("2.21:1"); + case VIDEO_ASPECT_RATIO_12_11: return cString::sprintf("12:11"); + case VIDEO_ASPECT_RATIO_10_11: return cString::sprintf("10:11"); + case VIDEO_ASPECT_RATIO_16_11: return cString::sprintf("16:11"); + case VIDEO_ASPECT_RATIO_40_33: return cString::sprintf("40:33"); + case VIDEO_ASPECT_RATIO_24_11: return cString::sprintf("24:11"); + case VIDEO_ASPECT_RATIO_20_11: return cString::sprintf("20:11"); + case VIDEO_ASPECT_RATIO_32_11: return cString::sprintf("32:11"); + case VIDEO_ASPECT_RATIO_80_33: return cString::sprintf("80:33"); + case VIDEO_ASPECT_RATIO_18_11: return cString::sprintf("18:11"); + case VIDEO_ASPECT_RATIO_15_11: return cString::sprintf("15:11"); + case VIDEO_ASPECT_RATIO_64_33: return cString::sprintf("64:33"); + case VIDEO_ASPECT_RATIO_160_99: return cString::sprintf("160:99"); + case VIDEO_ASPECT_RATIO_3_2: return cString::sprintf("3:2"); + case VIDEO_ASPECT_RATIO_2_1: return cString::sprintf("2:1"); } return cString::sprintf("---"); } @@ -301,24 +381,35 @@ cString getAspectRatio(int value) cString getVideoFormat(int value) { switch (value) { - case VF_UNKNOWN: return cString::sprintf("%s", tr("unknown")); - case VF_PAL: return cString::sprintf("%s", tr("PAL")); - case VF_NTSC: return cString::sprintf("%s", tr("NTSC")); + case VIDEO_FORMAT_UNKNOWN: return cString::sprintf("%s", tr("unknown")); + case VIDEO_FORMAT_RESERVED: return cString::sprintf("%s", tr("reserved")); + case VIDEO_FORMAT_COMPONENT: return cString::sprintf("%s", tr("component")); + case VIDEO_FORMAT_PAL: return cString::sprintf("%s", tr("PAL")); + case VIDEO_FORMAT_NTSC: return cString::sprintf("%s", tr("NTSC")); + case VIDEO_FORMAT_SECAM: return cString::sprintf("%s", tr("SECAM")); + case VIDEO_FORMAT_MAC: return cString::sprintf("%s", tr("MAC")); } return cString::sprintf("---"); } +cString getFrameRate(double value) +{ + if (value > 0) + return cString::sprintf("%.2f %s", value, tr("Hz")); + return cString::sprintf("---"); +} + cString getAC3BitStreamMode(int value, int coding) { switch (value) { - case 0: return cString::sprintf("%s", tr("Complete Main (CM)")); - case 1: return cString::sprintf("%s", tr("Music and Effects (ME)")); - case 2: return cString::sprintf("%s", tr("Visually Impaired (VI)")); - case 3: return cString::sprintf("%s", tr("Hearing Impaired (HI)")); - case 4: return cString::sprintf("%s", tr("Dialogue (D)")); - case 5: return cString::sprintf("%s", tr("Commentary (C)")); - case 6: return cString::sprintf("%s", tr("Emergency (E)")); - case 7: return cString::sprintf("%s", (coding == 1) ? tr("Voice Over (VO)") : tr("Karaoke")); + case AUDIO_BITSTREAM_MODE_CM: return cString::sprintf("%s", tr("Complete Main (CM)")); + case AUDIO_BITSTREAM_MODE_ME: return cString::sprintf("%s", tr("Music and Effects (ME)")); + case AUDIO_BITSTREAM_MODE_VI: return cString::sprintf("%s", tr("Visually Impaired (VI)")); + case AUDIO_BITSTREAM_MODE_HI: return cString::sprintf("%s", tr("Hearing Impaired (HI)")); + case AUDIO_BITSTREAM_MODE_D: return cString::sprintf("%s", tr("Dialogue (D)")); + case AUDIO_BITSTREAM_MODE_C: return cString::sprintf("%s", tr("Commentary (C)")); + case AUDIO_BITSTREAM_MODE_E: return cString::sprintf("%s", tr("Emergency (E)")); + case AUDIO_BITSTREAM_MODE_VO_KAR: return cString::sprintf("%s", (coding == 1) ? tr("Voice Over (VO)") : tr("Karaoke")); } return cString::sprintf("---"); } @@ -327,14 +418,14 @@ cString getAC3AudioCodingMode(int value, int stream) { if (stream != 7) { switch (value) { - case 0: return cString::sprintf("1+1 - %s, %s", tr("Ch1"), tr("Ch2")); - case 1: return cString::sprintf("1/0 - %s", tr("C")); - case 2: return cString::sprintf("2/0 - %s, %s", tr("L"), tr("R")); - case 3: return cString::sprintf("3/0 - %s, %s, %s", tr("L"), tr("C"), tr("R")); - case 4: return cString::sprintf("2/1 - %s, %s, %s", tr("L"), tr("R"), tr("S")); - case 5: return cString::sprintf("3/1 - %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("S")); - case 6: return cString::sprintf("2/2 - %s, %s, %s, %s", tr("L"), tr("R"), tr("SL"), tr("SR")); - case 7: return cString::sprintf("3/2 - %s, %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("SL"), tr("SR")); + case AUDIO_CODING_MODE_1_1: return cString::sprintf("1+1 - %s, %s", tr("Ch1"), tr("Ch2")); + case AUDIO_CODING_MODE_1_0: return cString::sprintf("1/0 - %s", tr("C")); + case AUDIO_CODING_MODE_2_0: return cString::sprintf("2/0 - %s, %s", tr("L"), tr("R")); + case AUDIO_CODING_MODE_3_0: return cString::sprintf("3/0 - %s, %s, %s", tr("L"), tr("C"), tr("R")); + case AUDIO_CODING_MODE_2_1: return cString::sprintf("2/1 - %s, %s, %s", tr("L"), tr("R"), tr("S")); + case AUDIO_CODING_MODE_3_1: return cString::sprintf("3/1 - %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("S")); + case AUDIO_CODING_MODE_2_2: return cString::sprintf("2/2 - %s, %s, %s, %s", tr("L"), tr("R"), tr("SL"), tr("SR")); + case AUDIO_CODING_MODE_3_2: return cString::sprintf("3/2 - %s, %s, %s, %s, %s", tr("L"), tr("C"), tr("R"), tr("SL"), tr("SR")); } } return cString::sprintf("---"); @@ -343,10 +434,10 @@ cString getAC3AudioCodingMode(int value, int stream) cString getAC3CenterMixLevel(int value) { switch (value) { - case CML_MINUS_3dB: return cString::sprintf("-3.0 %s", tr("dB")); - case CML_MINUS_4_5dB: return cString::sprintf("-4.5 %s", tr("dB")); - case CML_MINUS_6dB: return cString::sprintf("-6.0 %s", tr("dB")); - case CML_RESERVED: return cString::sprintf("%s", tr("reserved")); + case AUDIO_CENTER_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3.0 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_MINUS_4_5dB: return cString::sprintf("-4.5 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6.0 %s", tr("dB")); + case AUDIO_CENTER_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); } return cString::sprintf("---"); } @@ -354,10 +445,10 @@ cString getAC3CenterMixLevel(int value) cString getAC3SurroundMixLevel(int value) { switch (value) { - case SML_MINUS_3dB: return cString::sprintf("-3 %s", tr("dB")); - case SML_MINUS_6dB: return cString::sprintf("-6 %s", tr("dB")); - case SML_0_dB: return cString::sprintf("0 %s", tr("dB")); - case SML_RESERVED: return cString::sprintf("%s", tr("reserved")); + case AUDIO_SURROUND_MIX_LEVEL_MINUS_3dB: return cString::sprintf("-3 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_MINUS_6dB: return cString::sprintf("-6 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_0_dB: return cString::sprintf("0 %s", tr("dB")); + case AUDIO_SURROUND_MIX_LEVEL_RESERVED: return cString::sprintf("%s", tr("reserved")); } return cString::sprintf("---"); } @@ -365,10 +456,10 @@ cString getAC3SurroundMixLevel(int value) cString getAC3DolbySurroundMode(int value) { switch (value) { - case DSM_NOT_INDICATED: return cString::sprintf("%s", tr("not indicated")); - case DSM_NOT_DOLBYSURROUND: return cString::sprintf("%s", trVDR("no")); - case DSM_DOLBYSURROUND: return cString::sprintf("%s", trVDR("yes")); - case DSM_RESERVED: return cString::sprintf("%s", tr("reserved")); + case AUDIO_DOLBY_SURROUND_MODE_NOT_INDICATED: return cString::sprintf("%s", tr("not indicated")); + case AUDIO_DOLBY_SURROUND_MODE_NOT_DOLBYSURROUND: return cString::sprintf("%s", trVDR("no")); + case AUDIO_DOLBY_SURROUND_MODE_DOLBYSURROUND: return cString::sprintf("%s", trVDR("yes")); + case AUDIO_DOLBY_SURROUND_MODE_RESERVED: return cString::sprintf("%s", tr("reserved")); } return cString::sprintf("---"); } @@ -389,32 +480,37 @@ cString getFrequencyMHz(int value) cString getAudioSamplingFreq(int value) { switch (value) { - case FR_NOTVALID: return cString::sprintf("---"); - case FR_RESERVED: return cString::sprintf("%s", tr("reserved")); + case AUDIO_SAMPLING_FREQUENCY_INVALID: return cString::sprintf("---"); + case AUDIO_SAMPLING_FREQUENCY_RESERVED: return cString::sprintf("%s", tr("reserved")); } - return cString::sprintf("%.1f %s", ((double)value / 1000.0), tr("kHz")); + return cString::sprintf("%d %s", value, tr("Hz")); } cString getAudioBitrate(double value, double stream) { switch ((int)stream) { - case FR_NOTVALID: return cString::sprintf("---"); - case FR_RESERVED: return cString::sprintf("%s (%s)", tr("reserved"), *getBitrateKbits(value)); - case FR_FREE: return cString::sprintf("%s (%s)", tr("free"), *getBitrateKbits(value)); + case AUDIO_BITRATE_INVALID: return cString::sprintf("---"); + case AUDIO_BITRATE_RESERVED: return cString::sprintf("%s (%s)", tr("reserved"), *getBitrateKbits(value)); + case AUDIO_BITRATE_FREE: return cString::sprintf("%s (%s)", tr("free"), *getBitrateKbits(value)); } return cString::sprintf("%s (%s)", *getBitrateKbits(stream), *getBitrateKbits(value)); } +cString getVideoBitrate(double value, double stream) +{ + return cString::sprintf("%s (%s)", *getBitrateMbits(stream), *getBitrateMbits(value)); +} + cString getBitrateMbits(double value) { - if (value >= 0) + if (value > 0) return cString::sprintf("%.2f %s", value / 1000000.0, tr("Mbit/s")); - return cString::sprintf("--- %s", tr("Mbit/s")); + return cString::sprintf("---"); } cString getBitrateKbits(double value) { - if (value >= 0) + if (value > 0) return cString::sprintf("%.0f %s", value / 1000.0, tr("kbit/s")); - return cString::sprintf("--- %s", tr("kbit/s")); + return cString::sprintf("---"); } diff --git a/femontools.h b/femontools.h index 0ad54cd..164f482 100644 --- a/femontools.h +++ b/femontools.h @@ -3,7 +3,6 @@ * * See the README file for copyright information and how to reach the author. * - * $Id$ */ #ifndef __FEMONTOOLS_H @@ -19,6 +18,8 @@ #define Dprintf(x...) ; #endif +#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) + #define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" cString getFrontendInfo(int cardIndex = 0); @@ -36,6 +37,9 @@ cString getDpids(const cChannel *channel); cString getSpids(const cChannel *channel); cString getCAids(const cChannel *channel, bool identify = false); cString getCA(int value); +cString getVideoCodec(int value); +cString getAudioCodec(int value); +cString getAudioChannelMode(int value); cString getCoderate(int value); cString getTransmission(int value); cString getBandwidth(int value); @@ -43,8 +47,14 @@ cString getInversion(int value); cString getHierarchy(int value); cString getGuard(int value); cString getModulation(int value); +cString getAlpha(int value); +cString getPriority(int value); +cString getSystem(int value); +cString getRollOff(int value); +cString getResolution(int width, int height, int scan); cString getAspectRatio(int value); cString getVideoFormat(int value); +cString getFrameRate(double value); cString getAC3BitStreamMode(int value, int coding); cString getAC3AudioCodingMode(int value, int stream); cString getAC3CenterMixLevel(int value); @@ -54,6 +64,7 @@ cString getAC3DialogLevel(int value); cString getFrequencyMHz(int value); cString getAudioSamplingFreq(int value); cString getAudioBitrate(double value, double stream); +cString getVideoBitrate(double value, double stream); cString getBitrateMbits(double value); cString getBitrateKbits(double value); diff --git a/femonvideo.h b/femonvideo.h new file mode 100644 index 0000000..38f6793 --- /dev/null +++ b/femonvideo.h @@ -0,0 +1,72 @@ +/* + * Frontend Status Monitor plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __FEMONVIDEO_H +#define __FEMONVIDEO_H + +enum eVideoCodec { + VIDEO_CODEC_INVALID = -1, + VIDEO_CODEC_UNKNOWN, + VIDEO_CODEC_MPEG2, + VIDEO_CODEC_H264 + }; + +enum eVideoFormat { + VIDEO_FORMAT_INVALID = -1, + VIDEO_FORMAT_UNKNOWN, + VIDEO_FORMAT_RESERVED, + VIDEO_FORMAT_COMPONENT, + VIDEO_FORMAT_PAL, + VIDEO_FORMAT_NTSC, + VIDEO_FORMAT_SECAM, + VIDEO_FORMAT_MAC + }; + +enum eVideoScan { + VIDEO_SCAN_INVALID = -1, + VIDEO_SCAN_UNKNOWN, + VIDEO_SCAN_RESERVED, + VIDEO_SCAN_INTERLACED, + VIDEO_SCAN_PROGRESSIVE + }; + +enum eVideoAspectRatio { + VIDEO_ASPECT_RATIO_INVALID = -1, + VIDEO_ASPECT_RATIO_RESERVED, + VIDEO_ASPECT_RATIO_EXTENDED, + VIDEO_ASPECT_RATIO_1_1, + VIDEO_ASPECT_RATIO_4_3, + VIDEO_ASPECT_RATIO_16_9, + VIDEO_ASPECT_RATIO_2_21_1, + VIDEO_ASPECT_RATIO_12_11, + VIDEO_ASPECT_RATIO_10_11, + VIDEO_ASPECT_RATIO_16_11, + VIDEO_ASPECT_RATIO_40_33, + VIDEO_ASPECT_RATIO_24_11, + VIDEO_ASPECT_RATIO_20_11, + VIDEO_ASPECT_RATIO_32_11, + VIDEO_ASPECT_RATIO_80_33, + VIDEO_ASPECT_RATIO_18_11, + VIDEO_ASPECT_RATIO_15_11, + VIDEO_ASPECT_RATIO_64_33, + VIDEO_ASPECT_RATIO_160_99, + VIDEO_ASPECT_RATIO_3_2, + VIDEO_ASPECT_RATIO_2_1 + }; + +typedef struct video_info { + eVideoCodec codec; // enum + eVideoFormat format; // enum + eVideoScan scan; // enum + eVideoAspectRatio aspectRatio; // enum + int width; // pixels + int height; // pixels + double frameRate; // Hz + double bitrate; // Mbit/s +} video_info_t; + +#endif //__FEMONVIDEO_H diff --git a/po/de_DE.po b/po/de_DE.po index 8d16ec7..2760979 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,9 +7,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:53+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Christian Wieninger\n" "Language-Team: \n" @@ -209,6 +209,9 @@ msgstr "Streaminformation" msgid "Video Stream" msgstr "Video Stream" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "Bitrate" @@ -218,9 +221,6 @@ msgstr "Seitenverh msgid "Frame Rate" msgstr "Bildrate" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Bildformat" @@ -230,8 +230,8 @@ msgstr "Aufl msgid "Audio Stream" msgstr "Audio Stream" -msgid "MPEG Layer" -msgstr "MPEG Layer" +msgid "Channel Mode" +msgstr "" msgid "Sampling Frequency" msgstr "Abtastrate" @@ -239,12 +239,6 @@ msgstr "Abtastrate" msgid "AC-3 Stream" msgstr "AC-3 Stream" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Frame Größe" - msgid "Bit Stream Mode" msgstr "Bitstream Modus" @@ -308,6 +302,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "" + msgid "none" msgstr "Nichts" @@ -317,18 +350,39 @@ msgstr "Auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "belegt" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "unbekannt" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Complete Main (CM)" diff --git a/po/es_ES.po b/po/es_ES.po index 95b6206..8bb406e 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:42+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Luis Palacios\n" "Language-Team: \n" @@ -207,6 +207,9 @@ msgstr "Informaci msgid "Video Stream" msgstr "Flujo de video" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "Tasa de bits" @@ -216,9 +219,6 @@ msgstr "Proporciones de la imagen" msgid "Frame Rate" msgstr "Tasa de frames" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Formato de video" @@ -228,8 +228,8 @@ msgstr "Resoluci msgid "Audio Stream" msgstr "Flujo de audio" -msgid "MPEG Layer" -msgstr "Nivel MPEG" +msgid "Channel Mode" +msgstr "" msgid "Sampling Frequency" msgstr "Frecuencia de muestreo" @@ -237,12 +237,6 @@ msgstr "Frecuencia de muestreo" msgid "AC-3 Stream" msgstr "Flujo AC-3" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Tamaño de frame" - msgid "Bit Stream Mode" msgstr "Modo bitstream" @@ -306,6 +300,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "o" + msgid "none" msgstr "ninguno" @@ -315,18 +348,39 @@ msgstr "auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "reservado" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "desconocido" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Principal (CM)" diff --git a/po/et_EE.po b/po/et_EE.po index 51635a0..f5ab4dd 100644 --- a/po/et_EE.po +++ b/po/et_EE.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:42+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Arthur Konovalov\n" "Language-Team: \n" @@ -207,6 +207,9 @@ msgstr "Voo info" msgid "Video Stream" msgstr "Videovoog" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "Bitikiirus" @@ -216,9 +219,6 @@ msgstr "K msgid "Frame Rate" msgstr "Kaadrisagedus" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Videoformaat" @@ -228,8 +228,8 @@ msgstr "Resolutsioon" msgid "Audio Stream" msgstr "Audiovoog" -msgid "MPEG Layer" -msgstr "MPEG tase" +msgid "Channel Mode" +msgstr "" msgid "Sampling Frequency" msgstr "Sämplimissagedus" @@ -237,12 +237,6 @@ msgstr "S msgid "AC-3 Stream" msgstr "AC-3 voog" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Kaadri suurus" - msgid "Bit Stream Mode" msgstr "Bitivoo tüüp" @@ -306,6 +300,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "" + msgid "none" msgstr "ei" @@ -315,18 +348,39 @@ msgstr "auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "reserveeritud" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "tundmatu" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Täiskomplekt (CM)" diff --git a/po/fi_FI.po b/po/fi_FI.po index 8862bf1..02a328d 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:42+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Rolf Ahrenberg\n" "Language-Team: \n" @@ -210,6 +210,9 @@ msgstr "Lähetteen tiedot" msgid "Video Stream" msgstr "Kuvaraita" +msgid "Codec" +msgstr "Koodekki" + msgid "Bitrate" msgstr "Bittinopeus" @@ -219,9 +222,6 @@ msgstr "Kuvasuhde" msgid "Frame Rate" msgstr "Ruudunpäivitystaajuus" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Kuvaformaatti" @@ -231,8 +231,8 @@ msgstr "Resoluutio" msgid "Audio Stream" msgstr "Ääniraita" -msgid "MPEG Layer" -msgstr "MPEG-taso" +msgid "Channel Mode" +msgstr "Kanavatila" msgid "Sampling Frequency" msgstr "Näytteenottotaajuus" @@ -240,12 +240,6 @@ msgstr "Näytteenottotaajuus" msgid "AC-3 Stream" msgstr "AC-3-ääniraita" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Kehyksen koko" - msgid "Bit Stream Mode" msgstr "Lähetteen tyyppi" @@ -309,6 +303,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "MPEG-2" + +msgid "H.264" +msgstr "H.264" + +msgid "MPEG-1 Layer I" +msgstr "MPEG-1 kerros I" + +msgid "MPEG-1 Layer II" +msgstr "MPEG-1 kerros II" + +msgid "MPEG-1 Layer III" +msgstr "MPEG-1 kerros III" + +msgid "MPEG-2 Layer I" +msgstr "MPEG-2 kerros I" + +msgid "MPEG-2 Layer II" +msgstr "MPEG-2 kerros II" + +msgid "MPEG-2 Layer III" +msgstr "MPEG-2 kerros III" + +msgid "HE-AAC" +msgstr "HE-AAC" + +msgid "stereo" +msgstr "stereo" + +msgid "joint Stereo" +msgstr "joint-stereo" + +msgid "dual" +msgstr "kaksikanavainen" + +msgid "mono" +msgstr "mono" + msgid "none" msgstr "ei" @@ -318,18 +351,39 @@ msgstr "auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "lomiteltu" + +msgid "progressive" +msgstr "lomittelematon" + msgid "reserved" msgstr "varattu" +msgid "extended" +msgstr "laajennettu" + msgid "unknown" msgstr "tuntematon" +msgid "component" +msgstr "komponentti" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "SECAM" + +msgid "MAC" +msgstr "MAC" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Pääasiallinen (CM)" diff --git a/po/fr_FR.po b/po/fr_FR.po index dad643c..c30c6e5 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:42+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2008-01-26 09:59+0100\n" "Last-Translator: NIVAL Michaël \n" "Language-Team: \n" @@ -210,6 +210,9 @@ msgstr "Information flux" msgid "Video Stream" msgstr "Flux vidéo" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "Bitrate" @@ -219,9 +222,6 @@ msgstr "Proportions d'image" msgid "Frame Rate" msgstr "Rafraîchissement" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Standard vidéo" @@ -231,8 +231,8 @@ msgstr "R msgid "Audio Stream" msgstr "Flux audio" -msgid "MPEG Layer" -msgstr "MPEG Layer" +msgid "Channel Mode" +msgstr "" msgid "Sampling Frequency" msgstr "Fréquence d'échantillonage" @@ -240,12 +240,6 @@ msgstr "Fr msgid "AC-3 Stream" msgstr "Flux AC-3" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Taille de paquet" - msgid "Bit Stream Mode" msgstr "Mode bitstream" @@ -309,6 +303,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "" + msgid "none" msgstr "Aucun" @@ -318,18 +351,39 @@ msgstr "Auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "réservé" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "inconnu" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Principal (CM)" diff --git a/po/it_IT.po b/po/it_IT.po index 3d9866a..7733351 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -1,14 +1,14 @@ # VDR plugin language source file. # Copyright (C) 2007 Rolf Ahrenberg -# This file is distributed under the same license as the VDR package. +# This file is distributed under the same license as the femon package. # Sean Carlos # Diego Pierotto # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-02-16 01:01+0200\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2008-04-17 00:18+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: \n" @@ -211,6 +211,9 @@ msgstr "Informazioni flusso" msgid "Video Stream" msgstr "Flusso video" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "Bitrate" @@ -220,9 +223,6 @@ msgstr "Formato immagine" msgid "Frame Rate" msgstr "Frame rate" -msgid "Hz" -msgstr "Hz" - msgid "Video Format" msgstr "Formato video" @@ -232,8 +232,8 @@ msgstr "Risoluzione" msgid "Audio Stream" msgstr "Flusso audio" -msgid "MPEG Layer" -msgstr "Formato MPEG" +msgid "Channel Mode" +msgstr "" msgid "Sampling Frequency" msgstr "Frequenza campionamento" @@ -241,12 +241,6 @@ msgstr "Frequenza campionamento" msgid "AC-3 Stream" msgstr "Flusso AC-3" -msgid "kHz" -msgstr "kHz" - -msgid "Frame Size" -msgstr "Dimensione frame" - msgid "Bit Stream Mode" msgstr "Modalità bitstream" @@ -310,6 +304,45 @@ msgstr "BetaCrypt" msgid "SkyCrypt" msgstr "SkyCrypt" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "" + msgid "none" msgstr "nessuna" @@ -319,18 +352,39 @@ msgstr "auto" msgid "MHz" msgstr "MHz" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "riservato" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "sconosciuto" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "Hz" + msgid "Complete Main (CM)" msgstr "Principale (P)" @@ -396,4 +450,3 @@ msgstr "Mbit/s" msgid "kbit/s" msgstr "kbit/s" - diff --git a/po/ru_RU.po b/po/ru_RU.po index 598b021..f7ac2bc 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: femon 1.6.0\n" +"Project-Id-Version: femon 1.6.3\n" "Report-Msgid-Bugs-To: Rolf Ahrenberg\n" -"POT-Creation-Date: 2008-03-23 14:42+0100\n" +"POT-Creation-Date: 2008-11-09 13:31+0200\n" "PO-Revision-Date: 2007-08-12 23:22+0300\n" "Last-Translator: Vyacheslav Dikonov\n" "Language-Team: \n" @@ -207,6 +207,9 @@ msgstr "" msgid "Video Stream" msgstr "" +msgid "Codec" +msgstr "" + msgid "Bitrate" msgstr "" @@ -216,9 +219,6 @@ msgstr "" msgid "Frame Rate" msgstr "" -msgid "Hz" -msgstr "³æ" - msgid "Video Format" msgstr "" @@ -228,7 +228,7 @@ msgstr "" msgid "Audio Stream" msgstr "" -msgid "MPEG Layer" +msgid "Channel Mode" msgstr "" msgid "Sampling Frequency" @@ -237,12 +237,6 @@ msgstr "" msgid "AC-3 Stream" msgstr "" -msgid "kHz" -msgstr "Ú³æ" - -msgid "Frame Size" -msgstr "" - msgid "Bit Stream Mode" msgstr "" @@ -306,6 +300,45 @@ msgstr "" msgid "SkyCrypt" msgstr "" +msgid "MPEG-2" +msgstr "" + +msgid "H.264" +msgstr "" + +msgid "MPEG-1 Layer I" +msgstr "" + +msgid "MPEG-1 Layer II" +msgstr "" + +msgid "MPEG-1 Layer III" +msgstr "" + +msgid "MPEG-2 Layer I" +msgstr "" + +msgid "MPEG-2 Layer II" +msgstr "" + +msgid "MPEG-2 Layer III" +msgstr "" + +msgid "HE-AAC" +msgstr "" + +msgid "stereo" +msgstr "" + +msgid "joint Stereo" +msgstr "" + +msgid "dual" +msgstr "" + +msgid "mono" +msgstr "" + msgid "none" msgstr "ÝÕâ" @@ -315,18 +348,39 @@ msgstr " msgid "MHz" msgstr "¼³æ" +msgid "interlaced" +msgstr "" + +msgid "progressive" +msgstr "" + msgid "reserved" msgstr "" +msgid "extended" +msgstr "" + msgid "unknown" msgstr "" +msgid "component" +msgstr "" + msgid "PAL" msgstr "PAL" msgid "NTSC" msgstr "NTSC" +msgid "SECAM" +msgstr "" + +msgid "MAC" +msgstr "" + +msgid "Hz" +msgstr "³æ" + msgid "Complete Main (CM)" msgstr "" diff --git a/symbols/h264.xpm b/symbols/h264.xpm new file mode 100644 index 0000000..b03ed4e --- /dev/null +++ b/symbols/h264.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *const h264_xpm[] = { +"40 18 2 1", +". c #FFFFFF", +"+ c #000000", +"++++++++++++++++++++++++++++++++++++++++", +"+......................................+", +"+..++...++.....+++++...+++++.......++..+", +"+..++...++....+++++++.+++++++.....+++..+", +"+..++...++....++...++.++...++....++++..+", +"+..++...++.........++.++........+++....+", +"+..++...++.........++.++.......+++.....+", +"+..++...++........+++.++......+++......+", +"+..+++++++.......+++..++++++..++...++..+", +"+..+++++++......+++...+++++++.+++++++..+", +"+..++...++.....+++....++...++.+++++++..+", +"+..++...++....+++.....++...++......++..+", +"+..++...++....++......++...++......++..+", +"+..++...++....++...++.++...++......++..+", +"+..++...++.++.+++++++.+++++++......++..+", +"+..++...++.++.+++++++..+++++.......++..+", +"+......................................+", +"++++++++++++++++++++++++++++++++++++++++"}; diff --git a/symbols/mpeg2.xpm b/symbols/mpeg2.xpm new file mode 100644 index 0000000..3a24cbe --- /dev/null +++ b/symbols/mpeg2.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *const mpeg2_xpm[] = { +"44 18 2 1", +". c #FFFFFF", +"+ c #000000", +"++++++++++++++++++++++++++++++++++++++++++++", +"+..........................................+", +"+..++....++.+++++...+++++..+++++...+++++...+", +"+..++....++.++++++..+++++.+++++++.+++++++..+", +"+..+++..+++.++..+++.++....+++..++.++...++..+", +"+..+++..+++.++...++.++....++...........++..+", +"+..++++++++.++...++.++....++...........++..+", +"+..++++++++.++..+++.++....++..........+++..+", +"+..++.++.++.++++++..++++..++.++++....+++...+", +"+..++.++.++.+++++...++++..++.++++...+++....+", +"+..++....++.++......++....++...++..+++.....+", +"+..++....++.++......++....++...++.+++......+", +"+..++....++.++......++....++...++.++.......+", +"+..++....++.++......++....+++..++.++...++..+", +"+..++....++.++......+++++.+++++++.+++++++..+", +"+..++....++.++......+++++..+++++..+++++++..+", +"+..........................................+", +"++++++++++++++++++++++++++++++++++++++++++++"}; diff --git a/symbols/seven.xpm b/symbols/seven.xpm new file mode 100644 index 0000000..66a4b11 --- /dev/null +++ b/symbols/seven.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *const seven_xpm[] = { +"15 18 2 1", +". c #FFFFFF", +"+ c #000000", +"+++++++++++++++", +"..............+", +"...++++++++...+", +"...++++++++...+", +"...++....++...+", +".........++...+", +"........+++...+", +"........++....+", +"........++....+", +".......+++....+", +".......++.....+", +".......++.....+", +"......+++.....+", +"......++......+", +"......++......+", +"......++......+", +"..............+", +"+++++++++++++++"}; diff --git a/symbols/six.xpm b/symbols/six.xpm new file mode 100644 index 0000000..72b3209 --- /dev/null +++ b/symbols/six.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *const six_xpm[] = { +"15 18 2 1", +". c #FFFFFF", +"+ c #000000", +"+++++++++++++++", +"..............+", +"....++++++....+", +"...++++++++...+", +"...+++...++...+", +"...++.........+", +"...++.........+", +"...++.+++.....+", +"...+++++++....+", +"...+++..+++...+", +"...++....++...+", +"...++....++...+", +"...++....++...+", +"...+++..+++...+", +"...+++++++....+", +"....+++++.....+", +"..............+", +"+++++++++++++++"};