changed: Add logic to properly handle subtitles for stacked files
[vuplus_xbmc] / xbmc / cores / omxplayer / OMXPlayer.h
1 #pragma once
2 /*
3  *      Copyright (C) 2011-2013 Team XBMC
4  *      http://xbmc.org
5  *
6  *  This Program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2, or (at your option)
9  *  any later version.
10  *
11  *  This Program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with XBMC; see the file COPYING.  If not, see
18  *  <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "cores/IPlayer.h"
23 #include "threads/Thread.h"
24
25 #include "cores/dvdplayer/IDVDPlayer.h"
26
27 #include "DVDMessageQueue.h"
28 #include "OMXCore.h"
29 #include "OMXClock.h"
30 #include "OMXPlayerAudio.h"
31 #include "OMXPlayerVideo.h"
32 #include "DVDPlayerSubtitle.h"
33 #include "DVDPlayerTeletext.h"
34
35 //#include "DVDChapterReader.h"
36 #include "DVDSubtitles/DVDFactorySubtitle.h"
37 #include "utils/BitstreamStats.h"
38
39 #include "linux/DllBCM.h"
40 #include "Edl.h"
41 #include "FileItem.h"
42 #include "threads/SingleLock.h"
43
44 class COMXPlayer;
45 class OMXPlayerVideo;
46 class OMXPlayerAudio;
47
48 namespace PVR
49 {
50   class CPVRChannel;
51 }
52
53 #define DVDSTATE_NORMAL           0x00000001 // normal dvd state
54 #define DVDSTATE_STILL            0x00000002 // currently displaying a still frame
55 #define DVDSTATE_WAIT             0x00000003 // waiting for demuxer read error
56 #define DVDSTATE_SEEK             0x00000004 // we are finishing a seek request
57
58 class COMXCurrentStream
59 {
60 public:
61   int              id;     // demuxerid of current playing stream
62   int              source;
63   double           dts;    // last dts from demuxer, used to find disncontinuities
64   double           dur;    // last frame expected duration
65   double           dts_state; // when did we last send a playback state update
66   CDVDStreamInfo   hint;   // stream hints, used to notice stream changes
67   void*            stream; // pointer or integer, identifying stream playing. if it changes stream changed
68   int              changes; // remembered counter from stream to track codec changes
69   bool             inited;
70   bool             started; // has the player started
71   const StreamType type;
72   const int        player;
73   // stuff to handle starting after seek
74   double   startpts;
75
76   COMXCurrentStream(StreamType t, int i)
77     : type(t)
78     , player(i)
79   {
80     Clear();
81   }
82
83   void Clear()
84   {
85     id     = -1;
86     source = STREAM_SOURCE_NONE;
87     dts    = DVD_NOPTS_VALUE;
88     dts_state = DVD_NOPTS_VALUE;
89     dur    = DVD_NOPTS_VALUE;
90     hint.Clear();
91     stream = NULL;
92     changes = 0;
93     inited = false;
94     started = false;
95     startpts  = DVD_NOPTS_VALUE;
96   }
97   double dts_end()
98   {
99     if(dts == DVD_NOPTS_VALUE)
100       return DVD_NOPTS_VALUE;
101     if(dur == DVD_NOPTS_VALUE)
102       return dts;
103     return dts + dur;
104   }
105 };
106
107 typedef struct
108 {
109   StreamType   type;
110   int          type_index;
111   std::string  filename;
112   std::string  filename2;  // for vobsub subtitles, 2 files are necessary (idx/sub) 
113   std::string  language;
114   std::string  name;
115   CDemuxStream::EFlags flags;
116   int          source;
117   int          id;
118   std::string  codec;
119   int          channels;
120 } OMXSelectionStream;
121
122 typedef std::vector<OMXSelectionStream> OMXSelectionStreams;
123
124 class COMXSelectionStreams
125 {
126   CCriticalSection m_section;
127   OMXSelectionStream  m_invalid;
128 public:
129   COMXSelectionStreams()
130   {
131     m_invalid.id = -1;
132     m_invalid.source = STREAM_SOURCE_NONE;
133     m_invalid.type = STREAM_NONE;
134   }
135   std::vector<OMXSelectionStream> m_Streams;
136
137   int              IndexOf (StreamType type, int source, int id) const;
138   int              IndexOf (StreamType type, COMXPlayer& p) const;
139   int              Count   (StreamType type) const { return IndexOf(type, STREAM_SOURCE_NONE, -1) + 1; }
140   OMXSelectionStream& Get     (StreamType type, int index);
141   bool             Get     (StreamType type, CDemuxStream::EFlags flag, OMXSelectionStream& out);
142
143   OMXSelectionStreams Get(StreamType type);
144   template<typename Compare> OMXSelectionStreams Get(StreamType type, Compare compare)
145   {
146     OMXSelectionStreams streams = Get(type);
147     std::stable_sort(streams.begin(), streams.end(), compare);
148     return streams;
149   }
150
151   template<typename Filter>
152   OMXSelectionStreams RemoveIf(StreamType type, Filter filter)
153   {
154     OMXSelectionStreams streams = Get(type);
155     streams.erase(std::remove_if(streams.begin(), streams.end(), filter), streams.end());
156     return streams;
157   }
158
159   void             Clear   (StreamType type, StreamSource source);
160   int              Source  (StreamSource source, std::string filename);
161
162   void             Update  (OMXSelectionStream& s);
163   void             Update  (CDVDInputStream* input, CDVDDemux* demuxer);
164 };
165
166
167 #define DVDPLAYER_AUDIO    1
168 #define DVDPLAYER_VIDEO    2
169 #define DVDPLAYER_SUBTITLE 3
170 #define DVDPLAYER_TELETEXT 4
171
172 class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
173 {
174 public:
175
176   COMXPlayer(IPlayerCallback &callback);
177   virtual ~COMXPlayer();
178   
179   virtual bool  OpenFile(const CFileItem &file, const CPlayerOptions &options);
180   virtual bool  CloseFile();
181   virtual bool  IsPlaying() const;
182   virtual void  Pause();
183   virtual bool  IsPaused() const;
184   virtual bool  HasVideo() const;
185   virtual bool  HasAudio() const;
186   virtual bool  IsPassthrough() const;
187   virtual bool  CanSeek();
188   virtual void Seek(bool bPlus, bool bLargeStep, bool bChapterOverride);
189   virtual bool  SeekScene(bool bPlus = true);
190   virtual void SeekPercentage(float iPercent);
191   virtual float GetPercentage();
192   virtual float GetCachePercentage();
193
194   virtual void RegisterAudioCallback(IAudioCallback* pCallback) { m_omxPlayerAudio.RegisterAudioCallback(pCallback); }
195   virtual void UnRegisterAudioCallback()                        { m_omxPlayerAudio.UnRegisterAudioCallback(); }
196   virtual void SetVolume(float nVolume)                         { m_omxPlayerAudio.SetVolume(nVolume); }
197   virtual void SetMute(bool bOnOff)                             { m_omxPlayerAudio.SetMute(bOnOff); }
198   virtual void SetDynamicRangeCompression(long drc)             { m_omxPlayerAudio.SetDynamicRangeCompression(drc); }
199   virtual bool ControlsVolume() {return true;}
200   virtual void GetAudioInfo(CStdString &strAudioInfo);
201   virtual void GetVideoInfo(CStdString &strVideoInfo);
202   virtual void GetGeneralInfo(CStdString &strVideoInfo);
203   virtual bool CanRecord();
204   virtual bool IsRecording();
205   virtual bool CanPause();
206   virtual bool Record(bool bOnOff);
207   virtual void SetAVDelay(float fValue = 0.0f);
208   virtual float GetAVDelay();
209
210   virtual void  SetSubTitleDelay(float fValue = 0.0f);
211   virtual float GetSubTitleDelay();
212   virtual int   GetSubtitleCount();
213   virtual int   GetSubtitle();
214   virtual void  GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info);
215   virtual void  SetSubtitle(int iStream);
216   virtual bool  GetSubtitleVisible();
217   virtual void  SetSubtitleVisible(bool bVisible);
218   virtual int   AddSubtitle(const CStdString& strSubPath);
219
220   virtual int   GetAudioStreamCount();
221   virtual int   GetAudioStream();
222   virtual void  SetAudioStream(int iStream);
223
224   virtual TextCacheStruct_t* GetTeletextCache();
225   virtual void  LoadPage(int p, int sp, unsigned char* buffer);
226
227   virtual int   GetChapterCount();
228   virtual int   GetChapter();
229   virtual void  GetChapterName(CStdString& strChapterName);
230   virtual int   SeekChapter(int iChapter);
231
232   virtual void SeekTime(int64_t iTime);
233   virtual int64_t GetTime();
234   virtual int64_t GetTotalTime();
235   virtual void ToFFRW(int iSpeed );
236   virtual bool OnAction(const CAction &action);
237   virtual bool HasMenu();
238   virtual int GetSourceBitrate();
239   virtual void GetVideoStreamInfo(SPlayerVideoStreamInfo &info);
240
241   virtual bool GetStreamDetails(CStreamDetails &details);
242   virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
243
244   virtual CStdString GetPlayerState();
245   virtual bool SetPlayerState(CStdString state);
246   
247   virtual CStdString GetPlayingTitle();
248
249   virtual bool SwitchChannel(const PVR::CPVRChannel &channel);
250   virtual bool CachePVRStream(void) const;
251   
252   enum ECacheState
253   { CACHESTATE_DONE = 0
254   , CACHESTATE_FULL     // player is filling up the demux queue
255   , CACHESTATE_PVR      // player is waiting for some data in each buffer
256   , CACHESTATE_INIT     // player is waiting for first packet of each stream
257   , CACHESTATE_PLAY     // player is waiting for players to not be stalled
258   , CACHESTATE_FLUSH    // temporary state player will choose startup between init or full
259   };
260
261   virtual bool  IsCaching() const                                 { return m_caching == CACHESTATE_FULL || m_caching == CACHESTATE_PVR; }
262   virtual int   GetCacheLevel() const;
263
264   virtual int  OnDVDNavResult(void* pData, int iMessage);
265
266   virtual void  GetRenderFeatures(std::vector<int> &renderFeatures);
267   virtual void  GetDeinterlaceMethods(std::vector<int> &deinterlaceMethods);
268   virtual void  GetDeinterlaceModes(std::vector<int> &deinterlaceModes);
269   virtual void  GetScalingMethods(std::vector<int> &scalingMethods);
270   virtual void  GetAudioCapabilities(std::vector<int> &audioCaps);
271   virtual void  GetSubtitleCapabilities(std::vector<int> &subCaps);
272 protected:
273   friend class COMXSelectionStreams;
274
275   class OMXStreamLock : public CSingleLock
276   {
277   public:
278     inline OMXStreamLock(COMXPlayer* comxplayer) : CSingleLock(comxplayer->m_critStreamSection) {}
279   };
280
281   virtual void  OnStartup();
282   virtual void  OnExit();
283   virtual void  Process();
284
285   bool OpenAudioStream(int iStream, int source, bool reset = true);
286   bool OpenVideoStream(int iStream, int source, bool reset = true);
287   bool OpenSubtitleStream(int iStream, int source);
288
289   /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
290   *          If these are not available, subtitles are disabled.
291   *   \return true if the subtitles were changed, false otherwise.
292   */
293   bool AdaptForcedSubtitles();
294   bool OpenTeletextStream(int iStream, int source);
295   bool CloseAudioStream(bool bWaitForBuffers);
296   bool CloseVideoStream(bool bWaitForBuffers);
297   bool CloseSubtitleStream(bool bKeepOverlays);
298   bool CloseTeletextStream(bool bWaitForBuffers);
299
300   void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
301   void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
302   void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
303   void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
304   void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
305
306   bool ShowPVRChannelInfo();
307
308   int  AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
309
310   /**
311    * one of the DVD_PLAYSPEED defines
312    */
313   void SetPlaySpeed(int iSpeed);
314   int GetPlaySpeed()                                                { return m_playSpeed; }
315   void    SetCaching(ECacheState state);
316
317   int64_t GetTotalTimeInMsec();
318
319   double  GetQueueTime();
320   bool    GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
321
322
323   void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
324
325
326   void  HandleMessages();
327   void    HandlePlaySpeed();
328   bool  IsInMenu() const;
329
330   void SynchronizePlayers(unsigned int sources);
331   void SynchronizeDemuxer(unsigned int timeout);
332   void CheckAutoSceneSkip();
333   void CheckContinuity(COMXCurrentStream& current, DemuxPacket* pPacket);
334   bool CheckSceneSkip(COMXCurrentStream& current);
335   bool CheckPlayerInit(COMXCurrentStream& current, unsigned int source);
336   bool CheckStartCaching(COMXCurrentStream& current);
337   void UpdateCorrection(DemuxPacket* pkt, double correction);
338   void UpdateTimestamps(COMXCurrentStream& current, DemuxPacket* pPacket);
339   void SendPlayerMessage(CDVDMsg* pMsg, unsigned int target);
340   bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
341   bool IsValidStream(COMXCurrentStream& stream);
342   bool IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream);
343   bool CheckDelayedChannelEntry(void);
344   bool OpenInputStream();
345   bool OpenDemuxStream();
346   void OpenDefaultStreams(bool reset = true);
347
348   void UpdateApplication(double timeout);
349   void UpdatePlayState(double timeout);
350   double m_UpdateApplication;
351
352   bool m_bAbortRequest;
353
354   std::string           m_filename; // holds the actual filename
355   std::string  m_mimetype;  // hold a hint to what content file contains (mime type)
356   ECacheState  m_caching;
357   CFileItem    m_item;
358   XbmcThreads::EndTime m_ChannelEntryTimeOut;
359
360
361   COMXCurrentStream m_CurrentAudio;
362   COMXCurrentStream m_CurrentVideo;
363   COMXCurrentStream m_CurrentSubtitle;
364   COMXCurrentStream m_CurrentTeletext;
365
366   COMXSelectionStreams m_SelectionStreams;
367
368   int m_playSpeed;
369   struct SSpeedState
370   {
371     double lastpts;  // holds last display pts during ff/rw operations
372     double lasttime;
373   } m_SpeedState;
374
375   int m_errorCount;
376   double m_offset_pts;
377
378   CDVDMessageQueue m_messenger;     // thread messenger
379
380   OMXPlayerVideo m_omxPlayerVideo; // video part
381   OMXPlayerAudio m_omxPlayerAudio; // audio part
382   CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
383   CDVDTeletextData m_dvdPlayerTeletext; // teletext part
384
385   CDVDClock m_clock;                // master clock
386   OMXClock m_av_clock;
387
388   bool m_stepped;
389   int m_video_fifo;
390   int m_audio_fifo;
391   double m_last_check_time;         // we periodically check for gpu underrun
392   double m_stamp;                   // last media stamp
393
394   CDVDOverlayContainer m_overlayContainer;
395
396   CDVDInputStream* m_pInputStream;  // input stream for current playing file
397   CDVDDemux* m_pDemuxer;            // demuxer for current playing file
398   CDVDDemux*            m_pSubtitleDemuxer;
399
400   CStdString m_lastSub;
401
402   struct SDVDInfo
403   {
404     void Clear()
405     {
406       state                =  DVDSTATE_NORMAL;
407       iSelectedSPUStream   = -1;
408       iSelectedAudioStream = -1;
409       iDVDStillTime        =  0;
410       iDVDStillStartTime   =  0;
411     }
412
413     int state;                // current dvdstate
414     unsigned int iDVDStillTime;      // total time in ticks we should display the still before continuing
415     unsigned int iDVDStillStartTime; // time in ticks when we started the still
416     int iSelectedSPUStream;   // mpeg stream id, or -1 if disabled
417     int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
418   } m_dvd;
419
420   enum ETimeSource
421   {
422     ETIMESOURCE_CLOCK,
423     ETIMESOURCE_INPUT,
424     ETIMESOURCE_MENU,
425   };
426
427   friend class OMXPlayerVideo;
428   friend class OMXPlayerAudio;
429
430   struct SPlayerState
431   {
432     SPlayerState() { Clear(); }
433     void Clear()
434     {
435       player        = 0;
436       timestamp     = 0;
437       time          = 0;
438       time_total    = 0;
439       time_offset   = 0;
440       time_src      = ETIMESOURCE_CLOCK;
441       dts           = DVD_NOPTS_VALUE;
442       player_state  = "";
443       chapter       = 0;
444       chapter_name  = "";
445       chapter_count = 0;
446       canrecord     = false;
447       recording     = false;
448       canpause      = false;
449       canseek       = false;
450       demux_video   = "";
451       demux_audio   = "";
452       cache_bytes   = 0;
453       cache_level   = 0.0;
454       cache_delay   = 0.0;
455       cache_offset  = 0.0;
456     }
457
458     int    player;            // source of this data
459
460     double timestamp;         // last time of update
461     double time_offset;       // difference between time and pts
462
463     double time;              // current playback time
464     double time_total;        // total playback time
465     ETimeSource time_src;     // current time source
466     double dts;               // last known dts
467
468     std::string player_state;  // full player state
469
470     int         chapter;      // current chapter
471     std::string chapter_name; // name of current chapter
472     int         chapter_count;// number of chapter
473
474     bool canrecord;           // can input stream record
475     bool recording;           // are we currently recording
476
477     bool canpause;            // pvr: can pause the current playing item
478     bool canseek;             // pvr: can seek in the current playing item
479
480     std::string demux_video;
481     std::string demux_audio;
482
483     int64_t cache_bytes;   // number of bytes current's cached
484     double  cache_level;   // current estimated required cache level
485     double  cache_delay;   // time until cache is expected to reach estimated level
486     double  cache_offset;  // percentage of file ahead of current position
487   } m_State, m_StateInput;
488   CCriticalSection m_StateSection;
489
490   CEvent m_ready;
491   CCriticalSection m_critStreamSection; // need to have this lock when switching streams (audio / video)
492
493   CEdl m_Edl;
494
495   struct SEdlAutoSkipMarkers {
496
497     void Clear()
498     {
499       cut = -1;
500       commbreak_start = -1;
501       commbreak_end = -1;
502       seek_to_start = false;
503       mute = false;
504     }
505
506     int cut;              // last automatically skipped EDL cut seek position
507     int commbreak_start;  // start time of the last commercial break automatically skipped
508     int commbreak_end;    // end time of the last commercial break automatically skipped
509     bool seek_to_start;   // whether seeking can go back to the start of a previously skipped break
510     bool mute;            // whether EDL mute is on
511
512   } m_EdlAutoSkipMarkers;
513
514   CPlayerOptions          m_PlayerOptions;
515
516   bool m_HasVideo;
517   bool m_HasAudio;
518
519   bool m_DemuxerPausePending;
520 };