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 "DVDResource.h"
12 #include "FileItem.h"
13 #include "cores/IPlayer.h"
14 
15 #include <atomic>
16 #include <string.h>
17 #include <string>
18 
19 struct DemuxPacket;
20 
21 class CDVDMsg : public IDVDResourceCounted<CDVDMsg>
22 {
23 public:
24   // clang-format off
25   enum Message
26   {
27     NONE = 1000,
28 
29     // messages used in the whole system
30     GENERAL_RESYNC,                 //
31     GENERAL_FLUSH,                  // flush all buffers
32     GENERAL_RESET,                  // reset codecs for new data
33     GENERAL_PAUSE,
34     GENERAL_STREAMCHANGE,           //
35     GENERAL_SYNCHRONIZE,            //
36     GENERAL_GUI_ACTION,             // gui action of some sort
37     GENERAL_EOF,                    // eof of stream
38 
39     // player core related messages (cVideoPlayer.cpp)
40     PLAYER_SET_AUDIOSTREAM,         //
41     PLAYER_SET_VIDEOSTREAM,         //
42     PLAYER_SET_SUBTITLESTREAM,      //
43     PLAYER_SET_SUBTITLESTREAM_VISIBLE, //
44     PLAYER_SET_STATE,               // restore the VideoPlayer to a certain state
45     PLAYER_SET_PROGRAM,
46     PLAYER_SET_UPDATE_STREAM_DETAILS, // player should update file item stream details with its current streams
47     PLAYER_SEEK,                    //
48     PLAYER_SEEK_CHAPTER,            //
49     PLAYER_SETSPEED,                // set the playback speed
50     PLAYER_REQUEST_STATE,
51     PLAYER_OPENFILE,
52     PLAYER_STARTED,                 // sent whenever a sub player has finished it's first frame after open
53     PLAYER_AVCHANGE,                // signal a change in audio, video or subtitle parameters
54     PLAYER_ABORT,
55     PLAYER_REPORT_STATE,
56     PLAYER_FRAME_ADVANCE,
57     PLAYER_DISPLAY_RESET,           // report display reset event
58 
59     // demuxer related messages
60     DEMUXER_PACKET,                 // data packet
61     DEMUXER_RESET,                  // reset the demuxer
62 
63     // video related messages
64     VIDEO_SET_ASPECT,               // set aspectratio of video
65     VIDEO_DRAIN,                    // wait for decoder to output last frame
66 
67     // subtitle related messages
68     SUBTITLE_CLUTCHANGE,
69     SUBTITLE_ADDFILE
70   };
71   // clang-format on
72 
CDVDMsg(Message msg)73   explicit CDVDMsg(Message msg)
74   {
75     m_message = msg;
76   }
77 
78   ~CDVDMsg() override = default;
79 
80   /**
81    * checks for message type
82    */
IsType(Message msg)83   inline bool IsType(Message msg)
84   {
85     return (m_message == msg);
86   }
87 
GetMessageType()88   inline Message GetMessageType()
89   {
90     return m_message;
91   }
92 
GetNrOfReferences()93   long GetNrOfReferences()
94   {
95     return m_refs;
96   }
97 
98 private:
99   Message m_message;
100 };
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 //////
104 ////// GENERAL_ Messages
105 //////
106 ////////////////////////////////////////////////////////////////////////////////
107 
108 #define SYNCSOURCE_AUDIO  0x01
109 #define SYNCSOURCE_VIDEO  0x02
110 #define SYNCSOURCE_PLAYER 0x04
111 #define SYNCSOURCE_ANY    0x08
112 
113 class CDVDMsgGeneralSynchronizePriv;
114 class CDVDMsgGeneralSynchronize : public CDVDMsg
115 {
116 public:
117   CDVDMsgGeneralSynchronize(unsigned int timeout, unsigned int sources);
118  ~CDVDMsgGeneralSynchronize() override;
119   long Release() override;
120 
121   // waits until all threads waiting, released the object
122   // if abort is set somehow
123   bool Wait(unsigned int ms, unsigned int source);
124   void Wait(std::atomic<bool>& abort, unsigned int source);
125 
126 private:
127   class CDVDMsgGeneralSynchronizePriv* m_p;
128 };
129 
130 template <typename T>
131 class CDVDMsgType : public CDVDMsg
132 {
133 public:
CDVDMsgType(Message type,const T & value)134   CDVDMsgType(Message type, const T &value)
135     : CDVDMsg(type)
136     , m_value(value)
137   {}
T()138   operator T() { return m_value; }
139   T m_value;
140 };
141 
142 typedef CDVDMsgType<bool> CDVDMsgBool;
143 typedef CDVDMsgType<int> CDVDMsgInt;
144 typedef CDVDMsgType<double> CDVDMsgDouble;
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 //////
148 ////// PLAYER_ Messages
149 //////
150 ////////////////////////////////////////////////////////////////////////////////
151 
152 class CDVDMsgPlayerSetAudioStream : public CDVDMsg
153 {
154 public:
CDVDMsgPlayerSetAudioStream(int streamId)155   explicit CDVDMsgPlayerSetAudioStream(int streamId) : CDVDMsg(PLAYER_SET_AUDIOSTREAM) { m_streamId = streamId; }
GetStreamId()156   int GetStreamId() { return m_streamId; }
157 private:
158   int m_streamId;
159 };
160 
161 class CDVDMsgPlayerSetVideoStream : public CDVDMsg
162 {
163 public:
CDVDMsgPlayerSetVideoStream(int streamId)164   explicit CDVDMsgPlayerSetVideoStream(int streamId) : CDVDMsg(PLAYER_SET_VIDEOSTREAM) { m_streamId = streamId; }
GetStreamId()165   int GetStreamId() const { return m_streamId; }
166 private:
167   int m_streamId;
168 };
169 
170 class CDVDMsgPlayerSetSubtitleStream : public CDVDMsg
171 {
172 public:
CDVDMsgPlayerSetSubtitleStream(int streamId)173   explicit CDVDMsgPlayerSetSubtitleStream(int streamId) : CDVDMsg(PLAYER_SET_SUBTITLESTREAM) { m_streamId = streamId; }
GetStreamId()174   int GetStreamId() { return m_streamId; }
175 private:
176   int m_streamId;
177 };
178 
179 class CDVDMsgPlayerSetState : public CDVDMsg
180 {
181 public:
CDVDMsgPlayerSetState(const std::string & state)182   explicit CDVDMsgPlayerSetState(const std::string& state) : CDVDMsg(PLAYER_SET_STATE), m_state(state) {}
GetState()183   std::string GetState() { return m_state; }
184 private:
185   std::string m_state;
186 };
187 
188 class CDVDMsgPlayerSeek : public CDVDMsg
189 {
190 public:
191   struct CMode
192   {
193     double time = 0;
194     bool relative = false;
195     bool backward = false;
196     bool accurate = true;
197     bool sync = true;
198     bool restore = true;
199     bool trickplay = false;
200   };
201 
CDVDMsgPlayerSeek(CDVDMsgPlayerSeek::CMode mode)202   explicit CDVDMsgPlayerSeek(CDVDMsgPlayerSeek::CMode mode) : CDVDMsg(PLAYER_SEEK),
203     m_mode(mode)
204   {}
GetTime()205   double GetTime() { return m_mode.time; }
GetRelative()206   bool GetRelative() { return m_mode.relative; }
GetBackward()207   bool GetBackward() { return m_mode.backward; }
GetAccurate()208   bool GetAccurate() { return m_mode.accurate; }
GetRestore()209   bool GetRestore() { return m_mode.restore; }
GetTrickPlay()210   bool GetTrickPlay() { return m_mode.trickplay; }
GetSync()211   bool GetSync() { return m_mode.sync; }
212 
213 private:
214   CMode m_mode;
215 };
216 
217 class CDVDMsgPlayerSeekChapter : public CDVDMsg
218 {
219   public:
CDVDMsgPlayerSeekChapter(int iChapter)220     explicit CDVDMsgPlayerSeekChapter(int iChapter)
221       : CDVDMsg(PLAYER_SEEK_CHAPTER)
222       , m_iChapter(iChapter)
223     {}
224 
GetChapter()225     int GetChapter() const { return m_iChapter; }
226 
227   private:
228 
229     int m_iChapter;
230 };
231 
232 class CDVDMsgPlayerSetSpeed : public CDVDMsg
233 {
234 public:
235   struct SpeedParams
236   {
237     int m_speed;
238     bool m_isTempo;
239   };
240 
CDVDMsgPlayerSetSpeed(SpeedParams params)241   explicit CDVDMsgPlayerSetSpeed(SpeedParams params)
242   : CDVDMsg(PLAYER_SETSPEED)
243   , m_params(params)
244   {}
245 
GetSpeed()246   int GetSpeed() const { return m_params.m_speed; }
IsTempo()247   bool IsTempo() const { return m_params.m_isTempo; }
248 
249 private:
250 
251   SpeedParams m_params;
252 
253 };
254 
255 class CDVDMsgOpenFile : public CDVDMsg
256 {
257 public:
258   struct FileParams
259   {
260     CFileItem m_item;
261     CPlayerOptions m_options;
262   };
263 
CDVDMsgOpenFile(const FileParams & params)264   explicit CDVDMsgOpenFile(const FileParams &params)
265   : CDVDMsg(PLAYER_OPENFILE)
266   , m_params(params)
267   {}
268 
GetItem()269   CFileItem& GetItem() { return m_params.m_item; }
GetOptions()270   CPlayerOptions& GetOptions() { return m_params.m_options; }
271 
272 private:
273 
274   FileParams m_params;
275 };
276 
277 ////////////////////////////////////////////////////////////////////////////////
278 //////
279 ////// DEMUXER_ Messages
280 //////
281 ////////////////////////////////////////////////////////////////////////////////
282 
283 class CDVDMsgDemuxerPacket : public CDVDMsg
284 {
285 public:
286   CDVDMsgDemuxerPacket(DemuxPacket* packet, bool drop = false);
287   ~CDVDMsgDemuxerPacket() override;
GetPacket()288   DemuxPacket* GetPacket() { return m_packet; }
289   unsigned int GetPacketSize();
GetPacketDrop()290   bool GetPacketDrop() { return m_drop; }
291   DemuxPacket* m_packet;
292   bool m_drop;
293 };
294 
295 class CDVDMsgDemuxerReset : public CDVDMsg
296 {
297 public:
CDVDMsgDemuxerReset()298   CDVDMsgDemuxerReset() : CDVDMsg(DEMUXER_RESET)  {}
299 };
300 
301 
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 //////
305 ////// VIDEO_ Messages
306 //////
307 ////////////////////////////////////////////////////////////////////////////////
308 
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 //////
312 ////// SUBTITLE_ Messages
313 //////
314 ////////////////////////////////////////////////////////////////////////////////
315 
316 class CDVDMsgSubtitleClutChange : public CDVDMsg
317 {
318 public:
CDVDMsgSubtitleClutChange(uint8_t * data)319   explicit CDVDMsgSubtitleClutChange(uint8_t* data) : CDVDMsg(SUBTITLE_CLUTCHANGE) { memcpy(m_data, data, 16*4); }
320   uint8_t m_data[16][4];
321 private:
322 };
323