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