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 #include "DataCacheCore.h"
10 
11 #include "ServiceBroker.h"
12 #include "cores/Cut.h"
13 #include "threads/SingleLock.h"
14 
15 #include <utility>
16 
CDataCacheCore()17 CDataCacheCore::CDataCacheCore() :
18   m_playerVideoInfo {},
19   m_playerAudioInfo {},
20   m_contentInfo {},
21   m_renderInfo {},
22   m_stateInfo {}
23 {
24   m_hasAVInfoChanges = false;
25 }
26 
27 CDataCacheCore::~CDataCacheCore() = default;
28 
GetInstance()29 CDataCacheCore& CDataCacheCore::GetInstance()
30 {
31   return CServiceBroker::GetDataCacheCore();
32 }
33 
Reset()34 void CDataCacheCore::Reset()
35 {
36   {
37     CSingleLock lock(m_stateSection);
38 
39     m_stateInfo.m_speed = 1.0;
40     m_stateInfo.m_tempo = 1.0;
41     m_stateInfo.m_stateSeeking = false;
42     m_stateInfo.m_renderGuiLayer = false;
43     m_stateInfo.m_renderVideoLayer = false;
44     m_playerStateChanged = false;
45   }
46 
47   {
48     CSingleLock lock(m_contentSection);
49 
50     m_contentInfo.m_chapters.clear();
51     m_contentInfo.m_cutList.clear();
52   }
53 }
54 
HasAVInfoChanges()55 bool CDataCacheCore::HasAVInfoChanges()
56 {
57   bool ret = m_hasAVInfoChanges;
58   m_hasAVInfoChanges = false;
59   return ret;
60 }
61 
SignalVideoInfoChange()62 void CDataCacheCore::SignalVideoInfoChange()
63 {
64   m_hasAVInfoChanges = true;
65 }
66 
SignalAudioInfoChange()67 void CDataCacheCore::SignalAudioInfoChange()
68 {
69   m_hasAVInfoChanges = true;
70 }
71 
SignalSubtitleInfoChange()72 void CDataCacheCore::SignalSubtitleInfoChange()
73 {
74   m_hasAVInfoChanges = true;
75 }
76 
SetVideoDecoderName(std::string name,bool isHw)77 void CDataCacheCore::SetVideoDecoderName(std::string name, bool isHw)
78 {
79   CSingleLock lock(m_videoPlayerSection);
80 
81   m_playerVideoInfo.decoderName = std::move(name);
82   m_playerVideoInfo.isHwDecoder = isHw;
83 }
84 
GetVideoDecoderName()85 std::string CDataCacheCore::GetVideoDecoderName()
86 {
87   CSingleLock lock(m_videoPlayerSection);
88 
89   return m_playerVideoInfo.decoderName;
90 }
91 
IsVideoHwDecoder()92 bool CDataCacheCore::IsVideoHwDecoder()
93 {
94   CSingleLock lock(m_videoPlayerSection);
95 
96   return m_playerVideoInfo.isHwDecoder;
97 }
98 
99 
SetVideoDeintMethod(std::string method)100 void CDataCacheCore::SetVideoDeintMethod(std::string method)
101 {
102   CSingleLock lock(m_videoPlayerSection);
103 
104   m_playerVideoInfo.deintMethod = std::move(method);
105 }
106 
GetVideoDeintMethod()107 std::string CDataCacheCore::GetVideoDeintMethod()
108 {
109   CSingleLock lock(m_videoPlayerSection);
110 
111   return m_playerVideoInfo.deintMethod;
112 }
113 
SetVideoPixelFormat(std::string pixFormat)114 void CDataCacheCore::SetVideoPixelFormat(std::string pixFormat)
115 {
116   CSingleLock lock(m_videoPlayerSection);
117 
118   m_playerVideoInfo.pixFormat = std::move(pixFormat);
119 }
120 
GetVideoPixelFormat()121 std::string CDataCacheCore::GetVideoPixelFormat()
122 {
123   CSingleLock lock(m_videoPlayerSection);
124 
125   return m_playerVideoInfo.pixFormat;
126 }
127 
SetVideoStereoMode(std::string mode)128 void CDataCacheCore::SetVideoStereoMode(std::string mode)
129 {
130   CSingleLock lock(m_videoPlayerSection);
131 
132   m_playerVideoInfo.stereoMode = std::move(mode);
133 }
134 
GetVideoStereoMode()135 std::string CDataCacheCore::GetVideoStereoMode()
136 {
137   CSingleLock lock(m_videoPlayerSection);
138 
139   return m_playerVideoInfo.stereoMode;
140 }
141 
SetVideoDimensions(int width,int height)142 void CDataCacheCore::SetVideoDimensions(int width, int height)
143 {
144   CSingleLock lock(m_videoPlayerSection);
145 
146   m_playerVideoInfo.width = width;
147   m_playerVideoInfo.height = height;
148 }
149 
GetVideoWidth()150 int CDataCacheCore::GetVideoWidth()
151 {
152   CSingleLock lock(m_videoPlayerSection);
153 
154   return m_playerVideoInfo.width;
155 }
156 
GetVideoHeight()157 int CDataCacheCore::GetVideoHeight()
158 {
159   CSingleLock lock(m_videoPlayerSection);
160 
161   return m_playerVideoInfo.height;
162 }
163 
SetVideoFps(float fps)164 void CDataCacheCore::SetVideoFps(float fps)
165 {
166   CSingleLock lock(m_videoPlayerSection);
167 
168   m_playerVideoInfo.fps = fps;
169 }
170 
GetVideoFps()171 float CDataCacheCore::GetVideoFps()
172 {
173   CSingleLock lock(m_videoPlayerSection);
174 
175   return m_playerVideoInfo.fps;
176 }
177 
SetVideoDAR(float dar)178 void CDataCacheCore::SetVideoDAR(float dar)
179 {
180   CSingleLock lock(m_videoPlayerSection);
181 
182   m_playerVideoInfo.dar = dar;
183 }
184 
GetVideoDAR()185 float CDataCacheCore::GetVideoDAR()
186 {
187   CSingleLock lock(m_videoPlayerSection);
188 
189   return m_playerVideoInfo.dar;
190 }
191 
192 // player audio info
SetAudioDecoderName(std::string name)193 void CDataCacheCore::SetAudioDecoderName(std::string name)
194 {
195   CSingleLock lock(m_audioPlayerSection);
196 
197   m_playerAudioInfo.decoderName = std::move(name);
198 }
199 
GetAudioDecoderName()200 std::string CDataCacheCore::GetAudioDecoderName()
201 {
202   CSingleLock lock(m_audioPlayerSection);
203 
204   return m_playerAudioInfo.decoderName;
205 }
206 
SetAudioChannels(std::string channels)207 void CDataCacheCore::SetAudioChannels(std::string channels)
208 {
209   CSingleLock lock(m_audioPlayerSection);
210 
211   m_playerAudioInfo.channels = std::move(channels);
212 }
213 
GetAudioChannels()214 std::string CDataCacheCore::GetAudioChannels()
215 {
216   CSingleLock lock(m_audioPlayerSection);
217 
218   return m_playerAudioInfo.channels;
219 }
220 
SetAudioSampleRate(int sampleRate)221 void CDataCacheCore::SetAudioSampleRate(int sampleRate)
222 {
223   CSingleLock lock(m_audioPlayerSection);
224 
225   m_playerAudioInfo.sampleRate = sampleRate;
226 }
227 
GetAudioSampleRate()228 int CDataCacheCore::GetAudioSampleRate()
229 {
230   CSingleLock lock(m_audioPlayerSection);
231 
232   return m_playerAudioInfo.sampleRate;
233 }
234 
SetAudioBitsPerSample(int bitsPerSample)235 void CDataCacheCore::SetAudioBitsPerSample(int bitsPerSample)
236 {
237   CSingleLock lock(m_audioPlayerSection);
238 
239   m_playerAudioInfo.bitsPerSample = bitsPerSample;
240 }
241 
GetAudioBitsPerSample()242 int CDataCacheCore::GetAudioBitsPerSample()
243 {
244   CSingleLock lock(m_audioPlayerSection);
245 
246   return m_playerAudioInfo.bitsPerSample;
247 }
248 
SetCutList(const std::vector<EDL::Cut> & cutList)249 void CDataCacheCore::SetCutList(const std::vector<EDL::Cut>& cutList)
250 {
251   CSingleLock lock(m_contentSection);
252   m_contentInfo.m_cutList = cutList;
253 }
254 
GetCutList() const255 std::vector<EDL::Cut> CDataCacheCore::GetCutList() const
256 {
257   CSingleLock lock(m_contentSection);
258   return m_contentInfo.m_cutList;
259 }
260 
SetChapters(const std::vector<std::pair<std::string,int64_t>> & chapters)261 void CDataCacheCore::SetChapters(const std::vector<std::pair<std::string, int64_t>>& chapters)
262 {
263   CSingleLock lock(m_contentSection);
264   m_contentInfo.m_chapters = chapters;
265 }
266 
GetChapters() const267 std::vector<std::pair<std::string, int64_t>> CDataCacheCore::GetChapters() const
268 {
269   CSingleLock lock(m_contentSection);
270   return m_contentInfo.m_chapters;
271 }
272 
SetRenderClockSync(bool enable)273 void CDataCacheCore::SetRenderClockSync(bool enable)
274 {
275   CSingleLock lock(m_renderSection);
276 
277   m_renderInfo.m_isClockSync = enable;
278 }
279 
IsRenderClockSync()280 bool CDataCacheCore::IsRenderClockSync()
281 {
282   CSingleLock lock(m_renderSection);
283 
284   return m_renderInfo.m_isClockSync;
285 }
286 
287 // player states
SetStateSeeking(bool active)288 void CDataCacheCore::SetStateSeeking(bool active)
289 {
290   CSingleLock lock(m_stateSection);
291 
292   m_stateInfo.m_stateSeeking = active;
293   m_playerStateChanged = true;
294 }
295 
IsSeeking()296 bool CDataCacheCore::IsSeeking()
297 {
298   CSingleLock lock(m_stateSection);
299 
300   return m_stateInfo.m_stateSeeking;
301 }
302 
SetSpeed(float tempo,float speed)303 void CDataCacheCore::SetSpeed(float tempo, float speed)
304 {
305   CSingleLock lock(m_stateSection);
306 
307   m_stateInfo.m_tempo = tempo;
308   m_stateInfo.m_speed = speed;
309 }
310 
GetSpeed()311 float CDataCacheCore::GetSpeed()
312 {
313   CSingleLock lock(m_stateSection);
314 
315   return m_stateInfo.m_speed;
316 }
317 
GetTempo()318 float CDataCacheCore::GetTempo()
319 {
320   CSingleLock lock(m_stateSection);
321 
322   return m_stateInfo.m_tempo;
323 }
324 
SetFrameAdvance(bool fa)325 void CDataCacheCore::SetFrameAdvance(bool fa)
326 {
327   CSingleLock lock(m_stateSection);
328 
329   m_stateInfo.m_frameAdvance = fa;
330 }
331 
IsFrameAdvance()332 bool CDataCacheCore::IsFrameAdvance()
333 {
334   CSingleLock lock(m_stateSection);
335 
336   return m_stateInfo.m_frameAdvance;
337 }
338 
IsPlayerStateChanged()339 bool CDataCacheCore::IsPlayerStateChanged()
340 {
341   CSingleLock lock(m_stateSection);
342 
343   bool ret(m_playerStateChanged);
344   m_playerStateChanged = false;
345 
346   return ret;
347 }
348 
SetGuiRender(bool gui)349 void CDataCacheCore::SetGuiRender(bool gui)
350 {
351   CSingleLock lock(m_stateSection);
352 
353   m_stateInfo.m_renderGuiLayer = gui;
354   m_playerStateChanged = true;
355 }
356 
GetGuiRender()357 bool CDataCacheCore::GetGuiRender()
358 {
359   CSingleLock lock(m_stateSection);
360 
361   return m_stateInfo.m_renderGuiLayer;
362 }
363 
SetVideoRender(bool video)364 void CDataCacheCore::SetVideoRender(bool video)
365 {
366   CSingleLock lock(m_stateSection);
367 
368   m_stateInfo.m_renderVideoLayer = video;
369   m_playerStateChanged = true;
370 }
371 
GetVideoRender()372 bool CDataCacheCore::GetVideoRender()
373 {
374   CSingleLock lock(m_stateSection);
375 
376   return m_stateInfo.m_renderVideoLayer;
377 }
378 
SetPlayTimes(time_t start,int64_t current,int64_t min,int64_t max)379 void CDataCacheCore::SetPlayTimes(time_t start, int64_t current, int64_t min, int64_t max)
380 {
381   CSingleLock lock(m_stateSection);
382   m_timeInfo.m_startTime = start;
383   m_timeInfo.m_time = current;
384   m_timeInfo.m_timeMin = min;
385   m_timeInfo.m_timeMax = max;
386 }
387 
GetPlayTimes(time_t & start,int64_t & current,int64_t & min,int64_t & max)388 void CDataCacheCore::GetPlayTimes(time_t &start, int64_t &current, int64_t &min, int64_t &max)
389 {
390   CSingleLock lock(m_stateSection);
391   start = m_timeInfo.m_startTime;
392   current = m_timeInfo.m_time;
393   min = m_timeInfo.m_timeMin;
394   max = m_timeInfo.m_timeMax;
395 }
396 
GetStartTime()397 time_t CDataCacheCore::GetStartTime()
398 {
399   CSingleLock lock(m_stateSection);
400   return m_timeInfo.m_startTime;
401 }
402 
GetPlayTime()403 int64_t CDataCacheCore::GetPlayTime()
404 {
405   CSingleLock lock(m_stateSection);
406   return m_timeInfo.m_time;
407 }
408 
GetMinTime()409 int64_t CDataCacheCore::GetMinTime()
410 {
411   CSingleLock lock(m_stateSection);
412   return m_timeInfo.m_timeMin;
413 }
414 
GetMaxTime()415 int64_t CDataCacheCore::GetMaxTime()
416 {
417   CSingleLock lock(m_stateSection);
418   return m_timeInfo.m_timeMax;
419 }
420 
GetPlayPercentage()421 float CDataCacheCore::GetPlayPercentage()
422 {
423   CSingleLock lock(m_stateSection);
424 
425   // Note: To calculate accurate percentage, all time data must be consistent,
426   //       which is the case for data cache core. Calculation can not be done
427   //       outside of data cache core or a possibility to lock the data cache
428   //       core from outside would be needed.
429   int64_t iTotalTime = m_timeInfo.m_timeMax - m_timeInfo.m_timeMin;
430   if (iTotalTime <= 0)
431     return 0;
432 
433   return m_timeInfo.m_time * 100 / static_cast<float>(iTotalTime);
434 }
435