summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Reufer <thomas@reufer.ch>2014-09-29 21:36:38 +0200
committerThomas Reufer <thomas@reufer.ch>2014-09-29 21:36:38 +0200
commitef6e0314b8c0930e63ef8715c8bbb504e9adae52 (patch)
tree43c06bd0c825a42c8e963a094454e3f937f38328
parent0f3194b2021c98abaefc6d35d67457fafeb7107c (diff)
downloadvdr-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--HISTORY1
-rw-r--r--audio.c3
-rw-r--r--setup.c43
-rw-r--r--setup.h2
4 files changed, 49 insertions, 0 deletions
diff --git a/HISTORY b/HISTORY
index 3c15dc4..bc5f14f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/audio.c b/audio.c
index 9cf9f17..c99c51b 100644
--- a/audio.c
+++ b/audio.c
@@ -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);
}
}
diff --git a/setup.c b/setup.c
index fe2cd36..711f5b9 100644
--- a/setup.c
+++ b/setup.c
@@ -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);
diff --git a/setup.h b/setup.h
index 146fe53..d1b29c1 100644
--- a/setup.h
+++ b/setup.h
@@ -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; }