diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp index d6b8e0ea90e9b..5e6c0dfef578b 100644 --- a/xbmc/cores/omxplayer/OMXAudio.cpp +++ b/xbmc/cores/omxplayer/OMXAudio.cpp @@ -96,15 +96,14 @@ COMXAudio::COMXAudio() : m_BitsPerSample (0 ), m_omx_clock (NULL ), m_av_clock (NULL ), - m_external_clock (false ), m_first_frame (true ), m_LostSync (true ), m_SampleRate (0 ), m_eEncoding (OMX_AUDIO_CodingPCM), m_extradata (NULL ), m_extrasize (0 ), - m_omx_render (NULL ), - m_last_pts (DVD_NOPTS_VALUE) + m_last_pts (DVD_NOPTS_VALUE), + m_omx_render (NULL ) { m_vizBufferSize = m_vizRemapBufferSize = VIS_PACKET_SIZE * sizeof(float); m_vizRemapBuffer = (uint8_t *)_aligned_malloc(m_vizRemapBufferSize,16); @@ -113,8 +112,7 @@ COMXAudio::COMXAudio() : COMXAudio::~COMXAudio() { - if(m_Initialized) - Deinitialize(); + Deinitialize(); _aligned_free(m_vizRemapBuffer); _aligned_free(m_vizBuffer); @@ -156,14 +154,27 @@ CAEChannelInfo COMXAudio::GetChannelLayout(AEAudioFormat format) bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode) { + Deinitialize(); + + if(!m_dllAvUtil.Load()) + return false; + m_HWDecode = bUseHWDecode; m_Passthrough = bUsePassthrough; m_format = format; + if(m_format.m_channelLayout.Count() == 0) + return false; + if(hints.samplerate == 0) return false; + m_av_clock = clock; + + if(!m_av_clock) + return false; + /* passthrough overwrites hw decode */ if(m_Passthrough) { @@ -176,8 +187,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * } SetCodingType(format.m_dataFormat); - SetClock(clock); - if(hints.extrasize > 0 && hints.extradata != NULL) { m_extrasize = hints.extrasize; @@ -185,46 +194,7 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device, OMXClock * memcpy(m_extradata, hints.extradata, hints.extrasize); } - return Initialize(format, device); -} - -bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) -{ - if(m_Initialized) - Deinitialize(); - - m_format = format; - - if(m_format.m_channelLayout.Count() == 0) - return false; - - if(!m_dllAvUtil.Load()) - return false; - - if(m_av_clock == NULL) - { - /* no external clock set. generate one */ - m_external_clock = false; - - m_av_clock = new OMXClock(); - - if(!m_av_clock->OMXInitialize(false, true)) - { - delete m_av_clock; - m_av_clock = NULL; - CLog::Log(LOGERROR, "COMXAudio::Initialize error creating av clock\n"); - return false; - } - } - - m_omx_clock = m_av_clock->GetOMXClock(); - - /* - m_Passthrough = false; - - if(OMX_IS_RAW(m_format.m_dataFormat)) - m_Passthrough =true; - */ + m_omx_clock = m_av_clock->GetOMXClock(); m_drc = 0; @@ -342,7 +312,9 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) std::string componentName = ""; componentName = "OMX.broadcom.audio_render"; - m_omx_render = new COMXCoreComponent(); + + if(!m_omx_render) + m_omx_render = new COMXCoreComponent(); if(!m_omx_render) { CLog::Log(LOGERROR, "COMXAudio::Initialize error allocate OMX.broadcom.audio_render\n"); @@ -441,16 +413,6 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) return false; } - if(!m_external_clock) - { - omx_err = m_omx_clock->SetStateForComponent(OMX_StateExecuting); - if (omx_err != OMX_ErrorNone) - { - CLog::Log(LOGERROR, "COMXAudio::Initialize m_omx_clock.SetStateForComponent\n"); - return false; - } - } - omx_err = m_omx_decoder.AllocInputBuffers(); if(omx_err != OMX_ErrorNone) { @@ -575,6 +537,10 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) } } + /* return on decoder error so m_Initialized stays false */ + if(m_omx_decoder.BadState()) + return false; + m_Initialized = true; m_first_frame = true; m_last_pts = DVD_NOPTS_VALUE; @@ -585,10 +551,8 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) (int)m_pcm_output.nBitPerSample, (int)m_pcm_output.nSamplingRate, (int)m_pcm_output.nChannels, m_BufferLen, m_BytesPerSec); 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); - CLog::Log(LOGDEBUG, "COMXAudio::Initialize device %s passthrough %d hwdecode %d external clock %d", - device.c_str(), m_Passthrough, m_HWDecode, m_external_clock); - - m_av_clock->OMXStateExecute(false); + CLog::Log(LOGDEBUG, "COMXAudio::Initialize device %s passthrough %d hwdecode %d", + device.c_str(), m_Passthrough, m_HWDecode); return true; } @@ -596,17 +560,8 @@ bool COMXAudio::Initialize(AEAudioFormat format, std::string& device) //*********************************************************************************************** bool COMXAudio::Deinitialize() { - if(!m_Initialized) - return true; - CSingleLock lock (m_critSection); - if(m_av_clock && !m_external_clock) - { - m_av_clock->Lock(); - m_av_clock->OMXStop(false); - } - m_omx_tunnel_decoder.Flush(); if(!m_Passthrough) m_omx_tunnel_mixer.Flush(); @@ -614,12 +569,21 @@ bool COMXAudio::Deinitialize() m_omx_tunnel_clock.Deestablish(); if(!m_Passthrough) - m_omx_tunnel_mixer.Deestablish(); + { + // workaround for the strange BCM mixer component + if(m_omx_mixer.GetState() == OMX_StateExecuting) + m_omx_mixer.SetStateForComponent(OMX_StatePause); + if(m_omx_mixer.GetState() != OMX_StateIdle) + m_omx_mixer.SetStateForComponent(OMX_StateIdle); + m_omx_mixer.DisableAllPorts(); + m_omx_tunnel_mixer.Deestablish(true); + } m_omx_tunnel_decoder.Deestablish(); m_omx_decoder.FlushInput(); - m_omx_render->Deinitialize(); + if(m_omx_render) + m_omx_render->Deinitialize(); if(!m_Passthrough) m_omx_mixer.Deinitialize(); m_omx_decoder.Deinitialize(); @@ -627,14 +591,6 @@ bool COMXAudio::Deinitialize() m_BytesPerSec = 0; m_BufferLen = 0; - if(m_av_clock && !m_external_clock) - { - m_av_clock->OMXReset(false); - m_av_clock->UnLock(); - delete m_av_clock; - m_external_clock = false; - } - m_omx_clock = NULL; m_av_clock = NULL; @@ -852,7 +808,7 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt m_last_pts = pts; - CLog::Log(LOGDEBUG, "ADec : setStartTime %f\n", (float)val / DVD_TIME_BASE); + CLog::Log(LOGDEBUG, "COMXAudio::Decode ADec : setStartTime %f\n", (float)val / DVD_TIME_BASE); m_av_clock->AudioStart(false); } else @@ -1209,6 +1165,8 @@ void COMXAudio::WaitCompletion() nTimeOut -= 50; } + m_omx_render->ResetEos(); + return; } @@ -1217,16 +1175,6 @@ void COMXAudio::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) return ; } -bool COMXAudio::SetClock(OMXClock *clock) -{ - if(m_av_clock != NULL) - return false; - - m_av_clock = clock; - m_external_clock = true; - return true; -} - void COMXAudio::SetCodingType(AEDataFormat dataFormat) { switch(dataFormat) diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h index 66c6f9241430f..d812e0a8b859c 100644 --- a/xbmc/cores/omxplayer/OMXAudio.h +++ b/xbmc/cores/omxplayer/OMXAudio.h @@ -61,7 +61,6 @@ class COMXAudio float GetCacheTotal(); COMXAudio(); bool Initialize(AEAudioFormat format, std::string& device, OMXClock *clock, CDVDStreamInfo &hints, bool bUsePassthrough, bool bUseHWDecode); - bool Initialize(AEAudioFormat format, std::string& device); ~COMXAudio(); unsigned int AddPackets(const void* data, unsigned int len); @@ -84,7 +83,6 @@ class COMXAudio void Process(); - bool SetClock(OMXClock *clock); void SetCodingType(AEDataFormat dataFormat); static bool CanHWDecode(CodecID codec); @@ -95,6 +93,8 @@ class COMXAudio unsigned int SyncDTS(BYTE* pData, unsigned int iSize); unsigned int SyncAC3(BYTE* pData, unsigned int iSize); + bool BadState() { return !m_Initialized; }; + private: IAudioCallback* m_pCallback; bool m_Initialized; @@ -111,7 +111,6 @@ class COMXAudio unsigned int m_BitsPerSample; COMXCoreComponent *m_omx_clock; OMXClock *m_av_clock; - bool m_external_clock; bool m_first_frame; bool m_LostSync; int m_SampleRate; diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp index 76082cdbff07a..04076d78e412b 100644 --- a/xbmc/cores/omxplayer/OMXImage.cpp +++ b/xbmc/cores/omxplayer/OMXImage.cpp @@ -830,6 +830,9 @@ bool COMXImage::Decode(unsigned width, unsigned height) m_omx_tunnel_decode.Deestablish(); + if(m_omx_decoder.BadState()) + return false; + return true; } @@ -1007,6 +1010,9 @@ bool COMXImage::Encode(unsigned char *buffer, int size, unsigned width, unsigned return false; } + if(m_omx_encoder.BadState()) + return false; + return true; } diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp index 887f4ae40639e..c1deafe0a6cdc 100644 --- a/xbmc/cores/omxplayer/OMXPlayer.cpp +++ b/xbmc/cores/omxplayer/OMXPlayer.cpp @@ -571,19 +571,6 @@ bool COMXPlayer::OpenInputStream() if (!m_pInputStream->Open(m_filename.c_str(), m_mimetype)) { - if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) - { - CLog::Log(LOGERROR, "COMXPlayer::OpenInputStream - failed to open [%s] as DVD ISO, trying Bluray", m_filename.c_str()); - m_mimetype = "bluray/iso"; - filename = m_filename; - filename = filename + "/BDMV/index.bdmv"; - int title = (int)m_item.GetProperty("BlurayStartingTitle").asInteger(); - if( title ) - filename.AppendFormat("?title=%d",title); - - m_filename = filename; - goto retry; - } CLog::Log(LOGERROR, "COMXPlayer::OpenInputStream - error opening [%s]", m_filename.c_str()); return false; } @@ -597,6 +584,7 @@ bool COMXPlayer::OpenInputStream() // find any available external subtitles for non dvd files if (!m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) + && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_TV) && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_HTSP)) { @@ -633,7 +621,7 @@ bool COMXPlayer::OpenInputStream() SetAVDelay(g_settings.m_currentVideoSettings.m_AudioDelay); SetSubTitleDelay(g_settings.m_currentVideoSettings.m_SubtitleDelay); m_av_clock.Reset(); - m_av_clock.OMXReset(); + //m_av_clock.OMXReset(); m_dvd.Clear(); m_iChannelEntryTimeOut = 0; @@ -756,8 +744,8 @@ void COMXPlayer::OpenDefaultStreams(bool reset) CloseTeletextStream(true); */ - m_av_clock.OMXStop(); - m_av_clock.OMXReset(); + //m_av_clock.OMXStop(); + //m_av_clock.OMXReset(); } bool COMXPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream) @@ -942,6 +930,9 @@ bool COMXPlayer::WaitForPausedThumbJobs(int timeout_ms) void COMXPlayer::Process() { + bool bOmxWaitVideo = false; + bool bOmxWaitAudio = false; + //bool bAEStopped = false; if(!m_av_clock.OMXInitialize(false, false)) @@ -952,8 +943,8 @@ void COMXPlayer::Process() if(g_guiSettings.GetBool("videoplayer.adjustrefreshrate")) m_av_clock.HDMIClockSync(); - m_av_clock.OMXStateExecute(); - m_av_clock.OMXStart(); + //m_av_clock.OMXStateExecute(); + //m_av_clock.OMXStart(); //CLog::Log(LOGDEBUG, "COMXPlayer: Thread started"); @@ -1144,6 +1135,13 @@ void COMXPlayer::Process() // update application with our state UpdateApplication(1000); + // OMX emergency exit + if(HasAudio() && m_player_audio.BadState()) + { + m_bAbortRequest = true; + break; + } + if (CheckDelayedChannelEntry()) continue; @@ -1155,9 +1153,9 @@ void COMXPlayer::Process() continue; } - // always yield to players if they have data - if((m_player_audio.HasData() || m_CurrentAudio.id < 0) - && (m_player_video.HasData() || m_CurrentVideo.id < 0)) + // always yield to players if they have data levels > 50 percent + if((m_player_audio.GetLevel() > 50 || m_CurrentAudio.id < 0) + && (m_player_video.GetLevel() > 50 || m_CurrentVideo.id < 0)) Sleep(0); DemuxPacket* pPacket = NULL; @@ -1215,12 +1213,27 @@ void COMXPlayer::Process() Sleep(100); continue; } + else if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) + { + CDVDInputStreamPVRManager* pStream = static_cast(m_pInputStream); + if (pStream->IsEOF()) + break; + Sleep(100); + continue; + } + // make sure we tell all players to finish it's data if(m_CurrentAudio.inited) + { m_player_audio.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF)); + bOmxWaitAudio = true; + } if(m_CurrentVideo.inited) + { m_player_video.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF)); + bOmxWaitVideo = true; + } if(m_CurrentSubtitle.inited) m_player_subtitle.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF)); m_CurrentAudio.inited = false; @@ -1242,12 +1255,12 @@ void COMXPlayer::Process() } // wait for omx components to finish - if(HasVideo() && !m_player_video.IsEOS()) + if(bOmxWaitVideo && !m_player_video.IsEOS()) { Sleep(100); continue; } - if(HasAudio() && !m_player_audio.IsEOS()) + if(bOmxWaitAudio && !m_player_audio.IsEOS()) { Sleep(100); continue; @@ -3617,7 +3630,7 @@ bool COMXPlayer::GetCurrentSubtitle(CStdString& strSubtitle) if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) return false; - double pts = m_av_clock.OMXMediaTime(); + double pts = m_av_clock.OMXMediaTime(false); m_player_subtitle.GetCurrentSubtitle(strSubtitle, pts - m_player_video.GetSubtitleDelay()); diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp index bfd199e66e780..fbafe2ca7abe9 100644 --- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp +++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp @@ -62,8 +62,7 @@ class COMXMsgAudioCodecChange : public CDVDMsg CDVDStreamInfo m_hints; }; -OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, - CDVDMessageQueue& parent) +OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent) : CThread("COMXPlayerAudio") , m_messageQueue("audio") , m_messageParent(parent) @@ -79,11 +78,12 @@ OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, m_DecoderOpen = false; m_freq = CurrentHostFrequency(); m_send_eos = false; + m_bad_state = false; m_hints_current.Clear(); m_av_clock->SetMasterClock(false); - m_messageQueue.SetMaxDataSize(3 * 1024 * 1024); + m_messageQueue.SetMaxDataSize(6 * 1024 * 1024); m_messageQueue.SetMaxTimeSize(8.0); } @@ -100,6 +100,8 @@ bool OMXPlayerAudio::OpenStream(CDVDStreamInfo &hints) if(!m_DllBcmHost.Load()) return false; + m_bad_state = false; + COMXAudioCodecOMX *codec = new COMXAudioCodecOMX(); if(!codec || !codec->Open(hints)) @@ -323,15 +325,35 @@ bool OMXPlayerAudio::CodecChange() return false; } +void OMXPlayerAudio::HandlePlayspeed(bool bDropPacket) +{ + if(!bDropPacket && m_speed == DVD_PLAYSPEED_NORMAL && m_av_clock->HasVideo()) + { + if(GetDelay() < 0.1f && !m_av_clock->OMXAudioBuffer()) + { + clock_gettime(CLOCK_REALTIME, &m_starttime); + m_av_clock->OMXAudioBufferStart(); + } + else if(GetDelay() > (AUDIO_BUFFER_SECONDS * 0.75f) && m_av_clock->OMXAudioBuffer()) + { + m_av_clock->OMXAudioBufferStop(); + } + else if(m_av_clock->OMXAudioBuffer()) + { + clock_gettime(CLOCK_REALTIME, &m_endtime); + if((m_endtime.tv_sec - m_starttime.tv_sec) > 1) + { + m_av_clock->OMXAudioBufferStop(); + } + } + } +} + bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) { - if(!pkt) + if(!pkt || m_bad_state || !m_pAudioCodec) return false; - /* last decoder reinit went wrong */ - if(!m_pAudioCodec) - return true; - if(pkt->dts != DVD_NOPTS_VALUE) m_audioClock = pkt->dts; @@ -364,8 +386,6 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) if(CodecChange()) { - CloseDecoder(); - m_DecoderOpen = OpenDecoder(); if(!m_DecoderOpen) return false; @@ -373,6 +393,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) while(!m_bStop) { + HandlePlayspeed(bDropPacket); if(m_flush) { m_flush = false; @@ -414,8 +435,6 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) { if(CodecChange()) { - CloseDecoder(); - m_DecoderOpen = OpenDecoder(); if(!m_DecoderOpen) return false; @@ -423,6 +442,8 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) while(!m_bStop) { + HandlePlayspeed(bDropPacket); + if(m_flush) { m_flush = false; @@ -465,27 +486,6 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket) m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_AUDIO)); } - if(!bDropPacket && m_speed == DVD_PLAYSPEED_NORMAL && m_av_clock->HasVideo()) - { - if(GetDelay() < 0.1f && !m_av_clock->OMXAudioBuffer()) - { - clock_gettime(CLOCK_REALTIME, &m_starttime); - m_av_clock->OMXAudioBufferStart(); - } - else if(GetDelay() > (AUDIO_BUFFER_SECONDS * 0.75f) && m_av_clock->OMXAudioBuffer()) - { - m_av_clock->OMXAudioBufferStop(); - } - else if(m_av_clock->OMXAudioBuffer()) - { - clock_gettime(CLOCK_REALTIME, &m_endtime); - if((m_endtime.tv_sec - m_starttime.tv_sec) > 1) - { - m_av_clock->OMXAudioBufferStop(); - } - } - } - return true; } @@ -554,6 +554,11 @@ void OMXPlayerAudio::Process() { if (m_pAudioCodec) m_pAudioCodec->Reset(); + m_av_clock->Lock(); + m_av_clock->OMXStop(false); + m_omxAudio.Flush(); + m_av_clock->OMXReset(false); + m_av_clock->UnLock(); m_started = false; } else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) @@ -713,10 +718,15 @@ bool OMXPlayerAudio::OpenDecoder() m_passthrough = false; m_hw_decode = false; - m_omxAudio.SetClock(m_av_clock); + bool bSendParent = false; - m_av_clock->Lock(); - m_av_clock->OMXStop(false); + if(m_DecoderOpen) + { + WaitCompletion(); + m_omxAudio.Deinitialize(); + m_DecoderOpen = false; + bSendParent = true; + } /* setup audi format for audio render */ m_format.m_sampleRate = m_hints.samplerate; @@ -731,9 +741,13 @@ bool OMXPlayerAudio::OpenDecoder() else device = "local"; + m_av_clock->Lock(); + m_av_clock->OMXStop(false); + bool bAudioRenderOpen = m_omxAudio.Initialize(m_format, device, m_av_clock, m_hints, m_passthrough, m_hw_decode); m_codec_name = ""; + m_bad_state = !bAudioRenderOpen; if(!bAudioRenderOpen) { @@ -746,10 +760,19 @@ bool OMXPlayerAudio::OpenDecoder() m_codec_name.c_str(), m_nChannels, m_hints.samplerate, m_hints.bitspersample); } + m_av_clock->OMXStateExecute(false); m_av_clock->HasAudio(bAudioRenderOpen); m_av_clock->OMXReset(false); m_av_clock->UnLock(); + m_started = false; + + // TODO : Send FLUSH to parent, only if we had a valid open codec. + // this is just a workaround to get the omx video decoder happy again + // This situation happens, for example where we have in the stream an audio codec change + if(bSendParent) + m_messageParent.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH)); + return bAudioRenderOpen; } @@ -757,8 +780,8 @@ void OMXPlayerAudio::CloseDecoder() { m_av_clock->Lock(); m_av_clock->OMXStop(false); - m_av_clock->HasAudio(false); m_omxAudio.Deinitialize(); + m_av_clock->HasAudio(false); m_av_clock->OMXReset(false); m_av_clock->UnLock(); @@ -777,7 +800,7 @@ double OMXPlayerAudio::GetCacheTime() void OMXPlayerAudio::WaitCompletion() { - if(!m_send_eos) + if(!m_send_eos && !m_bad_state) m_omxAudio.WaitCompletion(); m_send_eos = true; } diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.h b/xbmc/cores/omxplayer/OMXPlayerAudio.h index ce2f3ee0c8d97..97607d784d441 100644 --- a/xbmc/cores/omxplayer/OMXPlayerAudio.h +++ b/xbmc/cores/omxplayer/OMXPlayerAudio.h @@ -89,10 +89,13 @@ class OMXPlayerAudio : public CThread DllBcmHost m_DllBcmHost; bool m_send_eos; + bool m_bad_state; virtual void OnStartup(); virtual void OnExit(); virtual void Process(); + + void HandlePlayspeed(bool bDropPacket); private: public: OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent); @@ -126,5 +129,7 @@ class OMXPlayerAudio : public CThread void SetSpeed(int iSpeed); int GetAudioBitrate(); std::string GetPlayerInfo(); + + bool BadState() { return m_bad_state; } }; #endif diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp index 4da86c7b9c362..318e133ac90d6 100644 --- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp @@ -96,7 +96,7 @@ OMXPlayerVideo::OMXPlayerVideo(OMXClock *av_clock, m_autosync = 1; m_fForcedAspectRatio = 0.0f; m_send_eos = false; - m_messageQueue.SetMaxDataSize(10 * 1024 * 1024); + m_messageQueue.SetMaxDataSize(40 * 1024 * 1024); m_messageQueue.SetMaxTimeSize(8.0); RESOLUTION res = g_graphicsContext.GetVideoResolution(); @@ -195,8 +195,8 @@ bool OMXPlayerVideo::CloseStream(bool bWaitForBuffers) m_av_clock->Lock(); m_av_clock->OMXStop(false); - m_av_clock->HasVideo(false); m_omxVideo.Close(); + m_av_clock->HasVideo(false); m_av_clock->OMXReset(false); m_av_clock->UnLock(); @@ -714,6 +714,7 @@ bool OMXPlayerVideo::OpenDecoder() // use aspect in stream always m_fForcedAspectRatio = m_hints.aspect; + m_av_clock->Lock(); m_av_clock->OMXStop(false); @@ -743,9 +744,11 @@ bool OMXPlayerVideo::OpenDecoder() m_av_clock->SetRefreshRate(m_fFrameRate); } + m_av_clock->OMXStateExecute(false); m_av_clock->HasVideo(bVideoDecoderOpen); m_av_clock->OMXReset(false); m_av_clock->UnLock(); + return bVideoDecoderOpen; } diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp index f911dc57a2404..6de0ee9ba9549 100644 --- a/xbmc/cores/omxplayer/OMXVideo.cpp +++ b/xbmc/cores/omxplayer/OMXVideo.cpp @@ -87,8 +87,7 @@ COMXVideo::COMXVideo() COMXVideo::~COMXVideo() { - if (m_is_open) - Close(); + Close(); } bool COMXVideo::SendDecoderConfig() @@ -145,8 +144,7 @@ bool COMXVideo::NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, bool hdmi_clock_sync) { - if(m_is_open) - Close(); + Close(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; std::string decoder_name; @@ -638,13 +636,14 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b */ + if(m_omx_decoder.BadState()) + return false; + CLog::Log(LOGDEBUG, "%s::%s - decoder_component(0x%p), input_port(0x%x), output_port(0x%x) deinterlace %d hdmiclocksync %d\n", CLASSNAME, __func__, m_omx_decoder.GetComponent(), m_omx_decoder.GetInputPort(), m_omx_decoder.GetOutputPort(), m_deinterlace, m_hdmi_clock_sync); - m_av_clock->OMXStateExecute(false); - m_first_frame = true; return true; } @@ -688,6 +687,7 @@ void COMXVideo::Close() m_video_codec_name = ""; m_deinterlace = false; m_first_frame = true; + m_av_clock = NULL; } void COMXVideo::SetDropState(bool bDrop) @@ -712,11 +712,11 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) if( m_drop_state ) return true; - if (pData || iSize > 0) - { - unsigned int demuxer_bytes = (unsigned int)iSize; - uint8_t *demuxer_content = pData; + unsigned int demuxer_bytes = (unsigned int)iSize; + uint8_t *demuxer_content = pData; + if (demuxer_content && demuxer_bytes > 0) + { while(demuxer_bytes) { // 500ms timeout @@ -745,7 +745,7 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) if(m_av_clock->VideoStart()) { omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME; - CLog::Log(LOGDEBUG, "VDec : setStartTime %f\n", (float)val / DVD_TIME_BASE); + CLog::Log(LOGDEBUG, "OMXVideo::Decode VDec : setStartTime %f\n", (float)val / DVD_TIME_BASE); m_av_clock->VideoStart(false); } else @@ -1000,5 +1000,7 @@ void COMXVideo::WaitCompletion() nTimeOut -= 50; } + m_omx_render.ResetEos(); + return; } diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h index 87efc36832a2c..80207f0a23827 100644 --- a/xbmc/cores/omxplayer/OMXVideo.h +++ b/xbmc/cores/omxplayer/OMXVideo.h @@ -59,6 +59,7 @@ class COMXVideo void SetVideoRect(const CRect& SrcRect, const CRect& DestRect); int GetInputBufferSize(); void WaitCompletion(); + bool BadState() { return m_omx_decoder.BadState(); }; protected: // Video format bool m_drop_state; diff --git a/xbmc/linux/OMXClock.cpp b/xbmc/linux/OMXClock.cpp index 525081e9f754d..c3c991c0fdb00 100644 --- a/xbmc/linux/OMXClock.cpp +++ b/xbmc/linux/OMXClock.cpp @@ -282,17 +282,27 @@ void OMXClock::OMXSetClockPorts(OMX_TIME_CONFIG_CLOCKSTATETYPE *clock) if(!clock) return; + clock->nWaitMask = 0; + if(m_has_audio) { m_audio_start = true; clock->nWaitMask |= OMX_CLOCKPORT0; } + else + { + m_audio_start = false; + } if(m_has_video) { m_video_start = true; clock->nWaitMask |= OMX_CLOCKPORT1; } + else + { + m_video_start = false; + } } bool OMXClock::OMXSetReferenceClock(bool lock /* = true */) @@ -343,6 +353,9 @@ bool OMXClock::OMXInitialize(bool has_video, bool has_audio) if(!m_omx_clock.Initialize((const std::string)componentName, OMX_IndexParamOtherInit)) return false; + m_omx_clock.DisableAllPorts(); + + /* if(!OMXSetReferenceClock(false)) return false; @@ -354,6 +367,7 @@ bool OMXClock::OMXInitialize(bool has_video, bool has_audio) omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) CLog::Log(LOGWARNING, "OMXClock::OMXInitialize setting OMX_IndexConfigTimeClockState\n"); + */ return true; } @@ -608,8 +622,6 @@ bool OMXClock::OMXReset(bool lock /* = true */) if(lock) Lock(); - CLog::Log(LOGDEBUG, "OMXClock::OMXReset 0x%08x\n", m_omx_clock.GetState()); - m_audio_buffer = false; OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -623,6 +635,15 @@ bool OMXClock::OMXReset(bool lock /* = true */) OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); + omx_err = m_omx_clock.GetConfig(OMX_IndexConfigTimeClockState, &clock); + if(omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "OMXClock::OMXReset error getting OMX_IndexConfigTimeClockState\n"); + if(lock) + UnLock(); + return false; + } + clock.eState = OMX_TIME_ClockStateWaitingForStartTime; //clock.nOffset = ToOMXTime(-1000LL * 200); @@ -640,6 +661,9 @@ bool OMXClock::OMXReset(bool lock /* = true */) } } + CLog::Log(LOGDEBUG, "OMXClock::OMXReset audio / video : %d / %d start audio / video : %d / %d wait mask %d\n", + m_has_audio, m_has_video, m_audio_start, m_video_start, clock.nWaitMask); + if(lock) UnLock(); diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp index 43a22356b14e5..1a2539adc7170 100644 --- a/xbmc/linux/OMXCore.cpp +++ b/xbmc/linux/OMXCore.cpp @@ -63,8 +63,13 @@ COMXCoreTunel::COMXCoreTunel() m_src_port = 0; m_dst_port = 0; m_portSettingsChanged = false; + m_tunnel_set = false; m_DllOMX = new DllOMX(); - m_DllOMXOpen = m_DllOMX->Load(); + + if(m_DllOMX) + m_DllOMXOpen = m_DllOMX->Load(); + else + m_DllOMXOpen = false; pthread_mutex_init(&m_lock, NULL); } @@ -98,12 +103,14 @@ void COMXCoreTunel::Initialize(COMXCoreComponent *src_component, unsigned int sr m_dst_port = dst_port; } -OMX_ERRORTYPE COMXCoreTunel::Flush() +bool COMXCoreTunel::IsInitialized() { - if(!m_DllOMXOpen) - return OMX_ErrorUndefined; + return m_tunnel_set; +} - if(!m_src_component || !m_dst_component) +OMX_ERRORTYPE COMXCoreTunel::Flush() +{ + if(!m_DllOMXOpen || !m_src_component || !m_dst_component || !m_tunnel_set || !IsInitialized()) return OMX_ErrorUndefined; Lock(); @@ -111,7 +118,7 @@ OMX_ERRORTYPE COMXCoreTunel::Flush() OMX_ERRORTYPE omx_err = OMX_ErrorNone; if(m_src_component->GetComponent()) { - omx_err = OMX_SendCommand(m_src_component->GetComponent(), OMX_CommandFlush, m_src_port, NULL); + omx_err = m_src_component->SendCommand(OMX_CommandFlush, m_src_port, NULL); if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState) { CLog::Log(LOGERROR, "COMXCoreTunel::Flush - Error flush port %d on component %s omx_err(0x%08x)", @@ -121,7 +128,7 @@ OMX_ERRORTYPE COMXCoreTunel::Flush() if(m_dst_component->GetComponent()) { - omx_err = OMX_SendCommand(m_dst_component->GetComponent(), OMX_CommandFlush, m_dst_port, NULL); + omx_err = m_dst_component->SendCommand(OMX_CommandFlush, m_dst_port, NULL); if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState) { CLog::Log(LOGERROR, "COMXCoreTunel::Flush - Error flush port %d on component %s omx_err(0x%08x)", @@ -145,7 +152,7 @@ OMX_ERRORTYPE COMXCoreTunel::Deestablish(bool noWait) if(!m_DllOMXOpen) return OMX_ErrorUndefined; - if(!m_src_component || !m_dst_component) + if(!m_src_component || !m_dst_component || !IsInitialized()) return OMX_ErrorUndefined; Lock(); @@ -195,12 +202,14 @@ OMX_ERRORTYPE COMXCoreTunel::Deestablish(bool noWait) } } + m_tunnel_set = false; + UnLock(); return OMX_ErrorNone; } -OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) +OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged, bool enable_ports /* = true */) { if(!m_DllOMXOpen) return OMX_ErrorUndefined; @@ -276,7 +285,9 @@ OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) return OMX_ErrorUndefined; } - if(m_src_component->GetComponent()) + m_tunnel_set = true; + + if(m_src_component->GetComponent() && enable_ports) { omx_err = m_src_component->EnablePort(m_src_port, false); if(omx_err != OMX_ErrorNone) @@ -288,7 +299,7 @@ OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) } } - if(m_dst_component->GetComponent()) + if(m_dst_component->GetComponent() && enable_ports) { omx_err = m_dst_component->EnablePort(m_dst_port, false); if(omx_err != OMX_ErrorNone) @@ -300,17 +311,17 @@ OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) } } - if(m_dst_component->GetComponent()) + if(m_dst_component->GetComponent() && enable_ports) { - if(m_dst_component->GetState() == OMX_StateLoaded) + omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port); + if(omx_err != OMX_ErrorNone) { - omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port); - if(omx_err != OMX_ErrorNone) - { - UnLock(); - return omx_err; - } + UnLock(); + return omx_err; + } + if(m_dst_component->GetState() == OMX_StateLoaded) + { omx_err = m_dst_component->SetStateForComponent(OMX_StateIdle); if(omx_err != OMX_ErrorNone) { @@ -320,18 +331,9 @@ OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) return omx_err; } } - else - { - omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port); - if(omx_err != OMX_ErrorNone) - { - UnLock(); - return omx_err; - } - } } - if(m_src_component->GetComponent()) + if(m_src_component->GetComponent() && enable_ports) { omx_err = m_src_component->WaitForCommand(OMX_CommandPortEnable, m_src_port); if(omx_err != OMX_ErrorNone) @@ -365,15 +367,16 @@ COMXCoreComponent::COMXCoreComponent() m_output_buffer_count = 0; m_flush_input = false; m_flush_output = false; + m_resource_error = false; m_eos = false; m_exit = false; - m_DllOMXOpen = false; pthread_mutex_init(&m_omx_input_mutex, NULL); pthread_mutex_init(&m_omx_output_mutex, NULL); pthread_mutex_init(&m_omx_event_mutex, NULL); + pthread_mutex_init(&m_omx_eos_mutex, NULL); pthread_cond_init(&m_input_buffer_cond, NULL); pthread_cond_init(&m_output_buffer_cond, NULL); pthread_cond_init(&m_omx_event_cond, NULL); @@ -383,22 +386,30 @@ COMXCoreComponent::COMXCoreComponent() m_DllOMX = new DllOMX(); + if(m_DllOMX) + m_DllOMXOpen = m_DllOMX->Load(); + else + m_DllOMXOpen = false; + pthread_mutex_init(&m_lock, NULL); } COMXCoreComponent::~COMXCoreComponent() { - Deinitialize(); + Deinitialize(true); pthread_mutex_destroy(&m_omx_input_mutex); pthread_mutex_destroy(&m_omx_output_mutex); pthread_mutex_destroy(&m_omx_event_mutex); + pthread_mutex_destroy(&m_omx_eos_mutex); pthread_cond_destroy(&m_input_buffer_cond); pthread_cond_destroy(&m_output_buffer_cond); pthread_cond_destroy(&m_omx_event_cond); pthread_mutex_destroy(&m_lock); + if(m_DllOMXOpen) + m_DllOMX->Unload(); delete m_DllOMX; } @@ -414,6 +425,9 @@ void COMXCoreComponent::UnLock() void COMXCoreComponent::TransitionToStateLoaded() { + if(!m_handle) + return; + if(GetState() == OMX_StateExecuting) SetStateForComponent(OMX_StatePause); @@ -507,6 +521,9 @@ void COMXCoreComponent::FlushAll() void COMXCoreComponent::FlushInput() { + if(!m_handle) + return; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -525,6 +542,9 @@ void COMXCoreComponent::FlushInput() void COMXCoreComponent::FlushOutput() { + if(!m_handle) + return; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -843,16 +863,13 @@ OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffers() OMX_ERRORTYPE COMXCoreComponent::DisableAllPorts() { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; - if(!m_handle) - { - UnLock(); - return OMX_ErrorUndefined; - } - OMX_INDEXTYPE idxTypes[] = { OMX_IndexParamAudioInit, OMX_IndexParamImageInit, @@ -1077,18 +1094,14 @@ OMX_ERRORTYPE COMXCoreComponent::WaitForCommand(OMX_U32 command, OMX_U32 nData2, OMX_ERRORTYPE COMXCoreComponent::SetStateForComponent(OMX_STATETYPE state) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_STATETYPE state_actual = OMX_StateMax; - if(!m_handle) - { - UnLock(); - return OMX_ErrorUndefined; - } - - OMX_GetState(m_handle, &state_actual); if(state == state_actual) { UnLock(); @@ -1127,24 +1140,23 @@ OMX_ERRORTYPE COMXCoreComponent::SetStateForComponent(OMX_STATETYPE state) OMX_STATETYPE COMXCoreComponent::GetState() { + if(!m_handle) + return (OMX_STATETYPE)0; + Lock(); OMX_STATETYPE state; - if(m_handle) - { - OMX_GetState(m_handle, &state); - UnLock(); - return state; - } - + OMX_GetState(m_handle, &state); UnLock(); - - return (OMX_STATETYPE)0; + return state; } OMX_ERRORTYPE COMXCoreComponent::SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1163,6 +1175,9 @@ OMX_ERRORTYPE COMXCoreComponent::SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR OMX_ERRORTYPE COMXCoreComponent::GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1181,6 +1196,9 @@ OMX_ERRORTYPE COMXCoreComponent::GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR OMX_ERRORTYPE COMXCoreComponent::SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1199,6 +1217,9 @@ OMX_ERRORTYPE COMXCoreComponent::SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR co OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1217,6 +1238,9 @@ OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR co OMX_ERRORTYPE COMXCoreComponent::SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdParam, OMX_PTR cmdParamData) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1235,6 +1259,9 @@ OMX_ERRORTYPE COMXCoreComponent::SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdPar OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port, bool wait) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -1276,6 +1303,9 @@ OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port, bool wait) OMX_ERRORTYPE COMXCoreComponent::DisablePort(unsigned int port, bool wait) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; @@ -1317,6 +1347,9 @@ OMX_ERRORTYPE COMXCoreComponent::DisablePort(unsigned int port, bool wait) OMX_ERRORTYPE COMXCoreComponent::UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage) { + if(!m_handle) + return OMX_ErrorUndefined; + Lock(); OMX_ERRORTYPE omx_err; @@ -1337,11 +1370,10 @@ bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEX { OMX_ERRORTYPE omx_err; - if(!m_DllOMX->Load()) + if(!m_DllOMXOpen) return false; - m_DllOMXOpen = true; - + m_resource_error = false; m_componentName = component_name; m_callbacks.EventHandler = &COMXCoreComponent::DecoderEventHandlerCallback; @@ -1349,13 +1381,19 @@ bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEX m_callbacks.FillBufferDone = &COMXCoreComponent::DecoderFillBufferDoneCallback; // Get video component handle setting up callbacks, component is in loaded state on return. - omx_err = m_DllOMX->OMX_GetHandle(&m_handle, (char*)component_name.c_str(), this, &m_callbacks); - if (omx_err != OMX_ErrorNone) + if(!m_handle) { - CLog::Log(LOGERROR, "COMXCoreComponent::Initialize - could not get component handle for %s omx_err(0x%08x)\n", - component_name.c_str(), (int)omx_err); - Deinitialize(); - return false; + omx_err = m_DllOMX->OMX_GetHandle(&m_handle, (char*)component_name.c_str(), this, &m_callbacks); + if (!m_handle || omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXCoreComponent::Initialize - could not get component handle for %s omx_err(0x%08x)\n", + component_name.c_str(), (int)omx_err); + Deinitialize(true); + return false; + } + + CLog::Log(LOGDEBUG, "COMXCoreComponent::Initialize : %s handle 0x%08x dllopen : %d\n", + m_componentName.c_str(), m_handle, m_DllOMXOpen); } OMX_PORT_PARAM_TYPE port_param; @@ -1397,21 +1435,29 @@ bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEX return true; } -bool COMXCoreComponent::Deinitialize() +bool COMXCoreComponent::IsInitialized() { - OMX_ERRORTYPE omx_err; + return (m_handle != NULL); +} - if(!m_DllOMXOpen) - return false; +void COMXCoreComponent::ResetEos() +{ + pthread_mutex_lock(&m_omx_eos_mutex); + m_eos = false; + pthread_mutex_unlock(&m_omx_eos_mutex); +} + +bool COMXCoreComponent::Deinitialize(bool free_component /* = false */) +{ + OMX_ERRORTYPE omx_err; m_exit = true; m_flush_input = true; m_flush_output = true; - if(m_handle) + if(m_handle && m_DllOMXOpen) { - FlushAll(); FreeOutputBuffers(); @@ -1419,24 +1465,25 @@ bool COMXCoreComponent::Deinitialize() TransitionToStateLoaded(); - omx_err = m_DllOMX->OMX_FreeHandle(m_handle); - if (omx_err != OMX_ErrorNone) + if(free_component) { - CLog::Log(LOGERROR, "COMXCoreComponent::Deinitialize - failed to free handle for component %s omx_err(0x%08x)", - m_componentName.c_str(), omx_err); - } - - m_handle = NULL; - + CLog::Log(LOGDEBUG, "COMXCoreComponent::Deinitialize : %s handle 0x%08x dllopen : %d\n", + m_componentName.c_str(), m_handle, m_DllOMXOpen); + omx_err = m_DllOMX->OMX_FreeHandle(m_handle); + if (omx_err != OMX_ErrorNone) + { + CLog::Log(LOGERROR, "COMXCoreComponent::Deinitialize - failed to free handle for component %s omx_err(0x%08x)", + m_componentName.c_str(), omx_err); + } + m_handle = NULL; + + m_input_port = 0; + m_output_port = 0; + m_componentName = ""; + m_resource_error = false; + } } - m_DllOMXOpen = false; - m_DllOMX->Unload(); - - m_input_port = 0; - m_output_port = 0; - m_componentName = ""; - return true; } @@ -1614,7 +1661,11 @@ OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandler( CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventBufferFlag(input)\n", CLASSNAME, __func__, ctx->GetName().c_str()); #endif if(nData2 & OMX_BUFFERFLAG_EOS) + { + pthread_mutex_lock(&ctx->m_omx_eos_mutex); ctx->m_eos = true; + pthread_mutex_unlock(&ctx->m_omx_eos_mutex); + } break; case OMX_EventPortSettingsChanged: #if defined(OMX_DEBUG_EVENTHANDLER) @@ -1639,6 +1690,7 @@ OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandler( break; case OMX_ErrorInsufficientResources: CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorInsufficientResources, insufficient resources\n", CLASSNAME, __func__, ctx->GetName().c_str()); + ctx->m_resource_error = true; break; case OMX_ErrorFormatNotDetected: CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorFormatNotDetected, cannot parse input stream\n", CLASSNAME, __func__, ctx->GetName().c_str()); diff --git a/xbmc/linux/OMXCore.h b/xbmc/linux/OMXCore.h index c8bbc06918b0a..2ce7cde73f7c5 100644 --- a/xbmc/linux/OMXCore.h +++ b/xbmc/linux/OMXCore.h @@ -71,9 +71,10 @@ class COMXCoreTunel ~COMXCoreTunel(); void Initialize(COMXCoreComponent *src_component, unsigned int src_port, COMXCoreComponent *dst_component, unsigned int dst_port); + bool IsInitialized(); OMX_ERRORTYPE Flush(); OMX_ERRORTYPE Deestablish(bool noWait = false); - OMX_ERRORTYPE Establish(bool portSettingsChanged); + OMX_ERRORTYPE Establish(bool portSettingsChanged, bool enable_ports = true); private: pthread_mutex_t m_lock; bool m_portSettingsChanged; @@ -85,6 +86,7 @@ class COMXCoreTunel bool m_DllOMXOpen; void Lock(); void UnLock(); + bool m_tunnel_set; }; class COMXCoreComponent @@ -115,7 +117,8 @@ class COMXCoreComponent OMX_ERRORTYPE UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage); bool Initialize( const std::string &component_name, OMX_INDEXTYPE index); - bool Deinitialize(); + bool IsInitialized(); + bool Deinitialize(bool free_component = false); // OMXCore Decoder delegate callback routines. static OMX_ERRORTYPE DecoderEventHandlerCallback(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, @@ -159,6 +162,8 @@ class COMXCoreComponent OMX_ERRORTYPE FreeOutputBuffers(); bool IsEOS() { return m_eos; }; + bool BadState() { return m_resource_error; }; + void ResetEos(); private: OMX_HANDLETYPE m_handle; @@ -166,6 +171,7 @@ class COMXCoreComponent unsigned int m_output_port; std::string m_componentName; pthread_mutex_t m_omx_event_mutex; + pthread_mutex_t m_omx_eos_mutex; pthread_mutex_t m_lock; std::vector m_omx_events; @@ -198,6 +204,7 @@ class COMXCoreComponent bool m_eos; bool m_flush_input; bool m_flush_output; + bool m_resource_error; void Lock(); void UnLock(); };