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.
12 #include "DVDMessageQueue.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"
31 #include <unordered_map>
37 SPlayerState() { Clear(); }
46 dts
= DVD_NOPTS_VALUE
;
49 menuType
= MenuType::NONE
;
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
71 double dts
; // last known dts
73 std::string player_state
; // full player state
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
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
;
95 class CDemuxStreamVideo
;
96 class CDemuxStreamAudio
;
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
109 int64_t demuxerId
; // demuxer's id of current playing stream
110 int id
; // id of current playing stream
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
119 unsigned int packets
;
120 IDVDStreamPlayer::ESyncState syncState
;
124 const StreamType type
;
126 // stuff to handle starting after seek
138 CCurrentStream(StreamType t
, int i
)
149 source
= STREAM_SOURCE_NONE
;
150 dts
= DVD_NOPTS_VALUE
;
151 dur
= DVD_NOPTS_VALUE
;
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
;
166 if(dts
== DVD_NOPTS_VALUE
)
167 return DVD_NOPTS_VALUE
;
168 if(dur
== DVD_NOPTS_VALUE
)
174 //------------------------------------------------------------------------------
176 //------------------------------------------------------------------------------
177 struct SelectionStream
179 StreamType type
= STREAM_NONE
;
181 std::string filename
;
182 std::string filename2
; // for vobsub subtitles, 2 files are necessary (idx/sub)
183 std::string language
;
185 StreamFlags flags
= StreamFlags::FLAG_NONE
;
188 int64_t demuxerId
= -1;
190 std::string codecDesc
;
198 std::string stereo_mode
;
199 float aspect_ratio
= 0.0f
;
200 StreamHdrType hdrType
= StreamHdrType::HDR_TYPE_NONE
;
201 uint32_t fpsScale
{0};
205 class CSelectionStreams
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
,
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
);
232 std::vector
<SelectionStream
> m_Streams
;
235 SelectionStream m_invalid
;
238 //------------------------------------------------------------------------------
240 //------------------------------------------------------------------------------
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
253 class CVideoPlayer
: public IPlayer
, public CThread
, public IVideoPlayer
,
254 public IDispResource
, public IRenderLoop
, public IRenderMsg
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();
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();
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
);
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();
470 void OpenDefaultStreams(bool reset
= true);
472 void UpdatePlayState(double timeout
);
473 void GetGeneralInfo(std::string
& strVideoInfo
);
474 int64_t GetUpdatedTime();
476 float GetPercentage();
478 void UpdateContent();
479 void UpdateContentState();
481 void UpdateFileItemStreamDetails(CFileItem
& item
);
482 int GetPreviousChapter();
484 bool m_players_created
;
487 CPlayerOptions m_playerOptions
;
488 bool m_bAbortRequest
;
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
;
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};
518 int m_streamPlayerSpeed
;
519 int m_demuxerSpeed
= DVD_PLAYSPEED_NORMAL
;
522 double lastpts
{0.0}; // holds last display pts during ff/rw operations
524 double lastseekpts
{0.0};
525 double lastabstime
{0.0};
527 void Reset(double pts
)
530 if (pts
!= DVD_NOPTS_VALUE
)
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
;
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
;
564 state
= DVDSTATE_NORMAL
;
565 iSelectedSPUStream
= -1;
566 iSelectedAudioStream
= -1;
567 iSelectedVideoStream
= -1;
568 iDVDStillTime
= std::chrono::milliseconds::zero();
569 iDVDStillStartTime
= {};
573 int state
; // current dvdstate
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
584 SPlayerState m_State
;
585 mutable CCriticalSection m_StateSection
;
586 XbmcThreads::EndTime
<> m_syncTimer
;
589 bool m_SkipCommercials
;
594 bool m_UpdateStreamDetails
;
596 std::atomic
<bool> m_displayLost
;
598 double m_messageQueueTimeSize
{0.0};