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 template<typename Filter>
158 SelectionStreams RemoveIf(StreamType type, Filter filter)
160 SelectionStreams streams = Get(type);
161 streams.erase(std::remove_if(streams.begin(), streams.end(), filter), streams.end());
165 void Clear (StreamType type, StreamSource source);
166 int Source (StreamSource source, std::string filename);
168 void Update (SelectionStream& s);
169 void Update (CDVDInputStream* input, CDVDDemux* demuxer);
173 #define DVDPLAYER_AUDIO 1
174 #define DVDPLAYER_VIDEO 2
175 #define DVDPLAYER_SUBTITLE 3
176 #define DVDPLAYER_TELETEXT 4
178 class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
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();
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();
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);
222 virtual int GetAudioStreamCount();
223 virtual int GetAudioStream();
224 virtual void SetAudioStream(int iStream);
226 virtual TextCacheStruct_t* GetTeletextCache();
227 virtual void LoadPage(int p, int sp, unsigned char* buffer);
229 virtual int GetChapterCount();
230 virtual int GetChapter();
231 virtual void GetChapterName(CStdString& strChapterName);
232 virtual int SeekChapter(int iChapter);
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();
241 virtual int GetSourceBitrate();
242 virtual void GetVideoStreamInfo(SPlayerVideoStreamInfo &info);
243 virtual bool GetStreamDetails(CStreamDetails &details);
244 virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
246 virtual CStdString GetPlayerState();
247 virtual bool SetPlayerState(CStdString state);
249 virtual CStdString GetPlayingTitle();
251 virtual bool SwitchChannel(const PVR::CPVRChannel &channel);
252 virtual bool CachePVRStream(void) const;
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
263 virtual bool IsCaching() const { return m_caching == CACHESTATE_FULL || m_caching == CACHESTATE_PVR; }
264 virtual int GetCacheLevel() const ;
266 virtual int OnDVDNavResult(void* pData, int iMessage);
268 friend class CSelectionStreams;
270 class StreamLock : public CSingleLock
273 inline StreamLock(CDVDPlayer* cdvdplayer) : CSingleLock(cdvdplayer->m_critStreamSection) {}
276 virtual void OnStartup();
277 virtual void OnExit();
278 virtual void Process();
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);
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.
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);
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);
301 bool ShowPVRChannelInfo();
303 int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
306 * one of the DVD_PLAYSPEED defines
308 void SetPlaySpeed(int iSpeed);
309 int GetPlaySpeed() { return m_playSpeed; }
310 void SetCaching(ECacheState state);
312 int64_t GetTotalTimeInMsec();
314 double GetQueueTime();
315 bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
318 void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
320 void HandleMessages();
321 void HandlePlaySpeed();
322 bool IsInMenu() const;
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);
335 bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
336 bool IsValidStream(CCurrentStream& stream);
337 bool IsBetterStream(CCurrentStream& current, CDemuxStream* stream);
338 bool CheckDelayedChannelEntry(void);
340 bool OpenInputStream();
341 bool OpenDemuxStream();
342 void OpenDefaultStreams(bool reset = true);
344 void UpdateApplication(double timeout);
345 void UpdatePlayState(double timeout);
346 double m_UpdateApplication;
348 bool m_bAbortRequest;
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;
354 XbmcThreads::EndTime m_ChannelEntryTimeOut;
357 CCurrentStream m_CurrentAudio;
358 CCurrentStream m_CurrentVideo;
359 CCurrentStream m_CurrentSubtitle;
360 CCurrentStream m_CurrentTeletext;
362 CSelectionStreams m_SelectionStreams;
367 double lastpts; // holds last display pts during ff/rw operations
374 CDVDMessageQueue m_messenger; // thread messenger
376 CDVDPlayerVideo m_dvdPlayerVideo; // video part
377 CDVDPlayerAudio m_dvdPlayerAudio; // audio part
378 CDVDPlayerSubtitle m_dvdPlayerSubtitle; // subtitle part
379 CDVDTeletextData m_dvdPlayerTeletext; // teletext part
381 CDVDClock m_clock; // master clock
382 CDVDOverlayContainer m_overlayContainer;
384 CDVDInputStream* m_pInputStream; // input stream for current playing file
385 CDVDDemux* m_pDemuxer; // demuxer for current playing file
386 CDVDDemux* m_pSubtitleDemuxer;
388 CStdString m_lastSub;
394 state = DVDSTATE_NORMAL;
395 iSelectedSPUStream = -1;
396 iSelectedAudioStream = -1;
398 iDVDStillStartTime = 0;
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
415 friend class CDVDPlayerVideo;
416 friend class CDVDPlayerAudio;
420 SPlayerState() { Clear(); }
428 time_src = ETIMESOURCE_CLOCK;
429 dts = DVD_NOPTS_VALUE;
446 int player; // source of this data
448 double timestamp; // last time of update
449 double time_offset; // difference between time and pts
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
456 std::string player_state; // full player state
458 int chapter; // current chapter
459 std::string chapter_name; // name of current chapter
460 int chapter_count;// number of chapter
462 bool canrecord; // can input stream record
463 bool recording; // are we currently recording
465 bool canpause; // pvr: can pause the current playing item
466 bool canseek; // pvr: can seek in the current playing item
468 std::string demux_video;
469 std::string demux_audio;
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;
479 CCriticalSection m_critStreamSection; // need to have this lock when switching streams (audio / video)
483 struct SEdlAutoSkipMarkers {
488 commbreak_start = -1;
490 seek_to_start = false;
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
500 } m_EdlAutoSkipMarkers;
502 CPlayerOptions m_PlayerOptions;
507 bool m_DemuxerPausePending;