Merge pull request #26350 from jjd-uk/estuary_media_align
[xbmc.git] / xbmc / cores / VideoPlayer / VideoPlayer.h
blob154650583000e43f4bb7eae4246dff0c03ee485a
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #pragma once
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"
28 #include <atomic>
29 #include <chrono>
30 #include <memory>
31 #include <unordered_map>
32 #include <utility>
33 #include <vector>
35 struct SPlayerState
37 SPlayerState() { Clear(); }
38 void Clear()
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;
63 double timestamp; // last time of update
64 double lastSeek; // time of last seek
65 double time_offset; // difference between time and pts
67 double time; // current playback time
68 double timeMax;
69 double timeMin;
70 time_t startTime;
71 double dts; // last known dts
73 std::string player_state; // full player state
74 bool isInMenu;
75 MenuType menuType;
76 bool streamsReady;
78 int chapter; // current chapter
79 std::vector<std::pair<std::string, int64_t>> chapters; // name and position for chapters
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;
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
92 class CDVDInputStream;
94 class CDVDDemux;
95 class CDemuxStreamVideo;
96 class CDemuxStreamAudio;
97 class CStreamInfo;
98 class CDVDDemuxCC;
99 class CVideoPlayer;
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
106 class CCurrentStream
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;
130 enum
132 AV_SYNC_NONE,
133 AV_SYNC_CHECK,
134 AV_SYNC_CONT,
135 AV_SYNC_FORCE
136 } avsync;
138 CCurrentStream(StreamType t, int i)
139 : type(t)
140 , player(i)
142 Clear();
145 void Clear()
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;
164 double dts_end()
166 if(dts == DVD_NOPTS_VALUE)
167 return DVD_NOPTS_VALUE;
168 if(dur == DVD_NOPTS_VALUE)
169 return dts;
170 return dts + dur;
174 //------------------------------------------------------------------------------
175 // selection streams
176 //------------------------------------------------------------------------------
177 struct SelectionStream
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 std::string codecDesc;
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 uint32_t fpsScale{0};
202 uint32_t fpsRate{0};
205 class CSelectionStreams
207 public:
208 CSelectionStreams() = default;
210 int TypeIndexOf(StreamType type, int source, int64_t demuxerId, int id) const;
211 int CountTypeOfSource(StreamType type, StreamSource source) const;
212 int CountType(StreamType type) const;
213 SelectionStream& Get(StreamType type, int index);
214 const SelectionStream& Get(StreamType type, int index) const;
215 bool Get(StreamType type, StreamFlags flag, SelectionStream& out);
216 void Clear(StreamType type, StreamSource source);
217 int Source(StreamSource source, const std::string& filename);
218 void Update(SelectionStream& s);
219 void Update(const std::shared_ptr<CDVDInputStream>& input, CDVDDemux* demuxer);
220 void Update(const std::shared_ptr<CDVDInputStream>& input,
221 CDVDDemux* demuxer,
222 const std::string& filename2);
224 std::vector<SelectionStream> Get(StreamType type);
225 template<typename Compare> std::vector<SelectionStream> Get(StreamType type, Compare compare)
227 std::vector<SelectionStream> streams = Get(type);
228 std::stable_sort(streams.begin(), streams.end(), compare);
229 return streams;
232 std::vector<SelectionStream> m_Streams;
234 protected:
235 SelectionStream m_invalid;
238 //------------------------------------------------------------------------------
239 // main class
240 //------------------------------------------------------------------------------
242 struct CacheInfo
244 double level; // current cache level
245 double offset; // percentage of file ahead of current position
246 double time; // estimated playback time of current cached bytes
247 bool valid;
250 class CProcessInfo;
251 class CJobQueue;
253 class CVideoPlayer : public IPlayer, public CThread, public IVideoPlayer,
254 public IDispResource, public IRenderLoop, public IRenderMsg
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(Direction seekDirection) override;
271 void SeekPercentage(float iPercent) override;
272 float GetCachePercentage() const override;
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;
281 * \brief Get the supported menu type
282 * \return The supported menu type
284 MenuType GetSupportedMenuType() const override;
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;
296 * \brief Set the subtitle vertical position,
297 * it depends on current screen resolution
298 * \param value The subtitle position in pixels
299 * \param save If true, the value will be saved to resolution info
301 void SetSubtitleVerticalPosition(const int value, bool save) override;
303 void AddSubtitle(const std::string& strSubPath) override;
305 int GetAudioStreamCount() const override;
306 int GetAudioStream() override;
307 void SetAudioStream(int iStream) override;
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;
314 int GetPrograms(std::vector<ProgramInfo>& programs) override;
315 void SetProgram(int progId) override;
316 int GetProgramsCount() const override;
318 std::shared_ptr<TextCacheStruct_t> GetTeletextCache() override;
319 bool HasTeletextCache() const override;
320 void LoadPage(int p, int sp, unsigned char* buffer) override;
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;
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;
336 void GetAudioStreamInfo(int index, AudioStreamInfo& info) const override;
338 std::string GetPlayerState() override;
339 bool SetPlayerState(const std::string& state) override;
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 GetRects(CRect& source, CRect& dest, CRect& view) const override;
347 unsigned int GetOrientation() const override;
348 void TriggerUpdateResolution() override;
349 bool IsRenderingVideo() const override;
350 bool Supports(EINTERLACEMETHOD method) const override;
351 EINTERLACEMETHOD GetDeinterlacingMethodDefault() const override;
352 bool Supports(ESCALINGMETHOD method) const override;
353 bool Supports(ERENDERFEATURE feature) const override;
355 unsigned int RenderCaptureAlloc() override;
356 void RenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags) override;
357 void RenderCaptureRelease(unsigned int captureId) override;
358 bool RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size) override;
360 // IDispResource interface
361 void OnLostDisplay() override;
362 void OnResetDisplay() override;
364 bool IsCaching() const override;
365 int GetCacheLevel() const override;
367 int OnDiscNavResult(void* pData, int iMessage) override;
368 void GetVideoResolution(unsigned int &width, unsigned int &height) override;
370 CVideoSettings GetVideoSettings() const override;
371 void SetVideoSettings(CVideoSettings& settings) override;
373 void SetUpdateStreamDetails();
375 protected:
376 friend class CSelectionStreams;
378 void OnStartup() override;
379 void OnExit() override;
380 void Process() override;
381 void VideoParamsChange() override;
382 void GetDebugInfo(std::string &audio, std::string &video, std::string &general) override;
383 void UpdateClockSync(bool enabled) override;
384 void UpdateRenderInfo(CRenderInfo &info) override;
385 void UpdateRenderBuffers(int queued, int discard, int free) override;
386 void UpdateGuiRender(bool gui) override;
387 void UpdateVideoRender(bool video) override;
389 void CreatePlayers();
390 void DestroyPlayers();
392 void Prepare();
393 bool OpenStream(CCurrentStream& current, int64_t demuxerId, int iStream, int source, bool reset = true);
394 bool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);
395 bool OpenVideoStream(CDVDStreamInfo& hint, bool reset = true);
396 bool OpenSubtitleStream(const CDVDStreamInfo& hint);
397 bool OpenTeletextStream(CDVDStreamInfo& hint);
398 bool OpenRadioRDSStream(CDVDStreamInfo& hint);
399 bool OpenAudioID3Stream(CDVDStreamInfo& hint);
401 /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
402 * If these are not available, subtitles are disabled.
404 void AdaptForcedSubtitles();
405 bool CloseStream(CCurrentStream& current, bool bWaitForBuffers);
407 bool CheckIsCurrent(const CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg);
408 void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
409 void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
410 void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
411 void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
412 void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
413 void ProcessRadioRDSData(CDemuxStream* pStream, DemuxPacket* pPacket);
414 void ProcessAudioID3Data(CDemuxStream* pStream, DemuxPacket* pPacket);
416 int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "");
419 * \brief Propagate enable stream callbacks to demuxers.
420 * \param current The current stream
421 * \param isEnabled Set to true to enable the stream, otherwise false
423 void SetEnableStream(CCurrentStream& current, bool isEnabled);
425 void SetSubtitleVisibleInternal(bool bVisible);
428 * one of the DVD_PLAYSPEED defines
430 void SetPlaySpeed(int iSpeed);
432 enum ECacheState
434 CACHESTATE_DONE = 0,
435 CACHESTATE_FULL, // player is filling up the demux queue
436 CACHESTATE_INIT, // player is waiting for first packet of each stream
437 CACHESTATE_PLAY, // player is waiting for players to not be stalled
438 CACHESTATE_FLUSH, // temporary state player will choose startup between init or full
441 void SetCaching(ECacheState state);
443 double GetQueueTime();
444 CacheInfo GetCachingTimes();
446 void FlushBuffers(double pts, bool accurate, bool sync);
448 void HandleMessages();
449 void HandlePlaySpeed();
450 bool IsInMenuInternal() const;
451 void SynchronizeDemuxer();
452 void CheckAutoSceneSkip();
453 bool CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket);
454 bool CheckSceneSkip(const CCurrentStream& current);
455 bool CheckPlayerInit(CCurrentStream& current);
456 void UpdateCorrection(DemuxPacket* pkt, double correction);
457 void UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket);
458 IDVDStreamPlayer* GetStreamPlayer(unsigned int player);
459 void SendPlayerMessage(std::shared_ptr<CDVDMsg> pMsg, unsigned int target);
461 bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
462 bool IsValidStream(const CCurrentStream& stream);
463 bool IsBetterStream(const CCurrentStream& current, CDemuxStream* stream);
464 void CheckBetterStream(CCurrentStream& current, CDemuxStream* stream);
465 void CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream);
467 bool OpenInputStream();
468 bool OpenDemuxStream();
469 void CloseDemuxer();
470 void OpenDefaultStreams(bool reset = true);
472 void UpdatePlayState(double timeout);
473 void GetGeneralInfo(std::string& strVideoInfo);
474 int64_t GetUpdatedTime();
475 int64_t GetTime();
476 float GetPercentage();
478 void UpdateContent();
479 void UpdateContentState();
481 void UpdateFileItemStreamDetails(CFileItem& item);
482 int GetPreviousChapter();
484 bool m_players_created;
486 CFileItem m_item;
487 CPlayerOptions m_playerOptions;
488 bool m_bAbortRequest;
489 bool m_error;
490 bool m_bCloseRequest;
492 ECacheState m_caching;
493 XbmcThreads::EndTime<> m_cachingTimer;
495 std::unique_ptr<CProcessInfo> m_processInfo;
497 CCurrentStream m_CurrentAudio;
498 CCurrentStream m_CurrentVideo;
499 CCurrentStream m_CurrentSubtitle;
500 CCurrentStream m_CurrentTeletext;
501 CCurrentStream m_CurrentRadioRDS;
502 CCurrentStream m_CurrentAudioID3;
504 CSelectionStreams m_SelectionStreams;
505 std::vector<ProgramInfo> m_programs;
507 struct SContent
509 mutable CCriticalSection m_section;
510 CSelectionStreams m_selectionStreams;
511 std::vector<ProgramInfo> m_programs;
512 int m_videoIndex{-1};
513 int m_audioIndex{-1};
514 int m_subtitleIndex{-1};
515 } m_content;
517 int m_playSpeed;
518 int m_streamPlayerSpeed;
519 int m_demuxerSpeed = DVD_PLAYSPEED_NORMAL;
520 struct SSpeedState
522 double lastpts{0.0}; // holds last display pts during ff/rw operations
523 int64_t lasttime{0};
524 double lastseekpts{0.0};
525 double lastabstime{0.0};
527 void Reset(double pts)
529 *this = {};
530 if (pts != DVD_NOPTS_VALUE)
532 lastseekpts = pts;
535 } m_SpeedState;
537 double m_offset_pts;
539 CDVDMessageQueue m_messenger;
540 std::unique_ptr<CJobQueue> m_outboundEvents;
542 IDVDStreamPlayerVideo *m_VideoPlayerVideo;
543 IDVDStreamPlayerAudio *m_VideoPlayerAudio;
544 CVideoPlayerSubtitle *m_VideoPlayerSubtitle;
545 CDVDTeletextData *m_VideoPlayerTeletext;
546 CDVDRadioRDSData *m_VideoPlayerRadioRDS;
547 std::unique_ptr<CVideoPlayerAudioID3> m_VideoPlayerAudioID3;
549 CDVDClock m_clock;
550 CDVDOverlayContainer m_overlayContainer;
552 std::shared_ptr<CDVDInputStream> m_pInputStream;
553 std::unique_ptr<CDVDDemux> m_pDemuxer;
554 std::shared_ptr<CDVDDemux> m_pSubtitleDemuxer;
555 std::unordered_map<int64_t, std::shared_ptr<CDVDDemux>> m_subtitleDemuxerMap;
556 std::unique_ptr<CDVDDemuxCC> m_pCCDemuxer;
558 CRenderManager m_renderManager;
560 struct SDVDInfo
562 void Clear()
564 state = DVDSTATE_NORMAL;
565 iSelectedSPUStream = -1;
566 iSelectedAudioStream = -1;
567 iSelectedVideoStream = -1;
568 iDVDStillTime = std::chrono::milliseconds::zero();
569 iDVDStillStartTime = {};
570 syncClock = false;
573 int state; // current dvdstate
574 bool syncClock;
575 std::chrono::milliseconds
576 iDVDStillTime; // total time in ticks we should display the still before continuing
577 std::chrono::time_point<std::chrono::steady_clock>
578 iDVDStillStartTime; // time in ticks when we started the still
579 int iSelectedSPUStream; // mpeg stream id, or -1 if disabled
580 int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
581 int iSelectedVideoStream; // mpeg stream id or angle, -1 if disabled
582 } m_dvd;
584 SPlayerState m_State;
585 mutable CCriticalSection m_StateSection;
586 XbmcThreads::EndTime<> m_syncTimer;
588 CEdl m_Edl;
589 bool m_SkipCommercials;
591 bool m_HasVideo;
592 bool m_HasAudio;
594 bool m_UpdateStreamDetails;
596 std::atomic<bool> m_displayLost;
598 double m_messageQueueTimeSize{0.0};