Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #2372 from huceke/raspberrypi

[rbp/omxplayer] sync up with dvdplayer master changes
  • Loading branch information...
commit 3caf659ddb92c83c2cc825a32126bc192651a233 2 parents 4e8a5a0 + 28de0da
huceke huceke authored
295 xbmc/cores/omxplayer/OMXPlayer.cpp
View
@@ -38,6 +38,7 @@
#include "filesystem/SpecialProtocol.h"
#include "guilib/GUIWindowManager.h"
#include "settings/AdvancedSettings.h"
+#include "settings/MediaSettings.h"
#include "settings/GUISettings.h"
#include "settings/Settings.h"
#include "threads/SingleLock.h"
@@ -424,9 +425,11 @@ COMXPlayer::COMXPlayer(IPlayerCallback &callback)
m_UpdateApplication = 0;
m_caching = CACHESTATE_DONE;
m_playSpeed = DVD_PLAYSPEED_NORMAL;
+ m_HasVideo = false;
+ m_HasAudio = false;
- m_State.Clear();
m_dvd.Clear();
+ m_State.Clear();
m_EdlAutoSkipMarkers.Clear();
memset(&m_SpeedState, 0, sizeof(m_SpeedState));
@@ -483,7 +486,6 @@ bool COMXPlayer::OpenFile(const CFileItem &file, const CPlayerOptions &options)
g_renderManager.PreInit();
Create();
-
if(!m_ready.WaitMSec(100))
{
CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
@@ -538,6 +540,9 @@ bool COMXPlayer::CloseFile()
m_Edl.Clear();
m_EdlAutoSkipMarkers.Clear();
+ m_HasVideo = false;
+ m_HasAudio = false;
+
g_renderManager.UnInit();
return true;
}
@@ -571,7 +576,7 @@ bool COMXPlayer::OpenInputStream()
{
m_filename = g_mediaManager.TranslateDevicePath("");
}
-retry:
+
// before creating the input stream, if this is an HLS playlist then get the
// most appropriate bitrate based on our network settings
if (filename.Left(7) == "http://" && filename.Right(5) == ".m3u8")
@@ -603,7 +608,6 @@ bool COMXPlayer::OpenInputStream()
|| m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
{
CLog::Log(LOGINFO, "COMXPlayer::OpenInputStream - DVD/BD not supported - Will try...");
- // return false;
}
// find any available external subtitles for non dvd files
@@ -637,7 +641,7 @@ bool COMXPlayer::OpenInputStream()
AddSubtitleFile(filenames[i]);
}
}
- } // end loop over all subtitle files
+ } // end loop over all subtitle files
CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleCached = true;
}
@@ -645,7 +649,6 @@ bool COMXPlayer::OpenInputStream()
SetAVDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay);
SetSubTitleDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleDelay);
m_av_clock.Reset();
- //m_av_clock.OMXReset();
m_dvd.Clear();
m_iChannelEntryTimeOut = 0;
@@ -704,8 +707,9 @@ bool COMXPlayer::OpenDemuxStream()
void COMXPlayer::OpenDefaultStreams(bool reset)
{
- // bypass for DVDs. The DVD Navigator has already dictated which streams to open.
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ // if input stream dictate, we will open later
+ if(m_dvd.iSelectedAudioStream >= 0
+ || m_dvd.iSelectedSPUStream >= 0)
return;
OMXSelectionStreams streams;
@@ -756,20 +760,15 @@ void COMXPlayer::OpenDefaultStreams(bool reset)
CloseSubtitleStream(true);
// open teletext stream
- /*
streams = m_SelectionStreams.Get(STREAM_TELETEXT);
valid = false;
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
+ for(OMXSelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
{
if(OpenTeletextStream(it->id, it->source))
valid = true;
}
if(!valid)
CloseTeletextStream(true);
- */
-
- //m_av_clock.OMXStop();
- //m_av_clock.OMXReset();
}
bool COMXPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
@@ -891,6 +890,9 @@ bool COMXPlayer::IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream
if(m_PlayerOptions.video_only && current.type != STREAM_VIDEO)
return false;
+ if(stream->disabled)
+ return false;
+
if (m_pInputStream && ( m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
|| m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
{
@@ -920,9 +922,6 @@ bool COMXPlayer::IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream
&& stream->iId == current.id)
return false;
- if(stream->disabled)
- return false;
-
if(stream->type != current.type)
return false;
@@ -940,21 +939,21 @@ void COMXPlayer::Process()
bool bOmxWaitVideo = false;
bool bOmxWaitAudio = false;
- if(!OpenInputStream())
+ if (!OpenInputStream())
{
m_bAbortRequest = true;
return;
}
- if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
{
- CLog::Log(LOGNOTICE, "OMXPlayer: playing a dvd with menu's");
+ CLog::Log(LOGNOTICE, "OMXPlayer: playing a file with menu's");
m_PlayerOptions.starttime = 0;
if(m_PlayerOptions.state.size() > 0)
- ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(m_PlayerOptions.state);
- else
- ((CDVDInputStreamNavigator*)m_pInputStream)->EnableSubtitleStream(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
+ ptr->SetState(m_PlayerOptions.state);
+ else if(CDVDInputStreamNavigator* nav = dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
+ nav->EnableSubtitleStream(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleCached = true;
}
@@ -1098,6 +1097,10 @@ void COMXPlayer::Process()
OpenDefaultStreams();
+ // never allow first frames after open to be skipped
+ if( m_player_video.IsInited() )
+ m_player_video.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
+
if (CachePVRStream())
SetCaching(CACHESTATE_PVR);
@@ -1154,10 +1157,8 @@ void COMXPlayer::Process()
continue;
// check for a still frame state
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ if (CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
{
- CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream);
-
// stills will be skipped
if(m_dvd.state == DVDSTATE_STILL)
{
@@ -1328,7 +1329,7 @@ void COMXPlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket)
void COMXPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
{
- if (m_CurrentAudio.stream != (void*)pStream
+ if (m_CurrentAudio.stream != (void*)pStream
|| m_CurrentAudio.changes != pStream->changes)
{
/* check so that dmuxer hints or extra data hasn't changed */
@@ -1594,6 +1595,7 @@ void COMXPlayer::HandlePlaySpeed()
if(m_caching != caching)
SetCaching(caching);
+
if(GetPlaySpeed() != DVD_PLAYSPEED_NORMAL && GetPlaySpeed() != DVD_PLAYSPEED_PAUSE)
{
if (IsInMenu())
@@ -1769,6 +1771,24 @@ void COMXPlayer::UpdateTimestamps(COMXCurrentStream& current, DemuxPacket* pPack
current.dur = 0.1 * (current.dur * 9 + (dts - current.dts));
current.dts = dts;
+
+ /* send a playback state structure periodically */
+ if(current.dts_state == DVD_NOPTS_VALUE
+ || abs(current.dts - current.dts_state) > DVD_MSEC_TO_TIME(200))
+ {
+ current.dts_state = current.dts;
+ if (current.inited)
+ {
+ // make sure we send no outdated state to a/v players
+ UpdatePlayState(0);
+ SendPlayerMessage(new CDVDMsgType<SPlayerState>(CDVDMsg::PLAYER_DISPLAYTIME, m_StateInput), current.player);
+ }
+ else
+ {
+ CSingleLock lock(m_StateSection);
+ m_State = m_StateInput;
+ }
+ }
}
void COMXPlayer::UpdateLimits(double& minimum, double& maximum, double dts)
@@ -2079,6 +2099,11 @@ void COMXPlayer::HandleMessages()
double start = DVD_NOPTS_VALUE;
int time = msg.GetRestore() ? (int)m_Edl.RestoreCutTime(msg.GetTime()) : msg.GetTime();
+
+ // if input streams doesn't support seektime we must convert back to clock
+ if(dynamic_cast<CDVDInputStream::ISeekTime*>(m_pInputStream) == NULL)
+ time -= DVD_TIME_TO_MSEC(m_State.time_offset - m_offset_pts);
+
CLog::Log(LOGDEBUG, "demuxer seek to: %d", time);
if (m_pDemuxer && m_pDemuxer->SeekTime(time, msg.GetBackward(), &start))
{
@@ -2088,6 +2113,9 @@ void COMXPlayer::HandleMessages()
if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward()))
CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time);
}
+ // dts after successful seek
+ m_StateInput.dts = start;
+
FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
}
else
@@ -2145,7 +2173,6 @@ void COMXPlayer::HandleMessages()
{
m_dvd.iSelectedAudioStream = -1;
CloseAudioStream(false);
- // TODO : check //CloseVideoStream(false);
m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
}
}
@@ -2196,13 +2223,14 @@ void COMXPlayer::HandleMessages()
CDVDMsgPlayerSetState* pMsgPlayerSetState = (CDVDMsgPlayerSetState*)pMsg;
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
{
- std::string s = pMsgPlayerSetState->GetState();
- ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(s);
- m_dvd.state = DVDSTATE_NORMAL;
- m_dvd.iDVDStillStartTime = 0;
- m_dvd.iDVDStillTime = 0;
+ if(ptr->SetState(pMsgPlayerSetState->GetState()))
+ {
+ m_dvd.state = DVDSTATE_NORMAL;
+ m_dvd.iDVDStillStartTime = 0;
+ m_dvd.iDVDStillTime = 0;
+ }
}
g_infoManager.SetDisplayAfterSeek();
@@ -2340,6 +2368,24 @@ void COMXPlayer::HandleMessages()
m_CurrentVideo.started = true;
CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started %d", player);
}
+ else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
+ {
+ COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
+
+ CSingleLock lock(m_StateSection);
+ /* prioritize data from video player, but only accept data *
+ * after it has been started to avoid race conditions after seeks */
+ if(m_CurrentVideo.started)
+ {
+ if(state.player == DVDPLAYER_VIDEO)
+ m_State = state;
+ }
+ else if(m_CurrentAudio.started)
+ {
+ if(state.player == DVDPLAYER_AUDIO)
+ m_State = state;
+ }
+ }
}
catch (...)
{
@@ -2348,6 +2394,7 @@ void COMXPlayer::HandleMessages()
pMsg->Release();
}
+
}
void COMXPlayer::SetCaching(ECacheState state)
@@ -2440,14 +2487,12 @@ bool COMXPlayer::IsPaused() const
bool COMXPlayer::HasVideo() const
{
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) return true;
-
- return m_SelectionStreams.Count(STREAM_VIDEO) > 0 ? true : false;
+ return m_HasVideo;
}
bool COMXPlayer::HasAudio() const
{
- return m_SelectionStreams.Count(STREAM_AUDIO) > 0 ? true : false;
+ return m_HasAudio;
}
bool COMXPlayer::IsPassthrough() const
@@ -2589,17 +2634,17 @@ bool COMXPlayer::SeekScene(bool bPlus)
void COMXPlayer::GetAudioInfo(CStdString &strAudioInfo)
{
{ CSingleLock lock(m_StateSection);
- strAudioInfo.Format("D(%s)", m_State.demux_audio.c_str());
+ strAudioInfo.Format("D(%s)", m_StateInput.demux_audio.c_str());
}
- strAudioInfo.AppendFormat(" P(%s)", m_player_audio.GetPlayerInfo().c_str());
+ strAudioInfo.AppendFormat("\nP(%s)", m_player_audio.GetPlayerInfo().c_str());
}
void COMXPlayer::GetVideoInfo(CStdString &strVideoInfo)
{
{ CSingleLock lock(m_StateSection);
- strVideoInfo.Format("D(%s)", m_State.demux_video.c_str());
+ strVideoInfo.Format("D(%s)", m_StateInput.demux_video.c_str());
}
- strVideoInfo.AppendFormat(" P(%s)", m_player_video.GetPlayerInfo().c_str());
+ strVideoInfo.AppendFormat("\nP(%s)", m_player_video.GetPlayerInfo().c_str());
}
void COMXPlayer::GetGeneralInfo(CStdString& strGeneralInfo)
@@ -2620,7 +2665,7 @@ void COMXPlayer::GetGeneralInfo(CStdString& strGeneralInfo)
CStdString strBuf;
CSingleLock lock(m_StateSection);
- if(m_State.cache_bytes >= 0)
+ if(m_StateInput.cache_bytes >= 0)
{
strBuf.AppendFormat(" cache:%s %2.0f%%"
, StringUtils::SizeToString(m_State.cache_bytes).c_str()
@@ -2666,7 +2711,7 @@ float COMXPlayer::GetPercentage()
float COMXPlayer::GetCachePercentage()
{
CSingleLock lock(m_StateSection);
- return m_State.cache_offset * 100; // NOTE: Percentage returned is relative
+ return m_StateInput.cache_offset * 100; // NOTE: Percentage returned is relative
}
void COMXPlayer::SetAVDelay(float fValue)
@@ -2689,6 +2734,7 @@ float COMXPlayer::GetSubTitleDelay()
return -m_player_video.GetSubtitleDelay() / DVD_TIME_BASE;
}
+// priority: 1: libdvdnav, 2: external subtitles, 3: muxed subtitles
int COMXPlayer::GetSubtitleCount()
{
OMXStreamLock lock(this);
@@ -2752,7 +2798,7 @@ int COMXPlayer::GetAudioStream()
{
return m_SelectionStreams.IndexOf(STREAM_AUDIO, *this);
}
-
+
void COMXPlayer::SetAudioStream(int iStream)
{
m_messenger.Put(new CDVDMsgPlayerSetAudioStream(iStream));
@@ -2788,12 +2834,13 @@ int64_t COMXPlayer::GetTime()
{
CSingleLock lock(m_StateSection);
double offset = 0;
+ const double limit = DVD_MSEC_TO_TIME(200);
if(m_State.timestamp > 0)
{
offset = m_av_clock.GetAbsoluteClock() - m_State.timestamp;
offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
- if(offset > 1000) offset = 1000;
- if(offset < -1000) offset = -1000;
+ if(offset > limit) offset = limit;
+ if(offset < -limit) offset = -limit;
}
return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
}
@@ -2874,6 +2921,7 @@ bool COMXPlayer::OpenAudioStream(int iStream, int source, bool reset)
m_CurrentAudio.hint = hint;
m_CurrentAudio.stream = (void*)pStream;
m_CurrentAudio.started = false;
+ m_HasAudio = true;
/* we are potentially going to be waiting on this */
m_player_audio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
@@ -2928,7 +2976,7 @@ bool COMXPlayer::OpenVideoStream(int iStream, int source, bool reset)
if(m_CurrentVideo.id < 0
|| m_CurrentVideo.hint != hint)
{
- if(!m_player_video.OpenStream(hint))
+ if (!m_player_video.OpenStream(hint))
{
/* mark stream as disabled, to disallaw further attempts */
CLog::Log(LOGWARNING, "%s - Unsupported stream %d. Stream disabled.", __FUNCTION__, iStream);
@@ -2955,6 +3003,7 @@ bool COMXPlayer::OpenVideoStream(int iStream, int source, bool reset)
m_CurrentVideo.hint = hint;
m_CurrentVideo.stream = (void*)pStream;
m_CurrentVideo.started = false;
+ m_HasVideo = true;
/* we are potentially going to be waiting on this */
m_player_video.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
@@ -3241,6 +3290,11 @@ void COMXPlayer::FlushBuffers(bool queued, double pts, bool accurate)
if(pts != DVD_NOPTS_VALUE)
m_av_clock.Discontinuity(pts);
UpdatePlayState(0);
+
+ // update state, buffers are flushed and it may take some time until
+ // we get an update from players
+ CSingleLock lock(m_StateSection);
+ m_State = m_StateInput;
}
}
@@ -3259,6 +3313,29 @@ int COMXPlayer::OnDVDNavResult(void* pData, int iMessage)
m_dvd.iSelectedSPUStream = *(int*)pData;
else if(iMessage == 4)
m_player_video.EnableSubtitle(*(int*)pData ? true: false);
+ else if(iMessage == 5)
+ {
+ if (m_dvd.state != DVDSTATE_STILL)
+ {
+ // else notify the player we have received a still frame
+
+ m_dvd.iDVDStillTime = *(int*)pData;
+ m_dvd.iDVDStillStartTime = XbmcThreads::SystemClockMillis();
+
+ /* adjust for the output delay in the video queue */
+ unsigned int time = 0;
+ if( m_CurrentVideo.stream && m_dvd.iDVDStillTime > 0 )
+ {
+ time = (unsigned int)(m_player_video.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
+ if( time < 10000 && time > 0 )
+ m_dvd.iDVDStillTime += time;
+ }
+ m_dvd.state = DVDSTATE_STILL;
+ CLog::Log(LOGDEBUG,
+ "DVDNAV_STILL_FRAME - waiting %i sec, with delay of %d sec",
+ m_dvd.iDVDStillTime, time / 1000);
+ }
+ }
return 0;
}
@@ -3497,11 +3574,12 @@ bool COMXPlayer::OnAction(const CAction &action)
pMenus->OnMenu();
// send a message to everyone that we've gone to the menu
CGUIMessage msg(GUI_MSG_VIDEO_MENU_STARTED, 0, 0);
- g_windowManager.SendMessage(msg);
+ g_windowManager.SendThreadMessage(msg);
return true;
}
break;
}
+
if (pMenus->IsInMenu())
{
switch (action.GetID())
@@ -3774,7 +3852,7 @@ int COMXPlayer::AddSubtitle(const CStdString& strSubPath)
int COMXPlayer::GetCacheLevel() const
{
CSingleLock lock(m_StateSection);
- return (int)(m_State.cache_level * 100);
+ return (int)(m_StateInput.cache_level * 100);
}
double COMXPlayer::GetQueueTime()
@@ -3784,6 +3862,26 @@ double COMXPlayer::GetQueueTime()
return max(a, v) * 8000.0 / 100;
}
+void COMXPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
+{
+ info.bitrate = m_player_video.GetVideoBitrate();
+
+ CStdString retVal;
+ if (m_pDemuxer && (m_CurrentVideo.id != -1))
+ m_pDemuxer->GetStreamCodecName(m_CurrentVideo.id, retVal);
+ info.videoCodecName = retVal;
+ info.videoAspectRatio = g_renderManager.GetAspectRatio();
+ g_renderManager.GetVideoRect(info.SrcRect, info.DestRect);
+}
+
+int COMXPlayer::GetSourceBitrate()
+{
+ if (m_pInputStream)
+ return (int)m_pInputStream->GetBitstreamStats().GetBitrate();
+
+ return 0;
+}
+
void COMXPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
{
if (index < 0 || index > GetAudioStreamCount() - 1)
@@ -3817,26 +3915,6 @@ void COMXPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
}
}
-void COMXPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
-{
- info.bitrate = m_player_video.GetVideoBitrate();
-
- CStdString retVal;
- if (m_pDemuxer && (m_CurrentVideo.id != -1))
- m_pDemuxer->GetStreamCodecName(m_CurrentVideo.id, retVal);
- info.videoCodecName = retVal;
- info.videoAspectRatio = g_renderManager.GetAspectRatio();
- g_renderManager.GetVideoRect(info.SrcRect, info.DestRect);
-}
-
-int COMXPlayer::GetSourceBitrate()
-{
- if (m_pInputStream)
- return (int)m_pInputStream->GetBitstreamStats().GetBitrate();
-
- return 0;
-}
-
int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string& subfilename, CDemuxStream::EFlags flags)
{
std::string ext = URIUtils::GetExtension(filename);
@@ -3874,18 +3952,16 @@ int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string&
void COMXPlayer::UpdatePlayState(double timeout)
{
- if(m_State.timestamp != 0
- && m_State.timestamp + DVD_MSEC_TO_TIME(timeout) > m_av_clock.GetAbsoluteClock())
+ if(m_StateInput.timestamp != 0
+ && m_StateInput.timestamp + DVD_MSEC_TO_TIME(timeout) > m_av_clock.GetAbsoluteClock())
return;
- SPlayerState state(m_State);
+ SPlayerState state(m_StateInput);
if (m_CurrentVideo.dts != DVD_NOPTS_VALUE)
state.dts = m_CurrentVideo.dts;
else if(m_CurrentAudio.dts != DVD_NOPTS_VALUE)
state.dts = m_CurrentAudio.dts;
- else
- state.dts = m_av_clock.GetClock();
if(m_pDemuxer)
{
@@ -3893,15 +3969,21 @@ void COMXPlayer::UpdatePlayState(double timeout)
state.chapter_count = m_pDemuxer->GetChapterCount();
m_pDemuxer->GetChapterName(state.chapter_name);
- // TODO : workaround until omx clock handling is rewritten
- if(m_playSpeed == DVD_PLAYSPEED_NORMAL)
- state.time = DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime(true, true));
- else
- state.time = DVD_TIME_TO_MSEC(m_av_clock.GetClock() + m_offset_pts);
+ if(state.dts == DVD_NOPTS_VALUE)
+ state.time = 0;
+ else
+ // TODO : workaround until omx clock handling is rewritten
+ if(m_playSpeed == DVD_PLAYSPEED_NORMAL)
+ state.time = DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime(true, true));
+ else
+ state.time = DVD_TIME_TO_MSEC(state.dts + m_offset_pts);
state.time_total = m_pDemuxer->GetStreamLength();
-
+ state.time_src = ETIMESOURCE_CLOCK;
}
+ state.canpause = true;
+ state.canseek = true;
+
if(m_pInputStream)
{
// override from input stream if needed
@@ -3917,27 +3999,26 @@ void COMXPlayer::UpdatePlayState(double timeout)
{
state.time = pDisplayTime->GetTime();
state.time_total = pDisplayTime->GetTotalTime();
+ state.time_src = ETIMESOURCE_INPUT;
}
- if (dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
+ if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
{
+ if(!ptr->GetState(state.player_state))
+ state.player_state = "";
+
if(m_dvd.state == DVDSTATE_STILL)
{
state.time = XbmcThreads::SystemClockMillis() - m_dvd.iDVDStillStartTime;
state.time_total = m_dvd.iDVDStillTime;
+ state.time_src = ETIMESOURCE_MENU;
}
}
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER))
- {
- CDVDInputStreamPVRManager* pvrinputstream = static_cast<CDVDInputStreamPVRManager*>(m_pInputStream);
- state.canpause = pvrinputstream->CanPause();
- state.canseek = pvrinputstream->CanSeek();
- }
- else
+ if (CDVDInputStream::ISeekable* ptr = dynamic_cast<CDVDInputStream::ISeekable*>(m_pInputStream))
{
- state.canseek = state.time_total > 0 ? true : false;
- state.canpause = true;
+ state.canpause = ptr->CanPause();
+ state.canseek = ptr->CanSeek();
}
}
@@ -3947,15 +4028,13 @@ void COMXPlayer::UpdatePlayState(double timeout)
state.time_total = m_Edl.RemoveCutTime(llrint(state.time_total));
}
- state.player_state = "";
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
+ if(state.time_total <= 0)
+ state.canseek = false;
+
+ if (state.time_src == ETIMESOURCE_CLOCK)
+ state.time_offset = m_offset_pts;
+ else if (state.dts != DVD_NOPTS_VALUE)
state.time_offset = DVD_MSEC_TO_TIME(state.time) - state.dts;
- if(!((CDVDInputStreamNavigator*)m_pInputStream)->GetNavigatorState(state.player_state))
- state.player_state = "";
- }
- else
- state.time_offset = 0;
if (m_CurrentAudio.id >= 0 && m_pDemuxer)
{
@@ -4002,7 +4081,7 @@ void COMXPlayer::UpdatePlayState(double timeout)
state.timestamp = m_av_clock.GetAbsoluteClock();
CSingleLock lock(m_StateSection);
- m_State = state;
+ m_StateInput = state;
}
void COMXPlayer::UpdateApplication(double timeout)
@@ -4073,11 +4152,21 @@ bool COMXPlayer::GetStreamDetails(CStreamDetails &details)
{
if (m_pDemuxer)
{
- bool result=CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, details);
+ bool result = CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, details);
if (result && details.GetStreamCount(CStreamDetail::VIDEO) > 0) // this is more correct (dvds in particular)
{
- ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_fAspect = g_renderManager.GetAspectRatio();
- ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_iDuration = GetTotalTime() / 1000;
+ /*
+ * We can only obtain the aspect & duration from dvdplayer when the Process() thread is running
+ * and UpdatePlayState() has been called at least once. In this case dvdplayer duration/AR will
+ * return 0 and we'll have to fallback to the (less accurate) info from the demuxer.
+ */
+ float aspect = m_player_video.GetAspectRatio();
+ if (aspect > 0.0f)
+ ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_fAspect = aspect;
+
+ int64_t duration = GetTotalTime() / 1000;
+ if (duration > 0)
+ ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_iDuration = duration;
}
return result;
}
22 xbmc/cores/omxplayer/OMXPlayer.h
View
@@ -74,6 +74,7 @@ class COMXCurrentStream
int source;
double dts; // last dts from demuxer, used to find disncontinuities
double dur; // last frame expected duration
+ double dts_state; // when did we last send a playback state update
CDVDStreamInfo hint; // stream hints, used to notice stream changes
void* stream; // pointer or integer, identifying stream playing. if it changes stream changed
int changes; // remembered counter from stream to track codec changes
@@ -96,6 +97,7 @@ class COMXCurrentStream
id = -1;
source = STREAM_SOURCE_NONE;
dts = DVD_NOPTS_VALUE;
+ dts_state = DVD_NOPTS_VALUE;
dur = DVD_NOPTS_VALUE;
hint.Clear();
stream = NULL;
@@ -366,15 +368,27 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
} m_dvd;
+ enum ETimeSource
+ {
+ ETIMESOURCE_CLOCK,
+ ETIMESOURCE_INPUT,
+ ETIMESOURCE_MENU,
+ };
+
+ friend class OMXPlayerVideo;
+ friend class OMXPlayerAudio;
+
struct SPlayerState
{
SPlayerState() { Clear(); }
void Clear()
{
+ player = 0;
timestamp = 0;
time = 0;
time_total = 0;
time_offset = 0;
+ time_src = ETIMESOURCE_CLOCK;
dts = DVD_NOPTS_VALUE;
player_state = "";
chapter = 0;
@@ -392,11 +406,14 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
cache_offset = 0.0;
}
+ int player; // source of this data
+
double timestamp; // last time of update
double time_offset; // difference between time and pts
double time; // current playback time
double time_total; // total playback time
+ ETimeSource time_src; // current time source
double dts; // last known dts
std::string player_state; // full player state
@@ -418,7 +435,7 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
double cache_level; // current estimated required cache level
double cache_delay; // time until cache is expected to reach estimated level
double cache_offset; // percentage of file ahead of current position
- } m_State;
+ } m_State, m_StateInput;
CCriticalSection m_StateSection;
CEdl m_Edl;
@@ -481,4 +498,7 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
bool m_change_volume;
CDVDOverlayContainer m_overlayContainer;
ECacheState m_caching;
+
+ bool m_HasVideo;
+ bool m_HasAudio;
};
12 xbmc/cores/omxplayer/OMXPlayerAudio.cpp
View
@@ -569,6 +569,18 @@ void OMXPlayerAudio::Process()
if(m_started)
m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_AUDIO));
}
+ else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
+ {
+ COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
+
+ if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
+ state.time = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime(true, true));
+ //state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
+ else
+ state.timestamp = m_av_clock->GetAbsoluteClock();
+ state.player = DVDPLAYER_AUDIO;
+ m_messageParent.Put(pMsg->Acquire());
+ }
else if (pMsg->IsType(CDVDMsg::GENERAL_EOF))
{
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_EOF");
13 xbmc/cores/omxplayer/OMXPlayerVideo.cpp
View
@@ -42,6 +42,7 @@
#include "DVDOverlayRenderer.h"
#include "settings/GUISettings.h"
#include "settings/Settings.h"
+#include "settings/MediaSettings.h"
#include "cores/VideoRenderers/RenderFormats.h"
#include "cores/VideoRenderers/RenderFlags.h"
@@ -490,6 +491,18 @@ void OMXPlayerVideo::Process()
if(m_started)
m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
}
+ else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
+ {
+ COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
+
+ if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
+ state.time = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime(true, true));
+ //state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
+ else
+ state.timestamp = m_av_clock->GetAbsoluteClock();
+ state.player = DVDPLAYER_VIDEO;
+ m_messageParent.Put(pMsg->Acquire());
+ }
else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
{
COMXMsgVideoCodecChange* msg(static_cast<COMXMsgVideoCodecChange*>(pMsg));
2  xbmc/cores/omxplayer/OMXPlayerVideo.h
View
@@ -38,6 +38,7 @@
#include "DVDMessageQueue.h"
#include "utils/BitstreamStats.h"
#include "linux/DllBCM.h"
+#include "cores/VideoRenderers/RenderManager.h"
using namespace std;
@@ -125,6 +126,7 @@ class OMXPlayerVideo : public CThread
void EnableSubtitle(bool bEnable) { m_bRenderSubs = bEnable; }
bool IsSubtitleEnabled() { return m_bRenderSubs; }
void EnableFullscreen(bool bEnable) { m_bAllowFullscreen = bEnable; }
+ float GetAspectRatio() { return g_renderManager.GetAspectRatio(); }
void SetFlags(unsigned flags) { m_flags = flags; };
int GetFreeSpace();
void SetVideoRect(const CRect &SrcRect, const CRect &DestRect);
Please sign in to comment.
Something went wrong with that request. Please try again.