summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h')
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h494
1 files changed, 314 insertions, 180 deletions
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h
index 7407830..25e39e2 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/AudioDecoder.h
@@ -16,45 +16,51 @@
16#endif 16#endif
17#include <stdint.h> 17#include <stdint.h>
18 18
19namespace kodi { namespace addon { class CInstanceAudioDecoder; }} 19namespace kodi
20{
21namespace addon
22{
23 class CInstanceAudioDecoder;
24} /* namespace addon */
25} /* namespace kodi */
20 26
21extern "C" 27extern "C"
22{ 28{
23 29
24 typedef struct AddonProps_AudioDecoder 30typedef struct AddonProps_AudioDecoder
25 { 31{
26 int dummy; 32 int dummy;
27 } AddonProps_AudioDecoder; 33} AddonProps_AudioDecoder;
28 34
29 typedef struct AddonToKodiFuncTable_AudioDecoder 35typedef struct AddonToKodiFuncTable_AudioDecoder
30 { 36{
31 void* kodiInstance; 37 void* kodiInstance;
32 } AddonToKodiFuncTable_AudioDecoder; 38} AddonToKodiFuncTable_AudioDecoder;
33 39
34 struct AddonInstance_AudioDecoder; 40struct AddonInstance_AudioDecoder;
35 typedef struct KodiToAddonFuncTable_AudioDecoder 41typedef struct KodiToAddonFuncTable_AudioDecoder
36 { 42{
37 kodi::addon::CInstanceAudioDecoder* addonInstance; 43 kodi::addon::CInstanceAudioDecoder* addonInstance;
38 bool (__cdecl* init) (const AddonInstance_AudioDecoder* instance, 44 bool (__cdecl* init)(const AddonInstance_AudioDecoder* instance,
39 const char* file, unsigned int filecache, 45 const char* file, unsigned int filecache,
40 int* channels, int* samplerate, 46 int* channels, int* samplerate,
41 int* bitspersample, int64_t* totaltime, 47 int* bitspersample, int64_t* totaltime,
42 int* bitrate, AEDataFormat* format, 48 int* bitrate, AEDataFormat* format,
43 const AEChannel** info); 49 const AEChannel** info);
44 int (__cdecl* read_pcm) (const AddonInstance_AudioDecoder* instance, uint8_t* buffer, int size, int* actualsize); 50 int (__cdecl* read_pcm)(const AddonInstance_AudioDecoder* instance, uint8_t* buffer, int size, int* actualsize);
45 int64_t (__cdecl* seek) (const AddonInstance_AudioDecoder* instance, int64_t time); 51 int64_t (__cdecl* seek)(const AddonInstance_AudioDecoder* instance, int64_t time);
46 bool (__cdecl* read_tag) (const AddonInstance_AudioDecoder* instance, 52 bool (__cdecl* read_tag)(const AddonInstance_AudioDecoder* instance,
47 const char* file, char* title, 53 const char* file, char* title,
48 char* artist, int* length); 54 char* artist, int* length);
49 int (__cdecl* track_count) (const AddonInstance_AudioDecoder* instance, const char* file); 55 int (__cdecl* track_count)(const AddonInstance_AudioDecoder* instance, const char* file);
50 } KodiToAddonFuncTable_AudioDecoder; 56} KodiToAddonFuncTable_AudioDecoder;
51 57
52 typedef struct AddonInstance_AudioDecoder 58typedef struct AddonInstance_AudioDecoder
53 { 59{
54 AddonProps_AudioDecoder props; 60 AddonProps_AudioDecoder props;
55 AddonToKodiFuncTable_AudioDecoder toKodi; 61 AddonToKodiFuncTable_AudioDecoder toKodi;
56 KodiToAddonFuncTable_AudioDecoder toAddon; 62 KodiToAddonFuncTable_AudioDecoder toAddon;
57 } AddonInstance_AudioDecoder; 63} AddonInstance_AudioDecoder;
58 64
59} /* extern "C" */ 65} /* extern "C" */
60 66
@@ -63,167 +69,295 @@ namespace kodi
63namespace addon 69namespace addon
64{ 70{
65 71
66 class CInstanceAudioDecoder : public IAddonInstance 72//==============================================================================
73///
74/// \addtogroup cpp_kodi_addon_audiodecoder
75/// @brief \cpp_class{ kodi::addon::CInstanceAudioDecoder }
76/// **Audio decoder add-on instance**
77///
78/// For audio decoders as binary add-ons. This class implements a way to handle
79/// special types of audio files.
80///
81/// The add-on handles loading of the source file and outputting the audio stream
82/// for consumption by the player.
83///
84/// The addon.xml defines the capabilities of this add-on.
85///
86/// @note The option to have multiple instances is possible with audio-decoder
87/// add-ons. This is useful, since some playback engines are riddled by global
88/// variables, making decoding of multiple streams using the same instance
89/// impossible.
90///
91///
92/// ----------------------------------------------------------------------------
93///
94/// **Here's an example on addon.xml:**
95/// ~~~~~~~~~~~~~{.xml}
96/// <extension
97/// point="kodi.audiodecoder"
98/// name="2sf"
99/// extension=".2sf|.mini2sf"
100/// tags="true"
101/// library_@PLATFORM@="@LIBRARY_FILENAME@"/>
102/// ~~~~~~~~~~~~~
103///
104/// Description to audio decoder related addon.xml values:
105/// | Name | Description
106/// |:------------------------------|----------------------------------------
107/// | <b>`point`</b> | Addon type specification<br>At all addon types and for this kind always <b>"kodi.audiodecoder"</b>.
108/// | <b>`library_@PLATFORM@`</b> | Sets the used library name, which is automatically set by cmake at addon build.
109/// | <b>`name`</b> | The name of the decoder used in Kodi for display.
110/// | <b>`extension`</b> | The file extensions / styles supported by this addon.
111/// | <b>`tags`</b> | Boolean to point out that addon can bring own information to replayed file, if <b>`false`</b> only the file name is used as info.<br>If <b>`true`</b>, \ref CInstanceAudioDecoder::ReadTag is used and must be implemented.
112///
113/// --------------------------------------------------------------------------
114///
115/// **Here is a code example how this addon is used:**
116///
117/// ~~~~~~~~~~~~~{.cpp}
118/// #include <kodi/addon-instance/AudioDecoder.h>
119///
120/// class CMyAudioDecoder : public ::kodi::addon::CInstanceAudioDecoder
121/// {
122/// public:
123/// CMyAudioDecoder(KODI_HANDLE instance);
124///
125/// bool Init(const std::string& filename, unsigned int filecache,
126/// int& channels, int& samplerate,
127/// int& bitspersample, int64_t& totaltime,
128/// int& bitrate, AEDataFormat& format,
129/// std::vector<AEChannel>& channellist) override;
130/// int ReadPCM(uint8_t* buffer, int size, int& actualsize) override;
131/// };
132///
133/// CMyAudioDecoder::CMyAudioDecoder(KODI_HANDLE instance)
134/// : CInstanceAudioDecoder(instance)
135/// {
136/// ...
137/// }
138///
139/// bool CMyAudioDecoder::Init(const std::string& filename, unsigned int filecache,
140/// int& channels, int& samplerate,
141/// int& bitspersample, int64_t& totaltime,
142/// int& bitrate, AEDataFormat& format,
143/// std::vector<AEChannel>& channellist)
144/// {
145/// ...
146/// return true;
147/// }
148///
149/// int CMyAudioDecoder::ReadPCM(uint8_t* buffer, int size, int& actualsize)
150/// {
151/// ...
152/// return 0;
153/// }
154///
155///
156/// /*----------------------------------------------------------------------*/
157///
158/// class CMyAddon : public ::kodi::addon::CAddonBase
159/// {
160/// public:
161/// CMyAddon() { }
162/// ADDON_STATUS CreateInstance(int instanceType,
163/// std::string instanceID,
164/// KODI_HANDLE instance,
165/// KODI_HANDLE& addonInstance) override;
166/// };
167///
168/// /* If you use only one instance in your add-on, can be instanceType and
169/// * instanceID ignored */
170/// ADDON_STATUS CMyAddon::CreateInstance(int instanceType,
171/// std::string instanceID,
172/// KODI_HANDLE instance,
173/// KODI_HANDLE& addonInstance)
174/// {
175/// if (instanceType == ADDON_INSTANCE_AUDIODECODER)
176/// {
177/// kodi::Log(ADDON_LOG_NOTICE, "Creating my audio decoder");
178/// addonInstance = new CMyAudioDecoder(instance);
179/// return ADDON_STATUS_OK;
180/// }
181/// else if (...)
182/// {
183/// ...
184/// }
185/// return ADDON_STATUS_UNKNOWN;
186/// }
187///
188/// ADDONCREATOR(CMyAddon)
189/// ~~~~~~~~~~~~~
190///
191/// The destruction of the example class `CMyAudioDecoder` is called from
192/// Kodi's header. Manually deleting the add-on instance is not required.
193///
194class ATTRIBUTE_HIDDEN CInstanceAudioDecoder : public IAddonInstance
195{
196public:
197 //==========================================================================
198 /// @ingroup cpp_kodi_addon_audiodecoder
199 /// @brief Class constructor
200 ///
201 /// @param[in] instance The addon instance class handler given by Kodi
202 /// at \ref kodi::addon::CAddonBase::CreateInstance(...)
203 /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to
204 /// allow compatibility to older Kodi versions.
205 /// @note Recommended to set.
206 ///
207 explicit CInstanceAudioDecoder(KODI_HANDLE instance, const std::string& kodiVersion = "")
208 : IAddonInstance(ADDON_INSTANCE_AUDIODECODER,
209 !kodiVersion.empty() ? kodiVersion
210 : GetKodiTypeVersion(ADDON_INSTANCE_AUDIODECODER))
67 { 211 {
68 public: 212 if (CAddonBase::m_interface->globalSingleInstance != nullptr)
69 //========================================================================== 213 throw std::logic_error("kodi::addon::CInstanceAudioDecoder: Creation of multiple together with single instance way is not allowed!");
70 /// @brief Class constructor
71 ///
72 /// @param[in] instance The from Kodi given instance given be
73 /// add-on CreateInstance call with instance
74 /// id ADDON_INSTANCE_AUDIODECODER.
75 explicit CInstanceAudioDecoder(KODI_HANDLE instance)
76 : IAddonInstance(ADDON_INSTANCE_AUDIODECODER)
77 {
78 if (CAddonBase::m_interface->globalSingleInstance != nullptr)
79 throw std::logic_error("kodi::addon::CInstanceAudioDecoder: Creation of multiple together with single instance way is not allowed!");
80 214
81 SetAddonStruct(instance); 215 SetAddonStruct(instance);
82 } 216 }
83 //-------------------------------------------------------------------------- 217 //--------------------------------------------------------------------------
84
85 //==========================================================================
86 /// @ingroup cpp_kodi_addon_audiodecoder
87 /// @brief Initialize a decoder
88 ///
89 /// @param[in] filename The file to read
90 /// @param[in] filecache The file cache size
91 /// @param[out] channels Number of channels in output stream
92 /// @param[out] samplerate Samplerate of output stream
93 /// @param[out] bitspersample Bits per sample in output stream
94 /// @param[out] totaltime Total time for stream
95 /// @param[out] bitrate Average bitrate of input stream
96 /// @param[out] format Data format for output stream
97 /// @param[out] channellist Channel mapping for output stream
98 /// @return true if successfully done, otherwise
99 /// false
100 ///
101 virtual bool Init(const std::string& filename, unsigned int filecache,
102 int& channels, int& samplerate,
103 int& bitspersample, int64_t& totaltime,
104 int& bitrate, AEDataFormat& format,
105 std::vector<AEChannel>& channellist) = 0;
106 //--------------------------------------------------------------------------
107
108 //==========================================================================
109 /// @ingroup cpp_kodi_addon_audiodecoder
110 /// @brief Produce some noise
111 ///
112 /// @param[in] buffer Output buffer
113 /// @param[in] size Size of output buffer
114 /// @param[out] actualsize Actual number of bytes written to output buffer
115 /// @return Return with following possible values:
116 /// | Value | Description |
117 /// |:-----:|:-----------------------------|
118 /// | 0 | on success
119 /// | -1 | on end of stream
120 /// | 1 | on failure
121 ///
122 virtual int ReadPCM(uint8_t* buffer, int size, int& actualsize) = 0;
123 //--------------------------------------------------------------------------
124
125 //==========================================================================
126 /// @ingroup cpp_kodi_addon_audiodecoder
127 /// @brief Seek in output stream
128 ///
129 /// @param[in] time Time position to seek to in milliseconds
130 /// @return Time position seek ended up on
131 ///
132 virtual int64_t Seek(int64_t time) { return time; }
133 //--------------------------------------------------------------------------
134
135 //==========================================================================
136 /// @ingroup cpp_kodi_addon_audiodecoder
137 /// @brief Read tag of a file
138 ///
139 /// @param[in] file File to read tag for
140 /// @param[out] title Title of file
141 /// @param[out] artist Artist of file
142 /// @param[out] length Length of file
143 /// @return True on success, false on failure
144 ///
145 virtual bool ReadTag(const std::string& file, std::string& title, std::string& artist, int& length) { return false; }
146 //--------------------------------------------------------------------------
147
148 //==========================================================================
149 /// @ingroup cpp_kodi_addon_audiodecoder
150 /// @brief Get number of tracks in a file
151 ///
152 /// @param[in] file File to read tag for
153 /// @return Number of tracks in file
154 ///
155 virtual int TrackCount(const std::string& file) { return 1; }
156 //--------------------------------------------------------------------------
157
158 private:
159 void SetAddonStruct(KODI_HANDLE instance)
160 {
161 if (instance == nullptr)
162 throw std::logic_error("kodi::addon::CInstanceAudioDecoder: Creation with empty addon structure not allowed, table must be given from Kodi!");
163 218
164 m_instanceData = static_cast<AddonInstance_AudioDecoder*>(instance); 219 //==========================================================================
220 /// @ingroup cpp_kodi_addon_audiodecoder
221 /// @brief Initialize a decoder
222 ///
223 /// @param[in] filename The file to read
224 /// @param[in] filecache The file cache size
225 /// @param[out] channels Number of channels in output stream
226 /// @param[out] samplerate Samplerate of output stream
227 /// @param[out] bitspersample Bits per sample in output stream
228 /// @param[out] totaltime Total time for stream
229 /// @param[out] bitrate Average bitrate of input stream
230 /// @param[out] format Data format for output stream
231 /// @param[out] channellist Channel mapping for output stream
232 /// @return true if successfully done, otherwise
233 /// false
234 ///
235 virtual bool Init(const std::string& filename, unsigned int filecache,
236 int& channels, int& samplerate,
237 int& bitspersample, int64_t& totaltime,
238 int& bitrate, AEDataFormat& format,
239 std::vector<AEChannel>& channellist) = 0;
240 //--------------------------------------------------------------------------
165 241
166 m_instanceData->toAddon.addonInstance = this; 242 //==========================================================================
167 m_instanceData->toAddon.init = ADDON_Init; 243 /// @ingroup cpp_kodi_addon_audiodecoder
168 m_instanceData->toAddon.read_pcm = ADDON_ReadPCM; 244 /// @brief Produce some noise
169 m_instanceData->toAddon.seek = ADDON_Seek; 245 ///
170 m_instanceData->toAddon.read_tag = ADDON_ReadTag; 246 /// @param[in] buffer Output buffer
171 m_instanceData->toAddon.track_count = ADDON_TrackCount; 247 /// @param[in] size Size of output buffer
172 } 248 /// @param[out] actualsize Actual number of bytes written to output buffer
249 /// @return Return with following possible values:
250 /// | Value | Description |
251 /// |:-----:|:-----------------------------|
252 /// | 0 | on success
253 /// | -1 | on end of stream
254 /// | 1 | on failure
255 ///
256 virtual int ReadPCM(uint8_t* buffer, int size, int& actualsize) = 0;
257 //--------------------------------------------------------------------------
173 258
174 inline static bool ADDON_Init(const AddonInstance_AudioDecoder* instance, const char* file, unsigned int filecache, 259 //==========================================================================
175 int* channels, int* samplerate, 260 /// @ingroup cpp_kodi_addon_audiodecoder
176 int* bitspersample, int64_t* totaltime, 261 /// @brief Seek in output stream
177 int* bitrate, AEDataFormat* format, 262 ///
178 const AEChannel** info) 263 /// @param[in] time Time position to seek to in milliseconds
179 { 264 /// @return Time position seek ended up on
180 instance->toAddon.addonInstance->m_channelList.clear(); 265 ///
181 bool ret = instance->toAddon.addonInstance->Init(file, filecache, *channels, 266 virtual int64_t Seek(int64_t time) { return time; }
182 *samplerate, *bitspersample, 267 //--------------------------------------------------------------------------
183 *totaltime, *bitrate, *format,
184 instance->toAddon.addonInstance->m_channelList);
185 if (!instance->toAddon.addonInstance->m_channelList.empty())
186 {
187 if (instance->toAddon.addonInstance->m_channelList.back() != AE_CH_NULL)
188 instance->toAddon.addonInstance->m_channelList.push_back(AE_CH_NULL);
189 *info = instance->toAddon.addonInstance->m_channelList.data();
190 }
191 else
192 *info = nullptr;
193 return ret;
194 }
195 268
196 inline static int ADDON_ReadPCM(const AddonInstance_AudioDecoder* instance, uint8_t* buffer, int size, int* actualsize) 269 //==========================================================================
197 { 270 /// @ingroup cpp_kodi_addon_audiodecoder
198 return instance->toAddon.addonInstance->ReadPCM(buffer, size, *actualsize); 271 /// @brief Read tag of a file
199 } 272 ///
273 /// @param[in] file File to read tag for
274 /// @param[out] title Title of file
275 /// @param[out] artist Artist of file
276 /// @param[out] length Length of file
277 /// @return True on success, false on failure
278 ///
279 virtual bool ReadTag(const std::string& file, std::string& title, std::string& artist, int& length) { return false; }
280 //--------------------------------------------------------------------------
200 281
201 inline static int64_t ADDON_Seek(const AddonInstance_AudioDecoder* instance, int64_t time) 282 //==========================================================================
202 { 283 /// @ingroup cpp_kodi_addon_audiodecoder
203 return instance->toAddon.addonInstance->Seek(time); 284 /// @brief Get number of tracks in a file
204 } 285 ///
286 /// @param[in] file File to read tag for
287 /// @return Number of tracks in file
288 ///
289 virtual int TrackCount(const std::string& file) { return 1; }
290 //--------------------------------------------------------------------------
291
292private:
293 void SetAddonStruct(KODI_HANDLE instance)
294 {
295 if (instance == nullptr)
296 throw std::logic_error("kodi::addon::CInstanceAudioDecoder: Creation with empty addon structure not allowed, table must be given from Kodi!");
297
298 m_instanceData = static_cast<AddonInstance_AudioDecoder*>(instance);
205 299
206 inline static bool ADDON_ReadTag(const AddonInstance_AudioDecoder* instance, const char* file, char* title, char* artist, int* length) 300 m_instanceData->toAddon.addonInstance = this;
301 m_instanceData->toAddon.init = ADDON_Init;
302 m_instanceData->toAddon.read_pcm = ADDON_ReadPCM;
303 m_instanceData->toAddon.seek = ADDON_Seek;
304 m_instanceData->toAddon.read_tag = ADDON_ReadTag;
305 m_instanceData->toAddon.track_count = ADDON_TrackCount;
306 }
307
308 inline static bool ADDON_Init(const AddonInstance_AudioDecoder* instance, const char* file, unsigned int filecache,
309 int* channels, int* samplerate,
310 int* bitspersample, int64_t* totaltime,
311 int* bitrate, AEDataFormat* format,
312 const AEChannel** info)
313 {
314 instance->toAddon.addonInstance->m_channelList.clear();
315 bool ret = instance->toAddon.addonInstance->Init(file, filecache, *channels,
316 *samplerate, *bitspersample,
317 *totaltime, *bitrate, *format,
318 instance->toAddon.addonInstance->m_channelList);
319 if (!instance->toAddon.addonInstance->m_channelList.empty())
207 { 320 {
208 std::string intTitle; 321 if (instance->toAddon.addonInstance->m_channelList.back() != AE_CH_NULL)
209 std::string intArtist; 322 instance->toAddon.addonInstance->m_channelList.push_back(AE_CH_NULL);
210 bool ret = instance->toAddon.addonInstance->ReadTag(file, intTitle, intArtist, *length); 323 *info = instance->toAddon.addonInstance->m_channelList.data();
211 if (ret)
212 {
213 strncpy(title, intTitle.c_str(), ADDON_STANDARD_STRING_LENGTH_SMALL-1);
214 strncpy(artist, intArtist.c_str(), ADDON_STANDARD_STRING_LENGTH_SMALL-1);
215 }
216 return ret;
217 } 324 }
325 else
326 *info = nullptr;
327 return ret;
328 }
218 329
219 inline static int ADDON_TrackCount(const AddonInstance_AudioDecoder* instance, const char* file) 330 inline static int ADDON_ReadPCM(const AddonInstance_AudioDecoder* instance, uint8_t* buffer, int size, int* actualsize)
331 {
332 return instance->toAddon.addonInstance->ReadPCM(buffer, size, *actualsize);
333 }
334
335 inline static int64_t ADDON_Seek(const AddonInstance_AudioDecoder* instance, int64_t time)
336 {
337 return instance->toAddon.addonInstance->Seek(time);
338 }
339
340 inline static bool ADDON_ReadTag(const AddonInstance_AudioDecoder* instance, const char* file, char* title, char* artist, int* length)
341 {
342 std::string intTitle;
343 std::string intArtist;
344 bool ret = instance->toAddon.addonInstance->ReadTag(file, intTitle, intArtist, *length);
345 if (ret)
220 { 346 {
221 return instance->toAddon.addonInstance->TrackCount(file); 347 strncpy(title, intTitle.c_str(), ADDON_STANDARD_STRING_LENGTH_SMALL-1);
348 strncpy(artist, intArtist.c_str(), ADDON_STANDARD_STRING_LENGTH_SMALL-1);
222 } 349 }
350 return ret;
351 }
352
353 inline static int ADDON_TrackCount(const AddonInstance_AudioDecoder* instance, const char* file)
354 {
355 return instance->toAddon.addonInstance->TrackCount(file);
356 }
223 357
224 std::vector<AEChannel> m_channelList; 358 std::vector<AEChannel> m_channelList;
225 AddonInstance_AudioDecoder* m_instanceData; 359 AddonInstance_AudioDecoder* m_instanceData;
226 }; 360};
227 361
228} /* namespace addon */ 362} /* namespace addon */
229} /* namespace kodi */ 363} /* namespace kodi */