From 923b00b0d2806afdfafdf7d6cd72831ead32dffd Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 4 Mar 2016 22:06:17 +0100 Subject: [PATCH 01/12] addons: allow addon to query its name --- xbmc/addons/AddonCallbacksAddon.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xbmc/addons/AddonCallbacksAddon.cpp b/xbmc/addons/AddonCallbacksAddon.cpp index f7833f657ea0a..37c58d833125d 100644 --- a/xbmc/addons/AddonCallbacksAddon.cpp +++ b/xbmc/addons/AddonCallbacksAddon.cpp @@ -194,6 +194,11 @@ bool CAddonCallbacksAddon::GetAddonSetting(void *addonData, const char *strSetti strcpy((char*) settingValue, addonHelper->m_addon->Path().c_str()); return true; } + else if (strcasecmp(strSettingName, "__addonname__") == 0) + { + strcpy((char*)settingValue, addonHelper->m_addon->Name().c_str()); + return true; + } if (!addonHelper->m_addon->ReloadSettings()) { From 1e51c05f2e5fe0fbeee20ea9ed18a9262612f5c9 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 4 Mar 2016 07:43:55 +0100 Subject: [PATCH 02/12] VideoPlayer: add bandwidth to DemuxStream --- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h | 4 ++++ xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h index 8d96e189f9f6f..d275f6a3a1ee1 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h @@ -93,6 +93,7 @@ class CDemuxStream changes = 0; flags = FLAG_NONE; realtime = false; + bandwidth = 0; } virtual ~CDemuxStream() @@ -114,6 +115,7 @@ class CDemuxStream StreamType type; int source; bool realtime; + unsigned int bandwidth; int iDuration; // in mseconds void* pPrivate; // private pointer for the demuxer @@ -123,6 +125,8 @@ class CDemuxStream char language[4]; // ISO 639 3-letter language code (empty string if undefined) bool disabled; // set when stream is disabled. (when no decoder exists) + std::string codecName; + int changes; // increment on change which player may need to know about enum EFlags diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index c36189dcdee20..3eaf38247886f 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -485,6 +485,8 @@ void CDVDDemuxClient::RequestStreams() } m_streams[i]->codec = stream->codec; + m_streams[i]->codecName = stream->codecName; + m_streams[i]->bandwidth = stream->bandwidth; m_streams[i]->iId = i; m_streams[i]->iPhysicalId = stream->iPhysicalId; for (int j=0; j<4; j++) From 0540ad644c26a66376a5714ac722fe64a5bd1e3c Mon Sep 17 00:00:00 2001 From: xbmc Date: Tue, 2 Feb 2016 22:38:22 +0100 Subject: [PATCH 03/12] Add binary addon InputStream --- Kodi.xcodeproj/project.pbxproj | 26 +- addons/kodi.inputstream/addon.xml | 7 + .../resources/strings.po | 5 +- project/VS2010Express/XBMC.vcxproj | 24 + project/VS2010Express/XBMC.vcxproj.filters | 75 +++ project/cmake/addons/CMakeLists.txt | 2 +- project/cmake/installdata/addon-bindings.txt | 4 +- xbmc/addons/Addon.cpp | 1 + xbmc/addons/AddonBuilder.cpp | 8 +- xbmc/addons/IAddon.h | 1 + xbmc/addons/InputStream.cpp | 505 ++++++++++++++++++ xbmc/addons/InputStream.h | 93 ++++ xbmc/addons/Makefile | 1 + xbmc/addons/addon-bindings.mk | 4 +- .../include/kodi/kodi_inputstream_dll.h | 248 +++++++++ .../include/kodi/kodi_inputstream_types.h | 159 ++++++ .../DVDInputStreams/DVDFactoryInputStream.cpp | 20 + .../DVDInputStreams/DVDInputStream.h | 1 + .../DVDInputStreams/InputStreamAddon.cpp | 240 +++++++++ .../DVDInputStreams/InputStreamAddon.h | 90 ++++ 20 files changed, 1508 insertions(+), 6 deletions(-) create mode 100644 addons/kodi.inputstream/addon.xml create mode 100644 xbmc/addons/InputStream.cpp create mode 100644 xbmc/addons/InputStream.h create mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_dll.h create mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h create mode 100644 xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp create mode 100644 xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 46c453198b4ed..c43fa236ad3bc 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 = ""; }; 7C4705AC12EF584C00369E51 /* AddonInstaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonInstaller.cpp; sourceTree = ""; }; 7C4705AD12EF584C00369E51 /* AddonInstaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonInstaller.h; sourceTree = ""; }; + 7C4B649D1C86F6BC000E1F74 /* AddonCallbacksInputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonCallbacksInputStream.cpp; sourceTree = ""; }; + 7C4B649E1C86F6BC000E1F74 /* AddonCallbacksInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonCallbacksInputStream.h; sourceTree = ""; }; + 7C4B64A11C86F6D8000E1F74 /* InputStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputStream.cpp; sourceTree = ""; }; + 7C4B64A21C86F6D8000E1F74 /* InputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputStream.h; sourceTree = ""; }; + 7C4B64A51C86F712000E1F74 /* InputStreamAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputStreamAddon.cpp; sourceTree = ""; }; + 7C4B64A61C86F712000E1F74 /* InputStreamAddon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputStreamAddon.h; sourceTree = ""; }; 7C4CED9F1C5E681E00BAD6CE /* DVDDemuxPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDDemuxPacket.h; sourceTree = ""; }; 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogSubtitles.cpp; sourceTree = ""; }; 7C4E6F711829AA9700F1068F /* GUIDialogSubtitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogSubtitles.h; sourceTree = ""; }; @@ -4541,7 +4553,7 @@ E46F7C2B0F77219700C25D29 /* ZeroconfOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZeroconfOSX.h; sourceTree = ""; }; E46F7C2C0F77219700C25D29 /* ZeroconfOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZeroconfOSX.cpp; sourceTree = ""; }; E47252BF175115F9001C1AAA /* Codesign.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Codesign.command; sourceTree = ""; }; - 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 0000000000000..94eb4068fd76d --- /dev/null +++ b/addons/kodi.inputstream/addon.xml @@ -0,0 +1,7 @@ + + + + + + + \ 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 8255ee0bcf71a..c03e3dcfed2c8 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 1331ab051c4b4..7e55657b90f5e 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -200,6 +200,7 @@ + @@ -925,6 +926,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index a014bc9af4482..aa57a03555fce 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -388,6 +388,9 @@ {45ab3e06-b8d3-44f5-994e-d6130258c99c} + + {353ba04b-a59a-4fb3-90d0-630277d5305b} + @@ -3283,6 +3286,9 @@ cores\Process + + addons + @@ -6314,6 +6320,75 @@ cores\Process + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons\include + + + addons + diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 00db97d8dec9d..8fc1a23d4d451 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 d4958197865c7..fbcdf99a9d742 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 e187823be3e16..14e767e9fcdf0 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 77ec92a41bac5..e3011a1e0290e 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 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 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(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 496b5eb5e19e5..db1f7a13e43a0 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 0000000000000..6b10156f2667a --- /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 + * . + * + */ +#include "InputStream.h" +#include "utils/StringUtils.h" +#include "utils/log.h" +#include "cores/VideoPlayer/DVDDemuxers/DVDDemux.h" + + +namespace ADDON +{ + +std::unique_ptr 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(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; iGetStream(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; jExtraData[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::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::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 0000000000000..57031b90c53f1 --- /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 + * . + * + */ +#pragma once + +#include "AddonDll.h" +#include "addons/kodi-addon-dev-kit/include/kodi/kodi_inputstream_types.h" +#include "FileItem.h" +#include +#include + +typedef DllAddon DllInputStream; + +class CDemuxStream; + +namespace ADDON +{ + typedef CAddonDll InputStreamDll; + + class CInputStream : public InputStreamDll + { + public: + + static std::unique_ptr 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 m_fileItemProps; + std::vector m_pathList; + std::vector m_extensionsList; + INPUTSTREAM_CAPABILITIES m_caps; + std::map m_streams; + }; + +} /*namespace ADDON*/ diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile index 22e7eadf24596..27cc506453985 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 9bcf95a6d02d5..ae0914d8cc989 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 0000000000000..2207160cde42f --- /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 +* . +* +*/ + +#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 0000000000000..b5abd29efe526 --- /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 + * . + * + */ + +#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 4176e085f033d..751585ae21acc 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 input(std::static_pointer_cast(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 8a0d006f3971e..b1664d52af376 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 0000000000000..de584a326a9b3 --- /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 + * . + * + */ + +#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 0000000000000..565e051ab4136 --- /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 + * . + * + */ + +#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; +}; From e3760717b838909387a9f14438c23c38df4d5c7c Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Tue, 9 Feb 2016 18:01:44 +0100 Subject: [PATCH 04/12] add callback lib for inputstream --- Makefile.in | 2 + addons/library.kodi.inputstream/.gitignore | 5 + configure.ac | 1 + .../library.kodi.inputstream/Makefile.in | 29 ++++ .../libKODI_inputstream.cpp | 77 +++++++++ xbmc/addons/AddonCallbacks.cpp | 31 ++++ xbmc/addons/AddonCallbacks.h | 10 ++ xbmc/addons/AddonCallbacksInputStream.cpp | 53 +++++++ xbmc/addons/AddonCallbacksInputStream.h | 70 ++++++++ xbmc/addons/Makefile | 1 + xbmc/addons/addon-bindings.mk | 1 + .../include/kodi/libKODI_inputstream.h | 150 ++++++++++++++++++ .../VideoPlayer/DVDInputStreams/Makefile | 1 + 13 files changed, 431 insertions(+) create mode 100644 addons/library.kodi.inputstream/.gitignore create mode 100644 lib/addons/library.kodi.inputstream/Makefile.in create mode 100644 lib/addons/library.kodi.inputstream/libKODI_inputstream.cpp create mode 100644 xbmc/addons/AddonCallbacksInputStream.cpp create mode 100644 xbmc/addons/AddonCallbacksInputStream.h create mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h diff --git a/Makefile.in b/Makefile.in index 10afc8b886b50..3416ba170a139 100644 --- a/Makefile.in +++ b/Makefile.in @@ -195,6 +195,7 @@ LIBADDON_DIRS=\ lib/addons/library.xbmc.codec \ lib/addons/library.xbmc.pvr \ lib/addons/library.kodi.guilib \ + lib/addons/library.kodi.inputstream ESTUARY_MEDIA=addons/skin.estuary/media SKIN_DIRS=$(ESTUARY_MEDIA) @@ -317,6 +318,7 @@ libaddon: exports $(MAKE) -C lib/addons/library.xbmc.codec $(MAKE) -C lib/addons/library.kodi.guilib $(MAKE) -C lib/addons/library.xbmc.pvr + $(MAKE) -C lib/addons/library.kodi.inputstream dvdpcodecs: dllloader $(MAKE) -C lib/libdvd diff --git a/addons/library.kodi.inputstream/.gitignore b/addons/library.kodi.inputstream/.gitignore new file mode 100644 index 0000000000000..76bedaeabbafd --- /dev/null +++ b/addons/library.kodi.inputstream/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore + diff --git a/configure.ac b/configure.ac index 4549020f0087a..70a7ac2eaa99a 100644 --- a/configure.ac +++ b/configure.ac @@ -2241,6 +2241,7 @@ OUTPUT_FILES="Makefile \ lib/addons/library.xbmc.codec/Makefile \ lib/addons/library.kodi.guilib/Makefile \ lib/addons/library.xbmc.pvr/Makefile \ + lib/addons/library.kodi.inputstream/Makefile \ tools/Linux/kodi.sh \ tools/Linux/kodi-standalone.sh \ tools/Linux/kodi-xsession.desktop \ diff --git a/lib/addons/library.kodi.inputstream/Makefile.in b/lib/addons/library.kodi.inputstream/Makefile.in new file mode 100644 index 0000000000000..0d14a2e0e1d2d --- /dev/null +++ b/lib/addons/library.kodi.inputstream/Makefile.in @@ -0,0 +1,29 @@ +ARCH=@ARCH@ +INCLUDES=-I. -I../../../xbmc/addons/include -I../../../xbmc +DEFINES+= +CXXFLAGS=-fPIC +LIBNAME=libKODI_inputstream +OBJS=$(LIBNAME).o + +ifeq ($(findstring osx,$(ARCH)), osx) +LIB_SHARED=../../../addons/library.kodi.inputstream/$(LIBNAME)-$(ARCH).dylib +else +LIB_SHARED=../../../addons/library.kodi.inputstream/$(LIBNAME)-$(ARCH).so +endif + +all: $(LIB_SHARED) + +$(LIB_SHARED): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -dynamiclib -o $@ $(OBJS) +else + $(CXX) $(CFLAGS) $(LDFLAGS) -shared -g -o $(LIB_SHARED) $(OBJS) +endif + +CLEAN_FILES = \ + $(LIB_SHARED) \ + +DISTCLEAN_FILES= \ + Makefile \ + +include ../../../Makefile.include diff --git a/lib/addons/library.kodi.inputstream/libKODI_inputstream.cpp b/lib/addons/library.kodi.inputstream/libKODI_inputstream.cpp new file mode 100644 index 0000000000000..3ec5bcbbae21a --- /dev/null +++ b/lib/addons/library.kodi.inputstream/libKODI_inputstream.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012-2013 Team XBMC + * http://www.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, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include +#include +#include +#include +#include "addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h" +#include "addons/AddonCallbacks.h" + +#ifdef _WIN32 +#include +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif + +using namespace std; + +extern "C" +{ + +DLLEXPORT void* INPUTSTREAM_register_me(void *hdl) +{ + CB_INPUTSTREAMLib *cb = nullptr; + if (!hdl) + fprintf(stderr, "libKODI_inputstream-ERROR: %s is called with NULL handle\n", __FUNCTION__); + else + { + cb = ((AddonCB*)hdl)->INPUTSTREAMLib_RegisterMe(((AddonCB*)hdl)->addonData); + if (!cb) + fprintf(stderr, "libKODI_inputstream--ERROR: %s can't get callback table from KODI\n", __FUNCTION__); + } + return cb; +} + +DLLEXPORT void INPUTSTREAM_unregister_me(void *hdl, void* cb) +{ + if (hdl && cb) + ((AddonCB*)hdl)->INPUTSTREAMLib_UnRegisterMe(((AddonCB*)hdl)->addonData, (CB_INPUTSTREAMLib*)cb); +} + +DLLEXPORT DemuxPacket* INPUTSTREAM_allocate_demux_packet(void *hdl, void* cb, int iDataSize) +{ + if (cb == NULL) + return NULL; + + return ((CB_INPUTSTREAMLib*)cb)->AllocateDemuxPacket(((AddonCB*)hdl)->addonData, iDataSize); +} + +DLLEXPORT void INPUTSTREAM_free_demux_packet(void *hdl, void* cb, DemuxPacket* pPacket) +{ + if (cb == NULL) + return; + + ((CB_INPUTSTREAMLib*)cb)->FreeDemuxPacket(((AddonCB*)hdl)->addonData, pPacket); +} + +}; diff --git a/xbmc/addons/AddonCallbacks.cpp b/xbmc/addons/AddonCallbacks.cpp index 3153a52ea1d50..2174b88c90312 100644 --- a/xbmc/addons/AddonCallbacks.cpp +++ b/xbmc/addons/AddonCallbacks.cpp @@ -42,6 +42,7 @@ CAddonCallbacks::CAddonCallbacks(CAddon* addon) m_helperGUI = NULL; m_helperPVR = NULL; m_helperCODEC = NULL; + m_helperInputStream = nullptr; m_callbacks->libBasePath = strdup(CSpecialProtocol::TranslatePath("special://xbmcbin/addons").c_str()); m_callbacks->addonData = this; @@ -57,6 +58,8 @@ CAddonCallbacks::CAddonCallbacks(CAddon* addon) m_callbacks->GUILib_UnRegisterMe = CAddonCallbacks::GUILib_UnRegisterMe; m_callbacks->PVRLib_RegisterMe = CAddonCallbacks::PVRLib_RegisterMe; m_callbacks->PVRLib_UnRegisterMe = CAddonCallbacks::PVRLib_UnRegisterMe; + m_callbacks->INPUTSTREAMLib_RegisterMe = CAddonCallbacks::INPUTSTREAMLib_RegisterMe; + m_callbacks->INPUTSTREAMLib_UnRegisterMe = CAddonCallbacks::INPUTSTREAMLib_UnRegisterMe; } CAddonCallbacks::~CAddonCallbacks() @@ -73,6 +76,8 @@ CAddonCallbacks::~CAddonCallbacks() m_helperGUI = NULL; delete m_helperPVR; m_helperPVR = NULL; + delete m_helperInputStream; + m_helperInputStream = nullptr; free((char*)m_callbacks->libBasePath); delete m_callbacks; m_callbacks = NULL; @@ -235,4 +240,30 @@ void CAddonCallbacks::PVRLib_UnRegisterMe(void *addonData, CB_PVRLib *cbTable) addon->m_helperPVR = NULL; } +CB_INPUTSTREAMLib* CAddonCallbacks::INPUTSTREAMLib_RegisterMe(void *addonData) +{ + CAddonCallbacks* addon = (CAddonCallbacks*) addonData; + if (addon == NULL) + { + CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); + return NULL; + } + + addon->m_helperInputStream = new CAddonCallbacksInputStream(addon->m_addon); + return addon->m_helperInputStream->GetCallbacks(); +} + +void CAddonCallbacks::INPUTSTREAMLib_UnRegisterMe(void *addonData, CB_INPUTSTREAMLib *cbTable) +{ + CAddonCallbacks* addon = (CAddonCallbacks*) addonData; + if (addon == NULL) + { + CLog::Log(LOGERROR, "CAddonCallbacks - %s - called with a null pointer", __FUNCTION__); + return; + } + + delete addon->m_helperInputStream; + addon->m_helperInputStream = nullptr; +} + }; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacks.h b/xbmc/addons/AddonCallbacks.h index f513d1c6c8aef..ec383c8212b25 100644 --- a/xbmc/addons/AddonCallbacks.h +++ b/xbmc/addons/AddonCallbacks.h @@ -24,11 +24,13 @@ #include "addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h" #include "addons/kodi-addon-dev-kit/include/kodi/libKODI_adsp.h" #include "addons/kodi-addon-dev-kit/include/kodi/libKODI_audioengine.h" +#include "addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h" #include "addons/kodi-addon-dev-kit/include/kodi/kodi_adsp_types.h" #include "addons/kodi-addon-dev-kit/include/kodi/kodi_audioengine_types.h" #include "addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h" #include "addons/kodi-addon-dev-kit/include/kodi/xbmc_codec_types.h" #include "cores/VideoPlayer/DVDDemuxers/DVDDemuxUtils.h" +#include "AddonCallbacksInputStream.h" #ifdef TARGET_WINDOWS #ifndef _SSIZE_T_DEFINED @@ -533,6 +535,8 @@ typedef CB_GUILib* (*XBMCGUILib_RegisterMe)(void *addonData); typedef void (*XBMCGUILib_UnRegisterMe)(void *addonData, CB_GUILib *cbTable); typedef CB_PVRLib* (*XBMCPVRLib_RegisterMe)(void *addonData); typedef void (*XBMCPVRLib_UnRegisterMe)(void *addonData, CB_PVRLib *cbTable); +typedef CB_INPUTSTREAMLib* (*KODIINPUTSTREAMLib_RegisterMe)(void *addonData); +typedef void (*KODIINPUTSTREAMLib_UnRegisterMe)(void *addonData, CB_INPUTSTREAMLib *cbTable); typedef struct AddonCB { @@ -550,6 +554,8 @@ typedef struct AddonCB XBMCPVRLib_UnRegisterMe PVRLib_UnRegisterMe; KODIADSPLib_RegisterMe ADSPLib_RegisterMe; KODIADSPLib_UnRegisterMe ADSPLib_UnRegisterMe; + KODIINPUTSTREAMLib_RegisterMe INPUTSTREAMLib_RegisterMe; + KODIINPUTSTREAMLib_UnRegisterMe INPUTSTREAMLib_UnRegisterMe; } AddonCB; @@ -583,6 +589,8 @@ class CAddonCallbacks static void GUILib_UnRegisterMe(void *addonData, CB_GUILib *cbTable); static CB_PVRLib* PVRLib_RegisterMe(void *addonData); static void PVRLib_UnRegisterMe(void *addonData, CB_PVRLib *cbTable); + static CB_INPUTSTREAMLib* INPUTSTREAMLib_RegisterMe(void *addonData); + static void INPUTSTREAMLib_UnRegisterMe(void *addonData, CB_INPUTSTREAMLib *cbTable); CAddonCallbacksAddon *GetHelperAddon() { return m_helperAddon; } CAddonCallbacksADSP *GetHelperADSP() { return m_helperADSP; } @@ -590,6 +598,7 @@ class CAddonCallbacks CAddonCallbacksCodec *GetHelperCodec() { return m_helperCODEC; } CAddonCallbacksGUI *GetHelperGUI() { return m_helperGUI; } CAddonCallbacksPVR *GetHelperPVR() { return m_helperPVR; } + CAddonCallbacksInputStream *GetHelperInputStream() { return m_helperInputStream; } private: AddonCB *m_callbacks; @@ -600,6 +609,7 @@ class CAddonCallbacks CAddonCallbacksCodec *m_helperCODEC; CAddonCallbacksGUI *m_helperGUI; CAddonCallbacksPVR *m_helperPVR; + CAddonCallbacksInputStream *m_helperInputStream; }; }; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksInputStream.cpp b/xbmc/addons/AddonCallbacksInputStream.cpp new file mode 100644 index 0000000000000..19616aab4899b --- /dev/null +++ b/xbmc/addons/AddonCallbacksInputStream.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012-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 + * . + * + */ + + +#include "AddonCallbacksInputStream.h" + + +namespace ADDON +{ + +CAddonCallbacksInputStream::CAddonCallbacksInputStream(CAddon* addon) +{ + m_addon = addon; + m_callbacks = new CB_INPUTSTREAMLib; + + m_callbacks->FreeDemuxPacket = InputStreamFreeDemuxPacket; + m_callbacks->AllocateDemuxPacket = InputStreamAllocateDemuxPacket; +} + +CAddonCallbacksInputStream::~CAddonCallbacksInputStream() +{ + /* delete the callback table */ + delete m_callbacks; +} + +void CAddonCallbacksInputStream::InputStreamFreeDemuxPacket(void *addonData, DemuxPacket* pPacket) +{ + CDVDDemuxUtils::FreeDemuxPacket(pPacket); +} + +DemuxPacket* CAddonCallbacksInputStream::InputStreamAllocateDemuxPacket(void *addonData, int iDataSize) +{ + return CDVDDemuxUtils::AllocateDemuxPacket(iDataSize); +} + +}; /* namespace ADDON */ diff --git a/xbmc/addons/AddonCallbacksInputStream.h b/xbmc/addons/AddonCallbacksInputStream.h new file mode 100644 index 0000000000000..7a4e6c9067d6a --- /dev/null +++ b/xbmc/addons/AddonCallbacksInputStream.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012-2016 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#pragma once + +#include "cores/VideoPlayer/DVDDemuxers/DVDDemuxUtils.h" + +typedef void (*InputStreamFreeDemuxPacket)(void *addonData, DemuxPacket* pPacket); +typedef DemuxPacket* (*InputStreamAllocateDemuxPacket)(void *addonData, int iDataSize); + +typedef struct CB_INPUTSTREAMLib +{ + InputStreamFreeDemuxPacket FreeDemuxPacket; + InputStreamAllocateDemuxPacket AllocateDemuxPacket; +} CB_INPUTSTREAMLib; + +namespace ADDON +{ + +class CAddon; + +class CAddonCallbacksInputStream +{ +public: + CAddonCallbacksInputStream(CAddon* addon); + ~CAddonCallbacksInputStream(); + + /*! + * @return The callback table. + */ + CB_INPUTSTREAMLib *GetCallbacks() { return m_callbacks; } + + /*! + * @brief Allocate a demux packet. Free with FreeDemuxPacket + * @param addonData A pointer to the add-on. + * @param iDataSize The size of the data that will go into the packet + * @return The allocated packet. + */ + static DemuxPacket* InputStreamAllocateDemuxPacket(void* addonData, int iDataSize = 0); + + /*! + * @brief Free a packet that was allocated with AllocateDemuxPacket + * @param addonData A pointer to the add-on. + * @param pPacket The packet to free. + */ + static void InputStreamFreeDemuxPacket(void* addonData, DemuxPacket* pPacket); + +private: + CB_INPUTSTREAMLib* m_callbacks; /*!< callback addresses */ + CAddon* m_addon; /*!< the add-on */ +}; + +}; /* namespace ADDON */ diff --git a/xbmc/addons/Makefile b/xbmc/addons/Makefile index 27cc506453985..7fc60a086c4d8 100644 --- a/xbmc/addons/Makefile +++ b/xbmc/addons/Makefile @@ -7,6 +7,7 @@ SRCS=Addon.cpp \ AddonCallbacksCodec.cpp \ AddonCallbacksGUI.cpp \ AddonCallbacksPVR.cpp \ + AddonCallbacksInputStream.cpp \ AddonDatabase.cpp \ AddonInstaller.cpp \ AddonManager.cpp \ diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk index ae0914d8cc989..49978b79cf301 100644 --- a/xbmc/addons/addon-bindings.mk +++ b/xbmc/addons/addon-bindings.mk @@ -25,6 +25,7 @@ BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_audioengine.h BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h 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/addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h BINDINGS+=xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxPacket.h BINDINGS+=xbmc/cores/AudioEngine/Utils/AEChannelData.h BINDINGS+=xbmc/filesystem/IFileTypes.h diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h new file mode 100644 index 0000000000000..e0dc88109dfcd --- /dev/null +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/libKODI_inputstream.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2005-2016 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "libXBMC_addon.h" + +#ifdef BUILD_KODI_ADDON +#include "DVDDemuxPacket.h" +#else +#include "cores/VideoPlayer/DVDDemuxers/DVDDemuxPacket.h" +#endif + +#ifdef _WIN32 +#define INPUTSTREAM_HELPER_DLL "\\library.kodi.inputstream\\libKODI_inputstream" ADDON_HELPER_EXT +#else +#define INPUTSTREAM_HELPER_DLL_NAME "libKODI_inputstream-" ADDON_HELPER_ARCH ADDON_HELPER_EXT +#define INPUTSTREAM_HELPER_DLL "/library.kodi.inputstream/" INPUTSTREAM_HELPER_DLL_NAME +#endif + +class CHelper_libKODI_inputstream +{ +public: + CHelper_libKODI_inputstream(void) + { + m_libKODI_inputstream = nullptr; + m_Handle = nullptr; + } + + ~CHelper_libKODI_inputstream(void) + { + if (m_libKODI_inputstream) + { + INPUTSTREAM_unregister_me(m_Handle, m_Callbacks); + dlclose(m_libKODI_inputstream); + } + } + + /*! + * @brief Resolve all callback methods + * @param handle Pointer to the add-on + * @return True when all methods were resolved, false otherwise. + */ + bool RegisterMe(void* handle) + { + m_Handle = handle; + + std::string libBasePath; + libBasePath = ((cb_array*)m_Handle)->libPath; + libBasePath += INPUTSTREAM_HELPER_DLL; + + m_libKODI_inputstream = dlopen(libBasePath.c_str(), RTLD_LAZY); + if (m_libKODI_inputstream == nullptr) + { + fprintf(stderr, "Unable to load %s\n", dlerror()); + return false; + } + + INPUTSTREAM_register_me = (void* (*)(void *HANDLE)) + dlsym(m_libKODI_inputstream, "INPUTSTREAM_register_me"); + if (INPUTSTREAM_register_me == nullptr) + { + fprintf(stderr, "Unable to assign function %s\n", dlerror()); + return false; + } + + INPUTSTREAM_unregister_me = (void (*)(void* HANDLE, void* CB)) + dlsym(m_libKODI_inputstream, "INPUTSTREAM_unregister_me"); + if (INPUTSTREAM_unregister_me == nullptr) + { + fprintf(stderr, "Unable to assign function %s\n", dlerror()); + return false; + } + + INPUTSTREAM_free_demux_packet = (void (*)(void* HANDLE, void* CB, DemuxPacket* pPacket)) + dlsym(m_libKODI_inputstream, "INPUTSTREAM_free_demux_packet"); + if (INPUTSTREAM_free_demux_packet == NULL) + { + fprintf(stderr, "Unable to assign function %s\n", dlerror()); + return false; + } + + INPUTSTREAM_allocate_demux_packet = (DemuxPacket* (*)(void* HANDLE, void* CB, int iDataSize)) + dlsym(m_libKODI_inputstream, "INPUTSTREAM_allocate_demux_packet"); + if (INPUTSTREAM_allocate_demux_packet == NULL) + { + fprintf(stderr, "Unable to assign function %s\n", dlerror()); + return false; + } + + m_Callbacks = INPUTSTREAM_register_me(m_Handle); + return m_Callbacks != nullptr; + } + + /*! + * @brief Allocate a demux packet. Free with FreeDemuxPacket + * @param iDataSize The size of the data that will go into the packet + * @return The allocated packet + */ + DemuxPacket* AllocateDemuxPacket(int iDataSize) + { + return INPUTSTREAM_allocate_demux_packet(m_Handle, m_Callbacks, iDataSize); + } + + /*! + * @brief Free a packet that was allocated with AllocateDemuxPacket + * @param pPacket The packet to free + */ + void FreeDemuxPacket(DemuxPacket* pPacket) + { + return INPUTSTREAM_free_demux_packet(m_Handle, m_Callbacks, pPacket); + } + +protected: + void* (*INPUTSTREAM_register_me)(void*); + void (*INPUTSTREAM_unregister_me)(void*, void*); + void (*INPUTSTREAM_free_demux_packet)(void*, void*, DemuxPacket*); + DemuxPacket* (*INPUTSTREAM_allocate_demux_packet)(void*, void*, int); + +private: + void* m_libKODI_inputstream; + void* m_Handle; + void* m_Callbacks; + struct cb_array + { + const char* libPath; + }; +}; diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/Makefile b/xbmc/cores/VideoPlayer/DVDInputStreams/Makefile index 32744e6e93559..f7c26593d18fb 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/Makefile +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/Makefile @@ -11,6 +11,7 @@ SRCS= DVDFactoryInputStream.cpp \ DVDInputStreamRTMP.cpp \ DVDInputStreamPVRManager.cpp \ DVDInputStreamStack.cpp \ + InputStreamAddon.cpp \ DVDStateSerializer.cpp \ LIB= DVDInputStreams.a From fd31fa0c6198c7d9f45b659cae4b715ada52ed76 Mon Sep 17 00:00:00 2001 From: mapfau Date: Tue, 9 Feb 2016 23:14:57 +0100 Subject: [PATCH 05/12] InputStream -> vcxproj --- project/VS2010Express/XBMC.vcxproj | 3 +++ project/VS2010Express/XBMC.vcxproj.filters | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 7e55657b90f5e..5d741f697da81 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -188,6 +188,7 @@ + @@ -283,6 +284,7 @@ + @@ -923,6 +925,7 @@ + diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index aa57a03555fce..d0c8a245d4e3c 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -3289,6 +3289,12 @@ addons + + addons + + + cores\VideoPlayer\DVDInputStreams + @@ -6389,6 +6395,9 @@ addons + + addons + From 018374dd33510c96df3345fc8383dd43e59654d5 Mon Sep 17 00:00:00 2001 From: mapfau Date: Thu, 11 Feb 2016 13:27:20 +0100 Subject: [PATCH 06/12] Integrated INPUTSTREAM lib into VS solution --- .../VS2010Express/libKODI_inputstream.vcxproj | 88 +++++++++++++++++++ .../libKODI_inputstream.vcxproj.filters | 18 ++++ project/VS2010Express/XBMC for Windows.sln | 7 ++ 3 files changed, 113 insertions(+) create mode 100644 lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj create mode 100644 lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj.filters diff --git a/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj b/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj new file mode 100644 index 0000000000000..51304ea7c69eb --- /dev/null +++ b/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj @@ -0,0 +1,88 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942} + XBMC_INPUTSTREAM + Win32Proj + + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + true + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\..\..\..\addons\library.kodi.inputstream\ + Debug\ + ..\..\..\..\..\addons\library.kodi.inputstream\ + Release\ + ..\..\..\..\..\addons\library.xbmc.addon\;$(IncludePath) + ..\..\..\..\..\addons\library.xbmc.addon\;$(IncludePath) + + + false + + + + ..\..\..\..\..\xbmc;..\..\..\..\..\xbmc\addons\include;..\..\..\..\..\xbmc\cores\VideoPlayer\DVDDemuxers;%(AdditionalIncludeDirectories) + INPUTSTREAM_EXPORTS;_WIN32PC;%(PreprocessorDefinitions) + Sync + + + + + ..\..\..\..\..\addons\library.kodi.inputstream\$(ProjectName).dll + + + + + + + + + ..\..\..\..\..\xbmc;..\..\..\..\..\xbmc\addons\include;..\..\..\..\..\xbmc\cores\VideoPlayer\DVDDemuxers;%(AdditionalIncludeDirectories) + HAS_SDL;_USRDLL;XBMC_VDR_EXPORTS;_WIN32PC;%(PreprocessorDefinitions) + Sync + + + + + ../../../../../addons/library.kodi.inputstream/$(ProjectName).dll + + + + + + \ No newline at end of file diff --git a/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj.filters b/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj.filters new file mode 100644 index 0000000000000..8dd6f51ac8057 --- /dev/null +++ b/lib/addons/library.kodi.inputstream/project/VS2010Express/libKODI_inputstream.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32FE52A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE5A2BFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + \ No newline at end of file diff --git a/project/VS2010Express/XBMC for Windows.sln b/project/VS2010Express/XBMC for Windows.sln index 80965bc43f666..3740952064ec7 100644 --- a/project/VS2010Express/XBMC for Windows.sln +++ b/project/VS2010Express/XBMC for Windows.sln @@ -39,6 +39,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libKODI_adsp", "..\..\lib\a EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libKODI_audioengine", "..\..\lib\addons\library.kodi.audioengine\project\VS2010Express\libKODI_audioengine.vcxproj", "{6B96FD7D-26EE-415B-8858-27757A0B1273}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libKODI_inputstream", "..\..\lib\addons\library.kodi.inputstream\project\VS2010Express\libKODI_inputstream.vcxproj", "{8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug Testsuite|Win32 = Debug Testsuite|Win32 @@ -191,6 +193,11 @@ Global {6B96FD7D-26EE-415B-8858-27757A0B1273}.Debug|Win32.Build.0 = Debug|Win32 {6B96FD7D-26EE-415B-8858-27757A0B1273}.Release|Win32.ActiveCfg = Release|Win32 {6B96FD7D-26EE-415B-8858-27757A0B1273}.Release|Win32.Build.0 = Release|Win32 + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}.Debug Testsuite|Win32.ActiveCfg = Debug|Win32 + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}.Debug Testsuite|Win32.Build.0 = Debug|Win32 + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}.Debug|Win32.ActiveCfg = Debug|Win32 + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}.Debug|Win32.Build.0 = Debug|Win32 + {8BC9CEB8-8B4A-11D0-8D11-00A0CFEBC942}.Release|Win32.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From c7b6c9bb6d9b78b9e4dcc1d1f6314609125a6fb3 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Wed, 17 Feb 2016 18:02:14 +0100 Subject: [PATCH 07/12] add mpd to video extensions --- xbmc/settings/AdvancedSettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 3e6231dfb45df..4c29b5daafab2 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -383,7 +383,7 @@ void CAdvancedSettings::Initialize() m_pictureExtensions = ".png|.jpg|.jpeg|.bmp|.gif|.ico|.tif|.tiff|.tga|.pcx|.cbz|.zip|.cbr|.rar|.dng|.nef|.cr2|.crw|.orf|.arw|.erf|.3fr|.dcr|.x3f|.mef|.raf|.mrw|.pef|.sr2|.rss|.webp|.jp2|.apng"; m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.gdm|.imf|.m15|.sfx|.uni|.ac3|.dts|.cue|.aif|.aiff|.wpl|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.rar|.wv|.dsp|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.wtv|.mka|.tak|.opus|.dff|.dsf"; - m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.m3u|.m3u8|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.mk3d|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.rar|.001|.wpl|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss|.mpls|.webm|.bdmv|.wtv"; + m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.mpd|.m3u|.m3u8|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.mk3d|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.rar|.001|.wpl|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss|.mpls|.webm|.bdmv|.wtv"; m_subtitlesExtensions = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.text|.ssa|.aqt|.jss|.ass|.idx|.ifo|.rar|.zip"; m_discStubExtensions = ".disc"; // internal music extensions From d4204be1b05a888948518cafda2ef1a3d453fef8 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 20 Feb 2016 09:10:58 +0100 Subject: [PATCH 08/12] VideoPlayer: refactor enable/disable demux streams --- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp | 11 ----------- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h | 10 +++++----- .../cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp | 12 ++++++++++++ xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h | 7 +++---- xbmc/cores/VideoPlayer/DVDFileInfo.cpp | 2 +- xbmc/cores/VideoPlayer/VideoPlayer.cpp | 8 ++++---- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp index 3201a87e6d0f2..f9709804a966a 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp @@ -70,14 +70,3 @@ std::string CDemuxStream::GetStreamName() { return ""; } - -AVDiscard CDemuxStream::GetDiscard() -{ - return AVDISCARD_NONE; -} - -void CDemuxStream::SetDiscard(AVDiscard discard) -{ - return; -} - diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h index d275f6a3a1ee1..7ffa5e6625f2a 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h @@ -43,8 +43,6 @@ extern "C" { #pragma warning(pop) #endif -enum AVDiscard; - enum StreamType { STREAM_NONE = 0,// if unknown @@ -103,9 +101,6 @@ class CDemuxStream virtual std::string GetStreamName(); - virtual void SetDiscard(AVDiscard discard); - virtual AVDiscard GetDiscard(); - int iId; // most of the time starting from 0 int iPhysicalId; // id AVCodecID codec; @@ -331,4 +326,9 @@ class CDVDDemux * return a user-presentable codec name of the given stream */ virtual std::string GetStreamCodecName(int iStreamId) { return ""; }; + + /* + * enable / disable demux stream + */ + virtual void EnableStream(int id, bool enable) {}; }; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp index 047805375c3ac..14367d940956b 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.cpp @@ -246,3 +246,15 @@ bool CDVDDemuxVobsub::ParseTimestamp(SState& state, char* line) m_Timestamps.push_back(timestamp); return true; } + +void CDVDDemuxVobsub::EnableStream(int id, bool enable) +{ + for (auto &stream : m_Streams) + { + if (stream->iId == id) + { + stream->m_discard = !enable; + break; + } + } +} diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h index 4b24160073d7b..918c5412c1565 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxVobsub.h @@ -47,6 +47,7 @@ class CDVDDemuxVobsub : public CDVDDemux virtual std::string GetFileName() { return m_Filename; } bool Open(const std::string& filename, int source, const std::string& subfilename); + virtual void EnableStream(int id, bool enable) override; private: class CStream @@ -54,12 +55,10 @@ class CDVDDemuxVobsub : public CDVDDemux { public: CStream(CDVDDemuxVobsub* parent) - : m_discard(AVDISCARD_NONE), m_parent(parent) + : m_discard(false), m_parent(parent) {} - virtual void SetDiscard(AVDiscard discard) { m_discard = discard; } - virtual AVDiscard GetDiscard() { return m_discard; } - AVDiscard m_discard; + bool m_discard; CDVDDemuxVobsub* m_parent; }; diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp index 2a9685a2397cf..769e8fd651487 100644 --- a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp +++ b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp @@ -196,7 +196,7 @@ bool CDVDFileInfo::ExtractThumb(const std::string &strPath, if(pStream->type == STREAM_VIDEO && !(pStream->flags & AV_DISPOSITION_ATTACHED_PIC)) nVideoStream = i; else - pStream->SetDiscard(AVDISCARD_ALL); + pDemuxer->EnableStream(pStream->iId, false); } } diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index 69f99424d16d0..a3b020e498adb 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -1601,7 +1601,8 @@ void CVideoPlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket) ProcessRadioRDSData(pStream, pPacket); else { - pStream->SetDiscard(AVDISCARD_ALL); + if (m_pDemuxer) + m_pDemuxer->EnableStream(pStream->iId, false); CDVDDemuxUtils::FreeDemuxPacket(pPacket); // free it since we won't do anything with it } } @@ -3442,7 +3443,7 @@ bool CVideoPlayer::OpenStream(CCurrentStream& current, int iStream, int source, stream = m_pSubtitleDemuxer->GetStream(iStream); if(!stream || stream->disabled) return false; - stream->SetDiscard(AVDISCARD_NONE); + m_pSubtitleDemuxer->EnableStream(iStream, true); hint.Assign(*stream, true); } @@ -3465,7 +3466,7 @@ bool CVideoPlayer::OpenStream(CCurrentStream& current, int iStream, int source, stream = m_pDemuxer->GetStream(iStream); if(!stream || stream->disabled) return false; - stream->SetDiscard(AVDISCARD_NONE); + m_pDemuxer->EnableStream(iStream, true); hint.Assign(*stream, true); @@ -3526,7 +3527,6 @@ bool CVideoPlayer::OpenStream(CCurrentStream& current, int iStream, int source, /* mark stream as disabled, to disallaw further attempts*/ CLog::Log(LOGWARNING, "%s - Unsupported stream %d. Stream disabled.", __FUNCTION__, stream->iId); stream->disabled = true; - stream->SetDiscard(AVDISCARD_ALL); } } From d479a424c68223e8c31aaf40474f99394c564581 Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 20 Feb 2016 09:36:32 +0100 Subject: [PATCH 09/12] VideoPlayer: disable unused demux stream if they are read from a remote source --- xbmc/cores/VideoPlayer/VideoPlayer.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index a3b020e498adb..8b2fa5e246fd9 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -955,6 +955,25 @@ void CVideoPlayer::OpenDefaultStreams(bool reset) } if(!valid) CloseStream(m_CurrentRadioRDS, false); + + // disable demux streams + if (m_item.IsRemote() && m_pDemuxer) + { + for (auto &stream : m_SelectionStreams.m_Streams) + { + if (STREAM_SOURCE_MASK(stream.source) == STREAM_SOURCE_DEMUX) + { + if (stream.id != m_CurrentVideo.id && + stream.id != m_CurrentAudio.id && + stream.id != m_CurrentSubtitle.id && + stream.id != m_CurrentTeletext.id && + stream.id != m_CurrentRadioRDS.id) + { + m_pDemuxer->EnableStream(stream.id, false); + } + } + } + } } bool CVideoPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream) From 133537cd625331d31f70c104cde1420ce868b7fb Mon Sep 17 00:00:00 2001 From: xbmc Date: Sat, 20 Feb 2016 10:25:17 +0100 Subject: [PATCH 10/12] VideoPlayer: implement EnableStream for DemuxClient --- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp | 8 ++++++++ xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h | 1 + xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h | 1 + .../DVDInputStreams/DVDInputStreamPVRManager.h | 1 + .../VideoPlayer/DVDInputStreams/InputStreamAddon.cpp | 8 ++++++++ xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h | 1 + 6 files changed, 20 insertions(+) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 3eaf38247886f..7fe2d8cb5fbd6 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -569,3 +569,11 @@ void CDVDDemuxClient::SetSpeed (int speed) m_IDemux->SetSpeed(speed); } } + +void CDVDDemuxClient::EnableStream(int id, bool enable) +{ + if (m_IDemux) + { + m_IDemux->EnableStream(id, enable); + } +} diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h index ae176089b3f82..0538113e8f4ee 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h @@ -46,6 +46,7 @@ class CDVDDemuxClient : public CDVDDemux int GetNrOfStreams() override; std::string GetFileName() override; virtual std::string GetStreamCodecName(int iStreamId) override; + virtual void EnableStream(int id, bool enable) override; protected: void RequestStreams(); diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h index b1664d52af376..ab7cdac77a41f 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h @@ -119,6 +119,7 @@ class CDVDInputStream virtual bool OpenDemux() = 0; virtual DemuxPacket* ReadDemux() = 0; virtual CDemuxStream* GetStream(int iStreamId) = 0; + virtual void EnableStream(int iStreamId, bool enable) = 0; virtual int GetNrOfStreams() = 0; virtual void SetSpeed(int iSpeed) = 0; virtual bool SeekTime(int time, bool backward = false, double* startpts = NULL) = 0; diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.h index d1c7e4b6c1372..1316e8b5af2b2 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamPVRManager.h @@ -108,6 +108,7 @@ class CDVDInputStreamPVRManager virtual bool SeekTime(int time, bool backward = false, double* startpts = NULL) override; virtual void AbortDemux() override; virtual void FlushDemux() override; + virtual void EnableStream(int iStreamId, bool enable) override {}; protected: bool CloseAndOpen(const char* strFile); diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp index de584a326a9b3..38d5fcd5e9183 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp @@ -186,6 +186,14 @@ CDemuxStream* CInputStreamAddon::GetStream(int iStreamId) return m_addon->GetStream(iStreamId); } +void CInputStreamAddon::EnableStream(int iStreamId, bool enable) +{ + if (!m_addon) + return; + + return m_addon->EnableStream(iStreamId, enable); +} + int CInputStreamAddon::GetNrOfStreams() { if (!m_addon) diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h index 565e051ab4136..228917b40ccea 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h @@ -74,6 +74,7 @@ class CInputStreamAddon : virtual bool OpenDemux() override; virtual DemuxPacket* ReadDemux() override; virtual CDemuxStream* GetStream(int iStreamId) override; + virtual void EnableStream(int iStreamId, bool enable) override; virtual int GetNrOfStreams() override; virtual void SetSpeed(int iSpeed) override; virtual bool SeekTime(int time, bool backward = false, double* startpts = NULL) override; From dd7cc882aa6f555acc2436591d7b4fbbedd55810 Mon Sep 17 00:00:00 2001 From: mapfau Date: Tue, 23 Feb 2016 21:12:09 +0100 Subject: [PATCH 11/12] pass save charptr for listitem value --- xbmc/addons/InputStream.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/addons/InputStream.cpp b/xbmc/addons/InputStream.cpp index 6b10156f2667a..c0eca75cde510 100644 --- a/xbmc/addons/InputStream.cpp +++ b/xbmc/addons/InputStream.cpp @@ -109,12 +109,14 @@ bool CInputStream::Open(CFileItem &fileitem) { INPUTSTREAM props; props.m_nCountInfoValues = 0; + std::vector values; 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(); + values.push_back(fileitem.GetProperty(key).asString()); + props.m_ListItemProperties[props.m_nCountInfoValues].m_strValue = values.back().c_str(); props.m_nCountInfoValues++; } props.m_strURL = fileitem.GetPath().c_str(); From 517935c4035f97f4036bfd62a653d99b840c4b8f Mon Sep 17 00:00:00 2001 From: mapfau Date: Thu, 25 Feb 2016 22:00:09 +0100 Subject: [PATCH 12/12] Load Inputstream addon only if extension matches / regexp for path comparision --- .../cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp index 751585ae21acc..ba843e5bf9236 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp @@ -52,7 +52,7 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer { std::shared_ptr input(std::static_pointer_cast(addons[i])); ADDON::CInputStream* clone = new ADDON::CInputStream(*input); - ADDON_STATUS status = clone->Create(); + ADDON_STATUS status = clone->Supports(fileitem) ? clone->Create() : ADDON_STATUS_PERMANENT_FAILURE; if (status == ADDON_STATUS_OK) { if (clone->Supports(fileitem))