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