summaryrefslogtreecommitdiffstats
path: root/xbmc/cores/DataCacheCore.h
blob: 95a734b4dc0dd618e1b9962aea9506254a885dad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "EdlEdit.h"
#include "threads/CriticalSection.h"

#include <atomic>
#include <chrono>
#include <string>
#include <vector>

class CDataCacheCore
{
public:
  CDataCacheCore();
  virtual ~CDataCacheCore();
  static CDataCacheCore& GetInstance();
  void Reset();
  bool HasAVInfoChanges();
  void SignalVideoInfoChange();
  void SignalAudioInfoChange();
  void SignalSubtitleInfoChange();

  // player video info
  void SetVideoDecoderName(std::string name, bool isHw);
  std::string GetVideoDecoderName();
  bool IsVideoHwDecoder();
  void SetVideoDeintMethod(std::string method);
  std::string GetVideoDeintMethod();
  void SetVideoPixelFormat(std::string pixFormat);
  std::string GetVideoPixelFormat();
  void SetVideoStereoMode(std::string mode);
  std::string GetVideoStereoMode();
  void SetVideoDimensions(int width, int height);
  int GetVideoWidth();
  int GetVideoHeight();
  void SetVideoFps(float fps);
  float GetVideoFps();
  void SetVideoDAR(float dar);
  float GetVideoDAR();

  /*!
   * @brief Set if the video is interlaced in cache.
   * @param isInterlaced Set true when the video is interlaced
   */
  void SetVideoInterlaced(bool isInterlaced);

  /*!
   * @brief Check if the video is interlaced from cache
   * @return True if interlaced, otherwise false
   */
  bool IsVideoInterlaced();

  // player audio info
  void SetAudioDecoderName(std::string name);
  std::string GetAudioDecoderName();
  void SetAudioChannels(std::string channels);
  std::string GetAudioChannels();
  void SetAudioSampleRate(int sampleRate);
  int GetAudioSampleRate();
  void SetAudioBitsPerSample(int bitsPerSample);
  int GetAudioBitsPerSample();

  // content info

  /*!
   * @brief Set the EDL edit list to cache.
   * @param editList The vector of edits to fill.
   */
  void SetEditList(const std::vector<EDL::Edit>& editList);

  /*!
   * @brief Get the EDL edit list in cache.
   * @return The EDL edits or an empty vector if no edits exist.
   */
  const std::vector<EDL::Edit>& GetEditList() const;

  /*!
   * @brief Set the list of cut markers in cache.
   * @return The list of cuts or an empty list if no cuts exist
   */
  void SetCuts(const std::vector<int64_t>& cuts);

  /*!
   * @brief Get the list of cut markers from cache.
   * @return The list of cut markers or an empty vector if no cuts exist.
   */
  const std::vector<int64_t>& GetCuts() const;

  /*!
   * @brief Set the list of scene markers in cache.
   * @return The list of scene markers or an empty list if no scene markers exist
   */
  void SetSceneMarkers(const std::vector<int64_t>& sceneMarkers);

  /*!
   * @brief Get the list of scene markers markers from cache.
   * @return The list of scene markers or an empty vector if no scene exist.
   */
  const std::vector<int64_t>& GetSceneMarkers() const;

  void SetChapters(const std::vector<std::pair<std::string, int64_t>>& chapters);

  /*!
   * @brief Get the chapter list in cache.
   * @return The list of chapters or an empty vector if no chapters exist.
   */
  const std::vector<std::pair<std::string, int64_t>>& GetChapters() const;

  // render info
  void SetRenderClockSync(bool enabled);
  bool IsRenderClockSync();

  // player states
  /*!
   * @brief Notifies the cache core that a seek operation has finished
   * @param offset - the seek offset
  */
  void SeekFinished(int64_t offset);

  void SetStateSeeking(bool active);
  bool IsSeeking();

  /*!
   * @brief Checks if a seek has been performed in the last provided seconds interval
   * @param lastSecondInterval - the last elapsed second interval to check for a seek operation
   * @return true if a seek was performed in the lastSecondInterval, false otherwise
  */
  bool HasPerformedSeek(int64_t lastSecondInterval) const;

  /*!
   * @brief Gets the last seek offset
   * @return the last seek offset
  */
  int64_t GetSeekOffSet() const;

  void SetSpeed(float tempo, float speed);
  float GetSpeed();
  float GetTempo();
  void SetFrameAdvance(bool fa);
  bool IsFrameAdvance();
  bool IsPlayerStateChanged();
  void SetGuiRender(bool gui);
  bool GetGuiRender();
  void SetVideoRender(bool video);
  bool GetVideoRender();
  void SetPlayTimes(time_t start, int64_t current, int64_t min, int64_t max);
  void GetPlayTimes(time_t &start, int64_t &current, int64_t &min, int64_t &max);

  /*!
   * \brief Get the start time
   *
   * For a typical video this will be zero. For live TV, this is a reference time
   * in units of time_t (UTC) from which time elapsed starts. Ideally this would
   * be the start of the tv show but can be any other time as well.
   */
  time_t GetStartTime();

  /*!
   * \brief Get the current time of playback
   *
   * This is the time elapsed, in ms, since the start time.
   */
  int64_t GetPlayTime();

  /*!
   * \brief Get the current percentage of playback if a playback buffer is available.
   *
   *  If there is no playback buffer, percentage will be 0.
   */
  float GetPlayPercentage();

  /*!
   * \brief Get the minimum time
   *
   * This will be zero for a typical video. With timeshift, this is the time,
   * in ms, that the player can go back. This can be before the start time.
   */
  int64_t GetMinTime();

  /*!
   * \brief Get the maximum time
   *
   * This is the maximum time, in ms, that the player can skip forward. For a
   * typical video, this will be the total length. For live TV without
   * timeshift this is zero, and for live TV with timeshift this will be the
   * buffer ahead.
   */
  int64_t GetMaxTime();

protected:
  std::atomic_bool m_hasAVInfoChanges = false;

  CCriticalSection m_videoPlayerSection;
  struct SPlayerVideoInfo
  {
    std::string decoderName;
    bool isHwDecoder;
    std::string deintMethod;
    std::string pixFormat;
    std::string stereoMode;
    int width;
    int height;
    float fps;
    float dar;
    bool m_isInterlaced;
  } m_playerVideoInfo;

  CCriticalSection m_audioPlayerSection;
  struct SPlayerAudioInfo
  {
    std::string decoderName;
    std::string channels;
    int sampleRate;
    int bitsPerSample;
  } m_playerAudioInfo;

  mutable CCriticalSection m_contentSection;
  struct SContentInfo
  {
  public:
    /*!
      * @brief Set the EDL edit list in cache.
      * @param editList the list of edits to store in cache
      */
    void SetEditList(const std::vector<EDL::Edit>& editList) { m_editList = editList; }

    /*!
      * @brief Get the EDL edit list in cache.
      * @return the list of edits in cache
      */
    const std::vector<EDL::Edit>& GetEditList() const { return m_editList; }

    /*!
      * @brief Save the list of cut markers in cache.
      * @param cuts the list of cut markers to store in cache
      */
    void SetCuts(const std::vector<int64_t>& cuts) { m_cuts = cuts; }

    /*!
      * @brief Get the list of cut markers in cache.
      * @return the list of cut markers in cache
      */
    const std::vector<int64_t>& GetCuts() const { return m_cuts; }

    /*!
      * @brief Save the list of scene markers in cache.
      * @param sceneMarkers the list of scene markers to store in cache
      */
    void SetSceneMarkers(const std::vector<int64_t>& sceneMarkers)
    {
      m_sceneMarkers = sceneMarkers;
    }

    /*!
      * @brief Get the list of scene markers in cache.
      * @return the list of scene markers in cache
      */
    const std::vector<int64_t>& GetSceneMarkers() const { return m_sceneMarkers; }

    /*!
      * @brief Save the chapter list in cache.
      * @param chapters the list of chapters to store in cache
      */
    void SetChapters(const std::vector<std::pair<std::string, int64_t>>& chapters)
    {
      m_chapters = chapters;
    }

    /*!
      * @brief Get the list of chapters in cache.
      * @return the list of chapters in cache
      */
    const std::vector<std::pair<std::string, int64_t>>& GetChapters() const { return m_chapters; }

    /*!
      * @brief Reset the content cache to the original values (all empty)
      */
    void Reset()
    {
      m_editList.clear();
      m_chapters.clear();
      m_cuts.clear();
      m_sceneMarkers.clear();
    }

  private:
    /*!< list of EDL edits */
    std::vector<EDL::Edit> m_editList;
    /*!< name and position for chapters */
    std::vector<std::pair<std::string, int64_t>> m_chapters;
    /*!< position for EDL cuts */
    std::vector<int64_t> m_cuts;
    /*!< position for EDL scene markers */
    std::vector<int64_t> m_sceneMarkers;
  } m_contentInfo;

  CCriticalSection m_renderSection;
  struct SRenderInfo
  {
    bool m_isClockSync;
  } m_renderInfo;

  mutable CCriticalSection m_stateSection;
  bool m_playerStateChanged = false;
  struct SStateInfo
  {
    bool m_stateSeeking;
    bool m_renderGuiLayer;
    bool m_renderVideoLayer;
    float m_tempo;
    float m_speed;
    bool m_frameAdvance;
    /*! Time point of the last seek operation */
    std::chrono::time_point<std::chrono::system_clock> m_lastSeekTime{
        std::chrono::time_point<std::chrono::system_clock>{}};
    /*! Last seek offset */
    int64_t m_lastSeekOffset{0};
  } m_stateInfo;

  struct STimeInfo
  {
    time_t m_startTime;
    int64_t m_time;
    int64_t m_timeMax;
    int64_t m_timeMin;
  } m_timeInfo = {};
};