Fix keymap.
[vuplus_xbmc] / xbmc / ApplicationPlayer.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "ApplicationPlayer.h"
22 #include "cores/IPlayer.h"
23 #include "Application.h"
24
25 #define VOLUME_MINIMUM 0.0f        // -60dB
26 #define VOLUME_MAXIMUM 1.0f        // 0dB
27
28 CApplicationPlayer::CApplicationPlayer()
29 {
30   m_iPlayerOPSeq = 0;
31   m_eCurrentPlayer = EPC_NONE;
32 }
33
34 boost::shared_ptr<IPlayer> CApplicationPlayer::GetInternal() const
35 {
36   CSingleLock lock(m_player_lock);
37   return m_pPlayer;
38 }
39
40 void CApplicationPlayer::ClosePlayer()
41 {
42   boost::shared_ptr<IPlayer> player = GetInternal();
43   if (player)
44   {
45     CloseFile();
46     // we need to do this directly on the member
47     CSingleLock lock(m_player_lock);
48     m_pPlayer.reset();
49   }
50 }
51
52 void CApplicationPlayer::CloseFile(bool reopen)
53 {
54   boost::shared_ptr<IPlayer> player = GetInternal();
55   if (player)
56   {
57     ++m_iPlayerOPSeq;
58     player->CloseFile(reopen);
59   }
60 }
61
62 void CApplicationPlayer::ClosePlayerGapless(PLAYERCOREID newCore)
63 {
64   boost::shared_ptr<IPlayer> player = GetInternal();
65   if (!player)
66     return;
67
68   bool gaplessSupported = (m_eCurrentPlayer == EPC_DVDPLAYER || m_eCurrentPlayer == EPC_PAPLAYER);
69 #if defined(HAS_OMXPLAYER)
70   gaplessSupported = gaplessSupported || (m_eCurrentPlayer == EPC_OMXPLAYER);
71 #endif            
72   gaplessSupported = gaplessSupported && (m_eCurrentPlayer == newCore);
73   if (!gaplessSupported)
74   {
75     ClosePlayer();
76   }
77   else
78   {
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.
84     CloseFile(true);
85   }
86 }
87
88 void CApplicationPlayer::CreatePlayer(PLAYERCOREID newCore, IPlayerCallback& callback)
89 {
90   CSingleLock lock(m_player_lock);
91   if (!m_pPlayer)
92   {
93     m_eCurrentPlayer = newCore;
94     m_pPlayer.reset(CPlayerCoreFactory::Get().CreatePlayer(newCore, callback));
95   }
96 }
97
98 PlayBackRet CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& options)
99 {
100   boost::shared_ptr<IPlayer> player = GetInternal();
101   PlayBackRet iResult = PLAYBACK_FAIL;
102   if (player)
103   {
104     // op seq for detect cancel (CloseFile be called or OpenFile be called again) during OpenFile.
105     unsigned int startingSeq = ++m_iPlayerOPSeq;
106
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;
111   }
112   return iResult;
113 }
114
115 bool CApplicationPlayer::HasPlayer() const 
116
117   boost::shared_ptr<IPlayer> player = GetInternal();
118   return player != NULL; 
119 }
120
121 void CApplicationPlayer::RegisterAudioCallback(IAudioCallback* pCallback)
122 {
123   boost::shared_ptr<IPlayer> player = GetInternal();
124   if (player)
125     player->RegisterAudioCallback(pCallback);
126 }
127
128 void CApplicationPlayer::UnRegisterAudioCallback()
129 {
130   boost::shared_ptr<IPlayer> player = GetInternal();
131   if (player)
132     player->UnRegisterAudioCallback();
133 }
134
135 int CApplicationPlayer::GetChapter()
136 {
137   boost::shared_ptr<IPlayer> player = GetInternal();
138   if (player)
139     return player->GetChapter();
140   else 
141     return -1;
142 }
143
144 int CApplicationPlayer::GetChapterCount()
145 {
146   boost::shared_ptr<IPlayer> player = GetInternal();
147   if (player)
148     return player->GetChapterCount();
149   else 
150     return 0;
151 }
152
153 void CApplicationPlayer::GetChapterName(CStdString& strChapterName)
154 {
155   boost::shared_ptr<IPlayer> player = GetInternal();
156   if (player)
157     player->GetChapterName(strChapterName);
158 }
159
160 bool CApplicationPlayer::HasAudio() const
161 {
162   boost::shared_ptr<IPlayer> player = GetInternal();
163   return (player && player->HasAudio());
164 }
165
166 bool CApplicationPlayer::HasVideo() const
167 {
168   boost::shared_ptr<IPlayer> player = GetInternal();
169   return (player && player->HasVideo());
170 }
171
172 bool CApplicationPlayer::IsPaused() const
173 {
174   boost::shared_ptr<IPlayer> player = GetInternal();
175   return (player && player->IsPaused());
176 }
177
178 bool CApplicationPlayer::IsPlaying() const
179 {
180   boost::shared_ptr<IPlayer> player = GetInternal();
181   return (player && player->IsPlaying());
182 }
183
184 bool CApplicationPlayer::IsPausedPlayback() const
185 {
186   return (IsPlaying() && IsPaused());
187 }
188
189 bool CApplicationPlayer::IsPlayingAudio() const
190 {
191   return (IsPlaying() && !HasVideo() && HasAudio());
192 }
193
194 bool CApplicationPlayer::IsPlayingVideo() const
195 {
196   return (IsPlaying() && HasVideo());
197 }
198
199 void CApplicationPlayer::Pause()
200 {
201   boost::shared_ptr<IPlayer> player = GetInternal();
202   if (player)
203     player->Pause();
204 }
205
206 bool CApplicationPlayer::ControlsVolume() const
207 {
208   boost::shared_ptr<IPlayer> player = GetInternal();
209   return (player && player->ControlsVolume());
210 }
211
212 void CApplicationPlayer::SetMute(bool bOnOff)
213 {
214   boost::shared_ptr<IPlayer> player = GetInternal();
215   if (player)
216     player->SetMute(bOnOff);
217 }
218
219 void CApplicationPlayer::SetVolume(float volume)
220 {
221   boost::shared_ptr<IPlayer> player = GetInternal();
222   if (player)
223     player->SetVolume(volume);
224 }
225
226 void CApplicationPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
227 {
228   boost::shared_ptr<IPlayer> player = GetInternal();
229   if (player)
230     player->Seek(bPlus, bLargeStep, bChapterOverride);
231 }
232
233 void CApplicationPlayer::SeekPercentage(float fPercent)
234 {
235   boost::shared_ptr<IPlayer> player = GetInternal();
236   if (player)
237     player->SeekPercentage(fPercent);
238 }
239
240 bool CApplicationPlayer::IsPassthrough() const
241 {
242   boost::shared_ptr<IPlayer> player = GetInternal();
243   return (player && player->IsPassthrough());
244 }
245
246 bool CApplicationPlayer::CanSeek()
247 {
248   boost::shared_ptr<IPlayer> player = GetInternal();
249   return (player && player->CanSeek());
250 }
251
252 bool CApplicationPlayer::SeekScene(bool bPlus)
253 {
254   boost::shared_ptr<IPlayer> player = GetInternal();
255   return (player && player->SeekScene(bPlus));
256 }
257
258 void CApplicationPlayer::SeekTime(int64_t iTime)
259 {
260   boost::shared_ptr<IPlayer> player = GetInternal();
261   if (player)
262     player->SeekTime(iTime);
263 }
264
265 CStdString CApplicationPlayer::GetPlayingTitle()
266 {
267   boost::shared_ptr<IPlayer> player = GetInternal();
268   if (player)
269     return player->GetPlayingTitle();
270   else
271     return "";
272 }
273
274 int64_t CApplicationPlayer::GetTime() const
275 {
276   boost::shared_ptr<IPlayer> player = GetInternal();
277   if (player)
278     return player->GetTime();
279   else
280     return 0;
281 }
282
283 bool CApplicationPlayer::IsCaching() const
284 {
285   boost::shared_ptr<IPlayer> player = GetInternal();
286   return (player && player->IsCaching());
287 }
288
289 bool CApplicationPlayer::IsInMenu() const
290 {
291   boost::shared_ptr<IPlayer> player = GetInternal();
292   return (player && player->IsInMenu());
293 }
294
295 bool CApplicationPlayer::HasMenu() const
296 {
297   boost::shared_ptr<IPlayer> player = GetInternal();
298   return (player && player->HasMenu());
299 }
300
301 int CApplicationPlayer::GetCacheLevel() const
302 {
303   boost::shared_ptr<IPlayer> player = GetInternal();
304   if (player)
305     return player->GetCacheLevel();
306   else
307     return 0;
308 }
309
310 int CApplicationPlayer::GetSubtitleCount()
311 {
312   boost::shared_ptr<IPlayer> player = GetInternal();
313   if (player)
314     return player->GetSubtitleCount();
315   else
316     return 0;
317 }
318
319 int CApplicationPlayer::GetAudioStream()
320 {
321   boost::shared_ptr<IPlayer> player = GetInternal();
322   if (player)
323     return player->GetAudioStream();
324   else
325     return 0;
326 }
327
328 int CApplicationPlayer::GetSubtitle()
329 {
330   boost::shared_ptr<IPlayer> player = GetInternal();
331   if (player)
332     return player->GetSubtitle();
333   else
334     return 0;
335 }
336
337 bool CApplicationPlayer::GetSubtitleVisible()
338 {
339   boost::shared_ptr<IPlayer> player = GetInternal();
340   return (player && player->GetSubtitleVisible());
341 }
342
343 bool CApplicationPlayer::CanRecord()
344 {
345   boost::shared_ptr<IPlayer> player = GetInternal();
346   return (player && player->CanRecord());
347 }
348
349 bool CApplicationPlayer::CanPause()
350 {
351   boost::shared_ptr<IPlayer> player = GetInternal();
352   return (player && player->CanPause());
353 }
354
355 bool CApplicationPlayer::IsRecording() const
356 {
357   boost::shared_ptr<IPlayer> player = GetInternal();
358   return (player && player->IsRecording());
359 }
360
361 TextCacheStruct_t* CApplicationPlayer::GetTeletextCache()
362 {
363   boost::shared_ptr<IPlayer> player = GetInternal();
364   if (player)
365     return player->GetTeletextCache();
366   else
367     return NULL;
368 }
369
370 int64_t CApplicationPlayer::GetTotalTime() const
371 {
372   boost::shared_ptr<IPlayer> player = GetInternal();
373   if (player)
374     return player->GetTotalTime();
375   else
376     return 0;
377 }
378
379 float CApplicationPlayer::GetPercentage() const
380 {
381   boost::shared_ptr<IPlayer> player = GetInternal();
382   if (player)
383     return player->GetPercentage();
384   else
385     return 0.0;
386 }
387
388 float CApplicationPlayer::GetCachePercentage() const
389 {
390   boost::shared_ptr<IPlayer> player = GetInternal();
391   if (player)
392     return player->GetCachePercentage();
393   else
394     return 0.0;
395 }
396
397 void CApplicationPlayer::ToFFRW(int iSpeed)
398 {
399   boost::shared_ptr<IPlayer> player = GetInternal();
400   if (player)
401     player->ToFFRW(iSpeed);
402 }
403
404 void CApplicationPlayer::DoAudioWork()
405 {
406   boost::shared_ptr<IPlayer> player = GetInternal();
407   if (player)
408     player->DoAudioWork();
409 }
410
411 CStdString CApplicationPlayer::GetPlayerState()
412 {
413   boost::shared_ptr<IPlayer> player = GetInternal();
414   if (player)
415     return player->GetPlayerState();
416   else
417     return "";
418 }
419
420 bool CApplicationPlayer::QueueNextFile(const CFileItem &file)
421 {
422   boost::shared_ptr<IPlayer> player = GetInternal();
423   return (player && player->QueueNextFile(file));
424 }
425
426 bool CApplicationPlayer::GetStreamDetails(CStreamDetails &details)
427 {
428   boost::shared_ptr<IPlayer> player = GetInternal();
429   return (player && player->GetStreamDetails(details));
430 }
431
432 bool CApplicationPlayer::SetPlayerState(CStdString state)
433 {
434   boost::shared_ptr<IPlayer> player = GetInternal();
435   return (player && player->SetPlayerState(state));
436 }
437
438 void CApplicationPlayer::OnNothingToQueueNotify()
439 {
440   boost::shared_ptr<IPlayer> player = GetInternal();
441   if (player)
442     player->OnNothingToQueueNotify();
443 }
444
445 void CApplicationPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
446 {
447   boost::shared_ptr<IPlayer> player = GetInternal();
448   if (player)
449     player->GetVideoStreamInfo(info);
450 }
451
452 void CApplicationPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
453 {
454   boost::shared_ptr<IPlayer> player = GetInternal();
455   if (player)
456     player->GetAudioStreamInfo(index, info);
457 }
458
459 bool CApplicationPlayer::OnAction(const CAction &action)
460 {
461   boost::shared_ptr<IPlayer> player = GetInternal();
462   return (player && player->OnAction(action));
463 }
464
465 bool CApplicationPlayer::Record(bool bOnOff)
466 {
467   boost::shared_ptr<IPlayer> player = GetInternal();
468   return (player && player->Record(bOnOff));
469 }
470
471 int  CApplicationPlayer::GetAudioStreamCount()
472 {
473   boost::shared_ptr<IPlayer> player = GetInternal();
474   if (player)
475     return player->GetAudioStreamCount();
476   else
477     return 0;
478 }
479
480 void CApplicationPlayer::SetAudioStream(int iStream)
481 {
482   boost::shared_ptr<IPlayer> player = GetInternal();
483   if (player)
484     player->SetAudioStream(iStream);
485 }
486
487 void CApplicationPlayer::GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info)
488 {
489   boost::shared_ptr<IPlayer> player = GetInternal();
490   if (player)
491     player->GetSubtitleStreamInfo(index, info);
492 }
493
494 void CApplicationPlayer::SetSubtitle(int iStream)
495 {
496   boost::shared_ptr<IPlayer> player = GetInternal();
497   if (player)
498     player->SetSubtitle(iStream);
499 }
500
501 void CApplicationPlayer::SetSubtitleVisible(bool bVisible)
502 {
503   boost::shared_ptr<IPlayer> player = GetInternal();
504   if (player)
505     player->SetSubtitleVisible(bVisible);
506 }
507
508 int  CApplicationPlayer::AddSubtitle(const CStdString& strSubPath)
509 {
510   boost::shared_ptr<IPlayer> player = GetInternal();
511   if (player)
512     return player->AddSubtitle(strSubPath);
513   else
514     return 0;
515 }
516
517 void CApplicationPlayer::SetSubTitleDelay(float fValue)
518 {
519   boost::shared_ptr<IPlayer> player = GetInternal();
520   if (player)
521     player->SetSubTitleDelay(fValue);
522 }
523
524 void CApplicationPlayer::SetAVDelay(float fValue)
525 {
526   boost::shared_ptr<IPlayer> player = GetInternal();
527   if (player)
528     player->SetAVDelay(fValue);
529 }
530
531 void CApplicationPlayer::SetDynamicRangeCompression(long drc)
532 {
533   boost::shared_ptr<IPlayer> player = GetInternal();
534   if (player)
535     player->SetDynamicRangeCompression(drc);
536 }
537
538 bool CApplicationPlayer::SwitchChannel(const PVR::CPVRChannel &channel)
539 {
540   boost::shared_ptr<IPlayer> player = GetInternal();
541   return (player && player->SwitchChannel(channel));
542 }
543
544 void CApplicationPlayer::LoadPage(int p, int sp, unsigned char* buffer)
545 {
546   boost::shared_ptr<IPlayer> player = GetInternal();
547   if (player)
548     player->LoadPage(p, sp, buffer);
549 }
550
551 void CApplicationPlayer::GetAudioCapabilities(std::vector<int> &audioCaps)
552 {
553   boost::shared_ptr<IPlayer> player = GetInternal();
554   if (player)
555     player->GetAudioCapabilities(audioCaps);
556 }
557
558 void CApplicationPlayer::GetSubtitleCapabilities(std::vector<int> &subCaps)
559 {
560   boost::shared_ptr<IPlayer> player = GetInternal();
561   if (player)
562     player->GetSubtitleCapabilities(subCaps);
563 }
564
565 void CApplicationPlayer::GetAudioInfo( CStdString& strAudioInfo)
566 {
567   boost::shared_ptr<IPlayer> player = GetInternal();
568   if (player)
569     player->GetAudioInfo(strAudioInfo);
570 }
571
572 void CApplicationPlayer::GetVideoInfo( CStdString& strVideoInfo)
573 {
574   boost::shared_ptr<IPlayer> player = GetInternal();
575   if (player)
576     player->GetVideoInfo(strVideoInfo);
577 }
578
579 void CApplicationPlayer::GetGeneralInfo( CStdString& strVideoInfo)
580 {
581   boost::shared_ptr<IPlayer> player = GetInternal();
582   if (player)
583     player->GetGeneralInfo(strVideoInfo);
584 }
585
586 int  CApplicationPlayer::SeekChapter(int iChapter)
587 {
588   boost::shared_ptr<IPlayer> player = GetInternal();
589   if (player)
590     return player->SeekChapter(iChapter);
591   else
592     return 0;
593 }
594
595 void CApplicationPlayer::GetRenderFeatures(std::vector<int> &renderFeatures)
596 {
597   boost::shared_ptr<IPlayer> player = GetInternal();
598   if (player)
599     player->GetRenderFeatures(renderFeatures);
600 }
601
602 void CApplicationPlayer::GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods)
603 {
604   boost::shared_ptr<IPlayer> player = GetInternal();
605   if (player)
606     player->GetDeinterlaceMethods(deinterlaceMethods);
607 }
608
609 void CApplicationPlayer::GetDeinterlaceModes(std::vector<int> &deinterlaceModes)
610 {
611   boost::shared_ptr<IPlayer> player = GetInternal();
612   if (player)
613     player->GetDeinterlaceModes(deinterlaceModes);
614 }
615
616 void CApplicationPlayer::GetScalingMethods(std::vector<int> &scalingMethods)
617 {
618   boost::shared_ptr<IPlayer> player = GetInternal();
619   if (player)
620     player->GetScalingMethods(scalingMethods);
621 }
622
623 void CApplicationPlayer::SetPlaySpeed(int iSpeed, bool bApplicationMuted)
624 {
625   boost::shared_ptr<IPlayer> player = GetInternal();
626   if (!player)
627     return;
628
629   if (!IsPlayingAudio() && !IsPlayingVideo())
630     return ;
631   if (m_iPlaySpeed == iSpeed)
632     return ;
633   if (!CanSeek())
634     return;
635   if (IsPaused())
636   {
637     if (
638       ((m_iPlaySpeed > 1) && (iSpeed > m_iPlaySpeed)) ||
639       ((m_iPlaySpeed < -1) && (iSpeed < m_iPlaySpeed))
640     )
641     {
642       iSpeed = m_iPlaySpeed; // from pause to ff/rw, do previous ff/rw speed
643     }
644     Pause();
645   }
646   m_iPlaySpeed = iSpeed;
647
648   ToFFRW(m_iPlaySpeed);
649
650   // if player has volume control, set it.
651   if (ControlsVolume())
652   {
653     if (m_iPlaySpeed == 1)
654     { // restore volume
655       player->SetVolume(g_application.GetVolume(false));
656     }
657     else
658     { // mute volume
659       player->SetVolume(VOLUME_MINIMUM);
660     }
661     player->SetMute(bApplicationMuted);
662   }
663 }
664
665 int CApplicationPlayer::GetPlaySpeed() const
666 {
667   return m_iPlaySpeed;
668 }