diff options
author | xbmc <fernetmenta@online.de> | 2016-02-02 22:38:22 +0100 |
---|---|---|
committer | Rainer Hochecker <fernetmenta@online.de> | 2016-03-05 08:38:00 +0100 |
commit | 0540ad644c26a66376a5714ac722fe64a5bd1e3c (patch) | |
tree | a193f6780290b8a528993ab4ed54f7e6b392fb98 | |
parent | 1e51c05f2e5fe0fbeee20ea9ed18a9262612f5c9 (diff) |
Add binary addon InputStream
20 files changed, 1508 insertions, 6 deletions
diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 46c453198b..c43fa236ad 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -296,6 +296,12 @@ 7C4458BD161E203800A905F6 /* Screenshot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4458BB161E203800A905F6 /* Screenshot.cpp */; }; 7C45DBE910F325C400D4BBF3 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */; }; 7C4705AE12EF584C00369E51 /* AddonInstaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4705AC12EF584C00369E51 /* AddonInstaller.cpp */; }; + 7C4B649F1C86F6BD000E1F74 /* AddonCallbacksInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B649D1C86F6BC000E1F74 /* AddonCallbacksInputStream.cpp */; }; + 7C4B64A01C86F6BD000E1F74 /* AddonCallbacksInputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B649D1C86F6BC000E1F74 /* AddonCallbacksInputStream.cpp */; }; + 7C4B64A31C86F6D8000E1F74 /* InputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B64A11C86F6D8000E1F74 /* InputStream.cpp */; }; + 7C4B64A41C86F6D8000E1F74 /* InputStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B64A11C86F6D8000E1F74 /* InputStream.cpp */; }; + 7C4B64A71C86F712000E1F74 /* InputStreamAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B64A51C86F712000E1F74 /* InputStreamAddon.cpp */; }; + 7C4B64A81C86F712000E1F74 /* InputStreamAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4B64A51C86F712000E1F74 /* InputStreamAddon.cpp */; }; 7C4E6F721829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */; }; 7C4E6F731829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */; }; 7C525DF5195E2D8100BE3482 /* SaveFileStateJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C525DF4195E2D8100BE3482 /* SaveFileStateJob.cpp */; }; @@ -2722,6 +2728,12 @@ 7C45DBE810F325C400D4BBF3 /* DAVDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVDirectory.h; sourceTree = "<group>"; }; 7C4705AC12EF584C00369E51 /* AddonInstaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonInstaller.cpp; sourceTree = "<group>"; }; 7C4705AD12EF584C00369E51 /* AddonInstaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonInstaller.h; sourceTree = "<group>"; }; + 7C4B649D1C86F6BC000E1F74 /* AddonCallbacksInputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonCallbacksInputStream.cpp; sourceTree = "<group>"; }; + 7C4B649E1C86F6BC000E1F74 /* AddonCallbacksInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonCallbacksInputStream.h; sourceTree = "<group>"; }; + 7C4B64A11C86F6D8000E1F74 /* InputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputStream.cpp; sourceTree = "<group>"; }; + 7C4B64A21C86F6D8000E1F74 /* InputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputStream.h; sourceTree = "<group>"; }; + 7C4B64A51C86F712000E1F74 /* InputStreamAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputStreamAddon.cpp; sourceTree = "<group>"; }; + 7C4B64A61C86F712000E1F74 /* InputStreamAddon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputStreamAddon.h; sourceTree = "<group>"; }; 7C4CED9F1C5E681E00BAD6CE /* DVDDemuxPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDDemuxPacket.h; sourceTree = "<group>"; }; 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogSubtitles.cpp; sourceTree = "<group>"; }; 7C4E6F711829AA9700F1068F /* GUIDialogSubtitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogSubtitles.h; sourceTree = "<group>"; }; @@ -4541,7 +4553,7 @@ E46F7C2B0F77219700C25D29 /* ZeroconfOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZeroconfOSX.h; sourceTree = "<group>"; }; E46F7C2C0F77219700C25D29 /* ZeroconfOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZeroconfOSX.cpp; sourceTree = "<group>"; }; E47252BF175115F9001C1AAA /* Codesign.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Codesign.command; sourceTree = "<group>"; }; - E4991089174D0D2600741B6D /* Kodi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = Kodi.app; path = .app; sourceTree = BUILT_PRODUCTS_DIR; }; + E4991089174D0D2600741B6D /* Kodi.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kodi.app; sourceTree = BUILT_PRODUCTS_DIR; }; E499108B174D0D2600741B6D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; E499108D174D0D2600741B6D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; E499108F174D0D2600741B6D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; @@ -4920,6 +4932,8 @@ isa = PBXGroup; children = ( EDE8C7091C7F60C200A86ECC /* kodi-addon-dev-kit */, + 7C4B649D1C86F6BC000E1F74 /* AddonCallbacksInputStream.cpp */, + 7C4B649E1C86F6BC000E1F74 /* AddonCallbacksInputStream.h */, 9A999F1B1C67B77600E4E0D5 /* AddonBuilder.cpp */, 9A999F1C1C67B77600E4E0D5 /* AddonBuilder.h */, 7C226E3C1BA5F61C00185CE0 /* AddonCallbacksAudioEngine.cpp */, @@ -4969,6 +4983,8 @@ 18B49FFB1152BFA5001AF8A6 /* IAddon.h */, DF2401241B41A26E001E02DA /* ImageResource.cpp */, DF2401251B41A26E001E02DA /* ImageResource.h */, + 7C4B64A11C86F6D8000E1F74 /* InputStream.cpp */, + 7C4B64A21C86F6D8000E1F74 /* InputStream.h */, 395C2A071A9F06EB00EBC7AD /* LanguageResource.cpp */, 395C2A081A9F06EB00EBC7AD /* LanguageResource.h */, 183FDF8811AF0B0500B81E9C /* PluginSource.cpp */, @@ -7697,6 +7713,8 @@ E38E15570D25F9FA00618676 /* DVDInputStreams */ = { isa = PBXGroup; children = ( + 7C4B64A51C86F712000E1F74 /* InputStreamAddon.cpp */, + 7C4B64A61C86F712000E1F74 /* InputStreamAddon.h */, E38E15670D25F9FA00618676 /* dvdnav */, E38E15580D25F9FA00618676 /* DllDvdNav.h */, E38E15590D25F9FA00618676 /* DVDFactoryInputStream.cpp */, @@ -9246,6 +9264,7 @@ E38E1FA90D25F9FD00618676 /* VideoPlayerSubtitle.cpp in Sources */, 395C2A141A9F072400EBC7AD /* ResourceFile.cpp in Sources */, E38E1FAA0D25F9FD00618676 /* VideoPlayerVideo.cpp in Sources */, + 7C4B649F1C86F6BD000E1F74 /* AddonCallbacksInputStream.cpp in Sources */, DF91E93E1C0A26350011084D /* SDLMain.mm in Sources */, E38E1FAB0D25F9FD00618676 /* DVDStreamInfo.cpp in Sources */, E38E1FAC0D25F9FD00618676 /* DVDFactorySubtitle.cpp in Sources */, @@ -9623,6 +9642,7 @@ 7CCA95BF1BC6E6670091D308 /* RendererVDA.cpp in Sources */, 431AE5DA109C1A63007428C3 /* OverlayRendererUtil.cpp in Sources */, 7C45DBE910F325C400D4BBF3 /* DAVDirectory.cpp in Sources */, + 7C4B64A71C86F712000E1F74 /* InputStreamAddon.cpp in Sources */, F592568810FBF2E100D2C91D /* ConvolutionKernels.cpp in Sources */, F5DC87E2110A287400EE1B15 /* RingBuffer.cpp in Sources */, F5F244651110DC6B009126C6 /* FileOperationJob.cpp in Sources */, @@ -9827,6 +9847,7 @@ F5E1053F140AA38100175026 /* PeripheralHID.cpp in Sources */, F5E10540140AA38100175026 /* PeripheralNIC.cpp in Sources */, F5E10541140AA38100175026 /* PeripheralNyxboard.cpp in Sources */, + 7C4B64A31C86F6D8000E1F74 /* InputStream.cpp in Sources */, 39520F911C3174EE00272121 /* AddonSystemSettings.cpp in Sources */, F5E10542140AA38100175026 /* PeripheralTuner.cpp in Sources */, F5E10544140AA38100175026 /* GUIDialogPeripheralSettings.cpp in Sources */, @@ -10698,6 +10719,7 @@ E4991319174E5DAD00741B6D /* GUITextureGL.cpp in Sources */, E499131A174E5DAD00741B6D /* GUITextureGLES.cpp in Sources */, E499131B174E5DAD00741B6D /* GUIToggleButtonControl.cpp in Sources */, + 7C4B64A41C86F6D8000E1F74 /* InputStream.cpp in Sources */, E499131C174E5DAD00741B6D /* GUIVideoControl.cpp in Sources */, E499131D174E5DAD00741B6D /* GUIVisualisationControl.cpp in Sources */, E499131E174E5DAD00741B6D /* GUIWindow.cpp in Sources */, @@ -10895,6 +10917,7 @@ E49913F5174E5FB000741B6D /* PVRChannelGroup.cpp in Sources */, E49913F6174E5FB000741B6D /* PVRChannelGroupInternal.cpp in Sources */, E49913F7174E5FB000741B6D /* PVRChannelGroups.cpp in Sources */, + 7C4B64A01C86F6BD000E1F74 /* AddonCallbacksInputStream.cpp in Sources */, E49913F8174E5FB000741B6D /* PVRChannelGroupsContainer.cpp in Sources */, E49913F9174E5FB000741B6D /* GUIDialogPVRChannelManager.cpp in Sources */, E49913FA174E5FB000741B6D /* GUIDialogPVRChannelsOSD.cpp in Sources */, @@ -11164,6 +11187,7 @@ F55BA71017AB2293002A36D1 /* RenderFlags.cpp in Sources */, F59EED7F17AD5174005BB7C6 /* ApplicationPlayer.cpp in Sources */, DF28DF4E17B8379E0077F41A /* ProfilesOperations.cpp in Sources */, + 7C4B64A81C86F712000E1F74 /* InputStreamAddon.cpp in Sources */, DF29BCE91B5D911800904347 /* AddonEvent.cpp in Sources */, DFD882F717DD1A5B001516FE /* AddonPythonInvoker.cpp in Sources */, DFD882E817DD189E001516FE /* StringValidation.cpp in Sources */, diff --git a/addons/kodi.inputstream/addon.xml b/addons/kodi.inputstream/addon.xml new file mode 100644 index 0000000000..94eb4068fd --- /dev/null +++ b/addons/kodi.inputstream/addon.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<addon id="kodi.inputstream" version="1.0.0" provider-name="Team Kodi"> + <backwards-compatibility abi="1.0.0"/> + <requires> + <import addon="xbmc.core" version="0.1.0"/> + </requires> +</addon>
\ No newline at end of file diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 8255ee0bcf..c03e3dcfed 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -13683,7 +13683,10 @@ msgctxt "#24047" msgid "This add-on can't be uninstalled" msgstr "" -#empty string with id 24048 +#: xbmc/addons/Addon.cpp +msgctxt "#24048" +msgid "VideoPlayer InputStream" +msgstr "" #: xbmc/filesystem/AddonsDirectory.cpp msgctxt "#24049" diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 1331ab051c..7e55657b90 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -200,6 +200,7 @@ <ClCompile Include="..\..\xbmc\addons\GUIViewStateAddonBrowser.cpp" /> <ClCompile Include="..\..\xbmc\addons\GUIWindowAddonBrowser.cpp" /> <ClCompile Include="..\..\xbmc\addons\ImageResource.cpp" /> + <ClCompile Include="..\..\xbmc\addons\InputStream.cpp" /> <ClCompile Include="..\..\xbmc\addons\LanguageResource.cpp" /> <ClCompile Include="..\..\xbmc\addons\PluginSource.cpp" /> <ClCompile Include="..\..\xbmc\addons\Repository.cpp" /> @@ -925,6 +926,29 @@ <ClInclude Include="..\..\xbmc\addons\AudioDecoder.h" /> <ClInclude Include="..\..\xbmc\addons\ContextMenuAddon.h" /> <ClInclude Include="..\..\xbmc\addons\ImageResource.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_adsp_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_adsp_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audiodec_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audiodec_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audioengine_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_inputstream_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_inputstream_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\kodi_vfs_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_cpp_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_audioenc_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_audioenc_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_codec_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_epg_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_pvr_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_pvr_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_scr_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_scr_types.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_stream_utils.hpp" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_vis_dll.h" /> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_vis_types.h" /> + <ClInclude Include="..\..\xbmc\addons\InputStream.h" /> <ClInclude Include="..\..\xbmc\addons\Webinterface.h" /> <ClInclude Include="..\..\xbmc\addons\UISoundsResource.h" /> <ClInclude Include="..\..\xbmc\addons\LanguageResource.h" /> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index a014bc9af4..aa57a03555 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -388,6 +388,9 @@ <Filter Include="cores\Process"> <UniqueIdentifier>{45ab3e06-b8d3-44f5-994e-d6130258c99c}</UniqueIdentifier> </Filter> + <Filter Include="addons\include"> + <UniqueIdentifier>{353ba04b-a59a-4fb3-90d0-630277d5305b}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\xbmc\win32\pch.cpp"> @@ -3283,6 +3286,9 @@ <ClCompile Include="..\..\xbmc\cores\VideoPlayer\Process\ProcessInfo.cpp"> <Filter>cores\Process</Filter> </ClCompile> + <ClCompile Include="..\..\xbmc\addons\InputStream.cpp"> + <Filter>addons</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\xbmc\win32\pch.h"> @@ -6314,6 +6320,75 @@ <ClInclude Include="..\..\xbmc\cores\VideoPlayer\Process\ProcessInfo.h"> <Filter>cores\Process</Filter> </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_adsp_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_adsp_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audiodec_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audiodec_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_audioengine_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_inputstream_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_inputstream_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\kodi_vfs_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_cpp_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_addon_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_audioenc_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_audioenc_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_codec_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_epg_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_pvr_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_pvr_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_scr_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_scr_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_stream_utils.hpp"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_vis_dll.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\include\xbmc_vis_types.h"> + <Filter>addons\include</Filter> + </ClInclude> + <ClInclude Include="..\..\xbmc\addons\InputStream.h"> + <Filter>addons</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc"> diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 00db97d8de..8fc1a23d4d 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -411,4 +411,4 @@ endif() # add custom target "supported_addons" that returns all addons that are supported on this platform string(REPLACE ";" " " ALL_ADDONS_BUILDING "${ALL_ADDONS_BUILDING}") -add_custom_target(supported_addons COMMAND ${CMAKE_COMMAND} -E echo "ALL_ADDONS_BUILDING: ${ALL_ADDONS_BUILDING}" VERBATIM) +add_custom_target(supported_addons COMMAND ${CMAKE_COMMAND} -E echo "ALL_ADDONS_BUILDING: ${ALL_ADDONS_BUILDING}" VERBATIM)
\ No newline at end of file diff --git a/project/cmake/installdata/addon-bindings.txt b/project/cmake/installdata/addon-bindings.txt index d495819786..fbcdf99a9d 100644 --- a/project/cmake/installdata/addon-bindings.txt +++ b/project/cmake/installdata/addon-bindings.txt @@ -16,6 +16,8 @@ xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_scr_types.h xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_vis_dll.h xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_vis_types.h xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_stream_utils.hpp +xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h +xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_addon.h xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_adsp.h xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h @@ -23,4 +25,4 @@ xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_codec.h xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxPacket.h xbmc/cores/AudioEngine/Utils/AEChannelData.h -xbmc/filesystem/IFileTypes.h
\ No newline at end of file +xbmc/filesystem/IFileTypes.h diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp index e187823be3..14e767e9fc 100644 --- a/xbmc/addons/Addon.cpp +++ b/xbmc/addons/Addon.cpp @@ -102,6 +102,7 @@ static const TypeMapping types[] = {"kodi.resource.language", ADDON_RESOURCE_LANGUAGE, 24026, "DefaultAddonLanguage.png" }, {"kodi.resource.uisounds", ADDON_RESOURCE_UISOUNDS, 24006, "DefaultAddonUISounds.png" }, {"kodi.adsp", ADDON_ADSPDLL, 24135, "DefaultAddonAudioDSP.png" }, + {"kodi.inputstream", ADDON_INPUTSTREAM, 24048, "DefaultAddonInputstream.png" }, }; const std::string TranslateType(const ADDON::TYPE &type, bool pretty/*=false*/) diff --git a/xbmc/addons/AddonBuilder.cpp b/xbmc/addons/AddonBuilder.cpp index 77ec92a41b..e3011a1e02 100644 --- a/xbmc/addons/AddonBuilder.cpp +++ b/xbmc/addons/AddonBuilder.cpp @@ -23,6 +23,7 @@ #include "addons/AudioEncoder.h" #include "addons/ContextMenuAddon.h" #include "addons/ImageResource.h" +#include "addons/InputStream.h" #include "addons/LanguageResource.h" #include "addons/PluginSource.h" #include "addons/Repository.h" @@ -84,6 +85,7 @@ std::shared_ptr<IAddon> CAddonBuilder::Build() case ADDON_ADSPDLL: case ADDON_AUDIOENCODER: case ADDON_AUDIODECODER: + case ADDON_INPUTSTREAM: { // begin temporary platform handling for Dlls // ideally platforms issues will be handled by C-Pluff // this is not an attempt at a solution @@ -127,6 +129,8 @@ std::shared_ptr<IAddon> CAddonBuilder::Build() return CAudioEncoder::FromExtension(std::move(m_props), m_extPoint); else if (type == ADDON_AUDIODECODER) return CAudioDecoder::FromExtension(std::move(m_props), m_extPoint); + else if (type == ADDON_INPUTSTREAM) + return CInputStream::FromExtension(std::move(m_props), m_extPoint); else return std::make_shared<CScreenSaver>(std::move(m_props));; } @@ -202,9 +206,11 @@ AddonPtr CAddonBuilder::FromProps(AddonProps addonProps) return AddonPtr(new CRepository(std::move(addonProps))); case ADDON_CONTEXT_ITEM: return AddonPtr(new CContextMenuAddon(std::move(addonProps))); + case ADDON_INPUTSTREAM: + return AddonPtr(new CInputStream(std::move(addonProps))); default: break; } return AddonPtr(); } -}
\ No newline at end of file +} diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h index 496b5eb5e1..db1f7a13e4 100644 --- a/xbmc/addons/IAddon.h +++ b/xbmc/addons/IAddon.h @@ -39,6 +39,7 @@ namespace ADDON ADDON_SKIN, ADDON_PVRDLL, ADDON_ADSPDLL, + ADDON_INPUTSTREAM, ADDON_SCRIPT, ADDON_SCRIPT_WEATHER, ADDON_SUBTITLE_MODULE, diff --git a/xbmc/addons/InputStream.cpp b/xbmc/addons/InputStream.cpp new file mode 100644 index 0000000000..6b10156f26 --- /dev/null +++ b/xbmc/addons/InputStream.cpp @@ -0,0 +1,505 @@ +/* + * Copyright (C) 2016 Team Kodi + * + * 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 + * <http://www.gnu.org/licenses/>. + * + */ +#include "InputStream.h" +#include "utils/StringUtils.h" +#include "utils/log.h" +#include "cores/VideoPlayer/DVDDemuxers/DVDDemux.h" + + +namespace ADDON +{ + +std::unique_ptr<CInputStream> CInputStream::FromExtension(AddonProps props, const cp_extension_t* ext) +{ + std::string listitemprops = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@listitemprops"); + std::string extensions = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@extension"); + std::string name(ext->plugin->identifier); + return std::unique_ptr<CInputStream>(new CInputStream(std::move(props), + std::move(name), + std::move(listitemprops), + std::move(extensions))); +} + +CInputStream::CInputStream(AddonProps props, std::string name, std::string listitemprops, std::string extensions) +: InputStreamDll(std::move(props)) +{ + m_fileItemProps = StringUtils::Tokenize(listitemprops, "|"); + for (auto &key : m_fileItemProps) + { + StringUtils::Trim(key); + key = name + "." + key; + } + + m_extensionsList = StringUtils::Tokenize(extensions, "|"); + for (auto &ext : m_extensionsList) + { + StringUtils::Trim(ext); + } +} + +bool CInputStream::Supports(CFileItem &fileitem) +{ + std::string extension = URIUtils::GetExtension(fileitem.GetPath()); + bool match = false; + for (auto &ext : m_extensionsList) + { + if (ext == extension) + { + match = true; + break; + } + } + if (!match) + return false; + + if (!m_pStruct) + return false; + + std::string pathList; + try + { + pathList = m_pStruct->GetPathList(); + } + catch (std::exception &e) + { + return false; + } + + m_pathList = StringUtils::Tokenize(pathList, "|"); + for (auto &path : m_pathList) + { + StringUtils::Trim(path); + } + + match = false; + for (auto &path : m_pathList) + { + if (path.empty()) + continue; + + if (fileitem.GetPath().compare(0, path.length(), path) == 0) + { + match = true; + break; + } + } + if (!match) + return false; + + return true; +} + +bool CInputStream::Open(CFileItem &fileitem) +{ + INPUTSTREAM props; + props.m_nCountInfoValues = 0; + for (auto &key : m_fileItemProps) + { + if (fileitem.GetProperty(key).isNull()) + continue; + props.m_ListItemProperties[props.m_nCountInfoValues].m_strKey = key.c_str(); + props.m_ListItemProperties[props.m_nCountInfoValues].m_strValue = fileitem.GetProperty(key).asString().c_str(); + props.m_nCountInfoValues++; + } + props.m_strURL = fileitem.GetPath().c_str(); + + bool ret = false; + try + { + ret = m_pStruct->Open(props); + if (ret) + m_caps = m_pStruct->GetCapabilities(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::Open - could not open stream"); + return false; + } + + UpdateStreams(); + return ret; +} + +void CInputStream::Close() +{ + try + { + m_pStruct->Close(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::Close - could not close stream"); + } +} + +// IDisplayTime +int CInputStream::GetTotalTime() +{ + int ret = 0; + try + { + ret = m_pStruct->GetTotalTime(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::GetTotalTime - error"); + } + return ret; +} + +int CInputStream::GetTime() +{ + int ret = 0; + try + { + ret = m_pStruct->GetTime(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::GetTime - error");; + } + return ret; +} + +// IPosTime +bool CInputStream::PosTime(int ms) +{ + bool ret = false; + try + { + ret = m_pStruct->PosTime(ms); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::PosTime - error");; + } + return ret; +} + +// IDemux +void CInputStream::UpdateStreams() +{ + DisposeStreams(); + + INPUTSTREAM_IDS streamIDs; + try + { + streamIDs = m_pStruct->GetStreamIds(); + } + catch (std::exception &e) + { + DisposeStreams(); + CLog::Log(LOGERROR, "CInputStream::UpdateStreams - error GetStreamIds"); + return; + } + + if (streamIDs.m_streamCount > INPUTSTREAM_IDS::MAX_STREAM_COUNT) + { + DisposeStreams(); + return; + } + + for (int i=0; i<streamIDs.m_streamCount; i++) + { + INPUTSTREAM_INFO stream; + try + { + stream = m_pStruct->GetStream(streamIDs.m_streamIds[i]); + } + catch (std::exception &e) + { + DisposeStreams(); + CLog::Log(LOGERROR, "CInputStream::GetTotalTime - error GetStream"); + return; + } + + if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_NONE) + continue; + + std::string codecName(stream.m_codecName); + StringUtils::ToLower(codecName); + AVCodec *codec = avcodec_find_decoder_by_name(codecName.c_str()); + if (!codec) + continue; + + CDemuxStream *demuxStream; + + if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_AUDIO) + { + CDemuxStreamAudio *audioStream = new CDemuxStreamAudio(); + + audioStream->iChannels = stream.m_Channels; + audioStream->iSampleRate = stream.m_SampleRate; + audioStream->iBlockAlign = stream.m_BlockAlign; + audioStream->iBitRate = stream.m_BitRate; + audioStream->iBitsPerSample = stream.m_BitsPerSample; + demuxStream = audioStream; + } + else if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_VIDEO) + { + CDemuxStreamVideo *videoStream = new CDemuxStreamVideo(); + + videoStream->iFpsScale = stream.m_FpsScale; + videoStream->iFpsRate = stream.m_FpsRate; + videoStream->iWidth = stream.m_Width; + videoStream->iHeight = stream.m_Height; + videoStream->fAspect = stream.m_Aspect; + videoStream->stereo_mode = "mono"; + demuxStream = videoStream; + } + else if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_SUBTITLE) + { + // TODO needs identifier in INPUTSTREAM_INFO + continue; + } + else + continue; + + demuxStream->iId = i; + demuxStream->codec = codec->id; + demuxStream->bandwidth = stream.m_Bandwidth; + demuxStream->codecName = stream.m_codecInternalName; + demuxStream->iPhysicalId = streamIDs.m_streamIds[i]; + demuxStream->language[0] = stream.m_language[0]; + demuxStream->language[1] = stream.m_language[1]; + demuxStream->language[2] = stream.m_language[2]; + demuxStream->language[3] = stream.m_language[3]; + + if (stream.m_ExtraData && stream.m_ExtraSize) + { + demuxStream->ExtraData = new uint8_t[stream.m_ExtraSize]; + demuxStream->ExtraSize = stream.m_ExtraSize; + for (unsigned int j=0; j<stream.m_ExtraSize; j++) + demuxStream->ExtraData[j] = stream.m_ExtraData[j]; + } + + m_streams[i] = demuxStream; + } +} + +void CInputStream::DisposeStreams() +{ + for (auto &stream : m_streams) + delete stream.second; + m_streams.clear(); +} + +int CInputStream::GetNrOfStreams() +{ + return m_streams.size(); +} + +CDemuxStream* CInputStream::GetStream(int iStreamId) +{ + std::map<int, CDemuxStream*>::iterator it = m_streams.find(iStreamId); + if (it != m_streams.end()) + return it->second; + + return nullptr; +} + +void CInputStream::EnableStream(int iStreamId, bool enable) +{ + std::map<int, CDemuxStream*>::iterator it = m_streams.find(iStreamId); + if (it == m_streams.end()) + return; + + try + { + m_pStruct->EnableStream(it->second->iPhysicalId, enable); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::EnableStream - error");; + } +} + +DemuxPacket* CInputStream::ReadDemux() +{ + DemuxPacket* pPacket = nullptr; + try + { + pPacket = m_pStruct->DemuxRead(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::ReadDemux - error"); + return nullptr; + } + + if (!pPacket) + { + return nullptr; + } + else if (pPacket->iStreamId == DMX_SPECIALID_STREAMINFO) + { + UpdateStreams(); + } + else if (pPacket->iStreamId == DMX_SPECIALID_STREAMCHANGE) + { + UpdateStreams(); + } + + int id = 0;; + for (auto &stream : m_streams) + { + if (stream.second->iPhysicalId == pPacket->iStreamId) + { + pPacket->iStreamId = id; + return pPacket; + } + id++; + } + return pPacket; +} + +bool CInputStream::SeekTime(int time, bool backward, double* startpts) +{ + bool ret = false; + try + { + ret = m_pStruct->DemuxSeekTime(time, backward, startpts); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::SeekTime - error");; + } + return ret; +} + +void CInputStream::AbortDemux() +{ + try + { + m_pStruct->DemuxAbort(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::AbortDemux - error");; + } +} + +void CInputStream::FlushDemux() +{ + try + { + m_pStruct->DemuxFlush(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::FlushDemux - error");; + } +} + +void CInputStream::SetSpeed(int iSpeed) +{ + try + { + m_pStruct->DemuxSetSpeed(iSpeed); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::SetSpeed - error");; + } +} + +int CInputStream::ReadStream(uint8_t* buf, unsigned int size) +{ + int ret = -1; + try + { + ret = m_pStruct->ReadStream(buf, size); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::ReadStream - error");; + } + return ret; +} + +int64_t CInputStream::SeekStream(int64_t offset, int whence) +{ + int64_t ret = -1; + try + { + ret = m_pStruct->SeekStream(offset, whence); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::SeekStream - error");; + } + return ret; +} + +int64_t CInputStream::PositionStream() +{ + int64_t ret = -1; + try + { + ret = m_pStruct->PositionStream(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::PositionStream - error");; + } + return ret; +} + +int64_t CInputStream::LengthStream() +{ + int64_t ret = -1; + try + { + ret = m_pStruct->LengthStream(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::LengthStream - error");; + } + return ret; +} + +void CInputStream::PauseStream(double time) +{ + try + { + m_pStruct->PauseStream(time); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::PauseStream - error");; + } +} + +bool CInputStream::IsRealTimeStream() +{ + bool ret = false; + try + { + ret = m_pStruct->IsRealTimeStream(); + } + catch (std::exception &e) + { + CLog::Log(LOGERROR, "CInputStream::IsRealTimeStream - error");; + } + return ret; +} + +} /*namespace ADDON*/ + diff --git a/xbmc/addons/InputStream.h b/xbmc/addons/InputStream.h new file mode 100644 index 0000000000..57031b90c5 --- /dev/null +++ b/xbmc/addons/InputStream.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 Team Kodi + * + * 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 + * <http://www.gnu.org/licenses/>. + * + */ +#pragma once + +#include "AddonDll.h" +#include "addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h" +#include "FileItem.h" +#include <vector> +#include <map> + +typedef DllAddon<InputStreamAddonFunctions, INPUTSTREAM_PROPS> DllInputStream; + +class CDemuxStream; + +namespace ADDON +{ + typedef CAddonDll<DllInputStream, InputStreamAddonFunctions, INPUTSTREAM_PROPS> InputStreamDll; + + class CInputStream : public InputStreamDll + { + public: + + static std::unique_ptr<CInputStream> FromExtension(AddonProps props, const cp_extension_t* ext); + + explicit CInputStream(AddonProps props) + : InputStreamDll(std::move(props)) + {}; + CInputStream(AddonProps props, std::string name, std::string listitemprops, std::string extensions); + virtual ~CInputStream() {} + + bool Supports(CFileItem &fileitem); + bool Open(CFileItem &fileitem); + void Close(); + + bool HasDemux() { return m_caps.m_supportsIDemux; }; + bool HasPosTime() { return m_caps.m_supportsIPosTime; }; + bool HasDisplayTime() { return m_caps.m_supportsIDisplayTime; }; + bool CanPause() { return m_caps.m_supportsPause; }; + bool CanSeek() { return m_caps.m_supportsSeek; }; + + // IDisplayTime + int GetTotalTime(); + int GetTime(); + + // IPosTime + bool PosTime(int ms); + + // demux + int GetNrOfStreams(); + CDemuxStream* GetStream(int iStreamId); + DemuxPacket* ReadDemux(); + bool SeekTime(int time, bool backward, double* startpts); + void AbortDemux(); + void FlushDemux(); + void SetSpeed(int iSpeed); + void EnableStream(int iStreamId, bool enable); + + // stream + int ReadStream(uint8_t* buf, unsigned int size); + int64_t SeekStream(int64_t offset, int whence); + int64_t PositionStream(); + int64_t LengthStream(); + void PauseStream(double time); + bool IsRealTimeStream(); + + protected: + void UpdateStreams(); + void DisposeStreams(); + + std::vector<std::string> m_fileItemProps; + std::vector<std::string> m_pathList; + std::vector<std::string> m_extensionsList; + INPUTSTREAM_CAPABILITIES m_caps; + std::map<int, CDemuxStream*> m_streams; + }; + +} /*namespace ADDON*/ diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile index 22e7eadf24..27cc506453 100644 --- a/xbmc/addons/Makefile +++ b/xbmc/addons/Makefile @@ -21,6 +21,7 @@ SRCS=Addon.cpp \ GUIViewStateAddonBrowser.cpp \ GUIWindowAddonBrowser.cpp \ ImageResource.cpp \ + InputStream.cpp \ LanguageResource.cpp \ PluginSource.cpp \ Repository.cpp \ diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk index 9bcf95a6d0..ae0914d8cc 100644 --- a/xbmc/addons/addon-bindings.mk +++ b/xbmc/addons/addon-bindings.mk @@ -10,6 +10,8 @@ BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_audiodec_dll.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_audiodec_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_codec_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_epg_types.h +BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h +BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_dll.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/xbmc_scr_dll.h @@ -25,4 +27,4 @@ BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_pvr.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/libXBMC_codec.h BINDINGS+=xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxPacket.h BINDINGS+=xbmc/cores/AudioEngine/Utils/AEChannelData.h -BINDINGS+=xbmc/filesystem/IFileTypes.h
\ No newline at end of file +BINDINGS+=xbmc/filesystem/IFileTypes.h diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h new file mode 100644 index 0000000000..2207160cde --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h @@ -0,0 +1,248 @@ +#pragma once + +/* +* Copyright (C) 2005-2016 Team Kodi +* http://kodi.tv +* +* 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 Kodi; see the file COPYING. If not, see +* <http://www.gnu.org/licenses/>. +* +*/ + +#include "kodi_inputstream_types.h" +#include "xbmc_addon_dll.h" + +/*! +* Functions that the InputStream client add-on must implement, but some can be empty. +* +* The 'remarks' field indicates which methods should be implemented, and which ones are optional. +*/ + +extern "C" +{ + /*! + * Open a stream. + * @param props + * @return True if the stream has been opened successfully, false otherwise. + * @remarks + */ + bool Open(INPUTSTREAM& props); + + /*! + * Close an open stream. + * @remarks + */ + void Close(void); + + /*! + * Get path/url for this addon. + * @remarks + */ + const char* GetPathList(void); + + /*! + * Get Capabilities of this addon. + * @remarks + */ + struct INPUTSTREAM_CAPABILITIES GetCapabilities(); + + + /*! + * Get IDs of available streams + * @remarks + */ + INPUTSTREAM_IDS GetStreamIds(); + + /*! + * Get stream properties of a stream. + * @param streamId unique id of stream + * @return struc of stream properties + * @remarks + */ + INPUTSTREAM_INFO GetStream(int streamid); + + /*! + * Enable or disable a stream. + * A disabled stream does not send demux packets + * @param streamId unique id of stream + * @param enable true for enable, false for disable + * @remarks + */ + void EnableStream(int streamid, bool enable); + + /*! + * Reset the demultiplexer in the add-on. + * @remarks Required if bHandlesDemuxing is set to true. + */ + void DemuxReset(void); + + /*! + * Abort the demultiplexer thread in the add-on. + * @remarks Required if bHandlesDemuxing is set to true. + */ + void DemuxAbort(void); + + /*! + * Flush all data that's currently in the demultiplexer buffer in the add-on. + * @remarks Required if bHandlesDemuxing is set to true. + */ + void DemuxFlush(void); + + /*! + * Read the next packet from the demultiplexer, if there is one. + * @return The next packet. + * If there is no next packet, then the add-on should return the + * packet created by calling AllocateDemuxPacket(0) on the callback. + * If the stream changed and XBMC's player needs to be reinitialised, + * then, the add-on should call AllocateDemuxPacket(0) on the + * callback, and set the streamid to DMX_SPECIALID_STREAMCHANGE and + * return the value. + * The add-on should return NULL if an error occured. + * @remarks Return NULL if this add-on won't provide this function. + */ + DemuxPacket* DemuxRead(void); + + /*! + * Notify the InputStream addon/demuxer that XBMC wishes to seek the stream by time + * Demuxer is required to set stream to an IDR frame + * @param time The absolute time since stream start + * @param backwards True to seek to keyframe BEFORE time, else AFTER + * @param startpts can be updated to point to where display should start + * @return True if the seek operation was possible + * @remarks Optional, and only used if addon has its own demuxer. + */ + bool DemuxSeekTime(int time, bool backwards, double *startpts); + + /*! + * Notify the InputStream addon/demuxer that XBMC wishes to change playback speed + * @param speed The requested playback speed + * @remarks Optional, and only used if addon has its own demuxer. + */ + void DemuxSetSpeed(int speed); + + + /*! + * Totel time in ms + * @remarks + */ + int GetTotalTime(); + + /*! + * Playing time in ms + * @remarks + */ + int GetTime(); + + /*! + * Positions inputstream to playing time given in ms + * @remarks + */ + bool PosTime(int ms); + + + /*! + * Check if the backend support pausing the currently playing stream + * This will enable/disable the pause button in XBMC based on the return value + * @return false if the InputStream addon/backend does not support pausing, true if possible + */ + bool CanPauseStream(); + + /*! + * Check if the backend supports seeking for the currently playing stream + * This will enable/disable the rewind/forward buttons in XBMC based on the return value + * @return false if the InputStream addon/backend does not support seeking, true if possible + */ + bool CanSeekStream(); + + + /*! + * Read from an open stream. + * @param pBuffer The buffer to store the data in. + * @param iBufferSize The amount of bytes to read. + * @return The amount of bytes that were actually read from the stream. + * @remarks Return -1 if this add-on won't provide this function. + */ + int ReadStream(uint8_t* pBuffer, unsigned int iBufferSize); + + /*! + * Seek in a stream. + * @param iPosition The position to seek to. + * @param iWhence ? + * @return The new position. + * @remarks Return -1 if this add-on won't provide this function. + */ + int64_t SeekStream(int64_t iPosition, int iWhence = SEEK_SET); + + /*! + * @return The position in the stream that's currently being read. + * @remarks Return -1 if this add-on won't provide this function. + */ + int64_t PositionStream(void); + + /*! + * @return The total length of the stream that's currently being read. + * @remarks Return -1 if this add-on won't provide this function. + */ + int64_t LengthStream(void); + + + /*! + * @brief Notify the InputStream addon that XBMC (un)paused the currently playing stream + */ + void PauseStream(double time); + + + /*! + * Check for real-time streaming + * @return true if current stream is real-time + */ + bool IsRealTimeStream(); + + /*! + * Called by XBMC to assign the function pointers of this add-on to pClient. + * @param pClient The struct to assign the function pointers to. + */ + void __declspec(dllexport) get_addon(struct InputStreamAddonFunctions* pClient) + { + pClient->Open = Open; + pClient->Close = Close; + pClient->GetPathList = GetPathList; + pClient->GetCapabilities = GetCapabilities; + + pClient->GetStreamIds = GetStreamIds; + pClient->GetStream = GetStream; + pClient->EnableStream = EnableStream; + pClient->DemuxReset = DemuxReset; + pClient->DemuxAbort = DemuxAbort; + pClient->DemuxFlush = DemuxFlush; + pClient->DemuxRead = DemuxRead; + pClient->DemuxSeekTime = DemuxSeekTime; + pClient->DemuxSetSpeed = DemuxSetSpeed; + + pClient->GetTotalTime = GetTotalTime; + pClient->GetTime = GetTime; + + pClient->PosTime = PosTime; + + pClient->CanPauseStream = CanPauseStream; + pClient->CanSeekStream = CanSeekStream; + + pClient->ReadStream = ReadStream; + pClient->SeekStream = SeekStream; + pClient->PositionStream = PositionStream; + pClient->LengthStream = LengthStream; + pClient->PauseStream = PauseStream; + pClient->IsRealTimeStream = IsRealTimeStream; + }; +}; diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h new file mode 100644 index 0000000000..b5abd29efe --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h @@ -0,0 +1,159 @@ +#pragma once + +/* + * Copyright (C) 2005-2016 Team Kodi + * http://kodi.tv + * + * 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 Kodi; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __cdecl +#define __cdecl +#endif + +#ifdef BUILD_KODI_ADDON +#include "DVDDemuxPacket.h" +#else +#include "cores/VideoPlayer/DVDDemuxers/DVDDemuxPacket.h" +#endif + +extern "C" { + + // this are properties given to the addon on create + // at this time we have no parameters for the addon + typedef struct INPUTSTREAM_PROPS + { + int dummy; + } INPUTSTREAM_PROPS; + + /*! + * @brief InputStream add-on capabilities. All capabilities are set to "false" as default. + */ + typedef struct INPUTSTREAM_CAPABILITIES + { + bool m_supportsIDemux; /*!< @brief supports interface IDemux */ + bool m_supportsIPosTime; /*!< @brief supports interface IPosTime */ + bool m_supportsIDisplayTime; /*!< @brief supports interface IDisplayTime */ + bool m_supportsSeek; /*!< @brief supports seek */ + bool m_supportsPause; /*!< @brief supports pause */ + } INPUTSTREAM_CAPABILITIES; + + /*! + * @brief structure of key/value pairs passed to addon on Open() + */ + typedef struct INPUTSTREAM + { + static const unsigned int MAX_INFO_COUNT = 8; + + const char *m_strURL; + + unsigned int m_nCountInfoValues; + struct LISTITEMPROPERTY + { + const char *m_strKey; + const char *m_strValue; + } m_ListItemProperties[MAX_INFO_COUNT]; + } INPUTSTREAM; + + /*! + * @brief Array of stream IDs + */ + typedef struct INPUTSTREAM_IDS + { + static const unsigned int MAX_STREAM_COUNT = 32; + unsigned int m_streamCount; + unsigned int m_streamIds[MAX_STREAM_COUNT]; + } INPUTSTREAM_IDS; + + /*! + * @brief stream properties + */ + typedef struct INPUTSTREAM_INFO + { + enum STREAM_TYPE + { + TYPE_NONE, + TYPE_VIDEO, + TYPE_AUDIO, + TYPE_SUBTITLE, + TYPE_TELETEXT + } m_streamType; + + char m_codecName[32]; /*!< @brief (required) name of codec according to ffmpeg */ + char m_codecInternalName[32]; /*!< @brief (optional) internal name of codec (selectionstream info) */ + unsigned int m_pID; /*!< @brief (required) physical index */ + unsigned int m_Bandwidth; /*!< @brief (optional) bandwidth of the stream (selectionstream info) */ + + const uint8_t *m_ExtraData; + unsigned int m_ExtraSize; + + char m_language[4]; /*!< @brief ISO 639 3-letter language code (empty string if undefined) */ + + unsigned int m_FpsScale; /*!< @brief Scale of 1000 and a rate of 29970 will result in 29.97 fps */ + unsigned int m_FpsRate; + unsigned int m_Height; /*!< @brief height of the stream reported by the demuxer */ + unsigned int m_Width; /*!< @brief width of the stream reported by the demuxer */ + float m_Aspect; /*!< @brief display aspect of stream */ + + unsigned int m_Channels; /*!< @brief (required) amount of channels */ + unsigned int m_SampleRate; /*!< @brief (required) sample rate */ + unsigned int m_BitRate; /*!< @brief (required) bit rate */ + unsigned int m_BitsPerSample; /*!< @brief (required) bits per sample */ + unsigned int m_BlockAlign; + } INPUTSTREAM_INFO; + + /*! + * @brief Structure to transfer the methods from xbmc_inputstream_dll.h to XBMC + */ + typedef struct InputStreamAddonFunctions + { + bool (__cdecl* Open)(INPUTSTREAM&); + void (__cdecl* Close)(void); + const char* (__cdecl* GetPathList)(void); + struct INPUTSTREAM_CAPABILITIES (__cdecl* GetCapabilities)(void); + + // IDemux + struct INPUTSTREAM_IDS (__cdecl* GetStreamIds)(); + struct INPUTSTREAM_INFO (__cdecl* GetStream)(int); + void (__cdecl* EnableStream)(int, bool); + void (__cdecl* DemuxReset)(void); + void (__cdecl* DemuxAbort)(void); + void (__cdecl* DemuxFlush)(void); + DemuxPacket* (__cdecl* DemuxRead)(void); + bool (__cdecl* DemuxSeekTime)(int, bool, double*); + void (__cdecl* DemuxSetSpeed)(int); + + // IDisplayTime + int (__cdecl* GetTotalTime)(void); + int (__cdecl* GetTime)(void); + + // IPosTime + bool (__cdecl* PosTime)(int); + + // Seekable (mandatory) + bool (__cdecl* CanPauseStream)(void); + bool (__cdecl* CanSeekStream)(void); + + int (__cdecl* ReadStream)(uint8_t*, unsigned int); + int64_t(__cdecl* SeekStream)(int64_t, int); + int64_t (__cdecl* PositionStream)(void); + int64_t (__cdecl* LengthStream)(void); + void (__cdecl* PauseStream)(double); + bool (__cdecl* IsRealTimeStream)(void); + } InputStreamAddonFunctions; +} + + diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp index 4176e085f0..751585ae21 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp @@ -26,6 +26,7 @@ #include "DVDInputStreamFFmpeg.h" #include "DVDInputStreamPVRManager.h" #include "DVDInputStreamRTMP.h" +#include "InputStreamAddon.h" #ifdef HAVE_LIBBLURAY #include "DVDInputStreamBluray.h" #endif @@ -37,12 +38,31 @@ #include "URL.h" #include "filesystem/File.h" #include "utils/URIUtils.h" +#include "addons/AddonManager.h" +#include "addons/InputStream.h" CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, CFileItem fileitem) { std::string file = fileitem.GetPath(); + ADDON::VECADDONS addons; + ADDON::CAddonMgr::GetInstance().GetAddons(addons, ADDON::ADDON_INPUTSTREAM); + for (size_t i=0; i<addons.size(); ++i) + { + std::shared_ptr<ADDON::CInputStream> input(std::static_pointer_cast<ADDON::CInputStream>(addons[i])); + ADDON::CInputStream* clone = new ADDON::CInputStream(*input); + ADDON_STATUS status = clone->Create(); + if (status == ADDON_STATUS_OK) + { + if (clone->Supports(fileitem)) + { + return new CInputStreamAddon(fileitem, clone); + } + delete clone; + } + } + if (fileitem.IsDiscImage()) { #ifdef HAVE_LIBBLURAY diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h index 8a0d006f39..b1664d52af 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h @@ -41,6 +41,7 @@ enum DVDStreamType DVDSTREAM_TYPE_MPLS = 10, DVDSTREAM_TYPE_BLURAY = 11, DVDSTREAM_TYPE_PVRMANAGER = 12, + DVDSTREAM_TYPE_ADDON = 13 }; #define SEEK_POSSIBLE 0x10 // flag used to check if protocol allows seeks diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp new file mode 100644 index 0000000000..de584a326a --- /dev/null +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2015 Team Kodi + * http://kodi.tv + * + * 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 Kodi; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "InputStreamAddon.h" +#include "addons/InputStream.h" +#include "cores/VideoPlayer/DVDClock.h" + +CInputStreamAddon::CInputStreamAddon(CFileItem& fileitem, ADDON::CInputStream *inputStream) +: CDVDInputStream(DVDSTREAM_TYPE_ADDON, fileitem), m_addon(inputStream) +{ + m_hasDemux = false; +} + +CInputStreamAddon::~CInputStreamAddon() +{ + Close(); + m_addon->Stop(); + delete m_addon; +} + +bool CInputStreamAddon::Open() +{ + bool ret = false; + if (m_addon) + ret = m_addon->Open(m_item); + if (ret) + { + m_hasDemux = m_addon->HasDemux(); + m_hasDisplayTime = m_addon->HasDisplayTime(); + m_hasPosTime = m_addon->HasPosTime(); + m_canPause = m_addon->CanPause(); + m_canSeek = m_addon->CanSeek(); + } + return ret; +} + +void CInputStreamAddon::Close() +{ + if (m_addon) + return m_addon->Close(); +} + +bool CInputStreamAddon::IsEOF() +{ + return false; +} + +int CInputStreamAddon::Read(uint8_t* buf, int buf_size) +{ + if (!m_addon) + return -1; + + return m_addon->ReadStream(buf, buf_size); +} + +int64_t CInputStreamAddon::Seek(int64_t offset, int whence) +{ + if (!m_addon) + return -1; + + return m_addon->SeekStream(offset, whence); +} + +int64_t CInputStreamAddon::GetLength() +{ + if (!m_addon) + return -1; + + return m_addon->LengthStream(); +} + +bool CInputStreamAddon::Pause(double dTime) +{ + if (!m_addon) + return false; + + m_addon->PauseStream(dTime); + return true; +} + +bool CInputStreamAddon::CanSeek() +{ + return m_canSeek; +} + +bool CInputStreamAddon::CanPause() +{ + return m_canPause; +} + +// IDisplayTime +CDVDInputStream::IDisplayTime* CInputStreamAddon::GetIDisplayTime() +{ + if (!m_addon) + return nullptr; + if (!m_hasDisplayTime) + return nullptr; + + return this; +} + +int CInputStreamAddon::GetTotalTime() +{ + if (!m_addon) + return 0; + + return m_addon->GetTotalTime(); +} + +int CInputStreamAddon::GetTime() +{ + if (!m_addon) + return 0; + + return m_addon->GetTime(); +} + +// IPosTime +CDVDInputStream::IPosTime* CInputStreamAddon::GetIPosTime() +{ + if (!m_addon) + return nullptr; + if (!m_hasPosTime) + return nullptr; + + return this; +} + +bool CInputStreamAddon::PosTime(int ms) +{ + if (!m_addon) + return false; + + return m_addon->PosTime(ms); +} + +// IDemux +CDVDInputStream::IDemux* CInputStreamAddon::GetIDemux() +{ + if (!m_addon) + return nullptr; + if (!m_hasDemux) + return nullptr; + + return this; +} + +bool CInputStreamAddon::OpenDemux() +{ + if (m_hasDemux) + return true; + else + return false; +} + +DemuxPacket* CInputStreamAddon::ReadDemux() +{ + if (!m_addon) + return nullptr; + + return m_addon->ReadDemux(); +} + +CDemuxStream* CInputStreamAddon::GetStream(int iStreamId) +{ + if (!m_addon) + return nullptr; + + return m_addon->GetStream(iStreamId); +} + +int CInputStreamAddon::GetNrOfStreams() +{ + if (!m_addon) + return 0; + + int count = m_addon->GetNrOfStreams(); + return count; +} + +void CInputStreamAddon::SetSpeed(int iSpeed) +{ + if (!m_addon) + return; + + m_addon->SetSpeed(iSpeed); +} + +bool CInputStreamAddon::SeekTime(int time, bool backward, double* startpts) +{ + if (!m_addon) + return false; + + if (m_hasPosTime) + { + if (!PosTime(time)) + return false; + + FlushDemux(); + + if(startpts) + *startpts = DVD_NOPTS_VALUE; + return true; + } + + return m_addon->SeekTime(time, backward, startpts); +} + +void CInputStreamAddon::AbortDemux() +{ + if (!m_addon) + return; + + m_addon->AbortDemux(); +} + +void CInputStreamAddon::FlushDemux() +{ + if (!m_addon) + return; + + m_addon->FlushDemux(); +} diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h new file mode 100644 index 0000000000..565e051ab4 --- /dev/null +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2016 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 + * <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include "DVDInputStream.h" +#include "addons/InputStream.h" + +//! \brief Input stream class +class CInputStreamAddon : + public CDVDInputStream, + public CDVDInputStream::IDisplayTime, + public CDVDInputStream::IPosTime, + public CDVDInputStream::IDemux +{ +public: + //! \brief constructor + CInputStreamAddon(CFileItem& fileitem, ADDON::CInputStream *inputStream); + + //! \brief Destructor. + virtual ~CInputStreamAddon(); + + //! \brief Open a MPD file + virtual bool Open() override; + + //! \brief Close input stream + virtual void Close() override; + + //! \brief Read data from stream + virtual int Read(uint8_t* buf, int buf_size) override; + + //! \brief Seeek in stream + virtual int64_t Seek(int64_t offset, int whence) override; + + //! \brief Pause stream + virtual bool Pause(double dTime) override; + //! \brief Return true if we have reached EOF + virtual bool IsEOF() override; + + virtual bool CanSeek() override; + virtual bool CanPause() override; + + //! \brief Get length of input data + virtual int64_t GetLength() override; + + // IDisplayTime + virtual CDVDInputStream::IDisplayTime* GetIDisplayTime() override; + virtual int GetTotalTime() override; + virtual int GetTime() override; + + // IPosTime + virtual CDVDInputStream::IPosTime* GetIPosTime() override; + virtual bool PosTime(int ms) override; + + //IDemux + CDVDInputStream::IDemux* GetIDemux() override; + virtual bool OpenDemux() override; + virtual DemuxPacket* ReadDemux() override; + virtual CDemuxStream* GetStream(int iStreamId) override; + virtual int GetNrOfStreams() override; + virtual void SetSpeed(int iSpeed) override; + virtual bool SeekTime(int time, bool backward = false, double* startpts = NULL) override; + virtual void AbortDemux() override; + virtual void FlushDemux() override; + +protected: + ADDON::CInputStream *m_addon; + bool m_hasDemux; + bool m_hasDisplayTime; + bool m_hasPosTime; + bool m_canPause; + bool m_canSeek; +}; |