4 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
23 #include "cores/IPlayer.h"
24 #include "threads/Thread.h"
26 #include "IDVDPlayer.h"
28 #include "DVDMessageQueue.h"
30 #include "DVDPlayerAudio.h"
31 #include "DVDPlayerVideo.h"
32 #include "DVDPlayerSubtitle.h"
33 #include "DVDPlayerTeletext.h"
35 //#include "DVDChapterReader.h"
36 #include "DVDSubtitles/DVDFactorySubtitle.h"
37 #include "utils/BitstreamStats.h"
41 #include "threads/SingleLock.h"
42 #include "utils/StreamDetails.h"
43 #include "threads/SystemClock.h"
46 class CDVDInputStream;
49 class CDemuxStreamVideo;
50 class CDemuxStreamAudio;
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
66 int id; // demuxerid of current playing stream
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
75 bool started; // has the player started
76 const StreamType type;
78 // stuff to handle starting after seek
81 CCurrentStream(StreamType t, int i)
91 source = STREAM_SOURCE_NONE;
92 dts = DVD_NOPTS_VALUE;
93 dts_state = DVD_NOPTS_VALUE;
94 dur = DVD_NOPTS_VALUE;
100 startpts = DVD_NOPTS_VALUE;
105 if(dts == DVD_NOPTS_VALUE)
106 return DVD_NOPTS_VALUE;
107 if(dur == DVD_NOPTS_VALUE)
117 std::string filename;
118 std::string filename2; // for vobsub subtitles, 2 files are necessary (idx/sub)
119 std::string language;
121 CDemuxStream::EFlags flags;
128 typedef std::vector<SelectionStream> SelectionStreams;
130 class CSelectionStreams
132 CCriticalSection m_section;
133 SelectionStream m_invalid;
138 m_invalid.source = STREAM_SOURCE_NONE;
139 m_invalid.type = STREAM_NONE;
141 std::vector<SelectionStream> m_Streams;
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);
149 SelectionStreams Get(StreamType type);
150 template<typename Compare> SelectionStreams Get(StreamType type, Compare compare)
152 SelectionStreams streams = Get(type);
153 std::stable_sort(streams.begin(), streams.end(), compare);
157 void Clear (StreamType type, StreamSource source);
158 int Source (StreamSource source, std::string filename);
160 void Update (SelectionStream& s);
161 void Update (CDVDInputStream* input, CDVDDemux* demuxer);
165 #define DVDPLAYER_AUDIO 1
166 #define DVDPLAYER_VIDEO 2
167 #define DVDPLAYER_SUBTITLE 3
168 #define DVDPLAYER_TELETEXT 4
170 class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
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();
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();
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);
214 virtual int GetAudioStreamCount();
215 virtual int GetAudioStream();
216 virtual void SetAudioStream(int iStream);
218 virtual TextCacheStruct_t* GetTeletextCache();
219 virtual void LoadPage(int p, int sp, unsigned char* buffer);
221 virtual int GetChapterCount();
222 virtual int GetChapter();
223 virtual void GetChapterName(CStdString& strChapterName);
224 virtual int SeekChapter(int iChapter);
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();
233 virtual int GetSourceBitrate();
234 virtual void GetVideoStreamInfo(SPlayerVideoStreamInfo &info);
235 virtual bool GetStreamDetails(CStreamDetails &details);
236 virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
238 virtual CStdString GetPlayerState();
239 virtual bool SetPlayerState(CStdString state);
241 virtual CStdString GetPlayingTitle();
243 virtual bool SwitchChannel(const PVR::CPVRChannel &channel);
244 virtual bool CachePVRStream(void) const;
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
255 virtual bool IsCaching() const { return m_caching == CACHESTATE_FULL || m_caching == CACHESTATE_PVR; }
256 virtual int GetCacheLevel() const ;
258 virtual int OnDVDNavResult(void* pData, int iMessage);
260 friend class CSelectionStreams;
262 class StreamLock : public CSingleLock
265 inline StreamLock(CDVDPlayer* cdvdplayer) : CSingleLock(cdvdplayer->m_critStreamSection) {}
268 virtual void OnStartup();
269 virtual void OnExit();
270 virtual void Process();
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);
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.
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);
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);
293 bool ShowPVRChannelInfo();
295 int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
296 void SetSubtitleVisibleInternal(bool bVisible);
299 * one of the DVD_PLAYSPEED defines
301 void SetPlaySpeed(int iSpeed);
302 int GetPlaySpeed() { return m_playSpeed; }
303 void SetCaching(ECacheState state);
305 int64_t GetTotalTimeInMsec();
307 double GetQueueTime();
308 bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
311 void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
313 void HandleMessages();
314 void HandlePlaySpeed();
315 bool IsInMenu() const;
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);
328 bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
329 bool IsValidStream(CCurrentStream& stream);
330 bool IsBetterStream(CCurrentStream& current, CDemuxStream* stream);
331 bool CheckDelayedChannelEntry(void);
333 bool OpenInputStream();
334 bool OpenDemuxStream();
335 void OpenDefaultStreams(bool reset = true);
337 void UpdateApplication(double timeout);
338 void UpdatePlayState(double timeout);
339 double m_UpdateApplication;
341 bool m_bAbortRequest;
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;
347 XbmcThreads::EndTime m_ChannelEntryTimeOut;
350 CCurrentStream m_CurrentAudio;
351 CCurrentStream m_CurrentVideo;
352 CCurrentStream m_CurrentSubtitle;
353 CCurrentStream m_CurrentTeletext;
355 CSelectionStreams m_SelectionStreams;
360 double lastpts; // holds last display pts during ff/rw operations
367 CDVDMessageQueue m_messenger; // thread messenger
369 CDVDPlayerVideo m_dvdPlayerVideo; // video part
370 CDVDPlayerAudio m_dvdPlayerAudio; // audio part
371 CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
372 CDVDTeletextData m_dvdPlayerTeletext; // teletext part
374 CDVDClock m_clock; // master clock
375 CDVDOverlayContainer m_overlayContainer;
377 CDVDInputStream* m_pInputStream; // input stream for current playing file
378 CDVDDemux* m_pDemuxer; // demuxer for current playing file
379 CDVDDemux* m_pSubtitleDemuxer;
381 CStdString m_lastSub;
387 state = DVDSTATE_NORMAL;
388 iSelectedSPUStream = -1;
389 iSelectedAudioStream = -1;
391 iDVDStillStartTime = 0;
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
408 friend class CDVDPlayerVideo;
409 friend class CDVDPlayerAudio;
413 SPlayerState() { Clear(); }
421 time_src = ETIMESOURCE_CLOCK;
422 dts = DVD_NOPTS_VALUE;
439 int player; // source of this data
441 double timestamp; // last time of update
442 double time_offset; // difference between time and pts
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
449 std::string player_state; // full player state
451 int chapter; // current chapter
452 std::string chapter_name; // name of current chapter
453 int chapter_count;// number of chapter
455 bool canrecord; // can input stream record
456 bool recording; // are we currently recording
458 bool canpause; // pvr: can pause the current playing item
459 bool canseek; // pvr: can seek in the current playing item
461 std::string demux_video;
462 std::string demux_audio;
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;
472 CCriticalSection m_critStreamSection; // need to have this lock when switching streams (audio / video)
476 struct SEdlAutoSkipMarkers {
481 commbreak_start = -1;
483 seek_to_start = false;
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
493 } m_EdlAutoSkipMarkers;
495 CPlayerOptions m_PlayerOptions;
500 bool m_DemuxerPausePending;