aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2014-09-04 04:42:52 +0200
committerRainer Hochecker <fernetmenta@online.de>2014-09-04 04:42:52 +0200
commit661706dc4a27b223d14bc463e5e71489d598b477 (patch)
tree8ec73624b6b4be405a3324db9afb55a5f105a43c
parentd3f48dd9128debf6a3b5b1749292ef19cdc37bbf (diff)
parent2d110347201448110782659b60586212801aeab4 (diff)
Merge pull request #5084 from popcornmix/dvdrefactor
[players] Make omxplayer be derived from dvdplayer [RFC]
-rwxr-xr-xlanguage/English/strings.po13
-rw-r--r--system/settings/settings.xml9
-rw-r--r--xbmc/ApplicationPlayer.cpp25
-rw-r--r--xbmc/ApplicationPlayer.h3
-rw-r--r--xbmc/addons/Visualisation.cpp2
-rw-r--r--xbmc/cores/DummyVideoPlayer.h2
-rw-r--r--xbmc/cores/ExternalPlayer/ExternalPlayer.h2
-rw-r--r--xbmc/cores/IPlayer.h12
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.cpp20
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.h5
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.cpp605
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.h79
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.h8
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.h4
-rw-r--r--xbmc/cores/dvdplayer/IDVDPlayer.h80
-rw-r--r--xbmc/cores/omxplayer/Makefile.in3
-rw-r--r--xbmc/cores/omxplayer/OMXAudio.cpp20
-rw-r--r--xbmc/cores/omxplayer/OMXAudio.h4
-rw-r--r--xbmc/cores/omxplayer/OMXPlayer.cpp4432
-rw-r--r--xbmc/cores/omxplayer/OMXPlayer.h508
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerAudio.cpp38
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerAudio.h6
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerVideo.cpp33
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerVideo.h4
-rw-r--r--xbmc/cores/omxplayer/OMXVideo.cpp5
-rw-r--r--xbmc/cores/omxplayer/OMXVideo.h2
-rw-r--r--xbmc/cores/omxplayer/omxplayer_advancedsettings.xml4
-rw-r--r--xbmc/cores/playercorefactory/PlayerCoreConfig.h14
-rw-r--r--xbmc/cores/playercorefactory/PlayerCoreFactory.cpp7
-rw-r--r--xbmc/cores/playercorefactory/PlayerCoreFactory.h6
-rw-r--r--xbmc/linux/OMXClock.cpp24
-rw-r--r--xbmc/linux/OMXClock.h1
-rw-r--r--xbmc/settings/SettingConditions.cpp3
33 files changed, 729 insertions, 5254 deletions
diff --git a/language/English/strings.po b/language/English/strings.po
index 1ff8f1313a..fea6e0837b 100755
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -6196,7 +6196,18 @@ msgctxt "#13457"
msgid "Prefer VAAPI render method"
msgstr ""
-#empty strings from id 13458 to 13499
+#: system/settings/settings.xml
+msgctxt "#13458"
+msgid "Allow hardware acceleration (OMXPlayer)"
+msgstr ""
+
+#. Description of setting "Videos -> Playback -> Allow hardware acceleration (OMXPlayer)" with label #13457
+#: system/settings/settings.xml
+msgctxt "#13459"
+msgid "Use OMXPlayer for decoding of video files."
+msgstr ""
+
+#empty strings from id 13460 to 13499
#: system/settings/settings.xml
msgctxt "#13500"
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
index f604b30e3c..af05fb7ddc 100644
--- a/system/settings/settings.xml
+++ b/system/settings/settings.xml
@@ -752,6 +752,15 @@
<default>true</default>
<control type="toggle" />
</setting>
+ <setting id="videoplayer.useomxplayer" type="boolean" label="13458" help="13459">
+ <requirement>HAS_OMXPLAYER</requirement>
+ <dependencies>
+ <dependency type="enable" setting="videoplayer.decodingmethod" operator="is">1</dependency>
+ </dependencies>
+ <level>2</level>
+ <default>true</default>
+ <control type="toggle" />
+ </setting>
<setting id="videoplayer.useomx" type="boolean" label="13430" help="36161">
<requirement>HAVE_LIBOPENMAX</requirement>
<dependencies>
diff --git a/xbmc/ApplicationPlayer.cpp b/xbmc/ApplicationPlayer.cpp
index fcf3dc3653..6981d24780 100644
--- a/xbmc/ApplicationPlayer.cpp
+++ b/xbmc/ApplicationPlayer.cpp
@@ -64,9 +64,6 @@ void CApplicationPlayer::ClosePlayerGapless(PLAYERCOREID newCore)
return;
bool gaplessSupported = (m_eCurrentPlayer == EPC_DVDPLAYER || m_eCurrentPlayer == EPC_PAPLAYER);
-#if defined(HAS_OMXPLAYER)
- gaplessSupported = gaplessSupported || (m_eCurrentPlayer == EPC_OMXPLAYER);
-#endif
gaplessSupported = gaplessSupported && (m_eCurrentPlayer == newCore);
if (!gaplessSupported)
{
@@ -116,20 +113,6 @@ bool CApplicationPlayer::HasPlayer() const
return player != NULL;
}
-void CApplicationPlayer::RegisterAudioCallback(IAudioCallback* pCallback)
-{
- boost::shared_ptr<IPlayer> player = GetInternal();
- if (player)
- player->RegisterAudioCallback(pCallback);
-}
-
-void CApplicationPlayer::UnRegisterAudioCallback()
-{
- boost::shared_ptr<IPlayer> player = GetInternal();
- if (player)
- player->UnRegisterAudioCallback();
-}
-
int CApplicationPlayer::GetChapter()
{
boost::shared_ptr<IPlayer> player = GetInternal();
@@ -621,28 +604,28 @@ void CApplicationPlayer::GetRenderFeatures(std::vector<int> &renderFeatures)
{
boost::shared_ptr<IPlayer> player = GetInternal();
if (player)
- player->GetRenderFeatures(renderFeatures);
+ player->OMXGetRenderFeatures(renderFeatures);
}
void CApplicationPlayer::GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods)
{
boost::shared_ptr<IPlayer> player = GetInternal();
if (player)
- player->GetDeinterlaceMethods(deinterlaceMethods);
+ player->OMXGetDeinterlaceMethods(deinterlaceMethods);
}
void CApplicationPlayer::GetDeinterlaceModes(std::vector<int> &deinterlaceModes)
{
boost::shared_ptr<IPlayer> player = GetInternal();
if (player)
- player->GetDeinterlaceModes(deinterlaceModes);
+ player->OMXGetDeinterlaceModes(deinterlaceModes);
}
void CApplicationPlayer::GetScalingMethods(std::vector<int> &scalingMethods)
{
boost::shared_ptr<IPlayer> player = GetInternal();
if (player)
- player->GetScalingMethods(scalingMethods);
+ player->OMXGetScalingMethods(scalingMethods);
}
void CApplicationPlayer::SetPlaySpeed(int iSpeed, bool bApplicationMuted)
diff --git a/xbmc/ApplicationPlayer.h b/xbmc/ApplicationPlayer.h
index 964570c251..8abcd46ec7 100644
--- a/xbmc/ApplicationPlayer.h
+++ b/xbmc/ApplicationPlayer.h
@@ -37,7 +37,6 @@ namespace PVR
class CPVRChannel;
}
-class IAudioCallback;
class CAction;
class CPlayerOptions;
class CStreamDetails;
@@ -133,7 +132,6 @@ public:
void Pause();
bool QueueNextFile(const CFileItem &file);
bool Record(bool bOnOff);
- void RegisterAudioCallback(IAudioCallback* pCallback);
void Seek(bool bPlus = true, bool bLargeStep = false, bool bChapterOverride = false);
int SeekChapter(int iChapter);
void SeekPercentage(float fPercent = 0);
@@ -150,5 +148,4 @@ public:
void SetVolume(float volume);
bool SwitchChannel(const PVR::CPVRChannel &channel);
void ToFFRW(int iSpeed = 0);
- void UnRegisterAudioCallback();
};
diff --git a/xbmc/addons/Visualisation.cpp b/xbmc/addons/Visualisation.cpp
index 9412963a78..810e5b2ff2 100644
--- a/xbmc/addons/Visualisation.cpp
+++ b/xbmc/addons/Visualisation.cpp
@@ -109,7 +109,6 @@ bool CVisualisation::Create(int x, int y, int w, int h, void *device)
CreateBuffers();
- g_application.m_pPlayer->RegisterAudioCallback(this);
CAEFactory::RegisterAudioCallback(this);
return true;
@@ -174,7 +173,6 @@ void CVisualisation::Render()
void CVisualisation::Stop()
{
- g_application.m_pPlayer->UnRegisterAudioCallback();
CAEFactory::UnregisterAudioCallback();
if (Initialized())
{
diff --git a/xbmc/cores/DummyVideoPlayer.h b/xbmc/cores/DummyVideoPlayer.h
index 85cb90edab..5bc12fd617 100644
--- a/xbmc/cores/DummyVideoPlayer.h
+++ b/xbmc/cores/DummyVideoPlayer.h
@@ -28,8 +28,6 @@ class CDummyVideoPlayer : public IPlayer, public CThread
public:
CDummyVideoPlayer(IPlayerCallback& callback);
virtual ~CDummyVideoPlayer();
- virtual void RegisterAudioCallback(IAudioCallback* pCallback) {}
- virtual void UnRegisterAudioCallback() {}
virtual bool OpenFile(const CFileItem& file, const CPlayerOptions &options);
virtual bool CloseFile();
virtual bool IsPlaying() const;
diff --git a/xbmc/cores/ExternalPlayer/ExternalPlayer.h b/xbmc/cores/ExternalPlayer/ExternalPlayer.h
index 66f1cbfa56..06ebf92c44 100644
--- a/xbmc/cores/ExternalPlayer/ExternalPlayer.h
+++ b/xbmc/cores/ExternalPlayer/ExternalPlayer.h
@@ -35,8 +35,6 @@ public:
CExternalPlayer(IPlayerCallback& callback);
virtual ~CExternalPlayer();
virtual bool Initialize(TiXmlElement* pConfig);
- virtual void RegisterAudioCallback(IAudioCallback* pCallback) {}
- virtual void UnRegisterAudioCallback() {}
virtual bool OpenFile(const CFileItem& file, const CPlayerOptions &options);
virtual bool CloseFile(bool reopen = false);
virtual bool IsPlaying() const;
diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h
index 26489cbe81..a72c219c22 100644
--- a/xbmc/cores/IPlayer.h
+++ b/xbmc/cores/IPlayer.h
@@ -128,8 +128,6 @@ public:
IPlayer(IPlayerCallback& callback): m_callback(callback){};
virtual ~IPlayer(){};
virtual bool Initialize(TiXmlElement* pConfig) { return true; };
- virtual void RegisterAudioCallback(IAudioCallback* pCallback) {};
- virtual void UnRegisterAudioCallback() {};
virtual bool OpenFile(const CFileItem& file, const CPlayerOptions& options){ return false;}
virtual bool QueueNextFile(const CFileItem &file) { return false; }
virtual void OnNothingToQueueNotify() {}
@@ -221,22 +219,24 @@ public:
virtual bool SwitchChannel(const PVR::CPVRChannel &channel) { return false; }
+ // Note: the following "OMX" methods are deprecated and will be removed in the future
+ // They should be handled by the video renderer, not the player
/*!
\brief If the player uses bypass mode, define its rendering capabilities
*/
- virtual void GetRenderFeatures(std::vector<int> &renderFeatures) {};
+ virtual void OMXGetRenderFeatures(std::vector<int> &renderFeatures) {};
/*!
\brief If the player uses bypass mode, define its deinterlace algorithms
*/
- virtual void GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods) {};
+ virtual void OMXGetDeinterlaceMethods(std::vector<int> &deinterlaceMethods) {};
/*!
\brief If the player uses bypass mode, define how deinterlace is set
*/
- virtual void GetDeinterlaceModes(std::vector<int> &deinterlaceModes) {};
+ virtual void OMXGetDeinterlaceModes(std::vector<int> &deinterlaceModes) {};
/*!
\brief If the player uses bypass mode, define its scaling capabilities
*/
- virtual void GetScalingMethods(std::vector<int> &scalingMethods) {};
+ virtual void OMXGetScalingMethods(std::vector<int> &scalingMethods) {};
/*!
\brief define the audio capabilities of the player (default=all)
*/
diff --git a/xbmc/cores/dvdplayer/DVDAudio.cpp b/xbmc/cores/dvdplayer/DVDAudio.cpp
index 46e9509b6b..6514030357 100644
--- a/xbmc/cores/dvdplayer/DVDAudio.cpp
+++ b/xbmc/cores/dvdplayer/DVDAudio.cpp
@@ -95,7 +95,6 @@ CDVDAudio::CDVDAudio(volatile bool &bStop)
: m_bStop(bStop)
{
m_pAudioStream = NULL;
- m_pAudioCallback = NULL;
m_bPassthrough = false;
m_iBitsPerSample = 0;
m_iBitrate = 0;
@@ -146,9 +145,6 @@ bool CDVDAudio::Create(const DVDAudioFrame &audioframe, AVCodecID codec, bool ne
SetDynamicRangeCompression((long)(CMediaSettings::Get().GetCurrentVideoSettings().m_VolumeAmplification * 100));
- if (m_pAudioCallback)
- RegisterAudioCallback(m_pAudioCallback);
-
return true;
}
@@ -225,22 +221,6 @@ void CDVDAudio::Drain()
m_pAudioStream->Drain(true);
}
-void CDVDAudio::RegisterAudioCallback(IAudioCallback* pCallback)
-{
- CSingleLock lock (m_critSection);
- m_pAudioCallback = pCallback;
- if (m_pAudioStream)
- m_pAudioStream->RegisterAudioCallback(pCallback);
-}
-
-void CDVDAudio::UnRegisterAudioCallback()
-{
- CSingleLock lock (m_critSection);
- if (m_pAudioStream)
- m_pAudioStream->UnRegisterAudioCallback();
- m_pAudioCallback = NULL;
-}
-
void CDVDAudio::SetVolume(float volume)
{
CSingleLock lock (m_critSection);
diff --git a/xbmc/cores/dvdplayer/DVDAudio.h b/xbmc/cores/dvdplayer/DVDAudio.h
index 54c34e5d93..629fb3237e 100644
--- a/xbmc/cores/dvdplayer/DVDAudio.h
+++ b/xbmc/cores/dvdplayer/DVDAudio.h
@@ -52,7 +52,6 @@ public:
};
class CSingleLock;
-class IAudioCallback;
class CDVDAudio
{
@@ -60,9 +59,6 @@ public:
CDVDAudio(volatile bool& bStop);
~CDVDAudio();
- void RegisterAudioCallback(IAudioCallback* pCallback);
- void UnRegisterAudioCallback();
-
void SetVolume(float fVolume);
void SetDynamicRangeCompression(long drc);
float GetCurrentAttenuation();
@@ -97,7 +93,6 @@ protected:
bool m_bPaused;
volatile bool& m_bStop;
- IAudioCallback* m_pAudioCallback; //the viz audio callback
//counter that will go from 0 to m_iSpeed-1 and reset, data will only be output when speedstep is 0
//int m_iSpeedStep;
};
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
index 39951a3110..8f41c763fc 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -85,6 +85,11 @@
#include "utils/LangCodeExpander.h"
#include "video/VideoReferenceClock.h"
+#ifdef HAS_OMXPLAYER
+#include "cores/omxplayer/OMXPlayerAudio.h"
+#include "cores/omxplayer/OMXPlayerVideo.h"
+#endif
+
using namespace std;
using namespace PVR;
@@ -483,6 +488,39 @@ void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer)
}
}
+void CDVDPlayer::CreatePlayers()
+{
+ if (m_players_created)
+ return;
+
+ if (m_omxplayer_mode)
+ {
+#ifdef HAS_OMXPLAYER
+ m_dvdPlayerVideo = new OMXPlayerVideo(&m_OmxPlayerState.av_clock, &m_overlayContainer, m_messenger);
+ m_dvdPlayerAudio = new OMXPlayerAudio(&m_OmxPlayerState.av_clock, m_messenger);
+#endif
+ }
+ else
+ {
+ m_dvdPlayerVideo = new CDVDPlayerVideo(&m_clock, &m_overlayContainer, m_messenger);
+ m_dvdPlayerAudio = new CDVDPlayerAudio(&m_clock, m_messenger);
+ }
+ m_dvdPlayerSubtitle = new CDVDPlayerSubtitle(&m_overlayContainer);
+ m_dvdPlayerTeletext = new CDVDTeletextData();
+ m_players_created = true;
+}
+
+void CDVDPlayer::DestroyPlayers()
+{
+ if (!m_players_created)
+ return;
+ delete m_dvdPlayerVideo;
+ delete m_dvdPlayerAudio;
+ delete m_dvdPlayerSubtitle;
+ delete m_dvdPlayerTeletext;
+ m_players_created = false;
+}
+
CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
: IPlayer(callback),
CThread("DVDPlayer"),
@@ -491,13 +529,10 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
m_CurrentSubtitle(STREAM_SUBTITLE, DVDPLAYER_SUBTITLE),
m_CurrentTeletext(STREAM_TELETEXT, DVDPLAYER_TELETEXT),
m_messenger("player"),
- m_dvdPlayerVideo(&m_clock, &m_overlayContainer, m_messenger),
- m_dvdPlayerAudio(&m_clock, m_messenger),
- m_dvdPlayerSubtitle(&m_overlayContainer),
- m_dvdPlayerTeletext(),
m_ready(true),
m_DemuxerPausePending(false)
{
+ m_players_created = false;
m_pDemuxer = NULL;
m_pSubtitleDemuxer = NULL;
m_pInputStream = NULL;
@@ -516,11 +551,30 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
m_HasAudio = false;
memset(&m_SpeedState, 0, sizeof(m_SpeedState));
+
+ // omxplayer variables
+ m_OmxPlayerState.video_fifo = 0;
+ m_OmxPlayerState.audio_fifo = 0;
+ m_OmxPlayerState.last_check_time = 0.0;
+ m_OmxPlayerState.stamp = 0.0;
+ m_OmxPlayerState.bOmxWaitVideo = false;
+ m_OmxPlayerState.bOmxWaitAudio = false;
+ m_OmxPlayerState.bOmxSentEOFs = false;
+ m_OmxPlayerState.threshold = 0.2f;
+ m_OmxPlayerState.current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
+#ifdef HAS_OMXPLAYER
+ m_omxplayer_mode = CSettings::Get().GetBool("videoplayer.useomxplayer");
+#else
+ m_omxplayer_mode = false;
+#endif
+
+ CreatePlayers();
}
CDVDPlayer::~CDVDPlayer()
{
CloseFile();
+ DestroyPlayers();
}
bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
@@ -812,7 +866,7 @@ bool CDVDPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
{
// check if we should read from subtitle demuxer
- if( m_pSubtitleDemuxer && m_dvdPlayerSubtitle.AcceptsData() )
+ if( m_pSubtitleDemuxer && m_dvdPlayerSubtitle->AcceptsData() )
{
packet = m_pSubtitleDemuxer->Read();
@@ -837,6 +891,16 @@ bool CDVDPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
}
}
+ if (m_omxplayer_mode)
+ {
+ // reset eos state when we get a packet (e.g. for case of seek after eos)
+ if (packet && stream)
+ {
+ m_OmxPlayerState.bOmxWaitVideo = false;
+ m_OmxPlayerState.bOmxWaitAudio = false;
+ m_OmxPlayerState.bOmxSentEOFs = false;
+ }
+ }
// read a data frame from stream.
if(m_pDemuxer)
packet = m_pDemuxer->Read();
@@ -982,6 +1046,120 @@ void CDVDPlayer::CheckBetterStream(CCurrentStream& current, CDemuxStream* stream
OpenStream(current, stream->iId, stream->source);
}
+void CDVDPlayer::OMXDoProcessing()
+{
+#ifdef HAS_OMXPLAYER
+ double now = CDVDClock::GetAbsoluteClock();
+ if (m_OmxPlayerState.last_check_time == 0.0 || m_OmxPlayerState.last_check_time + DVD_MSEC_TO_TIME(20) <= now)
+ {
+ m_OmxPlayerState.last_check_time = now;
+ m_OmxPlayerState.stamp = m_OmxPlayerState.av_clock.OMXMediaTime();
+ const bool m_Pause = m_playSpeed == DVD_PLAYSPEED_PAUSE;
+ const bool not_accepts_data = (!m_dvdPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||
+ (!m_dvdPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0);
+ /* when the video/audio fifos are low, we pause clock, when high we resume */
+ double audio_pts = floor(m_dvdPlayerAudio->GetCurrentPts());
+ double video_pts = floor(m_dvdPlayerVideo->GetCurrentPts());
+
+ float audio_fifo = audio_pts / DVD_TIME_BASE - m_OmxPlayerState.stamp * 1e-6;
+ float video_fifo = video_pts / DVD_TIME_BASE - m_OmxPlayerState.stamp * 1e-6;
+ float threshold = 0.1f;
+ bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false;
+
+ // if deinterlace setting has changed, we should close and open video
+ if (m_OmxPlayerState.current_deinterlace != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode)
+ {
+ CloseStream(m_CurrentVideo, false);
+ OpenStream(m_CurrentVideo, m_CurrentVideo.id, m_CurrentVideo.source);
+ if (m_State.canseek)
+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
+ m_OmxPlayerState.current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
+ }
+
+ m_OmxPlayerState.video_fifo = (int)(100.0*(m_dvdPlayerVideo->GetDecoderBufferSize()-m_dvdPlayerVideo->GetDecoderFreeSpace())/m_dvdPlayerVideo->GetDecoderBufferSize());
+ m_OmxPlayerState.audio_fifo = (int)(100.0*audio_fifo/m_dvdPlayerAudio->GetCacheTotal());
+
+ #ifdef _DEBUG
+ static unsigned count;
+ if ((count++ & 7) == 0)
+ {
+ char response[80];
+ if (m_dvdPlayerVideo->GetDecoderBufferSize() && m_dvdPlayerAudio->GetCacheTotal())
+ vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d",
+ m_OmxPlayerState.video_fifo,
+ (int)(100.0*video_fifo/m_dvdPlayerAudio->GetCacheTotal()),
+ 0, 100);
+ if (m_dvdPlayerAudio->GetCacheTotal())
+ vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d",
+ m_OmxPlayerState.audio_fifo,
+ (int)(100.0*m_dvdPlayerAudio->GetDelay()/m_dvdPlayerAudio->GetCacheTotal()),
+ 0, 100);
+ vc_gencmd(response, sizeof response, "render_bar 6 video_queue %d %d %d %d",
+ m_dvdPlayerVideo->GetLevel(), 0, 0, 100);
+ vc_gencmd(response, sizeof response, "render_bar 7 audio_queue %d %d %d %d",
+ m_dvdPlayerAudio->GetLevel(), 0, 0, 100);
+ }
+ #endif
+ if (audio_pts != DVD_NOPTS_VALUE)
+ {
+ audio_fifo_low = m_HasAudio && audio_fifo < threshold;
+ audio_fifo_high = audio_pts != DVD_NOPTS_VALUE && audio_fifo >= m_OmxPlayerState.threshold;
+ }
+ if (video_pts != DVD_NOPTS_VALUE)
+ {
+ video_fifo_low = m_HasVideo && video_fifo < threshold;
+ video_fifo_high = video_pts != DVD_NOPTS_VALUE && video_fifo >= m_OmxPlayerState.threshold;
+ }
+ if (!m_HasAudio && m_HasVideo)
+ audio_fifo_high = true;
+ if (!m_HasVideo && m_HasAudio)
+ video_fifo_high = true;
+
+ #ifdef _DEBUG
+ CLog::Log(LOGDEBUG, "%s::%s M:%.6f-%.6f (A:%.6f V:%.6f) PEF:%d%d%d S:%.2f A:%.2f V:%.2f/T:%.2f (A:%d%d V:%d%d) A:%d%% V:%d%% (%.2f,%.2f)", "CDVDPlayer", __FUNCTION__,
+ m_OmxPlayerState.stamp*1e-6, m_OmxPlayerState.av_clock.OMXClockAdjustment()*1e-6, audio_pts*1e-6, video_pts*1e-6, m_OmxPlayerState.av_clock.OMXIsPaused(), m_OmxPlayerState.bOmxSentEOFs, not_accepts_data, m_playSpeed * (1.0f/DVD_PLAYSPEED_NORMAL),
+ audio_pts == DVD_NOPTS_VALUE ? 0.0:audio_fifo, video_pts == DVD_NOPTS_VALUE ? 0.0:video_fifo, m_OmxPlayerState.threshold,
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high,
+ m_dvdPlayerAudio->GetLevel(), m_dvdPlayerVideo->GetLevel(), m_dvdPlayerAudio->GetDelay(), (float)m_dvdPlayerAudio->GetCacheTotal());
+ #endif
+
+ if(!m_Pause && (m_OmxPlayerState.bOmxSentEOFs || not_accepts_data || (audio_fifo_high && video_fifo_high) || m_playSpeed != DVD_PLAYSPEED_NORMAL))
+ {
+ if (m_OmxPlayerState.av_clock.OMXIsPaused())
+ {
+ CLog::Log(LOGDEBUG, "%s::%s Resume %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f", "CDVDPlayer", __FUNCTION__, audio_fifo, video_fifo,
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, m_OmxPlayerState.bOmxSentEOFs, not_accepts_data, m_OmxPlayerState.threshold);
+ m_OmxPlayerState.av_clock.OMXResume();
+ }
+ }
+ else if ((m_Pause || audio_fifo_low || video_fifo_low) && m_playSpeed == DVD_PLAYSPEED_NORMAL)
+ {
+ if (!m_OmxPlayerState.av_clock.OMXIsPaused())
+ {
+ if (!m_Pause)
+ m_OmxPlayerState.threshold = std::min(2.0f*m_OmxPlayerState.threshold, 16.0f);
+ CLog::Log(LOGDEBUG, "%s::%s Pause %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f", "CDVDPlayer", __FUNCTION__, audio_fifo, video_fifo,
+ audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, m_OmxPlayerState.bOmxSentEOFs, not_accepts_data, m_OmxPlayerState.threshold);
+ m_OmxPlayerState.av_clock.OMXPause();
+ }
+ }
+ }
+#endif
+}
+
+bool CDVDPlayer::OMXStillPlaying()
+{
+ if (m_omxplayer_mode)
+ {
+ // wait for omx components to finish
+ if(m_OmxPlayerState.bOmxWaitVideo && !m_dvdPlayerVideo->IsEOS())
+ return true;
+ if(m_OmxPlayerState.bOmxWaitAudio && !m_dvdPlayerAudio->IsEOS())
+ return true;
+ }
+ return false;
+}
+
void CDVDPlayer::Process()
{
if (!OpenInputStream())
@@ -1011,7 +1189,19 @@ void CDVDPlayer::Process()
}
// allow renderer to switch to fullscreen if requested
- m_dvdPlayerVideo.EnableFullscreen(m_PlayerOptions.fullscreen);
+ m_dvdPlayerVideo->EnableFullscreen(m_PlayerOptions.fullscreen);
+
+ if (m_omxplayer_mode)
+ {
+ if (!m_OmxPlayerState.av_clock.OMXInitialize(&m_clock))
+ m_bAbortRequest = true;
+ if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") != ADJUST_REFRESHRATE_OFF)
+ m_OmxPlayerState.av_clock.HDMIClockSync();
+ m_OmxPlayerState.av_clock.OMXStateIdle();
+ m_OmxPlayerState.av_clock.OMXStateExecute();
+ m_OmxPlayerState.av_clock.OMXStop();
+ m_OmxPlayerState.av_clock.OMXPause();
+ }
OpenDefaultStreams();
@@ -1099,6 +1289,9 @@ void CDVDPlayer::Process()
while (!m_bAbortRequest)
{
+ if (m_omxplayer_mode)
+ OMXDoProcessing();
+
// handle messages send to this thread, like seek or demuxer reset requests
HandleMessages();
@@ -1133,8 +1326,8 @@ void CDVDPlayer::Process()
OpenDefaultStreams();
// never allow first frames after open to be skipped
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
+ if( m_dvdPlayerVideo->IsInited() )
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
if (CachePVRStream())
SetCaching(CACHESTATE_PVR);
@@ -1153,14 +1346,14 @@ void CDVDPlayer::Process()
UpdateApplication(1000);
// make sure we run subtitle process here
- m_dvdPlayerSubtitle.Process(m_clock.GetClock() + m_State.time_offset - m_dvdPlayerVideo.GetSubtitleDelay(), m_State.time_offset);
+ m_dvdPlayerSubtitle->Process(m_clock.GetClock() + m_State.time_offset - m_dvdPlayerVideo->GetSubtitleDelay(), m_State.time_offset);
if (CheckDelayedChannelEntry())
continue;
// if the queues are full, no need to read more
- if ((!m_dvdPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0) ||
- (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0))
+ if ((!m_dvdPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||
+ (!m_dvdPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))
{
if(m_pDemuxer && m_DemuxerPausePending)
{
@@ -1173,8 +1366,8 @@ void CDVDPlayer::Process()
}
// always yield to players if they have data levels > 50 percent
- if((m_dvdPlayerAudio.GetLevel() > 50 || m_CurrentAudio.id < 0)
- && (m_dvdPlayerVideo.GetLevel() > 50 || m_CurrentVideo.id < 0))
+ if((m_dvdPlayerAudio->GetLevel() > 50 || m_CurrentAudio.id < 0)
+ && (m_dvdPlayerVideo->GetLevel() > 50 || m_CurrentVideo.id < 0))
Sleep(0);
DemuxPacket* pPacket = NULL;
@@ -1232,14 +1425,24 @@ void CDVDPlayer::Process()
}
// make sure we tell all players to finish it's data
+ if (m_omxplayer_mode && !m_OmxPlayerState.bOmxSentEOFs)
+ {
+ if(m_CurrentAudio.inited)
+ m_OmxPlayerState.bOmxWaitAudio = true;
+
+ if(m_CurrentVideo.inited)
+ m_OmxPlayerState.bOmxWaitVideo = true;
+
+ m_OmxPlayerState.bOmxSentEOFs = true;
+ }
if(m_CurrentAudio.inited)
- m_dvdPlayerAudio.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
+ m_dvdPlayerAudio->SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
if(m_CurrentVideo.inited)
- m_dvdPlayerVideo.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
+ m_dvdPlayerVideo->SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
if(m_CurrentSubtitle.inited)
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
+ m_dvdPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
if(m_CurrentTeletext.inited)
- m_dvdPlayerTeletext.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
+ m_dvdPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
m_CurrentAudio.inited = false;
m_CurrentVideo.inited = false;
m_CurrentSubtitle.inited = false;
@@ -1249,8 +1452,9 @@ void CDVDPlayer::Process()
SetCaching(CACHESTATE_DONE);
// while players are still playing, keep going to allow seekbacks
- if(m_dvdPlayerAudio.HasData()
- || m_dvdPlayerVideo.HasData())
+ if(m_dvdPlayerAudio->HasData()
+ || m_dvdPlayerVideo->HasData()
+ || OMXStillPlaying())
{
Sleep(100);
continue;
@@ -1372,17 +1576,17 @@ void CDVDPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE // Inside EDL mute
&& !m_EdlAutoSkipMarkers.mute) // Mute not already triggered
{
- m_dvdPlayerAudio.SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, true));
+ m_dvdPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, true));
m_EdlAutoSkipMarkers.mute = true;
}
else if (!m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) // Outside of any EDL
&& m_EdlAutoSkipMarkers.mute) // But the mute hasn't been removed yet
{
- m_dvdPlayerAudio.SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, false));
+ m_dvdPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, false));
m_EdlAutoSkipMarkers.mute = false;
}
- m_dvdPlayerAudio.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
+ m_dvdPlayerAudio->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
}
void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
@@ -1405,7 +1609,7 @@ void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
if (CheckSceneSkip(m_CurrentVideo))
drop = true;
- m_dvdPlayerVideo.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
+ m_dvdPlayerVideo->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
}
void CDVDPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket)
@@ -1421,10 +1625,10 @@ void CDVDPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket)
if (CheckSceneSkip(m_CurrentSubtitle))
drop = true;
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
+ m_dvdPlayerSubtitle->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
if(m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
+ m_dvdPlayerSubtitle->UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
}
void CDVDPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket)
@@ -1440,7 +1644,7 @@ void CDVDPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket
if (CheckSceneSkip(m_CurrentTeletext))
drop = true;
- m_dvdPlayerTeletext.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
+ m_dvdPlayerTeletext->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
}
bool CDVDPlayer::GetCachingTimes(double& level, double& delay, double& offset)
@@ -1510,8 +1714,8 @@ void CDVDPlayer::HandlePlaySpeed()
}
else
{
- if ((!m_dvdPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0)
- || (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0))
+ if ((!m_dvdPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0)
+ || (!m_dvdPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))
caching = CACHESTATE_INIT;
}
}
@@ -1526,8 +1730,8 @@ void CDVDPlayer::HandlePlaySpeed()
// handle situation that we get no data on one stream
if(m_CurrentAudio.id >= 0 && m_CurrentVideo.id >= 0)
{
- if ((!m_dvdPlayerAudio.AcceptsData() && !m_CurrentVideo.started)
- || (!m_dvdPlayerVideo.AcceptsData() && !m_CurrentAudio.started))
+ if ((!m_dvdPlayerAudio->AcceptsData() && !m_CurrentVideo.started)
+ || (!m_dvdPlayerVideo->AcceptsData() && !m_CurrentAudio.started))
{
caching = CACHESTATE_DONE;
}
@@ -1538,10 +1742,10 @@ void CDVDPlayer::HandlePlaySpeed()
{
bool bGotAudio(m_pDemuxer->GetNrOfAudioStreams() > 0);
bool bGotVideo(m_pDemuxer->GetNrOfVideoStreams() > 0);
- bool bAudioLevelOk(m_dvdPlayerAudio.GetLevel() > g_advancedSettings.m_iPVRMinAudioCacheLevel);
- bool bVideoLevelOk(m_dvdPlayerVideo.GetLevel() > g_advancedSettings.m_iPVRMinVideoCacheLevel);
- bool bAudioFull(!m_dvdPlayerAudio.AcceptsData());
- bool bVideoFull(!m_dvdPlayerVideo.AcceptsData());
+ bool bAudioLevelOk(m_dvdPlayerAudio->GetLevel() > g_advancedSettings.m_iPVRMinAudioCacheLevel);
+ bool bVideoLevelOk(m_dvdPlayerVideo->GetLevel() > g_advancedSettings.m_iPVRMinVideoCacheLevel);
+ bool bAudioFull(!m_dvdPlayerAudio->AcceptsData());
+ bool bVideoFull(!m_dvdPlayerVideo->AcceptsData());
if (/* if all streams got at least g_advancedSettings.m_iPVRMinCacheLevel in their buffers, we're done */
((bGotVideo || bGotAudio) && (!bGotAudio || bAudioLevelOk) && (!bGotVideo || bVideoLevelOk)) ||
@@ -1549,8 +1753,8 @@ void CDVDPlayer::HandlePlaySpeed()
(bAudioFull || bVideoFull))
{
CLog::Log(LOGDEBUG, "set caching from pvr to done. audio (%d) = %d. video (%d) = %d",
- bGotAudio, m_dvdPlayerAudio.GetLevel(),
- bGotVideo, m_dvdPlayerVideo.GetLevel());
+ bGotAudio, m_dvdPlayerAudio->GetLevel(),
+ bGotVideo, m_dvdPlayerVideo->GetLevel());
caching = CACHESTATE_DONE;
}
@@ -1558,17 +1762,17 @@ void CDVDPlayer::HandlePlaySpeed()
{
/* ensure that automatically started players are stopped while caching */
if (m_CurrentAudio.started)
- m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
+ m_dvdPlayerAudio->SetSpeed(DVD_PLAYSPEED_PAUSE);
if (m_CurrentVideo.started)
- m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
+ m_dvdPlayerVideo->SetSpeed(DVD_PLAYSPEED_PAUSE);
}
}
if(caching == CACHESTATE_PLAY)
{
// if all enabled streams have started playing we are done
- if((m_CurrentVideo.id < 0 || !m_dvdPlayerVideo.IsStalled())
- && (m_CurrentAudio.id < 0 || !m_dvdPlayerAudio.IsStalled()))
+ if((m_CurrentVideo.id < 0 || !m_dvdPlayerVideo->IsStalled())
+ && (m_CurrentAudio.id < 0 || !m_dvdPlayerAudio->IsStalled()))
caching = CACHESTATE_DONE;
}
@@ -1586,10 +1790,10 @@ void CDVDPlayer::HandlePlaySpeed()
}
else if (m_CurrentVideo.id >= 0
&& m_CurrentVideo.inited == true
- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts()
+ && m_SpeedState.lastpts != m_dvdPlayerVideo->GetCurrentPts()
&& m_SpeedState.lasttime != GetTime())
{
- m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts();
+ m_SpeedState.lastpts = m_dvdPlayerVideo->GetCurrentPts();
m_SpeedState.lasttime = (double) GetTime();
// check how much off clock video is when ff/rw:ing
// a problem here is that seeking isn't very accurate
@@ -1624,13 +1828,13 @@ bool CDVDPlayer::CheckStartCaching(CCurrentStream& current)
if(IsInMenu())
return false;
- if((current.type == STREAM_AUDIO && m_dvdPlayerAudio.IsStalled())
- || (current.type == STREAM_VIDEO && m_dvdPlayerVideo.IsStalled()))
+ if((current.type == STREAM_AUDIO && m_dvdPlayerAudio->IsStalled())
+ || (current.type == STREAM_VIDEO && m_dvdPlayerVideo->IsStalled()))
{
if (CachePVRStream())
{
- if ((current.type == STREAM_AUDIO && current.started && m_dvdPlayerAudio.GetLevel() == 0) ||
- (current.type == STREAM_VIDEO && current.started && m_dvdPlayerVideo.GetLevel() == 0))
+ if ((current.type == STREAM_AUDIO && current.started && m_dvdPlayerAudio->GetLevel() == 0) ||
+ (current.type == STREAM_VIDEO && current.started && m_dvdPlayerVideo->GetLevel() == 0))
{
CLog::Log(LOGDEBUG, "%s stream stalled. start buffering", current.type == STREAM_AUDIO ? "audio" : "video");
SetCaching(CACHESTATE_PVR);
@@ -1639,8 +1843,8 @@ bool CDVDPlayer::CheckStartCaching(CCurrentStream& current)
}
// don't start caching if it's only a single stream that has run dry
- if(m_dvdPlayerAudio.GetLevel() > 50
- || m_dvdPlayerVideo.GetLevel() > 50)
+ if(m_dvdPlayerAudio->GetLevel() > 50
+ || m_dvdPlayerVideo->GetLevel() > 50)
return false;
if(current.inited)
@@ -1879,7 +2083,7 @@ void CDVDPlayer::CheckAutoSceneSkip()
|| m_CurrentVideo.dts == DVD_NOPTS_VALUE)
return;
- const int64_t clock = DVD_TIME_TO_MSEC(min(m_CurrentAudio.dts, m_CurrentVideo.dts) + m_offset_pts);
+ const int64_t clock = m_omxplayer_mode ? GetTime() : DVD_TIME_TO_MSEC(min(m_CurrentAudio.dts, m_CurrentVideo.dts) + m_offset_pts);
CEdl::Cut cut;
if(!m_Edl.InCut(clock, &cut))
@@ -1949,15 +2153,15 @@ void CDVDPlayer::SynchronizePlayers(unsigned int sources)
CDVDMsgGeneralSynchronize* message = new CDVDMsgGeneralSynchronize(timeout, sources);
if (m_CurrentAudio.id >= 0)
- m_dvdPlayerAudio.SendMessage(message->Acquire());
+ m_dvdPlayerAudio->SendMessage(message->Acquire());
if (m_CurrentVideo.id >= 0)
- m_dvdPlayerVideo.SendMessage(message->Acquire());
+ m_dvdPlayerVideo->SendMessage(message->Acquire());
/* TODO - we have to rewrite the sync class, to not require
all other players waiting for subtitle, should only
be the oposite way
if (m_CurrentSubtitle.id >= 0)
- m_dvdPlayerSubtitle.SendMessage(message->Acquire());
+ m_dvdPlayerSubtitle->SendMessage(message->Acquire());
*/
message->Release();
}
@@ -1965,13 +2169,13 @@ void CDVDPlayer::SynchronizePlayers(unsigned int sources)
IDVDStreamPlayer* CDVDPlayer::GetStreamPlayer(unsigned int target)
{
if(target == DVDPLAYER_AUDIO)
- return &m_dvdPlayerAudio;
+ return m_dvdPlayerAudio;
if(target == DVDPLAYER_VIDEO)
- return &m_dvdPlayerVideo;
+ return m_dvdPlayerVideo;
if(target == DVDPLAYER_SUBTITLE)
- return &m_dvdPlayerSubtitle;
+ return m_dvdPlayerSubtitle;
if(target == DVDPLAYER_TELETEXT)
- return &m_dvdPlayerTeletext;
+ return m_dvdPlayerTeletext;
return NULL;
}
@@ -2006,6 +2210,13 @@ void CDVDPlayer::OnExit()
m_messenger.End();
+ if (m_omxplayer_mode)
+ {
+ m_OmxPlayerState.av_clock.OMXStop();
+ m_OmxPlayerState.av_clock.OMXStateIdle();
+ m_OmxPlayerState.av_clock.OMXDeinitialize();
+ }
+
m_bStop = true;
// if we didn't stop playing, advance to the next item in xbmc's playlist
if(m_PlayerOptions.identify == false)
@@ -2228,8 +2439,8 @@ void CDVDPlayer::HandleMessages()
m_playSpeed = speed;
m_caching = CACHESTATE_DONE;
m_clock.SetSpeed(speed);
- m_dvdPlayerAudio.SetSpeed(speed);
- m_dvdPlayerVideo.SetSpeed(speed);
+ m_dvdPlayerAudio->SetSpeed(speed);
+ m_dvdPlayerVideo->SetSpeed(speed);
// We can't pause demuxer until our buffers are full. Doing so will result in continued
// calls to Read() which may then block indefinitely (CDVDInputStreamRTMP for example).
@@ -2239,6 +2450,23 @@ void CDVDPlayer::HandleMessages()
if (!m_DemuxerPausePending)
m_pDemuxer->SetSpeed(speed);
}
+
+ if (m_omxplayer_mode)
+ {
+ int old_speed = m_playSpeed;
+ // when switching from trickplay to normal, we may not have a full set of reference frames
+ // in decoder and we may get corrupt frames out. Seeking to current time will avoid this.
+ if ( (speed != DVD_PLAYSPEED_PAUSE && speed != DVD_PLAYSPEED_NORMAL) ||
+ (old_speed != DVD_PLAYSPEED_PAUSE && old_speed != DVD_PLAYSPEED_NORMAL) )
+ {
+ m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, true, false, true));
+ }
+ else
+ m_OmxPlayerState.av_clock.OMXPause();
+
+ m_OmxPlayerState.av_clock.OMXSetSpeed(speed);
+ CLog::Log(LOGDEBUG, "%s::%s CDVDMsg::PLAYER_SETSPEED speed : %d (%d)", "CDVDPlayer", __FUNCTION__, speed, old_speed);
+ }
}
else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) == 0)
{
@@ -2327,6 +2555,18 @@ void CDVDPlayer::HandleMessages()
if(player == DVDPLAYER_VIDEO)
m_CurrentVideo.started = true;
CLog::Log(LOGDEBUG, "CDVDPlayer::HandleMessages - player started %d", player);
+
+ if (m_omxplayer_mode)
+ {
+ if ((player == DVDPLAYER_AUDIO || player == DVDPLAYER_VIDEO) &&
+ ((m_playSpeed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_NORMAL) || !m_HasAudio || m_CurrentAudio.started) &&
+ (!m_HasVideo || m_CurrentVideo.started))
+ {
+ CLog::Log(LOGDEBUG, "%s::%s player started RESET", "CDVDPlayer", __FUNCTION__);
+ m_OmxPlayerState.av_clock.OMXReset(m_HasVideo, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false:m_HasAudio);
+ }
+ CLog::Log(LOGDEBUG, "%s::%s player started %d (s:%d a:%d v:%d)", "CDVDPlayer", __FUNCTION__, player, m_playSpeed, m_CurrentAudio.started, m_CurrentVideo.started);
+ }
}
else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
{
@@ -2335,7 +2575,7 @@ void CDVDPlayer::HandleMessages()
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(m_CurrentVideo.started && !m_dvdPlayerVideo->SubmittedEOS())
{
if(state.player == DVDPLAYER_VIDEO)
m_State = state;
@@ -2372,10 +2612,14 @@ void CDVDPlayer::SetCaching(ECacheState state)
|| state == CACHESTATE_PVR)
{
m_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
- m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
+
+ if (m_omxplayer_mode)
+ m_OmxPlayerState.av_clock.OMXPause();
+
+ m_dvdPlayerAudio->SetSpeed(DVD_PLAYSPEED_PAUSE);
+ m_dvdPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
+ m_dvdPlayerVideo->SetSpeed(DVD_PLAYSPEED_PAUSE);
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
if (state == CACHESTATE_PVR)
m_pInputStream->ResetScanTimeout((unsigned int) CSettings::Get().GetInt("pvrplayback.scantime") * 1000);
@@ -2385,8 +2629,8 @@ void CDVDPlayer::SetCaching(ECacheState state)
||(state == CACHESTATE_DONE && m_caching != CACHESTATE_PLAY))
{
m_clock.SetSpeed(m_playSpeed);
- m_dvdPlayerAudio.SetSpeed(m_playSpeed);
- m_dvdPlayerVideo.SetSpeed(m_playSpeed);
+ m_dvdPlayerAudio->SetSpeed(m_playSpeed);
+ m_dvdPlayerVideo->SetSpeed(m_playSpeed);
m_pInputStream->ResetScanTimeout(0);
}
m_caching = state;
@@ -2399,8 +2643,8 @@ void CDVDPlayer::SetPlaySpeed(int speed)
else
m_playSpeed = speed;
- m_dvdPlayerAudio.SetSpeed(speed);
- m_dvdPlayerVideo.SetSpeed(speed);
+ m_dvdPlayerAudio->SetSpeed(speed);
+ m_dvdPlayerVideo->SetSpeed(speed);
SynchronizeDemuxer(100);
}
@@ -2453,7 +2697,7 @@ bool CDVDPlayer::HasAudio() const
bool CDVDPlayer::IsPassthrough() const
{
- return m_dvdPlayerAudio.IsPassthrough();
+ return m_dvdPlayerAudio->IsPassthrough();
}
bool CDVDPlayer::CanSeek()
@@ -2466,7 +2710,7 @@ void CDVDPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
{
if( m_playSpeed == DVD_PLAYSPEED_PAUSE && bPlus && !bLargeStep)
{
- if (m_dvdPlayerVideo.StepFrame())
+ if (m_dvdPlayerVideo->StepFrame())
return;
}
if (!m_State.canseek)
@@ -2601,7 +2845,7 @@ void CDVDPlayer::GetAudioInfo(std::string& strAudioInfo)
{ CSingleLock lock(m_StateSection);
strAudioInfo = StringUtils::Format("D(%s)", m_StateInput.demux_audio.c_str());
}
- strAudioInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerAudio.GetPlayerInfo().c_str());
+ strAudioInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerAudio->GetPlayerInfo().c_str());
}
void CDVDPlayer::GetVideoInfo(std::string& strVideoInfo)
@@ -2609,44 +2853,83 @@ void CDVDPlayer::GetVideoInfo(std::string& strVideoInfo)
{ CSingleLock lock(m_StateSection);
strVideoInfo = StringUtils::Format("D(%s)", m_StateInput.demux_video.c_str());
}
- strVideoInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerVideo.GetPlayerInfo().c_str());
+ strVideoInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerVideo->GetPlayerInfo().c_str());
}
void CDVDPlayer::GetGeneralInfo(std::string& strGeneralInfo)
{
if (!m_bStop)
{
- double dDelay = m_dvdPlayerVideo.GetDelay() / DVD_TIME_BASE - g_renderManager.GetDisplayLatency();
+ if (m_omxplayer_mode)
+ {
+ double dDelay = m_dvdPlayerAudio->GetDelay();
- double apts = m_dvdPlayerAudio.GetCurrentPts();
- double vpts = m_dvdPlayerVideo.GetCurrentPts();
- double dDiff = 0;
+ double apts = m_dvdPlayerAudio->GetCurrentPts();
+ double vpts = m_dvdPlayerVideo->GetCurrentPts();
+ double dDiff = 0;
- if( apts != DVD_NOPTS_VALUE && vpts != DVD_NOPTS_VALUE )
- dDiff = (apts - vpts) / DVD_TIME_BASE;
+ if( apts != DVD_NOPTS_VALUE && vpts != DVD_NOPTS_VALUE )
+ dDiff = (apts - vpts) / DVD_TIME_BASE;
- std::string strEDL = StringUtils::Format(", edl:%s", m_Edl.GetInfo().c_str());
+ CStdString strEDL;
+ strEDL += StringUtils::Format(", edl:%s", m_Edl.GetInfo().c_str());
- std::string strBuf;
- CSingleLock lock(m_StateSection);
- if(m_StateInput.cache_bytes >= 0)
- {
- strBuf += StringUtils::Format(" cache:%s %2.0f%%"
- , StringUtils::SizeToString(m_State.cache_bytes).c_str()
- , m_State.cache_level * 100);
- if(m_playSpeed == 0 || m_caching == CACHESTATE_FULL)
- strBuf += StringUtils::Format(" %d sec", DVD_TIME_TO_SEC(m_State.cache_delay));
+ CStdString strBuf;
+ CSingleLock lock(m_StateSection);
+ if(m_StateInput.cache_bytes >= 0)
+ {
+ strBuf += StringUtils::Format(" cache:%s %2.0f%%"
+ , StringUtils::SizeToString(m_State.cache_bytes).c_str()
+ , m_State.cache_level * 100);
+ if(m_playSpeed == 0 || m_caching == CACHESTATE_FULL)
+ strBuf += StringUtils::Format(" %d sec", DVD_TIME_TO_SEC(m_State.cache_delay));
+ }
+
+ strGeneralInfo = StringUtils::Format("C( ad:% 6.3f, a/v:% 6.3f%s, dcpu:%2i%% acpu:%2i%% vcpu:%2i%%%s af:%d%% vf:%d%% amp:% 5.2f )"
+ , dDelay
+ , dDiff
+ , strEDL.c_str()
+ , (int)(CThread::GetRelativeUsage()*100)
+ , (int)(m_dvdPlayerAudio->GetRelativeUsage()*100)
+ , (int)(m_dvdPlayerVideo->GetRelativeUsage()*100)
+ , strBuf.c_str()
+ , m_OmxPlayerState.audio_fifo
+ , m_OmxPlayerState.video_fifo
+ , m_dvdPlayerAudio->GetDynamicRangeAmplification());
}
+ else
+ {
+ double dDelay = m_dvdPlayerVideo->GetDelay() / DVD_TIME_BASE - g_renderManager.GetDisplayLatency();
- strGeneralInfo = StringUtils::Format("C( ad:% 6.3f, a/v:% 6.3f%s, dcpu:%2i%% acpu:%2i%% vcpu:%2i%%%s )"
- , dDelay
- , dDiff
- , strEDL.c_str()
- , (int)(CThread::GetRelativeUsage()*100)
- , (int)(m_dvdPlayerAudio.GetRelativeUsage()*100)
- , (int)(m_dvdPlayerVideo.GetRelativeUsage()*100)
- , strBuf.c_str());
+ double apts = m_dvdPlayerAudio->GetCurrentPts();
+ double vpts = m_dvdPlayerVideo->GetCurrentPts();
+ double dDiff = 0;
+ if( apts != DVD_NOPTS_VALUE && vpts != DVD_NOPTS_VALUE )
+ dDiff = (apts - vpts) / DVD_TIME_BASE;
+
+ std::string strEDL = StringUtils::Format(", edl:%s", m_Edl.GetInfo().c_str());
+
+ std::string strBuf;
+ CSingleLock lock(m_StateSection);
+ if(m_StateInput.cache_bytes >= 0)
+ {
+ strBuf += StringUtils::Format(" cache:%s %2.0f%%"
+ , StringUtils::SizeToString(m_State.cache_bytes).c_str()
+ , m_State.cache_level * 100);
+ if(m_playSpeed == 0 || m_caching == CACHESTATE_FULL)
+ strBuf += StringUtils::Format(" %d sec", DVD_TIME_TO_SEC(m_State.cache_delay));
+ }
+
+ strGeneralInfo = StringUtils::Format("C( ad:% 6.3f, a/v:% 6.3f%s, dcpu:%2i%% acpu:%2i%% vcpu:%2i%%%s )"
+ , dDelay
+ , dDiff
+ , strEDL.c_str()
+ , (int)(CThread::GetRelativeUsage()*100)
+ , (int)(m_dvdPlayerAudio->GetRelativeUsage()*100)
+ , (int)(m_dvdPlayerVideo->GetRelativeUsage()*100)
+ , strBuf.c_str());
+ }
}
}
@@ -2678,22 +2961,22 @@ float CDVDPlayer::GetCachePercentage()
void CDVDPlayer::SetAVDelay(float fValue)
{
- m_dvdPlayerVideo.SetDelay( (fValue * DVD_TIME_BASE) ) ;
+ m_dvdPlayerVideo->SetDelay( (fValue * DVD_TIME_BASE) ) ;
}
float CDVDPlayer::GetAVDelay()
{
- return (float) m_dvdPlayerVideo.GetDelay() / (float)DVD_TIME_BASE;
+ return (float) m_dvdPlayerVideo->GetDelay() / (float)DVD_TIME_BASE;
}
void CDVDPlayer::SetSubTitleDelay(float fValue)
{
- m_dvdPlayerVideo.SetSubtitleDelay(-fValue * DVD_TIME_BASE);
+ m_dvdPlayerVideo->SetSubtitleDelay(-fValue * DVD_TIME_BASE);
}
float CDVDPlayer::GetSubTitleDelay()
{
- return (float) -m_dvdPlayerVideo.GetSubtitleDelay() / DVD_TIME_BASE;
+ return (float) -m_dvdPlayerVideo->GetSubtitleDelay() / DVD_TIME_BASE;
}
// priority: 1: libdvdnav, 2: external subtitles, 3: muxed subtitles
@@ -2735,7 +3018,7 @@ bool CDVDPlayer::GetSubtitleVisible()
return pStream->IsSubtitleStreamEnabled();
}
- return m_dvdPlayerVideo.IsSubtitleEnabled();
+ return m_dvdPlayerVideo->IsSubtitleEnabled();
}
void CDVDPlayer::SetSubtitleVisible(bool bVisible)
@@ -2745,7 +3028,7 @@ void CDVDPlayer::SetSubtitleVisible(bool bVisible)
void CDVDPlayer::SetSubtitleVisibleInternal(bool bVisible)
{
- m_dvdPlayerVideo.EnableSubtitle(bVisible);
+ m_dvdPlayerVideo->EnableSubtitle(bVisible);
if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(bVisible);
@@ -2772,7 +3055,7 @@ TextCacheStruct_t* CDVDPlayer::GetTeletextCache()
if (m_CurrentTeletext.id < 0)
return 0;
- return m_dvdPlayerTeletext.GetTeletextCache();
+ return m_dvdPlayerTeletext->GetTeletextCache();
}
void CDVDPlayer::LoadPage(int p, int sp, unsigned char* buffer)
@@ -2780,7 +3063,7 @@ void CDVDPlayer::LoadPage(int p, int sp, unsigned char* buffer)
if (m_CurrentTeletext.id < 0)
return;
- return m_dvdPlayerTeletext.LoadPage(p, sp, buffer);
+ return m_dvdPlayerTeletext->LoadPage(p, sp, buffer);
}
void CDVDPlayer::SeekTime(int64_t iTime)
@@ -2851,7 +3134,7 @@ bool CDVDPlayer::OpenStream(CCurrentStream& current, int iStream, int source, bo
m_pSubtitleDemuxer = demux.release();
}
- double pts = m_dvdPlayerVideo.GetCurrentPts();
+ double pts = m_dvdPlayerVideo->GetCurrentPts();
if(pts == DVD_NOPTS_VALUE)
pts = m_CurrentVideo.dts;
if(pts == DVD_NOPTS_VALUE)
@@ -2964,10 +3247,10 @@ bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset)
m_HasAudio = true;
/* we are potentially going to be waiting on this */
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
+ m_dvdPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
/* audio normally won't consume full cpu, so let it have prio */
- m_dvdPlayerAudio.SetPriority(GetPriority()+1);
+ m_dvdPlayerAudio->SetPriority(GetPriority()+1);
return true;
}
@@ -3001,7 +3284,7 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset)
m_HasVideo = true;
/* we are potentially going to be waiting on this */
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
#if defined(TARGET_DARWIN)
// Apple thread scheduler works a little different than Linux. It
@@ -3011,11 +3294,11 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset)
// the CoreAudio audio device handler thread. We do the same for
// the DVDPlayerVideo thread so it can run to sleep without getting
// swapped out by a busy OS.
- m_dvdPlayerVideo.SetPriority(GetSchedRRPriority());
+ m_dvdPlayerVideo->SetPriority(GetSchedRRPriority());
#else
/* use same priority for video thread as demuxing thread, as */
/* otherwise demuxer will starve if video consumes the full cpu */
- m_dvdPlayerVideo.SetPriority(GetPriority());
+ m_dvdPlayerVideo->SetPriority(GetPriority());
#endif
return true;
@@ -3060,7 +3343,7 @@ bool CDVDPlayer::AdaptForcedSubtitles()
bool CDVDPlayer::OpenTeletextStream(CDVDStreamInfo& hint)
{
- if (!m_dvdPlayerTeletext.CheckStream(hint))
+ if (!m_dvdPlayerTeletext->CheckStream(hint))
return false;
if(!OpenStreamPlayer(m_CurrentTeletext, hint, true))
@@ -3144,19 +3427,19 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
if(queued)
{
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerTeletext.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
+ m_dvdPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
+ m_dvdPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
+ m_dvdPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
SynchronizePlayers(SYNCSOURCE_ALL);
}
else
{
- m_dvdPlayerAudio.Flush();
- m_dvdPlayerVideo.Flush();
- m_dvdPlayerSubtitle.Flush();
- m_dvdPlayerTeletext.Flush();
+ m_dvdPlayerAudio->Flush();
+ m_dvdPlayerVideo->Flush();
+ m_dvdPlayerSubtitle->Flush();
+ m_dvdPlayerTeletext->Flush();
// clear subtitle and menu overlays
m_overlayContainer.Clear();
@@ -3166,8 +3449,8 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
{
// make sure players are properly flushed, should put them in stalled state
CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, 0);
- m_dvdPlayerAudio.SendMessage(msg->Acquire(), 1);
- m_dvdPlayerVideo.SendMessage(msg->Acquire(), 1);
+ m_dvdPlayerAudio->SendMessage(msg->Acquire(), 1);
+ m_dvdPlayerVideo->SendMessage(msg->Acquire(), 1);
msg->Wait(&m_bStop, 0);
msg->Release();
@@ -3191,6 +3474,15 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
CSingleLock lock(m_StateSection);
m_State = m_StateInput;
}
+
+ if (m_omxplayer_mode)
+ {
+ m_OmxPlayerState.av_clock.OMXFlush();
+ if (!queued)
+ m_OmxPlayerState.av_clock.OMXStop();
+ m_OmxPlayerState.av_clock.OMXPause();
+ m_OmxPlayerState.av_clock.OMXMediaTime(0.0);
+ }
}
// since we call ffmpeg functions to decode, this is being called in the same thread as ::Process() is
@@ -3207,7 +3499,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
else if(iMessage == 3)
m_dvd.iSelectedSPUStream = *(int*)pData;
else if(iMessage == 4)
- m_dvdPlayerVideo.EnableSubtitle(*(int*)pData ? true: false);
+ m_dvdPlayerVideo->EnableSubtitle(*(int*)pData ? true: false);
else if(iMessage == 5)
{
if (m_dvd.state != DVDSTATE_STILL)
@@ -3221,7 +3513,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
unsigned int time = 0;
if( m_CurrentVideo.stream && m_dvd.iDVDStillTime > 0 )
{
- time = (unsigned int)(m_dvdPlayerVideo.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
+ time = (unsigned int)(m_dvdPlayerVideo->GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
if( time < 10000 && time > 0 )
m_dvd.iDVDStillTime += time;
}
@@ -3270,7 +3562,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
unsigned int time = 0;
if( m_CurrentVideo.stream && m_dvd.iDVDStillTime > 0 )
{
- time = (unsigned int)(m_dvdPlayerVideo.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
+ time = (unsigned int)(m_dvdPlayerVideo->GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
if( time < 10000 && time > 0 )
m_dvd.iDVDStillTime += time;
}
@@ -3284,7 +3576,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
break;
case DVDNAV_SPU_CLUT_CHANGE:
{
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsgSubtitleClutChange((uint8_t*)pData));
+ m_dvdPlayerSubtitle->SendMessage(new CDVDMsgSubtitleClutChange((uint8_t*)pData));
}
break;
case DVDNAV_SPU_STREAM_CHANGE:
@@ -3324,7 +3616,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
//dvdnav_highlight_event_t* pInfo = (dvdnav_highlight_event_t*)pData;
int iButton = pStream->GetCurrentButton();
CLog::Log(LOGDEBUG, "DVDNAV_HIGHLIGHT: Highlight button %d\n", iButton);
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
+ m_dvdPlayerSubtitle->UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
}
break;
case DVDNAV_VTS_CHANGE:
@@ -3337,8 +3629,8 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
//Force an aspect ratio that is set in the dvdheaders if available
m_CurrentVideo.hint.aspect = pStream->GetVideoAspectRatio();
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsgDouble(CDVDMsg::VIDEO_SET_ASPECT, m_CurrentVideo.hint.aspect));
+ if( m_dvdPlayerVideo->IsInited() )
+ m_dvdPlayerVideo->SendMessage(new CDVDMsgDouble(CDVDMsg::VIDEO_SET_ASPECT, m_CurrentVideo.hint.aspect));
m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NAV);
m_SelectionStreams.Update(m_pInputStream, m_pDemuxer);
@@ -3353,8 +3645,8 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
m_dvd.state = DVDSTATE_NORMAL;
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
+ if( m_dvdPlayerVideo->IsInited() )
+ m_dvdPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
}
break;
case DVDNAV_NAV_PACKET:
@@ -3543,7 +3835,7 @@ bool CDVDPlayer::OnAction(const CAction &action)
case ACTION_MOUSE_LEFT_CLICK:
{
CRect rs, rd;
- m_dvdPlayerVideo.GetVideoRect(rs, rd);
+ m_dvdPlayerVideo->GetVideoRect(rs, rd);
CPoint pt(action.GetAmount(), action.GetAmount(1));
if (!rd.PtInRect(pt))
return false; // out of bounds
@@ -3572,7 +3864,7 @@ bool CDVDPlayer::OnAction(const CAction &action)
CLog::Log(LOGDEBUG, " - button select");
// show button pushed overlay
if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_CLICKED);
+ m_dvdPlayerSubtitle->UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_CLICKED);
pMenus->ActivateButton();
}
@@ -3746,14 +4038,14 @@ int CDVDPlayer::GetCacheLevel() const
double CDVDPlayer::GetQueueTime()
{
- int a = m_dvdPlayerAudio.GetLevel();
- int v = m_dvdPlayerVideo.GetLevel();
+ int a = m_dvdPlayerAudio->GetLevel();
+ int v = m_dvdPlayerVideo->GetLevel();
return max(a, v) * 8000.0 / 100;
}
void CDVDPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
{
- info.bitrate = m_dvdPlayerVideo.GetVideoBitrate();
+ info.bitrate = m_dvdPlayerVideo->GetVideoBitrate();
std::string retVal;
if (m_pDemuxer && (m_CurrentVideo.id != -1))
@@ -3767,9 +4059,9 @@ void CDVDPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
}
}
info.videoCodecName = retVal;
- info.videoAspectRatio = m_dvdPlayerVideo.GetAspectRatio();
- m_dvdPlayerVideo.GetVideoRect(info.SrcRect, info.DestRect);
- info.stereoMode = m_dvdPlayerVideo.GetStereoMode();
+ info.videoAspectRatio = m_dvdPlayerVideo->GetAspectRatio();
+ m_dvdPlayerVideo->GetVideoRect(info.SrcRect, info.DestRect);
+ info.stereoMode = m_dvdPlayerVideo->GetStereoMode();
if (info.stereoMode == "mono")
info.stereoMode = "";
}
@@ -3789,8 +4081,8 @@ void CDVDPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
if (index == GetAudioStream())
{
- info.bitrate = m_dvdPlayerAudio.GetAudioBitrate();
- info.channels = m_dvdPlayerAudio.GetAudioChannels();
+ info.bitrate = m_dvdPlayerAudio->GetAudioBitrate();
+ info.channels = m_dvdPlayerAudio->GetAudioChannels();
}
else if (m_pDemuxer)
{
@@ -4083,7 +4375,7 @@ bool CDVDPlayer::GetStreamDetails(CStreamDetails &details)
* 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_dvdPlayerVideo.GetAspectRatio();
+ float aspect = m_dvdPlayerVideo->GetAspectRatio();
if (aspect > 0.0f)
((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_fAspect = aspect;
@@ -4100,7 +4392,7 @@ bool CDVDPlayer::GetStreamDetails(CStreamDetails &details)
std::string CDVDPlayer::GetPlayingTitle()
{
/* Currently we support only Title Name from Teletext line 30 */
- TextCacheStruct_t* ttcache = m_dvdPlayerTeletext.GetTeletextCache();
+ TextCacheStruct_t* ttcache = m_dvdPlayerTeletext->GetTeletextCache();
if (ttcache && !ttcache->line30.empty())
return ttcache->line30;
@@ -4131,3 +4423,32 @@ bool CDVDPlayer::CachePVRStream(void) const
!g_PVRManager.IsPlayingRecording() &&
g_advancedSettings.m_bPVRCacheInDvdPlayer;
}
+
+void CDVDPlayer::OMXGetRenderFeatures(std::vector<int> &renderFeatures)
+{
+ if (m_omxplayer_mode)
+ {
+ renderFeatures.push_back(RENDERFEATURE_STRETCH);
+ renderFeatures.push_back(RENDERFEATURE_CROP);
+ renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
+ renderFeatures.push_back(RENDERFEATURE_ZOOM);
+ }
+}
+
+void CDVDPlayer::OMXGetDeinterlaceMethods(std::vector<int> &deinterlaceMethods)
+{
+ if (m_omxplayer_mode)
+ {
+ deinterlaceMethods.push_back(VS_INTERLACEMETHOD_DEINTERLACE);
+ }
+}
+
+void CDVDPlayer::OMXGetDeinterlaceModes(std::vector<int> &deinterlaceModes)
+{
+ if (m_omxplayer_mode)
+ {
+ deinterlaceModes.push_back(VS_DEINTERLACEMODE_AUTO);
+ deinterlaceModes.push_back(VS_DEINTERLACEMODE_OFF);
+ deinterlaceModes.push_back(VS_DEINTERLACEMODE_FORCE);
+ }
+}
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h
index b811003e05..951382c2f7 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.h
+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
@@ -42,6 +42,34 @@
#include "utils/StreamDetails.h"
#include "threads/SystemClock.h"
+#ifdef HAS_OMXPLAYER
+#include "OMXCore.h"
+#include "OMXClock.h"
+#include "linux/RBP.h"
+#else
+
+// dummy class to avoid ifdefs where calls are made
+class OMXClock
+{
+public:
+ bool OMXInitialize(CDVDClock *clock) { return false; }
+ void OMXDeinitialize() {}
+ bool OMXIsPaused() { return false; }
+ bool OMXStop(bool lock = true) { return false; }
+ bool OMXStep(int steps = 1, bool lock = true) { return false; }
+ bool OMXReset(bool has_video, bool has_audio, bool lock = true) { return false; }
+ double OMXMediaTime(bool lock = true) { return 0.0; }
+ double OMXClockAdjustment(bool lock = true) { return 0.0; }
+ bool OMXMediaTime(double pts, bool lock = true) { return false; }
+ bool OMXPause(bool lock = true) { return false; }
+ bool OMXResume(bool lock = true) { return false; }
+ bool OMXSetSpeed(int speed, bool lock = true, bool pause_resume = false) { return false; }
+ bool OMXFlush(bool lock = true) { return false; }
+ bool OMXStateExecute(bool lock = true) { return false; }
+ void OMXStateIdle(bool lock = true) {}
+ bool HDMIClockSync(bool lock = true) { return false; }
+};
+#endif
class CDVDInputStream;
@@ -189,11 +217,9 @@ public:
virtual float GetPercentage();
virtual float GetCachePercentage();
- virtual void RegisterAudioCallback(IAudioCallback* pCallback) { m_dvdPlayerAudio.RegisterAudioCallback(pCallback); }
- virtual void UnRegisterAudioCallback() { m_dvdPlayerAudio.UnRegisterAudioCallback(); }
- virtual void SetVolume(float nVolume) { m_dvdPlayerAudio.SetVolume(nVolume); }
- virtual void SetMute(bool bOnOff) { m_dvdPlayerAudio.SetMute(bOnOff); }
- virtual void SetDynamicRangeCompression(long drc) { m_dvdPlayerAudio.SetDynamicRangeCompression(drc); }
+ virtual void SetVolume(float nVolume) { m_dvdPlayerAudio->SetVolume(nVolume); }
+ virtual void SetMute(bool bOnOff) { m_dvdPlayerAudio->SetMute(bOnOff); }
+ virtual void SetDynamicRangeCompression(long drc) { m_dvdPlayerAudio->SetDynamicRangeCompression(drc); }
virtual void GetAudioInfo(std::string& strAudioInfo);
virtual void GetVideoInfo(std::string& strVideoInfo);
virtual void GetGeneralInfo(std::string& strVideoInfo);
@@ -259,6 +285,15 @@ public:
virtual int GetCacheLevel() const ;
virtual int OnDVDNavResult(void* pData, int iMessage);
+
+ // Note: the following "OMX" methods are deprecated and will be removed in the future
+ // They should be handled by the video renderer, not the player
+ virtual void OMXGetRenderFeatures(std::vector<int> &renderFeatures);
+ virtual void OMXGetDeinterlaceMethods(std::vector<int> &deinterlaceMethods);
+ virtual void OMXGetDeinterlaceModes(std::vector<int> &deinterlaceModes);
+
+ virtual bool ControlsVolume() {return m_omxplayer_mode;}
+
protected:
friend class CSelectionStreams;
@@ -266,6 +301,11 @@ protected:
virtual void OnExit();
virtual void Process();
+ void CreatePlayers();
+ void DestroyPlayers();
+ void OMXDoProcessing();
+ bool OMXStillPlaying();
+
bool OpenStream(CCurrentStream& current, int iStream, int source, bool reset = true);
bool OpenStreamPlayer(CCurrentStream& current, CDVDStreamInfo& hint, bool reset);
bool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);
@@ -339,6 +379,7 @@ protected:
void UpdateClockMaster();
double m_UpdateApplication;
+ bool m_players_created;
bool m_bAbortRequest;
std::string m_filename; // holds the actual filename
@@ -367,10 +408,10 @@ protected:
CDVDMessageQueue m_messenger; // thread messenger
- CDVDPlayerVideo m_dvdPlayerVideo; // video part
- CDVDPlayerAudio m_dvdPlayerAudio; // audio part
- CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
- CDVDTeletextData m_dvdPlayerTeletext; // teletext part
+ IDVDStreamPlayerVideo *m_dvdPlayerVideo; // video part
+ IDVDStreamPlayerAudio *m_dvdPlayerAudio; // audio part
+ CDVDPlayerSubtitle *m_dvdPlayerSubtitle; // subtitle part
+ CDVDTeletextData *m_dvdPlayerTeletext; // teletext part
CDVDClock m_clock; // master clock
CDVDOverlayContainer m_overlayContainer;
@@ -406,6 +447,10 @@ protected:
friend class CDVDPlayerVideo;
friend class CDVDPlayerAudio;
+#ifdef HAS_OMXPLAYER
+ friend class OMXPlayerVideo;
+ friend class OMXPlayerAudio;
+#endif
struct SPlayerState
{
@@ -496,4 +541,20 @@ protected:
bool m_HasAudio;
bool m_DemuxerPausePending;
+
+ // omxplayer variables
+ struct SOmxPlayerState
+ {
+ OMXClock av_clock; // openmax clock component
+ EDEINTERLACEMODE current_deinterlace; // whether deinterlace is currently enabled
+ bool bOmxWaitVideo; // whether we need to wait for video to play out on EOS
+ bool bOmxWaitAudio; // whether we need to wait for audio to play out on EOS
+ bool bOmxSentEOFs; // flag if we've send EOFs to audio/video players
+ float threshold; // current fifo threshold required to come out of buffering
+ int video_fifo; // video fifo to gpu level
+ int audio_fifo; // audio fifo to gpu level
+ double last_check_time; // we periodically check for gpu underrun
+ double stamp; // last media timestamp
+ } m_OmxPlayerState;
+ bool m_omxplayer_mode; // using omxplayer acceleration
};
diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h
index 3761912a5d..e8b2ab6086 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h
+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h
@@ -36,7 +36,6 @@
class CDVDPlayer;
class CDVDAudioCodec;
-class IAudioCallback;
class CDVDAudioCodec;
#define DECODE_FLAG_DROP 1
@@ -102,7 +101,7 @@ public:
XbmcThreads::EndTime m_timer;
};
-class CDVDPlayerAudio : public CThread, public IDVDStreamPlayer
+class CDVDPlayerAudio : public CThread, public IDVDStreamPlayerAudio
{
public:
CDVDPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent);
@@ -111,9 +110,6 @@ public:
bool OpenStream(CDVDStreamInfo &hints);
void CloseStream(bool bWaitForBuffers);
- void RegisterAudioCallback(IAudioCallback* pCallback) { m_dvdAudio.RegisterAudioCallback(pCallback); }
- void UnRegisterAudioCallback() { m_dvdAudio.UnRegisterAudioCallback(); }
-
void SetSpeed(int speed);
void Flush();
@@ -146,6 +142,8 @@ public:
bool IsStalled() const { return m_stalled; }
bool IsEOS() { return false; }
bool IsPassthrough() const;
+ double GetDelay() { return 0.0; }
+ double GetCacheTotal() { return 0.0; }
protected:
virtual void OnStartup();
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
index 37a37c46b0..dcd0ffda00 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
@@ -37,7 +37,7 @@ class CDVDOverlayCodecCC;
#define VIDEO_PICTURE_QUEUE_SIZE 1
-class CDVDPlayerVideo : public CThread, public IDVDStreamPlayer
+class CDVDPlayerVideo : public CThread, public IDVDStreamPlayerVideo
{
public:
CDVDPlayerVideo( CDVDClock* pClock
@@ -78,10 +78,12 @@ public:
bool IsStalled() const { return m_stalled; }
bool IsEOS() { return false; }
+ bool SubmittedEOS() const { return false; }
double GetCurrentPts() { return m_iCurrentPts; }
double GetOutputDelay(); /* returns the expected delay, from that a packet is put in queue */
+ int GetDecoderFreeSpace() { return 0; }
std::string GetPlayerInfo();
int GetVideoBitrate();
std::string GetStereoMode();
diff --git a/xbmc/cores/dvdplayer/IDVDPlayer.h b/xbmc/cores/dvdplayer/IDVDPlayer.h
index d99ec49813..cd8abfdc78 100644
--- a/xbmc/cores/dvdplayer/IDVDPlayer.h
+++ b/xbmc/cores/dvdplayer/IDVDPlayer.h
@@ -23,6 +23,9 @@
#include "DVDStreamInfo.h"
#include "DVDMessageQueue.h"
+template <typename T> class CRectGen;
+typedef CRectGen<float> CRect;
+
class DVDNavResult;
class IDVDPlayer
@@ -35,10 +38,85 @@ public:
class IDVDStreamPlayer
{
public:
+ virtual ~IDVDStreamPlayer() {}
virtual bool OpenStream(CDVDStreamInfo &hint) = 0;
virtual void CloseStream(bool bWaitForBuffers) = 0;
- virtual void SendMessage(CDVDMsg* pMsg, int priority) = 0;
+ virtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;
virtual bool IsInited() const = 0;
virtual bool AcceptsData() const = 0;
virtual bool IsStalled() const = 0;
};
+
+class CDVDVideoCodec;
+
+class IDVDStreamPlayerVideo : public IDVDStreamPlayer
+{
+public:
+ ~IDVDStreamPlayerVideo() {}
+ float GetRelativeUsage() { return 0.0f; }
+ bool SetPriority(const int iPriority) { return true; }
+ virtual bool OpenStream(CDVDStreamInfo &hint) = 0;
+ virtual void CloseStream(bool bWaitForBuffers) = 0;
+ virtual bool StepFrame() = 0;
+ virtual void Flush() = 0;
+ virtual void WaitForBuffers() = 0;
+ virtual bool AcceptsData() const = 0;
+ virtual bool HasData() const = 0;
+ virtual int GetLevel() const = 0;
+ virtual bool IsInited() const = 0;
+ virtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;
+ virtual void EnableSubtitle(bool bEnable) = 0;
+ virtual bool IsSubtitleEnabled() = 0;
+ virtual void EnableFullscreen(bool bEnable) = 0;
+#ifdef HAS_VIDEO_PLAYBACK
+ virtual void GetVideoRect(CRect& SrcRect, CRect& DestRect) const = 0;
+ virtual float GetAspectRatio() = 0;
+#endif
+ virtual double GetDelay() = 0;
+ virtual void SetDelay(double delay) = 0;
+ virtual double GetSubtitleDelay() = 0;
+ virtual void SetSubtitleDelay(double delay) = 0;
+ virtual bool IsStalled() const = 0;
+ virtual double GetCurrentPts() = 0;
+ virtual double GetOutputDelay() = 0;
+ virtual std::string GetPlayerInfo() = 0;
+ virtual int GetVideoBitrate() = 0;
+ virtual std::string GetStereoMode() = 0;
+ virtual void SetSpeed(int iSpeed) = 0;
+ virtual int GetDecoderBufferSize() { return 0; }
+ virtual int GetDecoderFreeSpace() = 0;
+ virtual bool IsEOS() = 0;
+ virtual bool SubmittedEOS() const = 0;
+};
+
+class CDVDAudioCodec;
+class IDVDStreamPlayerAudio : public IDVDStreamPlayer
+{
+public:
+ ~IDVDStreamPlayerAudio() {}
+ float GetRelativeUsage() { return 0.0f; }
+ bool SetPriority(const int iPriority) { return true; }
+ virtual bool OpenStream(CDVDStreamInfo &hints) = 0;
+ virtual void CloseStream(bool bWaitForBuffers) = 0;
+ virtual void SetSpeed(int speed) = 0;
+ virtual void Flush() = 0;
+ virtual void WaitForBuffers() = 0;
+ virtual bool AcceptsData() const = 0;
+ virtual bool HasData() const = 0;
+ virtual int GetLevel() const = 0;
+ virtual bool IsInited() const = 0;
+ virtual void SendMessage(CDVDMsg* pMsg, int priority = 0) = 0;
+ virtual void SetVolume(float fVolume) = 0;
+ virtual void SetMute(bool bOnOff) = 0;
+ virtual void SetDynamicRangeCompression(long drc) = 0;
+ virtual std::string GetPlayerInfo() = 0;
+ virtual int GetAudioBitrate() = 0;
+ virtual int GetAudioChannels() = 0;
+ virtual double GetCurrentPts() = 0;
+ virtual bool IsStalled() const = 0;
+ virtual bool IsPassthrough() const = 0;
+ virtual double GetDelay() = 0;
+ virtual double GetCacheTotal() = 0;
+ virtual float GetDynamicRangeAmplification() const = 0;
+ virtual bool IsEOS() = 0;
+};
diff --git a/xbmc/cores/omxplayer/Makefile.in b/xbmc/cores/omxplayer/Makefile.in
index e5cad70f2f..77c25aa212 100644
--- a/xbmc/cores/omxplayer/Makefile.in
+++ b/xbmc/cores/omxplayer/Makefile.in
@@ -1,7 +1,6 @@
CXXFLAGS += -D__STDC_FORMAT_MACROS
-SRCS = OMXPlayer.cpp
-SRCS += OMXAudio.cpp
+SRCS = OMXAudio.cpp
SRCS += OMXVideo.cpp
SRCS += OMXAudioCodecOMX.cpp
SRCS += OMXPlayerAudio.cpp
diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp
index a2f9b0cffa..7e854410eb 100644
--- a/xbmc/cores/omxplayer/OMXAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXAudio.cpp
@@ -65,7 +65,6 @@ static const uint16_t DTSFSCod [] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050
//////////////////////////////////////////////////////////////////////
//***********************************************************************************************
COMXAudio::COMXAudio() :
- m_pCallback (NULL ),
m_Initialized (false ),
m_CurrentVolume (0 ),
m_Mute (false ),
@@ -1393,25 +1392,6 @@ int COMXAudio::SetPlaySpeed(int iSpeed)
return 0;
}
-void COMXAudio::RegisterAudioCallback(IAudioCallback *pCallback)
-{
- CSingleLock lock (m_critSection);
- if(!m_Passthrough && !m_HWDecode)
- {
- m_pCallback = pCallback;
- if (m_pCallback)
- m_pCallback->OnInitialize(2, m_SampleRate, 32);
- }
- else
- m_pCallback = NULL;
-}
-
-void COMXAudio::UnRegisterAudioCallback()
-{
- CSingleLock lock (m_critSection);
- m_pCallback = NULL;
-}
-
unsigned int COMXAudio::GetAudioRenderingLatency() const
{
CSingleLock lock (m_critSection);
diff --git a/xbmc/cores/omxplayer/OMXAudio.h b/xbmc/cores/omxplayer/OMXAudio.h
index c86c1d1c8d..85a0b98d19 100644
--- a/xbmc/cores/omxplayer/OMXAudio.h
+++ b/xbmc/cores/omxplayer/OMXAudio.h
@@ -29,7 +29,6 @@
#include "cores/AudioEngine/Utils/AEAudioFormat.h"
#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "cores/IAudioCallback.h"
#include "linux/PlatformDefs.h"
#include "DVDStreamInfo.h"
@@ -55,8 +54,6 @@ extern "C" {
class COMXAudio
{
public:
- void UnRegisterAudioCallback();
- void RegisterAudioCallback(IAudioCallback* pCallback);
unsigned int GetChunkLen();
float GetDelay();
float GetCacheTime();
@@ -101,7 +98,6 @@ public:
float GetMaxLevel(double &pts);
private:
- IAudioCallback* m_pCallback;
bool m_Initialized;
float m_CurrentVolume;
bool m_Mute;
diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp
deleted file mode 100644
index 53fe37daae..0000000000
--- a/xbmc/cores/omxplayer/OMXPlayer.cpp
+++ /dev/null
@@ -1,4432 +0,0 @@
-/*
- * Copyright (C) 2011-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "system.h"
-
-#if defined (HAS_OMXPLAYER)
-
-#include <sstream>
-#include <iomanip>
-
-#include "OMXPlayerAudio.h"
-#include "OMXPlayerVideo.h"
-#include "OMXPlayer.h"
-#include "Application.h"
-#include "ApplicationMessenger.h"
-#include "GUIInfoManager.h"
-#include "cores/VideoRenderers/RenderManager.h"
-#include "cores/VideoRenderers/RenderFlags.h"
-#include "FileItem.h"
-#include "filesystem/File.h"
-#include "filesystem/SpecialProtocol.h"
-#include "guilib/GUIWindowManager.h"
-#include "settings/AdvancedSettings.h"
-#include "settings/MediaSettings.h"
-#include "settings/Settings.h"
-#include "threads/SingleLock.h"
-#include "windowing/WindowingFactory.h"
-
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "utils/URIUtils.h"
-#include "utils/Variant.h"
-#include "utils/StreamDetails.h"
-#include "xbmc/playlists/PlayListM3U.h"
-
-#include "utils/LangCodeExpander.h"
-#include "video/VideoReferenceClock.h"
-#include "guilib/LocalizeStrings.h"
-#include "guilib/Key.h"
-
-#include "storage/MediaManager.h"
-#include "GUIUserMessages.h"
-#include "utils/StreamUtils.h"
-
-#include "DVDInputStreams/DVDFactoryInputStream.h"
-#include "DVDInputStreams/DVDInputStreamNavigator.h"
-#include "DVDInputStreams/DVDInputStreamTV.h"
-#include "DVDInputStreams/DVDInputStreamPVRManager.h"
-
-#include "DVDDemuxers/DVDDemux.h"
-#include "DVDDemuxers/DVDDemuxUtils.h"
-#include "DVDDemuxers/DVDDemuxVobsub.h"
-#include "DVDDemuxers/DVDFactoryDemuxer.h"
-#include "DVDDemuxers/DVDDemuxFFmpeg.h"
-
-#include "DVDCodecs/DVDCodecs.h"
-#include "DVDCodecs/DVDFactoryCodec.h"
-
-#include "DVDFileInfo.h"
-
-#include "utils/LangCodeExpander.h"
-#include "guilib/Key.h"
-#include "guilib/LocalizeStrings.h"
-
-#include "utils/URIUtils.h"
-#include "GUIInfoManager.h"
-#include "guilib/GUIWindowManager.h"
-#include "guilib/StereoscopicsManager.h"
-#include "Application.h"
-#include "ApplicationMessenger.h"
-#include "filesystem/File.h"
-#include "pictures/Picture.h"
-#include "libswscale/swscale.h"
-#ifdef HAS_VIDEO_PLAYBACK
-#include "cores/VideoRenderers/RenderManager.h"
-#endif
-#ifdef HAS_PERFORMANCE_SAMPLE
-#include "xbmc/utils/PerformanceSample.h"
-#else
-#define MEASURE_FUNCTION
-#endif
-#include "settings/AdvancedSettings.h"
-#include "FileItem.h"
-#include "GUIUserMessages.h"
-#include "settings/Settings.h"
-#include "settings/MediaSettings.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "utils/StreamDetails.h"
-#include "pvr/PVRManager.h"
-#include "pvr/channels/PVRChannel.h"
-#include "pvr/addons/PVRClients.h"
-#include "filesystem/PVRFile.h"
-#include "video/dialogs/GUIDialogFullScreenInfo.h"
-#include "utils/StreamUtils.h"
-#include "utils/Variant.h"
-#include "storage/MediaManager.h"
-#include "dialogs/GUIDialogBusy.h"
-#include "dialogs/GUIDialogKaiToast.h"
-#include "xbmc/playlists/PlayListM3U.h"
-#include "utils/StringUtils.h"
-#include "Util.h"
-#include "LangInfo.h"
-#include "URL.h"
-#include "utils/LangCodeExpander.h"
-
-// video not playing from clock, but stepped
-#define TP(speed) ((speed) < 0 || (speed) > 4*DVD_PLAYSPEED_NORMAL)
-// audio not playing
-#define TPA(speed) ((speed) != DVD_PLAYSPEED_PAUSE && (speed) != DVD_PLAYSPEED_NORMAL)
-
-using namespace std;
-using namespace PVR;
-
-#define CSelectionStreams COMXSelectionStreams
-#define SelectionStreams OMXSelectionStreams
-#define SelectionStream OMXSelectionStream
-#define CDVDPlayer COMXPlayer
-#define m_dvdPlayerVideo m_omxPlayerVideo
-#define m_dvdPlayerAudio m_omxPlayerAudio
-#define CCurrentStream COMXCurrentStream
-
-void CSelectionStreams::Clear(StreamType type, StreamSource source)
-{
- CSingleLock lock(m_section);
- for(int i=m_Streams.size()-1;i>=0;i--)
- {
- if(type && m_Streams[i].type != type)
- continue;
-
- if(source && m_Streams[i].source != source)
- continue;
-
- m_Streams.erase(m_Streams.begin() + i);
- }
-}
-
-SelectionStream& CSelectionStreams::Get(StreamType type, int index)
-{
- CSingleLock lock(m_section);
- int count = -1;
- for(int i=0;i<(int)m_Streams.size();i++)
- {
- if(m_Streams[i].type != type)
- continue;
- count++;
- if(count == index)
- return m_Streams[i];
- }
- CLog::Log(LOGERROR, "%s - failed to get stream", __FUNCTION__);
- return m_invalid;
-}
-
-std::vector<SelectionStream> CSelectionStreams::Get(StreamType type)
-{
- std::vector<SelectionStream> streams;
- int count = Count(type);
- for(int index = 0; index < count; ++index){
- streams.push_back(Get(type, index));
- }
- return streams;
-}
-
-#define PREDICATE_RETURN(lh, rh) \
- do { \
- if((lh) != (rh)) \
- return (lh) > (rh); \
- } while(0)
-
-class PredicateSubtitleFilter
-{
-private:
- std::string audiolang;
- bool original;
-public:
- /** \brief The class' operator() decides if the given (subtitle) SelectionStream is relevant wrt.
- * preferred subtitle language and audio language. If the subtitle is relevant <B>false</B> false is returned.
- *
- * A subtitle is relevant if
- * - it was previously selected, or
- * - it's an external sub, or
- * - it's a forced sub and "original stream's language" was selected, or
- * - it's a forced sub and its language matches the audio's language, or
- * - it's a default sub, or
- * - its language matches the preferred subtitle's language (unequal to "original stream's language")
- */
- PredicateSubtitleFilter(std::string& lang)
- : audiolang(lang),
- original(StringUtils::EqualsNoCase(CSettings::Get().GetString("locale.subtitlelanguage"), "original"))
- {
- };
-
- bool operator()(const SelectionStream& ss) const
- {
- if (ss.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream)
- return false;
-
- if(STREAM_SOURCE_MASK(ss.source) == STREAM_SOURCE_DEMUX_SUB || STREAM_SOURCE_MASK(ss.source) == STREAM_SOURCE_TEXT)
- return false;
-
- if ((ss.flags & CDemuxStream::FLAG_FORCED) && (original || g_LangCodeExpander.CompareLangCodes(ss.language, audiolang)))
- return false;
-
- if ((ss.flags & CDemuxStream::FLAG_DEFAULT))
- return false;
-
- if(!original)
- {
- std::string subtitle_language = g_langInfo.GetSubtitleLanguage();
- if (g_LangCodeExpander.CompareLangCodes(subtitle_language, ss.language))
- return false;
- }
-
- return true;
- }
-};
-
-static bool PredicateAudioPriority(const SelectionStream& lh, const SelectionStream& rh)
-{
- PREDICATE_RETURN(lh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream
- , rh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream);
-
- // TrueHD never has enough cpu to decode on Pi, so prefer to avoid that
- PREDICATE_RETURN(lh.codec != "truehd"
- , rh.codec != "truehd");
-
- if(!StringUtils::EqualsNoCase(CSettings::Get().GetString("locale.audiolanguage"), "original"))
- {
- std::string audio_language = g_langInfo.GetAudioLanguage();
- PREDICATE_RETURN(g_LangCodeExpander.CompareLangCodes(audio_language, lh.language)
- , g_LangCodeExpander.CompareLangCodes(audio_language, rh.language));
- }
-
- PREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT
- , rh.flags & CDemuxStream::FLAG_DEFAULT);
-
- PREDICATE_RETURN(lh.channels
- , rh.channels);
-
- PREDICATE_RETURN(StreamUtils::GetCodecPriority(lh.codec)
- , StreamUtils::GetCodecPriority(rh.codec));
- return false;
-}
-
-/** \brief The class' operator() decides if the given (subtitle) SelectionStream lh is 'better than' the given (subtitle) SelectionStream rh.
-* If lh is 'better than' rh the return value is true, false otherwise.
-*
-* A subtitle lh is 'better than' a subtitle rh (in evaluation order) if
-* - lh was previously selected, or
-* - lh is an external sub and rh not, or
-* - lh is a forced sub and ("original stream's language" was selected or subtitles are off) and rh not, or
-* - lh is an external sub and its language matches the preferred subtitle's language (unequal to "original stream's language") and rh not, or
-* - lh is language matches the preferred subtitle's language (unequal to "original stream's language") and rh not, or
-* - lh is a default sub and rh not
-*/
-class PredicateSubtitlePriority
-{
-private:
- std::string audiolang;
- bool original;
- bool subson;
- PredicateSubtitleFilter filter;
-public:
- PredicateSubtitlePriority(std::string& lang)
- : audiolang(lang),
- original(StringUtils::EqualsNoCase(CSettings::Get().GetString("locale.subtitlelanguage"), "original")),
- subson(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn),
- filter(lang)
- {
- };
-
- bool relevant(const SelectionStream& ss) const
- {
- return !filter(ss);
- }
-
- bool operator()(const SelectionStream& lh, const SelectionStream& rh) const
- {
- PREDICATE_RETURN(relevant(lh)
- , relevant(rh));
-
- PREDICATE_RETURN(lh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream
- , rh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream);
-
- // prefer external subs
- PREDICATE_RETURN(STREAM_SOURCE_MASK(lh.source) == STREAM_SOURCE_DEMUX_SUB
- , STREAM_SOURCE_MASK(rh.source) == STREAM_SOURCE_DEMUX_SUB);
-
- PREDICATE_RETURN(STREAM_SOURCE_MASK(lh.source) == STREAM_SOURCE_TEXT
- , STREAM_SOURCE_MASK(rh.source) == STREAM_SOURCE_TEXT);
-
- if(!subson || original)
- {
- PREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_FORCED && g_LangCodeExpander.CompareLangCodes(lh.language, audiolang)
- , rh.flags & CDemuxStream::FLAG_FORCED && g_LangCodeExpander.CompareLangCodes(rh.language, audiolang));
-
- PREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_FORCED
- , rh.flags & CDemuxStream::FLAG_FORCED);
- }
-
- std::string subtitle_language = g_langInfo.GetSubtitleLanguage();
- if(!original)
- {
- PREDICATE_RETURN((STREAM_SOURCE_MASK(lh.source) == STREAM_SOURCE_DEMUX_SUB || STREAM_SOURCE_MASK(lh.source) == STREAM_SOURCE_TEXT) && g_LangCodeExpander.CompareLangCodes(subtitle_language, lh.language)
- , (STREAM_SOURCE_MASK(rh.source) == STREAM_SOURCE_DEMUX_SUB || STREAM_SOURCE_MASK(rh.source) == STREAM_SOURCE_TEXT) && g_LangCodeExpander.CompareLangCodes(subtitle_language, rh.language));
- }
-
- if(!original)
- {
- PREDICATE_RETURN(g_LangCodeExpander.CompareLangCodes(subtitle_language, lh.language)
- , g_LangCodeExpander.CompareLangCodes(subtitle_language, rh.language));
- }
-
- PREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT
- , rh.flags & CDemuxStream::FLAG_DEFAULT);
-
- return false;
- }
-};
-
-static bool PredicateVideoPriority(const SelectionStream& lh, const SelectionStream& rh)
-{
- PREDICATE_RETURN(lh.flags & CDemuxStream::FLAG_DEFAULT
- , rh.flags & CDemuxStream::FLAG_DEFAULT);
- return false;
-}
-
-bool CSelectionStreams::Get(StreamType type, CDemuxStream::EFlags flag, SelectionStream& out)
-{
- CSingleLock lock(m_section);
- for(int i=0;i<(int)m_Streams.size();i++)
- {
- if(m_Streams[i].type != type)
- continue;
- if((m_Streams[i].flags & flag) != flag)
- continue;
- out = m_Streams[i];
- return true;
- }
- return false;
-}
-
-int CSelectionStreams::IndexOf(StreamType type, int source, int id) const
-{
- CSingleLock lock(m_section);
- int count = -1;
- for(int i=0;i<(int)m_Streams.size();i++)
- {
- if(type && m_Streams[i].type != type)
- continue;
- count++;
- if(source && m_Streams[i].source != source)
- continue;
- if(id < 0)
- continue;
- if(m_Streams[i].id == id)
- return count;
- }
- if(id < 0)
- return count;
- else
- return -1;
-}
-
-int CSelectionStreams::IndexOf(StreamType type, CDVDPlayer& p) const
-{
- if (p.m_pInputStream && p.m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- int id = -1;
- if(type == STREAM_AUDIO)
- id = ((CDVDInputStreamNavigator*)p.m_pInputStream)->GetActiveAudioStream();
- else if(type == STREAM_VIDEO)
- id = p.m_CurrentVideo.id;
- else if(type == STREAM_SUBTITLE)
- id = ((CDVDInputStreamNavigator*)p.m_pInputStream)->GetActiveSubtitleStream();
-
- return IndexOf(type, STREAM_SOURCE_NAV, id);
- }
-
- if(type == STREAM_AUDIO)
- return IndexOf(type, p.m_CurrentAudio.source, p.m_CurrentAudio.id);
- else if(type == STREAM_VIDEO)
- return IndexOf(type, p.m_CurrentVideo.source, p.m_CurrentVideo.id);
- else if(type == STREAM_SUBTITLE)
- return IndexOf(type, p.m_CurrentSubtitle.source, p.m_CurrentSubtitle.id);
- else if(type == STREAM_TELETEXT)
- return IndexOf(type, p.m_CurrentTeletext.source, p.m_CurrentTeletext.id);
-
- return -1;
-}
-
-int CSelectionStreams::Source(StreamSource source, std::string filename)
-{
- CSingleLock lock(m_section);
- int index = source - 1;
- for(int i=0;i<(int)m_Streams.size();i++)
- {
- SelectionStream &s = m_Streams[i];
- if(STREAM_SOURCE_MASK(s.source) != source)
- continue;
- // if it already exists, return same
- if(s.filename == filename)
- return s.source;
- if(index < s.source)
- index = s.source;
- }
- // return next index
- return index + 1;
-}
-
-void CSelectionStreams::Update(SelectionStream& s)
-{
- CSingleLock lock(m_section);
- int index = IndexOf(s.type, s.source, s.id);
- if(index >= 0)
- {
- SelectionStream& o = Get(s.type, index);
- s.type_index = o.type_index;
- o = s;
- }
- else
- {
- s.type_index = Count(s.type);
- m_Streams.push_back(s);
- }
-}
-
-void CSelectionStreams::Update(CDVDInputStream* input, CDVDDemux* demuxer)
-{
- if(input && input->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- CDVDInputStreamNavigator* nav = (CDVDInputStreamNavigator*)input;
- string filename = nav->GetFileName();
- int source = Source(STREAM_SOURCE_NAV, filename);
-
- int count;
- count = nav->GetAudioStreamCount();
- for(int i=0;i<count;i++)
- {
- SelectionStream s;
- s.source = source;
- s.type = STREAM_AUDIO;
- s.id = i;
- s.flags = CDemuxStream::FLAG_NONE;
- s.filename = filename;
-
- DVDNavStreamInfo info;
- nav->GetAudioStreamInfo(i, info);
- s.name = info.name;
- s.language = g_LangCodeExpander.ConvertToISO6392T(info.language);
- s.channels = info.channels;
- Update(s);
- }
-
- count = nav->GetSubTitleStreamCount();
- for(int i=0;i<count;i++)
- {
- SelectionStream s;
- s.source = source;
- s.type = STREAM_SUBTITLE;
- s.id = i;
- s.flags = CDemuxStream::FLAG_NONE;
- s.filename = filename;
- s.channels = 0;
-
- DVDNavStreamInfo info;
- nav->GetSubtitleStreamInfo(i, info);
- s.name = info.name;
- s.language = g_LangCodeExpander.ConvertToISO6392T(info.language);
- Update(s);
- }
- }
- else if(demuxer)
- {
- string filename = demuxer->GetFileName();
- int count = demuxer->GetNrOfStreams();
- int source;
- if(input) /* hack to know this is sub decoder */
- source = Source(STREAM_SOURCE_DEMUX, filename);
- else
- source = Source(STREAM_SOURCE_DEMUX_SUB, filename);
-
-
- for(int i=0;i<count;i++)
- {
- CDemuxStream* stream = demuxer->GetStream(i);
- /* skip streams with no type */
- if (stream->type == STREAM_NONE)
- continue;
- /* make sure stream is marked with right source */
- stream->source = source;
-
- SelectionStream s;
- s.source = source;
- s.type = stream->type;
- s.id = stream->iId;
- s.language = g_LangCodeExpander.ConvertToISO6392T(stream->language);
- s.flags = stream->flags;
- s.filename = demuxer->GetFileName();
- stream->GetStreamName(s.name);
- std::string codec;
- demuxer->GetStreamCodecName(stream->iId, codec);
- s.codec = codec;
- s.channels = 0; // Default to 0. Overwrite if STREAM_AUDIO below.
- if(stream->type == STREAM_AUDIO)
- {
- std::string type;
- ((CDemuxStreamAudio*)stream)->GetStreamType(type);
- if(type.length() > 0)
- {
- if(s.name.length() > 0)
- s.name += " - ";
- s.name += type;
- }
- s.channels = ((CDemuxStreamAudio*)stream)->iChannels;
- }
- Update(s);
- }
- }
-}
-
-CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
- : IPlayer(callback),
- CThread("OMXPlayer"),
- m_CurrentAudio(STREAM_AUDIO, DVDPLAYER_AUDIO),
- m_CurrentVideo(STREAM_VIDEO, DVDPLAYER_VIDEO),
- m_CurrentSubtitle(STREAM_SUBTITLE, DVDPLAYER_SUBTITLE),
- m_CurrentTeletext(STREAM_TELETEXT, DVDPLAYER_TELETEXT),
- m_messenger("player"),
- m_dvdPlayerVideo(&m_av_clock, &m_overlayContainer, m_messenger),
- m_dvdPlayerAudio(&m_av_clock, m_messenger),
- m_dvdPlayerSubtitle(&m_overlayContainer),
- m_dvdPlayerTeletext(),
- m_ready(true),
- m_DemuxerPausePending(false)
-{
- m_pDemuxer = NULL;
- m_pSubtitleDemuxer = NULL;
- m_pInputStream = NULL;
-
- m_dvd.Clear();
- m_State.Clear();
- m_EdlAutoSkipMarkers.Clear();
- m_UpdateApplication = 0;
-
- m_bAbortRequest = false;
- m_errorCount = 0;
- m_offset_pts = 0.0;
- m_playSpeed = DVD_PLAYSPEED_NORMAL;
- m_caching = CACHESTATE_DONE;
- m_HasVideo = false;
- m_HasAudio = false;
- m_stepped = false;
- m_video_fifo = 0;
- m_audio_fifo = 0;
- m_last_check_time = 0.0;
- m_stamp = 0.0;
-
- memset(&m_SpeedState, 0, sizeof(m_SpeedState));
-}
-
-CDVDPlayer::~CDVDPlayer()
-{
- CloseFile();
-}
-
-bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
-{
- CLog::Log(LOGNOTICE, "DVDPlayer: Opening: %s", CURL::GetRedacted(file.GetPath()).c_str());
-
- // if playing a file close it first
- // this has to be changed so we won't have to close it.
- if(IsRunning())
- CloseFile();
-
- m_bAbortRequest = false;
- SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
-
- m_State.Clear();
- m_UpdateApplication = 0;
- m_offset_pts = 0;
-
- m_PlayerOptions = options;
- m_item = file;
- m_mimetype = file.GetMimeType();
- m_filename = file.GetPath();
-
- m_ready.Reset();
-
-#if defined(HAS_VIDEO_PLAYBACK)
- g_renderManager.PreInit();
-#endif
-
- Create();
-
- // wait for the ready event
- CGUIDialogBusy::WaitOnEvent(m_ready, g_advancedSettings.m_videoBusyDialogDelay_ms, false);
-
- // Playback might have been stopped due to some error
- if (m_bStop || m_bAbortRequest)
- return false;
-
- return true;
-}
-
-bool CDVDPlayer::CloseFile(bool reopen)
-{
- CLog::Log(LOGNOTICE, "CDVDPlayer::CloseFile()");
-
- // set the abort request so that other threads can finish up
- m_bAbortRequest = true;
-
- // tell demuxer to abort
- if(m_pDemuxer)
- m_pDemuxer->Abort();
-
- if(m_pSubtitleDemuxer)
- m_pSubtitleDemuxer->Abort();
-
- if(m_pInputStream)
- m_pInputStream->Abort();
-
- CLog::Log(LOGNOTICE, "DVDPlayer: waiting for threads to exit");
-
- // wait for the main thread to finish up
- // since this main thread cleans up all other resources and threads
- // we are done after the StopThread call
- StopThread();
-
- m_Edl.Clear();
- m_EdlAutoSkipMarkers.Clear();
-
- m_HasVideo = false;
- m_HasAudio = false;
-
- CLog::Log(LOGNOTICE, "DVDPlayer: finished waiting");
-#if defined(HAS_VIDEO_PLAYBACK)
- g_renderManager.UnInit();
-#endif
- return true;
-}
-
-bool CDVDPlayer::IsPlaying() const
-{
- return !m_bStop;
-}
-
-void CDVDPlayer::OnStartup()
-{
- m_CurrentVideo.Clear();
- m_CurrentAudio.Clear();
- m_CurrentSubtitle.Clear();
- m_CurrentTeletext.Clear();
-
- m_messenger.Init();
-
- CUtil::ClearTempFonts();
-}
-
-bool CDVDPlayer::OpenInputStream()
-{
- if(m_pInputStream)
- SAFE_DELETE(m_pInputStream);
-
- CLog::Log(LOGNOTICE, "Creating InputStream");
-
- // correct the filename if needed
- std::string filename(m_filename);
- if (URIUtils::IsProtocol(filename, "dvd")
- || StringUtils::EqualsNoCase(filename, "iso9660://video_ts/video_ts.ifo"))
- {
- m_filename = g_mediaManager.TranslateDevicePath("");
- }
-
- m_pInputStream = CDVDFactoryInputStream::CreateInputStream(this, m_filename, m_mimetype);
- if(m_pInputStream == NULL)
- {
- CLog::Log(LOGERROR, "CDVDPlayer::OpenInputStream - unable to create input stream for [%s]", m_filename.c_str());
- return false;
- }
- else
- m_pInputStream->SetFileItem(m_item);
-
- if (!m_pInputStream->Open(m_filename.c_str(), m_mimetype))
- {
- CLog::Log(LOGERROR, "CDVDPlayer::OpenInputStream - error opening [%s]", m_filename.c_str());
- return false;
- }
-
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
- || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY))
- {
- CLog::Log(LOGINFO, "CDVDPlayer::OpenInputStream - DVD/BD not supported - Will try...");
- }
-
- // 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))
- {
- // find any available external subtitles
- std::vector<std::string> filenames;
- CUtil::ScanForExternalSubtitles( m_filename, filenames );
-
- // load any subtitles from file item
- std::string key("subtitle:1");
- for(unsigned s = 1; m_item.HasProperty(key); key = StringUtils::Format("subtitle:%u", ++s))
- filenames.push_back(m_item.GetProperty(key).asString());
-
- for(unsigned int i=0;i<filenames.size();i++)
- {
- // if vobsub subtitle:
- if (URIUtils::HasExtension(filenames[i], ".idx"))
- {
- std::string strSubFile;
- if ( CUtil::FindVobSubPair( filenames, filenames[i], strSubFile ) )
- AddSubtitleFile(filenames[i], strSubFile);
- }
- else
- {
- if ( !CUtil::IsVobSub(filenames, filenames[i] ) )
- {
- AddSubtitleFile(filenames[i]);
- }
- }
- } // end loop over all subtitle files
-
- CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleCached = true;
- }
-
- SetAVDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay);
- SetSubTitleDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleDelay);
- m_clock.Reset();
- m_dvd.Clear();
- m_errorCount = 0;
- m_ChannelEntryTimeOut.SetInfinite();
-
- return true;
-}
-
-bool CDVDPlayer::OpenDemuxStream()
-{
- if(m_pDemuxer)
- SAFE_DELETE(m_pDemuxer);
-
- CLog::Log(LOGNOTICE, "Creating Demuxer");
-
- int attempts = 10;
- while(!m_bStop && attempts-- > 0)
- {
- m_pDemuxer = CDVDFactoryDemuxer::CreateDemuxer(m_pInputStream);
- if(!m_pDemuxer && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER))
- {
- continue;
- }
- else if(!m_pDemuxer && m_pInputStream->NextStream() != CDVDInputStream::NEXTSTREAM_NONE)
- {
- CLog::Log(LOGDEBUG, "%s - New stream available from input, retry open", __FUNCTION__);
- continue;
- }
- break;
- }
-
- if(!m_pDemuxer)
- {
- CLog::Log(LOGERROR, "%s - Error creating demuxer", __FUNCTION__);
- return false;
- }
-
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NAV);
- m_SelectionStreams.Update(m_pInputStream, m_pDemuxer);
-
- int64_t len = m_pInputStream->GetLength();
- int64_t tim = m_pDemuxer->GetStreamLength();
- if(len > 0 && tim > 0)
- m_pInputStream->SetReadRate(g_advancedSettings.m_readBufferFactor * len * 1000 / tim);
-
- return true;
-}
-
-void CDVDPlayer::OpenDefaultStreams(bool reset)
-{
- // if input stream dictate, we will open later
- if(m_dvd.iSelectedAudioStream >= 0
- || m_dvd.iSelectedSPUStream >= 0)
- return;
-
- SelectionStreams streams;
- bool valid;
-
- // open video stream
- streams = m_SelectionStreams.Get(STREAM_VIDEO, PredicateVideoPriority);
- valid = false;
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
- {
- if(OpenStream(m_CurrentVideo, it->id, it->source, reset))
- valid = true;
- }
- if(!valid)
- CloseStream(m_CurrentVideo, true);
-
- // open audio stream
- if(m_PlayerOptions.video_only)
- streams.clear();
- else
- streams = m_SelectionStreams.Get(STREAM_AUDIO, PredicateAudioPriority);
- valid = false;
-
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
- {
- if(OpenStream(m_CurrentAudio, it->id, it->source, reset))
- valid = true;
- }
- if(!valid)
- CloseStream(m_CurrentAudio, true);
-
- // enable or disable subtitles
- bool visible = CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn;
-
- // open subtitle stream
- SelectionStream as = m_SelectionStreams.Get(STREAM_AUDIO, GetAudioStream());
- PredicateSubtitlePriority psp(as.language);
- streams = m_SelectionStreams.Get(STREAM_SUBTITLE, psp);
- valid = false;
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
- {
- if(OpenStream(m_CurrentSubtitle, it->id, it->source))
- {
- valid = true;
- if(!psp.relevant(*it))
- visible = false;
- else if(it->flags & CDemuxStream::FLAG_FORCED)
- visible = true;
- }
- }
- if(!valid)
- CloseStream(m_CurrentSubtitle, true);
-
- SetSubtitleVisibleInternal(visible);
-
- // open teletext stream
- streams = m_SelectionStreams.Get(STREAM_TELETEXT);
- valid = false;
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
- {
- if(OpenStream(m_CurrentTeletext, it->id, it->source))
- valid = true;
- }
- if(!valid)
- CloseStream(m_CurrentTeletext, true);
-}
-
-bool CDVDPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
-{
-
- // check if we should read from subtitle demuxer
- if( m_pSubtitleDemuxer && m_dvdPlayerSubtitle.AcceptsData() )
- {
- packet = m_pSubtitleDemuxer->Read();
-
- if(packet)
- {
- UpdateCorrection(packet, m_offset_pts);
- if(packet->iStreamId < 0)
- return true;
-
- stream = m_pSubtitleDemuxer->GetStream(packet->iStreamId);
- if (!stream)
- {
- CLog::Log(LOGERROR, "%s - Error demux packet doesn't belong to a valid stream", __FUNCTION__);
- return false;
- }
- if(stream->source == STREAM_SOURCE_NONE)
- {
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX_SUB);
- m_SelectionStreams.Update(NULL, m_pSubtitleDemuxer);
- }
- return true;
- }
- }
-
- // read a data frame from stream.
- if(m_pDemuxer)
- packet = m_pDemuxer->Read();
-
- if(packet)
- {
- // stream changed, update and open defaults
- if(packet->iStreamId == DMX_SPECIALID_STREAMCHANGE)
- {
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);
- m_SelectionStreams.Update(m_pInputStream, m_pDemuxer);
- OpenDefaultStreams(false);
-
- // reevaluate HasVideo/Audio, we may have switched from/to a radio channel
- if(m_CurrentVideo.id < 0)
- m_HasVideo = false;
- if(m_CurrentAudio.id < 0)
- m_HasAudio = false;
-
- return true;
- }
-
- UpdateCorrection(packet, m_offset_pts);
-
- if(packet->iStreamId < 0)
- return true;
-
- if(m_pDemuxer)
- {
- stream = m_pDemuxer->GetStream(packet->iStreamId);
- if (!stream)
- {
- CLog::Log(LOGERROR, "%s - Error demux packet doesn't belong to a valid stream", __FUNCTION__);
- return false;
- }
- if(stream->source == STREAM_SOURCE_NONE)
- {
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_DEMUX);
- m_SelectionStreams.Update(m_pInputStream, m_pDemuxer);
- }
- }
- return true;
- }
- return false;
-}
-
-bool CDVDPlayer::IsValidStream(CCurrentStream& stream)
-{
- if(stream.id<0)
- return true; // we consider non selected as valid
-
- int source = STREAM_SOURCE_MASK(stream.source);
- if(source == STREAM_SOURCE_TEXT)
- return true;
- if(source == STREAM_SOURCE_DEMUX_SUB)
- {
- CDemuxStream* st = m_pSubtitleDemuxer->GetStream(stream.id);
- if(st == NULL || st->disabled)
- return false;
- if(st->type != stream.type)
- return false;
- return true;
- }
- if(source == STREAM_SOURCE_DEMUX)
- {
- CDemuxStream* st = m_pDemuxer->GetStream(stream.id);
- if(st == NULL || st->disabled)
- return false;
- if(st->type != stream.type)
- return false;
-
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- if(stream.type == STREAM_AUDIO && st->iPhysicalId != m_dvd.iSelectedAudioStream)
- return false;
- if(stream.type == STREAM_SUBTITLE && st->iPhysicalId != m_dvd.iSelectedSPUStream)
- return false;
- }
-
- return true;
- }
-
- return false;
-}
-
-bool CDVDPlayer::IsBetterStream(CCurrentStream& current, CDemuxStream* stream)
-{
- // Do not reopen non-video streams if we're in video-only mode
- 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) ) )
- {
- int source_type;
-
- source_type = STREAM_SOURCE_MASK(current.source);
- if(source_type != STREAM_SOURCE_DEMUX
- && source_type != STREAM_SOURCE_NONE)
- return false;
-
- source_type = STREAM_SOURCE_MASK(stream->source);
- if(source_type != STREAM_SOURCE_DEMUX
- || stream->type != current.type
- || stream->iId == current.id)
- return false;
-
- if(current.type == STREAM_AUDIO && stream->iPhysicalId == m_dvd.iSelectedAudioStream)
- return true;
- if(current.type == STREAM_SUBTITLE && stream->iPhysicalId == m_dvd.iSelectedSPUStream)
- return true;
- if(current.type == STREAM_VIDEO && current.id < 0)
- return true;
- }
- else
- {
- if(stream->source == current.source
- && stream->iId == current.id)
- return false;
-
- if(stream->type != current.type)
- return false;
-
- if(current.type == STREAM_SUBTITLE)
- return false;
-
- if(current.id < 0)
- return true;
- }
- return false;
-}
-
-void CDVDPlayer::CheckBetterStream(CCurrentStream& current, CDemuxStream* stream)
-{
- IDVDStreamPlayer* player = GetStreamPlayer(current.player);
- if (!IsValidStream(current) && (player == NULL || player->IsStalled()))
- CloseStream(current, true);
-
- if (IsBetterStream(current, stream))
- OpenStream(current, stream->iId, stream->source);
-}
-
-void CDVDPlayer::Process()
-{
- bool bOmxWaitVideo = false;
- bool bOmxWaitAudio = false;
- bool bOmxSentEOFs = false;
- float m_threshold = 0.2f;
-
- if (!OpenInputStream())
- {
- m_bAbortRequest = true;
- return;
- }
-
- if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
- {
- CLog::Log(LOGNOTICE, "DVDPlayer: playing a file with menu's");
- if(dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
- m_PlayerOptions.starttime = 0;
-
- if(m_PlayerOptions.state.size() > 0)
- 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;
- }
-
- if(!OpenDemuxStream())
- {
- m_bAbortRequest = true;
- return;
- }
-
- // allow renderer to switch to fullscreen if requested
- m_dvdPlayerVideo.EnableFullscreen(m_PlayerOptions.fullscreen);
-
- if(!m_av_clock.OMXInitialize(&m_clock))
- {
- m_bAbortRequest = true;
- return;
- }
- if(CSettings::Get().GetInt("videoplayer.adjustrefreshrate") != ADJUST_REFRESHRATE_OFF)
- m_av_clock.HDMIClockSync();
- m_av_clock.OMXStateIdle();
- m_av_clock.OMXStop();
- m_av_clock.OMXPause();
-
- OpenDefaultStreams();
-
- // look for any EDL files
- m_Edl.Clear();
- m_EdlAutoSkipMarkers.Clear();
- if (m_CurrentVideo.id >= 0 && m_CurrentVideo.hint.fpsrate > 0 && m_CurrentVideo.hint.fpsscale > 0)
- {
- float fFramesPerSecond = (float)m_CurrentVideo.hint.fpsrate / (float)m_CurrentVideo.hint.fpsscale;
- m_Edl.ReadEditDecisionLists(m_filename, fFramesPerSecond, m_CurrentVideo.hint.height);
- }
-
- /*
- * Check to see if the demuxer should start at something other than time 0. This will be the case
- * if there was a start time specified as part of the "Start from where last stopped" (aka
- * auto-resume) feature or if there is an EDL cut or commercial break that starts at time 0.
- */
- CEdl::Cut cut;
- int starttime = 0;
- if(m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0)
- {
- if (m_PlayerOptions.startpercent > 0 && m_pDemuxer)
- {
- int64_t playerStartTime = (int64_t) ( ( (float) m_pDemuxer->GetStreamLength() ) * ( m_PlayerOptions.startpercent/(float)100 ) );
- starttime = m_Edl.RestoreCutTime(playerStartTime);
- }
- else
- {
- starttime = m_Edl.RestoreCutTime((int64_t)m_PlayerOptions.starttime * 1000); // s to ms
- }
- CLog::Log(LOGDEBUG, "%s - Start position set to last stopped position: %d", __FUNCTION__, starttime);
- }
- else if(m_Edl.InCut(0, &cut)
- && (cut.action == CEdl::CUT || cut.action == CEdl::COMM_BREAK))
- {
- starttime = cut.end;
- CLog::Log(LOGDEBUG, "%s - Start position set to end of first cut or commercial break: %d", __FUNCTION__, starttime);
- if(cut.action == CEdl::COMM_BREAK)
- {
- /*
- * Setup auto skip markers as if the commercial break had been skipped using standard
- * detection.
- */
- m_EdlAutoSkipMarkers.commbreak_start = cut.start;
- m_EdlAutoSkipMarkers.commbreak_end = cut.end;
- m_EdlAutoSkipMarkers.seek_to_start = true;
- }
- }
- if(starttime > 0)
- {
- double startpts = DVD_NOPTS_VALUE;
- if(m_pDemuxer)
- {
- if (m_pDemuxer->SeekTime(starttime, false, &startpts))
- CLog::Log(LOGDEBUG, "%s - starting demuxer from: %d", __FUNCTION__, starttime);
- else
- CLog::Log(LOGDEBUG, "%s - failed to start demuxing from: %d", __FUNCTION__, starttime);
- }
-
- if(m_pSubtitleDemuxer)
- {
- if(m_pSubtitleDemuxer->SeekTime(starttime, false, &startpts))
- CLog::Log(LOGDEBUG, "%s - starting subtitle demuxer from: %d", __FUNCTION__, starttime);
- else
- CLog::Log(LOGDEBUG, "%s - failed to start subtitle demuxing from: %d", __FUNCTION__, starttime);
- }
- }
-
- // make sure all selected stream have data on startup
- if (CachePVRStream())
- SetCaching(CACHESTATE_PVR);
-
- // make sure application know our info
- UpdateApplication(0);
- UpdatePlayState(0);
-
- if(m_PlayerOptions.identify == false)
- m_callback.OnPlayBackStarted();
-
- // we are done initializing now, set the readyevent
- m_ready.Set();
-
- if (!CachePVRStream())
- SetCaching(CACHESTATE_FLUSH);
-
- EDEINTERLACEMODE current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
-
- while (!m_bAbortRequest)
- {
- double now = CDVDClock::GetAbsoluteClock();
- if (m_last_check_time == 0.0 || m_last_check_time + DVD_MSEC_TO_TIME(20) <= now)
- {
- m_last_check_time = now;
- m_stamp = m_av_clock.OMXMediaTime();
- const bool m_Pause = m_playSpeed == DVD_PLAYSPEED_PAUSE;
- const bool not_accepts_data = (!m_dvdPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0) ||
- (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0);
- /* when the video/audio fifos are low, we pause clock, when high we resume */
- double audio_pts = floor(m_dvdPlayerAudio.GetCurrentPts());
- double video_pts = floor(m_dvdPlayerVideo.GetCurrentPts());
-
- float audio_fifo = audio_pts / DVD_TIME_BASE - m_stamp * 1e-6;
- float video_fifo = video_pts / DVD_TIME_BASE - m_stamp * 1e-6;
- float threshold = 0.1f;
- bool audio_fifo_low = false, video_fifo_low = false, audio_fifo_high = false, video_fifo_high = false;
-
- // if deinterlace setting has changed, we should close and open video
- if (current_deinterlace != CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode)
- {
- CloseStream(m_CurrentVideo, false);
- OpenStream(m_CurrentVideo, m_CurrentVideo.id, m_CurrentVideo.source);
- if (m_State.canseek)
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
- current_deinterlace = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
- }
-
- m_video_fifo = (int)(100.0*(m_dvdPlayerVideo.GetDecoderBufferSize()-m_dvdPlayerVideo.GetDecoderFreeSpace())/m_dvdPlayerVideo.GetDecoderBufferSize());
- m_audio_fifo = (int)(100.0*audio_fifo/m_dvdPlayerAudio.GetCacheTotal());
-
- #ifdef _DEBUG
- static unsigned count;
- if ((count++ & 7) == 0)
- {
- char response[80];
- if (m_dvdPlayerVideo.GetDecoderBufferSize() && m_dvdPlayerAudio.GetCacheTotal())
- vc_gencmd(response, sizeof response, "render_bar 4 video_fifo %d %d %d %d",
- m_video_fifo,
- (int)(100.0*video_fifo/m_dvdPlayerAudio.GetCacheTotal()),
- 0, 100);
- if (m_dvdPlayerAudio.GetCacheTotal())
- vc_gencmd(response, sizeof response, "render_bar 5 audio_fifo %d %d %d %d",
- m_audio_fifo,
- (int)(100.0*m_dvdPlayerAudio.GetDelay()/m_dvdPlayerAudio.GetCacheTotal()),
- 0, 100);
- vc_gencmd(response, sizeof response, "render_bar 6 video_queue %d %d %d %d",
- m_dvdPlayerVideo.GetLevel(), 0, 0, 100);
- vc_gencmd(response, sizeof response, "render_bar 7 audio_queue %d %d %d %d",
- m_dvdPlayerAudio.GetLevel(), 0, 0, 100);
- }
- #endif
- if (audio_pts != DVD_NOPTS_VALUE)
- {
- audio_fifo_low = m_HasAudio && audio_fifo < threshold;
- audio_fifo_high = audio_pts != DVD_NOPTS_VALUE && audio_fifo >= m_threshold;
- }
- if (video_pts != DVD_NOPTS_VALUE)
- {
- video_fifo_low = m_HasVideo && video_fifo < threshold;
- video_fifo_high = video_pts != DVD_NOPTS_VALUE && video_fifo >= m_threshold;
- }
- if (!m_HasAudio && m_HasVideo)
- audio_fifo_high = true;
- if (!m_HasVideo && m_HasAudio)
- video_fifo_high = true;
-
- #ifdef _DEBUG
- CLog::Log(LOGDEBUG, "%s - M:%.6f-%.6f (A:%.6f V:%.6f) PEF:%d%d%d S:%.2f A:%.2f V:%.2f/T:%.2f (A:%d%d V:%d%d) A:%d%% V:%d%% (%.2f,%.2f)", __FUNCTION__,
- m_stamp*1e-6, m_av_clock.OMXClockAdjustment()*1e-6, audio_pts*1e-6, video_pts*1e-6, m_av_clock.OMXIsPaused(), bOmxSentEOFs, not_accepts_data, m_playSpeed * (1.0f/DVD_PLAYSPEED_NORMAL),
- audio_pts == DVD_NOPTS_VALUE ? 0.0:audio_fifo, video_pts == DVD_NOPTS_VALUE ? 0.0:video_fifo, m_threshold,
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high,
- m_dvdPlayerAudio.GetLevel(), m_dvdPlayerVideo.GetLevel(), m_dvdPlayerAudio.GetDelay(), (float)m_dvdPlayerAudio.GetCacheTotal());
- #endif
-
- if (TP(m_playSpeed))
- {
- if (m_CurrentVideo.started)
- {
- if (m_stamp == 0.0 && (!m_stepped || m_playSpeed > 0))
- {
- /* trickplay modes progress by stepping */
- CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking step speed:%.2f last:%.2f v:%.2f", (double)m_playSpeed / DVD_PLAYSPEED_NORMAL, m_SpeedState.lastpts*1e-6, video_pts*1e-6);
- m_av_clock.OMXStep();
- }
- else
- {
- m_av_clock.OMXMediaTime(0.0);
- m_last_check_time = 0.0;
- m_stepped = true;
- }
- }
- }
- else if(!m_Pause && (bOmxSentEOFs || not_accepts_data || (audio_fifo_high && video_fifo_high)))
- {
- if (m_av_clock.OMXIsPaused())
- {
- CLog::Log(LOGDEBUG, "Resume %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
- m_av_clock.OMXStateExecute();
- m_av_clock.OMXResume();
- }
- }
- else if (m_Pause || audio_fifo_low || video_fifo_low)
- {
- if (!m_av_clock.OMXIsPaused() && !TPA(m_playSpeed))
- {
- if (!m_Pause)
- m_threshold = std::min(2.0f*m_threshold, 16.0f);
- CLog::Log(LOGDEBUG, "Pause %.2f,%.2f (A:%d%d V:%d%d) EOF:%d FULL:%d T:%.2f\n", audio_fifo, video_fifo,
- audio_fifo_low, audio_fifo_high, video_fifo_low, video_fifo_high, bOmxSentEOFs, not_accepts_data, m_threshold);
- m_av_clock.OMXPause();
- }
- }
- }
- HandleMessages();
-
- if(m_bAbortRequest)
- break;
-
- // should we open a new input stream?
- if(!m_pInputStream)
- {
- if (OpenInputStream() == false)
- {
- CLog::Log(LOGERROR, "%s - Closing stream due to OpenInputStream()", __FUNCTION__);
- m_bAbortRequest = true;
- break;
- }
- }
-
- // should we open a new demuxer?
- if(!m_pDemuxer)
- {
- if (m_pInputStream->NextStream() == CDVDInputStream::NEXTSTREAM_NONE)
- break;
-
- if (m_pInputStream->IsEOF())
- break;
-
- if (OpenDemuxStream() == false)
- {
- CLog::Log(LOGERROR, "%s - Closing stream due to OpenDemuxStream()", __FUNCTION__);
- m_bAbortRequest = true;
- break;
- }
-
- OpenDefaultStreams();
-
- // never allow first frames after open to be skipped
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
-
- if (CachePVRStream())
- SetCaching(CACHESTATE_PVR);
-
- UpdateApplication(0);
- UpdatePlayState(0);
- }
-
- // handle eventual seeks due to playspeed
- HandlePlaySpeed();
-
- // update player state
- UpdatePlayState(200);
-
- // update application with our state
- UpdateApplication(1000);
-
- // make sure we run subtitle process here
- m_dvdPlayerSubtitle.Process(m_clock.GetClock() + m_State.time_offset - m_dvdPlayerVideo.GetSubtitleDelay(), m_State.time_offset);
-
- // OMX emergency exit
- if(HasAudio() && m_dvdPlayerAudio.BadState())
- {
- CLog::Log(LOGERROR, "%s - Closing stream due to m_dvdPlayerAudio.BadState()", __FUNCTION__);
- m_bAbortRequest = true;
- break;
- }
-
- if (CheckDelayedChannelEntry())
- continue;
-
- // if the queues are full, no need to read more
- if ((!m_dvdPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0) ||
- (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0))
- {
- if(m_pDemuxer && m_DemuxerPausePending)
- {
- m_DemuxerPausePending = false;
- m_pDemuxer->SetSpeed(DVD_PLAYSPEED_PAUSE);
- }
-
- Sleep(10);
- continue;
- }
-
- // always yield to players if they have data levels > 50 percent
- if((m_dvdPlayerAudio.GetLevel() > 50 || m_CurrentAudio.id < 0)
- && (m_dvdPlayerVideo.GetLevel() > 50 || m_CurrentVideo.id < 0))
- Sleep(0);
-
- DemuxPacket* pPacket = NULL;
- CDemuxStream *pStream = NULL;
- ReadPacket(pPacket, pStream);
- if (pPacket && !pStream)
- {
- /* probably a empty packet, just free it and move on */
- CDVDDemuxUtils::FreeDemuxPacket(pPacket);
- continue;
- }
- if (pPacket)
- {
- // reset eos state when we get a packet (e.g. for case of seek after eos)
- bOmxWaitVideo = false;
- bOmxWaitAudio = false;
- bOmxSentEOFs = false;
- }
- if (!pPacket)
- {
- // when paused, demuxer could be be returning empty
- if (m_playSpeed == DVD_PLAYSPEED_PAUSE)
- continue;
-
- // check for a still frame state
- if (CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
- {
- // stills will be skipped
- if(m_dvd.state == DVDSTATE_STILL)
- {
- if (m_dvd.iDVDStillTime > 0)
- {
- if ((XbmcThreads::SystemClockMillis() - m_dvd.iDVDStillStartTime) >= m_dvd.iDVDStillTime)
- {
- m_dvd.iDVDStillTime = 0;
- m_dvd.iDVDStillStartTime = 0;
- m_dvd.state = DVDSTATE_NORMAL;
- pStream->SkipStill();
- continue;
- }
- }
- }
- }
-
- // if there is another stream available, reopen demuxer
- CDVDInputStream::ENextStream next = m_pInputStream->NextStream();
- if(next == CDVDInputStream::NEXTSTREAM_OPEN)
- {
- SAFE_DELETE(m_pDemuxer);
- m_CurrentAudio.stream = NULL;
- m_CurrentVideo.stream = NULL;
- m_CurrentSubtitle.stream = NULL;
- continue;
- }
-
- // input stream asked us to just retry
- if(next == CDVDInputStream::NEXTSTREAM_RETRY)
- {
- Sleep(100);
- continue;
- }
-
- // make sure we tell all players to finish it's data
- if (!bOmxSentEOFs)
- {
- if(m_CurrentAudio.inited)
- {
- m_dvdPlayerAudio.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
- bOmxWaitAudio = true;
- }
- if(m_CurrentVideo.inited)
- {
- m_dvdPlayerVideo.SendMessage (new CDVDMsg(CDVDMsg::GENERAL_EOF));
- bOmxWaitVideo = true;
- }
- if(m_CurrentSubtitle.inited)
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
- if(m_CurrentTeletext.inited)
- m_dvdPlayerTeletext.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
- m_CurrentAudio.inited = false;
- m_CurrentVideo.inited = false;
- m_CurrentSubtitle.inited = false;
- m_CurrentTeletext.inited = false;
- bOmxSentEOFs = true;
- }
-
- // if we are caching, start playing it again
- SetCaching(CACHESTATE_DONE);
-
- // while players are still playing, keep going to allow seekbacks
- if(m_dvdPlayerAudio.HasData()
- || m_dvdPlayerVideo.HasData())
- {
- Sleep(100);
- continue;
- }
-
- // wait for omx components to finish
- if(bOmxWaitVideo && !m_dvdPlayerVideo.IsEOS())
- {
- Sleep(100);
- continue;
- }
- if(bOmxWaitAudio && !m_dvdPlayerAudio.IsEOS())
- {
- Sleep(100);
- continue;
- }
-
- if (!m_pInputStream->IsEOF())
- CLog::Log(LOGINFO, "%s - eof reading from demuxer", __FUNCTION__);
-
- m_CurrentAudio.started = false;
- m_CurrentVideo.started = false;
- m_CurrentSubtitle.started = false;
- m_CurrentTeletext.started = false;
-
- break;
- }
-
- // it's a valid data packet, reset error counter
- m_errorCount = 0;
-
- // see if we can find something better to play
- CheckBetterStream(m_CurrentAudio, pStream);
- CheckBetterStream(m_CurrentVideo, pStream);
- CheckBetterStream(m_CurrentSubtitle, pStream);
- CheckBetterStream(m_CurrentTeletext, pStream);
-
- // process the packet
- ProcessPacket(pStream, pPacket);
-
- // check if in a cut or commercial break that should be automatically skipped
- CheckAutoSceneSkip();
- }
-}
-
-bool CDVDPlayer::CheckDelayedChannelEntry(void)
-{
- bool bReturn(false);
-
- if (m_ChannelEntryTimeOut.IsTimePast())
- {
- CFileItem currentFile(g_application.CurrentFileItem());
- CPVRChannel *currentChannel = currentFile.GetPVRChannelInfoTag();
- SwitchChannel(*currentChannel);
-
- bReturn = true;
- m_ChannelEntryTimeOut.SetInfinite();
- }
-
- return bReturn;
-}
-
-bool CDVDPlayer::CheckIsCurrent(CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg)
-{
- if(current.id == pkg->iStreamId
- && current.source == stream->source
- && current.type == stream->type)
- return true;
- else
- return false;
-}
-
-void CDVDPlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket)
-{
- /* process packet if it belongs to selected stream. for dvd's don't allow automatic opening of streams*/
-
- if (CheckIsCurrent(m_CurrentAudio, pStream, pPacket))
- ProcessAudioData(pStream, pPacket);
- else if (CheckIsCurrent(m_CurrentVideo, pStream, pPacket))
- ProcessVideoData(pStream, pPacket);
- else if (CheckIsCurrent(m_CurrentSubtitle, pStream, pPacket))
- ProcessSubData(pStream, pPacket);
- else if (CheckIsCurrent(m_CurrentTeletext, pStream, pPacket))
- ProcessTeletextData(pStream, pPacket);
- else
- {
- pStream->SetDiscard(AVDISCARD_ALL);
- CDVDDemuxUtils::FreeDemuxPacket(pPacket); // free it since we won't do anything with it
- }
-}
-
-void CDVDPlayer::CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream)
-{
- if (current.stream != (void*)stream
- || current.changes != stream->changes)
- {
- /* check so that dmuxer hints or extra data hasn't changed */
- /* if they have, reopen stream */
-
- if (current.hint != CDVDStreamInfo(*stream, true))
- OpenStream(current, stream->iId, stream->source );
-
- current.stream = (void*)stream;
- current.changes = stream->changes;
- }
-}
-
-void CDVDPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
-{
- CheckStreamChanges(m_CurrentAudio, pStream);
-
- // check if we are too slow and need to recache
- CheckStartCaching(m_CurrentAudio);
-
- CheckContinuity(m_CurrentAudio, pPacket);
- UpdateTimestamps(m_CurrentAudio, pPacket);
-
- bool drop = false;
- if (CheckPlayerInit(m_CurrentAudio))
- drop = true;
-
- /*
- * If CheckSceneSkip() returns true then demux point is inside an EDL cut and the packets are dropped.
- * If not inside a hard cut, but the demux point has reached an EDL mute section then trigger the
- * AUDIO_SILENCE state. The AUDIO_SILENCE state is reverted as soon as the demux point is outside
- * of any EDL section while EDL mute is still active.
- */
- CEdl::Cut cut;
- if (CheckSceneSkip(m_CurrentAudio))
- drop = true;
- else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE // Inside EDL mute
- && !m_EdlAutoSkipMarkers.mute) // Mute not already triggered
- {
- m_dvdPlayerAudio.SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, true));
- m_EdlAutoSkipMarkers.mute = true;
- }
- else if (!m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) // Outside of any EDL
- && m_EdlAutoSkipMarkers.mute) // But the mute hasn't been removed yet
- {
- m_dvdPlayerAudio.SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, false));
- m_EdlAutoSkipMarkers.mute = false;
- }
-
- m_dvdPlayerAudio.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
-}
-
-void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
-{
- CheckStreamChanges(m_CurrentVideo, pStream);
-
- // check if we are too slow and need to recache
- CheckStartCaching(m_CurrentVideo);
-
- if( pPacket->iSize != 4) //don't check the EOF_SEQUENCE of stillframes
- {
- CheckContinuity(m_CurrentVideo, pPacket);
- UpdateTimestamps(m_CurrentVideo, pPacket);
- }
-
- bool drop = false;
- if (CheckPlayerInit(m_CurrentVideo))
- drop = true;
-
- if (CheckSceneSkip(m_CurrentVideo))
- drop = true;
-
- m_dvdPlayerVideo.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
-}
-
-void CDVDPlayer::ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket)
-{
- CheckStreamChanges(m_CurrentSubtitle, pStream);
-
- UpdateTimestamps(m_CurrentSubtitle, pPacket);
-
- bool drop = false;
- if (CheckPlayerInit(m_CurrentSubtitle))
- drop = true;
-
- if (CheckSceneSkip(m_CurrentSubtitle))
- drop = true;
-
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
-
- if(m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
-}
-
-void CDVDPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket)
-{
- CheckStreamChanges(m_CurrentTeletext, pStream);
-
- UpdateTimestamps(m_CurrentTeletext, pPacket);
-
- bool drop = false;
- if (CheckPlayerInit(m_CurrentTeletext))
- drop = true;
-
- if (CheckSceneSkip(m_CurrentTeletext))
- drop = true;
-
- m_dvdPlayerTeletext.SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
-}
-
-bool CDVDPlayer::GetCachingTimes(double& level, double& delay, double& offset)
-{
- if(!m_pInputStream || !m_pDemuxer)
- return false;
-
- XFILE::SCacheStatus status;
- if (!m_pInputStream->GetCacheStatus(&status))
- return false;
-
- int64_t cached = status.forward;
- unsigned currate = status.currate;
- unsigned maxrate = status.maxrate;
- bool full = status.full;
-
- int64_t length = m_pInputStream->GetLength();
- int64_t remain = length - m_pInputStream->Seek(0, SEEK_CUR);
-
- if(cached < 0 || length <= 0 || remain < 0)
- return false;
-
- double play_sbp = DVD_MSEC_TO_TIME(m_pDemuxer->GetStreamLength()) / length;
- double queued = 1000.0 * GetQueueTime() / play_sbp;
-
- delay = 0.0;
- level = 0.0;
- offset = (double)(cached + queued) / length;
-
- if (currate == 0)
- return true;
-
- double cache_sbp = 1.1 * (double)DVD_TIME_BASE / currate; /* underestimate by 10 % */
- double play_left = play_sbp * (remain + queued); /* time to play out all remaining bytes */
- double cache_left = cache_sbp * (remain - cached); /* time to cache the remaining bytes */
- double cache_need = std::max(0.0, remain - play_left / cache_sbp); /* bytes needed until play_left == cache_left */
-
- delay = cache_left - play_left;
-
- if (full && (currate < maxrate) )
- level = -1.0; /* buffer is full & our read rate is too low */
- else
- level = (cached + queued) / (cache_need + queued);
-
- return true;
-}
-
-void CDVDPlayer::HandlePlaySpeed()
-{
- ECacheState caching = m_caching;
-
- if(IsInMenu() && caching != CACHESTATE_DONE)
- caching = CACHESTATE_DONE;
-
- if(caching == CACHESTATE_FULL)
- {
- double level, delay, offset;
- if(GetCachingTimes(level, delay, offset))
- {
- if(level < 0.0)
- {
- CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(21454), g_localizeStrings.Get(21455));
- caching = CACHESTATE_INIT;
- }
- if(level >= 1.0)
- caching = CACHESTATE_INIT;
- }
- else
- {
- if ((!m_dvdPlayerAudio.AcceptsData() && m_CurrentAudio.id >= 0)
- || (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0))
- caching = CACHESTATE_INIT;
- }
- }
-
- if(caching == CACHESTATE_INIT)
- {
- // if all enabled streams have been inited we are done
- if((m_CurrentVideo.id < 0 || m_CurrentVideo.started)
- && (m_CurrentAudio.id < 0 || m_CurrentAudio.started))
- caching = CACHESTATE_PLAY;
-
- // handle situation that we get no data on one stream
- if(m_CurrentAudio.id >= 0 && m_CurrentVideo.id >= 0)
- {
- if ((!m_dvdPlayerAudio.AcceptsData() && !m_CurrentVideo.started)
- || (!m_dvdPlayerVideo.AcceptsData() && !m_CurrentAudio.started))
- {
- caching = CACHESTATE_DONE;
- }
- }
- }
-
- if (caching == CACHESTATE_PVR)
- {
- bool bGotAudio(m_pDemuxer->GetNrOfAudioStreams() > 0);
- bool bGotVideo(m_pDemuxer->GetNrOfVideoStreams() > 0);
- bool bAudioLevelOk(m_dvdPlayerAudio.GetLevel() > g_advancedSettings.m_iPVRMinAudioCacheLevel);
- bool bVideoLevelOk(m_dvdPlayerVideo.GetLevel() > g_advancedSettings.m_iPVRMinVideoCacheLevel);
- bool bAudioFull(!m_dvdPlayerAudio.AcceptsData());
- bool bVideoFull(!m_dvdPlayerVideo.AcceptsData());
-
- if (/* if all streams got at least g_advancedSettings.m_iPVRMinCacheLevel in their buffers, we're done */
- ((bGotVideo || bGotAudio) && (!bGotAudio || bAudioLevelOk) && (!bGotVideo || bVideoLevelOk)) ||
- /* or if one of the buffers is full */
- (bAudioFull || bVideoFull))
- {
- CLog::Log(LOGDEBUG, "set caching from pvr to done. audio (%d) = %d. video (%d) = %d",
- bGotAudio, m_dvdPlayerAudio.GetLevel(),
- bGotVideo, m_dvdPlayerVideo.GetLevel());
-
- caching = CACHESTATE_DONE;
- }
- else
- {
- /* ensure that automatically started players are stopped while caching */
- if (m_CurrentAudio.started)
- m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
- if (m_CurrentVideo.started)
- m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
- }
- }
-
- if(caching == CACHESTATE_PLAY)
- {
- // if all enabled streams have started playing we are done
- if((m_CurrentVideo.id < 0 || !m_dvdPlayerVideo.IsStalled())
- && (m_CurrentAudio.id < 0 || !m_dvdPlayerAudio.IsStalled()))
- caching = CACHESTATE_DONE;
- }
-
- if(m_caching != caching)
- SetCaching(caching);
-
-
- if(GetPlaySpeed() != DVD_PLAYSPEED_NORMAL && GetPlaySpeed() != DVD_PLAYSPEED_PAUSE)
- {
- if (IsInMenu())
- {
- // this can't be done in menu
- SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
-
- }
- else if (m_CurrentVideo.id >= 0
- && m_CurrentVideo.inited == true
- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts()
- && m_SpeedState.lasttime != GetTime()
- && m_stepped)
- {
- m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts();
- m_SpeedState.lasttime = GetTime();
- // check how much off clock video is when ff/rw:ing
- // a problem here is that seeking isn't very accurate
- // and since the clock will be resynced after seek
- // we might actually not really be playing at the wanted
- // speed. we'd need to have some way to not resync the clock
- // after a seek to remember timing. still need to handle
- // discontinuities somehow
-
- // when seeking, give the player a headstart to make sure
- // the time it takes to seek doesn't make a difference.
- double error;
- error = m_clock.GetClock() - m_SpeedState.lastpts;
- error *= m_playSpeed / abs(m_playSpeed);
-
- if(error > DVD_MSEC_TO_TIME(1000))
- {
- CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up");
- int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL);
- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true));
- }
- }
- }
-}
-
-bool CDVDPlayer::CheckStartCaching(CCurrentStream& current)
-{
- if(m_caching != CACHESTATE_DONE
- || m_playSpeed != DVD_PLAYSPEED_NORMAL)
- return false;
-
- if(IsInMenu())
- return false;
-
- if((current.type == STREAM_AUDIO && m_dvdPlayerAudio.IsStalled())
- || (current.type == STREAM_VIDEO && m_dvdPlayerVideo.IsStalled()))
- {
- if (CachePVRStream())
- {
- if ((current.type == STREAM_AUDIO && current.started && m_dvdPlayerAudio.GetLevel() == 0) ||
- (current.type == STREAM_VIDEO && current.started && m_dvdPlayerVideo.GetLevel() == 0))
- {
- CLog::Log(LOGDEBUG, "%s stream stalled. start buffering", current.type == STREAM_AUDIO ? "audio" : "video");
- SetCaching(CACHESTATE_PVR);
- }
- return true;
- }
-
- // don't start caching if it's only a single stream that has run dry
- if(m_dvdPlayerAudio.GetLevel() > 50
- || m_dvdPlayerVideo.GetLevel() > 50)
- return false;
-
- if(current.inited)
- SetCaching(CACHESTATE_FULL);
- else
- SetCaching(CACHESTATE_INIT);
- return true;
- }
- return false;
-}
-
-bool CDVDPlayer::CheckPlayerInit(CCurrentStream& current)
-{
- if(current.inited)
- return false;
-
- if(current.startpts != DVD_NOPTS_VALUE)
- {
- if(current.dts == DVD_NOPTS_VALUE)
- {
- CLog::Log(LOGDEBUG, "%s - dropping packet type:%d dts:%f to get to start point at %f", __FUNCTION__, current.player, current.dts, current.startpts);
- return true;
- }
-
- if((current.startpts - current.dts) > DVD_SEC_TO_TIME(20))
- {
- CLog::Log(LOGDEBUG, "%s - too far to decode before finishing seek", __FUNCTION__);
- if(m_CurrentAudio.startpts != DVD_NOPTS_VALUE)
- m_CurrentAudio.startpts = current.dts;
- if(m_CurrentVideo.startpts != DVD_NOPTS_VALUE)
- m_CurrentVideo.startpts = current.dts;
- if(m_CurrentSubtitle.startpts != DVD_NOPTS_VALUE)
- m_CurrentSubtitle.startpts = current.dts;
- if(m_CurrentTeletext.startpts != DVD_NOPTS_VALUE)
- m_CurrentTeletext.startpts = current.dts;
- }
-
- if(current.dts < current.startpts)
- {
- CLog::Log(LOGDEBUG, "%s - dropping packet type:%d dts:%f to get to start point at %f", __FUNCTION__, current.player, current.dts, current.startpts);
- return true;
- }
- }
-
- //If this is the first packet after a discontinuity, send it as a resync
- if (current.dts != DVD_NOPTS_VALUE)
- {
- current.inited = true;
- current.startpts = current.dts;
-
- bool setclock = false;
- if(m_playSpeed == DVD_PLAYSPEED_NORMAL)
- {
- if( current.player == DVDPLAYER_AUDIO)
- setclock = m_clock.GetMaster() == MASTER_CLOCK_AUDIO
- || m_clock.GetMaster() == MASTER_CLOCK_AUDIO_VIDEOREF;
- else if(current.player == DVDPLAYER_VIDEO)
- setclock = m_clock.GetMaster() == MASTER_CLOCK_VIDEO;
- }
- else
- {
- if(current.player == DVDPLAYER_VIDEO)
- setclock = true;
- }
-
- double starttime = current.startpts;
- if(m_CurrentAudio.inited
- && m_CurrentAudio.startpts != DVD_NOPTS_VALUE
- && m_CurrentAudio.startpts < starttime)
- starttime = m_CurrentAudio.startpts;
- if(m_CurrentVideo.inited
- && m_CurrentVideo.startpts != DVD_NOPTS_VALUE
- && m_CurrentVideo.startpts < starttime)
- starttime = m_CurrentVideo.startpts;
-
- starttime = current.startpts - starttime;
- if(starttime > 0 && setclock)
- {
- if(starttime > DVD_SEC_TO_TIME(2))
- CLog::Log(LOGWARNING, "CDVDPlayer::CheckPlayerInit(%d) - Ignoring too large delay of %f", current.player, starttime);
- else
- SendPlayerMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_DELAY, starttime), current.player);
- }
-
- SendPlayerMessage(new CDVDMsgGeneralResync(current.dts, setclock), current.player);
- }
- return false;
-}
-
-void CDVDPlayer::UpdateCorrection(DemuxPacket* pkt, double correction)
-{
- //CLog::Log(LOGINFO,"%s: %d dts:%.0f pts:%.0f s:%d c:%.0f (%d,%d)", __func__, (int)pkt->iStreamId, pkt->dts, pkt->pts, pkt->iSize, correction, pkt->dts==DVD_NOPTS_VALUE, pkt->pts==DVD_NOPTS_VALUE);
- if(pkt->dts != DVD_NOPTS_VALUE) pkt->dts -= correction;
- if(pkt->pts != DVD_NOPTS_VALUE) pkt->pts -= correction;
-}
-
-void CDVDPlayer::UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket)
-{
- double dts = current.dts;
- /* update stored values */
- if(pPacket->dts != DVD_NOPTS_VALUE)
- dts = pPacket->dts;
- else if(pPacket->pts != DVD_NOPTS_VALUE)
- dts = pPacket->pts;
-
- /* calculate some average duration */
- if(pPacket->duration != DVD_NOPTS_VALUE)
- current.dur = pPacket->duration;
- else if(dts != DVD_NOPTS_VALUE && current.dts != DVD_NOPTS_VALUE)
- 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;
- }
- }
-}
-
-static void UpdateLimits(double& minimum, double& maximum, double dts)
-{
- if(dts == DVD_NOPTS_VALUE)
- return;
- if(minimum == DVD_NOPTS_VALUE || minimum > dts) minimum = dts;
- if(maximum == DVD_NOPTS_VALUE || maximum < dts) maximum = dts;
-}
-
-void CDVDPlayer::CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket)
-{
- if (m_playSpeed < DVD_PLAYSPEED_PAUSE)
- return;
-
- if( pPacket->dts == DVD_NOPTS_VALUE || current.dts == DVD_NOPTS_VALUE)
- return;
-
- double mindts = DVD_NOPTS_VALUE, maxdts = DVD_NOPTS_VALUE;
- UpdateLimits(mindts, maxdts, m_CurrentAudio.dts);
- UpdateLimits(mindts, maxdts, m_CurrentVideo.dts);
- UpdateLimits(mindts, maxdts, m_CurrentAudio.dts_end());
- UpdateLimits(mindts, maxdts, m_CurrentVideo.dts_end());
-
- /* if we don't have max and min, we can't do anything more */
- if( mindts == DVD_NOPTS_VALUE || maxdts == DVD_NOPTS_VALUE )
- return;
-
- double correction = 0.0;
- if( pPacket->dts > maxdts + DVD_MSEC_TO_TIME(1000))
- {
- CLog::Log(LOGDEBUG, "CDVDPlayer::CheckContinuity - resync forward :%d, prev:%f, curr:%f, diff:%f"
- , current.type, current.dts, pPacket->dts, pPacket->dts - maxdts);
- correction = pPacket->dts - maxdts;
- }
-
- /* if it's large scale jump, correct for it */
- if(pPacket->dts + DVD_MSEC_TO_TIME(100) < current.dts_end())
- {
- CLog::Log(LOGDEBUG, "CDVDPlayer::CheckContinuity - resync backward :%d, prev:%f, curr:%f, diff:%f"
- , current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);
- correction = pPacket->dts - current.dts_end();
- }
- else if(pPacket->dts < current.dts)
- {
- CLog::Log(LOGDEBUG, "CDVDPlayer::CheckContinuity - wrapback :%d, prev:%f, curr:%f, diff:%f"
- , current.type, current.dts, pPacket->dts, pPacket->dts - current.dts);
- }
-
- if(correction != 0.0)
- {
- /* disable detection on next packet on other stream to avoid ping pong-ing */
- if(m_CurrentAudio.player != current.player) m_CurrentAudio.dts = DVD_NOPTS_VALUE;
- if(m_CurrentVideo.player != current.player) m_CurrentVideo.dts = DVD_NOPTS_VALUE;
-
- m_offset_pts += correction;
- UpdateCorrection(pPacket, correction);
- }
-}
-
-bool CDVDPlayer::CheckSceneSkip(CCurrentStream& current)
-{
- if(!m_Edl.HasCut())
- return false;
-
- if(current.dts == DVD_NOPTS_VALUE)
- return false;
-
- if(current.inited == false)
- return false;
-
- CEdl::Cut cut;
- return m_Edl.InCut(DVD_TIME_TO_MSEC(current.dts + m_offset_pts), &cut) && cut.action == CEdl::CUT;
-}
-
-void CDVDPlayer::CheckAutoSceneSkip()
-{
- if(!m_Edl.HasCut())
- return;
-
- /*
- * Check that there is an audio and video stream.
- */
- if(m_CurrentAudio.id < 0
- || m_CurrentVideo.id < 0)
- return;
-
- /*
- * If there is a startpts defined for either the audio or video stream then dvdplayer is still
- * still decoding frames to get to the previously requested seek point.
- */
- if(m_CurrentAudio.inited == false
- || m_CurrentVideo.inited == false)
- return;
-
- if(m_CurrentAudio.dts == DVD_NOPTS_VALUE
- || m_CurrentVideo.dts == DVD_NOPTS_VALUE)
- return;
-
- const int64_t clock = GetTime();
-
- CEdl::Cut cut;
- if(!m_Edl.InCut(clock, &cut))
- return;
-
- if(cut.action == CEdl::CUT
- && !(cut.end == m_EdlAutoSkipMarkers.cut || cut.start == m_EdlAutoSkipMarkers.cut)) // To prevent looping if same cut again
- {
- CLog::Log(LOGDEBUG, "%s - Clock in EDL cut [%s - %s]: %s. Automatically skipping over.",
- __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(),
- CEdl::MillisecondsToTimeString(cut.end).c_str(), CEdl::MillisecondsToTimeString(clock).c_str());
- /*
- * Seeking either goes to the start or the end of the cut depending on the play direction.
- */
- int64_t seek = GetPlaySpeed() >= 0 ? cut.end : cut.start;
- /*
- * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards.
- */
- m_messenger.Put(new CDVDMsgPlayerSeek((int)seek, true, true, true, false, true));
- /*
- * Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping
- * if there was an error with seeking and it landed somewhere unexpected, perhaps back in the
- * cut. The cut automatic skip marker is reset every 500ms allowing another attempt at the seek.
- */
- m_EdlAutoSkipMarkers.cut = GetPlaySpeed() >= 0 ? cut.end : cut.start;
- }
- else if(cut.action == CEdl::COMM_BREAK
- && GetPlaySpeed() >= 0
- && cut.start > m_EdlAutoSkipMarkers.commbreak_end)
- {
- CLog::Log(LOGDEBUG, "%s - Clock in commercial break [%s - %s]: %s. Automatically skipping to end of commercial break (only done once per break)",
- __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), CEdl::MillisecondsToTimeString(cut.end).c_str(),
- CEdl::MillisecondsToTimeString(clock).c_str());
- /*
- * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards.
- */
- m_messenger.Put(new CDVDMsgPlayerSeek(cut.end + 1, true, true, true, false, true));
- /*
- * Each commercial break is only skipped once so poorly detected commercial breaks can be
- * manually re-entered. Start and end are recorded to prevent looping and to allow seeking back
- * to the start of the commercial break if incorrectly flagged.
- */
- m_EdlAutoSkipMarkers.commbreak_start = cut.start;
- m_EdlAutoSkipMarkers.commbreak_end = cut.end;
- m_EdlAutoSkipMarkers.seek_to_start = true; // Allow backwards Seek() to go directly to the start
- }
-}
-
-
-void CDVDPlayer::SynchronizeDemuxer(unsigned int timeout)
-{
- if(IsCurrentThread())
- return;
- if(!m_messenger.IsInited())
- return;
-
- CDVDMsgGeneralSynchronize* message = new CDVDMsgGeneralSynchronize(timeout, 0);
- m_messenger.Put(message->Acquire());
- message->Wait(&m_bStop, 0);
- message->Release();
-}
-
-void CDVDPlayer::SynchronizePlayers(unsigned int sources)
-{
- /* we need a big timeout as audio queue is about 8seconds for 2ch ac3 */
- const int timeout = 10*1000; // in milliseconds
-
- CDVDMsgGeneralSynchronize* message = new CDVDMsgGeneralSynchronize(timeout, sources);
- if (m_CurrentAudio.id >= 0)
- m_dvdPlayerAudio.SendMessage(message->Acquire());
-
- if (m_CurrentVideo.id >= 0)
- m_dvdPlayerVideo.SendMessage(message->Acquire());
-/* TODO - we have to rewrite the sync class, to not require
- all other players waiting for subtitle, should only
- be the oposite way
- if (m_CurrentSubtitle.id >= 0)
- m_dvdPlayerSubtitle.SendMessage(message->Acquire());
-*/
- message->Release();
-}
-
-IDVDStreamPlayer* CDVDPlayer::GetStreamPlayer(unsigned int target)
-{
- if(target == DVDPLAYER_AUDIO)
- return &m_dvdPlayerAudio;
- if(target == DVDPLAYER_VIDEO)
- return &m_dvdPlayerVideo;
- if(target == DVDPLAYER_SUBTITLE)
- return &m_dvdPlayerSubtitle;
- if(target == DVDPLAYER_TELETEXT)
- return &m_dvdPlayerTeletext;
- return NULL;
-}
-
-void CDVDPlayer::SendPlayerMessage(CDVDMsg* pMsg, unsigned int target)
-{
- IDVDStreamPlayer* player = GetStreamPlayer(target);
- if(player)
- player->SendMessage(pMsg, 0);
-}
-
-void CDVDPlayer::OnExit()
-{
- CLog::Log(LOGNOTICE, "CDVDPlayer::OnExit()");
-
- // set event to inform openfile something went wrong in case openfile is still waiting for this event
- SetCaching(CACHESTATE_DONE);
-
- // close each stream
- if (!m_bAbortRequest) CLog::Log(LOGNOTICE, "DVDPlayer: eof, waiting for queues to empty");
- CloseStream(m_CurrentAudio, !m_bAbortRequest);
- CloseStream(m_CurrentVideo, !m_bAbortRequest);
- CloseStream(m_CurrentSubtitle, !m_bAbortRequest);
- CloseStream(m_CurrentTeletext, !m_bAbortRequest);
-
- // destroy objects
- SAFE_DELETE(m_pDemuxer);
- SAFE_DELETE(m_pSubtitleDemuxer);
- SAFE_DELETE(m_pInputStream);
-
- // clean up all selection streams
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NONE);
-
- m_messenger.End();
-
- m_av_clock.OMXStop();
- m_av_clock.OMXStateIdle();
-
- m_av_clock.OMXDeinitialize();
-
- m_bStop = true;
- // if we didn't stop playing, advance to the next item in xbmc's playlist
- if(m_PlayerOptions.identify == false)
- {
- if (m_bAbortRequest)
- m_callback.OnPlayBackStopped();
- else
- m_callback.OnPlayBackEnded();
- }
-
- // set event to inform openfile something went wrong in case openfile is still waiting for this event
- m_ready.Set();
-}
-
-void CDVDPlayer::HandleMessages()
-{
- CDVDMsg* pMsg;
-
- while (m_messenger.Get(&pMsg, 0) == MSGQ_OK)
- {
-
- if (pMsg->IsType(CDVDMsg::PLAYER_SEEK) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK) == 0
- && m_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK_CHAPTER) == 0)
- {
- CDVDMsgPlayerSeek &msg(*((CDVDMsgPlayerSeek*)pMsg));
-
- if (!m_State.canseek)
- {
- pMsg->Release();
- continue;
- }
-
- if(!msg.GetTrickPlay())
- {
- g_infoManager.SetDisplayAfterSeek(100000);
- }
- if(msg.GetFlush())
- SetCaching(CACHESTATE_FLUSH);
-
- 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))
- {
- CLog::Log(LOGDEBUG, "demuxer seek to: %.0f, success", start);
- if(m_pSubtitleDemuxer)
- {
- if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward()))
- CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time);
- }
- // dts after successful seek
- if (m_StateInput.time_src == ETIMESOURCE_CLOCK && start == DVD_NOPTS_VALUE)
- m_StateInput.dts = DVD_MSEC_TO_TIME(time);
- else
- m_StateInput.dts = start;
-
- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
- // mark mediatime as invalid
- m_av_clock.OMXMediaTime(0.0);
- m_last_check_time = 0.0;
- }
- else
- CLog::Log(LOGWARNING, "error while seeking");
-
- // set flag to indicate we have finished a seeking request
- if(!msg.GetTrickPlay())
- g_infoManager.SetDisplayAfterSeek();
-
- // dvd's will issue a HOP_CHANNEL that we need to skip
- if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- m_dvd.state = DVDSTATE_SEEK;
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SEEK_CHAPTER) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK) == 0
- && m_messenger.GetPacketCount(CDVDMsg::PLAYER_SEEK_CHAPTER) == 0)
- {
- g_infoManager.SetDisplayAfterSeek(100000);
- SetCaching(CACHESTATE_FLUSH);
-
- CDVDMsgPlayerSeekChapter &msg(*((CDVDMsgPlayerSeekChapter*)pMsg));
- double start = DVD_NOPTS_VALUE;
-
- // This should always be the case.
- if(m_pDemuxer && m_pDemuxer->SeekChapter(msg.GetChapter(), &start))
- {
- FlushBuffers(false, start, true);
- // mark mediatime as invalid
- m_av_clock.OMXMediaTime(0.0);
-
- m_callback.OnPlayBackSeekChapter(msg.GetChapter());
- }
-
- g_infoManager.SetDisplayAfterSeek();
- }
- else if (pMsg->IsType(CDVDMsg::DEMUXER_RESET))
- {
- m_CurrentAudio.stream = NULL;
- m_CurrentVideo.stream = NULL;
- m_CurrentSubtitle.stream = NULL;
-
- // we need to reset the demuxer, probably because the streams have changed
- if(m_pDemuxer)
- m_pDemuxer->Reset();
- if(m_pSubtitleDemuxer)
- m_pSubtitleDemuxer->Reset();
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SET_AUDIOSTREAM))
- {
- CDVDMsgPlayerSetAudioStream* pMsg2 = (CDVDMsgPlayerSetAudioStream*)pMsg;
-
- SelectionStream& st = m_SelectionStreams.Get(STREAM_AUDIO, pMsg2->GetStreamId());
- if(st.source != STREAM_SOURCE_NONE)
- {
- if(st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;
- if(pStream->SetActiveAudioStream(st.id))
- {
- m_dvd.iSelectedAudioStream = -1;
- CloseStream(m_CurrentAudio, false);
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
- }
- }
- else
- {
- CloseStream(m_CurrentAudio, false);
- OpenStream(m_CurrentAudio, st.id, st.source);
- AdaptForcedSubtitles();
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
- }
- }
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM))
- {
- CDVDMsgPlayerSetSubtitleStream* pMsg2 = (CDVDMsgPlayerSetSubtitleStream*)pMsg;
-
- SelectionStream& st = m_SelectionStreams.Get(STREAM_SUBTITLE, pMsg2->GetStreamId());
- if(st.source != STREAM_SOURCE_NONE)
- {
- if(st.source == STREAM_SOURCE_NAV && m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;
- if(pStream->SetActiveSubtitleStream(st.id))
- {
- m_dvd.iSelectedSPUStream = -1;
- CloseStream(m_CurrentSubtitle, false);
- }
- }
- else
- {
- CloseStream(m_CurrentSubtitle, false);
- OpenStream(m_CurrentSubtitle, st.id, st.source);
- }
- }
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE))
- {
- CDVDMsgBool* pValue = (CDVDMsgBool*)pMsg;
- SetSubtitleVisibleInternal(pValue->m_value);
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SET_STATE))
- {
- g_infoManager.SetDisplayAfterSeek(100000);
- SetCaching(CACHESTATE_FLUSH);
-
- CDVDMsgPlayerSetState* pMsgPlayerSetState = (CDVDMsgPlayerSetState*)pMsg;
-
- if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
- {
- if(ptr->SetState(pMsgPlayerSetState->GetState()))
- {
- m_dvd.state = DVDSTATE_NORMAL;
- m_dvd.iDVDStillStartTime = 0;
- m_dvd.iDVDStillTime = 0;
- }
- }
-
- g_infoManager.SetDisplayAfterSeek();
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SET_RECORD))
- {
- CDVDInputStream::IChannel* input = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if(input)
- input->Record(*(CDVDMsgBool*)pMsg);
- }
- else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH))
- {
- FlushBuffers(false);
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
- {
- int speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;
-
- // correct our current clock, as it would start going wrong otherwise
- if(m_State.timestamp > 0)
- {
- double offset;
- offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp;
- offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
- if(offset > 1000) offset = 1000;
- if(offset < -1000) offset = -1000;
- m_State.time += DVD_TIME_TO_MSEC(offset);
- m_State.timestamp = CDVDClock::GetAbsoluteClock();
- }
-
- if (speed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_PAUSE && speed != m_playSpeed)
- m_callback.OnPlayBackSpeedChanged(speed / DVD_PLAYSPEED_NORMAL);
-
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) && speed != m_playSpeed)
- {
- CDVDInputStreamPVRManager* pvrinputstream = static_cast<CDVDInputStreamPVRManager*>(m_pInputStream);
- pvrinputstream->Pause( speed == 0 );
- }
-
- // if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE
- // audioplayer, stops outputing audio to audiorendere, but still tries to
- // sleep an correct amount for each packet
- // videoplayer just plays faster after the clock speed has been increased
- // 1. disable audio
- // 2. skip frames and adjust their pts or the clock
-
- // when switching from trickplay to normal, we may not have a full set of reference frames
- // in decoder and we may get corrupt frames out. Seeking to current time will avoid this.
- if ( TP(speed) || TP(m_playSpeed) ||
- ( (speed == DVD_PLAYSPEED_PAUSE || speed == DVD_PLAYSPEED_NORMAL) &&
- (m_playSpeed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_NORMAL) ) )
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), (speed < 0), true, false, false, true));
-
- m_playSpeed = speed;
- m_caching = CACHESTATE_DONE;
- m_clock.SetSpeed(speed);
- m_av_clock.OMXSetSpeed(speed);
- m_av_clock.OMXPause();
- m_dvdPlayerAudio.SetSpeed(speed);
- m_dvdPlayerVideo.SetSpeed(speed);
-
- // We can't pause demuxer until our buffers are full. Doing so will result in continued
- // calls to Read() which may then block indefinitely (CDVDInputStreamRTMP for example).
- if(m_pDemuxer)
- {
- m_DemuxerPausePending = (speed == DVD_PLAYSPEED_PAUSE);
- if (!m_DemuxerPausePending)
- m_pDemuxer->SetSpeed(speed);
- }
- CLog::Log(LOGDEBUG, "CDVDPlayer - CDVDMsg::PLAYER_SETSPEED speed : %d", speed);
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) == 0)
- {
- FlushBuffers(false);
- CDVDInputStream::IChannel* input = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if(input && input->SelectChannelByNumber(static_cast<CDVDMsgInt*>(pMsg)->m_value))
- {
- SAFE_DELETE(m_pDemuxer);
- }else
- {
- CLog::Log(LOGWARNING, "%s - failed to switch channel. playback stopped", __FUNCTION__);
- CApplicationMessenger::Get().MediaStop(false);
- }
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT) && m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT) == 0)
- {
- FlushBuffers(false);
- CDVDInputStream::IChannel* input = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if(input && input->SelectChannel(static_cast<CDVDMsgType <CPVRChannel> *>(pMsg)->m_value))
- {
- SAFE_DELETE(m_pDemuxer);
- }else
- {
- CLog::Log(LOGWARNING, "%s - failed to switch channel. playback stopped", __FUNCTION__);
- CApplicationMessenger::Get().MediaStop(false);
- }
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_NEXT) || pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_PREV))
- {
- CDVDInputStream::IChannel* input = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if(input)
- {
- bool bSwitchSuccessful(false);
- bool bShowPreview(CSettings::Get().GetInt("pvrplayback.channelentrytimeout") > 0);
-
- if (!bShowPreview)
- {
- g_infoManager.SetDisplayAfterSeek(100000);
- FlushBuffers(false);
- }
-
- if(pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_NEXT))
- bSwitchSuccessful = input->NextChannel(bShowPreview);
- else
- bSwitchSuccessful = input->PrevChannel(bShowPreview);
-
- if(bSwitchSuccessful)
- {
- if (bShowPreview)
- {
- UpdateApplication(0);
- m_ChannelEntryTimeOut.Set(CSettings::Get().GetInt("pvrplayback.channelentrytimeout"));
- }
- else
- {
- m_ChannelEntryTimeOut.SetInfinite();
- SAFE_DELETE(m_pDemuxer);
-
- g_infoManager.SetDisplayAfterSeek();
- }
- }
- else
- {
- CLog::Log(LOGWARNING, "%s - failed to switch channel. playback stopped", __FUNCTION__);
- CApplicationMessenger::Get().MediaStop(false);
- }
- }
- }
- else if (pMsg->IsType(CDVDMsg::GENERAL_GUI_ACTION))
- OnAction(((CDVDMsgType<CAction>*)pMsg)->m_value);
- else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
- {
- int player = ((CDVDMsgInt*)pMsg)->m_value;
- if(player == DVDPLAYER_AUDIO)
- m_CurrentAudio.started = true;
- if(player == DVDPLAYER_VIDEO)
- m_CurrentVideo.started = true;
-
- if ((player == DVDPLAYER_AUDIO || player == DVDPLAYER_VIDEO) &&
- (TPA(m_playSpeed) || !m_HasAudio || m_CurrentAudio.started) &&
- (!m_HasVideo || m_CurrentVideo.started))
- {
- CLog::Log(LOGDEBUG, "CDVDPlayer::HandleMessages - player started RESET");
- m_av_clock.OMXReset(m_HasVideo, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false:m_HasAudio);
- }
-
- CLog::Log(LOGDEBUG, "CDVDPlayer::HandleMessages - player started %d (tpa:%d,a:%d,v:%d)", player, TPA(m_playSpeed), m_CurrentAudio.started, m_CurrentVideo.started);
- }
- else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
- {
- CDVDPlayer::SPlayerState& state = ((CDVDMsgType<CDVDPlayer::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 && !m_dvdPlayerVideo.SubmittedEOS())
- {
- if(state.player == DVDPLAYER_VIDEO)
- m_State = state;
- }
- else if(m_CurrentAudio.started)
- {
- if(state.player == DVDPLAYER_AUDIO)
- m_State = state;
- }
- }
-
- pMsg->Release();
- }
-
-}
-
-void CDVDPlayer::SetCaching(ECacheState state)
-{
- if(state == CACHESTATE_FLUSH)
- {
- double level, delay, offset;
- if(GetCachingTimes(level, delay, offset))
- state = CACHESTATE_FULL;
- else
- state = CACHESTATE_INIT;
- }
-
- if(m_caching == state)
- return;
-
- CLog::Log(LOGDEBUG, "CDVDPlayer::SetCaching - caching state %d", state);
- if(state == CACHESTATE_FULL
- || state == CACHESTATE_INIT
- || state == CACHESTATE_PVR)
- {
- m_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_av_clock.OMXPause();
- m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
- m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
-
- if (state == CACHESTATE_PVR)
- m_pInputStream->ResetScanTimeout((unsigned int) CSettings::Get().GetInt("pvrplayback.scantime") * 1000);
- }
-
- if(state == CACHESTATE_PLAY
- ||(state == CACHESTATE_DONE && m_caching != CACHESTATE_PLAY))
- {
- m_clock.SetSpeed(m_playSpeed);
- m_dvdPlayerAudio.SetSpeed(m_playSpeed);
- m_dvdPlayerVideo.SetSpeed(m_playSpeed);
- m_pInputStream->ResetScanTimeout(0);
- }
- m_caching = state;
-}
-
-void CDVDPlayer::SetPlaySpeed(int speed)
-{
- m_messenger.Put(new CDVDMsgInt(CDVDMsg::PLAYER_SETSPEED, speed));
- m_dvdPlayerAudio.SetSpeed(speed);
- m_dvdPlayerVideo.SetSpeed(speed);
- SynchronizeDemuxer(100);
-}
-
-bool CDVDPlayer::CanPause()
-{
- CSingleLock lock(m_StateSection);
- return m_State.canpause;
-}
-
-void CDVDPlayer::Pause()
-{
- CSingleLock lock(m_StateSection);
- if (!m_State.canpause)
- return;
- lock.Leave();
-
- if(m_playSpeed != DVD_PLAYSPEED_PAUSE && IsCaching())
- {
- SetCaching(CACHESTATE_DONE);
- return;
- }
-
- // return to normal speed if it was paused before, pause otherwise
- if (m_playSpeed == DVD_PLAYSPEED_PAUSE)
- {
- SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
- m_callback.OnPlayBackResumed();
- }
- else
- {
- SetPlaySpeed(DVD_PLAYSPEED_PAUSE);
- m_callback.OnPlayBackPaused();
- }
-}
-
-bool CDVDPlayer::IsPaused() const
-{
- return m_playSpeed == DVD_PLAYSPEED_PAUSE || IsCaching();
-}
-
-bool CDVDPlayer::HasVideo() const
-{
- return m_HasVideo;
-}
-
-bool CDVDPlayer::HasAudio() const
-{
- return m_HasAudio;
-}
-
-bool CDVDPlayer::IsPassthrough() const
-{
- return m_dvdPlayerAudio.IsPassthrough();
-}
-
-bool CDVDPlayer::CanSeek()
-{
- CSingleLock lock(m_StateSection);
- return m_State.canseek;
-}
-
-void CDVDPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
-{
- // Single step
- if( m_playSpeed == DVD_PLAYSPEED_PAUSE && bPlus && !bLargeStep)
- {
- m_av_clock.OMXStep();
- return;
- }
-
- if (!m_State.canseek)
- return;
-
- if (bLargeStep && bChapterOverride && GetChapter() > 0)
- {
- if (!bPlus)
- {
- SeekChapter(GetChapter() - 1);
- return;
- }
- else if (GetChapter() < GetChapterCount())
- {
- SeekChapter(GetChapter() + 1);
- return;
- }
- }
-
- int64_t seek;
- if (g_advancedSettings.m_videoUseTimeSeeking && GetTotalTime() > 2000*g_advancedSettings.m_videoTimeSeekForwardBig)
- {
- if (bLargeStep)
- seek = bPlus ? g_advancedSettings.m_videoTimeSeekForwardBig : g_advancedSettings.m_videoTimeSeekBackwardBig;
- else
- seek = bPlus ? g_advancedSettings.m_videoTimeSeekForward : g_advancedSettings.m_videoTimeSeekBackward;
- seek *= 1000;
- seek += GetTime();
- }
- else
- {
- float percent;
- if (bLargeStep)
- percent = bPlus ? g_advancedSettings.m_videoPercentSeekForwardBig : g_advancedSettings.m_videoPercentSeekBackwardBig;
- else
- percent = bPlus ? g_advancedSettings.m_videoPercentSeekForward : g_advancedSettings.m_videoPercentSeekBackward;
- seek = (int64_t)(GetTotalTimeInMsec()*(GetPercentage()+percent)/100);
- }
-
- bool restore = true;
- if (m_Edl.HasCut())
- {
- /*
- * Alter the standard seek position based on whether any commercial breaks have been
- * automatically skipped.
- */
- const int clock = DVD_TIME_TO_MSEC(m_clock.GetClock());
- /*
- * If a large backwards seek occurs within 10 seconds of the end of the last automated
- * commercial skip, then seek back to the start of the commercial break under the assumption
- * it was flagged incorrectly. 10 seconds grace period is allowed in case the watcher has to
- * fumble around finding the remote. Only happens once per commercial break.
- *
- * Small skip does not trigger this in case the start of the commercial break was in fact fine
- * but it skipped too far into the program. In that case small skip backwards behaves as normal.
- */
- if (!bPlus && bLargeStep
- && m_EdlAutoSkipMarkers.seek_to_start
- && clock >= m_EdlAutoSkipMarkers.commbreak_end
- && clock <= m_EdlAutoSkipMarkers.commbreak_end + 10*1000) // Only if within 10 seconds of the end (in msec)
- {
- CLog::Log(LOGDEBUG, "%s - Seeking back to start of commercial break [%s - %s] as large backwards skip activated within 10 seconds of the automatic commercial skip (only done once per break).",
- __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(),
- CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str());
- seek = m_EdlAutoSkipMarkers.commbreak_start;
- restore = false;
- m_EdlAutoSkipMarkers.seek_to_start = false; // So this will only happen within the 10 second grace period once.
- }
- /*
- * If big skip forward within the last "reverted" commercial break, seek to the end of the
- * commercial break under the assumption that the break was incorrectly flagged and playback has
- * now reached the actual start of the commercial break. Assume that the end is flagged more
- * correctly than the landing point for a standard big skip (ends seem to be flagged more
- * accurately than the start).
- */
- else if (bPlus && bLargeStep
- && clock >= m_EdlAutoSkipMarkers.commbreak_start
- && clock <= m_EdlAutoSkipMarkers.commbreak_end)
- {
- CLog::Log(LOGDEBUG, "%s - Seeking to end of previously skipped commercial break [%s - %s] as big forwards skip activated within the break.",
- __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(),
- CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str());
- seek = m_EdlAutoSkipMarkers.commbreak_end;
- restore = false;
- }
- }
-
- int64_t time = GetTime();
- if(g_application.CurrentFileItem().IsStack()
- && (seek > GetTotalTimeInMsec() || seek < 0))
- {
- g_application.SeekTime((seek - time) * 0.001 + g_application.GetTime());
- // warning, don't access any dvdplayer variables here as
- // the dvdplayer object may have been destroyed
- return;
- }
-
- m_messenger.Put(new CDVDMsgPlayerSeek((int)seek, !bPlus, true, false, restore));
- SynchronizeDemuxer(100);
- if (seek < 0) seek = 0;
- m_callback.OnPlayBackSeek((int)seek, (int)(seek - time));
-}
-
-bool CDVDPlayer::SeekScene(bool bPlus)
-{
- if (!m_Edl.HasSceneMarker())
- return false;
-
- /*
- * There is a 5 second grace period applied when seeking for scenes backwards. If there is no
- * grace period applied it is impossible to go backwards past a scene marker.
- */
- int64_t clock = GetTime();
- if (!bPlus && clock > 5 * 1000) // 5 seconds
- clock -= 5 * 1000;
-
- int iScenemarker;
- if (m_Edl.GetNextSceneMarker(bPlus, clock, &iScenemarker))
- {
- /*
- * Seeking is flushed and inaccurate, just like Seek()
- */
- m_messenger.Put(new CDVDMsgPlayerSeek(iScenemarker, !bPlus, true, false, false));
- SynchronizeDemuxer(100);
- return true;
- }
- return false;
-}
-
-void CDVDPlayer::GetAudioInfo(std::string &strAudioInfo)
-{
- { CSingleLock lock(m_StateSection);
- strAudioInfo = StringUtils::Format("D(%s)", m_StateInput.demux_audio.c_str());
- }
- strAudioInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerAudio.GetPlayerInfo().c_str());
-}
-
-void CDVDPlayer::GetVideoInfo(std::string& strVideoInfo)
-{
- { CSingleLock lock(m_StateSection);
- strVideoInfo = StringUtils::Format("D(%s)", m_StateInput.demux_video.c_str());
- }
- strVideoInfo += StringUtils::Format("\nP(%s)", m_dvdPlayerVideo.GetPlayerInfo().c_str());
-}
-
-void CDVDPlayer::GetGeneralInfo(std::string& strGeneralInfo)
-{
- if (!m_bStop)
- {
- double dDelay = m_dvdPlayerAudio.GetDelay();
-
- double apts = m_dvdPlayerAudio.GetCurrentPts();
- double vpts = m_dvdPlayerVideo.GetCurrentPts();
- double dDiff = 0;
-
- if( apts != DVD_NOPTS_VALUE && vpts != DVD_NOPTS_VALUE )
- dDiff = (apts - vpts) / DVD_TIME_BASE;
-
- std::string strEDL = StringUtils::Format(", edl:%s", m_Edl.GetInfo().c_str());
-
- std::string strBuf;
- CSingleLock lock(m_StateSection);
- if(m_StateInput.cache_bytes >= 0)
- {
- strBuf += StringUtils::Format(" cache:%s %2.0f%%"
- , StringUtils::SizeToString(m_State.cache_bytes).c_str()
- , m_State.cache_level * 100);
- if(m_playSpeed == 0 || m_caching == CACHESTATE_FULL)
- strBuf += StringUtils::Format(" %d sec", DVD_TIME_TO_SEC(m_State.cache_delay));
- }
-
- strGeneralInfo = StringUtils::Format("C( ad:% 6.3f, a/v:% 6.3f%s, dcpu:%2i%% acpu:%2i%% vcpu:%2i%%%s af:%d%% vf:%d%% amp:% 5.2f )"
- , dDelay
- , dDiff
- , strEDL.c_str()
- , (int)(CThread::GetRelativeUsage()*100)
- , (int)(m_dvdPlayerAudio.GetRelativeUsage()*100)
- , (int)(m_dvdPlayerVideo.GetRelativeUsage()*100)
- , strBuf.c_str()
- , m_audio_fifo
- , m_video_fifo
- , m_dvdPlayerAudio.GetDynamicRangeAmplification());
-
- }
-}
-
-void CDVDPlayer::SeekPercentage(float iPercent)
-{
- int64_t iTotalTime = GetTotalTimeInMsec();
-
- if (!iTotalTime)
- return;
-
- SeekTime((int64_t)(iTotalTime * iPercent / 100));
-}
-
-float CDVDPlayer::GetPercentage()
-{
- int64_t iTotalTime = GetTotalTimeInMsec();
-
- if (!iTotalTime)
- return 0.0f;
-
- return GetTime() * 100 / (float)iTotalTime;
-}
-
-float CDVDPlayer::GetCachePercentage()
-{
- CSingleLock lock(m_StateSection);
- return m_StateInput.cache_offset * 100; // NOTE: Percentage returned is relative
-}
-
-void CDVDPlayer::SetAVDelay(float fValue)
-{
- m_dvdPlayerVideo.SetDelay( (fValue * DVD_TIME_BASE) ) ;
-}
-
-float CDVDPlayer::GetAVDelay()
-{
- return m_dvdPlayerVideo.GetDelay() / (float)DVD_TIME_BASE;
-}
-
-void CDVDPlayer::SetSubTitleDelay(float fValue)
-{
- m_dvdPlayerVideo.SetSubtitleDelay(-fValue * DVD_TIME_BASE);
-}
-
-float CDVDPlayer::GetSubTitleDelay()
-{
- return -m_dvdPlayerVideo.GetSubtitleDelay() / DVD_TIME_BASE;
-}
-
-// priority: 1: libdvdnav, 2: external subtitles, 3: muxed subtitles
-int CDVDPlayer::GetSubtitleCount()
-{
- return m_SelectionStreams.Count(STREAM_SUBTITLE);
-}
-
-int CDVDPlayer::GetSubtitle()
-{
- return m_SelectionStreams.IndexOf(STREAM_SUBTITLE, *this);
-}
-
-void CDVDPlayer::GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info)
-{
- if (index < 0 || index > (int) GetSubtitleCount() - 1)
- return;
-
- SelectionStream& s = m_SelectionStreams.Get(STREAM_SUBTITLE, index);
- if(s.name.length() > 0)
- info.name = s.name;
-
- if(s.type == STREAM_NONE)
- info.name += "(Invalid)";
-
- info.language = s.language;
-}
-
-void CDVDPlayer::SetSubtitle(int iStream)
-{
- CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = iStream;
- m_messenger.Put(new CDVDMsgPlayerSetSubtitleStream(iStream));
-}
-
-bool CDVDPlayer::GetSubtitleVisible()
-{
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;
- if(pStream->IsInMenu())
- return CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn;
- else
- return pStream->IsSubtitleStreamEnabled();
- }
-
- return m_dvdPlayerVideo.IsSubtitleEnabled();
-}
-
-void CDVDPlayer::SetSubtitleVisible(bool bVisible)
-{
- CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn = bVisible;
- m_messenger.Put(new CDVDMsgBool(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE, bVisible));
-}
-
-void CDVDPlayer::SetSubtitleVisibleInternal(bool bVisible)
-{
- CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn = bVisible;
- m_dvdPlayerVideo.EnableSubtitle(bVisible);
-
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(bVisible);
-}
-
-int CDVDPlayer::GetAudioStreamCount()
-{
- return m_SelectionStreams.Count(STREAM_AUDIO);
-}
-
-int CDVDPlayer::GetAudioStream()
-{
- return m_SelectionStreams.IndexOf(STREAM_AUDIO, *this);
-}
-
-void CDVDPlayer::SetAudioStream(int iStream)
-{
- CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream = iStream;
- m_messenger.Put(new CDVDMsgPlayerSetAudioStream(iStream));
- SynchronizeDemuxer(100);
-}
-
-TextCacheStruct_t* CDVDPlayer::GetTeletextCache()
-{
- if (m_CurrentTeletext.id < 0)
- return 0;
-
- return m_dvdPlayerTeletext.GetTeletextCache();
-}
-
-void CDVDPlayer::LoadPage(int p, int sp, unsigned char* buffer)
-{
- if (m_CurrentTeletext.id < 0)
- return;
-
- return m_dvdPlayerTeletext.LoadPage(p, sp, buffer);
-}
-
-void CDVDPlayer::SeekTime(int64_t iTime)
-{
- int seekOffset = (int)(iTime - GetTime());
- m_messenger.Put(new CDVDMsgPlayerSeek((int)iTime, true, true, true));
- SynchronizeDemuxer(100);
- m_callback.OnPlayBackSeek((int)iTime, seekOffset);
-}
-
-// return the time in milliseconds
-int64_t CDVDPlayer::GetTime()
-{
- CSingleLock lock(m_StateSection);
- double offset = 0;
- const double limit = DVD_MSEC_TO_TIME(200);
- if(m_State.timestamp > 0)
- {
- offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp;
- offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
- if(offset > limit) offset = limit;
- if(offset < -limit) offset = -limit;
- }
- //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)m_State.time, (double)m_State.timestamp, (int)DVD_TIME_TO_MSEC(m_State.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_stamp), (int)m_playSpeed, (int)m_caching, llrint(m_State.time + DVD_TIME_TO_MSEC(offset)));}
- return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
-}
-
-// return length in msec
-int64_t CDVDPlayer::GetTotalTimeInMsec()
-{
- CSingleLock lock(m_StateSection);
- return llrint(m_State.time_total);
-}
-
-// return length in seconds.. this should be changed to return in milleseconds throughout xbmc
-int64_t CDVDPlayer::GetTotalTime()
-{
- return GetTotalTimeInMsec();
-}
-
-void CDVDPlayer::ToFFRW(int iSpeed)
-{
- // can't rewind in menu as seeking isn't possible
- // forward is fine
- if (iSpeed < 0 && IsInMenu()) return;
- SetPlaySpeed(iSpeed * DVD_PLAYSPEED_NORMAL);
-}
-
-bool CDVDPlayer::OpenStream(CCurrentStream& current, int iStream, int source, bool reset)
-{
- CDemuxStream* stream = NULL;
- CDVDStreamInfo hint;
-
- CLog::Log(LOGNOTICE, "Opening stream: %i source: %i", iStream, source);
-
- if(STREAM_SOURCE_MASK(source) == STREAM_SOURCE_DEMUX_SUB)
- {
- int index = m_SelectionStreams.IndexOf(current.type, source, iStream);
- if(index < 0)
- return false;
- SelectionStream st = m_SelectionStreams.Get(current.type, index);
-
- if(!m_pSubtitleDemuxer || m_pSubtitleDemuxer->GetFileName() != st.filename)
- {
- CLog::Log(LOGNOTICE, "Opening Subtitle file: %s", st.filename.c_str());
- auto_ptr<CDVDDemuxVobsub> demux(new CDVDDemuxVobsub());
- if(!demux->Open(st.filename, st.filename2))
- return false;
- m_pSubtitleDemuxer = demux.release();
- }
-
- double pts = m_dvdPlayerVideo.GetCurrentPts();
- if(pts == DVD_NOPTS_VALUE)
- pts = m_CurrentVideo.dts;
- if(pts == DVD_NOPTS_VALUE)
- pts = 0;
- pts += m_offset_pts;
- m_pSubtitleDemuxer->SeekTime((int)(1000.0 * pts / (double)DVD_TIME_BASE));
-
- stream = m_pSubtitleDemuxer->GetStream(iStream);
- if(!stream || stream->disabled)
- return false;
- stream->SetDiscard(AVDISCARD_NONE);
-
- hint.Assign(*stream, true);
- }
- else if(STREAM_SOURCE_MASK(source) == STREAM_SOURCE_TEXT)
- {
- int index = m_SelectionStreams.IndexOf(current.type, source, iStream);
- if(index < 0)
- return false;
-
- hint.Clear();
- hint.filename = m_SelectionStreams.Get(current.type, index).filename;
- hint.fpsscale = m_CurrentVideo.hint.fpsscale;
- hint.fpsrate = m_CurrentVideo.hint.fpsrate;
- }
- else if(STREAM_SOURCE_MASK(source) == STREAM_SOURCE_DEMUX)
- {
- if(!m_pDemuxer)
- return false;
-
- stream = m_pDemuxer->GetStream(iStream);
- if(!stream || stream->disabled)
- return false;
- stream->SetDiscard(AVDISCARD_NONE);
-
- hint.Assign(*stream, true);
-
- if(m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- hint.filename = "dvd";
- }
-
- bool res;
- switch(current.type)
- {
- case STREAM_AUDIO:
- res = OpenAudioStream(hint, reset);
- break;
- case STREAM_VIDEO:
- res = OpenVideoStream(hint, reset);
- break;
- case STREAM_SUBTITLE:
- res = OpenSubtitleStream(hint);
- break;
- case STREAM_TELETEXT:
- res = OpenTeletextStream(hint);
- break;
- default:
- res = false;
- break;
- }
-
- if (res)
- {
- current.id = iStream;
- current.source = source;
- current.hint = hint;
- current.stream = (void*)stream;
- current.started = false;
- if(stream)
- current.changes = stream->changes;
-
- UpdateClockMaster();
- }
- else
- {
- if(stream)
- {
- /* mark stream as disabled, to disallaw further attempts*/
- CLog::Log(LOGWARNING, "%s - Unsupported stream %d. Stream disabled.", __FUNCTION__, stream->iId);
- stream->disabled = true;
- stream->SetDiscard(AVDISCARD_ALL);
- }
- }
-
- return res;
-}
-
-bool CDVDPlayer::OpenStreamPlayer(CCurrentStream& current, CDVDStreamInfo& hint, bool reset)
-{
- IDVDStreamPlayer* player = GetStreamPlayer(current.player);
- if(player == NULL)
- return false;
-
- if(current.id < 0
- || current.hint != hint)
- {
- if (!player->OpenStream( hint ))
- return false;
- }
- else if (reset)
- player->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET), 0);
- return true;
-}
-
-bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset)
-{
- if(!OpenStreamPlayer(m_CurrentAudio, hint, reset))
- return false;
-
- m_HasAudio = true;
-
- /* we are potentially going to be waiting on this */
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
-
- /* audio normally won't consume full cpu, so let it have prio */
- m_dvdPlayerAudio.SetPriority(GetPriority()+1);
- CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream = GetAudioStream();
- return true;
-}
-
-bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset)
-{
- if( m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) )
- {
- /* set aspect ratio as requested by navigator for dvd's */
- float aspect = static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->GetVideoAspectRatio();
- if(aspect != 0.0)
- {
- hint.aspect = aspect;
- hint.forced_aspect = true;
- }
- hint.software = true;
- }
-
- CDVDInputStream::IMenus* pMenus = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream);
- if(pMenus && pMenus->IsInMenu())
- hint.stills = true;
-
- if (hint.stereo_mode.empty())
- hint.stereo_mode = CStereoscopicsManager::Get().DetectStereoModeByString(m_filename);
-
- if(hint.flags & AV_DISPOSITION_ATTACHED_PIC)
- return false;
-
- if(!OpenStreamPlayer(m_CurrentVideo, hint, reset))
- return false;
-
- m_HasVideo = true;
-
- /* we are potentially going to be waiting on this */
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
-
-#if defined(TARGET_DARWIN)
- // Apple thread scheduler works a little different than Linux. It
- // will favor OS GUI side and can cause DVDPlayerVideo to miss frame
- // updates when the OS gets busy. Apple's recomended method is to
- // elevate time critical threads to SCHED_RR and OSX does this for
- // the CoreAudio audio device handler thread. We do the same for
- // the DVDPlayerVideo thread so it can run to sleep without getting
- // swapped out by a busy OS.
- m_dvdPlayerVideo.SetPriority(GetSchedRRPriority());
-#else
- /* use same priority for video thread as demuxing thread, as */
- /* otherwise demuxer will starve if video consumes the full cpu */
- m_dvdPlayerVideo.SetPriority(GetPriority());
-#endif
- return true;
-
-}
-
-bool CDVDPlayer::OpenSubtitleStream(CDVDStreamInfo& hint)
-{
- if(!OpenStreamPlayer(m_CurrentSubtitle, hint, true))
- return false;
-
- CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = GetSubtitle();
- return true;
-}
-
-bool CDVDPlayer::AdaptForcedSubtitles()
-{
- bool valid = false;
- SelectionStream ss = m_SelectionStreams.Get(STREAM_SUBTITLE, GetSubtitle());
- if (ss.flags & CDemuxStream::FLAG_FORCED || !GetSubtitleVisible())
- {
- SelectionStream as = m_SelectionStreams.Get(STREAM_AUDIO, GetAudioStream());
- SelectionStreams streams = m_SelectionStreams.Get(STREAM_SUBTITLE);
-
- for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
- {
- if (it->flags & CDemuxStream::FLAG_FORCED && g_LangCodeExpander.CompareLangCodes(it->language, as.language))
- {
- if(OpenStream(m_CurrentSubtitle, it->id, it->source))
- {
- valid = true;
- SetSubtitleVisibleInternal(true);
- }
- }
- }
- if(!valid)
- {
- CloseStream(m_CurrentSubtitle, true);
- SetSubtitleVisibleInternal(false);
- }
- }
- return valid;
-}
-
-bool CDVDPlayer::OpenTeletextStream(CDVDStreamInfo& hint)
-{
- if (!m_dvdPlayerTeletext.CheckStream(hint))
- return false;
-
- if(!OpenStreamPlayer(m_CurrentTeletext, hint, true))
- return false;
-
- return true;
-}
-
-bool CDVDPlayer::CloseStream(CCurrentStream& current, bool bWaitForBuffers)
-{
- if (current.id < 0)
- return false;
-
- CLog::Log(LOGNOTICE, "Closing stream player %d", current.player);
-
- if(bWaitForBuffers)
- SetCaching(CACHESTATE_DONE);
-
- IDVDStreamPlayer* player = GetStreamPlayer(current.player);
- if(player)
- player->CloseStream(bWaitForBuffers);
-
- current.Clear();
- UpdateClockMaster();
- return true;
-}
-
-void CDVDPlayer::UpdateClockMaster()
-{
- EMasterClock clock;
- if(m_CurrentAudio.id >= 0)
- {
- if(m_CurrentVideo.id >= 0 && g_VideoReferenceClock.GetRefreshRate() > 0)
- clock = MASTER_CLOCK_AUDIO_VIDEOREF;
- else
- clock = MASTER_CLOCK_AUDIO;
- }
- else if(m_CurrentVideo.id >= 0)
- clock = MASTER_CLOCK_VIDEO;
- else
- clock = MASTER_CLOCK_NONE;
-
- if (m_clock.GetMaster() != clock)
- {
- /* the new clock should be somewhat in sync with old */
- if (clock == MASTER_CLOCK_AUDIO
- || clock == MASTER_CLOCK_AUDIO_VIDEOREF)
- SynchronizePlayers(SYNCSOURCE_AUDIO);
-
- m_clock.SetMaster(clock);
- }
-}
-
-void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
-{
- double startpts;
-
- CLog::Log(LOGNOTICE, "FlushBuffers: q:%d pts:%.0f a:%d", queued, pts, accurate);
-
- if (!TP(m_playSpeed))
- m_av_clock.OMXStop();
- m_av_clock.OMXPause();
- m_stepped = false;
-
- /* for now, ignore accurate flag as it discards keyframes and causes corrupt frames */
- if(0 && accurate)
- startpts = pts;
- else
- startpts = DVD_NOPTS_VALUE;
-
- /* call with demuxer pts */
- if(startpts != DVD_NOPTS_VALUE)
- startpts -= m_offset_pts;
-
- m_CurrentAudio.inited = false;
- m_CurrentAudio.dts = DVD_NOPTS_VALUE;
- m_CurrentAudio.startpts = startpts;
-
- m_CurrentVideo.inited = false;
- m_CurrentVideo.dts = DVD_NOPTS_VALUE;
- m_CurrentVideo.startpts = startpts;
-
- m_CurrentSubtitle.inited = false;
- m_CurrentSubtitle.dts = DVD_NOPTS_VALUE;
- m_CurrentSubtitle.startpts = startpts;
-
- m_CurrentTeletext.inited = false;
- m_CurrentTeletext.dts = DVD_NOPTS_VALUE;
- m_CurrentTeletext.startpts = startpts;
-
- if(queued)
- {
- m_dvdPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_dvdPlayerTeletext.SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- SynchronizePlayers(SYNCSOURCE_ALL);
- }
- else
- {
- m_dvdPlayerAudio.Flush();
- m_dvdPlayerVideo.Flush();
- m_dvdPlayerSubtitle.Flush();
- m_dvdPlayerTeletext.Flush();
-
- // clear subtitle and menu overlays
- m_overlayContainer.Clear();
-
- if(m_playSpeed == DVD_PLAYSPEED_NORMAL
- || m_playSpeed == DVD_PLAYSPEED_PAUSE)
- {
- // make sure players are properly flushed, should put them in stalled state
- CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, 0);
- m_dvdPlayerAudio.SendMessage(msg->Acquire(), 1);
- m_dvdPlayerVideo.SendMessage(msg->Acquire(), 1);
- msg->Wait(&m_bStop, 0);
- msg->Release();
-
- // purge any pending PLAYER_STARTED messages
- m_messenger.Flush(CDVDMsg::PLAYER_STARTED);
-
- // we should now wait for init cache
- SetCaching(CACHESTATE_FLUSH);
- m_CurrentAudio.started = false;
- m_CurrentVideo.started = false;
- m_CurrentSubtitle.started = false;
- m_CurrentTeletext.started = false;
- }
-
- if(pts != DVD_NOPTS_VALUE)
- m_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;
- }
-}
-
-// since we call ffmpeg functions to decode, this is being called in the same thread as ::Process() is
-int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
-{
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY))
- {
- if(iMessage == 0)
- m_overlayContainer.Add((CDVDOverlay*)pData);
- else if(iMessage == 1)
- m_messenger.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH));
- else if(iMessage == 2)
- m_dvd.iSelectedAudioStream = *(int*)pData;
- else if(iMessage == 3)
- m_dvd.iSelectedSPUStream = *(int*)pData;
- else if(iMessage == 4)
- m_dvdPlayerVideo.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_dvdPlayerVideo.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);
- }
- }
- else if (iMessage == 6)
- {
- m_dvd.state = DVDSTATE_NORMAL;
- CLog::Log(LOGDEBUG, "CDVDPlayer::OnDVDNavResult - libbluray read error (DVDSTATE_NORMAL)");
- CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25008), g_localizeStrings.Get(25009));
- }
-
- return 0;
- }
-
- if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- {
- CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;
-
- switch (iMessage)
- {
- case DVDNAV_STILL_FRAME:
- {
- //CLog::Log(LOGDEBUG, "DVDNAV_STILL_FRAME");
-
- dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)pData;
- // should wait the specified time here while we let the player running
- // after that call dvdnav_still_skip(m_dvdnav);
-
- if (m_dvd.state != DVDSTATE_STILL)
- {
- // else notify the player we have received a still frame
-
- if(still_event->length < 0xff)
- m_dvd.iDVDStillTime = still_event->length * 1000;
- else
- m_dvd.iDVDStillTime = 0;
-
- 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_dvdPlayerVideo.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",
- still_event->length, time / 1000);
- }
- return NAVRESULT_HOLD;
- }
- break;
- case DVDNAV_SPU_CLUT_CHANGE:
- {
- m_dvdPlayerSubtitle.SendMessage(new CDVDMsgSubtitleClutChange((uint8_t*)pData));
- }
- break;
- case DVDNAV_SPU_STREAM_CHANGE:
- {
- dvdnav_spu_stream_change_event_t* event = (dvdnav_spu_stream_change_event_t*)pData;
-
- int iStream = event->physical_wide;
- bool visible = !(iStream & 0x80);
-
- SetSubtitleVisibleInternal(visible);
-
- if (iStream >= 0)
- m_dvd.iSelectedSPUStream = (iStream & ~0x80);
- else
- m_dvd.iSelectedSPUStream = -1;
-
- m_CurrentSubtitle.stream = NULL;
- }
- break;
- case DVDNAV_AUDIO_STREAM_CHANGE:
- {
- // This should be the correct way i think, however we don't have any streams right now
- // since the demuxer hasn't started so it doesn't change. not sure how to do this.
- dvdnav_audio_stream_change_event_t* event = (dvdnav_audio_stream_change_event_t*)pData;
-
- // Tell system what audiostream should be opened by default
- if (event->logical >= 0)
- m_dvd.iSelectedAudioStream = event->physical;
- else
- m_dvd.iSelectedAudioStream = -1;
-
- m_CurrentAudio.stream = NULL;
- }
- break;
- case DVDNAV_HIGHLIGHT:
- {
- //dvdnav_highlight_event_t* pInfo = (dvdnav_highlight_event_t*)pData;
- int iButton = pStream->GetCurrentButton();
- CLog::Log(LOGDEBUG, "DVDNAV_HIGHLIGHT: Highlight button %d\n", iButton);
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_NORMAL);
- }
- break;
- case DVDNAV_VTS_CHANGE:
- {
- //dvdnav_vts_change_event_t* vts_change_event = (dvdnav_vts_change_event_t*)pData;
- CLog::Log(LOGDEBUG, "DVDNAV_VTS_CHANGE");
-
- //Make sure we clear all the old overlays here, or else old forced items are left.
- m_overlayContainer.Clear();
-
- //Force an aspect ratio that is set in the dvdheaders if available
- m_CurrentVideo.hint.aspect = pStream->GetVideoAspectRatio();
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsgDouble(CDVDMsg::VIDEO_SET_ASPECT, m_CurrentVideo.hint.aspect));
-
- m_SelectionStreams.Clear(STREAM_NONE, STREAM_SOURCE_NAV);
- m_SelectionStreams.Update(m_pInputStream, m_pDemuxer);
-
- return NAVRESULT_HOLD;
- }
- break;
- case DVDNAV_CELL_CHANGE:
- {
- //dvdnav_cell_change_event_t* cell_change_event = (dvdnav_cell_change_event_t*)pData;
- CLog::Log(LOGDEBUG, "DVDNAV_CELL_CHANGE");
-
- m_dvd.state = DVDSTATE_NORMAL;
-
- if( m_dvdPlayerVideo.IsInited() )
- m_dvdPlayerVideo.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
- }
- break;
- case DVDNAV_NAV_PACKET:
- {
- //pci_t* pci = (pci_t*)pData;
-
- // this should be possible to use to make sure we get
- // seamless transitions over these boundaries
- // if we remember the old vobunits boundaries
- // when a packet comes out of demuxer that has
- // pts values outside that boundary, it belongs
- // to the new vobunit, wich has new timestamps
- UpdatePlayState(0);
- }
- break;
- case DVDNAV_HOP_CHANNEL:
- {
- // This event is issued whenever a non-seamless operation has been executed.
- // Applications with fifos should drop the fifos content to speed up responsiveness.
- CLog::Log(LOGDEBUG, "DVDNAV_HOP_CHANNEL");
- if(m_dvd.state == DVDSTATE_SEEK)
- m_dvd.state = DVDSTATE_NORMAL;
- else
- m_messenger.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH));
-
- return NAVRESULT_ERROR;
- }
- break;
- case DVDNAV_STOP:
- {
- CLog::Log(LOGDEBUG, "DVDNAV_STOP");
- m_dvd.state = DVDSTATE_NORMAL;
- CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(16026), g_localizeStrings.Get(16029));
- }
- break;
- default:
- {}
- break;
- }
- }
- return NAVRESULT_NOP;
-}
-
-bool CDVDPlayer::ShowPVRChannelInfo(void)
-{
- bool bReturn(false);
-
- if (CSettings::Get().GetInt("pvrmenu.displaychannelinfo") > 0)
- {
- g_PVRManager.ShowPlayerInfo(CSettings::Get().GetInt("pvrmenu.displaychannelinfo"));
-
- bReturn = true;
- }
-
- return bReturn;
-}
-
-bool CDVDPlayer::OnAction(const CAction &action)
-{
-#define THREAD_ACTION(action) \
- do { \
- if (!IsCurrentThread()) { \
- m_messenger.Put(new CDVDMsgType<CAction>(CDVDMsg::GENERAL_GUI_ACTION, action)); \
- return true; \
- } \
- } while(false)
-
- CDVDInputStream::IMenus* pMenus = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream);
- if (pMenus)
- {
- if( m_dvd.state == DVDSTATE_STILL && m_dvd.iDVDStillTime != 0 && pMenus->GetTotalButtons() == 0 )
- {
- switch(action.GetID())
- {
- case ACTION_NEXT_ITEM:
- case ACTION_MOVE_RIGHT:
- case ACTION_MOVE_UP:
- case ACTION_SELECT_ITEM:
- {
- THREAD_ACTION(action);
- /* this will force us out of the stillframe */
- CLog::Log(LOGDEBUG, "%s - User asked to exit stillframe", __FUNCTION__);
- m_dvd.iDVDStillStartTime = 0;
- m_dvd.iDVDStillTime = 1;
- }
- return true;
- }
- }
-
-
- switch (action.GetID())
- {
-/* this code is disabled to allow switching playlist items (dvdimage "stacks") */
-#if 0
- case ACTION_PREV_ITEM: // SKIP-:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - pushed prev");
- pMenus->OnPrevious();
- g_infoManager.SetDisplayAfterSeek();
- return true;
- }
- break;
- case ACTION_NEXT_ITEM: // SKIP+:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - pushed next");
- pMenus->OnNext();
- g_infoManager.SetDisplayAfterSeek();
- return true;
- }
- break;
-#endif
- case ACTION_SHOW_VIDEOMENU: // start button
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - go to menu");
- pMenus->OnMenu();
- if (m_playSpeed == DVD_PLAYSPEED_PAUSE)
- {
- SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
- m_callback.OnPlayBackResumed();
- }
- // send a message to everyone that we've gone to the menu
- CGUIMessage msg(GUI_MSG_VIDEO_MENU_STARTED, 0, 0);
- g_windowManager.SendThreadMessage(msg);
- return true;
- }
- break;
- }
-
- if (pMenus->IsInMenu())
- {
- switch (action.GetID())
- {
- case ACTION_NEXT_ITEM:
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - pushed next in menu, stream will decide");
- pMenus->OnNext();
- g_infoManager.SetDisplayAfterSeek();
- return true;
- case ACTION_PREV_ITEM:
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - pushed prev in menu, stream will decide");
- pMenus->OnPrevious();
- g_infoManager.SetDisplayAfterSeek();
- return true;
- case ACTION_PREVIOUS_MENU:
- case ACTION_NAV_BACK:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - menu back");
- pMenus->OnBack();
- }
- break;
- case ACTION_MOVE_LEFT:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - move left");
- pMenus->OnLeft();
- }
- break;
- case ACTION_MOVE_RIGHT:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - move right");
- pMenus->OnRight();
- }
- break;
- case ACTION_MOVE_UP:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - move up");
- pMenus->OnUp();
- }
- break;
- case ACTION_MOVE_DOWN:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - move down");
- pMenus->OnDown();
- }
- break;
-
- case ACTION_MOUSE_MOVE:
- case ACTION_MOUSE_LEFT_CLICK:
- {
- CRect rs, rd;
- m_dvdPlayerVideo.GetVideoRect(rs, rd);
- CPoint pt(action.GetAmount(), action.GetAmount(1));
- if (!rd.PtInRect(pt))
- return false; // out of bounds
- THREAD_ACTION(action);
- // convert to video coords...
- pt -= CPoint(rd.x1, rd.y1);
- pt.x *= rs.Width() / rd.Width();
- pt.y *= rs.Height() / rd.Height();
- pt += CPoint(rs.x1, rs.y1);
- if (action.GetID() == ACTION_MOUSE_LEFT_CLICK)
- {
- if (pMenus->OnMouseClick(pt))
- return true;
- else
- {
- CApplicationMessenger::Get().SendAction(CAction(ACTION_TRIGGER_OSD), WINDOW_INVALID, false); // Trigger the osd
- return false;
- }
- }
- return pMenus->OnMouseMove(pt);
- }
- break;
- case ACTION_SELECT_ITEM:
- {
- THREAD_ACTION(action);
- CLog::Log(LOGDEBUG, " - button select");
- // show button pushed overlay
- if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
- m_dvdPlayerSubtitle.UpdateOverlayInfo((CDVDInputStreamNavigator*)m_pInputStream, LIBDVDNAV_BUTTON_CLICKED);
-
- pMenus->ActivateButton();
- }
- break;
- case REMOTE_0:
- case REMOTE_1:
- case REMOTE_2:
- case REMOTE_3:
- case REMOTE_4:
- case REMOTE_5:
- case REMOTE_6:
- case REMOTE_7:
- case REMOTE_8:
- case REMOTE_9:
- {
- THREAD_ACTION(action);
- // Offset from key codes back to button number
- int button = action.GetID() - REMOTE_0;
- CLog::Log(LOGDEBUG, " - button pressed %d", button);
- pMenus->SelectButton(button);
- }
- break;
- default:
- return false;
- break;
- }
- return true; // message is handled
- }
- }
-
- if (dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream))
- {
- switch (action.GetID())
- {
- case ACTION_MOVE_UP:
- case ACTION_NEXT_ITEM:
- case ACTION_CHANNEL_UP:
- m_messenger.Put(new CDVDMsg(CDVDMsg::PLAYER_CHANNEL_NEXT));
- g_infoManager.SetDisplayAfterSeek();
- ShowPVRChannelInfo();
- return true;
- break;
-
- case ACTION_MOVE_DOWN:
- case ACTION_PREV_ITEM:
- case ACTION_CHANNEL_DOWN:
- m_messenger.Put(new CDVDMsg(CDVDMsg::PLAYER_CHANNEL_PREV));
- g_infoManager.SetDisplayAfterSeek();
- ShowPVRChannelInfo();
- return true;
- break;
-
- case ACTION_CHANNEL_SWITCH:
- {
- // Offset from key codes back to button number
- int channel = action.GetAmount();
- m_messenger.Put(new CDVDMsgInt(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER, channel));
- g_infoManager.SetDisplayAfterSeek();
- ShowPVRChannelInfo();
- return true;
- }
- break;
- }
- }
-
- switch (action.GetID())
- {
- case ACTION_NEXT_ITEM:
- if (GetChapter() > 0 && GetChapter() < GetChapterCount())
- {
- m_messenger.Put(new CDVDMsgPlayerSeekChapter(GetChapter() + 1));
- g_infoManager.SetDisplayAfterSeek();
- return true;
- }
- else
- break;
- case ACTION_PREV_ITEM:
- if (GetChapter() > 0)
- {
- m_messenger.Put(new CDVDMsgPlayerSeekChapter(GetChapter() - 1));
- g_infoManager.SetDisplayAfterSeek();
- return true;
- }
- else
- break;
- }
-
- // return false to inform the caller we didn't handle the message
- return false;
-}
-
-bool CDVDPlayer::IsInMenu() const
-{
- CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream);
- if (pStream)
- {
- if( m_dvd.state == DVDSTATE_STILL )
- return true;
- else
- return pStream->IsInMenu();
- }
- return false;
-}
-
-bool CDVDPlayer::HasMenu()
-{
- CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream);
- if (pStream)
- return pStream->HasMenu();
- else
- return false;
-}
-
-std::string CDVDPlayer::GetPlayerState()
-{
- CSingleLock lock(m_StateSection);
- return m_State.player_state;
-}
-
-bool CDVDPlayer::SetPlayerState(std::string state)
-{
- m_messenger.Put(new CDVDMsgPlayerSetState(state));
- return true;
-}
-
-int CDVDPlayer::GetChapterCount()
-{
- CSingleLock lock(m_StateSection);
- return m_State.chapter_count;
-}
-
-int CDVDPlayer::GetChapter()
-{
- CSingleLock lock(m_StateSection);
- return m_State.chapter;
-}
-
-void CDVDPlayer::GetChapterName(std::string& strChapterName)
-{
- CSingleLock lock(m_StateSection);
- strChapterName = m_State.chapter_name;
-}
-
-int CDVDPlayer::SeekChapter(int iChapter)
-{
- if (GetChapter() > 0)
- {
- if (iChapter < 0)
- iChapter = 0;
- if (iChapter > GetChapterCount())
- return 0;
-
- // Seek to the chapter.
- m_messenger.Put(new CDVDMsgPlayerSeekChapter(iChapter));
- SynchronizeDemuxer(100);
- }
-
- return 0;
-}
-
-int CDVDPlayer::AddSubtitle(const std::string& strSubPath)
-{
- return AddSubtitleFile(strSubPath);
-}
-
-int CDVDPlayer::GetCacheLevel() const
-{
- CSingleLock lock(m_StateSection);
- return (int)(m_StateInput.cache_level * 100);
-}
-
-double CDVDPlayer::GetQueueTime()
-{
- int a = m_dvdPlayerAudio.GetLevel();
- int v = m_dvdPlayerVideo.GetLevel();
- return max(a, v) * 8000.0 / 100;
-}
-
-void CDVDPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
-{
- info.bitrate = m_dvdPlayerVideo.GetVideoBitrate();
-
- std::string retVal;
- if (m_pDemuxer && (m_CurrentVideo.id != -1))
- {
- m_pDemuxer->GetStreamCodecName(m_CurrentVideo.id, retVal);
- CDemuxStreamVideo* stream = static_cast<CDemuxStreamVideo*>(m_pDemuxer->GetStream(m_CurrentVideo.id));
- if (stream)
- {
- info.width = stream->iWidth;
- info.height = stream->iHeight;
- }
- }
- info.videoCodecName = retVal;
- info.videoAspectRatio = m_dvdPlayerVideo.GetAspectRatio();
- m_dvdPlayerVideo.GetVideoRect(info.SrcRect, info.DestRect);
- info.stereoMode = m_dvdPlayerVideo.GetStereoMode();
- if (info.stereoMode == "mono")
- info.stereoMode = "";
-}
-
-int CDVDPlayer::GetSourceBitrate()
-{
- if (m_pInputStream)
- return (int)m_pInputStream->GetBitstreamStats().GetBitrate();
-
- return 0;
-}
-
-void CDVDPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
-{
- if (index < 0 || index > GetAudioStreamCount() - 1 )
- return;
-
- if (index == GetAudioStream())
- info.bitrate = m_dvdPlayerAudio.GetAudioBitrate();
- else if (m_pDemuxer)
- {
- CDemuxStreamAudio* stream = m_pDemuxer->GetStreamFromAudioId(index);
- if (stream)
- info.bitrate = stream->iBitRate;
- }
-
- SelectionStream& s = m_SelectionStreams.Get(STREAM_AUDIO, index);
- if(s.language.length() > 0)
- info.language = s.language;
-
- if(s.name.length() > 0)
- info.name = s.name;
-
- if(s.type == STREAM_NONE)
- info.name += " (Invalid)";
-
- if (m_pDemuxer)
- {
- CDemuxStreamAudio* stream = static_cast<CDemuxStreamAudio*>(m_pDemuxer->GetStreamFromAudioId(index));
- if (stream)
- {
- info.channels = stream->iChannels;
- std::string codecName;
- m_pDemuxer->GetStreamCodecName(stream->iId, codecName);
- info.audioCodecName = codecName;
- }
- }
-}
-
-int CDVDPlayer::AddSubtitleFile(const std::string& filename, const std::string& subfilename, CDemuxStream::EFlags flags)
-{
- std::string ext = URIUtils::GetExtension(filename);
- std::string vobsubfile = subfilename;
- if(ext == ".idx")
- {
- if (vobsubfile.empty()) {
- // find corresponding .sub (e.g. in case of manually selected .idx sub)
- vobsubfile = CUtil::GetVobSubSubFromIdx(filename);
- if (vobsubfile.empty())
- return -1;
- }
-
- CDVDDemuxVobsub v;
- if(!v.Open(filename, vobsubfile))
- return -1;
- m_SelectionStreams.Update(NULL, &v);
- int index = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, m_SelectionStreams.Source(STREAM_SOURCE_DEMUX_SUB, filename), 0);
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = flags;
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).filename2 = vobsubfile;
- ExternalStreamInfo info;
- CUtil::GetExternalStreamDetailsFromFilename(m_filename, vobsubfile, info);
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).name = info.name;
- if (m_SelectionStreams.Get(STREAM_SUBTITLE, index).language.empty())
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).language = info.language;
-
- if (static_cast<CDemuxStream::EFlags>(info.flag) == CDemuxStream::FLAG_NONE)
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = flags;
- else
- m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = static_cast<CDemuxStream::EFlags>(info.flag);
-
- return index;
- }
- if(ext == ".sub")
- {
- // if this looks like vobsub file (i.e. .idx found), add it as such
- std::string vobsubidx = CUtil::GetVobSubIdxFromSub(filename);
- if (!vobsubidx.empty())
- return AddSubtitleFile(vobsubidx, filename, flags);
- }
- SelectionStream s;
- s.source = m_SelectionStreams.Source(STREAM_SOURCE_TEXT, filename);
- s.type = STREAM_SUBTITLE;
- s.id = 0;
- s.filename = filename;
- ExternalStreamInfo info;
- CUtil::GetExternalStreamDetailsFromFilename(m_filename, filename, info);
- s.name = info.name;
- s.language = info.language;
- if (static_cast<CDemuxStream::EFlags>(info.flag) == CDemuxStream::FLAG_NONE)
- s .flags = flags;
- else
- s.flags = static_cast<CDemuxStream::EFlags>(info.flag);
-
- m_SelectionStreams.Update(s);
- return m_SelectionStreams.IndexOf(STREAM_SUBTITLE, s.source, s.id);
-}
-
-void CDVDPlayer::UpdatePlayState(double timeout)
-{
- if(m_StateInput.timestamp != 0
- && m_StateInput.timestamp + DVD_MSEC_TO_TIME(timeout) > CDVDClock::GetAbsoluteClock())
- return;
-
- 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 if(m_CurrentVideo.startpts != DVD_NOPTS_VALUE)
- state.dts = m_CurrentVideo.startpts;
- else if(m_CurrentAudio.startpts != DVD_NOPTS_VALUE)
- state.dts = m_CurrentAudio.startpts;
-
-
- if(m_pDemuxer)
- {
- state.chapter = m_pDemuxer->GetChapter();
- state.chapter_count = m_pDemuxer->GetChapterCount();
- m_pDemuxer->GetChapterName(state.chapter_name);
-
- if(state.dts == DVD_NOPTS_VALUE)
- state.time = 0;
- 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
- CDVDInputStream::IChannel* pChannel = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if (pChannel)
- {
- state.canrecord = pChannel->CanRecord();
- state.recording = pChannel->IsRecording();
- }
-
- CDVDInputStream::IDisplayTime* pDisplayTime = dynamic_cast<CDVDInputStream::IDisplayTime*>(m_pInputStream);
- if (pDisplayTime && pDisplayTime->GetTotalTime() > 0)
- {
- state.time = pDisplayTime->GetTime();
- state.time_total = pDisplayTime->GetTotalTime();
- state.time_src = ETIMESOURCE_INPUT;
- }
-
- 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 (CDVDInputStream::ISeekable* ptr = dynamic_cast<CDVDInputStream::ISeekable*>(m_pInputStream))
- {
- state.canpause = ptr->CanPause();
- state.canseek = ptr->CanSeek();
- }
- }
-
- if (m_Edl.HasCut())
- {
- state.time = m_Edl.RemoveCutTime(llrint(state.time));
- state.time_total = m_Edl.RemoveCutTime(llrint(state.time_total));
- }
-
- 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 (m_CurrentAudio.id >= 0 && m_pDemuxer)
- {
- CDemuxStream* pStream = m_pDemuxer->GetStream(m_CurrentAudio.id);
- if (pStream && pStream->type == STREAM_AUDIO)
- ((CDemuxStreamAudio*)pStream)->GetStreamInfo(state.demux_audio);
- }
- else
- state.demux_audio = "";
-
- if (m_CurrentVideo.id >= 0 && m_pDemuxer)
- {
- CDemuxStream* pStream = m_pDemuxer->GetStream(m_CurrentVideo.id);
- if (pStream && pStream->type == STREAM_VIDEO)
- ((CDemuxStreamVideo*)pStream)->GetStreamInfo(state.demux_video);
- }
- else
- state.demux_video = "";
-
- double level, delay, offset;
- if(GetCachingTimes(level, delay, offset))
- {
- state.cache_delay = max(0.0, delay);
- state.cache_level = max(0.0, min(1.0, level));
- state.cache_offset = offset;
- }
- else
- {
- state.cache_delay = 0.0;
- state.cache_level = min(1.0, GetQueueTime() / 8000.0);
- state.cache_offset = GetQueueTime() / state.time_total;
- }
-
- XFILE::SCacheStatus status;
- if(m_pInputStream && m_pInputStream->GetCacheStatus(&status))
- {
- state.cache_bytes = status.forward;
- if(state.time_total)
- state.cache_bytes += m_pInputStream->GetLength() * GetQueueTime() / state.time_total;
- }
- else
- state.cache_bytes = 0;
-
- state.timestamp = CDVDClock::GetAbsoluteClock();
- //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)state.time, (double)state.timestamp, (int)DVD_TIME_TO_MSEC(state.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_stamp), (int)m_playSpeed, (int)m_caching, llrint(state.time + DVD_TIME_TO_MSEC(offset)));}
-
- CSingleLock lock(m_StateSection);
- m_StateInput = state;
-}
-
-void CDVDPlayer::UpdateApplication(double timeout)
-{
- if(m_UpdateApplication != 0
- && m_UpdateApplication + DVD_MSEC_TO_TIME(timeout) > CDVDClock::GetAbsoluteClock())
- return;
-
- CDVDInputStream::IChannel* pStream = dynamic_cast<CDVDInputStream::IChannel*>(m_pInputStream);
- if(pStream)
- {
- CFileItem item(g_application.CurrentFileItem());
- if(pStream->UpdateItem(item))
- {
- g_application.CurrentFileItem() = item;
- CApplicationMessenger::Get().SetCurrentItem(item);
- }
- }
- m_UpdateApplication = CDVDClock::GetAbsoluteClock();
-}
-
-bool CDVDPlayer::CanRecord()
-{
- CSingleLock lock(m_StateSection);
- return m_State.canrecord;
-}
-
-bool CDVDPlayer::IsRecording()
-{
- CSingleLock lock(m_StateSection);
- return m_State.recording;
-}
-
-bool CDVDPlayer::Record(bool bOnOff)
-{
- if (m_pInputStream && (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_TV) ||
- m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) )
- {
- m_messenger.Put(new CDVDMsgBool(CDVDMsg::PLAYER_SET_RECORD, bOnOff));
- return true;
- }
- return false;
-}
-
-bool CDVDPlayer::GetStreamDetails(CStreamDetails &details)
-{
- if (m_pDemuxer)
- {
- std::vector<SelectionStream> subs = m_SelectionStreams.Get(STREAM_SUBTITLE);
- std::vector<CStreamDetailSubtitle> extSubDetails;
- for (unsigned int i = 0; i < subs.size(); i++)
- {
- if (subs[i].filename == m_filename)
- continue;
-
- CStreamDetailSubtitle p;
- p.m_strLanguage = subs[i].language;
- extSubDetails.push_back(p);
- }
-
- bool result = CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, extSubDetails, details);
- if (result && details.GetStreamCount(CStreamDetail::VIDEO) > 0) // this is more correct (dvds in particular)
- {
- /*
- * 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_dvdPlayerVideo.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;
- }
- else
- return false;
-}
-
-std::string CDVDPlayer::GetPlayingTitle()
-{
- /* Currently we support only Title Name from Teletext line 30 */
- TextCacheStruct_t* ttcache = m_dvdPlayerTeletext.GetTeletextCache();
- if (ttcache && !ttcache->line30.empty())
- return ttcache->line30;
-
- return "";
-}
-
-bool CDVDPlayer::SwitchChannel(const CPVRChannel &channel)
-{
- if (!g_PVRManager.CheckParentalLock(channel))
- return false;
-
- /* set GUI info */
- if (!g_PVRManager.PerformChannelSwitch(channel, true))
- return false;
-
- UpdateApplication(0);
- UpdatePlayState(0);
-
- /* select the new channel */
- m_messenger.Put(new CDVDMsgType<CPVRChannel>(CDVDMsg::PLAYER_CHANNEL_SELECT, channel));
-
- return true;
-}
-
-bool CDVDPlayer::CachePVRStream(void) const
-{
- return m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) &&
- !g_PVRManager.IsPlayingRecording() &&
- g_advancedSettings.m_bPVRCacheInDvdPlayer;
-}
-
-void CDVDPlayer::GetRenderFeatures(std::vector<int> &renderFeatures)
-{
- renderFeatures.push_back(RENDERFEATURE_STRETCH);
- renderFeatures.push_back(RENDERFEATURE_CROP);
- renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO);
- renderFeatures.push_back(RENDERFEATURE_ZOOM);
-}
-
-void CDVDPlayer::GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods)
-{
- deinterlaceMethods.push_back(VS_INTERLACEMETHOD_DEINTERLACE);
-}
-
-void CDVDPlayer::GetDeinterlaceModes(std::vector<int> &deinterlaceModes)
-{
- deinterlaceModes.push_back(VS_DEINTERLACEMODE_AUTO);
- deinterlaceModes.push_back(VS_DEINTERLACEMODE_OFF);
- deinterlaceModes.push_back(VS_DEINTERLACEMODE_FORCE);
-}
-
-void CDVDPlayer::GetScalingMethods(std::vector<int> &scalingMethods)
-{
-}
-
-void CDVDPlayer::GetAudioCapabilities(std::vector<int> &audioCaps)
-{
- audioCaps.push_back(IPC_AUD_OFFSET);
- audioCaps.push_back(IPC_AUD_SELECT_STREAM);
- audioCaps.push_back(IPC_AUD_SELECT_OUTPUT);
- audioCaps.push_back(IPC_AUD_AMP);
-}
-
-void CDVDPlayer::GetSubtitleCapabilities(std::vector<int> &subCaps)
-{
- subCaps.push_back(IPC_SUBS_ALL);
-}
-
-#endif
diff --git a/xbmc/cores/omxplayer/OMXPlayer.h b/xbmc/cores/omxplayer/OMXPlayer.h
deleted file mode 100644
index 7c1b34d5ed..0000000000
--- a/xbmc/cores/omxplayer/OMXPlayer.h
+++ /dev/null
@@ -1,508 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2011-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "cores/IPlayer.h"
-#include "threads/Thread.h"
-
-#include "cores/dvdplayer/IDVDPlayer.h"
-
-#include "DVDMessageQueue.h"
-#include "OMXCore.h"
-#include "OMXClock.h"
-#include "OMXPlayerAudio.h"
-#include "OMXPlayerVideo.h"
-#include "DVDPlayerSubtitle.h"
-#include "DVDPlayerTeletext.h"
-
-//#include "DVDChapterReader.h"
-#include "DVDSubtitles/DVDFactorySubtitle.h"
-#include "utils/BitstreamStats.h"
-
-#include "linux/DllBCM.h"
-#include "Edl.h"
-#include "FileItem.h"
-#include "threads/SingleLock.h"
-
-class COMXPlayer;
-class OMXPlayerVideo;
-class OMXPlayerAudio;
-
-namespace PVR
-{
- class CPVRChannel;
-}
-
-#define DVDSTATE_NORMAL 0x00000001 // normal dvd state
-#define DVDSTATE_STILL 0x00000002 // currently displaying a still frame
-#define DVDSTATE_WAIT 0x00000003 // waiting for demuxer read error
-#define DVDSTATE_SEEK 0x00000004 // we are finishing a seek request
-
-class COMXCurrentStream
-{
-public:
- int id; // demuxerid of current playing stream
- 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
- bool inited;
- bool started; // has the player started
- const StreamType type;
- const int player;
- // stuff to handle starting after seek
- double startpts;
-
- COMXCurrentStream(StreamType t, int i)
- : type(t)
- , player(i)
- {
- Clear();
- }
-
- void Clear()
- {
- id = -1;
- source = STREAM_SOURCE_NONE;
- dts = DVD_NOPTS_VALUE;
- dts_state = DVD_NOPTS_VALUE;
- dur = DVD_NOPTS_VALUE;
- hint.Clear();
- stream = NULL;
- changes = 0;
- inited = false;
- started = false;
- startpts = DVD_NOPTS_VALUE;
- }
-
- double dts_end()
- {
- if(dts == DVD_NOPTS_VALUE)
- return DVD_NOPTS_VALUE;
- if(dur == DVD_NOPTS_VALUE)
- return dts;
- return dts + dur;
- }
-};
-
-typedef struct
-{
- StreamType type;
- int type_index;
- std::string filename;
- std::string filename2; // for vobsub subtitles, 2 files are necessary (idx/sub)
- std::string language;
- std::string name;
- CDemuxStream::EFlags flags;
- int source;
- int id;
- std::string codec;
- int channels;
-} OMXSelectionStream;
-
-typedef std::vector<OMXSelectionStream> OMXSelectionStreams;
-
-class COMXSelectionStreams
-{
- CCriticalSection m_section;
- OMXSelectionStream m_invalid;
-public:
- COMXSelectionStreams()
- {
- m_invalid.id = -1;
- m_invalid.source = STREAM_SOURCE_NONE;
- m_invalid.type = STREAM_NONE;
- }
- std::vector<OMXSelectionStream> m_Streams;
-
- int IndexOf (StreamType type, int source, int id) const;
- int IndexOf (StreamType type, COMXPlayer& p) const;
- int Count (StreamType type) const { return IndexOf(type, STREAM_SOURCE_NONE, -1) + 1; }
- OMXSelectionStream& Get (StreamType type, int index);
- bool Get (StreamType type, CDemuxStream::EFlags flag, OMXSelectionStream& out);
-
- OMXSelectionStreams Get(StreamType type);
- template<typename Compare> OMXSelectionStreams Get(StreamType type, Compare compare)
- {
- OMXSelectionStreams streams = Get(type);
- std::stable_sort(streams.begin(), streams.end(), compare);
- return streams;
- }
-
- void Clear (StreamType type, StreamSource source);
- int Source (StreamSource source, std::string filename);
-
- void Update (OMXSelectionStream& s);
- void Update (CDVDInputStream* input, CDVDDemux* demuxer);
-};
-
-
-#define DVDPLAYER_AUDIO 1
-#define DVDPLAYER_VIDEO 2
-#define DVDPLAYER_SUBTITLE 3
-#define DVDPLAYER_TELETEXT 4
-
-class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
-{
-public:
- COMXPlayer(IPlayerCallback& callback);
- virtual ~COMXPlayer();
- virtual bool OpenFile(const CFileItem& file, const CPlayerOptions &options);
- virtual bool CloseFile(bool reopen = false);
- virtual bool IsPlaying() const;
- virtual void Pause();
- virtual bool IsPaused() const;
- virtual bool HasVideo() const;
- virtual bool HasAudio() const;
- virtual bool IsPassthrough() const;
- virtual bool CanSeek();
- virtual void Seek(bool bPlus, bool bLargeStep, bool bChapterOverride);
- virtual bool SeekScene(bool bPlus = true);
- virtual void SeekPercentage(float iPercent);
- virtual float GetPercentage();
- virtual float GetCachePercentage();
-
- virtual void RegisterAudioCallback(IAudioCallback* pCallback) { m_omxPlayerAudio.RegisterAudioCallback(pCallback); }
- virtual void UnRegisterAudioCallback() { m_omxPlayerAudio.UnRegisterAudioCallback(); }
- virtual void SetVolume(float nVolume) { m_omxPlayerAudio.SetVolume(nVolume); }
- virtual void SetDynamicRangeCompression(long drc) { m_omxPlayerAudio.SetDynamicRangeCompression(drc); }
- virtual void SetMute(bool bOnOff) { m_omxPlayerAudio.SetMute(bOnOff); }
- virtual bool ControlsVolume() {return true;}
- virtual void GetAudioInfo(std::string &strAudioInfo);
- virtual void GetVideoInfo(std::string &strVideoInfo);
- virtual void GetGeneralInfo(std::string &strVideoInfo);
- virtual bool CanRecord();
- virtual bool IsRecording();
- virtual bool CanPause();
- virtual bool Record(bool bOnOff);
- virtual void SetAVDelay(float fValue = 0.0f);
- virtual float GetAVDelay();
-
- virtual void SetSubTitleDelay(float fValue = 0.0f);
- virtual float GetSubTitleDelay();
- virtual int GetSubtitleCount();
- virtual int GetSubtitle();
- virtual void GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info);
- virtual void SetSubtitle(int iStream);
- virtual bool GetSubtitleVisible();
- virtual void SetSubtitleVisible(bool bVisible);
- virtual int AddSubtitle(const std::string& strSubPath);
-
- virtual int GetAudioStreamCount();
- virtual int GetAudioStream();
- virtual void SetAudioStream(int iStream);
-
- virtual TextCacheStruct_t* GetTeletextCache();
- virtual void LoadPage(int p, int sp, unsigned char* buffer);
-
- virtual int GetChapterCount();
- virtual int GetChapter();
- virtual void GetChapterName(std::string& strChapterName);
- virtual int SeekChapter(int iChapter);
-
- virtual void SeekTime(int64_t iTime);
- virtual int64_t GetTime();
- virtual int64_t GetTotalTime();
- virtual void ToFFRW(int iSpeed);
- virtual bool OnAction(const CAction &action);
- virtual bool HasMenu();
-
- virtual int GetSourceBitrate();
- virtual void GetVideoStreamInfo(SPlayerVideoStreamInfo &info);
- virtual bool GetStreamDetails(CStreamDetails &details);
- virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
-
- virtual std::string GetPlayerState();
- virtual bool SetPlayerState(std::string state);
-
- virtual std::string GetPlayingTitle();
-
- virtual bool SwitchChannel(const PVR::CPVRChannel &channel);
- virtual bool CachePVRStream(void) const;
-
- enum ECacheState
- { CACHESTATE_DONE = 0
- , CACHESTATE_FULL // player is filling up the demux queue
- , CACHESTATE_PVR // player is waiting for some data in each buffer
- , CACHESTATE_INIT // player is waiting for first packet of each stream
- , CACHESTATE_PLAY // player is waiting for players to not be stalled
- , CACHESTATE_FLUSH // temporary state player will choose startup between init or full
- };
-
- virtual bool IsCaching() const { return m_caching == CACHESTATE_FULL || m_caching == CACHESTATE_PVR; }
- virtual int GetCacheLevel() const ;
-
- virtual int OnDVDNavResult(void* pData, int iMessage);
-
- virtual void GetRenderFeatures(std::vector<int> &renderFeatures);
- virtual void GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods);
- virtual void GetDeinterlaceModes(std::vector<int> &deinterlaceModes);
- virtual void GetScalingMethods(std::vector<int> &scalingMethods);
- virtual void GetAudioCapabilities(std::vector<int> &audioCaps);
- virtual void GetSubtitleCapabilities(std::vector<int> &subCaps);
-protected:
- friend class COMXSelectionStreams;
-
- virtual void OnStartup();
- virtual void OnExit();
- virtual void Process();
-
- bool OpenStream(COMXCurrentStream& current, int iStream, int source, bool reset = true);
- bool OpenStreamPlayer(COMXCurrentStream& current, CDVDStreamInfo& hint, bool reset);
- bool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);
- bool OpenVideoStream(CDVDStreamInfo& hint, bool reset = true);
- bool OpenSubtitleStream(CDVDStreamInfo& hint);
- bool OpenTeletextStream(CDVDStreamInfo& hint);
-
- /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
- * If these are not available, subtitles are disabled.
- * \return true if the subtitles were changed, false otherwise.
- */
- bool AdaptForcedSubtitles();
- bool CloseStream(COMXCurrentStream& current, bool bWaitForBuffers);
-
- bool CheckIsCurrent(COMXCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg);
- void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
- void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
- void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
- void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
- void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
-
- bool ShowPVRChannelInfo();
-
- int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
- void SetSubtitleVisibleInternal(bool bVisible);
-
- /**
- * one of the DVD_PLAYSPEED defines
- */
- void SetPlaySpeed(int iSpeed);
- int GetPlaySpeed() { return m_playSpeed; }
- void SetCaching(ECacheState state);
-
- int64_t GetTotalTimeInMsec();
-
- double GetQueueTime();
- bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
-
-
- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
-
- void HandleMessages();
- void HandlePlaySpeed();
- bool IsInMenu() const;
-
- void SynchronizePlayers(unsigned int sources);
- void SynchronizeDemuxer(unsigned int timeout);
- void CheckAutoSceneSkip();
- void CheckContinuity(COMXCurrentStream& current, DemuxPacket* pPacket);
- bool CheckSceneSkip(COMXCurrentStream& current);
- bool CheckPlayerInit(COMXCurrentStream& current);
- bool CheckStartCaching(COMXCurrentStream& current);
- void UpdateCorrection(DemuxPacket* pkt, double correction);
- void UpdateTimestamps(COMXCurrentStream& current, DemuxPacket* pPacket);
- IDVDStreamPlayer* GetStreamPlayer(unsigned int player);
- void SendPlayerMessage(CDVDMsg* pMsg, unsigned int target);
-
- bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
- bool IsValidStream(COMXCurrentStream& stream);
- bool IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream);
- void CheckBetterStream(COMXCurrentStream& current, CDemuxStream* stream);
- void CheckStreamChanges(COMXCurrentStream& current, CDemuxStream* stream);
- bool CheckDelayedChannelEntry(void);
-
- bool OpenInputStream();
- bool OpenDemuxStream();
- void OpenDefaultStreams(bool reset = true);
-
- void UpdateApplication(double timeout);
- void UpdatePlayState(double timeout);
- void UpdateClockMaster();
- double m_UpdateApplication;
-
- bool m_bAbortRequest;
-
- std::string m_filename; // holds the actual filename
- std::string m_mimetype; // hold a hint to what content file contains (mime type)
- ECacheState m_caching;
- CFileItem m_item;
- XbmcThreads::EndTime m_ChannelEntryTimeOut;
-
-
- COMXCurrentStream m_CurrentAudio;
- COMXCurrentStream m_CurrentVideo;
- COMXCurrentStream m_CurrentSubtitle;
- COMXCurrentStream m_CurrentTeletext;
-
- COMXSelectionStreams m_SelectionStreams;
-
- int m_playSpeed;
- struct SSpeedState
- {
- double lastpts; // holds last display pts during ff/rw operations
- double lasttime;
- } m_SpeedState;
-
- int m_errorCount;
- double m_offset_pts;
-
- CDVDMessageQueue m_messenger; // thread messenger
-
- OMXPlayerVideo m_omxPlayerVideo; // video part
- OMXPlayerAudio m_omxPlayerAudio; // audio part
- CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
- CDVDTeletextData m_dvdPlayerTeletext; // teletext part
-
- CDVDClock m_clock; // master clock
- OMXClock m_av_clock;
-
- bool m_stepped;
- int m_video_fifo;
- int m_audio_fifo;
- double m_last_check_time; // we periodically check for gpu underrun
- double m_stamp; // last media stamp
-
- CDVDOverlayContainer m_overlayContainer;
-
- CDVDInputStream* m_pInputStream; // input stream for current playing file
- CDVDDemux* m_pDemuxer; // demuxer for current playing file
- CDVDDemux* m_pSubtitleDemuxer;
-
- struct SDVDInfo
- {
- void Clear()
- {
- state = DVDSTATE_NORMAL;
- iSelectedSPUStream = -1;
- iSelectedAudioStream = -1;
- iDVDStillTime = 0;
- iDVDStillStartTime = 0;
- }
-
- int state; // current dvdstate
- unsigned int iDVDStillTime; // total time in ticks we should display the still before continuing
- unsigned int iDVDStillStartTime; // time in ticks when we started the still
- int iSelectedSPUStream; // mpeg stream id, or -1 if disabled
- 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;
- chapter_name = "";
- chapter_count = 0;
- canrecord = false;
- recording = false;
- canpause = false;
- canseek = false;
- demux_video = "";
- demux_audio = "";
- cache_bytes = 0;
- cache_level = 0.0;
- cache_delay = 0.0;
- 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
-
- int chapter; // current chapter
- std::string chapter_name; // name of current chapter
- int chapter_count;// number of chapter
-
- bool canrecord; // can input stream record
- bool recording; // are we currently recording
-
- bool canpause; // pvr: can pause the current playing item
- bool canseek; // pvr: can seek in the current playing item
-
- std::string demux_video;
- std::string demux_audio;
-
- int64_t cache_bytes; // number of bytes current's cached
- 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_StateInput;
- CCriticalSection m_StateSection;
-
- CEvent m_ready;
-
- CEdl m_Edl;
-
- struct SEdlAutoSkipMarkers {
-
- void Clear()
- {
- cut = -1;
- commbreak_start = -1;
- commbreak_end = -1;
- seek_to_start = false;
- mute = false;
- }
-
- int cut; // last automatically skipped EDL cut seek position
- int commbreak_start; // start time of the last commercial break automatically skipped
- int commbreak_end; // end time of the last commercial break automatically skipped
- bool seek_to_start; // whether seeking can go back to the start of a previously skipped break
- bool mute; // whether EDL mute is on
-
- } m_EdlAutoSkipMarkers;
-
- CPlayerOptions m_PlayerOptions;
-
- bool m_HasVideo;
- bool m_HasAudio;
-
- bool m_DemuxerPausePending;
-};
diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
index c1b7a0dcfa..55f8ac779b 100644
--- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -40,7 +40,7 @@
#include "settings/Settings.h"
#include "utils/TimeUtils.h"
-#include "OMXPlayer.h"
+#include "DVDPlayer.h"
#include "linux/RBP.h"
#include "cores/AudioEngine/AEFactory.h"
@@ -77,7 +77,6 @@ OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent)
m_stalled = false;
m_audioClock = DVD_NOPTS_VALUE;
m_buffer_empty = false;
- m_nChannels = 0;
m_DecoderOpen = false;
m_bad_state = false;
m_hints_current.Clear();
@@ -141,7 +140,6 @@ void OMXPlayerAudio::OpenStream(CDVDStreamInfo &hints, COMXAudioCodecOMX *codec)
m_silence = false;
m_started = false;
m_flush = false;
- m_nChannels = 0;
m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;
m_use_hw_decode = g_advancedSettings.m_omxHWAudioDecode;
m_format.m_dataFormat = GetDataFormat(m_hints);
@@ -428,15 +426,27 @@ void OMXPlayerAudio::Process()
}
else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
{
- COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
- double pts = m_audioClock;
- double stamp = m_av_clock->OMXMediaTime();
+ CDVDPlayer::SPlayerState& state = ((CDVDMsgType<CDVDPlayer::SPlayerState>*)pMsg)->m_value;
- if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
- state.time = stamp == 0.0 ? state.time : DVD_TIME_TO_MSEC(stamp + state.time_offset);
+ if (m_speed != DVD_PLAYSPEED_NORMAL && m_speed != DVD_PLAYSPEED_PAUSE)
+ {
+ if(state.time_src == CDVDPlayer::ETIMESOURCE_CLOCK)
+ state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
+ else
+ state.timestamp = CDVDClock::GetAbsoluteClock();
+ }
else
- state.time = stamp == 0.0 || pts == DVD_NOPTS_VALUE ? state.time : state.time + DVD_TIME_TO_MSEC(stamp - pts);
- state.timestamp = m_av_clock->GetAbsoluteClock();
+ {
+ double pts = m_audioClock;
+ double stamp = m_av_clock->OMXMediaTime();
+ if(state.time_src == CDVDPlayer::ETIMESOURCE_CLOCK)
+ state.time = stamp == 0.0 ? state.time : DVD_TIME_TO_MSEC(stamp + state.time_offset);
+ else
+ state.time = stamp == 0.0 || pts == DVD_NOPTS_VALUE ? state.time : state.time + DVD_TIME_TO_MSEC(stamp - pts);
+ state.timestamp = CDVDClock::GetAbsoluteClock();
+ if (stamp == 0.0) // cause message to be ignored
+ state.player = 0;
+ }
state.player = DVDPLAYER_AUDIO;
m_messageParent.Put(pMsg->Acquire());
}
@@ -552,7 +562,6 @@ AEDataFormat OMXPlayerAudio::GetDataFormat(CDVDStreamInfo hints)
bool OMXPlayerAudio::OpenDecoder()
{
- m_nChannels = m_hints.channels;
m_passthrough = false;
m_hw_decode = false;
@@ -587,7 +596,7 @@ bool OMXPlayerAudio::OpenDecoder()
else
{
CLog::Log(LOGINFO, "Audio codec %s channels %d samplerate %d bitspersample %d\n",
- m_codec_name.c_str(), m_nChannels, m_hints.samplerate, m_hints.bitspersample);
+ m_codec_name.c_str(), m_hints.channels, m_hints.samplerate, m_hints.bitspersample);
}
m_started = false;
@@ -640,6 +649,11 @@ int OMXPlayerAudio::GetAudioBitrate()
return (int)m_audioStats.GetBitrate();
}
+int OMXPlayerAudio::GetAudioChannels()
+{
+ return m_hints.channels;
+}
+
std::string OMXPlayerAudio::GetPlayerInfo()
{
std::ostringstream s;
diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.h b/xbmc/cores/omxplayer/OMXPlayerAudio.h
index 636249e689..2397db4753 100644
--- a/xbmc/cores/omxplayer/OMXPlayerAudio.h
+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.h
@@ -36,7 +36,7 @@
#include "utils/BitstreamStats.h"
#include "xbmc/linux/DllBCM.h"
-class OMXPlayerAudio : public CThread, public IDVDStreamPlayer
+class OMXPlayerAudio : public CThread, public IDVDStreamPlayerAudio
{
protected:
CDVDMessageQueue m_messageQueue;
@@ -63,7 +63,6 @@ protected:
bool m_buffer_empty;
bool m_flush;
- int m_nChannels;
bool m_DecoderOpen;
bool m_bad_state;
@@ -100,14 +99,13 @@ public:
double GetCurrentPts() { return m_audioClock; };
void SubmitEOS();
- void RegisterAudioCallback(IAudioCallback* pCallback) { m_omxAudio.RegisterAudioCallback(pCallback); }
- void UnRegisterAudioCallback() { m_omxAudio.UnRegisterAudioCallback(); }
void SetVolume(float fVolume) { m_omxAudio.SetVolume(fVolume); }
void SetMute(bool bOnOff) { m_omxAudio.SetMute(bOnOff); }
void SetDynamicRangeCompression(long drc) { m_omxAudio.SetDynamicRangeCompression(drc); }
float GetDynamicRangeAmplification() const { return m_omxAudio.GetDynamicRangeAmplification(); }
void SetSpeed(int iSpeed);
int GetAudioBitrate();
+ int GetAudioChannels();
std::string GetPlayerInfo();
bool BadState() { return m_bad_state; }
diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp
index af7123523d..7a30c6c689 100644
--- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp
+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp
@@ -47,7 +47,7 @@
#include "cores/VideoRenderers/RenderFlags.h"
#include "guilib/GraphicContext.h"
-#include "OMXPlayer.h"
+#include "DVDPlayer.h"
#include "linux/RBP.h"
using namespace RenderManager;
@@ -422,15 +422,27 @@ void OMXPlayerVideo::Process()
}
else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
{
- COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
- double pts = m_iCurrentPts;
- double stamp = m_av_clock->OMXMediaTime();
+ CDVDPlayer::SPlayerState& state = ((CDVDMsgType<CDVDPlayer::SPlayerState>*)pMsg)->m_value;
- if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
- state.time = stamp == 0.0 ? state.time : DVD_TIME_TO_MSEC(stamp + state.time_offset);
+ if (m_speed != DVD_PLAYSPEED_NORMAL && m_speed != DVD_PLAYSPEED_PAUSE)
+ {
+ if(state.time_src == CDVDPlayer::ETIMESOURCE_CLOCK)
+ state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
+ else
+ state.timestamp = CDVDClock::GetAbsoluteClock();
+ }
else
- state.time = stamp == 0.0 || pts == DVD_NOPTS_VALUE ? state.time : state.time + DVD_TIME_TO_MSEC(stamp - pts);
- state.timestamp = m_av_clock->GetAbsoluteClock();
+ {
+ double pts = m_iCurrentPts;
+ double stamp = m_av_clock->OMXMediaTime();
+ if(state.time_src == CDVDPlayer::ETIMESOURCE_CLOCK)
+ state.time = stamp == 0.0 ? state.time : DVD_TIME_TO_MSEC(stamp + state.time_offset);
+ else
+ state.time = stamp == 0.0 || pts == DVD_NOPTS_VALUE ? state.time : state.time + DVD_TIME_TO_MSEC(stamp - pts);
+ state.timestamp = CDVDClock::GetAbsoluteClock();
+ if (stamp == 0.0) // cause message to be ignored
+ state.player = 0;
+ }
state.player = DVDPLAYER_VIDEO;
m_messageParent.Put(pMsg->Acquire());
}
@@ -592,11 +604,6 @@ void OMXPlayerVideo::SubmitEOS()
m_omxVideo.SubmitEOS();
}
-bool OMXPlayerVideo::SubmittedEOS()
-{
- return m_omxVideo.SubmittedEOS();
-}
-
bool OMXPlayerVideo::IsEOS()
{
return m_omxVideo.IsEOS();
diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.h b/xbmc/cores/omxplayer/OMXPlayerVideo.h
index 556f9ea892..7908ee57a2 100644
--- a/xbmc/cores/omxplayer/OMXPlayerVideo.h
+++ b/xbmc/cores/omxplayer/OMXPlayerVideo.h
@@ -38,7 +38,7 @@
#include "linux/DllBCM.h"
#include "cores/VideoRenderers/RenderManager.h"
-class OMXPlayerVideo : public CThread, public IDVDStreamPlayer
+class OMXPlayerVideo : public CThread, public IDVDStreamPlayerVideo
{
protected:
CDVDMessageQueue m_messageQueue;
@@ -107,7 +107,7 @@ public:
double GetCurrentPts() { return m_iCurrentPts; };
double GetFPS() { return m_fFrameRate; };
void SubmitEOS();
- bool SubmittedEOS();
+ bool SubmittedEOS() const { return m_omxVideo.SubmittedEOS(); }
void SetDelay(double delay) { m_iVideoDelay = delay; }
double GetDelay() { return m_iVideoDelay; }
void SetSpeed(int iSpeed);
diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp
index b9256eaf5d..0363aaad3b 100644
--- a/xbmc/cores/omxplayer/OMXVideo.cpp
+++ b/xbmc/cores/omxplayer/OMXVideo.cpp
@@ -851,9 +851,10 @@ void COMXVideo::Reset(void)
return;
m_setStartTime = true;
- m_omx_decoder.FlushInput();
+ m_omx_decoder.FlushAll();
if(m_deinterlace)
- m_omx_image_fx.FlushInput();
+ m_omx_image_fx.FlushAll();
+ m_omx_sched.FlushAll();
}
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h
index 226000e925..c8fd5fbce4 100644
--- a/xbmc/cores/omxplayer/OMXVideo.h
+++ b/xbmc/cores/omxplayer/OMXVideo.h
@@ -63,7 +63,7 @@ public:
int GetInputBufferSize();
void SubmitEOS();
bool IsEOS();
- bool SubmittedEOS() { return m_submitted_eos; }
+ bool SubmittedEOS() const { return m_submitted_eos; }
bool BadState() { return m_omx_decoder.BadState(); };
protected:
// Video format
diff --git a/xbmc/cores/omxplayer/omxplayer_advancedsettings.xml b/xbmc/cores/omxplayer/omxplayer_advancedsettings.xml
index 77c6a155cd..1d4b72eb1a 100644
--- a/xbmc/cores/omxplayer/omxplayer_advancedsettings.xml
+++ b/xbmc/cores/omxplayer/omxplayer_advancedsettings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<advancedsettings>
<video>
- <defaultplayer>omxplayer</defaultplayer>
- <defaultdvdplayer>omxplayer</defaultdvdplayer>
+ <defaultplayer>dvdplayer</defaultplayer>
+ <defaultdvdplayer>dvdplayer</defaultdvdplayer>
</video>
</advancedsettings>
diff --git a/xbmc/cores/playercorefactory/PlayerCoreConfig.h b/xbmc/cores/playercorefactory/PlayerCoreConfig.h
index c590cca364..696a26c170 100644
--- a/xbmc/cores/playercorefactory/PlayerCoreConfig.h
+++ b/xbmc/cores/playercorefactory/PlayerCoreConfig.h
@@ -24,9 +24,6 @@
#include "PlayerCoreFactory.h"
#include "cores/dvdplayer/DVDPlayer.h"
#include "cores/paplayer/PAPlayer.h"
-#if defined(HAS_OMXPLAYER)
-#include "cores/omxplayer/OMXPlayer.h"
-#endif
#include "cores/ExternalPlayer/ExternalPlayer.h"
#ifdef HAS_UPNP
#include "network/upnp/UPnPPlayer.h"
@@ -97,20 +94,9 @@ public:
switch(m_eCore)
{
case EPC_MPLAYER:
- // TODO: this hack needs removal until we have a better player selection
-#if defined(HAS_OMXPLAYER)
- case EPC_DVDPLAYER:
- pPlayer = new COMXPlayer(callback);
- CLog::Log(LOGINFO, "Created player %s for core %d / OMXPlayer forced as DVDPlayer", "OMXPlayer", m_eCore);
- break;
-#else
case EPC_DVDPLAYER: pPlayer = new CDVDPlayer(callback); break;
-#endif
case EPC_PAPLAYER: pPlayer = new PAPlayer(callback); break;
case EPC_EXTPLAYER: pPlayer = new CExternalPlayer(callback); break;
-#if defined(HAS_OMXPLAYER)
- case EPC_OMXPLAYER: pPlayer = new COMXPlayer(callback); break;
-#endif
#if defined(HAS_UPNP)
case EPC_UPNPPLAYER: pPlayer = new UPNP::CUPnPPlayer(callback, m_id.c_str()); break;
#endif
diff --git a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
index f0990b0b8f..09d09e643b 100644
--- a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
+++ b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
@@ -342,13 +342,6 @@ bool CPlayerCoreFactory::LoadConfiguration(const std::string &file, bool clear)
paplayer->m_bPlaysAudio = true;
m_vecCoreConfigs.push_back(paplayer);
-#if defined(HAS_OMXPLAYER)
- CPlayerCoreConfig* omxplayer = new CPlayerCoreConfig("OMXPlayer", EPC_OMXPLAYER, NULL);
- omxplayer->m_bPlaysAudio = true;
- omxplayer->m_bPlaysVideo = true;
- m_vecCoreConfigs.push_back(omxplayer);
-#endif
-
for(std::vector<CPlayerSelectionRule *>::iterator it = m_vecCoreSelectionRules.begin(); it != m_vecCoreSelectionRules.end(); ++it)
delete *it;
m_vecCoreSelectionRules.clear();
diff --git a/xbmc/cores/playercorefactory/PlayerCoreFactory.h b/xbmc/cores/playercorefactory/PlayerCoreFactory.h
index 70c50e2ce0..3f0e4a4c6b 100644
--- a/xbmc/cores/playercorefactory/PlayerCoreFactory.h
+++ b/xbmc/cores/playercorefactory/PlayerCoreFactory.h
@@ -44,9 +44,6 @@ enum EPLAYERCORES
EPC_DVDPLAYER,
EPC_MPLAYER,
EPC_PAPLAYER,
-#if defined(HAS_OMXPLAYER)
- EPC_OMXPLAYER,
-#endif
EPC_EXTPLAYER,
EPC_UPNPPLAYER,
};
@@ -57,9 +54,6 @@ const PLAYERCOREID PCID_NONE = EPC_NONE;
const PLAYERCOREID PCID_DVDPLAYER = EPC_DVDPLAYER;
const PLAYERCOREID PCID_MPLAYER = EPC_MPLAYER;
const PLAYERCOREID PCID_PAPLAYER = EPC_PAPLAYER;
-#if defined(HAS_OMXPLAYER)
-const PLAYERCOREID PCID_OMXPLAYER = EPC_OMXPLAYER;
-#endif
class CPlayerCoreFactory : public ISettingsHandler
{
diff --git a/xbmc/linux/OMXClock.cpp b/xbmc/linux/OMXClock.cpp
index c631ab670d..80219a0d6d 100644
--- a/xbmc/linux/OMXClock.cpp
+++ b/xbmc/linux/OMXClock.cpp
@@ -33,7 +33,6 @@
#include "utils/MathUtils.h"
#define OMX_PRE_ROLL 200
-#define TP(speed) ((speed) < 0 || (speed) > 4*DVD_PLAYSPEED_NORMAL)
OMXClock::OMXClock()
{
@@ -492,10 +491,7 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
OMX_TIME_CONFIG_SCALETYPE scaleType;
OMX_INIT_STRUCTURE(scaleType);
- if (TP(speed))
- scaleType.xScale = 0; // for trickplay we just pause, and single step
- else
- scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL;
+ scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL;
omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType);
if(omx_err != OMX_ErrorNone)
{
@@ -515,6 +511,24 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
return true;
}
+bool OMXClock::OMXFlush(bool lock)
+{
+ if(m_omx_clock.GetComponent() == NULL)
+ return false;
+
+ if(lock)
+ Lock();
+
+ CLog::Log(LOGDEBUG, "OMXClock::OMXFlush");
+
+ m_omx_clock.FlushAll();
+
+ if(lock)
+ UnLock();
+
+ return true;
+}
+
bool OMXClock::HDMIClockSync(bool lock /* = true */)
{
if(m_omx_clock.GetComponent() == NULL)
diff --git a/xbmc/linux/OMXClock.h b/xbmc/linux/OMXClock.h
index 7bb6d4d1cf..8f0613487d 100644
--- a/xbmc/linux/OMXClock.h
+++ b/xbmc/linux/OMXClock.h
@@ -83,6 +83,7 @@ public:
bool OMXResume(bool lock = true);
bool OMXSetSpeed(int speed, bool lock = true, bool pause_resume = false);
int OMXPlaySpeed() { return m_omx_speed; };
+ bool OMXFlush(bool lock = true);
COMXCoreComponent *GetOMXClock();
bool OMXStateExecute(bool lock = true);
void OMXStateIdle(bool lock = true);
diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp
index 7b615127d1..c1cdfc1c0f 100644
--- a/xbmc/settings/SettingConditions.cpp
+++ b/xbmc/settings/SettingConditions.cpp
@@ -227,6 +227,9 @@ void CSettingConditions::Initialize()
#ifdef HAVE_LIBOPENMAX
m_simpleConditions.insert("have_libopenmax");
#endif
+#ifdef HAS_OMXPLAYER
+ m_simpleConditions.insert("has_omxplayer");
+#endif
#ifdef HAVE_LIBVA
m_simpleConditions.insert("have_libva");
#endif