aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--addons/kodi.imagedecoder/addon.xml7
-rw-r--r--addons/metadata.demo.artists/demo.py3
-rw-r--r--addons/resource.language.en_gb/resources/strings.po127
-rw-r--r--addons/skin.estouchy/xml/CustomVolume.xml4
-rw-r--r--addons/skin.estouchy/xml/DialogSeekBar.xml66
-rw-r--r--addons/skin.estouchy/xml/SlideShow.xml10
-rw-r--r--addons/skin.estouchy/xml/ViewsList.xml20
-rw-r--r--addons/skin.estouchy/xml/ViewsThumbnail.xml8
-rw-r--r--addons/skin.estuary/xml/AddonBrowser.xml2
-rw-r--r--addons/skin.estuary/xml/Constants_1920.xml2
-rw-r--r--addons/skin.estuary/xml/Constants_2560.xml2
-rw-r--r--addons/skin.estuary/xml/DialogMusicInfo.xml2
-rw-r--r--addons/skin.estuary/xml/Includes.xml3
-rw-r--r--addons/skin.estuary/xml/Includes_MediaMenu.xml81
-rw-r--r--addons/skin.estuary/xml/MyPlaylist.xml13
-rw-r--r--addons/skin.estuary/xml/MyVideoNav.xml2
-rw-r--r--addons/skin.estuary/xml/SlideShow.xml10
-rw-r--r--addons/skin.estuary/xml/Variables.xml6
-rw-r--r--addons/skin.estuary/xml/View_51_Poster.xml1
-rw-r--r--addons/skin.estuary/xml/View_55_WideList.xml8
-rw-r--r--cmake/cpack/deb/packages/kodi-image-dev.txt.in25
-rw-r--r--cmake/installdata/common/addons.txt1
-rw-r--r--cmake/modules/FindEMBEDDED.cmake2
-rw-r--r--cmake/modules/FindSSE.cmake11
-rw-r--r--cmake/scripts/ios/ArchSetup.cmake2
-rw-r--r--cmake/scripts/linux/Install.cmake6
-rw-r--r--cmake/treedata/common/video.txt1
-rw-r--r--docs/README.android6
-rw-r--r--docs/README.ios.md2
-rw-r--r--docs/README.raspberrypi6
-rw-r--r--system/addon-manifest.xml1
-rw-r--r--system/library/video/movies/actors.xml2
-rw-r--r--system/library/video/movies/country.xml2
-rw-r--r--system/library/video/movies/directors.xml2
-rw-r--r--system/library/video/movies/genres.xml2
-rw-r--r--system/library/video/movies/recentlyaddedmovies.xml4
-rw-r--r--system/library/video/movies/sets.xml2
-rw-r--r--system/library/video/movies/studios.xml2
-rw-r--r--system/library/video/movies/tags.xml2
-rw-r--r--system/library/video/movies/titles.xml2
-rw-r--r--system/library/video/movies/years.xml2
-rw-r--r--system/library/video/musicvideos/albums.xml2
-rw-r--r--system/library/video/musicvideos/artists.xml2
-rw-r--r--system/library/video/musicvideos/directors.xml2
-rw-r--r--system/library/video/musicvideos/genres.xml2
-rw-r--r--system/library/video/musicvideos/recentlyaddedmusicvideos.xml4
-rw-r--r--system/library/video/musicvideos/studios.xml2
-rw-r--r--system/library/video/musicvideos/tags.xml2
-rw-r--r--system/library/video/musicvideos/titles.xml2
-rw-r--r--system/library/video/musicvideos/years.xml2
-rw-r--r--system/library/video/tvshows/actors.xml2
-rw-r--r--system/library/video/tvshows/genres.xml2
-rw-r--r--system/library/video/tvshows/inprogressshows.xml4
-rw-r--r--system/library/video/tvshows/recentlyaddedepisodes.xml4
-rw-r--r--system/library/video/tvshows/studios.xml2
-rw-r--r--system/library/video/tvshows/tags.xml2
-rw-r--r--system/library/video/tvshows/titles.xml2
-rw-r--r--system/library/video/tvshows/years.xml2
-rw-r--r--tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp6
-rw-r--r--tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h2
-rw-r--r--tools/codegenerator/Helper.groovy4
-rw-r--r--tools/darwin/Configurations/App-iOS.xcconfig2
-rwxr-xr-xtools/darwin/Support/Codesign.command5
-rw-r--r--tools/depends/Makefile.include.in23
-rw-r--r--tools/depends/configure.ac21
-rw-r--r--tools/depends/native/cmake-native/Makefile7
-rw-r--r--tools/depends/native/config.site.native.in4
-rw-r--r--tools/depends/target/Toolchain.cmake.in9
-rw-r--r--tools/depends/target/config-binaddons.site.in6
-rw-r--r--tools/depends/target/config.site.in16
-rw-r--r--tools/depends/target/curl/Makefile3
-rw-r--r--tools/depends/target/ffmpeg/Makefile5
-rw-r--r--tools/depends/target/gnutls/Makefile2
-rw-r--r--tools/depends/target/openssl/Makefile2
-rw-r--r--tools/depends/target/samba-gplv3/Makefile2
-rw-r--r--xbmc/Application.cpp20
-rw-r--r--xbmc/Application.h1
-rw-r--r--xbmc/FileItem.cpp4
-rw-r--r--xbmc/Util.cpp2
-rw-r--r--xbmc/addons/Addon.cpp1
-rw-r--r--xbmc/addons/AddonBuilder.cpp4
-rw-r--r--xbmc/addons/AddonDatabase.cpp1
-rw-r--r--xbmc/addons/AddonInstaller.cpp42
-rw-r--r--xbmc/addons/AddonInstaller.h9
-rw-r--r--xbmc/addons/AddonManager.cpp14
-rw-r--r--xbmc/addons/AddonSystemSettings.cpp2
-rw-r--r--xbmc/addons/BinaryAddonCache.cpp1
-rw-r--r--xbmc/addons/CMakeLists.txt2
-rw-r--r--xbmc/addons/GUIDialogAddonSettings.cpp8
-rw-r--r--xbmc/addons/IAddon.h1
-rw-r--r--xbmc/addons/ImageDecoder.cpp92
-rw-r--r--xbmc/addons/ImageDecoder.h62
-rw-r--r--xbmc/addons/PVRClient.cpp117
-rw-r--r--xbmc/addons/PVRClient.h32
-rw-r--r--xbmc/addons/Repository.cpp43
-rw-r--r--xbmc/addons/RepositoryUpdater.cpp6
-rw-r--r--xbmc/addons/Scraper.cpp14
-rw-r--r--xbmc/addons/addon-bindings.mk2
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h47
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h64
-rw-r--r--xbmc/addons/test/TestAddonBuilder.cpp2
-rw-r--r--xbmc/addons/test/TestAddonFactory.cpp4
-rw-r--r--xbmc/cores/AudioEngine/AEDefines_override.h0
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp4
-rw-r--r--xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h2
-rw-r--r--xbmc/cores/VideoPlayer/CMakeLists.txt6
-rw-r--r--xbmc/cores/VideoPlayer/DVDClock.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp473
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h52
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp113
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h13
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp4
-rw-r--r--xbmc/cores/VideoPlayer/DVDMessage.h6
-rw-r--r--xbmc/cores/VideoPlayer/Edl.cpp12
-rw-r--r--xbmc/cores/VideoPlayer/Edl.h7
-rw-r--r--xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.cpp301
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.h22
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp16
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerAudio.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoReferenceClock.cpp (renamed from xbmc/video/VideoReferenceClock.cpp)68
-rw-r--r--xbmc/cores/VideoPlayer/VideoReferenceClock.h (renamed from xbmc/video/VideoReferenceClock.h)5
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp110
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h37
-rw-r--r--xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp2
-rw-r--r--xbmc/cores/omxplayer/OMXPlayerAudio.cpp18
-rw-r--r--xbmc/dbwrappers/Database.cpp2
-rw-r--r--xbmc/dbwrappers/Database.h2
-rw-r--r--xbmc/dbwrappers/DatabaseQuery.cpp3
-rw-r--r--xbmc/dialogs/GUIDialogFileBrowser.cpp4
-rw-r--r--xbmc/filesystem/AddonsDirectory.cpp4
-rw-r--r--xbmc/filesystem/File.h2
-rw-r--r--xbmc/filesystem/FileCache.cpp8
-rw-r--r--xbmc/filesystem/PipeFile.cpp4
-rw-r--r--xbmc/filesystem/PipeFile.h2
-rw-r--r--xbmc/filesystem/PipesManager.cpp2
-rw-r--r--xbmc/filesystem/PipesManager.h2
-rw-r--r--xbmc/filesystem/RSSDirectory.cpp4
-rw-r--r--xbmc/filesystem/SFTPFile.cpp4
-rw-r--r--xbmc/filesystem/SFTPFile.h2
-rw-r--r--xbmc/games/addons/GameClient.cpp1
-rw-r--r--xbmc/games/addons/GameClientInput.cpp1
-rw-r--r--xbmc/games/addons/GameClientInput.h4
-rw-r--r--xbmc/games/addons/GameClientKeyboard.cpp1
-rw-r--r--xbmc/games/addons/GameClientKeyboard.h2
-rw-r--r--xbmc/games/addons/GameClientMouse.cpp1
-rw-r--r--xbmc/games/addons/GameClientMouse.h2
-rw-r--r--xbmc/games/controllers/ControllerFeature.cpp1
-rw-r--r--xbmc/games/controllers/ControllerFeature.h14
-rw-r--r--xbmc/games/controllers/ControllerLayout.cpp1
-rw-r--r--xbmc/games/controllers/ControllerLayout.h4
-rw-r--r--xbmc/games/controllers/ControllerTranslator.cpp1
-rw-r--r--xbmc/games/controllers/ControllerTranslator.h12
-rw-r--r--xbmc/games/controllers/dialogs/CMakeLists.txt10
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp83
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h61
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp108
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h36
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp129
-rw-r--r--xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h52
-rw-r--r--xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp1
-rw-r--r--xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h2
-rw-r--r--xbmc/games/controllers/guicontrols/GUIFeatureButton.h2
-rw-r--r--xbmc/games/controllers/windows/GUIConfigurationWizard.cpp84
-rw-r--r--xbmc/games/controllers/windows/GUIConfigurationWizard.h40
-rw-r--r--xbmc/games/controllers/windows/GUIControllerWindow.cpp4
-rw-r--r--xbmc/games/controllers/windows/GUIFeatureList.cpp1
-rw-r--r--xbmc/games/controllers/windows/IConfigurationWindow.h2
-rw-r--r--xbmc/games/ports/PortManager.cpp1
-rw-r--r--xbmc/games/ports/PortManager.h24
-rw-r--r--xbmc/games/ports/PortMapper.cpp1
-rw-r--r--xbmc/games/ports/PortMapper.h11
-rw-r--r--xbmc/guilib/GUIMultiImage.cpp2
-rw-r--r--xbmc/guilib/GUISliderControl.h1
-rw-r--r--xbmc/guilib/GUIWindowManager.cpp2
-rw-r--r--xbmc/guilib/TextureFormats.h34
-rw-r--r--xbmc/guilib/XBTF.h13
-rw-r--r--xbmc/guilib/imagefactory.cpp23
-rw-r--r--xbmc/input/Action.cpp153
-rw-r--r--xbmc/input/Action.h113
-rw-r--r--xbmc/input/ActionIDs.h305
-rw-r--r--xbmc/input/ButtonTranslator.cpp6
-rw-r--r--xbmc/input/ButtonTranslator.h2
-rw-r--r--xbmc/input/CMakeLists.txt7
-rw-r--r--xbmc/input/InputManager.cpp5
-rw-r--r--xbmc/input/InputManager.h21
-rw-r--r--xbmc/input/Key.cpp120
-rw-r--r--xbmc/input/Key.h377
-rw-r--r--xbmc/input/joysticks/DeadzoneFilter.cpp1
-rw-r--r--xbmc/input/joysticks/DeadzoneFilter.h3
-rw-r--r--xbmc/input/joysticks/DefaultJoystick.cpp1
-rw-r--r--xbmc/input/joysticks/DefaultJoystick.h3
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.cpp1
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.h3
-rw-r--r--xbmc/input/joysticks/IActionMap.h3
-rw-r--r--xbmc/input/joysticks/IButtonMap.h3
-rw-r--r--xbmc/input/joysticks/IButtonMapCallback.h3
-rw-r--r--xbmc/input/joysticks/IButtonMapper.h14
-rw-r--r--xbmc/input/joysticks/IButtonSequence.h3
-rw-r--r--xbmc/input/joysticks/IDriverHandler.h3
-rw-r--r--xbmc/input/joysticks/IDriverReceiver.h3
-rw-r--r--xbmc/input/joysticks/IInputHandler.h3
-rw-r--r--xbmc/input/joysticks/IInputReceiver.h3
-rw-r--r--xbmc/input/joysticks/IKeymapHandler.h3
-rw-r--r--xbmc/input/joysticks/JoystickEasterEgg.cpp1
-rw-r--r--xbmc/input/joysticks/JoystickEasterEgg.h3
-rw-r--r--xbmc/input/joysticks/JoystickMonitor.cpp1
-rw-r--r--xbmc/input/joysticks/JoystickMonitor.h3
-rw-r--r--xbmc/input/joysticks/JoystickTranslator.cpp22
-rw-r--r--xbmc/input/joysticks/JoystickTranslator.h14
-rw-r--r--xbmc/input/joysticks/JoystickTypes.h3
-rw-r--r--xbmc/input/joysticks/JoystickUtils.h24
-rw-r--r--xbmc/input/joysticks/KeymapHandler.cpp4
-rw-r--r--xbmc/input/joysticks/KeymapHandler.h3
-rw-r--r--xbmc/input/joysticks/RumbleGenerator.cpp3
-rw-r--r--xbmc/input/joysticks/RumbleGenerator.h3
-rw-r--r--xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp3
-rw-r--r--xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h3
-rw-r--r--xbmc/input/joysticks/generic/ButtonMapping.cpp36
-rw-r--r--xbmc/input/joysticks/generic/ButtonMapping.h12
-rw-r--r--xbmc/input/joysticks/generic/DriverReceiving.cpp1
-rw-r--r--xbmc/input/joysticks/generic/DriverReceiving.h3
-rw-r--r--xbmc/input/joysticks/generic/FeatureHandling.cpp1
-rw-r--r--xbmc/input/joysticks/generic/FeatureHandling.h3
-rw-r--r--xbmc/input/joysticks/generic/InputHandling.cpp1
-rw-r--r--xbmc/input/joysticks/generic/InputHandling.h3
-rw-r--r--xbmc/input/keyboard/CMakeLists.txt11
-rw-r--r--xbmc/input/keyboard/IActionMap.h47
-rw-r--r--xbmc/input/keyboard/IKeyboardHandler.h3
-rw-r--r--xbmc/input/keyboard/KeyboardEasterEgg.cpp1
-rw-r--r--xbmc/input/keyboard/KeyboardEasterEgg.h3
-rw-r--r--xbmc/input/keyboard/KeymapActionMap.cpp34
-rw-r--r--xbmc/input/keyboard/KeymapActionMap.h39
-rw-r--r--xbmc/input/keyboard/generic/JoystickEmulation.cpp1
-rw-r--r--xbmc/input/keyboard/generic/JoystickEmulation.h3
-rw-r--r--xbmc/input/mouse/IMouseButtonMap.h3
-rw-r--r--xbmc/input/mouse/IMouseDriverHandler.h3
-rw-r--r--xbmc/input/mouse/IMouseInputHandler.h3
-rw-r--r--xbmc/input/mouse/MouseWindowingButtonMap.cpp1
-rw-r--r--xbmc/input/mouse/MouseWindowingButtonMap.h3
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.cpp1
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.h3
-rw-r--r--xbmc/interfaces/json-rpc/FileOperations.cpp4
-rw-r--r--xbmc/interfaces/json-rpc/JSONRPC.cpp4
-rw-r--r--xbmc/interfaces/json-rpc/JSONUtils.h2
-rw-r--r--xbmc/interfaces/json-rpc/PVROperations.cpp13
-rw-r--r--xbmc/interfaces/json-rpc/PlayerOperations.cpp35
-rw-r--r--xbmc/interfaces/json-rpc/SettingsOperations.cpp2
-rw-r--r--xbmc/interfaces/legacy/ListItem.cpp2
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmc.cpp2
-rw-r--r--xbmc/interfaces/python/PythonSwig.cpp.template2
-rw-r--r--xbmc/linux/OMXClock.cpp2
-rw-r--r--xbmc/linux/RBP.cpp2
-rw-r--r--xbmc/linux/RBP.h4
-rw-r--r--xbmc/messaging/ApplicationMessenger.h218
-rw-r--r--xbmc/messaging/IMessageTarget.h32
-rw-r--r--xbmc/messaging/ThreadMessage.h7
-rw-r--r--xbmc/music/MusicDatabase.cpp100
-rw-r--r--xbmc/music/MusicDatabase.h20
-rw-r--r--xbmc/music/infoscanner/MusicInfoScanner.cpp29
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp8
-rw-r--r--xbmc/network/AirTunesServer.cpp2
-rw-r--r--xbmc/network/cddb.cpp2
-rw-r--r--xbmc/network/cddb.h2
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp2
-rw-r--r--xbmc/network/websocket/WebSocket.h2
-rw-r--r--xbmc/peripherals/Peripherals.cpp6
-rw-r--r--xbmc/peripherals/Peripherals.h7
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.cpp1
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.h56
-rw-r--r--xbmc/peripherals/addons/AddonButtonMapping.cpp1
-rw-r--r--xbmc/peripherals/addons/AddonButtonMapping.h15
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.cpp1
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.h19
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.h11
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.cpp1
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.h22
-rw-r--r--xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp1
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp3
-rw-r--r--xbmc/peripherals/devices/Peripheral.cpp1
-rw-r--r--xbmc/peripherals/devices/Peripheral.h23
-rw-r--r--xbmc/peripherals/devices/PeripheralCecAdapter.cpp3
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystick.cpp1
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystick.h25
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp1
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystickEmulation.h10
-rw-r--r--xbmc/pictures/GUIViewStatePictures.cpp2
-rw-r--r--xbmc/pictures/PictureThumbLoader.cpp4
-rw-r--r--xbmc/platform/android/activity/XBMCApp.cpp2
-rw-r--r--xbmc/platform/android/jni/InetAddress.h2
-rw-r--r--xbmc/platform/darwin/ios/XBMCController.mm1
-rw-r--r--xbmc/platform/xbmc.cpp2
-rw-r--r--xbmc/powermanagement/PowerManager.cpp2
-rw-r--r--xbmc/pvr/CMakeLists.txt6
-rw-r--r--xbmc/pvr/PVRActionListener.cpp106
-rw-r--r--xbmc/pvr/PVRActionListener.h21
-rw-r--r--xbmc/pvr/PVRChannelNumberInputHandler.cpp2
-rw-r--r--xbmc/pvr/PVRContextMenus.cpp16
-rw-r--r--xbmc/pvr/PVRDatabase.cpp55
-rw-r--r--xbmc/pvr/PVRDatabase.h19
-rw-r--r--xbmc/pvr/PVRGUIActions.cpp733
-rw-r--r--xbmc/pvr/PVRGUIActions.h94
-rw-r--r--xbmc/pvr/PVRJobs.cpp67
-rw-r--r--xbmc/pvr/PVRJobs.h81
-rw-r--r--xbmc/pvr/PVRManager.cpp610
-rw-r--r--xbmc/pvr/PVRManager.h133
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp178
-rw-r--r--xbmc/pvr/addons/PVRClients.h69
-rw-r--r--xbmc/pvr/channels/PVRChannel.cpp18
-rw-r--r--xbmc/pvr/channels/PVRChannel.h15
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp24
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp7
-rw-r--r--xbmc/pvr/recordings/PVRRecording.cpp40
-rw-r--r--xbmc/pvr/recordings/PVRRecording.h3
-rw-r--r--xbmc/pvr/timers/PVRTimerInfoTag.cpp2
-rw-r--r--xbmc/pvr/timers/PVRTimers.cpp37
-rw-r--r--xbmc/pvr/timers/PVRTimers.h10
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.cpp6
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.h2
-rw-r--r--xbmc/settings/AdvancedSettings.cpp20
-rw-r--r--xbmc/settings/AdvancedSettings.h6
-rw-r--r--xbmc/settings/SettingConditions.cpp4
-rw-r--r--xbmc/settings/Settings.cpp2
-rw-r--r--xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp4
-rw-r--r--xbmc/settings/dialogs/GUIDialogAudioDSPManager.h2
-rw-r--r--xbmc/utils/BitstreamConverter.cpp107
-rw-r--r--xbmc/utils/BitstreamConverter.h7
-rw-r--r--xbmc/utils/Mime.cpp4
-rw-r--r--xbmc/utils/URIUtils.cpp2
-rw-r--r--xbmc/utils/test/TestHttpHeader.cpp12
-rw-r--r--xbmc/utils/test/TestVariant.cpp2
-rw-r--r--xbmc/video/CMakeLists.txt2
-rw-r--r--xbmc/video/VideoInfoScanner.cpp4
-rw-r--r--xbmc/video/videosync/CMakeLists.txt45
-rw-r--r--xbmc/windowing/CMakeLists.txt3
-rw-r--r--xbmc/windowing/VideoSync.h (renamed from xbmc/video/videosync/VideoSync.h)6
-rw-r--r--xbmc/windowing/WinSystem.h5
-rw-r--r--xbmc/windowing/X11/CMakeLists.txt4
-rw-r--r--xbmc/windowing/X11/VideoSyncDRM.cpp (renamed from xbmc/video/videosync/VideoSyncDRM.cpp)2
-rw-r--r--xbmc/windowing/X11/VideoSyncDRM.h (renamed from xbmc/video/videosync/VideoSyncDRM.h)7
-rw-r--r--xbmc/windowing/X11/VideoSyncGLX.cpp (renamed from xbmc/video/videosync/VideoSyncGLX.cpp)2
-rw-r--r--xbmc/windowing/X11/VideoSyncGLX.h (renamed from xbmc/video/videosync/VideoSyncGLX.h)4
-rw-r--r--xbmc/windowing/X11/WinSystemX11.cpp4
-rw-r--r--xbmc/windowing/X11/WinSystemX11GLContext.cpp19
-rw-r--r--xbmc/windowing/X11/WinSystemX11GLContext.h3
-rw-r--r--xbmc/windowing/egl/CMakeLists.txt6
-rw-r--r--xbmc/windowing/egl/VideoSyncAML.cpp110
-rw-r--r--xbmc/windowing/egl/VideoSyncAML.h41
-rw-r--r--xbmc/windowing/egl/VideoSyncAndroid.cpp (renamed from xbmc/video/videosync/VideoSyncAndroid.cpp)10
-rw-r--r--xbmc/windowing/egl/VideoSyncAndroid.h (renamed from xbmc/video/videosync/VideoSyncAndroid.h)20
-rw-r--r--xbmc/windowing/egl/VideoSyncIMX.cpp (renamed from xbmc/video/videosync/VideoSyncIMX.cpp)0
-rw-r--r--xbmc/windowing/egl/VideoSyncIMX.h (renamed from xbmc/video/videosync/VideoSyncIMX.h)0
-rw-r--r--xbmc/windowing/egl/VideoSyncPi.cpp (renamed from xbmc/video/videosync/VideoSyncPi.cpp)8
-rw-r--r--xbmc/windowing/egl/VideoSyncPi.h (renamed from xbmc/video/videosync/VideoSyncPi.h)5
-rw-r--r--xbmc/windowing/egl/WinSystemEGL.cpp26
-rw-r--r--xbmc/windowing/egl/WinSystemEGL.h3
-rw-r--r--xbmc/windowing/osx/CMakeLists.txt12
-rw-r--r--xbmc/windowing/osx/VideoSyncIos.cpp (renamed from xbmc/video/videosync/VideoSyncIos.cpp)2
-rw-r--r--xbmc/windowing/osx/VideoSyncIos.h (renamed from xbmc/video/videosync/VideoSyncIos.h)4
-rw-r--r--xbmc/windowing/osx/VideoSyncOsx.cpp (renamed from xbmc/video/videosync/VideoSyncOsx.cpp)3
-rw-r--r--xbmc/windowing/osx/VideoSyncOsx.h (renamed from xbmc/video/videosync/VideoSyncOsx.h)6
-rw-r--r--xbmc/windowing/osx/WinSystemIOS.h2
-rw-r--r--xbmc/windowing/osx/WinSystemIOS.mm13
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.h3
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.mm9
-rw-r--r--xbmc/windowing/windows/CMakeLists.txt6
-rw-r--r--xbmc/windowing/windows/VideoSyncD3D.cpp (renamed from xbmc/video/videosync/VideoSyncD3D.cpp)5
-rw-r--r--xbmc/windowing/windows/VideoSyncD3D.h (renamed from xbmc/video/videosync/VideoSyncD3D.h)7
-rw-r--r--xbmc/windowing/windows/WinSystemWin32.cpp8
-rw-r--r--xbmc/windowing/windows/WinSystemWin32.h3
374 files changed, 5215 insertions, 3241 deletions
diff --git a/.gitignore b/.gitignore
index d65eb08d45..39ef1aa169 100644
--- a/.gitignore
+++ b/.gitignore
@@ -309,6 +309,7 @@ lib/cpluff/stamp-h1
#/tools/depends
/tools/depends/native/*/*native/
+/tools/depends/target/*/aarch64-linux-gnu/
/tools/depends/native/JsonSchemaBuilder/bin/
/tools/depends/native/TexturePacker/bin/
/tools/depends/target/ffmpeg/.ffmpeg-installed
diff --git a/addons/kodi.imagedecoder/addon.xml b/addons/kodi.imagedecoder/addon.xml
new file mode 100644
index 0000000000..aa0af75ad1
--- /dev/null
+++ b/addons/kodi.imagedecoder/addon.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<addon id="kodi.imagedecoder" version="1.0.0" provider-name="Team Kodi">
+ <backwards-compatibility abi="1.0.0"/>
+ <requires>
+ <import addon="xbmc.core" version="0.1.0"/>
+ </requires>
+</addon>
diff --git a/addons/metadata.demo.artists/demo.py b/addons/metadata.demo.artists/demo.py
index 819528cda2..98f071ba80 100644
--- a/addons/metadata.demo.artists/demo.py
+++ b/addons/metadata.demo.artists/demo.py
@@ -46,6 +46,9 @@ if action == 'find':
liz.setProperty('artist.genre', 'classical / jazz')
liz.setProperty('artist.born', '2012')
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url="/path/to/artist2", listitem=liz, isFolder=True)
+elif action == 'resolveid':
+ liz=xbmcgui.ListItem(path='/path/to/artist2', offscreen=True)
+ xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=liz)
elif action == 'getdetails':
url=urllib.unquote_plus(params["url"])
print 'Artist with url %s' %(url)
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 0cdc64916a..d8b58cec6e 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -1179,6 +1179,7 @@ msgid "Fetching CD information"
msgstr ""
#: xbmc/dialogs/GUIDialogFileBrowser.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
#: xbmc/video/dialogs/GUIDialogVideoInfo.cpp
#: xbmc/music/windows/GUIWindowMusicBase.cpp
#: xbmc/video/windows/GUIWindowVideoNav.cpp
@@ -3631,7 +3632,7 @@ msgstr ""
#empty strings from id 824 to 827
#. Text for notification that a timer rule has been deleted
-#: xbmc/pvr/timers/PVRTimers.cpp
+#: xbmc/pvr/timers/PVRTimerInfoTag.cpp
msgctxt "#828"
msgid "Timer rule deleted"
msgstr ""
@@ -9016,7 +9017,7 @@ msgstr ""
#: addons/skin.estuary/xml/SkinSettings.xml:
#: addons/skin.estuary/xml/Variables.xml
#: xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19020"
msgid "TV"
msgstr ""
@@ -9026,7 +9027,7 @@ msgstr ""
#: addons/skin.estuary/xml/SkinSettings.xml
#: addons/skin.estuary/xml/Variables.xml
#: xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19021"
msgid "Radio"
msgstr ""
@@ -9114,12 +9115,10 @@ msgstr ""
#. generic 'information' label used in different places, like labels for message box headers
#: xbmc/event/windows/GUIWindowEventLog.cpp
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
#: xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
#: xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp
-#: xbmc/pvr/recordings/PVRRecording.cpp
#: xbmc/pvr/timers/PVRTimerInfoTag.cpp
-#: xbmc/pvr/timers/PVRTimers.cpp
#: xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
#: xbmc/pvr/PVRGUIActions.cpp
#: xbmc/pvr/PVRManager.cpp
@@ -9156,7 +9155,7 @@ msgid "Show signal quality"
msgstr ""
#. message box text stating that a PVR backend does not support a certain functionality.
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
msgctxt "#19038"
msgid "Not supported by the PVR backend."
msgstr ""
@@ -9345,11 +9344,7 @@ msgctxt "#19067"
msgid "This event is already being recorded."
msgstr ""
-#. error box text stating that a given pvr recording could not be deleted
-#: xbmc/pvr/recording/PVRRecording.cpp
-msgctxt "#19068"
-msgid "This recording couldn't be deleted. Check the log for more information about this message."
-msgstr ""
+#empty string with id 19068
#. Electronic program guide
#: addons/skin.estuary/xml/Variables.xml
@@ -9452,7 +9447,7 @@ msgstr ""
#. Label for "Instant recording action" setting
#: system/settings/settings.xml
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19086"
msgid "Instant recording action"
msgstr ""
@@ -9476,19 +9471,19 @@ msgid "Ask what to do"
msgstr ""
#. Label for "Instant recording action" dialog settings value
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19090"
msgid "Record the next %d minutes"
msgstr ""
#. Label for "Instant recording action" dialog settings value
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19091"
msgid "Record current show (%s)"
msgstr ""
#. Label for "Instant recording action" dialog settings value
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19092"
msgid "Record next show (%s)"
msgstr ""
@@ -9592,7 +9587,7 @@ msgstr ""
#. message box text stating that a timer could not be saved
#: xbmc/pvr/timers/PVRTimerInfoTag.cpp
-#: xbmc/pvr/timers/PVRTimers.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19109"
msgid "Couldn't save timer. Check the log for more information about this message."
msgstr ""
@@ -9604,8 +9599,7 @@ msgid "An unexpected error occurred. Try again later or check the log for more i
msgstr ""
#. message box text stating that a PVR backend error occured
-#: xbmc/pvr/addons/PVRClients.cpp
-#: xbmc/pvr/recording/PVRRecording.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
#: xbmc/pvr/timers/PVRTimerInfoTag.cpp
msgctxt "#19111"
msgid "PVR backend error. Check the log for more information about this message."
@@ -9653,7 +9647,7 @@ msgid "Can't use PVR functions while searching."
msgstr ""
#. channel scan backend selection dialog text
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19119"
msgid "On which backend do you want to search?"
msgstr ""
@@ -9810,11 +9804,7 @@ msgctxt "#19146"
msgid "Groups"
msgstr ""
-#. message box text stating that a PVR backend does not support a certain functionality.
-#: xbmc/pvr/recording/PVRRecording.cpp
-msgctxt "#19147"
-msgid "The PVR backend does not support this action. Check the log for more information about this message."
-msgstr ""
+#empty string with id 191407
#: addons/skin.estuary/xml/DialogPVRRadioRDSInfo.xml
#: addons/skin.estuary/xml/DialogPVRGuideSearch.xml
@@ -9910,7 +9900,7 @@ msgid "Recordings"
msgstr ""
#. error box text stating that recording could not be started
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19164"
msgid "Can't start recording. Check the log for more information about this message."
msgstr ""
@@ -9920,8 +9910,10 @@ msgctxt "#19165"
msgid "Switch"
msgstr ""
-#. label for header of system information's PVR section
+#. label for header of misc PVR GUI elements
#: xbmc/windows/GUIWindowSystemInfo.cpp
+#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19166"
msgid "PVR information"
msgstr ""
@@ -10076,13 +10068,13 @@ msgid "PVR service"
msgstr ""
#. error message box text stating that none of the available pvr clients does support channel scanning
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19192"
msgid "None of the connected PVR backends supports scanning for channels."
msgstr ""
#. error message box text stating that a given pvr channel could not be played
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19193"
msgid "The channel scan can't be started. Check the log for more information about this message."
msgstr ""
@@ -10099,7 +10091,7 @@ msgid "Client actions"
msgstr ""
#. value for "pvr client specific actions" dialog headers
-#: xbmc/pvr/addons/PVRClients.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19196"
msgid "PVR client specific actions"
msgstr ""
@@ -10208,7 +10200,7 @@ msgid "Enter a valid URL for the new channel"
msgstr ""
#. message box text stating that a pvr backend does not support timers
-#: xbmc/pvr/timers/PVRTimers.cpp
+#: xbmc/pvr/timers/PVRGUIActions.cpp
#: xbmc/pvr/windows/GUIWindowsPVRTimersBase.cpp
msgctxt "#19215"
msgid "The PVR backend does not support timers."
@@ -10482,27 +10474,21 @@ msgid "Change PIN"
msgstr ""
#. generic 'parental control enter pin' label
-#: xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
-#: xbmc/pvr/PVRManager.cpp
-#: xbmc/settings/SettingConditions.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19262"
msgid "Parental control. Enter PIN:"
msgstr ""
-#. label for 'parental control pin' verification dialog
-#: xbmc/pvr/PVRManager.cpp
-msgctxt "#19263"
-msgid "Locked channel. Enter PIN:"
-msgstr ""
+# empty string with id 19263
#. label for 'incorrect pin' error dialog header
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19264"
msgid "Incorrect PIN"
msgstr ""
#. label for 'incorrect pin' error dialog text
-#: xbmc/pvr/PVRManager.cpp
+#: xbmc/pvr/PVRGUIActions.cpp
msgctxt "#19265"
msgid "The entered PIN was incorrect."
msgstr ""
@@ -11270,23 +11256,7 @@ msgctxt "#19687"
msgid "Play recording"
msgstr ""
-#. label for 'scanning for pvr services' dialog header
-#: xbmc/addons/PVRClient.cpp
-msgctxt "#19688"
-msgid "Scanning for PVR services"
-msgstr ""
-
-#. label for 'scanning for pvr services' dialog text
-#: xbmc/addons/PVRClient.cpp
-msgctxt "#19689"
-msgid "%s service found at %s"
-msgstr ""
-
-#. label for 'scanning for pvr services' dialog text
-#: xbmc/addons/PVRClient.cpp
-msgctxt "#19690"
-msgid "Do you want to use this service?"
-msgstr ""
+#empty strings from id 19688 to 19690
#. Text for shutdown confirmation dialog.
#: xbmc/pvr/PVRManager.cpp
@@ -12638,7 +12608,10 @@ msgctxt "#20381"
msgid "Specials"
msgstr ""
-#empty string with id 20382
+#: xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
+msgctxt "#20382"
+msgid "Recently added"
+msgstr ""
msgctxt "#20383"
msgid "Selected folder contains a single video"
@@ -14783,17 +14756,19 @@ msgctxt "#24093"
msgid "Checking %s..."
msgstr ""
-#empty string with id 24094
+#: xbmc/addons/AddonInstaller.cpp
+msgctxt "#24094"
+msgid "Add-on disabled due to being marked broken in repository."
+msgstr ""
#: xbmc/addons/GUIDialogAddonInfo.cpp
msgctxt "#24095"
msgid "Local package cache"
msgstr ""
-#: xbmc/addons/Repository.cpp
#: addons/skin.estuary/xml/DialogAddonInfo.xml
msgctxt "#24096"
-msgid "Add-on is incompatible or has been marked broken in repository."
+msgid "Add-on has been marked broken in repository."
msgstr ""
#: xbmc/addons/Repository.cpp
@@ -16465,16 +16440,19 @@ msgstr ""
#empty string with id 35013
#. Help text of the button to fix the bug where buttons are skipped in the controller dialog. %s - list of disabled buttons and axes
+#: xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp
msgctxt "#35014"
msgid "Some controllers have buttons and axes that interfere with mapping. Press these now to disable them:[CR]%s"
msgstr ""
-#. Name of a controller button, e.g. Button 1. %d - button index
+#. Name of a controller button, e.g. "Button 1". %d - button index
+#: xbmc/input/joysticks/JoystickTranslator.cpp
msgctxt "#35015"
msgid "Button %d"
msgstr ""
-#. Name of a controller axis, e.g. Axis 2. %d - axis index
+#. Name of a controller axis, e.g. "Axis 2". %d - axis index
+#: xbmc/input/joysticks/JoystickTranslator.cpp
msgctxt "#35016"
msgid "Axis %d"
msgstr ""
@@ -16498,7 +16476,13 @@ msgctxt "#35019"
msgid "Ignore input"
msgstr ""
-#empty strings from id 35020 to 35048
+#. Help text of the dialog to detect analog buttons on controllers. %s - list of detected axes
+#: xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp
+msgctxt "#35020"
+msgid "Press all analog buttons now to detect them:[CR][CR]%s"
+msgstr ""
+
+#empty strings from id 35021 to 35048
#. Name of game add-ons category
#: xbmc/addons/Addon.cpp
@@ -20254,7 +20238,13 @@ msgctxt "#38061"
msgid "Fetch additional information for albums and artists? This could take some time so you may prefer to do this later"
msgstr ""
-#empty strings from id 38062 to 38099
+#. Full tag scanning question on library update (by default tags are only scanned when the file has changed since last time)
+#: xbmc/Application.cpp
+msgctxt "#38062"
+msgid "Do full tag scan even when music files are unchanged?"
+msgstr ""
+
+#empty strings from id 38063 to 38099
#. Description of section #14200 "Player""
#: system/settings/settings.xml
@@ -20424,3 +20414,8 @@ msgstr ""
msgctxt "#39014"
msgid "Would you also like to remove all related data (e.g. settings) of this add-on?"
msgstr ""
+
+#: /xbmc/addons/Addon.cpp
+msgctxt "#39015"
+msgid "Image decoder"
+msgstr ""
diff --git a/addons/skin.estouchy/xml/CustomVolume.xml b/addons/skin.estouchy/xml/CustomVolume.xml
index df87f5e7c7..4a94a1a8e8 100644
--- a/addons/skin.estouchy/xml/CustomVolume.xml
+++ b/addons/skin.estouchy/xml/CustomVolume.xml
@@ -11,7 +11,7 @@
<texturenofocus></texturenofocus>
<texturefocus></texturefocus>
<onclick>Back</onclick>
- <visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar)]</visible>
+ <visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar) | Window.IsVisible(SeekBar)]</visible>
</control>
<control type="group">
<posx>430</posx>
@@ -19,7 +19,7 @@
<width>420</width>
<height>78</height>
<include>16x9_xPos_Relocation</include>
- <visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar)]</visible>
+ <visible>![Window.IsVisible(Notification) | Window.IsVisible(VolumeBar) | Window.IsVisible(SeekBar)]</visible>
<control type="label">
<description>label</description>
<posx>20</posx>
diff --git a/addons/skin.estouchy/xml/DialogSeekBar.xml b/addons/skin.estouchy/xml/DialogSeekBar.xml
index bfe6d61c65..64bd320f01 100644
--- a/addons/skin.estouchy/xml/DialogSeekBar.xml
+++ b/addons/skin.estouchy/xml/DialogSeekBar.xml
@@ -1,3 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
+ <visible>[Window.IsActive(FullscreenVideo) | Window.IsActive(Visualisation)] + ![Window.IsActive(VideoOSD) | Window.IsActive(MusicOSD)] + [Player.Seeking | Player.DisplayAfterSeek]</visible>
+ <controls>
+ <control type="group">
+ <posx>364</posx>
+ <posy>10</posy>
+ <include>VisibleFadeEffect</include>
+ <control type="label">
+ <posx>0</posx>
+ <posy>0</posy>
+ <width>180</width>
+ <height>32</height>
+ <font>font20_title</font>
+ <aligny>center</aligny>
+ <label>$INFO[Player.Time(hh:mm:ss)]</label>
+ </control>
+ <control type="label">
+ <posx>0</posx>
+ <posy>0</posy>
+ <width>552</width>
+ <height>32</height>
+ <font>font20_title</font>
+ <align>center</align>
+ <aligny>center</aligny>
+ <label>$VAR[SeekLabel]</label>
+ </control>
+ <control type="label">
+ <posx>552</posx>
+ <posy>0</posy>
+ <width>180</width>
+ <height>32</height>
+ <font>font20_title</font>
+ <align>right</align>
+ <aligny>center</aligny>
+ <label>$INFO[Player.Duration(hh:mm:ss)]</label>
+ </control>
+ <control type="progress">
+ <description>Progressbar</description>
+ <posx>0</posx>
+ <posy>40</posy>
+ <width>552</width>
+ <height>12</height>
+ <info>Player.Cache</info>
+ <midtexture colordiffuse="grey2">white.png</midtexture>
+ <texturebg></texturebg>
+ </control>
+ <control type="progress">
+ <description>Progressbar</description>
+ <posx>0</posx>
+ <posy>40</posy>
+ <width>552</width>
+ <height>12</height>
+ <info>Player.Progress</info>
+ </control>
+ <control type="slider" id="87">
+ <description>Seek Slider</description>
+ <posx>0</posx>
+ <posy>30</posy>
+ <width>552</width>
+ <height>32</height>
+ <action>seek</action>
+ <texturesliderbar></texturesliderbar>
+ <textureslidernib></textureslidernib>
+ <textureslidernibfocus></textureslidernibfocus>
+ </control>
+ </control>
+ </controls>
</window>
diff --git a/addons/skin.estouchy/xml/SlideShow.xml b/addons/skin.estouchy/xml/SlideShow.xml
index bfe6d61c65..e27f40ac2d 100644
--- a/addons/skin.estouchy/xml/SlideShow.xml
+++ b/addons/skin.estouchy/xml/SlideShow.xml
@@ -1,3 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
+ <controls>
+ <control type="image">
+ <centerleft>50%</centerleft>
+ <centertop>50%</centertop>
+ <width>283</width>
+ <height>283</height>
+ <texture>icon_settings_player.png</texture>
+ <visible>SlideShow.IsVideo + [![Player.Playing + Player.HasVideo] | SlideShow.IsPaused]</visible>
+ </control>
+ </controls>
</window>
diff --git a/addons/skin.estouchy/xml/ViewsList.xml b/addons/skin.estouchy/xml/ViewsList.xml
index ad100fd8c9..e0c32771b4 100644
--- a/addons/skin.estouchy/xml/ViewsList.xml
+++ b/addons/skin.estouchy/xml/ViewsList.xml
@@ -42,7 +42,7 @@
<height>62</height>
<texture background="true">$VAR[PosterThumb]</texture>
<aspectratio>keep</aspectratio>
- <visible>Container.Content(Movies) | Container.Content(Seasons) | Container.Content(TVShows) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Artists) | Container.Content(Albums) | Container.Content(Songs) | [Container.Content(Addons) + !ListItem.IsFolder] | Container.Content(Actors) | Container.Content(Sets) | [Window.IsVisible(Pictures) + !String.IsEmpty(Container.FolderPath)]</visible>
+ <visible>Container.Content(Movies) | Container.Content(Seasons) | Container.Content(TVShows) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos) | Container.Content(Artists) | Container.Content(Albums) | Container.Content(Songs) | [Container.Content(Addons) + !ListItem.IsFolder] | Container.Content(Actors) | Container.Content(Sets) | [Window.IsVisible(Pictures) + !String.IsEmpty(Container.FolderPath)]</visible>
</control>
<control type="image">
<posx>4</posx>
@@ -74,7 +74,7 @@
<align>right</align>
<aligny>center</aligny>
<label>$INFO[ListItem.Label2]</label>
- <animation effect="slide" start="0" end ="100,0" time="0" condition="![Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)]">Conditional</animation>
+ <animation effect="slide" start="0" end ="100,0" time="0" condition="![Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)]">Conditional</animation>
<animation effect="slide" start="0" end ="-40,0" time="0" condition="Container.Content(TVShows)">Conditional</animation>
<visible>!Window.IsVisible(AddonBrowser)</visible>
</control>
@@ -105,7 +105,7 @@
<width>60</width>
<height>40</height>
<texture>$INFO[ListItem.VideoResolution,flagging/resolution/,.png]</texture>
- <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)]</visible>
+ <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)]</visible>
</control>
<control type="image">
<posx>110r</posx>
@@ -122,7 +122,7 @@
<height>26</height>
<aspectratio>keep</aspectratio>
<texture>OverlayWatching.png</texture>
- <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)] + ListItem.IsResumable</visible>
+ <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)] + ListItem.IsResumable</visible>
</control>
<control type="image">
<posx>50r</posx>
@@ -130,7 +130,7 @@
<width>30</width>
<height>30</height>
<texture>$INFO[ListItem.Overlay]</texture>
- <visible>[Container.Content(Movies) | Container.Content(TVShows) | Container.Content(Seasons) | Container.Content(Episodes) | Container.Content(MusicVideos)] + !ListItem.IsResumable</visible>
+ <visible>[Container.Content(Movies) | Container.Content(TVShows) | Container.Content(Seasons) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)] + !ListItem.IsResumable</visible>
</control>
<control type="label">
<posx>$PARAM[label2-posx]</posx>
@@ -184,7 +184,7 @@
<height>62</height>
<texture background="true">$VAR[PosterThumb]</texture>
<aspectratio>keep</aspectratio>
- <visible>Container.Content(Movies) | Container.Content(Seasons) | Container.Content(TVShows) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Artists) | Container.Content(Albums) | Container.Content(Songs) | [Container.Content(Addons) + !ListItem.IsFolder] | Container.Content(Actors) | Container.Content(Sets) | [Window.IsVisible(Pictures) + !String.IsEmpty(Container.FolderPath)]</visible>
+ <visible>Container.Content(Movies) | Container.Content(Seasons) | Container.Content(TVShows) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos) | Container.Content(Artists) | Container.Content(Albums) | Container.Content(Songs) | [Container.Content(Addons) + !ListItem.IsFolder] | Container.Content(Actors) | Container.Content(Sets) | [Window.IsVisible(Pictures) + !String.IsEmpty(Container.FolderPath)]</visible>
</control>
<control type="image">
<posx>4</posx>
@@ -216,7 +216,7 @@
<align>right</align>
<aligny>center</aligny>
<label>$INFO[ListItem.Label2]</label>
- <animation effect="slide" start="0" end ="100,0" time="0" condition="![Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)]">Conditional</animation>
+ <animation effect="slide" start="0" end ="100,0" time="0" condition="![Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)]">Conditional</animation>
<animation effect="slide" start="0" end ="-40,0" time="0" condition="Container.Content(TVShows)">Conditional</animation>
<visible>!Window.IsVisible(AddonBrowser)</visible>
</control>
@@ -247,7 +247,7 @@
<width>60</width>
<height>40</height>
<texture>$INFO[ListItem.VideoResolution,flagging/resolution/,.png]</texture>
- <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)]</visible>
+ <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)]</visible>
</control>
<control type="image">
<posx>110r</posx>
@@ -264,7 +264,7 @@
<height>26</height>
<aspectratio>keep</aspectratio>
<texture>OverlayWatching.png</texture>
- <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos)] + ListItem.IsResumable</visible>
+ <visible>[Container.Content(Movies) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)] + ListItem.IsResumable</visible>
</control>
<control type="image">
<posx>50r</posx>
@@ -272,7 +272,7 @@
<width>30</width>
<height>30</height>
<texture>$INFO[ListItem.Overlay]</texture>
- <visible>[Container.Content(Movies) | Container.Content(TVShows) | Container.Content(Seasons) | Container.Content(Episodes) | Container.Content(MusicVideos)] + !ListItem.IsResumable</visible>
+ <visible>[Container.Content(Movies) | Container.Content(TVShows) | Container.Content(Seasons) | Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)] + !ListItem.IsResumable</visible>
</control>
<control type="label">
<posx>$PARAM[label2-posx]</posx>
diff --git a/addons/skin.estouchy/xml/ViewsThumbnail.xml b/addons/skin.estouchy/xml/ViewsThumbnail.xml
index fcc599a9ac..a3e4dade5a 100644
--- a/addons/skin.estouchy/xml/ViewsThumbnail.xml
+++ b/addons/skin.estouchy/xml/ViewsThumbnail.xml
@@ -17,7 +17,7 @@
<animation effect="slide" start="0,0" end="-1,0" time="0" condition="String.IsEqual(Skin.AspectRatio,4:3)">Conditional</animation>
<animation effect="slide" start="0,0" end="-1,0" time="0" condition="String.IsEqual(Skin.AspectRatio,16:9) + Container.Content(Episodes)">Conditional</animation>
<animation effect="slide" start="0,0" end="28,0" time="0" condition="String.IsEqual(Skin.AspectRatio,4:3) + Container.Content(Episodes)">Conditional</animation>
- <itemlayout condition="!Container.Content(Movies) + !Container.Content(Seasons) + !Container.Content(Episodes) + !Container.Content(TVShows) + !Container.Content(MusicVideos)" height="250" width="218">
+ <itemlayout condition="!Container.Content(Movies) + !Container.Content(Seasons) + !Container.Content(Episodes) + !Container.Content(TVShows) + !Container.Content(MusicVideos) + !Container.Content(Videos)" height="250" width="218">
<control type="image">
<posx>5</posx>
<posy>0</posy>
@@ -73,7 +73,7 @@
<visible>Window.IsVisible(AddonBrowser) + String.IsEqual(ListItem.Label2,$LOCALIZE[305])</visible>
</control>
</itemlayout>
- <focusedlayout condition="!Container.Content(Movies) + !Container.Content(Seasons) + !Container.Content(Episodes) + !Container.Content(TVShows) + !Container.Content(MusicVideos)" height="250" width="218">
+ <focusedlayout condition="!Container.Content(Movies) + !Container.Content(Seasons) + !Container.Content(Episodes) + !Container.Content(TVShows) + !Container.Content(MusicVideos) + !Container.Content(Videos)" height="250" width="218">
<control type="image">
<posx>5</posx>
<posy>0</posy>
@@ -247,7 +247,7 @@
<texture>$INFO[ListItem.Overlay]</texture>
</control>
</focusedlayout>
- <itemlayout condition="Container.Content(Episodes) | Container.Content(MusicVideos)" height="250" width="$PARAM[layout-width]">
+ <itemlayout condition="Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)" height="250" width="$PARAM[layout-width]">
<control type="image">
<posx>0</posx>
<posy>0</posy>
@@ -298,7 +298,7 @@
<texture>$INFO[ListItem.Overlay]</texture>
</control>
</itemlayout>
- <focusedlayout condition="Container.Content(Episodes) | Container.Content(MusicVideos)" height="250" width="$PARAM[layout-width]">
+ <focusedlayout condition="Container.Content(Episodes) | Container.Content(MusicVideos) | Container.Content(Videos)" height="250" width="$PARAM[layout-width]">
<control type="image">
<posx>0</posx>
<posy>0</posy>
diff --git a/addons/skin.estuary/xml/AddonBrowser.xml b/addons/skin.estuary/xml/AddonBrowser.xml
index f3ee214b28..dd211bcc78 100644
--- a/addons/skin.estuary/xml/AddonBrowser.xml
+++ b/addons/skin.estuary/xml/AddonBrowser.xml
@@ -63,7 +63,7 @@
<control type="group">
<height>78</height>
<bottom>0</bottom>
- <visible>$EXP[sidebar_focused]</visible>
+ <visible>$EXP[sidebar_visible]</visible>
<animation effect="fade" time="300">VisibleChange</animation>
<include content="LeftAlignedInfo">
<param name="main_label" value="$INFO[Window(AddonBrowser).Property(Updated)]" />
diff --git a/addons/skin.estuary/xml/Constants_1920.xml b/addons/skin.estuary/xml/Constants_1920.xml
index d85f2d53d2..f9b714beff 100644
--- a/addons/skin.estuary/xml/Constants_1920.xml
+++ b/addons/skin.estuary/xml/Constants_1920.xml
@@ -7,5 +7,5 @@
<constant name="tvrecordings_width">1060</constant>
<constant name="eventloglist_width">1430</constant>
<constant name="playlisteditorlist_width">770</constant>
- <constant name="playlistlist_width">904</constant>
+ <constant name="playlistlist_width">896</constant>
</includes>
diff --git a/addons/skin.estuary/xml/Constants_2560.xml b/addons/skin.estuary/xml/Constants_2560.xml
index fea8fc5886..ba83217abd 100644
--- a/addons/skin.estuary/xml/Constants_2560.xml
+++ b/addons/skin.estuary/xml/Constants_2560.xml
@@ -7,5 +7,5 @@
<constant name="tvrecordings_width">1700</constant>
<constant name="eventloglist_width">2070</constant>
<constant name="playlisteditorlist_width">1410</constant>
- <constant name="playlistlist_width">1544</constant>
+ <constant name="playlistlist_width">1536</constant>
</includes>
diff --git a/addons/skin.estuary/xml/DialogMusicInfo.xml b/addons/skin.estuary/xml/DialogMusicInfo.xml
index 4f895ab4e2..08940cc059 100644
--- a/addons/skin.estuary/xml/DialogMusicInfo.xml
+++ b/addons/skin.estuary/xml/DialogMusicInfo.xml
@@ -31,7 +31,7 @@
<height>567</height>
<aspectratio aligny="top">scale</aspectratio>
<fadetime>300</fadetime>
- <texture background="true" fallback="DefaultAudio.png">$INFO[ListItem.Art(thumb)]</texture>
+ <texture background="true">$VAR[MusicInfoThumbVar]</texture>
</control>
</control>
<control type="group">
diff --git a/addons/skin.estuary/xml/Includes.xml b/addons/skin.estuary/xml/Includes.xml
index b3f7993305..205e0ea551 100644
--- a/addons/skin.estuary/xml/Includes.xml
+++ b/addons/skin.estuary/xml/Includes.xml
@@ -34,7 +34,7 @@
<constant name="list_y_offset">0</constant>
<constant name="list_item_height">80</constant>
<expression name="infodialog_active">Window.IsActive(musicinformation) | Window.IsActive(songinformation) | Window.IsActive(movieinformation) | Window.IsActive(addoninformation) | Window.IsActive(pvrguideinfo) | Window.IsActive(pvrrecordinginfo) | Window.IsActive(pictureinfo) | Window.IsVisible(script-script.extendedinfo-DialogVideoInfo.xml) | Window.IsVisible(script-script.extendedinfo-DialogInfo.xml) | Window.IsVisible(script-script.extendedinfo-VideoList.xml)</expression>
- <expression name="sidebar_focused">ControlGroup(9000).HasFocus | Control.HasFocus(6130)</expression>
+ <expression name="sidebar_visible">ControlGroup(9000).HasFocus | Control.HasFocus(6130) | Window.IsActive(MyPlaylist.xml)</expression>
<include name="CommonScrollbars">
<control type="group">
<animation effect="fade" start="100" end="0" time="150">WindowClose</animation>
@@ -320,6 +320,7 @@
<font>$PARAM[font]</font>
<aligny>center</aligny>
<label>$INFO[ListItem.Label]</label>
+ <scroll>true</scroll>
</control>
</focusedlayout>
</definition>
diff --git a/addons/skin.estuary/xml/Includes_MediaMenu.xml b/addons/skin.estuary/xml/Includes_MediaMenu.xml
index 89cb087b65..9a3c103748 100644
--- a/addons/skin.estuary/xml/Includes_MediaMenu.xml
+++ b/addons/skin.estuary/xml/Includes_MediaMenu.xml
@@ -198,7 +198,7 @@
<onleft>14100</onleft>
<onup>8</onup>
<ondown>6056</ondown>
- <visible>Player.HasMedia + [$EXP[sidebar_focused]]</visible>
+ <visible>Player.HasMedia + [$EXP[sidebar_visible]]</visible>
<visible>!System.HasActiveModalDialog</visible>
<include content="BottomMainMenuToggleItem">
<param name="control_id" value="14101" />
@@ -241,7 +241,7 @@
<include>OpenClose_Left</include>
<depth>DepthSideBlade</depth>
<left>-520</left>
- <animation type="Conditional" condition="$EXP[sidebar_focused]" reversible="true">
+ <animation type="Conditional" condition="$EXP[sidebar_visible]" reversible="true">
<effect type="slide" start="0" end="520" time="400" tween="cubic" easing="out" />
</animation>
<control type="image">
@@ -249,7 +249,7 @@
<height>100%</height>
<aspectratio>scale</aspectratio>
<texture colordiffuse="80FFFFFF">colors/black.png</texture>
- <visible>$EXP[sidebar_focused] + !System.HasActiveModalDialog</visible>
+ <visible>$EXP[sidebar_visible] + !System.HasActiveModalDialog</visible>
<animation effect="fade" time="200">VisibleChange</animation>
</control>
<control type="image">
@@ -269,41 +269,45 @@
</control>
</include>
<include name="MediaMenuNowPlaying">
- <control type="grouplist" id="14100">
- <animation effect="fade" start="0" end="100" time="400">WindowOpen</animation>
- <animation effect="fade" start="100" end="0" time="300">WindowClose</animation>
- <animation effect="fade" time="300">VisibleChange</animation>
- <orientation>horizontal</orientation>
- <itemgap>-17</itemgap>
- <left>5</left>
- <onleft>14100</onleft>
- <width>450</width>
- <visible>Player.HasMedia + [$EXP[sidebar_focused]]</visible>
- <visible>!System.HasActiveModalDialog</visible>
- <include content="BottomMainMenuToggleItem">
- <param name="control_id" value="14101" />
- <param name="onclick" value="PlayerControl(Play)" />
- <param name="icon_on" value="icons/now-playing/play.png" />
- <param name="icon_off" value="icons/now-playing/pause.png" />
- <param name="selected" value="Player.Paused" />
- </include>
- <include content="IconButton">
- <param name="control_id" value="14102" />
- <param name="onclick" value="Stop" />
- <param name="onclick_2" value="SetFocus(50)" />
- <param name="icon" value="icons/now-playing/stop.png" />
- </include>
- <include content="IconButton">
- <param name="control_id" value="14104" />
- <param name="onclick" value="PlayerControl(Next)" />
- <param name="icon" value="icons/now-playing/next.png" />
- </include>
- <include content="IconButton">
- <param name="control_id" value="14105" />
- <param name="onclick" value="Fullscreen" />
- <param name="icon" value="icons/now-playing/fullscreen.png" />
- </include>
- </control>
+ <param name="left">5</param>
+ <definition>
+ <control type="grouplist" id="14100">
+ <animation effect="fade" start="0" end="100" time="400">WindowOpen</animation>
+ <animation effect="fade" start="100" end="0" time="300">WindowClose</animation>
+ <animation effect="fade" time="300">VisibleChange</animation>
+ <animation effect="slide" end="-10,0" time="0" condition ="Window.IsActive(MyPlaylist.xml)">Conditional</animation>
+ <orientation>horizontal</orientation>
+ <itemgap>-17</itemgap>
+ <left>$PARAM[left]</left>
+ <onleft>14100</onleft>
+ <width>450</width>
+ <visible>Player.HasMedia + [$EXP[sidebar_visible]]</visible>
+ <visible>!System.HasActiveModalDialog</visible>
+ <include content="BottomMainMenuToggleItem">
+ <param name="control_id" value="14101" />
+ <param name="onclick" value="PlayerControl(Play)" />
+ <param name="icon_on" value="icons/now-playing/play.png" />
+ <param name="icon_off" value="icons/now-playing/pause.png" />
+ <param name="selected" value="Player.Paused" />
+ </include>
+ <include content="IconButton">
+ <param name="control_id" value="14102" />
+ <param name="onclick" value="Stop" />
+ <param name="onclick_2" value="SetFocus(50)" />
+ <param name="icon" value="icons/now-playing/stop.png" />
+ </include>
+ <include content="IconButton">
+ <param name="control_id" value="14104" />
+ <param name="onclick" value="PlayerControl(Next)" />
+ <param name="icon" value="icons/now-playing/next.png" />
+ </include>
+ <include content="IconButton">
+ <param name="control_id" value="14105" />
+ <param name="onclick" value="Fullscreen" />
+ <param name="icon" value="icons/now-playing/fullscreen.png" />
+ </include>
+ </control>
+ </definition>
</include>
<include name="MediaMenuListCommon">
<definition>
@@ -343,7 +347,6 @@
</control>
<control type="button" id="19">
<visible>Container.CanFilter + !Container.CanFilterAdvanced</visible>
- <visible>!Container.Content()</visible>
<include>MediaMenuItemsCommon</include>
<label>$LOCALIZE[137]</label>
</control>
diff --git a/addons/skin.estuary/xml/MyPlaylist.xml b/addons/skin.estuary/xml/MyPlaylist.xml
index 51361f04c8..f66dc10734 100644
--- a/addons/skin.estuary/xml/MyPlaylist.xml
+++ b/addons/skin.estuary/xml/MyPlaylist.xml
@@ -10,9 +10,9 @@
<control type="group">
<include>OpenClose_Left</include>
<control type="fixedlist" id="50">
- <left>402</left>
+ <left>410</left>
<top>list_y_offset</top>
- <right>594</right>
+ <right>586</right>
<bottom>list_y_offset</bottom>
<scrolltime tween="cubic" easing="out">500</scrolltime>
<orientation>vertical</orientation>
@@ -79,7 +79,7 @@
<control type="group">
<depth>DepthContentPanel</depth>
<include content="ContentPanel">
- <param name="width" value="462" />
+ <param name="width" value="470" />
</include>
<control type="grouplist" id="700">
<orientation>vertical</orientation>
@@ -90,9 +90,9 @@
<ondown>700</ondown>
<onleft>50</onleft>
<onright>50</onright>
- <width>402</width>
+ <width>410</width>
<control type="radiobutton" id="20">
- <width>402</width>
+ <width>410</width>
<height>110</height>
<align>left</align>
<aligny>top</aligny>
@@ -115,6 +115,9 @@
<param name="control_id" value="22" />
<param name="label" value="$LOCALIZE[192]" />
</include>
+ <include content="MediaMenuNowPlaying">
+ <param name="left" value="-5" />
+ </include>
</control>
</control>
</control>
diff --git a/addons/skin.estuary/xml/MyVideoNav.xml b/addons/skin.estuary/xml/MyVideoNav.xml
index 8b2b8f8da3..ea67f8e956 100644
--- a/addons/skin.estuary/xml/MyVideoNav.xml
+++ b/addons/skin.estuary/xml/MyVideoNav.xml
@@ -138,7 +138,7 @@
<include>MediaMenuItemsCommon</include>
<label>$LOCALIZE[31056]</label>
<onclick>ActivateWindow(videoplaylist)</onclick>
- <visible>IntegerGreaterThan(Playlist.Length(video),0)</visible>
+ <visible>Integer.IsGreater(Playlist.Length(video),0)</visible>
</control>
<control type="button" id="621">
<description>Get more</description>
diff --git a/addons/skin.estuary/xml/SlideShow.xml b/addons/skin.estuary/xml/SlideShow.xml
index bfe6d61c65..666f38cbfb 100644
--- a/addons/skin.estuary/xml/SlideShow.xml
+++ b/addons/skin.estuary/xml/SlideShow.xml
@@ -1,3 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
+ <controls>
+ <control type="image">
+ <centerleft>50%</centerleft>
+ <centertop>50%</centertop>
+ <width>256</width>
+ <height>256</height>
+ <texture>icons/settings/player.png</texture>
+ <visible>SlideShow.IsVideo + [![Player.Playing + Player.HasVideo] | SlideShow.IsPaused]</visible>
+ </control>
+ </controls>
</window>
diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml
index 35407add0b..007ed12300 100644
--- a/addons/skin.estuary/xml/Variables.xml
+++ b/addons/skin.estuary/xml/Variables.xml
@@ -65,6 +65,12 @@
<value condition="ListItem.IsFolder + String.IsEmpty(ListItem.Thumb)">DefaultFolderSquare.png</value>
<value>$INFO[ListItem.Thumb]</value>
</variable>
+ <variable name="MusicInfoThumbVar">
+ <value condition="!String.IsEmpty(Listitem.Art(thumb))">$INFO[Listitem.Art(thumb)]</value>
+ <value condition="String.IsEqual(listitem.dbtype,artist)">DefaultArtist.png</value>
+ <value condition="String.IsEqual(listitem.dbtype,album)">DefaultAlbumCover.png</value>
+ <value>DefaultAudio.png</value>
+ </variable>
<variable name="InfoWallThumbVar">
<value condition="!String.IsEmpty(Listitem.Art(poster))">$INFO[Listitem.Art(poster)]</value>
<value>$INFO[ListItem.Icon]</value>
diff --git a/addons/skin.estuary/xml/View_51_Poster.xml b/addons/skin.estuary/xml/View_51_Poster.xml
index 2d3b96de61..ff91cb130d 100644
--- a/addons/skin.estuary/xml/View_51_Poster.xml
+++ b/addons/skin.estuary/xml/View_51_Poster.xml
@@ -190,6 +190,7 @@
<autoscroll time="3000" delay="7000" repeat="5000">!System.HasActiveModalDialog + Skin.HasSetting(AutoScroll)</autoscroll>
<label>$INFO[ListItem.Plot]</label>
<shadowcolor>text_shadow</shadowcolor>
+ <visible>!ListItem.IsCollection</visible>
</control>
</control>
</control>
diff --git a/addons/skin.estuary/xml/View_55_WideList.xml b/addons/skin.estuary/xml/View_55_WideList.xml
index 6652a00893..7ce10ede2e 100644
--- a/addons/skin.estuary/xml/View_55_WideList.xml
+++ b/addons/skin.estuary/xml/View_55_WideList.xml
@@ -37,7 +37,7 @@
<aligny>center</aligny>
<label>$INFO[ListItem.Year]</label>
<shadowcolor>text_shadow</shadowcolor>
- <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies)</visible>
+ <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies) + !Container.Content(videos)</visible>
</control>
<control type="image">
<left>35</left>
@@ -45,7 +45,7 @@
<width>32</width>
<height>32</height>
<texture>$VAR[ListWatchedIconVar]</texture>
- <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | String.IsEmpty(ListItem.Year)</visible>
+ <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | Container.Content(videos) | String.IsEmpty(ListItem.Year)</visible>
</control>
<control type="label">
<left>105</left>
@@ -78,7 +78,7 @@
<label>$INFO[ListItem.Year]</label>
<textcolor>button_focus</textcolor>
<shadowcolor>text_shadow</shadowcolor>
- <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies)</visible>
+ <visible>!Container.Content(tvshows) + !Container.Content(seasons) + !Container.Content(episodes) + !Container.Content(movies) + !Container.Content(videos)</visible>
</control>
<control type="image">
<left>35</left>
@@ -86,7 +86,7 @@
<width>32</width>
<height>32</height>
<texture colordiffuse="grey">$VAR[ListWatchedIconVar]</texture>
- <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | String.IsEmpty(ListItem.Year)</visible>
+ <visible>Container.Content(tvshows) | Container.Content(seasons) | Container.Content(episodes) | Container.Content(movies) | Container.Content(videos) | String.IsEmpty(ListItem.Year)</visible>
</control>
<control type="label">
<left>105</left>
diff --git a/cmake/cpack/deb/packages/kodi-image-dev.txt.in b/cmake/cpack/deb/packages/kodi-image-dev.txt.in
new file mode 100644
index 0000000000..e9b72f144e
--- /dev/null
+++ b/cmake/cpack/deb/packages/kodi-image-dev.txt.in
@@ -0,0 +1,25 @@
+# kodi-image-dev debian package metadata
+#
+# Setting PACKAGE_SHLIBDEPS to 'ON' will cause CPack to use dpkg-shlibdeps to
+# automatically generate the package dependency list and append its output to
+# PACKAGE_DEPENDS list. Only useful for packages that contain binaries.
+#
+# PACKAGE_ARCHITECTURE should be set to 'all' only if package contains
+# architecture agnostic data. CPack will set proper architecture (amd64/i386/etc)
+# based on build options.
+#
+# Remaining settings are (hopefully) self-explanatory.
+
+PACKAGE_NAME @APP_NAME_LC@-image-dev
+PACKAGE_ARCHITECTURE all
+PACKAGE_SECTION libdevel
+PACKAGE_PRIORITY optional
+PACKAGE_SHLIBDEPS
+PACKAGE_DEPENDS @APP_NAME_LC@-addon-dev
+PACKAGE_RECOMMENDS
+PACKAGE_SUGGESTS
+PACKAGE_BREAKS
+PACKAGE_REPLACES
+PACKAGE_PROVIDES xbmc-image-dev
+PACKAGE_DESCRIPTION_HEADER @APP_NAME@ Media Center (image add-ons dev package)
+PACKAGE_DESCRIPTION_FOOTER This is the development package for @APP_NAME@'s image add-ons.
diff --git a/cmake/installdata/common/addons.txt b/cmake/installdata/common/addons.txt
index ad951eced6..0c8f296b59 100644
--- a/cmake/installdata/common/addons.txt
+++ b/cmake/installdata/common/addons.txt
@@ -5,6 +5,7 @@ addons/game.controller.default/*
addons/kodi.adsp/*
addons/kodi.audiodecoder/*
addons/kodi.game/*
+addons/kodi.imagedecoder/*
addons/kodi.inputstream/*
addons/kodi.peripheral/*
addons/kodi.resource/*
diff --git a/cmake/modules/FindEMBEDDED.cmake b/cmake/modules/FindEMBEDDED.cmake
index 5e49716549..8034c4e959 100644
--- a/cmake/modules/FindEMBEDDED.cmake
+++ b/cmake/modules/FindEMBEDDED.cmake
@@ -13,4 +13,4 @@ if(NOT KODI_DEPENDSBUILD AND NOT TARGET_ARCH_ARM)
return()
endif()
-find_path(EMBEDDED_FOUND NAMES include/linux/imxfb.h include/bcm_host.h PATHS /opt/vc)
+find_path(EMBEDDED_FOUND NAMES include/linux/mxcfb.h include/bcm_host.h PATHS /opt/vc)
diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake
index 055466367b..ba9fb541ed 100644
--- a/cmake/modules/FindSSE.cmake
+++ b/cmake/modules/FindSSE.cmake
@@ -14,13 +14,10 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
string(COMPARE EQUAL "sse2" "${_SSE_THERE}" _SSE2_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse2" _SSE2_OK)
- # /proc/cpuinfo apparently omits sse3 :(
- string(REGEX REPLACE "^.*[^s](sse3).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "sse3" "${_SSE_THERE}" _SSE3_TRUE)
- if(NOT _SSE3_TRUE)
- string(REGEX REPLACE "^.*(T2300).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "T2300" "${_SSE_THERE}" _SSE3_TRUE)
- endif()
+ # SSE3 is also known as the Prescott New Instructions (PNI)
+ # it's labeled as pni in /proc/cpuinfo
+ string(REGEX REPLACE "^.*(pni).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(COMPARE EQUAL "pni" "${_SSE_THERE}" _SSE3_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse3" _SSE3_OK)
string(REGEX REPLACE "^.*(ssse3).*$" "\\1" _SSE_THERE ${CPUINFO})
diff --git a/cmake/scripts/ios/ArchSetup.cmake b/cmake/scripts/ios/ArchSetup.cmake
index bdd2656c1b..dbb7c4858e 100644
--- a/cmake/scripts/ios/ArchSetup.cmake
+++ b/cmake/scripts/ios/ArchSetup.cmake
@@ -36,7 +36,7 @@ list(APPEND DEPLIBS "-framework CoreFoundation" "-framework CoreVideo"
set(ENABLE_DVDCSS OFF CACHE BOOL "" FORCE)
set(ENABLE_OPTICAL OFF CACHE BOOL "" FORCE)
-set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "5.1")
+set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "6.0")
set(CMAKE_XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
set(CMAKE_XCODE_ATTRIBUTE_INLINES_ARE_PRIVATE_EXTERN OFF)
diff --git a/cmake/scripts/linux/Install.cmake b/cmake/scripts/linux/Install.cmake
index 7c96e8f3ae..0462c77a11 100644
--- a/cmake/scripts/linux/Install.cmake
+++ b/cmake/scripts/linux/Install.cmake
@@ -196,6 +196,12 @@ install(FILES ${CMAKE_SOURCE_DIR}/xbmc/cores/AudioEngine/Utils/AEChannelData.h
DESTINATION ${includedir}/${APP_NAME_LC}
COMPONENT kodi-audio-dev)
+# Install kodi-image-dev
+install(FILES ${CMAKE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h
+ ${CMAKE_SOURCE_DIR}/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h
+ DESTINATION ${includedir}/${APP_NAME_LC}
+ COMPONENT kodi-image-dev)
+
if(ENABLE_EVENTCLIENTS)
# Install kodi-eventclients-common BT python files
install(PROGRAMS ${CMAKE_SOURCE_DIR}/tools/EventClients/lib/python/bt/__init__.py
diff --git a/cmake/treedata/common/video.txt b/cmake/treedata/common/video.txt
index e7855a0809..acfb33bf57 100644
--- a/cmake/treedata/common/video.txt
+++ b/cmake/treedata/common/video.txt
@@ -1,5 +1,4 @@
xbmc/video video
xbmc/video/dialogs video/dialogs
xbmc/video/jobs video/jobs
-xbmc/video/videosync video/sync
xbmc/video/windows video/windows
diff --git a/docs/README.android b/docs/README.android
index d8e43b619c..8fb67a71f2 100644
--- a/docs/README.android
+++ b/docs/README.android
@@ -1,8 +1,8 @@
TOC
1. Introduction
-2. Installing and setting up the Android environment
-3. Getting the source code
-4. Installing the required Ubuntu packages
+2. Installing the required Ubuntu packages
+3. Installing and setting up the Android environment
+4. Getting the source code
5. How to compile
6. Installing Kodi in an Android system
7. Running and debugging Kodi in an Android system
diff --git a/docs/README.ios.md b/docs/README.ios.md
index 0a3adb56da..c7f9332153 100644
--- a/docs/README.ios.md
+++ b/docs/README.ios.md
@@ -60,6 +60,8 @@ constellations of Xcode and macOS versions (to be updated once we know more):
5. Xcode 7.x against iOS SDK 9.x on 10.10 (Yosemite)
6. Xcode 7.x against iOS SDK 9.x on 10.11 (El Capitan)
7. Xcode 7.x against iOS SDK 9.x on 10.12 (Sierra)
+8. Xcode 8.x against iOS SDK 10.x (El Capitan)
+9. Xcode 8.x against iOS SDK 10.x (Sierra)
The preferred iOS SDK Version is 8.1.
diff --git a/docs/README.raspberrypi b/docs/README.raspberrypi
index b13d763c91..29eaa86273 100644
--- a/docs/README.raspberrypi
+++ b/docs/README.raspberrypi
@@ -32,8 +32,8 @@ build for the first Raspberry Pi, the commands have to be adapted to use
$ sudo mkdir -p /opt/bcm-rootfs/opt
$ sudo cp -r firmware/opt/vc /opt/bcm-rootfs/opt
- $ sudo mkdir -p /opt/xbmc-bcm
- $ sudo chmod 777 /opt/xbmc-bcm
+ $ sudo mkdir -p /opt/kodi-bcm
+ $ sudo chmod 777 /opt/kodi-bcm
$ git clone https://github.com/xbmc/xbmc
@@ -41,7 +41,7 @@ build for the first Raspberry Pi, the commands have to be adapted to use
$ ./bootstrap
$ PATH="$PATH:/opt/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin" \
./configure --host=arm-linux-gnueabihf \
- --prefix=/opt/xbmc-bcm/xbmc-dbg \
+ --prefix=/opt/kodi-bcm/kodi-dbg \
--with-toolchain=/usr/local/bcm-gcc/arm-bcm2708hardfp-linux-gnueabi/sysroot \
--with-firmware=/opt/bcm-rootfs \
--with-platform=raspberry-pi2 \
diff --git a/system/addon-manifest.xml b/system/addon-manifest.xml
index fd7737470e..8d557bde9d 100644
--- a/system/addon-manifest.xml
+++ b/system/addon-manifest.xml
@@ -6,6 +6,7 @@
<addon>kodi.audiodecoder</addon>
<addon>kodi.game</addon>
<addon>kodi.guilib</addon>
+ <addon>kodi.imagedecoder</addon>
<addon>kodi.inputstream</addon>
<addon>kodi.peripheral</addon>
<addon>kodi.resource</addon>
diff --git a/system/library/video/movies/actors.xml b/system/library/video/movies/actors.xml
index 48a0912272..ceccc45dc9 100644
--- a/system/library/video/movies/actors.xml
+++ b/system/library/video/movies/actors.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="4" type="filter">
+<node order="5" type="filter">
<label>344</label>
<icon>DefaultActor.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/country.xml b/system/library/video/movies/country.xml
index 1b68b82201..2f5a54f6d0 100644
--- a/system/library/video/movies/country.xml
+++ b/system/library/video/movies/country.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="8" type="filter">
+<node order="9" type="filter">
<label>20451</label>
<icon>DefaultCountry.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/directors.xml b/system/library/video/movies/directors.xml
index f074dcb6c0..60c672442f 100644
--- a/system/library/video/movies/directors.xml
+++ b/system/library/video/movies/directors.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="5" type="filter">
+<node order="6" type="filter">
<label>20348</label>
<icon>DefaultDirector.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/genres.xml b/system/library/video/movies/genres.xml
index 1764b03ed3..d57c7069dd 100644
--- a/system/library/video/movies/genres.xml
+++ b/system/library/video/movies/genres.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="1" type="filter">
+<node order="2" type="filter">
<label>135</label>
<icon>DefaultGenre.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/recentlyaddedmovies.xml b/system/library/video/movies/recentlyaddedmovies.xml
index 721d45237a..e61c22af2e 100644
--- a/system/library/video/movies/recentlyaddedmovies.xml
+++ b/system/library/video/movies/recentlyaddedmovies.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="10" type="folder">
- <label>20386</label>
+<node order="1" type="folder">
+ <label>20382</label>
<icon>DefaultRecentlyAddedMovies.png</icon>
<path>videodb://recentlyaddedmovies/</path>
</node>
diff --git a/system/library/video/movies/sets.xml b/system/library/video/movies/sets.xml
index 4f1e065b30..e8e9491907 100644
--- a/system/library/video/movies/sets.xml
+++ b/system/library/video/movies/sets.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="7" type="filter" visible="Library.HasContent(MovieSets)">
+<node order="8" type="filter" visible="Library.HasContent(MovieSets)">
<label>20434</label>
<icon>DefaultSets.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/studios.xml b/system/library/video/movies/studios.xml
index 6dd1f77ed8..d167cb8945 100644
--- a/system/library/video/movies/studios.xml
+++ b/system/library/video/movies/studios.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="6" type="filter">
+<node order="7" type="filter">
<label>20388</label>
<icon>DefaultStudios.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/tags.xml b/system/library/video/movies/tags.xml
index f2f09c370e..92b6521b2e 100644
--- a/system/library/video/movies/tags.xml
+++ b/system/library/video/movies/tags.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="9" type="filter">
+<node order="10" type="filter">
<label>20459</label>
<icon>DefaultTags.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/titles.xml b/system/library/video/movies/titles.xml
index ec41450b2f..9dfd483080 100644
--- a/system/library/video/movies/titles.xml
+++ b/system/library/video/movies/titles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="2" type="filter">
+<node order="3" type="filter">
<label>10024</label>
<icon>DefaultMovieTitle.png</icon>
<content>movies</content>
diff --git a/system/library/video/movies/years.xml b/system/library/video/movies/years.xml
index 234bd9a963..30217f7740 100644
--- a/system/library/video/movies/years.xml
+++ b/system/library/video/movies/years.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="3" type="filter">
+<node order="4" type="filter">
<label>652</label>
<icon>DefaultYear.png</icon>
<content>movies</content>
diff --git a/system/library/video/musicvideos/albums.xml b/system/library/video/musicvideos/albums.xml
index ce44b5b6d6..ee0fbf9574 100644
--- a/system/library/video/musicvideos/albums.xml
+++ b/system/library/video/musicvideos/albums.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="5" type="filter">
+<node order="6" type="filter">
<label>132</label>
<icon>DefaultMusicAlbums.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/artists.xml b/system/library/video/musicvideos/artists.xml
index 4913592fd8..f73acd8ad7 100644
--- a/system/library/video/musicvideos/artists.xml
+++ b/system/library/video/musicvideos/artists.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="4" type="filter">
+<node order="5" type="filter">
<label>133</label>
<icon>DefaultMusicArtists.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/directors.xml b/system/library/video/musicvideos/directors.xml
index 880742b656..06cc0e06d4 100644
--- a/system/library/video/musicvideos/directors.xml
+++ b/system/library/video/musicvideos/directors.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="6" type="filter">
+<node order="7" type="filter">
<label>20348</label>
<icon>DefaultDirector.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/genres.xml b/system/library/video/musicvideos/genres.xml
index ed4812150e..77745f8a01 100644
--- a/system/library/video/musicvideos/genres.xml
+++ b/system/library/video/musicvideos/genres.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="1" type="filter">
+<node order="2" type="filter">
<label>135</label>
<icon>DefaultGenre.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/recentlyaddedmusicvideos.xml b/system/library/video/musicvideos/recentlyaddedmusicvideos.xml
index a8ee085e71..fed8cba25f 100644
--- a/system/library/video/musicvideos/recentlyaddedmusicvideos.xml
+++ b/system/library/video/musicvideos/recentlyaddedmusicvideos.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="12" type="folder">
- <label>20390</label>
+<node order="1" type="folder">
+ <label>20382</label>
<icon>DefaultRecentlyAddedMusicVideos.png</icon>
<path>videodb://recentlyaddedmusicvideos/</path>
</node>
diff --git a/system/library/video/musicvideos/studios.xml b/system/library/video/musicvideos/studios.xml
index 82023a4993..b6f2f779d3 100644
--- a/system/library/video/musicvideos/studios.xml
+++ b/system/library/video/musicvideos/studios.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="7" type="filter">
+<node order="8" type="filter">
<label>20388</label>
<icon>DefaultStudios.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/tags.xml b/system/library/video/musicvideos/tags.xml
index c63f826200..284bd4c9dd 100644
--- a/system/library/video/musicvideos/tags.xml
+++ b/system/library/video/musicvideos/tags.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="8" type="filter">
+<node order="9" type="filter">
<label>20459</label>
<icon>DefaultTags.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/titles.xml b/system/library/video/musicvideos/titles.xml
index adfcb1e254..aab72a993b 100644
--- a/system/library/video/musicvideos/titles.xml
+++ b/system/library/video/musicvideos/titles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="2" type="filter">
+<node order="3" type="filter">
<label>10024</label>
<icon>DefaultMusicVideoTitle.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/musicvideos/years.xml b/system/library/video/musicvideos/years.xml
index 1f11fdf114..622002bc48 100644
--- a/system/library/video/musicvideos/years.xml
+++ b/system/library/video/musicvideos/years.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="3" type="filter">
+<node order="4" type="filter">
<label>652</label>
<icon>DefaultYear.png</icon>
<content>musicvideos</content>
diff --git a/system/library/video/tvshows/actors.xml b/system/library/video/tvshows/actors.xml
index 8e4f10ea04..19fc20eeb4 100644
--- a/system/library/video/tvshows/actors.xml
+++ b/system/library/video/tvshows/actors.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="4" type="filter">
+<node order="6" type="filter">
<label>344</label>
<icon>DefaultActor.png</icon>
<content>tvshows</content>
diff --git a/system/library/video/tvshows/genres.xml b/system/library/video/tvshows/genres.xml
index f3445092b0..bc066ce55c 100644
--- a/system/library/video/tvshows/genres.xml
+++ b/system/library/video/tvshows/genres.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="1" type="filter">
+<node order="3" type="filter">
<label>135</label>
<icon>DefaultGenre.png</icon>
<content>tvshows</content>
diff --git a/system/library/video/tvshows/inprogressshows.xml b/system/library/video/tvshows/inprogressshows.xml
index 146230c6ca..df725caee9 100644
--- a/system/library/video/tvshows/inprogressshows.xml
+++ b/system/library/video/tvshows/inprogressshows.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="4" type="folder">
- <label>626</label>
+<node order="2" type="folder">
+ <label>575</label>
<icon>DefaultInProgressShows.png</icon>
<path>videodb://inprogresstvshows/</path>
</node>
diff --git a/system/library/video/tvshows/recentlyaddedepisodes.xml b/system/library/video/tvshows/recentlyaddedepisodes.xml
index 6cf35dbfa6..3cfcda83cb 100644
--- a/system/library/video/tvshows/recentlyaddedepisodes.xml
+++ b/system/library/video/tvshows/recentlyaddedepisodes.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="11" type="folder">
- <label>20387</label>
+<node order="1" type="folder">
+ <label>20382</label>
<icon>DefaultRecentlyAddedEpisodes.png</icon>
<path>videodb://recentlyaddedepisodes/</path>
</node>
diff --git a/system/library/video/tvshows/studios.xml b/system/library/video/tvshows/studios.xml
index a7b49b9d3b..a7e1d24bda 100644
--- a/system/library/video/tvshows/studios.xml
+++ b/system/library/video/tvshows/studios.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="5" type="filter">
+<node order="7" type="filter">
<label>20388</label>
<icon>DefaultStudios.png</icon>
<content>tvshows</content>
diff --git a/system/library/video/tvshows/tags.xml b/system/library/video/tvshows/tags.xml
index 3bf9076d6e..6577990817 100644
--- a/system/library/video/tvshows/tags.xml
+++ b/system/library/video/tvshows/tags.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="6" type="filter">
+<node order="8" type="filter">
<label>20459</label>
<icon>DefaultTags.png</icon>
<content>tvshows</content>
diff --git a/system/library/video/tvshows/titles.xml b/system/library/video/tvshows/titles.xml
index c2415246ab..427f2674de 100644
--- a/system/library/video/tvshows/titles.xml
+++ b/system/library/video/tvshows/titles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="2" type="filter">
+<node order="4" type="filter">
<label>10024</label>
<icon>DefaultTVShowTitle.png</icon>
<content>tvshows</content>
diff --git a/system/library/video/tvshows/years.xml b/system/library/video/tvshows/years.xml
index 1ea069d30d..26e1f1edc9 100644
--- a/system/library/video/tvshows/years.xml
+++ b/system/library/video/tvshows/years.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<node order="3" type="filter">
+<node order="5" type="filter">
<label>652</label>
<icon>DefaultYear.png</icon>
<content>tvshows</content>
diff --git a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp
index 3d232d26f8..a4efd8af65 100644
--- a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp
+++ b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.cpp
@@ -163,7 +163,7 @@ void CWiiRemote::SetBluetoothAddress(const char *btaddr)
bacpy(&m_btaddr, &b);
}
-void CWiiRemote::SetSensativity(float DeadX, float DeadY, int NumSamples)
+void CWiiRemote::SetSensitivity(float DeadX, float DeadY, int NumSamples)
{
m_NumSamples = NumSamples;
@@ -742,8 +742,8 @@ int main(int argc, char **argv)
g_Ping = new CPacketHELO("WiiRemote", ICON_PNG, g_BluetoothIconPath.c_str());
g_WiiRemote.Initialize(my_addr, sockfd);
g_WiiRemote.SetBluetoothAddress(btaddr);
- g_WiiRemote.SetSensativity(DeadX, DeadY, NumSamples);
- g_WiiRemote.SetSensativity(DeadX, DeadY, NumSamples);
+ g_WiiRemote.SetSensitivity(DeadX, DeadY, NumSamples);
+ g_WiiRemote.SetSensitivity(DeadX, DeadY, NumSamples);
g_WiiRemote.SetJoystickMap(JoyMap);
if (g_AllowMouse)
g_WiiRemote.EnableMouseEmulation();
diff --git a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h
index 3a60479ca1..5dd7333fd3 100644
--- a/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h
+++ b/tools/EventClients/Clients/WiiRemote/CWIID_WiiRemote.h
@@ -90,7 +90,7 @@ public:
bool Connect();
void SetBluetoothAddress(const char * btaddr);
- void SetSensativity(float DeadX, float DeadY, int Samples);
+ void SetSensitivity(float DeadX, float DeadY, int Samples);
void SetJoystickMap(const char *JoyMap);
private:
int m_NumSamples;
diff --git a/tools/codegenerator/Helper.groovy b/tools/codegenerator/Helper.groovy
index cf195a2dfe..2b474aeb16 100644
--- a/tools/codegenerator/Helper.groovy
+++ b/tools/codegenerator/Helper.groovy
@@ -43,7 +43,7 @@ public class Helper
public static String newline = System.getProperty("line.separator");
public static File curTemplateFile = null;
- public static void setTempateFile(File templateFile) { curTemplateFile = templateFile }
+ public static void setTemplateFile(File templateFile) { curTemplateFile = templateFile }
/**
* In order to use any of the typemap helper features, the Helper class needs to be initialized with
@@ -57,7 +57,7 @@ public class Helper
public static void setup(def template,List pclasses, Map poutTypemap, def defaultOutTypemap,
Map pinTypemap, def defaultInTypemap)
{
- setTempateFile(template.binding.templateFile)
+ setTemplateFile(template.binding.templateFile)
classes = pclasses ? pclasses : []
if (poutTypemap) outTypemap.putAll(poutTypemap)
if (defaultOutTypemap) defaultOutTypeConversion = defaultOutTypemap
diff --git a/tools/darwin/Configurations/App-iOS.xcconfig b/tools/darwin/Configurations/App-iOS.xcconfig
index b7145c3c04..b70faba9a7 100644
--- a/tools/darwin/Configurations/App-iOS.xcconfig
+++ b/tools/darwin/Configurations/App-iOS.xcconfig
@@ -23,7 +23,7 @@
PRODUCT_NAME = $(APP_NAME)
//build against latest
SDKROOT = iphoneos
-IPHONEOS_DEPLOYMENT_TARGET = 5.1
+IPHONEOS_DEPLOYMENT_TARGET = 6.0
ARCHS = armv7
VALID_ARCHS = armv7
diff --git a/tools/darwin/Support/Codesign.command b/tools/darwin/Support/Codesign.command
index ff09f12309..528f74a0be 100755
--- a/tools/darwin/Support/Codesign.command
+++ b/tools/darwin/Support/Codesign.command
@@ -28,8 +28,13 @@ if [ "${PLATFORM_NAME}" == "iphoneos" ] || [ "${PLATFORM_NAME}" == "appletvos" ]
# pull the CFBundleIdentifier out of the built xxx.app
BUNDLEID=`mdls -raw -name kMDItemCFBundleIdentifier ${CODESIGNING_FOLDER_PATH}`
+ if [ "${BUNDLEID}" == "(null)" ] ; then
+ BUNDLEID=`/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' ${CODESIGNING_FOLDER_PATH}/Info.plist`
+ fi
+
echo "CFBundleIdentifier is ${BUNDLEID}"
+
# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
diff --git a/tools/depends/Makefile.include.in b/tools/depends/Makefile.include.in
index 0ddd0444e3..2affdb9b13 100644
--- a/tools/depends/Makefile.include.in
+++ b/tools/depends/Makefile.include.in
@@ -44,10 +44,18 @@ CONFIG_GUESS=@prefix@/@tool_dir@/share/automake-1.15/config.guess
RPL=@prefix@/@tool_dir@/bin/python @prefix@/@tool_dir@/bin/rpl
+USE_CCACHE=@use_ccache@
+
LD=@LD@
-CC=@CC@
-CXX=@CXX@
-CPP=@CPP@
+ifneq (@use_ccache@,yes)
+ CC=@CC@
+ CXX=@CXX@
+ CPP=@CPP@
+else
+ CC=@CCACHE@ @CC@
+ CXX=@CCACHE@ @CXX@
+ CPP=@CCACHE@ @CPP@
+endif
AR=@AR@
RANLIB=@RANLIB@
AS=@AS@
@@ -67,8 +75,13 @@ ifneq (@use_build_toolchain@,)
PATH:=@use_build_toolchain@/bin:@use_build_toolchain@/usr/bin:$(PATH)
endif
LD_FOR_BUILD=@LD_FOR_BUILD@
-CC_FOR_BUILD=@CC_FOR_BUILD@
-CXX_FOR_BUILD=@CXX_FOR_BUILD@
+ifneq (@use_ccache@,yes)
+ CC_FOR_BUILD=@CC_FOR_BUILD@
+ CXX_FOR_BUILD=@CXX_FOR_BUILD@
+else
+ CC_FOR_BUILD=@CCACHE@ @CC_FOR_BUILD@
+ CXX_FOR_BUILD=@CCACHE@ @CXX_FOR_BUILD@
+endif
AR_FOR_BUILD=@AR_FOR_BUILD@
RANLIB_FOR_BUILD=@RANLIB_FOR_BUILD@
AS_FOR_BUILD=@AS_FOR_BUILD@
diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac
index ac2ac3cf68..9caba4a654 100644
--- a/tools/depends/configure.ac
+++ b/tools/depends/configure.ac
@@ -37,6 +37,12 @@ AC_ARG_ENABLE([debug],
[use_debug=$enableval],
[use_debug=yes])
+AC_ARG_ENABLE([ccache],
+ [AS_HELP_STRING([--disable-ccache],
+ [disable ccache])],
+ [use_ccache=no],
+ [use_ccache=yes])
+
AC_ARG_WITH([toolchain],
[AS_HELP_STRING([--with-toolchain],
[specify path to toolchain. Required for android. Defaults to xcode root for darwin, /usr for linux])],
@@ -83,6 +89,12 @@ AC_ARG_ENABLE([gplv3],
[use_gplv3=$enableval],
[use_gplv3=yes])
+if test "$use_ccache" = "yes"; then
+ AC_CHECK_PROG(HAVE_CCACHE,ccache,"yes","no",)
+ if test "x$HAVE_CCACHE" = "xno" ; then
+ use_ccache=no
+ fi
+fi
AC_CHECK_PROG(HAVE_UNZIP,unzip,"yes","no",)
if test "x$HAVE_UNZIP" = "xno" ; then
@@ -341,7 +353,7 @@ case $host in
found_sdk_version=[`$use_xcodebuild -showsdks | grep $target_platform | sort | tail -n 1 | awk '{ print $2}'`]
use_sdk="${use_sdk:-$found_sdk_version}"
sdk_name=$target_platform$use_sdk
- platform_min_version="$target_platform-version-min=5.1"
+ platform_min_version="$target_platform-version-min=6.0"
fi
case $use_sdk in
4.*);;
@@ -350,6 +362,7 @@ case $host in
7.*);;
8.*);;
9.*);;
+ 10.*);;
*)
AC_MSG_ERROR(error in configure of --with-sdk=$use_sdk)
;;
@@ -489,6 +502,10 @@ if test "x$prefix" = "xNONE"; then
AC_MSG_ERROR([No prefix path defined. Use for ex: --prefix=/opt/xbmc-depends]);
fi
+if test "$use_ccache" = "yes"; then
+ AC_PATH_TOOL([CCACHE], [ccache],, $PATH_FOR_HOST)
+fi
+
if test -z $use_tarballs; then
use_tarballs=$prefix/xbmc-tarballs
fi
@@ -620,8 +637,10 @@ AC_SUBST(need_libiconv)
AC_SUBST(use_gplv3)
AC_SUBST(has_libcrystax)
AC_SUBST(use_xcode)
+AC_SUBST(use_ccache)
AC_OUTPUT
+echo -e "ccache:\t $use_ccache"
echo -e "toolchain:\t $use_toolchain"
echo -e "cpu:\t\t $use_cpu"
echo -e "host:\t\t $use_host"
diff --git a/tools/depends/native/cmake-native/Makefile b/tools/depends/native/cmake-native/Makefile
index a4788316a7..77e55535ac 100644
--- a/tools/depends/native/cmake-native/Makefile
+++ b/tools/depends/native/cmake-native/Makefile
@@ -1,6 +1,6 @@
include ../../Makefile.include
PLATFORM=$(NATIVEPLATFORM)
-DEPS= ../../Makefile.include.in Makefile
+DEPS= ../../Makefile.include Makefile
APPNAME=cmake
VERSION=3.6.2
@@ -9,7 +9,7 @@ ARCHIVE=$(SOURCE).tar.gz
# configuration settings
-SETENV=CC=$(CC_FOR_BUILD) CXX=$(CXX_FOR_BUILD) LD=$(LD_FOR_BUILD) CFLAGS=$(NATIVE_CFLAGS) \
+SETENV=CC="$(CC_FOR_BUILD)" CXX="$(CXX_FOR_BUILD)" LD=$(LD_FOR_BUILD) CFLAGS=$(NATIVE_CFLAGS) \
CXXFLAGS=$(NATIVE_CXXFLAGS) LDFLAGS=$(NATIVE_LDFLAGS)
ifeq ($(NATIVE_OS), osx)
@@ -17,6 +17,9 @@ ifeq ($(NATIVE_OS), osx)
endif
CONFIGURE=./bootstrap --prefix=$(NATIVEPREFIX) --system-curl
+ifeq ($(USE_CCACHE), yes)
+ CONFIGURE+=--enable-ccache
+endif
APP=$(PLATFORM)/bin/$(APPNAME)
diff --git a/tools/depends/native/config.site.native.in b/tools/depends/native/config.site.native.in
index 007ee5724a..ee9c747deb 100644
--- a/tools/depends/native/config.site.native.in
+++ b/tools/depends/native/config.site.native.in
@@ -1,6 +1,6 @@
LD="${LD:-@LD_FOR_BUILD@}"
-CC="${CC:-@CC_FOR_BUILD@}"
-CXX="${CXX:-@CXX_FOR_BUILD@}"
+CC="${CC:-@CCACHE@ @CC_FOR_BUILD@}"
+CXX="${CXX:-@CCACHE@ @CXX_FOR_BUILD@}"
AR="${AR:-@AR_FOR_BUILD@}"
RANLIB="${RANLIB:-@RANLIB_FOR_BUILD@}"
AS="${AS:-@AS_FOR_BUILD@}"
diff --git a/tools/depends/target/Toolchain.cmake.in b/tools/depends/target/Toolchain.cmake.in
index 55922cd188..0fa21561b6 100644
--- a/tools/depends/target/Toolchain.cmake.in
+++ b/tools/depends/target/Toolchain.cmake.in
@@ -48,6 +48,15 @@ set(CMAKE_AR @AR@ CACHE FILEPATH "Archiver")
set(CMAKE_LINKER @LD@ CACHE FILEPATH "Linker")
set(CMAKE_STRIP @STRIP@ CACHE PATH "strip binary" FORCE)
+if(PROJECT_SOURCE_DIR MATCHES "tools/depends")
+ if(@use_ccache@ STREQUAL "yes")
+ find_program(CCACHE_PROGRAM ccache)
+ if(CCACHE_PROGRAM)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
+ endif()
+ endif()
+endif()
+
# where is the target environment
set(CMAKE_FIND_ROOT_PATH @prefix@/@deps_dir@)
set(CMAKE_LIBRARY_PATH @prefix@/@deps_dir@/lib)
diff --git a/tools/depends/target/config-binaddons.site.in b/tools/depends/target/config-binaddons.site.in
index d71c378810..47b3fcecc4 100644
--- a/tools/depends/target/config-binaddons.site.in
+++ b/tools/depends/target/config-binaddons.site.in
@@ -128,6 +128,12 @@ fi
if test "@platform_os@" = "ios"; then
+ # Xcode 8 + 10.11, clock_gettime getentropy is present
+ # in 10.12 but will get wrongly detected if building on 10.11
+ ac_cv_search_clock_gettime=no
+ ac_cv_func_clock_gettime=no
+ ac_cv_func_getentropy=no
+
# tweaks for libffi (ios must use llvm-gcc-4.2)
if test "${PACKAGE_NAME}" = "libffi" ; then
case "@use_xcode@" in
diff --git a/tools/depends/target/config.site.in b/tools/depends/target/config.site.in
index 8c7e68d47b..d3a2e2e3cc 100644
--- a/tools/depends/target/config.site.in
+++ b/tools/depends/target/config.site.in
@@ -5,9 +5,9 @@ host_alias=@use_host@
fi
LD="@LD@"
-CC="@CC@"
-CXX="@CXX@"
-CPP="@CPP@"
+CC="@CCACHE@ @CC@"
+CXX="@CCACHE@ @CXX@"
+CPP="@CCACHE@ @CPP@"
AR="@AR@"
AS="@AS@"
NM="@NM@"
@@ -16,8 +16,8 @@ RANLIB="@RANLIB@"
OBJDUMP="@OBJDUMP@"
if test "@platform_os@" = "ios" ; then
- export AS="@prefix@/@tool_dir@/bin/gas-preprocessor.pl @CC@ -arch @use_cpu@"
- export CCAS="--tag CC @prefix@/@tool_dir@/bin/gas-preprocessor.pl @CC@ -arch @use_cpu@"
+ export AS="@prefix@/@tool_dir@/bin/gas-preprocessor.pl @CCACHE@ @CC@ -arch @use_cpu@"
+ export CCAS="--tag CC @prefix@/@tool_dir@/bin/gas-preprocessor.pl @CCACHE@ @CC@ -arch @use_cpu@"
fi
CFLAGS="@platform_cflags@ @platform_includes@ -isystem @prefix@/@deps_dir@/include $CFLAGS"
@@ -150,6 +150,12 @@ fi
if test "@platform_os@" = "ios"; then
+ # Xcode 8 + 10.11, clock_gettime and getentropy is present
+ # in 10.12 but will get wrongly detected if building on 10.11
+ ac_cv_search_clock_gettime=no
+ ac_cv_func_clock_gettime=no
+ ac_cv_func_getentropy=no
+
# tweaks for libffi (ios must use llvm-gcc-4.2)
if test "${PACKAGE_NAME}" = "libffi" ; then
case "@use_xcode@" in
diff --git a/tools/depends/target/curl/Makefile b/tools/depends/target/curl/Makefile
index 11d85b9ef6..1d1dff194f 100644
--- a/tools/depends/target/curl/Makefile
+++ b/tools/depends/target/curl/Makefile
@@ -30,6 +30,9 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
ifeq (osx, $(findstring osx, $(OS)))
cd $(PLATFORM); patch -p1 < ../0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
endif
+ifeq (darwin, $(findstring darwin, $(HOST)))
+ cd $(PLATFORM); sed -ie "s/elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)/#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC_NOPE)/" lib/timeval.c
+endif
cd $(PLATFORM); $(CONFIGURE)
$(LIBDYLIB): $(PLATFORM)
diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile
index eaf9fc4931..9440021fef 100644
--- a/tools/depends/target/ffmpeg/Makefile
+++ b/tools/depends/target/ffmpeg/Makefile
@@ -8,7 +8,7 @@ APPLY_PATCHES=no
# configuration settings
ffmpg_config = --prefix=$(PREFIX) --extra-version="kodi-$(VERSION)"
-ffmpg_config += --cc=$(CC) --cxx=$(CXX) --ar=$(AR) --ranlib=$(RANLIB)
+ffmpg_config += --cc="$(CC)" --cxx="$(CXX)" --ar=$(AR) --ranlib=$(RANLIB)
ffmpg_config += --disable-devices --disable-doc
ffmpg_config += --disable-ffplay --disable-ffmpeg --disable-sdl
ffmpg_config += --disable-ffprobe --disable-ffserver
@@ -79,6 +79,9 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
cd $(PLATFORM);\
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure $(ffmpg_config)
+ifeq ($(OS), ios)
+ cd $(PLATFORM); sed -i -- 's/HAVE_CLOCK_GETTIME 1/HAVE_CLOCK_GETTIME 0/g' config.h
+endif
build: $(PLATFORM)
$(MAKE) -C $(PLATFORM)
diff --git a/tools/depends/target/gnutls/Makefile b/tools/depends/target/gnutls/Makefile
index 1a7c2431c8..69efb3a5a1 100644
--- a/tools/depends/target/gnutls/Makefile
+++ b/tools/depends/target/gnutls/Makefile
@@ -33,7 +33,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p0 < ../size-max.patch
cd $(PLATFORM); $(CONFIGURE)
-ifeq ($(OS),osx)
+ifeq (darwin, $(findstring darwin, $(HOST)))
cd $(PLATFORM); sed -ie "s/HAVE_GETENTROPY/HAVE_GETENTROPY_NOPE/" config.h
endif
diff --git a/tools/depends/target/openssl/Makefile b/tools/depends/target/openssl/Makefile
index def05255ed..dcae452bcf 100644
--- a/tools/depends/target/openssl/Makefile
+++ b/tools/depends/target/openssl/Makefile
@@ -33,7 +33,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM); mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
- cd $(PLATFORM); AR="$(AR)" CFLAGS="$(CFLAGS)" CC=$(CC) RANLIB=$(RANLIB) $(CONFIGURE)
+ cd $(PLATFORM); AR="$(AR)" CFLAGS="$(CFLAGS)" CC="$(CC)" RANLIB=$(RANLIB) $(CONFIGURE)
if test "$(OS)" = "osx"; then \
sed -ie "s|CC= /usr/bin/gcc-4.2|CC= $(CC)|" "$(PLATFORM)/Makefile"; \
sed -ie "s|CFLAG= |CFLAG=$(CFLAGS) |" "$(PLATFORM)/Makefile"; \
diff --git a/tools/depends/target/samba-gplv3/Makefile b/tools/depends/target/samba-gplv3/Makefile
index f5d84bac76..e15987d9c4 100644
--- a/tools/depends/target/samba-gplv3/Makefile
+++ b/tools/depends/target/samba-gplv3/Makefile
@@ -55,7 +55,7 @@ endif
ifeq ($(TARGET_PLATFORM),appletvos)
cd $(PLATFORM); patch -p0 < ../no_fork_and_exec.patch
endif
-ifeq ($(OS),osx)
+ifeq (darwin, $(findstring darwin, $(HOST)))
sed -ie "s|ifndef HAVE_CLOCK_GETTIME|if !defined(HAVE_CLOCK_GETTIME) \&\& !defined(CLOCK_REALTIME)|" "$(PLATFORM)/lib/replace/system/time.h"
endif
cd $(PLATFORM)/source3; $(CONFIGURE)
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 11f8005d16..73141d8c37 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -2585,7 +2585,7 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)
else
pathToUrl = URIUtils::CreateArchivePath("rar", CURL(pMsg->strParam), "");
- CUtil::GetRecursiveListing(pathToUrl.Get(), items, g_advancedSettings.m_pictureExtensions, XFILE::DIR_FLAG_NO_FILE_DIRS);
+ CUtil::GetRecursiveListing(pathToUrl.Get(), items, g_advancedSettings.GetPictureExtensions(), XFILE::DIR_FLAG_NO_FILE_DIRS);
if (items.Size() > 0)
{
pSlideShow->Reset();
@@ -2620,7 +2620,7 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)
CFileItemList items;
std::string strPath = pMsg->strParam;
- std::string extensions = g_advancedSettings.m_pictureExtensions;
+ std::string extensions = g_advancedSettings.GetPictureExtensions();
if (pMsg->param1)
extensions += "|.tbn";
CUtil::GetRecursiveListing(strPath, items, extensions);
@@ -2745,11 +2745,14 @@ void CApplication::FrameMove(bool processEvents, bool processGUI)
CSingleExit ex(g_graphicsContext);
m_frameMoveGuard.unlock();
// Calculate a window size between 2 and 10ms, 4 continuous requests let the window grow by 1ms
- unsigned int sleepTime = std::max(static_cast<unsigned int>(2), std::min(m_ProcessedExternalCalls >> 2, static_cast<unsigned int>(10)));
+ // WHen not playing video we allow it to increase to 80ms
+ unsigned int max_sleep = m_pPlayer->IsPlayingVideo() && !m_pPlayer->IsPausedPlayback() ? 10 : 80;
+ unsigned int sleepTime = std::max(static_cast<unsigned int>(2), std::min(m_ProcessedExternalCalls >> 2, max_sleep));
Sleep(sleepTime);
m_frameMoveGuard.lock();
+ m_ProcessedExternalDecay = 5;
}
- else
+ if (m_ProcessedExternalDecay && --m_ProcessedExternalDecay == 0)
m_ProcessedExternalCalls = 0;
}
@@ -4093,7 +4096,9 @@ void CApplication::ActivateScreenSaver(bool forceType /*= false */)
if (!forceType)
{
// set to Dim in the case of a dialog on screen or playing video
- if (g_windowManager.HasModalDialog() || (m_pPlayer->IsPlayingVideo() && m_ServiceManager->GetSettings().GetBool(CSettings::SETTING_SCREENSAVER_USEDIMONPAUSE)) || g_PVRManager.IsRunningChannelScan())
+ if (g_windowManager.HasModalDialog() ||
+ (m_pPlayer->IsPlayingVideo() && m_ServiceManager->GetSettings().GetBool(CSettings::SETTING_SCREENSAVER_USEDIMONPAUSE)) ||
+ CPVRGUIActions::GetInstance().IsRunningChannelScan())
{
if (!CAddonMgr::GetInstance().GetAddon("screensaver.xbmc.builtin.dim", m_screenSaver))
m_screenSaver.reset(new CScreenSaver(""));
@@ -5085,6 +5090,11 @@ void CApplication::StartMusicScan(const std::string &strDirectory, bool userInit
flags |= CMusicInfoScanner::SCAN_ONLINE;
if (!userInitiated || m_ServiceManager->GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE))
flags |= CMusicInfoScanner::SCAN_BACKGROUND;
+ // Ask for full rescan of music files
+ //! @todo replace with a music library setting in UI
+ if (g_advancedSettings.m_bMusicLibraryPromptFullTagScan)
+ if (CGUIDialogYesNo::ShowAndGetInput(CVariant{ 799 }, CVariant{ 38062 }))
+ flags |= CMusicInfoScanner::SCAN_RESCAN;
}
if (!(flags & CMusicInfoScanner::SCAN_BACKGROUND))
diff --git a/xbmc/Application.h b/xbmc/Application.h
index 59a1ec96b2..93bf3cce99 100644
--- a/xbmc/Application.h
+++ b/xbmc/Application.h
@@ -519,6 +519,7 @@ private:
CCriticalSection m_frameMoveGuard; /*!< critical section for synchronizing GUI actions from inside and outside (python) */
std::atomic_uint m_WaitingExternalCalls; /*!< counts threads wich are waiting to be processed in FrameMove */
unsigned int m_ProcessedExternalCalls; /*!< counts calls wich are processed during one "door open" cycle in FrameMove */
+ unsigned int m_ProcessedExternalDecay = 0; /*!< counts to close door after a few frames of no python activity */
};
XBMC_GLOBAL_REF(CApplication,g_application);
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index 71e7c56a72..94d7bef42a 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -3200,11 +3200,11 @@ std::string CFileItem::GetLocalFanart() const
return "";
CFileItemList items;
- CDirectory::GetDirectory(strDir, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO);
+ CDirectory::GetDirectory(strDir, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO);
if (IsOpticalMediaFile())
{ // grab from the optical media parent folder as well
CFileItemList moreItems;
- CDirectory::GetDirectory(GetLocalMetadataPath(), moreItems, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO);
+ CDirectory::GetDirectory(GetLocalMetadataPath(), moreItems, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO);
items.Append(moreItems);
}
diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp
index f2d69da28c..b705562c19 100644
--- a/xbmc/Util.cpp
+++ b/xbmc/Util.cpp
@@ -543,7 +543,7 @@ bool CUtil::IsTVRecording(const std::string& strFile)
bool CUtil::IsPicture(const std::string& strFile)
{
return URIUtils::HasExtension(strFile,
- g_advancedSettings.m_pictureExtensions + "|.tbn|.dds");
+ g_advancedSettings.GetPictureExtensions()+ "|.tbn|.dds");
}
bool CUtil::ExcludeFileOrFolder(const std::string& strFileOrFolder, const std::vector<std::string>& regexps)
diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp
index ce6dc4fcb9..2a96ae09c1 100644
--- a/xbmc/addons/Addon.cpp
+++ b/xbmc/addons/Addon.cpp
@@ -110,6 +110,7 @@ static const TypeMapping types[] =
{"kodi.adsp", ADDON_ADSPDLL, 24135, "DefaultAddonAudioDSP.png" },
{"kodi.inputstream", ADDON_INPUTSTREAM, 24048, "DefaultAddonInputstream.png" },
{"kodi.vfs", ADDON_VFS, 39013, "DefaultAddonVfs.png" },
+ {"kodi.imagedecoder", ADDON_IMAGEDECODER, 39015, "DefaultAddonImageDecoder.png" },
};
std::string TranslateType(ADDON::TYPE type, bool pretty/*=false*/)
diff --git a/xbmc/addons/AddonBuilder.cpp b/xbmc/addons/AddonBuilder.cpp
index 2df8abcd3f..d47c5aa198 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/GameResource.h"
+#include "addons/ImageDecoder.h"
#include "addons/ImageResource.h"
#include "addons/InputStream.h"
#include "addons/LanguageResource.h"
@@ -91,6 +92,7 @@ std::shared_ptr<IAddon> CAddonBuilder::Build()
type == ADDON_AUDIOENCODER ||
type == ADDON_AUDIODECODER ||
type == ADDON_VFS ||
+ type == ADDON_IMAGEDECODER ||
type == ADDON_INPUTSTREAM ||
type == ADDON_PERIPHERALDLL ||
type == ADDON_GAMEDLL)
@@ -138,6 +140,8 @@ std::shared_ptr<IAddon> CAddonBuilder::Build()
return CAudioEncoder::FromExtension(std::move(m_props), m_extPoint);
case ADDON_AUDIODECODER:
return CAudioDecoder::FromExtension(std::move(m_props), m_extPoint);
+ case ADDON_IMAGEDECODER:
+ return CImageDecoder::FromExtension(std::move(m_props), m_extPoint);
case ADDON_INPUTSTREAM:
return CInputStream::FromExtension(std::move(m_props), m_extPoint);
case ADDON_PERIPHERALDLL:
diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp
index 67ad41d247..ad655d6ae8 100644
--- a/xbmc/addons/AddonDatabase.cpp
+++ b/xbmc/addons/AddonDatabase.cpp
@@ -539,7 +539,6 @@ bool CAddonDatabase::GetAvailableVersions(const std::string& addonId,
"WHERE "
"repo.checksum IS NOT NULL AND repo.checksum != '' "
"AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repoID AND installed.enabled=1) "
- "AND NOT EXISTS (SELECT * FROM broken WHERE broken.addonID=addons.addonID) "
"AND addons.addonID='%s'", addonId.c_str());
m_pDS->query(sql.c_str());
diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp
index 9f2480ce88..55d300904d 100644
--- a/xbmc/addons/AddonInstaller.cpp
+++ b/xbmc/addons/AddonInstaller.cpp
@@ -228,14 +228,15 @@ void CAddonInstaller::Install(const std::string& addonId, const AddonVersion& ve
}
bool CAddonInstaller::DoInstall(const AddonPtr &addon, const RepositoryPtr& repo,
- const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */)
+ const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */,
+ bool autoUpdate /* = false*/)
{
// check whether we already have the addon installing
CSingleLock lock(m_critSection);
if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end())
return false;
- CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash);
+ CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash, autoUpdate);
if (background)
{
// Workaround: because CAddonInstallJob is blocking waiting for other jobs, it needs to be run
@@ -431,9 +432,18 @@ void CAddonInstaller::InstallUpdates()
for (const auto& addon : updates)
{
if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID()))
- CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID());
+ {
+ AddonPtr toInstall;
+ RepositoryPtr repo;
+ std::string hash;
+ if (CAddonInstallJob::GetAddonWithHash(addon->ID(), repo, toInstall, hash))
+ DoInstall(toInstall, repo, hash, true, false, true);
+ }
}
+}
+void CAddonInstaller::InstallUpdatesAndWait()
+{
CSingleLock lock(m_critSection);
if (!m_downloadJobs.empty())
{
@@ -464,13 +474,15 @@ int64_t CAddonInstaller::EnumeratePackageFolder(std::map<std::string,CFileItemLi
return size;
}
-CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo, const std::string &hash /* = "" */)
+CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo,
+ const std::string &hash, bool isAutoUpdate)
: m_addon(addon),
m_repo(repo),
- m_hash(hash)
+ m_hash(hash),
+ m_isAutoUpdate(isAutoUpdate)
{
AddonPtr dummy;
- m_update = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false);
+ m_isUpdate = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false);
}
bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, RepositoryPtr& repo,
@@ -605,20 +617,30 @@ bool CAddonInstallJob::DoWork()
g_localizeStrings.LoadAddonStrings(URIUtils::AddFileToFolder(m_addon->Path(), "resources/language/"),
CServiceBroker::GetSettings().GetString(CSettings::SETTING_LOCALE_LANGUAGE), m_addon->ID());
- ADDON::OnPostInstall(m_addon, m_update, IsModal());
+ ADDON::OnPostInstall(m_addon, m_isUpdate, IsModal());
{
CAddonDatabase database;
database.Open();
database.SetOrigin(m_addon->ID(), m_repo ? m_repo->ID() : "");
- if (m_update)
+ if (m_isUpdate)
database.SetLastUpdated(m_addon->ID(), CDateTime::GetCurrentDateTime());
}
CEventLog::GetInstance().Add(
- EventPtr(new CAddonManagementEvent(m_addon, m_update ? 24065 : 24064)),
+ EventPtr(new CAddonManagementEvent(m_addon, m_isUpdate ? 24065 : 24064)),
!IsModal() && CServiceBroker::GetSettings().GetBool(CSettings::SETTING_ADDONS_NOTIFICATIONS), false);
+ if (m_isAutoUpdate && !m_addon->Broken().empty())
+ {
+ CLog::Log(LOGDEBUG, "CAddonInstallJob[%s]: auto-disabling due to being marked as broken", m_addon->ID().c_str());
+ CAddonMgr::GetInstance().DisableAddon(m_addon->ID());
+ CEventLog::GetInstance().Add(
+ EventPtr(new CAddonManagementEvent(m_addon, 24094)),
+ CServiceBroker::GetSettings().GetBool(CSettings::SETTING_ADDONS_NOTIFICATIONS),
+ false);
+ }
+
// and we're done!
MarkFinished();
return true;
@@ -725,7 +747,7 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& r
return false;
}
- CAddonInstallJob dependencyJob(addon, repoForDep, hash);
+ CAddonInstallJob dependencyJob(addon, repoForDep, hash, false);
// pass our progress indicators to the temporary job and don't allow it to
// show progress or information updates (no progress, title or text changes)
diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h
index 57a38c9624..d42617adf2 100644
--- a/xbmc/addons/AddonInstaller.h
+++ b/xbmc/addons/AddonInstaller.h
@@ -95,6 +95,7 @@ public:
bool HasJob(const std::string& ID) const;
/*! Install update and block until all updates have installed. */
+ void InstallUpdatesAndWait();
void InstallUpdates();
void OnJobComplete(unsigned int jobID, bool success, CJob* job);
@@ -129,7 +130,7 @@ private:
\return true on successful install, false on failure.
*/
bool DoInstall(const ADDON::AddonPtr &addon, const ADDON::RepositoryPtr &repo,
- const std::string &hash = "", bool background = true, bool modal = false);
+ const std::string &hash = "", bool background = true, bool modal = false, bool autoUpdate = false);
/*! \brief Check whether dependencies of an addon exist or are installable.
Iterates through the addon's dependencies, checking they're installed or installable.
@@ -153,7 +154,8 @@ private:
class CAddonInstallJob : public CFileOperationJob
{
public:
- CAddonInstallJob(const ADDON::AddonPtr &addon, const ADDON::AddonPtr &repo, const std::string &hash = "");
+ CAddonInstallJob(const ADDON::AddonPtr& addon, const ADDON::AddonPtr& repo,
+ const std::string& hash, bool isAutoUpdate);
virtual bool DoWork();
@@ -185,7 +187,8 @@ private:
ADDON::AddonPtr m_addon;
ADDON::AddonPtr m_repo;
std::string m_hash;
- bool m_update;
+ bool m_isUpdate;
+ bool m_isAutoUpdate;
};
class CAddonUnInstallJob : public CFileOperationJob
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 4c7c1cd5a3..8dd7395c35 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -848,19 +848,7 @@ bool CAddonMgr::IsAddonInstalled(const std::string& ID)
bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon)
{
- if (addon == NULL)
- return false;
-
- CSingleLock lock(m_critSection);
- // can't install already installed addon
- if (IsAddonInstalled(addon->ID()))
- return false;
-
- // can't install broken addons
- if (!addon->Broken().empty())
- return false;
-
- return true;
+ return addon != nullptr &&!IsAddonInstalled(addon->ID());
}
bool CAddonMgr::CanUninstall(const AddonPtr& addon)
diff --git a/xbmc/addons/AddonSystemSettings.cpp b/xbmc/addons/AddonSystemSettings.cpp
index 6f245936d5..f0f3dad990 100644
--- a/xbmc/addons/AddonSystemSettings.cpp
+++ b/xbmc/addons/AddonSystemSettings.cpp
@@ -148,7 +148,7 @@ std::vector<std::string> CAddonSystemSettings::MigrateAddons(std::function<void(
CRepositoryUpdater::GetInstance().Await();
CLog::Log(LOGINFO, "ADDON: waiting for add-ons to update...");
- CAddonInstaller::GetInstance().InstallUpdates();
+ CAddonInstaller::GetInstance().InstallUpdatesAndWait();
}
auto incompatible = getIncompatible();
diff --git a/xbmc/addons/BinaryAddonCache.cpp b/xbmc/addons/BinaryAddonCache.cpp
index 41f08ff6a5..c926c9eff3 100644
--- a/xbmc/addons/BinaryAddonCache.cpp
+++ b/xbmc/addons/BinaryAddonCache.cpp
@@ -34,6 +34,7 @@ void CBinaryAddonCache::Init()
{
m_addonsToCache = {
ADDON_AUDIODECODER,
+ ADDON_IMAGEDECODER,
ADDON_INPUTSTREAM,
ADDON_PVRDLL,
ADDON_GAMEDLL,
diff --git a/xbmc/addons/CMakeLists.txt b/xbmc/addons/CMakeLists.txt
index b6d26bcb5a..a2188c6739 100644
--- a/xbmc/addons/CMakeLists.txt
+++ b/xbmc/addons/CMakeLists.txt
@@ -18,6 +18,7 @@ set(SOURCES Addon.cpp
GUIDialogAddonSettings.cpp
GUIViewStateAddonBrowser.cpp
GUIWindowAddonBrowser.cpp
+ ImageDecoder.cpp
ImageResource.cpp
InputStream.cpp
LanguageResource.cpp
@@ -58,6 +59,7 @@ set(HEADERS Addon.h
GUIViewStateAddonBrowser.h
GUIWindowAddonBrowser.h
IAddon.h
+ ImageDecoder.h
ImageResource.h
InputStream.h
LanguageResource.h
diff --git a/xbmc/addons/GUIDialogAddonSettings.cpp b/xbmc/addons/GUIDialogAddonSettings.cpp
index 274d30361b..7dc73d53f0 100644
--- a/xbmc/addons/GUIDialogAddonSettings.cpp
+++ b/xbmc/addons/GUIDialogAddonSettings.cpp
@@ -400,7 +400,7 @@ bool CGUIDialogAddonSettings::ShowVirtualKeyboard(int iControl)
// convert mask qualifiers
StringUtils::Replace(strMask, "$AUDIO", g_advancedSettings.GetMusicExtensions());
StringUtils::Replace(strMask, "$VIDEO", g_advancedSettings.m_videoExtensions);
- StringUtils::Replace(strMask, "$IMAGE", g_advancedSettings.m_pictureExtensions);
+ StringUtils::Replace(strMask, "$IMAGE", g_advancedSettings.GetPictureExtensions());
#if defined(_WIN32_WINNT)
StringUtils::Replace(strMask, "$EXECUTABLE", ".exe|.bat|.cmd|.py");
#else
@@ -1039,6 +1039,12 @@ bool CGUIDialogAddonSettings::GetCondition(const std::string &condition, const i
else
value = StringUtils::Format("%i", ((CGUISpinControlEx*) control2)->GetValue());
break;
+ case CGUIControl::GUICONTROL_SETTINGS_SLIDER:
+ if (((CGUISettingsSliderControl *)control2)->GetType() == SLIDER_CONTROL_TYPE_INT)
+ value = StringUtils::Format("%i", ((CGUISettingsSliderControl *)control2)->GetIntValue());
+ else
+ value = StringUtils::Format("%f", ((CGUISettingsSliderControl *)control2)->GetFloatValue());
+ break;
default:
break;
}
diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h
index b58e19e752..f7b3a279ed 100644
--- a/xbmc/addons/IAddon.h
+++ b/xbmc/addons/IAddon.h
@@ -65,6 +65,7 @@ namespace ADDON
ADDON_RESOURCE_UISOUNDS,
ADDON_RESOURCE_GAMES,
ADDON_VFS,
+ ADDON_IMAGEDECODER,
ADDON_VIDEO, // virtual addon types
ADDON_AUDIO,
ADDON_IMAGE,
diff --git a/xbmc/addons/ImageDecoder.cpp b/xbmc/addons/ImageDecoder.cpp
new file mode 100644
index 0000000000..c22eaf142e
--- /dev/null
+++ b/xbmc/addons/ImageDecoder.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2013 Arne Morten Kvarving
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "ImageDecoder.h"
+#include "kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h"
+#include "guilib/TextureFormats.h"
+
+static const std::map<int,int> KodiToAddonFormat = {{XB_FMT_A8R8G8B8, ADDON_IMG_FMT_A8R8G8B8},
+ {XB_FMT_A8, ADDON_IMG_FMT_A8},
+ {XB_FMT_RGBA8, ADDON_IMG_FMT_RGBA8},
+ {XB_FMT_RGB8, ADDON_IMG_FMT_RGB8}};
+
+namespace ADDON
+{
+
+std::unique_ptr<CImageDecoder>
+CImageDecoder::FromExtension(AddonProps&& props, const cp_extension_t* ext)
+{
+ std::string mime = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@mimetype");
+ std::string extension = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@extension");
+ return std::unique_ptr<CImageDecoder>(new CImageDecoder(std::move(props),
+ std::move(mime),
+ std::move(extension)));
+}
+
+CImageDecoder::CImageDecoder(AddonProps&& props, std::string mime, std::string extension) :
+ CAddonDll(std::move(props)),
+ m_mimetype(std::move(mime)),
+ m_extension(std::move(extension))
+{
+}
+
+CImageDecoder::~CImageDecoder()
+{
+ if (m_image && Initialized())
+ m_struct.Close(m_image);
+}
+
+bool CImageDecoder::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize,
+ unsigned int width, unsigned int height)
+{
+ if (!Initialized())
+ return false;
+
+ m_width = width;
+ m_height = height;
+ m_image = m_struct.LoadImage(buffer, bufSize, &m_width, &m_height);
+
+ return m_image != nullptr;
+}
+
+bool CImageDecoder::Decode(unsigned char* const pixels, unsigned int width,
+ unsigned int height, unsigned int pitch,
+ unsigned int format)
+{
+ if (!Initialized())
+ return false;
+
+ auto it = KodiToAddonFormat.find(format & XB_FMT_MASK);
+ if (it == KodiToAddonFormat.end())
+ return false;
+
+ bool result = m_struct.Decode(m_image, pixels, width, height, pitch, it->second);
+ m_width = width;
+ m_height = height;
+
+ return result;
+}
+
+bool CImageDecoder::Create(const std::string& mimetype)
+{
+ m_info.mimetype = mimetype.c_str();
+
+ return CAddonDll::Create(&m_struct, &m_info) == ADDON_STATUS_OK;
+}
+
+} /*namespace ADDON*/
diff --git a/xbmc/addons/ImageDecoder.h b/xbmc/addons/ImageDecoder.h
new file mode 100644
index 0000000000..4743281e11
--- /dev/null
+++ b/xbmc/addons/ImageDecoder.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 Arne Morten Kvarving
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "AddonDll.h"
+#include "addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h"
+#include "guilib/iimage.h"
+
+namespace ADDON
+{
+ class CImageDecoder : public CAddonDll,
+ public IImage
+ {
+ public:
+ static std::unique_ptr<CImageDecoder> FromExtension(AddonProps&&,
+ const cp_extension_t* ext);
+ explicit CImageDecoder(AddonProps props) :
+ CAddonDll(std::move(props))
+ {}
+
+ CImageDecoder(AddonProps&& props, std::string mimetypes, std::string extensions);
+ virtual ~CImageDecoder();
+
+ bool Create(const std::string& mimetype);
+
+ bool CreateThumbnailFromSurface(unsigned char*, unsigned int, unsigned int,
+ unsigned int, unsigned int, const std::string&,
+ unsigned char*&, unsigned int&) { return false; }
+
+ bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize,
+ unsigned int width, unsigned int height);
+ bool Decode(unsigned char* const pixels, unsigned int width,
+ unsigned int height, unsigned int pitch,
+ unsigned int format);
+
+ const std::string& GetMimetypes() const { return m_mimetype; }
+ const std::string& GetExtensions() const { return m_extension; }
+ protected:
+ void* m_image = nullptr;
+ std::string m_mimetype;
+ std::string m_extension;
+ IMAGEDEC_PROPS m_info;
+ KodiToAddonFuncTable_ImageDecoder m_struct = {};
+ };
+
+} /*namespace ADDON*/
diff --git a/xbmc/addons/PVRClient.cpp b/xbmc/addons/PVRClient.cpp
index 60fed68942..9a54ff153c 100644
--- a/xbmc/addons/PVRClient.cpp
+++ b/xbmc/addons/PVRClient.cpp
@@ -18,18 +18,21 @@
*
*/
-#include "Application.h"
+#include "PVRClient.h"
+
+#include <cassert>
+#include <cmath>
+#include <memory>
+#include <algorithm>
+
#include "ServiceBroker.h"
#include "addons/kodi-addon-dev-kit/include/kodi/libKODI_guilib.h"
#include "epg/Epg.h"
#include "filesystem/SpecialProtocol.h"
-#include "messaging/ApplicationMessenger.h"
-#include "messaging/helpers/DialogHelper.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
-#include "utils/Variant.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
@@ -39,55 +42,26 @@
#include "pvr/timers/PVRTimerInfoTag.h"
#include "pvr/timers/PVRTimerType.h"
-#include "PVRClient.h"
-
-#include <assert.h>
-#include <cmath>
-#include <memory>
-#include <algorithm>
-
using namespace ADDON;
using namespace PVR;
using namespace EPG;
-using namespace KODI::MESSAGING;
-
-using KODI::MESSAGING::HELPERS::DialogResponse;
#define DEFAULT_INFO_STRING_VALUE "unknown"
std::unique_ptr<CPVRClient> CPVRClient::FromExtension(AddonProps props, const cp_extension_t* ext)
{
- std::string strAvahiType = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@avahi_type");
- std::string strAvahiIpSetting = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@avahi_ip_setting");
- std::string strAvahiPortSetting = CAddonMgr::GetInstance().GetExtValue(ext->configuration, "@avahi_port_setting");
- return std::unique_ptr<CPVRClient>(new CPVRClient(std::move(props), strAvahiType,
- strAvahiIpSetting, strAvahiPortSetting));
+ return std::unique_ptr<CPVRClient>(new CPVRClient(std::move(props)));
}
CPVRClient::CPVRClient(AddonProps props)
: CAddonDll(std::move(props)),
- m_apiVersion("0.0.0"),
- m_bAvahiServiceAdded(false)
-{
- ResetProperties();
-}
-
-CPVRClient::CPVRClient(AddonProps props, const std::string& strAvahiType, const std::string& strAvahiIpSetting,
- const std::string& strAvahiPortSetting)
- : CAddonDll(std::move(props)),
- m_strAvahiType(strAvahiType),
- m_strAvahiIpSetting(strAvahiIpSetting),
- m_strAvahiPortSetting(strAvahiPortSetting),
- m_apiVersion("0.0.0"),
- m_bAvahiServiceAdded(false)
+ m_apiVersion("0.0.0")
{
ResetProperties();
}
CPVRClient::~CPVRClient(void)
{
- if (m_bAvahiServiceAdded)
- CZeroconfBrowser::GetInstance()->RemoveServiceType(m_strAvahiType);
Destroy();
}
@@ -1253,7 +1227,7 @@ DemuxPacket* CPVRClient::DemuxRead(void)
return NULL;
}
-bool CPVRClient::HaveMenuHooks(PVR_MENUHOOK_CAT cat) const
+bool CPVRClient::HasMenuHooks(PVR_MENUHOOK_CAT cat) const
{
bool bReturn(false);
if (m_bReadyToUse && !m_menuhooks.empty())
@@ -1618,77 +1592,6 @@ time_t CPVRClient::GetBufferTimeEnd(void) const
return time;
}
-bool CPVRClient::CanAutoconfigure(void) const
-{
- /** can only auto-configure when avahi details are provided in addon.xml */
- return !m_strAvahiType.empty() &&
- !m_strAvahiIpSetting.empty() &&
- !m_strAvahiPortSetting.empty();
-}
-
-bool CPVRClient::AutoconfigureRegisterType(void)
-{
- if (!m_strAvahiType.empty())
- {
- // AddServiceType() returns false when already registered
- m_bAvahiServiceAdded |= CZeroconfBrowser::GetInstance()->AddServiceType(m_strAvahiType);
- return true;
- }
-
- return false;
-}
-
-bool CPVRClient::Autoconfigure(void)
-{
- bool bReturn(false);
-
- if (!CanAutoconfigure())
- return bReturn;
-
- std::string strHostPort;
- std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices();
- for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); !bReturn && it != found_services.end(); ++it)
- {
- /** found the type that we are looking for */
- if ((*it).GetType() == m_strAvahiType && std::find(m_rejectedAvahiHosts.begin(), m_rejectedAvahiHosts.end(), *it) == m_rejectedAvahiHosts.end())
- {
- /** try to resolve */
- if(!CZeroconfBrowser::GetInstance()->ResolveService((*it)))
- {
- CLog::Log(LOGWARNING, "%s - %s service found but the host name couldn't be resolved", __FUNCTION__, (*it).GetName().c_str());
- }
- else
- {
- // %s service found at %s
- std::string strLogLine(StringUtils::Format(g_localizeStrings.Get(19689).c_str(), (*it).GetName().c_str(), (*it).GetIP().c_str()));
- CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str());
-
- if (DialogResponse::YES !=
- HELPERS::ShowYesNoDialogLines(CVariant{19688}, // Scanning for PVR services
- CVariant{strLogLine},
- CVariant{19690})) // Do you want to use this service?
- {
- CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str());
- m_rejectedAvahiHosts.push_back(*it);
- }
- else
- {
- /** update the settings and return */
- std::string strPort(StringUtils::Format("%d", (*it).GetPort()));
- UpdateSetting(m_strAvahiIpSetting, (*it).GetIP());
- UpdateSetting(m_strAvahiPortSetting, strPort);
- SaveSettings();
- CLog::Log(LOGNOTICE, "%s - auto-configured %s using host '%s' and port '%d'", __FUNCTION__, (*it).GetName().c_str(), (*it).GetIP().c_str(), (*it).GetPort());
-
- bReturn = true;
- }
- }
- }
- }
-
- return bReturn;
-}
-
bool CPVRClient::IsRealTimeStream(void) const
{
bool bReturn(false);
diff --git a/xbmc/addons/PVRClient.h b/xbmc/addons/PVRClient.h
index ef58bca7c7..107720e347 100644
--- a/xbmc/addons/PVRClient.h
+++ b/xbmc/addons/PVRClient.h
@@ -27,7 +27,6 @@
#include "addons/Addon.h"
#include "addons/AddonDll.h"
#include "addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h"
-#include "network/ZeroconfBrowser.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/PVRTypes.h"
@@ -66,9 +65,6 @@ namespace PVR
static std::unique_ptr<CPVRClient> FromExtension(ADDON::AddonProps props, const cp_extension_t* ext);
explicit CPVRClient(ADDON::AddonProps props);
- CPVRClient(ADDON::AddonProps props, const std::string& strAvahiType,
- const std::string& strAvahiIpSetting, const std::string& strAvahiPortSetting);
-
~CPVRClient(void);
virtual void OnDisabled() override;
@@ -224,7 +220,7 @@ namespace PVR
/*!
* @return True if this add-on has menu hooks, false otherwise.
*/
- bool HaveMenuHooks(PVR_MENUHOOK_CAT cat) const;
+ bool HasMenuHooks(PVR_MENUHOOK_CAT cat) const;
/*!
* @return The menu hooks for this add-on.
@@ -611,23 +607,6 @@ namespace PVR
time_t GetBufferTimeEnd() const;
/*!
- * @return True if this add-on can be auto-configured via avahi, false otherwise
- */
- bool CanAutoconfigure(void) const;
-
- /*!
- * Registers the avahi type for this add-on
- * @return True if registered, false if not.
- */
- bool AutoconfigureRegisterType(void);
-
- /*!
- * Try to auto-configure this add-on via avahi
- * @return True if auto-configured and the configured was accepted by the user, false otherwise
- */
- bool Autoconfigure(void);
-
- /*!
* @brief is real-time stream?
*/
bool IsRealTimeStream() const;
@@ -732,12 +711,8 @@ namespace PVR
std::string m_strBackendHostname; /*!< the cached backend hostname */
/* stored strings to make sure const char* members in PVR_PROPERTIES stay valid */
- std::string m_strUserPath; /*!< @brief translated path to the user profile */
- std::string m_strClientPath; /*!< @brief translated path to this add-on */
- std::string m_strAvahiType; /*!< avahi service type */
- std::string m_strAvahiIpSetting; /*!< add-on setting name to change to the found ip address */
- std::string m_strAvahiPortSetting; /*!< add-on setting name to change to the found port number */
- std::vector<CZeroconfBrowser::ZeroconfService> m_rejectedAvahiHosts; /*!< hosts that were rejected by the user */
+ std::string m_strUserPath; /*!< @brief translated path to the user profile */
+ std::string m_strClientPath; /*!< @brief translated path to this add-on */
CCriticalSection m_critSection;
@@ -746,7 +721,6 @@ namespace PVR
bool m_bIsPlayingRecording;
CPVRRecordingPtr m_playingRecording;
ADDON::AddonVersion m_apiVersion;
- bool m_bAvahiServiceAdded;
PVR_PROPERTIES m_info;
KodiToAddonFuncTable_PVR m_struct;
};
diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp
index e64a3665c1..ce1e8ab7ed 100644
--- a/xbmc/addons/Repository.cpp
+++ b/xbmc/addons/Repository.cpp
@@ -257,48 +257,5 @@ bool CRepositoryUpdateJob::DoWork()
}
database.UpdateRepositoryContent(m_repo->ID(), m_repo->Version(), newChecksum, addons);
-
- //Notify about broken status changes
- for (const auto& addon : addons)
- {
- AddonPtr localAddon;
- if (!CAddonMgr::GetInstance().GetAddon(addon->ID(), localAddon))
- continue;
-
- if (localAddon && localAddon->Version() > addon->Version())
- //We have a newer version locally
- continue;
-
- AddonPtr oldAddon;
- database.GetAddon(addon->ID(), oldAddon);
-
- if (database.GetAddonVersion(addon->ID()).first > addon->Version())
- //Newer version in db (ie. in a different repo)
- continue;
-
- std::string broken = addon->Broken();
- bool isBroken = !addon->Broken().empty();
- bool isBrokenInDb = oldAddon && !oldAddon->Broken().empty();
- if (isBroken && !isBrokenInDb)
- {
- //newly broken
- if (HELPERS::ShowYesNoDialogLines(CVariant{addon->Name()}, CVariant{24096}, CVariant{24097}, CVariant{""})
- == DialogResponse::YES)
- {
- CAddonMgr::GetInstance().DisableAddon(addon->ID());
- }
-
- CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' marked broken. reason: \"%s\"",
- m_repo->ID().c_str(), addon->ID().c_str(), broken.c_str());
-
- CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24096)));
- }
- else if (!isBroken && isBrokenInDb)
- {
- //Unbroken
- CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' unbroken",
- m_repo->ID().c_str(), addon->ID().c_str());
- }
- }
return true;
}
diff --git a/xbmc/addons/RepositoryUpdater.cpp b/xbmc/addons/RepositoryUpdater.cpp
index ca008ce8a5..659c39012d 100644
--- a/xbmc/addons/RepositoryUpdater.cpp
+++ b/xbmc/addons/RepositoryUpdater.cpp
@@ -87,11 +87,7 @@ void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* j
if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON)
{
- for (const auto& addon : updates)
- {
- if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID()))
- CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID());
- }
+ CAddonInstaller::GetInstance().InstallUpdates();
}
ScheduleUpdate();
diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp
index 0fcf5d04f2..bfa272ac57 100644
--- a/xbmc/addons/Scraper.cpp
+++ b/xbmc/addons/Scraper.cpp
@@ -496,6 +496,20 @@ CScraperUrl CScraper::ResolveIDToUrl(const std::string& externalID)
{
CScraperUrl scurlRet;
+ if (m_isPython)
+ {
+ std::stringstream str;
+ str << "plugin://" << ID()
+ << "?action=resolveid&key=" << CURL::Encode(externalID);
+
+ CFileItem item("resolve me", false);
+
+ if (XFILE::CPluginDirectory::GetPluginResult(str.str(), item))
+ scurlRet.ParseString(item.GetPath());
+
+ return scurlRet;
+ }
+
// scraper function takes an external ID, returns XML (see below)
std::vector<std::string> vcsIn;
vcsIn.push_back(externalID);
diff --git a/xbmc/addons/addon-bindings.mk b/xbmc/addons/addon-bindings.mk
index 6bbfe69dbe..aa2525b9b0 100644
--- a/xbmc/addons/addon-bindings.mk
+++ b/xbmc/addons/addon-bindings.mk
@@ -15,6 +15,8 @@ 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_game_dll.h
BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h
+BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h
+BINDINGS+=xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.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/kodi_peripheral_dll.h
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h
new file mode 100644
index 0000000000..9438f242b9
--- /dev/null
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_dll.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include "xbmc_addon_dll.h"
+#include "kodi_imagedec_types.h"
+
+extern "C"
+{
+ void* LoadImage(unsigned char* buffer, unsigned int bufSize,
+ unsigned int* width, unsigned int* height);
+
+ bool Decode(void* image, unsigned char* pixels,
+ unsigned int width, unsigned int height,
+ unsigned int pitch, unsigned int format);
+
+ void Close(void* image);
+
+ // function to export the above structure to Kodi
+ void __declspec(dllexport) get_addon(void* ptr)
+ {
+ KodiToAddonFuncTable_ImageDecoder* img =
+ static_cast<KodiToAddonFuncTable_ImageDecoder*>(ptr);
+ img->LoadImage = LoadImage;
+ img->Decode = Decode;
+ img->Close = Close;
+ }
+};
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h
new file mode 100644
index 0000000000..ad8eb54f23
--- /dev/null
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_imagedec_types.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#define ADDON_IMG_FMT_A8R8G8B8 1
+#define ADDON_IMG_FMT_A8 2
+#define ADDON_IMG_FMT_RGBA8 3
+#define ADDON_IMG_FMT_RGB8 4
+
+extern "C"
+{
+ struct IMAGEDEC_PROPS
+ {
+ const char* mimetype;
+ };
+
+ typedef struct KodiToAddonFuncTable_ImageDecoder
+ {
+ //! \brief Initialize an encoder
+ //! \param buffer The data to read from memory
+ //! \param bufSize The buffer size
+ //! \param width The optimal width of image on entry, obtained width on return
+ //! \param height The optimal height of image, actual obtained height on return
+ //! \return Image or nullptr on error
+ void* (__cdecl* LoadImage) (unsigned char* buffer, unsigned int bufSize,
+ unsigned int* width, unsigned int* height);
+
+ //! \brief Decode previously loaded image
+ //! \param image Image to decode
+ //! \param pixels Output buffer
+ //! \param width Width of output image
+ //! \param height Height of output image
+ //! \param pitch Pitch of output image
+ //! \param format Format of output image
+ bool (__cdecl* Decode) (void* image, unsigned char* pixels,
+ unsigned int width, unsigned int height,
+ unsigned int pitch, unsigned int format);
+
+ //! \brief Close an opened image
+ //! \param image Image to close
+ //! \return True on success, false on failure
+ void (__cdecl* Close)(void* image);
+ } KodiToAddonFuncTable_ImageDecoder;
+}
diff --git a/xbmc/addons/test/TestAddonBuilder.cpp b/xbmc/addons/test/TestAddonBuilder.cpp
index 51cd0b2f14..c30800b5f5 100644
--- a/xbmc/addons/test/TestAddonBuilder.cpp
+++ b/xbmc/addons/test/TestAddonBuilder.cpp
@@ -55,7 +55,7 @@ TEST_F(TestAddonBuilder, ShouldBuildDependencyAddons)
EXPECT_EQ(deps, addon->GetDeps());
}
-TEST_F(TestAddonBuilder, ShouldReturnDeivedType)
+TEST_F(TestAddonBuilder, ShouldReturnDerivedType)
{
builder.SetType(ADDON_RESOURCE_LANGUAGE);
auto addon = std::dynamic_pointer_cast<CLanguageResource>(builder.Build());
diff --git a/xbmc/addons/test/TestAddonFactory.cpp b/xbmc/addons/test/TestAddonFactory.cpp
index c58539522c..00f37cd05c 100644
--- a/xbmc/addons/test/TestAddonFactory.cpp
+++ b/xbmc/addons/test/TestAddonFactory.cpp
@@ -57,7 +57,7 @@ TEST_F(TestAddonFactory, ShouldFailWhenAddonDoesNotHaveRequestedType)
EXPECT_EQ(nullptr, addon);
}
-TEST_F(TestAddonFactory, ShouldPickFirstExtenstionWhenNotRequestingSpecificType)
+TEST_F(TestAddonFactory, ShouldPickFirstExtensionWhenNotRequestingSpecificType)
{
cp_extension_t extensions[2] = {
{&plugin, (char*)"xbmc.python.script", nullptr, nullptr, nullptr, nullptr},
@@ -71,7 +71,7 @@ TEST_F(TestAddonFactory, ShouldPickFirstExtenstionWhenNotRequestingSpecificType)
EXPECT_EQ(ADDON_SCRIPT, addon->Type());
}
-TEST_F(TestAddonFactory, ShouldIgnoreMetadataExtenstion)
+TEST_F(TestAddonFactory, ShouldIgnoreMetadataExtension)
{
cp_extension_t extensions[2] = {
{&plugin, (char*)"kodi.addon.metadata", nullptr, nullptr, nullptr, nullptr},
diff --git a/xbmc/cores/AudioEngine/AEDefines_override.h b/xbmc/cores/AudioEngine/AEDefines_override.h
deleted file mode 100644
index e69de29bb2..0000000000
--- a/xbmc/cores/AudioEngine/AEDefines_override.h
+++ /dev/null
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
index 9f5b8c24fc..bd85d4f771 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
@@ -245,7 +245,7 @@ bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device)
int stream = CJNIAudioManager::STREAM_MUSIC;
m_encoding = CJNIAudioFormat::ENCODING_PCM_16BIT;
- uint32_t distance = 192000; // max upper distance
+ uint32_t distance = UINT32_MAX; // max upper distance, update at least ones to use one of our samplerates
for (auto& s : m_sink_sampleRates)
{
// prefer best match or alternatively something that divides nicely and
@@ -825,7 +825,7 @@ void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
else
{
bool supports_192khz = false;
- int test_sample[] = { 32000, 44100, 48000, 96000, 192000 };
+ int test_sample[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
int test_sample_sz = sizeof(test_sample) / sizeof(int);
int encoding = CJNIAudioFormat::ENCODING_PCM_16BIT;
if (CJNIAudioManager::GetSDKVersion() >= 21)
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp
index 7596537302..ced1200f21 100644
--- a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp
@@ -130,7 +130,7 @@ UInt32 CCoreAudioStream::GetDirection()
// WARNING - don't rely on this method - the return value of
// GetTerminalType is driver specific - the checked return
// values are only recommendations from apple
-bool CCoreAudioStream::IsDigitalOuptut(AudioStreamID id)
+bool CCoreAudioStream::IsDigitalOutput(AudioStreamID id)
{
UInt32 type = GetTerminalType(id);
// yes apple is mixing types here...
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h
index 3f01060e85..ba6d883e8f 100644
--- a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h
+++ b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h
@@ -60,7 +60,7 @@ public:
bool GetAvailablePhysicalFormats(StreamFormatList *pList);
static bool GetAvailableVirtualFormats(AudioStreamID id, StreamFormatList *pList);
static bool GetAvailablePhysicalFormats(AudioStreamID id, StreamFormatList *pList);
- static bool IsDigitalOuptut(AudioStreamID id);
+ static bool IsDigitalOutput(AudioStreamID id);
static bool GetStartingChannelInDevice(AudioStreamID id, UInt32 &startingChannel);
protected:
diff --git a/xbmc/cores/VideoPlayer/CMakeLists.txt b/xbmc/cores/VideoPlayer/CMakeLists.txt
index 00d0232922..4ceff1b890 100644
--- a/xbmc/cores/VideoPlayer/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/CMakeLists.txt
@@ -13,7 +13,8 @@ set(SOURCES DVDAudio.cpp
VideoPlayerRadioRDS.cpp
VideoPlayerSubtitle.cpp
VideoPlayerTeletext.cpp
- VideoPlayerVideo.cpp)
+ VideoPlayerVideo.cpp
+ VideoReferenceClock.cpp)
set(HEADERS DVDAudio.h
DVDClock.h
@@ -32,6 +33,7 @@ set(HEADERS DVDAudio.h
VideoPlayerRadioRDS.h
VideoPlayerSubtitle.h
VideoPlayerTeletext.h
- VideoPlayerVideo.h)
+ VideoPlayerVideo.h
+ VideoReferenceClock.h)
core_add_library(VideoPlayer)
diff --git a/xbmc/cores/VideoPlayer/DVDClock.cpp b/xbmc/cores/VideoPlayer/DVDClock.cpp
index f4ae45d816..4cf90d546e 100644
--- a/xbmc/cores/VideoPlayer/DVDClock.cpp
+++ b/xbmc/cores/VideoPlayer/DVDClock.cpp
@@ -19,7 +19,7 @@
*/
#include "DVDClock.h"
-#include "video/VideoReferenceClock.h"
+#include "VideoReferenceClock.h"
#include <math.h>
#include "utils/MathUtils.h"
#include "threads/SingleLock.h"
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
index 9f2270ef44..c49ec70ef9 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.cpp
@@ -26,36 +26,39 @@
#include "cores/VideoPlayer/DVDClock.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
+#include "settings/AdvancedSettings.h"
#include "guilib/GraphicContext.h"
#include "settings/DisplaySettings.h"
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
+#include "threads/Atomics.h"
#include "utils/AMLUtils.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/SysfsUtils.h"
#include "utils/TimeUtils.h"
-extern "C" {
-#include "libavutil/avutil.h"
-} // extern "C"
-
#include <unistd.h>
#include <queue>
#include <vector>
#include <signal.h>
-#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#include <sys/utsname.h>
#include <linux/videodev2.h>
+#include <sys/poll.h>
+#include <chrono>
+#include <thread>
// amcodec include
extern "C" {
#include <amcodec/codec.h>
} // extern "C"
+CEvent g_aml_sync_event;
+
class PosixFile
{
public:
@@ -128,6 +131,11 @@ public:
virtual int codec_set_cntl_mode(codec_para_t *pcodec, unsigned int mode)=0;
virtual int codec_set_cntl_avthresh(codec_para_t *pcodec, unsigned int avthresh)=0;
virtual int codec_set_cntl_syncthresh(codec_para_t *pcodec, unsigned int syncthresh)=0;
+
+ virtual int codec_set_av_threshold(codec_para_t *pcodec, int threshold)=0;
+ virtual int codec_set_video_delay_limited_ms(codec_para_t *pcodec,int delay_ms)=0;
+ virtual int codec_get_video_delay_limited_ms(codec_para_t *pcodec,int *delay_ms)=0;
+ virtual int codec_get_video_cur_delay_ms(codec_para_t *pcodec,int *delay_ms)=0;
};
class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
@@ -151,6 +159,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
DEFINE_METHOD2(int, codec_set_cntl_avthresh, (codec_para_t *p1, unsigned int p2))
DEFINE_METHOD2(int, codec_set_cntl_syncthresh,(codec_para_t *p1, unsigned int p2))
+ DEFINE_METHOD2(int, codec_set_av_threshold, (codec_para_t *p1, int p2))
+ DEFINE_METHOD2(int, codec_set_video_delay_limited_ms, (codec_para_t *p1, int p2))
+ DEFINE_METHOD2(int, codec_get_video_delay_limited_ms, (codec_para_t *p1, int *p2))
+ DEFINE_METHOD2(int, codec_get_video_cur_delay_ms, (codec_para_t *p1, int *p2))
+
BEGIN_METHOD_RESOLVE()
RESOLVE_METHOD(codec_init)
RESOLVE_METHOD(codec_close)
@@ -167,6 +180,11 @@ class DllLibAmCodec : public DllDynamic, DllLibamCodecInterface
RESOLVE_METHOD(codec_set_cntl_mode)
RESOLVE_METHOD(codec_set_cntl_avthresh)
RESOLVE_METHOD(codec_set_cntl_syncthresh)
+
+ RESOLVE_METHOD(codec_set_av_threshold)
+ RESOLVE_METHOD(codec_set_video_delay_limited_ms)
+ RESOLVE_METHOD(codec_get_video_delay_limited_ms)
+ RESOLVE_METHOD(codec_get_video_cur_delay_ms)
END_METHOD_RESOLVE()
public:
@@ -218,14 +236,17 @@ public:
#define TRICKMODE_I 0x01
#define TRICKMODE_FFFB 0x02
-// same as AV_NOPTS_VALUE
-#define INT64_0 INT64_C(0x8000000000000000)
+static const int64_t INT64_0 = 0x8000000000000000ULL;
#define EXTERNAL_PTS (1)
#define SYNC_OUTSIDE (2)
+#define KEYFRAME_PTS_ONLY 0x100
// missing tags
+#ifndef CODEC_TAG_VC_1
#define CODEC_TAG_VC_1 (0x312D4356)
+#endif
+
#define CODEC_TAG_RV30 (0x30335652)
#define CODEC_TAG_RV40 (0x30345652)
#define CODEC_TAG_MJPEG (0x47504a4d)
@@ -310,6 +331,19 @@ typedef struct am_private_t
bool dumpdemux;
} am_private_t;
+typedef struct vframe_states
+{
+ int vf_pool_size;
+ int buf_free_num;
+ int buf_recycle_num;
+ int buf_avail_num;
+} vframe_states_t;
+
+#ifndef AMSTREAM_IOC_VF_STATUS
+#define AMSTREAM_IOC_MAGIC 'S'
+#define AMSTREAM_IOC_VF_STATUS _IOR(AMSTREAM_IOC_MAGIC, 0x60, unsigned long)
+#endif
+
/*************************************************************************/
/*************************************************************************/
void dumpfile_open(am_private_t *para)
@@ -518,7 +552,7 @@ static void am_packet_init(am_packet_t *pkt)
pkt->avduration = 0;
pkt->isvalid = 0;
pkt->newflag = 0;
- pkt->lastpts = 0;
+ pkt->lastpts = INT64_0;
pkt->data = NULL;
pkt->buf = NULL;
pkt->data_size = 0;
@@ -543,46 +577,14 @@ void am_packet_release(am_packet_t *pkt)
int check_in_pts(am_private_t *para, am_packet_t *pkt)
{
- int last_duration = 0;
- static int last_v_duration = 0;
- int64_t pts = 0;
-
- last_duration = last_v_duration;
-
- if (para->stream_type == AM_STREAM_ES) {
- if ((int64_t)INT64_0 != pkt->avpts) {
- pts = pkt->avpts;
-
- if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
- CLog::Log(LOGDEBUG, "ERROR check in pts error!");
- return PLAYER_PTS_ERROR;
- }
-
- } else if ((int64_t)INT64_0 != pkt->avdts) {
- pts = pkt->avdts * last_duration;
-
- if (para->m_dll->codec_checkin_pts(pkt->codec, pts) != 0) {
- CLog::Log(LOGDEBUG, "ERROR check in dts error!");
- return PLAYER_PTS_ERROR;
- }
-
- last_v_duration = pkt->avduration ? pkt->avduration : 1;
- } else {
- if (!para->check_first_pts) {
- if (para->m_dll->codec_checkin_pts(pkt->codec, 0) != 0) {
- CLog::Log(LOGDEBUG, "ERROR check in 0 to video pts error!");
- return PLAYER_PTS_ERROR;
- }
- }
- }
- if (!para->check_first_pts) {
- para->check_first_pts = 1;
- }
- }
- if (pts > 0)
- pkt->lastpts = pts;
-
- return PLAYER_SUCCESS;
+ if (para->stream_type == AM_STREAM_ES
+ && INT64_0 != pkt->avpts
+ && para->m_dll->codec_checkin_pts(pkt->codec, pkt->avpts) != 0)
+ {
+ CLog::Log(LOGDEBUG, "ERROR check in pts error!");
+ return PLAYER_PTS_ERROR;
+ }
+ return PLAYER_SUCCESS;
}
static int write_header(am_private_t *para, am_packet_t *pkt)
@@ -652,7 +654,7 @@ int write_av_packet(am_private_t *para, am_packet_t *pkt)
}
pkt->newflag = 0;
}
-
+
buf = pkt->data;
size = pkt->data_size ;
if (size == 0 && pkt->isvalid) {
@@ -1319,9 +1321,14 @@ int set_header_info(am_private_t *para)
/*************************************************************************/
CAMLCodec::CAMLCodec()
- : CThread("CAMLCodec")
+ : m_opened(false)
+ , m_ptsIs64us(false)
+ , m_cur_pts(INT64_0)
+ , m_last_pts(0)
+ , m_bufferIndex(-1)
+ , m_state(0)
+ , m_frameSizeSum(0)
{
- m_opened = false;
am_private = new am_private_t;
memset(am_private, 0, sizeof(am_private_t));
m_dll = new DllLibAmCodec;
@@ -1337,25 +1344,39 @@ CAMLCodec::CAMLCodec()
CAMLCodec::~CAMLCodec()
{
- StopThread();
delete am_private;
am_private = NULL;
delete m_dll, m_dll = NULL;
}
+float CAMLCodec::OMXPtsToSeconds(int omxpts)
+{
+ return static_cast<float>(omxpts) / PTS_FREQ;
+}
+
+int CAMLCodec::OMXDurationToNs(int duration)
+{
+ return static_cast<int>(static_cast<float>(duration) / PTS_FREQ * 1000000 );
+}
+
+int CAMLCodec::GetAmlDuration() const
+{
+ return am_private ? (am_private->video_rate * PTS_FREQ) / UNIT_FREQ : 0;
+};
+
bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
{
m_speed = DVD_PLAYSPEED_NORMAL;
- m_1st_pts = 0;
- m_cur_pts = 0;
+ m_cur_pts = INT64_0;
m_dst_rect.SetRect(0, 0, 0, 0);
m_zoom = -1;
m_contrast = -1;
m_brightness = -1;
- m_vbufsize = 500000 * 2;
- m_start_dts = 0;
- m_start_pts = 0;
+ m_start_adj = 0;
m_hints = hints;
+ m_state = 0;
+ m_frameSizes.clear();
+ m_frameSizeSum = 0;
if (!OpenAmlVideo(hints))
{
@@ -1480,6 +1501,8 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
break;
case VFORMAT_MPEG4:
am_private->gcodec.param = (void*)EXTERNAL_PTS;
+ if (m_hints.ptsinvalid)
+ am_private->gcodec.param = (void*)(EXTERNAL_PTS | KEYFRAME_PTS_ONLY);
break;
case VFORMAT_H264:
case VFORMAT_H264MVC:
@@ -1522,7 +1545,7 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
case VFORMAT_VC1:
// vc1 in an avi file
if (m_hints.ptsinvalid)
- am_private->gcodec.param = (void*)EXTERNAL_PTS;
+ am_private->gcodec.param = (void*)KEYFRAME_PTS_ONLY;
break;
case VFORMAT_HEVC:
am_private->gcodec.format = VIDEO_DEC_FORMAT_HEVC;
@@ -1546,9 +1569,10 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
am_private->dumpdemux = false;
dumpfile_open(am_private);
- //! @bug make sure we are not stuck in pause (amcodec bug)
- m_dll->codec_resume(&am_private->vcodec);
+ m_dll->codec_pause(&am_private->vcodec);
+
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
+ m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000);
m_dll->codec_set_cntl_avthresh(&am_private->vcodec, AV_SYNC_THRESH);
m_dll->codec_set_cntl_syncthresh(&am_private->vcodec, 0);
@@ -1558,8 +1582,6 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
am_private->am_pkt.codec = &am_private->vcodec;
pre_header_feeding(am_private, &am_private->am_pkt);
- Create();
-
m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iHeight);
std::string strScaler;
@@ -1567,21 +1589,25 @@ bool CAMLCodec::OpenDecoder(CDVDStreamInfo &hints)
if (strScaler.find("enabled") == std::string::npos) // Scaler not enabled, use screen size
m_display_rect = CRect(0, 0, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenWidth, CDisplaySettings::GetInstance().GetCurrentResolutionInfo().iScreenHeight);
-/*
- // if display is set to 1080xxx, then disable deinterlacer for HD content
- // else bandwidth usage is too heavy and it will slow down video decoder.
- char display_mode[256] = {0};
- SysfsUtils::GetString("/sys/class/display/mode", display_mode, 255);
- if (strstr(display_mode,"1080"))
- SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 1);
- else
- SysfsUtils::SetInt("/sys/module/di/parameters/bypass_all", 0);
-*/
+ SysfsUtils::SetInt("/sys/class/video/freerun_mode", 1);
+
+
+ struct utsname un;
+ if (uname(&un) == 0)
+ {
+ int linuxversion[2];
+ sscanf(un.release,"%d.%d", &linuxversion[0], &linuxversion[1]);
+ if (linuxversion[0] > 3 || (linuxversion[0] == 3 && linuxversion[1] >= 14))
+ m_ptsIs64us = true;
+ }
+
+ CLog::Log(LOGNOTICE, "CAMLCodec::OpenDecoder - using V4L2 pts format: %s", m_ptsIs64us ? "64Bit":"32Bit");
m_opened = true;
// vcodec is open, update speed if it was
// changed before VideoPlayer called OpenDecoder.
SetSpeed(m_speed);
+ SetPollDevice(am_private->vcodec.cntl_handle);
return true;
}
@@ -1600,7 +1626,7 @@ bool CAMLCodec::OpenAmlVideo(const CDVDStreamInfo &hints)
m_defaultVfmMap = GetVfmMap("default");
SetVfmMap("default", "decoder ppmgr deinterlace amlvideo amvideo");
- SysfsUtils::SetInt("/sys/module/amlvideodri/parameters/freerun_mode", 1);
+ SysfsUtils::SetInt("/sys/module/amlvideodri/parameters/freerun_mode", 3);
return true;
}
@@ -1636,12 +1662,13 @@ void CAMLCodec::SetVfmMap(const std::string &name, const std::string &map)
void CAMLCodec::CloseDecoder()
{
CLog::Log(LOGDEBUG, "CAMLCodec::CloseDecoder");
- StopThread();
+
+ SetPollDevice(-1);
// never leave vcodec ff/rw or paused.
if (m_speed != DVD_PLAYSPEED_NORMAL)
{
- m_dll->codec_resume(&am_private->vcodec);
+ //m_dll->codec_resume(&am_private->vcodec);
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
}
m_dll->codec_close(&am_private->vcodec);
@@ -1672,6 +1699,8 @@ void CAMLCodec::Reset()
if (!m_opened)
return;
+ SetPollDevice(-1);
+
// set the system blackout_policy to leave the last frame showing
int blackout_policy;
SysfsUtils::GetInt("/sys/class/video/blackout_policy", blackout_policy);
@@ -1680,11 +1709,14 @@ void CAMLCodec::Reset()
// restore the speed (some amcodec versions require this)
if (m_speed != DVD_PLAYSPEED_NORMAL)
{
- m_dll->codec_resume(&am_private->vcodec);
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
}
+ m_dll->codec_pause(&am_private->vcodec);
+
// reset the decoder
m_dll->codec_reset(&am_private->vcodec);
+ m_dll->codec_set_video_delay_limited_ms(&am_private->vcodec, 1000);
+
dumpfile_close(am_private);
dumpfile_open(am_private);
@@ -1697,20 +1729,31 @@ void CAMLCodec::Reset()
// restore the saved system blackout_policy value
SysfsUtils::SetInt("/sys/class/video/blackout_policy", blackout_policy);
- // reset some internal vars
- m_1st_pts = 0;
- m_cur_pts = 0;
- m_ptsQueue.clear();
+ // reset some interal vars
+ m_cur_pts = INT64_0;
+ m_state = 0;
+ m_start_adj = 0;
+ m_frameSizes.clear();
+ m_frameSizeSum = 0;
+
SetSpeed(m_speed);
+
+ SetPollDevice(am_private->vcodec.cntl_handle);
}
int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
{
if (!m_opened)
- return VC_BUFFER;
+ return VC_ERROR;
+ int rtn(0);
+
+ float timesize(GetTimeSize());
if (pData)
{
+ m_frameSizes.push_back(iSize);
+ m_frameSizeSum += iSize;
+
am_private->am_pkt.data = pData;
am_private->am_pkt.data_size = iSize;
@@ -1721,31 +1764,39 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
// handle pts, including 31bit wrap, aml can only handle 31
// bit pts as it uses an int in kernel.
if (m_hints.ptsinvalid || pts == DVD_NOPTS_VALUE)
- am_private->am_pkt.avpts = AV_NOPTS_VALUE;
+ am_private->am_pkt.avpts = INT64_0;
else
{
am_private->am_pkt.avpts = 0.5 + (pts * PTS_FREQ) / DVD_TIME_BASE;\
- if (!m_start_pts && am_private->am_pkt.avpts >= 0x7fffffff)
- m_start_pts = am_private->am_pkt.avpts & ~0x0000ffff;
+ if (!m_start_adj && am_private->am_pkt.avpts >= 0x7fffffff)
+ m_start_adj = am_private->am_pkt.avpts & ~0x0000ffff;
+ am_private->am_pkt.avpts -= m_start_adj;
+ m_state |= STATE_HASPTS;
}
- if (am_private->am_pkt.avpts != (int64_t)AV_NOPTS_VALUE)
- am_private->am_pkt.avpts -= m_start_pts;
// handle dts, including 31bit wrap, aml can only handle 31
// bit dts as it uses an int in kernel.
if (dts == DVD_NOPTS_VALUE)
- am_private->am_pkt.avdts = AV_NOPTS_VALUE;
+ am_private->am_pkt.avdts = am_private->am_pkt.avpts;
else
{
am_private->am_pkt.avdts = 0.5 + (dts * PTS_FREQ) / DVD_TIME_BASE;
- if (!m_start_dts && am_private->am_pkt.avdts >= 0x7fffffff)
- m_start_dts = am_private->am_pkt.avdts & ~0x0000ffff;
- }
- if (am_private->am_pkt.avdts != (int64_t)AV_NOPTS_VALUE)
- am_private->am_pkt.avdts -= m_start_dts;
+ if (!m_start_adj && am_private->am_pkt.avdts >= 0x7fffffff)
+ m_start_adj = am_private->am_pkt.avdts & ~0x0000ffff;
+ am_private->am_pkt.avdts -= m_start_adj;
- //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: iSize(%d), dts(%f), pts(%f), avdts(%llx), avpts(%llx)",
- // iSize, dts, pts, am_private->am_pkt.avdts, am_private->am_pkt.avpts);
+ // For VC1 AML decoder uses PTS only on I-Frames
+ if (am_private->am_pkt.avpts == INT64_0 && (((size_t)am_private->gcodec.param) & KEYFRAME_PTS_ONLY))
+ am_private->am_pkt.avpts = am_private->am_pkt.avdts;
+ }
+ // We use this to determine the fill state if no PTS is given
+ if (m_cur_pts == INT64_0)
+ {
+ m_cur_pts = am_private->am_pkt.avdts;
+ // No PTS given -> use first DTS for AML ptsserver initialization
+ if ((m_state & STATE_HASPTS) == 0)
+ am_private->am_pkt.avpts = am_private->am_pkt.avdts;
+ }
// some formats need header/data tweaks.
// the actual write occurs once in write_av_packet
@@ -1767,80 +1818,142 @@ int CAMLCodec::Decode(uint8_t *pData, size_t iSize, double dts, double pts)
loop++;
}
if (loop == 100)
- {
// Decoder got stuck; Reset
Reset();
- }
- // if we seek, then GetTimeSize is wrong as
- // reports lastpts - cur_pts and hw decoder has
- // not started outputing new pts values yet.
- // so we grab the 1st pts sent into driver and
- // use that to calc GetTimeSize.
- if (m_1st_pts == 0)
- m_1st_pts = am_private->am_pkt.lastpts;
+ if ((m_state & STATE_PREFILLED) == 0 && timesize >= 1.0)
+ m_state |= STATE_PREFILLED;
}
- // if we have still frames, demux size will be small
- // and we need to pre-buffer more.
- double target_timesize = 1.0;
- if (iSize < 20)
- target_timesize = 2.0;
-
- int rtn = 0;
+ if ((m_state & STATE_PREFILLED) != 0 && timesize > 0.5 && DequeueBuffer() == 0)
+ rtn |= VC_PICTURE;
- // keep hw buffered demux above 1 second
- if (GetTimeSize() < target_timesize)
+ if (((rtn & VC_PICTURE) == 0 && timesize < 2.0) || timesize < 1.0)
rtn |= VC_BUFFER;
- // wait until we get a new frame or 25ms,
- if (m_ptsQueue.size() == 0)
- m_ready_event.WaitMSec(25);
- if (m_ptsQueue.size() > 0)
+ if (g_advancedSettings.CanLogComponent(LOGVIDEO))
{
- CSingleLock lock(m_ptsQueueMutex);
- m_cur_pts = m_ptsQueue.front();
- m_ptsQueue.pop_front();
- rtn |= VC_PICTURE;
+ CLog::Log(LOGDEBUG, "CAMLCodec::Decode: ret: %d, sz: %u, dts_in: %0.4lf[%llX], pts_in: %0.4lf[%llX], adj:%llu, ptsOut:%0.4f, amlpts:%d, idx:%u, timesize:%0.4f",
+ rtn,
+ static_cast<unsigned int>(iSize),
+ dts / DVD_TIME_BASE, am_private->am_pkt.avdts,
+ pts / DVD_TIME_BASE, am_private->am_pkt.avpts,
+ m_start_adj,
+ static_cast<float>(m_cur_pts)/PTS_FREQ,
+ static_cast<int>(m_cur_pts),
+ m_bufferIndex,
+ timesize
+ );
}
-/*
- CLog::Log(LOGDEBUG, "CAMLCodec::Decode: "
- "rtn(%d), m_cur_pictcnt(%lld), m_cur_pts(%f), lastpts(%f), GetTimeSize(%f), GetDataSize(%d)",
- rtn, m_cur_pictcnt, (float)m_cur_pts/PTS_FREQ, (float)am_private->am_pkt.lastpts/PTS_FREQ, GetTimeSize(), GetDataSize());
-*/
+
return rtn;
}
-int CAMLCodec::DequeueBuffer(int64_t &pts)
+std::atomic_flag CAMLCodec::m_pollSync = ATOMIC_FLAG_INIT;
+int CAMLCodec::m_pollDevice;
+
+int CAMLCodec::PollFrame()
+{
+ CAtomicSpinLock lock(m_pollSync);
+ if (m_pollDevice < 0)
+ return 0;
+
+ struct pollfd codec_poll_fd[1];
+
+ codec_poll_fd[0].fd = m_pollDevice;
+ codec_poll_fd[0].events = POLLOUT;
+
+ if (poll(codec_poll_fd, 1, 100) > 0)
+ {
+ g_aml_sync_event.Set();
+ return 1;
+ }
+ return 0;
+}
+
+void CAMLCodec::SetPollDevice(int dev)
{
+ CAtomicSpinLock lock(m_pollSync);
+ m_pollDevice = dev;
+}
+
+int CAMLCodec::ReleaseFrame(const uint32_t index, bool drop)
+{
+ int ret;
v4l2_buffer vbuf = { 0 };
vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vbuf.index = index;
+
+ if (drop)
+ vbuf.flags |= V4L2_BUF_FLAG_DONE;
+
+ if (g_advancedSettings.CanLogComponent(LOGVIDEO))
+ CLog::Log(LOGDEBUG, "CAMLCodec::ReleaseFrame idx:%u", index);
+
+ if ((ret = m_amlVideoFile->IOControl(VIDIOC_QBUF, &vbuf)) < 0)
+ CLog::Log(LOGERROR, "CAMLCodec::ReleaseFrame - VIDIOC_QBUF failed: %s", strerror(errno));
+ return ret;
+}
+
+int CAMLCodec::DequeueBuffer()
+{
+ v4l2_buffer vbuf = { 0 };
+ vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ //Driver change from 10 to 0ms latency, throttle here
+ std::chrono::time_point<std::chrono::system_clock> now(std::chrono::system_clock::now());
if (m_amlVideoFile->IOControl(VIDIOC_DQBUF, &vbuf) < 0)
{
if (errno != EAGAIN)
CLog::Log(LOGERROR, "CAMLCodec::DequeueBuffer - VIDIOC_DQBUF failed: %s", strerror(errno));
+
+ std::chrono::milliseconds elapsed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now).count());
+
+ if (elapsed < std::chrono::milliseconds(10))
+ std::this_thread::sleep_for(std::chrono::milliseconds(10) - elapsed);
+
return -errno;
}
// Since kernel 3.14 Amlogic changed length and units of PTS values reported here.
// To differentiate such PTS values we check for existence of omx_pts_interval_lower
// parameter, because it was introduced since kernel 3.14.
- if (access("/sys/module/amvideo/parameters/omx_pts_interval_lower", F_OK) != -1)
+ m_last_pts = m_cur_pts;
+
+ if (m_ptsIs64us)
{
- pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF;
- pts <<= 32;
- pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF;
- pts = (pts * PTS_FREQ) / DVD_TIME_BASE;
+ m_cur_pts = vbuf.timestamp.tv_sec & 0xFFFFFFFF;
+ m_cur_pts <<= 32;
+ m_cur_pts += vbuf.timestamp.tv_usec & 0xFFFFFFFF;
+ m_cur_pts = (m_cur_pts * PTS_FREQ) / DVD_TIME_BASE;
}
else
{
- pts = vbuf.timestamp.tv_usec;
+ m_cur_pts = vbuf.timestamp.tv_usec;
}
+ m_bufferIndex = vbuf.index;
return 0;
}
+float CAMLCodec::GetTimeSize()
+{
+ struct buf_status bs;
+ m_dll->codec_get_vbuf_state(&am_private->vcodec, &bs);
+
+ //CLog::Log(LOGDEBUG, "CAMLCodec::Decode: buf status: s:%d dl:%d fl:%d rp:%u wp:%u",bs.size, bs.data_len, bs.free_len, bs.read_pointer, bs.write_pointer);
+ while (m_frameSizeSum > (unsigned int)bs.data_len)
+ {
+ m_frameSizeSum -= m_frameSizes.front();
+ m_frameSizes.pop_front();
+ }
+ if (bs.free_len < bs.data_len)
+ return 7.0;
+
+ return (float)(m_frameSizes.size() * am_private->video_rate) / UNIT_FREQ;
+}
+
bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
{
if (!m_opened)
@@ -1848,24 +1961,23 @@ bool CAMLCodec::GetPicture(DVDVideoPicture *pDvdVideoPicture)
pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
pDvdVideoPicture->format = RENDER_FMT_AML;
- pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
- pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
- if (m_speed == DVD_PLAYSPEED_NORMAL)
- pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
+ if (m_last_pts <= 0)
+ pDvdVideoPicture->iDuration = (double)(am_private->video_rate * DVD_TIME_BASE) / UNIT_FREQ;
else
- {
- if (m_cur_pts == 0)
- pDvdVideoPicture->pts = (double)m_1st_pts / PTS_FREQ * DVD_TIME_BASE;
- else
- pDvdVideoPicture->pts = (double)m_cur_pts / PTS_FREQ * DVD_TIME_BASE;
- }
+ pDvdVideoPicture->iDuration = (double)((m_cur_pts - m_last_pts) * DVD_TIME_BASE) / PTS_FREQ;
+
+ pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
+ pDvdVideoPicture->pts = (double)GetCurPts() / PTS_FREQ * DVD_TIME_BASE;
return true;
}
void CAMLCodec::SetSpeed(int speed)
{
+ if (m_speed == speed)
+ return;
+
CLog::Log(LOGDEBUG, "CAMLCodec::SetSpeed, speed(%d)", speed);
// update internal vars regardless
@@ -1878,15 +1990,15 @@ void CAMLCodec::SetSpeed(int speed)
switch(speed)
{
case DVD_PLAYSPEED_PAUSE:
- m_dll->codec_pause(&am_private->vcodec);
+ //m_dll->codec_pause(&am_private->vcodec);
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
break;
case DVD_PLAYSPEED_NORMAL:
- m_dll->codec_resume(&am_private->vcodec);
+ //m_dll->codec_resume(&am_private->vcodec);
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_NONE);
break;
default:
- m_dll->codec_resume(&am_private->vcodec);
+ //m_dll->codec_resume(&am_private->vcodec);
if ((am_private->video_format == VFORMAT_H264) || (am_private->video_format == VFORMAT_H264_4K2K))
m_dll->codec_set_cntl_mode(&am_private->vcodec, TRICKMODE_FFFB);
else
@@ -1895,68 +2007,6 @@ void CAMLCodec::SetSpeed(int speed)
}
}
-int CAMLCodec::GetDataSize()
-{
- if (!m_opened)
- return 0;
-
- struct buf_status vbuf ={0};
- if (m_dll->codec_get_vbuf_state(&am_private->vcodec, &vbuf) >= 0)
- m_vbufsize = vbuf.size;
-
- return vbuf.data_len;
-}
-
-double CAMLCodec::GetTimeSize()
-{
- if (!m_opened)
- return 0;
-
- // if m_cur_pts is zero, hw decoder was not started yet
- // so we use the pts of the 1st demux packet that was send
- // to hw decoder to calc timesize.
- if (m_cur_pts == 0)
- m_timesize = (double)(am_private->am_pkt.lastpts - m_1st_pts) / PTS_FREQ;
- else
- m_timesize = (double)(am_private->am_pkt.lastpts - GetOMXPts()) / PTS_FREQ;
-
- // lie to VideoPlayer, it is hardcoded to a max of 8 seconds,
- // if you buffer more than 8 seconds, it goes nuts.
- double timesize = m_timesize;
- if (timesize < 0.0)
- timesize = 0.0;
- else if (timesize > 7.0)
- timesize = 7.0;
-
- return timesize;
-}
-
-void CAMLCodec::Process()
-{
- CLog::Log(LOGDEBUG, "CAMLCodec::Process Started");
-
- while (!m_bStop)
- {
- if (m_dll->codec_poll_cntl(&am_private->vcodec) < 0)
- {
- CLog::Log(LOGDEBUG, "CAMLCodec::Process: codec_poll_cntl failed");
- Sleep(10);
- }
-
- {
- CSingleLock lock(m_ptsQueueMutex);
- int64_t pts = 0;
- if (DequeueBuffer(pts) == 0)
- {
- m_ptsQueue.push_back(pts + m_start_pts);
- m_ready_event.Set();
- }
- }
- }
-
- CLog::Log(LOGDEBUG, "CAMLCodec::Process Stopped");
-}
-
void CAMLCodec::ShowMainVideo(const bool show)
{
static int saved_disable_video = -1;
@@ -2083,7 +2133,8 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
case 1:
case 3:
{
- int diff = (int) ((dst_rect.Height() - dst_rect.Width()) / 2);
+ double scale = (double)dst_rect.Height() / dst_rect.Width();
+ int diff = (int) ((dst_rect.Height()*scale - dst_rect.Width()) / 2);
dst_rect = CRect(DestRect.x1 - diff, DestRect.y1, DestRect.x2 + diff, DestRect.y2);
}
@@ -2208,3 +2259,9 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
// that would show video playback, so show it.
ShowMainVideo(true);
}
+
+void CAMLCodec::SetVideoRate(int videoRate)
+{
+ if (am_private)
+ am_private->video_rate = videoRate;
+}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
index ede815d805..402ef7f93a 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h
@@ -24,8 +24,9 @@
#include "cores/IPlayer.h"
#include "guilib/Geometry.h"
#include "rendering/RenderSystem.h"
-#include "threads/Thread.h"
+
#include <deque>
+#include <atomic>
typedef struct am_private_t am_private_t;
@@ -34,7 +35,7 @@ class DllLibAmCodec;
class PosixFile;
typedef std::shared_ptr<PosixFile> PosixFilePtr;
-class CAMLCodec : public CThread
+class CAMLCodec
{
public:
CAMLCodec();
@@ -48,14 +49,18 @@ public:
bool GetPicture(DVDVideoPicture* pDvdVideoPicture);
void SetSpeed(int speed);
- int GetDataSize();
- double GetTimeSize();
void SetVideoRect(const CRect &SrcRect, const CRect &DestRect);
- int64_t GetCurPts() const { return m_cur_pts; }
- int GetOMXPts() const { return static_cast<int>(m_cur_pts - m_start_pts); }
+ void SetVideoRate(int videoRate);
+ int64_t GetCurPts() const { return m_cur_pts + m_start_adj; }
+ int GetOMXPts() const { return static_cast<int>(m_cur_pts); }
+ uint32_t GetBufferIndex() const { return m_bufferIndex; };
+ static float OMXPtsToSeconds(int omxpts);
+ static int OMXDurationToNs(int duration);
+ int GetAmlDuration() const;
+ int ReleaseFrame(const uint32_t index, bool bDrop = false);
-protected:
- virtual void Process();
+ static int PollFrame();
+ static void SetPollDevice(int device);
private:
void ShowMainVideo(const bool show);
@@ -69,20 +74,20 @@ private:
void CloseAmlVideo();
std::string GetVfmMap(const std::string &name);
void SetVfmMap(const std::string &name, const std::string &map);
- int DequeueBuffer(int64_t &pts);
+ int DequeueBuffer();
+ float GetTimeSize();
DllLibAmCodec *m_dll;
bool m_opened;
+ bool m_ptsIs64us;
am_private_t *am_private;
CDVDStreamInfo m_hints;
- volatile int m_speed;
- volatile int64_t m_1st_pts;
- volatile int64_t m_cur_pts;
- volatile double m_timesize;
- volatile int64_t m_vbufsize;
- int64_t m_start_dts;
- int64_t m_start_pts;
- CEvent m_ready_event;
+ int m_speed;
+ int64_t m_cur_pts;
+ uint32_t m_max_frame_size;
+ int64_t m_start_adj;
+ int64_t m_last_pts;
+ uint32_t m_bufferIndex;
CRect m_dst_rect;
CRect m_display_rect;
@@ -95,8 +100,17 @@ private:
int m_brightness;
RESOLUTION m_video_res;
+ static const unsigned int STATE_PREFILLED = 1;
+ static const unsigned int STATE_HASPTS = 2;
+
+ unsigned int m_state;
+
PosixFilePtr m_amlVideoFile;
std::string m_defaultVfmMap;
- std::deque<int64_t> m_ptsQueue;
- CCriticalSection m_ptsQueueMutex;
+
+ std::deque<uint32_t> m_frameSizes;
+ std::uint32_t m_frameSizeSum;
+
+ static std::atomic_flag m_pollSync;
+ static int m_pollDevice;
};
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
index d78631d0c6..ec0395974c 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.cpp
@@ -30,6 +30,7 @@
#include "utils/log.h"
#include "utils/SysfsUtils.h"
#include "settings/Settings.h"
+#include "threads/Thread.h"
#define __MODULE_NAME__ "DVDVideoCodecAmlogic"
@@ -43,16 +44,17 @@ typedef struct frame_queue {
CDVDVideoCodecAmlogic::CDVDVideoCodecAmlogic(CProcessInfo &processInfo) : CDVDVideoCodec(processInfo),
m_Codec(NULL),
m_pFormatName("amcodec"),
+ m_opened(false),
m_last_pts(0.0),
m_frame_queue(NULL),
m_queue_depth(0),
m_framerate(0.0),
m_video_rate(0),
m_mpeg2_sequence(NULL),
+ m_drop(false),
+ m_has_keyframe(false),
m_bitparser(NULL),
- m_bitstream(NULL),
- m_opened(false),
- m_drop(false)
+ m_bitstream(NULL)
{
pthread_mutex_init(&m_queue_mutex, NULL);
}
@@ -125,14 +127,18 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option
{
m_bitstream = new CBitstreamConverter;
m_bitstream->Open(m_hints.codec, (uint8_t*)m_hints.extradata, m_hints.extrasize, true);
+ m_bitstream->ResetKeyframe();
// make sure we do not leak the existing m_hints.extradata
free(m_hints.extradata);
m_hints.extrasize = m_bitstream->GetExtraSize();
m_hints.extradata = malloc(m_hints.extrasize);
memcpy(m_hints.extradata, m_bitstream->GetExtraData(), m_hints.extrasize);
}
- //m_bitparser = new CBitstreamParser();
- //m_bitparser->Open();
+ else
+ {
+ m_bitparser = new CBitstreamParser();
+ m_bitparser->Open();
+ }
break;
case AV_CODEC_ID_MPEG4:
case AV_CODEC_ID_MSMPEG4V2:
@@ -147,9 +153,9 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option
// amcodec can't handle h263
return false;
break;
- case AV_CODEC_ID_FLV1:
- m_pFormatName = "am-flv1";
- break;
+// case AV_CODEC_ID_FLV1:
+// m_pFormatName = "am-flv1";
+// break;
case AV_CODEC_ID_RV10:
case AV_CODEC_ID_RV20:
case AV_CODEC_ID_RV30:
@@ -236,6 +242,9 @@ bool CDVDVideoCodecAmlogic::Open(CDVDStreamInfo &hints, CDVDCodecOptions &option
m_processInfo.SetVideoDecoderName(m_pFormatName, true);
m_processInfo.SetVideoDimensions(m_hints.width, m_hints.height);
m_processInfo.SetVideoDeintMethod("hardware");
+ m_processInfo.SetVideoDAR(m_hints.aspect);
+
+ m_has_keyframe = false;
CLog::Log(LOGINFO, "%s: Opened Amlogic Codec", __MODULE_NAME__);
return true;
@@ -277,21 +286,35 @@ int CDVDVideoCodecAmlogic::Decode(uint8_t *pData, int iSize, double dts, double
if (!m_bitstream->Convert(pData, iSize))
return VC_ERROR;
+ if (!m_bitstream->HasKeyframe())
+ {
+ CLog::Log(LOGDEBUG, "%s::Decode waiting for keyframe (bitstream)", __MODULE_NAME__);
+ return VC_BUFFER;
+ }
pData = m_bitstream->GetConvertBuffer();
iSize = m_bitstream->GetConvertSize();
}
-
- if (m_bitparser)
- m_bitparser->FindIdrSlice(pData, iSize);
-
+ else if (!m_has_keyframe && m_bitparser)
+ {
+ if (!m_bitparser->HasKeyframe(pData, iSize))
+ {
+ CLog::Log(LOGDEBUG, "%s::Decode waiting for keyframe (bitparser)", __MODULE_NAME__);
+ return VC_BUFFER;
+ }
+ else
+ m_has_keyframe = true;
+ }
FrameRateTracking( pData, iSize, dts, pts);
- }
- if (!m_opened)
- {
- if (m_Codec && !m_Codec->OpenDecoder(m_hints))
- CLog::Log(LOGERROR, "%s: Failed to open Amlogic Codec", __MODULE_NAME__);
- m_opened = true;
+ if (!m_opened)
+ {
+ if (pts == DVD_NOPTS_VALUE)
+ m_hints.ptsinvalid = true;
+
+ if (m_Codec && !m_Codec->OpenDecoder(m_hints))
+ CLog::Log(LOGERROR, "%s: Failed to open Amlogic Codec", __MODULE_NAME__);
+ m_opened = true;
+ }
}
if (m_hints.ptsinvalid)
@@ -307,6 +330,9 @@ void CDVDVideoCodecAmlogic::Reset(void)
m_Codec->Reset();
m_mpeg2_sequence_pts = 0;
+ m_has_keyframe = false;
+ if (m_bitstream && m_hints.codec == AV_CODEC_ID_H264)
+ m_bitstream->ResetKeyframe();
}
bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture)
@@ -315,7 +341,8 @@ bool CDVDVideoCodecAmlogic::GetPicture(DVDVideoPicture* pDvdVideoPicture)
m_Codec->GetPicture(&m_videobuffer);
*pDvdVideoPicture = m_videobuffer;
- CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec, m_Codec->GetOMXPts());
+ CDVDAmlogicInfo* info = new CDVDAmlogicInfo(this, m_Codec,
+ m_Codec->GetOMXPts(), m_Codec->GetAmlDuration(), m_Codec->GetBufferIndex());
{
CSingleLock lock(m_secure);
@@ -363,7 +390,7 @@ void CDVDVideoCodecAmlogic::SetDropState(bool bDrop)
// Freerun mode causes amvideo driver to ignore timing and process frames
// as quickly as they are coming from decoder. By enabling freerun mode we can
// skip rendering of the frames that are requested to be dropped by VideoPlayer.
- SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0);
+ //SysfsUtils::SetInt("/sys/class/video/freerun_mode", bDrop ? 1 : 0);
}
void CDVDVideoCodecAmlogic::SetSpeed(int iSpeed)
@@ -372,22 +399,6 @@ void CDVDVideoCodecAmlogic::SetSpeed(int iSpeed)
m_Codec->SetSpeed(iSpeed);
}
-int CDVDVideoCodecAmlogic::GetDataSize(void)
-{
- if (m_Codec)
- return m_Codec->GetDataSize();
-
- return 0;
-}
-
-double CDVDVideoCodecAmlogic::GetTimeSize(void)
-{
- if (m_Codec)
- return m_Codec->GetTimeSize();
-
- return 0.0;
-}
-
void CDVDVideoCodecAmlogic::FrameQueuePop(void)
{
if (!m_frame_queue || m_queue_depth == 0)
@@ -466,8 +477,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
m_framerate = m_mpeg2_sequence->rate;
m_video_rate = (int)(0.5 + (96000.0 / m_framerate));
- CLog::Log(LOGDEBUG, "%s: detected mpeg2 aspect ratio(%f), framerate(%f), video_rate(%d)",
- __MODULE_NAME__, m_mpeg2_sequence->ratio, m_framerate, m_video_rate);
+ m_processInfo.SetVideoFps(m_framerate);
// update m_hints for 1st frame fixup.
switch(m_mpeg2_sequence->rate_info)
@@ -526,7 +536,7 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
if (cur_pts == DVD_NOPTS_VALUE)
cur_pts = m_frame_queue->dts;
- pthread_mutex_unlock(&m_queue_mutex);
+ pthread_mutex_unlock(&m_queue_mutex);
float duration = cur_pts - m_last_pts;
m_last_pts = cur_pts;
@@ -559,22 +569,10 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
break;
// 25.000 (40000.000000)
- case 40000:
+ case 39900 ... 40100:
framerate = 25000.0 / 1000.0;
break;
- // 24.975 (40040.000000)
- case 40040:
- framerate = 25000.0 / 1001.0;
- break;
-
- /*
- // 24.000 (41666.666666)
- case 41667:
- framerate = 24000.0 / 1000.0;
- break;
- */
-
// 23.976 (41708.33333)
case 40200 ... 43200:
// 23.976 seems to have the crappiest encodings :)
@@ -592,6 +590,12 @@ void CDVDVideoCodecAmlogic::FrameRateTracking(uint8_t *pData, int iSize, double
{
m_framerate = framerate;
m_video_rate = (int)(0.5 + (96000.0 / framerate));
+
+ if (m_Codec)
+ m_Codec->SetVideoRate(m_video_rate);
+
+ m_processInfo.SetVideoFps(m_framerate);
+
CLog::Log(LOGDEBUG, "%s: detected new framerate(%f), video_rate(%d)",
__MODULE_NAME__, m_framerate, m_video_rate);
}
@@ -607,11 +611,14 @@ void CDVDVideoCodecAmlogic::RemoveInfo(CDVDAmlogicInfo *info)
m_inflight.erase(m_inflight.find(info));
}
-CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts)
+CDVDAmlogicInfo::CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration, uint32_t bufferIndex)
: m_refs(0)
, m_codec(codec)
, m_amlCodec(amlcodec)
, m_omxPts(omxPts)
+ , m_amlDuration(amlDuration)
+ , m_bufferIndex(bufferIndex)
+ , m_rendered(false)
{
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
index 2c442413eb..9e57295701 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h
@@ -36,7 +36,7 @@ class CDVDVideoCodecAmlogic;
class CDVDAmlogicInfo
{
public:
- CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts);
+ CDVDAmlogicInfo(CDVDVideoCodecAmlogic *codec, CAMLCodec *amlcodec, int omxPts, int amlDuration, uint32_t bufferIndex);
// reference counting
CDVDAmlogicInfo* Retain();
@@ -44,7 +44,11 @@ public:
CAMLCodec *getAmlCodec() const;
int GetOmxPts() const { return m_omxPts; }
+ int GetAmlDuration() const { return m_amlDuration; }
+ uint32_t GetBufferIndex() const { return m_bufferIndex; };
void invalidate();
+ void SetRendered() { m_rendered = true; };
+ bool IsRendered() { return m_rendered; };
protected:
long m_refs;
@@ -52,7 +56,9 @@ protected:
CDVDVideoCodecAmlogic* m_codec;
CAMLCodec* m_amlCodec;
- int m_omxPts;
+ int m_omxPts, m_amlDuration;
+ uint32_t m_bufferIndex;
+ bool m_rendered;
};
class CDVDVideoCodecAmlogic : public CDVDVideoCodec
@@ -71,8 +77,6 @@ public:
virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture);
virtual void SetSpeed(int iSpeed);
virtual void SetDropState(bool bDrop);
- virtual int GetDataSize(void);
- virtual double GetTimeSize(void);
virtual const char* GetName(void) { return (const char*)m_pFormatName; }
protected:
@@ -98,6 +102,7 @@ protected:
mpeg2_sequence *m_mpeg2_sequence;
double m_mpeg2_sequence_pts;
bool m_drop;
+ bool m_has_keyframe;
CBitstreamParser *m_bitparser;
CBitstreamConverter *m_bitstream;
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
index 6f2d4f98cb..87cdc52dac 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
@@ -97,8 +97,8 @@ bool CDVDInputStreamFile::Open()
return false;
}
- if (m_pFile->GetImplemenation() && (content.empty() || content == "application/octet-stream"))
- m_content = m_pFile->GetImplemenation()->GetContent();
+ if (m_pFile->GetImplementation() && (content.empty() || content == "application/octet-stream"))
+ m_content = m_pFile->GetImplementation()->GetContent();
m_eof = false;
return true;
diff --git a/xbmc/cores/VideoPlayer/DVDMessage.h b/xbmc/cores/VideoPlayer/DVDMessage.h
index 7291399222..729068ef03 100644
--- a/xbmc/cores/VideoPlayer/DVDMessage.h
+++ b/xbmc/cores/VideoPlayer/DVDMessage.h
@@ -87,10 +87,6 @@ public:
VIDEO_SET_ASPECT, // set aspectratio of video
VIDEO_DRAIN, // wait for decoder to output last frame
- // audio related messages
-
- AUDIO_SILENCE,
-
// subtitle related messages
SUBTITLE_CLUTCHANGE,
SUBTITLE_ADDFILE
@@ -221,7 +217,6 @@ public:
int time = 0;
bool relative = false;
bool backward = false;
- bool flush = true;
bool accurate = true;
bool sync = true;
bool restore = true;
@@ -234,7 +229,6 @@ public:
int GetTime() { return m_mode.time; }
bool GetRelative() { return m_mode.relative; }
bool GetBackward() { return m_mode.backward; }
- bool GetFlush() { return m_mode.flush; }
bool GetAccurate() { return m_mode.accurate; }
bool GetRestore() { return m_mode.restore; }
bool GetTrickPlay() { return m_mode.trickplay; }
diff --git a/xbmc/cores/VideoPlayer/Edl.cpp b/xbmc/cores/VideoPlayer/Edl.cpp
index c87fe21a79..9d2edda39d 100644
--- a/xbmc/cores/VideoPlayer/Edl.cpp
+++ b/xbmc/cores/VideoPlayer/Edl.cpp
@@ -46,6 +46,7 @@ void CEdl::Clear()
m_vecCuts.clear();
m_vecSceneMarkers.clear();
m_iTotalCutTime = 0;
+ m_lastQueryTime = 0;
}
bool CEdl::ReadEditDecisionLists(const std::string& strMovie, const float fFrameRate, const int iHeight)
@@ -822,8 +823,10 @@ std::string CEdl::GetInfo() const
return strInfo.empty() ? "-" : strInfo;
}
-bool CEdl::InCut(const int iSeek, Cut *pCut) const
+bool CEdl::InCut(const int iSeek, Cut *pCut)
{
+ m_lastQueryTime = iSeek;
+
for (int i = 0; i < (int)m_vecCuts.size(); i++)
{
if (iSeek < m_vecCuts[i].start) // Early exit if not even up to the cut start time.
@@ -840,6 +843,11 @@ bool CEdl::InCut(const int iSeek, Cut *pCut) const
return false;
}
+int CEdl::GetLastQueryTime() const
+{
+ return m_lastQueryTime;
+}
+
bool CEdl::GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const
{
if (bPlus)
@@ -885,7 +893,7 @@ bool CEdl::GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const
}
}
-bool CEdl::GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker) const
+bool CEdl::GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker)
{
if (!HasSceneMarker())
return false;
diff --git a/xbmc/cores/VideoPlayer/Edl.h b/xbmc/cores/VideoPlayer/Edl.h
index c19b69fa5c..21c99088ea 100644
--- a/xbmc/cores/VideoPlayer/Edl.h
+++ b/xbmc/cores/VideoPlayer/Edl.h
@@ -53,18 +53,19 @@ public:
int RemoveCutTime(int iSeek) const;
int RestoreCutTime(int iClock) const;
- bool InCut(int iSeek, Cut *pCut = NULL) const;
+ bool InCut(int iSeek, Cut *pCut = NULL);
bool GetNearestCut(bool bPlus, const int iSeek, Cut *pCut) const;
+ int GetLastQueryTime() const;
- bool GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker) const;
+ bool GetNextSceneMarker(bool bPlus, const int iClock, int *iSceneMarker);
static std::string MillisecondsToTimeString(const int iMilliseconds);
-protected:
private:
int m_iTotalCutTime; // ms
std::vector<Cut> m_vecCuts;
std::vector<int> m_vecSceneMarkers;
+ int m_lastQueryTime;
bool ReadEdl(const std::string& strMovie, const float fFramesPerSecond);
bool ReadComskip(const std::string& strMovie, const float fFramesPerSecond);
diff --git a/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp b/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp
index dab7a05956..f2fbe81aec 100644
--- a/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp
+++ b/xbmc/cores/VideoPlayer/Process/overrides/rbpi/ProcessInfoPi.cpp
@@ -48,7 +48,7 @@ EINTERLACEMETHOD CProcessInfoPi::GetFallbackDeintMethod()
bool CProcessInfoPi::AllowDTSHDDecode()
{
- if (g_RBP.RasberryPiVersion() == 1)
+ if (g_RBP.RaspberryPiVersion() == 1)
return false;
return true;
}
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
index 5945d06dea..2e1c637486 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
@@ -635,7 +635,6 @@ CVideoPlayer::CVideoPlayer(IPlayerCallback& callback)
m_dvd.Clear();
m_State.Clear();
- m_EdlAutoSkipMarkers.Clear();
m_UpdateApplication = 0;
m_bAbortRequest = false;
@@ -747,7 +746,6 @@ bool CVideoPlayer::CloseFile(bool reopen)
StopThread();
m_Edl.Clear();
- m_EdlAutoSkipMarkers.Clear();
m_HasVideo = false;
m_HasAudio = false;
@@ -1274,7 +1272,6 @@ void CVideoPlayer::Process()
// look for any EDL files
m_Edl.Clear();
- m_EdlAutoSkipMarkers.Clear();
if (m_CurrentVideo.id >= 0 && m_CurrentVideo.hint.fpsrate > 0 && m_CurrentVideo.hint.fpsscale > 0)
{
float fFramesPerSecond = (float)m_CurrentVideo.hint.fpsrate / (float)m_CurrentVideo.hint.fpsscale;
@@ -1288,7 +1285,7 @@ void CVideoPlayer::Process()
*/
CEdl::Cut cut;
int starttime = 0;
- if(m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0)
+ if (m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0)
{
if (m_PlayerOptions.startpercent > 0 && m_pDemuxer)
{
@@ -1301,7 +1298,7 @@ void CVideoPlayer::Process()
}
CLog::Log(LOGDEBUG, "%s - Start position set to last stopped position: %d", __FUNCTION__, starttime);
}
- else if(m_Edl.InCut(0, &cut))
+ else if (m_Edl.InCut(starttime, &cut))
{
if (cut.action == CEdl::CUT)
{
@@ -1318,20 +1315,13 @@ void CVideoPlayer::Process()
std::string strTimeString = StringUtils::SecondsToTimeString(cut.end / 1000, TIME_FORMAT_MM_SS);
CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString);
-
- /*
- * Setup auto skip markers as if the commercial break had been skipped using standard
- * detection.
- */
- m_EdlAutoSkipMarkers.commbreak_start = cut.start;
- m_EdlAutoSkipMarkers.commbreak_end = cut.end;
- m_EdlAutoSkipMarkers.seek_to_start = true;
}
}
- if(starttime > 0)
+
+ if (starttime > 0)
{
double startpts = DVD_NOPTS_VALUE;
- if(m_pDemuxer)
+ if (m_pDemuxer)
{
if (m_pDemuxer->SeekTime(starttime, false, &startpts))
CLog::Log(LOGDEBUG, "%s - starting demuxer from: %d", __FUNCTION__, starttime);
@@ -1339,13 +1329,15 @@ void CVideoPlayer::Process()
CLog::Log(LOGDEBUG, "%s - failed to start demuxing from: %d", __FUNCTION__, starttime);
}
- if(m_pSubtitleDemuxer)
+ if (m_pSubtitleDemuxer)
{
if(m_pSubtitleDemuxer->SeekTime(starttime, false, &startpts))
CLog::Log(LOGDEBUG, "%s - starting subtitle demuxer from: %d", __FUNCTION__, starttime);
else
CLog::Log(LOGDEBUG, "%s - failed to start subtitle demuxing from: %d", __FUNCTION__, starttime);
}
+
+ m_clock.Discontinuity(DVD_MSEC_TO_TIME(starttime));
}
// make sure application know our info
@@ -1372,7 +1364,6 @@ void CVideoPlayer::Process()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.sync = true;
m_messenger.Put(new CDVDMsgPlayerSeek(mode));
@@ -1387,6 +1378,9 @@ void CVideoPlayer::Process()
continue;
}
+ // check if in a cut or commercial break that should be automatically skipped
+ CheckAutoSceneSkip();
+
// handle messages send to this thread, like seek or demuxer reset requests
HandleMessages();
@@ -1627,9 +1621,6 @@ void CVideoPlayer::Process()
// process the packet
ProcessPacket(pStream, pPacket);
- // check if in a cut or commercial break that should be automatically skipped
- CheckAutoSceneSkip();
-
// update the player info for streams
if (m_player_status_timer.IsTimePast())
{
@@ -1727,24 +1718,13 @@ void CVideoPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
/*
* If CheckSceneSkip() returns true then demux point is inside an EDL cut and the packets are dropped.
- * If not inside a hard cut, but the demux point has reached an EDL mute section then trigger the
- * AUDIO_SILENCE state. The AUDIO_SILENCE state is reverted as soon as the demux point is outside
- * of any EDL section while EDL mute is still active.
*/
CEdl::Cut cut;
if (CheckSceneSkip(m_CurrentAudio))
drop = true;
- else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE // Inside EDL mute
- && !m_EdlAutoSkipMarkers.mute) // Mute not already triggered
- {
- m_VideoPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, true));
- m_EdlAutoSkipMarkers.mute = true;
- }
- else if (!m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) // Outside of any EDL
- && m_EdlAutoSkipMarkers.mute) // But the mute hasn't been removed yet
+ else if (m_Edl.InCut(DVD_TIME_TO_MSEC(m_CurrentAudio.dts + m_offset_pts), &cut) && cut.action == CEdl::MUTE)
{
- m_VideoPlayerAudio->SendMessage(new CDVDMsgBool(CDVDMsg::AUDIO_SILENCE, false));
- m_EdlAutoSkipMarkers.mute = false;
+ drop = true;
}
m_VideoPlayerAudio->SendMessage(new CDVDMsgDemuxerPacket(pPacket, drop));
@@ -1951,7 +1931,7 @@ void CVideoPlayer::HandlePlaySpeed()
{
CLog::Log(LOGDEBUG, "Stream stalled, start buffering. Audio: %d - Video: %d",
m_VideoPlayerAudio->GetLevel(),m_VideoPlayerVideo->GetLevel());
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
}
}
else
@@ -1967,11 +1947,10 @@ void CVideoPlayer::HandlePlaySpeed()
m_VideoPlayerAudio->GetLevel() == 0)
{
CLog::Log(LOGDEBUG,"CVideoPlayer::HandlePlaySpeed - audio stream stalled, triggering re-sync");
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = false;
- mode.flush = true;
mode.accurate = true;
mode.sync = true;
m_messenger.Put(new CDVDMsgPlayerSeek(mode));
@@ -2076,6 +2055,7 @@ void CVideoPlayer::HandlePlaySpeed()
m_VideoPlayerAudio->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1);
m_VideoPlayerVideo->SendMessage(new CDVDMsgDouble(CDVDMsg::GENERAL_RESYNC, clock), 1);
SetCaching(CACHESTATE_DONE);
+ UpdatePlayState(0);
m_syncTimer.Set(3000);
}
@@ -2089,7 +2069,7 @@ void CVideoPlayer::HandlePlaySpeed()
m_VideoPlayerVideo->IsStalled())
{
CLog::Log(LOGWARNING, "VideoPlayer::Sync - stream player video does not start, flushing buffers");
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
}
}
}
@@ -2164,7 +2144,6 @@ void CVideoPlayer::HandlePlaySpeed()
CDVDMsgPlayerSeek::CMode mode;
mode.time = iTime;
mode.backward = (GetPlaySpeed() < 0);
- mode.flush = true;
mode.accurate = false;
mode.restore = false;
mode.trickplay = true;
@@ -2347,86 +2326,71 @@ void CVideoPlayer::CheckAutoSceneSkip()
if (!m_Edl.HasCut())
return;
-
// Check that there is an audio and video stream.
- if(m_CurrentAudio.id < 0 ||
- m_CurrentVideo.id < 0)
+ if((m_CurrentAudio.id < 0 || m_CurrentAudio.syncState != IDVDStreamPlayer::SYNC_INSYNC) ||
+ (m_CurrentVideo.id < 0 || m_CurrentVideo.syncState != IDVDStreamPlayer::SYNC_INSYNC))
return;
-
// If there is a startpts defined for either the audio or video stream then VideoPlayer is still
// still decoding frames to get to the previously requested seek point.
-
if (m_CurrentAudio.inited == false ||
m_CurrentVideo.inited == false)
return;
- if (m_CurrentAudio.dts == DVD_NOPTS_VALUE ||
- m_CurrentVideo.dts == DVD_NOPTS_VALUE)
- return;
-
- const int64_t clock = m_omxplayer_mode ? GetTime() : DVD_TIME_TO_MSEC(std::min(m_CurrentAudio.dts, m_CurrentVideo.dts) + m_offset_pts);
+ const int64_t clock = GetTime();
+ int lastPos = m_Edl.GetLastQueryTime();
CEdl::Cut cut;
if (!m_Edl.InCut(clock, &cut))
return;
- if (cut.action == CEdl::CUT &&
- !(cut.end == m_EdlAutoSkipMarkers.cut || cut.start == m_EdlAutoSkipMarkers.cut)) // To prevent looping if same cut again
+ if (cut.action == CEdl::CUT)
{
- CLog::Log(LOGDEBUG, "%s - Clock in EDL cut [%s - %s]: %s. Automatically skipping over.",
- __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(),
- CEdl::MillisecondsToTimeString(cut.end).c_str(), CEdl::MillisecondsToTimeString(clock).c_str());
-
- //Seeking either goes to the start or the end of the cut depending on the play direction.
- int seek = GetPlaySpeed() >= 0 ? cut.end : cut.start;
-
- // Seeking is NOT flushed so any content up to the demux point is retained when playing forwards.
- CDVDMsgPlayerSeek::CMode mode;
- mode.time = seek;
- mode.backward = true;
- mode.flush = false;
- mode.accurate = false;
- mode.restore = true;
- mode.trickplay = false;
- mode.sync = true;
- m_messenger.Put(new CDVDMsgPlayerSeek(mode));
-
- // Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping
- // if there was an error with seeking and it landed somewhere unexpected, perhaps back in the
- // cut. The cut automatic skip marker is reset every 500ms allowing another attempt at the seek.
- m_EdlAutoSkipMarkers.cut = GetPlaySpeed() >= 0 ? cut.end : cut.start;
- }
- else if (cut.action == CEdl::COMM_BREAK && GetPlaySpeed() >= 0 &&
- cut.start > m_EdlAutoSkipMarkers.commbreak_end)
- {
- std::string strTimeString = StringUtils::SecondsToTimeString((cut.end - cut.start) / 1000, TIME_FORMAT_MM_SS);
- CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString);
-
- if (m_SkipCommercials)
+ if ((GetPlaySpeed() > 0 && clock < cut.end - 1000) ||
+ (GetPlaySpeed() < 0 && clock < cut.start + 1000))
{
- CLog::Log(LOGDEBUG, "%s - Clock in commercial break [%s - %s]: %s. Automatically skipping to end of commercial break (only done once per break)",
- __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(), CEdl::MillisecondsToTimeString(cut.end).c_str(),
- CEdl::MillisecondsToTimeString(clock).c_str());
+ CLog::Log(LOGDEBUG, "%s - Clock in EDL cut [%s - %s]: %s. Automatically skipping over.",
+ __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(),
+ CEdl::MillisecondsToTimeString(cut.end).c_str(), CEdl::MillisecondsToTimeString(clock).c_str());
+
+ //Seeking either goes to the start or the end of the cut depending on the play direction.
+ int seek = GetPlaySpeed() >= 0 ? cut.end : cut.start;
- // Seeking is NOT flushed so any content up to the demux point is retained when playing forwards.
CDVDMsgPlayerSeek::CMode mode;
- mode.time = cut.end + 1;
+ mode.time = seek;
mode.backward = true;
- mode.flush = false;
- mode.accurate = false;
+ mode.accurate = true;
mode.restore = true;
mode.trickplay = false;
mode.sync = true;
m_messenger.Put(new CDVDMsgPlayerSeek(mode));
}
+ }
+ else if (cut.action == CEdl::COMM_BREAK)
+ {
+ // marker for commbrak may be inaccurate. allow user to skip into break from the back
+ if (GetPlaySpeed() >= 0 && lastPos <= cut.start && clock < cut.end - 1000)
+ {
+ std::string strTimeString = StringUtils::SecondsToTimeString((cut.end - cut.start) / 1000, TIME_FORMAT_MM_SS);
+ CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString);
+
+ if (m_SkipCommercials)
+ {
+ CLog::Log(LOGDEBUG, "%s - Clock in commercial break [%s - %s]: %s. Automatically skipping to end of commercial break",
+ __FUNCTION__, CEdl::MillisecondsToTimeString(cut.start).c_str(),
+ CEdl::MillisecondsToTimeString(cut.end).c_str(),
+ CEdl::MillisecondsToTimeString(clock).c_str());
- // Each commercial break is only skipped once so poorly detected commercial breaks can be
- // manually re-entered. Start and end are recorded to prevent looping and to allow seeking back
- // to the start of the commercial break if incorrectly flagged.
- m_EdlAutoSkipMarkers.commbreak_start = cut.start;
- m_EdlAutoSkipMarkers.commbreak_end = cut.end;
- m_EdlAutoSkipMarkers.seek_to_start = true; // Allow backwards Seek() to go directly to the start
+ CDVDMsgPlayerSeek::CMode mode;
+ mode.time = cut.end;
+ mode.backward = true;
+ mode.accurate = true;
+ mode.restore = false;
+ mode.trickplay = false;
+ mode.sync = true;
+ m_messenger.Put(new CDVDMsgPlayerSeek(mode));
+ }
+ }
}
}
@@ -2559,8 +2523,7 @@ void CVideoPlayer::HandleMessages()
if (!msg.GetTrickPlay())
{
g_infoManager.SetDisplayAfterSeek(100000);
- if(msg.GetFlush())
- SetCaching(CACHESTATE_FLUSH);
+ SetCaching(CACHESTATE_FLUSH);
}
double start = DVD_NOPTS_VALUE;
@@ -2596,7 +2559,7 @@ void CVideoPlayer::HandleMessages()
m_State.dts = start;
m_State.lastSeek = m_clock.GetAbsoluteClock();
- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync());
+ FlushBuffers(start, msg.GetAccurate(), msg.GetSync());
}
else if (m_pDemuxer)
{
@@ -2607,7 +2570,7 @@ void CVideoPlayer::HandleMessages()
m_State.dts = start;
- FlushBuffers(false, start, false, true);
+ FlushBuffers(start, false, true);
if (m_playSpeed != DVD_PLAYSPEED_PAUSE)
{
SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
@@ -2639,7 +2602,7 @@ void CVideoPlayer::HandleMessages()
// This should always be the case.
if(m_pDemuxer && m_pDemuxer->SeekChapter(msg.GetChapter(), &start))
{
- FlushBuffers(false, start, true);
+ FlushBuffers(start, true, true);
offset = DVD_TIME_TO_MSEC(start) - beforeSeek;
m_callback.OnPlayBackSeekChapter(msg.GetChapter());
}
@@ -2675,7 +2638,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.trickplay = true;
mode.sync = true;
@@ -2691,7 +2653,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.trickplay = true;
mode.sync = true;
@@ -2716,7 +2677,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.trickplay = true;
mode.sync = true;
@@ -2730,7 +2690,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.trickplay = true;
mode.sync = true;
@@ -2793,7 +2752,7 @@ void CVideoPlayer::HandleMessages()
}
else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH))
{
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
}
else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
{
@@ -2839,7 +2798,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = iTime;
mode.backward = m_playSpeed < 0;
- mode.flush = true;
mode.accurate = false;
mode.trickplay = true;
mode.sync = true;
@@ -2858,7 +2816,6 @@ void CVideoPlayer::HandleMessages()
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)GetTime();
mode.backward = (speed < 0);
- mode.flush = true;
mode.accurate = true;
mode.restore = false;
mode.trickplay = true;
@@ -2887,7 +2844,7 @@ void CVideoPlayer::HandleMessages()
else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) &&
m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT_NUMBER) == 0)
{
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
CDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);
//! @todo find a better solution for the "otherStreamHack"
//! a stream is not supposed to be terminated before demuxer
@@ -2914,7 +2871,7 @@ void CVideoPlayer::HandleMessages()
else if (pMsg->IsType(CDVDMsg::PLAYER_CHANNEL_SELECT) &&
m_messenger.GetPacketCount(CDVDMsg::PLAYER_CHANNEL_SELECT) == 0)
{
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
CDVDInputStreamPVRManager* input = dynamic_cast<CDVDInputStreamPVRManager*>(m_pInputStream);
if (input && input->IsOtherStreamHack())
{
@@ -2947,7 +2904,7 @@ void CVideoPlayer::HandleMessages()
if (!bShowPreview)
{
g_infoManager.SetDisplayAfterSeek(100000);
- FlushBuffers(false);
+ FlushBuffers(DVD_NOPTS_VALUE, true, true);
if (input->IsOtherStreamHack())
{
CloseDemuxer();
@@ -3185,52 +3142,6 @@ void CVideoPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
}
bool restore = true;
- if (m_Edl.HasCut())
- {
- /*
- * Alter the standard seek position based on whether any commercial breaks have been
- * automatically skipped.
- */
- const int clock = DVD_TIME_TO_MSEC(m_clock.GetClock());
- /*
- * If a large backwards seek occurs within 10 seconds of the end of the last automated
- * commercial skip, then seek back to the start of the commercial break under the assumption
- * it was flagged incorrectly. 10 seconds grace period is allowed in case the watcher has to
- * fumble around finding the remote. Only happens once per commercial break.
- *
- * Small skip does not trigger this in case the start of the commercial break was in fact fine
- * but it skipped too far into the program. In that case small skip backwards behaves as normal.
- */
- if (!bPlus && bLargeStep &&
- m_EdlAutoSkipMarkers.seek_to_start &&
- clock >= m_EdlAutoSkipMarkers.commbreak_end &&
- clock <= m_EdlAutoSkipMarkers.commbreak_end + 10*1000) // Only if within 10 seconds of the end (in msec)
- {
- CLog::Log(LOGDEBUG, "%s - Seeking back to start of commercial break [%s - %s] as large backwards skip activated within 10 seconds of the automatic commercial skip (only done once per break).",
- __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(),
- CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str());
- seekTarget = m_EdlAutoSkipMarkers.commbreak_start;
- restore = false;
- m_EdlAutoSkipMarkers.seek_to_start = false; // So this will only happen within the 10 second grace period once.
- }
- /*
- * If big skip forward within the last "reverted" commercial break, seek to the end of the
- * commercial break under the assumption that the break was incorrectly flagged and playback has
- * now reached the actual start of the commercial break. Assume that the end is flagged more
- * correctly than the landing point for a standard big skip (ends seem to be flagged more
- * accurately than the start).
- */
- else if (bPlus && bLargeStep &&
- clock >= m_EdlAutoSkipMarkers.commbreak_start &&
- clock <= m_EdlAutoSkipMarkers.commbreak_end)
- {
- CLog::Log(LOGDEBUG, "%s - Seeking to end of previously skipped commercial break [%s - %s] as big forwards skip activated within the break.",
- __FUNCTION__, CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_start).c_str(),
- CEdl::MillisecondsToTimeString(m_EdlAutoSkipMarkers.commbreak_end).c_str());
- seekTarget = m_EdlAutoSkipMarkers.commbreak_end;
- restore = false;
- }
- }
int64_t time = GetTime();
if(g_application.CurrentFileItem().IsStack() &&
@@ -3245,7 +3156,6 @@ void CVideoPlayer::Seek(bool bPlus, bool bLargeStep, bool bChapterOverride)
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)seekTarget;
mode.backward = !bPlus;
- mode.flush = true;
mode.accurate = false;
mode.restore = restore;
mode.trickplay = false;
@@ -3280,7 +3190,6 @@ bool CVideoPlayer::SeekScene(bool bPlus)
CDVDMsgPlayerSeek::CMode mode;
mode.time = iScenemarker;
mode.backward = !bPlus;
- mode.flush = true;
mode.accurate = false;
mode.restore = false;
mode.trickplay = false;
@@ -3577,7 +3486,6 @@ void CVideoPlayer::SeekTime(int64_t iTime)
CDVDMsgPlayerSeek::CMode mode;
mode.time = (int)iTime;
mode.backward = true;
- mode.flush = true;
mode.accurate = true;
mode.trickplay = false;
mode.sync = true;
@@ -3595,7 +3503,6 @@ bool CVideoPlayer::SeekTimeRelative(int64_t iTime)
mode.time = (int)iTime;
mode.relative = true;
mode.backward = (iTime < 0) ? true : false;
- mode.flush = true;
mode.accurate = false;
mode.trickplay = false;
mode.sync = true;
@@ -4027,7 +3934,7 @@ bool CVideoPlayer::CloseStream(CCurrentStream& current, bool bWaitForBuffers)
return true;
}
-void CVideoPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync)
+void CVideoPlayer::FlushBuffers(double pts, bool accurate, bool sync)
{
CLog::Log(LOGDEBUG, "CVideoPlayer::FlushBuffers - flushing buffers");
@@ -4068,63 +3975,45 @@ void CVideoPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool syn
m_CurrentRadioRDS.startpts = startpts;
m_CurrentRadioRDS.packets = 0;
- if (queued)
- {
- m_VideoPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_VideoPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_VideoPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_VideoPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
- m_VideoPlayerRadioRDS->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_RESET));
+ m_VideoPlayerAudio->Flush(sync);
+ m_VideoPlayerVideo->Flush(sync);
+ m_VideoPlayerSubtitle->Flush();
+ m_VideoPlayerTeletext->Flush();
+ m_VideoPlayerRadioRDS->Flush();
+
+ // clear subtitle and menu overlays
+ m_overlayContainer.Clear();
- CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(10*1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO);
+ if(m_playSpeed == DVD_PLAYSPEED_NORMAL ||
+ m_playSpeed == DVD_PLAYSPEED_PAUSE)
+ {
+ // make sure players are properly flushed, should put them in stalled state
+ CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO);
m_VideoPlayerAudio->SendMessage(msg->Acquire(), 1);
m_VideoPlayerVideo->SendMessage(msg->Acquire(), 1);
msg->Wait(m_bStop, 0);
msg->Release();
- }
- else
- {
- m_VideoPlayerAudio->Flush(sync);
- m_VideoPlayerVideo->Flush(sync);
- m_VideoPlayerSubtitle->Flush();
- m_VideoPlayerTeletext->Flush();
- m_VideoPlayerRadioRDS->Flush();
- // clear subtitle and menu overlays
- m_overlayContainer.Clear();
+ // purge any pending PLAYER_STARTED messages
+ m_messenger.Flush(CDVDMsg::PLAYER_STARTED);
- if(m_playSpeed == DVD_PLAYSPEED_NORMAL
- || m_playSpeed == DVD_PLAYSPEED_PAUSE)
+ // we should now wait for init cache
+ SetCaching(CACHESTATE_FLUSH);
+ if (sync)
{
- // make sure players are properly flushed, should put them in stalled state
- CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO);
- m_VideoPlayerAudio->SendMessage(msg->Acquire(), 1);
- m_VideoPlayerVideo->SendMessage(msg->Acquire(), 1);
- msg->Wait(m_bStop, 0);
- msg->Release();
-
- // purge any pending PLAYER_STARTED messages
- m_messenger.Flush(CDVDMsg::PLAYER_STARTED);
-
- // we should now wait for init cache
- SetCaching(CACHESTATE_FLUSH);
- if (sync)
- {
- m_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING;
- m_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING;
- }
+ m_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_STARTING;
+ m_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_STARTING;
}
-
- if(pts != DVD_NOPTS_VALUE && sync)
- m_clock.Discontinuity(pts);
- UpdatePlayState(0);
}
+ if(pts != DVD_NOPTS_VALUE && sync)
+ m_clock.Discontinuity(pts);
+ UpdatePlayState(0);
+
if (m_omxplayer_mode)
{
m_OmxPlayerState.av_clock.OMXFlush();
- if (!queued)
- m_OmxPlayerState.av_clock.OMXStop();
+ m_OmxPlayerState.av_clock.OMXStop();
m_OmxPlayerState.av_clock.OMXPause();
m_OmxPlayerState.av_clock.OMXMediaTime(0.0);
}
@@ -4315,7 +4204,7 @@ int CVideoPlayer::OnDVDNavResult(void* pData, int iMessage)
else
{
bool sync = !IsInMenuInternal();
- FlushBuffers(false, DVD_NOPTS_VALUE, false, sync);
+ FlushBuffers(DVD_NOPTS_VALUE, false, sync);
m_dvd.syncClock = true;
m_dvd.state = DVDSTATE_NORMAL;
if (m_pDemuxer)
@@ -4572,7 +4461,6 @@ bool CVideoPlayer::OnAction(const CAction &action)
CDVDMsgPlayerSeek::CMode mode;
mode.time = cut.end + 1;
mode.backward = false;
- mode.flush = true;
mode.accurate = false;
mode.restore = true;
mode.trickplay = false;
@@ -4612,7 +4500,6 @@ bool CVideoPlayer::OnAction(const CAction &action)
CDVDMsgPlayerSeek::CMode mode;
mode.time = cut.start - 1;
mode.backward = true;
- mode.flush = true;
mode.accurate = false;
mode.restore = true;
mode.trickplay = false;
@@ -4627,7 +4514,6 @@ bool CVideoPlayer::OnAction(const CAction &action)
CDVDMsgPlayerSeek::CMode mode;
mode.time = 0;
mode.backward = true;
- mode.flush = true;
mode.accurate = false;
mode.restore = true;
mode.trickplay = false;
@@ -5203,9 +5089,6 @@ bool CVideoPlayer::SwitchChannel(const CPVRChannelPtr &channel)
if (g_PVRManager.IsPlayingChannel(channel))
return false; // desired channel already active, nothing to do.
- if (!g_PVRManager.CheckParentalLock(channel))
- return false;
-
/* set GUI info */
if (!g_PVRManager.PerformChannelSwitch(channel, true))
return false;
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h
index 1cc1abbf5a..a19f3d1d7f 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.h
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.h
@@ -463,8 +463,7 @@ protected:
double GetQueueTime();
bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
-
- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true);
+ void FlushBuffers(double pts, bool accurate, bool sync);
void HandleMessages();
void HandlePlaySpeed();
@@ -586,25 +585,6 @@ protected:
CEdl m_Edl;
bool m_SkipCommercials;
- struct SEdlAutoSkipMarkers {
-
- void Clear()
- {
- cut = -1;
- commbreak_start = -1;
- commbreak_end = -1;
- seek_to_start = false;
- mute = false;
- }
-
- int cut; // last automatically skipped EDL cut seek position
- int commbreak_start; // start time of the last commercial break automatically skipped
- int commbreak_end; // end time of the last commercial break automatically skipped
- bool seek_to_start; // whether seeking can go back to the start of a previously skipped break
- bool mute; // whether EDL mute is on
-
- } m_EdlAutoSkipMarkers;
-
CPlayerOptions m_PlayerOptions;
bool m_HasVideo;
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
index a40c6191e5..9a5164eae9 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
@@ -70,7 +70,6 @@ CVideoPlayerAudio::CVideoPlayerAudio(CDVDClock* pClock, CDVDMessageQueue& parent
m_stalled = true;
m_paused = false;
m_syncState = IDVDStreamPlayer::SYNC_STARTING;
- m_silence = false;
m_synctype = SYNC_DISCON;
m_setsynctype = SYNC_DISCON;
m_prevsynctype = -1;
@@ -151,7 +150,6 @@ void CVideoPlayerAudio::OpenStream(CDVDStreamInfo &hints, CDVDAudioCodec* codec)
m_prevsynctype = -1;
m_prevskipped = false;
- m_silence = false;
m_maxspeedadjust = 5.0;
@@ -346,12 +344,6 @@ void CVideoPlayerAudio::Process()
}
m_speed = speed;
}
- else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE))
- {
- m_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value;
- CLog::Log(LOGDEBUG, "CVideoPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, %d)"
- , m_audioClock, m_silence);
- }
else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
{
CDVDMsgAudioCodecChange* msg(static_cast<CDVDMsgAudioCodecChange*>(pMsg));
@@ -458,14 +450,6 @@ void CVideoPlayerAudio::Process()
m_messageParent.Put(new CDVDMsg(CDVDMsg::PLAYER_AVCHANGE));
}
- // Zero out the frame data if we are supposed to silence the audio
- if (m_silence)
- {
- int size = audioframe.nb_frames * audioframe.framesize / audioframe.planes;
- for (unsigned int i=0; i<audioframe.planes; i++)
- memset(audioframe.data[i], 0, size);
- }
-
SetSyncType(audioframe.passthrough);
if (!bPacketDrop)
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerAudio.h b/xbmc/cores/VideoPlayer/VideoPlayerAudio.h
index ca1da99a23..3345fcf49e 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerAudio.h
+++ b/xbmc/cores/VideoPlayer/VideoPlayerAudio.h
@@ -95,7 +95,6 @@ protected:
int m_speed;
bool m_stalled;
- bool m_silence;
bool m_paused;
IDVDStreamPlayer::ESyncState m_syncState;
XbmcThreads::EndTime m_syncTimer;
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/cores/VideoPlayer/VideoReferenceClock.cpp
index 83bed67a32..0dd7ea9b87 100644
--- a/xbmc/video/VideoReferenceClock.cpp
+++ b/xbmc/cores/VideoPlayer/VideoReferenceClock.cpp
@@ -24,36 +24,9 @@
#include "utils/TimeUtils.h"
#include "threads/SingleLock.h"
#include "guilib/GraphicContext.h"
-#include "video/videosync/VideoSync.h"
#include "settings/Settings.h"
-
-#if defined(HAS_GLX)
-#include "video/videosync/VideoSyncGLX.h"
-#endif
-#if defined(HAVE_X11)
-#include "video/videosync/VideoSyncDRM.h"
+#include "windowing/VideoSync.h"
#include "windowing/WindowingFactory.h"
-#elif defined(TARGET_RASPBERRY_PI)
-#include "video/videosync/VideoSyncPi.h"
-#elif defined(HAS_IMXVPU)
-#include "video/videosync/VideoSyncIMX.h"
-#endif
-#if defined(TARGET_WINDOWS)
-#include "video/videosync/VideoSyncD3D.h"
-#endif
-#if defined(TARGET_DARWIN_OSX)
-#include "video/videosync/VideoSyncOsx.h"
-#endif
-#if defined(TARGET_DARWIN_IOS)
-#include "video/videosync/VideoSyncIos.h"
-#endif
-#if defined(TARGET_ANDROID)
-#include "video/videosync/VideoSyncAndroid.h"
-#endif
-
-#ifdef TARGET_POSIX
-#include "linux/XTimeUtils.h"
-#endif
CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock")
{
@@ -70,8 +43,6 @@ CVideoReferenceClock::CVideoReferenceClock() : CThread("RefClock")
m_MissedVblanks = 0;
m_VblankTime = 0;
- m_pVideoSync = nullptr;
-
Start();
}
@@ -87,12 +58,13 @@ void CVideoReferenceClock::Start()
Create();
}
-void CVideoReferenceClock::CBUpdateClock(int NrVBlanks, uint64_t time, CVideoReferenceClock *clock)
+void CVideoReferenceClock::CBUpdateClock(int NrVBlanks, uint64_t time, void *clock)
{
{
- CSingleLock lock(clock->m_CritSection);
- clock->m_VblankTime = time;
- clock->UpdateClock(NrVBlanks, true);
+ CVideoReferenceClock *refClock = static_cast<CVideoReferenceClock*>(clock);
+ CSingleLock lock(refClock->m_CritSection);
+ refClock->m_VblankTime = time;
+ refClock->UpdateClock(NrVBlanks, true);
}
}
@@ -103,30 +75,7 @@ void CVideoReferenceClock::Process()
while(!m_bStop)
{
- //set up the vblank clock
-#if defined(HAVE_X11)
- std::string gpuvendor = g_Windowing.GetRenderVendor();
- std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower);
- if ((gpuvendor.compare(0, 5, "intel") == 0 ||
- gpuvendor.compare(0, 5, "x.org") == 0)) // AMD
- m_pVideoSync = new CVideoSyncDRM(this);
-#if defined(HAS_GLX)
- else
- m_pVideoSync = new CVideoSyncGLX(this);
-#endif
-#elif defined(TARGET_WINDOWS)
- m_pVideoSync = new CVideoSyncD3D(this);
-#elif defined(TARGET_DARWIN_OSX)
- m_pVideoSync = new CVideoSyncOsx(this);
-#elif defined(TARGET_DARWIN_IOS)
- m_pVideoSync = new CVideoSyncIos(this);
-#elif defined(TARGET_RASPBERRY_PI)
- m_pVideoSync = new CVideoSyncPi(this);
-#elif defined(HAS_IMXVPU)
- m_pVideoSync = new CVideoSyncIMX(this);
-#elif defined(TARGET_ANDROID)
- m_pVideoSync = new CVideoSyncAndroid(this);
-#endif
+ m_pVideoSync = g_Windowing.GetVideoSync(this);
if (m_pVideoSync)
{
@@ -168,8 +117,7 @@ void CVideoReferenceClock::Process()
if (m_pVideoSync)
{
m_pVideoSync->Cleanup();
- delete m_pVideoSync;
- m_pVideoSync = nullptr;
+ m_pVideoSync.reset();
}
if (!SetupSuccess)
diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/cores/VideoPlayer/VideoReferenceClock.h
index 659e4269a2..00f58bf7ec 100644
--- a/xbmc/video/VideoReferenceClock.h
+++ b/xbmc/cores/VideoPlayer/VideoReferenceClock.h
@@ -21,6 +21,7 @@
#include "threads/Thread.h"
#include "threads/CriticalSection.h"
+#include <memory>
class CVideoSync;
@@ -43,7 +44,7 @@ class CVideoReferenceClock : public CThread
void UpdateClock(int NrVBlanks, bool CheckMissed);
double UpdateInterval() const;
int64_t TimeOfNextVblank() const;
- static void CBUpdateClock(int NrVBlanks, uint64_t time, CVideoReferenceClock *clock);
+ static void CBUpdateClock(int NrVBlanks, uint64_t time, void *clock);
int64_t m_CurrTime; //the current time of the clock when using vblank as clock source
int64_t m_LastIntTime; //last interpolated clock value, to make sure the clock doesn't go backwards
@@ -60,5 +61,5 @@ class CVideoReferenceClock : public CThread
CCriticalSection m_CritSection;
- CVideoSync *m_pVideoSync;
+ std::unique_ptr<CVideoSync> m_pVideoSync;
};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
index d8674c8578..292f07b9b6 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.cpp
@@ -21,26 +21,58 @@
#include "RendererAML.h"
#if defined(HAS_LIBAMCODEC)
-#include "cores/IPlayer.h"
-#include "windowing/egl/EGLWrapper.h"
#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAmlogic.h"
#include "cores/VideoPlayer/DVDCodecs/Video/AMLCodec.h"
#include "utils/log.h"
-#include "utils/GLUtils.h"
#include "utils/SysfsUtils.h"
#include "settings/MediaSettings.h"
#include "windowing/WindowingFactory.h"
#include "cores/VideoPlayer/VideoRenderers/RenderCapture.h"
+#include "settings/AdvancedSettings.h"
CRendererAML::CRendererAML()
+ : m_prevVPts(-1)
+ , m_bConfigured(false)
+ , m_iRenderBuffer(0)
{
- m_prevPts = -1;
}
CRendererAML::~CRendererAML()
{
}
+bool CRendererAML::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation)
+{
+ m_sourceWidth = width;
+ m_sourceHeight = height;
+ m_renderOrientation = orientation;
+
+ // Save the flags.
+ m_iFlags = flags;
+ m_format = format;
+
+ // Calculate the input frame aspect ratio.
+ CalculateFrameAspectRatio(d_width, d_height);
+ SetViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode);
+ ManageRenderArea();
+
+ m_bConfigured = true;
+
+ for (int i = 0 ; i < m_numRenderBuffers ; ++i)
+ m_buffers[i].hwDec = 0;
+
+ return true;
+}
+
+CRenderInfo CRendererAML::GetRenderInfo()
+{
+ CRenderInfo info;
+ info.formats.push_back(RENDER_FMT_BYPASS);
+ info.max_buffer_size = m_numRenderBuffers;
+ info.optimal_buffer_size = m_numRenderBuffers;
+ return info;
+}
+
bool CRendererAML::RenderCapture(CRenderCapture* capture)
{
capture->BeginRender();
@@ -48,27 +80,50 @@ bool CRendererAML::RenderCapture(CRenderCapture* capture)
return true;
}
+int CRendererAML::GetImage(YV12Image *image, int source, bool readonly)
+{
+ if (image == nullptr)
+ return -1;
+
+ /* take next available buffer */
+ if (source == -1)
+ source = (m_iRenderBuffer + 1) % m_numRenderBuffers;
+
+ return source;
+}
+
void CRendererAML::AddVideoPictureHW(DVDVideoPicture &picture, int index)
{
- YUVBUFFER &buf = m_buffers[index];
+ BUFFER &buf = m_buffers[index];
if (picture.amlcodec)
buf.hwDec = picture.amlcodec->Retain();
}
void CRendererAML::ReleaseBuffer(int idx)
{
- YUVBUFFER &buf = m_buffers[idx];
+ BUFFER &buf = m_buffers[idx];
if (buf.hwDec)
{
CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(buf.hwDec);
- SAFE_RELEASE(amli);
+ if (amli)
+ {
+ CAMLCodec *amlcodec;
+ if (!amli->IsRendered() && (amlcodec = amli->getAmlCodec()))
+ amlcodec->ReleaseFrame(amli->GetBufferIndex(), true);
+ SAFE_RELEASE(amli);
+ }
buf.hwDec = NULL;
}
}
-int CRendererAML::GetImageHook(YV12Image *image, int source, bool readonly)
+void CRendererAML::FlipPage(int source)
{
- return source;
+ if( source >= 0 && source < m_numRenderBuffers )
+ m_iRenderBuffer = source;
+ else
+ m_iRenderBuffer = (m_iRenderBuffer + 1) % m_numRenderBuffers;
+
+ return;
}
bool CRendererAML::IsGuiLayer()
@@ -104,37 +159,30 @@ EINTERLACEMETHOD CRendererAML::AutoInterlaceMethod()
return VS_INTERLACEMETHOD_NONE;
}
-bool CRendererAML::LoadShadersHook()
+void CRendererAML::Reset()
{
- CLog::Log(LOGNOTICE, "GL: Using AML render method");
- m_textureTarget = GL_TEXTURE_2D;
- m_renderMethod = RENDER_BYPASS;
- return false;
+ m_prevVPts = -1;
}
-bool CRendererAML::RenderHook(int index)
-{
- return true;// nothing to be done for aml
-}
-
-bool CRendererAML::RenderUpdateVideoHook(bool clear, DWORD flags, DWORD alpha)
+void CRendererAML::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
{
ManageRenderArea();
- CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iYV12RenderBuffer].hwDec);
- if (amli && amli->GetOmxPts() != m_prevPts)
- {
- m_prevPts = amli->GetOmxPts();
- SysfsUtils::SetInt("/sys/module/amvideo/parameters/omx_pts", amli->GetOmxPts());
+ CDVDAmlogicInfo *amli = static_cast<CDVDAmlogicInfo *>(m_buffers[m_iRenderBuffer].hwDec);
+ CAMLCodec *amlcodec = amli ? amli->getAmlCodec() : 0;
- CAMLCodec *amlcodec = amli->getAmlCodec();
- if (amlcodec)
+ if(amlcodec)
+ {
+ int pts = amli->GetOmxPts();
+ if (pts != m_prevVPts)
+ {
+ amlcodec->ReleaseFrame(amli->GetBufferIndex());
amlcodec->SetVideoRect(m_sourceRect, m_destRect);
+ amli->SetRendered();
+ m_prevVPts = pts;
+ }
}
-
- usleep(10000);
-
- return true;
+ CAMLCodec::PollFrame();
}
#endif
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
index 828f584a94..cd68401953 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererAML.h
@@ -24,17 +24,29 @@
#if defined(HAS_LIBAMCODEC)
-#include "cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h"
+#include "cores/VideoPlayer/VideoRenderers/BaseRenderer.h"
-class CRendererAML : public CLinuxRendererGLES
+class CRendererAML : public CBaseRenderer
{
public:
CRendererAML();
virtual ~CRendererAML();
-
+
virtual bool RenderCapture(CRenderCapture* capture);
virtual void AddVideoPictureHW(DVDVideoPicture &picture, int index);
virtual void ReleaseBuffer(int idx);
+ virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation);
+ virtual bool IsConfigured(){ return m_bConfigured; };
+ virtual CRenderInfo GetRenderInfo();
+ virtual int GetImage(YV12Image *image, int source = -1, bool readonly = false);
+ virtual void ReleaseImage(int source, bool preserve = false){};
+ virtual void FlipPage(int source);
+ virtual void PreInit(){};
+ virtual void UnInit(){};
+ virtual void Reset();
+ virtual void Update(){};
+ virtual void RenderUpdate(bool clear, unsigned int flags = 0, unsigned int alpha = 255);
+ virtual bool SupportsMultiPassRendering(){ return false; };
// Player functions
virtual bool IsGuiLayer();
@@ -47,16 +59,19 @@ public:
virtual EINTERLACEMETHOD AutoInterlaceMethod();
-protected:
+private:
+
+ int m_iRenderBuffer;
+ static const int m_numRenderBuffers = 4;
- // hooks for hw dec renderer
- virtual bool LoadShadersHook();
- virtual bool RenderHook(int index);
- virtual int GetImageHook(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
- virtual bool RenderUpdateVideoHook(bool clear, DWORD flags = 0, DWORD alpha = 255);
+ struct BUFFER
+ {
+ void *hwDec;
+ int duration;
+ } m_buffers[m_numRenderBuffers];
-private:
- int m_prevPts;
+ int m_prevVPts;
+ bool m_bConfigured;
};
#endif
diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp
index 920ac4ab75..e399556582 100644
--- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp
+++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp
@@ -65,7 +65,7 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints)
{
AVCodec* pCodec = NULL;
- if (hints.codec == AV_CODEC_ID_DTS && g_RBP.RasberryPiVersion() > 1)
+ if (hints.codec == AV_CODEC_ID_DTS && g_RBP.RaspberryPiVersion() > 1)
pCodec = avcodec_find_decoder_by_name("dcadec");
if (!pCodec)
diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
index 968724e81d..890d91c5cf 100644
--- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -85,7 +85,6 @@ OMXPlayerAudio::OMXPlayerAudio(OMXClock *av_clock, CDVDMessageQueue& parent, CPr
m_messageQueue.SetMaxTimeSize(8.0);
m_passthrough = false;
- m_silence = false;
m_flush = false;
}
@@ -134,7 +133,6 @@ void OMXPlayerAudio::OpenStream(CDVDStreamInfo &hints, COMXAudioCodecOMX *codec)
m_speed = DVD_PLAYSPEED_NORMAL;
m_audioClock = DVD_NOPTS_VALUE;
- m_silence = false;
m_syncState = IDVDStreamPlayer::SYNC_STARTING;
m_flush = false;
m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;
@@ -277,12 +275,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay)
if(!bDropPacket)
{
- // Zero out the frame data if we are supposed to silence the audio
- if(m_silence)
- memset(decoded, 0x0, decoded_size);
-
ret = m_omxAudio.AddPackets(decoded, decoded_size, dts, pts, m_pAudioCodec->GetFrameSize(), settings_changed);
-
if(ret != decoded_size)
{
CLog::Log(LOGERROR, "error ret %d decoded_size %d\n", ret, decoded_size);
@@ -316,9 +309,6 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay)
if(!bDropPacket)
{
- if(m_silence)
- memset(pkt->pData, 0x0, pkt->iSize);
-
m_omxAudio.AddPackets(pkt->pData, pkt->iSize, m_audioClock, m_audioClock, 0, settings_changed);
}
@@ -456,14 +446,6 @@ void OMXPlayerAudio::Process()
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_SETSPEED %d", m_speed);
}
}
- else if (pMsg->IsType(CDVDMsg::AUDIO_SILENCE))
- {
- m_silence = static_cast<CDVDMsgBool*>(pMsg)->m_value;
- if (m_silence)
- CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 1)", m_audioClock);
- else
- CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::AUDIO_SILENCE(%f, 0)", m_audioClock);
- }
else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
{
COMXMsgAudioCodecChange* msg(static_cast<COMXMsgAudioCodecChange*>(pMsg));
diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp
index bd7974aeba..383ddb1606 100644
--- a/xbmc/dbwrappers/Database.cpp
+++ b/xbmc/dbwrappers/Database.cpp
@@ -574,7 +574,7 @@ bool CDatabase::Compress(bool bForce /* =true */)
return true;
}
-void CDatabase::Interupt()
+void CDatabase::Interrupt()
{
m_pDS->interrupt();
}
diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h
index 593a8eac47..cf4a795b31 100644
--- a/xbmc/dbwrappers/Database.h
+++ b/xbmc/dbwrappers/Database.h
@@ -78,7 +78,7 @@ public:
bool IsOpen();
void Close();
bool Compress(bool bForce=true);
- void Interupt();
+ void Interrupt();
bool Open(const DatabaseSettings &db);
diff --git a/xbmc/dbwrappers/DatabaseQuery.cpp b/xbmc/dbwrappers/DatabaseQuery.cpp
index b6c96fee65..1f6c8ad8ef 100644
--- a/xbmc/dbwrappers/DatabaseQuery.cpp
+++ b/xbmc/dbwrappers/DatabaseQuery.cpp
@@ -128,8 +128,7 @@ bool CDatabaseQueryRule::Load(const TiXmlNode *node, const std::string &encoding
bool CDatabaseQueryRule::Load(const CVariant &obj)
{
- if (!obj.isObject() ||
- !obj.isMember("field") || !obj["field"].isString() ||
+ if (!obj.isMember("field") || !obj["field"].isString() ||
!obj.isMember("operator") || !obj["operator"].isString())
return false;
diff --git a/xbmc/dialogs/GUIDialogFileBrowser.cpp b/xbmc/dialogs/GUIDialogFileBrowser.cpp
index f6e002e016..f373d08ca1 100644
--- a/xbmc/dialogs/GUIDialogFileBrowser.cpp
+++ b/xbmc/dialogs/GUIDialogFileBrowser.cpp
@@ -653,12 +653,12 @@ bool CGUIDialogFileBrowser::ShowAndGetImage(const CFileItemList &items, const VE
bool CGUIDialogFileBrowser::ShowAndGetImage(const VECSOURCES &shares, const std::string &heading, std::string &path)
{
- return ShowAndGetFile(shares, g_advancedSettings.m_pictureExtensions, heading, path, true); // true for use thumbs
+ return ShowAndGetFile(shares, g_advancedSettings.GetPictureExtensions(), heading, path, true); // true for use thumbs
}
bool CGUIDialogFileBrowser::ShowAndGetImageList(const VECSOURCES &shares, const std::string &heading, std::vector<std::string> &path)
{
- return ShowAndGetFileList(shares, g_advancedSettings.m_pictureExtensions, heading, path, true); // true for use thumbs
+ return ShowAndGetFileList(shares, g_advancedSettings.GetPictureExtensions(), heading, path, true); // true for use thumbs
}
bool CGUIDialogFileBrowser::ShowAndGetDirectory(const VECSOURCES &shares, const std::string &heading, std::string &path, bool bWriteOnly)
diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp
index 94dfa65502..d7c9e5972a 100644
--- a/xbmc/filesystem/AddonsDirectory.cpp
+++ b/xbmc/filesystem/AddonsDirectory.cpp
@@ -153,7 +153,7 @@ static bool IsGameAddon(const AddonPtr& addon)
IsGameSupportAddon(addon);
}
-static bool IsDependecyType(TYPE type)
+static bool IsDependencyType(TYPE type)
{
return dependencyTypes.find(type) != dependencyTypes.end();
}
@@ -351,7 +351,7 @@ static void GenerateMainCategoryListing(const CURL& path, const VECADDONS& addon
for (unsigned int i = ADDON_UNKNOWN + 1; i < ADDON_MAX - 1; ++i)
{
const TYPE type = (TYPE)i;
- if (!IsInfoProviderType(type) && !IsLookAndFeelType(type) && !IsDependecyType(type) && !IsGameType(type))
+ if (!IsInfoProviderType(type) && !IsLookAndFeelType(type) && !IsDependencyType(type) && !IsGameType(type))
uncategorized.insert(static_cast<TYPE>(i));
}
GenerateTypeListing(path, uncategorized, addons, items);
diff --git a/xbmc/filesystem/File.h b/xbmc/filesystem/File.h
index adcac32bd8..02649a5088 100644
--- a/xbmc/filesystem/File.h
+++ b/xbmc/filesystem/File.h
@@ -129,7 +129,7 @@ public:
int IoControl(EIoControl request, void* param);
- IFile *GetImplemenation() { return m_pFile; }
+ IFile *GetImplementation() { return m_pFile; }
// CURL interface
static bool Exists(const CURL& file, bool bUseCache = true);
diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp
index afea2fe5d5..8e1c95c7e5 100644
--- a/xbmc/filesystem/FileCache.cpp
+++ b/xbmc/filesystem/FileCache.cpp
@@ -146,7 +146,7 @@ void CFileCache::SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache /* =
IFile *CFileCache::GetFileImp()
{
- return m_source.GetImplemenation();
+ return m_source.GetImplementation();
}
bool CFileCache::Open(const CURL& url)
@@ -568,15 +568,15 @@ void CFileCache::StopThread(bool bWait /*= true*/)
std::string CFileCache::GetContent()
{
- if (!m_source.GetImplemenation())
+ if (!m_source.GetImplementation())
return IFile::GetContent();
- return m_source.GetImplemenation()->GetContent();
+ return m_source.GetImplementation()->GetContent();
}
std::string CFileCache::GetContentCharset(void)
{
- IFile* impl = m_source.GetImplemenation();
+ IFile* impl = m_source.GetImplementation();
if (!impl)
return IFile::GetContentCharset();
diff --git a/xbmc/filesystem/PipeFile.cpp b/xbmc/filesystem/PipeFile.cpp
index 28230fb447..72250e6e7c 100644
--- a/xbmc/filesystem/PipeFile.cpp
+++ b/xbmc/filesystem/PipeFile.cpp
@@ -217,8 +217,8 @@ void CPipeFile::RemoveListener(IPipeListener *l)
}
}
-void CPipeFile::SetOpenThreashold(int threashold)
+void CPipeFile::SetOpenThreshold(int threshold)
{
- m_pipe->SetOpenThreashold(threashold);
+ m_pipe->SetOpenThreshold(threshold);
}
diff --git a/xbmc/filesystem/PipeFile.h b/xbmc/filesystem/PipeFile.h
index 27204f10e5..2991d1a68e 100644
--- a/xbmc/filesystem/PipeFile.h
+++ b/xbmc/filesystem/PipeFile.h
@@ -76,7 +76,7 @@ public:
bool IsEmpty();
bool IsClosed();
- void SetOpenThreashold(int threashold);
+ void SetOpenThreshold(int threshold);
protected:
int64_t m_pos;
diff --git a/xbmc/filesystem/PipesManager.cpp b/xbmc/filesystem/PipesManager.cpp
index 63627964d9..5f91ba67f0 100644
--- a/xbmc/filesystem/PipesManager.cpp
+++ b/xbmc/filesystem/PipesManager.cpp
@@ -46,7 +46,7 @@ Pipe::~Pipe()
{
}
-void Pipe::SetOpenThreashold(int threshold)
+void Pipe::SetOpenThreshold(int threshold)
{
m_nOpenThreshold = threshold;
}
diff --git a/xbmc/filesystem/PipesManager.h b/xbmc/filesystem/PipesManager.h
index 33294b1330..9e4b31aa0b 100644
--- a/xbmc/filesystem/PipesManager.h
+++ b/xbmc/filesystem/PipesManager.h
@@ -87,7 +87,7 @@ class Pipe
bool IsEof();
int GetAvailableRead();
- void SetOpenThreashold(int threshold);
+ void SetOpenThreshold(int threshold);
protected:
diff --git a/xbmc/filesystem/RSSDirectory.cpp b/xbmc/filesystem/RSSDirectory.cpp
index 36768e7774..12693d774e 100644
--- a/xbmc/filesystem/RSSDirectory.cpp
+++ b/xbmc/filesystem/RSSDirectory.cpp
@@ -93,7 +93,7 @@ static bool IsPathToMedia(const std::string& strPath )
return URIUtils::HasExtension(strPath,
g_advancedSettings.m_videoExtensions + '|' +
g_advancedSettings.GetMusicExtensions() + '|' +
- g_advancedSettings.m_pictureExtensions);
+ g_advancedSettings.GetPictureExtensions());
}
static bool IsPathToThumbnail(const std::string& strPath )
@@ -101,7 +101,7 @@ static bool IsPathToThumbnail(const std::string& strPath )
// Currently just check if this is an image, maybe we will add some
// other checks later
return URIUtils::HasExtension(strPath,
- g_advancedSettings.m_pictureExtensions);
+ g_advancedSettings.GetPictureExtensions());
}
static time_t ParseDate(const std::string & strDate)
diff --git a/xbmc/filesystem/SFTPFile.cpp b/xbmc/filesystem/SFTPFile.cpp
index 8fad5bd882..c97203b130 100644
--- a/xbmc/filesystem/SFTPFile.cpp
+++ b/xbmc/filesystem/SFTPFile.cpp
@@ -111,7 +111,7 @@ CSFTPSession::~CSFTPSession()
Disconnect();
}
-sftp_file CSFTPSession::CreateFileHande(const std::string &file)
+sftp_file CSFTPSession::CreateFileHandle(const std::string &file)
{
if (m_connected)
{
@@ -603,7 +603,7 @@ bool CSFTPFile::Open(const CURL& url)
if (m_session)
{
m_file = url.GetFileName().c_str();
- m_sftp_handle = m_session->CreateFileHande(m_file);
+ m_sftp_handle = m_session->CreateFileHandle(m_file);
return (m_sftp_handle != NULL);
}
diff --git a/xbmc/filesystem/SFTPFile.h b/xbmc/filesystem/SFTPFile.h
index 973b2df226..229ce4686b 100644
--- a/xbmc/filesystem/SFTPFile.h
+++ b/xbmc/filesystem/SFTPFile.h
@@ -60,7 +60,7 @@ public:
CSFTPSession(const std::string &host, unsigned int port, const std::string &username, const std::string &password);
virtual ~CSFTPSession();
- sftp_file CreateFileHande(const std::string &file);
+ sftp_file CreateFileHandle(const std::string &file);
void CloseFileHandle(sftp_file handle);
bool GetDirectory(const std::string &base, const std::string &folder, CFileItemList &items);
bool DirectoryExists(const char *path);
diff --git a/xbmc/games/addons/GameClient.cpp b/xbmc/games/addons/GameClient.cpp
index 4c719e1eed..7530294e1a 100644
--- a/xbmc/games/addons/GameClient.cpp
+++ b/xbmc/games/addons/GameClient.cpp
@@ -56,6 +56,7 @@
#include <iterator>
#include <utility>
+using namespace KODI;
using namespace GAME;
#define EXTENSION_SEPARATOR "|"
diff --git a/xbmc/games/addons/GameClientInput.cpp b/xbmc/games/addons/GameClientInput.cpp
index 5cfb05132f..8e694d4bfb 100644
--- a/xbmc/games/addons/GameClientInput.cpp
+++ b/xbmc/games/addons/GameClientInput.cpp
@@ -27,6 +27,7 @@
#include <algorithm>
#include <assert.h>
+using namespace KODI;
using namespace GAME;
CGameClientInput::CGameClientInput(CGameClient* gameClient, int port, const ControllerPtr& controller, const KodiToAddonFuncTable_Game *dllStruct) :
diff --git a/xbmc/games/addons/GameClientInput.h b/xbmc/games/addons/GameClientInput.h
index e65fae8cdd..546ec775d1 100644
--- a/xbmc/games/addons/GameClientInput.h
+++ b/xbmc/games/addons/GameClientInput.h
@@ -34,7 +34,7 @@ namespace GAME
*
* Listens to game controller events and forwards them to the games (as game_input_event).
*/
- class CGameClientInput : public JOYSTICK::IInputHandler
+ class CGameClientInput : public KODI::JOYSTICK::IInputHandler
{
public:
/*!
@@ -50,7 +50,7 @@ namespace GAME
virtual std::string ControllerID(void) const override;
virtual bool HasFeature(const std::string& feature) const override;
virtual bool AcceptsInput(void) override;
- virtual JOYSTICK::INPUT_TYPE GetInputType(const std::string& feature) const override;
+ virtual KODI::JOYSTICK::INPUT_TYPE GetInputType(const std::string& feature) const override;
virtual bool OnButtonPress(const std::string& feature, bool bPressed) override;
virtual void OnButtonHold(const std::string& feature, unsigned int holdTimeMs) override { }
virtual bool OnButtonMotion(const std::string& feature, float magnitude) override;
diff --git a/xbmc/games/addons/GameClientKeyboard.cpp b/xbmc/games/addons/GameClientKeyboard.cpp
index 0154e3406d..917da282ed 100644
--- a/xbmc/games/addons/GameClientKeyboard.cpp
+++ b/xbmc/games/addons/GameClientKeyboard.cpp
@@ -26,6 +26,7 @@
#include "input/Key.h"
#include "utils/log.h"
+using namespace KODI;
using namespace GAME;
#define BUTTON_INDEX_MASK 0x01ff
diff --git a/xbmc/games/addons/GameClientKeyboard.h b/xbmc/games/addons/GameClientKeyboard.h
index 0482ef641e..a82236863f 100644
--- a/xbmc/games/addons/GameClientKeyboard.h
+++ b/xbmc/games/addons/GameClientKeyboard.h
@@ -33,7 +33,7 @@ namespace GAME
*
* Listens to keyboard events and forwards them to the games (as game_input_event).
*/
- class CGameClientKeyboard : public KEYBOARD::IKeyboardHandler
+ class CGameClientKeyboard : public KODI::KEYBOARD::IKeyboardHandler
{
public:
/*!
diff --git a/xbmc/games/addons/GameClientMouse.cpp b/xbmc/games/addons/GameClientMouse.cpp
index df1a0403f6..727b662bfa 100644
--- a/xbmc/games/addons/GameClientMouse.cpp
+++ b/xbmc/games/addons/GameClientMouse.cpp
@@ -26,6 +26,7 @@
#include "input/Key.h"
#include "utils/log.h"
+using namespace KODI;
using namespace GAME;
CGameClientMouse::CGameClientMouse(const CGameClient* gameClient, const KodiToAddonFuncTable_Game* dllStruct) :
diff --git a/xbmc/games/addons/GameClientMouse.h b/xbmc/games/addons/GameClientMouse.h
index e1b34ca1c8..4ab7a127a5 100644
--- a/xbmc/games/addons/GameClientMouse.h
+++ b/xbmc/games/addons/GameClientMouse.h
@@ -33,7 +33,7 @@ namespace GAME
*
* Listens to mouse events and forwards them to the games (as game_input_event).
*/
- class CGameClientMouse : public MOUSE::IMouseInputHandler
+ class CGameClientMouse : public KODI::MOUSE::IMouseInputHandler
{
public:
/*!
diff --git a/xbmc/games/controllers/ControllerFeature.cpp b/xbmc/games/controllers/ControllerFeature.cpp
index 2801bd2790..4b15c39492 100644
--- a/xbmc/games/controllers/ControllerFeature.cpp
+++ b/xbmc/games/controllers/ControllerFeature.cpp
@@ -28,6 +28,7 @@
#include <sstream>
+using namespace KODI;
using namespace GAME;
using namespace JOYSTICK;
diff --git a/xbmc/games/controllers/ControllerFeature.h b/xbmc/games/controllers/ControllerFeature.h
index 753c9837ac..9b90f68653 100644
--- a/xbmc/games/controllers/ControllerFeature.h
+++ b/xbmc/games/controllers/ControllerFeature.h
@@ -39,27 +39,27 @@ public:
CControllerFeature& operator=(const CControllerFeature& rhs);
- JOYSTICK::FEATURE_TYPE Type(void) const { return m_type; }
- JOYSTICK::FEATURE_CATEGORY Category(void) const { return m_category; }
+ KODI::JOYSTICK::FEATURE_TYPE Type(void) const { return m_type; }
+ KODI::JOYSTICK::FEATURE_CATEGORY Category(void) const { return m_category; }
const std::string& CategoryLabel(void) const { return m_strCategory; }
const std::string& Name(void) const { return m_strName; }
const std::string& Label(void) const { return m_strLabel; }
unsigned int LabelID(void) const { return m_labelId; }
- JOYSTICK::INPUT_TYPE InputType(void) const { return m_inputType; }
+ KODI::JOYSTICK::INPUT_TYPE InputType(void) const { return m_inputType; }
bool Deserialize(const TiXmlElement* pElement,
const CController* controller,
- JOYSTICK::FEATURE_CATEGORY category,
+ KODI::JOYSTICK::FEATURE_CATEGORY category,
const std::string& strCategory);
private:
- JOYSTICK::FEATURE_TYPE m_type;
- JOYSTICK::FEATURE_CATEGORY m_category;
+ KODI::JOYSTICK::FEATURE_TYPE m_type;
+ KODI::JOYSTICK::FEATURE_CATEGORY m_category;
std::string m_strCategory;
std::string m_strName;
std::string m_strLabel;
unsigned int m_labelId;
- JOYSTICK::INPUT_TYPE m_inputType;
+ KODI::JOYSTICK::INPUT_TYPE m_inputType;
};
}
diff --git a/xbmc/games/controllers/ControllerLayout.cpp b/xbmc/games/controllers/ControllerLayout.cpp
index 48ae67ef99..dc7f8d5ddb 100644
--- a/xbmc/games/controllers/ControllerLayout.cpp
+++ b/xbmc/games/controllers/ControllerLayout.cpp
@@ -29,6 +29,7 @@
#include <algorithm>
#include <sstream>
+using namespace KODI;
using namespace GAME;
using namespace JOYSTICK;
diff --git a/xbmc/games/controllers/ControllerLayout.h b/xbmc/games/controllers/ControllerLayout.h
index 559fe27b43..db5dac2d7b 100644
--- a/xbmc/games/controllers/ControllerLayout.h
+++ b/xbmc/games/controllers/ControllerLayout.h
@@ -43,8 +43,8 @@ public:
const std::vector<CControllerFeature>& Features(void) const { return m_features; }
- unsigned int FeatureCount(JOYSTICK::FEATURE_TYPE type = JOYSTICK::FEATURE_TYPE::UNKNOWN,
- JOYSTICK::INPUT_TYPE buttonType = JOYSTICK::INPUT_TYPE::UNKNOWN) const;
+ unsigned int FeatureCount(KODI::JOYSTICK::FEATURE_TYPE type = KODI::JOYSTICK::FEATURE_TYPE::UNKNOWN,
+ KODI::JOYSTICK::INPUT_TYPE buttonType = KODI::JOYSTICK::INPUT_TYPE::UNKNOWN) const;
bool Deserialize(const TiXmlElement* pLayoutElement, const CController* controller);
diff --git a/xbmc/games/controllers/ControllerTranslator.cpp b/xbmc/games/controllers/ControllerTranslator.cpp
index e76226987c..72af8ed4e5 100644
--- a/xbmc/games/controllers/ControllerTranslator.cpp
+++ b/xbmc/games/controllers/ControllerTranslator.cpp
@@ -21,6 +21,7 @@
#include "ControllerTranslator.h"
#include "ControllerDefinitions.h"
+using namespace KODI;
using namespace GAME;
using namespace JOYSTICK;
diff --git a/xbmc/games/controllers/ControllerTranslator.h b/xbmc/games/controllers/ControllerTranslator.h
index df82aad557..ea8b06d3c4 100644
--- a/xbmc/games/controllers/ControllerTranslator.h
+++ b/xbmc/games/controllers/ControllerTranslator.h
@@ -30,14 +30,14 @@ namespace GAME
class CControllerTranslator
{
public:
- static const char* TranslateFeatureType(JOYSTICK::FEATURE_TYPE type);
- static JOYSTICK::FEATURE_TYPE TranslateFeatureType(const std::string& strType);
+ static const char* TranslateFeatureType(KODI::JOYSTICK::FEATURE_TYPE type);
+ static KODI::JOYSTICK::FEATURE_TYPE TranslateFeatureType(const std::string& strType);
- static const char* TranslateFeatureCategory(JOYSTICK::FEATURE_CATEGORY category);
- static JOYSTICK::FEATURE_CATEGORY TranslateFeatureCategory(const std::string& strCategory);
+ static const char* TranslateFeatureCategory(KODI::JOYSTICK::FEATURE_CATEGORY category);
+ static KODI::JOYSTICK::FEATURE_CATEGORY TranslateFeatureCategory(const std::string& strCategory);
- static const char* TranslateInputType(JOYSTICK::INPUT_TYPE type);
- static JOYSTICK::INPUT_TYPE TranslateInputType(const std::string& strType);
+ static const char* TranslateInputType(KODI::JOYSTICK::INPUT_TYPE type);
+ static KODI::JOYSTICK::INPUT_TYPE TranslateInputType(const std::string& strType);
};
}
diff --git a/xbmc/games/controllers/dialogs/CMakeLists.txt b/xbmc/games/controllers/dialogs/CMakeLists.txt
index 436712ca8c..2b398e98ed 100644
--- a/xbmc/games/controllers/dialogs/CMakeLists.txt
+++ b/xbmc/games/controllers/dialogs/CMakeLists.txt
@@ -1,5 +1,11 @@
-set(SOURCES GUIDialogButtonCapture.cpp)
+set(SOURCES GUIDialogAxisDetection.cpp
+ GUIDialogButtonCapture.cpp
+ GUIDialogIgnoreInput.cpp
+)
-set(HEADERS GUIDialogButtonCapture.h)
+set(HEADERS GUIDialogAxisDetection.h
+ GUIDialogButtonCapture.h
+ GUIDialogIgnoreInput.h
+)
core_add_library(games_controller_dialogs)
diff --git a/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp
new file mode 100644
index 0000000000..fb74519fa1
--- /dev/null
+++ b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "GUIDialogAxisDetection.h"
+#include "guilib/LocalizeStrings.h"
+#include "input/joysticks/DriverPrimitive.h"
+#include "input/joysticks/IButtonMap.h"
+#include "input/joysticks/JoystickTranslator.h"
+#include "utils/StringUtils.h"
+
+#include <algorithm>
+
+using namespace KODI;
+using namespace GAME;
+
+std::string CGUIDialogAxisDetection::GetDialogText()
+{
+ // "Press all analog buttons now to detect them:[CR][CR]%s"
+ std::string dialogText = g_localizeStrings.Get(35020);
+
+ std::vector<std::string> primitives;
+
+ for (const auto& axisEntry : m_detectedAxes)
+ {
+ JOYSTICK::CDriverPrimitive axis(axisEntry.second, 0, JOYSTICK::SEMIAXIS_DIRECTION::POSITIVE, 1);
+ primitives.emplace_back(JOYSTICK::CJoystickTranslator::GetPrimitiveName(axis));
+ }
+
+ return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str());
+}
+
+std::string CGUIDialogAxisDetection::GetDialogHeader()
+{
+ return g_localizeStrings.Get(35058); // "Controller Configuration"
+}
+
+bool CGUIDialogAxisDetection::MapPrimitiveInternal(JOYSTICK::IButtonMap* buttonMap,
+ JOYSTICK::IActionMap* actionMap,
+ const JOYSTICK::CDriverPrimitive& primitive)
+{
+ if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS)
+ AddAxis(buttonMap->DeviceName(), primitive.Index());
+
+ return true;
+}
+
+void CGUIDialogAxisDetection::OnLateAxis(const JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex)
+{
+ AddAxis(buttonMap->DeviceName(), axisIndex);
+}
+
+void CGUIDialogAxisDetection::AddAxis(const std::string& deviceName, unsigned int axisIndex)
+{
+ auto it = std::find_if(m_detectedAxes.begin(), m_detectedAxes.end(),
+ [&deviceName, axisIndex](const AxisEntry& axis)
+ {
+ return axis.first == deviceName &&
+ axis.second == axisIndex;
+ });
+
+ if (it == m_detectedAxes.end())
+ {
+ m_detectedAxes.emplace_back(std::make_pair(deviceName, axisIndex));
+ m_captureEvent.Set();
+ }
+}
diff --git a/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h
new file mode 100644
index 0000000000..2ad7c9b568
--- /dev/null
+++ b/xbmc/games/controllers/dialogs/GUIDialogAxisDetection.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "GUIDialogButtonCapture.h"
+
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace GAME
+{
+ class CGUIDialogAxisDetection : public CGUIDialogButtonCapture
+ {
+ public:
+ CGUIDialogAxisDetection() = default;
+
+ virtual ~CGUIDialogAxisDetection() = default;
+
+ // specialization of IButtonMapper via CGUIDialogButtonCapture
+ void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override;
+
+ protected:
+ // implementation of CGUIDialogButtonCapture
+ virtual std::string GetDialogText() override;
+ virtual std::string GetDialogHeader() override;
+ virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap,
+ KODI::JOYSTICK::IActionMap* actionMap,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive) override;
+ virtual void OnClose(bool bAccepted) override { }
+
+ private:
+ void AddAxis(const std::string& deviceName, unsigned int axisIndex);
+
+ // Axis types
+ using DeviceName = std::string;
+ using AxisIndex = unsigned int;
+ using AxisEntry = std::pair<DeviceName, AxisIndex>;
+ using AxisVector = std::vector<AxisEntry>;
+
+ // Axis detection
+ AxisVector m_detectedAxes;
+ };
+}
diff --git a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp
index b65b544480..490f97a2b4 100644
--- a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp
+++ b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.cpp
@@ -21,22 +21,20 @@
#include "GUIDialogButtonCapture.h"
#include "dialogs/GUIDialogOK.h"
#include "guilib/GUIWindowManager.h"
-#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
#include "input/joysticks/DefaultJoystick.h"
#include "input/joysticks/IActionMap.h"
#include "input/joysticks/IButtonMap.h"
#include "input/joysticks/IButtonMapCallback.h"
#include "input/joysticks/JoystickUtils.h"
-#include "input/Key.h"
-#include "utils/log.h"
+#include "input/ActionIDs.h"
#include "peripherals/Peripherals.h"
-#include "utils/StringUtils.h"
#include "utils/Variant.h"
#include <algorithm>
#include <iterator>
+using namespace KODI;
using namespace GAME;
CGUIDialogButtonCapture::CGUIDialogButtonCapture() :
@@ -59,27 +57,13 @@ void CGUIDialogButtonCapture::Show()
Create();
- bool bAccepted = CGUIDialogOK::ShowAndGetInput(CVariant{ 35019 }, CVariant{ GetDialogText() }); // "Ignore input"
+ bool bAccepted = CGUIDialogOK::ShowAndGetInput(CVariant{ GetDialogHeader() }, CVariant{ GetDialogText() });
StopThread(false);
m_captureEvent.Set();
- for (auto& callback : ButtonMapCallbacks())
- {
- if (bAccepted)
- {
- // See documentation of IButtonMapCallback::ResetIgnoredPrimitives()
- // for why this call is needed
- if (m_deviceName.empty())
- callback.second->ResetIgnoredPrimitives();
-
- if (m_deviceName.empty() || m_deviceName == callback.first)
- callback.second->SaveButtonMap();
- }
- else
- callback.second->RevertButtonMap();
- }
+ OnClose(bAccepted);
RemoveHooks();
}
@@ -126,71 +110,7 @@ bool CGUIDialogButtonCapture::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
}
}
- // Check if we have already started capturing primitives for a device
- const bool bHasDevice = !m_deviceName.empty();
-
- // If a primitive comes from a different device, ignore it
- if (bHasDevice && m_deviceName != buttonMap->DeviceName())
- {
- CLog::Log(LOGDEBUG, "%s: ignoring input from device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
- return false;
- }
-
- if (!bHasDevice)
- {
- CLog::Log(LOGDEBUG, "%s: capturing input for device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
- m_deviceName = buttonMap->DeviceName();
- }
-
- if (AddPrimitive(primitive))
- {
- buttonMap->SetIgnoredPrimitives(m_capturedPrimitives);
- m_captureEvent.Set();
- }
-
- return true;
-}
-
-bool CGUIDialogButtonCapture::AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive)
-{
- bool bValid = false;
-
- if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::BUTTON ||
- primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS)
- {
- auto PrimitiveMatch = [&primitive](const JOYSTICK::CDriverPrimitive& other)
- {
- return primitive.Type() == other.Type() &&
- primitive.Index() == other.Index();
- };
-
- bValid = std::find_if(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), PrimitiveMatch) == m_capturedPrimitives.end();
- }
-
- if (bValid)
- {
- m_capturedPrimitives.emplace_back(primitive);
- return true;
- }
-
- return false;
-}
-
-std::string CGUIDialogButtonCapture::GetDialogText()
-{
- // "Some controllers have buttons and axes that interfere with mapping. Press
- // these now to disable them:[CR][CR]%s"
- std::string dialogText = g_localizeStrings.Get(35014);
-
- std::vector<std::string> primitives;
-
- std::transform(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), std::back_inserter(primitives),
- [](const JOYSTICK::CDriverPrimitive& primitive)
- {
- return GetPrimitiveName(primitive);
- });
-
- return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str());
+ return MapPrimitiveInternal(buttonMap, actionMap, primitive);
}
void CGUIDialogButtonCapture::InstallHooks(void)
@@ -225,21 +145,3 @@ void CGUIDialogButtonCapture::Notify(const Observable& obs, const ObservableMess
break;
}
}
-
-std::string CGUIDialogButtonCapture::GetPrimitiveName(const JOYSTICK::CDriverPrimitive& primitive)
-{
- std::string primitiveTemplate;
-
- switch (primitive.Type())
- {
- case JOYSTICK::PRIMITIVE_TYPE::BUTTON:
- primitiveTemplate = g_localizeStrings.Get(35015); // "Button %d"
- break;
- case JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS:
- primitiveTemplate = g_localizeStrings.Get(35016); // "Axis %d"
- break;
- default: break;
- }
-
- return StringUtils::Format(primitiveTemplate.c_str(), primitive.Index());
-}
diff --git a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h
index fe242c3e44..00cda4046a 100644
--- a/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h
+++ b/xbmc/games/controllers/dialogs/GUIDialogButtonCapture.h
@@ -19,55 +19,59 @@
*/
#pragma once
-#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/IButtonMapper.h"
#include "threads/Event.h"
#include "threads/Thread.h"
#include "utils/Observer.h"
+#include <string>
#include <vector>
namespace GAME
{
- class CGUIDialogButtonCapture : public JOYSTICK::IButtonMapper,
+ class CGUIDialogButtonCapture : public KODI::JOYSTICK::IButtonMapper,
public Observer,
protected CThread
{
public:
CGUIDialogButtonCapture();
+ virtual ~CGUIDialogButtonCapture() = default;
+
// implementation of IButtonMapper
virtual std::string ControllerID(void) const override;
virtual bool NeedsCooldown(void) const override { return false; }
virtual bool Emulation(void) const override { return false; }
virtual unsigned int ControllerNumber(void) const override { return 0; }
- virtual bool MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
- JOYSTICK::IActionMap* actionMap,
- const JOYSTICK::CDriverPrimitive& primitive) override;
- virtual void OnEventFrame(const JOYSTICK::IButtonMap* buttonMap, bool bMotion) override { }
+ virtual bool MapPrimitive(KODI::JOYSTICK::IButtonMap* buttonMap,
+ KODI::JOYSTICK::IActionMap* actionMap,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive) override;
+ virtual void OnEventFrame(const KODI::JOYSTICK::IButtonMap* buttonMap, bool bMotion) override { }
+ virtual void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override { }
// implementation of Observer
virtual void Notify(const Observable &obs, const ObservableMessage msg) override;
+ /*!
+ * \brief Show the dialog
+ */
void Show();
protected:
// implementation of CThread
virtual void Process() override;
- private:
- bool AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive);
+ virtual std::string GetDialogText() = 0;
+ virtual std::string GetDialogHeader() = 0;
+ virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap,
+ KODI::JOYSTICK::IActionMap* actionMap,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive) = 0;
+ virtual void OnClose(bool bAccepted) = 0;
- std::string GetDialogText();
+ CEvent m_captureEvent;
+ private:
void InstallHooks();
void RemoveHooks();
-
- static std::string GetPrimitiveName(const JOYSTICK::CDriverPrimitive& primitive);
-
- // Button capture parameters
- std::string m_deviceName;
- std::vector<JOYSTICK::CDriverPrimitive> m_capturedPrimitives;
- CEvent m_captureEvent;
};
}
diff --git a/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp
new file mode 100644
index 0000000000..a767340438
--- /dev/null
+++ b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "GUIDialogIgnoreInput.h"
+#include "guilib/LocalizeStrings.h"
+#include "input/joysticks/IButtonMap.h"
+#include "input/joysticks/IButtonMapCallback.h"
+#include "input/joysticks/JoystickTranslator.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+
+#include <algorithm>
+#include <iterator>
+
+using namespace KODI;
+using namespace GAME;
+
+std::string CGUIDialogIgnoreInput::GetDialogText()
+{
+ // "Some controllers have buttons and axes that interfere with mapping. Press
+ // these now to disable them:[CR]%s"
+ std::string dialogText = g_localizeStrings.Get(35014);
+
+ std::vector<std::string> primitives;
+
+ std::transform(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), std::back_inserter(primitives),
+ [](const JOYSTICK::CDriverPrimitive& primitive)
+ {
+ return JOYSTICK::CJoystickTranslator::GetPrimitiveName(primitive);
+ });
+
+ return StringUtils::Format(dialogText.c_str(), StringUtils::Join(primitives, " | ").c_str());
+}
+
+std::string CGUIDialogIgnoreInput::GetDialogHeader()
+{
+
+ return g_localizeStrings.Get(35019); // "Ignore input"
+}
+
+bool CGUIDialogIgnoreInput::MapPrimitiveInternal(JOYSTICK::IButtonMap* buttonMap,
+ JOYSTICK::IActionMap* actionMap,
+ const JOYSTICK::CDriverPrimitive& primitive)
+{
+ // Check if we have already started capturing primitives for a device
+ const bool bHasDevice = !m_deviceName.empty();
+
+ // If a primitive comes from a different device, ignore it
+ if (bHasDevice && m_deviceName != buttonMap->DeviceName())
+ {
+ CLog::Log(LOGDEBUG, "%s: ignoring input from device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
+ return false;
+ }
+
+ if (!bHasDevice)
+ {
+ CLog::Log(LOGDEBUG, "%s: capturing input for device %s", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
+ m_deviceName = buttonMap->DeviceName();
+ }
+
+ if (AddPrimitive(primitive))
+ {
+ buttonMap->SetIgnoredPrimitives(m_capturedPrimitives);
+ m_captureEvent.Set();
+ }
+
+ return true;
+}
+
+void CGUIDialogIgnoreInput::OnClose(bool bAccepted)
+{
+ for (auto& callback : ButtonMapCallbacks())
+ {
+ if (bAccepted)
+ {
+ // See documentation of IButtonMapCallback::ResetIgnoredPrimitives()
+ // for why this call is needed
+ if (m_deviceName.empty())
+ callback.second->ResetIgnoredPrimitives();
+
+ if (m_deviceName.empty() || m_deviceName == callback.first)
+ callback.second->SaveButtonMap();
+ }
+ else
+ callback.second->RevertButtonMap();
+ }
+}
+
+bool CGUIDialogIgnoreInput::AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive)
+{
+ bool bValid = false;
+
+ if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::BUTTON ||
+ primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS)
+ {
+ auto PrimitiveMatch = [&primitive](const JOYSTICK::CDriverPrimitive& other)
+ {
+ return primitive.Type() == other.Type() &&
+ primitive.Index() == other.Index();
+ };
+
+ bValid = std::find_if(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), PrimitiveMatch) == m_capturedPrimitives.end();
+ }
+
+ if (bValid)
+ {
+ m_capturedPrimitives.emplace_back(primitive);
+ return true;
+ }
+
+ return false;
+}
diff --git a/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h
new file mode 100644
index 0000000000..a4b358412a
--- /dev/null
+++ b/xbmc/games/controllers/dialogs/GUIDialogIgnoreInput.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "GUIDialogButtonCapture.h"
+#include "input/joysticks/DriverPrimitive.h"
+
+#include <string>
+#include <vector>
+
+namespace GAME
+{
+ class CGUIDialogIgnoreInput : public CGUIDialogButtonCapture
+ {
+ public:
+ CGUIDialogIgnoreInput() = default;
+
+ virtual ~CGUIDialogIgnoreInput() = default;
+
+ protected:
+ // implementation of CGUIDialogButtonCapture
+ virtual std::string GetDialogText() override;
+ virtual std::string GetDialogHeader() override;
+ virtual bool MapPrimitiveInternal(KODI::JOYSTICK::IButtonMap* buttonMap,
+ KODI::JOYSTICK::IActionMap* actionMap,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive) override;
+ void OnClose(bool bAccepted) override;
+
+ private:
+ bool AddPrimitive(const KODI::JOYSTICK::CDriverPrimitive& primitive);
+
+ std::string m_deviceName;
+ std::vector<KODI::JOYSTICK::CDriverPrimitive> m_capturedPrimitives;
+ };
+}
diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp
index 8e1fb3971e..1ba9b81cba 100644
--- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp
+++ b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp
@@ -24,6 +24,7 @@
#include <string>
+using namespace KODI;
using namespace GAME;
CGUIAnalogStickButton::CGUIAnalogStickButton(const CGUIButtonControl& buttonTemplate,
diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h
index 19990f36bf..c5d632b831 100644
--- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h
+++ b/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h
@@ -36,7 +36,7 @@ namespace GAME
// implementation of IFeatureButton
virtual bool PromptForInput(CEvent& waitEvent) override;
virtual bool IsFinished(void) const override;
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override;
+ virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override;
virtual void Reset(void) override;
private:
diff --git a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
index 354f314111..cd6583aaab 100644
--- a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
+++ b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
@@ -44,7 +44,7 @@ namespace GAME
// partial implementation of IFeatureButton
virtual const CControllerFeature& Feature(void) const override { return m_feature; }
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override { return JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; }
+ virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const override { return KODI::JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; }
protected:
bool DoPrompt(const std::string& strPrompt, const std::string& strWarn, const std::string& strFeature, CEvent& waitEvent);
diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
index 2e50db1b58..9071db44f8 100644
--- a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
+++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
@@ -19,16 +19,19 @@
*/
#include "GUIConfigurationWizard.h"
+#include "games/controllers/dialogs/GUIDialogAxisDetection.h"
#include "games/controllers/guicontrols/GUIFeatureButton.h"
#include "games/controllers/Controller.h"
#include "games/controllers/ControllerFeature.h"
#include "input/joysticks/IButtonMap.h"
#include "input/joysticks/IButtonMapCallback.h"
+#include "input/keyboard/KeymapActionMap.h"
#include "input/InputManager.h"
#include "peripherals/Peripherals.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
+using namespace KODI;
using namespace GAME;
#define ESC_KEY_CODE 27
@@ -40,16 +43,22 @@ using namespace GAME;
CGUIConfigurationWizard::CGUIConfigurationWizard(bool bEmulation, unsigned int controllerNumber /* = 0 */) :
CThread("GUIConfigurationWizard"),
m_bEmulation(bEmulation),
- m_controllerNumber(controllerNumber)
+ m_controllerNumber(controllerNumber),
+ m_actionMap(new KEYBOARD::CKeymapActionMap)
{
InitializeState();
}
+CGUIConfigurationWizard::~CGUIConfigurationWizard(void)
+{
+}
+
void CGUIConfigurationWizard::InitializeState(void)
{
m_currentButton = nullptr;
m_currentDirection = JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN;
m_history.clear();
+ m_lateAxisDetected = false;
}
void CGUIConfigurationWizard::Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons)
@@ -85,7 +94,7 @@ void CGUIConfigurationWizard::OnUnfocus(IFeatureButton* button)
bool CGUIConfigurationWizard::Abort(bool bWait /* = true */)
{
- if (IsRunning())
+ if (!m_bStop)
{
StopThread(false);
@@ -106,6 +115,8 @@ void CGUIConfigurationWizard::Process(void)
InstallHooks();
+ bool bLateAxisDetected = false;
+
{
CSingleLock lock(m_stateMutex);
for (IFeatureButton* button : m_buttons)
@@ -138,6 +149,8 @@ void CGUIConfigurationWizard::Process(void)
break;
}
+ bLateAxisDetected = m_lateAxisDetected;
+
// Finished mapping
InitializeState();
}
@@ -145,17 +158,27 @@ void CGUIConfigurationWizard::Process(void)
for (auto callback : ButtonMapCallbacks())
callback.second->SaveButtonMap();
- bool bInMotion;
-
+ if (bLateAxisDetected)
{
- CSingleLock lock(m_motionMutex);
- bInMotion = !m_bInMotion.empty();
+ CGUIDialogAxisDetection dialog;
+ dialog.Show();
}
-
- if (bInMotion)
+ else
{
- CLog::Log(LOGDEBUG, "Configuration wizard: waiting %ums for axes to neutralize", POST_MAPPING_WAIT_TIME_MS);
- m_motionlessEvent.WaitMSec(POST_MAPPING_WAIT_TIME_MS);
+ // Wait for motion to stop to avoid sending analog actions for the button
+ // that is pressed immediately after button mapping finishes.
+ bool bInMotion;
+
+ {
+ CSingleLock lock(m_motionMutex);
+ bInMotion = !m_bInMotion.empty();
+ }
+
+ if (bInMotion)
+ {
+ CLog::Log(LOGDEBUG, "Configuration wizard: waiting %ums for axes to neutralize", POST_MAPPING_WAIT_TIME_MS);
+ m_motionlessEvent.WaitMSec(POST_MAPPING_WAIT_TIME_MS);
+ }
}
RemoveHooks();
@@ -243,6 +266,14 @@ void CGUIConfigurationWizard::OnEventFrame(const JOYSTICK::IButtonMap* buttonMap
OnMotionless(buttonMap);
}
+void CGUIConfigurationWizard::OnLateAxis(const JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex)
+{
+ CSingleLock lock(m_stateMutex);
+
+ m_lateAxisDetected = true;
+ Abort(false);
+}
+
void CGUIConfigurationWizard::OnMotion(const JOYSTICK::IButtonMap* buttonMap)
{
CSingleLock lock(m_motionMutex);
@@ -260,7 +291,38 @@ void CGUIConfigurationWizard::OnMotionless(const JOYSTICK::IButtonMap* buttonMap
bool CGUIConfigurationWizard::OnKeyPress(const CKey& key)
{
- return Abort(false);
+ using namespace KEYBOARD;
+
+ bool bHandled = false;
+
+ switch (m_actionMap->GetActionID(key))
+ {
+ case ACTION_MOVE_LEFT:
+ case ACTION_MOVE_RIGHT:
+ case ACTION_MOVE_UP:
+ case ACTION_MOVE_DOWN:
+ case ACTION_PAGE_UP:
+ case ACTION_PAGE_DOWN:
+ // Abort and allow motion
+ Abort(false);
+ bHandled = false;
+ break;
+
+ case ACTION_PARENT_DIR:
+ case ACTION_PREVIOUS_MENU:
+ case ACTION_STOP:
+ // Abort and prevent action
+ Abort(false);
+ bHandled = true;
+ break;
+
+ default:
+ // Absorb keypress
+ bHandled = true;
+ break;
+ }
+
+ return bHandled;
}
bool CGUIConfigurationWizard::OnButtonPress(const std::string& button)
diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.h b/xbmc/games/controllers/windows/GUIConfigurationWizard.h
index 4076afd9fc..a006ae5f78 100644
--- a/xbmc/games/controllers/windows/GUIConfigurationWizard.h
+++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.h
@@ -29,23 +29,32 @@
#include "threads/Thread.h"
#include "utils/Observer.h"
+#include <memory>
#include <set>
#include <string>
#include <vector>
+namespace KODI
+{
+namespace KEYBOARD
+{
+ class IActionMap;
+}
+}
+
namespace GAME
{
class CGUIConfigurationWizard : public IConfigurationWizard,
- public JOYSTICK::IButtonMapper,
- public KEYBOARD::IKeyboardHandler,
- public MOUSE::IMouseInputHandler,
+ public KODI::JOYSTICK::IButtonMapper,
+ public KODI::KEYBOARD::IKeyboardHandler,
+ public KODI::MOUSE::IMouseInputHandler,
public Observer,
protected CThread
{
public:
CGUIConfigurationWizard(bool bEmulation, unsigned int controllerNumber = 0);
- virtual ~CGUIConfigurationWizard(void) { }
+ virtual ~CGUIConfigurationWizard(void);
// implementation of IConfigurationWizard
virtual void Run(const std::string& strControllerId, const std::vector<IFeatureButton*>& buttons) override;
@@ -57,10 +66,11 @@ namespace GAME
virtual bool NeedsCooldown(void) const override { return true; }
virtual bool Emulation(void) const override { return m_bEmulation; }
virtual unsigned int ControllerNumber(void) const override { return m_controllerNumber; }
- virtual bool MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
- JOYSTICK::IActionMap* actionMap,
- const JOYSTICK::CDriverPrimitive& primitive) override;
- virtual void OnEventFrame(const JOYSTICK::IButtonMap* buttonMap, bool bMotion) override;
+ virtual bool MapPrimitive(KODI::JOYSTICK::IButtonMap* buttonMap,
+ KODI::JOYSTICK::IActionMap* actionMap,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive) override;
+ virtual void OnEventFrame(const KODI::JOYSTICK::IButtonMap* buttonMap, bool bMotion) override;
+ virtual void OnLateAxis(const KODI::JOYSTICK::IButtonMap* buttonMap, unsigned int axisIndex) override;
// implementation of IKeyboardHandler
virtual bool OnKeyPress(const CKey& key) override;
@@ -84,8 +94,8 @@ namespace GAME
void InstallHooks(void);
void RemoveHooks(void);
- void OnMotion(const JOYSTICK::IButtonMap* buttonMap);
- void OnMotionless(const JOYSTICK::IButtonMap* buttonMap);
+ void OnMotion(const KODI::JOYSTICK::IButtonMap* buttonMap);
+ void OnMotionless(const KODI::JOYSTICK::IButtonMap* buttonMap);
// Construction parameters
const bool m_bEmulation;
@@ -97,14 +107,18 @@ namespace GAME
// State variables and mutex
IFeatureButton* m_currentButton;
- JOYSTICK::ANALOG_STICK_DIRECTION m_currentDirection;
- std::set<JOYSTICK::CDriverPrimitive> m_history; // History to avoid repeated features
+ KODI::JOYSTICK::ANALOG_STICK_DIRECTION m_currentDirection;
+ std::set<KODI::JOYSTICK::CDriverPrimitive> m_history; // History to avoid repeated features
+ bool m_lateAxisDetected; // Set to true if an axis is detected during button mapping
CCriticalSection m_stateMutex;
// Synchronization events
CEvent m_inputEvent;
CEvent m_motionlessEvent;
CCriticalSection m_motionMutex;
- std::set<const JOYSTICK::IButtonMap*> m_bInMotion;
+ std::set<const KODI::JOYSTICK::IButtonMap*> m_bInMotion;
+
+ // Keyboard handling
+ std::unique_ptr<KODI::KEYBOARD::IActionMap> m_actionMap;
};
}
diff --git a/xbmc/games/controllers/windows/GUIControllerWindow.cpp b/xbmc/games/controllers/windows/GUIControllerWindow.cpp
index 6fb34a82f5..7316f8758d 100644
--- a/xbmc/games/controllers/windows/GUIControllerWindow.cpp
+++ b/xbmc/games/controllers/windows/GUIControllerWindow.cpp
@@ -26,7 +26,7 @@
#include "addons/GUIWindowAddonBrowser.h"
#include "addons/IAddon.h"
#include "addons/AddonManager.h"
-#include "games/controllers/dialogs/GUIDialogButtonCapture.h"
+#include "games/controllers/dialogs/GUIDialogIgnoreInput.h"
#include "guilib/GUIButtonControl.h"
#include "guilib/GUIControl.h"
#include "guilib/GUIMessage.h"
@@ -322,6 +322,6 @@ void CGUIControllerWindow::ShowHelp(void)
void CGUIControllerWindow::ShowButtonCaptureDialog(void)
{
- CGUIDialogButtonCapture dialog;
+ CGUIDialogIgnoreInput dialog;
dialog.Show();
}
diff --git a/xbmc/games/controllers/windows/GUIFeatureList.cpp b/xbmc/games/controllers/windows/GUIFeatureList.cpp
index 6518d1957c..9633495e91 100644
--- a/xbmc/games/controllers/windows/GUIFeatureList.cpp
+++ b/xbmc/games/controllers/windows/GUIFeatureList.cpp
@@ -34,6 +34,7 @@
#include "guilib/GUIWindow.h"
#include "messaging/ApplicationMessenger.h"
+using namespace KODI;
using namespace GAME;
CGUIFeatureList::CGUIFeatureList(CGUIWindow* window, const std::string& windowParam) :
diff --git a/xbmc/games/controllers/windows/IConfigurationWindow.h b/xbmc/games/controllers/windows/IConfigurationWindow.h
index 5f57a5bb8f..43f141640e 100644
--- a/xbmc/games/controllers/windows/IConfigurationWindow.h
+++ b/xbmc/games/controllers/windows/IConfigurationWindow.h
@@ -173,7 +173,7 @@ namespace GAME
* \return The next direction to be prompted, or UNKNOWN if this isn't an
* analog stick or the prompt is finished
*/
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const = 0;
+ virtual KODI::JOYSTICK::ANALOG_STICK_DIRECTION GetDirection(void) const = 0;
/*!
* \brief Reset button after prompting for input has finished
diff --git a/xbmc/games/ports/PortManager.cpp b/xbmc/games/ports/PortManager.cpp
index 5eafc923f9..6809e00959 100644
--- a/xbmc/games/ports/PortManager.cpp
+++ b/xbmc/games/ports/PortManager.cpp
@@ -26,6 +26,7 @@
#include <algorithm>
+using namespace KODI;
using namespace GAME;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/games/ports/PortManager.h b/xbmc/games/ports/PortManager.h
index 289c9ee935..b466ca8814 100644
--- a/xbmc/games/ports/PortManager.h
+++ b/xbmc/games/ports/PortManager.h
@@ -26,8 +26,18 @@
#include <map>
#include <vector>
-namespace JOYSTICK { class IInputHandler; }
-namespace PERIPHERALS { class CPeripheral; }
+namespace KODI
+{
+namespace JOYSTICK
+{
+ class IInputHandler;
+}
+}
+
+namespace PERIPHERALS
+{
+ class CPeripheral;
+}
namespace GAME
{
@@ -50,7 +60,7 @@ namespace GAME
* \param port The port number belonging to the game client
* \param requiredType Used to restrict port to devices of only a certain type
*/
- void OpenPort(JOYSTICK::IInputHandler* handler,
+ void OpenPort(KODI::JOYSTICK::IInputHandler* handler,
unsigned int port,
PERIPHERALS::PeripheralType requiredType = PERIPHERALS::PERIPHERAL_UNKNOWN);
@@ -59,7 +69,7 @@ namespace GAME
*
* \param handler The handler used to open the port
*/
- void ClosePort(JOYSTICK::IInputHandler* handler);
+ void ClosePort(KODI::JOYSTICK::IInputHandler* handler);
/*!
* \brief Map a list of devices to the available ports
@@ -72,14 +82,14 @@ namespace GAME
* attempt to honor that request.
*/
void MapDevices(const PERIPHERALS::PeripheralVector& devices,
- std::map<PERIPHERALS::PeripheralPtr, JOYSTICK::IInputHandler*>& deviceToPortMap);
+ std::map<PERIPHERALS::PeripheralPtr, KODI::JOYSTICK::IInputHandler*>& deviceToPortMap);
private:
- JOYSTICK::IInputHandler* AssignToPort(const PERIPHERALS::PeripheralPtr& device, bool checkPortNumber = true);
+ KODI::JOYSTICK::IInputHandler* AssignToPort(const PERIPHERALS::PeripheralPtr& device, bool checkPortNumber = true);
struct SPort
{
- JOYSTICK::IInputHandler* handler; // Input handler for this port
+ KODI::JOYSTICK::IInputHandler* handler; // Input handler for this port
unsigned int port; // Port number belonging to the game client
PERIPHERALS::PeripheralType requiredType;
void* device;
diff --git a/xbmc/games/ports/PortMapper.cpp b/xbmc/games/ports/PortMapper.cpp
index 2471c39a2b..282eb513ef 100644
--- a/xbmc/games/ports/PortMapper.cpp
+++ b/xbmc/games/ports/PortMapper.cpp
@@ -23,6 +23,7 @@
#include "peripherals/devices/Peripheral.h"
#include "peripherals/Peripherals.h"
+using namespace KODI;
using namespace GAME;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/games/ports/PortMapper.h b/xbmc/games/ports/PortMapper.h
index 60330039a2..4d14445812 100644
--- a/xbmc/games/ports/PortMapper.h
+++ b/xbmc/games/ports/PortMapper.h
@@ -24,7 +24,14 @@
#include <map>
-namespace JOYSTICK { class IInputHandler; }
+namespace KODI
+{
+namespace JOYSTICK
+{
+ class IInputHandler;
+}
+}
+
namespace GAME
{
class CPortMapper : public Observer
@@ -39,6 +46,6 @@ namespace GAME
private:
void ProcessPeripherals();
- std::map<PERIPHERALS::PeripheralPtr, JOYSTICK::IInputHandler*> m_portMap;
+ std::map<PERIPHERALS::PeripheralPtr, KODI::JOYSTICK::IInputHandler*> m_portMap;
};
}
diff --git a/xbmc/guilib/GUIMultiImage.cpp b/xbmc/guilib/GUIMultiImage.cpp
index 4d43531401..83b8839637 100644
--- a/xbmc/guilib/GUIMultiImage.cpp
+++ b/xbmc/guilib/GUIMultiImage.cpp
@@ -315,7 +315,7 @@ bool CGUIMultiImage::CMultiImageJob::DoWork()
URIUtils::AddSlashAtEnd(realPath);
CFileItemList items;
- CDirectory::GetDirectory(realPath, items, g_advancedSettings.m_pictureExtensions + "|.tbn|.dds", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_NO_FILE_INFO);
+ CDirectory::GetDirectory(realPath, items, g_advancedSettings.GetPictureExtensions()+ "|.tbn|.dds", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_NO_FILE_INFO);
for (int i=0; i < items.Size(); i++)
{
CFileItem* pItem = items[i].get();
diff --git a/xbmc/guilib/GUISliderControl.h b/xbmc/guilib/GUISliderControl.h
index 717be42376..196ef2586a 100644
--- a/xbmc/guilib/GUISliderControl.h
+++ b/xbmc/guilib/GUISliderControl.h
@@ -86,6 +86,7 @@ public:
void SetIntInterval(int iInterval);
void SetFloatInterval(float fInterval);
void SetType(int iType) { m_iType = iType; };
+ int GetType() const { return m_iType; }
virtual std::string GetDescription() const;
void SetTextValue(const std::string &textValue) { m_textValue = textValue; };
void SetAction(const std::string &action);
diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp
index 77ab06e490..9186b15893 100644
--- a/xbmc/guilib/GUIWindowManager.cpp
+++ b/xbmc/guilib/GUIWindowManager.cpp
@@ -995,6 +995,8 @@ bool CGUIWindowManager::OnAction(const CAction &action) const
break;
return false;
}
+ CLog::Log(LOGWARNING, "CGUIWindowManager - %s - ignoring action %i, because topmost modal dialog closing animation is running",
+ __FUNCTION__, action.GetID());
return true; // do nothing with the action until the anim is finished
}
lock.Enter();
diff --git a/xbmc/guilib/TextureFormats.h b/xbmc/guilib/TextureFormats.h
new file mode 100644
index 0000000000..ee8b68dc37
--- /dev/null
+++ b/xbmc/guilib/TextureFormats.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#define XB_FMT_MASK 0xffff ///< mask for format info - other flags are outside this
+#define XB_FMT_DXT_MASK 15
+#define XB_FMT_UNKNOWN 0
+#define XB_FMT_DXT1 1
+#define XB_FMT_DXT3 2
+#define XB_FMT_DXT5 4
+#define XB_FMT_DXT5_YCoCg 8
+#define XB_FMT_A8R8G8B8 16 // texture.xbt byte order (matches BGRA8)
+#define XB_FMT_A8 32
+#define XB_FMT_RGBA8 64
+#define XB_FMT_RGB8 128
+#define XB_FMT_OPAQUE 65536
diff --git a/xbmc/guilib/XBTF.h b/xbmc/guilib/XBTF.h
index 53dc6d997e..4e6499ad80 100644
--- a/xbmc/guilib/XBTF.h
+++ b/xbmc/guilib/XBTF.h
@@ -28,18 +28,7 @@
static const std::string XBTF_MAGIC = "XBTF";
static const std::string XBTF_VERSION = "2";
-#define XB_FMT_MASK 0xffff ///< mask for format info - other flags are outside this
-#define XB_FMT_DXT_MASK 15
-#define XB_FMT_UNKNOWN 0
-#define XB_FMT_DXT1 1
-#define XB_FMT_DXT3 2
-#define XB_FMT_DXT5 4
-#define XB_FMT_DXT5_YCoCg 8
-#define XB_FMT_A8R8G8B8 16 // texture.xbt byte order (matches BGRA8)
-#define XB_FMT_A8 32
-#define XB_FMT_RGBA8 64
-#define XB_FMT_RGB8 128
-#define XB_FMT_OPAQUE 65536
+#include "TextureFormats.h"
class CXBTFFrame
{
diff --git a/xbmc/guilib/imagefactory.cpp b/xbmc/guilib/imagefactory.cpp
index 1500dfdba0..beb9d79ccd 100644
--- a/xbmc/guilib/imagefactory.cpp
+++ b/xbmc/guilib/imagefactory.cpp
@@ -20,7 +20,15 @@
#include "imagefactory.h"
#include "guilib/FFmpegImage.h"
+#include "addons/BinaryAddonCache.h"
+#include "addons/ImageDecoder.h"
#include "utils/Mime.h"
+#include "utils/StringUtils.h"
+#include "ServiceBroker.h"
+
+#include <algorithm>
+
+using namespace ADDON;
IImage* ImageFactory::CreateLoader(const std::string& strFileName)
{
@@ -38,5 +46,20 @@ IImage* ImageFactory::CreateLoader(const CURL& url)
IImage* ImageFactory::CreateLoaderFromMimeType(const std::string& strMimeType)
{
+ VECADDONS codecs;
+ ADDON::CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache();
+ addonCache.GetAddons(codecs, ADDON::ADDON_IMAGEDECODER);
+ for (auto& codec : codecs)
+ {
+ std::shared_ptr<CImageDecoder> enc(std::static_pointer_cast<CImageDecoder>(codec));
+ std::vector<std::string> mime = StringUtils::Split(enc->GetMimetypes(), "|");
+ if (std::find(mime.begin(), mime.end(), strMimeType) != mime.end())
+ {
+ CImageDecoder* result = new CImageDecoder(*enc);
+ result->Create(strMimeType);
+ return result;
+ }
+ }
+
return new CFFmpegImage(strMimeType);
}
diff --git a/xbmc/input/Action.cpp b/xbmc/input/Action.cpp
new file mode 100644
index 0000000000..5bab5ae99f
--- /dev/null
+++ b/xbmc/input/Action.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2005-2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "Action.h"
+#include "ActionIDs.h"
+#include "ButtonTranslator.h"
+#include "Key.h"
+
+CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const std::string &name /* = "" */, unsigned int holdTime /*= 0*/)
+{
+ m_id = actionID;
+ m_amount[0] = amount1;
+ m_amount[1] = amount2;
+ for (unsigned int i = 2; i < max_amounts; i++)
+ m_amount[i] = 0;
+ m_name = name;
+ m_repeat = 0;
+ m_buttonCode = 0;
+ m_unicode = 0;
+ m_holdTime = holdTime;
+}
+
+CAction::CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name):
+ m_name(name)
+{
+ m_id = actionID;
+ m_amount[0] = posX;
+ m_amount[1] = posY;
+ m_amount[2] = offsetX;
+ m_amount[3] = offsetY;
+ for (unsigned int i = 4; i < max_amounts; i++)
+ m_amount[i] = 0;
+ m_repeat = 0;
+ m_buttonCode = 0;
+ m_unicode = 0;
+ m_holdTime = state;
+}
+
+CAction::CAction(int actionID, wchar_t unicode)
+{
+ m_id = actionID;
+ for (unsigned int i = 0; i < max_amounts; i++)
+ m_amount[i] = 0;
+ m_repeat = 0;
+ m_buttonCode = 0;
+ m_unicode = unicode;
+ m_holdTime = 0;
+}
+
+CAction::CAction(int actionID, const std::string &name, const CKey &key):
+ m_name(name)
+{
+ m_id = actionID;
+ m_amount[0] = 1; // digital button (could change this for repeat acceleration)
+ for (unsigned int i = 1; i < max_amounts; i++)
+ m_amount[i] = 0;
+ m_repeat = key.GetRepeat();
+ m_buttonCode = key.GetButtonCode();
+ m_unicode = 0;
+ m_holdTime = key.GetHeld();
+ // get the action amounts of the analog buttons
+ if (key.GetButtonCode() == KEY_BUTTON_LEFT_ANALOG_TRIGGER)
+ m_amount[0] = (float)key.GetLeftTrigger() / 255.0f;
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_ANALOG_TRIGGER)
+ m_amount[0] = (float)key.GetRightTrigger() / 255.0f;
+ else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK)
+ {
+ m_amount[0] = key.GetLeftThumbX();
+ m_amount[1] = key.GetLeftThumbY();
+ }
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK)
+ {
+ m_amount[0] = key.GetRightThumbX();
+ m_amount[1] = key.GetRightThumbY();
+ }
+ else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_UP)
+ m_amount[0] = key.GetLeftThumbY();
+ else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_DOWN)
+ m_amount[0] = -key.GetLeftThumbY();
+ else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_LEFT)
+ m_amount[0] = -key.GetLeftThumbX();
+ else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_RIGHT)
+ m_amount[0] = key.GetLeftThumbX();
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_UP)
+ m_amount[0] = key.GetRightThumbY();
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_DOWN)
+ m_amount[0] = -key.GetRightThumbY();
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_LEFT)
+ m_amount[0] = -key.GetRightThumbX();
+ else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_RIGHT)
+ m_amount[0] = key.GetRightThumbX();
+}
+
+CAction::CAction(int actionID, const std::string &name):
+ m_name(name)
+{
+ m_id = actionID;
+ for (unsigned int i = 0; i < max_amounts; i++)
+ m_amount[i] = 0;
+ m_repeat = 0;
+ m_buttonCode = 0;
+ m_unicode = 0;
+ m_holdTime = 0;
+}
+
+CAction& CAction::operator=(const CAction& rhs)
+{
+ if (this != &rhs)
+ {
+ m_id = rhs.m_id;
+ for (unsigned int i = 0; i < max_amounts; i++)
+ m_amount[i] = rhs.m_amount[i];
+ m_name = rhs.m_name;
+ m_repeat = rhs.m_repeat;
+ m_buttonCode = rhs.m_buttonCode;
+ m_unicode = rhs.m_unicode;
+ m_holdTime = rhs.m_holdTime;
+ m_text = rhs.m_text;
+ }
+ return *this;
+}
+
+bool CAction::IsMouse() const
+{
+ return (m_id >= ACTION_MOUSE_START && m_id <= ACTION_MOUSE_END);
+}
+
+bool CAction::IsGesture() const
+{
+ return (m_id >= ACTION_GESTURE_NOTIFY && m_id <= ACTION_GESTURE_END);
+}
+
+bool CAction::IsAnalog() const
+{
+ return CButtonTranslator::IsAnalog(m_id);
+}
diff --git a/xbmc/input/Action.h b/xbmc/input/Action.h
new file mode 100644
index 0000000000..e6941652a8
--- /dev/null
+++ b/xbmc/input/Action.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include <string>
+
+#ifndef SWIG
+
+class CKey;
+
+/*!
+ \ingroup actionkeys
+ \brief class encapsulating information regarding a particular user action to be sent to windows and controls
+ */
+class CAction
+{
+public:
+ CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const std::string &name = "", unsigned int holdTime = 0);
+ CAction(int actionID, wchar_t unicode);
+ CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name = "");
+ CAction(int actionID, const std::string &name, const CKey &key);
+ CAction(int actionID, const std::string &name);
+
+ CAction(const CAction& other) { *this = other; }
+ CAction& operator=(const CAction& rhs);
+
+ /*! \brief Identifier of the action
+ \return id of the action
+ */
+ int GetID() const { return m_id; };
+
+ /*! \brief Is this an action from the mouse
+ \return true if this is a mouse action, false otherwise
+ */
+ bool IsMouse() const;
+
+ bool IsGesture() const;
+
+ /*! \brief Human-readable name of the action
+ \return name of the action
+ */
+ const std::string &GetName() const { return m_name; };
+
+ /*! \brief Text of the action if any
+ \return text payload of this action.
+ */
+ const std::string &GetText() const { return m_text; };
+
+ /*! \brief Set the text payload of the action
+ \param text to be set
+ */
+ void SetText(const std::string &text) { m_text = text; };
+
+ /*! \brief Get an amount associated with this action
+ \param zero-based index of amount to retrieve, defaults to 0
+ \return an amount associated with this action
+ */
+ float GetAmount(unsigned int index = 0) const { return (index < max_amounts) ? m_amount[index] : 0; };
+
+ /*! \brief Unicode value associated with this action
+ \return unicode value associated with this action, for keyboard input.
+ */
+ wchar_t GetUnicode() const { return m_unicode; };
+
+ /*! \brief Time in ms that the key has been held
+ \return time that the key has been held down in ms.
+ */
+ unsigned int GetHoldTime() const { return m_holdTime; };
+
+ /*! \brief Time since last repeat in ms
+ \return time since last repeat in ms. Returns 0 if unknown.
+ */
+ float GetRepeat() const { return m_repeat; };
+
+ /*! \brief Button code that triggered this action
+ \return button code
+ */
+ unsigned int GetButtonCode() const { return m_buttonCode; };
+
+ bool IsAnalog() const;
+
+private:
+ int m_id;
+ std::string m_name;
+
+ static const unsigned int max_amounts = 4; // Must be at least 4.
+ float m_amount[max_amounts];
+
+ float m_repeat;
+ unsigned int m_holdTime;
+ unsigned int m_buttonCode;
+ wchar_t m_unicode;
+ std::string m_text;
+};
+
+#endif
diff --git a/xbmc/input/ActionIDs.h b/xbmc/input/ActionIDs.h
new file mode 100644
index 0000000000..986f275a53
--- /dev/null
+++ b/xbmc/input/ActionIDs.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2005-2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+/**
+ * \defgroup kodi_key_action_ids Action Id's
+ * \ingroup python_xbmcgui_window_cb
+ * \ingroup python_xbmcgui_action
+ * @{
+ * @brief Actions that we have defined.
+ */
+#define ACTION_NONE 0
+#define ACTION_MOVE_LEFT 1
+#define ACTION_MOVE_RIGHT 2
+#define ACTION_MOVE_UP 3
+#define ACTION_MOVE_DOWN 4
+#define ACTION_PAGE_UP 5
+#define ACTION_PAGE_DOWN 6
+#define ACTION_SELECT_ITEM 7
+#define ACTION_HIGHLIGHT_ITEM 8
+#define ACTION_PARENT_DIR 9
+#define ACTION_PREVIOUS_MENU 10
+#define ACTION_SHOW_INFO 11
+
+#define ACTION_PAUSE 12
+#define ACTION_STOP 13
+#define ACTION_NEXT_ITEM 14
+#define ACTION_PREV_ITEM 15
+#define ACTION_FORWARD 16 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
+#define ACTION_REWIND 17 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
+
+#define ACTION_SHOW_GUI 18 //!< toggle between GUI and movie or GUI and visualisation.
+#define ACTION_ASPECT_RATIO 19 //!< toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005
+#define ACTION_STEP_FORWARD 20 //!< seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_STEP_BACK 21 //!< seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_BIG_STEP_FORWARD 22 //!< seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_BIG_STEP_BACK 23 //!< seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_SHOW_OSD 24 //!< show/hide OSD. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_SHOW_SUBTITLES 25 //!< turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_NEXT_SUBTITLE 26 //!< switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_PLAYER_DEBUG 27 //!< show debug info for VideoPlayer
+#define ACTION_NEXT_PICTURE 28 //!< show next picture of slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_PREV_PICTURE 29 //!< show previous picture of slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_OUT 30 //!< zoom in picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_IN 31 //!< zoom out picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_TOGGLE_SOURCE_DEST 32 //!< used to toggle between source view and destination view. Can be used in myfiles.xml window id=3
+#define ACTION_SHOW_PLAYLIST 33 //!< used to toggle between current view and playlist view. Can b used in all mymusic xml files
+#define ACTION_QUEUE_ITEM 34 //!< used to queue a item to the playlist. Can b used in all mymusic xml files
+#define ACTION_REMOVE_ITEM 35 //!< not used anymore
+#define ACTION_SHOW_FULLSCREEN 36 //!< not used anymore
+#define ACTION_ZOOM_LEVEL_NORMAL 37 //!< zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_1 38 //!< zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_2 39 //!< zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_3 40 //!< zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_4 41 //!< zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_5 42 //!< zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_6 43 //!< zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_7 44 //!< zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_8 45 //!< zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007
+#define ACTION_ZOOM_LEVEL_9 46 //!< zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007
+
+#define ACTION_CALIBRATE_SWAP_ARROWS 47 //!< select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11
+#define ACTION_CALIBRATE_RESET 48 //!< reset calibration to defaults. Can b used in: `settingsScreenCalibration.xml` windowid=11/settingsUICalibration.xml windowid=10
+#define ACTION_ANALOG_MOVE 49 //!< analog thumbstick move. Can b used in: `slideshow.xml` windowid=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10
+ //!< @note see also ACTION_ANALOG_MOVE_X, ACTION_ANALOG_MOVE_Y
+#define ACTION_ROTATE_PICTURE_CW 50 //!< rotate current picture clockwise during slideshow. Can be used in slideshow.xml window id=2007
+#define ACTION_ROTATE_PICTURE_CCW 51 //!< rotate current picture counterclockwise during slideshow. Can be used in slideshow.xml window id=2007
+
+#define ACTION_SUBTITLE_DELAY_MIN 52 //!< Decrease subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_SUBTITLE_DELAY_PLUS 53 //!< Increase subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_AUDIO_DELAY_MIN 54 //!< Increase avsync delay. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_AUDIO_DELAY_PLUS 55 //!< Decrease avsync delay. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_AUDIO_NEXT_LANGUAGE 56 //!< Select next language in movie. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_CHANGE_RESOLUTION 57 //!< switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11
+
+#define REMOTE_0 58 //!< remote keys 0-9. are used by multiple windows
+#define REMOTE_1 59 //!< for example in videoFullScreen.xml window id=2005 you can
+#define REMOTE_2 60 //!< enter time (mmss) to jump to particular point in the movie
+#define REMOTE_3 61
+#define REMOTE_4 62 //!< with spincontrols you can enter 3digit number to quickly set
+#define REMOTE_5 63 //!< spincontrol to desired value
+#define REMOTE_6 64
+#define REMOTE_7 65
+#define REMOTE_8 66
+#define REMOTE_9 67
+
+#define ACTION_PLAY 68 //!< Unused at the moment
+#define ACTION_PLAYER_PROCESS_INFO 69 //!< show player process info (video decoder, pixel format, pvr signal strength and the like
+#define ACTION_SMALL_STEP_BACK 76 //!< jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005
+
+#define ACTION_PLAYER_FORWARD 77 //!< FF in current file played. global action, can be used anywhere
+#define ACTION_PLAYER_REWIND 78 //!< RW in current file played. global action, can be used anywhere
+#define ACTION_PLAYER_PLAY 79 //!< Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere
+
+#define ACTION_DELETE_ITEM 80 //!< delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25
+#define ACTION_COPY_ITEM 81 //!< copy current selected item. Can be used in myfiles.xml window id=3
+#define ACTION_MOVE_ITEM 82 //!< move current selected item. Can be used in myfiles.xml window id=3
+#define ACTION_TAKE_SCREENSHOT 85 //!< take a screenshot
+#define ACTION_RENAME_ITEM 87 //!< rename item
+
+#define ACTION_VOLUME_UP 88
+#define ACTION_VOLUME_DOWN 89
+#define ACTION_VOLAMP 90
+#define ACTION_MUTE 91
+#define ACTION_NAV_BACK 92
+#define ACTION_VOLAMP_UP 93
+#define ACTION_VOLAMP_DOWN 94
+
+#define ACTION_CREATE_EPISODE_BOOKMARK 95 //!< Creates an episode bookmark on the currently playing video file containing more than one episode
+#define ACTION_CREATE_BOOKMARK 96 //!< Creates a bookmark of the currently playing video file
+
+#define ACTION_CHAPTER_OR_BIG_STEP_FORWARD 97 //!< Goto the next chapter, if not available perform a big step forward
+#define ACTION_CHAPTER_OR_BIG_STEP_BACK 98 //!< Goto the previous chapter, if not available perform a big step back
+
+#define ACTION_CYCLE_SUBTITLE 99 //!< switch to next subtitle of movie, but will not enable/disable the subtitles. Can be used in videoFullScreen.xml window id=2005
+
+#define ACTION_MOUSE_START 100
+#define ACTION_MOUSE_LEFT_CLICK 100
+#define ACTION_MOUSE_RIGHT_CLICK 101
+#define ACTION_MOUSE_MIDDLE_CLICK 102
+#define ACTION_MOUSE_DOUBLE_CLICK 103
+#define ACTION_MOUSE_WHEEL_UP 104
+#define ACTION_MOUSE_WHEEL_DOWN 105
+#define ACTION_MOUSE_DRAG 106
+#define ACTION_MOUSE_MOVE 107
+#define ACTION_MOUSE_LONG_CLICK 108
+#define ACTION_MOUSE_END 109
+
+#define ACTION_BACKSPACE 110
+#define ACTION_SCROLL_UP 111
+#define ACTION_SCROLL_DOWN 112
+#define ACTION_ANALOG_FORWARD 113
+#define ACTION_ANALOG_REWIND 114
+
+#define ACTION_MOVE_ITEM_UP 115 //!< move item up in playlist
+#define ACTION_MOVE_ITEM_DOWN 116 //!< move item down in playlist
+#define ACTION_CONTEXT_MENU 117 //!< pops up the context menu
+
+// stuff for virtual keyboard shortcuts
+#define ACTION_SHIFT 118 //!< stuff for virtual keyboard shortcuts
+#define ACTION_SYMBOLS 119 //!< stuff for virtual keyboard shortcuts
+#define ACTION_CURSOR_LEFT 120 //!< stuff for virtual keyboard shortcuts
+#define ACTION_CURSOR_RIGHT 121 //!< stuff for virtual keyboard shortcuts
+
+#define ACTION_BUILT_IN_FUNCTION 122
+
+#define ACTION_SHOW_OSD_TIME 123 //!< displays current time, can be used in videoFullScreen.xml window id=2005
+#define ACTION_ANALOG_SEEK_FORWARD 124 //!< seeks forward, and displays the seek bar.
+#define ACTION_ANALOG_SEEK_BACK 125 //!< seeks backward, and displays the seek bar.
+
+#define ACTION_VIS_PRESET_SHOW 126
+#define ACTION_VIS_PRESET_NEXT 128
+#define ACTION_VIS_PRESET_PREV 129
+#define ACTION_VIS_PRESET_LOCK 130
+#define ACTION_VIS_PRESET_RANDOM 131
+#define ACTION_VIS_RATE_PRESET_PLUS 132
+#define ACTION_VIS_RATE_PRESET_MINUS 133
+
+#define ACTION_SHOW_VIDEOMENU 134
+#define ACTION_ENTER 135
+
+#define ACTION_INCREASE_RATING 136
+#define ACTION_DECREASE_RATING 137
+
+#define ACTION_NEXT_SCENE 138 //!< switch to next scene/cutpoint in movie
+#define ACTION_PREV_SCENE 139 //!< switch to previous scene/cutpoint in movie
+
+#define ACTION_NEXT_LETTER 140 //!< jump through a list or container by letter
+#define ACTION_PREV_LETTER 141
+
+#define ACTION_JUMP_SMS2 142 //!< jump direct to a particular letter using SMS-style input
+#define ACTION_JUMP_SMS3 143
+#define ACTION_JUMP_SMS4 144
+#define ACTION_JUMP_SMS5 145
+#define ACTION_JUMP_SMS6 146
+#define ACTION_JUMP_SMS7 147
+#define ACTION_JUMP_SMS8 148
+#define ACTION_JUMP_SMS9 149
+
+#define ACTION_FILTER_CLEAR 150
+#define ACTION_FILTER_SMS2 151
+#define ACTION_FILTER_SMS3 152
+#define ACTION_FILTER_SMS4 153
+#define ACTION_FILTER_SMS5 154
+#define ACTION_FILTER_SMS6 155
+#define ACTION_FILTER_SMS7 156
+#define ACTION_FILTER_SMS8 157
+#define ACTION_FILTER_SMS9 158
+
+#define ACTION_FIRST_PAGE 159
+#define ACTION_LAST_PAGE 160
+
+#define ACTION_AUDIO_DELAY 161
+#define ACTION_SUBTITLE_DELAY 162
+#define ACTION_MENU 163
+
+#define ACTION_SET_RATING 164
+
+#define ACTION_RECORD 170
+
+#define ACTION_PASTE 180
+#define ACTION_NEXT_CONTROL 181
+#define ACTION_PREV_CONTROL 182
+#define ACTION_CHANNEL_SWITCH 183
+#define ACTION_CHANNEL_UP 184
+#define ACTION_CHANNEL_DOWN 185
+#define ACTION_NEXT_CHANNELGROUP 186
+#define ACTION_PREVIOUS_CHANNELGROUP 187
+#define ACTION_PVR_PLAY 188
+#define ACTION_PVR_PLAY_TV 189
+#define ACTION_PVR_PLAY_RADIO 190
+#define ACTION_PVR_SHOW_TIMER_RULE 191
+
+#define ACTION_TOGGLE_FULLSCREEN 199 //!< switch 2 desktop resolution
+#define ACTION_TOGGLE_WATCHED 200 //!< Toggle watched status (videos)
+#define ACTION_SCAN_ITEM 201 //!< scan item
+#define ACTION_TOGGLE_DIGITAL_ANALOG 202 //!< switch digital <-> analog
+#define ACTION_RELOAD_KEYMAPS 203 //!< reloads CButtonTranslator's keymaps
+#define ACTION_GUIPROFILE_BEGIN 204 //!< start the GUIControlProfiler running
+
+#define ACTION_TELETEXT_RED 215 //!< Teletext Color button <b>Red</b> to control TopText
+#define ACTION_TELETEXT_GREEN 216 //!< Teletext Color button <b>Green</b> to control TopText
+#define ACTION_TELETEXT_YELLOW 217 //!< Teletext Color button <b>Yellow</b> to control TopText
+#define ACTION_TELETEXT_BLUE 218 //!< Teletext Color button <b>Blue</b> to control TopText
+
+#define ACTION_INCREASE_PAR 219
+#define ACTION_DECREASE_PAR 220
+
+#define ACTION_VSHIFT_UP 227 //!< shift up video image in VideoPlayer
+#define ACTION_VSHIFT_DOWN 228 //!< shift down video image in VideoPlayer
+
+#define ACTION_PLAYER_PLAYPAUSE 229 //!< Play/pause. If playing it pauses, if paused it plays.
+
+#define ACTION_SUBTITLE_VSHIFT_UP 230 //!< shift up subtitles in VideoPlayer
+#define ACTION_SUBTITLE_VSHIFT_DOWN 231 //!< shift down subtitles in VideoPlayer
+#define ACTION_SUBTITLE_ALIGN 232 //!< toggle vertical alignment of subtitles
+
+#define ACTION_FILTER 233
+
+#define ACTION_SWITCH_PLAYER 234
+
+#define ACTION_STEREOMODE_NEXT 235
+#define ACTION_STEREOMODE_PREVIOUS 236
+#define ACTION_STEREOMODE_TOGGLE 237 //!< turns 3d mode on/off
+#define ACTION_STEREOMODE_SELECT 238
+#define ACTION_STEREOMODE_TOMONO 239
+#define ACTION_STEREOMODE_SET 240
+
+#define ACTION_SETTINGS_RESET 241
+#define ACTION_SETTINGS_LEVEL_CHANGE 242
+
+#define ACTION_TRIGGER_OSD 243 //!< show autoclosing OSD. Can b used in videoFullScreen.xml window id=2005
+#define ACTION_INPUT_TEXT 244
+#define ACTION_VOLUME_SET 245
+#define ACTION_TOGGLE_COMMSKIP 246
+
+#define ACTION_TOUCH_TAP 401 //!< touch actions
+#define ACTION_TOUCH_TAP_TEN 410 //!< touch actions
+#define ACTION_TOUCH_LONGPRESS 411 //!< touch actions
+#define ACTION_TOUCH_LONGPRESS_TEN 420 //!< touch actions
+
+#define ACTION_GESTURE_NOTIFY 500
+#define ACTION_GESTURE_BEGIN 501
+#define ACTION_GESTURE_ZOOM 502 //!< sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0)
+#define ACTION_GESTURE_ROTATE 503
+#define ACTION_GESTURE_PAN 504
+
+#define ACTION_GESTURE_SWIPE_LEFT 511
+#define ACTION_GESTURE_SWIPE_LEFT_TEN 520
+#define ACTION_GESTURE_SWIPE_RIGHT 521
+#define ACTION_GESTURE_SWIPE_RIGHT_TEN 530
+#define ACTION_GESTURE_SWIPE_UP 531
+#define ACTION_GESTURE_SWIPE_UP_TEN 540
+#define ACTION_GESTURE_SWIPE_DOWN 541
+#define ACTION_GESTURE_SWIPE_DOWN_TEN 550
+// 5xx is reserved for additional gesture actions
+#define ACTION_GESTURE_END 599
+
+// other, non-gesture actions
+#define ACTION_ANALOG_MOVE_X 601 //!< analog thumbstick move, horizontal axis; see ACTION_ANALOG_MOVE
+#define ACTION_ANALOG_MOVE_Y 602 //!< analog thumbstick move, vertical axis; see ACTION_ANALOG_MOVE
+//@}
+
+// The NOOP action can be specified to disable an input event. This is
+// useful in user keyboard.xml etc to disable actions specified in the
+// system mappings. ERROR action is used to play an error sound
+#define ACTION_ERROR 998
+#define ACTION_NOOP 999
diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp
index 67455196f8..cc628c0316 100644
--- a/xbmc/input/ButtonTranslator.cpp
+++ b/xbmc/input/ButtonTranslator.cpp
@@ -911,7 +911,7 @@ CAction CButtonTranslator::GetGlobalAction(const CKey &key)
return GetAction(-1, key, true);
}
-bool CButtonTranslator::HasLonpressMapping(int window, const CKey &key)
+bool CButtonTranslator::HasLongpressMapping(int window, const CKey &key)
{
std::map<int, buttonMap>::const_iterator it = m_translatorMap.find(window);
if (it != m_translatorMap.end())
@@ -940,11 +940,11 @@ bool CButtonTranslator::HasLonpressMapping(int window, const CKey &key)
{
// first check if we have a fallback for the window
int fallbackWindow = GetFallbackWindow(window);
- if (fallbackWindow > -1 && HasLonpressMapping(fallbackWindow, key))
+ if (fallbackWindow > -1 && HasLongpressMapping(fallbackWindow, key))
return true;
// fallback to default section
- return HasLonpressMapping(-1, key);
+ return HasLongpressMapping(-1, key);
}
return false;
diff --git a/xbmc/input/ButtonTranslator.h b/xbmc/input/ButtonTranslator.h
index 1cbac59453..0ccd82ebc6 100644
--- a/xbmc/input/ButtonTranslator.h
+++ b/xbmc/input/ButtonTranslator.h
@@ -79,7 +79,7 @@ public:
\param key to search a mapping for
\return true if a longpress mapping exists
*/
- bool HasLonpressMapping(int window, const CKey &key);
+ bool HasLongpressMapping(int window, const CKey &key);
/*! \brief Obtain the action configured for a given window and key
\param window the window id
diff --git a/xbmc/input/CMakeLists.txt b/xbmc/input/CMakeLists.txt
index a961423028..a1fec26d31 100644
--- a/xbmc/input/CMakeLists.txt
+++ b/xbmc/input/CMakeLists.txt
@@ -1,4 +1,5 @@
-set(SOURCES ButtonTranslator.cpp
+set(SOURCES Action.cpp
+ ButtonTranslator.cpp
InertialScrollingHandler.cpp
InputCodingTableBaiduPY.cpp
InputCodingTableBasePY.cpp
@@ -12,7 +13,9 @@ set(SOURCES ButtonTranslator.cpp
MouseStat.cpp
XBMC_keytable.cpp)
-set(HEADERS ButtonTranslator.h
+set(HEADERS Action.h
+ ActionIDs.h
+ ButtonTranslator.h
InertialScrollingHandler.h
InputCodingTable.h
InputCodingTableBaiduPY.h
diff --git a/xbmc/input/InputManager.cpp b/xbmc/input/InputManager.cpp
index 4f1663fed9..b24387ec82 100644
--- a/xbmc/input/InputManager.cpp
+++ b/xbmc/input/InputManager.cpp
@@ -70,7 +70,8 @@
using EVENTSERVER::CEventServer;
#endif
-using namespace KODI::MESSAGING;
+using namespace KODI;
+using namespace MESSAGING;
using PERIPHERALS::CPeripherals;
CInputManager::CInputManager() :
@@ -368,7 +369,7 @@ bool CInputManager::OnEvent(XBMC_Event& newEvent)
// Do not repeat long presses
break;
}
- if (!CButtonTranslator::GetInstance().HasLonpressMapping(g_windowManager.GetActiveWindowID(), key))
+ if (!CButtonTranslator::GetInstance().HasLongpressMapping(g_windowManager.GetActiveWindowID(), key))
{
m_LastKey.Reset();
OnKey(key);
diff --git a/xbmc/input/InputManager.h b/xbmc/input/InputManager.h
index ba31cfcbf3..f161315179 100644
--- a/xbmc/input/InputManager.h
+++ b/xbmc/input/InputManager.h
@@ -39,6 +39,8 @@
class CKey;
+namespace KODI
+{
namespace KEYBOARD
{
class IKeyboardHandler;
@@ -50,6 +52,7 @@ namespace MOUSE
class IMouseDriverHandler;
class IMouseInputHandler;
}
+}
/// \addtogroup input
/// \{
@@ -244,13 +247,13 @@ public:
*
* \param handler The handler to call on keyboard input.
*/
- void RegisterKeyboardHandler(KEYBOARD::IKeyboardHandler* handler);
+ void RegisterKeyboardHandler(KODI::KEYBOARD::IKeyboardHandler* handler);
/*! \brief Unregisters handler from keyboard input.
*
* \param[in] handler The handler to unregister from keyboard input.
*/
- void UnregisterKeyboardHandler(KEYBOARD::IKeyboardHandler* handler);
+ void UnregisterKeyboardHandler(KODI::KEYBOARD::IKeyboardHandler* handler);
/*! \brief Registers a handler to be called on mouse input (e.g a game client).
*
@@ -258,13 +261,13 @@ public:
* \return[in] The controller ID that serves as a context for incoming events.
* \sa IMouseButtonMap
*/
- std::string RegisterMouseHandler(MOUSE::IMouseInputHandler* handler);
+ std::string RegisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler);
/*! \brief Unregisters handler from mouse input.
*
* \param[in] handler The handler to unregister from mouse input.
*/
- void UnregisterMouseHandler(MOUSE::IMouseInputHandler* handler);
+ void UnregisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler);
private:
@@ -316,18 +319,18 @@ private:
std::vector<CAction> m_queuedActions;
CCriticalSection m_actionMutex;
- std::vector<KEYBOARD::IKeyboardHandler*> m_keyboardHandlers;
+ std::vector<KODI::KEYBOARD::IKeyboardHandler*> m_keyboardHandlers;
struct MouseHandlerHandle
{
- MOUSE::IMouseInputHandler* inputHandler;
- std::unique_ptr<MOUSE::IMouseDriverHandler> driverHandler;
+ KODI::MOUSE::IMouseInputHandler* inputHandler;
+ std::unique_ptr<KODI::MOUSE::IMouseDriverHandler> driverHandler;
};
std::vector<MouseHandlerHandle> m_mouseHandlers;
- std::unique_ptr<MOUSE::IMouseButtonMap> m_mouseButtonMap;
+ std::unique_ptr<KODI::MOUSE::IMouseButtonMap> m_mouseButtonMap;
- std::unique_ptr<KEYBOARD::IKeyboardHandler> m_keyboardEasterEgg;
+ std::unique_ptr<KODI::KEYBOARD::IKeyboardHandler> m_keyboardEasterEgg;
};
/// \}
diff --git a/xbmc/input/Key.cpp b/xbmc/input/Key.cpp
index a200663332..aa428ecb9e 100644
--- a/xbmc/input/Key.cpp
+++ b/xbmc/input/Key.cpp
@@ -20,7 +20,6 @@
#include "system.h"
#include "input/Key.h"
-#include "input/ButtonTranslator.h"
CKey::CKey(void)
{
@@ -171,122 +170,3 @@ void CKey::SetFromService(bool fromService)
m_fromService = fromService;
}
-
-CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const std::string &name /* = "" */, unsigned int holdTime /*= 0*/)
-{
- m_id = actionID;
- m_amount[0] = amount1;
- m_amount[1] = amount2;
- for (unsigned int i = 2; i < max_amounts; i++)
- m_amount[i] = 0;
- m_name = name;
- m_repeat = 0;
- m_buttonCode = 0;
- m_unicode = 0;
- m_holdTime = holdTime;
-}
-
-CAction::CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name):
- m_name(name)
-{
- m_id = actionID;
- m_amount[0] = posX;
- m_amount[1] = posY;
- m_amount[2] = offsetX;
- m_amount[3] = offsetY;
- for (unsigned int i = 4; i < max_amounts; i++)
- m_amount[i] = 0;
- m_repeat = 0;
- m_buttonCode = 0;
- m_unicode = 0;
- m_holdTime = state;
-}
-
-CAction::CAction(int actionID, wchar_t unicode)
-{
- m_id = actionID;
- for (unsigned int i = 0; i < max_amounts; i++)
- m_amount[i] = 0;
- m_repeat = 0;
- m_buttonCode = 0;
- m_unicode = unicode;
- m_holdTime = 0;
-}
-
-CAction::CAction(int actionID, const std::string &name, const CKey &key):
- m_name(name)
-{
- m_id = actionID;
- m_amount[0] = 1; // digital button (could change this for repeat acceleration)
- for (unsigned int i = 1; i < max_amounts; i++)
- m_amount[i] = 0;
- m_repeat = key.GetRepeat();
- m_buttonCode = key.GetButtonCode();
- m_unicode = 0;
- m_holdTime = key.GetHeld();
- // get the action amounts of the analog buttons
- if (key.GetButtonCode() == KEY_BUTTON_LEFT_ANALOG_TRIGGER)
- m_amount[0] = (float)key.GetLeftTrigger() / 255.0f;
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_ANALOG_TRIGGER)
- m_amount[0] = (float)key.GetRightTrigger() / 255.0f;
- else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK)
- {
- m_amount[0] = key.GetLeftThumbX();
- m_amount[1] = key.GetLeftThumbY();
- }
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK)
- {
- m_amount[0] = key.GetRightThumbX();
- m_amount[1] = key.GetRightThumbY();
- }
- else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_UP)
- m_amount[0] = key.GetLeftThumbY();
- else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_DOWN)
- m_amount[0] = -key.GetLeftThumbY();
- else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_LEFT)
- m_amount[0] = -key.GetLeftThumbX();
- else if (key.GetButtonCode() == KEY_BUTTON_LEFT_THUMB_STICK_RIGHT)
- m_amount[0] = key.GetLeftThumbX();
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_UP)
- m_amount[0] = key.GetRightThumbY();
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_DOWN)
- m_amount[0] = -key.GetRightThumbY();
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_LEFT)
- m_amount[0] = -key.GetRightThumbX();
- else if (key.GetButtonCode() == KEY_BUTTON_RIGHT_THUMB_STICK_RIGHT)
- m_amount[0] = key.GetRightThumbX();
-}
-
-CAction::CAction(int actionID, const std::string &name):
- m_name(name)
-{
- m_id = actionID;
- for (unsigned int i = 0; i < max_amounts; i++)
- m_amount[i] = 0;
- m_repeat = 0;
- m_buttonCode = 0;
- m_unicode = 0;
- m_holdTime = 0;
-}
-
-CAction& CAction::operator=(const CAction& rhs)
-{
- if (this != &rhs)
- {
- m_id = rhs.m_id;
- for (unsigned int i = 0; i < max_amounts; i++)
- m_amount[i] = rhs.m_amount[i];
- m_name = rhs.m_name;
- m_repeat = rhs.m_repeat;
- m_buttonCode = rhs.m_buttonCode;
- m_unicode = rhs.m_unicode;
- m_holdTime = rhs.m_holdTime;
- m_text = rhs.m_text;
- }
- return *this;
-}
-
-bool CAction::IsAnalog() const
-{
- return CButtonTranslator::IsAnalog(m_id);
-}
diff --git a/xbmc/input/Key.h b/xbmc/input/Key.h
index bdc478cbd5..9836315721 100644
--- a/xbmc/input/Key.h
+++ b/xbmc/input/Key.h
@@ -24,6 +24,10 @@
*
*/
+//! @todo Remove dependence on CAction
+#include "Action.h"
+#include "ActionIDs.h"
+
#include <string>
#include <stdint.h>
@@ -135,292 +139,6 @@
#define KEY_INVALID 0xFFFF
-// actions that we have defined...
-/**
- * \defgroup kodi_key_action_ids Action Id's
- * \ingroup python_xbmcgui_window_cb
- * \ingroup python_xbmcgui_action
- * @{
- * @brief Actions that we have defined.
- */
-#define ACTION_NONE 0
-#define ACTION_MOVE_LEFT 1
-#define ACTION_MOVE_RIGHT 2
-#define ACTION_MOVE_UP 3
-#define ACTION_MOVE_DOWN 4
-#define ACTION_PAGE_UP 5
-#define ACTION_PAGE_DOWN 6
-#define ACTION_SELECT_ITEM 7
-#define ACTION_HIGHLIGHT_ITEM 8
-#define ACTION_PARENT_DIR 9
-#define ACTION_PREVIOUS_MENU 10
-#define ACTION_SHOW_INFO 11
-
-#define ACTION_PAUSE 12
-#define ACTION_STOP 13
-#define ACTION_NEXT_ITEM 14
-#define ACTION_PREV_ITEM 15
-#define ACTION_FORWARD 16 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
-#define ACTION_REWIND 17 //!< Can be used to specify specific action in a window, Playback control is handled in ACTION_PLAYER_*
-
-#define ACTION_SHOW_GUI 18 //!< toggle between GUI and movie or GUI and visualisation.
-#define ACTION_ASPECT_RATIO 19 //!< toggle quick-access zoom modes. Can b used in videoFullScreen.zml window id=2005
-#define ACTION_STEP_FORWARD 20 //!< seek +1% in the movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_STEP_BACK 21 //!< seek -1% in the movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_BIG_STEP_FORWARD 22 //!< seek +10% in the movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_BIG_STEP_BACK 23 //!< seek -10% in the movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_SHOW_OSD 24 //!< show/hide OSD. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_SHOW_SUBTITLES 25 //!< turn subtitles on/off. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_NEXT_SUBTITLE 26 //!< switch to next subtitle of movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_PLAYER_DEBUG 27 //!< show debug info for VideoPlayer
-#define ACTION_NEXT_PICTURE 28 //!< show next picture of slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_PREV_PICTURE 29 //!< show previous picture of slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_OUT 30 //!< zoom in picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_IN 31 //!< zoom out picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_TOGGLE_SOURCE_DEST 32 //!< used to toggle between source view and destination view. Can be used in myfiles.xml window id=3
-#define ACTION_SHOW_PLAYLIST 33 //!< used to toggle between current view and playlist view. Can b used in all mymusic xml files
-#define ACTION_QUEUE_ITEM 34 //!< used to queue a item to the playlist. Can b used in all mymusic xml files
-#define ACTION_REMOVE_ITEM 35 //!< not used anymore
-#define ACTION_SHOW_FULLSCREEN 36 //!< not used anymore
-#define ACTION_ZOOM_LEVEL_NORMAL 37 //!< zoom 1x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_1 38 //!< zoom 2x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_2 39 //!< zoom 3x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_3 40 //!< zoom 4x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_4 41 //!< zoom 5x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_5 42 //!< zoom 6x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_6 43 //!< zoom 7x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_7 44 //!< zoom 8x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_8 45 //!< zoom 9x picture during slideshow. Can b used in slideshow.xml window id=2007
-#define ACTION_ZOOM_LEVEL_9 46 //!< zoom 10x picture during slideshow. Can b used in slideshow.xml window id=2007
-
-#define ACTION_CALIBRATE_SWAP_ARROWS 47 //!< select next arrow. Can b used in: settingsScreenCalibration.xml windowid=11
-#define ACTION_CALIBRATE_RESET 48 //!< reset calibration to defaults. Can b used in: `settingsScreenCalibration.xml` windowid=11/settingsUICalibration.xml windowid=10
-#define ACTION_ANALOG_MOVE 49 //!< analog thumbstick move. Can b used in: `slideshow.xml` windowid=2007/settingsScreenCalibration.xml windowid=11/settingsUICalibration.xml windowid=10
- //!< @note see also ACTION_ANALOG_MOVE_X, ACTION_ANALOG_MOVE_Y
-#define ACTION_ROTATE_PICTURE_CW 50 //!< rotate current picture clockwise during slideshow. Can be used in slideshow.xml window id=2007
-#define ACTION_ROTATE_PICTURE_CCW 51 //!< rotate current picture counterclockwise during slideshow. Can be used in slideshow.xml window id=2007
-
-#define ACTION_SUBTITLE_DELAY_MIN 52 //!< Decrease subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_SUBTITLE_DELAY_PLUS 53 //!< Increase subtitle/movie Delay. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_AUDIO_DELAY_MIN 54 //!< Increase avsync delay. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_AUDIO_DELAY_PLUS 55 //!< Decrease avsync delay. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_AUDIO_NEXT_LANGUAGE 56 //!< Select next language in movie. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_CHANGE_RESOLUTION 57 //!< switch 2 next resolution. Can b used during screen calibration settingsScreenCalibration.xml windowid=11
-
-#define REMOTE_0 58 //!< remote keys 0-9. are used by multiple windows
-#define REMOTE_1 59 //!< for example in videoFullScreen.xml window id=2005 you can
-#define REMOTE_2 60 //!< enter time (mmss) to jump to particular point in the movie
-#define REMOTE_3 61
-#define REMOTE_4 62 //!< with spincontrols you can enter 3digit number to quickly set
-#define REMOTE_5 63 //!< spincontrol to desired value
-#define REMOTE_6 64
-#define REMOTE_7 65
-#define REMOTE_8 66
-#define REMOTE_9 67
-
-#define ACTION_PLAY 68 //!< Unused at the moment
-#define ACTION_PLAYER_PROCESS_INFO 69 //!< show player process info (video decoder, pixel format, pvr signal strength and the like
-#define ACTION_SMALL_STEP_BACK 76 //!< jumps a few seconds back during playback of movie. Can b used in videoFullScreen.xml window id=2005
-
-#define ACTION_PLAYER_FORWARD 77 //!< FF in current file played. global action, can be used anywhere
-#define ACTION_PLAYER_REWIND 78 //!< RW in current file played. global action, can be used anywhere
-#define ACTION_PLAYER_PLAY 79 //!< Play current song. Unpauses song and sets playspeed to 1x. global action, can be used anywhere
-
-#define ACTION_DELETE_ITEM 80 //!< delete current selected item. Can be used in myfiles.xml window id=3 and in myvideoTitle.xml window id=25
-#define ACTION_COPY_ITEM 81 //!< copy current selected item. Can be used in myfiles.xml window id=3
-#define ACTION_MOVE_ITEM 82 //!< move current selected item. Can be used in myfiles.xml window id=3
-#define ACTION_TAKE_SCREENSHOT 85 //!< take a screenshot
-#define ACTION_RENAME_ITEM 87 //!< rename item
-
-#define ACTION_VOLUME_UP 88
-#define ACTION_VOLUME_DOWN 89
-#define ACTION_VOLAMP 90
-#define ACTION_MUTE 91
-#define ACTION_NAV_BACK 92
-#define ACTION_VOLAMP_UP 93
-#define ACTION_VOLAMP_DOWN 94
-
-#define ACTION_CREATE_EPISODE_BOOKMARK 95 //!< Creates an episode bookmark on the currently playing video file containing more than one episode
-#define ACTION_CREATE_BOOKMARK 96 //!< Creates a bookmark of the currently playing video file
-
-#define ACTION_CHAPTER_OR_BIG_STEP_FORWARD 97 //!< Goto the next chapter, if not available perform a big step forward
-#define ACTION_CHAPTER_OR_BIG_STEP_BACK 98 //!< Goto the previous chapter, if not available perform a big step back
-
-#define ACTION_CYCLE_SUBTITLE 99 //!< switch to next subtitle of movie, but will not enable/disable the subtitles. Can be used in videoFullScreen.xml window id=2005
-
-#define ACTION_MOUSE_START 100
-#define ACTION_MOUSE_LEFT_CLICK 100
-#define ACTION_MOUSE_RIGHT_CLICK 101
-#define ACTION_MOUSE_MIDDLE_CLICK 102
-#define ACTION_MOUSE_DOUBLE_CLICK 103
-#define ACTION_MOUSE_WHEEL_UP 104
-#define ACTION_MOUSE_WHEEL_DOWN 105
-#define ACTION_MOUSE_DRAG 106
-#define ACTION_MOUSE_MOVE 107
-#define ACTION_MOUSE_LONG_CLICK 108
-#define ACTION_MOUSE_END 109
-
-#define ACTION_BACKSPACE 110
-#define ACTION_SCROLL_UP 111
-#define ACTION_SCROLL_DOWN 112
-#define ACTION_ANALOG_FORWARD 113
-#define ACTION_ANALOG_REWIND 114
-
-#define ACTION_MOVE_ITEM_UP 115 //!< move item up in playlist
-#define ACTION_MOVE_ITEM_DOWN 116 //!< move item down in playlist
-#define ACTION_CONTEXT_MENU 117 //!< pops up the context menu
-
-// stuff for virtual keyboard shortcuts
-#define ACTION_SHIFT 118 //!< stuff for virtual keyboard shortcuts
-#define ACTION_SYMBOLS 119 //!< stuff for virtual keyboard shortcuts
-#define ACTION_CURSOR_LEFT 120 //!< stuff for virtual keyboard shortcuts
-#define ACTION_CURSOR_RIGHT 121 //!< stuff for virtual keyboard shortcuts
-
-#define ACTION_BUILT_IN_FUNCTION 122
-
-#define ACTION_SHOW_OSD_TIME 123 //!< displays current time, can be used in videoFullScreen.xml window id=2005
-#define ACTION_ANALOG_SEEK_FORWARD 124 //!< seeks forward, and displays the seek bar.
-#define ACTION_ANALOG_SEEK_BACK 125 //!< seeks backward, and displays the seek bar.
-
-#define ACTION_VIS_PRESET_SHOW 126
-#define ACTION_VIS_PRESET_NEXT 128
-#define ACTION_VIS_PRESET_PREV 129
-#define ACTION_VIS_PRESET_LOCK 130
-#define ACTION_VIS_PRESET_RANDOM 131
-#define ACTION_VIS_RATE_PRESET_PLUS 132
-#define ACTION_VIS_RATE_PRESET_MINUS 133
-
-#define ACTION_SHOW_VIDEOMENU 134
-#define ACTION_ENTER 135
-
-#define ACTION_INCREASE_RATING 136
-#define ACTION_DECREASE_RATING 137
-
-#define ACTION_NEXT_SCENE 138 //!< switch to next scene/cutpoint in movie
-#define ACTION_PREV_SCENE 139 //!< switch to previous scene/cutpoint in movie
-
-#define ACTION_NEXT_LETTER 140 //!< jump through a list or container by letter
-#define ACTION_PREV_LETTER 141
-
-#define ACTION_JUMP_SMS2 142 //!< jump direct to a particular letter using SMS-style input
-#define ACTION_JUMP_SMS3 143
-#define ACTION_JUMP_SMS4 144
-#define ACTION_JUMP_SMS5 145
-#define ACTION_JUMP_SMS6 146
-#define ACTION_JUMP_SMS7 147
-#define ACTION_JUMP_SMS8 148
-#define ACTION_JUMP_SMS9 149
-
-#define ACTION_FILTER_CLEAR 150
-#define ACTION_FILTER_SMS2 151
-#define ACTION_FILTER_SMS3 152
-#define ACTION_FILTER_SMS4 153
-#define ACTION_FILTER_SMS5 154
-#define ACTION_FILTER_SMS6 155
-#define ACTION_FILTER_SMS7 156
-#define ACTION_FILTER_SMS8 157
-#define ACTION_FILTER_SMS9 158
-
-#define ACTION_FIRST_PAGE 159
-#define ACTION_LAST_PAGE 160
-
-#define ACTION_AUDIO_DELAY 161
-#define ACTION_SUBTITLE_DELAY 162
-#define ACTION_MENU 163
-
-#define ACTION_SET_RATING 164
-
-#define ACTION_RECORD 170
-
-#define ACTION_PASTE 180
-#define ACTION_NEXT_CONTROL 181
-#define ACTION_PREV_CONTROL 182
-#define ACTION_CHANNEL_SWITCH 183
-#define ACTION_CHANNEL_UP 184
-#define ACTION_CHANNEL_DOWN 185
-#define ACTION_NEXT_CHANNELGROUP 186
-#define ACTION_PREVIOUS_CHANNELGROUP 187
-#define ACTION_PVR_PLAY 188
-#define ACTION_PVR_PLAY_TV 189
-#define ACTION_PVR_PLAY_RADIO 190
-#define ACTION_PVR_SHOW_TIMER_RULE 191
-
-#define ACTION_TOGGLE_FULLSCREEN 199 //!< switch 2 desktop resolution
-#define ACTION_TOGGLE_WATCHED 200 //!< Toggle watched status (videos)
-#define ACTION_SCAN_ITEM 201 //!< scan item
-#define ACTION_TOGGLE_DIGITAL_ANALOG 202 //!< switch digital <-> analog
-#define ACTION_RELOAD_KEYMAPS 203 //!< reloads CButtonTranslator's keymaps
-#define ACTION_GUIPROFILE_BEGIN 204 //!< start the GUIControlProfiler running
-
-#define ACTION_TELETEXT_RED 215 //!< Teletext Color button <b>Red</b> to control TopText
-#define ACTION_TELETEXT_GREEN 216 //!< Teletext Color button <b>Green</b> to control TopText
-#define ACTION_TELETEXT_YELLOW 217 //!< Teletext Color button <b>Yellow</b> to control TopText
-#define ACTION_TELETEXT_BLUE 218 //!< Teletext Color button <b>Blue</b> to control TopText
-
-#define ACTION_INCREASE_PAR 219
-#define ACTION_DECREASE_PAR 220
-
-#define ACTION_VSHIFT_UP 227 //!< shift up video image in VideoPlayer
-#define ACTION_VSHIFT_DOWN 228 //!< shift down video image in VideoPlayer
-
-#define ACTION_PLAYER_PLAYPAUSE 229 //!< Play/pause. If playing it pauses, if paused it plays.
-
-#define ACTION_SUBTITLE_VSHIFT_UP 230 //!< shift up subtitles in VideoPlayer
-#define ACTION_SUBTITLE_VSHIFT_DOWN 231 //!< shift down subtitles in VideoPlayer
-#define ACTION_SUBTITLE_ALIGN 232 //!< toggle vertical alignment of subtitles
-
-#define ACTION_FILTER 233
-
-#define ACTION_SWITCH_PLAYER 234
-
-#define ACTION_STEREOMODE_NEXT 235
-#define ACTION_STEREOMODE_PREVIOUS 236
-#define ACTION_STEREOMODE_TOGGLE 237 //!< turns 3d mode on/off
-#define ACTION_STEREOMODE_SELECT 238
-#define ACTION_STEREOMODE_TOMONO 239
-#define ACTION_STEREOMODE_SET 240
-
-#define ACTION_SETTINGS_RESET 241
-#define ACTION_SETTINGS_LEVEL_CHANGE 242
-
-#define ACTION_TRIGGER_OSD 243 //!< show autoclosing OSD. Can b used in videoFullScreen.xml window id=2005
-#define ACTION_INPUT_TEXT 244
-#define ACTION_VOLUME_SET 245
-#define ACTION_TOGGLE_COMMSKIP 246
-
-#define ACTION_TOUCH_TAP 401 //!< touch actions
-#define ACTION_TOUCH_TAP_TEN 410 //!< touch actions
-#define ACTION_TOUCH_LONGPRESS 411 //!< touch actions
-#define ACTION_TOUCH_LONGPRESS_TEN 420 //!< touch actions
-
-#define ACTION_GESTURE_NOTIFY 500
-#define ACTION_GESTURE_BEGIN 501
-#define ACTION_GESTURE_ZOOM 502 //!< sendaction with point and currentPinchScale (fingers together < 1.0 -> fingers apart > 1.0)
-#define ACTION_GESTURE_ROTATE 503
-#define ACTION_GESTURE_PAN 504
-
-#define ACTION_GESTURE_SWIPE_LEFT 511
-#define ACTION_GESTURE_SWIPE_LEFT_TEN 520
-#define ACTION_GESTURE_SWIPE_RIGHT 521
-#define ACTION_GESTURE_SWIPE_RIGHT_TEN 530
-#define ACTION_GESTURE_SWIPE_UP 531
-#define ACTION_GESTURE_SWIPE_UP_TEN 540
-#define ACTION_GESTURE_SWIPE_DOWN 541
-#define ACTION_GESTURE_SWIPE_DOWN_TEN 550
-// 5xx is reserved for additional gesture actions
-#define ACTION_GESTURE_END 599
-
-// other, non-gesture actions
-#define ACTION_ANALOG_MOVE_X 601 //!< analog thumbstick move, horizontal axis; see ACTION_ANALOG_MOVE
-#define ACTION_ANALOG_MOVE_Y 602 //!< analog thumbstick move, vertical axis; see ACTION_ANALOG_MOVE
-//@}
-
-// The NOOP action can be specified to disable an input event. This is
-// useful in user keyboard.xml etc to disable actions specified in the
-// system mappings. ERROR action is used to play an error sound
-#define ACTION_ERROR 998
-#define ACTION_NOOP 999
-
#define ICON_TYPE_NONE 101
#define ICON_TYPE_PROGRAMS 102
#define ICON_TYPE_MUSIC 103
@@ -432,93 +150,6 @@
#ifndef SWIG
-class CKey;
-
-/*!
- \ingroup actionkeys
- \brief class encapsulating information regarding a particular user action to be sent to windows and controls
- */
-class CAction
-{
-public:
- CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const std::string &name = "", unsigned int holdTime = 0);
- CAction(int actionID, wchar_t unicode);
- CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const std::string &name = "");
- CAction(int actionID, const std::string &name, const CKey &key);
- CAction(int actionID, const std::string &name);
-
- CAction(const CAction& other) { *this = other; }
- CAction& operator=(const CAction& rhs);
-
- /*! \brief Identifier of the action
- \return id of the action
- */
- int GetID() const { return m_id; };
-
- /*! \brief Is this an action from the mouse
- \return true if this is a mouse action, false otherwise
- */
- bool IsMouse() const { return (m_id >= ACTION_MOUSE_START && m_id <= ACTION_MOUSE_END); };
-
- bool IsGesture() const { return (m_id >= ACTION_GESTURE_NOTIFY && m_id <= ACTION_GESTURE_END); };
-
- /*! \brief Human-readable name of the action
- \return name of the action
- */
- const std::string &GetName() const { return m_name; };
-
- /*! \brief Text of the action if any
- \return text payload of this action.
- */
- const std::string &GetText() const { return m_text; };
-
- /*! \brief Set the text payload of the action
- \param text to be set
- */
- void SetText(const std::string &text) { m_text = text; };
-
- /*! \brief Get an amount associated with this action
- \param zero-based index of amount to retrieve, defaults to 0
- \return an amount associated with this action
- */
- float GetAmount(unsigned int index = 0) const { return (index < max_amounts) ? m_amount[index] : 0; };
-
- /*! \brief Unicode value associated with this action
- \return unicode value associated with this action, for keyboard input.
- */
- wchar_t GetUnicode() const { return m_unicode; };
-
- /*! \brief Time in ms that the key has been held
- \return time that the key has been held down in ms.
- */
- unsigned int GetHoldTime() const { return m_holdTime; };
-
- /*! \brief Time since last repeat in ms
- \return time since last repeat in ms. Returns 0 if unknown.
- */
- float GetRepeat() const { return m_repeat; };
-
- /*! \brief Button code that triggered this action
- \return button code
- */
- unsigned int GetButtonCode() const { return m_buttonCode; };
-
- bool IsAnalog() const;
-
-private:
- int m_id;
- std::string m_name;
-
- static const unsigned int max_amounts = 4; // Must be at least 4.
- float m_amount[max_amounts];
-
- float m_repeat;
- unsigned int m_holdTime;
- unsigned int m_buttonCode;
- wchar_t m_unicode;
- std::string m_text;
-};
-
/*!
\ingroup actionkeys, mouse
\brief Simple class for mouse events
diff --git a/xbmc/input/joysticks/DeadzoneFilter.cpp b/xbmc/input/joysticks/DeadzoneFilter.cpp
index 0bf30738d0..988c36a539 100644
--- a/xbmc/input/joysticks/DeadzoneFilter.cpp
+++ b/xbmc/input/joysticks/DeadzoneFilter.cpp
@@ -27,6 +27,7 @@
#include <cmath>
#include <vector>
+using namespace KODI;
using namespace JOYSTICK;
#define AXIS_EPSILON 0.01f // Allowed noise for detecting discrete D-pads (value of 0.007 when centered has been observed)
diff --git a/xbmc/input/joysticks/DeadzoneFilter.h b/xbmc/input/joysticks/DeadzoneFilter.h
index 750ef4ed44..403bffdc59 100644
--- a/xbmc/input/joysticks/DeadzoneFilter.h
+++ b/xbmc/input/joysticks/DeadzoneFilter.h
@@ -24,6 +24,8 @@ namespace PERIPHERALS
class CPeripheral;
}
+namespace KODI
+{
namespace JOYSTICK
{
class IButtonMap;
@@ -85,3 +87,4 @@ namespace JOYSTICK
PERIPHERALS::CPeripheral* const m_peripheral;
};
}
+}
diff --git a/xbmc/input/joysticks/DefaultJoystick.cpp b/xbmc/input/joysticks/DefaultJoystick.cpp
index d474023850..70ef187c78 100644
--- a/xbmc/input/joysticks/DefaultJoystick.cpp
+++ b/xbmc/input/joysticks/DefaultJoystick.cpp
@@ -31,6 +31,7 @@
#define ANALOG_DIGITAL_THRESHOLD 0.5f
+using namespace KODI;
using namespace JOYSTICK;
CDefaultJoystick::CDefaultJoystick(void) :
diff --git a/xbmc/input/joysticks/DefaultJoystick.h b/xbmc/input/joysticks/DefaultJoystick.h
index 0c22e14a2c..77a2720b75 100644
--- a/xbmc/input/joysticks/DefaultJoystick.h
+++ b/xbmc/input/joysticks/DefaultJoystick.h
@@ -34,6 +34,8 @@
#define DEFAULT_LEFT_STICK_NAME "leftstick"
#define DEFAULT_RIGHT_STICK_NAME "rightstick"
+namespace KODI
+{
namespace JOYSTICK
{
class IKeymapHandler;
@@ -105,3 +107,4 @@ namespace JOYSTICK
std::unique_ptr<IButtonSequence> m_easterEgg;
};
}
+}
diff --git a/xbmc/input/joysticks/DriverPrimitive.cpp b/xbmc/input/joysticks/DriverPrimitive.cpp
index 1a222acb20..9766f3594a 100644
--- a/xbmc/input/joysticks/DriverPrimitive.cpp
+++ b/xbmc/input/joysticks/DriverPrimitive.cpp
@@ -20,6 +20,7 @@
#include "DriverPrimitive.h"
+using namespace KODI;
using namespace JOYSTICK;
CDriverPrimitive::CDriverPrimitive(void)
diff --git a/xbmc/input/joysticks/DriverPrimitive.h b/xbmc/input/joysticks/DriverPrimitive.h
index 736b33dd3a..7354853a29 100644
--- a/xbmc/input/joysticks/DriverPrimitive.h
+++ b/xbmc/input/joysticks/DriverPrimitive.h
@@ -23,6 +23,8 @@
#include <stdint.h>
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -146,3 +148,4 @@ namespace JOYSTICK
unsigned int m_range;
};
}
+}
diff --git a/xbmc/input/joysticks/IActionMap.h b/xbmc/input/joysticks/IActionMap.h
index 5fc5c9fc2f..3c9ceb77ec 100644
--- a/xbmc/input/joysticks/IActionMap.h
+++ b/xbmc/input/joysticks/IActionMap.h
@@ -22,6 +22,8 @@
#include "JoystickTypes.h"
#include "input/Key.h"
+namespace KODI
+{
namespace JOYSTICK
{
class CDriverPrimitive;
@@ -55,3 +57,4 @@ namespace JOYSTICK
virtual int GetActionID(const FeatureName& feature) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IButtonMap.h b/xbmc/input/joysticks/IButtonMap.h
index 4fc109e327..5e3d4157de 100644
--- a/xbmc/input/joysticks/IButtonMap.h
+++ b/xbmc/input/joysticks/IButtonMap.h
@@ -25,6 +25,8 @@
#include <string>
#include <vector>
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -248,3 +250,4 @@ namespace JOYSTICK
virtual void RevertButtonMap() = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IButtonMapCallback.h b/xbmc/input/joysticks/IButtonMapCallback.h
index 4d22f91ba4..c71c99281d 100644
--- a/xbmc/input/joysticks/IButtonMapCallback.h
+++ b/xbmc/input/joysticks/IButtonMapCallback.h
@@ -19,6 +19,8 @@
*/
#pragma once
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -53,3 +55,4 @@ namespace JOYSTICK
virtual void RevertButtonMap() = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IButtonMapper.h b/xbmc/input/joysticks/IButtonMapper.h
index 9cbd199224..855f76b108 100644
--- a/xbmc/input/joysticks/IButtonMapper.h
+++ b/xbmc/input/joysticks/IButtonMapper.h
@@ -22,6 +22,8 @@
#include <map>
#include <string>
+namespace KODI
+{
namespace JOYSTICK
{
class CDriverPrimitive;
@@ -109,6 +111,17 @@ namespace JOYSTICK
*/
virtual void OnEventFrame(const IButtonMap* buttonMap, bool bMotion) = 0;
+ /*!
+ * \brief Called when an axis has been detected after mapping began
+ *
+ * \param axisIndex The index of the axis being discovered
+ *
+ * Some joystick drivers don't report an initial value for analog axes.
+ *
+ * Called in the same thread as \ref IButtonMapper::MapPrimitive.
+ */
+ virtual void OnLateAxis(const IButtonMap* buttonMap, unsigned int axisIndex) = 0;
+
// Button map callback interface
void SetButtonMapCallback(const std::string& deviceName, IButtonMapCallback* callback) { m_callbacks[deviceName] = callback; }
void ResetButtonMapCallbacks(void) { m_callbacks.clear(); }
@@ -118,3 +131,4 @@ namespace JOYSTICK
std::map<std::string, IButtonMapCallback*> m_callbacks;
};
}
+}
diff --git a/xbmc/input/joysticks/IButtonSequence.h b/xbmc/input/joysticks/IButtonSequence.h
index d2646582e4..31b64c4e5b 100644
--- a/xbmc/input/joysticks/IButtonSequence.h
+++ b/xbmc/input/joysticks/IButtonSequence.h
@@ -21,6 +21,8 @@
#include "JoystickTypes.h"
+namespace KODI
+{
namespace JOYSTICK
{
class IButtonSequence
@@ -31,3 +33,4 @@ namespace JOYSTICK
virtual bool OnButtonPress(const FeatureName& feature) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IDriverHandler.h b/xbmc/input/joysticks/IDriverHandler.h
index b58a921ff7..5843b868d6 100644
--- a/xbmc/input/joysticks/IDriverHandler.h
+++ b/xbmc/input/joysticks/IDriverHandler.h
@@ -21,6 +21,8 @@
#include "JoystickTypes.h"
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -80,3 +82,4 @@ namespace JOYSTICK
virtual void ProcessAxisMotions(void) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IDriverReceiver.h b/xbmc/input/joysticks/IDriverReceiver.h
index df181ea838..0255a7b752 100644
--- a/xbmc/input/joysticks/IDriverReceiver.h
+++ b/xbmc/input/joysticks/IDriverReceiver.h
@@ -19,6 +19,8 @@
*/
#pragma once
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -41,3 +43,4 @@ namespace JOYSTICK
virtual bool SetMotorState(unsigned int motorIndex, float magnitude) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IInputHandler.h b/xbmc/input/joysticks/IInputHandler.h
index 44629f5c52..9b6795f921 100644
--- a/xbmc/input/joysticks/IInputHandler.h
+++ b/xbmc/input/joysticks/IInputHandler.h
@@ -23,6 +23,8 @@
#include <string>
+namespace KODI
+{
namespace JOYSTICK
{
class IInputReceiver;
@@ -133,3 +135,4 @@ namespace JOYSTICK
IInputReceiver* m_receiver;
};
}
+}
diff --git a/xbmc/input/joysticks/IInputReceiver.h b/xbmc/input/joysticks/IInputReceiver.h
index 182e27ab0b..2292ce87a2 100644
--- a/xbmc/input/joysticks/IInputReceiver.h
+++ b/xbmc/input/joysticks/IInputReceiver.h
@@ -21,6 +21,8 @@
#include "JoystickTypes.h"
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -43,3 +45,4 @@ namespace JOYSTICK
virtual bool SetRumbleState(const FeatureName& feature, float magnitude) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/IKeymapHandler.h b/xbmc/input/joysticks/IKeymapHandler.h
index 83e21c6666..efdbdb367f 100644
--- a/xbmc/input/joysticks/IKeymapHandler.h
+++ b/xbmc/input/joysticks/IKeymapHandler.h
@@ -21,6 +21,8 @@
#include "JoystickTypes.h"
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -75,3 +77,4 @@ namespace JOYSTICK
virtual void OnAnalogKey(unsigned int buttonKeyId, float magnitude) = 0;
};
}
+}
diff --git a/xbmc/input/joysticks/JoystickEasterEgg.cpp b/xbmc/input/joysticks/JoystickEasterEgg.cpp
index d50b79edab..aea96fc390 100644
--- a/xbmc/input/joysticks/JoystickEasterEgg.cpp
+++ b/xbmc/input/joysticks/JoystickEasterEgg.cpp
@@ -24,6 +24,7 @@
#include "guilib/WindowIDs.h"
#include "settings/Settings.h"
+using namespace KODI;
using namespace JOYSTICK;
std::vector<FeatureName> CJoystickEasterEgg::m_sequence = {
diff --git a/xbmc/input/joysticks/JoystickEasterEgg.h b/xbmc/input/joysticks/JoystickEasterEgg.h
index fe239fcec7..78e1fe978e 100644
--- a/xbmc/input/joysticks/JoystickEasterEgg.h
+++ b/xbmc/input/joysticks/JoystickEasterEgg.h
@@ -23,6 +23,8 @@
#include <vector>
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -45,3 +47,4 @@ namespace JOYSTICK
unsigned int m_state;
};
}
+}
diff --git a/xbmc/input/joysticks/JoystickMonitor.cpp b/xbmc/input/joysticks/JoystickMonitor.cpp
index ee081bea4d..3aef3c8442 100644
--- a/xbmc/input/joysticks/JoystickMonitor.cpp
+++ b/xbmc/input/joysticks/JoystickMonitor.cpp
@@ -22,6 +22,7 @@
#include "Application.h"
#include "input/InputManager.h"
+using namespace KODI;
using namespace JOYSTICK;
bool CJoystickMonitor::OnButtonMotion(unsigned int buttonIndex, bool bPressed)
diff --git a/xbmc/input/joysticks/JoystickMonitor.h b/xbmc/input/joysticks/JoystickMonitor.h
index 6409ea0544..912d2039a0 100644
--- a/xbmc/input/joysticks/JoystickMonitor.h
+++ b/xbmc/input/joysticks/JoystickMonitor.h
@@ -21,6 +21,8 @@
#include "IDriverHandler.h"
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -45,3 +47,4 @@ namespace JOYSTICK
bool ResetTimers(void);
};
}
+}
diff --git a/xbmc/input/joysticks/JoystickTranslator.cpp b/xbmc/input/joysticks/JoystickTranslator.cpp
index e1f76a9f26..80e932efbc 100644
--- a/xbmc/input/joysticks/JoystickTranslator.cpp
+++ b/xbmc/input/joysticks/JoystickTranslator.cpp
@@ -19,7 +19,11 @@
*/
#include "JoystickTranslator.h"
+#include "guilib/LocalizeStrings.h"
+#include "input/joysticks/DriverPrimitive.h"
+#include "utils/StringUtils.h"
+using namespace KODI;
using namespace JOYSTICK;
const char* CJoystickTranslator::HatStateToString(HAT_STATE state)
@@ -59,3 +63,21 @@ ANALOG_STICK_DIRECTION CJoystickTranslator::VectorToAnalogStickDirection(float x
return ANALOG_STICK_DIRECTION::UNKNOWN;
}
+
+std::string CJoystickTranslator::GetPrimitiveName(const CDriverPrimitive& primitive)
+{
+ std::string primitiveTemplate;
+
+ switch (primitive.Type())
+ {
+ case PRIMITIVE_TYPE::BUTTON:
+ primitiveTemplate = g_localizeStrings.Get(35015); // "Button %d"
+ break;
+ case PRIMITIVE_TYPE::SEMIAXIS:
+ primitiveTemplate = g_localizeStrings.Get(35016); // "Axis %d"
+ break;
+ default: break;
+ }
+
+ return StringUtils::Format(primitiveTemplate.c_str(), primitive.Index());
+}
diff --git a/xbmc/input/joysticks/JoystickTranslator.h b/xbmc/input/joysticks/JoystickTranslator.h
index 2c26e54416..e6a5f0ce44 100644
--- a/xbmc/input/joysticks/JoystickTranslator.h
+++ b/xbmc/input/joysticks/JoystickTranslator.h
@@ -21,8 +21,12 @@
#include "JoystickTypes.h"
+namespace KODI
+{
namespace JOYSTICK
{
+ class CDriverPrimitive;
+
/*!
* \brief Joystick translation utilities
*/
@@ -60,5 +64,15 @@ namespace JOYSTICK
* ANALOG_STICK_DIRECTION::UNKNOWN if x and y are both 0
*/
static ANALOG_STICK_DIRECTION VectorToAnalogStickDirection(float x, float y);
+
+ /*!
+ * \brief Get the localized name of the primitive
+ *
+ * \param primitive The primitive, currently only buttons and axes are supported
+ *
+ * \return A title for the primitive, e.g. "Button 0" or "Axis 1"
+ */
+ static std::string GetPrimitiveName(const CDriverPrimitive& primitive);
};
}
+}
diff --git a/xbmc/input/joysticks/JoystickTypes.h b/xbmc/input/joysticks/JoystickTypes.h
index a01a8881d1..7a56bae039 100644
--- a/xbmc/input/joysticks/JoystickTypes.h
+++ b/xbmc/input/joysticks/JoystickTypes.h
@@ -26,6 +26,8 @@
#include <string>
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -137,3 +139,4 @@ namespace JOYSTICK
MOTOR, // a rumble motor
};
}
+}
diff --git a/xbmc/input/joysticks/JoystickUtils.h b/xbmc/input/joysticks/JoystickUtils.h
index 88bf9e4f4d..665e75673e 100644
--- a/xbmc/input/joysticks/JoystickUtils.h
+++ b/xbmc/input/joysticks/JoystickUtils.h
@@ -24,29 +24,37 @@
/// \ingroup joystick
/// \{
-inline JOYSTICK::HAT_DIRECTION& operator|=(JOYSTICK::HAT_DIRECTION& lhs, JOYSTICK::HAT_DIRECTION rhs)
+namespace KODI
{
- return lhs = static_cast<JOYSTICK::HAT_DIRECTION>(static_cast<int>(lhs) | static_cast<int>(rhs));
+namespace JOYSTICK
+{
+
+inline HAT_DIRECTION& operator|=(HAT_DIRECTION& lhs, HAT_DIRECTION rhs)
+{
+ return lhs = static_cast<HAT_DIRECTION>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
-inline JOYSTICK::HAT_STATE& operator|=(JOYSTICK::HAT_STATE& lhs, JOYSTICK::HAT_STATE rhs)
+inline HAT_STATE& operator|=(HAT_STATE& lhs, HAT_STATE rhs)
{
- return lhs = static_cast<JOYSTICK::HAT_STATE>(static_cast<int>(lhs) | static_cast<int>(rhs));
+ return lhs = static_cast<HAT_STATE>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
-inline bool operator&(JOYSTICK::HAT_STATE lhs, JOYSTICK::HAT_DIRECTION rhs)
+inline bool operator&(HAT_STATE lhs, HAT_DIRECTION rhs)
{
return (static_cast<int>(lhs) & static_cast<int>(rhs)) ? true : false;
}
-inline JOYSTICK::SEMIAXIS_DIRECTION operator*(JOYSTICK::SEMIAXIS_DIRECTION lhs, int rhs)
+inline SEMIAXIS_DIRECTION operator*(SEMIAXIS_DIRECTION lhs, int rhs)
{
- return static_cast<JOYSTICK::SEMIAXIS_DIRECTION>(static_cast<int>(lhs) * rhs);
+ return static_cast<SEMIAXIS_DIRECTION>(static_cast<int>(lhs) * rhs);
}
-inline float operator*(float lhs, JOYSTICK::SEMIAXIS_DIRECTION rhs)
+inline float operator*(float lhs, SEMIAXIS_DIRECTION rhs)
{
return lhs * static_cast<int>(rhs);
}
+}
+}
+
/// \}
diff --git a/xbmc/input/joysticks/KeymapHandler.cpp b/xbmc/input/joysticks/KeymapHandler.cpp
index ca14cc5da8..b0fb082774 100644
--- a/xbmc/input/joysticks/KeymapHandler.cpp
+++ b/xbmc/input/joysticks/KeymapHandler.cpp
@@ -28,13 +28,11 @@
#include <algorithm>
using namespace KODI;
-using namespace MESSAGING;
+using namespace JOYSTICK;
#define HOLD_TIMEOUT_MS 500
#define REPEAT_TIMEOUT_MS 50
-using namespace JOYSTICK;
-
CKeymapHandler::CKeymapHandler(void) :
m_lastButtonPress(0),
m_lastDigitalActionMs(0)
diff --git a/xbmc/input/joysticks/KeymapHandler.h b/xbmc/input/joysticks/KeymapHandler.h
index 39dbbf14db..13dd940743 100644
--- a/xbmc/input/joysticks/KeymapHandler.h
+++ b/xbmc/input/joysticks/KeymapHandler.h
@@ -23,6 +23,8 @@
#include <vector>
+namespace KODI
+{
namespace JOYSTICK
{
/*!
@@ -61,3 +63,4 @@ namespace JOYSTICK
std::vector<unsigned int> m_pressedButtons;
};
}
+}
diff --git a/xbmc/input/joysticks/RumbleGenerator.cpp b/xbmc/input/joysticks/RumbleGenerator.cpp
index a45bf5dbea..894d056f3f 100644
--- a/xbmc/input/joysticks/RumbleGenerator.cpp
+++ b/xbmc/input/joysticks/RumbleGenerator.cpp
@@ -33,6 +33,7 @@
// From game.controller.default profile
#define WEAK_MOTOR_NAME "rightmotor"
+using namespace KODI;
using namespace JOYSTICK;
CRumbleGenerator::CRumbleGenerator(const std::string& controllerId) :
@@ -130,7 +131,7 @@ std::vector<std::string> CRumbleGenerator::GetMotors(const std::string& controll
{
for (const CControllerFeature& feature : controller->Layout().Features())
{
- if (feature.Type() == JOYSTICK::FEATURE_TYPE::MOTOR)
+ if (feature.Type() == FEATURE_TYPE::MOTOR)
motors.push_back(feature.Name());
}
}
diff --git a/xbmc/input/joysticks/RumbleGenerator.h b/xbmc/input/joysticks/RumbleGenerator.h
index c3431bd0eb..26474c4cf7 100644
--- a/xbmc/input/joysticks/RumbleGenerator.h
+++ b/xbmc/input/joysticks/RumbleGenerator.h
@@ -21,6 +21,8 @@
#include "threads/Thread.h"
+namespace KODI
+{
namespace JOYSTICK
{
class IInputReceiver;
@@ -59,3 +61,4 @@ namespace JOYSTICK
RUMBLE_TYPE m_type;
};
}
+}
diff --git a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
index 6223eb3c5e..d0b42d9dae 100644
--- a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
+++ b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
@@ -25,6 +25,7 @@
#include "messaging/helpers/DialogHelper.h"
#include "settings/Settings.h"
+using namespace KODI;
using namespace JOYSTICK;
CGUIDialogNewJoystick::CGUIDialogNewJoystick() :
@@ -49,7 +50,7 @@ void CGUIDialogNewJoystick::ShowAsync()
void CGUIDialogNewJoystick::Process()
{
- using namespace KODI::MESSAGING::HELPERS;
+ using namespace MESSAGING::HELPERS;
// "New controller detected"
// "A new controller has been detected. Configuration can be done at any time in "Settings -> System Settings -> Input". Would you like to configure it now?"
diff --git a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h
index b44ba37dfb..71bff72aec 100644
--- a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h
+++ b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.h
@@ -21,6 +21,8 @@
#include "threads/Thread.h"
+namespace KODI
+{
namespace JOYSTICK
{
class CGUIDialogNewJoystick : protected CThread
@@ -36,3 +38,4 @@ namespace JOYSTICK
virtual void Process() override;
};
}
+}
diff --git a/xbmc/input/joysticks/generic/ButtonMapping.cpp b/xbmc/input/joysticks/generic/ButtonMapping.cpp
index b5c6b23949..9b74ff52c0 100644
--- a/xbmc/input/joysticks/generic/ButtonMapping.cpp
+++ b/xbmc/input/joysticks/generic/ButtonMapping.cpp
@@ -36,6 +36,7 @@
#include <assert.h>
#include <cmath>
+using namespace KODI;
using namespace JOYSTICK;
using namespace XbmcThreads;
@@ -185,6 +186,12 @@ void CAxisDetector::SetEmitted(const CDriverPrimitive& activePrimitive)
void CAxisDetector::DetectType(float position)
{
+ // Some platforms don't report a value until the axis is first changed.
+ // Detection relies on an initial value, so this axis will be disabled until
+ // the user begins button mapping again.
+ if (m_config.bLateDiscovery)
+ return;
+
// Update range if a range of > 1 is observed
if (std::abs(position - m_config.center) > 1.0f)
m_config.range = 2;
@@ -241,7 +248,8 @@ CButtonMapping::CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMa
m_buttonMapper(buttonMapper),
m_buttonMap(buttonMap),
m_actionMap(actionMap),
- m_lastAction(0)
+ m_lastAction(0),
+ m_frameCount(0)
{
assert(m_buttonMapper != nullptr);
assert(m_buttonMap != nullptr);
@@ -274,7 +282,7 @@ CButtonMapping::CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMa
axisConfig.center = primitive.Center();
axisConfig.range = primitive.Range();
- GetAxis(primitive.Index(), axisConfig).SetEmitted(primitive);
+ GetAxis(primitive.Index(), primitive.Center(), axisConfig).SetEmitted(primitive);
}
}
}
@@ -291,7 +299,7 @@ bool CButtonMapping::OnHatMotion(unsigned int hatIndex, HAT_STATE state)
bool CButtonMapping::OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range)
{
- return GetAxis(axisIndex).OnMotion(position);
+ return GetAxis(axisIndex, position).OnMotion(position);
}
void CButtonMapping::ProcessAxisMotions(void)
@@ -300,6 +308,8 @@ void CButtonMapping::ProcessAxisMotions(void)
axis.second.ProcessMotion();
m_buttonMapper->OnEventFrame(m_buttonMap, IsMapping());
+
+ m_frameCount++;
}
void CButtonMapping::SaveButtonMap()
@@ -389,15 +399,33 @@ CHatDetector& CButtonMapping::GetHat(unsigned int hatIndex)
}
CAxisDetector& CButtonMapping::GetAxis(unsigned int axisIndex,
+ float position,
const AxisConfiguration& initialConfig /* = AxisConfiguration() */)
{
auto itAxis = m_axes.find(axisIndex);
if (itAxis == m_axes.end())
{
- m_axes.insert(std::make_pair(axisIndex, CAxisDetector(this, axisIndex, initialConfig)));
+ AxisConfiguration config(initialConfig);
+
+ if (m_frameCount >= 2)
+ {
+ config.bLateDiscovery = true;
+ OnLateDiscovery(axisIndex);
+ }
+
+ // Report axis
+ CLog::Log(LOGDEBUG, "Axis %u discovered at position %.04f after %lu frames",
+ axisIndex, position, static_cast<unsigned long>(m_frameCount));
+
+ m_axes.insert(std::make_pair(axisIndex, CAxisDetector(this, axisIndex, config)));
itAxis = m_axes.find(axisIndex);
}
return itAxis->second;
}
+
+void CButtonMapping::OnLateDiscovery(unsigned int axisIndex)
+{
+ m_buttonMapper->OnLateAxis(m_buttonMap, axisIndex);
+}
diff --git a/xbmc/input/joysticks/generic/ButtonMapping.h b/xbmc/input/joysticks/generic/ButtonMapping.h
index e75de46c59..5961483977 100644
--- a/xbmc/input/joysticks/generic/ButtonMapping.h
+++ b/xbmc/input/joysticks/generic/ButtonMapping.h
@@ -24,7 +24,10 @@
#include "input/joysticks/IDriverHandler.h"
#include <map>
+#include <stdint.h>
+namespace KODI
+{
namespace JOYSTICK
{
class CButtonMapping;
@@ -75,6 +78,7 @@ namespace JOYSTICK
bool bKnown = false;
int center = 0;
unsigned int range = 1;
+ bool bLateDiscovery = false;
};
class CAxisDetector
@@ -240,9 +244,11 @@ namespace JOYSTICK
private:
bool IsMapping() const;
+ void OnLateDiscovery(unsigned int axisIndex);
+
CButtonDetector& GetButton(unsigned int buttonIndex);
CHatDetector& GetHat(unsigned int hatIndex);
- CAxisDetector& GetAxis(unsigned int axisIndex, const AxisConfiguration& initialConfig = AxisConfiguration());
+ CAxisDetector& GetAxis(unsigned int axisIndex, float position, const AxisConfiguration& initialConfig = AxisConfiguration());
// Construction parameters
IButtonMapper* const m_buttonMapper;
@@ -252,6 +258,8 @@ namespace JOYSTICK
std::map<unsigned int, CButtonDetector> m_buttons;
std::map<unsigned int, CHatDetector> m_hats;
std::map<unsigned int, CAxisDetector> m_axes;
- unsigned int m_lastAction;
+ unsigned int m_lastAction;
+ uint64_t m_frameCount;
};
}
+}
diff --git a/xbmc/input/joysticks/generic/DriverReceiving.cpp b/xbmc/input/joysticks/generic/DriverReceiving.cpp
index d44eabd1c0..beb6bb9ea6 100644
--- a/xbmc/input/joysticks/generic/DriverReceiving.cpp
+++ b/xbmc/input/joysticks/generic/DriverReceiving.cpp
@@ -23,6 +23,7 @@
#include "input/joysticks/IButtonMap.h"
#include "input/joysticks/IDriverReceiver.h"
+using namespace KODI;
using namespace JOYSTICK;
CDriverReceiving::CDriverReceiving(IDriverReceiver* receiver, IButtonMap* buttonMap)
diff --git a/xbmc/input/joysticks/generic/DriverReceiving.h b/xbmc/input/joysticks/generic/DriverReceiving.h
index b35cfc442e..bfadfa5397 100644
--- a/xbmc/input/joysticks/generic/DriverReceiving.h
+++ b/xbmc/input/joysticks/generic/DriverReceiving.h
@@ -24,6 +24,8 @@
#include <map>
+namespace KODI
+{
namespace JOYSTICK
{
class IDriverReceiver;
@@ -52,3 +54,4 @@ namespace JOYSTICK
IButtonMap* const m_buttonMap;
};
}
+}
diff --git a/xbmc/input/joysticks/generic/FeatureHandling.cpp b/xbmc/input/joysticks/generic/FeatureHandling.cpp
index 850dd871ea..24a4b35d67 100644
--- a/xbmc/input/joysticks/generic/FeatureHandling.cpp
+++ b/xbmc/input/joysticks/generic/FeatureHandling.cpp
@@ -27,6 +27,7 @@
#include <vector>
+using namespace KODI;
using namespace JOYSTICK;
#define ANALOG_DIGITAL_THRESHOLD 0.5f
diff --git a/xbmc/input/joysticks/generic/FeatureHandling.h b/xbmc/input/joysticks/generic/FeatureHandling.h
index 52d992be01..3d276771c0 100644
--- a/xbmc/input/joysticks/generic/FeatureHandling.h
+++ b/xbmc/input/joysticks/generic/FeatureHandling.h
@@ -23,6 +23,8 @@
#include <memory>
+namespace KODI
+{
namespace JOYSTICK
{
class CDriverPrimitive;
@@ -225,3 +227,4 @@ namespace JOYSTICK
float m_zAxisState;
};
}
+}
diff --git a/xbmc/input/joysticks/generic/InputHandling.cpp b/xbmc/input/joysticks/generic/InputHandling.cpp
index 94f93c5a39..98ec01f3a5 100644
--- a/xbmc/input/joysticks/generic/InputHandling.cpp
+++ b/xbmc/input/joysticks/generic/InputHandling.cpp
@@ -28,6 +28,7 @@
#include <array>
#include <cmath>
+using namespace KODI;
using namespace JOYSTICK;
CGUIDialogNewJoystick* const CInputHandling::m_dialog = new CGUIDialogNewJoystick;
diff --git a/xbmc/input/joysticks/generic/InputHandling.h b/xbmc/input/joysticks/generic/InputHandling.h
index dd6e82733e..2a0f2453f0 100644
--- a/xbmc/input/joysticks/generic/InputHandling.h
+++ b/xbmc/input/joysticks/generic/InputHandling.h
@@ -25,6 +25,8 @@
#include <map>
+namespace KODI
+{
namespace JOYSTICK
{
class CDriverPrimitive;
@@ -72,3 +74,4 @@ namespace JOYSTICK
static CGUIDialogNewJoystick* const m_dialog;
};
}
+}
diff --git a/xbmc/input/keyboard/CMakeLists.txt b/xbmc/input/keyboard/CMakeLists.txt
index ed121ac30a..69d84b8d3a 100644
--- a/xbmc/input/keyboard/CMakeLists.txt
+++ b/xbmc/input/keyboard/CMakeLists.txt
@@ -1,6 +1,11 @@
-set(SOURCES KeyboardEasterEgg.cpp)
+set(SOURCES KeyboardEasterEgg.cpp
+ KeymapActionMap.cpp
+)
-set(HEADERS IKeyboardHandler.h
- KeyboardEasterEgg.h)
+set(HEADERS IActionMap.h
+ IKeyboardHandler.h
+ KeyboardEasterEgg.h
+ KeymapActionMap.h
+)
core_add_library(input_keyboard)
diff --git a/xbmc/input/keyboard/IActionMap.h b/xbmc/input/keyboard/IActionMap.h
new file mode 100644
index 0000000000..ae89742d41
--- /dev/null
+++ b/xbmc/input/keyboard/IActionMap.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+class CKey;
+
+namespace KODI
+{
+namespace KEYBOARD
+{
+ /*!
+ * \brief Interface for translating keys to action IDs
+ */
+ class IActionMap
+ {
+ public:
+ virtual ~IActionMap() = default;
+
+ /*!
+ * \brief Get the action ID mapped to the specified key
+ *
+ * \param key The key to look up
+ *
+ * \return The action ID from Action.h, or ACTION_NONE if no action is
+ * mapped to the specified key
+ */
+ virtual unsigned int GetActionID(const CKey& key) = 0;
+ };
+}
+}
diff --git a/xbmc/input/keyboard/IKeyboardHandler.h b/xbmc/input/keyboard/IKeyboardHandler.h
index 5958aac650..b19712bbc1 100644
--- a/xbmc/input/keyboard/IKeyboardHandler.h
+++ b/xbmc/input/keyboard/IKeyboardHandler.h
@@ -21,6 +21,8 @@
class CKey;
+namespace KODI
+{
namespace KEYBOARD
{
/*!
@@ -49,3 +51,4 @@ namespace KEYBOARD
virtual void OnKeyRelease(const CKey& key) = 0;
};
}
+}
diff --git a/xbmc/input/keyboard/KeyboardEasterEgg.cpp b/xbmc/input/keyboard/KeyboardEasterEgg.cpp
index a2f089256c..c9fd7179b9 100644
--- a/xbmc/input/keyboard/KeyboardEasterEgg.cpp
+++ b/xbmc/input/keyboard/KeyboardEasterEgg.cpp
@@ -22,6 +22,7 @@
#include "input/joysticks/JoystickEasterEgg.h"
#include "input/Key.h"
+using namespace KODI;
using namespace KEYBOARD;
std::vector<XBMCVKey> CKeyboardEasterEgg::m_sequence = {
diff --git a/xbmc/input/keyboard/KeyboardEasterEgg.h b/xbmc/input/keyboard/KeyboardEasterEgg.h
index 7d3888644c..e98187be26 100644
--- a/xbmc/input/keyboard/KeyboardEasterEgg.h
+++ b/xbmc/input/keyboard/KeyboardEasterEgg.h
@@ -24,6 +24,8 @@
#include <vector>
+namespace KODI
+{
namespace KEYBOARD
{
/*!
@@ -45,3 +47,4 @@ namespace KEYBOARD
unsigned int m_state;
};
}
+}
diff --git a/xbmc/input/keyboard/KeymapActionMap.cpp b/xbmc/input/keyboard/KeymapActionMap.cpp
new file mode 100644
index 0000000000..41fe927186
--- /dev/null
+++ b/xbmc/input/keyboard/KeymapActionMap.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "KeymapActionMap.h"
+#include "guilib/GUIWindowManager.h"
+#include "input/Action.h"
+#include "input/ButtonTranslator.h"
+#include "input/Key.h"
+
+using namespace KODI;
+using namespace KEYBOARD;
+
+unsigned int CKeymapActionMap::GetActionID(const CKey& key)
+{
+ CAction action = CButtonTranslator::GetInstance().GetAction(g_windowManager.GetActiveWindowID(), key);
+ return action.GetID();
+}
diff --git a/xbmc/input/keyboard/KeymapActionMap.h b/xbmc/input/keyboard/KeymapActionMap.h
new file mode 100644
index 0000000000..8f67cc8686
--- /dev/null
+++ b/xbmc/input/keyboard/KeymapActionMap.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "input/keyboard/IActionMap.h"
+
+namespace KODI
+{
+namespace KEYBOARD
+{
+ class CKeymapActionMap : public IActionMap
+ {
+ public:
+ CKeymapActionMap(void) = default;
+
+ virtual ~CKeymapActionMap(void) = default;
+
+ // implementation of IActionMap
+ virtual unsigned int GetActionID(const CKey& key) override;
+ };
+}
+}
diff --git a/xbmc/input/keyboard/generic/JoystickEmulation.cpp b/xbmc/input/keyboard/generic/JoystickEmulation.cpp
index de4ce1850f..f292b2b5fd 100644
--- a/xbmc/input/keyboard/generic/JoystickEmulation.cpp
+++ b/xbmc/input/keyboard/generic/JoystickEmulation.cpp
@@ -27,6 +27,7 @@
#define BUTTON_INDEX_MASK 0x01ff
+using namespace KODI;
using namespace KEYBOARD;
CJoystickEmulation::CJoystickEmulation(JOYSTICK::IDriverHandler* handler) :
diff --git a/xbmc/input/keyboard/generic/JoystickEmulation.h b/xbmc/input/keyboard/generic/JoystickEmulation.h
index 1bab9b7434..12bc40301a 100644
--- a/xbmc/input/keyboard/generic/JoystickEmulation.h
+++ b/xbmc/input/keyboard/generic/JoystickEmulation.h
@@ -23,6 +23,8 @@
#include <vector>
+namespace KODI
+{
namespace JOYSTICK
{
class IDriverHandler;
@@ -63,3 +65,4 @@ namespace KEYBOARD
std::vector<KeyEvent> m_pressedKeys;
};
}
+}
diff --git a/xbmc/input/mouse/IMouseButtonMap.h b/xbmc/input/mouse/IMouseButtonMap.h
index 80d812da4f..2f24161056 100644
--- a/xbmc/input/mouse/IMouseButtonMap.h
+++ b/xbmc/input/mouse/IMouseButtonMap.h
@@ -21,6 +21,8 @@
#include <string>
+namespace KODI
+{
namespace MOUSE
{
/*!
@@ -73,3 +75,4 @@ namespace MOUSE
virtual bool GetButtonIndex(const std::string& feature, unsigned int& buttonIndex) = 0;
};
}
+}
diff --git a/xbmc/input/mouse/IMouseDriverHandler.h b/xbmc/input/mouse/IMouseDriverHandler.h
index 9da004a4a4..b3d674016c 100644
--- a/xbmc/input/mouse/IMouseDriverHandler.h
+++ b/xbmc/input/mouse/IMouseDriverHandler.h
@@ -19,6 +19,8 @@
*/
#pragma once
+namespace KODI
+{
namespace MOUSE
{
/*!
@@ -57,3 +59,4 @@ namespace MOUSE
virtual void OnButtonRelease(unsigned int button) = 0;
};
}
+}
diff --git a/xbmc/input/mouse/IMouseInputHandler.h b/xbmc/input/mouse/IMouseInputHandler.h
index 6eda79b954..c388229181 100644
--- a/xbmc/input/mouse/IMouseInputHandler.h
+++ b/xbmc/input/mouse/IMouseInputHandler.h
@@ -21,6 +21,8 @@
#include <string>
+namespace KODI
+{
namespace MOUSE
{
/*!
@@ -67,3 +69,4 @@ namespace MOUSE
virtual void OnButtonRelease(const std::string& button) = 0;
};
}
+}
diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.cpp b/xbmc/input/mouse/MouseWindowingButtonMap.cpp
index e2da4ae005..11442c596a 100644
--- a/xbmc/input/mouse/MouseWindowingButtonMap.cpp
+++ b/xbmc/input/mouse/MouseWindowingButtonMap.cpp
@@ -23,6 +23,7 @@
#include <algorithm>
+using namespace KODI;
using namespace MOUSE;
#define CONTROLLER_PROFILE "game.controller.mouse"
diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.h b/xbmc/input/mouse/MouseWindowingButtonMap.h
index a728257178..f3c7c43d23 100644
--- a/xbmc/input/mouse/MouseWindowingButtonMap.h
+++ b/xbmc/input/mouse/MouseWindowingButtonMap.h
@@ -25,6 +25,8 @@
#include <utility>
#include <vector>
+namespace KODI
+{
namespace MOUSE
{
/*!
@@ -47,3 +49,4 @@ namespace MOUSE
static std::string m_pointerName;
};
}
+}
diff --git a/xbmc/input/mouse/generic/MouseInputHandling.cpp b/xbmc/input/mouse/generic/MouseInputHandling.cpp
index 641dd48ecb..9459b4bb4c 100644
--- a/xbmc/input/mouse/generic/MouseInputHandling.cpp
+++ b/xbmc/input/mouse/generic/MouseInputHandling.cpp
@@ -22,6 +22,7 @@
#include "input/mouse/IMouseButtonMap.h"
#include "input/mouse/IMouseInputHandler.h"
+using namespace KODI;
using namespace MOUSE;
CMouseInputHandling::CMouseInputHandling(IMouseInputHandler* handler, IMouseButtonMap* buttonMap) :
diff --git a/xbmc/input/mouse/generic/MouseInputHandling.h b/xbmc/input/mouse/generic/MouseInputHandling.h
index be1f7a94b6..291e1da9fd 100644
--- a/xbmc/input/mouse/generic/MouseInputHandling.h
+++ b/xbmc/input/mouse/generic/MouseInputHandling.h
@@ -21,6 +21,8 @@
#include "input/mouse/IMouseDriverHandler.h"
+namespace KODI
+{
namespace MOUSE
{
class IMouseInputHandler;
@@ -53,3 +55,4 @@ namespace MOUSE
int m_y;
};
}
+}
diff --git a/xbmc/interfaces/json-rpc/FileOperations.cpp b/xbmc/interfaces/json-rpc/FileOperations.cpp
index ab0ed83a67..1797e4a5db 100644
--- a/xbmc/interfaces/json-rpc/FileOperations.cpp
+++ b/xbmc/interfaces/json-rpc/FileOperations.cpp
@@ -100,7 +100,7 @@ JSONRPC_STATUS CFileOperations::GetDirectory(const std::string &method, ITranspo
else if (media == "pictures")
{
regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
- extensions = g_advancedSettings.m_pictureExtensions;
+ extensions = g_advancedSettings.GetPictureExtensions();
}
if (CDirectory::GetDirectory(strPath, items, extensions))
@@ -362,7 +362,7 @@ bool CFileOperations::FillFileItemList(const CVariant &parameterObject, CFileIte
else if (media == "pictures")
{
regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
- extensions = g_advancedSettings.m_pictureExtensions;
+ extensions = g_advancedSettings.GetPictureExtensions();
}
CDirectory directory;
diff --git a/xbmc/interfaces/json-rpc/JSONRPC.cpp b/xbmc/interfaces/json-rpc/JSONRPC.cpp
index c784ff5960..3749fe55d9 100644
--- a/xbmc/interfaces/json-rpc/JSONRPC.cpp
+++ b/xbmc/interfaces/json-rpc/JSONRPC.cpp
@@ -313,13 +313,13 @@ bool CJSONRPC::HandleMethodCall(const CVariant& request, CVariant& response, ITr
inline bool CJSONRPC::IsProperJSONRPC(const CVariant& inputroot)
{
- return inputroot.isObject() && inputroot.isMember("jsonrpc") && inputroot["jsonrpc"].isString() && inputroot["jsonrpc"] == CVariant("2.0") && inputroot.isMember("method") && inputroot["method"].isString() && (!inputroot.isMember("params") || inputroot["params"].isArray() || inputroot["params"].isObject());
+ return inputroot.isMember("jsonrpc") && inputroot["jsonrpc"].isString() && inputroot["jsonrpc"] == CVariant("2.0") && inputroot.isMember("method") && inputroot["method"].isString() && (!inputroot.isMember("params") || inputroot["params"].isArray() || inputroot["params"].isObject());
}
inline void CJSONRPC::BuildResponse(const CVariant& request, JSONRPC_STATUS code, const CVariant& result, CVariant& response)
{
response["jsonrpc"] = "2.0";
- response["id"] = request.isObject() && request.isMember("id") ? request["id"] : CVariant();
+ response["id"] = request.isMember("id") ? request["id"] : CVariant();
switch (code)
{
diff --git a/xbmc/interfaces/json-rpc/JSONUtils.h b/xbmc/interfaces/json-rpc/JSONUtils.h
index 0e1cd1c55d..4414753567 100644
--- a/xbmc/interfaces/json-rpc/JSONUtils.h
+++ b/xbmc/interfaces/json-rpc/JSONUtils.h
@@ -141,7 +141,7 @@ namespace JSONRPC
\return True if the given object contains a member with
the given key otherwise false
*/
- static inline bool IsValueMember(const CVariant &value, std::string key) { return value.isObject() && value.isMember(key); }
+ static inline bool IsValueMember(const CVariant &value, std::string key) { return value.isMember(key); }
/*!
\brief Returns the json value of a parameter
diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp
index 9d7cde95c1..707d586655 100644
--- a/xbmc/interfaces/json-rpc/PVROperations.cpp
+++ b/xbmc/interfaces/json-rpc/PVROperations.cpp
@@ -21,6 +21,7 @@
#include "PVROperations.h"
#include "messaging/ApplicationMessenger.h"
+#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/channels/PVRChannel.h"
@@ -227,7 +228,7 @@ JSONRPC_STATUS CPVROperations::Record(const std::string &method, ITransportLayer
if (toggle)
{
- if (!g_PVRManager.ToggleRecordingOnChannel(pChannel->ChannelID()))
+ if (!CPVRGUIActions::GetInstance().SetRecordingOnChannel(pChannel, pChannel->IsRecording()))
return FailedToExecute;
}
@@ -239,9 +240,7 @@ JSONRPC_STATUS CPVROperations::Scan(const std::string &method, ITransportLayer *
if (!g_PVRManager.IsStarted())
return FailedToExecute;
- if (!g_PVRManager.IsRunningChannelScan())
- g_PVRManager.StartChannelScan();
-
+ CPVRGUIActions::GetInstance().StartChannelScan();
return ACK;
}
@@ -261,7 +260,7 @@ JSONRPC_STATUS CPVROperations::GetPropertyValue(const std::string &property, CVa
else if (property == "scanning")
{
if (started)
- result = g_PVRManager.IsRunningChannelScan();
+ result = CPVRGUIActions::GetInstance().IsRunningChannelScan();
else
result = false;
}
@@ -345,7 +344,7 @@ JSONRPC_STATUS CPVROperations::AddTimer(const std::string &method, ITransportLay
CPVRTimerInfoTagPtr newTimer = CPVRTimerInfoTag::CreateFromEpg(epgTag, parameterObject["timerrule"].asBoolean(false));
if (newTimer)
{
- if (g_PVRTimers->AddTimer(newTimer))
+ if (CPVRGUIActions::GetInstance().AddTimer(newTimer))
return ACK;
}
return FailedToExecute;
@@ -398,7 +397,7 @@ JSONRPC_STATUS CPVROperations::ToggleTimer(const std::string &method, ITransport
if (!timer)
return InvalidParams;
- sentOkay = g_PVRTimers->AddTimer(timer);
+ sentOkay = CPVRGUIActions::GetInstance().AddTimer(timer);
}
if (sentOkay)
diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
index f325ee0df2..e2cb354a6e 100644
--- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -375,11 +375,9 @@ JSONRPC_STATUS CPlayerOperations::Seek(const std::string &method, ITransportLaye
return FailedToExecute;
const CVariant& value = parameterObject["value"];
- if (IsType(value, NumberValue) ||
- (value.isObject() && value.isMember("percentage")))
+ if (IsType(value, NumberValue) || value.isMember("percentage"))
g_application.SeekPercentage(IsType(value, NumberValue) ? value.asFloat() : value["percentage"].asFloat());
- else if (value.isString() ||
- (value.isObject() && value.isMember("step")))
+ else if (value.isString() || value.isMember("step"))
{
std::string step = value.isString() ? value.asString() : value["step"].asString();
if (step == "smallforward")
@@ -393,7 +391,7 @@ JSONRPC_STATUS CPlayerOperations::Seek(const std::string &method, ITransportLaye
else
return InvalidParams;
}
- else if (value.isObject() && value.isMember("seconds") && value.size() == 1)
+ else if (value.isMember("seconds") && value.size() == 1)
CSeekHandler::GetInstance().SeekSeconds(static_cast<int>(value["seconds"].asInteger()));
else if (value.isObject())
g_application.SeekTime(ParseTimeInSeconds(value.isMember("time") ? value["time"] : value));
@@ -507,7 +505,7 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye
CVariant optionResume = options["resume"];
CVariant optionPlayer = options["playername"];
- if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
+ if (parameterObject["item"].isMember("playlistid"))
{
int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();
@@ -553,7 +551,7 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye
return ACK;
}
- else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path"))
+ else if (parameterObject["item"].isMember("path"))
{
bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) ||
(!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean());
@@ -566,7 +564,7 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye
CApplicationMessenger::GetInstance().SendMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, "playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))");
return ACK;
}
- else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid"))
+ else if (parameterObject["item"].isMember("channelid"))
{
if (!g_PVRManager.IsStarted())
return FailedToExecute;
@@ -591,7 +589,7 @@ JSONRPC_STATUS CPlayerOperations::Open(const std::string &method, ITransportLaye
return ACK;
}
- else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("recordingid"))
+ else if (parameterObject["item"].isMember("recordingid"))
{
if (!g_PVRManager.IsStarted())
return FailedToExecute;
@@ -1759,17 +1757,14 @@ int CPlayerOperations::ParseRepeatState(const CVariant &repeat)
double CPlayerOperations::ParseTimeInSeconds(const CVariant &time)
{
double seconds = 0.0;
- if (time.isObject())
- {
- if (time.isMember("hours"))
- seconds += time["hours"].asInteger() * 60 * 60;
- if (time.isMember("minutes"))
- seconds += time["minutes"].asInteger() * 60;
- if (time.isMember("seconds"))
- seconds += time["seconds"].asInteger();
- if (time.isMember("milliseconds"))
- seconds += time["milliseconds"].asDouble() / 1000.0;
- }
+ if (time.isMember("hours"))
+ seconds += time["hours"].asInteger() * 60 * 60;
+ if (time.isMember("minutes"))
+ seconds += time["minutes"].asInteger() * 60;
+ if (time.isMember("seconds"))
+ seconds += time["seconds"].asInteger();
+ if (time.isMember("milliseconds"))
+ seconds += time["milliseconds"].asDouble() / 1000.0;
return seconds;
}
diff --git a/xbmc/interfaces/json-rpc/SettingsOperations.cpp b/xbmc/interfaces/json-rpc/SettingsOperations.cpp
index 8dfe557e3f..c9328ef403 100644
--- a/xbmc/interfaces/json-rpc/SettingsOperations.cpp
+++ b/xbmc/interfaces/json-rpc/SettingsOperations.cpp
@@ -141,7 +141,7 @@ JSONRPC_STATUS CSettingsOperations::GetSettings(const std::string &method, ITran
{
SettingLevel level = (SettingLevel)ParseSettingLevel(parameterObject["level"].asString());
const CVariant &filter = parameterObject["filter"];
- bool doFilter = filter.isObject() && filter.isMember("section") && filter.isMember("category");
+ bool doFilter = filter.isMember("section") && filter.isMember("category");
std::string strSection, strCategory;
if (doFilter)
{
diff --git a/xbmc/interfaces/legacy/ListItem.cpp b/xbmc/interfaces/legacy/ListItem.cpp
index 1f301327c0..99ec1853eb 100644
--- a/xbmc/interfaces/legacy/ListItem.cpp
+++ b/xbmc/interfaces/legacy/ListItem.cpp
@@ -857,7 +857,7 @@ namespace XBMCAddon
for (const auto& el : alt.later())
{
if (el.which() == second)
- throw WrongTypeException(StringUtils::Format("When using \"%s\" you need to supply a string or list of strings for the value in the dictionary", tag.c_str()).c_str());
+ throw WrongTypeException("When using \"%s\" you need to supply a string or list of strings for the value in the dictionary", tag.c_str());
els.emplace_back(el.former());
}
return els;
diff --git a/xbmc/interfaces/legacy/ModuleXbmc.cpp b/xbmc/interfaces/legacy/ModuleXbmc.cpp
index a9c6d06b6f..1032adb81f 100644
--- a/xbmc/interfaces/legacy/ModuleXbmc.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmc.cpp
@@ -461,7 +461,7 @@ namespace XBMCAddon
else if (strcmpi(mediaType, "music") == 0)
result = g_advancedSettings.GetMusicExtensions();
else if (strcmpi(mediaType, "picture") == 0)
- result = g_advancedSettings.m_pictureExtensions;
+ result = g_advancedSettings.GetPictureExtensions();
//! @todo implement
// else
diff --git a/xbmc/interfaces/python/PythonSwig.cpp.template b/xbmc/interfaces/python/PythonSwig.cpp.template
index 1af3ab210c..f473eb55aa 100644
--- a/xbmc/interfaces/python/PythonSwig.cpp.template
+++ b/xbmc/interfaces/python/PythonSwig.cpp.template
@@ -166,7 +166,7 @@ void doMethod(Node method, MethodType methodType)
<% }
params.each {
%>
- ${SwigTypeParser.SwigType_str(SwigTypeParser.convertTypeToLTypeForParam(it.@type))} ${it.@name} ${it.@value != null ? ' = ' + it.@value : ''};<%
+ ${SwigTypeParser.SwigType_str(SwigTypeParser.convertTypeToLTypeForParam(it.@type))} ${it.@name} ${it.@value != null ? ' = ' + it.@value : SwigTypeParser.SwigType_ispointer(it.@type) ? ' = nullptr' : ''};<%
if (!PythonTools.parameterCanBeUsedDirectly(it) && !doAsMappingIndex)
{ %>
PyObject* py${it.@name} = NULL;<%
diff --git a/xbmc/linux/OMXClock.cpp b/xbmc/linux/OMXClock.cpp
index 0b6dfc3ba0..3764952438 100644
--- a/xbmc/linux/OMXClock.cpp
+++ b/xbmc/linux/OMXClock.cpp
@@ -25,7 +25,7 @@
#if defined(HAVE_OMXLIB)
#include "ServiceBroker.h"
-#include "video/VideoReferenceClock.h"
+#include "cores/VideoPlayer/VideoReferenceClock.h"
#include "settings/Settings.h"
#include "OMXClock.h"
diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp
index 356d64b0b1..053c10deaf 100644
--- a/xbmc/linux/RBP.cpp
+++ b/xbmc/linux/RBP.cpp
@@ -103,7 +103,7 @@ bool CRBP::Initialize()
return true;
}
-void CRBP::LogFirmwareVerison()
+void CRBP::LogFirmwareVersion()
{
char response[1024];
m_DllBcmHost->vc_gencmd(response, sizeof response, "version");
diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h
index eff631d24c..10f5776fd4 100644
--- a/xbmc/linux/RBP.h
+++ b/xbmc/linux/RBP.h
@@ -61,12 +61,12 @@ public:
~CRBP();
bool Initialize();
- void LogFirmwareVerison();
+ void LogFirmwareVersion();
void Deinitialize();
int GetArmMem() { return m_arm_mem; }
int GetGpuMem() { return m_gpu_mem; }
bool GetCodecMpg2() { return m_codec_mpg2_enabled; }
- int RasberryPiVersion() { return g_cpuInfo.getCPUCount() == 1 ? 1 : 2; };
+ int RaspberryPiVersion() { return g_cpuInfo.getCPUCount() == 1 ? 1 : 2; };
bool GetCodecWvc1() { return m_codec_wvc1_enabled; }
void GetDisplaySize(int &width, int &height);
DISPMANX_DISPLAY_HANDLE_T OpenDisplay(uint32_t device);
diff --git a/xbmc/messaging/ApplicationMessenger.h b/xbmc/messaging/ApplicationMessenger.h
index b54b1c88f9..f3ad2aabde 100644
--- a/xbmc/messaging/ApplicationMessenger.h
+++ b/xbmc/messaging/ApplicationMessenger.h
@@ -164,6 +164,79 @@ struct ThreadMessageCallback
class IMessageTarget;
+/*!
+ * \class CApplicationMessenger ApplicationMessenger.h "messaging/ApplicationMessenger.h"
+ * \brief This implements a simple message dispatcher/router for Kodi
+ *
+ * For most users that wants to send message go to the documentation for these
+ * \sa CApplicationMessenger::SendMsg
+ * \sa CApplicationMessenger::PostMsg
+ *
+ * For anyone wanting to implement a message receiver, go to the documentation for
+ * \sa IMessageTarget
+ *
+ * IMPLEMENTATION SPECIFIC NOTES - DOCUMENTED HERE FOR THE SOLE PURPOSE OF IMPLEMENTERS OF THIS CLASS
+ * On a high level this implements two methods for dispatching messages, SendMsg and PostMsg.
+ * These are roughly modeled on the implementation of SendMessage and PostMessage in Windows.
+ *
+ * PostMsg is the preferred method to use as it's non-blocking and does not wait for any response before
+ * returning to the caller. Messages will be stored in a queue and processed in order.
+ *
+ * SendMsg is a blocking version and has a bit more subtleties to it regarding how inter-process
+ * dispatching is handled.
+ *
+ * Calling SendMsg with a message type that doesn't require marshalling will bypass the message queue
+ * and call the receiver directly
+ *
+ * Calling SendMsg with a message type that require marshalling to a specific thread when not on that thread
+ * will add a message to the queue with a an event, it will then block the calling thread waiting on this event
+ * to be signaled.
+ * The message will be processed by the correct thread in it's message pump and the event will be signaled, unblocking
+ * the calling thread
+ *
+ * Calling SendMsg with a message type that require marshalling to a specific thread when already on that thread
+ * will behave as scenario one, it will bypass the queue and call the receiver directly.
+ *
+ * Currently there is a hack implemented in the message dispatcher that releases the graphicslock before dispatching
+ * a message. This was here before the redesign and removing it will require careful inspection of every call site.
+ * TODO: add logging if the graphicslock is held during message dispatch
+ *
+ * Current design has three different message types
+ * 1. Normal messages that can be processed on any thread
+ * 2. GUI messages that require marshalling to the UI thread
+ * 3. A thread message that will spin up a background thread and wait a specified amount of time before posting the message
+ * This should probably be removed, it's left for compatibility
+ *
+ * Heavy emphasis on current design, the idea is that we can easily add more message types to route messages
+ * to more threads or other scenarios.
+ *
+ * \sa CApplicationMessenger::ProcessMessages()
+ * handles regular messages that require no marshalling, this can be called from any thread to drive the message
+ * pump
+ *
+ * \sa CApplicationMessenger::ProcessWindowMessages()
+ * handles GUI messages and currently should only be called on the UI thread
+ *
+ * If/When this is expanded upon ProcessMessage() and ProcessWindowMessages() should be combined into a single method
+ * taking an enum or similar to indicate which message it's interested in.
+ *
+ * The above methods are backed by two messages queues, one for each type of message. If more types are added
+ * this might need to be redesigned to simplify the lookup of the correct message queue but currently they're implemented
+ * as two member variables
+ *
+ * The design is meant to be very encapsulated and easy to extend without altering the public interface.
+ * e.g. If GUI messages should be handled on another thread, call \sa CApplicationMessenger::ProcessWindowMessage() on that
+ * thread and nothing else has to change. The callers have no knowledge of how this is implemented.
+ *
+ * The design is also meant to be very dependency free to work as a bridge between lower layer functionality without
+ * having to have knowledge of the GUI or having a dependency on the GUI in any way. This is not the reality currently as
+ * this depends on \sa CApplication and the graphicslock but should be fixed soon enough.
+ *
+ * To keep things simple the current implementation routes messages based on a mask that the receiver provides.
+ * Any message fitting that mask will be routed to that specific receiver.
+ * This will likely need to change if many different receivers are added but it should be possible to do it without
+ * any of the callers being changed.
+ */
class CApplicationMessenger
{
public:
@@ -175,27 +248,156 @@ public:
void Cleanup();
// if a message has to be send to the gui, use MSG_TYPE_WINDOW instead
+ /*!
+ * \brief Send a blocking message and wait for a response
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * Under no circumestances shall the caller hold a lock when calling SendMsg as there's
+ * no guarantee what the receiver will do to answer the request.
+ *
+ * \param [in] messageId defined further up in this file
+ * \return meaning of the return varies based on the message
+ */
int SendMsg(uint32_t messageId);
+
+ /*!
+ * \brief Send a blocking message and wait for a response
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * Under no circumestances shall the caller hold a lock when calling SendMsg as there's
+ * no guarantee what the receiver will do to answer the request.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent, defaults to -1
+ * \param [in] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ * \return meaning of the return varies based on the message
+ */
int SendMsg(uint32_t messageId, int param1, int param2 = -1, void* payload = nullptr);
+
+ /*!
+ * \brief Send a blocking message and wait for a response
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * Under no circumestances shall the caller hold a lock when calling SendMsg as there's
+ * no guarantee what the receiver will do to answer the request.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent
+ * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ * \param [in] strParam value depends on the message being sent, remains for backward compat
+ * \return meaning of the return varies based on the message
+ */
int SendMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam);
+
+ /*!
+ * \brief Send a blocking message and wait for a response
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * Under no circumestances shall the caller hold a lock when calling SendMsg as there's
+ * no guarantee what the receiver will do to answer the request.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent
+ * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ * \param [in] strParam value depends on the message being sent, remains for backward compat
+ * \param [in] params value depends on the message being sent, kept for backward compatiblity
+ * \return meaning of the return varies based on the message
+ */
int SendMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam, std::vector<std::string> params);
+ /*!
+ * \brief Send a non-blocking message and return immediately
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * \param [in] messageId defined further up in this file
+ */
void PostMsg(uint32_t messageId);
+
+ /*!
+ * \brief Send a non-blocking message and return immediately
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent
+ * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ */
void PostMsg(uint32_t messageId, int param1, int param2 = -1, void* payload = nullptr);
+
+ /*!
+ * \brief Send a non-blocking message and return immediately
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent
+ * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ * \param [in] strParam value depends on the message being sent, remains for backward compat
+ */
void PostMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam);
+ /*!
+ * \brief Send a non-blocking message and return immediately
+ *
+ * If and what the response is depends entirely on the message being sent and
+ * should be documented on the message.
+ *
+ * \param [in] messageId defined further up in this file
+ * \param [in] param1 value depends on the message being sent
+ * \param [in] param2 value depends on the message being sent
+ * \param [in,out] payload this is a void pointer that is meant to send larger objects to the receiver
+ * what to send depends on the message
+ * \param [in] strParam value depends on the message being sent, remains for backward compat
+ * \param [in] params value depends on the message being sent, kept for backward compatiblity
+ */
void PostMsg(uint32_t messageId, int param1, int param2, void* payload, std::string strParam, std::vector<std::string> params);
- void ProcessMessages(); // only call from main thread.
+ /*!
+ * \brief Called from any thread to dispatch messages
+ */
+ void ProcessMessages();
+
+ /*!
+ * \brief Called from the UI thread to dispatch UI messages
+ * This is only of value to implementers of the message pump, do not rely on a specific thread
+ * being used other than that it's appropriate for UI messages
+ */
void ProcessWindowMessages();
/*! \brief Send a GUIMessage, optionally waiting before it's processed to return.
- Should be used to send messages to the GUI from other threads.
- \param msg the GUIMessage to send.
- \param windowID optional window to send the message to (defaults to no specified window).
- \param waitResult whether to wait for the result (defaults to false).
+ * This is kept for backward compat and is just a convenience wrapper for for SendMsg and PostMsg
+ * specifically for UI messages
+ * \param msg the GUIMessage to send.
+ * \param windowID optional window to send the message to (defaults to no specified window).
+ * \param waitResult whether to wait for the result (defaults to false).
*/
void SendGUIMessage(const CGUIMessage &msg, int windowID = WINDOW_INVALID, bool waitResult=false);
+ /*!
+ * \brief This should be called any class implementing \sa IMessageTarget before it
+ * can receive any messages
+ */
void RegisterReceiver(IMessageTarget* target);
private:
@@ -208,9 +410,9 @@ private:
int SendMsg(ThreadMessage&& msg, bool wait);
void ProcessMessage(ThreadMessage *pMsg);
- std::queue<ThreadMessage*> m_vecMessages;
- std::queue<ThreadMessage*> m_vecWindowMessages;
- std::map<int, IMessageTarget*> m_mapTargets;
+ std::queue<ThreadMessage*> m_vecMessages; /*!< queue for regular messages */
+ std::queue<ThreadMessage*> m_vecWindowMessages; /*!< queue for UI messages */
+ std::map<int, IMessageTarget*> m_mapTargets; /*!< a map of registered receivers indexed on the message mask*/
CCriticalSection m_critSection;
};
}
diff --git a/xbmc/messaging/IMessageTarget.h b/xbmc/messaging/IMessageTarget.h
index b59f150b54..a67d9adf9f 100644
--- a/xbmc/messaging/IMessageTarget.h
+++ b/xbmc/messaging/IMessageTarget.h
@@ -25,11 +25,43 @@ namespace MESSAGING
{
class ThreadMessage;
+/*!
+ * \class IMessageTarget IMessageTarget.h "messaging/IMessageTarget.h"
+ * \brief A class wishing to receive messages should implement this
+ * and call \sa CApplicationMessenger::RegisterReceiver
+ * to start receiving messages
+ */
class IMessageTarget
{
public:
virtual ~IMessageTarget() { }
+ /*!
+ * \brief Should return the message mask that it wishes to receive
+ * messages for
+ *
+ * The message mask is defined in "messaging/ApplicationMessenger.h"
+ * pick the next one available when creating a new
+ */
virtual int GetMessageMask() = 0;
+
+ /*!
+ * \brief This gets called whenever a message matching the registered
+ * message mask is processed.
+ *
+ * There are no ordering guarantees here so implementations should never
+ * rely on a certain ordering of messages.
+ *
+ * Cleaning up any pointers stored in the message payload is not specified
+ * and is decided by the implementer of the message.
+ * In general prefer to delete any data in this method to keep the callsites cleaner
+ * and simpler but if data is to be passed back it's perfectly valid to handle it any way
+ * that fits the situation as long as it's documented along with the message.
+ *
+ * To return a simple value the result parameter of \sa ThreadMessage can be used
+ * as it will be used as the return value for \sa CApplicationMessenger::SendMsg.
+ * It is up to the implementer to decide if this is to be used and it should be documented
+ * along with any new message implemented.
+ */
virtual void OnApplicationMessage(ThreadMessage* msg) = 0;
};
}
diff --git a/xbmc/messaging/ThreadMessage.h b/xbmc/messaging/ThreadMessage.h
index 86fd4d4741..6471f2ffdc 100644
--- a/xbmc/messaging/ThreadMessage.h
+++ b/xbmc/messaging/ThreadMessage.h
@@ -125,7 +125,12 @@ public:
std::string strParam;
std::vector<std::string> params;
- void SetResult(int res)
+ /*!
+ * \brief set the message return value, will only be returned when
+ * the message is sent using SendMsg
+ * \param [in] res the return value or a result status code that is returned to the caller
+ */
+ void SetResult(int res) const
{
//On posted messages result will be zero, since they can't
//retrieve the response we silently ignore this to let message
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index 57b6047c72..0fb70f1b6f 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -192,6 +192,10 @@ void CMusicDatabase::CreateTables()
CLog::Log(LOGINFO, "create cue table");
m_pDS->exec("CREATE TABLE cue (idPath integer, strFileName text, strCuesheet text)");
+
+ CLog::Log(LOGINFO, "create versiontagscan table");
+ m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)");
+ m_pDS->exec(PrepareSQL("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(%i, 0)", GetSchemaVersion()));
}
void CMusicDatabase::CreateAnalytics()
@@ -4250,19 +4254,25 @@ bool CMusicDatabase::GetSongsFullByWhere(const std::string &baseDir, const Filte
// Count number of songs that satisfy selection criteria
total = (int)strtol(GetSingleValue("SELECT COUNT(1) FROM songview " + strSQLExtra, m_pDS).c_str(), NULL, 10);
- // Apply the limiting directly here if there's no special sorting but limiting
- bool limited = extFilter.limit.empty() && sortDescription.sortBy == SortByNone &&
+ // Apply any limiting directly in SQL if there is either no special sorting or random sort
+ // When limited, random sort is also applied in SQL
+ bool limitedInSQL = extFilter.limit.empty() &&
+ (sortDescription.sortBy == SortByNone || sortDescription.sortBy == SortByRandom) &&
(sortDescription.limitStart > 0 || sortDescription.limitEnd > 0);
- if (limited)
+ if (limitedInSQL)
+ {
+ if (sortDescription.sortBy == SortByRandom)
+ strSQLExtra += PrepareSQL(" ORDER BY RANDOM()");
strSQLExtra += DatabaseUtils::BuildLimitClause(sortDescription.limitEnd, sortDescription.limitStart);
+ }
std::string strSQL;
if (artistData)
{ // Get data from song and song_artist tables to fully populate songs with artists
// All songs now have at least one artist so inner join sufficient
// Need guaranteed ordering for dataset processing to extract songs
- if (limited)
- //Apply where clause and limits to songview, then join as multiple records in result set per song
+ if (limitedInSQL)
+ //Apply where clause, limits and random order to songview, then join as multiple records in result set per song
strSQL = "SELECT sv.*, songartistview.* "
"FROM (SELECT songview.* FROM songview " + strSQLExtra + ") AS sv "
"JOIN songartistview ON songartistview.idsong = sv.idsong ";
@@ -4355,8 +4365,9 @@ bool CMusicDatabase::GetSongsFullByWhere(const std::string &baseDir, const Filte
// cleanup
m_pDS->close();
- // When have join with songartistview apply sort (and limit) to items rather than dataset
- if (artistData && sortDescription.sortBy != SortByNone)
+ // Finally do any sorting in items list we have not been able to do before in SQL or dataset,
+ // that is when have join with songartistview and sorting other than random with limit
+ if (artistData && sortDescription.sortBy != SortByNone && !(limitedInSQL && sortDescription.sortBy == SortByRandom))
items.Sort(sortDescription);
if (cueSheetData)
@@ -4662,8 +4673,6 @@ void CMusicDatabase::UpdateTables(int version)
if (version < 53)
{
m_pDS->exec("ALTER TABLE song ADD dateAdded text");
- CMediaSettings::GetInstance().SetMusicNeedsUpdate(53);
- CServiceBroker::GetSettings().Save();
}
if (version < 54)
{
@@ -4958,17 +4967,78 @@ void CMusicDatabase::UpdateTables(int version)
//Remove temp indices, full analytics for database created later
m_pDS->exec("DROP INDEX idxSongArtist1 ON song_artist");
m_pDS->exec("DROP INDEX idxAlbumArtist1 ON album_artist");
-
- // Prompt for rescan of library to read tags that were not processed by previous versions
- // and accomodate changes to the way some tags are processed
- CMediaSettings::GetInstance().SetMusicNeedsUpdate(60);
- CServiceBroker::GetSettings().Save();
}
+ if (version < 61)
+ {
+ // Create versiontagscan table
+ m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)");
+ m_pDS->exec("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(0, 0)");
+ }
+
+ // Set the version of tag scanning required.
+ // Not every schema change requires the tags to be rescanned, set to the highest schema version
+ // that needs this. Forced rescanning (of music files that have not changed since they were
+ // previously scanned) also accommodates any changes to the way tags are processed
+ // e.g. read tags that were not processed by previous versions.
+ // The original db version when the tags were scanned, and the minimal db version needed are
+ // later used to determine if a forced rescan should be prompted
+
+ // The last schema change needing forced rescanning was 60.
+ // Mostly because of the new tags processed by v17 rather than a schema change.
+ SetMusicNeedsTagScan(60);
+
+ // After all updates, store the original db version.
+ // This indicates the version of tag processing that was used to populate db
+ SetMusicTagScanVersion(version);
}
int CMusicDatabase::GetSchemaVersion() const
{
- return 60;
+ return 61;
+}
+
+int CMusicDatabase::GetMusicNeedsTagScan()
+{
+ try
+ {
+ if (NULL == m_pDB.get()) return -1;
+ if (NULL == m_pDS.get()) return -1;
+
+ std::string sql = "SELECT * FROM versiontagscan";
+ if (!m_pDS->query(sql)) return -1;
+
+ if (m_pDS->num_rows() != 1)
+ {
+ m_pDS->close();
+ return -1;
+ }
+
+ int idVersion = m_pDS->fv("idVersion").get_asInt();
+ int iNeedsScan = m_pDS->fv("iNeedsScan").get_asInt();
+ m_pDS->close();
+ if (idVersion < iNeedsScan)
+ return idVersion;
+ else
+ return 0;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
+ }
+ return -1;
+}
+
+void CMusicDatabase::SetMusicNeedsTagScan(int version)
+{
+ m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET iNeedsScan=%i", version));
+}
+
+void CMusicDatabase::SetMusicTagScanVersion(int version /* = 0 */)
+{
+ if (version == 0)
+ m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", GetSchemaVersion()));
+ else
+ m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", version));
}
unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, std::vector<std::pair<int,int> > &songIDs)
diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h
index f51a981a2d..3bc2caa15b 100644
--- a/xbmc/music/MusicDatabase.h
+++ b/xbmc/music/MusicDatabase.h
@@ -497,6 +497,26 @@ public:
*/
std::string GetArtistArtForItem(int mediaId, const std::string &mediaType, const std::string &artType);
+ /////////////////////////////////////////////////
+ // Tag Scan Version
+ /////////////////////////////////////////////////
+ /*! \brief Check if music files need all tags rescanning regardless of file being unchanged
+ because the tag processing has changed (which may happen without db version changes) since they
+ where last scanned.
+ \return -1 if an error occured, 0 if no scan is needed, or the version number of tags if not the same as current.
+ */
+ virtual int GetMusicNeedsTagScan();
+
+ /*! \brief Set minimum version number of db needed when tag data scanned from music files
+ \param version the version number of db
+ */
+ void SetMusicNeedsTagScan(int version);
+
+ /*! \brief Set the version number of tag data
+ \param version the version number of db when tags last scanned, 0 (default) means current db version
+ */
+ void SetMusicTagScanVersion(int version = 0);
+
protected:
std::map<std::string, int> m_artistCache;
std::map<std::string, int> m_genreCache;
diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp
index 6bf6628b21..0991c5f76d 100644
--- a/xbmc/music/infoscanner/MusicInfoScanner.cpp
+++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp
@@ -92,18 +92,6 @@ void CMusicInfoScanner::Process()
ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnScanStarted");
try
{
- if (m_bClean)
- {
- CleanDatabase(false);
- m_bRunning = false;
-
- return;
- }
-
- unsigned int tick = XbmcThreads::SystemClockMillis();
-
- m_musicDatabase.Open();
-
if (m_showDialog && !CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE))
{
CGUIDialogExtendedProgressBar* dialog =
@@ -112,8 +100,18 @@ void CMusicInfoScanner::Process()
m_handle = dialog->GetHandle(g_localizeStrings.Get(314));
}
- m_bClean = g_advancedSettings.m_bMusicLibraryCleanOnUpdate;
+ // check if we only need to perform a cleaning
+ if (m_bClean && m_pathsToScan.empty())
+ {
+ CleanDatabase(false);
+ m_handle = NULL;
+ m_bRunning = false;
+ return;
+ }
+
+ unsigned int tick = XbmcThreads::SystemClockMillis();
+ m_musicDatabase.Open();
m_bCanInterrupt = true;
if (m_scanType == 0) // load info from files
@@ -287,7 +285,8 @@ void CMusicInfoScanner::Start(const std::string& strDirectory, int flags)
}
else
m_pathsToScan.insert(strDirectory);
- m_bClean = false;
+
+ m_bClean = g_advancedSettings.m_bMusicLibraryCleanOnUpdate;
m_scanType = 0;
Create();
@@ -416,7 +415,7 @@ bool CMusicInfoScanner::IsScanning()
void CMusicInfoScanner::Stop(bool wait /* = false*/)
{
if (m_bCanInterrupt)
- m_musicDatabase.Interupt();
+ m_musicDatabase.Interrupt();
StopThread(wait);
}
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index 81e457a04c..6cc1c68039 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -1308,7 +1308,7 @@ void CGUIWindowMusicBase::OnInitWindow()
CGUIMediaWindow::OnInitWindow();
// Prompt for rescan of library to read music file tags that were not processed by previous versions
// and accomodate any changes to the way some tags are processed
- if (CMediaSettings::GetInstance().GetMusicNeedsUpdate() != 0)
+ if (m_musicdatabase.GetMusicNeedsTagScan() != 0)
{
if (g_infoManager.GetLibraryBool(LIBRARY_HAS_MUSIC) && !g_application.IsMusicScanning())
{
@@ -1324,15 +1324,13 @@ void CGUIWindowMusicBase::OnInitWindow()
if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE))
flags |= CMusicInfoScanner::SCAN_BACKGROUND;
g_application.StartMusicScan("", true, flags);
- CMediaSettings::GetInstance().SetMusicNeedsUpdate(0); // once is enough (user may interrupt, but that's up to them)
- CServiceBroker::GetSettings().Save();
+ m_musicdatabase.SetMusicTagScanVersion(); // once is enough (user may interrupt, but that's up to them)
}
}
else
{
// no need to force a rescan if there's no music in the library or if a library scan is already active
- CMediaSettings::GetInstance().SetMusicNeedsUpdate(0);
- CServiceBroker::GetSettings().Save();
+ m_musicdatabase.SetMusicTagScanVersion();
}
}
}
diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp
index 466468539f..2f9e0f796b 100644
--- a/xbmc/network/AirTunesServer.cpp
+++ b/xbmc/network/AirTunesServer.cpp
@@ -365,7 +365,7 @@ void* CAirTunesServer::AudioOutputFunctions::audio_init(void *cls, int bits, int
XFILE::CPipeFile *pipe=(XFILE::CPipeFile *)cls;
const CURL pathToUrl(XFILE::PipesManager::GetInstance().GetUniquePipeName());
pipe->OpenForWrite(pathToUrl);
- pipe->SetOpenThreashold(300);
+ pipe->SetOpenThreshold(300);
Demux_BXA_FmtHeader header;
strncpy(header.fourcc, "BXA ", 4);
diff --git a/xbmc/network/cddb.cpp b/xbmc/network/cddb.cpp
index 5831a1968d..0cf1caa34b 100644
--- a/xbmc/network/cddb.cpp
+++ b/xbmc/network/cddb.cpp
@@ -730,7 +730,7 @@ void Xcddb::addInexactListLine(int line_cnt, const char *line, int len)
}
//-------------------------------------------------------------------------------------------------------------------
-void Xcddb::setCDDBIpAdress(const std::string& ip_address)
+void Xcddb::setCDDBIpAddress(const std::string& ip_address)
{
m_cddb_ip_address = ip_address;
}
diff --git a/xbmc/network/cddb.h b/xbmc/network/cddb.h
index ef2dc2ef9c..de8da75eca 100644
--- a/xbmc/network/cddb.h
+++ b/xbmc/network/cddb.h
@@ -67,7 +67,7 @@ class Xcddb
public:
Xcddb();
virtual ~Xcddb();
- void setCDDBIpAdress(const std::string& ip_address);
+ void setCDDBIpAddress(const std::string& ip_address);
void setCacheDir(const std::string& pCacheDir );
// int queryCDinfo(int real_track_count, toc cdtoc[]);
diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp
index a2e1f9c869..10d3e9fc29 100644
--- a/xbmc/network/upnp/UPnPServer.cpp
+++ b/xbmc/network/upnp/UPnPServer.cpp
@@ -677,7 +677,7 @@ CUPnPServer::OnBrowseDirectChildren(PLT_ActionReference& action,
// this is the only way to hide unplayable items in the 'files'
// view as we cannot tell what context (eg music vs video) the
// request came from
- std::string supported = g_advancedSettings.m_pictureExtensions + "|"
+ std::string supported = g_advancedSettings.GetPictureExtensions() + "|"
+ g_advancedSettings.m_videoExtensions + "|"
+ g_advancedSettings.GetMusicExtensions() + "|"
+ g_advancedSettings.m_discStubExtensions;
diff --git a/xbmc/network/websocket/WebSocket.h b/xbmc/network/websocket/WebSocket.h
index 6e2c4ae954..769156c94c 100644
--- a/xbmc/network/websocket/WebSocket.h
+++ b/xbmc/network/websocket/WebSocket.h
@@ -69,7 +69,7 @@ public:
virtual int8_t GetExtension() const { return m_extension; }
virtual WebSocketFrameOpcode GetOpcode() const { return m_opcode; }
virtual bool IsControlFrame() const { return (m_valid && (m_opcode & 0x8) == 0x8); }
- virtual bool IsMasekd() const { return m_masked; }
+ virtual bool IsMasked() const { return m_masked; }
virtual uint64_t GetLength() const { return m_length; }
virtual int32_t GetMask() const { return m_mask; }
virtual const char* GetFrameData() const { return m_data; }
diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp
index a92ce3c4e3..7d1bbfeb75 100644
--- a/xbmc/peripherals/Peripherals.cpp
+++ b/xbmc/peripherals/Peripherals.cpp
@@ -69,7 +69,7 @@
#include "bus/virtual/PeripheralBusCEC.h"
#endif
-
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
using namespace XFILE;
@@ -132,7 +132,7 @@ void CPeripherals::Initialise()
m_eventScanner.Start();
m_bInitialised = true;
- KODI::MESSAGING::CApplicationMessenger::GetInstance().RegisterReceiver(this);
+ MESSAGING::CApplicationMessenger::GetInstance().RegisterReceiver(this);
}
void CPeripherals::Clear()
@@ -964,7 +964,7 @@ void CPeripherals::OnSettingAction(const CSetting *setting)
TestFeature(FEATURE_RUMBLE);
}
-void CPeripherals::OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg)
+void CPeripherals::OnApplicationMessage(MESSAGING::ThreadMessage* pMsg)
{
switch (pMsg->dwMessage)
{
diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h
index 6495b5ecba..63d4e91da7 100644
--- a/xbmc/peripherals/Peripherals.h
+++ b/xbmc/peripherals/Peripherals.h
@@ -39,10 +39,13 @@ class TiXmlElement;
class CAction;
class CKey;
+namespace KODI
+{
namespace JOYSTICK
{
class IButtonMapper;
}
+}
namespace PERIPHERALS
{
@@ -277,13 +280,13 @@ namespace PERIPHERALS
* \ref CPeripheral::RegisterJoystickButtonMapper for what is done to the
* mapper after being given to the peripheral.
*/
- void RegisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
+ void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
/*!
* \brief Unregister a button mapper interface
* \param mapper The button mapper
*/
- void UnregisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
+ void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
virtual void OnSettingChanged(const CSetting *setting) override;
virtual void OnSettingAction(const CSetting *setting) override;
diff --git a/xbmc/peripherals/addons/AddonButtonMap.cpp b/xbmc/peripherals/addons/AddonButtonMap.cpp
index 039c5ba02f..5beb76b80a 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.cpp
+++ b/xbmc/peripherals/addons/AddonButtonMap.cpp
@@ -28,6 +28,7 @@
#include <assert.h>
#include <vector>
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/addons/AddonButtonMap.h b/xbmc/peripherals/addons/AddonButtonMap.h
index 172d6b275a..eddbaca2cf 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.h
+++ b/xbmc/peripherals/addons/AddonButtonMap.h
@@ -31,7 +31,7 @@ namespace PERIPHERALS
{
class CPeripheral;
- class CAddonButtonMap : public JOYSTICK::IButtonMap
+ class CAddonButtonMap : public KODI::JOYSTICK::IButtonMap
{
public:
CAddonButtonMap(CPeripheral* device, const std::weak_ptr<CPeripheralAddon>& addon, const std::string& strControllerId);
@@ -50,53 +50,53 @@ namespace PERIPHERALS
virtual bool IsEmpty(void) const override;
virtual bool GetFeature(
- const JOYSTICK::CDriverPrimitive& primitive,
- JOYSTICK::FeatureName& feature
+ const KODI::JOYSTICK::CDriverPrimitive& primitive,
+ KODI::JOYSTICK::FeatureName& feature
) override;
- virtual JOYSTICK::FEATURE_TYPE GetFeatureType(
- const JOYSTICK::FeatureName& feature
+ virtual KODI::JOYSTICK::FEATURE_TYPE GetFeatureType(
+ const KODI::JOYSTICK::FeatureName& feature
) override;
virtual bool GetScalar(
- const JOYSTICK::FeatureName& feature,
- JOYSTICK::CDriverPrimitive& primitive
+ const KODI::JOYSTICK::FeatureName& feature,
+ KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
virtual void AddScalar(
- const JOYSTICK::FeatureName& feature,
- const JOYSTICK::CDriverPrimitive& primitive
+ const KODI::JOYSTICK::FeatureName& feature,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
virtual bool GetAnalogStick(
- const JOYSTICK::FeatureName& feature,
- JOYSTICK::ANALOG_STICK_DIRECTION direction,
- JOYSTICK::CDriverPrimitive& primitive
+ const KODI::JOYSTICK::FeatureName& feature,
+ KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
virtual void AddAnalogStick(
- const JOYSTICK::FeatureName& feature,
- JOYSTICK::ANALOG_STICK_DIRECTION direction,
- const JOYSTICK::CDriverPrimitive& primitive
+ const KODI::JOYSTICK::FeatureName& feature,
+ KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ const KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
virtual bool GetAccelerometer(
- const JOYSTICK::FeatureName& feature,
- JOYSTICK::CDriverPrimitive& positiveX,
- JOYSTICK::CDriverPrimitive& positiveY,
- JOYSTICK::CDriverPrimitive& positiveZ
+ const KODI::JOYSTICK::FeatureName& feature,
+ KODI::JOYSTICK::CDriverPrimitive& positiveX,
+ KODI::JOYSTICK::CDriverPrimitive& positiveY,
+ KODI::JOYSTICK::CDriverPrimitive& positiveZ
) override;
virtual void AddAccelerometer(
- const JOYSTICK::FeatureName& feature,
- const JOYSTICK::CDriverPrimitive& positiveX,
- const JOYSTICK::CDriverPrimitive& positiveY,
- const JOYSTICK::CDriverPrimitive& positiveZ
+ const KODI::JOYSTICK::FeatureName& feature,
+ const KODI::JOYSTICK::CDriverPrimitive& positiveX,
+ const KODI::JOYSTICK::CDriverPrimitive& positiveY,
+ const KODI::JOYSTICK::CDriverPrimitive& positiveZ
) override;
- virtual void SetIgnoredPrimitives(const std::vector<JOYSTICK::CDriverPrimitive>& primitives) override;
+ virtual void SetIgnoredPrimitives(const std::vector<KODI::JOYSTICK::CDriverPrimitive>& primitives) override;
- virtual bool IsIgnored(const JOYSTICK::CDriverPrimitive& primitive) override;
+ virtual bool IsIgnored(const KODI::JOYSTICK::CDriverPrimitive& primitive) override;
virtual bool GetAxisProperties(unsigned int axisIndex, int& center, unsigned int& range) override;
@@ -105,13 +105,13 @@ namespace PERIPHERALS
virtual void RevertButtonMap() override;
private:
- typedef std::map<JOYSTICK::CDriverPrimitive, JOYSTICK::FeatureName> DriverMap;
- typedef std::vector<JOYSTICK::CDriverPrimitive> JoystickPrimitiveVector;
+ typedef std::map<KODI::JOYSTICK::CDriverPrimitive, KODI::JOYSTICK::FeatureName> DriverMap;
+ typedef std::vector<KODI::JOYSTICK::CDriverPrimitive> JoystickPrimitiveVector;
// Utility functions
static DriverMap CreateLookupTable(const FeatureMap& features);
- static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(JOYSTICK::ANALOG_STICK_DIRECTION dir);
+ static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(KODI::JOYSTICK::ANALOG_STICK_DIRECTION dir);
CPeripheral* const m_device;
std::weak_ptr<CPeripheralAddon> m_addon;
diff --git a/xbmc/peripherals/addons/AddonButtonMapping.cpp b/xbmc/peripherals/addons/AddonButtonMapping.cpp
index d7c08d0b32..8717033c87 100644
--- a/xbmc/peripherals/addons/AddonButtonMapping.cpp
+++ b/xbmc/peripherals/addons/AddonButtonMapping.cpp
@@ -25,6 +25,7 @@
#include "peripherals/Peripherals.h"
#include "utils/log.h"
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/addons/AddonButtonMapping.h b/xbmc/peripherals/addons/AddonButtonMapping.h
index fa18d5ca7a..1474ef2a1a 100644
--- a/xbmc/peripherals/addons/AddonButtonMapping.h
+++ b/xbmc/peripherals/addons/AddonButtonMapping.h
@@ -24,28 +24,31 @@
#include <memory>
+namespace KODI
+{
namespace JOYSTICK
{
class CButtonMapping;
class IButtonMap;
class IButtonMapper;
}
+}
namespace PERIPHERALS
{
class CPeripheral;
- class CAddonButtonMapping : public JOYSTICK::IDriverHandler,
- public JOYSTICK::IButtonMapCallback
+ class CAddonButtonMapping : public KODI::JOYSTICK::IDriverHandler,
+ public KODI::JOYSTICK::IButtonMapCallback
{
public:
- CAddonButtonMapping(CPeripheral* peripheral, JOYSTICK::IButtonMapper* mapper);
+ CAddonButtonMapping(CPeripheral* peripheral, KODI::JOYSTICK::IButtonMapper* mapper);
virtual ~CAddonButtonMapping(void);
// implementation of IDriverHandler
virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override;
- virtual bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state) override;
+ virtual bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state) override;
virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override;
virtual void ProcessAxisMotions(void) override;
@@ -55,7 +58,7 @@ namespace PERIPHERALS
virtual void RevertButtonMap() override;
private:
- std::unique_ptr<JOYSTICK::CButtonMapping> m_buttonMapping;
- std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap;
+ std::unique_ptr<KODI::JOYSTICK::CButtonMapping> m_buttonMapping;
+ std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap;
};
}
diff --git a/xbmc/peripherals/addons/AddonInputHandling.cpp b/xbmc/peripherals/addons/AddonInputHandling.cpp
index a598fbbafd..cc995ee0b5 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.cpp
+++ b/xbmc/peripherals/addons/AddonInputHandling.cpp
@@ -28,6 +28,7 @@
#include "peripherals/Peripherals.h"
#include "utils/log.h"
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/addons/AddonInputHandling.h b/xbmc/peripherals/addons/AddonInputHandling.h
index a1c7b2346f..b249792b99 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.h
+++ b/xbmc/peripherals/addons/AddonInputHandling.h
@@ -24,37 +24,40 @@
#include <memory>
+namespace KODI
+{
namespace JOYSTICK
{
class IButtonMap;
class IDriverReceiver;
class IInputHandler;
}
+}
namespace PERIPHERALS
{
class CPeripheral;
- class CAddonInputHandling : public JOYSTICK::IDriverHandler,
- public JOYSTICK::IInputReceiver
+ class CAddonInputHandling : public KODI::JOYSTICK::IDriverHandler,
+ public KODI::JOYSTICK::IInputReceiver
{
public:
- CAddonInputHandling(CPeripheral* peripheral, JOYSTICK::IInputHandler* handler, JOYSTICK::IDriverReceiver* receiver);
+ CAddonInputHandling(CPeripheral* peripheral, KODI::JOYSTICK::IInputHandler* handler, KODI::JOYSTICK::IDriverReceiver* receiver);
virtual ~CAddonInputHandling(void);
// implementation of IDriverHandler
virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override;
- virtual bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state) override;
+ virtual bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state) override;
virtual bool OnAxisMotion(unsigned int axisIndex, float position, int center, unsigned int range) override;
virtual void ProcessAxisMotions(void) override;
// implementation of IInputReceiver
- virtual bool SetRumbleState(const JOYSTICK::FeatureName& feature, float magnitude) override;
+ virtual bool SetRumbleState(const KODI::JOYSTICK::FeatureName& feature, float magnitude) override;
private:
- std::unique_ptr<JOYSTICK::IDriverHandler> m_driverHandler;
- std::unique_ptr<JOYSTICK::IInputReceiver> m_inputReceiver;
- std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap;
+ std::unique_ptr<KODI::JOYSTICK::IDriverHandler> m_driverHandler;
+ std::unique_ptr<KODI::JOYSTICK::IInputReceiver> m_inputReceiver;
+ std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap;
};
}
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index b070ac7484..2b408fe980 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -43,6 +43,7 @@
#include <string.h>
#include <utility>
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
using namespace XFILE;
diff --git a/xbmc/peripherals/addons/PeripheralAddon.h b/xbmc/peripherals/addons/PeripheralAddon.h
index afb5c5760e..016a3fe793 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.h
+++ b/xbmc/peripherals/addons/PeripheralAddon.h
@@ -30,11 +30,14 @@
#include <memory>
#include <vector>
+namespace KODI
+{
namespace JOYSTICK
{
class IButtonMap;
class IDriverHandler;
}
+}
namespace PERIPHERALS
{
@@ -42,7 +45,7 @@ namespace PERIPHERALS
class CPeripheralJoystick;
typedef std::vector<ADDON::DriverPrimitive> PrimitiveVector;
- typedef std::map<JOYSTICK::FeatureName, ADDON::JoystickFeature> FeatureMap;
+ typedef std::map<KODI::JOYSTICK::FeatureName, ADDON::JoystickFeature> FeatureMap;
class CPeripheralAddon : public ADDON::CAddonDll
{
@@ -93,8 +96,8 @@ namespace PERIPHERALS
void PowerOffJoystick(unsigned int index);
//@}
- void RegisterButtonMap(CPeripheral* device, JOYSTICK::IButtonMap* buttonMap);
- void UnregisterButtonMap(JOYSTICK::IButtonMap* buttonMap);
+ void RegisterButtonMap(CPeripheral* device, KODI::JOYSTICK::IButtonMap* buttonMap);
+ void UnregisterButtonMap(KODI::JOYSTICK::IButtonMap* buttonMap);
void RefreshButtonMaps(const std::string& strDeviceName = "");
protected:
@@ -149,7 +152,7 @@ namespace PERIPHERALS
std::map<unsigned int, PeripheralPtr> m_peripherals;
/* @brief Button map observers */
- std::vector<std::pair<CPeripheral*, JOYSTICK::IButtonMap*> > m_buttonMaps;
+ std::vector<std::pair<CPeripheral*, KODI::JOYSTICK::IButtonMap*> > m_buttonMaps;
CCriticalSection m_buttonMapMutex;
/* @brief Thread synchronization */
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
index 3ab40dea6a..4c9725cc84 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
@@ -24,6 +24,7 @@
#include <algorithm>
#include <iterator>
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.h b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
index 88e74dc966..94388641cb 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.h
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
@@ -37,22 +37,22 @@ namespace PERIPHERALS
static PeripheralType TranslateType(PERIPHERAL_TYPE type);
static PERIPHERAL_TYPE TranslateType(PeripheralType type);
- static JOYSTICK::CDriverPrimitive TranslatePrimitive(const ADDON::DriverPrimitive& primitive);
- static ADDON::DriverPrimitive TranslatePrimitive(const JOYSTICK::CDriverPrimitive& primitive);
+ static KODI::JOYSTICK::CDriverPrimitive TranslatePrimitive(const ADDON::DriverPrimitive& primitive);
+ static ADDON::DriverPrimitive TranslatePrimitive(const KODI::JOYSTICK::CDriverPrimitive& primitive);
- static std::vector<JOYSTICK::CDriverPrimitive> TranslatePrimitives(const std::vector<ADDON::DriverPrimitive>& primitives);
- static std::vector<ADDON::DriverPrimitive> TranslatePrimitives(const std::vector<JOYSTICK::CDriverPrimitive>& primitives);
+ static std::vector<KODI::JOYSTICK::CDriverPrimitive> TranslatePrimitives(const std::vector<ADDON::DriverPrimitive>& primitives);
+ static std::vector<ADDON::DriverPrimitive> TranslatePrimitives(const std::vector<KODI::JOYSTICK::CDriverPrimitive>& primitives);
- static JOYSTICK::HAT_DIRECTION TranslateHatDirection(JOYSTICK_DRIVER_HAT_DIRECTION dir);
- static JOYSTICK_DRIVER_HAT_DIRECTION TranslateHatDirection(JOYSTICK::HAT_DIRECTION dir);
+ static KODI::JOYSTICK::HAT_DIRECTION TranslateHatDirection(JOYSTICK_DRIVER_HAT_DIRECTION dir);
+ static JOYSTICK_DRIVER_HAT_DIRECTION TranslateHatDirection(KODI::JOYSTICK::HAT_DIRECTION dir);
- static JOYSTICK::HAT_STATE TranslateHatState(JOYSTICK_STATE_HAT state);
+ static KODI::JOYSTICK::HAT_STATE TranslateHatState(JOYSTICK_STATE_HAT state);
- static JOYSTICK::SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_DIRECTION dir);
- static JOYSTICK_DRIVER_SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK::SEMIAXIS_DIRECTION dir);
+ static KODI::JOYSTICK::SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_DIRECTION dir);
+ static JOYSTICK_DRIVER_SEMIAXIS_DIRECTION TranslateSemiAxisDirection(KODI::JOYSTICK::SEMIAXIS_DIRECTION dir);
- static JOYSTICK::FEATURE_TYPE TranslateFeatureType(JOYSTICK_FEATURE_TYPE type);
- static JOYSTICK_FEATURE_TYPE TranslateFeatureType(JOYSTICK::FEATURE_TYPE type);
+ static KODI::JOYSTICK::FEATURE_TYPE TranslateFeatureType(JOYSTICK_FEATURE_TYPE type);
+ static JOYSTICK_FEATURE_TYPE TranslateFeatureType(KODI::JOYSTICK::FEATURE_TYPE type);
static ADDON::DriverPrimitive Opposite(const ADDON::DriverPrimitive& semiaxis);
};
diff --git a/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp b/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp
index efb81a8fb5..56e8436b3d 100644
--- a/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp
+++ b/xbmc/peripherals/bus/android/PeripheralBusAndroid.cpp
@@ -31,6 +31,7 @@
#include "utils/log.h"
#include "utils/StringUtils.h"
+using namespace KODI;
using namespace PERIPHERALS;
static const std::string DeviceLocationPrefix = "android/inputdevice/";
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
index fcd3ff6062..9cc928fe32 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
@@ -31,6 +31,7 @@
#include <algorithm>
#include <memory>
+using namespace KODI;
using namespace PERIPHERALS;
CPeripheralBusAddon::CPeripheralBusAddon(CPeripherals *manager) :
@@ -494,7 +495,7 @@ void CPeripheralBusAddon::UpdateAddons(void)
bool CPeripheralBusAddon::PromptEnableAddons(const ADDON::VECADDONS& disabledAddons)
{
using namespace ADDON;
- using namespace KODI::MESSAGING::HELPERS;
+ using namespace MESSAGING::HELPERS;
// True if the user confirms enabling the disabled peripheral add-on
bool bAccepted = false;
diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp
index b0cf3de067..12968e3ec0 100644
--- a/xbmc/peripherals/devices/Peripheral.cpp
+++ b/xbmc/peripherals/devices/Peripheral.cpp
@@ -38,6 +38,7 @@
#include "Util.h"
#include "filesystem/File.h"
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h
index f77dfa1910..cc2192c408 100644
--- a/xbmc/peripherals/devices/Peripheral.h
+++ b/xbmc/peripherals/devices/Peripheral.h
@@ -28,6 +28,8 @@
class TiXmlDocument;
class CSetting;
+namespace KODI
+{
namespace JOYSTICK
{
class IActionMap;
@@ -36,6 +38,7 @@ namespace JOYSTICK
class IDriverReceiver;
class IInputHandler;
}
+}
namespace PERIPHERALS
{
@@ -192,18 +195,18 @@ namespace PERIPHERALS
virtual bool ErrorOccured(void) const { return m_bError; }
- virtual void RegisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler, bool bPromiscuous) { }
- virtual void UnregisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler) { }
+ virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) { }
+ virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) { }
- virtual void RegisterJoystickInputHandler(JOYSTICK::IInputHandler* handler);
- virtual void UnregisterJoystickInputHandler(JOYSTICK::IInputHandler* handler);
+ virtual void RegisterJoystickInputHandler(KODI::JOYSTICK::IInputHandler* handler);
+ virtual void UnregisterJoystickInputHandler(KODI::JOYSTICK::IInputHandler* handler);
- virtual void RegisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
- virtual void UnregisterJoystickButtonMapper(JOYSTICK::IButtonMapper* mapper);
+ virtual void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
+ virtual void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
- virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() { return nullptr; }
+ virtual KODI::JOYSTICK::IDriverReceiver* GetDriverReceiver() { return nullptr; }
- virtual JOYSTICK::IActionMap* GetActionMap() { return nullptr; }
+ virtual KODI::JOYSTICK::IActionMap* GetActionMap() { return nullptr; }
protected:
virtual void ClearSettings(void);
@@ -228,7 +231,7 @@ namespace PERIPHERALS
std::map<std::string, PeripheralDeviceSetting> m_settings;
std::set<std::string> m_changedSettings;
CPeripheralBus* m_bus;
- std::map<JOYSTICK::IInputHandler*, std::unique_ptr<JOYSTICK::IDriverHandler>> m_inputHandlers;
- std::map<JOYSTICK::IButtonMapper*, JOYSTICK::IDriverHandler*> m_buttonMappers;
+ std::map<KODI::JOYSTICK::IInputHandler*, std::unique_ptr<KODI::JOYSTICK::IDriverHandler>> m_inputHandlers;
+ std::map<KODI::JOYSTICK::IButtonMapper*, KODI::JOYSTICK::IDriverHandler*> m_buttonMappers;
};
}
diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
index 54dc37e751..5b5b38df65 100644
--- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
+++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
@@ -38,7 +38,8 @@
#include <libcec/cec.h>
-using namespace KODI::MESSAGING;
+using namespace KODI;
+using namespace MESSAGING;
using namespace PERIPHERALS;
using namespace ANNOUNCEMENT;
using namespace CEC;
diff --git a/xbmc/peripherals/devices/PeripheralJoystick.cpp b/xbmc/peripherals/devices/PeripheralJoystick.cpp
index 2f47c09cab..493a261191 100644
--- a/xbmc/peripherals/devices/PeripheralJoystick.cpp
+++ b/xbmc/peripherals/devices/PeripheralJoystick.cpp
@@ -29,6 +29,7 @@
#include <algorithm>
+using namespace KODI;
using namespace JOYSTICK;
using namespace PERIPHERALS;
diff --git a/xbmc/peripherals/devices/PeripheralJoystick.h b/xbmc/peripherals/devices/PeripheralJoystick.h
index 7695778f3a..03288c9946 100644
--- a/xbmc/peripherals/devices/PeripheralJoystick.h
+++ b/xbmc/peripherals/devices/PeripheralJoystick.h
@@ -32,17 +32,20 @@
#define JOYSTICK_PORT_UNKNOWN (-1)
+namespace KODI
+{
namespace JOYSTICK
{
class CDeadzoneFilter;
class IButtonMap;
class IDriverHandler;
}
+}
namespace PERIPHERALS
{
class CPeripheralJoystick : public CPeripheral, //! @todo extend CPeripheralHID
- public JOYSTICK::IDriverReceiver
+ public KODI::JOYSTICK::IDriverReceiver
{
public:
CPeripheralJoystick(const PeripheralScanResult& scanResult, CPeripheralBus* bus);
@@ -53,13 +56,13 @@ namespace PERIPHERALS
virtual bool InitialiseFeature(const PeripheralFeature feature) override;
virtual void OnUserNotification() override;
virtual bool TestFeature(PeripheralFeature feature) override;
- virtual void RegisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override;
- virtual void UnregisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler) override;
- virtual JOYSTICK::IDriverReceiver* GetDriverReceiver() override { return this; }
- virtual JOYSTICK::IActionMap* GetActionMap() override { return &m_defaultInputHandler; }
+ virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override;
+ virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) override;
+ virtual KODI::JOYSTICK::IDriverReceiver* GetDriverReceiver() override { return this; }
+ virtual KODI::JOYSTICK::IActionMap* GetActionMap() override { return &m_defaultInputHandler; }
bool OnButtonMotion(unsigned int buttonIndex, bool bPressed);
- bool OnHatMotion(unsigned int hatIndex, JOYSTICK::HAT_STATE state);
+ bool OnHatMotion(unsigned int hatIndex, KODI::JOYSTICK::HAT_STATE state);
bool OnAxisMotion(unsigned int axisIndex, float position);
void ProcessAxisMotions(void);
@@ -107,7 +110,7 @@ namespace PERIPHERALS
struct DriverHandler
{
- JOYSTICK::IDriverHandler* handler;
+ KODI::JOYSTICK::IDriverHandler* handler;
bool bPromiscuous;
};
@@ -118,10 +121,10 @@ namespace PERIPHERALS
unsigned int m_axisCount;
unsigned int m_motorCount;
bool m_supportsPowerOff;
- JOYSTICK::CDefaultJoystick m_defaultInputHandler;
- JOYSTICK::CJoystickMonitor m_joystickMonitor;
- std::unique_ptr<JOYSTICK::IButtonMap> m_buttonMap;
- std::unique_ptr<JOYSTICK::CDeadzoneFilter> m_deadzoneFilter;
+ KODI::JOYSTICK::CDefaultJoystick m_defaultInputHandler;
+ KODI::JOYSTICK::CJoystickMonitor m_joystickMonitor;
+ std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap;
+ std::unique_ptr<KODI::JOYSTICK::CDeadzoneFilter> m_deadzoneFilter;
std::vector<DriverHandler> m_driverHandlers;
CCriticalSection m_handlerMutex;
};
diff --git a/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp b/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp
index dceadeb478..266949b32b 100644
--- a/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp
+++ b/xbmc/peripherals/devices/PeripheralJoystickEmulation.cpp
@@ -25,6 +25,7 @@
#include <sstream>
+using namespace KODI;
using namespace PERIPHERALS;
CPeripheralJoystickEmulation::CPeripheralJoystickEmulation(const PeripheralScanResult& scanResult, CPeripheralBus* bus) :
diff --git a/xbmc/peripherals/devices/PeripheralJoystickEmulation.h b/xbmc/peripherals/devices/PeripheralJoystickEmulation.h
index 1d22a63e8e..901aedde90 100644
--- a/xbmc/peripherals/devices/PeripheralJoystickEmulation.h
+++ b/xbmc/peripherals/devices/PeripheralJoystickEmulation.h
@@ -26,7 +26,7 @@
namespace PERIPHERALS
{
class CPeripheralJoystickEmulation : public CPeripheral,
- public KEYBOARD::IKeyboardHandler
+ public KODI::KEYBOARD::IKeyboardHandler
{
public:
CPeripheralJoystickEmulation(const PeripheralScanResult& scanResult, CPeripheralBus* bus);
@@ -35,8 +35,8 @@ namespace PERIPHERALS
// implementation of CPeripheral
virtual bool InitialiseFeature(const PeripheralFeature feature) override;
- virtual void RegisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override;
- virtual void UnregisterJoystickDriverHandler(JOYSTICK::IDriverHandler* handler) override;
+ virtual void RegisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler, bool bPromiscuous) override;
+ virtual void UnregisterJoystickDriverHandler(KODI::JOYSTICK::IDriverHandler* handler) override;
// implementation of IKeyboardHandler
virtual bool OnKeyPress(const CKey& key) override;
@@ -50,11 +50,11 @@ namespace PERIPHERALS
private:
struct KeyboardHandle
{
- KEYBOARD::IKeyboardHandler* handler;
+ KODI::KEYBOARD::IKeyboardHandler* handler;
bool bPromiscuous;
};
- typedef std::map<JOYSTICK::IDriverHandler*, KeyboardHandle> KeyboardHandlers;
+ typedef std::map<KODI::JOYSTICK::IDriverHandler*, KeyboardHandle> KeyboardHandlers;
KeyboardHandlers m_keyboardHandlers;
CCriticalSection m_mutex;
diff --git a/xbmc/pictures/GUIViewStatePictures.cpp b/xbmc/pictures/GUIViewStatePictures.cpp
index 226cb8a173..138e3a42c6 100644
--- a/xbmc/pictures/GUIViewStatePictures.cpp
+++ b/xbmc/pictures/GUIViewStatePictures.cpp
@@ -73,7 +73,7 @@ std::string CGUIViewStateWindowPictures::GetLockType()
std::string CGUIViewStateWindowPictures::GetExtensions()
{
- std::string extensions = g_advancedSettings.m_pictureExtensions;
+ std::string extensions = g_advancedSettings.GetPictureExtensions();
if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PICTURES_SHOWVIDEOS))
extensions += "|" + g_advancedSettings.m_videoExtensions;
diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp
index 7f271c31d2..6b2c4ece87 100644
--- a/xbmc/pictures/PictureThumbLoader.cpp
+++ b/xbmc/pictures/PictureThumbLoader.cpp
@@ -183,7 +183,7 @@ void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem)
CFileItemList items;
- CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS);
+ CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS);
// create the folder thumb by choosing 4 random thumbs within the folder and putting
// them into one thumb.
@@ -202,7 +202,7 @@ void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem)
{
if (pItem->IsCBZ() || pItem->IsCBR())
{
- CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS);
+ CDirectory::GetDirectory(pathToUrl, items, g_advancedSettings.GetPictureExtensions(), DIR_FLAG_NO_FILE_DIRS);
for (int i=0;i<items.Size();++i)
{
CFileItemPtr item = items[i];
diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp
index 6d2b1ea2dc..46bdfa408a 100644
--- a/xbmc/platform/android/activity/XBMCApp.cpp
+++ b/xbmc/platform/android/activity/XBMCApp.cpp
@@ -87,7 +87,7 @@
#include "AndroidKey.h"
#include "CompileInfo.h"
-#include "video/videosync/VideoSyncAndroid.h"
+#include "windowing/egl/VideoSyncAndroid.h"
#define GIGABYTES 1073741824
diff --git a/xbmc/platform/android/jni/InetAddress.h b/xbmc/platform/android/jni/InetAddress.h
index a8fb0f8e78..42119b41f9 100644
--- a/xbmc/platform/android/jni/InetAddress.h
+++ b/xbmc/platform/android/jni/InetAddress.h
@@ -47,4 +47,4 @@ protected:
static const char *m_classname;
};
-typedef std::vector<CJNIInetAddress> CJNIInetAddresss;
+typedef std::vector<CJNIInetAddress> CJNIInetAddresses;
diff --git a/xbmc/platform/darwin/ios/XBMCController.mm b/xbmc/platform/darwin/ios/XBMCController.mm
index 380537e944..2d6b85fe56 100644
--- a/xbmc/platform/darwin/ios/XBMCController.mm
+++ b/xbmc/platform/darwin/ios/XBMCController.mm
@@ -37,7 +37,6 @@
#include "guilib/GUIControl.h"
#include "input/Key.h"
#include "windowing/WindowingFactory.h"
-#include "video/VideoReferenceClock.h"
#include "utils/log.h"
#include "utils/TimeUtils.h"
#include "Util.h"
diff --git a/xbmc/platform/xbmc.cpp b/xbmc/platform/xbmc.cpp
index 34e5ea67d4..5791e306ff 100644
--- a/xbmc/platform/xbmc.cpp
+++ b/xbmc/platform/xbmc.cpp
@@ -58,7 +58,7 @@ extern "C" int XBMC_Run(bool renderGUI, CFileItemList &playlist)
#ifdef TARGET_RASPBERRY_PI
if(!g_RBP.Initialize())
return false;
- g_RBP.LogFirmwareVerison();
+ g_RBP.LogFirmwareVersion();
#endif
if (renderGUI && !g_application.CreateGUI())
diff --git a/xbmc/powermanagement/PowerManager.cpp b/xbmc/powermanagement/PowerManager.cpp
index 6ec7cab205..86a7645866 100644
--- a/xbmc/powermanagement/PowerManager.cpp
+++ b/xbmc/powermanagement/PowerManager.cpp
@@ -278,7 +278,7 @@ void CPowerManager::OnWake()
CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
if (dialog)
- dialog->Close();
+ dialog->Close(true); // force close. no closing animation, sound etc at this early stage
#if defined(HAS_SDL) || defined(TARGET_WINDOWS)
if (g_Windowing.IsFullScreen())
diff --git a/xbmc/pvr/CMakeLists.txt b/xbmc/pvr/CMakeLists.txt
index 8761e726f0..7b9181adc3 100644
--- a/xbmc/pvr/CMakeLists.txt
+++ b/xbmc/pvr/CMakeLists.txt
@@ -6,7 +6,8 @@ set(SOURCES PVRActionListener.cpp
PVRContextMenus.cpp
PVRGUIActions.cpp
PVRItem.cpp
- PVRChannelNumberInputHandler.cpp)
+ PVRChannelNumberInputHandler.cpp
+ PVRJobs.cpp)
set(HEADERS PVRActionListener.h
PVRDatabase.h
@@ -18,6 +19,7 @@ set(HEADERS PVRActionListener.h
PVRGUIActions.h
PVRItem.h
PVRTypes.h
- PVRChannelNumberInputHandler.h)
+ PVRChannelNumberInputHandler.h
+ PVRJobs.h)
core_add_library(pvr)
diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp
index 9a6a04131c..002d1175a2 100644
--- a/xbmc/pvr/PVRActionListener.cpp
+++ b/xbmc/pvr/PVRActionListener.cpp
@@ -19,11 +19,15 @@
*/
#include "Application.h"
+#include "ServiceBroker.h"
+#include "dialogs/GUIDialogNumeric.h"
#include "guilib/GUIWindowManager.h"
#include "input/Key.h"
+#include "settings/Settings.h"
#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
+#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "PVRActionListener.h"
@@ -31,16 +35,32 @@
namespace PVR
{
-CPVRActionListener::CPVRActionListener()
-{
-}
-
CPVRActionListener &CPVRActionListener::GetInstance()
{
static CPVRActionListener instance;
return instance;
}
+void CPVRActionListener::Init()
+{
+ std::set<std::string> settingSet;
+ settingSet.insert(CSettings::SETTING_PVRPARENTAL_ENABLED);
+ settingSet.insert(CSettings::SETTING_PVRMANAGER_RESETDB);
+ settingSet.insert(CSettings::SETTING_EPG_RESETEPG);
+ settingSet.insert(CSettings::SETTING_PVRMANAGER_CHANNELMANAGER);
+ settingSet.insert(CSettings::SETTING_PVRMANAGER_GROUPMANAGER);
+ settingSet.insert(CSettings::SETTING_PVRMANAGER_CHANNELSCAN);
+ settingSet.insert(CSettings::SETTING_PVRMENU_SEARCHICONS);
+ settingSet.insert(CSettings::SETTING_PVRCLIENT_MENUHOOK);
+ settingSet.insert(CSettings::SETTING_EPG_DAYSTODISPLAY);
+ CServiceBroker::GetSettings().RegisterCallback(this, settingSet);
+}
+
+void CPVRActionListener::Deinit()
+{
+ CServiceBroker::GetSettings().UnregisterCallback(this);
+}
+
bool CPVRActionListener::OnAction(const CAction &action)
{
bool bIsJumpSMS = false;
@@ -58,19 +78,20 @@ bool CPVRActionListener::OnAction(const CAction &action)
{
case ACTION_PVR_PLAY:
if (!isPlayingPvr)
- g_PVRManager.StartPlayback(PlaybackTypeAny);
+ CPVRGUIActions::GetInstance().SwitchToChannel(PlaybackTypeAny);
break;
case ACTION_PVR_PLAY_TV:
if (!isPlayingPvr || g_application.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
- g_PVRManager.StartPlayback(PlaybackTypeTv);
+ CPVRGUIActions::GetInstance().SwitchToChannel(PlaybackTypeTV);
break;
case ACTION_PVR_PLAY_RADIO:
if (!isPlayingPvr || !g_application.CurrentFileItem().GetPVRChannelInfoTag()->IsRadio())
- g_PVRManager.StartPlayback(PlaybackTypeRadio);
+ CPVRGUIActions::GetInstance().SwitchToChannel(PlaybackTypeRadio);
break;
}
return true;
}
+
case ACTION_JUMP_SMS2:
case ACTION_JUMP_SMS3:
case ACTION_JUMP_SMS4:
@@ -111,4 +132,75 @@ bool CPVRActionListener::OnAction(const CAction &action)
return false;
}
+void CPVRActionListener::OnSettingChanged(const CSetting *setting)
+{
+ if (setting == nullptr)
+ return;
+
+ const std::string &settingId = setting->GetId();
+ if (settingId == CSettings::SETTING_PVRPARENTAL_ENABLED)
+ {
+ if (dynamic_cast<const CSettingBool*>(setting)->GetValue() && CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRPARENTAL_PIN).empty())
+ {
+ std::string newPassword = "";
+ // password set... save it
+ if (CGUIDialogNumeric::ShowAndVerifyNewPassword(newPassword))
+ CServiceBroker::GetSettings().SetString(CSettings::SETTING_PVRPARENTAL_PIN, newPassword);
+ // password not set... disable parental
+ else
+ dynamic_cast<CSettingBool*>(const_cast<CSetting*>(setting))->SetValue(false);
+ }
+ }
+}
+
+void CPVRActionListener::OnSettingAction(const CSetting *setting)
+{
+ if (setting == nullptr)
+ return;
+
+ const std::string &settingId = setting->GetId();
+ if (settingId == CSettings::SETTING_PVRMANAGER_RESETDB)
+ {
+ CPVRGUIActions::GetInstance().ResetPVRDatabase(false);
+ }
+ else if (settingId == CSettings::SETTING_EPG_RESETEPG)
+ {
+ CPVRGUIActions::GetInstance().ResetPVRDatabase(true);
+ }
+ else if (settingId == CSettings::SETTING_PVRMANAGER_CHANNELMANAGER)
+ {
+ if (g_PVRManager.IsStarted())
+ {
+ CGUIDialog *dialog = dynamic_cast<CGUIDialog *>(g_windowManager.GetWindow(WINDOW_DIALOG_PVR_CHANNEL_MANAGER));
+ if (dialog)
+ dialog->Open();
+ }
+ }
+ else if (settingId == CSettings::SETTING_PVRMANAGER_GROUPMANAGER)
+ {
+ if (g_PVRManager.IsStarted())
+ {
+ CGUIDialog *dialog = dynamic_cast<CGUIDialog *>(g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER));
+ if (dialog)
+ dialog->Open();
+ }
+ }
+ else if (settingId == CSettings::SETTING_PVRMANAGER_CHANNELSCAN)
+ {
+ CPVRGUIActions::GetInstance().StartChannelScan();
+ }
+ else if (settingId == CSettings::SETTING_PVRMENU_SEARCHICONS)
+ {
+ g_PVRManager.TriggerSearchMissingChannelIcons();
+ }
+ else if (settingId == CSettings::SETTING_PVRCLIENT_MENUHOOK)
+ {
+ CPVRGUIActions::GetInstance().ProcessMenuHooks(CFileItemPtr());
+ }
+ else if (settingId == CSettings::SETTING_EPG_DAYSTODISPLAY)
+ {
+ g_PVRClients->SetEPGTimeFrame(static_cast<const CSettingInt*>(setting)->GetValue());
+ }
+}
+
} // namespace PVR
diff --git a/xbmc/pvr/PVRActionListener.h b/xbmc/pvr/PVRActionListener.h
index 3bca56d6f7..2bb7bea95d 100644
--- a/xbmc/pvr/PVRActionListener.h
+++ b/xbmc/pvr/PVRActionListener.h
@@ -21,23 +21,32 @@
*/
#include "interfaces/IActionListener.h"
+#include "settings/lib/ISettingCallback.h"
namespace PVR
{
-class CPVRActionListener : public IActionListener
+class CPVRActionListener : public IActionListener, public ISettingCallback
{
public:
+ void Init();
+ void Deinit();
+
static CPVRActionListener &GetInstance();
- bool OnAction(const CAction &action);
+ // IActionListener implementation
+ bool OnAction(const CAction &action) override;
+
+ // ISettingCallback implementation
+ void OnSettingChanged(const CSetting *setting) override;
+ void OnSettingAction(const CSetting *setting) override;
private:
- CPVRActionListener();
- CPVRActionListener(const CPVRActionListener&);
- CPVRActionListener& operator=(const CPVRActionListener&);
- ~CPVRActionListener() {};
+ CPVRActionListener() = default;
+ ~CPVRActionListener() = default;
+ CPVRActionListener(const CPVRActionListener&) = delete;
+ CPVRActionListener& operator=(const CPVRActionListener&) = delete;
};
} // namespace PVR
diff --git a/xbmc/pvr/PVRChannelNumberInputHandler.cpp b/xbmc/pvr/PVRChannelNumberInputHandler.cpp
index 09d0207fbe..87b52a752a 100644
--- a/xbmc/pvr/PVRChannelNumberInputHandler.cpp
+++ b/xbmc/pvr/PVRChannelNumberInputHandler.cpp
@@ -62,7 +62,7 @@ void CPVRChannelNumberInputHandler::AppendChannelNumberDigit(int iDigit)
// recalc channel string
m_strChannel.erase();
- if (m_digits.size() != m_iMaxDigits || GetChannelNumber() > 0)
+ if (m_digits.size() != (size_t)m_iMaxDigits || GetChannelNumber() > 0)
{
for (int digit : m_digits)
m_strChannel.append(StringUtils::Format("%d", digit));
diff --git a/xbmc/pvr/PVRContextMenus.cpp b/xbmc/pvr/PVRContextMenus.cpp
index 0a6053aab2..fc77c084de 100644
--- a/xbmc/pvr/PVRContextMenus.cpp
+++ b/xbmc/pvr/PVRContextMenus.cpp
@@ -499,21 +499,9 @@ namespace PVR
bool PVRClientMenuHook::Execute(const CFileItemPtr &item) const
{
- if (item->IsEPG() && item->GetEPGInfoTag()->HasPVRChannel())
- g_PVRClients->ProcessMenuHooks(item->GetEPGInfoTag()->ChannelTag()->ClientID(), PVR_MENUHOOK_EPG, item.get());
- else if (item->IsPVRChannel())
- g_PVRClients->ProcessMenuHooks(item->GetPVRChannelInfoTag()->ClientID(), PVR_MENUHOOK_CHANNEL, item.get());
- else if (item->IsDeletedPVRRecording())
- g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_DELETED_RECORDING, item.get());
- else if (item->IsUsablePVRRecording())
- g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING, item.get());
- else if (item->IsPVRTimer())
- g_PVRClients->ProcessMenuHooks(item->GetPVRTimerInfoTag()->m_iClientId, PVR_MENUHOOK_TIMER, item.get());
- else
- return false;
-
- return true;
+ return CPVRGUIActions::GetInstance().ProcessMenuHooks(item);;
}
+
} // namespace CONEXTMENUITEM
CPVRContextMenuManager& CPVRContextMenuManager::GetInstance()
diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp
index 60504489b9..234567d38c 100644
--- a/xbmc/pvr/PVRDatabase.cpp
+++ b/xbmc/pvr/PVRDatabase.cpp
@@ -62,12 +62,10 @@ void CPVRDatabase::CreateTables()
"bIsVirtual bool, "
"bEPGEnabled bool, "
"sEPGScraper varchar(32), "
- "iLastWatched integer,"
-
- //! @todo use mapping table
- "iClientId integer, "
-
- "idEpg integer"
+ "iLastWatched integer, "
+ "iClientId integer, " //! @todo use mapping table
+ "idEpg integer, "
+ "bWasPlayingOnQuit bool"
")"
);
@@ -138,12 +136,13 @@ void CPVRDatabase::UpdateTables(int iVersion)
m_pDS->exec("ALTER TABLE channelgroups ADD bIsHidden bool");
if (iVersion < 28)
- {
m_pDS->exec("DROP TABLE clients");
- }
if (iVersion < 29)
m_pDS->exec("ALTER TABLE channelgroups ADD iPosition integer");
+
+ if (iVersion < 30)
+ m_pDS->exec("ALTER TABLE channels ADD bWasPlayingOnQuit bool");
}
/********** Channel methods **********/
@@ -652,6 +651,46 @@ bool CPVRDatabase::Persist(CPVRChannel &channel)
return bReturn;
}
+bool CPVRDatabase::SetWasPlayingOnLastQuit(const CPVRChannel &channel, bool bSet, bool& bWasPlaying)
+{
+ bool bRet = false;
+
+ // Obtain previous value.
+ try
+ {
+ const std::string strSQL(PrepareSQL("SELECT bWasPlayingOnQuit FROM channels WHERE iUniqueId = %u AND iClientId = %u",
+ channel.UniqueID(), channel.ClientID()));
+ m_pDS->query(strSQL);
+ if (m_pDS->num_rows() > 0)
+ {
+ bWasPlaying = m_pDS->fv(0).get_asBool();
+ bRet = true;
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "PVR - %s - couldn't obtain value from channels (no rows)", __FUNCTION__);
+ }
+ m_pDS->close();
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "PVR - %s - couldn't obtain value from channels (exception)", __FUNCTION__);
+ }
+
+ // Set new value.
+ if (bRet && bSet != bWasPlaying)
+ bRet = SetWasPlayingOnLastQuit(channel, bSet);
+
+ return bRet;
+}
+
+bool CPVRDatabase::SetWasPlayingOnLastQuit(const CPVRChannel &channel, bool bSet)
+{
+ const std::string strQuery(PrepareSQL("UPDATE channels SET bWasPlayingOnQuit = %i WHERE iUniqueId = %u AND iClientId = %u",
+ bSet, channel.UniqueID(), channel.ClientID()));
+ return ExecuteQuery(strQuery);
+}
+
bool CPVRDatabase::UpdateLastWatched(const CPVRChannel &channel)
{
std::string strQuery = PrepareSQL("UPDATE channels SET iLastWatched = %d WHERE idChannel = %d",
diff --git a/xbmc/pvr/PVRDatabase.h b/xbmc/pvr/PVRDatabase.h
index 11be7b469e..5f44d5a756 100644
--- a/xbmc/pvr/PVRDatabase.h
+++ b/xbmc/pvr/PVRDatabase.h
@@ -56,7 +56,7 @@ namespace PVR
* @brief Get the minimal database version that is required to operate correctly.
* @return The minimal database version.
*/
- virtual int GetSchemaVersion() const { return 29; };
+ virtual int GetSchemaVersion() const { return 30; };
/*!
* @brief Get the default sqlite database filename.
@@ -145,6 +145,23 @@ namespace PVR
//@{
/*!
+ * @brief Sets the 'was playing on last app quit' flag for a channel.
+ * @param channel the channel
+ * @param bSet True to set the flag, false to reset the flag
+ * @return True if the operation was successful, false otherwise
+ */
+ bool SetWasPlayingOnLastQuit(const CPVRChannel &channel, bool bSet);
+
+ /*!
+ * @brief Sets the 'was playing on last app quit' flag for a channel.
+ * @param channel the channel
+ * @param bSet True to set the flag, false to reset the flag
+ * @param bWasPlaying on return contains the previous value of the flag
+ * @return True if the operation was successful, false otherwise
+ */
+ bool SetWasPlayingOnLastQuit(const CPVRChannel &channel, bool bSet, bool& bWasPlaying);
+
+ /*!
* @brief Updates the last watched timestamp for the channel
* @param channel the channel
* @return whether the update was successful
diff --git a/xbmc/pvr/PVRGUIActions.cpp b/xbmc/pvr/PVRGUIActions.cpp
index 3265b143b0..8a14690b8e 100644
--- a/xbmc/pvr/PVRGUIActions.cpp
+++ b/xbmc/pvr/PVRGUIActions.cpp
@@ -20,8 +20,12 @@
#include "Application.h"
#include "dialogs/GUIDialogKaiToast.h"
+#include "dialogs/GUIDialogNumeric.h"
#include "dialogs/GUIDialogOK.h"
+#include "dialogs/GUIDialogProgress.h"
+#include "dialogs/GUIDialogSelect.h"
#include "dialogs/GUIDialogYesNo.h"
+#include "epg/EpgContainer.h"
#include "epg/EpgInfoTag.h"
#include "FileItem.h"
#include "filesystem/Directory.h"
@@ -31,14 +35,17 @@
#include "guilib/LocalizeStrings.h"
#include "input/Key.h"
#include "messaging/ApplicationMessenger.h"
+#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/dialogs/GUIDialogPVRGuideInfo.h"
#include "pvr/dialogs/GUIDialogPVRRecordingInfo.h"
#include "pvr/dialogs/GUIDialogPVRTimerSettings.h"
+#include "pvr/PVRDatabase.h"
#include "pvr/PVRItem.h"
#include "pvr/PVRManager.h"
#include "pvr/timers/PVRTimers.h"
#include "pvr/recordings/PVRRecordings.h"
+#include "pvr/recordings/PVRRecordingsPath.h"
#include "pvr/windows/GUIWindowPVRSearch.h"
#include "ServiceBroker.h"
#include "settings/MediaSettings.h"
@@ -61,10 +68,15 @@ namespace PVR
return instance;
}
+ CPVRGUIActions::CPVRGUIActions()
+ : m_bChannelScanRunning(false)
+ {
+ }
+
bool CPVRGUIActions::ShowEPGInfo(const CFileItemPtr &item) const
{
const CPVRChannelPtr channel(CPVRItem(item).GetChannel());
- if (channel && !g_PVRManager.CheckParentalLock(channel))
+ if (channel && !CheckParentalLock(channel))
return false;
const CEpgInfoTagPtr epgTag(CPVRItem(item).GetEpgInfoTag());
@@ -147,7 +159,7 @@ namespace PVR
if (ShowTimerSettings(newTimer))
{
/* Add timer to backend */
- return g_PVRTimers->AddTimer(newTimer);
+ return AddTimer(newTimer);
}
return false;
}
@@ -171,7 +183,7 @@ namespace PVR
return false;
}
- if (!g_PVRManager.CheckParentalLock(channel))
+ if (!CheckParentalLock(channel))
return false;
const CEpgInfoTagPtr epgTag(CPVRItem(item).GetEpgInfoTag());
@@ -205,7 +217,267 @@ namespace PVR
return false;
}
- return g_PVRTimers->AddTimer(newTimer);
+ return AddTimer(newTimer);
+ }
+
+ bool CPVRGUIActions::AddTimer(const CPVRTimerInfoTagPtr &item) const
+ {
+ if (!item->m_channel && item->GetTimerType() && !item->GetTimerType()->IsEpgBasedTimerRule())
+ {
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - no channel given", __FUNCTION__);
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19109}); // "Information", "Couldn't save timer. Check the log for more information about this message."
+ return false;
+ }
+
+ if (!g_PVRClients->SupportsTimers(item->m_iClientId))
+ {
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19215}); // "Information", "The PVR backend does not support timers."
+ return false;
+ }
+
+ if (!CheckParentalLock(item->m_channel))
+ return false;
+
+ return g_PVRTimers->AddTimer(item);
+ }
+
+ namespace
+ {
+ enum PVRRECORD_INSTANTRECORDACTION
+ {
+ NONE = -1,
+ RECORD_CURRENT_SHOW = 0,
+ RECORD_INSTANTRECORDTIME = 1,
+ ASK = 2,
+ RECORD_30_MINUTES = 3,
+ RECORD_60_MINUTES = 4,
+ RECORD_120_MINUTES = 5,
+ RECORD_NEXT_SHOW = 6
+ };
+
+ class InstantRecordingActionSelector
+ {
+ public:
+ InstantRecordingActionSelector();
+ virtual ~InstantRecordingActionSelector() {}
+
+ void AddAction(PVRRECORD_INSTANTRECORDACTION eAction, const std::string &title);
+ void PreSelectAction(PVRRECORD_INSTANTRECORDACTION eAction);
+ PVRRECORD_INSTANTRECORDACTION Select();
+
+ private:
+ CGUIDialogSelect *m_pDlgSelect; // not owner!
+ std::map<PVRRECORD_INSTANTRECORDACTION, int> m_actions;
+ };
+
+ InstantRecordingActionSelector::InstantRecordingActionSelector()
+ : m_pDlgSelect(dynamic_cast<CGUIDialogSelect *>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT)))
+ {
+ if (m_pDlgSelect)
+ {
+ m_pDlgSelect->SetMultiSelection(false);
+ m_pDlgSelect->SetHeading(CVariant{19086}); // Instant recording action
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "InstantRecordingActionSelector - %s - unable to obtain WINDOW_DIALOG_SELECT instance", __FUNCTION__);
+ }
+ }
+
+ void InstantRecordingActionSelector::AddAction(PVRRECORD_INSTANTRECORDACTION eAction, const std::string &title)
+ {
+ if (m_actions.find(eAction) == m_actions.end())
+ {
+ switch (eAction)
+ {
+ case RECORD_INSTANTRECORDTIME:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(),
+ CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME))); // Record next <default duration> minutes
+ break;
+ case RECORD_30_MINUTES:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 30)); // Record next 30 minutes
+ break;
+ case RECORD_60_MINUTES:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 60)); // Record next 60 minutes
+ break;
+ case RECORD_120_MINUTES:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 120)); // Record next 120 minutes
+ break;
+ case RECORD_CURRENT_SHOW:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19091).c_str(), title.c_str())); // Record current show (<title>)
+ break;
+ case RECORD_NEXT_SHOW:
+ m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19092).c_str(), title.c_str())); // Record next show (<title>)
+ break;
+ case NONE:
+ case ASK:
+ default:
+ return;
+ }
+
+ m_actions.insert(std::make_pair(eAction, m_actions.size()));
+ }
+ }
+
+ void InstantRecordingActionSelector::PreSelectAction(PVRRECORD_INSTANTRECORDACTION eAction)
+ {
+ const auto &it = m_actions.find(eAction);
+ if (it != m_actions.end())
+ m_pDlgSelect->SetSelected(it->second);
+ }
+
+ PVRRECORD_INSTANTRECORDACTION InstantRecordingActionSelector::Select()
+ {
+ PVRRECORD_INSTANTRECORDACTION eAction = NONE;
+
+ m_pDlgSelect->Open();
+
+ if (m_pDlgSelect->IsConfirmed())
+ {
+ int iSelection = m_pDlgSelect->GetSelectedItem();
+ for (const auto &action : m_actions)
+ {
+ if (action.second == iSelection)
+ {
+ eAction = action.first;
+ break;
+ }
+ }
+ }
+
+ return eAction;
+ }
+
+ } // unnamed namespace
+
+ bool CPVRGUIActions::SetRecordingOnChannel(const CPVRChannelPtr &channel, bool bOnOff)
+ {
+ bool bReturn = false;
+
+ if (!channel)
+ return bReturn;
+
+ if (!CheckParentalLock(channel))
+ return bReturn;
+
+ if (g_PVRClients->HasTimerSupport(channel->ClientID()))
+ {
+ /* timers are supported on this channel */
+ if (bOnOff && !channel->IsRecording())
+ {
+ CEpgInfoTagPtr epgTag;
+ int iDuration = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME);
+
+ int iAction = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDACTION);
+ switch (iAction)
+ {
+ case RECORD_CURRENT_SHOW:
+ epgTag = channel->GetEPGNow();
+ break;
+
+ case RECORD_INSTANTRECORDTIME:
+ epgTag.reset();
+ break;
+
+ case ASK:
+ {
+ PVRRECORD_INSTANTRECORDACTION ePreselect = RECORD_INSTANTRECORDTIME;
+ InstantRecordingActionSelector selector;
+ CEpgInfoTagPtr epgTagNext;
+
+ // fixed length recordings
+ selector.AddAction(RECORD_30_MINUTES, "");
+ selector.AddAction(RECORD_60_MINUTES, "");
+ selector.AddAction(RECORD_120_MINUTES, "");
+
+ const int iDurationDefault = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME);
+ if (iDurationDefault != 30 && iDurationDefault != 60 && iDurationDefault != 120)
+ selector.AddAction(RECORD_INSTANTRECORDTIME, "");
+
+ // epg-based recordings
+ epgTag = channel->GetEPGNow();
+ if (epgTag)
+ {
+ // "now"
+ selector.AddAction(RECORD_CURRENT_SHOW, epgTag->Title());
+ ePreselect = RECORD_CURRENT_SHOW;
+
+ // "next"
+ epgTagNext = channel->GetEPGNext();
+ if (epgTagNext)
+ {
+ selector.AddAction(RECORD_NEXT_SHOW, epgTagNext->Title());
+
+ // be smart. if current show is almost over, preselect next show.
+ if (epgTag->ProgressPercentage() > 90.0f)
+ ePreselect = RECORD_NEXT_SHOW;
+ }
+ }
+
+ selector.PreSelectAction(ePreselect);
+
+ PVRRECORD_INSTANTRECORDACTION eSelected = selector.Select();
+ switch (eSelected)
+ {
+ case NONE:
+ return false; // dialog canceled
+
+ case RECORD_30_MINUTES:
+ iDuration = 30;
+ epgTag.reset();
+ break;
+
+ case RECORD_60_MINUTES:
+ iDuration = 60;
+ epgTag.reset();
+ break;
+
+ case RECORD_120_MINUTES:
+ iDuration = 120;
+ epgTag.reset();
+ break;
+
+ case RECORD_INSTANTRECORDTIME:
+ iDuration = iDurationDefault;
+ epgTag.reset();
+ break;
+
+ case RECORD_CURRENT_SHOW:
+ break;
+
+ case RECORD_NEXT_SHOW:
+ epgTag = epgTagNext;
+ break;
+
+ default:
+ CLog::Log(LOGERROR, "PVRManager - %s - unknown instant record action selection (%d), defaulting to fixed length recording.", __FUNCTION__, eSelected);
+ epgTag.reset();
+ break;
+ }
+ break;
+ }
+
+ default:
+ CLog::Log(LOGERROR, "PVRManager - %s - unknown instant record action setting value (%d), defaulting to fixed length recording.", __FUNCTION__, iAction);
+ break;
+ }
+
+ const CPVRTimerInfoTagPtr newTimer(epgTag ? CPVRTimerInfoTag::CreateFromEpg(epgTag, false) : CPVRTimerInfoTag::CreateInstantTimerTag(channel, iDuration));
+
+ if (newTimer)
+ bReturn = newTimer->AddToClient();
+
+ if (!bReturn)
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19164}); // "Information", "Can't start recording. Check the log for more information about this message."
+ }
+ else if (!bOnOff && channel->IsRecording())
+ {
+ /* delete active timers */
+ bReturn = g_PVRTimers->DeleteTimersOnChannel(channel, true, true);
+ }
+ }
+
+ return bReturn;
}
bool CPVRGUIActions::ToggleTimer(const CFileItemPtr &item) const
@@ -266,11 +538,11 @@ namespace PVR
// end up with one timer missing wrt to the rule defined by the new timer.
if (g_PVRTimers->DeleteTimer(timer, timer->IsRecording(), false))
{
- if (g_PVRTimers->AddTimer(newTimer))
+ if (AddTimer(newTimer))
return true;
// rollback.
- return g_PVRTimers->AddTimer(timer);
+ return AddTimer(timer);
}
}
}
@@ -419,7 +691,10 @@ namespace PVR
return false;
if (!g_PVRRecordings->RenameRecording(*item, strNewName))
+ {
+ CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{19111}); // "Error", "PVR backend error. Check the log for more information about this message."
return false;
+ }
g_PVRManager.TriggerRecordingsUpdate();
return true;
@@ -434,7 +709,10 @@ namespace PVR
return false;
if (!g_PVRRecordings->Delete(*item))
+ {
+ CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{19111}); // "Error", "PVR backend error. Check the log for more information about this message."
return false;
+ }
g_PVRManager.TriggerRecordingsUpdate();
return true;
@@ -477,7 +755,10 @@ namespace PVR
/* undelete the recording */
if (!g_PVRRecordings->Undelete(*item))
+ {
+ CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{19111}); // "Error", "PVR backend error. Check the log for more information about this message."
return false;
+ }
g_PVRManager.TriggerRecordingsUpdate();
return true;
@@ -534,9 +815,8 @@ namespace PVR
return PlayRecording(item, false);
}
- void CPVRGUIActions::CheckAndSwitchToFullscreen() const
+ void CPVRGUIActions::CheckAndSwitchToFullscreen(bool bFullscreen) const
{
- const bool bFullscreen(CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRPLAYBACK_SWITCHTOFULLSCREEN));
CMediaSettings::GetInstance().SetVideoStartWindowed(!bFullscreen);
if (bFullscreen)
@@ -546,7 +826,7 @@ namespace PVR
}
}
- bool CPVRGUIActions::TryFastChannelSwitch(const CPVRChannelPtr &channel) const
+ bool CPVRGUIActions::TryFastChannelSwitch(const CPVRChannelPtr &channel, bool bFullscreen) const
{
bool bSwitchSuccessful(false);
@@ -557,16 +837,16 @@ namespace PVR
bSwitchSuccessful = g_application.m_pPlayer->SwitchChannel(channel);
if (bSwitchSuccessful)
- CheckAndSwitchToFullscreen();
+ CheckAndSwitchToFullscreen(bFullscreen);
}
return bSwitchSuccessful;
}
- void CPVRGUIActions::StartPlayback(CFileItem *item) const
+ void CPVRGUIActions::StartPlayback(CFileItem *item, bool bFullscreen) const
{
CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(item));
- CheckAndSwitchToFullscreen();
+ CheckAndSwitchToFullscreen(bFullscreen);
}
bool CPVRGUIActions::PlayRecording(const CFileItemPtr &item, bool bCheckResume) const
@@ -589,7 +869,7 @@ namespace PVR
{
CFileItem *itemToPlay = new CFileItem(recording);
itemToPlay->m_lStartOffset = item->m_lStartOffset;
- StartPlayback(itemToPlay);
+ StartPlayback(itemToPlay, true);
}
return true;
}
@@ -641,13 +921,18 @@ namespace PVR
}
if (!bCheckResume || CheckResumeRecording(item))
- StartPlayback(new CFileItem(*item));
+ StartPlayback(new CFileItem(*item), true);
return true;
}
bool CPVRGUIActions::SwitchToChannel(const CFileItemPtr &item, bool bCheckResume) const
{
+ return SwitchToChannel(item, bCheckResume, CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRPLAYBACK_SWITCHTOFULLSCREEN));
+ }
+
+ bool CPVRGUIActions::SwitchToChannel(const CFileItemPtr &item, bool bCheckResume, bool bFullscreen) const
+ {
if (item->m_bIsFolder)
return false;
@@ -663,7 +948,7 @@ namespace PVR
// switch to channel or if recording present, ask whether to switch or play recording...
bool bSwitchSuccessful(false);
- if (channel && g_PVRManager.CheckParentalLock(channel))
+ if (channel && CheckParentalLock(channel))
{
const CPVRRecordingPtr recording(channel->GetRecording());
if (recording)
@@ -688,11 +973,11 @@ namespace PVR
}
/* optimization: try a fast switch */
- bSwitchSuccessful = TryFastChannelSwitch(channel);
+ bSwitchSuccessful = TryFastChannelSwitch(channel, bFullscreen);
if (!bSwitchSuccessful)
{
- StartPlayback(new CFileItem(channel));
+ StartPlayback(new CFileItem(channel), bFullscreen);
return true;
}
}
@@ -711,6 +996,93 @@ namespace PVR
return true;
}
+ bool CPVRGUIActions::SwitchToChannel(PlaybackType type) const
+ {
+ CFileItemPtr channel;
+ bool bIsRadio(false);
+
+ // check if the desired PlaybackType is already playing,
+ // and if not, try to grab the last played channel of this type
+ switch (type)
+ {
+ case PlaybackTypeRadio:
+ if (g_PVRManager.IsPlayingRadio())
+ return true;
+
+ channel = g_PVRChannelGroups->GetGroupAllRadio()->GetLastPlayedChannel();
+ bIsRadio = true;
+ break;
+
+ case PlaybackTypeTV:
+ if (g_PVRManager.IsPlayingTV())
+ return true;
+
+ channel = g_PVRChannelGroups->GetGroupAllTV()->GetLastPlayedChannel();
+ break;
+
+ default:
+ if (g_PVRManager.IsPlaying())
+ return true;
+
+ channel = g_PVRChannelGroups->GetLastPlayedChannel();
+ break;
+ }
+
+ // if we have a last played channel, start playback
+ if (channel && channel->HasPVRChannelInfoTag())
+ {
+ return SwitchToChannel(channel, true);
+ }
+ else
+ {
+ // if we don't, find the active channel group of the demanded type and play it's first channel
+ const CPVRChannelGroupPtr channelGroup(g_PVRManager.GetPlayingGroup(bIsRadio));
+ if (channelGroup)
+ {
+ // try to start playback of first channel in this group
+ std::vector<PVRChannelGroupMember> groupMembers(channelGroup->GetMembers());
+ if (!groupMembers.empty())
+ {
+ return SwitchToChannel(CFileItemPtr(new CFileItem((*groupMembers.begin()).channel)), true);
+ }
+ }
+ }
+
+ CLog::Log(LOGNOTICE, "PVRGUIActions - %s - could not determine %s channel to start playback with. No last played channel found, and first channel of active group could also not be determined.", __FUNCTION__, bIsRadio ? "Radio": "TV");
+
+ CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
+ g_localizeStrings.Get(19166), // PVR information
+ StringUtils::Format(g_localizeStrings.Get(19035).c_str(),
+ g_localizeStrings.Get(bIsRadio ? 19021 : 19020).c_str())); // Radio/TV could not be played. Check the log for details.
+ return false;
+ }
+
+ bool CPVRGUIActions::ContinueLastPlayedChannel() const
+ {
+ const CFileItemPtr item(g_PVRChannelGroups->GetLastPlayedChannel());
+ const CPVRChannelPtr channel(item ? item->GetPVRChannelInfoTag() : CPVRChannelPtr());
+ bool bWasPlaying = false;
+ if (channel)
+ {
+ // Obtain previous 'was playing on last app quit' flag and reset it, then.
+ channel->SetWasPlayingOnLastQuit(false, bWasPlaying);
+ }
+
+ int iPlayMode = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRPLAYBACK_STARTLAST);
+ if (iPlayMode == CONTINUE_LAST_CHANNEL_OFF)
+ return false;
+
+ // Only switch to the channel if it was playing on last app quit.
+ if (bWasPlaying)
+ {
+ CLog::Log(LOGNOTICE, "PVRGUIActions - %s - continue playback on channel '%s'", __FUNCTION__, channel->ChannelName().c_str());
+ g_PVRManager.SetPlayingGroup(g_PVRChannelGroups->GetLastPlayedGroup(channel->ChannelID()));
+ return SwitchToChannel(item, true, iPlayMode == CONTINUE_LAST_CHANNEL_IN_FOREGROUND);
+ }
+
+ return false;
+ }
+
bool CPVRGUIActions::PlayMedia(const CFileItemPtr &item) const
{
CFileItemPtr pvrItem(item);
@@ -761,6 +1133,333 @@ namespace PVR
return true;
}
+ bool CPVRGUIActions::StartChannelScan()
+ {
+ if (!g_PVRManager.IsStarted() || IsRunningChannelScan())
+ return false;
+
+ PVR_CLIENT scanClient;
+ std::vector<PVR_CLIENT> possibleScanClients = g_PVRClients->GetClientsSupportingChannelScan();
+ m_bChannelScanRunning = true;
+
+ /* multiple clients found */
+ if (possibleScanClients.size() > 1)
+ {
+ CGUIDialogSelect* pDialog= dynamic_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT));
+ if (!pDialog)
+ {
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - unable to get WINDOW_DIALOG_SELECT!", __FUNCTION__);
+ m_bChannelScanRunning = false;
+ return false;
+ }
+
+ pDialog->Reset();
+ pDialog->SetHeading(CVariant{19119}); // "On which backend do you want to search?"
+
+ for (const auto client : possibleScanClients)
+ pDialog->Add(client->GetFriendlyName());
+
+ pDialog->Open();
+
+ int selection = pDialog->GetSelectedItem();
+ if (selection >= 0)
+ scanClient = possibleScanClients[selection];
+ }
+ /* one client found */
+ else if (possibleScanClients.size() == 1)
+ {
+ scanClient = possibleScanClients[0];
+ }
+ /* no clients found */
+ else if (!scanClient)
+ {
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, // "Information"
+ CVariant{19192}); // "None of the connected PVR backends supports scanning for channels."
+ m_bChannelScanRunning = false;
+ return false;
+ }
+
+ /* start the channel scan */
+ CLog::Log(LOGNOTICE,"CPVRGUIActions - %s - starting to scan for channels on client %s",
+ __FUNCTION__, scanClient->GetFriendlyName().c_str());
+ long perfCnt = XbmcThreads::SystemClockMillis();
+
+ /* do the scan */
+ if (scanClient->StartChannelScan() != PVR_ERROR_NO_ERROR)
+ CGUIDialogOK::ShowAndGetInput(CVariant{257}, // "Error"
+ CVariant{19193}); // "The channel scan can't be started. Check the log for more information about this message."
+
+ CLog::Log(LOGNOTICE, "CPVRGUIActions - %s - channel scan finished after %li.%li seconds",
+ __FUNCTION__, (XbmcThreads::SystemClockMillis() - perfCnt) / 1000, (XbmcThreads::SystemClockMillis() - perfCnt) % 1000);
+ m_bChannelScanRunning = false;
+ return true;
+ }
+
+ bool CPVRGUIActions::ProcessMenuHooks(const CFileItemPtr &item)
+ {
+ if (!g_PVRManager.IsStarted())
+ return false;
+
+ int iClientID = -1;
+ PVR_MENUHOOK_CAT menuCategory = PVR_MENUHOOK_SETTING;
+
+ if (item->IsEPG())
+ {
+ if (item->GetEPGInfoTag()->HasPVRChannel())
+ {
+ iClientID = item->GetEPGInfoTag()->ChannelTag()->ClientID();
+ menuCategory = PVR_MENUHOOK_EPG;
+ }
+ else
+ return false;
+ }
+ else if (item->IsPVRChannel())
+ {
+ iClientID = item->GetPVRChannelInfoTag()->ClientID();
+ menuCategory = PVR_MENUHOOK_CHANNEL;
+ }
+ else if (item->IsDeletedPVRRecording())
+ {
+ iClientID = item->GetPVRRecordingInfoTag()->m_iClientId;
+ menuCategory = PVR_MENUHOOK_DELETED_RECORDING;
+ }
+ else if (item->IsUsablePVRRecording())
+ {
+ iClientID = item->GetPVRRecordingInfoTag()->m_iClientId;
+ menuCategory = PVR_MENUHOOK_RECORDING;
+ }
+ else if (item->IsPVRTimer())
+ {
+ iClientID = item->GetPVRTimerInfoTag()->m_iClientId;
+ menuCategory = PVR_MENUHOOK_TIMER;
+ }
+
+ // get client id
+ if (iClientID < 0 && menuCategory == PVR_MENUHOOK_SETTING)
+ {
+ PVR_CLIENTMAP clients;
+ g_PVRClients->GetCreatedClients(clients);
+
+ if (clients.size() == 1)
+ {
+ iClientID = clients.begin()->first;
+ }
+ else if (clients.size() > 1)
+ {
+ // have user select client
+ CGUIDialogSelect* pDialog= dynamic_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT));
+ if (!pDialog)
+ {
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - unable to get WINDOW_DIALOG_SELECT!", __FUNCTION__);
+ return false;
+ }
+
+ pDialog->Reset();
+ pDialog->SetHeading(CVariant{19196}); // "PVR client specific actions"
+
+ for (const auto client : clients)
+ {
+ pDialog->Add(client.second->GetBackendName());
+ }
+
+ pDialog->Open();
+
+ int selection = pDialog->GetSelectedItem();
+ if (selection >= 0)
+ {
+ auto client = clients.begin();
+ std::advance(client, selection);
+ iClientID = client->first;
+ }
+ }
+ }
+
+ if (iClientID < 0)
+ iClientID = g_PVRClients->GetPlayingClientID();
+
+ PVR_CLIENT client;
+ if (g_PVRClients->GetCreatedClient(iClientID, client) && client->HasMenuHooks(menuCategory))
+ {
+ CGUIDialogSelect* pDialog= dynamic_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT));
+ if (!pDialog)
+ {
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - unable to get WINDOW_DIALOG_SELECT!", __FUNCTION__);
+ return false;
+ }
+
+ pDialog->Reset();
+ pDialog->SetHeading(CVariant{19196}); // "PVR client specific actions"
+
+ PVR_MENUHOOKS *hooks = client->GetMenuHooks();
+ std::vector<int> hookIDs;
+ int selection = 0;
+
+ for (unsigned int i = 0; i < hooks->size(); ++i)
+ {
+ if (hooks->at(i).category == menuCategory || hooks->at(i).category == PVR_MENUHOOK_ALL)
+ {
+ pDialog->Add(g_localizeStrings.GetAddonString(client->ID(), hooks->at(i).iLocalizedStringId));
+ hookIDs.push_back(i);
+ }
+ }
+
+ if (hookIDs.size() > 1)
+ {
+ pDialog->Open();
+ selection = pDialog->GetSelectedItem();
+ }
+
+ if (selection >= 0)
+ client->CallMenuHook(hooks->at(hookIDs.at(selection)), item.get());
+ else
+ return false;
+ }
+
+ return true;
+ }
+
+ bool CPVRGUIActions::ResetPVRDatabase(bool bResetEPGOnly)
+ {
+ CLog::Log(LOGNOTICE,"CPVRGUIActions - %s - clearing the PVR database", __FUNCTION__);
+
+ CGUIDialogProgress* pDlgProgress = dynamic_cast<CGUIDialogProgress*>(g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS));
+ if (!pDlgProgress)
+ {
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - unable to get WINDOW_DIALOG_PROGRESS!", __FUNCTION__);
+ return false;
+ }
+
+ if (bResetEPGOnly)
+ {
+ if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{19098}, // "Warning!"
+ CVariant{19188})) // "All your guide data will be cleared. Are you sure?"
+ return false;
+ }
+ else
+ {
+ if (!CheckParentalPIN() ||
+ !CGUIDialogYesNo::ShowAndGetInput(CVariant{19098}, // "Warning!"
+ CVariant{19186})) // "All your TV related data (channels, groups, guide) will be cleared. Are you sure?"
+ return false;
+ }
+
+ CDateTime::ResetTimezoneBias();
+
+ g_EpgContainer.Stop();
+
+ pDlgProgress->SetHeading(CVariant{313}); // "Cleaning database"
+ pDlgProgress->SetLine(0, CVariant{g_localizeStrings.Get(19187)}); // "Clearing all related data."
+ pDlgProgress->SetLine(1, CVariant{""});
+ pDlgProgress->SetLine(2, CVariant{""});
+
+ pDlgProgress->Open();
+ pDlgProgress->Progress();
+
+ if (g_PVRManager.IsPlaying())
+ {
+ CLog::Log(LOGNOTICE,"CPVRGUIActions - %s - stopping playback", __FUNCTION__);
+ CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
+ }
+
+ pDlgProgress->SetPercentage(10);
+ pDlgProgress->Progress();
+
+ /* reset the EPG pointers */
+ const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase());
+ if (database)
+ database->ResetEPG();
+
+ /* stop the thread, close database */
+ g_PVRManager.Stop();
+
+ pDlgProgress->SetPercentage(20);
+ pDlgProgress->Progress();
+
+ if (database && database->Open())
+ {
+ /* clean the EPG database */
+ g_EpgContainer.Reset();
+ pDlgProgress->SetPercentage(30);
+ pDlgProgress->Progress();
+
+ if (!bResetEPGOnly)
+ {
+ database->DeleteChannelGroups();
+ pDlgProgress->SetPercentage(50);
+ pDlgProgress->Progress();
+
+ /* delete all channels */
+ database->DeleteChannels();
+ pDlgProgress->SetPercentage(70);
+ pDlgProgress->Progress();
+
+ /* delete all channel and recording settings */
+ CVideoDatabase videoDatabase;
+
+ if (videoDatabase.Open())
+ {
+ videoDatabase.EraseVideoSettings("pvr://channels/");
+ videoDatabase.EraseVideoSettings(CPVRRecordingsPath::PATH_RECORDINGS);
+ videoDatabase.Close();
+ }
+
+ pDlgProgress->SetPercentage(80);
+ pDlgProgress->Progress();
+
+ /* delete all client information */
+ pDlgProgress->SetPercentage(90);
+ pDlgProgress->Progress();
+ }
+
+ database->Close();
+ }
+
+ CLog::Log(LOGNOTICE,"CPVRGUIActions - %s - %s database cleared", __FUNCTION__, bResetEPGOnly ? "EPG" : "PVR and EPG");
+
+ if (database)
+ database->Open();
+
+ CLog::Log(LOGNOTICE,"CPVRGUIActions - %s - restarting the PVRManager", __FUNCTION__);
+ g_PVRManager.Start();
+
+ pDlgProgress->SetPercentage(100);
+ pDlgProgress->Close();
+ return true;
+ }
+
+ bool CPVRGUIActions::CheckParentalLock(const CPVRChannelPtr &channel) const
+ {
+ bool bReturn = !g_PVRManager.IsParentalLocked(channel) || CheckParentalPIN();
+
+ if (!bReturn)
+ CLog::Log(LOGERROR, "CPVRGUIActions - %s - parental lock verification failed for channel '%s': wrong PIN entered.", __FUNCTION__, channel->ChannelName().c_str());
+
+ return bReturn;
+ }
+
+ bool CPVRGUIActions::CheckParentalPIN() const
+ {
+ std::string pinCode = CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRPARENTAL_PIN);
+
+ if (!CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRPARENTAL_ENABLED) || pinCode.empty())
+ return true;
+
+ // Locked channel. Enter PIN:
+ bool bValidPIN = CGUIDialogNumeric::ShowAndVerifyInput(pinCode, g_localizeStrings.Get(19262), true); // "Parental control. Enter PIN:"
+ if (!bValidPIN)
+ {
+ // display message: The entered PIN number was incorrect
+ CGUIDialogOK::ShowAndGetInput(CVariant{19264}, CVariant{19265}); // "Incorrect PIN", "The entered PIN was incorrect."
+ }
+ else
+ {
+ // restart the parental timer
+ g_PVRManager.RestartParentalTimer();
+ }
+
+ return bValidPIN;
+ }
+
CPVRChannelNumberInputHandler &CPVRGUIActions::GetChannelNumberInputHandler()
{
// window/dialog specific input handler
diff --git a/xbmc/pvr/PVRGUIActions.h b/xbmc/pvr/PVRGUIActions.h
index eabc2d5df2..43ff28eba0 100644
--- a/xbmc/pvr/PVRGUIActions.h
+++ b/xbmc/pvr/PVRGUIActions.h
@@ -32,6 +32,13 @@ class CGUIWindow;
namespace PVR
{
+ enum PlaybackType
+ {
+ PlaybackTypeAny = 0,
+ PlaybackTypeTV,
+ PlaybackTypeRadio
+ };
+
class CPVRChannelSwitchingInputHandler : public CPVRChannelNumberInputHandler
{
public:
@@ -91,6 +98,12 @@ namespace PVR
bool AddTimer(const CFileItemPtr &item, bool bShowTimerSettings) const;
/*!
+ * @brief Add a timer to the client. Doesn't add the timer to the container. The backend will do this.
+ * @return True if it was sent correctly, false if not.
+ */
+ bool AddTimer(const CPVRTimerInfoTagPtr &item) const;
+
+ /*!
* @brief Create a new timer rule, either interactive or non-interactive.
* @param item containing epg data to create a timer rule for. item must be an epg tag or a channel.
* @param bShowTimerSettings is used to control whether a settings dialog will be opened prior creating the timer rule.
@@ -155,6 +168,14 @@ namespace PVR
bool ShowRecordingInfo(const CFileItemPtr &item) const;
/*!
+ * @brief Start or stop recording on a given channel.
+ * @param channel the channel to start/stop recording.
+ * @param bOnOff True to start recording, false to stop.
+ * @return True if the recording was started or stopped successfully, false otherwise.
+ */
+ bool SetRecordingOnChannel(const CPVRChannelPtr &channel, bool bOnOff);
+
+ /*!
* @brief Stop a currently active recording, always showing a confirmation dialog.
* @param item containing a recording to stop. item must be a timer, an epg tag or a channel.
* @return true, if the recording was stopped successfully, false otherwise.
@@ -227,6 +248,19 @@ namespace PVR
bool PlayMedia(const CFileItemPtr &item) const;
/*!
+ * @brief Start playback of the last played channel, and if there is none, play first channel in the current channelgroup.
+ * @param type The type of playback to be started (any, radio, tv). See PlaybackType enum
+ * @return True if playback was started, false otherwise.
+ */
+ bool SwitchToChannel(PlaybackType type) const;
+
+ /*!
+ * @brief Continue playback of the last played channel.
+ * @return True if playback was continued, false otherwise.
+ */
+ bool ContinueLastPlayedChannel() const;
+
+ /*!
* @brief Hide a channel, always showing a confirmation dialog.
* @param item containing a channel or an epg tag.
* @return true on success, false otherwise.
@@ -234,13 +268,51 @@ namespace PVR
bool HideChannel(const CFileItemPtr &item) const;
/*!
+ * @brief Open a selection dialog and start a channel scan on the selected client.
+ * @return true on success, false otherwise.
+ */
+ bool StartChannelScan();
+
+ /*!
+ * @return True when a channel scan is currently running, false otherwise.
+ */
+ bool IsRunningChannelScan() const { return m_bChannelScanRunning; }
+
+ /*!
+ * @brief Open selection and progress PVR actions.
+ * @param item The selected file item for which the hook was called.
+ * @return true on success, false otherwise.
+ */
+ bool ProcessMenuHooks(const CFileItemPtr &item);
+
+ /*!
+ * @brief Reset the TV database to it's initial state and delete all the data.
+ * @param bResetEPGOnly True to only reset the EPG database, false to reset both PVR and EPG database.
+ * @return true on success, false otherwise.
+ */
+ bool ResetPVRDatabase(bool bResetEPGOnly);
+
+ /*!
+ * @brief Check if channel is parental locked. Ask for PIN if necessary.
+ * @param channel The channel to do the check for.
+ * @return True if channel is unlocked (by default or PIN unlocked), false otherwise.
+ */
+ bool CheckParentalLock(const CPVRChannelPtr &channel) const;
+
+ /*!
+ * @brief Open Numeric dialog to check for parental PIN.
+ * @return True if entered PIN was correct, false otherwise.
+ */
+ bool CheckParentalPIN() const;
+
+ /*!
* @brief Get the currently active channel number input handler.
* @return the handler.
*/
CPVRChannelNumberInputHandler &GetChannelNumberInputHandler();
private:
- CPVRGUIActions() = default;
+ CPVRGUIActions();
CPVRGUIActions(const CPVRGUIActions&) = delete;
CPVRGUIActions const& operator=(CPVRGUIActions const&) = delete;
virtual ~CPVRGUIActions() {}
@@ -310,24 +382,38 @@ namespace PVR
/*!
* @brief Check "play minimized" settings value and switch to fullscreen if not set.
+ * @param bFullscreen switch to fullscreen or set windowed playback.
*/
- void CheckAndSwitchToFullscreen() const;
+ void CheckAndSwitchToFullscreen(bool bFullscreen) const;
+
+ /*!
+ * @brief Switch channel.
+ * @param item containing a channel or an epg tag.
+ * @param bCheckResume controls resume check in case a recording for the current epg event is present.
+ * @param bFullscreen start playback fullscreen or not.
+ * @return true on success, false otherwise.
+ */
+ bool SwitchToChannel(const CFileItemPtr &item, bool bCheckResume, bool bFullscreen) const;
/*!
* @brief Try a fast Live TV/Radio channel switch. Calls directly into active player instead of using messaging
* @param channel the channel to switch to.
+ * @param bFullscreen start playback fullscreen or not.
* @return true if the switch was succesful, false otherwise.
*/
- bool TryFastChannelSwitch(const CPVRChannelPtr &channel) const;
+ bool TryFastChannelSwitch(const CPVRChannelPtr &channel, bool bFullscreen) const;
/*!
* @brief Start playback of the given item.
+ * @param bFullscreen start playback fullscreen or not.
* @param item containing a channel or a recording.
*/
- void StartPlayback(CFileItem *item) const;
+ void StartPlayback(CFileItem *item, bool bFullscreen) const;
private:
CPVRChannelSwitchingInputHandler m_channelNumberInputHandler;
+ bool m_bChannelScanRunning;
+
};
} // namespace PVR
diff --git a/xbmc/pvr/PVRJobs.cpp b/xbmc/pvr/PVRJobs.cpp
new file mode 100644
index 0000000000..135256c516
--- /dev/null
+++ b/xbmc/pvr/PVRJobs.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012-2015 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Kodi; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "PVRJobs.h"
+
+#include "dialogs/GUIDialogKaiToast.h"
+#include "events/EventLog.h"
+#include "events/NotificationEvent.h"
+
+#include "pvr/PVRGUIActions.h"
+
+namespace PVR
+{
+
+bool CPVRSetRecordingOnChannelJob::DoWork()
+{
+ return CPVRGUIActions::GetInstance().SetRecordingOnChannel(m_channel, m_bOnOff);
+}
+
+bool CPVRContinueLastChannelJob::DoWork()
+{
+ return CPVRGUIActions::GetInstance().ContinueLastPlayedChannel();
+}
+
+CPVREventlogJob::CPVREventlogJob(bool bNotifyUser, bool bError, const std::string &label, const std::string &msg, const std::string &icon)
+{
+ AddEvent(bNotifyUser, bError, label, msg, icon);
+}
+
+void CPVREventlogJob::AddEvent(bool bNotifyUser, bool bError, const std::string &label, const std::string &msg, const std::string &icon)
+{
+ m_events.emplace_back(Event(bNotifyUser, bError, label, msg, icon));
+}
+
+bool CPVREventlogJob::DoWork()
+{
+ for (const auto &event : m_events)
+ {
+ if (event.m_bNotifyUser)
+ CGUIDialogKaiToast::QueueNotification(
+ event.m_bError ? CGUIDialogKaiToast::Error : CGUIDialogKaiToast::Info, event.m_label.c_str(), event.m_msg, 5000, true);
+
+ // Write event log entry.
+ CEventLog::GetInstance().Add(
+ EventPtr(new CNotificationEvent(event.m_label, event.m_msg, event.m_icon, event.m_bError ? EventLevel::Error : EventLevel::Information)));
+ }
+ return true;
+}
+
+} // namespace PVR
diff --git a/xbmc/pvr/PVRJobs.h b/xbmc/pvr/PVRJobs.h
new file mode 100644
index 0000000000..4671e1bf46
--- /dev/null
+++ b/xbmc/pvr/PVRJobs.h
@@ -0,0 +1,81 @@
+#pragma once
+/*
+ * Copyright (C) 2012-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <vector>
+
+#include "utils/JobManager.h"
+
+#include "pvr/PVRTypes.h"
+
+namespace PVR
+{
+ class CPVRSetRecordingOnChannelJob : public CJob
+ {
+ public:
+ CPVRSetRecordingOnChannelJob(const CPVRChannelPtr &channel, bool bOnOff)
+ : m_channel(channel), m_bOnOff(bOnOff) {}
+ virtual ~CPVRSetRecordingOnChannelJob() = default;
+ const char *GetType() const override { return "pvr-set-recording-on-channel"; }
+
+ bool DoWork() override;
+ private:
+ CPVRChannelPtr m_channel;
+ bool m_bOnOff;
+ };
+
+ class CPVRContinueLastChannelJob : public CJob
+ {
+ public:
+ CPVRContinueLastChannelJob() = default;
+ virtual ~CPVRContinueLastChannelJob() = default;
+ const char *GetType() const override { return "pvr-continue-last-channel-job"; }
+
+ bool DoWork() override;
+ };
+
+ class CPVREventlogJob : public CJob
+ {
+ public:
+ CPVREventlogJob() = default;
+ CPVREventlogJob(bool bNotifyUser, bool bError, const std::string &label, const std::string &msg, const std::string &icon);
+ virtual ~CPVREventlogJob() = default;
+ const char *GetType() const override { return "pvr-eventlog-job"; }
+
+ void AddEvent(bool bNotifyUser, bool bError, const std::string &label, const std::string &msg, const std::string &icon);
+
+ bool DoWork() override;
+ private:
+ struct Event
+ {
+ bool m_bNotifyUser;
+ bool m_bError;
+ std::string m_label;
+ std::string m_msg;
+ std::string m_icon;
+
+ Event(bool bNotifyUser, bool bError, const std::string &label, const std::string &msg, const std::string &icon)
+ : m_bNotifyUser(bNotifyUser), m_bError(bError), m_label(label), m_msg(msg), m_icon(icon) {}
+ };
+
+ std::vector<Event> m_events;
+ };
+
+} // namespace PVR
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index 6887349a23..7795c50f73 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -26,15 +26,12 @@
#include "Application.h"
#include "dialogs/GUIDialogExtendedProgressBar.h"
#include "dialogs/GUIDialogKaiToast.h"
-#include "dialogs/GUIDialogNumeric.h"
-#include "dialogs/GUIDialogOK.h"
-#include "dialogs/GUIDialogProgress.h"
-#include "dialogs/GUIDialogSelect.h"
#include "epg/EpgContainer.h"
#include "GUIInfoManager.h"
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "interfaces/AnnouncementManager.h"
+#include "input/Key.h"
#include "messaging/ApplicationMessenger.h"
#include "messaging/helpers/DialogHelper.h"
#include "music/tags/MusicInfoTag.h"
@@ -44,11 +41,10 @@
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
-#include "pvr/dialogs/GUIDialogPVRChannelManager.h"
-#include "pvr/dialogs/GUIDialogPVRGroupManager.h"
#include "pvr/PVRActionListener.h"
#include "pvr/PVRDatabase.h"
#include "pvr/PVRGUIInfo.h"
+#include "pvr/PVRJobs.h"
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/recordings/PVRRecordingsPath.h"
#include "pvr/timers/PVRTimers.h"
@@ -170,7 +166,6 @@ CPVRManager::CPVRManager(void) :
CPVRManager::~CPVRManager(void)
{
- CServiceBroker::GetSettings().UnregisterCallback(this);
CAnnouncementManager::GetInstance().RemoveAnnouncer(this);
CLog::Log(LOGDEBUG,"PVRManager - destroyed");
}
@@ -182,13 +177,21 @@ void CPVRManager::Announce(AnnouncementFlag flag, const char *sender, const char
if ((flag & (ANNOUNCEMENT::System)))
{
- if (strcmp(message, "OnWake") == 0)
+ if (strcmp(message, "OnQuit") == 0 ||
+ strcmp(message, "OnSleep") == 0)
+ {
+ // save the currently playing channel.
+ const CPVRChannelPtr playingChannel(GetCurrentChannel());
+ if (playingChannel)
+ playingChannel->SetWasPlayingOnLastQuit(true);
+ }
+ else if (strcmp(message, "OnWake") == 0)
{
/* start job to search for missing channel icons */
TriggerSearchMissingChannelIcons();
/* continue last watched channel */
- ContinueLastChannel();
+ TriggerContinueLastChannel();
/* trigger PVR data updates */
TriggerChannelGroupsUpdate();
@@ -246,89 +249,6 @@ CPVRClientsPtr CPVRManager::Clients(void) const
return m_addons;
}
-void CPVRManager::OnSettingChanged(const CSetting *setting)
-{
- if (setting == NULL)
- return;
-
- const std::string &settingId = setting->GetId();
- if (settingId == CSettings::SETTING_PVRPARENTAL_ENABLED)
- {
- if (((CSettingBool*)setting)->GetValue() && CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRPARENTAL_PIN).empty())
- {
- std::string newPassword = "";
- // password set... save it
- if (CGUIDialogNumeric::ShowAndVerifyNewPassword(newPassword))
- CServiceBroker::GetSettings().SetString(CSettings::SETTING_PVRPARENTAL_PIN, newPassword);
- // password not set... disable parental
- else
- ((CSettingBool*)setting)->SetValue(false);
- }
- }
- else if(settingId == CSettings::SETTING_EPG_DAYSTODISPLAY)
- {
- m_addons->SetEPGTimeFrame(static_cast<const CSettingInt*>(setting)->GetValue());
- }
-}
-
-void CPVRManager::OnSettingAction(const CSetting *setting)
-{
- if (setting == NULL)
- return;
-
- const std::string &settingId = setting->GetId();
- if (settingId == CSettings::SETTING_PVRMENU_SEARCHICONS)
- {
- if (IsStarted())
- TriggerSearchMissingChannelIcons();
- }
- else if (settingId == CSettings::SETTING_PVRMANAGER_RESETDB)
- {
- if (CheckParentalPIN(g_localizeStrings.Get(19262)) &&
- HELPERS::ShowYesNoDialogText(CVariant{19098}, CVariant{19186}) == DialogResponse::YES)
- {
- CDateTime::ResetTimezoneBias();
- ResetDatabase(false);
- }
- }
- else if (settingId == CSettings::SETTING_EPG_RESETEPG)
- {
- if (HELPERS::ShowYesNoDialogText(CVariant{19098}, CVariant{19188}) == DialogResponse::YES)
- {
- CDateTime::ResetTimezoneBias();
- ResetDatabase(true);
- }
- }
- else if (settingId == CSettings::SETTING_PVRMANAGER_CHANNELSCAN)
- {
- if (IsStarted())
- StartChannelScan();
- }
- else if (settingId == CSettings::SETTING_PVRMANAGER_CHANNELMANAGER)
- {
- if (IsStarted())
- {
- CGUIDialogPVRChannelManager *dialog = (CGUIDialogPVRChannelManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_CHANNEL_MANAGER);
- if (dialog)
- dialog->Open();
- }
- }
- else if (settingId == CSettings::SETTING_PVRMANAGER_GROUPMANAGER)
- {
- if (IsStarted())
- {
- CGUIDialogPVRGroupManager *dialog = (CGUIDialogPVRGroupManager *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER);
- if (dialog)
- dialog->Open();
- }
- }
- else if (settingId == CSettings::SETTING_PVRCLIENT_MENUHOOK)
- {
- if (IsStarted())
- m_addons->ProcessMenuHooks(-1, PVR_MENUHOOK_SETTING, NULL);
- }
-}
-
void CPVRManager::Clear(void)
{
g_application.UnregisterActionListener(&CPVRActionListener::GetInstance());
@@ -366,17 +286,8 @@ void CPVRManager::ResetProperties(void)
void CPVRManager::Init()
{
- std::set<std::string> settingSet;
- settingSet.insert(CSettings::SETTING_PVRMANAGER_CHANNELMANAGER);
- settingSet.insert(CSettings::SETTING_PVRMANAGER_GROUPMANAGER);
- settingSet.insert(CSettings::SETTING_PVRMANAGER_CHANNELSCAN);
- settingSet.insert(CSettings::SETTING_PVRMANAGER_RESETDB);
- settingSet.insert(CSettings::SETTING_PVRCLIENT_MENUHOOK);
- settingSet.insert(CSettings::SETTING_PVRMENU_SEARCHICONS);
- settingSet.insert(CSettings::SETTING_EPG_RESETEPG);
- settingSet.insert(CSettings::SETTING_EPG_DAYSTODISPLAY);
- settingSet.insert(CSettings::SETTING_PVRPARENTAL_ENABLED);
- CServiceBroker::GetSettings().RegisterCallback(this, settingSet);
+ // Create and init action listener
+ CPVRActionListener::GetInstance().Init();
// Note: we're holding the progress bar dialog instance pointer in a member because it is needed by pvr core
// components. The latter might run in a different thread than the gui and g_windowManager.GetWindow()
@@ -485,6 +396,9 @@ void CPVRManager::Shutdown()
// release addons
m_addons.reset();
+
+ // deinit action listener
+ CPVRActionListener::GetInstance().Deinit();
}
CPVRManager::ManagerState CPVRManager::GetState(void) const
@@ -587,9 +501,8 @@ void CPVRManager::Process(void)
/* start job to search for missing channel icons */
TriggerSearchMissingChannelIcons();
- /* try to continue last watched channel otherwise set group to last played group */
- if (!ContinueLastChannel())
- SetPlayingGroup(m_channelGroups->GetLastPlayedGroup());
+ /* try to continue last watched channel */
+ TriggerContinueLastChannel();
}
/* execute the next pending jobs if there are any */
try
@@ -771,108 +684,9 @@ bool CPVRManager::ChannelUpDown(unsigned int *iNewChannelNumber, bool bPreview,
return bReturn;
}
-bool CPVRManager::ContinueLastChannel(void)
+void CPVRManager::TriggerContinueLastChannel(void)
{
- if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRPLAYBACK_STARTLAST) == CONTINUE_LAST_CHANNEL_OFF)
- return false;
-
- CFileItemPtr channel = m_channelGroups->GetLastPlayedChannel();
- if (channel && channel->HasPVRChannelInfoTag())
- {
- CLog::Log(LOGNOTICE, "PVRManager - %s - continue playback on channel '%s'", __FUNCTION__, channel->GetPVRChannelInfoTag()->ChannelName().c_str());
- SetPlayingGroup(m_channelGroups->GetLastPlayedGroup(channel->GetPVRChannelInfoTag()->ChannelID()));
- StartPlayback(channel->GetPVRChannelInfoTag(), (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRPLAYBACK_STARTLAST) == CONTINUE_LAST_CHANNEL_IN_BACKGROUND));
- return true;
- }
-
- CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__);
-
- return false;
-}
-
-void CPVRManager::ResetDatabase(bool bResetEPGOnly /* = false */)
-{
- CLog::Log(LOGNOTICE,"PVRManager - %s - clearing the PVR database", __FUNCTION__);
-
- g_EpgContainer.Stop();
-
- CGUIDialogProgress* pDlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
- pDlgProgress->SetHeading(CVariant{313});
- pDlgProgress->SetLine(0, CVariant{g_localizeStrings.Get(19187)}); // All data in the PVR database is being erased
- pDlgProgress->SetLine(1, CVariant{""});
- pDlgProgress->SetLine(2, CVariant{""});
- pDlgProgress->Open();
- pDlgProgress->Progress();
-
- if (m_addons->IsPlaying())
- {
- CLog::Log(LOGNOTICE,"PVRManager - %s - stopping playback", __FUNCTION__);
- CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP);
- }
-
- pDlgProgress->SetPercentage(10);
- pDlgProgress->Progress();
-
- /* reset the EPG pointers */
- const CPVRDatabasePtr database(GetTVDatabase());
- if (database)
- database->ResetEPG();
-
- /* stop the thread, close database */
- Stop();
-
- pDlgProgress->SetPercentage(20);
- pDlgProgress->Progress();
-
- if (database && database->Open())
- {
- /* clean the EPG database */
- g_EpgContainer.Reset();
- pDlgProgress->SetPercentage(30);
- pDlgProgress->Progress();
-
- if (!bResetEPGOnly)
- {
- database->DeleteChannelGroups();
- pDlgProgress->SetPercentage(50);
- pDlgProgress->Progress();
-
- /* delete all channels */
- database->DeleteChannels();
- pDlgProgress->SetPercentage(70);
- pDlgProgress->Progress();
-
- /* delete all channel and recording settings */
- CVideoDatabase videoDatabase;
-
- if (videoDatabase.Open())
- {
- videoDatabase.EraseVideoSettings("pvr://channels/");
- videoDatabase.EraseVideoSettings(CPVRRecordingsPath::PATH_RECORDINGS);
- videoDatabase.Close();
- }
-
- pDlgProgress->SetPercentage(80);
- pDlgProgress->Progress();
-
- /* delete all client information */
- pDlgProgress->SetPercentage(90);
- pDlgProgress->Progress();
- }
-
- database->Close();
- }
-
- CLog::Log(LOGNOTICE,"PVRManager - %s - %s database cleared", __FUNCTION__, bResetEPGOnly ? "EPG" : "PVR and EPG");
-
- if (database)
- database->Open();
-
- CLog::Log(LOGNOTICE,"PVRManager - %s - restarting the PVRManager", __FUNCTION__);
- Start();
-
- pDlgProgress->SetPercentage(100);
- pDlgProgress->Close();
+ CJobManager::GetInstance().AddJob(new CPVRContinueLastChannelJob(), nullptr);
}
bool CPVRManager::IsPlaying(void) const
@@ -938,269 +752,16 @@ void CPVRManager::ResetPlayingTag(void)
m_guiInfo->ResetPlayingTag();
}
-bool CPVRManager::ToggleRecordingOnChannel(unsigned int iChannelId)
-{
- const CPVRChannelPtr channel(m_channelGroups->GetChannelById(iChannelId));
- if (!channel)
- return false;
-
- return SetRecordingOnChannel(channel, !channel->IsRecording());
-}
-
void CPVRManager::StartRecordingOnPlayingChannel(bool bOnOff)
{
// can be called from VideoPlayer thread. SetRecordingOnChannel can open a dialog. Thus, execute async.
CJobManager::GetInstance().AddJob(new CPVRSetRecordingOnChannelJob(m_addons->GetPlayingChannel(), bOnOff), NULL);
}
-namespace
-{
-enum PVRRECORD_INSTANTRECORDACTION
-{
- NONE = -1,
- RECORD_CURRENT_SHOW = 0,
- RECORD_INSTANTRECORDTIME = 1,
- ASK = 2,
- RECORD_30_MINUTES = 3,
- RECORD_60_MINUTES = 4,
- RECORD_120_MINUTES = 5,
- RECORD_NEXT_SHOW = 6
-};
-
-class InstantRecordingActionSelector
-{
-public:
- InstantRecordingActionSelector();
- virtual ~InstantRecordingActionSelector() {}
-
- void AddAction(PVRRECORD_INSTANTRECORDACTION eAction, const std::string &title);
- void PreSelectAction(PVRRECORD_INSTANTRECORDACTION eAction);
- PVRRECORD_INSTANTRECORDACTION Select();
-
-private:
- CGUIDialogSelect *m_pDlgSelect; // not owner!
- std::map<PVRRECORD_INSTANTRECORDACTION, int> m_actions;
-};
-
-InstantRecordingActionSelector::InstantRecordingActionSelector()
-: m_pDlgSelect(dynamic_cast<CGUIDialogSelect *>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT)))
-{
- if (m_pDlgSelect)
- {
- m_pDlgSelect->SetMultiSelection(false);
- m_pDlgSelect->SetHeading(CVariant{19086}); // Instant recording action
- }
- else
- {
- CLog::Log(LOGERROR, "InstantRecordingActionSelector - %s - unable to obtain WINDOW_DIALOG_SELECT instance", __FUNCTION__);
- }
-}
-
-void InstantRecordingActionSelector::AddAction(PVRRECORD_INSTANTRECORDACTION eAction, const std::string &title)
-{
- if (m_actions.find(eAction) == m_actions.end())
- {
- switch (eAction)
- {
- case RECORD_INSTANTRECORDTIME:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(),
- CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME))); // Record next <default duration> minutes
- break;
- case RECORD_30_MINUTES:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 30)); // Record next 30 minutes
- break;
- case RECORD_60_MINUTES:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 60)); // Record next 60 minutes
- break;
- case RECORD_120_MINUTES:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19090).c_str(), 120)); // Record next 120 minutes
- break;
- case RECORD_CURRENT_SHOW:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19091).c_str(), title.c_str())); // Record current show (<title>)
- break;
- case RECORD_NEXT_SHOW:
- m_pDlgSelect->Add(StringUtils::Format(g_localizeStrings.Get(19092).c_str(), title.c_str())); // Record next show (<title>)
- break;
- case NONE:
- case ASK:
- default:
- return;
- }
-
- m_actions.insert(std::make_pair(eAction, m_actions.size()));
- }
-}
-
-void InstantRecordingActionSelector::PreSelectAction(PVRRECORD_INSTANTRECORDACTION eAction)
-{
- const auto &it = m_actions.find(eAction);
- if (it != m_actions.end())
- m_pDlgSelect->SetSelected(it->second);
-}
-
-PVRRECORD_INSTANTRECORDACTION InstantRecordingActionSelector::Select()
-{
- PVRRECORD_INSTANTRECORDACTION eAction = NONE;
-
- m_pDlgSelect->Open();
-
- if (m_pDlgSelect->IsConfirmed())
- {
- int iSelection = m_pDlgSelect->GetSelectedItem();
- for (const auto &action : m_actions)
- {
- if (action.second == iSelection)
- {
- eAction = action.first;
- break;
- }
- }
- }
-
- return eAction;
-}
-
-} // unnamed namespace
-
-bool CPVRManager::SetRecordingOnChannel(const CPVRChannelPtr &channel, bool bOnOff)
-{
- bool bReturn = false;
-
- if (!channel)
- return bReturn;
-
- if (!g_PVRManager.CheckParentalLock(channel))
- return bReturn;
-
- if (m_addons->HasTimerSupport(channel->ClientID()))
- {
- /* timers are supported on this channel */
- if (bOnOff && !channel->IsRecording())
- {
- CEpgInfoTagPtr epgTag;
- int iDuration = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME);
-
- int iAction = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDACTION);
- switch (iAction)
- {
- case RECORD_CURRENT_SHOW:
- epgTag = channel->GetEPGNow();
- break;
-
- case RECORD_INSTANTRECORDTIME:
- epgTag.reset();
- break;
-
- case ASK:
- {
- PVRRECORD_INSTANTRECORDACTION ePreselect = RECORD_INSTANTRECORDTIME;
- InstantRecordingActionSelector selector;
- CEpgInfoTagPtr epgTagNext;
-
- // fixed length recordings
- selector.AddAction(RECORD_30_MINUTES, "");
- selector.AddAction(RECORD_60_MINUTES, "");
- selector.AddAction(RECORD_120_MINUTES, "");
-
- const int iDurationDefault = CServiceBroker::GetSettings().GetInt(CSettings::SETTING_PVRRECORD_INSTANTRECORDTIME);
- if (iDurationDefault != 30 && iDurationDefault != 60 && iDurationDefault != 120)
- selector.AddAction(RECORD_INSTANTRECORDTIME, "");
-
- // epg-based recordings
- epgTag = channel->GetEPGNow();
- if (epgTag)
- {
- // "now"
- selector.AddAction(RECORD_CURRENT_SHOW, epgTag->Title());
- ePreselect = RECORD_CURRENT_SHOW;
-
- // "next"
- epgTagNext = channel->GetEPGNext();
- if (epgTagNext)
- {
- selector.AddAction(RECORD_NEXT_SHOW, epgTagNext->Title());
-
- // be smart. if current show is almost over, preselect next show.
- if (epgTag->ProgressPercentage() > 90.0f)
- ePreselect = RECORD_NEXT_SHOW;
- }
- }
-
- selector.PreSelectAction(ePreselect);
-
- PVRRECORD_INSTANTRECORDACTION eSelected = selector.Select();
- switch (eSelected)
- {
- case NONE:
- return false; // dialog canceled
-
- case RECORD_30_MINUTES:
- iDuration = 30;
- epgTag.reset();
- break;
-
- case RECORD_60_MINUTES:
- iDuration = 60;
- epgTag.reset();
- break;
-
- case RECORD_120_MINUTES:
- iDuration = 120;
- epgTag.reset();
- break;
-
- case RECORD_INSTANTRECORDTIME:
- iDuration = iDurationDefault;
- epgTag.reset();
- break;
-
- case RECORD_CURRENT_SHOW:
- break;
-
- case RECORD_NEXT_SHOW:
- epgTag = epgTagNext;
- break;
-
- default:
- CLog::Log(LOGERROR, "PVRManager - %s - unknown instant record action selection (%d), defaulting to fixed length recording.", __FUNCTION__, eSelected);
- epgTag.reset();
- break;
- }
- break;
- }
-
- default:
- CLog::Log(LOGERROR, "PVRManager - %s - unknown instant record action setting value (%d), defaulting to fixed length recording.", __FUNCTION__, iAction);
- break;
- }
-
- const CPVRTimerInfoTagPtr newTimer(epgTag ? CPVRTimerInfoTag::CreateFromEpg(epgTag, false) : CPVRTimerInfoTag::CreateInstantTimerTag(channel, iDuration));
-
- if (newTimer)
- bReturn = newTimer->AddToClient();
-
- if (!bReturn)
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19164});
- }
- else if (!bOnOff && channel->IsRecording())
- {
- /* delete active timers */
- bReturn = m_timers->DeleteTimersOnChannel(channel, true, true);
- }
- }
-
- return bReturn;
-}
-
-bool CPVRManager::CheckParentalLock(const CPVRChannelPtr &channel)
+void CPVRManager::RestartParentalTimer()
{
- bool bReturn = !IsParentalLocked(channel) ||
- CheckParentalPIN();
-
- if (!bReturn)
- CLog::Log(LOGERROR, "PVRManager - %s - parental lock verification failed for channel '%s': wrong PIN entered.", __FUNCTION__, channel->ChannelName().c_str());
-
- return bReturn;
+ if (m_parentalTimer)
+ m_parentalTimer->StartZero();
}
bool CPVRManager::IsParentalLocked(const CPVRChannelPtr &channel)
@@ -1226,27 +787,6 @@ bool CPVRManager::IsParentalLocked(const CPVRChannelPtr &channel)
return bReturn;
}
-bool CPVRManager::CheckParentalPIN(const std::string& strTitle /* = "" */)
-{
- std::string pinCode = CServiceBroker::GetSettings().GetString(CSettings::SETTING_PVRPARENTAL_PIN);
-
- if (!CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRPARENTAL_ENABLED) || pinCode.empty())
- return true;
-
- // Locked channel. Enter PIN:
- bool bValidPIN = CGUIDialogNumeric::ShowAndVerifyInput(pinCode, !strTitle.empty() ? strTitle : g_localizeStrings.Get(19263), true);
- if (!bValidPIN)
- // display message: The entered PIN number was incorrect
- CGUIDialogOK::ShowAndGetInput(CVariant{19264}, CVariant{19265});
- else if (m_parentalTimer)
- {
- // reset the timer
- m_parentalTimer->StartZero();
- }
-
- return bValidPIN;
-}
-
void CPVRManager::SetPlayingGroup(const CPVRChannelGroupPtr &group)
{
if (m_channelGroups && group)
@@ -1461,88 +1001,6 @@ bool CPVRManager::UpdateItem(CFileItem& item)
return false;
}
-bool CPVRManager::StartPlayback(const CPVRChannelPtr &channel, bool bMinimised /* = false */)
-{
- CMediaSettings::GetInstance().SetVideoStartWindowed(bMinimised);
-
- CFileItemList *l = new CFileItemList; //don't delete,
- l->Add(std::make_shared<CFileItem>(channel));
- CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, -1, -1, static_cast<void*>(l));
-
- CLog::Log(LOGNOTICE, "PVRManager - %s - started playback on channel '%s'",
- __FUNCTION__, channel->ChannelName().c_str());
- return true;
-}
-
-bool CPVRManager::StartPlayback(PlaybackType type /* = PlaybackTypeAny */)
-{
- bool bIsRadio(false);
- bool bReturn(false);
- bool bIsPlaying(false);
- CFileItemPtr channel;
-
- // check if the desired PlaybackType is already playing,
- // and if not, try to grab the last played channel of this type
- switch (type)
- {
- case PlaybackTypeRadio:
- if (IsPlayingRadio())
- bIsPlaying = true;
- else
- channel = m_channelGroups->GetGroupAllRadio()->GetLastPlayedChannel();
- bIsRadio = true;
- break;
-
- case PlaybackTypeTv:
- if (IsPlayingTV())
- bIsPlaying = true;
- else
- channel = m_channelGroups->GetGroupAllTV()->GetLastPlayedChannel();
- break;
-
- default:
- if (IsPlaying())
- bIsPlaying = true;
- else
- channel = m_channelGroups->GetLastPlayedChannel();
- }
-
- // we're already playing? Then nothing to do
- if (bIsPlaying)
- return true;
-
- // if we have a last played channel, start playback
- if (channel && channel->HasPVRChannelInfoTag())
- {
- bReturn = StartPlayback(channel->GetPVRChannelInfoTag(), false);
- }
- else
- {
- // if we don't, find the active channel group of the demanded type and play it's first channel
- CPVRChannelGroupPtr channelGroup = GetPlayingGroup(bIsRadio);
- if (channelGroup)
- {
- // try to start playback of first channel in this group
- std::vector<PVRChannelGroupMember> groupMembers(channelGroup->GetMembers());
- if (!groupMembers.empty())
- bReturn = StartPlayback((*groupMembers.begin()).channel, false);
- }
- }
-
- if (!bReturn)
- {
- CLog::Log(LOGNOTICE, "PVRManager - %s - could not determine %s channel to start playback with. No last played channel found, and first channel of active group could also not be determined.", __FUNCTION__, bIsRadio ? "radio": "tv");
-
- std::string msg = StringUtils::Format(g_localizeStrings.Get(19035).c_str(), g_localizeStrings.Get(bIsRadio ? 19021 : 19020).c_str()); // RADIO/TV could not be played. Check the log for details.
- CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
- g_localizeStrings.Get(19166), // PVR information
- msg);
- }
-
- return bReturn;
-}
-
-
bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPreview)
{
assert(channel.get());
@@ -1866,17 +1324,6 @@ bool CPVRManager::IsPlayingRecording(void) const
return IsStarted() && m_addons->IsPlayingRecording();
}
-bool CPVRManager::IsRunningChannelScan(void) const
-{
- return IsStarted() && m_addons->IsRunningChannelScan();
-}
-
-void CPVRManager::StartChannelScan(void)
-{
- if (IsStarted())
- m_addons->StartChannelScan();
-}
-
void CPVRManager::SearchMissingChannelIcons(void)
{
if (IsStarted() && m_channelGroups)
@@ -1910,7 +1357,8 @@ void CPVRManager::TriggerChannelGroupsUpdate(void)
void CPVRManager::TriggerSearchMissingChannelIcons(void)
{
- CJobManager::GetInstance().AddJob(new CPVRSearchMissingChannelIconsJob(), NULL);
+ if (IsStarted())
+ CJobManager::GetInstance().AddJob(new CPVRSearchMissingChannelIconsJob(), NULL);
}
void CPVRManager::ConnectionStateChange(CPVRClient *client, std::string connectString, PVR_CONNECTION_STATE state, std::string message)
@@ -1952,12 +1400,6 @@ bool CPVRClientConnectionJob::DoWork(void)
return true;
}
-bool CPVRSetRecordingOnChannelJob::DoWork(void)
-{
- g_PVRManager.SetRecordingOnChannel(m_channel, m_bOnOff);
- return true;
-}
-
bool CPVRManager::CreateChannelEpgs(void)
{
if (EpgsCreated())
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index 891c3376fb..3ecface1be 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -22,7 +22,6 @@
#include "FileItem.h"
#include "addons/kodi-addon-dev-kit/include/kodi/xbmc_pvr_types.h"
#include "interfaces/IAnnouncer.h"
-#include "settings/lib/ISettingCallback.h"
#include "threads/Event.h"
#include "threads/Thread.h"
#include "utils/EventStream.h"
@@ -62,13 +61,6 @@ namespace PVR
class CPVRDatabase;
class CGUIWindowPVRCommon;
- enum PlaybackType
- {
- PlaybackTypeAny = 0,
- PlaybackTypeTv,
- PlaybackTypeRadio
- };
-
enum ContinueLastChannelOnStartup
{
CONTINUE_LAST_CHANNEL_OFF = 0,
@@ -102,7 +94,7 @@ namespace PVR
bool m_bStopped;
};
- class CPVRManager : public ISettingCallback, private CThread, public Observable, public ANNOUNCEMENT::IAnnouncer
+ class CPVRManager : private CThread, public Observable, public ANNOUNCEMENT::IAnnouncer
{
friend class CPVRClients;
@@ -139,9 +131,6 @@ namespace PVR
*/
static CPVRManager &GetInstance();
- virtual void OnSettingChanged(const CSetting *setting) override;
- virtual void OnSettingAction(const CSetting *setting) override;
-
/*!
* @brief Get the channel groups container.
* @return The groups container.
@@ -177,6 +166,11 @@ namespace PVR
void Reinit(void);
/*!
+ * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data.
+ */
+ void Start();
+
+ /*!
* @brief Stop PVRManager.
*/
void Stop(void);
@@ -226,12 +220,6 @@ namespace PVR
void ShowPlayerInfo(int iTimeout);
/*!
- * @brief Reset the TV database to it's initial state and delete all the data inside.
- * @param bResetEPGOnly True to only reset the EPG database, false to reset both PVR and EPG.
- */
- void ResetDatabase(bool bResetEPGOnly = false);
-
- /*!
* @brief Check if a TV channel, radio channel or recording is playing.
* @return True if it's playing, false otherwise.
*/
@@ -347,27 +335,12 @@ namespace PVR
bool OpenRecordedStream(const CPVRRecordingPtr &tag);
/*!
- * @brief Start recording on a given channel if it is not already recording, stop if it is.
- * @param channel the channel to start/stop recording.
- * @return True if the recording was started or stopped successfully, false otherwise.
- */
- bool ToggleRecordingOnChannel(unsigned int iChannelId);
-
- /*!
* @brief Start or stop recording on the channel that is currently being played.
* @param bOnOff True to start recording, false to stop.
*/
void StartRecordingOnPlayingChannel(bool bOnOff);
/*!
- * @brief Start or stop recording on a given channel.
- * @param channel the channel to start/stop recording.
- * @param bOnOff True to start recording, false to stop.
- * @return True if the recording was started or stopped successfully, false otherwise.
- */
- bool SetRecordingOnChannel(const CPVRChannelPtr &channel, bool bOnOff);
-
- /*!
* @brief Check whether there are active recordings.
* @return True if there are active recordings, false otherwise.
*/
@@ -473,21 +446,6 @@ namespace PVR
int GetStartTime(void) const;
/*!
- * @brief Start playback on a channel.
- * @param channel The channel to start to play.
- * @param bMinimised If true, playback starts minimised, otherwise in fullscreen.
- * @return True if playback was started, false otherwise.
- */
- bool StartPlayback(const CPVRChannelPtr &channel, bool bMinimised = false);
-
- /*!
- * @brief Start playback of the last used channel, and if it fails use first channel in the current channelgroup.
- * @param type The type of playback to be started (any, radio, tv). See PlaybackType enum
- * @return True if playback was started, false otherwise.
- */
- bool StartPlayback(PlaybackType type = PlaybackTypeAny);
-
- /*!
* @brief Update the current playing file in the guiinfomanager and application.
*/
void UpdateCurrentFile(void);
@@ -516,28 +474,11 @@ namespace PVR
bool IsPlayingRecording(void) const;
/*!
- * @return True when a channel scan is currently running, false otherwise.
- */
- bool IsRunningChannelScan(void) const;
-
- /*!
- * @brief Open a selection dialog and start a channel scan on the selected client.
- */
- void StartChannelScan(void);
-
- /*!
* @brief Try to find missing channel icons automatically
*/
void SearchMissingChannelIcons(void);
/*!
- * @brief Check if channel is parental locked. Ask for PIN if necessary.
- * @param channel The channel to open.
- * @return True if channel is unlocked (by default or PIN unlocked), false otherwise.
- */
- bool CheckParentalLock(const CPVRChannelPtr &channel);
-
- /*!
* @brief Check if parental lock is overridden at the given moment.
* @param channel The channel to open.
* @return True if parental lock is overridden, false otherwise.
@@ -545,11 +486,9 @@ namespace PVR
bool IsParentalLocked(const CPVRChannelPtr &channel);
/*!
- * @brief Open Numeric dialog to check for parental PIN.
- * @param strTitle Override the title of the dialog if set.
- * @return True if entered PIN was correct, false otherwise.
+ * @brief Restart the parental timer.
*/
- bool CheckParentalPIN(const std::string& strTitle = "");
+ void RestartParentalTimer();
/*!
* @brief Executes "pvrpowermanagement.setwakeupcmd"
@@ -613,11 +552,6 @@ namespace PVR
protected:
/*!
- * @brief Start the PVRManager, which loads all PVR data and starts some threads to update the PVR data.
- */
- void Start();
-
- /*!
* @brief PVR update and control thread.
*/
virtual void Process(void) override;
@@ -663,10 +597,9 @@ namespace PVR
bool ChannelUpDown(unsigned int *iNewChannelNumber, bool bPreview, bool bUp);
/*!
- * @brief Continue playback on the last channel if it was stored in the database.
- * @return True if playback was continued, false otherwise.
+ * @brief Continue playback on the last played channel.
*/
- bool ContinueLastChannel(void);
+ void TriggerContinueLastChannel(void);
enum ManagerState
{
@@ -719,8 +652,8 @@ namespace PVR
class CPVRStartupJob : public CJob
{
public:
- CPVRStartupJob(void) {}
- virtual ~CPVRStartupJob() {}
+ CPVRStartupJob(void) = default;
+ virtual ~CPVRStartupJob() = default;
virtual const char *GetType() const { return "pvr-startup"; }
virtual bool DoWork();
@@ -729,8 +662,8 @@ namespace PVR
class CPVREpgsCreateJob : public CJob
{
public:
- CPVREpgsCreateJob(void) {}
- virtual ~CPVREpgsCreateJob() {}
+ CPVREpgsCreateJob(void) = default;
+ virtual ~CPVREpgsCreateJob() = default;
virtual const char *GetType() const { return "pvr-create-epgs"; }
virtual bool DoWork();
@@ -739,8 +672,8 @@ namespace PVR
class CPVRRecordingsUpdateJob : public CJob
{
public:
- CPVRRecordingsUpdateJob(void) {}
- virtual ~CPVRRecordingsUpdateJob() {}
+ CPVRRecordingsUpdateJob(void) = default;
+ virtual ~CPVRRecordingsUpdateJob() = default;
virtual const char *GetType() const { return "pvr-update-recordings"; }
virtual bool DoWork();
@@ -749,8 +682,8 @@ namespace PVR
class CPVRTimersUpdateJob : public CJob
{
public:
- CPVRTimersUpdateJob(void) {}
- virtual ~CPVRTimersUpdateJob() {}
+ CPVRTimersUpdateJob(void) = default;
+ virtual ~CPVRTimersUpdateJob() = default;
virtual const char *GetType() const { return "pvr-update-timers"; }
virtual bool DoWork();
@@ -759,8 +692,8 @@ namespace PVR
class CPVRChannelsUpdateJob : public CJob
{
public:
- CPVRChannelsUpdateJob(void) {}
- virtual ~CPVRChannelsUpdateJob() {}
+ CPVRChannelsUpdateJob(void) = default;
+ virtual ~CPVRChannelsUpdateJob() = default;
virtual const char *GetType() const { return "pvr-update-channels"; }
virtual bool DoWork();
@@ -769,8 +702,8 @@ namespace PVR
class CPVRChannelGroupsUpdateJob : public CJob
{
public:
- CPVRChannelGroupsUpdateJob(void) {}
- virtual ~CPVRChannelGroupsUpdateJob() {}
+ CPVRChannelGroupsUpdateJob(void) = default;
+ virtual ~CPVRChannelGroupsUpdateJob() = default;
virtual const char *GetType() const { return "pvr-update-channelgroups"; }
virtual bool DoWork();
@@ -780,7 +713,7 @@ namespace PVR
{
public:
CPVRChannelSwitchJob(const CFileItemPtr &previous, const CFileItemPtr & next) : m_previous(previous), m_next(next) {}
- virtual ~CPVRChannelSwitchJob() {}
+ virtual ~CPVRChannelSwitchJob() = default;
virtual const char *GetType() const { return "pvr-channel-switch"; }
virtual bool DoWork();
@@ -792,8 +725,8 @@ namespace PVR
class CPVRSearchMissingChannelIconsJob : public CJob
{
public:
- CPVRSearchMissingChannelIconsJob(void) {}
- virtual ~CPVRSearchMissingChannelIconsJob() {}
+ CPVRSearchMissingChannelIconsJob(void) = default;
+ virtual ~CPVRSearchMissingChannelIconsJob() = default;
virtual const char *GetType() const { return "pvr-search-missing-channel-icons"; }
bool DoWork();
@@ -804,7 +737,7 @@ namespace PVR
public:
CPVRClientConnectionJob(CPVRClient *client, std::string connectString, PVR_CONNECTION_STATE state, std::string message)
: m_client(client), m_connectString(connectString), m_state(state), m_message(message) {}
- virtual ~CPVRClientConnectionJob() {}
+ virtual ~CPVRClientConnectionJob() = default;
virtual const char *GetType() const { return "pvr-client-connection"; }
virtual bool DoWork();
@@ -814,18 +747,4 @@ namespace PVR
PVR_CONNECTION_STATE m_state;
std::string m_message;
};
-
- class CPVRSetRecordingOnChannelJob : public CJob
- {
- public:
- CPVRSetRecordingOnChannelJob(const CPVRChannelPtr &channel, bool bOnOff) :
- m_channel(channel), m_bOnOff(bOnOff) {}
- virtual ~CPVRSetRecordingOnChannelJob() {}
- virtual const char *GetType() const { return "pvr-set-recording-on-channel"; }
-
- bool DoWork();
- private:
- CPVRChannelPtr m_channel;
- bool m_bOnOff;
- };
}
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index 9bd717a529..1bd94dc84f 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -27,21 +27,14 @@
#include "Application.h"
#include "ServiceBroker.h"
#include "cores/IPlayer.h"
-#include "dialogs/GUIDialogOK.h"
-#include "dialogs/GUIDialogSelect.h"
-#include "dialogs/GUIDialogKaiToast.h"
-#include "events/EventLog.h"
-#include "events/NotificationEvent.h"
-#include "guilib/GUIWindowManager.h"
-#include "GUIUserMessages.h"
#include "messaging/ApplicationMessenger.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
#include "pvr/channels/PVRChannelGroups.h"
+#include "pvr/PVRJobs.h"
#include "pvr/PVRManager.h"
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/timers/PVRTimers.h"
#include "utils/log.h"
-#include "utils/Variant.h"
using namespace ADDON;
using namespace PVR;
@@ -54,7 +47,6 @@ using namespace KODI::MESSAGING;
#define PVR_CLIENT_AVAHI_SLEEP_TIME_MS (250)
CPVRClients::CPVRClients(void) :
- m_bChannelScanRunning(false),
m_bIsSwitchingChannels(false),
m_playingClientId(-EINVAL),
m_bIsPlayingLiveTV(false),
@@ -153,7 +145,6 @@ void CPVRClients::Unload(void)
CSingleLock lock(m_critSection);
/* reset class properties */
- m_bChannelScanRunning = false;
m_bIsPlayingLiveTV = false;
m_bIsPlayingRecording = false;
m_strPlayingClientName = "";
@@ -859,80 +850,7 @@ bool CPVRClients::HasMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat)
iClientID = GetPlayingClientID();
PVR_CLIENT client;
- return (GetCreatedClient(iClientID, client) &&
- client->HaveMenuHooks(cat));
-}
-
-void CPVRClients::ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CFileItem *item)
-{
- // get client id
- if (iClientID < 0 && cat == PVR_MENUHOOK_SETTING)
- {
- PVR_CLIENTMAP clients;
- GetCreatedClients(clients);
-
- if (clients.size() == 1)
- {
- iClientID = clients.begin()->first;
- }
- else if (clients.size() > 1)
- {
- // have user select client
- CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
- pDialog->Reset();
- pDialog->SetHeading(CVariant{19196});
-
- for (const auto client : clients)
- {
- pDialog->Add(client.second->GetBackendName());
- }
- pDialog->Open();
-
- int selection = pDialog->GetSelectedItem();
- if (selection >= 0)
- {
- auto client = clients.begin();
- std::advance(client, selection);
- iClientID = client->first;
- }
- }
- }
-
- if (iClientID < 0)
- iClientID = GetPlayingClientID();
-
- PVR_CLIENT client;
- if (GetCreatedClient(iClientID, client) && client->HaveMenuHooks(cat))
- {
- PVR_MENUHOOKS *hooks = client->GetMenuHooks();
- std::vector<int> hookIDs;
- int selection = 0;
-
- CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
- pDialog->Reset();
- pDialog->SetHeading(CVariant{19196});
- for (unsigned int i = 0; i < hooks->size(); ++i)
- {
- if (hooks->at(i).category == cat || hooks->at(i).category == PVR_MENUHOOK_ALL)
- {
- pDialog->Add(g_localizeStrings.GetAddonString(client->ID(), hooks->at(i).iLocalizedStringId));
- hookIDs.push_back(i);
- }
- }
- if (hookIDs.size() > 1)
- {
- pDialog->Open();
- selection = pDialog->GetSelectedItem();
- }
- if (selection >= 0)
- client->CallMenuHook(hooks->at(hookIDs.at(selection)), item);
- }
-}
-
-bool CPVRClients::IsRunningChannelScan(void) const
-{
- CSingleLock lock(m_critSection);
- return m_bChannelScanRunning;
+ return (GetCreatedClient(iClientID, client) && client->HasMenuHooks(cat));
}
std::vector<PVR_CLIENT> CPVRClients::GetClientsSupportingChannelScan(void) const
@@ -950,57 +868,6 @@ std::vector<PVR_CLIENT> CPVRClients::GetClientsSupportingChannelScan(void) const
return possibleScanClients;
}
-void CPVRClients::StartChannelScan(void)
-{
- PVR_CLIENT scanClient;
- CSingleLock lock(m_critSection);
- std::vector<PVR_CLIENT> possibleScanClients = GetClientsSupportingChannelScan();
- m_bChannelScanRunning = true;
-
- /* multiple clients found */
- if (possibleScanClients.size() > 1)
- {
- CGUIDialogSelect* pDialog= (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
-
- pDialog->Reset();
- pDialog->SetHeading(CVariant{19119});
-
- for (const auto client : possibleScanClients)
- pDialog->Add(client->GetFriendlyName());
-
- pDialog->Open();
-
- int selection = pDialog->GetSelectedItem();
- if (selection >= 0)
- scanClient = possibleScanClients[selection];
- }
- /* one client found */
- else if (possibleScanClients.size() == 1)
- {
- scanClient = possibleScanClients[0];
- }
- /* no clients found */
- else if (!scanClient)
- {
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19192});
- return;
- }
-
- /* start the channel scan */
- CLog::Log(LOGNOTICE,"PVR - %s - starting to scan for channels on client %s",
- __FUNCTION__, scanClient->GetFriendlyName().c_str());
- long perfCnt = XbmcThreads::SystemClockMillis();
-
- /* do the scan */
- if (scanClient->StartChannelScan() != PVR_ERROR_NO_ERROR)
- /* an error occured */
- CGUIDialogOK::ShowAndGetInput(CVariant{19111}, CVariant{19193});
-
- CLog::Log(LOGNOTICE, "PVRManager - %s - channel scan finished after %li.%li seconds",
- __FUNCTION__, (XbmcThreads::SystemClockMillis()-perfCnt)/1000, (XbmcThreads::SystemClockMillis()-perfCnt)%1000);
- m_bChannelScanRunning = false;
-}
-
std::vector<PVR_CLIENT> CPVRClients::GetClientsSupportingChannelSettings(bool bRadio) const
{
std::vector<PVR_CLIENT> possibleSettingsClients;
@@ -1017,8 +884,7 @@ std::vector<PVR_CLIENT> CPVRClients::GetClientsSupportingChannelSettings(bool bR
return possibleSettingsClients;
}
-
-bool CPVRClients::OpenDialogChannelAdd(const CPVRChannelPtr &channel)
+PVR_ERROR CPVRClients::OpenDialogChannelAdd(const CPVRChannelPtr &channel)
{
PVR_ERROR error = PVR_ERROR_UNKNOWN;
@@ -1028,16 +894,10 @@ bool CPVRClients::OpenDialogChannelAdd(const CPVRChannelPtr &channel)
else
CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel->ClientID());
- if (error == PVR_ERROR_NOT_IMPLEMENTED)
- {
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038});
- return true;
- }
-
- return error == PVR_ERROR_NO_ERROR;
+ return error;
}
-bool CPVRClients::OpenDialogChannelSettings(const CPVRChannelPtr &channel)
+PVR_ERROR CPVRClients::OpenDialogChannelSettings(const CPVRChannelPtr &channel)
{
PVR_ERROR error = PVR_ERROR_UNKNOWN;
@@ -1047,16 +907,10 @@ bool CPVRClients::OpenDialogChannelSettings(const CPVRChannelPtr &channel)
else
CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel->ClientID());
- if (error == PVR_ERROR_NOT_IMPLEMENTED)
- {
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038});
- return true;
- }
-
- return error == PVR_ERROR_NO_ERROR;
+ return error;
}
-bool CPVRClients::DeleteChannel(const CPVRChannelPtr &channel)
+PVR_ERROR CPVRClients::DeleteChannel(const CPVRChannelPtr &channel)
{
PVR_ERROR error = PVR_ERROR_UNKNOWN;
@@ -1066,13 +920,7 @@ bool CPVRClients::DeleteChannel(const CPVRChannelPtr &channel)
else
CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel->ClientID());
- if (error == PVR_ERROR_NOT_IMPLEMENTED)
- {
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038});
- return true;
- }
-
- return error == PVR_ERROR_NO_ERROR;
+ return error;
}
bool CPVRClients::RenameChannel(const CPVRChannelPtr &channel)
@@ -1142,8 +990,8 @@ void CPVRClients::UpdateAddons(void)
CLog::Log(LOGERROR, "%s - failed to create add-on %s, status = %d", __FUNCTION__, addon->Name().c_str(), status);
if (status == ADDON_STATUS_PERMANENT_FAILURE)
{
- CGUIDialogOK::ShowAndGetInput(CVariant{24070}, CVariant{16029});
CAddonMgr::GetInstance().DisableAddon(addon->ID());
+ CJobManager::GetInstance().AddJob(new CPVREventlogJob(true, true, addon->Name(), g_localizeStrings.Get(24070), addon->Icon()), nullptr);
}
}
}
@@ -1541,13 +1389,7 @@ void CPVRClients::ConnectionStateChange(CPVRClient *client, std::string &strConn
strMsg = g_localizeStrings.Get(iMsg);
// Notify user.
- if (bNotify)
- CGUIDialogKaiToast::QueueNotification(bError ? CGUIDialogKaiToast::Error : CGUIDialogKaiToast::Info, client->Name().c_str(),
- strMsg, 5000, true);
-
- // Write event log entry.
- CEventLog::GetInstance().Add(EventPtr(new CNotificationEvent(client->Name(), strMsg, client->Icon(),
- bError ? EventLevel::Error : EventLevel::Information)));
+ CJobManager::GetInstance().AddJob(new CPVREventlogJob(bNotify, bError, client->Name(), strMsg, client->Icon()), nullptr);
if (newState == PVR_CONNECTION_STATE_CONNECTED)
{
diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h
index 310d655ee3..39283fe74c 100644
--- a/xbmc/pvr/addons/PVRClients.h
+++ b/xbmc/pvr/addons/PVRClients.h
@@ -79,15 +79,35 @@ namespace PVR
//@{
/*!
- * @brief Check whether a client ID points to a valid and connected add-on.
+ * @brief Check whether a given client ID points to a created pvr client.
* @param iClientId The client ID.
- * @return True when the client ID is valid and connected, false otherwise.
+ * @return True if the the client ID represents a created client, false otherwise.
*/
bool IsCreatedClient(int iClientId) const;
+ /*!
+ * @brief Check whether an given addon instance is a created pvr client.
+ * @param addon The addon.
+ * @return True if the the addon represents a created client, false otherwise.
+ */
bool IsCreatedClient(const ADDON::AddonPtr &addon);
/*!
+ * @brief Get the instance of the client, if it's created.
+ * @param iClientId The id of the client to get.
+ * @param addon The client.
+ * @return True on success, false otherwise.
+ */
+ bool GetCreatedClient(int iClientId, PVR_CLIENT &addon) const;
+
+ /*!
+ * @brief Get all created clients.
+ * @param clients Store the active clients in this map.
+ * @return The amount of added clients.
+ */
+ int GetCreatedClients(PVR_CLIENTMAP &clients) const;
+
+ /*!
* @brief Restart a single client add-on.
* @param addon The add-on to restart.
* @param bDataChanged True if the client's data changed, false otherwise (unused).
@@ -565,29 +585,12 @@ namespace PVR
*/
bool HasMenuHooks(int iClientId, PVR_MENUHOOK_CAT cat);
- /*!
- * @brief Open selection and progress PVR actions.
- * @param iClientId The ID of the client to process the menu entries for. Process the menu entries for the active channel if iClientId < 0.
- * @param item The selected file item for which the hook was called.
- */
- void ProcessMenuHooks(int iClientID, PVR_MENUHOOK_CAT cat, const CFileItem *item);
-
//@}
/*! @name Channel scan methods */
//@{
/*!
- * @return True when a channel scan is currently running, false otherwise.
- */
- bool IsRunningChannelScan(void) const;
-
- /*!
- * @brief Open a selection dialog and start a channel scan on the selected client.
- */
- void StartChannelScan(void);
-
- /*!
* @return All clients that support channel scanning.
*/
std::vector<PVR_CLIENT> GetClientsSupportingChannelScan(void) const;
@@ -605,23 +608,23 @@ namespace PVR
/*!
* @brief Open addon settings dialog to add a channel
* @param channel The channel to edit.
- * @return True if the edit was successful, false otherwise.
+ * @return PVR_ERROR_NO_ERROR if the dialog was opened successfully, the respective error code otherwise.
*/
- bool OpenDialogChannelAdd(const CPVRChannelPtr &channel);
+ PVR_ERROR OpenDialogChannelAdd(const CPVRChannelPtr &channel);
/*!
* @brief Open addon settings dialog to related channel
* @param channel The channel to edit.
- * @return True if the edit was successful, false otherwise.
+ * @return PVR_ERROR_NO_ERROR if the dialog was opened successfully, the respective error code otherwise.
*/
- bool OpenDialogChannelSettings(const CPVRChannelPtr &channel);
+ PVR_ERROR OpenDialogChannelSettings(const CPVRChannelPtr &channel);
/*!
* @brief Inform addon to delete channel
* @param channel The channel to delete.
- * @return True if it was successful, false otherwise.
+ * @return PVR_ERROR_NO_ERROR if the channel was deleted successfully, the respective error code otherwise.
*/
- bool DeleteChannel(const CPVRChannelPtr &channel);
+ PVR_ERROR DeleteChannel(const CPVRChannelPtr &channel);
/*!
* @brief Request the client to rename given channel
@@ -685,21 +688,6 @@ namespace PVR
bool GetClient(int iClientId, PVR_CLIENT &addon) const;
/*!
- * @brief Get the instance of the client, if it's created.
- * @param iClientId The id of the client to get.
- * @param addon The client.
- * @return True if the client is connected, false otherwise.
- */
- bool GetCreatedClient(int iClientId, PVR_CLIENT &addon) const;
-
- /*!
- * @brief Get all created clients.
- * @param clients Store the active clients in this map.
- * @return The amount of added clients.
- */
- int GetCreatedClients(PVR_CLIENTMAP &clients) const;
-
- /*!
* @brief Check whether a client is registered.
* @param client The client to check.
* @return True if this client is registered, false otherwise.
@@ -710,7 +698,6 @@ namespace PVR
int GetClientId(const ADDON::AddonPtr &client) const;
- bool m_bChannelScanRunning; /*!< true when a channel scan is currently running, false otherwise */
bool m_bIsSwitchingChannels; /*!< true while switching channels */
int m_playingClientId; /*!< the ID of the client that is currently playing */
bool m_bIsPlayingLiveTV;
diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp
index 8eee72284e..9d687bc120 100644
--- a/xbmc/pvr/channels/PVRChannel.cpp
+++ b/xbmc/pvr/channels/PVRChannel.cpp
@@ -376,6 +376,24 @@ bool CPVRChannel::SetLastWatched(time_t iLastWatched)
return false;
}
+bool CPVRChannel::SetWasPlayingOnLastQuit(bool bSet)
+{
+ const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase());
+ if (database)
+ return database->SetWasPlayingOnLastQuit(*this, bSet);
+
+ return false;
+}
+
+bool CPVRChannel::SetWasPlayingOnLastQuit(bool bSet, bool& bWasPlaying)
+{
+ const CPVRDatabasePtr database(g_PVRManager.GetTVDatabase());
+ if (database)
+ return database->SetWasPlayingOnLastQuit(*this, bSet, bWasPlaying);
+
+ return false;
+}
+
bool CPVRChannel::IsEmpty() const
{
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h
index 31a172d414..0b4170c9c9 100644
--- a/xbmc/pvr/channels/PVRChannel.h
+++ b/xbmc/pvr/channels/PVRChannel.h
@@ -230,6 +230,21 @@ namespace PVR
bool SetLastWatched(time_t iLastWatched);
/*!
+ * @brief Sets the 'was playing on last app quit' flag for a channel.
+ * @param bSet True to set the flag, false to reset the flag
+ * @return True if the operation was successful, false otherwise
+ */
+ bool SetWasPlayingOnLastQuit(bool bSet);
+
+ /*!
+ * @brief Sets the 'was playing on last app quit' flag for a channel.
+ * @param bSet True to set the flag, false to reset the flag
+ * @param bWasPlaying on return contains the previous value of the flag
+ * @return True if the operation was successful, false otherwise
+ */
+ bool SetWasPlayingOnLastQuit(bool bSet, bool& bWasPlaying);
+
+ /*!
* @brief True if this channel has no file or stream name
* @return True if this channel has no file or stream name
*/
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
index f6acd5e064..e0cd1ff430 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -19,7 +19,6 @@
*/
#include "URL.h"
-#include "dialogs/GUIDialogOK.h"
#include "guilib/LocalizeStrings.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
index e8598956b3..d3277a76c1 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
@@ -36,6 +36,7 @@
#include "utils/StringUtils.h"
#include "utils/Variant.h"
+#include "pvr/PVRGUIActions.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -291,7 +292,7 @@ bool CGUIDialogPVRChannelManager::OnClickButtonRadioParentalLocked(CGUIMessage &
bool selected(msg.GetParam1() == 1);
// ask for PIN first
- if (!g_PVRManager.CheckParentalPIN(g_localizeStrings.Get(19262).c_str()))
+ if (!CPVRGUIActions::GetInstance().CheckParentalPIN())
{ // failed - reset to previous
SET_CONTROL_SELECTED(GetID(), RADIOBUTTON_PARENTAL_LOCK, !selected);
return false;
@@ -469,10 +470,13 @@ bool CGUIDialogPVRChannelManager::OnClickButtonNewChannel()
channel->SetEPGEnabled(g_PVRClients->SupportsEPG(iClientID));
channel->SetClientID(iClientID);
- if (g_PVRClients->OpenDialogChannelAdd(channel))
+ PVR_ERROR ret = g_PVRClients->OpenDialogChannelAdd(channel);
+ if (ret == PVR_ERROR_NO_ERROR)
Update();
+ else if (ret == PVR_ERROR_NOT_IMPLEMENTED)
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038}); // "Information", "Not supported by the PVR backend."
else
- CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // Add-on error;Check the log file for details.
+ CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // "Add-on error", "Check the log for more information about this message."
}
return true;
}
@@ -598,8 +602,11 @@ bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON
}
else if (button == CONTEXT_BUTTON_SETTINGS)
{
- if (!g_PVRClients->OpenDialogChannelSettings(pItem->GetPVRChannelInfoTag()))
- CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // Add-on error;Check the log file for details.
+ PVR_ERROR ret = g_PVRClients->OpenDialogChannelSettings(pItem->GetPVRChannelInfoTag());
+ if (ret == PVR_ERROR_NOT_IMPLEMENTED)
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038}); // "Information", "Not supported by the PVR backend."
+ else if (ret != PVR_ERROR_NO_ERROR)
+ CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // "Add-on error", "Check the log for more information about this message."
}
else if (button == CONTEXT_BUTTON_DELETE)
{
@@ -614,15 +621,18 @@ bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON
if (pDialog->IsConfirmed())
{
CPVRChannelPtr channel = pItem->GetPVRChannelInfoTag();
- if (g_PVRClients->DeleteChannel(channel))
+ PVR_ERROR ret = g_PVRClients->DeleteChannel(channel);
+ if (ret == PVR_ERROR_NO_ERROR)
{
g_PVRChannelGroups->GetGroupAll(channel->IsRadio())->RemoveFromGroup(channel);
m_channelItems->Remove(m_iSelected);
m_viewControl.SetItems(*m_channelItems);
Renumber();
}
+ else if (ret == PVR_ERROR_NOT_IMPLEMENTED)
+ CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19038}); // "Information", "Not supported by the PVR backend."
else
- CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // Add-on error;Check the log file for details.
+ CGUIDialogOK::ShowAndGetInput(CVariant{2103}, CVariant{16029}); // "Add-on error", "Check the log for more information about this message."
}
}
else if (button == CONTEXT_BUTTON_EDIT_SOURCE)
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
index 10445f949b..3d0d8ffa65 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
@@ -149,7 +149,12 @@ void CGUIDialogPVRTimerSettings::SetTimer(const CPVRTimerInfoTagPtr &timer)
m_iPriority = m_timerInfoTag->m_iPriority;
m_iLifetime = m_timerInfoTag->m_iLifetime;
m_iMaxRecordings = m_timerInfoTag->m_iMaxRecordings;
- m_strDirectory = m_timerInfoTag->m_strDirectory;
+
+ if (m_bIsNewTimer && m_timerInfoTag->m_strDirectory.empty() && m_timerType->SupportsRecordingFolders())
+ m_strDirectory = m_strTitle;
+ else
+ m_strDirectory = m_timerInfoTag->m_strDirectory;
+
m_iRecordingGroup = m_timerInfoTag->m_iRecordingGroup;
InitializeChannelsList();
diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp
index e81603455d..d93846c13f 100644
--- a/xbmc/pvr/recordings/PVRRecording.cpp
+++ b/xbmc/pvr/recordings/PVRRecording.cpp
@@ -226,10 +226,8 @@ bool CPVRRecording::Delete(void)
{
PVR_ERROR error = g_PVRClients->DeleteRecording(*this);
if (error != PVR_ERROR_NO_ERROR)
- {
- DisplayError(error);
return false;
- }
+
OnDelete();
return true;
}
@@ -252,10 +250,7 @@ bool CPVRRecording::Undelete(void)
{
PVR_ERROR error = g_PVRClients->UndeleteRecording(*this);
if (error != PVR_ERROR_NO_ERROR)
- {
- DisplayError(error);
return false;
- }
return true;
}
@@ -265,10 +260,7 @@ bool CPVRRecording::Rename(const std::string &strNewName)
m_strTitle = StringUtils::Format("%s", strNewName.c_str());
PVR_ERROR error = g_PVRClients->RenameRecording(*this);
if (error != PVR_ERROR_NO_ERROR)
- {
- DisplayError(error);
return false;
- }
return true;
}
@@ -278,10 +270,7 @@ bool CPVRRecording::SetPlayCount(int count)
PVR_ERROR error;
if (g_PVRClients->SupportsRecordingPlayCount(m_iClientId) &&
!g_PVRClients->SetRecordingPlayCount(*this, count, &error))
- {
- DisplayError(error);
return false;
- }
return CVideoInfoTag::SetPlayCount(count);
}
@@ -291,10 +280,7 @@ bool CPVRRecording::IncrementPlayCount()
PVR_ERROR error;
if (g_PVRClients->SupportsRecordingPlayCount(m_iClientId) &&
!g_PVRClients->SetRecordingPlayCount(*this, CVideoInfoTag::GetPlayCount(), &error))
- {
- DisplayError(error);
return false;
- }
return CVideoInfoTag::IncrementPlayCount();
}
@@ -304,10 +290,7 @@ bool CPVRRecording::SetResumePoint(const CBookmark &resumePoint)
PVR_ERROR error;
if (g_PVRClients->SupportsLastPlayedPosition(m_iClientId) &&
!g_PVRClients->SetRecordingLastPlayedPosition(*this, lrint(resumePoint.timeInSeconds), &error))
- {
- DisplayError(error);
return false;
- }
return CVideoInfoTag::SetResumePoint(resumePoint);
}
@@ -317,10 +300,7 @@ bool CPVRRecording::SetResumePoint(double timeInSeconds, double totalTimeInSecon
PVR_ERROR error;
if (g_PVRClients->SupportsLastPlayedPosition(m_iClientId) &&
!g_PVRClients->SetRecordingLastPlayedPosition(*this, lrint(timeInSeconds), &error))
- {
- DisplayError(error);
return false;
- }
return CVideoInfoTag::SetResumePoint(timeInSeconds, totalTimeInSeconds, playerState);
}
@@ -330,11 +310,7 @@ CBookmark CPVRRecording::GetResumePoint() const
if (g_PVRClients->SupportsLastPlayedPosition(m_iClientId))
{
int pos = g_PVRClients->GetRecordingLastPlayedPosition(*this);
- if (pos < 0)
- {
- DisplayError(PVR_ERROR_SERVER_ERROR);
- }
- else
+ if (pos >= 0)
{
CBookmark resumePoint(CVideoInfoTag::GetResumePoint());
resumePoint.timeInSeconds = pos;
@@ -374,18 +350,6 @@ std::vector<PVR_EDL_ENTRY> CPVRRecording::GetEdl() const
return std::vector<PVR_EDL_ENTRY>();
}
-void CPVRRecording::DisplayError(PVR_ERROR err) const
-{
- if (err == PVR_ERROR_SERVER_ERROR)
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19111}); /* print info dialog "Server error!" */
- else if (err == PVR_ERROR_REJECTED)
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19068}); /* print info dialog "Couldn't delete recording!" */
- else
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19147}); /* print info dialog "Unknown error!" */
-
- return;
-}
-
void CPVRRecording::Update(const CPVRRecording &tag)
{
m_strRecordingId = tag.m_strRecordingId;
diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h
index b5d8c6bb5d..3267453ca8 100644
--- a/xbmc/pvr/recordings/PVRRecording.h
+++ b/xbmc/pvr/recordings/PVRRecording.h
@@ -94,7 +94,7 @@ namespace PVR
bool operator ==(const CPVRRecording& right) const;
bool operator !=(const CPVRRecording& right) const;
- virtual void Serialize(CVariant& value) const;
+ void Serialize(CVariant& value) const override;
/*!
* @brief Reset this tag to it's initial state.
@@ -276,6 +276,5 @@ namespace PVR
bool m_bRadio; /*!< radio or tv recording */
void UpdatePath(void);
- void DisplayError(PVR_ERROR err) const;
};
}
diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.cpp b/xbmc/pvr/timers/PVRTimerInfoTag.cpp
index 51d7d0a9e9..4bfbf018a0 100644
--- a/xbmc/pvr/timers/PVRTimerInfoTag.cpp
+++ b/xbmc/pvr/timers/PVRTimerInfoTag.cpp
@@ -19,9 +19,7 @@
*/
#include "ServiceBroker.h"
-#include "dialogs/GUIDialogKaiToast.h"
#include "dialogs/GUIDialogOK.h"
-#include "dialogs/GUIDialogYesNo.h"
#include "epg/Epg.h"
#include "epg/EpgContainer.h"
#include "messaging/ApplicationMessenger.h"
diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp
index 6b3cc4d9ac..ffba81cfd7 100644
--- a/xbmc/pvr/timers/PVRTimers.cpp
+++ b/xbmc/pvr/timers/PVRTimers.cpp
@@ -25,21 +25,17 @@
#include <utility>
#include "ServiceBroker.h"
-#include "dialogs/GUIDialogKaiToast.h"
-#include "dialogs/GUIDialogOK.h"
#include "epg/EpgContainer.h"
-#include "events/EventLog.h"
-#include "events/NotificationEvent.h"
#include "FileItem.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/PVRJobs.h"
#include "pvr/PVRManager.h"
#include "settings/Settings.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
-#include "utils/Variant.h"
using namespace PVR;
using namespace EPG;
@@ -326,22 +322,27 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers, const std::vector<int>
g_PVRManager.SetChanged();
g_PVRManager.NotifyObservers(bAddedOrDeleted ? ObservableMessageTimersReset : ObservableMessageTimers);
- if (g_PVRManager.IsStarted())
+ if (!timerNotifications.empty() && g_PVRManager.IsStarted())
{
+ CPVREventlogJob *job = new CPVREventlogJob;
+
/* queue notifications / fill eventlog */
for (const auto &entry : timerNotifications)
{
- if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS))
- CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(19166), entry.second);
-
std::string strName;
g_PVRClients->GetClientAddonName(entry.first, strName);
std::string strIcon;
g_PVRClients->GetClientAddonIcon(entry.first, strIcon);
- CEventLog::GetInstance().Add(EventPtr(new CNotificationEvent(strName, entry.second, strIcon, EventLevel::Information)));
+ job->AddEvent(CServiceBroker::GetSettings().GetBool(CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS),
+ false, // info, no error
+ strName,
+ entry.second,
+ strIcon);
}
+
+ CJobManager::GetInstance().AddJob(job, nullptr);
}
}
@@ -677,22 +678,6 @@ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDele
bool CPVRTimers::AddTimer(const CPVRTimerInfoTagPtr &item)
{
- if (!item->m_channel && item->GetTimerType() && !item->GetTimerType()->IsEpgBasedTimerRule())
- {
- CLog::Log(LOGERROR, "PVRTimers - %s - no channel given", __FUNCTION__);
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19109}); // Couldn't save timer
- return false;
- }
-
- if (!g_PVRClients->SupportsTimers(item->m_iClientId))
- {
- CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19215});
- return false;
- }
-
- if (!g_PVRManager.CheckParentalLock(item->m_channel))
- return false;
-
return item->AddToClient();
}
diff --git a/xbmc/pvr/timers/PVRTimers.h b/xbmc/pvr/timers/PVRTimers.h
index 5519f6f541..0ffa7aa747 100644
--- a/xbmc/pvr/timers/PVRTimers.h
+++ b/xbmc/pvr/timers/PVRTimers.h
@@ -183,26 +183,26 @@ namespace PVR
/*!
* @brief Add a timer to the client. Doesn't add the timer to the container. The backend will do this.
- * @return True if it was sent correctly, false if not.
+ * @return True if timer add request was sent correctly, false if not.
*/
- static bool AddTimer(const CPVRTimerInfoTagPtr &item);
+ static bool AddTimer(const CPVRTimerInfoTagPtr &item);
/*!
* @brief Delete a timer on the client. Doesn't delete the timer from the container. The backend will do this.
* @param bDeleteRule Also delete the timer rule that scheduled the timer instead of single timer only.
- * @return True if it was sent correctly, false if not.
+ * @return True if timer delete request was sent correctly, false if not.
*/
static bool DeleteTimer(const CPVRTimerInfoTagPtr &tag, bool bForce = false, bool bDeleteRule = false);
/*!
* @brief Rename a timer on the client. Doesn't update the timer in the container. The backend will do this.
- * @return True if it was sent correctly, false if not.
+ * @return True if timer rename request was sent correctly, false if not.
*/
static bool RenameTimer(CFileItem &item, const std::string &strNewName);
/*!
* @brief Update the timer on the client. Doesn't update the timer in the container. The backend will do this.
- * @return True if it was sent correctly, false if not.
+ * @return True if timer update request was sent correctly, false if not.
*/
static bool UpdateTimer(const CPVRTimerInfoTagPtr &item);
diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp
index 0cd42d1a0c..a2cdc15039 100644
--- a/xbmc/rendering/dx/RenderSystemDX.cpp
+++ b/xbmc/rendering/dx/RenderSystemDX.cpp
@@ -772,7 +772,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources()
if (!bNeedRecreate && !bNeedResize)
{
- CheckInterlasedStereoView();
+ CheckInterlacedStereoView();
return true;
}
@@ -1010,7 +1010,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources()
CPoint camPoint = { m_nBackBufferWidth * 0.5f, m_nBackBufferHeight * 0.5f };
SetCameraPosition(camPoint, m_nBackBufferWidth, m_nBackBufferHeight);
- CheckInterlasedStereoView();
+ CheckInterlacedStereoView();
if (bRestoreRTView)
m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_depthStencilView);
@@ -1025,7 +1025,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources()
return true;
}
-void CRenderSystemDX::CheckInterlasedStereoView(void)
+void CRenderSystemDX::CheckInterlacedStereoView(void)
{
RENDER_STEREO_MODE stereoMode = g_graphicsContext.GetStereoMode();
diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h
index e2fcdf54a6..19f5964dba 100644
--- a/xbmc/rendering/dx/RenderSystemDX.h
+++ b/xbmc/rendering/dx/RenderSystemDX.h
@@ -115,7 +115,7 @@ protected:
void OnResize(unsigned int width, unsigned int height);
void SetFullScreenInternal();
void GetClosestDisplayModeToCurrent(IDXGIOutput* output, DXGI_MODE_DESC* outCurrentDisplayMode, bool useCached = false);
- void CheckInterlasedStereoView(void);
+ void CheckInterlacedStereoView(void);
void SetMaximumFrameLatency(uint8_t latency = -1) const;
bool GetStereoEnabled() const;
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
index 5634ed111a..9ce6384c07 100644
--- a/xbmc/settings/AdvancedSettings.cpp
+++ b/xbmc/settings/AdvancedSettings.cpp
@@ -28,6 +28,7 @@
#include "addons/AudioDecoder.h"
#include "addons/BinaryAddonCache.h"
#include "addons/IAddon.h"
+#include "addons/ImageDecoder.h"
#include "Application.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
@@ -275,6 +276,7 @@ void CAdvancedSettings::Initialize()
m_bMusicLibraryAllItemsOnBottom = false;
m_bMusicLibraryCleanOnUpdate = false;
+ m_bMusicLibraryPromptFullTagScan = false;
m_iMusicLibraryRecentlyAddedItems = 25;
m_strMusicLibraryAlbumFormat = "";
m_prioritiseAPEv2tags = false;
@@ -732,6 +734,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file)
XMLUtils::GetBoolean(pElement, "prioritiseapetags", m_prioritiseAPEv2tags);
XMLUtils::GetBoolean(pElement, "allitemsonbottom", m_bMusicLibraryAllItemsOnBottom);
XMLUtils::GetBoolean(pElement, "cleanonupdate", m_bMusicLibraryCleanOnUpdate);
+ XMLUtils::GetBoolean(pElement, "promptfulltagscan", m_bMusicLibraryPromptFullTagScan);
XMLUtils::GetString(pElement, "albumformat", m_strMusicLibraryAlbumFormat);
XMLUtils::GetString(pElement, "itemseparator", m_musicItemSeparator);
XMLUtils::GetInt(pElement, "dateadded", m_iMusicLibraryDateAdded);
@@ -1437,3 +1440,20 @@ std::string CAdvancedSettings::GetMusicExtensions() const
return result;
}
+
+std::string CAdvancedSettings::GetPictureExtensions() const
+{
+ std::string result(m_pictureExtensions);
+
+ VECADDONS codecs;
+ CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache();
+ addonCache.GetAddons(codecs, ADDON_IMAGEDECODER);
+ for (size_t i=0;i<codecs.size();++i)
+ {
+ std::shared_ptr<CImageDecoder> dec(std::static_pointer_cast<CImageDecoder>(codecs[i]));
+ result += '|';
+ result += dec->GetExtensions();
+ }
+
+ return result;
+}
diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h
index 64d42f8bdc..76428eef8d 100644
--- a/xbmc/settings/AdvancedSettings.h
+++ b/xbmc/settings/AdvancedSettings.h
@@ -256,6 +256,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
int m_iMusicLibraryDateAdded;
bool m_bMusicLibraryAllItemsOnBottom;
bool m_bMusicLibraryCleanOnUpdate;
+ bool m_bMusicLibraryPromptFullTagScan;
std::string m_strMusicLibraryAlbumFormat;
bool m_prioritiseAPEv2tags;
std::string m_musicItemSeparator;
@@ -356,6 +357,9 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
float GetDisplayLatency(float refreshrate);
bool m_initialized;
+ //! \brief Returns a list of picture extension for filtering in the GUI
+ std::string GetPictureExtensions() const;
+
//! \brief Returns a list of music extension for filtering in the GUI
std::string GetMusicExtensions() const;
@@ -365,7 +369,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
void ToggleDirtyRegionVisualization() { m_guiVisualizeDirtyRegions = !m_guiVisualizeDirtyRegions; };
// runtime settings which cannot be set from advancedsettings.xml
- std::string m_pictureExtensions;
std::string m_videoExtensions;
std::string m_discStubExtensions;
std::string m_subtitlesExtensions;
@@ -385,6 +388,7 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
private:
std::string m_musicExtensions;
+ std::string m_pictureExtensions;
void setExtraLogLevel(const std::vector<CVariant> &components);
};
diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp
index 6b1f2b6d75..4abfb5c43d 100644
--- a/xbmc/settings/SettingConditions.cpp
+++ b/xbmc/settings/SettingConditions.cpp
@@ -34,7 +34,7 @@
#include "peripherals/Peripherals.h"
#include "peripherals/bus/virtual/PeripheralBusAddon.h"
#include "profiles/ProfilesManager.h"
-#include "pvr/PVRManager.h"
+#include "pvr/PVRGUIActions.h"
#include "settings/SettingAddon.h"
#if defined(HAS_LIBAMCODEC)
#include "utils/AMLUtils.h"
@@ -72,7 +72,7 @@ bool CheckMasterLock(const std::string &condition, const std::string &value, con
bool CheckPVRParentalPin(const std::string &condition, const std::string &value, const CSetting *setting, void *data)
{
- return PVR::g_PVRManager.CheckParentalPIN(g_localizeStrings.Get(19262).c_str());
+ return PVR::CPVRGUIActions::GetInstance().CheckParentalPIN();
}
bool HasPeripherals(const std::string &condition, const std::string &value, const CSetting *setting, void *data)
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
index e745aebf57..89f0414803 100644
--- a/xbmc/settings/Settings.cpp
+++ b/xbmc/settings/Settings.cpp
@@ -728,7 +728,7 @@ bool CSettings::InitializeDefinitions()
#elif defined(TARGET_RASPBERRY_PI)
if (CFile::Exists(SETTINGS_XML_FOLDER "rbp.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp.xml"))
CLog::Log(LOGFATAL, "Unable to load rbp-specific settings definitions");
- if (g_RBP.RasberryPiVersion() > 1 && CFile::Exists(SETTINGS_XML_FOLDER "rbp2.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp2.xml"))
+ if (g_RBP.RaspberryPiVersion() > 1 && CFile::Exists(SETTINGS_XML_FOLDER "rbp2.xml") && !Initialize(SETTINGS_XML_FOLDER "rbp2.xml"))
CLog::Log(LOGFATAL, "Unable to load rbp2-specific settings definitions");
#elif defined(TARGET_FREEBSD)
if (CFile::Exists(SETTINGS_XML_FOLDER "freebsd.xml") && !Initialize(SETTINGS_XML_FOLDER "freebsd.xml"))
diff --git a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp
index b6301e490c..8a39ebbcb3 100644
--- a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp
+++ b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.cpp
@@ -306,7 +306,7 @@ bool CGUIDialogAudioDSPManager::OnClickListActive(CGUIMessage &message)
return false;
}
-bool CGUIDialogAudioDSPManager::OnClickRadioContinousSaving(CGUIMessage &message)
+bool CGUIDialogAudioDSPManager::OnClickRadioContinuousSaving(CGUIMessage &message)
{
CGUIRadioButtonControl *radioButton = dynamic_cast<CGUIRadioButtonControl*>(GetControl(CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING));
CGUIButtonControl *applyChangesButton = dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_BUTTON_APPLY_CHANGES));
@@ -383,7 +383,7 @@ bool CGUIDialogAudioDSPManager::OnMessageClick(CGUIMessage &message)
case CONTROL_LIST_ACTIVE:
return OnClickListActive(message);
case CONTROL_RADIO_BUTTON_CONTINUOUS_SAVING:
- return OnClickRadioContinousSaving(message);
+ return OnClickRadioContinuousSaving(message);
case CONTROL_BUTTON_CLEAR_ACTIVE_MODES:
return OnClickClearActiveModes(message);
case CONTROL_BUTTON_APPLY_CHANGES:
diff --git a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h
index 4843c39eea..3e13225969 100644
--- a/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h
+++ b/xbmc/settings/dialogs/GUIDialogAudioDSPManager.h
@@ -53,7 +53,7 @@ namespace ActiveAE
bool OnClickListAvailable(CGUIMessage &message);
bool OnClickListActive(CGUIMessage &message);
- bool OnClickRadioContinousSaving(CGUIMessage &message);
+ bool OnClickRadioContinuousSaving(CGUIMessage &message);
bool OnClickApplyChanges(CGUIMessage &message);
bool OnClickClearActiveModes(CGUIMessage &message);
diff --git a/xbmc/utils/BitstreamConverter.cpp b/xbmc/utils/BitstreamConverter.cpp
index 7bb100ffb0..84f105f5fe 100644
--- a/xbmc/utils/BitstreamConverter.cpp
+++ b/xbmc/utils/BitstreamConverter.cpp
@@ -74,6 +74,34 @@ enum {
HEVC_NAL_SEI_SUFFIX = 40
};
+enum {
+ SEI_BUFFERING_PERIOD = 0,
+ SEI_PIC_TIMING,
+ SEI_PAN_SCAN_RECT,
+ SEI_FILLER_PAYLOAD,
+ SEI_USER_DATA_REGISTERED_ITU_T_T35,
+ SEI_USER_DATA_UNREGISTERED,
+ SEI_RECOVERY_POINT,
+ SEI_DEC_REF_PIC_MARKING_REPETITION,
+ SEI_SPARE_PIC,
+ SEI_SCENE_INFO,
+ SEI_SUB_SEQ_INFO,
+ SEI_SUB_SEQ_LAYER_CHARACTERISTICS,
+ SEI_SUB_SEQ_CHARACTERISTICS,
+ SEI_FULL_FRAME_FREEZE,
+ SEI_FULL_FRAME_FREEZE_RELEASE,
+ SEI_FULL_FRAME_SNAPSHOT,
+ SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START,
+ SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END,
+ SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET,
+ SEI_FILM_GRAIN_CHARACTERISTICS,
+ SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE,
+ SEI_STEREO_VIDEO_INFO,
+ SEI_POST_FILTER_HINTS,
+ SEI_TONE_MAPPING
+};
+
+
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// GStreamer h264 parser
@@ -207,6 +235,34 @@ static const uint8_t* avc_find_startcode(const uint8_t *p, const uint8_t *end)
return out;
}
+static bool has_sei_recovery_point(const uint8_t *p, const uint8_t *end)
+{
+ int pt(0), ps(0), offset(1);
+
+ do
+ {
+ pt = 0;
+ do {
+ pt += p[offset];
+ } while (p[offset++] == 0xFF);
+
+ ps = 0;
+ do {
+ ps += p[offset];
+ } while (p[offset++] == 0xFF);
+
+ if (pt == SEI_RECOVERY_POINT)
+ {
+ nal_bitstream bs;
+ nal_bs_init(&bs, p + offset, ps);
+ return nal_bs_read_ue(&bs) >= 0;
+ }
+ offset += ps;
+ } while(p + offset < end && p[offset] != 0x80);
+
+ return false;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
CBitstreamParser::CBitstreamParser()
@@ -217,49 +273,44 @@ CBitstreamParser::~CBitstreamParser()
{
}
-bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size)
+bool CBitstreamParser::HasKeyframe(const uint8_t *buf, int buf_size)
{
if (!buf)
return false;
bool rtn = false;
uint32_t state = -1;
- const uint8_t *buf_end = buf + buf_size;
+ const uint8_t *buf_begin, *buf_end = buf + buf_size;
- for(;;)
+ for(;rtn == false;)
{
buf = find_start_code(buf, buf_end, &state);
if (buf >= buf_end)
{
- //CLog::Log(LOGDEBUG, "FindIdrSlice: buf(%p), buf_end(%p)", buf, buf_end);
break;
}
- --buf;
- int src_length = buf_end - buf;
switch (state & 0x1f)
{
- default:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found nal_type(%d)", state & 0x1f);
- break;
case AVC_NAL_SLICE:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SLICE");
break;
case AVC_NAL_IDR_SLICE:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_IDR_SLICE");
rtn = true;
break;
case AVC_NAL_SEI:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SEI");
+ buf_begin = buf - 1;
+ buf = find_start_code(buf, buf_end, &state) - 4;
+ if (has_sei_recovery_point(buf_begin, buf))
+ rtn = true;
break;
case AVC_NAL_SPS:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SPS");
+ rtn = true;
break;
case AVC_NAL_PPS:
- CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_PPS");
+ break;
+ default:
break;
}
- buf += src_length;
}
return rtn;
@@ -280,6 +331,7 @@ CBitstreamConverter::CBitstreamConverter()
m_convert_3byteTo4byteNALSize = false;
m_convert_bytestream = false;
m_sps_pps_context.sps_pps_data = NULL;
+ m_has_keyframe = true;
}
CBitstreamConverter::~CBitstreamConverter()
@@ -359,7 +411,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
// are valid, setup to convert 3 byte NAL sizes to 4 byte.
in_extradata[4] = 0xFF;
m_convert_3byteTo4byteNALSize = true;
-
+
m_extradata = (uint8_t *)av_malloc(in_extrasize);
memcpy(m_extradata, in_extradata, in_extrasize);
m_extrasize = in_extrasize;
@@ -470,7 +522,7 @@ void CBitstreamConverter::Close(void)
bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
{
if (m_convertBuffer)
- {
+ {
av_free(m_convertBuffer);
m_convertBuffer = NULL;
}
@@ -520,7 +572,7 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
{
m_inputSize = iSize;
m_inputBuffer = pData;
-
+
if (m_convert_bytestream)
{
if(m_convertBuffer)
@@ -608,6 +660,16 @@ int CBitstreamConverter::GetExtraSize() const
return m_extrasize;
}
+void CBitstreamConverter::ResetKeyframe(void)
+{
+ m_has_keyframe = false;
+}
+
+bool CBitstreamConverter::HasKeyframe() const
+{
+ return m_has_keyframe;
+}
+
bool CBitstreamConverter::BitstreamConvertInitAVC(void *in_extradata, int in_extrasize)
{
// based on h264_mp4toannexb_bsf.c (ffmpeg)
@@ -822,7 +884,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
int i;
uint8_t *buf = pData;
uint32_t buf_size = iSize;
- uint8_t unit_type, nal_sps, nal_pps;
+ uint8_t unit_type, nal_sps, nal_pps, nal_sei;
int32_t nal_size;
uint32_t cumul_size = 0;
const uint8_t *buf_end = buf + buf_size;
@@ -832,10 +894,12 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
case AV_CODEC_ID_H264:
nal_sps = AVC_NAL_SPS;
nal_pps = AVC_NAL_PPS;
+ nal_sei = AVC_NAL_SEI;
break;
case AV_CODEC_ID_HEVC:
nal_sps = HEVC_NAL_SPS;
nal_pps = HEVC_NAL_PPS;
+ nal_sei = HEVC_NAL_SEI_PREFIX;
break;
default:
return false;
@@ -866,7 +930,10 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
if (m_sps_pps_context.first_idr && (unit_type == nal_sps || unit_type == nal_pps))
m_sps_pps_context.idr_sps_pps_seen = 1;
- // prepend only to the first access unit of an IDR picture, if no sps/pps already present
+ if (!m_has_keyframe && (unit_type == nal_sps || IsIDR(unit_type) || (unit_type == nal_sei && has_sei_recovery_point(buf, buf + nal_size))))
+ m_has_keyframe = true;
+
+ // prepend only to the first access unit of an IDR picture, if no sps/pps already present
if (m_sps_pps_context.first_idr && IsIDR(unit_type) && !m_sps_pps_context.idr_sps_pps_seen)
{
BitstreamAllocAndCopy(poutbuf, poutbuf_size,
diff --git a/xbmc/utils/BitstreamConverter.h b/xbmc/utils/BitstreamConverter.h
index 81e4037473..bdcc3be630 100644
--- a/xbmc/utils/BitstreamConverter.h
+++ b/xbmc/utils/BitstreamConverter.h
@@ -87,7 +87,9 @@ public:
CBitstreamParser();
~CBitstreamParser();
- static bool FindIdrSlice(const uint8_t *buf, int buf_size);
+ static bool Open(){};
+ static void Close(){};
+ static bool HasKeyframe(const uint8_t *buf, int buf_size);
};
class CBitstreamConverter
@@ -104,6 +106,8 @@ public:
int GetConvertSize() const;
uint8_t* GetExtraData(void) const;
int GetExtraSize() const;
+ void ResetKeyframe(void);
+ bool HasKeyframe() const;
static void parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames);
static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);
@@ -144,4 +148,5 @@ protected:
bool m_convert_3byteTo4byteNALSize;
bool m_convert_bytestream;
AVCodecID m_codec;
+ bool m_has_keyframe;
};
diff --git a/xbmc/utils/Mime.cpp b/xbmc/utils/Mime.cpp
index 91234c90da..875148f6d8 100644
--- a/xbmc/utils/Mime.cpp
+++ b/xbmc/utils/Mime.cpp
@@ -55,6 +55,7 @@ std::map<std::string, std::string> fillMimeTypes()
mimeTypes.insert(std::pair<std::string, std::string>("arc", "application/octet-stream"));
mimeTypes.insert(std::pair<std::string, std::string>("arj", "application/arj"));
mimeTypes.insert(std::pair<std::string, std::string>("art", "image/x-jg"));
+ mimeTypes.insert(std::pair<std::string, std::string>("arw", "image/arw"));
mimeTypes.insert(std::pair<std::string, std::string>("asf", "video/x-ms-asf"));
mimeTypes.insert(std::pair<std::string, std::string>("asm", "text/x-asm"));
mimeTypes.insert(std::pair<std::string, std::string>("asp", "text/asp"));
@@ -91,6 +92,7 @@ std::map<std::string, std::string> fillMimeTypes()
mimeTypes.insert(std::pair<std::string, std::string>("cpt", "application/x-cpt"));
mimeTypes.insert(std::pair<std::string, std::string>("crl", "application/pkcs-crl"));
mimeTypes.insert(std::pair<std::string, std::string>("crt", "application/pkix-cert"));
+ mimeTypes.insert(std::pair<std::string, std::string>("cr2", "image/cr2"));
mimeTypes.insert(std::pair<std::string, std::string>("csh", "application/x-csh"));
mimeTypes.insert(std::pair<std::string, std::string>("css", "text/css"));
mimeTypes.insert(std::pair<std::string, std::string>("cxx", "text/plain"));
@@ -102,6 +104,7 @@ std::map<std::string, std::string> fillMimeTypes()
mimeTypes.insert(std::pair<std::string, std::string>("dir", "application/x-director"));
mimeTypes.insert(std::pair<std::string, std::string>("dl", "video/dl"));
mimeTypes.insert(std::pair<std::string, std::string>("divx", "video/x-msvideo"));
+ mimeTypes.insert(std::pair<std::string, std::string>("dng", "image/dng"));
mimeTypes.insert(std::pair<std::string, std::string>("doc", "application/msword"));
mimeTypes.insert(std::pair<std::string, std::string>("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"));
mimeTypes.insert(std::pair<std::string, std::string>("dot", "application/msword"));
@@ -268,6 +271,7 @@ std::map<std::string, std::string> fillMimeTypes()
mimeTypes.insert(std::pair<std::string, std::string>("naplps", "image/naplps"));
mimeTypes.insert(std::pair<std::string, std::string>("nc", "application/x-netcdf"));
mimeTypes.insert(std::pair<std::string, std::string>("ncm", "application/vnd.nokia.configuration-message"));
+ mimeTypes.insert(std::pair<std::string, std::string>("nef", "image/nef"));
mimeTypes.insert(std::pair<std::string, std::string>("nfo", "text/xml"));
mimeTypes.insert(std::pair<std::string, std::string>("nif", "image/x-niff"));
mimeTypes.insert(std::pair<std::string, std::string>("niff", "image/x-niff"));
diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
index 06b2068207..76f4c6f750 100644
--- a/xbmc/utils/URIUtils.cpp
+++ b/xbmc/utils/URIUtils.cpp
@@ -127,7 +127,7 @@ void URIUtils::RemoveExtension(std::string& strFileName)
strExtension += "|";
std::string strFileMask;
- strFileMask = g_advancedSettings.m_pictureExtensions;
+ strFileMask = g_advancedSettings.GetPictureExtensions();
strFileMask += "|" + g_advancedSettings.GetMusicExtensions();
strFileMask += "|" + g_advancedSettings.m_videoExtensions;
strFileMask += "|" + g_advancedSettings.m_subtitlesExtensions;
diff --git a/xbmc/utils/test/TestHttpHeader.cpp b/xbmc/utils/test/TestHttpHeader.cpp
index 72a50e1a2f..45c8337858 100644
--- a/xbmc/utils/test/TestHttpHeader.cpp
+++ b/xbmc/utils/test/TestHttpHeader.cpp
@@ -75,7 +75,7 @@
"\r\n"
// local helper function: replace substrings
-std::string strReplc(const std::string& str, const std::string& from, const std::string& to)
+std::string strReplace(const std::string& str, const std::string& from, const std::string& to)
{
std::string result;
size_t prevPos = 0;
@@ -175,14 +175,14 @@ TEST(TestHttpHeader, Parse)
EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()); // case-sensitive match of value
/* check support for '\n' line endings */
- testHdr.Parse(strReplc(CHECK_HEADER_SMPL, "\r\n", "\n"));
+ testHdr.Parse(strReplace(CHECK_HEADER_SMPL, "\r\n", "\n"));
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
EXPECT_STRCASEEQ(CHECK_HEADER_SMPL, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
- testHdr.Parse(strReplc(CHECK_HEADER_L1, "\r\n", "\n"));
+ testHdr.Parse(strReplace(CHECK_HEADER_L1, "\r\n", "\n"));
EXPECT_STRCASEEQ(CHECK_HEADER_L1, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
- testHdr.Parse(strReplc(CHECK_HEADER_L2, "\r\n", "\n"));
+ testHdr.Parse(strReplace(CHECK_HEADER_L2, "\r\n", "\n"));
EXPECT_STRCASEEQ(CHECK_HEADER_L2, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
testHdr.Parse(CHECK_PROT_LINE_200 "\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n"); // mixed "\n" and "\r\n"
@@ -332,7 +332,7 @@ TEST(TestHttpHeader, Parse_Multiline)
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string";
EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string";
- EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplc(strReplc(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
+ EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
testHdr.Clear();
testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
@@ -343,7 +343,7 @@ TEST(TestHttpHeader, Parse_Multiline)
EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string";
EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string";
- EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplc(strReplc(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
+ EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
}
TEST(TestHttpHeader, GetValue)
diff --git a/xbmc/utils/test/TestVariant.cpp b/xbmc/utils/test/TestVariant.cpp
index 45ee687758..ad9f089907 100644
--- a/xbmc/utils/test/TestVariant.cpp
+++ b/xbmc/utils/test/TestVariant.cpp
@@ -236,7 +236,7 @@ TEST(TestVariant, swap)
EXPECT_TRUE(a.isString());
}
-TEST(TestVariant, interator_array)
+TEST(TestVariant, iterator_array)
{
std::vector<std::string> strarray;
strarray.push_back("string");
diff --git a/xbmc/video/CMakeLists.txt b/xbmc/video/CMakeLists.txt
index 9842fce0aa..c3ee3d7554 100644
--- a/xbmc/video/CMakeLists.txt
+++ b/xbmc/video/CMakeLists.txt
@@ -9,7 +9,6 @@ set(SOURCES Bookmark.cpp
VideoInfoScanner.cpp
VideoInfoTag.cpp
VideoLibraryQueue.cpp
- VideoReferenceClock.cpp
VideoThumbLoader.cpp
ViewModeSettings.cpp)
@@ -26,7 +25,6 @@ set(HEADERS Bookmark.h
VideoInfoScanner.h
VideoInfoTag.h
VideoLibraryQueue.h
- VideoReferenceClock.h
VideoThumbLoader.h)
core_add_library(video)
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index 5f8dbf85bc..b3bef3e19f 100644
--- a/xbmc/video/VideoInfoScanner.cpp
+++ b/xbmc/video/VideoInfoScanner.cpp
@@ -126,7 +126,7 @@ namespace VIDEO
m_itemCount = -1;
// Database operations should not be canceled
- // using Interupt() while scanning as it could
+ // using Interrupt() while scanning as it could
// result in unexpected behaviour.
m_bCanInterrupt = false;
@@ -229,7 +229,7 @@ namespace VIDEO
void CVideoInfoScanner::Stop()
{
if (m_bCanInterrupt)
- m_database.Interupt();
+ m_database.Interrupt();
m_bStop = true;
}
diff --git a/xbmc/video/videosync/CMakeLists.txt b/xbmc/video/videosync/CMakeLists.txt
deleted file mode 100644
index 82f7169c78..0000000000
--- a/xbmc/video/videosync/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-set(HEADERS VideoSync.h)
-
-if(OPENGL_FOUND)
- list(APPEND SOURCES VideoSyncGLX.cpp)
- list(APPEND HEADERS VideoSyncGLX.h)
-endif()
-
-if(X_FOUND)
- list(APPEND SOURCES VideoSyncDRM.cpp)
- list(APPEND HEADERS VideoSyncDRM.h)
-endif()
-
-if(CORE_SYSTEM_NAME STREQUAL windows)
- list(APPEND SOURCES VideoSyncD3D.cpp)
- list(APPEND HEADERS VideoSyncD3D.h)
-endif()
-
-if(CORE_SYSTEM_NAME STREQUAL rbpi)
- list(APPEND SOURCES VideoSyncPi.cpp)
- list(APPEND HEADERS VideoSyncPi.h)
-endif()
-
-if(CORE_SYSTEM_NAME STREQUAL osx)
- list(APPEND SOURCES VideoSyncOsx.cpp)
- list(APPEND HEADERS VideoSyncOsx.h)
-endif()
-
-if(CORE_SYSTEM_NAME STREQUAL ios)
- list(APPEND SOURCES VideoSyncIos.cpp)
- list(APPEND HEADERS VideoSyncIos.h)
-endif()
-
-if(CORE_SYSTEM_NAME STREQUAL android)
- list(APPEND SOURCES VideoSyncAndroid.cpp)
- list(APPEND HEADERS VideoSyncAndroid.h)
-endif()
-
-if(IMX_FOUND)
- list(APPEND SOURCES VideoSyncIMX.cpp)
- list(APPEND HEADERS VideoSyncIMX.h)
-endif()
-
-if(SOURCES AND HEADERS)
- core_add_library(video_sync)
-endif()
diff --git a/xbmc/windowing/CMakeLists.txt b/xbmc/windowing/CMakeLists.txt
index 0e0cf87a1e..b8924a3104 100644
--- a/xbmc/windowing/CMakeLists.txt
+++ b/xbmc/windowing/CMakeLists.txt
@@ -4,7 +4,8 @@ set(SOURCES WinEvents.cpp
set(HEADERS WindowingFactory.h
WinEvents.h
WinSystem.h
- XBMC_events.h)
+ XBMC_events.h
+ VideoSync.h)
if (NOT MIR_FOUND)
if(SDL_FOUND AND NOT X_FOUND)
diff --git a/xbmc/video/videosync/VideoSync.h b/xbmc/windowing/VideoSync.h
index a430cb029f..8db21957ca 100644
--- a/xbmc/video/videosync/VideoSync.h
+++ b/xbmc/windowing/VideoSync.h
@@ -21,12 +21,12 @@
#include <atomic>
class CVideoReferenceClock;
-typedef void (*PUPDATECLOCK)(int NrVBlanks, uint64_t time, CVideoReferenceClock *clock);
+typedef void (*PUPDATECLOCK)(int NrVBlanks, uint64_t time, void *clock);
class CVideoSync
{
public:
- CVideoSync(CVideoReferenceClock *clock) { m_refClock = clock; };
+ CVideoSync(void *clock) { m_refClock = clock; };
virtual ~CVideoSync() {};
virtual bool Setup(PUPDATECLOCK func) = 0;
virtual void Run(std::atomic<bool>& stop) = 0;
@@ -36,5 +36,5 @@ public:
protected:
PUPDATECLOCK UpdateClock;
float m_fps;
- CVideoReferenceClock *m_refClock;
+ void *m_refClock;
};
diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h
index d67a2a9298..95676b4358 100644
--- a/xbmc/windowing/WinSystem.h
+++ b/xbmc/windowing/WinSystem.h
@@ -21,8 +21,10 @@
#ifndef WINDOW_SYSTEM_BASE_H
#define WINDOW_SYSTEM_BASE_H
+#include "VideoSync.h"
#include "WinEvents.h"
#include "guilib/Resolution.h"
+#include <memory>
#include <vector>
typedef enum _WindowSystemType
@@ -84,6 +86,9 @@ public:
virtual bool Hide() { return false; }
virtual bool Show(bool raise = true) { return false; }
+ // videosync
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) { return nullptr; }
+
// notifications
virtual void OnMove(int x, int y) {}
diff --git a/xbmc/windowing/X11/CMakeLists.txt b/xbmc/windowing/X11/CMakeLists.txt
index 6d2527d563..902dea50a4 100644
--- a/xbmc/windowing/X11/CMakeLists.txt
+++ b/xbmc/windowing/X11/CMakeLists.txt
@@ -6,6 +6,8 @@ if (X_FOUND)
WinSystemX11GLContext.cpp
WinSystemX11GLESContext.cpp
XRandR.cpp
+ VideoSyncGLX.cpp
+ VideoSyncDRM.cpp
WinSystemX11.cpp)
set(HEADERS GLContext.h
@@ -14,6 +16,8 @@ if (X_FOUND)
WinSystemX11GLContext.h
WinSystemX11GLESContext.h
XRandR.h
+ VideoSyncGLX.h
+ VideoSyncDRM.h
WinSystemX11.h)
core_add_library(windowing_X11)
diff --git a/xbmc/video/videosync/VideoSyncDRM.cpp b/xbmc/windowing/X11/VideoSyncDRM.cpp
index c86a7b771d..f31b349124 100644
--- a/xbmc/video/videosync/VideoSyncDRM.cpp
+++ b/xbmc/windowing/X11/VideoSyncDRM.cpp
@@ -22,7 +22,7 @@
#if defined(HAVE_X11)
-#include "video/videosync/VideoSyncDRM.h"
+#include "VideoSyncDRM.h"
#include "xf86drm.h"
#include <sys/poll.h>
#include <sys/time.h>
diff --git a/xbmc/video/videosync/VideoSyncDRM.h b/xbmc/windowing/X11/VideoSyncDRM.h
index b6807171f3..3f41cc25ee 100644
--- a/xbmc/video/videosync/VideoSyncDRM.h
+++ b/xbmc/windowing/X11/VideoSyncDRM.h
@@ -19,15 +19,13 @@
*
*/
-#if defined(HAVE_X11)
-
-#include "video/videosync/VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
class CVideoSyncDRM : public CVideoSync, IDispResource
{
public:
- CVideoSyncDRM(CVideoReferenceClock *clock) : CVideoSync(clock) {};
+ CVideoSyncDRM(void *clock) : CVideoSync(clock) {};
virtual bool Setup(PUPDATECLOCK func);
virtual void Run(std::atomic<bool>& stop);
virtual void Cleanup();
@@ -45,4 +43,3 @@ private:
};
};
-#endif
diff --git a/xbmc/video/videosync/VideoSyncGLX.cpp b/xbmc/windowing/X11/VideoSyncGLX.cpp
index fd28e007e3..a0da423254 100644
--- a/xbmc/video/videosync/VideoSyncGLX.cpp
+++ b/xbmc/windowing/X11/VideoSyncGLX.cpp
@@ -22,7 +22,7 @@
#if defined(HAS_GLX)
-#include "video/videosync/VideoSyncGLX.h"
+#include "VideoSyncGLX.h"
#include <sstream>
#include <X11/extensions/Xrandr.h>
#include "windowing/WindowingFactory.h"
diff --git a/xbmc/video/videosync/VideoSyncGLX.h b/xbmc/windowing/X11/VideoSyncGLX.h
index 7d23c47f03..eb390d6a84 100644
--- a/xbmc/video/videosync/VideoSyncGLX.h
+++ b/xbmc/windowing/X11/VideoSyncGLX.h
@@ -21,7 +21,7 @@
#if defined(HAS_GLX)
-#include "video/videosync/VideoSync.h"
+#include "windowing/VideoSync.h"
#include "system_gl.h"
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -32,7 +32,7 @@
class CVideoSyncGLX : public CVideoSync, IDispResource
{
public:
- CVideoSyncGLX(CVideoReferenceClock *clock) : CVideoSync(clock) {};
+ CVideoSyncGLX(void *clock) : CVideoSync(clock) {};
virtual bool Setup(PUPDATECLOCK func);
virtual void Run(std::atomic<bool>& stop);
virtual void Cleanup();
diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp
index 291bbf6420..ff7abe675d 100644
--- a/xbmc/windowing/X11/WinSystemX11.cpp
+++ b/xbmc/windowing/X11/WinSystemX11.cpp
@@ -20,8 +20,6 @@
#include "system.h"
-#if defined(HAVE_X11)
-
#include "WinSystemX11.h"
#include "ServiceBroker.h"
#include "settings/DisplaySettings.h"
@@ -1071,4 +1069,4 @@ void CWinSystemX11::UpdateCrtc()
g_graphicsContext.SetFPS(fps);
}
-#endif
+
diff --git a/xbmc/windowing/X11/WinSystemX11GLContext.cpp b/xbmc/windowing/X11/WinSystemX11GLContext.cpp
index 33c5858b8b..c776dbdf96 100644
--- a/xbmc/windowing/X11/WinSystemX11GLContext.cpp
+++ b/xbmc/windowing/X11/WinSystemX11GLContext.cpp
@@ -19,7 +19,7 @@
*/
#include "system.h"
-#if defined(HAVE_X11) && defined(HAS_GL)
+#if defined(HAS_GL)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -34,6 +34,8 @@
#include "threads/SingleLock.h"
#include <vector>
#include "Application.h"
+#include "VideoSyncDRM.h"
+#include "VideoSyncGLX.h"
CWinSystemX11GLContext::CWinSystemX11GLContext()
{
@@ -219,4 +221,19 @@ bool CWinSystemX11GLContext::RefreshGLContext(bool force)
return ret;
}
+std::unique_ptr<CVideoSync> CWinSystemX11GLContext::GetVideoSync(void *clock)
+{
+ std::unique_ptr<CVideoSync> pVSync;
+
+ if (dynamic_cast<CGLContextEGL*>(m_pGLContext))
+ {
+ pVSync.reset(new CVideoSyncDRM(clock));
+ }
+ else if (dynamic_cast<CGLContextGLX*>(m_pGLContext))
+ {
+ pVSync.reset(new CVideoSyncGLX(clock));
+ }
+ return pVSync;
+}
+
#endif
diff --git a/xbmc/windowing/X11/WinSystemX11GLContext.h b/xbmc/windowing/X11/WinSystemX11GLContext.h
index 4e0ca8c62e..b4e7f390d9 100644
--- a/xbmc/windowing/X11/WinSystemX11GLContext.h
+++ b/xbmc/windowing/X11/WinSystemX11GLContext.h
@@ -43,6 +43,9 @@ public:
bool IsExtSupported(const char* extension) override;
+ // videosync
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
+
GLXWindow GetWindow() const;
GLXContext GetGlxContext() const;
EGLDisplay GetEGLDisplay() const;
diff --git a/xbmc/windowing/egl/CMakeLists.txt b/xbmc/windowing/egl/CMakeLists.txt
index cab9495aab..361de124a5 100644
--- a/xbmc/windowing/egl/CMakeLists.txt
+++ b/xbmc/windowing/egl/CMakeLists.txt
@@ -16,16 +16,22 @@ endif()
if(CORE_SYSTEM_NAME STREQUAL android)
list(APPEND SOURCES EGLNativeTypeAndroid.cpp)
list(APPEND HEADERS EGLNativeTypeAndroid.h)
+ list(APPEND SOURCES VideoSyncAndroid.h)
+ list(APPEND SOURCES VideoSyncAndroid.cpp)
endif()
if(AML_FOUND)
list(APPEND SOURCES EGLNativeTypeAmlogic.cpp)
list(APPEND HEADERS EGLNativeTypeAmlogic.h)
+ list(APPEND SOURCES VideoSyncAML.h)
+ list(APPEND SOURCES VideoSyncAML.cpp)
endif()
if(MMAL_FOUND)
list(APPEND SOURCES EGLNativeTypeRaspberryPI.cpp)
list(APPEND HEADERS EGLNativeTypeRaspberryPI.h)
+ list(APPEND SOURCES VideoSyncPi.cpp)
+ list(APPEND HEADERS VideoSyncPi.h)
endif()
if(IMX_FOUND)
diff --git a/xbmc/windowing/egl/VideoSyncAML.cpp b/xbmc/windowing/egl/VideoSyncAML.cpp
new file mode 100644
index 0000000000..ebf3fb9546
--- /dev/null
+++ b/xbmc/windowing/egl/VideoSyncAML.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+
+#if defined(HAS_LIBAMCODEC)
+
+#include "VideoSyncAML.h"
+#include "guilib/GraphicContext.h"
+#include "windowing/WindowingFactory.h"
+#include "utils/TimeUtils.h"
+#include "utils/log.h"
+#include "threads/Thread.h"
+#include <sys/poll.h>
+
+#include <chrono>
+#include <thread>
+
+extern CEvent g_aml_sync_event;
+
+CVideoSyncAML::CVideoSyncAML(void *clock)
+: CVideoSync(clock)
+, m_abort(false)
+{
+}
+
+CVideoSyncAML::~CVideoSyncAML()
+{
+}
+
+bool CVideoSyncAML::Setup(PUPDATECLOCK func)
+{
+ UpdateClock = func;
+
+ m_abort = false;
+
+ g_Windowing.Register(this);
+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up AML");
+
+ return true;
+}
+
+void CVideoSyncAML::Run(std::atomic<bool>& stop)
+{
+ // We use the wall clock for timout handling (no AML h/w, startup)
+ std::chrono::time_point<std::chrono::system_clock> now(std::chrono::system_clock::now());
+ unsigned int waittime (3000 / m_fps);
+ uint64_t numVBlanks (0);
+
+ while (!stop && !m_abort)
+ {
+ int countVSyncs(1);
+ if( !g_aml_sync_event.WaitMSec(waittime))
+ {
+ std::chrono::milliseconds elapsed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now).count());
+ uint64_t curVBlanks = (m_fps * elapsed.count()) / 1000;
+ int64_t lastVBlankTime((curVBlanks * 1000) / m_fps);
+ if (elapsed.count() > lastVBlankTime)
+ {
+ lastVBlankTime = (++curVBlanks * 1000) / m_fps;
+ std::this_thread::sleep_for(std::chrono::milliseconds(lastVBlankTime - elapsed.count()));
+ }
+ countVSyncs = curVBlanks - numVBlanks;
+ numVBlanks = curVBlanks;
+ }
+ else
+ ++numVBlanks;
+
+ uint64_t now = CurrentHostCounter();
+
+ UpdateClock(countVSyncs, now, m_refClock);
+ }
+}
+
+void CVideoSyncAML::Cleanup()
+{
+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up AML");
+ g_Windowing.Unregister(this);
+}
+
+float CVideoSyncAML::GetFps()
+{
+ m_fps = g_graphicsContext.GetFPS();
+ CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.3f", m_fps);
+ return m_fps;
+}
+
+void CVideoSyncAML::OnResetDisplay()
+{
+ m_abort = true;
+}
+
+#endif
diff --git a/xbmc/windowing/egl/VideoSyncAML.h b/xbmc/windowing/egl/VideoSyncAML.h
new file mode 100644
index 0000000000..8186459f9f
--- /dev/null
+++ b/xbmc/windowing/egl/VideoSyncAML.h
@@ -0,0 +1,41 @@
+#pragma once
+/*
+ * Copyright (C) 2017 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if defined(HAS_LIBAMCODEC)
+
+#include "windowing/VideoSync.h"
+#include "guilib/DispResource.h"
+
+class CVideoSyncAML : public CVideoSync, IDispResource
+{
+public:
+ CVideoSyncAML(void *clock);
+ virtual ~CVideoSyncAML();
+ virtual bool Setup(PUPDATECLOCK func)override;
+ virtual void Run(std::atomic<bool>& stop)override;
+ virtual void Cleanup()override;
+ virtual float GetFps()override;
+ virtual void OnResetDisplay()override;
+private:
+ volatile bool m_abort;
+};
+
+#endif
diff --git a/xbmc/video/videosync/VideoSyncAndroid.cpp b/xbmc/windowing/egl/VideoSyncAndroid.cpp
index 71d7906267..65f48dd17b 100644
--- a/xbmc/video/videosync/VideoSyncAndroid.cpp
+++ b/xbmc/windowing/egl/VideoSyncAndroid.cpp
@@ -23,7 +23,7 @@
#if defined(TARGET_ANDROID)
#include "utils/log.h"
#include "VideoSyncAndroid.h"
-#include "video/VideoReferenceClock.h"
+#include "cores/VideoPlayer/VideoReferenceClock.h"
#include "utils/TimeUtils.h"
#include "platform/android/activity/XBMCApp.h"
#include "windowing/WindowingFactory.h"
@@ -35,12 +35,12 @@
bool CVideoSyncAndroid::Setup(PUPDATECLOCK func)
{
CLog::Log(LOGDEBUG, "CVideoSyncAndroid::%s setting up", __FUNCTION__);
-
+
//init the vblank timestamp
m_LastVBlankTime = CurrentHostCounter();
UpdateClock = func;
m_abort = false;
-
+
CXBMCApp::InitFrameCallback(this);
g_Windowing.Register(this);
@@ -79,14 +79,14 @@ void CVideoSyncAndroid::FrameCallback(int64_t frameTimeNanos)
int NrVBlanks;
double VBlankTime;
int64_t nowtime = CurrentHostCounter();
-
+
//calculate how many vblanks happened
VBlankTime = (double)(nowtime - m_LastVBlankTime) / (double)CurrentHostFrequency();
NrVBlanks = MathUtils::round_int(VBlankTime * m_fps);
//save the timestamp of this vblank so we can calculate how many happened next time
m_LastVBlankTime = nowtime;
-
+
//update the vblank timestamp, update the clock and send a signal that we got a vblank
UpdateClock(NrVBlanks, nowtime, m_refClock);
}
diff --git a/xbmc/video/videosync/VideoSyncAndroid.h b/xbmc/windowing/egl/VideoSyncAndroid.h
index 803df561b2..789c6a1c99 100644
--- a/xbmc/video/videosync/VideoSyncAndroid.h
+++ b/xbmc/windowing/egl/VideoSyncAndroid.h
@@ -20,26 +20,26 @@
*/
#if defined(TARGET_ANDROID)
-#include "VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
class CVideoSyncAndroid : public CVideoSync, IDispResource
{
public:
- CVideoSyncAndroid(CVideoReferenceClock *clock) : CVideoSync(clock), m_LastVBlankTime(0), m_abort(false){}
-
+ CVideoSyncAndroid(void *clock) : CVideoSync(clock), m_LastVBlankTime(0), m_abort(false){}
+
// CVideoSync interface
- virtual bool Setup(PUPDATECLOCK func);
- virtual void Run(std::atomic<bool>& stop);
- virtual void Cleanup();
- virtual float GetFps();
-
+ virtual bool Setup(PUPDATECLOCK func) override;
+ virtual void Run(std::atomic<bool>& stop) override;
+ virtual void Cleanup() override;
+ virtual float GetFps() override;
+
// IDispResource interface
- virtual void OnResetDisplay();
+ virtual void OnResetDisplay() override;
// Choreographer callback
void FrameCallback(int64_t frameTimeNanos);
-
+
private:
int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened
volatile bool m_abort;
diff --git a/xbmc/video/videosync/VideoSyncIMX.cpp b/xbmc/windowing/egl/VideoSyncIMX.cpp
index fa7c27c4e5..fa7c27c4e5 100644
--- a/xbmc/video/videosync/VideoSyncIMX.cpp
+++ b/xbmc/windowing/egl/VideoSyncIMX.cpp
diff --git a/xbmc/video/videosync/VideoSyncIMX.h b/xbmc/windowing/egl/VideoSyncIMX.h
index 7220ac60ba..7220ac60ba 100644
--- a/xbmc/video/videosync/VideoSyncIMX.h
+++ b/xbmc/windowing/egl/VideoSyncIMX.h
diff --git a/xbmc/video/videosync/VideoSyncPi.cpp b/xbmc/windowing/egl/VideoSyncPi.cpp
index 0b512d3b0b..d37b3b4c46 100644
--- a/xbmc/video/videosync/VideoSyncPi.cpp
+++ b/xbmc/windowing/egl/VideoSyncPi.cpp
@@ -22,7 +22,7 @@
#if defined(TARGET_RASPBERRY_PI)
-#include "video/videosync/VideoSyncPi.h"
+#include "VideoSyncPi.h"
#include "guilib/GraphicContext.h"
#include "windowing/WindowingFactory.h"
#include "utils/TimeUtils.h"
@@ -70,4 +70,10 @@ void CVideoSyncPi::OnResetDisplay()
m_abort = true;
}
+void CVideoSyncPi::RefreshChanged()
+{
+ if (m_fps != g_graphicsContext.GetFPS())
+ m_abort = true;
+}
+
#endif
diff --git a/xbmc/video/videosync/VideoSyncPi.h b/xbmc/windowing/egl/VideoSyncPi.h
index c7c3d12c71..2fa2216cca 100644
--- a/xbmc/video/videosync/VideoSyncPi.h
+++ b/xbmc/windowing/egl/VideoSyncPi.h
@@ -21,18 +21,19 @@
#if defined(TARGET_RASPBERRY_PI)
-#include "video/videosync/VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
class CVideoSyncPi : public CVideoSync, IDispResource
{
public:
- CVideoSyncPi(CVideoReferenceClock *clock) : CVideoSync(clock) {};
+ CVideoSyncPi(void *clock) : CVideoSync(clock) {};
virtual bool Setup(PUPDATECLOCK func);
virtual void Run(std::atomic<bool>& stop);
virtual void Cleanup();
virtual float GetFps();
virtual void OnResetDisplay();
+ virtual void RefreshChanged();
private:
volatile bool m_abort;
diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp
index 815d389fa5..bd72af5f72 100644
--- a/xbmc/windowing/egl/WinSystemEGL.cpp
+++ b/xbmc/windowing/egl/WinSystemEGL.cpp
@@ -32,6 +32,15 @@
#include "settings/DisplaySettings.h"
#include "guilib/DispResource.h"
#include "threads/SingleLock.h"
+
+#if defined(TARGET_RASPBERRY_PI)
+#include "VideoSyncPi.h"
+#elif defined(TARGET_ANDROID)
+#include "VideoSyncAndroid.h"
+#elif defined(HAS_LIBAMCODEC)
+#include "VideoSyncAML.h"
+#endif
+
#ifdef HAS_IMXVPU
// This has to go into another header file
#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecIMX.h"
@@ -556,4 +565,21 @@ bool CWinSystemEGL::ClampToGUIDisplayLimits(int &width, int &height)
return true;
}
+std::unique_ptr<CVideoSync> CWinSystemEGL::GetVideoSync(void *clock)
+{
+#if defined(TARGET_RASPBERRY_PI)
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncPi(clock));
+ return pVSync;
+#elif defined(TARGET_ANDROID)
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncAndroid(clock));
+ return pVSync;
+#elif defined(HAS_LIBAMCODEC)
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncAML(clock));
+ return pVSync;
+#else
+ return nullptr;
+#endif
+}
+
+
#endif
diff --git a/xbmc/windowing/egl/WinSystemEGL.h b/xbmc/windowing/egl/WinSystemEGL.h
index c24bb356b9..c9a5506922 100644
--- a/xbmc/windowing/egl/WinSystemEGL.h
+++ b/xbmc/windowing/egl/WinSystemEGL.h
@@ -69,6 +69,9 @@ public:
EGLDisplay GetEGLDisplay();
EGLContext GetEGLContext();
+
+ // videosync
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
protected:
virtual void PresentRenderImpl(bool rendered);
virtual void SetVSyncImpl(bool enable);
diff --git a/xbmc/windowing/osx/CMakeLists.txt b/xbmc/windowing/osx/CMakeLists.txt
index a007c38df2..0191ddefb5 100644
--- a/xbmc/windowing/osx/CMakeLists.txt
+++ b/xbmc/windowing/osx/CMakeLists.txt
@@ -1,17 +1,21 @@
if(CORE_SYSTEM_NAME STREQUAL osx)
set(SOURCES WinEventsOSX.mm
WinSystemOSX.mm
- WinSystemOSXGL.mm)
+ WinSystemOSXGL.mm
+ VideoSyncOsx.cpp)
set(HEADERS WinEventsOSX.h
WinSystemOSX.h
- WinSystemOSXGL.h)
+ WinSystemOSXGL.h
+ VideoSyncOsx.h)
endif()
if(CORE_SYSTEM_NAME STREQUAL ios)
set(SOURCES WinEventsIOS.mm
- WinSystemIOS.mm)
+ WinSystemIOS.mm
+ VideoSyncIos.cpp)
set(HEADERS WinEventsIOS.h
- WinSystemIOS.h)
+ WinSystemIOS.h
+ VideoSyncIos.h)
endif()
core_add_library(windowing_osx)
diff --git a/xbmc/video/videosync/VideoSyncIos.cpp b/xbmc/windowing/osx/VideoSyncIos.cpp
index 026dd7ed91..ac23993dd8 100644
--- a/xbmc/video/videosync/VideoSyncIos.cpp
+++ b/xbmc/windowing/osx/VideoSyncIos.cpp
@@ -24,7 +24,7 @@
#include "utils/log.h"
#include "VideoSyncIos.h"
#include "utils/MathUtils.h"
-#include "video/VideoReferenceClock.h"
+#include "cores/VideoPlayer/VideoReferenceClock.h"
#include "guilib/GraphicContext.h"
#include "windowing/WindowingFactory.h"
#include "utils/TimeUtils.h"
diff --git a/xbmc/video/videosync/VideoSyncIos.h b/xbmc/windowing/osx/VideoSyncIos.h
index bf336b80dd..6d129eb63d 100644
--- a/xbmc/video/videosync/VideoSyncIos.h
+++ b/xbmc/windowing/osx/VideoSyncIos.h
@@ -20,13 +20,13 @@
*/
#if defined(TARGET_DARWIN_IOS)
-#include "VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
class CVideoSyncIos : public CVideoSync, IDispResource
{
public:
- CVideoSyncIos(CVideoReferenceClock *clock) : CVideoSync(clock), m_LastVBlankTime(0), m_abort(false){}
+ CVideoSyncIos(void *clock) : CVideoSync(clock), m_LastVBlankTime(0), m_abort(false){}
// CVideoSync interface
virtual bool Setup(PUPDATECLOCK func) override;
diff --git a/xbmc/video/videosync/VideoSyncOsx.cpp b/xbmc/windowing/osx/VideoSyncOsx.cpp
index f6320c49b3..9ea7145b33 100644
--- a/xbmc/video/videosync/VideoSyncOsx.cpp
+++ b/xbmc/windowing/osx/VideoSyncOsx.cpp
@@ -20,11 +20,9 @@
#include "system.h"
-#if defined(TARGET_DARWIN_OSX)
#include "utils/log.h"
#include "VideoSyncOsx.h"
#include "utils/MathUtils.h"
-#include "video/VideoReferenceClock.h"
#include "guilib/GraphicContext.h"
#include "utils/TimeUtils.h"
#include "windowing/WindowingFactory.h"
@@ -159,4 +157,3 @@ void CVideoSyncOsx::DeinitDisplayLink()
Cocoa_CVDisplayLinkRelease();
}
-#endif//TARGET_DARWIN_OSX
diff --git a/xbmc/video/videosync/VideoSyncOsx.h b/xbmc/windowing/osx/VideoSyncOsx.h
index 1a2eedcd7e..276c9085a5 100644
--- a/xbmc/video/videosync/VideoSyncOsx.h
+++ b/xbmc/windowing/osx/VideoSyncOsx.h
@@ -19,8 +19,7 @@
*
*/
-#if defined(TARGET_DARWIN_OSX)
-#include "VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
#include "threads/Event.h"
@@ -28,7 +27,7 @@ class CVideoSyncOsx : public CVideoSync, IDispResource
{
public:
- CVideoSyncOsx(CVideoReferenceClock *clock) :
+ CVideoSyncOsx(void *clock) :
CVideoSync(clock),
m_LastVBlankTime(0),
m_displayLost(false),
@@ -58,4 +57,3 @@ private:
CEvent m_lostEvent;
};
-#endif// TARGET_DARWIN_OSX
diff --git a/xbmc/windowing/osx/WinSystemIOS.h b/xbmc/windowing/osx/WinSystemIOS.h
index 7ecdf672a7..2ee5645b22 100644
--- a/xbmc/windowing/osx/WinSystemIOS.h
+++ b/xbmc/windowing/osx/WinSystemIOS.h
@@ -72,6 +72,8 @@ public:
virtual int GetNumScreens();
virtual int GetCurrentScreen();
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
+
bool InitDisplayLink(CVideoSyncIos *syncImpl);
void DeinitDisplayLink(void);
void OnAppFocusChange(bool focus);
diff --git a/xbmc/windowing/osx/WinSystemIOS.mm b/xbmc/windowing/osx/WinSystemIOS.mm
index a2e74332a4..84f1770185 100644
--- a/xbmc/windowing/osx/WinSystemIOS.mm
+++ b/xbmc/windowing/osx/WinSystemIOS.mm
@@ -18,7 +18,6 @@
*
*/
-#if defined(TARGET_DARWIN_IOS)
//hack around problem with xbmc's typedef int BOOL
// and obj-c's typedef unsigned char BOOL
#define BOOL XBMC_BOOL
@@ -26,7 +25,8 @@
#undef BOOL
#ifdef HAS_EGL
-#define BOOL XBMC_BOOL
+#define BOOL XBMC_BOOL
+#include "VideoSyncIos.h"
#include "WinSystemIOS.h"
#include "utils/log.h"
#include "filesystem/SpecialProtocol.h"
@@ -37,7 +37,7 @@
#include "utils/StringUtils.h"
#include "guilib/DispResource.h"
#include "threads/SingleLock.h"
-#include "video/videosync/VideoSyncIos.h"
+#include "VideoSyncIos.h"
#include <vector>
#undef BOOL
@@ -485,6 +485,11 @@ void* CWinSystemIOS::GetEAGLContextObj()
return [g_xbmcController getEAGLContextObj];
}
-#endif
+std::unique_ptr<CVideoSync> CWinSystemIOS::GetVideoSync(void *clock)
+{
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncIos(clock));
+ return pVSync;
+}
#endif
+
diff --git a/xbmc/windowing/osx/WinSystemOSX.h b/xbmc/windowing/osx/WinSystemOSX.h
index c46e27b41e..fe37b26b68 100644
--- a/xbmc/windowing/osx/WinSystemOSX.h
+++ b/xbmc/windowing/osx/WinSystemOSX.h
@@ -74,6 +74,8 @@ public:
virtual int GetNumScreens();
virtual int GetCurrentScreen();
virtual double GetCurrentRefreshrate() { return m_refreshRate; }
+
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
void WindowChangedScreen();
@@ -88,6 +90,7 @@ public:
std::string GetClipboardText(void);
+
protected:
void HandlePossibleRefreshrateChange();
void* CreateWindowedContext(void* shareCtx);
diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm
index 752e8655a8..365bb0badb 100644
--- a/xbmc/windowing/osx/WinSystemOSX.mm
+++ b/xbmc/windowing/osx/WinSystemOSX.mm
@@ -18,13 +18,12 @@
*
*/
-#if defined(TARGET_DARWIN_OSX)
-
//hack around problem with xbmc's typedef int BOOL
// and obj-c's typedef unsigned char BOOL
#define BOOL XBMC_BOOL
#include "WinSystemOSX.h"
#include "WinEventsOSX.h"
+#include "VideoSyncOsx.h"
#include "Application.h"
#include "ServiceBroker.h"
#include "messaging/ApplicationMessenger.h"
@@ -1798,4 +1797,8 @@ std::string CWinSystemOSX::GetClipboardText(void)
return utf8_text;
}
-#endif
+std::unique_ptr<CVideoSync> CWinSystemOSX::GetVideoSync(void *clock)
+{
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncOsx(clock));
+ return pVSync;
+}
diff --git a/xbmc/windowing/windows/CMakeLists.txt b/xbmc/windowing/windows/CMakeLists.txt
index 4a1f1b3b5b..76c5293f0b 100644
--- a/xbmc/windowing/windows/CMakeLists.txt
+++ b/xbmc/windowing/windows/CMakeLists.txt
@@ -1,8 +1,10 @@
-set(SOURCES WinEventsWin32.cpp
+set(SOURCES VideoSyncD3D.cpp
+ WinEventsWin32.cpp
WinSystemWin32.cpp
WinSystemWin32DX.cpp)
-set(HEADERS WinEventsWin32.h
+set(HEADERS VideoSyncD3D.h
+ WinEventsWin32.h
WinSystemWin32.h
WinSystemWin32DX.h)
diff --git a/xbmc/video/videosync/VideoSyncD3D.cpp b/xbmc/windowing/windows/VideoSyncD3D.cpp
index e48b91e121..3d9462723b 100644
--- a/xbmc/video/videosync/VideoSyncD3D.cpp
+++ b/xbmc/windowing/windows/VideoSyncD3D.cpp
@@ -20,13 +20,11 @@
#include "system.h"
-#if defined(TARGET_WINDOWS)
-
#include "utils/log.h"
#include "Utils/TimeUtils.h"
#include "Utils/MathUtils.h"
#include "windowing\WindowingFactory.h"
-#include "video/videosync/VideoSyncD3D.h"
+#include "VideoSyncD3D.h"
#include "guilib/GraphicContext.h"
#include "platform/win32/dxerr.h"
#include "utils/StringUtils.h"
@@ -155,4 +153,3 @@ std::string CVideoSyncD3D::GetErrorDescription(HRESULT hr)
return StringUtils::Format("%ls: %ls", error.c_str(), descr.c_str());
}
-#endif
diff --git a/xbmc/video/videosync/VideoSyncD3D.h b/xbmc/windowing/windows/VideoSyncD3D.h
index 486b6206f6..64a28cdc3e 100644
--- a/xbmc/video/videosync/VideoSyncD3D.h
+++ b/xbmc/windowing/windows/VideoSyncD3D.h
@@ -19,16 +19,14 @@
*
*/
-#if defined(TARGET_WINDOWS)
-
-#include "video/videosync/VideoSync.h"
+#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"
#include "threads/Event.h"
class CVideoSyncD3D : public CVideoSync, IDispResource
{
public:
- CVideoSyncD3D(CVideoReferenceClock *clock) : CVideoSync(clock) {};
+ CVideoSyncD3D(void *clock) : CVideoSync(clock) {};
bool Setup(PUPDATECLOCK func) override;
void Run(std::atomic<bool>& stop) override;
void Cleanup() override;
@@ -47,4 +45,3 @@ private:
int64_t m_lastUpdateTime;
};
-#endif
diff --git a/xbmc/windowing/windows/WinSystemWin32.cpp b/xbmc/windowing/windows/WinSystemWin32.cpp
index 1e7edb2337..6989179933 100644
--- a/xbmc/windowing/windows/WinSystemWin32.cpp
+++ b/xbmc/windowing/windows/WinSystemWin32.cpp
@@ -31,8 +31,8 @@
#include "utils/log.h"
#include "utils/CharsetConverter.h"
#include "utils/SystemInfo.h"
+#include "VideoSyncD3D.h"
-#ifdef TARGET_WINDOWS
#include <tpcshrd.h>
CWinSystemWin32::CWinSystemWin32()
@@ -939,4 +939,8 @@ void CWinSystemWin32::SetForegroundWindowInternal(HWND hWnd)
}
}
-#endif
+std::unique_ptr<CVideoSync> CWinSystemWin32::GetVideoSync(void *clock)
+{
+ std::unique_ptr<CVideoSync> pVSync(new CVideoSyncD3D(clock));
+ return pVSync;
+}
diff --git a/xbmc/windowing/windows/WinSystemWin32.h b/xbmc/windowing/windows/WinSystemWin32.h
index d5aebef1a4..dc522809ec 100644
--- a/xbmc/windowing/windows/WinSystemWin32.h
+++ b/xbmc/windowing/windows/WinSystemWin32.h
@@ -154,6 +154,9 @@ public:
virtual bool Hide();
virtual bool Show(bool raise = true);
+ // videosync
+ virtual std::unique_ptr<CVideoSync> GetVideoSync(void *clock) override;
+
// CWinSystemWin32
HWND GetHwnd() { return m_hWnd; }
bool IsAlteringWindow() { return m_IsAlteringWindow; }