diff options
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.h | 494 |
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 | ||
| 19 | namespace kodi { namespace addon { class CInstanceAudioDecoder; }} | 19 | namespace kodi |
| 20 | { | ||
| 21 | namespace addon | ||
| 22 | { | ||
| 23 | class CInstanceAudioDecoder; | ||
| 24 | } /* namespace addon */ | ||
| 25 | } /* namespace kodi */ | ||
| 20 | 26 | ||
| 21 | extern "C" | 27 | extern "C" |
| 22 | { | 28 | { |
| 23 | 29 | ||
| 24 | typedef struct AddonProps_AudioDecoder | 30 | typedef struct AddonProps_AudioDecoder |
| 25 | { | 31 | { |
| 26 | int dummy; | 32 | int dummy; |
| 27 | } AddonProps_AudioDecoder; | 33 | } AddonProps_AudioDecoder; |
| 28 | 34 | ||
| 29 | typedef struct AddonToKodiFuncTable_AudioDecoder | 35 | typedef struct AddonToKodiFuncTable_AudioDecoder |
| 30 | { | 36 | { |
| 31 | void* kodiInstance; | 37 | void* kodiInstance; |
| 32 | } AddonToKodiFuncTable_AudioDecoder; | 38 | } AddonToKodiFuncTable_AudioDecoder; |
| 33 | 39 | ||
| 34 | struct AddonInstance_AudioDecoder; | 40 | struct AddonInstance_AudioDecoder; |
| 35 | typedef struct KodiToAddonFuncTable_AudioDecoder | 41 | typedef 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 | 58 | typedef 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 | |||
| 63 | namespace addon | 69 | namespace 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 | /// | ||
| 194 | class ATTRIBUTE_HIDDEN CInstanceAudioDecoder : public IAddonInstance | ||
| 195 | { | ||
| 196 | public: | ||
| 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 | |||
| 292 | private: | ||
| 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 */ |
