[release] version bump to 13.0 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   template<typename Filter>
158   SelectionStreams RemoveIf(StreamType type, Filter filter)
159   {
160     SelectionStreams streams = Get(type);
161     streams.erase(std::remove_if(streams.begin(), streams.end(), filter), streams.end());
162     return streams;
163   }
164
165   void             Clear   (StreamType type, StreamSource source);
166   int              Source  (StreamSource source, std::string filename);
167
168   void             Update  (SelectionStream& s);
169   void             Update  (CDVDInputStream* input, CDVDDemux* demuxer);
170 };
171
172
173 #define DVDPLAYER_AUDIO    1
174 #define DVDPLAYER_VIDEO    2
175 #define DVDPLAYER_SUBTITLE 3
176 #define DVDPLAYER_TELETEXT 4
177
178 class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
179 {
180 public:
181   CDVDPlayer(IPlayerCallback& callback);
182   virtual ~CDVDPlayer();
183   virtual bool OpenFile(const CFileItem& file, const CPlayerOptions &options);
184   virtual bool CloseFile(bool reopen = false);
185   virtual bool IsPlaying() const;
186   virtual void Pause();
187   virtual bool IsPaused() const;
188   virtual bool HasVideo() const;
189   virtual bool HasAudio() const;
190   virtual bool IsPassthrough() const;
191   virtual bool CanSeek();
192   virtual void Seek(bool bPlus, bool bLargeStep, bool bChapterOverride);
193   virtual bool SeekScene(bool bPlus = true);
194   virtual void SeekPercentage(float iPercent);
195   virtual float GetPercentage();
196   virtual float GetCachePercentage();
197
198   virtual void RegisterAudioCallback(IAudioCallback* pCallback) { m_dvdPlayerAudio.RegisterAudioCallback(pCallback); }
199   virtual void UnRegisterAudioCallback()                        { m_dvdPlayerAudio.UnRegisterAudioCallback(); }
200   virtual void SetVolume(float nVolume)                         { m_dvdPlayerAudio.SetVolume(nVolume); }
201   virtual void SetDynamicRangeCompression(long drc)             { m_dvdPlayerAudio.SetDynamicRangeCompression(drc); }
202   virtual void GetAudioInfo(CStdString& strAudioInfo);
203   virtual void GetVideoInfo(CStdString& strVideoInfo);
204   virtual void GetGeneralInfo( CStdString& strVideoInfo);
205   virtual bool CanRecord();
206   virtual bool IsRecording();
207   virtual bool CanPause();
208   virtual bool Record(bool bOnOff);
209   virtual void SetAVDelay(float fValue = 0.0f);
210   virtual float GetAVDelay();
211
212   virtual void SetSubTitleDelay(float fValue = 0.0f);
213   virtual float GetSubTitleDelay();
214   virtual int GetSubtitleCount();
215   virtual int GetSubtitle();
216   virtual void GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info);
217   virtual void SetSubtitle(int iStream);
218   virtual bool GetSubtitleVisible();
219   virtual void SetSubtitleVisible(bool bVisible);
220   virtual int  AddSubtitle(const CStdString& strSubPath);
221
222   virtual int GetAudioStreamCount();
223   virtual int GetAudioStream();
224   virtual void SetAudioStream(int iStream);
225
226   virtual TextCacheStruct_t* GetTeletextCache();
227   virtual void LoadPage(int p, int sp, unsigned char* buffer);
228
229   virtual int  GetChapterCount();
230   virtual int  GetChapter();
231   virtual void GetChapterName(CStdString& strChapterName);
232   virtual int  SeekChapter(int iChapter);
233
234   virtual void SeekTime(int64_t iTime);
235   virtual int64_t GetTime();
236   virtual int64_t GetTotalTime();
237   virtual void ToFFRW(int iSpeed);
238   virtual bool OnAction(const CAction &action);
239   virtual bool HasMenu();
240
241   virtual int GetSourceBitrate();
242   virtual void GetVideoStreamInfo(SPlayerVideoStreamInfo &info);
243   virtual bool GetStreamDetails(CStreamDetails &details);
244   virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
245
246   virtual CStdString GetPlayerState();
247   virtual bool SetPlayerState(CStdString state);
248
249   virtual CStdString GetPlayingTitle();
250
251   virtual bool SwitchChannel(const PVR::CPVRChannel &channel);
252   virtual bool CachePVRStream(void) const;
253
254   enum ECacheState
255   { CACHESTATE_DONE = 0
256   , CACHESTATE_FULL     // player is filling up the demux queue
257   , CACHESTATE_PVR      // player is waiting for some data in each buffer
258   , CACHESTATE_INIT     // player is waiting for first packet of each stream
259   , CACHESTATE_PLAY     // player is waiting for players to not be stalled
260   , CACHESTATE_FLUSH    // temporary state player will choose startup between init or full
261   };
262
263   virtual bool IsCaching() const { return m_caching == CACHESTATE_FULL || m_caching == CACHESTATE_PVR; }
264   virtual int GetCacheLevel() const ;
265
266   virtual int OnDVDNavResult(void* pData, int iMessage);
267 protected:
268   friend class CSelectionStreams;
269
270   class StreamLock : public CSingleLock
271   {
272   public:
273     inline StreamLock(CDVDPlayer* cdvdplayer) : CSingleLock(cdvdplayer->m_critStreamSection) {}
274   };
275
276   virtual void OnStartup();
277   virtual void OnExit();
278   virtual void Process();
279
280   bool OpenAudioStream(int iStream, int source, bool reset = true);
281   bool OpenVideoStream(int iStream, int source, bool reset = true);
282   bool OpenSubtitleStream(int iStream, int source);
283
284   /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
285   *          If these are not available, subtitles are disabled.
286   *   \return true if the subtitles were changed, false otherwise.
287   */
288   bool AdaptForcedSubtitles();
289   bool OpenTeletextStream(int iStream, int source);
290   bool CloseAudioStream(bool bWaitForBuffers);
291   bool CloseVideoStream(bool bWaitForBuffers);
292   bool CloseSubtitleStream(bool bKeepOverlays);
293   bool CloseTeletextStream(bool bWaitForBuffers);
294
295   void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
296   void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
297   void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
298   void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
299   void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
300
301   bool ShowPVRChannelInfo();
302
303   int  AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
304
305   /**
306    * one of the DVD_PLAYSPEED defines
307    */
308   void SetPlaySpeed(int iSpeed);
309   int GetPlaySpeed()                                                { return m_playSpeed; }
310   void SetCaching(ECacheState state);
311
312   int64_t GetTotalTimeInMsec();
313
314   double GetQueueTime();
315   bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
316
317
318   void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
319
320   void HandleMessages();
321   void HandlePlaySpeed();
322   bool IsInMenu() const;
323
324   void SynchronizePlayers(unsigned int sources);
325   void SynchronizeDemuxer(unsigned int timeout);
326   void CheckAutoSceneSkip();
327   void CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket);
328   bool CheckSceneSkip(CCurrentStream& current);
329   bool CheckPlayerInit(CCurrentStream& current, unsigned int source);
330   bool CheckStartCaching(CCurrentStream& current);
331   void UpdateCorrection(DemuxPacket* pkt, double correction);
332   void UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket);
333   void SendPlayerMessage(CDVDMsg* pMsg, unsigned int target);
334
335   bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
336   bool IsValidStream(CCurrentStream& stream);
337   bool IsBetterStream(CCurrentStream& current, CDemuxStream* stream);
338   bool CheckDelayedChannelEntry(void);
339
340   bool OpenInputStream();
341   bool OpenDemuxStream();
342   void OpenDefaultStreams(bool reset = true);
343
344   void UpdateApplication(double timeout);
345   void UpdatePlayState(double timeout);
346   double m_UpdateApplication;
347
348   bool m_bAbortRequest;
349
350   std::string  m_filename; // holds the actual filename
351   std::string  m_mimetype;  // hold a hint to what content file contains (mime type)
352   ECacheState  m_caching;
353   CFileItem    m_item;
354   XbmcThreads::EndTime m_ChannelEntryTimeOut;
355
356
357   CCurrentStream m_CurrentAudio;
358   CCurrentStream m_CurrentVideo;
359   CCurrentStream m_CurrentSubtitle;
360   CCurrentStream m_CurrentTeletext;
361
362   CSelectionStreams m_SelectionStreams;
363
364   int m_playSpeed;
365   struct SSpeedState
366   {
367     double lastpts;  // holds last display pts during ff/rw operations
368     double lasttime;
369   } m_SpeedState;
370
371   int m_errorCount;
372   double m_offset_pts;
373
374   CDVDMessageQueue m_messenger;     // thread messenger
375
376   CDVDPlayerVideo m_dvdPlayerVideo; // video part
377   CDVDPlayerAudio m_dvdPlayerAudio; // audio part
378   CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
379   CDVDTeletextData m_dvdPlayerTeletext; // teletext part
380
381   CDVDClock m_clock;                // master clock
382   CDVDOverlayContainer m_overlayContainer;
383
384   CDVDInputStream* m_pInputStream;  // input stream for current playing file
385   CDVDDemux* m_pDemuxer;            // demuxer for current playing file
386   CDVDDemux* m_pSubtitleDemuxer;
387
388   CStdString m_lastSub;
389
390   struct SDVDInfo
391   {
392     void Clear()
393     {
394       state                =  DVDSTATE_NORMAL;
395       iSelectedSPUStream   = -1;
396       iSelectedAudioStream = -1;
397       iDVDStillTime        =  0;
398       iDVDStillStartTime   =  0;
399     }
400
401     int state;                // current dvdstate
402     unsigned int iDVDStillTime;      // total time in ticks we should display the still before continuing
403     unsigned int iDVDStillStartTime; // time in ticks when we started the still
404     int iSelectedSPUStream;   // mpeg stream id, or -1 if disabled
405     int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
406   } m_dvd;
407
408   enum ETimeSource
409   {
410     ETIMESOURCE_CLOCK,
411     ETIMESOURCE_INPUT,
412     ETIMESOURCE_MENU,
413   };
414
415   friend class CDVDPlayerVideo;
416   friend class CDVDPlayerAudio;
417
418   struct SPlayerState
419   {
420     SPlayerState() { Clear(); }
421     void Clear()
422     {
423       player        = 0;
424       timestamp     = 0;
425       time          = 0;
426       time_total    = 0;
427       time_offset   = 0;
428       time_src      = ETIMESOURCE_CLOCK;
429       dts           = DVD_NOPTS_VALUE;
430       player_state  = "";
431       chapter       = 0;
432       chapter_name  = "";
433       chapter_count = 0;
434       canrecord     = false;
435       recording     = false;
436       canpause      = false;
437       canseek       = false;
438       demux_video   = "";
439       demux_audio   = "";
440       cache_bytes   = 0;
441       cache_level   = 0.0;
442       cache_delay   = 0.0;
443       cache_offset  = 0.0;
444     }
445
446     int    player;            // source of this data
447
448     double timestamp;         // last time of update
449     double time_offset;       // difference between time and pts
450
451     double time;              // current playback time
452     double time_total;        // total playback time
453     ETimeSource time_src;     // current time source
454     double dts;               // last known dts
455
456     std::string player_state;  // full player state
457
458     int         chapter;      // current chapter
459     std::string chapter_name; // name of current chapter
460     int         chapter_count;// number of chapter
461
462     bool canrecord;           // can input stream record
463     bool recording;           // are we currently recording
464
465     bool canpause;            // pvr: can pause the current playing item
466     bool canseek;             // pvr: can seek in the current playing item
467
468     std::string demux_video;
469     std::string demux_audio;
470
471     int64_t cache_bytes;   // number of bytes current's cached
472     double  cache_level;   // current estimated required cache level
473     double  cache_delay;   // time until cache is expected to reach estimated level
474     double  cache_offset;  // percentage of file ahead of current position
475   } m_State, m_StateInput;
476   CCriticalSection m_StateSection;
477
478   CEvent m_ready;
479   CCriticalSection m_critStreamSection; // need to have this lock when switching streams (audio / video)
480
481   CEdl m_Edl;
482
483   struct SEdlAutoSkipMarkers {
484
485     void Clear()
486     {
487       cut = -1;
488       commbreak_start = -1;
489       commbreak_end = -1;
490       seek_to_start = false;
491       mute = false;
492     }
493
494     int cut;              // last automatically skipped EDL cut seek position
495     int commbreak_start;  // start time of the last commercial break automatically skipped
496     int commbreak_end;    // end time of the last commercial break automatically skipped
497     bool seek_to_start;   // whether seeking can go back to the start of a previously skipped break
498     bool mute;            // whether EDL mute is on
499
500   } m_EdlAutoSkipMarkers;
501
502   CPlayerOptions m_PlayerOptions;
503
504   bool m_HasVideo;
505   bool m_HasAudio;
506
507   bool m_DemuxerPausePending;
508 };