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;
197 std::string stereo_mode
;
198 float aspect_ratio
= 0.0f
;
199 StreamHdrType hdrType
= StreamHdrType::HDR_TYPE_NONE
;
202 class CSelectionStreams
205 CSelectionStreams() = default;
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
,
219 const std::string
& filename2
);
221 std::vector
<SelectionStream
> Get(StreamType type
);
222 template<typename Compare
> std::vector
<SelectionStream
> Get(StreamType type
, Compare compare
)
224 std::vector
<SelectionStream
> streams
= Get(type
);
225 std::stable_sort(streams
.begin(), streams
.end(), compare
);
229 std::vector
<SelectionStream
> m_Streams
;
232 SelectionStream m_invalid
;
235 //------------------------------------------------------------------------------
237 //------------------------------------------------------------------------------
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
250 class CVideoPlayer
: public IPlayer
, public CThread
, public IVideoPlayer
,
251 public IDispResource
, public IRenderLoop
, public IRenderMsg
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
;
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
;
278 * \brief Get the supported menu type
279 * \return The supported menu type
281 MenuType
GetSupportedMenuType() const override
;
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
;
293 * \brief Set the subtitle vertical position,
294 * it depends on current screen resolution
295 * \param value The subtitle position in pixels
296 * \param save If true, the value will be saved to resolution info
298 void SetSubtitleVerticalPosition(const int value
, bool save
) override
;
300 void AddSubtitle(const std::string
& strSubPath
) override
;
302 int GetAudioStreamCount() const override
;
303 int GetAudioStream() override
;
304 void SetAudioStream(int iStream
) override
;
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
;
311 int GetPrograms(std::vector
<ProgramInfo
>& programs
) override
;
312 void SetProgram(int progId
) override
;
313 int GetProgramsCount() const override
;
315 std::shared_ptr
<TextCacheStruct_t
> GetTeletextCache() override
;
316 bool HasTeletextCache() const override
;
317 void LoadPage(int p
, int sp
, unsigned char* buffer
) override
;
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
;
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
;
333 void GetAudioStreamInfo(int index
, AudioStreamInfo
& info
) const override
;
335 std::string
GetPlayerState() override
;
336 bool SetPlayerState(const std::string
& state
) override
;
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 void TriggerUpdateResolution() override
;
345 bool IsRenderingVideo() const override
;
346 bool Supports(EINTERLACEMETHOD method
) const override
;
347 EINTERLACEMETHOD
GetDeinterlacingMethodDefault() const override
;
348 bool Supports(ESCALINGMETHOD method
) const override
;
349 bool Supports(ERENDERFEATURE feature
) const override
;
351 unsigned int RenderCaptureAlloc() override
;
352 void RenderCapture(unsigned int captureId
, unsigned int width
, unsigned int height
, int flags
) override
;
353 void RenderCaptureRelease(unsigned int captureId
) override
;
354 bool RenderCaptureGetPixels(unsigned int captureId
, unsigned int millis
, uint8_t *buffer
, unsigned int size
) override
;
356 // IDispResource interface
357 void OnLostDisplay() override
;
358 void OnResetDisplay() override
;
360 bool IsCaching() const override
;
361 int GetCacheLevel() const override
;
363 int OnDiscNavResult(void* pData
, int iMessage
) override
;
364 void GetVideoResolution(unsigned int &width
, unsigned int &height
) override
;
366 CVideoSettings
GetVideoSettings() const override
;
367 void SetVideoSettings(CVideoSettings
& settings
) override
;
369 void SetUpdateStreamDetails();
372 friend class CSelectionStreams
;
374 void OnStartup() override
;
375 void OnExit() override
;
376 void Process() override
;
377 void VideoParamsChange() override
;
378 void GetDebugInfo(std::string
&audio
, std::string
&video
, std::string
&general
) override
;
379 void UpdateClockSync(bool enabled
) override
;
380 void UpdateRenderInfo(CRenderInfo
&info
) override
;
381 void UpdateRenderBuffers(int queued
, int discard
, int free
) override
;
382 void UpdateGuiRender(bool gui
) override
;
383 void UpdateVideoRender(bool video
) override
;
385 void CreatePlayers();
386 void DestroyPlayers();
389 bool OpenStream(CCurrentStream
& current
, int64_t demuxerId
, int iStream
, int source
, bool reset
= true);
390 bool OpenAudioStream(CDVDStreamInfo
& hint
, bool reset
= true);
391 bool OpenVideoStream(CDVDStreamInfo
& hint
, bool reset
= true);
392 bool OpenSubtitleStream(const CDVDStreamInfo
& hint
);
393 bool OpenTeletextStream(CDVDStreamInfo
& hint
);
394 bool OpenRadioRDSStream(CDVDStreamInfo
& hint
);
395 bool OpenAudioID3Stream(CDVDStreamInfo
& hint
);
397 /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
398 * If these are not available, subtitles are disabled.
400 void AdaptForcedSubtitles();
401 bool CloseStream(CCurrentStream
& current
, bool bWaitForBuffers
);
403 bool CheckIsCurrent(const CCurrentStream
& current
, CDemuxStream
* stream
, DemuxPacket
* pkg
);
404 void ProcessPacket(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
405 void ProcessAudioData(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
406 void ProcessVideoData(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
407 void ProcessSubData(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
408 void ProcessTeletextData(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
409 void ProcessRadioRDSData(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
410 void ProcessAudioID3Data(CDemuxStream
* pStream
, DemuxPacket
* pPacket
);
412 int AddSubtitleFile(const std::string
& filename
, const std::string
& subfilename
= "");
415 * \brief Propagate enable stream callbacks to demuxers.
416 * \param current The current stream
417 * \param isEnabled Set to true to enable the stream, otherwise false
419 void SetEnableStream(CCurrentStream
& current
, bool isEnabled
);
421 void SetSubtitleVisibleInternal(bool bVisible
);
424 * one of the DVD_PLAYSPEED defines
426 void SetPlaySpeed(int iSpeed
);
431 CACHESTATE_FULL
, // player is filling up the demux queue
432 CACHESTATE_INIT
, // player is waiting for first packet of each stream
433 CACHESTATE_PLAY
, // player is waiting for players to not be stalled
434 CACHESTATE_FLUSH
, // temporary state player will choose startup between init or full
437 void SetCaching(ECacheState state
);
439 double GetQueueTime();
440 CacheInfo
GetCachingTimes();
442 void FlushBuffers(double pts
, bool accurate
, bool sync
);
444 void HandleMessages();
445 void HandlePlaySpeed();
446 bool IsInMenuInternal() const;
447 void SynchronizeDemuxer();
448 void CheckAutoSceneSkip();
449 bool CheckContinuity(CCurrentStream
& current
, DemuxPacket
* pPacket
);
450 bool CheckSceneSkip(const CCurrentStream
& current
);
451 bool CheckPlayerInit(CCurrentStream
& current
);
452 void UpdateCorrection(DemuxPacket
* pkt
, double correction
);
453 void UpdateTimestamps(CCurrentStream
& current
, DemuxPacket
* pPacket
);
454 IDVDStreamPlayer
* GetStreamPlayer(unsigned int player
);
455 void SendPlayerMessage(std::shared_ptr
<CDVDMsg
> pMsg
, unsigned int target
);
457 bool ReadPacket(DemuxPacket
*& packet
, CDemuxStream
*& stream
);
458 bool IsValidStream(const CCurrentStream
& stream
);
459 bool IsBetterStream(const CCurrentStream
& current
, CDemuxStream
* stream
);
460 void CheckBetterStream(CCurrentStream
& current
, CDemuxStream
* stream
);
461 void CheckStreamChanges(CCurrentStream
& current
, CDemuxStream
* stream
);
463 bool OpenInputStream();
464 bool OpenDemuxStream();
466 void OpenDefaultStreams(bool reset
= true);
468 void UpdatePlayState(double timeout
);
469 void GetGeneralInfo(std::string
& strVideoInfo
);
470 int64_t GetUpdatedTime();
472 float GetPercentage();
474 void UpdateContent();
475 void UpdateContentState();
477 void UpdateFileItemStreamDetails(CFileItem
& item
);
478 int GetPreviousChapter();
480 bool m_players_created
;
483 CPlayerOptions m_playerOptions
;
484 bool m_bAbortRequest
;
486 bool m_bCloseRequest
;
488 ECacheState m_caching
;
489 XbmcThreads::EndTime
<> m_cachingTimer
;
491 std::unique_ptr
<CProcessInfo
> m_processInfo
;
493 CCurrentStream m_CurrentAudio
;
494 CCurrentStream m_CurrentVideo
;
495 CCurrentStream m_CurrentSubtitle
;
496 CCurrentStream m_CurrentTeletext
;
497 CCurrentStream m_CurrentRadioRDS
;
498 CCurrentStream m_CurrentAudioID3
;
500 CSelectionStreams m_SelectionStreams
;
501 std::vector
<ProgramInfo
> m_programs
;
505 mutable CCriticalSection m_section
;
506 CSelectionStreams m_selectionStreams
;
507 std::vector
<ProgramInfo
> m_programs
;
508 int m_videoIndex
{-1};
509 int m_audioIndex
{-1};
510 int m_subtitleIndex
{-1};
514 int m_streamPlayerSpeed
;
515 int m_demuxerSpeed
= DVD_PLAYSPEED_NORMAL
;
518 double lastpts
{0.0}; // holds last display pts during ff/rw operations
520 double lastseekpts
{0.0};
521 double lastabstime
{0.0};
523 void Reset(double pts
)
526 if (pts
!= DVD_NOPTS_VALUE
)
535 CDVDMessageQueue m_messenger
;
536 std::unique_ptr
<CJobQueue
> m_outboundEvents
;
538 IDVDStreamPlayerVideo
*m_VideoPlayerVideo
;
539 IDVDStreamPlayerAudio
*m_VideoPlayerAudio
;
540 CVideoPlayerSubtitle
*m_VideoPlayerSubtitle
;
541 CDVDTeletextData
*m_VideoPlayerTeletext
;
542 CDVDRadioRDSData
*m_VideoPlayerRadioRDS
;
543 std::unique_ptr
<CVideoPlayerAudioID3
> m_VideoPlayerAudioID3
;
546 CDVDOverlayContainer m_overlayContainer
;
548 std::shared_ptr
<CDVDInputStream
> m_pInputStream
;
549 std::unique_ptr
<CDVDDemux
> m_pDemuxer
;
550 std::shared_ptr
<CDVDDemux
> m_pSubtitleDemuxer
;
551 std::unordered_map
<int64_t, std::shared_ptr
<CDVDDemux
>> m_subtitleDemuxerMap
;
552 std::unique_ptr
<CDVDDemuxCC
> m_pCCDemuxer
;
554 CRenderManager m_renderManager
;
560 state
= DVDSTATE_NORMAL
;
561 iSelectedSPUStream
= -1;
562 iSelectedAudioStream
= -1;
563 iSelectedVideoStream
= -1;
564 iDVDStillTime
= std::chrono::milliseconds::zero();
565 iDVDStillStartTime
= {};
569 int state
; // current dvdstate
571 std::chrono::milliseconds
572 iDVDStillTime
; // total time in ticks we should display the still before continuing
573 std::chrono::time_point
<std::chrono::steady_clock
>
574 iDVDStillStartTime
; // time in ticks when we started the still
575 int iSelectedSPUStream
; // mpeg stream id, or -1 if disabled
576 int iSelectedAudioStream
; // mpeg stream id, or -1 if disabled
577 int iSelectedVideoStream
; // mpeg stream id or angle, -1 if disabled
580 SPlayerState m_State
;
581 mutable CCriticalSection m_StateSection
;
582 XbmcThreads::EndTime
<> m_syncTimer
;
585 bool m_SkipCommercials
;
590 bool m_UpdateStreamDetails
;
592 std::atomic
<bool> m_displayLost
;