aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxbmc <fernetmenta@online.de>2016-02-02 22:38:22 +0100
committerRainer Hochecker <fernetmenta@online.de>2016-03-05 08:38:00 +0100
commit0540ad644c26a66376a5714ac722fe64a5bd1e3c (patch)
treea193f6780290b8a528993ab4ed54f7e6b392fb98
parent1e51c05f2e5fe0fbeee20ea9ed18a9262612f5c9 (diff)
Add binary addon InputStream
-rw-r--r--Kodi.xcodeproj/project.pbxproj26
-rw-r--r--addons/kodi.inputstream/addon.xml7
-rw-r--r--addons/resource.language.en_gb/resources/strings.po5
-rw-r--r--project/VS2010Express/XBMC.vcxproj24
-rw-r--r--project/VS2010Express/XBMC.vcxproj.filters75
-rw-r--r--project/cmake/addons/CMakeLists.txt2
-rw-r--r--project/cmake/installdata/addon-bindings.txt4
-rw-r--r--xbmc/addons/Addon.cpp1
-rw-r--r--xbmc/addons/AddonBuilder.cpp8
-rw-r--r--xbmc/addons/IAddon.h1
-rw-r--r--xbmc/addons/InputStream.cpp505
-rw-r--r--xbmc/addons/InputStream.h93
-rw-r--r--xbmc/addons/Makefile1
-rw-r--r--xbmc/addons/addon-bindings.mk4
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h248
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h159
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp20
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp240
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h90
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;
+};