subs: move rendering to text subtitles to overlay renderer
[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()
53 {
54   boost::shared_ptr<IPlayer> player = GetInternal();
55   if (player)
56   {
57     ++m_iPlayerOPSeq;
58     player->CloseFile();
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();
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 int CApplicationPlayer::GetPictureHeight()
284 {
285   boost::shared_ptr<IPlayer> player = GetInternal();
286   if (player)
287     return player->GetPictureHeight();
288   else
289     return 0;
290 }
291
292 int CApplicationPlayer::GetPictureWidth()
293 {
294   boost::shared_ptr<IPlayer> player = GetInternal();
295   if (player)
296     return player->GetPictureWidth();
297   else
298     return 0;
299 }
300
301 int CApplicationPlayer::GetSampleRate()
302 {
303   boost::shared_ptr<IPlayer> player = GetInternal();
304   if (player)
305     return player->GetSampleRate();
306   else
307     return 0;
308 }
309
310 bool CApplicationPlayer::IsCaching() const
311 {
312   boost::shared_ptr<IPlayer> player = GetInternal();
313   return (player && player->IsCaching());
314 }
315
316 bool CApplicationPlayer::IsInMenu() const
317 {
318   boost::shared_ptr<IPlayer> player = GetInternal();
319   return (player && player->IsInMenu());
320 }
321
322 bool CApplicationPlayer::HasMenu() const
323 {
324   boost::shared_ptr<IPlayer> player = GetInternal();
325   return (player && player->HasMenu());
326 }
327
328 int CApplicationPlayer::GetCacheLevel() const
329 {
330   boost::shared_ptr<IPlayer> player = GetInternal();
331   if (player)
332     return player->GetCacheLevel();
333   else
334     return 0;
335 }
336
337 int CApplicationPlayer::GetSubtitleCount()
338 {
339   boost::shared_ptr<IPlayer> player = GetInternal();
340   if (player)
341     return player->GetSubtitleCount();
342   else
343     return 0;
344 }
345
346 int CApplicationPlayer::GetBitsPerSample()
347 {
348   boost::shared_ptr<IPlayer> player = GetInternal();
349   if (player)
350     return player->GetBitsPerSample();
351   else
352     return 0;
353 }
354
355 int CApplicationPlayer::GetAudioStream()
356 {
357   boost::shared_ptr<IPlayer> player = GetInternal();
358   if (player)
359     return player->GetAudioStream();
360   else
361     return 0;
362 }
363
364 int CApplicationPlayer::GetSubtitle()
365 {
366   boost::shared_ptr<IPlayer> player = GetInternal();
367   if (player)
368     return player->GetSubtitle();
369   else
370     return 0;
371 }
372
373 bool CApplicationPlayer::GetSubtitleVisible()
374 {
375   boost::shared_ptr<IPlayer> player = GetInternal();
376   return (player && player->GetSubtitleVisible());
377 }
378
379 bool CApplicationPlayer::CanRecord()
380 {
381   boost::shared_ptr<IPlayer> player = GetInternal();
382   return (player && player->CanRecord());
383 }
384
385 bool CApplicationPlayer::CanPause()
386 {
387   boost::shared_ptr<IPlayer> player = GetInternal();
388   return (player && player->CanPause());
389 }
390
391 bool CApplicationPlayer::IsRecording() const
392 {
393   boost::shared_ptr<IPlayer> player = GetInternal();
394   return (player && player->IsRecording());
395 }
396
397 TextCacheStruct_t* CApplicationPlayer::GetTeletextCache()
398 {
399   boost::shared_ptr<IPlayer> player = GetInternal();
400   if (player)
401     return player->GetTeletextCache();
402   else
403     return NULL;
404 }
405
406 int64_t CApplicationPlayer::GetTotalTime() const
407 {
408   boost::shared_ptr<IPlayer> player = GetInternal();
409   if (player)
410     return player->GetTotalTime();
411   else
412     return 0;
413 }
414
415 float CApplicationPlayer::GetPercentage() const
416 {
417   boost::shared_ptr<IPlayer> player = GetInternal();
418   if (player)
419     return player->GetPercentage();
420   else
421     return 0.0;
422 }
423
424 float CApplicationPlayer::GetCachePercentage() const
425 {
426   boost::shared_ptr<IPlayer> player = GetInternal();
427   if (player)
428     return player->GetCachePercentage();
429   else
430     return 0.0;
431 }
432
433 void CApplicationPlayer::ToFFRW(int iSpeed)
434 {
435   boost::shared_ptr<IPlayer> player = GetInternal();
436   if (player)
437     player->ToFFRW(iSpeed);
438 }
439
440 void CApplicationPlayer::DoAudioWork()
441 {
442   boost::shared_ptr<IPlayer> player = GetInternal();
443   if (player)
444     player->DoAudioWork();
445 }
446
447 CStdString CApplicationPlayer::GetPlayerState()
448 {
449   boost::shared_ptr<IPlayer> player = GetInternal();
450   if (player)
451     return player->GetPlayerState();
452   else
453     return "";
454 }
455
456 bool CApplicationPlayer::QueueNextFile(const CFileItem &file)
457 {
458   boost::shared_ptr<IPlayer> player = GetInternal();
459   return (player && player->QueueNextFile(file));
460 }
461
462 bool CApplicationPlayer::GetStreamDetails(CStreamDetails &details)
463 {
464   boost::shared_ptr<IPlayer> player = GetInternal();
465   return (player && player->GetStreamDetails(details));
466 }
467
468 bool CApplicationPlayer::SetPlayerState(CStdString state)
469 {
470   boost::shared_ptr<IPlayer> player = GetInternal();
471   return (player && player->SetPlayerState(state));
472 }
473
474 void CApplicationPlayer::OnNothingToQueueNotify()
475 {
476   boost::shared_ptr<IPlayer> player = GetInternal();
477   if (player)
478     player->OnNothingToQueueNotify();
479 }
480
481 void CApplicationPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
482 {
483   boost::shared_ptr<IPlayer> player = GetInternal();
484   if (player)
485     player->GetVideoStreamInfo(info);
486 }
487
488 void CApplicationPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
489 {
490   boost::shared_ptr<IPlayer> player = GetInternal();
491   if (player)
492     player->GetAudioStreamInfo(index, info);
493 }
494
495 bool CApplicationPlayer::OnAction(const CAction &action)
496 {
497   boost::shared_ptr<IPlayer> player = GetInternal();
498   return (player && player->OnAction(action));
499 }
500
501 bool CApplicationPlayer::Record(bool bOnOff)
502 {
503   boost::shared_ptr<IPlayer> player = GetInternal();
504   return (player && player->Record(bOnOff));
505 }
506
507 int  CApplicationPlayer::GetAudioStreamCount()
508 {
509   boost::shared_ptr<IPlayer> player = GetInternal();
510   if (player)
511     return player->GetAudioStreamCount();
512   else
513     return 0;
514 }
515
516 void CApplicationPlayer::SetAudioStream(int iStream)
517 {
518   boost::shared_ptr<IPlayer> player = GetInternal();
519   if (player)
520     player->SetAudioStream(iStream);
521 }
522
523 void CApplicationPlayer::GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info)
524 {
525   boost::shared_ptr<IPlayer> player = GetInternal();
526   if (player)
527     player->GetSubtitleStreamInfo(index, info);
528 }
529
530 void CApplicationPlayer::SetSubtitle(int iStream)
531 {
532   boost::shared_ptr<IPlayer> player = GetInternal();
533   if (player)
534     player->SetSubtitle(iStream);
535 }
536
537 void CApplicationPlayer::SetSubtitleVisible(bool bVisible)
538 {
539   boost::shared_ptr<IPlayer> player = GetInternal();
540   if (player)
541     player->SetSubtitleVisible(bVisible);
542 }
543
544 int  CApplicationPlayer::AddSubtitle(const CStdString& strSubPath)
545 {
546   boost::shared_ptr<IPlayer> player = GetInternal();
547   if (player)
548     return player->AddSubtitle(strSubPath);
549   else
550     return 0;
551 }
552
553 void CApplicationPlayer::SetSubTitleDelay(float fValue)
554 {
555   boost::shared_ptr<IPlayer> player = GetInternal();
556   if (player)
557     player->SetSubTitleDelay(fValue);
558 }
559
560 void CApplicationPlayer::SetAVDelay(float fValue)
561 {
562   boost::shared_ptr<IPlayer> player = GetInternal();
563   if (player)
564     player->SetAVDelay(fValue);
565 }
566
567 void CApplicationPlayer::SetDynamicRangeCompression(long drc)
568 {
569   boost::shared_ptr<IPlayer> player = GetInternal();
570   if (player)
571     player->SetDynamicRangeCompression(drc);
572 }
573
574 bool CApplicationPlayer::SwitchChannel(const PVR::CPVRChannel &channel)
575 {
576   boost::shared_ptr<IPlayer> player = GetInternal();
577   return (player && player->SwitchChannel(channel));
578 }
579
580 void CApplicationPlayer::LoadPage(int p, int sp, unsigned char* buffer)
581 {
582   boost::shared_ptr<IPlayer> player = GetInternal();
583   if (player)
584     player->LoadPage(p, sp, buffer);
585 }
586
587 void CApplicationPlayer::GetAudioCapabilities(std::vector<int> &audioCaps)
588 {
589   boost::shared_ptr<IPlayer> player = GetInternal();
590   if (player)
591     player->GetAudioCapabilities(audioCaps);
592 }
593
594 void CApplicationPlayer::GetSubtitleCapabilities(std::vector<int> &subCaps)
595 {
596   boost::shared_ptr<IPlayer> player = GetInternal();
597   if (player)
598     player->GetSubtitleCapabilities(subCaps);
599 }
600
601 void CApplicationPlayer::GetAudioInfo( CStdString& strAudioInfo)
602 {
603   boost::shared_ptr<IPlayer> player = GetInternal();
604   if (player)
605     player->GetAudioInfo(strAudioInfo);
606 }
607
608 void CApplicationPlayer::GetVideoInfo( CStdString& strVideoInfo)
609 {
610   boost::shared_ptr<IPlayer> player = GetInternal();
611   if (player)
612     player->GetVideoInfo(strVideoInfo);
613 }
614
615 void CApplicationPlayer::GetGeneralInfo( CStdString& strVideoInfo)
616 {
617   boost::shared_ptr<IPlayer> player = GetInternal();
618   if (player)
619     player->GetGeneralInfo(strVideoInfo);
620 }
621
622 int  CApplicationPlayer::SeekChapter(int iChapter)
623 {
624   boost::shared_ptr<IPlayer> player = GetInternal();
625   if (player)
626     return player->SeekChapter(iChapter);
627   else
628     return 0;
629 }
630
631 void CApplicationPlayer::GetRenderFeatures(std::vector<int> &renderFeatures)
632 {
633   boost::shared_ptr<IPlayer> player = GetInternal();
634   if (player)
635     player->GetRenderFeatures(renderFeatures);
636 }
637
638 void CApplicationPlayer::GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods)
639 {
640   boost::shared_ptr<IPlayer> player = GetInternal();
641   if (player)
642     player->GetDeinterlaceMethods(deinterlaceMethods);
643 }
644
645 void CApplicationPlayer::GetDeinterlaceModes(std::vector<int> &deinterlaceModes)
646 {
647   boost::shared_ptr<IPlayer> player = GetInternal();
648   if (player)
649     player->GetDeinterlaceModes(deinterlaceModes);
650 }
651
652 void CApplicationPlayer::GetScalingMethods(std::vector<int> &scalingMethods)
653 {
654   boost::shared_ptr<IPlayer> player = GetInternal();
655   if (player)
656     player->GetScalingMethods(scalingMethods);
657 }
658
659 void CApplicationPlayer::SetPlaySpeed(int iSpeed, bool bApplicationMuted)
660 {
661   boost::shared_ptr<IPlayer> player = GetInternal();
662   if (!player)
663     return;
664
665   if (!IsPlayingAudio() && !IsPlayingVideo())
666     return ;
667   if (m_iPlaySpeed == iSpeed)
668     return ;
669   if (!CanSeek())
670     return;
671   if (IsPaused())
672   {
673     if (
674       ((m_iPlaySpeed > 1) && (iSpeed > m_iPlaySpeed)) ||
675       ((m_iPlaySpeed < -1) && (iSpeed < m_iPlaySpeed))
676     )
677     {
678       iSpeed = m_iPlaySpeed; // from pause to ff/rw, do previous ff/rw speed
679     }
680     Pause();
681   }
682   m_iPlaySpeed = iSpeed;
683
684   ToFFRW(m_iPlaySpeed);
685
686   // if player has volume control, set it.
687   if (ControlsVolume())
688   {
689     if (m_iPlaySpeed == 1)
690     { // restore volume
691       player->SetVolume(g_application.GetVolume(false));
692     }
693     else
694     { // mute volume
695       player->SetVolume(VOLUME_MINIMUM);
696     }
697     player->SetMute(bApplicationMuted);
698   }
699 }
700
701 int CApplicationPlayer::GetPlaySpeed() const
702 {
703   return m_iPlaySpeed;
704 }