aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--language/English/strings.po12
-rw-r--r--system/settings/rbp.xml35
-rw-r--r--xbmc/cores/omxplayer/OMXAudio.cpp361
-rw-r--r--xbmc/cores/omxplayer/OMXAudio.h12
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerAudio.cpp12
5 files changed, 343 insertions, 89 deletions
diff --git a/language/English/strings.po b/language/English/strings.po
index b89ee27d51..3f957b07d7 100644
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -14332,6 +14332,11 @@ msgctxt "#36541"
msgid "Allows volume control from AirPlay clients."
msgstr ""
+#: system/settings/rbp.xml
+msgctxt "#36542"
+msgid "Output to both analogue (headphones) and HDMI"
+msgstr ""
+
#reserved strings 365XX
#: xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp
@@ -14379,4 +14384,9 @@ msgstr ""
#: system/settings/settings.xml
msgctxt "#37016"
msgid "Select this option if your receiver is capable of decoding E-AC3 streams."
-msgstr "" \ No newline at end of file
+msgstr ""
+
+#: system/settings/rbp.xml
+msgctxt "#37017"
+msgid "Dual audio output"
+msgstr ""
diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml
index 0369c50615..5293091a0f 100644
--- a/system/settings/rbp.xml
+++ b/system/settings/rbp.xml
@@ -53,6 +53,41 @@
<setting id="audiooutput.dtshdpassthrough">
<visible>false</visible>
</setting>
+ <setting id="audiooutput.eac3passthrough">
+ <visible>false</visible>
+ </setting>
+ <setting id="audiooutput.ac3passthrough">
+ <default>true</default>
+ <dependencies>
+ <dependency type="enable">
+ <and>
+ <or>
+ <condition setting="audiooutput.mode">1</condition> <!-- AUDIO_IEC958 -->
+ <condition setting="audiooutput.mode">2</condition> <!-- AUDIO_HDMI -->
+ </or>
+ <condition setting="audiooutput.dualaudio">false</condition>
+ </and>
+ </dependency>
+ </dependencies>
+ </setting>
+ <setting id="audiooutput.dtspassthrough">
+ <default>true</default>
+ <dependencies>
+ <dependency type="enable">
+ <and>
+ <or>
+ <condition setting="audiooutput.mode">1</condition> <!-- AUDIO_IEC958 -->
+ <condition setting="audiooutput.mode">2</condition> <!-- AUDIO_HDMI -->
+ </or>
+ <condition setting="audiooutput.dualaudio">false</condition>
+ </and>
+ </dependency>
+ </dependencies>
+ </setting>
+ <setting id="audiooutput.dualaudio" type="boolean" label="37017" help="36542">
+ <level>2</level>
+ <default>false</default>
+ </setting>
</group>
<group id="2">
<visible>false</visible>
diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp
index cc1391f5d5..d2864b947e 100644
--- a/xbmc/cores/omxplayer/OMXAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXAudio.cpp
@@ -184,84 +184,224 @@ bool COMXAudio::PortSettingsChanged()
if(!m_omx_mixer.Initialize("OMX.broadcom.audio_mixer", OMX_IndexParamAudioInit))
return false;
}
-
- if(!m_omx_render.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit))
- return false;
+ if(CSettings::Get().GetBool("audiooutput.dualaudio"))
+ {
+ if(!m_omx_splitter.Initialize("OMX.broadcom.audio_splitter", OMX_IndexParamAudioInit))
+ return false;
+ }
+ if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetInt("audiooutput.mode") == AUDIO_ANALOG)
+ {
+ if(!m_omx_render_analog.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit))
+ return false;
+ }
+ if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetInt("audiooutput.mode") == AUDIO_HDMI)
+ {
+ if(!m_omx_render_hdmi.Initialize("OMX.broadcom.audio_render", OMX_IndexParamAudioInit))
+ return false;
+ }
ApplyVolume();
- if(!m_Passthrough)
+ if( m_omx_mixer.IsInitialized() )
{
/* setup mixer output */
OMX_INIT_STRUCTURE(m_pcm_output);
- m_pcm_output.nPortIndex = m_omx_decoder.GetOutputPort();
+ m_pcm_output.nPortIndex = m_omx_decoder.GetOutputPort();
omx_err = m_omx_decoder.GetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
if(omx_err != OMX_ErrorNone)
{
- CLog::Log(LOGERROR, "%s::%s - error SetParameter 1 output omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder GetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
}
- m_pcm_output.nPortIndex = m_omx_mixer.GetOutputPort();
/* mixer output is always stereo */
m_pcm_output.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
m_pcm_output.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
m_pcm_output.nChannels = 2;
+ m_pcm_output.nPortIndex = m_omx_mixer.GetOutputPort();
omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
if(omx_err != OMX_ErrorNone)
{
- CLog::Log(LOGERROR, "%s::%s - error SetParameter 1 output omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ CLog::Log(LOGERROR, "%s::%s - error m_omx_mixer SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
}
+
CLog::Log(LOGDEBUG, "%s::%s - Output bps %d samplerate %d channels %d buffer size %d bytes per second %d",
CLASSNAME, __func__, (int)m_pcm_output.nBitPerSample, (int)m_pcm_output.nSamplingRate, (int)m_pcm_output.nChannels, m_BufferLen, m_BytesPerSec);
PrintPCM(&m_pcm_output, std::string("output"));
- }
- m_omx_tunnel_clock.Initialize(m_omx_clock, m_omx_clock->GetInputPort(), &m_omx_render, m_omx_render.GetInputPort()+1);
+ if( m_omx_splitter.IsInitialized() )
+ {
+ m_pcm_output.nPortIndex = m_omx_splitter.GetInputPort();
+ omx_err = m_omx_splitter.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error m_omx_splitter SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+
+ // Splitter will copy input params to output when input port is enabled.
+ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateIdle);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "COMXAudio::AddPackets - Error setting OMX_StateIdle 0x%08x for m_omx_splitter", omx_err);
+ return false;
+ }
+ m_omx_splitter.EnablePort(m_omx_splitter.GetInputPort(), false);
+ m_omx_splitter.DisablePort(m_omx_splitter.GetInputPort(), false);
+ }
- omx_err = m_omx_tunnel_clock.Establish(false);
- if(omx_err != OMX_ErrorNone)
+ if( m_omx_render_analog.IsInitialized() )
+ {
+ m_pcm_output.nPortIndex = m_omx_render_analog.GetInputPort();
+ omx_err = m_omx_render_analog.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error m_omx_render_analog SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ }
+
+ if( m_omx_render_hdmi.IsInitialized() )
+ {
+ m_pcm_output.nPortIndex = m_omx_render_hdmi.GetInputPort();
+ omx_err = m_omx_render_hdmi.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error m_omx_render_hdmi SetParameter omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ }
+ }
+ if( m_omx_render_analog.IsInitialized() )
{
- CLog::Log(LOGERROR, "%s::%s - m_omx_tunnel_clock.Establish omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- return false;
+ m_omx_tunnel_clock_analog.Initialize(m_omx_clock, m_omx_clock->GetInputPort(),
+ &m_omx_render_analog, m_omx_render_analog.GetInputPort()+1);
+
+ omx_err = m_omx_tunnel_clock_analog.Establish(false);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_tunnel_clock_analog.Establish omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ m_omx_render_analog.ResetEos();
}
+ if( m_omx_render_hdmi.IsInitialized() )
+ {
+ m_omx_tunnel_clock_hdmi.Initialize(m_omx_clock, m_omx_clock->GetInputPort() + (m_omx_render_analog.IsInitialized() ? 2 : 0),
+ &m_omx_render_hdmi, m_omx_render_hdmi.GetInputPort()+1);
- m_omx_render.ResetEos();
+ omx_err = m_omx_tunnel_clock_hdmi.Establish(false);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_tunnel_clock_hdmi.Establish omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ m_omx_render_hdmi.ResetEos();
+ }
- // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock.
- // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync
- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock"))
+ if( m_omx_render_analog.IsInitialized() )
{
- OMX_CONFIG_BOOLEANTYPE configBool;
- OMX_INIT_STRUCTURE(configBool);
- configBool.bEnabled = OMX_FALSE;
+ // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock.
+ // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync
+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock"))
+ {
+ OMX_CONFIG_BOOLEANTYPE configBool;
+ OMX_INIT_STRUCTURE(configBool);
+ configBool.bEnabled = OMX_FALSE;
- omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool);
+ omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool);
+ if (omx_err != OMX_ErrorNone)
+ return false;
+ }
+
+ OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
+ OMX_INIT_STRUCTURE(audioDest);
+ strncpy((char *)audioDest.sName, "local", strlen("local"));
+ omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest);
if (omx_err != OMX_ErrorNone)
- return false;
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_render_analog.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
}
- OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
- OMX_INIT_STRUCTURE(audioDest);
- strncpy((char *)audioDest.sName, m_deviceuse.c_str(), strlen(m_deviceuse.c_str()));
-
- omx_err = m_omx_render.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest);
- if (omx_err != OMX_ErrorNone)
+ if( m_omx_render_hdmi.IsInitialized() )
{
- CLog::Log(LOGERROR, "%s::%s - m_omx_render.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- return false;
+ // By default audio_render is the clock master, and if output samples don't fit the timestamps, it will speed up/slow down the clock.
+ // This tends to be better for maintaining audio sync and avoiding audio glitches, but can affect video/display sync
+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock"))
+ {
+ OMX_CONFIG_BOOLEANTYPE configBool;
+ OMX_INIT_STRUCTURE(configBool);
+ configBool.bEnabled = OMX_FALSE;
+
+ omx_err = m_omx_render_hdmi.SetConfig(OMX_IndexConfigBrcmClockReferenceSource, &configBool);
+ if (omx_err != OMX_ErrorNone)
+ return false;
+ }
+
+ OMX_CONFIG_BRCMAUDIODESTINATIONTYPE audioDest;
+ OMX_INIT_STRUCTURE(audioDest);
+ strncpy((char *)audioDest.sName, "hdmi", strlen("hdmi"));
+ omx_err = m_omx_render_hdmi.SetConfig(OMX_IndexConfigBrcmAudioDestination, &audioDest);
+ if (omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_render_hdmi.SetConfig omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
}
- if(!m_Passthrough)
+ if( m_omx_splitter.IsInitialized() )
+ {
+ m_omx_tunnel_splitter_analog.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort(), &m_omx_render_analog, m_omx_render_analog.GetInputPort());
+ omx_err = m_omx_tunnel_splitter_analog.Establish(false);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_analog.Establish 0x%08x", omx_err);
+ return false;
+ }
+
+ m_omx_tunnel_splitter_hdmi.Initialize(&m_omx_splitter, m_omx_splitter.GetOutputPort() + 1, &m_omx_render_hdmi, m_omx_render_hdmi.GetInputPort());
+ omx_err = m_omx_tunnel_splitter_hdmi.Establish(false);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "COMXAudio::Initialize - Error m_omx_tunnel_splitter_hdmi.Establish 0x%08x", omx_err);
+ return false;
+ }
+ }
+ if( m_omx_mixer.IsInitialized() )
{
m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_mixer, m_omx_mixer.GetInputPort());
- m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort());
+ if( m_omx_splitter.IsInitialized() )
+ {
+ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), &m_omx_splitter, m_omx_splitter.GetInputPort());
+ }
+ else
+ {
+ if( m_omx_render_analog.IsInitialized() )
+ {
+ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), &m_omx_render_analog, m_omx_render_analog.GetInputPort());
+ }
+ if( m_omx_render_hdmi.IsInitialized() )
+ {
+ m_omx_tunnel_mixer.Initialize(&m_omx_mixer, m_omx_mixer.GetOutputPort(), &m_omx_render_hdmi, m_omx_render_hdmi.GetInputPort());
+ }
+ }
CLog::Log(LOGDEBUG, "%s::%s - bits:%d mode:%d channels:%d srate:%d nopassthrough", CLASSNAME, __func__,
(int)m_pcm_input.nBitPerSample, m_pcm_input.ePCMMode, (int)m_pcm_input.nChannels, (int)m_pcm_input.nSamplingRate);
}
else
{
- m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort());
+ if( m_omx_render_analog.IsInitialized() )
+ {
+ m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_render_analog, m_omx_render_analog.GetInputPort());
+ }
+ else if( m_omx_render_hdmi.IsInitialized() )
+ {
+ m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_render_hdmi, m_omx_render_hdmi.GetInputPort());
+ }
CLog::Log(LOGDEBUG, "%s::%s - bits:%d mode:%d channels:%d srate:%d passthrough", CLASSNAME, __func__,
0, 0, 0, 0);
}
@@ -272,13 +412,18 @@ bool COMXAudio::PortSettingsChanged()
CLog::Log(LOGERROR, "%s::%s - m_omx_tunnel_decoder.Establish omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
return false;
}
- if(!m_Passthrough)
+
+ if( m_omx_mixer.IsInitialized() )
{
omx_err = m_omx_mixer.SetStateForComponent(OMX_StateExecuting);
if(omx_err != OMX_ErrorNone) {
CLog::Log(LOGERROR, "%s::%s - m_omx_mixer OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
return false;
}
+ }
+
+ if( m_omx_mixer.IsInitialized() )
+ {
omx_err = m_omx_tunnel_mixer.Establish(false);
if(omx_err != OMX_ErrorNone)
{
@@ -287,18 +432,39 @@ bool COMXAudio::PortSettingsChanged()
}
}
- omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting);
- if(omx_err != OMX_ErrorNone)
+ if( m_omx_splitter.IsInitialized() )
{
- CLog::Log(LOGERROR, "%s::%s - m_omx_render OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
- return false;
+ omx_err = m_omx_splitter.SetStateForComponent(OMX_StateExecuting);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_splitter OMX_StateExecuting 0x%08x", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ }
+ if( m_omx_render_analog.IsInitialized() )
+ {
+ omx_err = m_omx_render_analog.SetStateForComponent(OMX_StateExecuting);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_render_analog OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
+ }
+ if( m_omx_render_hdmi.IsInitialized() )
+ {
+ omx_err = m_omx_render_hdmi.SetStateForComponent(OMX_StateExecuting);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - m_omx_render_hdmi OMX_StateExecuting omx_err(0x%08x)", CLASSNAME, __func__, omx_err);
+ return false;
+ }
}
m_settings_changed = true;
return true;
}
-bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode)
+bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode)
{
CSingleLock lock (m_critSection);
OMX_ERRORTYPE omx_err;
@@ -308,12 +474,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *
if(!m_dllAvUtil.Load())
return false;
- if(device == "hdmi") {
- m_deviceuse = "hdmi";
- } else {
- m_deviceuse = "local";
- }
-
m_HWDecode = bUseHWDecode;
m_Passthrough = bUsePassthrough;
@@ -592,8 +752,8 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *
CLog::Log(LOGDEBUG, "COMXAudio::Initialize Input bps %d samplerate %d channels %d buffer size %d bytes per second %d",
(int)m_pcm_input.nBitPerSample, (int)m_pcm_input.nSamplingRate, (int)m_pcm_input.nChannels, m_BufferLen, m_BytesPerSec);
PrintPCM(&m_pcm_output, std::string("input"));
- CLog::Log(LOGDEBUG, "COMXAudio::Initialize device %s passthrough %d hwdecode %d",
- device.c_str(), m_Passthrough, m_HWDecode);
+ CLog::Log(LOGDEBUG, "COMXAudio::Initialize device passthrough %d hwdecode %d",
+ m_Passthrough, m_HWDecode);
return true;
}
@@ -603,20 +763,27 @@ bool COMXAudio::Deinitialize()
{
CSingleLock lock (m_critSection);
- m_omx_tunnel_decoder.Flush();
- if(!m_Passthrough)
- m_omx_tunnel_mixer.Flush();
- m_omx_tunnel_clock.Flush();
-
- m_omx_tunnel_clock.Deestablish();
- if(!m_Passthrough)
+ Flush();
+
+ if ( m_omx_tunnel_clock_analog.IsInitialized() )
+ m_omx_tunnel_clock_analog.Deestablish();
+ if ( m_omx_tunnel_clock_hdmi.IsInitialized() )
+ m_omx_tunnel_clock_hdmi.Deestablish();
+ if ( m_omx_tunnel_splitter_analog.IsInitialized() )
+ m_omx_tunnel_splitter_analog.Deestablish();
+ if ( m_omx_tunnel_splitter_hdmi.IsInitialized() )
+ m_omx_tunnel_splitter_hdmi.Deestablish();
+ if ( m_omx_tunnel_mixer.IsInitialized() )
m_omx_tunnel_mixer.Deestablish();
m_omx_tunnel_decoder.Deestablish();
- m_omx_decoder.FlushInput();
-
- m_omx_render.Deinitialize(true);
- if(!m_Passthrough)
+ if ( m_omx_render_analog.IsInitialized() )
+ m_omx_render_analog.Deinitialize(true);
+ if ( m_omx_render_hdmi.IsInitialized() )
+ m_omx_render_hdmi.Deinitialize(true);
+ if ( m_omx_splitter.IsInitialized() )
+ m_omx_splitter.Deinitialize(true);
+ if ( m_omx_mixer.IsInitialized() )
m_omx_mixer.Deinitialize(true);
m_omx_decoder.Deinitialize(true);
@@ -651,11 +818,26 @@ void COMXAudio::Flush()
if(!m_Initialized)
return;
- m_omx_decoder.FlushInput();
+ m_omx_decoder.FlushAll();
m_omx_tunnel_decoder.Flush();
- if(!m_Passthrough)
+
+ if ( m_omx_mixer.IsInitialized() )
+ m_omx_mixer.FlushAll();
+ if( m_omx_tunnel_mixer.IsInitialized() )
m_omx_tunnel_mixer.Flush();
-
+
+ if ( m_omx_splitter.IsInitialized() )
+ m_omx_splitter.FlushAll();
+ if ( m_omx_tunnel_splitter_analog.IsInitialized() )
+ m_omx_tunnel_splitter_analog.Flush();
+ if ( m_omx_tunnel_splitter_hdmi.IsInitialized() )
+ m_omx_tunnel_splitter_hdmi.Flush();
+
+ if ( m_omx_render_analog.IsInitialized() )
+ m_omx_render_analog.FlushAll();
+ if ( m_omx_render_hdmi.IsInitialized() )
+ m_omx_render_hdmi.FlushAll();
+
m_last_pts = DVD_NOPTS_VALUE;
m_LostSync = true;
m_setStartTime = true;
@@ -746,19 +928,32 @@ bool COMXAudio::ApplyVolume(void)
{
OMX_AUDIO_CONFIG_VOLUMETYPE volume;
OMX_INIT_STRUCTURE(volume);
- volume.nPortIndex = m_omx_render.GetInputPort();
volume.bLinear = OMX_TRUE;
float hardwareVolume = fVolume * gain * 100.0f;
volume.sVolume.nValue = (int)(hardwareVolume + 0.5f);
- OMX_ERRORTYPE omx_err =
- m_omx_render.SetConfig(OMX_IndexConfigAudioVolume, &volume);
- if(omx_err != OMX_ErrorNone)
+ if(m_omx_render_analog.IsInitialized())
{
- CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x\n",
+ volume.nPortIndex = m_omx_render_analog.GetInputPort();
+ OMX_ERRORTYPE omx_err = m_omx_render_analog.SetConfig(OMX_IndexConfigAudioVolume, &volume);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x\n",
CLASSNAME, __func__, omx_err);
- return false;
+ return false;
+ }
+ }
+ if(m_omx_render_hdmi.IsInitialized())
+ {
+ volume.nPortIndex = m_omx_render_hdmi.GetInputPort();
+ OMX_ERRORTYPE omx_err = m_omx_render_hdmi.SetConfig(OMX_IndexConfigAudioVolume, &volume);
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error setting OMX_IndexConfigAudioVolume, error 0x%08x\n",
+ CLASSNAME, __func__, omx_err);
+ return false;
+ }
}
}
CLog::Log(LOGINFO, "%s::%s - Volume=%.2f\n", CLASSNAME, __func__, fVolume);
@@ -1043,16 +1238,32 @@ unsigned int COMXAudio::GetAudioRenderingLatency()
OMX_PARAM_U32TYPE param;
OMX_INIT_STRUCTURE(param);
- param.nPortIndex = m_omx_render.GetInputPort();
- OMX_ERRORTYPE omx_err =
- m_omx_render.GetConfig(OMX_IndexConfigAudioRenderingLatency, &param);
+ if(m_omx_render_analog.IsInitialized())
+ {
+ param.nPortIndex = m_omx_render_analog.GetInputPort();
+
+ OMX_ERRORTYPE omx_err = m_omx_render_analog.GetConfig(OMX_IndexConfigAudioRenderingLatency, &param);
- if(omx_err != OMX_ErrorNone)
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n",
+ CLASSNAME, __func__, omx_err);
+ return 0;
+ }
+ }
+ else if(m_omx_render_hdmi.IsInitialized())
{
- CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n",
- CLASSNAME, __func__, omx_err);
- return 0;
+ param.nPortIndex = m_omx_render_hdmi.GetInputPort();
+
+ OMX_ERRORTYPE omx_err = m_omx_render_hdmi.GetConfig(OMX_IndexConfigAudioRenderingLatency, &param);
+
+ if(omx_err != OMX_ErrorNone)
+ {
+ CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x\n",
+ CLASSNAME, __func__, omx_err);
+ return 0;
+ }
}
return param.nU32;
diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h
index 309dc7509f..09993e6ba0 100644
--- a/xbmc/cores/omxplayer/OMXAudio.h
+++ b/xbmc/cores/omxplayer/OMXAudio.h
@@ -60,7 +60,7 @@ public:
float GetCacheTime();
float GetCacheTotal();
COMXAudio();
- bool Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode);
+ bool Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode);
bool PortSettingsChanged();
~COMXAudio();
@@ -118,7 +118,6 @@ private:
OMX_AUDIO_CODINGTYPE m_eEncoding;
uint8_t *m_extradata;
int m_extrasize;
- std::string m_deviceuse;
// stuff for visualisation
double m_last_pts;
int m_vizBufferSize;
@@ -141,12 +140,17 @@ private:
WAVEFORMATEXTENSIBLE m_wave_header;
AEAudioFormat m_format;
protected:
- COMXCoreComponent m_omx_render;
+ COMXCoreComponent m_omx_render_analog;
+ COMXCoreComponent m_omx_render_hdmi;
+ COMXCoreComponent m_omx_splitter;
COMXCoreComponent m_omx_mixer;
COMXCoreComponent m_omx_decoder;
- COMXCoreTunel m_omx_tunnel_clock;
+ COMXCoreTunel m_omx_tunnel_clock_analog;
+ COMXCoreTunel m_omx_tunnel_clock_hdmi;
COMXCoreTunel m_omx_tunnel_mixer;
COMXCoreTunel m_omx_tunnel_decoder;
+ COMXCoreTunel m_omx_tunnel_splitter_analog;
+ COMXCoreTunel m_omx_tunnel_splitter_hdmi;
DllAvUtil m_dllAvUtil;
OMX_AUDIO_CHANNELTYPE m_input_channels[OMX_AUDIO_MAXCHANNELS];
diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
index 8343d62f23..4121300d15 100644
--- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -146,7 +146,8 @@ void OMXPlayerAudio::OpenStream(CDVDStreamInfo &hints, COMXAudioCodecOMX *codec)
m_flush = false;
m_nChannels = 0;
m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;
- m_use_passthrough = (CSettings::Get().GetInt("audiooutput.mode") == AUDIO_HDMI) ? true : false ;
+ m_use_passthrough = (CSettings::Get().GetInt("audiooutput.mode") == AUDIO_HDMI &&
+ !CSettings::Get().GetBool("audiooutput.dualaudio")) ? true : false ;
m_use_hw_decode = g_advancedSettings.m_omxHWAudioDecode;
m_format.m_dataFormat = GetDataFormat(m_hints);
m_format.m_sampleRate = 0;
@@ -580,13 +581,6 @@ bool OMXPlayerAudio::OpenDecoder()
/* GetDataFormat is setting up evrything */
m_format.m_dataFormat = GetDataFormat(m_hints);
- std::string device = "";
-
- if(CSettings::Get().GetInt("audiooutput.mode") == AUDIO_HDMI)
- device = "hdmi";
- else
- device = "local";
-
m_format.m_channelLayout.Reset();
if (m_pAudioCodec && !m_passthrough)
m_format.m_channelLayout = m_pAudioCodec->GetChannelMap();
@@ -601,7 +595,7 @@ bool OMXPlayerAudio::OpenDecoder()
if (m_nChannels > 4 ) m_format.m_channelLayout += AE_CH_BL;
if (m_nChannels > 5 ) m_format.m_channelLayout += AE_CH_BR;
}
- bool bAudioRenderOpen = m_omxAudio.Initialize(m_format, device, m_av_clock, m_hints, m_passthrough, m_hw_decode);
+ bool bAudioRenderOpen = m_omxAudio.Initialize(m_format, m_av_clock, m_hints, m_passthrough, m_hw_decode);
m_codec_name = "";
m_bad_state = !bAudioRenderOpen;