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 "Interface/StreamInfo.h"
12 
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 struct DemuxPacket;
18 struct DemuxCryptoSession;
19 
20 class CDVDInputStream;
21 
22 namespace ADDON
23 {
24 class IAddonProvider;
25 }
26 
27 #ifndef __GNUC__
28 #pragma warning(push)
29 #pragma warning(disable : 4244)
30 #endif
31 
32 extern "C"
33 {
34 #include <libavcodec/avcodec.h>
35 #include <libavutil/mastering_display_metadata.h>
36 }
37 
38 #ifndef __GNUC__
39 #pragma warning(pop)
40 #endif
41 
42 enum StreamType
43 {
44   STREAM_NONE = 0, // if unknown
45   STREAM_AUDIO, // audio stream
46   STREAM_VIDEO, // video stream
47   STREAM_DATA, // data stream
48   STREAM_SUBTITLE, // subtitle stream
49   STREAM_TELETEXT, // Teletext data stream
50   STREAM_RADIO_RDS // Radio RDS data stream
51 };
52 
53 enum StreamSource
54 {
55   STREAM_SOURCE_NONE = 0x000,
56   STREAM_SOURCE_DEMUX = 0x100,
57   STREAM_SOURCE_NAV = 0x200,
58   STREAM_SOURCE_DEMUX_SUB = 0x300,
59   STREAM_SOURCE_TEXT = 0x400,
60   STREAM_SOURCE_VIDEOMUX = 0x500
61 };
62 
63 #define STREAM_SOURCE_MASK(a) ((a)&0xf00)
64 
65 /*
66  * CDemuxStream
67  * Base class for all demuxer streams
68  */
69 class CDemuxStream
70 {
71 public:
CDemuxStream()72   CDemuxStream()
73   {
74     uniqueId = 0;
75     dvdNavId = 0;
76     demuxerId = -1;
77     codec = (AVCodecID)0; // AV_CODEC_ID_NONE
78     codec_fourcc = 0;
79     profile = FF_PROFILE_UNKNOWN;
80     level = FF_LEVEL_UNKNOWN;
81     type = STREAM_NONE;
82     source = STREAM_SOURCE_NONE;
83     iDuration = 0;
84     pPrivate = NULL;
85     ExtraData = NULL;
86     ExtraSize = 0;
87     disabled = false;
88     changes = 0;
89     flags = StreamFlags::FLAG_NONE;
90   }
91 
~CDemuxStream()92   virtual ~CDemuxStream() { delete[] ExtraData; }
93 
94   virtual std::string GetStreamName();
95 
96   int uniqueId; // unique stream id
97   int dvdNavId;
98   int64_t demuxerId; // id of the associated demuxer
99   AVCodecID codec;
100   unsigned int codec_fourcc; // if available
101   int profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders.
102   int level; // encoder level of the stream reported by the decoder. used to qualify hw decoders.
103   StreamType type;
104   int source;
105 
106   int iDuration; // in mseconds
107   void* pPrivate; // private pointer for the demuxer
108   uint8_t* ExtraData; // extra data for codec to use
109   unsigned int ExtraSize; // size of extra data
110 
111   StreamFlags flags;
112   std::string language; // RFC 5646 language code (empty string if undefined)
113   bool disabled; // set when stream is disabled. (when no decoder exists)
114 
115   std::string name;
116   std::string codecName;
117 
118   int changes; // increment on change which player may need to know about
119 
120   std::shared_ptr<DemuxCryptoSession> cryptoSession;
121   std::shared_ptr<ADDON::IAddonProvider> externalInterfaces;
122 };
123 
124 class CDemuxStreamVideo : public CDemuxStream
125 {
126 public:
CDemuxStreamVideo()127   CDemuxStreamVideo() { type = STREAM_VIDEO; };
128 
129   ~CDemuxStreamVideo() override = default;
130   int iFpsScale = 0; // scale of 1000 and a rate of 29970 will result in 29.97 fps
131   int iFpsRate = 0;
132   int iHeight = 0; // height of the stream reported by the demuxer
133   int iWidth = 0; // width of the stream reported by the demuxer
134   double fAspect = 0; // display aspect of stream
135   bool bVFR = false; // variable framerate
136   bool bPTSInvalid = false; // pts cannot be trusted (avi's).
137   bool bForcedAspect = false; // aspect is forced from container
138   int iOrientation = 0; // orientation of the video in degrees counter clockwise
139   int iBitsPerPixel = 0;
140   int iBitRate = 0;
141 
142   AVColorSpace colorSpace = AVCOL_SPC_UNSPECIFIED;
143   AVColorRange colorRange = AVCOL_RANGE_UNSPECIFIED;
144   AVColorPrimaries colorPrimaries = AVCOL_PRI_UNSPECIFIED;
145   AVColorTransferCharacteristic colorTransferCharacteristic = AVCOL_TRC_UNSPECIFIED;
146 
147   std::shared_ptr<AVMasteringDisplayMetadata> masteringMetaData;
148   std::shared_ptr<AVContentLightMetadata> contentLightMetaData;
149 
150   std::string stereo_mode; // expected stereo mode
151 };
152 
153 class CDemuxStreamAudio : public CDemuxStream
154 {
155 public:
CDemuxStreamAudio()156   CDemuxStreamAudio()
157     : CDemuxStream()
158   {
159     iChannels = 0;
160     iSampleRate = 0;
161     iBlockAlign = 0;
162     iBitRate = 0;
163     iBitsPerSample = 0;
164     iChannelLayout = 0;
165     type = STREAM_AUDIO;
166   }
167 
168   ~CDemuxStreamAudio() override = default;
169 
170   std::string GetStreamType();
171 
172   int iChannels;
173   int iSampleRate;
174   int iBlockAlign;
175   int iBitRate;
176   int iBitsPerSample;
177   uint64_t iChannelLayout;
178   std::string m_channelLayoutName;
179 };
180 
181 class CDemuxStreamSubtitle : public CDemuxStream
182 {
183 public:
CDemuxStreamSubtitle()184   CDemuxStreamSubtitle()
185     : CDemuxStream()
186   {
187     type = STREAM_SUBTITLE;
188   }
189 };
190 
191 class CDemuxStreamTeletext : public CDemuxStream
192 {
193 public:
CDemuxStreamTeletext()194   CDemuxStreamTeletext()
195     : CDemuxStream()
196   {
197     type = STREAM_TELETEXT;
198   }
199 };
200 
201 class CDemuxStreamRadioRDS : public CDemuxStream
202 {
203 public:
CDemuxStreamRadioRDS()204   CDemuxStreamRadioRDS()
205     : CDemuxStream()
206   {
207     type = STREAM_RADIO_RDS;
208   }
209 };
210 
211 class CDVDDemux
212 {
213 public:
CDVDDemux()214   CDVDDemux()
215     : m_demuxerId(NewGuid())
216   {
217   }
218   virtual ~CDVDDemux() = default;
219 
220 
221   /*
222    * Reset the entire demuxer (same result as closing and opening it)
223    */
224   virtual bool Reset() = 0;
225 
226   /*
227    * Aborts any internal reading that might be stalling main thread
228    * NOTICE - this can be called from another thread
229    */
Abort()230   virtual void Abort() {}
231 
232   /*
233    * Flush the demuxer, if any data is kept in buffers, this should be freed now
234    */
235   virtual void Flush() = 0;
236 
237   /*
238    * Read a packet, returns NULL on error
239    *
240    */
241   virtual DemuxPacket* Read() = 0;
242 
243   /*
244    * Seek, time in msec calculated from stream start
245    */
246   virtual bool SeekTime(double time, bool backwards = false, double* startpts = NULL) = 0;
247 
248   /*
249    * Seek to a specified chapter.
250    * startpts can be updated to the point where display should start
251    */
252   virtual bool SeekChapter(int chapter, double* startpts = NULL) { return false; }
253 
254   /*
255    * Get the number of chapters available
256    */
GetChapterCount()257   virtual int GetChapterCount() { return 0; }
258 
259   /*
260    * Get current chapter
261    */
GetChapter()262   virtual int GetChapter() { return 0; }
263 
264   /*
265    * Get the name of a chapter
266    * \param strChapterName[out] Name of chapter
267    * \param chapterIdx -1 for current chapter, else a chapter index
268    */
269   virtual void GetChapterName(std::string& strChapterName, int chapterIdx = -1) {}
270 
271   /*
272    * Get the position of a chapter
273    * \param chapterIdx -1 for current chapter, else a chapter index
274    */
275   virtual int64_t GetChapterPos(int chapterIdx = -1) { return 0; }
276 
277   /*
278    * Set the playspeed, if demuxer can handle different
279    * speeds of playback
280    */
SetSpeed(int iSpeed)281   virtual void SetSpeed(int iSpeed) {}
282 
283   /*
284    * Let demuxer know if we want to fill demux queue
285    */
FillBuffer(bool mode)286   virtual void FillBuffer(bool mode) {}
287 
288   /*
289    * returns the total time in msec
290    */
GetStreamLength()291   virtual int GetStreamLength() { return 0; }
292 
293   /*
294    * returns the stream or NULL on error
295    */
GetStream(int64_t demuxerId,int iStreamId)296   virtual CDemuxStream* GetStream(int64_t demuxerId, int iStreamId) const
297   {
298     return GetStream(iStreamId);
299   };
300 
301   virtual std::vector<CDemuxStream*> GetStreams() const = 0;
302 
303   /*
304    * return nr of streams, 0 if none
305    */
306   virtual int GetNrOfStreams() const = 0;
307 
308   /*
309    * get a list of available programs
310    */
GetPrograms(std::vector<ProgramInfo> & programs)311   virtual int GetPrograms(std::vector<ProgramInfo>& programs) { return 0; }
312 
313   /*
314    * select programs
315    */
SetProgram(int progId)316   virtual void SetProgram(int progId) {}
317 
318   /*
319    * returns opened filename
320    */
GetFileName()321   virtual std::string GetFileName() { return ""; }
322 
323   /*
324    * return nr of subtitle streams, 0 if none
325    */
326   int GetNrOfSubtitleStreams();
327 
328   /*
329    * return a user-presentable codec name of the given stream
330    */
GetStreamCodecName(int64_t demuxerId,int iStreamId)331   virtual std::string GetStreamCodecName(int64_t demuxerId, int iStreamId)
332   {
333     return GetStreamCodecName(iStreamId);
334   };
335 
336   /*
337    * enable / disable demux stream
338    */
EnableStream(int64_t demuxerId,int id,bool enable)339   virtual void EnableStream(int64_t demuxerId, int id, bool enable) { EnableStream(id, enable); };
340 
341   /*
342   * implicitly enable and open a demux stream for playback
343   */
OpenStream(int64_t demuxerId,int id)344   virtual void OpenStream(int64_t demuxerId, int id) { OpenStream(id); };
345 
346   /*
347    * sets desired width / height for video stream
348    * adaptive demuxers like DASH can use this to choose best fitting video stream
349    */
SetVideoResolution(int width,int height)350   virtual void SetVideoResolution(int width, int height){};
351 
352   /*
353   * return the id of the demuxer
354   */
GetDemuxerId()355   int64_t GetDemuxerId() { return m_demuxerId; };
356 
357 protected:
EnableStream(int id,bool enable)358   virtual void EnableStream(int id, bool enable){};
OpenStream(int id)359   virtual void OpenStream(int id){};
360   virtual CDemuxStream* GetStream(int iStreamId) const = 0;
GetStreamCodecName(int iStreamId)361   virtual std::string GetStreamCodecName(int iStreamId) { return ""; };
362 
363   int GetNrOfStreams(StreamType streamType);
364 
365   int64_t m_demuxerId;
366 
367 private:
NewGuid()368   int64_t NewGuid()
369   {
370     static int64_t guid = 0;
371     return guid++;
372   }
373 };
374