diff options
| author | Thomas Reufer <thomas@reufer.ch> | 2014-09-29 21:36:38 +0200 |
|---|---|---|
| committer | Thomas Reufer <thomas@reufer.ch> | 2014-09-29 21:36:38 +0200 |
| commit | ef6e0314b8c0930e63ef8715c8bbb504e9adae52 (patch) | |
| tree | 43c06bd0c825a42c8e963a094454e3f937f38328 | |
| parent | 0f3194b2021c98abaefc6d35d67457fafeb7107c (diff) | |
| download | vdr-plugin-rpihddevice-ef6e0314b8c0930e63ef8715c8bbb504e9adae52.tar.gz vdr-plugin-rpihddevice-ef6e0314b8c0930e63ef8715c8bbb504e9adae52.tar.bz2 | |
set HDMI speaker layout to fix channel mapping for multi channel PCM output
| -rw-r--r-- | HISTORY | 1 | ||||
| -rw-r--r-- | audio.c | 3 | ||||
| -rw-r--r-- | setup.c | 43 | ||||
| -rw-r--r-- | setup.h | 2 |
4 files changed, 49 insertions, 0 deletions
@@ -2,6 +2,7 @@ VDR Plugin 'rpihddevice' Revision History ----------------------------------------- - new: + - set HDMI speaker layout to fix channel mapping for multi channel PCM output - support building against external ffmpeg/libav by setting EXT_LIBAV - support for >=ffmpeg-1.2 and >=libav-0.8 with resampling - setup option for video framing mode in case of incompatible aspect ratio @@ -1170,6 +1170,9 @@ void cRpiAudioDecoder::SetCodec(cAudioCodec::eCodec codec, unsigned int &channel cRpiAudioPort::Str(outputPort), channels, cAudioCodec::Str(outputFormat), samplingRate / 1000, (samplingRate % 1000) / 100, m_passthrough ? " (pass-through)" : ""); + + if (outputPort == cRpiAudioPort::eHDMI) + cRpiSetup::SetHDMIChannelMapping(m_passthrough, channels); } } @@ -226,6 +226,49 @@ int cRpiSetup::GetDisplaySize(int &width, int &height, double &aspect) return 0; } +void cRpiSetup::SetHDMIChannelMapping(bool passthrough, int channels) +{ + char command[80], response[80]; + + sprintf(command, "hdmi_stream_channels %d", passthrough ? 1 : 0); + vc_gencmd(response, sizeof response, command); + + uint32_t channel_map = 0; + + if (!passthrough && channels > 0 && channels <= 6) + { + const unsigned char ch_mapping[6][8] = + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, // not supported + { 1, 2, 0, 0, 0, 0, 0, 0 }, // 2.0 + { 1, 2, 4, 0, 0, 0, 0, 0 }, // 2.1 + { 0, 0, 0, 0, 0, 0, 0, 0 }, // not supported + { 0, 0, 0, 0, 0, 0, 0, 0 }, // not supported + { 1, 2, 4, 3, 5, 6, 0, 0 }, // 5.1 + }; + + // speaker layout according CEA 861, Table 28: Audio InfoFrame, byte 4 + const unsigned char cea_map[] = + { + 0xff, // not supported + 0x00, // 2.0 + 0x01, // 2.1 + 0xff, // not supported + 0xff, // not supported + 0x0b // 5.1 + }; + + for (int ch = 0; ch < channels; ch++) + if (ch_mapping[channels - 1][ch]) + channel_map |= (ch_mapping[channels - 1][ch] - 1) << (3 * ch); + + channel_map |= cea_map[channels - 1] << 24; + } + + sprintf(command, "hdmi_channel_map 0x%08x", channel_map); + vc_gencmd(response, sizeof response, command); +} + cMenuSetupPage* cRpiSetup::GetSetupPage(void) { return new cRpiSetupPage(m_audio, m_video); @@ -72,6 +72,8 @@ public: static int GetDisplaySize(int &width, int &height, double &aspect); + static void SetHDMIChannelMapping(bool passthrough, int channels); + static bool IsDisplayProgressive(void) { return GetInstance()->m_isProgressive; } |
