2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "ApplicationPlayer.h"
22 #include "cores/IPlayer.h"
23 #include "Application.h"
25 #define VOLUME_MINIMUM 0.0f // -60dB
26 #define VOLUME_MAXIMUM 1.0f // 0dB
28 CApplicationPlayer::CApplicationPlayer()
31 m_eCurrentPlayer
= EPC_NONE
;
34 boost::shared_ptr
<IPlayer
> CApplicationPlayer::GetInternal() const
36 CSingleLock
lock(m_player_lock
);
40 void CApplicationPlayer::ClosePlayer()
42 boost::shared_ptr
<IPlayer
> player
= GetInternal();
46 // we need to do this directly on the member
47 CSingleLock
lock(m_player_lock
);
52 void CApplicationPlayer::CloseFile(bool reopen
)
54 boost::shared_ptr
<IPlayer
> player
= GetInternal();
58 player
->CloseFile(reopen
);
62 void CApplicationPlayer::ClosePlayerGapless(PLAYERCOREID newCore
)
64 boost::shared_ptr
<IPlayer
> player
= GetInternal();
68 bool gaplessSupported
= (m_eCurrentPlayer
== EPC_DVDPLAYER
|| m_eCurrentPlayer
== EPC_PAPLAYER
);
69 #if defined(HAS_OMXPLAYER)
70 gaplessSupported
= gaplessSupported
|| (m_eCurrentPlayer
== EPC_OMXPLAYER
);
72 gaplessSupported
= gaplessSupported
&& (m_eCurrentPlayer
== newCore
);
73 if (!gaplessSupported
)
79 // XXX: we had to stop the previous playing item, it was done in dvdplayer::OpenFile.
80 // but in paplayer::OpenFile, it sometimes just fade in without call CloseFile.
81 // but if we do not stop it, we can not distingush callbacks from previous
82 // item and current item, it will confused us then we can not make correct delay
83 // callback after the starting state.
88 void CApplicationPlayer::CreatePlayer(PLAYERCOREID newCore
, IPlayerCallback
& callback
)
90 CSingleLock
lock(m_player_lock
);
93 m_eCurrentPlayer
= newCore
;
94 m_pPlayer
.reset(CPlayerCoreFactory::Get().CreatePlayer(newCore
, callback
));
98 PlayBackRet
CApplicationPlayer::OpenFile(const CFileItem
& item
, const CPlayerOptions
& options
)
100 boost::shared_ptr
<IPlayer
> player
= GetInternal();
101 PlayBackRet iResult
= PLAYBACK_FAIL
;
104 // op seq for detect cancel (CloseFile be called or OpenFile be called again) during OpenFile.
105 unsigned int startingSeq
= ++m_iPlayerOPSeq
;
107 iResult
= player
->OpenFile(item
, options
) ? PLAYBACK_OK
: PLAYBACK_FAIL
;
108 // check whether the OpenFile was canceled by either CloseFile or another OpenFile.
109 if (m_iPlayerOPSeq
!= startingSeq
)
110 iResult
= PLAYBACK_CANCELED
;
115 bool CApplicationPlayer::HasPlayer() const
117 boost::shared_ptr
<IPlayer
> player
= GetInternal();
118 return player
!= NULL
;
121 void CApplicationPlayer::RegisterAudioCallback(IAudioCallback
* pCallback
)
123 boost::shared_ptr
<IPlayer
> player
= GetInternal();
125 player
->RegisterAudioCallback(pCallback
);
128 void CApplicationPlayer::UnRegisterAudioCallback()
130 boost::shared_ptr
<IPlayer
> player
= GetInternal();
132 player
->UnRegisterAudioCallback();
135 int CApplicationPlayer::GetChapter()
137 boost::shared_ptr
<IPlayer
> player
= GetInternal();
139 return player
->GetChapter();
144 int CApplicationPlayer::GetChapterCount()
146 boost::shared_ptr
<IPlayer
> player
= GetInternal();
148 return player
->GetChapterCount();
153 void CApplicationPlayer::GetChapterName(CStdString
& strChapterName
)
155 boost::shared_ptr
<IPlayer
> player
= GetInternal();
157 player
->GetChapterName(strChapterName
);
160 bool CApplicationPlayer::HasAudio() const
162 boost::shared_ptr
<IPlayer
> player
= GetInternal();
163 return (player
&& player
->HasAudio());
166 bool CApplicationPlayer::HasVideo() const
168 boost::shared_ptr
<IPlayer
> player
= GetInternal();
169 return (player
&& player
->HasVideo());
172 bool CApplicationPlayer::IsPaused() const
174 boost::shared_ptr
<IPlayer
> player
= GetInternal();
175 return (player
&& player
->IsPaused());
178 bool CApplicationPlayer::IsPlaying() const
180 boost::shared_ptr
<IPlayer
> player
= GetInternal();
181 return (player
&& player
->IsPlaying());
184 bool CApplicationPlayer::IsPausedPlayback() const
186 return (IsPlaying() && IsPaused());
189 bool CApplicationPlayer::IsPlayingAudio() const
191 return (IsPlaying() && !HasVideo() && HasAudio());
194 bool CApplicationPlayer::IsPlayingVideo() const
196 return (IsPlaying() && HasVideo());
199 void CApplicationPlayer::Pause()
201 boost::shared_ptr
<IPlayer
> player
= GetInternal();
206 bool CApplicationPlayer::ControlsVolume() const
208 boost::shared_ptr
<IPlayer
> player
= GetInternal();
209 return (player
&& player
->ControlsVolume());
212 void CApplicationPlayer::SetMute(bool bOnOff
)
214 boost::shared_ptr
<IPlayer
> player
= GetInternal();
216 player
->SetMute(bOnOff
);
219 void CApplicationPlayer::SetVolume(float volume
)
221 boost::shared_ptr
<IPlayer
> player
= GetInternal();
223 player
->SetVolume(volume
);
226 void CApplicationPlayer::Seek(bool bPlus
, bool bLargeStep
, bool bChapterOverride
)
228 boost::shared_ptr
<IPlayer
> player
= GetInternal();
230 player
->Seek(bPlus
, bLargeStep
, bChapterOverride
);
233 void CApplicationPlayer::SeekPercentage(float fPercent
)
235 boost::shared_ptr
<IPlayer
> player
= GetInternal();
237 player
->SeekPercentage(fPercent
);
240 bool CApplicationPlayer::IsPassthrough() const
242 boost::shared_ptr
<IPlayer
> player
= GetInternal();
243 return (player
&& player
->IsPassthrough());
246 bool CApplicationPlayer::CanSeek()
248 boost::shared_ptr
<IPlayer
> player
= GetInternal();
249 return (player
&& player
->CanSeek());
252 bool CApplicationPlayer::SeekScene(bool bPlus
)
254 boost::shared_ptr
<IPlayer
> player
= GetInternal();
255 return (player
&& player
->SeekScene(bPlus
));
258 void CApplicationPlayer::SeekTime(int64_t iTime
)
260 boost::shared_ptr
<IPlayer
> player
= GetInternal();
262 player
->SeekTime(iTime
);
265 CStdString
CApplicationPlayer::GetPlayingTitle()
267 boost::shared_ptr
<IPlayer
> player
= GetInternal();
269 return player
->GetPlayingTitle();
274 int64_t CApplicationPlayer::GetTime() const
276 boost::shared_ptr
<IPlayer
> player
= GetInternal();
278 return player
->GetTime();
283 bool CApplicationPlayer::IsCaching() const
285 boost::shared_ptr
<IPlayer
> player
= GetInternal();
286 return (player
&& player
->IsCaching());
289 bool CApplicationPlayer::IsInMenu() const
291 boost::shared_ptr
<IPlayer
> player
= GetInternal();
292 return (player
&& player
->IsInMenu());
295 bool CApplicationPlayer::HasMenu() const
297 boost::shared_ptr
<IPlayer
> player
= GetInternal();
298 return (player
&& player
->HasMenu());
301 int CApplicationPlayer::GetCacheLevel() const
303 boost::shared_ptr
<IPlayer
> player
= GetInternal();
305 return player
->GetCacheLevel();
310 int CApplicationPlayer::GetSubtitleCount()
312 boost::shared_ptr
<IPlayer
> player
= GetInternal();
314 return player
->GetSubtitleCount();
319 int CApplicationPlayer::GetAudioStream()
321 boost::shared_ptr
<IPlayer
> player
= GetInternal();
323 return player
->GetAudioStream();
328 int CApplicationPlayer::GetSubtitle()
330 boost::shared_ptr
<IPlayer
> player
= GetInternal();
332 return player
->GetSubtitle();
337 bool CApplicationPlayer::GetSubtitleVisible()
339 boost::shared_ptr
<IPlayer
> player
= GetInternal();
340 return (player
&& player
->GetSubtitleVisible());
343 bool CApplicationPlayer::CanRecord()
345 boost::shared_ptr
<IPlayer
> player
= GetInternal();
346 return (player
&& player
->CanRecord());
349 bool CApplicationPlayer::CanPause()
351 boost::shared_ptr
<IPlayer
> player
= GetInternal();
352 return (player
&& player
->CanPause());
355 bool CApplicationPlayer::IsRecording() const
357 boost::shared_ptr
<IPlayer
> player
= GetInternal();
358 return (player
&& player
->IsRecording());
361 TextCacheStruct_t
* CApplicationPlayer::GetTeletextCache()
363 boost::shared_ptr
<IPlayer
> player
= GetInternal();
365 return player
->GetTeletextCache();
370 int64_t CApplicationPlayer::GetTotalTime() const
372 boost::shared_ptr
<IPlayer
> player
= GetInternal();
374 return player
->GetTotalTime();
379 float CApplicationPlayer::GetPercentage() const
381 boost::shared_ptr
<IPlayer
> player
= GetInternal();
383 return player
->GetPercentage();
388 float CApplicationPlayer::GetCachePercentage() const
390 boost::shared_ptr
<IPlayer
> player
= GetInternal();
392 return player
->GetCachePercentage();
397 void CApplicationPlayer::ToFFRW(int iSpeed
)
399 boost::shared_ptr
<IPlayer
> player
= GetInternal();
401 player
->ToFFRW(iSpeed
);
404 void CApplicationPlayer::DoAudioWork()
406 boost::shared_ptr
<IPlayer
> player
= GetInternal();
408 player
->DoAudioWork();
411 CStdString
CApplicationPlayer::GetPlayerState()
413 boost::shared_ptr
<IPlayer
> player
= GetInternal();
415 return player
->GetPlayerState();
420 bool CApplicationPlayer::QueueNextFile(const CFileItem
&file
)
422 boost::shared_ptr
<IPlayer
> player
= GetInternal();
423 return (player
&& player
->QueueNextFile(file
));
426 bool CApplicationPlayer::GetStreamDetails(CStreamDetails
&details
)
428 boost::shared_ptr
<IPlayer
> player
= GetInternal();
429 return (player
&& player
->GetStreamDetails(details
));
432 bool CApplicationPlayer::SetPlayerState(CStdString state
)
434 boost::shared_ptr
<IPlayer
> player
= GetInternal();
435 return (player
&& player
->SetPlayerState(state
));
438 void CApplicationPlayer::OnNothingToQueueNotify()
440 boost::shared_ptr
<IPlayer
> player
= GetInternal();
442 player
->OnNothingToQueueNotify();
445 void CApplicationPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo
&info
)
447 boost::shared_ptr
<IPlayer
> player
= GetInternal();
449 player
->GetVideoStreamInfo(info
);
452 void CApplicationPlayer::GetAudioStreamInfo(int index
, SPlayerAudioStreamInfo
&info
)
454 boost::shared_ptr
<IPlayer
> player
= GetInternal();
456 player
->GetAudioStreamInfo(index
, info
);
459 bool CApplicationPlayer::OnAction(const CAction
&action
)
461 boost::shared_ptr
<IPlayer
> player
= GetInternal();
462 return (player
&& player
->OnAction(action
));
465 bool CApplicationPlayer::Record(bool bOnOff
)
467 boost::shared_ptr
<IPlayer
> player
= GetInternal();
468 return (player
&& player
->Record(bOnOff
));
471 int CApplicationPlayer::GetAudioStreamCount()
473 boost::shared_ptr
<IPlayer
> player
= GetInternal();
475 return player
->GetAudioStreamCount();
480 void CApplicationPlayer::SetAudioStream(int iStream
)
482 boost::shared_ptr
<IPlayer
> player
= GetInternal();
484 player
->SetAudioStream(iStream
);
487 void CApplicationPlayer::GetSubtitleStreamInfo(int index
, SPlayerSubtitleStreamInfo
&info
)
489 boost::shared_ptr
<IPlayer
> player
= GetInternal();
491 player
->GetSubtitleStreamInfo(index
, info
);
494 void CApplicationPlayer::SetSubtitle(int iStream
)
496 boost::shared_ptr
<IPlayer
> player
= GetInternal();
498 player
->SetSubtitle(iStream
);
501 void CApplicationPlayer::SetSubtitleVisible(bool bVisible
)
503 boost::shared_ptr
<IPlayer
> player
= GetInternal();
505 player
->SetSubtitleVisible(bVisible
);
508 int CApplicationPlayer::AddSubtitle(const CStdString
& strSubPath
)
510 boost::shared_ptr
<IPlayer
> player
= GetInternal();
512 return player
->AddSubtitle(strSubPath
);
517 void CApplicationPlayer::SetSubTitleDelay(float fValue
)
519 boost::shared_ptr
<IPlayer
> player
= GetInternal();
521 player
->SetSubTitleDelay(fValue
);
524 void CApplicationPlayer::SetAVDelay(float fValue
)
526 boost::shared_ptr
<IPlayer
> player
= GetInternal();
528 player
->SetAVDelay(fValue
);
531 void CApplicationPlayer::SetDynamicRangeCompression(long drc
)
533 boost::shared_ptr
<IPlayer
> player
= GetInternal();
535 player
->SetDynamicRangeCompression(drc
);
538 bool CApplicationPlayer::SwitchChannel(const PVR::CPVRChannel
&channel
)
540 boost::shared_ptr
<IPlayer
> player
= GetInternal();
541 return (player
&& player
->SwitchChannel(channel
));
544 void CApplicationPlayer::LoadPage(int p
, int sp
, unsigned char* buffer
)
546 boost::shared_ptr
<IPlayer
> player
= GetInternal();
548 player
->LoadPage(p
, sp
, buffer
);
551 void CApplicationPlayer::GetAudioCapabilities(std::vector
<int> &audioCaps
)
553 boost::shared_ptr
<IPlayer
> player
= GetInternal();
555 player
->GetAudioCapabilities(audioCaps
);
558 void CApplicationPlayer::GetSubtitleCapabilities(std::vector
<int> &subCaps
)
560 boost::shared_ptr
<IPlayer
> player
= GetInternal();
562 player
->GetSubtitleCapabilities(subCaps
);
565 void CApplicationPlayer::GetAudioInfo( CStdString
& strAudioInfo
)
567 boost::shared_ptr
<IPlayer
> player
= GetInternal();
569 player
->GetAudioInfo(strAudioInfo
);
572 void CApplicationPlayer::GetVideoInfo( CStdString
& strVideoInfo
)
574 boost::shared_ptr
<IPlayer
> player
= GetInternal();
576 player
->GetVideoInfo(strVideoInfo
);
579 void CApplicationPlayer::GetGeneralInfo( CStdString
& strVideoInfo
)
581 boost::shared_ptr
<IPlayer
> player
= GetInternal();
583 player
->GetGeneralInfo(strVideoInfo
);
586 int CApplicationPlayer::SeekChapter(int iChapter
)
588 boost::shared_ptr
<IPlayer
> player
= GetInternal();
590 return player
->SeekChapter(iChapter
);
595 void CApplicationPlayer::GetRenderFeatures(std::vector
<int> &renderFeatures
)
597 boost::shared_ptr
<IPlayer
> player
= GetInternal();
599 player
->GetRenderFeatures(renderFeatures
);
602 void CApplicationPlayer::GetDeinterlaceMethods(std::vector
<int> &deinterlaceMethods
)
604 boost::shared_ptr
<IPlayer
> player
= GetInternal();
606 player
->GetDeinterlaceMethods(deinterlaceMethods
);
609 void CApplicationPlayer::GetDeinterlaceModes(std::vector
<int> &deinterlaceModes
)
611 boost::shared_ptr
<IPlayer
> player
= GetInternal();
613 player
->GetDeinterlaceModes(deinterlaceModes
);
616 void CApplicationPlayer::GetScalingMethods(std::vector
<int> &scalingMethods
)
618 boost::shared_ptr
<IPlayer
> player
= GetInternal();
620 player
->GetScalingMethods(scalingMethods
);
623 void CApplicationPlayer::SetPlaySpeed(int iSpeed
, bool bApplicationMuted
)
625 boost::shared_ptr
<IPlayer
> player
= GetInternal();
629 if (!IsPlayingAudio() && !IsPlayingVideo())
631 if (m_iPlaySpeed
== iSpeed
)
638 ((m_iPlaySpeed
> 1) && (iSpeed
> m_iPlaySpeed
)) ||
639 ((m_iPlaySpeed
< -1) && (iSpeed
< m_iPlaySpeed
))
642 iSpeed
= m_iPlaySpeed
; // from pause to ff/rw, do previous ff/rw speed
646 m_iPlaySpeed
= iSpeed
;
648 ToFFRW(m_iPlaySpeed
);
650 // if player has volume control, set it.
651 if (ControlsVolume())
653 if (m_iPlaySpeed
== 1)
655 player
->SetVolume(g_application
.GetVolume(false));
659 player
->SetVolume(VOLUME_MINIMUM
);
661 player
->SetMute(bApplicationMuted
);
665 int CApplicationPlayer::GetPlaySpeed() const