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