/*
* Copyright (C) 2005-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
* .
*
*/
#include "ApplicationPlayer.h"
#include "cores/IPlayer.h"
#include "Application.h"
#include "settings/MediaSettings.h"
CApplicationPlayer::CApplicationPlayer()
{
m_iPlayerOPSeq = 0;
m_eCurrentPlayer = EPC_NONE;
}
boost::shared_ptr CApplicationPlayer::GetInternal() const
{
CSingleLock lock(m_player_lock);
return m_pPlayer;
}
void CApplicationPlayer::ClosePlayer()
{
boost::shared_ptr player = GetInternal();
if (player)
{
CloseFile();
// we need to do this directly on the member
CSingleLock lock(m_player_lock);
m_pPlayer.reset();
}
}
void CApplicationPlayer::CloseFile(bool reopen)
{
boost::shared_ptr player = GetInternal();
if (player)
{
++m_iPlayerOPSeq;
player->CloseFile(reopen);
}
}
void CApplicationPlayer::ClosePlayerGapless(PLAYERCOREID newCore)
{
boost::shared_ptr player = GetInternal();
if (!player)
return;
bool gaplessSupported = (m_eCurrentPlayer == EPC_DVDPLAYER || m_eCurrentPlayer == EPC_PAPLAYER);
gaplessSupported = gaplessSupported && (m_eCurrentPlayer == newCore);
if (!gaplessSupported)
{
ClosePlayer();
}
else
{
// XXX: we had to stop the previous playing item, it was done in dvdplayer::OpenFile.
// but in paplayer::OpenFile, it sometimes just fade in without call CloseFile.
// but if we do not stop it, we can not distingush callbacks from previous
// item and current item, it will confused us then we can not make correct delay
// callback after the starting state.
CloseFile(true);
}
}
void CApplicationPlayer::CreatePlayer(PLAYERCOREID newCore, IPlayerCallback& callback)
{
CSingleLock lock(m_player_lock);
if (!m_pPlayer)
{
m_eCurrentPlayer = newCore;
m_pPlayer.reset(CPlayerCoreFactory::Get().CreatePlayer(newCore, callback));
}
}
PlayBackRet CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& options)
{
boost::shared_ptr player = GetInternal();
PlayBackRet iResult = PLAYBACK_FAIL;
if (player)
{
// op seq for detect cancel (CloseFile be called or OpenFile be called again) during OpenFile.
unsigned int startingSeq = ++m_iPlayerOPSeq;
iResult = player->OpenFile(item, options) ? PLAYBACK_OK : PLAYBACK_FAIL;
// check whether the OpenFile was canceled by either CloseFile or another OpenFile.
if (m_iPlayerOPSeq != startingSeq)
iResult = PLAYBACK_CANCELED;
}
return iResult;
}
bool CApplicationPlayer::HasPlayer() const
{
boost::shared_ptr player = GetInternal();
return player != NULL;
}
int CApplicationPlayer::GetChapter()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetChapter();
else
return -1;
}
int CApplicationPlayer::GetChapterCount()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetChapterCount();
else
return 0;
}
void CApplicationPlayer::GetChapterName(std::string& strChapterName)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetChapterName(strChapterName);
}
bool CApplicationPlayer::HasAudio() const
{
boost::shared_ptr player = GetInternal();
return (player && player->HasAudio());
}
bool CApplicationPlayer::HasVideo() const
{
boost::shared_ptr player = GetInternal();
return (player && player->HasVideo());
}
bool CApplicationPlayer::IsPaused() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsPaused());
}
bool CApplicationPlayer::IsPlaying() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsPlaying());
}
bool CApplicationPlayer::IsPausedPlayback() const
{
return (IsPlaying() && IsPaused());
}
bool CApplicationPlayer::IsPlayingAudio() const
{
return (IsPlaying() && !HasVideo() && HasAudio());
}
bool CApplicationPlayer::IsPlayingVideo() const
{
return (IsPlaying() && HasVideo());
}
void CApplicationPlayer::Pause()
{
boost::shared_ptr player = GetInternal();
if (player)
player->Pause();
}
bool CApplicationPlayer::ControlsVolume() const
{
boost::shared_ptr player = GetInternal();
return (player && player->ControlsVolume());
}
void CApplicationPlayer::SetMute(bool bOnOff)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SetMute(bOnOff);
}
void CApplicationPlayer::SetVolume(float volume)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SetVolume(volume);
}
void CApplicationPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
{
boost::shared_ptr player = GetInternal();
if (player)
player->Seek(bPlus, bLargeStep, bChapterOverride);
}
void CApplicationPlayer::SeekPercentage(float fPercent)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SeekPercentage(fPercent);
}
bool CApplicationPlayer::IsPassthrough() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsPassthrough());
}
bool CApplicationPlayer::CanSeek()
{
boost::shared_ptr player = GetInternal();
return (player && player->CanSeek());
}
bool CApplicationPlayer::SeekScene(bool bPlus)
{
boost::shared_ptr player = GetInternal();
return (player && player->SeekScene(bPlus));
}
void CApplicationPlayer::SeekTime(int64_t iTime)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SeekTime(iTime);
}
std::string CApplicationPlayer::GetPlayingTitle()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetPlayingTitle();
else
return "";
}
int64_t CApplicationPlayer::GetTime() const
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetTime();
else
return 0;
}
bool CApplicationPlayer::IsCaching() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsCaching());
}
bool CApplicationPlayer::IsInMenu() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsInMenu());
}
bool CApplicationPlayer::HasMenu() const
{
boost::shared_ptr player = GetInternal();
return (player && player->HasMenu());
}
int CApplicationPlayer::GetCacheLevel() const
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetCacheLevel();
else
return 0;
}
int CApplicationPlayer::GetSubtitleCount()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetSubtitleCount();
else
return 0;
}
int CApplicationPlayer::GetAudioStream()
{
if (!m_audioStreamUpdate.IsTimePast())
return m_iAudioStream;
boost::shared_ptr player = GetInternal();
if (player)
{
m_iAudioStream = player->GetAudioStream();
m_audioStreamUpdate.Set(1000);
return m_iAudioStream;
}
else
return 0;
}
int CApplicationPlayer::GetSubtitle()
{
if (!m_subtitleStreamUpdate.IsTimePast())
return m_iSubtitleStream;
boost::shared_ptr player = GetInternal();
if (player)
{
m_iSubtitleStream = player->GetSubtitle();
m_subtitleStreamUpdate.Set(1000);
return m_iSubtitleStream;
}
else
return 0;
}
bool CApplicationPlayer::GetSubtitleVisible()
{
boost::shared_ptr player = GetInternal();
return (player && player->GetSubtitleVisible());
}
bool CApplicationPlayer::CanRecord()
{
boost::shared_ptr player = GetInternal();
return (player && player->CanRecord());
}
bool CApplicationPlayer::CanPause()
{
boost::shared_ptr player = GetInternal();
return (player && player->CanPause());
}
bool CApplicationPlayer::IsRecording() const
{
boost::shared_ptr player = GetInternal();
return (player && player->IsRecording());
}
TextCacheStruct_t* CApplicationPlayer::GetTeletextCache()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetTeletextCache();
else
return NULL;
}
int64_t CApplicationPlayer::GetTotalTime() const
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetTotalTime();
else
return 0;
}
float CApplicationPlayer::GetPercentage() const
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetPercentage();
else
return 0.0;
}
float CApplicationPlayer::GetCachePercentage() const
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetCachePercentage();
else
return 0.0;
}
void CApplicationPlayer::ToFFRW(int iSpeed)
{
boost::shared_ptr player = GetInternal();
if (player)
player->ToFFRW(iSpeed);
}
void CApplicationPlayer::DoAudioWork()
{
boost::shared_ptr player = GetInternal();
if (player)
player->DoAudioWork();
}
std::string CApplicationPlayer::GetPlayerState()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetPlayerState();
else
return "";
}
bool CApplicationPlayer::QueueNextFile(const CFileItem &file)
{
boost::shared_ptr player = GetInternal();
return (player && player->QueueNextFile(file));
}
bool CApplicationPlayer::GetStreamDetails(CStreamDetails &details)
{
boost::shared_ptr player = GetInternal();
return (player && player->GetStreamDetails(details));
}
bool CApplicationPlayer::SetPlayerState(const std::string& state)
{
boost::shared_ptr player = GetInternal();
return (player && player->SetPlayerState(state));
}
void CApplicationPlayer::OnNothingToQueueNotify()
{
boost::shared_ptr player = GetInternal();
if (player)
player->OnNothingToQueueNotify();
}
void CApplicationPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetVideoStreamInfo(info);
}
void CApplicationPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetAudioStreamInfo(index, info);
}
bool CApplicationPlayer::OnAction(const CAction &action)
{
boost::shared_ptr player = GetInternal();
return (player && player->OnAction(action));
}
bool CApplicationPlayer::Record(bool bOnOff)
{
boost::shared_ptr player = GetInternal();
return (player && player->Record(bOnOff));
}
int CApplicationPlayer::GetAudioStreamCount()
{
boost::shared_ptr player = GetInternal();
if (player)
return player->GetAudioStreamCount();
else
return 0;
}
void CApplicationPlayer::SetAudioStream(int iStream)
{
boost::shared_ptr player = GetInternal();
if (player)
{
player->SetAudioStream(iStream);
m_iAudioStream = iStream;
m_audioStreamUpdate.Set(1000);
CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream = iStream;
}
}
void CApplicationPlayer::GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetSubtitleStreamInfo(index, info);
}
void CApplicationPlayer::SetSubtitle(int iStream)
{
boost::shared_ptr player = GetInternal();
if (player)
{
player->SetSubtitle(iStream);
m_iSubtitleStream = iStream;
m_subtitleStreamUpdate.Set(1000);
CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = iStream;
}
}
void CApplicationPlayer::SetSubtitleVisible(bool bVisible)
{
boost::shared_ptr player = GetInternal();
if (player)
{
player->SetSubtitleVisible(bVisible);
CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn = bVisible;
CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = player->GetSubtitle();
}
}
int CApplicationPlayer::AddSubtitle(const std::string& strSubPath)
{
boost::shared_ptr player = GetInternal();
if (player)
return player->AddSubtitle(strSubPath);
else
return 0;
}
void CApplicationPlayer::SetSubTitleDelay(float fValue)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SetSubTitleDelay(fValue);
}
void CApplicationPlayer::SetAVDelay(float fValue)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SetAVDelay(fValue);
}
void CApplicationPlayer::SetDynamicRangeCompression(long drc)
{
boost::shared_ptr player = GetInternal();
if (player)
player->SetDynamicRangeCompression(drc);
}
bool CApplicationPlayer::SwitchChannel(PVR::CPVRChannel &channel)
{
boost::shared_ptr player = GetInternal();
return (player && player->SwitchChannel(channel));
}
void CApplicationPlayer::LoadPage(int p, int sp, unsigned char* buffer)
{
boost::shared_ptr player = GetInternal();
if (player)
player->LoadPage(p, sp, buffer);
}
void CApplicationPlayer::GetAudioCapabilities(std::vector &audioCaps)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetAudioCapabilities(audioCaps);
}
void CApplicationPlayer::GetSubtitleCapabilities(std::vector &subCaps)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetSubtitleCapabilities(subCaps);
}
void CApplicationPlayer::GetAudioInfo(std::string& strAudioInfo)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetAudioInfo(strAudioInfo);
}
void CApplicationPlayer::GetVideoInfo(std::string& strVideoInfo)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetVideoInfo(strVideoInfo);
}
void CApplicationPlayer::GetGeneralInfo(std::string& strVideoInfo)
{
boost::shared_ptr player = GetInternal();
if (player)
player->GetGeneralInfo(strVideoInfo);
}
int CApplicationPlayer::SeekChapter(int iChapter)
{
boost::shared_ptr player = GetInternal();
if (player)
return player->SeekChapter(iChapter);
else
return 0;
}
void CApplicationPlayer::GetRenderFeatures(std::vector &renderFeatures)
{
boost::shared_ptr player = GetInternal();
if (player)
player->OMXGetRenderFeatures(renderFeatures);
}
void CApplicationPlayer::GetDeinterlaceMethods(std::vector &deinterlaceMethods)
{
boost::shared_ptr player = GetInternal();
if (player)
player->OMXGetDeinterlaceMethods(deinterlaceMethods);
}
void CApplicationPlayer::GetDeinterlaceModes(std::vector &deinterlaceModes)
{
boost::shared_ptr player = GetInternal();
if (player)
player->OMXGetDeinterlaceModes(deinterlaceModes);
}
void CApplicationPlayer::GetScalingMethods(std::vector &scalingMethods)
{
boost::shared_ptr player = GetInternal();
if (player)
player->OMXGetScalingMethods(scalingMethods);
}
void CApplicationPlayer::SetPlaySpeed(int iSpeed, bool bApplicationMuted)
{
boost::shared_ptr player = GetInternal();
if (!player)
return;
if (!IsPlayingAudio() && !IsPlayingVideo())
return ;
if (m_iPlaySpeed == iSpeed)
return ;
if (!CanSeek())
return;
if (IsPaused())
{
if (
((m_iPlaySpeed > 1) && (iSpeed > m_iPlaySpeed)) ||
((m_iPlaySpeed < -1) && (iSpeed < m_iPlaySpeed))
)
{
iSpeed = m_iPlaySpeed; // from pause to ff/rw, do previous ff/rw speed
}
Pause();
}
m_iPlaySpeed = iSpeed;
ToFFRW(m_iPlaySpeed);
// if player has volume control, set it.
if (ControlsVolume())
{
if (m_iPlaySpeed == 1)
{ // restore volume
player->SetVolume(g_application.GetVolume(false));
}
else
{ // mute volume
player->SetVolume(VOLUME_MINIMUM);
}
player->SetMute(bApplicationMuted);
}
}
int CApplicationPlayer::GetPlaySpeed() const
{
return m_iPlaySpeed;
}