xbmc
VideoPlayer.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "DVDClock.h"
12 #include "DVDMessageQueue.h"
13 #include "Edl.h"
14 #include "FileItem.h"
15 #include "IVideoPlayer.h"
16 #include "VideoPlayerAudioID3.h"
17 #include "VideoPlayerRadioRDS.h"
18 #include "VideoPlayerSubtitle.h"
19 #include "VideoPlayerTeletext.h"
20 #include "cores/IPlayer.h"
21 #include "cores/MenuType.h"
22 #include "cores/VideoPlayer/Interface/TimingConstants.h"
23 #include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
24 #include "guilib/DispResource.h"
25 #include "threads/SystemClock.h"
26 #include "threads/Thread.h"
27 
28 #include <atomic>
29 #include <chrono>
30 #include <memory>
31 #include <unordered_map>
32 #include <utility>
33 #include <vector>
34 
36 {
37  SPlayerState() { Clear(); }
38  void Clear()
39  {
40  timestamp = 0;
41  time = 0;
42  startTime = 0;
43  timeMin = 0;
44  timeMax = 0;
45  time_offset = 0;
46  dts = DVD_NOPTS_VALUE;
47  player_state = "";
48  isInMenu = false;
49  menuType = MenuType::NONE;
50  chapter = 0;
51  chapters.clear();
52  canpause = false;
53  canseek = false;
54  cantempo = false;
55  caching = false;
56  cache_bytes = 0;
57  cache_level = 0.0;
58  cache_delay = 0.0;
59  cache_offset = 0.0;
60  lastSeek = 0;
61  streamsReady = false;
62  }
63 
64  double timestamp; // last time of update
65  double lastSeek; // time of last seek
66  double time_offset; // difference between time and pts
67 
68  double time; // current playback time
69  double timeMax;
70  double timeMin;
71  time_t startTime;
72  double dts; // last known dts
73 
74  std::string player_state; // full player state
75  bool isInMenu;
76  MenuType menuType;
77  bool streamsReady;
78 
79  int chapter; // current chapter
80  std::vector<std::pair<std::string, int64_t>> chapters; // name and position for chapters
81 
82  bool canpause; // pvr: can pause the current playing item
83  bool canseek; // pvr: can seek in the current playing item
84  bool cantempo;
85  bool caching;
86 
87  int64_t cache_bytes; // number of bytes current's cached
88  double cache_level; // current estimated required cache level
89  double cache_delay; // time until cache is expected to reach estimated level
90  double cache_offset; // percentage of file ahead of current position
91  double cache_time; // estimated playback time of current cached bytes
92 };
93 
94 class CDVDInputStream;
95 
96 class CDVDDemux;
97 class CDemuxStreamVideo;
98 class CDemuxStreamAudio;
99 class CStreamInfo;
100 class CDVDDemuxCC;
101 class CVideoPlayer;
102 
103 #define DVDSTATE_NORMAL 0x00000001 // normal dvd state
104 #define DVDSTATE_STILL 0x00000002 // currently displaying a still frame
105 #define DVDSTATE_WAIT 0x00000003 // waiting for demuxer read error
106 #define DVDSTATE_SEEK 0x00000004 // we are finishing a seek request
107 
109 {
110 public:
111  int64_t demuxerId; // demuxer's id of current playing stream
112  int id; // id of current playing stream
113  int source;
114  double dts; // last dts from demuxer, used to find discontinuities
115  double dur; // last frame expected duration
116  int dispTime; // display time from input stream
117  CDVDStreamInfo hint; // stream hints, used to notice stream changes
118  void* stream; // pointer or integer, identifying stream playing. if it changes stream changed
119  int changes; // remembered counter from stream to track codec changes
120  bool inited;
121  unsigned int packets;
122  IDVDStreamPlayer::ESyncState syncState;
123  double starttime;
124  double cachetime;
125  double cachetotal;
126  const StreamType type;
127  const int player;
128  // stuff to handle starting after seek
129  double startpts;
130  double lastdts;
131 
132  enum
133  {
134  AV_SYNC_NONE,
135  AV_SYNC_CHECK,
136  AV_SYNC_CONT,
137  AV_SYNC_FORCE
138  } avsync;
139 
140  CCurrentStream(StreamType t, int i)
141  : type(t)
142  , player(i)
143  {
144  Clear();
145  }
146 
147  void Clear()
148  {
149  id = -1;
150  demuxerId = -1;
151  source = STREAM_SOURCE_NONE;
152  dts = DVD_NOPTS_VALUE;
153  dur = DVD_NOPTS_VALUE;
154  hint.Clear();
155  stream = NULL;
156  changes = 0;
157  inited = false;
158  packets = 0;
159  syncState = IDVDStreamPlayer::SYNC_STARTING;
160  starttime = DVD_NOPTS_VALUE;
161  startpts = DVD_NOPTS_VALUE;
162  lastdts = DVD_NOPTS_VALUE;
163  avsync = AV_SYNC_FORCE;
164  }
165 
166  double dts_end()
167  {
168  if(dts == DVD_NOPTS_VALUE)
169  return DVD_NOPTS_VALUE;
170  if(dur == DVD_NOPTS_VALUE)
171  return dts;
172  return dts + dur;
173  }
174 };
175 
176 //------------------------------------------------------------------------------
177 // selection streams
178 //------------------------------------------------------------------------------
180 {
181  StreamType type = STREAM_NONE;
182  int type_index = 0;
183  std::string filename;
184  std::string filename2; // for vobsub subtitles, 2 files are necessary (idx/sub)
185  std::string language;
186  std::string name;
187  StreamFlags flags = StreamFlags::FLAG_NONE;
188  int source = 0;
189  int id = 0;
190  int64_t demuxerId = -1;
191  std::string codec;
192  int channels = 0;
193  int bitrate = 0;
194  int width = 0;
195  int height = 0;
196  CRect SrcRect;
197  CRect DestRect;
198  CRect VideoRect;
199  std::string stereo_mode;
200  float aspect_ratio = 0.0f;
201  StreamHdrType hdrType = StreamHdrType::HDR_TYPE_NONE;
202 };
203 
205 {
206 public:
207  CSelectionStreams() = default;
208 
209  int TypeIndexOf(StreamType type, int source, int64_t demuxerId, int id) const;
210  int CountTypeOfSource(StreamType type, StreamSource source) const;
211  int CountType(StreamType type) const;
212  SelectionStream& Get(StreamType type, int index);
213  const SelectionStream& Get(StreamType type, int index) const;
214  bool Get(StreamType type, StreamFlags flag, SelectionStream& out);
215  void Clear(StreamType type, StreamSource source);
216  int Source(StreamSource source, const std::string& filename);
217  void Update(SelectionStream& s);
218  void Update(const std::shared_ptr<CDVDInputStream>& input, CDVDDemux* demuxer);
219  void Update(const std::shared_ptr<CDVDInputStream>& input,
220  CDVDDemux* demuxer,
221  const std::string& filename2);
222 
223  std::vector<SelectionStream> Get(StreamType type);
224  template<typename Compare> std::vector<SelectionStream> Get(StreamType type, Compare compare)
225  {
226  std::vector<SelectionStream> streams = Get(type);
227  std::stable_sort(streams.begin(), streams.end(), compare);
228  return streams;
229  }
230 
231  std::vector<SelectionStream> m_Streams;
232 
233 protected:
234  SelectionStream m_invalid;
235 };
236 
237 //------------------------------------------------------------------------------
238 // main class
239 //------------------------------------------------------------------------------
240 
241 struct CacheInfo
242 {
243  double level; // current estimated required cache level
244  double delay; // time until cache is expected to reach estimated level
245  double offset; // percentage of file ahead of current position
246  double time; // estimated playback time of current cached bytes
247  bool valid;
248 };
249 
250 class CProcessInfo;
251 class CJobQueue;
252 
253 class CVideoPlayer : public IPlayer, public CThread, public IVideoPlayer,
254  public IDispResource, public IRenderLoop, public IRenderMsg
255 {
256 public:
257  explicit CVideoPlayer(IPlayerCallback& callback);
258  ~CVideoPlayer() override;
259  bool OpenFile(const CFileItem& file, const CPlayerOptions &options) override;
260  bool CloseFile(bool reopen = false) override;
261  bool IsPlaying() const override;
262  void Pause() override;
263  bool HasVideo() const override;
264  bool HasAudio() const override;
265  bool HasRDS() const override;
266  bool HasID3() const override;
267  bool IsPassthrough() const override;
268  bool CanSeek() const override;
269  void Seek(bool bPlus, bool bLargeStep, bool bChapterOverride) override;
270  bool SeekScene(bool bPlus = true) override;
271  void SeekPercentage(float iPercent) override;
272  float GetCachePercentage() const override;
273 
274  void SetDynamicRangeCompression(long drc) override;
275  bool CanPause() const override;
276  void SetAVDelay(float fValue = 0.0f) override;
277  float GetAVDelay() override;
278  bool IsInMenu() const override;
279 
284  MenuType GetSupportedMenuType() const override;
285 
286  void SetSubTitleDelay(float fValue = 0.0f) override;
287  float GetSubTitleDelay() override;
288  int GetSubtitleCount() const override;
289  int GetSubtitle() override;
290  void GetSubtitleStreamInfo(int index, SubtitleStreamInfo& info) const override;
291  void SetSubtitle(int iStream) override;
292  bool GetSubtitleVisible() const override;
293  void SetSubtitleVisible(bool bVisible) override;
294 
301  void SetSubtitleVerticalPosition(const int value, bool save) override;
302 
303  void AddSubtitle(const std::string& strSubPath) override;
304 
305  int GetAudioStreamCount() const override;
306  int GetAudioStream() override;
307  void SetAudioStream(int iStream) override;
308 
309  int GetVideoStream() const override;
310  int GetVideoStreamCount() const override;
311  void GetVideoStreamInfo(int streamId, VideoStreamInfo& info) const override;
312  void SetVideoStream(int iStream) override;
313 
314  int GetPrograms(std::vector<ProgramInfo>& programs) override;
315  void SetProgram(int progId) override;
316  int GetProgramsCount() const override;
317 
318  std::shared_ptr<TextCacheStruct_t> GetTeletextCache() override;
319  bool HasTeletextCache() const override;
320  void LoadPage(int p, int sp, unsigned char* buffer) override;
321 
322  int GetChapterCount() const override;
323  int GetChapter() const override;
324  void GetChapterName(std::string& strChapterName, int chapterIdx = -1) const override;
325  int64_t GetChapterPos(int chapterIdx = -1) const override;
326  int SeekChapter(int iChapter) override;
327 
328  void SeekTime(int64_t iTime) override;
329  bool SeekTimeRelative(int64_t iTime) override;
330  void SetSpeed(float speed) override;
331  void SetTempo(float tempo) override;
332  bool SupportsTempo() const override;
333  void FrameAdvance(int frames) override;
334  bool OnAction(const CAction &action) override;
335 
336  void GetAudioStreamInfo(int index, AudioStreamInfo& info) const override;
337 
338  std::string GetPlayerState() override;
339  bool SetPlayerState(const std::string& state) override;
340 
341  void FrameMove() override;
342  void Render(bool clear, uint32_t alpha = 255, bool gui = true) override;
343  void FlushRenderer() override;
344  void SetRenderViewMode(int mode, float zoom, float par, float shift, bool stretch) override;
345  float GetRenderAspectRatio() const override;
346  void TriggerUpdateResolution() override;
347  bool IsRenderingVideo() const override;
348  bool Supports(EINTERLACEMETHOD method) const override;
349  EINTERLACEMETHOD GetDeinterlacingMethodDefault() const override;
350  bool Supports(ESCALINGMETHOD method) const override;
351  bool Supports(ERENDERFEATURE feature) const override;
352 
353  unsigned int RenderCaptureAlloc() override;
354  void RenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags) override;
355  void RenderCaptureRelease(unsigned int captureId) override;
356  bool RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size) override;
357 
358  // IDispResource interface
359  void OnLostDisplay() override;
360  void OnResetDisplay() override;
361 
362  bool IsCaching() const override;
363  int GetCacheLevel() const override;
364 
365  int OnDiscNavResult(void* pData, int iMessage) override;
366  void GetVideoResolution(unsigned int &width, unsigned int &height) override;
367 
368  CVideoSettings GetVideoSettings() const override;
369  void SetVideoSettings(CVideoSettings& settings) override;
370 
371  void SetUpdateStreamDetails();
372 
373 protected:
374  friend class CSelectionStreams;
375 
376  void OnStartup() override;
377  void OnExit() override;
378  void Process() override;
379  void VideoParamsChange() override;
380  void GetDebugInfo(std::string &audio, std::string &video, std::string &general) override;
381  void UpdateClockSync(bool enabled) override;
382  void UpdateRenderInfo(CRenderInfo &info) override;
383  void UpdateRenderBuffers(int queued, int discard, int free) override;
384  void UpdateGuiRender(bool gui) override;
385  void UpdateVideoRender(bool video) override;
386 
387  void CreatePlayers();
388  void DestroyPlayers();
389 
390  void Prepare();
391  bool OpenStream(CCurrentStream& current, int64_t demuxerId, int iStream, int source, bool reset = true);
392  bool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);
393  bool OpenVideoStream(CDVDStreamInfo& hint, bool reset = true);
394  bool OpenSubtitleStream(const CDVDStreamInfo& hint);
395  bool OpenTeletextStream(CDVDStreamInfo& hint);
396  bool OpenRadioRDSStream(CDVDStreamInfo& hint);
397  bool OpenAudioID3Stream(CDVDStreamInfo& hint);
398 
402  void AdaptForcedSubtitles();
403  bool CloseStream(CCurrentStream& current, bool bWaitForBuffers);
404 
405  bool CheckIsCurrent(const CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg);
406  void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
407  void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
408  void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
409  void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
410  void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
411  void ProcessRadioRDSData(CDemuxStream* pStream, DemuxPacket* pPacket);
412  void ProcessAudioID3Data(CDemuxStream* pStream, DemuxPacket* pPacket);
413 
414  int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "");
415  void SetSubtitleVisibleInternal(bool bVisible);
416 
420  void SetPlaySpeed(int iSpeed);
421 
422  enum ECacheState
423  {
424  CACHESTATE_DONE = 0,
425  CACHESTATE_FULL, // player is filling up the demux queue
426  CACHESTATE_INIT, // player is waiting for first packet of each stream
427  CACHESTATE_PLAY, // player is waiting for players to not be stalled
428  CACHESTATE_FLUSH, // temporary state player will choose startup between init or full
429  };
430 
431  void SetCaching(ECacheState state);
432 
433  double GetQueueTime();
434  CacheInfo GetCachingTimes();
435 
436  void FlushBuffers(double pts, bool accurate, bool sync);
437 
438  void HandleMessages();
439  void HandlePlaySpeed();
440  bool IsInMenuInternal() const;
441  void SynchronizeDemuxer();
442  void CheckAutoSceneSkip();
443  bool CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket);
444  bool CheckSceneSkip(const CCurrentStream& current);
445  bool CheckPlayerInit(CCurrentStream& current);
446  void UpdateCorrection(DemuxPacket* pkt, double correction);
447  void UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket);
448  IDVDStreamPlayer* GetStreamPlayer(unsigned int player);
449  void SendPlayerMessage(std::shared_ptr<CDVDMsg> pMsg, unsigned int target);
450 
451  bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
452  bool IsValidStream(const CCurrentStream& stream);
453  bool IsBetterStream(const CCurrentStream& current, CDemuxStream* stream);
454  void CheckBetterStream(CCurrentStream& current, CDemuxStream* stream);
455  void CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream);
456 
457  bool OpenInputStream();
458  bool OpenDemuxStream();
459  void CloseDemuxer();
460  void OpenDefaultStreams(bool reset = true);
461 
462  void UpdatePlayState(double timeout);
463  void GetGeneralInfo(std::string& strVideoInfo);
464  int64_t GetUpdatedTime();
465  int64_t GetTime();
466  float GetPercentage();
467 
468  void UpdateContent();
469  void UpdateContentState();
470 
471  void UpdateFileItemStreamDetails(CFileItem& item);
472 
473  bool m_players_created;
474 
475  CFileItem m_item;
476  CPlayerOptions m_playerOptions;
477  bool m_bAbortRequest;
478  bool m_error;
479  bool m_bCloseRequest;
480 
481  ECacheState m_caching;
482  XbmcThreads::EndTime<> m_cachingTimer;
483 
484  std::unique_ptr<CProcessInfo> m_processInfo;
485 
486  CCurrentStream m_CurrentAudio;
487  CCurrentStream m_CurrentVideo;
488  CCurrentStream m_CurrentSubtitle;
489  CCurrentStream m_CurrentTeletext;
490  CCurrentStream m_CurrentRadioRDS;
491  CCurrentStream m_CurrentAudioID3;
492 
493  CSelectionStreams m_SelectionStreams;
494  std::vector<ProgramInfo> m_programs;
495 
496  struct SContent
497  {
498  mutable CCriticalSection m_section;
499  CSelectionStreams m_selectionStreams;
500  std::vector<ProgramInfo> m_programs;
501  int m_videoIndex{-1};
502  int m_audioIndex{-1};
503  int m_subtitleIndex{-1};
504  } m_content;
505 
506  int m_playSpeed;
507  int m_streamPlayerSpeed;
508  int m_demuxerSpeed = DVD_PLAYSPEED_NORMAL;
509  struct SSpeedState
510  {
511  double lastpts; // holds last display pts during ff/rw operations
512  int64_t lasttime;
513  double lastseekpts;
514  double lastabstime;
515  } m_SpeedState;
516 
517  double m_offset_pts;
518 
519  CDVDMessageQueue m_messenger;
520  std::unique_ptr<CJobQueue> m_outboundEvents;
521 
522  IDVDStreamPlayerVideo *m_VideoPlayerVideo;
523  IDVDStreamPlayerAudio *m_VideoPlayerAudio;
524  CVideoPlayerSubtitle *m_VideoPlayerSubtitle;
525  CDVDTeletextData *m_VideoPlayerTeletext;
526  CDVDRadioRDSData *m_VideoPlayerRadioRDS;
527  std::unique_ptr<CVideoPlayerAudioID3> m_VideoPlayerAudioID3;
528 
529  CDVDClock m_clock;
530  CDVDOverlayContainer m_overlayContainer;
531 
532  std::shared_ptr<CDVDInputStream> m_pInputStream;
533  std::unique_ptr<CDVDDemux> m_pDemuxer;
534  std::shared_ptr<CDVDDemux> m_pSubtitleDemuxer;
535  std::unordered_map<int64_t, std::shared_ptr<CDVDDemux>> m_subtitleDemuxerMap;
536  std::unique_ptr<CDVDDemuxCC> m_pCCDemuxer;
537 
538  CRenderManager m_renderManager;
539 
540  struct SDVDInfo
541  {
542  void Clear()
543  {
544  state = DVDSTATE_NORMAL;
545  iSelectedSPUStream = -1;
546  iSelectedAudioStream = -1;
547  iSelectedVideoStream = -1;
548  iDVDStillTime = std::chrono::milliseconds::zero();
549  iDVDStillStartTime = {};
550  syncClock = false;
551  }
552 
553  int state; // current dvdstate
554  bool syncClock;
555  std::chrono::milliseconds
556  iDVDStillTime; // total time in ticks we should display the still before continuing
557  std::chrono::time_point<std::chrono::steady_clock>
558  iDVDStillStartTime; // time in ticks when we started the still
559  int iSelectedSPUStream; // mpeg stream id, or -1 if disabled
560  int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
561  int iSelectedVideoStream; // mpeg stream id or angle, -1 if disabled
562  } m_dvd;
563 
564  SPlayerState m_State;
565  mutable CCriticalSection m_StateSection;
566  XbmcThreads::EndTime<> m_syncTimer;
567 
568  CEdl m_Edl;
569  bool m_SkipCommercials;
570 
571  bool m_HasVideo;
572  bool m_HasAudio;
573 
574  bool m_UpdateStreamDetails;
575 
576  std::atomic<bool> m_displayLost;
577 };
Definition: IVideoPlayer.h:28
Definition: DVDDemux.h:220
Definition: StreamInfo.h:65
Definition: DVDStreamInfo.h:25
Definition: IVideoPlayer.h:36
Definition: VideoPlayer.h:540
Definition: VideoPlayer.h:35
Definition: DispResource.h:26
Definition: VideoPlayer.h:253
Definition: RenderInfo.h:19
Definition: Thread.h:44
Definition: VideoPlayerRadioRDS.h:36
Definition: VideoPlayer.h:496
Definition: DVDInputStream.h:50
Definition: DVDMessageQueue.h:48
Definition: VideoPlayerSubtitle.h:24
Definition: IVideoPlayer.h:75
Definition: VideoPlayer.h:108
Definition: SystemClock.h:31
Definition: StreamInfo.h:55
Definition: DVDDemux.h:156
Definition: VideoPlayer.h:179
Definition: VideoPlayer.h:509
Definition: IPlayer.h:87
Definition: DVDDemux.h:124
Definition: StreamInfo.h:62
Definition: VideoPlayerTeletext.h:18
class encapsulating information regarding a particular user action to be sent to windows and controls...
Definition: Action.h:22
Definition: DispResource.h:14
Definition: RenderManager.h:54
Definition: DVDDemuxCC.h:19
Definition: VideoPlayer.h:204
Definition: ProcessInfo.h:26
Definition: IPlayerCallback.h:18
Definition: Edl.h:18
Definition: settings.py:1
Definition: DVDClock.h:18
Definition: VideoPlayer.h:241
Definition: DVDDemux.h:72
Definition: DemuxPacket.h:22
Definition: DVDOverlayContainer.h:19
Definition: IPlayer.h:31
Definition: VideoSettings.h:194
Definition: IVideoPlayer.h:102
Definition: RenderManager.h:38
Represents a file on a share.
Definition: FileItem.h:102
Job Queue class to handle a queue of unique jobs to be processed sequentially.
Definition: JobManager.h:63