kodi
RenderManager.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 "DebugRenderer.h"
13 #include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
14 #include "cores/VideoPlayer/VideoRenderers/OverlayRenderer.h"
15 #include "cores/VideoSettings.h"
16 #include "threads/CriticalSection.h"
17 #include "threads/Event.h"
18 #include "threads/SystemClock.h"
19 #include "utils/Geometry.h"
20 #include "windowing/Resolution.h"
21 
22 #include <atomic>
23 #include <deque>
24 #include <list>
25 #include <map>
26 
27 #include "PlatformDefs.h"
28 
29 class CRenderCapture;
30 struct VideoPicture;
31 
32 class CWinRenderer;
33 class CLinuxRenderer;
34 class CLinuxRendererGL;
35 class CLinuxRendererGLES;
36 class CRenderManager;
37 
39 {
40  friend CRenderManager;
41 public:
42  virtual ~IRenderMsg() = default;
43 protected:
44  virtual void VideoParamsChange() = 0;
45  virtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) = 0;
46  virtual void UpdateClockSync(bool enabled) = 0;
47  virtual void UpdateRenderInfo(CRenderInfo &info) = 0;
48  virtual void UpdateRenderBuffers(int queued, int discard, int free) = 0;
49  virtual void UpdateGuiRender(bool gui) = 0;
50  virtual void UpdateVideoRender(bool video) = 0;
51  virtual CVideoSettings GetVideoSettings() const = 0;
52 };
53 
55 {
56 public:
57  CRenderManager(CDVDClock &clock, IRenderMsg *player);
58  virtual ~CRenderManager();
59 
60  // Functions called from render thread
61  void GetVideoRect(CRect& source, CRect& dest, CRect& view) const;
62  float GetAspectRatio() const;
63  unsigned int GetOrientation() const;
64  void FrameMove();
65  void FrameWait(std::chrono::milliseconds duration);
66  void Render(bool clear, DWORD flags = 0, DWORD alpha = 255, bool gui = true);
67  bool IsVideoLayer();
68  RESOLUTION GetResolution();
69  void UpdateResolution();
70  void TriggerUpdateResolution(float fps, int width, int height, std::string &stereomode);
71  void SetViewMode(int iViewMode);
72  void PreInit();
73  void UnInit();
74  bool Flush(bool wait, bool saveBuffers);
75  bool IsConfigured() const;
76  void ToggleDebug();
77  void ToggleDebugVideo();
78 
85  void SetSubtitleVerticalPosition(const int value, bool save);
86 
87  unsigned int AllocRenderCapture();
88  void ReleaseRenderCapture(unsigned int captureId);
89  void StartRenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags);
90  bool RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size);
91 
92  // Functions called from GUI
93  bool Supports(ERENDERFEATURE feature) const;
94  bool Supports(ESCALINGMETHOD method) const;
95 
96  int GetSkippedFrames() { return m_QueueSkip; }
97 
98  bool Configure(const VideoPicture& picture, float fps, unsigned int orientation, int buffers = 0);
99  bool AddVideoPicture(const VideoPicture& picture, volatile std::atomic_bool& bStop, EINTERLACEMETHOD deintMethod, bool wait);
100  void AddOverlay(std::shared_ptr<CDVDOverlay> o, double pts);
101  void ShowVideo(bool enable);
102 
109  int WaitForBuffer(volatile std::atomic_bool& bStop,
110  std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
111 
116  bool GetStats(int &lateframes, double &pts, int &queued, int &discard);
117 
121  void DiscardBuffer();
122 
123  void SetDelay(int delay) { m_videoDelay = delay; }
124  int GetDelay() { return m_videoDelay; }
125 
126  void SetVideoSettings(const CVideoSettings& settings);
127 
128 protected:
129 
130  void PresentSingle(bool clear, DWORD flags, DWORD alpha);
131  void PresentFields(bool clear, DWORD flags, DWORD alpha);
132  void PresentBlend(bool clear, DWORD flags, DWORD alpha);
133 
134  void PrepareNextRender();
135  bool IsPresenting();
136  bool IsGuiLayer();
137 
138  bool Configure();
139  void CreateRenderer();
140  void DeleteRenderer();
141  void ManageCaptures();
142 
143  void UpdateLatencyTweak();
144  void CheckEnableClockSync();
145 
146  CBaseRenderer *m_pRenderer = nullptr;
147  OVERLAY::CRenderer m_overlays;
148  CDebugRenderer m_debugRenderer;
149  mutable CCriticalSection m_statelock;
150  CCriticalSection m_presentlock;
151  CCriticalSection m_datalock;
152  bool m_bTriggerUpdateResolution = false;
153  bool m_bRenderGUI = true;
154  bool m_renderedOverlay = false;
155  bool m_renderDebug = false;
156  bool m_renderDebugVideo = false;
157  XbmcThreads::EndTime<> m_debugTimer;
158  std::atomic_bool m_showVideo = {false};
159 
160  enum EPRESENTSTEP
161  {
162  PRESENT_IDLE = 0
163  , PRESENT_FLIP
164  , PRESENT_FRAME
165  , PRESENT_FRAME2
166  , PRESENT_READY
167  };
168 
169  enum EPRESENTMETHOD
170  {
171  PRESENT_METHOD_SINGLE = 0,
172  PRESENT_METHOD_BLEND,
173  PRESENT_METHOD_BOB,
174  };
175 
176  enum ERENDERSTATE
177  {
178  STATE_UNCONFIGURED = 0,
179  STATE_CONFIGURING,
180  STATE_CONFIGURED,
181  };
182  ERENDERSTATE m_renderState = STATE_UNCONFIGURED;
183  CEvent m_stateEvent;
184 
187  double m_latencyTweak = 0.0;
189  double m_displayLatency = 0.0;
190  std::atomic_int m_videoDelay = {};
191 
192  int m_QueueSize = 2;
193  int m_QueueSkip = 0;
194 
195  struct SPresent
196  {
197  double pts;
198  EFIELDSYNC presentfield;
199  EPRESENTMETHOD presentmethod;
200  } m_Queue[NUM_BUFFERS]{};
201 
202  std::deque<int> m_free;
203  std::deque<int> m_queued;
204  std::deque<int> m_discard;
205 
206  std::unique_ptr<VideoPicture> m_pConfigPicture;
207  unsigned int m_width = 0;
208  unsigned int m_height = 0;
209  unsigned int m_dwidth = 0;
210  unsigned int m_dheight = 0;
211  float m_fps = 0.0;
212  unsigned int m_orientation = 0;
213  int m_NumberBuffers = 0;
214  std::string m_stereomode;
215 
216  int m_lateframes = -1;
217  double m_presentpts = 0.0;
218  EPRESENTSTEP m_presentstep = PRESENT_IDLE;
219  XbmcThreads::EndTime<> m_presentTimer;
220  bool m_forceNext = false;
221  int m_presentsource = 0;
222  int m_presentsourcePast = -1;
223  XbmcThreads::ConditionVariable m_presentevent;
224  CEvent m_flushEvent;
225  CEvent m_initEvent;
226  CDVDClock &m_dvdClock;
227  IRenderMsg *m_playerPort;
228 
229  struct CClockSync
230  {
231  void Reset();
232  double m_error;
233  int m_errCount;
234  double m_syncOffset;
235  bool m_enabled;
236  };
237  CClockSync m_clockSync;
238 
239  void RenderCapture(CRenderCapture* capture);
240  void RemoveCaptures();
241  CCriticalSection m_captCritSect;
242  std::map<unsigned int, CRenderCapture*> m_captures;
243  static unsigned int m_nextCaptureId;
244  unsigned int m_captureWaitCounter = 0;
245  //set to true when adding something to m_captures, set to false when m_captures is made empty
246  //std::list::empty() isn't thread safe, using an extra bool will save a lock per render when no captures are requested
247  bool m_hasCaptures = false;
248 };
This is an Event class built from a ConditionVariable.
Definition: Event.h:35
Definition: RenderCapture.h:23
Definition: RenderInfo.h:19
Definition: OverlayRenderer.h:92
Definition: SystemClock.h:31
Definition: DebugRenderer.h:20
Definition: LinuxRendererGL.h:56
Definition: RenderManager.h:54
Definition: WinRenderer.h:17
Definition: settings.py:1
Definition: RenderManager.h:229
Definition: DVDClock.h:18
Definition: RenderManager.h:195
This is a thin wrapper around std::condition_variable_any.
Definition: Condition.h:26
Definition: DVDVideoCodec.h:36
Definition: LinuxRendererGLES.h:57
Definition: BaseRenderer.h:48
Definition: VideoSettings.h:194
Definition: RenderManager.h:38