diff options
-rw-r--r-- | language/English/strings.po | 12 | ||||
-rw-r--r-- | system/settings/rbp.xml | 35 | ||||
-rw-r--r-- | xbmc/cores/omxplayer/OMXAudio.cpp | 361 | ||||
-rw-r--r-- | xbmc/cores/omxplayer/OMXAudio.h | 12 | ||||
-rw-r--r-- | xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 12 |
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, ¶m); + if(m_omx_render_analog.IsInitialized()) + { + param.nPortIndex = m_omx_render_analog.GetInputPort(); + + OMX_ERRORTYPE omx_err = m_omx_render_analog.GetConfig(OMX_IndexConfigAudioRenderingLatency, ¶m); - 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, ¶m); + + 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; |