/* * Copyright (C) 2017 Team XBMC * http://xbmc.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBMC; see the file COPYING. If not, see * . * */ #pragma once #include "../AddonBase.h" #include "../StreamCrypto.h" #include "../StreamCodec.h" #ifdef BUILD_KODI_ADDON #include "../DemuxPacket.h" #else #include "cores/VideoPlayer/Interface/Addon/DemuxPacket.h" #endif namespace kodi { namespace addon { class CInstanceVideoCodec; } } extern "C" { enum VIDEOCODEC_FORMAT { UnknownVideoFormat = 0, VideoFormatYV12, VideoFormatI420, MaxVideoFormats }; struct VIDEOCODEC_INITDATA { enum Codec { CodecUnknown = 0, CodecVp8, CodecH264, CodecVp9 } codec; STREAMCODEC_PROFILE codecProfile; //UnknownVideoFormat is terminator VIDEOCODEC_FORMAT *videoFormats; uint32_t width, height; const uint8_t *extraData; unsigned int extraDataSize; CRYPTO_INFO cryptoInfo; }; struct VIDEOCODEC_PICTURE { enum VideoPlane { YPlane = 0, UPlane, VPlane, MaxPlanes = 3, }; enum Flags : uint32_t { FLAG_DROP, FLAG_DRAIN }; VIDEOCODEC_FORMAT videoFormat; uint32_t flags; uint32_t width, height; uint8_t *decodedData; size_t decodedDataSize; uint32_t planeOffsets[VideoPlane::MaxPlanes]; uint32_t stride[VideoPlane::MaxPlanes]; int64_t pts; void *buffer; //< will be passed in release_frame_buffer }; enum VIDEOCODEC_RETVAL { VC_NONE = 0, //< noop VC_ERROR, //< an error occured, no other messages will be returned VC_BUFFER, //< the decoder needs more data VC_PICTURE, //< the decoder got a picture VC_EOF, //< the decoder signals EOF }; // this are properties given to the addon on create // at this time we have no parameters for the addon typedef struct AddonProps_VideoCodec { int dummy; } AddonProps_VideoCodec; struct AddonInstance_VideoCodec; typedef struct KodiToAddonFuncTable_VideoCodec { kodi::addon::CInstanceVideoCodec* addonInstance; //! \brief Opens a codec bool (__cdecl* open) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData); //! \brief Reconfigures a codec bool (__cdecl* reconfigure) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData); //! \brief Feed codec if requested from GetPicture() (return VC_BUFFER) bool (__cdecl* add_data) (const AddonInstance_VideoCodec* instance, const DemuxPacket *packet); //! \brief Get a decoded picture / request new data VIDEOCODEC_RETVAL (__cdecl* get_picture) (const AddonInstance_VideoCodec* instance, VIDEOCODEC_PICTURE *picture); //! \brief Get the name of this video decoder const char *(__cdecl* get_name) (const AddonInstance_VideoCodec* instance); //! \brief Reset the codec void (__cdecl* reset)(const AddonInstance_VideoCodec* instance); } KodiToAddonFuncTable_VideoCodec; typedef struct AddonToKodiFuncTable_VideoCodec { KODI_HANDLE kodiInstance; bool(*get_frame_buffer)(void* kodiInstance, VIDEOCODEC_PICTURE *picture); void(*release_frame_buffer)(void* kodiInstance, void *buffer); } AddonToKodiFuncTable_VideoCodec; typedef struct AddonInstance_VideoCodec { AddonProps_VideoCodec props; AddonToKodiFuncTable_VideoCodec toKodi; KodiToAddonFuncTable_VideoCodec toAddon; } AddonInstance_VideoCodec; } namespace kodi { namespace addon { class CInstanceVideoCodec : public IAddonInstance { public: explicit CInstanceVideoCodec(KODI_HANDLE instance) : IAddonInstance(ADDON_INSTANCE_VIDEOCODEC) { if (CAddonBase::m_interface->globalSingleInstance != nullptr) throw std::logic_error("kodi::addon::CInstanceVideoCodec: Creation of multiple together with single instance way is not allowed!"); SetAddonStruct(instance); } ~CInstanceVideoCodec() override = default; //! \copydoc CInstanceVideoCodec::Open virtual bool Open(VIDEOCODEC_INITDATA &initData) { return false; }; //! \copydoc CInstanceVideoCodec::Reconfigure virtual bool Reconfigure(VIDEOCODEC_INITDATA &initData) { return false; }; //! \copydoc CInstanceVideoCodec::AddData virtual bool AddData(const DemuxPacket &packet) { return false; }; //! \copydoc CInstanceVideoCodec::GetPicture virtual VIDEOCODEC_RETVAL GetPicture(VIDEOCODEC_PICTURE &picture) { return VC_ERROR; }; //! \copydoc CInstanceVideoCodec::GetName virtual const char *GetName() { return nullptr; }; //! \copydoc CInstanceVideoCodec::Reset virtual void Reset() {}; /*! * @brief AddonToKodi interface */ //! \copydoc CInstanceVideoCodec::GetFrameBuffer bool GetFrameBuffer(VIDEOCODEC_PICTURE &picture) { return m_instanceData->toKodi.get_frame_buffer(m_instanceData->toKodi.kodiInstance, &picture); } //! \copydoc CInstanceVideoCodec::ReleaseFrameBuffer void ReleaseFrameBuffer(void *buffer) { return m_instanceData->toKodi.release_frame_buffer(m_instanceData->toKodi.kodiInstance, buffer); } private: void SetAddonStruct(KODI_HANDLE instance) { if (instance == nullptr) throw std::logic_error("kodi::addon::CInstanceVideoCodec: Creation with empty addon structure not allowed, table must be given from Kodi!"); m_instanceData = static_cast(instance); m_instanceData->toAddon.addonInstance = this; m_instanceData->toAddon.open = ADDON_Open; m_instanceData->toAddon.reconfigure = ADDON_Reconfigure; m_instanceData->toAddon.add_data = ADDON_AddData; m_instanceData->toAddon.get_picture = ADDON_GetPicture; m_instanceData->toAddon.get_name = ADDON_GetName; m_instanceData->toAddon.reset = ADDON_Reset; } inline static bool ADDON_Open(const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData) { return instance->toAddon.addonInstance->Open(*initData); } inline static bool ADDON_Reconfigure(const AddonInstance_VideoCodec* instance, VIDEOCODEC_INITDATA *initData) { return instance->toAddon.addonInstance->Reconfigure(*initData); } inline static bool ADDON_AddData(const AddonInstance_VideoCodec* instance, const DemuxPacket *packet) { return instance->toAddon.addonInstance->AddData(*packet); } inline static VIDEOCODEC_RETVAL ADDON_GetPicture(const AddonInstance_VideoCodec* instance, VIDEOCODEC_PICTURE *picture) { return instance->toAddon.addonInstance->GetPicture(*picture); } inline static const char *ADDON_GetName(const AddonInstance_VideoCodec* instance) { return instance->toAddon.addonInstance->GetName(); } inline static void ADDON_Reset(const AddonInstance_VideoCodec* instance) { return instance->toAddon.addonInstance->Reset(); } AddonInstance_VideoCodec* m_instanceData; }; } // namespace addon } // namespace kodi