Merge pull request #4154 from sraue/ffmpeg-static-fixes
authorTrent Nelson <trent.a.b.nelson@gmail.com>
Sun, 23 Feb 2014 22:54:13 +0000 (17:54 -0500)
committerTrent Nelson <trent.a.b.nelson@gmail.com>
Sun, 23 Feb 2014 22:54:13 +0000 (17:54 -0500)
configure.in: enable FFMPEG static build for ARM, some cleanups. Tested ...

378 files changed:
.gitignore
Makefile.in
XBMC.xcodeproj/project.pbxproj
addons/repository.pvr-android.xbmc.org/addon.xml
addons/repository.pvr-ios.xbmc.org/addon.xml
addons/repository.pvr-osx32.xbmc.org/addon.xml
addons/repository.pvr-osx64.xbmc.org/addon.xml
addons/repository.pvr-win32.xbmc.org/addon.xml
addons/repository.xbmc.org/addon.xml
addons/screensaver.rsxs.euphoria/addon.xml
addons/screensaver.rsxs.plasma/addon.xml
addons/screensaver.rsxs.solarwinds/addon.xml
addons/screensaver.xbmc.builtin.black/addon.xml
addons/screensaver.xbmc.builtin.dim/addon.xml
addons/skin.confluence/720p/DialogSeekBar.xml
addons/skin.confluence/720p/DialogSubtitles.xml
addons/skin.confluence/720p/SettingsCategory.xml
addons/skin.confluence/720p/ViewsPVR.xml
addons/skin.confluence/addon.xml
addons/skin.confluence/changelog.txt
addons/skin.confluence/language/French (Canada)/strings.po
addons/skin.confluence/language/Hebrew/strings.po
addons/skin.confluence/language/Slovenian/strings.po
addons/skin.confluence/language/Turkish/strings.po
addons/visualization.dxspectrum/addon.xml
addons/visualization.fishbmc/addon.xml
addons/visualization.fishbmc/changelog.txt
addons/visualization.fishbmc/resources/language/Croatian/strings.po
addons/visualization.fishbmc/resources/language/Hebrew/strings.po
addons/visualization.fishbmc/resources/language/Korean/strings.po
addons/visualization.fishbmc/resources/language/Polish/strings.po
addons/visualization.fishbmc/resources/language/Swedish/strings.po
addons/visualization.glspectrum/addon.xml
addons/visualization.milkdrop/addon.xml
addons/visualization.milkdrop/resources/language/Hebrew/strings.po
addons/visualization.milkdrop/resources/language/Turkish/strings.po
addons/visualization.projectm/addon.xml
addons/visualization.projectm/resources/language/Hebrew/strings.po
addons/visualization.projectm/resources/language/Turkish/strings.po
addons/visualization.vortex/addon.xml
addons/visualization.vortex/resources/language/Croatian/strings.po
addons/visualization.vortex/resources/language/Hebrew/strings.po
addons/visualization.vortex/resources/language/Korean/strings.po
addons/visualization.vortex/resources/language/Swedish/strings.po
addons/visualization.vortex/resources/language/Turkish/strings.po
addons/visualization.waveform/addon.xml
addons/webinterface.default/addon.xml
addons/xbmc.debug/addon.xml
addons/xbmc.debug/resources/language/Turkish/strings.po
addons/xbmc.gui/addon.xml
configure.in
language/Afrikaans/strings.po
language/Albanian/strings.po
language/Amharic/strings.po
language/Arabic/strings.po
language/Azerbaijani/strings.po
language/Basque/strings.po
language/Belarusian/strings.po
language/Bosnian/strings.po
language/Bulgarian/strings.po
language/Burmese/strings.po
language/Catalan/strings.po
language/Chinese (Simple)/strings.po
language/Chinese (Traditional)/strings.po
language/Croatian/strings.po
language/Czech/strings.po
language/Danish/strings.po
language/Dutch/strings.po
language/English (Australia)/langinfo.xml [new file with mode: 0644]
language/English (US)/strings.po
language/English/strings.po
language/Esperanto/strings.po
language/Estonian/strings.po
language/Faroese/strings.po
language/Finnish/strings.po
language/French (Canada)/langinfo.xml [new file with mode: 0644]
language/French (Canada)/strings.po
language/French/strings.po
language/Galician/strings.po
language/German/strings.po
language/Greek/strings.po
language/Hebrew/strings.po
language/Hindi (Devanagiri)/strings.po
language/Hungarian/strings.po
language/Icelandic/strings.po
language/Indonesian/strings.po
language/Italian/strings.po
language/Japanese/strings.po
language/Korean/strings.po
language/Latvian/strings.po
language/Lithuanian/strings.po
language/Macedonian/strings.po
language/Malay/strings.po
language/Maltese/strings.po
language/Norwegian/strings.po
language/Persian (Iran)/strings.po
language/Polish/strings.po
language/Portuguese (Brazil)/strings.po
language/Portuguese/strings.po
language/Romanian/strings.po
language/Russian/strings.po
language/Serbian (Cyrillic)/strings.po
language/Serbian/strings.po
language/Slovak/strings.po
language/Slovenian/strings.po
language/Spanish (Argentina)/strings.po
language/Spanish (Mexico)/strings.po
language/Spanish/strings.po
language/Swedish/strings.po
language/Tajik/strings.po
language/Tamil (India)/strings.po
language/Thai/strings.po
language/Turkish/strings.po
language/Ukrainian/strings.po
language/Uzbek/strings.po
language/Vietnamese (Viet Nam)/strings.po
language/Vietnamese/strings.po
language/Welsh/strings.po
lib/cximage-6.0/raw/libdcr.c
lib/ffmpeg/libavcodec/dxva2_vc1.c
lib/ffmpeg/libavcodec/vc1.c
lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch [new file with mode: 0644]
lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch [new file with mode: 0644]
lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch [new file with mode: 0644]
lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch [new file with mode: 0644]
lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch [new file with mode: 0644]
lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch [new file with mode: 0644]
lib/libUPnP/patches/0001-platinum-add-custom-Makefile.in.patch [new file with mode: 0644]
lib/libUPnP/patches/0002-UPnP-Platinum-log-allowed-values-with-state-variable.patch [new file with mode: 0644]
lib/libUPnP/patches/0003-UPnP-reinstated-changed-make-sure-Neptune-threads-ar.patch [new file with mode: 0644]
lib/libUPnP/patches/0004-UPnP-reinstated-fixed-upnp-server-s-http-server-woul.patch [new file with mode: 0644]
lib/libUPnP/patches/0005-UPnP-reinstated-UPnP-use-server-provided-item-count-.patch [new file with mode: 0644]
lib/libUPnP/patches/0006-upnp-report-and-support-proper-mimetypes-for-matrosk.patch [new file with mode: 0644]
lib/libUPnP/patches/0007-UPnP-Platinum-should-also-support-sort-criterias-in-.patch [new file with mode: 0644]
lib/libUPnP/patches/0008-Platinum-allow-some-statevariables-to-reset-to-defau.patch [new file with mode: 0644]
lib/libUPnP/patches/0009-UPnP-add-support-for-upnp-lastPlaybackPosition-upnp-.patch [new file with mode: 0644]
lib/libUPnP/patches/0010-Platinum-use-PersonRole-for-directors.-Also-fixes-Fr.patch [new file with mode: 0644]
lib/libUPnP/patches/0011-UPnP-support-video-ratings.patch [new file with mode: 0644]
lib/libUPnP/patches/0012-UPnP-increase-number-of-requested-items-per-iteratio.patch [new file with mode: 0644]
lib/libUPnP/patches/0013-upnp-fixes-support-for-filtering-by-the-extended-pro.patch [new file with mode: 0644]
lib/libUPnP/patches/0014-Platinum-switch-to-NPT_UInt64-for-bitmask-flags.patch [new file with mode: 0644]
lib/libUPnP/patches/0015-Platinum-fix-missing-filtering-for-extra-metadata.patch [new file with mode: 0644]
lib/libUPnP/patches/0016-osx-fix-compilation-by-using-the-right-suffix-for-64.patch [new file with mode: 0644]
lib/libUPnP/patches/0017-Platinum-don-t-disregard-PLT_MediaObjects-only-for-l.patch [new file with mode: 0644]
lib/libUPnP/patches/0018-Platinum-add-SetNextAVTransportURI-support-to-media-.patch [new file with mode: 0644]
lib/libUPnP/patches/0019-upnp-add-support-for-UpdateObject-action-to-Platinum.patch [new file with mode: 0644]
lib/libUPnP/patches/0020-fixed-compiler-warning-about-unused-var.patch [new file with mode: 0644]
lib/libUPnP/patches/0021-platinum-fix-shadowed-local-var.patch [new file with mode: 0644]
lib/libUPnP/patches/0022-fixed-compiler-warning.-album_art-is-never-used.patch [new file with mode: 0644]
lib/libUPnP/patches/0023-platinum-fix-parsing-of-upnp-actor-in-PltMediaItem.patch [new file with mode: 0644]
lib/libbluray/Makefile
lib/libdvd/build-xbmc-win32.sh
lib/libdvd/dvdread-config [new file with mode: 0755]
project/BuildDependencies/scripts/get_mingw_env.txt
project/BuildDependencies/scripts/harfbuzz_d.bat [deleted file]
project/BuildDependencies/scripts/harfbuzz_d.txt [deleted file]
project/VS2010Express/XBMC.vcxproj
project/VS2010Express/XBMC.vcxproj.filters
project/Win32BuildSetup/buildpvraddons.bat
system/Lircmap.xml
system/keymaps/remote.xml
system/settings/darwin.xml
system/settings/darwin_ios.xml
system/settings/rbp.xml
system/settings/settings.xml
system/settings/win32.xml
tools/Linux/xbmc.sh.in
tools/buildsteps/linux32/run-tests [new file with mode: 0755]
tools/buildsteps/linux64/run-tests [new file with mode: 0755]
tools/buildsteps/osx32/run-tests [new file with mode: 0755]
tools/buildsteps/osx64/run-tests [new file with mode: 0755]
tools/darwin/Configurations/App-iOS.xcconfig
tools/depends/target/boost/Makefile
tools/depends/target/boost/fix-self-assignment-warnings.patch [new file with mode: 0644]
tools/depends/target/curl/0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch [new file with mode: 0644]
tools/depends/target/curl/Makefile
tools/depends/target/libmpeg2/04-clang-fix.patch
tools/depends/target/libmpeg2/05-upstream-motion_comp_arm_s.S-is-not-PIC-enough.patch [new file with mode: 0644]
tools/depends/target/libmpeg2/Makefile
tools/depends/target/xbmc-pvr-addons/Makefile
xbmc/Application.cpp
xbmc/Application.h
xbmc/ApplicationMessenger.cpp
xbmc/ApplicationMessenger.h
xbmc/CueDocument.cpp
xbmc/CueDocument.h
xbmc/TextureDatabase.cpp
xbmc/TextureDatabase.h
xbmc/URL.cpp
xbmc/addons/AddonDatabase.cpp
xbmc/addons/AddonDatabase.h
xbmc/addons/AddonInstaller.cpp
xbmc/addons/AddonManager.cpp
xbmc/addons/AddonManager.h
xbmc/addons/GUIWindowAddonBrowser.cpp
xbmc/addons/Repository.cpp
xbmc/android/activity/XBMCApp.cpp
xbmc/cores/AudioEngine/AEFactory.cpp
xbmc/cores/AudioEngine/AEFactory.h
xbmc/cores/AudioEngine/AESinkFactory.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.h
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.h
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.cpp [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioAEHAL.h [deleted file]
xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioSource.h [deleted file]
xbmc/cores/AudioEngine/Interfaces/AE.h
xbmc/cores/AudioEngine/Makefile.in
xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp
xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.h
xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp
xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp [new file with mode: 0644]
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h [new file with mode: 0644]
xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
xbmc/cores/VideoRenderers/OverlayRenderer.cpp
xbmc/cores/VideoRenderers/OverlayRendererGUI.cpp
xbmc/cores/VideoRenderers/OverlayRendererUtil.cpp
xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp
xbmc/cores/VideoRenderers/WinRenderer.cpp
xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h
xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp [deleted file]
xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h [deleted file]
xbmc/cores/dvdplayer/DVDCodecs/Audio/Makefile.in
xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/AMLCodec.h
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.cpp [new file with mode: 0644]
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DllLibMpeg2.h
xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in
xbmc/cores/dvdplayer/DVDCodecs/Video/VAAPI.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
xbmc/cores/dvdplayer/DVDPlayer.cpp
xbmc/cores/dvdplayer/DVDPlayer.h
xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp
xbmc/cores/dvdplayer/DVDPlayerSubtitle.h
xbmc/cores/omxplayer/OMXPlayer.cpp
xbmc/cores/omxplayer/OMXPlayer.h
xbmc/dbwrappers/Database.cpp
xbmc/dbwrappers/Database.h
xbmc/dbwrappers/dataset.h
xbmc/dbwrappers/mysqldataset.cpp
xbmc/dbwrappers/mysqldataset.h
xbmc/dbwrappers/sqlitedataset.cpp
xbmc/dbwrappers/sqlitedataset.h
xbmc/dialogs/GUIDialogBusy.cpp
xbmc/dialogs/GUIDialogBusy.h
xbmc/epg/EpgDatabase.cpp
xbmc/epg/EpgDatabase.h
xbmc/filesystem/AddonsDirectory.cpp
xbmc/filesystem/DllLibCurl.cpp
xbmc/filesystem/DllLibCurl.h
xbmc/filesystem/FavouritesDirectory.cpp
xbmc/filesystem/test/TestNfsFile.cpp
xbmc/guilib/AnimatedGif.cpp
xbmc/guilib/AnimatedGif.h
xbmc/guilib/GUIFixedListContainer.cpp
xbmc/guilib/GUIFont.cpp
xbmc/guilib/GUIKeyboard.h
xbmc/guilib/GUIKeyboardFactory.cpp
xbmc/guilib/GUIKeyboardFactory.h
xbmc/guilib/GUIRSSControl.cpp
xbmc/guilib/GUIScrollBarControl.cpp
xbmc/input/ButtonTranslator.cpp
xbmc/input/ButtonTranslator.h
xbmc/input/SDLJoystick.cpp
xbmc/input/touch/generic/GenericTouchActionHandler.cpp
xbmc/interfaces/Builtins.cpp
xbmc/interfaces/json-rpc/AudioLibrary.cpp
xbmc/interfaces/json-rpc/FileItemHandler.cpp
xbmc/interfaces/json-rpc/InputOperations.cpp
xbmc/linux/LinuxTimezone.cpp
xbmc/linux/LinuxTimezone.h
xbmc/listproviders/DirectoryProvider.cpp
xbmc/music/Album.cpp
xbmc/music/MusicDatabase.cpp
xbmc/music/MusicDatabase.h
xbmc/music/Song.cpp
xbmc/network/Network.cpp
xbmc/network/WakeOnAccess.cpp
xbmc/network/WakeOnAccess.h
xbmc/network/upnp/UPnPPlayer.cpp
xbmc/osx/IOSEAGLView.mm
xbmc/osx/IOSScreenManager.mm
xbmc/osx/ios/IOSKeyboard.h
xbmc/osx/ios/IOSKeyboard.mm
xbmc/osx/ios/IOSKeyboardView.h
xbmc/osx/ios/IOSKeyboardView.mm
xbmc/osx/ios/XBMCApplication.h
xbmc/osx/ios/XBMCApplication.m
xbmc/osx/ios/XBMCController.h
xbmc/osx/ios/XBMCController.mm
xbmc/profiles/ProfilesManager.cpp
xbmc/profiles/ProfilesManager.h
xbmc/pvr/PVRDatabase.cpp
xbmc/pvr/PVRDatabase.h
xbmc/pvr/PVRManager.cpp
xbmc/rendering/RenderSystem.h
xbmc/rendering/dx/RenderSystemDX.cpp
xbmc/rendering/dx/RenderSystemDX.h
xbmc/settings/AdvancedSettings.cpp
xbmc/settings/AdvancedSettings.h
xbmc/settings/Settings.cpp
xbmc/settings/dialogs/GUIDialogContentSettings.cpp
xbmc/settings/lib/ISettingsHandler.h
xbmc/settings/lib/Setting.cpp
xbmc/settings/lib/SettingsManager.cpp
xbmc/settings/lib/SettingsManager.h
xbmc/utils/AMLUtils.cpp
xbmc/utils/ActorProtocol.cpp
xbmc/utils/ActorProtocol.h
xbmc/utils/LangCodeExpander.cpp
xbmc/utils/test/TestCharsetConverter.cpp
xbmc/video/GUIViewStateVideo.cpp
xbmc/video/VideoDatabase.cpp
xbmc/video/VideoDatabase.h
xbmc/video/dialogs/GUIDialogSubtitles.cpp
xbmc/video/dialogs/GUIDialogVideoInfo.cpp
xbmc/video/windows/GUIWindowFullScreen.cpp
xbmc/video/windows/GUIWindowVideoNav.cpp
xbmc/view/ViewDatabase.cpp
xbmc/view/ViewDatabase.h
xbmc/win32/IMMNotificationClient.h [new file with mode: 0644]
xbmc/win32/XBMC_PC.cpp
xbmc/windowing/XBMC_events.h
xbmc/windowing/osx/WinSystemIOS.h
xbmc/windowing/osx/WinSystemIOS.mm
xbmc/windowing/osx/WinSystemOSX.mm
xbmc/windowing/windows/WinSystemWin32.cpp
xbmc/windowing/windows/WinSystemWin32.h

index 65ca4a6..555417f 100644 (file)
@@ -66,6 +66,8 @@ config.log
 .project
 .cproject
 
+/nbproject
+
 # /
 /.dummy
 /.dummy.in
@@ -210,6 +212,7 @@ lib/cmyth/Makefile
 /lib/gtest/build-aux/config.h
 /lib/gtest/build-aux/config.h.in~
 /lib/gtest/build-aux/stamp-h1
+/lib/gtest/build-aux/test-driver
 /lib/gtest/fused-src/
 /lib/gtest/lib/
 /lib/gtest/libtool
index 428b67c..8eda3c4 100644 (file)
@@ -176,12 +176,9 @@ ifeq (@HAVE_XBMC_NONFREE@,1)
 DIRECTORY_ARCHIVES += lib/UnrarXLib/UnrarXLib.a
 endif
 
-BIN_DIRS = $(dir $(DIRECTORY_ARCHIVES)) $(dir $(NWAOBJSXBMC))
-
 ifeq (@USE_ANDROID@,1)
 DIRECTORY_ARCHIVES += xbmc/android/loader/AndroidDyload.a
 DIRECTORY_ARCHIVES += xbmc/windowing/android/windowing_android.a
-DIRECTORY_ARCHIVES += xbmc/android/activity/activity.a
 DIRECTORY_ARCHIVES += xbmc/android/bionic_supplement/bionic_supplement.a
 DIRECTORY_ARCHIVES += xbmc/android/jni/jni.a
 endif
@@ -271,9 +268,6 @@ TOUCHED_MEDIA=addons/skin.touched/media
 SKIN_DIRS+=$(TOUCHED_MEDIA)
 endif
 
-DIRS= $(BIN_DIRS) $(EC_DIRS) $(XBMCTEX_DIRS) $(DVDPCODECS_DIRS) $(PAPCODECS_DIRS) \
-       $(LIB_DIRS) $(SS_DIRS) $(VIS_DIRS) $(LIBADDON_DIRS) $(SKIN_DIRS) xbmc/main
-
 LIBS=@LIBS@
 CFLAGS=@CFLAGS@
 CXXFLAGS=@CXXFLAGS@
@@ -361,12 +355,6 @@ endif
 xbmc/cores/paplayer/paplayer.a: papcodecs
 $(DVDPLAYER_ARCHIVES)         : dvdpcodecs
 
-$(NWAOBJSXBMC): force
-       @$(MAKE) $(if $(V),,-s) -C $(@D)
-
-$(DIRECTORY_ARCHIVES): force
-       @$(MAKE) $(if $(V),,-s) -C $(@D)
-
 lib/cpluff/libcpluff/.libs/libcpluff.a: force
        $(MAKE) -C lib/cpluff/libcpluff
 system/libcpluff-@ARCH@.so: lib/cpluff/libcpluff/.libs/libcpluff.a exports
@@ -469,8 +457,6 @@ xcode_depends: \
        lib/libXDAAP/libxdaap.a \
        lib/SlingboxLib/SlingboxLib.a
 
-OBJSXBMC =$(DIRECTORY_ARCHIVES)
-
 DYNOBJSXBMC= \
        xbmc/linux/linux.a \
        xbmc/network/network.a \
@@ -489,25 +475,38 @@ DYNOBJSXBMC+= xbmc/freebsd/freebsd.a
 endif
 
 ifeq (@USE_STATIC_FFMPEG@,1)
-DYNOBJSXBMC += lib/ffmpeg/libavcodec/libavcodec.a \
-               lib/ffmpeg/libavfilter/libavfilter.a \
-               lib/ffmpeg/libswresample/libswresample.a \
-               lib/ffmpeg/libavformat/libavformat.a \
-               lib/ffmpeg/libavutil/libavutil.a \
-               lib/ffmpeg/libpostproc/libpostproc.a \
-               lib/ffmpeg/libswscale/libswscale.a
+FFMPEGOBJS = lib/ffmpeg/libavcodec/libavcodec.a \
+             lib/ffmpeg/libavfilter/libavfilter.a \
+             lib/ffmpeg/libswresample/libswresample.a \
+             lib/ffmpeg/libavformat/libavformat.a \
+             lib/ffmpeg/libavutil/libavutil.a \
+             lib/ffmpeg/libpostproc/libpostproc.a \
+             lib/ffmpeg/libswscale/libswscale.a
+DYNOBJSXBMC+= $(FFMPEGOBJS)
 LIBS+= @GNUTLS_ALL_LIBS@ @VORBISENC_ALL_LIBS@
+
+$(FFMPEGOBJS): dvdpcodecs
 endif
 
+ifneq (@USE_LIBXBMC@,1)
+MAINOBJS+=xbmc/main/main.a
+else
+ifeq (@USE_ANDROID@,1)
+MAINOBJS+=xbmc/android/activity/activity.a
+endif # USE_ANDROID
+endif # USE_LIBXBMC
+
+
+OBJSXBMC =$(DIRECTORY_ARCHIVES)
 OBJSXBMC:=$(filter-out $(DYNOBJSXBMC), $(OBJSXBMC))
 
-MAINOBJS=xbmc/xbmc.o
-ifeq (@USE_ANDROID@,1)
-MAINOBJS+=xbmc/android/activity/android_main.o
-endif
-ifneq (@USE_LIBXBMC@,1)
-MAINOBJS+=xbmc/main/main.o
-endif
+BIN_DIRS = $(dir $(DIRECTORY_ARCHIVES)) $(dir $(NWAOBJSXBMC)) $(dir $(MAINOBJS))
+
+DIRS= $(BIN_DIRS) $(EC_DIRS) $(XBMCTEX_DIRS) $(DVDPCODECS_DIRS) $(PAPCODECS_DIRS) \
+       $(LIB_DIRS) $(SS_DIRS) $(VIS_DIRS) $(LIBADDON_DIRS) $(SKIN_DIRS) xbmc/main
+
+$(NWAOBJSXBMC) $(DIRECTORY_ARCHIVES) $(MAINOBJS): force
+       @$(MAKE) $(if $(V),,-s) -C $(@D)
 
 # sync these entries manually with tools/depends/target/xbmc-addon-bindings/Makefile
 BINDINGS =xbmc/addons/include/xbmc_addon_cpp_dll.h
@@ -530,20 +529,17 @@ BINDINGS+=xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPacket.h
 
 libxbmc.so: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS)
 ifeq ($(findstring osx,@ARCH@), osx)
-       $(SILENT_LD) $(CXX) $(LDFLAGS) -bundle -o $@ -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -read_only_relocs suppress
+       $(SILENT_LD) $(CXX) $(LDFLAGS) -bundle -o $@ $(MAINOBJS) -Wl,-all_load,-ObjC $(MAINOBJS) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -read_only_relocs suppress
 else
-       $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ $(MAINOBJS) -Wl,--start-group $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group -Wl,--no-undefined $(NWAOBJSXBMC) $(LIBS)
+       $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ -Wl,--whole-archive $(MAINOBJS) -Wl,--no-whole-archive,--start-group $(MAINOBJS) $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group -Wl,--no-undefined $(NWAOBJSXBMC) $(LIBS)
 endif
 
-xbmc/main/main.a: force
-       $(MAKE) -C xbmc/main
-
-xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS) xbmc/main/main.a
+xbmc.bin: $(OBJSXBMC) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(MAINOBJS)
 
 ifeq ($(findstring osx,@ARCH@), osx)
-       $(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin xbmc/main/main.a -Wl,-all_load,-ObjC $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic
+       $(SILENT_LD) $(CXX) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,-all_load,-ObjC $(MAINOBJS) $(DYNOBJSXBMC) $(NWAOBJSXBMC) $(OBJSXBMC) $(LIBS) -rdynamic
 else
-       $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,--start-group $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group $(NWAOBJSXBMC) $(LIBS) -rdynamic
+       $(SILENT_LD) $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xbmc.bin $(MAINOBJS) -Wl,--start-group $(MAINOBJS) $(DYNOBJSXBMC) $(OBJSXBMC) -Wl,--end-group $(NWAOBJSXBMC) $(LIBS) -rdynamic
 endif
 
 xbmc-xrandr: xbmc-xrandr.c
index ae59e25..8e5fe7e 100644 (file)
                7C89619213B6A16F003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89619013B6A16F003631FE /* GUIWindowScreensaverDim.cpp */; };
                7C8A14571154CB2600E5FCFA /* TextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A14541154CB2600E5FCFA /* TextureCache.cpp */; };
                7C8A187D115B2A8200E5FCFA /* TextureDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */; };
+               7C8AE84E189DE3CD00C33786 /* CoreAudioChannelLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE849189DE3CD00C33786 /* CoreAudioChannelLayout.cpp */; };
+               7C8AE84F189DE3CD00C33786 /* CoreAudioDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE84A189DE3CD00C33786 /* CoreAudioDevice.cpp */; };
+               7C8AE850189DE3CD00C33786 /* CoreAudioHardware.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE84B189DE3CD00C33786 /* CoreAudioHardware.cpp */; };
+               7C8AE851189DE3CD00C33786 /* CoreAudioStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE84C189DE3CD00C33786 /* CoreAudioStream.cpp */; };
+               7C8AE854189DE47F00C33786 /* CoreAudioHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE852189DE47400C33786 /* CoreAudioHelpers.cpp */; };
                7C8FC6EE1829A4580045153D /* DirectoryProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8FC6EC1829A4580045153D /* DirectoryProvider.cpp */; };
                7C8FC6EF1829A4580045153D /* DirectoryProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8FC6EC1829A4580045153D /* DirectoryProvider.cpp */; };
                7C8FC6F01829A4580045153D /* DirectoryProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8FC6EC1829A4580045153D /* DirectoryProvider.cpp */; };
                DF3488E713FD958F0026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF3488E513FD958F0026A711 /* GUIAction.cpp */; };
                DF34892A13FD9C780026A711 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34892813FD9C780026A711 /* AirPlayServer.cpp */; };
                DF34898213FDAAF60026A711 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34898113FDAAF60026A711 /* HttpParser.cpp */; };
+               DF374B2418AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE852189DE47400C33786 /* CoreAudioHelpers.cpp */; };
+               DF374B2518AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8AE852189DE47400C33786 /* CoreAudioHelpers.cpp */; };
                DF3C3C0E1752A7EE000989C3 /* IOSEAGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910D7174E4A6400741B6D /* IOSEAGLView.mm */; };
                DF3C3C0F1752A7EE000989C3 /* IOSExternalTouchController.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910D9174E4A6400741B6D /* IOSExternalTouchController.mm */; };
                DF3C3C101752A7EE000989C3 /* IOSScreenManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = E49910DB174E4A6400741B6D /* IOSScreenManager.mm */; };
                DFB25D48163D4743006C4A48 /* WindowXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF1AD1EC15FCE77900E10810 /* WindowXML.cpp */; };
                DFB65FB515373AE7006B8FF1 /* AEFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6515373AE7006B8FF1 /* AEFactory.cpp */; };
                DFB65FB715373AE7006B8FF1 /* AEEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6A15373AE7006B8FF1 /* AEEncoderFFmpeg.cpp */; };
-               DFB65FB815373AE7006B8FF1 /* CoreAudioAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6D15373AE7006B8FF1 /* CoreAudioAE.cpp */; };
-               DFB65FB915373AE7006B8FF1 /* CoreAudioAEHAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6F15373AE7006B8FF1 /* CoreAudioAEHAL.cpp */; };
-               DFB65FBA15373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7115373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp */; };
-               DFB65FBB15373AE7006B8FF1 /* CoreAudioAEHALOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7315373AE7006B8FF1 /* CoreAudioAEHALOSX.cpp */; };
-               DFB65FBC15373AE7006B8FF1 /* CoreAudioAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7515373AE7006B8FF1 /* CoreAudioAESound.cpp */; };
-               DFB65FBD15373AE7006B8FF1 /* CoreAudioAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7715373AE7006B8FF1 /* CoreAudioAEStream.cpp */; };
                DFB65FCC15373AE7006B8FF1 /* AEBitstreamPacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA315373AE7006B8FF1 /* AEBitstreamPacker.cpp */; };
                DFB65FCD15373AE7006B8FF1 /* AEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA515373AE7006B8FF1 /* AEBuffer.cpp */; };
                DFB65FCE15373AE7006B8FF1 /* AEChannelInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA715373AE7006B8FF1 /* AEChannelInfo.cpp */; };
                DFF0F13617528350002DA3A4 /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE0443315828F4B005DDB4D /* Exception.cpp */; };
                DFF0F13717528350002DA3A4 /* ilog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC720A8D155091BB00FFD782 /* ilog.cpp */; };
                DFF0F13817528350002DA3A4 /* AEEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6A15373AE7006B8FF1 /* AEEncoderFFmpeg.cpp */; };
-               DFF0F13917528350002DA3A4 /* CoreAudioAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6D15373AE7006B8FF1 /* CoreAudioAE.cpp */; };
-               DFF0F13A17528350002DA3A4 /* CoreAudioAEHAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6F15373AE7006B8FF1 /* CoreAudioAEHAL.cpp */; };
-               DFF0F13B17528350002DA3A4 /* CoreAudioAEHALIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7115373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp */; };
-               DFF0F13C17528350002DA3A4 /* CoreAudioAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7515373AE7006B8FF1 /* CoreAudioAESound.cpp */; };
-               DFF0F13D17528350002DA3A4 /* CoreAudioAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7715373AE7006B8FF1 /* CoreAudioAEStream.cpp */; };
                DFF0F13E17528350002DA3A4 /* AEBitstreamPacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA315373AE7006B8FF1 /* AEBitstreamPacker.cpp */; };
                DFF0F13F17528350002DA3A4 /* AEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA515373AE7006B8FF1 /* AEBuffer.cpp */; };
                DFF0F14017528350002DA3A4 /* AEChannelInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA715373AE7006B8FF1 /* AEChannelInfo.cpp */; };
                DFF0F15917528350002DA3A4 /* DVDAudioCodecLibMad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E150F0D25F9F900618676 /* DVDAudioCodecLibMad.cpp */; };
                DFF0F15A17528350002DA3A4 /* DVDAudioCodecLPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E15110D25F9F900618676 /* DVDAudioCodecLPcm.cpp */; };
                DFF0F15B17528350002DA3A4 /* DVDAudioCodecPassthrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB6610615374E80006B8FF1 /* DVDAudioCodecPassthrough.cpp */; };
-               DFF0F15C17528350002DA3A4 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */; };
                DFF0F15D17528350002DA3A4 /* DVDAudioCodecPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E15150D25F9F900618676 /* DVDAudioCodecPcm.cpp */; };
                DFF0F15E17528350002DA3A4 /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */; };
                DFF0F15F17528350002DA3A4 /* DVDOverlayCodecCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E152B0D25F9F900618676 /* DVDOverlayCodecCC.cpp */; };
                E4991196174E5CEB00741B6D /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE0443315828F4B005DDB4D /* Exception.cpp */; };
                E4991197174E5CEB00741B6D /* ilog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC720A8D155091BB00FFD782 /* ilog.cpp */; };
                E4991198174E5CF600741B6D /* AEEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6A15373AE7006B8FF1 /* AEEncoderFFmpeg.cpp */; };
-               E4991199174E5CFA00741B6D /* CoreAudioAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6D15373AE7006B8FF1 /* CoreAudioAE.cpp */; };
-               E499119A174E5CFA00741B6D /* CoreAudioAEHAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F6F15373AE7006B8FF1 /* CoreAudioAEHAL.cpp */; };
-               E499119B174E5CFA00741B6D /* CoreAudioAEHALIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7115373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp */; };
-               E499119D174E5CFA00741B6D /* CoreAudioAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7515373AE7006B8FF1 /* CoreAudioAESound.cpp */; };
-               E499119E174E5CFA00741B6D /* CoreAudioAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65F7715373AE7006B8FF1 /* CoreAudioAEStream.cpp */; };
                E49911A6174E5CFE00741B6D /* AEBitstreamPacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA315373AE7006B8FF1 /* AEBitstreamPacker.cpp */; };
                E49911A7174E5CFE00741B6D /* AEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA515373AE7006B8FF1 /* AEBuffer.cpp */; };
                E49911A8174E5CFE00741B6D /* AEChannelInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB65FA715373AE7006B8FF1 /* AEChannelInfo.cpp */; };
                E49911C1174E5D2500741B6D /* DVDAudioCodecLibMad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E150F0D25F9F900618676 /* DVDAudioCodecLibMad.cpp */; };
                E49911C2174E5D2500741B6D /* DVDAudioCodecLPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E15110D25F9F900618676 /* DVDAudioCodecLPcm.cpp */; };
                E49911C3174E5D2500741B6D /* DVDAudioCodecPassthrough.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFB6610615374E80006B8FF1 /* DVDAudioCodecPassthrough.cpp */; };
-               E49911C4174E5D2500741B6D /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */; };
                E49911C5174E5D2500741B6D /* DVDAudioCodecPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E15150D25F9F900618676 /* DVDAudioCodecPcm.cpp */; };
                E49911C6174E5D2500741B6D /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */; };
                E49911C7174E5D2500741B6D /* DVDOverlayCodecCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E152B0D25F9F900618676 /* DVDOverlayCodecCC.cpp */; };
                F58E293911FFC103006F4D46 /* DVDInputStreamBluray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F58E293711FFC103006F4D46 /* DVDInputStreamBluray.cpp */; };
                F592568810FBF2E100D2C91D /* ConvolutionKernels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F592568710FBF2E100D2C91D /* ConvolutionKernels.cpp */; };
                F595994510E9F322004B58B3 /* DVDVideoCodecCrystalHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F595994410E9F322004B58B3 /* DVDVideoCodecCrystalHD.cpp */; };
+               F597B05B18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F597B05A18A804E0005AADAE /* DVDVideoCodec.cpp */; };
+               F597B05C18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F597B05A18A804E0005AADAE /* DVDVideoCodec.cpp */; };
+               F597B05D18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F597B05A18A804E0005AADAE /* DVDVideoCodec.cpp */; };
                F59876C00FBA351D008EF4FB /* VideoReferenceClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F59876BF0FBA351D008EF4FB /* VideoReferenceClock.cpp */; };
                F59879080FBAA0C3008EF4FB /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F59879070FBAA0C3008EF4FB /* QuartzCore.framework */; };
                F5987F050FBDF274008EF4FB /* DPMSSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5987F040FBDF274008EF4FB /* DPMSSupport.cpp */; };
                F5BDB80C120202F400F0B710 /* DVDSubtitleTagSami.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB80B120202F400F0B710 /* DVDSubtitleTagSami.cpp */; };
                F5BDB81A1202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB8191202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp */; };
                F5BDB820120203C200F0B710 /* AutoPtrHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */; };
+               F5CC228B1814F7E9006B5E91 /* AESinkDARWINOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22891814F7E9006B5E91 /* AESinkDARWINOSX.cpp */; };
+               F5CC228E1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */; };
+               F5CC228F1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */; };
+               F5CC22DF1814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; };
+               F5CC22E01814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; };
+               F5CC22E11814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; };
+               F5CC22E21814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; };
+               F5CC22E31814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; };
+               F5CC22E41814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; };
+               F5CC22E51814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; };
+               F5CC22E61814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; };
+               F5CC22E71814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; };
+               F5CC22E81814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; };
+               F5CC22E91814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; };
+               F5CC22EA1814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; };
+               F5CC22EB1814FF3B006B5E91 /* ActiveAE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */; };
+               F5CC22EC1814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */; };
+               F5CC22ED1814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */; };
+               F5CC22EE1814FF3B006B5E91 /* ActiveAESink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */; };
+               F5CC22EF1814FF3B006B5E91 /* ActiveAESound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */; };
+               F5CC22F01814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */; };
+               F5CC22FD18150065006B5E91 /* ActorProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22FB18150065006B5E91 /* ActorProtocol.cpp */; };
+               F5CC22FE18150065006B5E91 /* ActorProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22FB18150065006B5E91 /* ActorProtocol.cpp */; };
+               F5CC22FF18150065006B5E91 /* ActorProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC22FB18150065006B5E91 /* ActorProtocol.cpp */; };
+               F5CC2303181500B1006B5E91 /* EndianSwap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC2302181500B1006B5E91 /* EndianSwap.cpp */; };
+               F5CC2304181500B1006B5E91 /* EndianSwap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC2302181500B1006B5E91 /* EndianSwap.cpp */; };
+               F5CC2305181500B1006B5E91 /* EndianSwap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC2302181500B1006B5E91 /* EndianSwap.cpp */; };
+               F5CC230C18150118006B5E91 /* AESinkFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC230A18150118006B5E91 /* AESinkFactory.cpp */; };
+               F5CC230D18150118006B5E91 /* AESinkFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC230A18150118006B5E91 /* AESinkFactory.cpp */; };
+               F5CC230E18150118006B5E91 /* AESinkFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC230A18150118006B5E91 /* AESinkFactory.cpp */; };
+               F5CC234718150277006B5E91 /* AESinkNULL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC234518150277006B5E91 /* AESinkNULL.cpp */; };
+               F5CC234818150277006B5E91 /* AESinkNULL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC234518150277006B5E91 /* AESinkNULL.cpp */; };
+               F5CC234918150277006B5E91 /* AESinkNULL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC234518150277006B5E91 /* AESinkNULL.cpp */; };
+               F5CC238818150768006B5E91 /* AESinkProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC238618150768006B5E91 /* AESinkProfiler.cpp */; };
+               F5CC238918150768006B5E91 /* AESinkProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC238618150768006B5E91 /* AESinkProfiler.cpp */; };
+               F5CC238A18150768006B5E91 /* AESinkProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CC238618150768006B5E91 /* AESinkProfiler.cpp */; };
                F5CEE60913D3C89700225F72 /* DVDOverlayCodecTX3G.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5CEE60713D3C89700225F72 /* DVDOverlayCodecTX3G.cpp */; };
                F5D8D732102BB3B1004A11AB /* OverlayRendererGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D8D72F102BB3B1004A11AB /* OverlayRendererGL.cpp */; };
                F5D8D733102BB3B1004A11AB /* OverlayRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D8D731102BB3B1004A11AB /* OverlayRenderer.cpp */; };
                F5ED8D6C1551F91400842059 /* BlurayDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED8D6A1551F91400842059 /* BlurayDirectory.cpp */; };
                F5ED908815538DCE00842059 /* XBMCTinyXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED908615538DCE00842059 /* XBMCTinyXML.cpp */; };
                F5ED908E15538E2300842059 /* POUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED908C15538E2300842059 /* POUtils.cpp */; };
-               F5ED942E155D729500842059 /* CoreAudioDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED942A155D729500842059 /* CoreAudioDevice.cpp */; };
-               F5ED942F155D729500842059 /* CoreAudioHardware.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED942C155D729500842059 /* CoreAudioHardware.cpp */; };
-               F5ED943E155D743700842059 /* CoreAudioStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED943C155D743700842059 /* CoreAudioStream.cpp */; };
-               F5ED9462155D777B00842059 /* CoreAudioChannelLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED9460155D777B00842059 /* CoreAudioChannelLayout.cpp */; };
-               F5ED9496155D7B9900842059 /* CoreAudioMixMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED9494155D7B9900842059 /* CoreAudioMixMap.cpp */; };
-               F5ED94AB155D7F8000842059 /* CoreAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED94A9155D7F8000842059 /* CoreAudioUnit.cpp */; };
-               F5ED9509155D855200842059 /* CoreAudioGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED9507155D855200842059 /* CoreAudioGraph.cpp */; };
                F5ED9A0C155EBDC000842059 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E38E238E0D2626E600618676 /* CoreAudio.framework */; };
                F5ED9A15155EBE0000842059 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88ECB6580DE013C4003396A7 /* DiskArbitration.framework */; };
                F5ED9BFB155EC77400842059 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E38E25340D26365C00618676 /* ApplicationServices.framework */; };
                F5EDC48C1651A6F900B852D8 /* GroupUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5EDC48A1651A6F900B852D8 /* GroupUtils.cpp */; };
                F5F240EF110A4F76009126C6 /* CrystalHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F240EB110A4F76009126C6 /* CrystalHD.cpp */; };
                F5F244651110DC6B009126C6 /* FileOperationJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F244641110DC6B009126C6 /* FileOperationJob.cpp */; };
-               F5F245DA1112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */; };
                F5F245EE1112C9AB009126C6 /* FileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245EC1112C9AB009126C6 /* FileUtils.cpp */; };
                F5F2EF4B0E593E0D0092C37F /* DVDFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F2EF4A0E593E0D0092C37F /* DVDFileInfo.cpp */; };
                F5F8E1DA0E427E8000A8E96F /* VGMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F8E1D90E427E8000A8E96F /* VGMCodec.cpp */; };
                7C8A14551154CB2600E5FCFA /* TextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCache.h; sourceTree = "<group>"; };
                7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureDatabase.cpp; sourceTree = "<group>"; };
                7C8A187B115B2A8200E5FCFA /* TextureDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureDatabase.h; sourceTree = "<group>"; };
+               7C8AE844189DE3CD00C33786 /* CoreAudioChannelLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioChannelLayout.h; path = Sinks/osx/CoreAudioChannelLayout.h; sourceTree = "<group>"; };
+               7C8AE845189DE3CD00C33786 /* CoreAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioDevice.h; path = Sinks/osx/CoreAudioDevice.h; sourceTree = "<group>"; };
+               7C8AE846189DE3CD00C33786 /* CoreAudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioHardware.h; path = Sinks/osx/CoreAudioHardware.h; sourceTree = "<group>"; };
+               7C8AE847189DE3CD00C33786 /* CoreAudioStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioStream.h; path = Sinks/osx/CoreAudioStream.h; sourceTree = "<group>"; };
+               7C8AE849189DE3CD00C33786 /* CoreAudioChannelLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioChannelLayout.cpp; path = Sinks/osx/CoreAudioChannelLayout.cpp; sourceTree = "<group>"; };
+               7C8AE84A189DE3CD00C33786 /* CoreAudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioDevice.cpp; path = Sinks/osx/CoreAudioDevice.cpp; sourceTree = "<group>"; };
+               7C8AE84B189DE3CD00C33786 /* CoreAudioHardware.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioHardware.cpp; path = Sinks/osx/CoreAudioHardware.cpp; sourceTree = "<group>"; };
+               7C8AE84C189DE3CD00C33786 /* CoreAudioStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioStream.cpp; path = Sinks/osx/CoreAudioStream.cpp; sourceTree = "<group>"; };
+               7C8AE852189DE47400C33786 /* CoreAudioHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioHelpers.cpp; path = Sinks/osx/CoreAudioHelpers.cpp; sourceTree = "<group>"; };
+               7C8AE853189DE47700C33786 /* CoreAudioHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioHelpers.h; path = Sinks/osx/CoreAudioHelpers.h; sourceTree = "<group>"; };
                7C8FC6EC1829A4580045153D /* DirectoryProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DirectoryProvider.cpp; path = xbmc/listproviders/DirectoryProvider.cpp; sourceTree = SOURCE_ROOT; };
                7C8FC6ED1829A4580045153D /* DirectoryProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryProvider.h; path = xbmc/listproviders/DirectoryProvider.h; sourceTree = SOURCE_ROOT; };
                7C920CF7181669FF00DA1477 /* TextureOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureOperations.cpp; sourceTree = "<group>"; };
                DFB65F6615373AE7006B8FF1 /* AEFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFactory.h; sourceTree = "<group>"; };
                DFB65F6A15373AE7006B8FF1 /* AEEncoderFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AEEncoderFFmpeg.cpp; sourceTree = "<group>"; };
                DFB65F6B15373AE7006B8FF1 /* AEEncoderFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEEncoderFFmpeg.h; sourceTree = "<group>"; };
-               DFB65F6D15373AE7006B8FF1 /* CoreAudioAE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAE.cpp; path = CoreAudio/CoreAudioAE.cpp; sourceTree = "<group>"; };
-               DFB65F6E15373AE7006B8FF1 /* CoreAudioAE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAE.h; path = CoreAudio/CoreAudioAE.h; sourceTree = "<group>"; };
-               DFB65F6F15373AE7006B8FF1 /* CoreAudioAEHAL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAEHAL.cpp; path = CoreAudio/CoreAudioAEHAL.cpp; sourceTree = "<group>"; };
-               DFB65F7015373AE7006B8FF1 /* CoreAudioAEHAL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAEHAL.h; path = CoreAudio/CoreAudioAEHAL.h; sourceTree = "<group>"; };
-               DFB65F7115373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAEHALIOS.cpp; path = CoreAudio/CoreAudioAEHALIOS.cpp; sourceTree = "<group>"; };
-               DFB65F7215373AE7006B8FF1 /* CoreAudioAEHALIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAEHALIOS.h; path = CoreAudio/CoreAudioAEHALIOS.h; sourceTree = "<group>"; };
-               DFB65F7315373AE7006B8FF1 /* CoreAudioAEHALOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAEHALOSX.cpp; path = CoreAudio/CoreAudioAEHALOSX.cpp; sourceTree = "<group>"; };
-               DFB65F7415373AE7006B8FF1 /* CoreAudioAEHALOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAEHALOSX.h; path = CoreAudio/CoreAudioAEHALOSX.h; sourceTree = "<group>"; };
-               DFB65F7515373AE7006B8FF1 /* CoreAudioAESound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAESound.cpp; path = CoreAudio/CoreAudioAESound.cpp; sourceTree = "<group>"; };
-               DFB65F7615373AE7006B8FF1 /* CoreAudioAESound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAESound.h; path = CoreAudio/CoreAudioAESound.h; sourceTree = "<group>"; };
-               DFB65F7715373AE7006B8FF1 /* CoreAudioAEStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioAEStream.cpp; path = CoreAudio/CoreAudioAEStream.cpp; sourceTree = "<group>"; };
-               DFB65F7815373AE7006B8FF1 /* CoreAudioAEStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioAEStream.h; path = CoreAudio/CoreAudioAEStream.h; sourceTree = "<group>"; };
-               DFB65F7A15373AE7006B8FF1 /* ICoreAudioAEHAL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ICoreAudioAEHAL.h; path = CoreAudio/ICoreAudioAEHAL.h; sourceTree = "<group>"; };
-               DFB65F7B15373AE7006B8FF1 /* ICoreAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ICoreAudioSource.h; path = CoreAudio/ICoreAudioSource.h; sourceTree = "<group>"; };
                DFB65F8915373AE7006B8FF1 /* AE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AE.h; sourceTree = "<group>"; };
                DFB65F8A15373AE7006B8FF1 /* AEEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEEncoder.h; sourceTree = "<group>"; };
                DFB65F8C15373AE7006B8FF1 /* AESink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESink.h; sourceTree = "<group>"; };
                F592568710FBF2E100D2C91D /* ConvolutionKernels.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvolutionKernels.cpp; sourceTree = "<group>"; };
                F595994310E9F322004B58B3 /* DVDVideoCodecCrystalHD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDVideoCodecCrystalHD.h; sourceTree = "<group>"; };
                F595994410E9F322004B58B3 /* DVDVideoCodecCrystalHD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDVideoCodecCrystalHD.cpp; sourceTree = "<group>"; };
+               F597B05A18A804E0005AADAE /* DVDVideoCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDVideoCodec.cpp; sourceTree = "<group>"; };
                F59876BE0FBA351D008EF4FB /* VideoReferenceClock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoReferenceClock.h; sourceTree = "<group>"; };
                F59876BF0FBA351D008EF4FB /* VideoReferenceClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoReferenceClock.cpp; sourceTree = "<group>"; };
                F59879070FBAA0C3008EF4FB /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
                F5BDB8191202032400F0B710 /* DVDSubtitleTagMicroDVD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleTagMicroDVD.cpp; sourceTree = "<group>"; };
                F5BDB81E120203C200F0B710 /* AutoPtrHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoPtrHandle.h; sourceTree = "<group>"; };
                F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoPtrHandle.cpp; sourceTree = "<group>"; };
+               F5CC22891814F7E9006B5E91 /* AESinkDARWINOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkDARWINOSX.cpp; path = Sinks/AESinkDARWINOSX.cpp; sourceTree = "<group>"; };
+               F5CC228A1814F7E9006B5E91 /* AESinkDARWINOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESinkDARWINOSX.h; path = Sinks/AESinkDARWINOSX.h; sourceTree = "<group>"; };
+               F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkDARWINIOS.cpp; path = Sinks/AESinkDARWINIOS.cpp; sourceTree = "<group>"; };
+               F5CC228D1814F7F7006B5E91 /* AESinkDARWINIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESinkDARWINIOS.h; path = Sinks/AESinkDARWINIOS.h; sourceTree = "<group>"; };
+               F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAE.cpp; sourceTree = "<group>"; };
+               F5CC22D41814FF3B006B5E91 /* ActiveAE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAE.h; sourceTree = "<group>"; };
+               F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEBuffer.cpp; sourceTree = "<group>"; };
+               F5CC22D61814FF3B006B5E91 /* ActiveAEBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEBuffer.h; sourceTree = "<group>"; };
+               F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEResample.cpp; sourceTree = "<group>"; };
+               F5CC22D81814FF3B006B5E91 /* ActiveAEResample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEResample.h; sourceTree = "<group>"; };
+               F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAESink.cpp; sourceTree = "<group>"; };
+               F5CC22DA1814FF3B006B5E91 /* ActiveAESink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAESink.h; sourceTree = "<group>"; };
+               F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAESound.cpp; sourceTree = "<group>"; };
+               F5CC22DC1814FF3B006B5E91 /* ActiveAESound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAESound.h; sourceTree = "<group>"; };
+               F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveAEStream.cpp; sourceTree = "<group>"; };
+               F5CC22DE1814FF3B006B5E91 /* ActiveAEStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveAEStream.h; sourceTree = "<group>"; };
+               F5CC22FB18150065006B5E91 /* ActorProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActorProtocol.cpp; sourceTree = "<group>"; };
+               F5CC22FC18150065006B5E91 /* ActorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActorProtocol.h; sourceTree = "<group>"; };
+               F5CC2302181500B1006B5E91 /* EndianSwap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EndianSwap.cpp; sourceTree = "<group>"; };
+               F5CC230A18150118006B5E91 /* AESinkFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AESinkFactory.cpp; sourceTree = "<group>"; };
+               F5CC230B18150118006B5E91 /* AESinkFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESinkFactory.h; sourceTree = "<group>"; };
+               F5CC234518150277006B5E91 /* AESinkNULL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkNULL.cpp; path = Sinks/AESinkNULL.cpp; sourceTree = "<group>"; };
+               F5CC234618150277006B5E91 /* AESinkNULL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESinkNULL.h; path = Sinks/AESinkNULL.h; sourceTree = "<group>"; };
+               F5CC238618150768006B5E91 /* AESinkProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AESinkProfiler.cpp; path = Sinks/AESinkProfiler.cpp; sourceTree = "<group>"; };
+               F5CC238718150768006B5E91 /* AESinkProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESinkProfiler.h; path = Sinks/AESinkProfiler.h; sourceTree = "<group>"; };
                F5CEE60713D3C89700225F72 /* DVDOverlayCodecTX3G.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodecTX3G.cpp; sourceTree = "<group>"; };
                F5CEE60813D3C89700225F72 /* DVDOverlayCodecTX3G.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDOverlayCodecTX3G.h; sourceTree = "<group>"; };
                F5D8D72E102BB3B1004A11AB /* OverlayRendererGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverlayRendererGL.h; sourceTree = "<group>"; };
                F5ED908715538DCE00842059 /* XBMCTinyXML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCTinyXML.h; sourceTree = "<group>"; };
                F5ED908C15538E2300842059 /* POUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = POUtils.cpp; sourceTree = "<group>"; };
                F5ED908D15538E2300842059 /* POUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = POUtils.h; sourceTree = "<group>"; };
-               F5ED942A155D729500842059 /* CoreAudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioDevice.cpp; path = CoreAudio/CoreAudioDevice.cpp; sourceTree = "<group>"; };
-               F5ED942B155D729500842059 /* CoreAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioDevice.h; path = CoreAudio/CoreAudioDevice.h; sourceTree = "<group>"; };
-               F5ED942C155D729500842059 /* CoreAudioHardware.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioHardware.cpp; path = CoreAudio/CoreAudioHardware.cpp; sourceTree = "<group>"; };
-               F5ED942D155D729500842059 /* CoreAudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioHardware.h; path = CoreAudio/CoreAudioHardware.h; sourceTree = "<group>"; };
-               F5ED943C155D743700842059 /* CoreAudioStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioStream.cpp; path = CoreAudio/CoreAudioStream.cpp; sourceTree = "<group>"; };
-               F5ED943D155D743700842059 /* CoreAudioStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioStream.h; path = CoreAudio/CoreAudioStream.h; sourceTree = "<group>"; };
-               F5ED9460155D777B00842059 /* CoreAudioChannelLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioChannelLayout.cpp; path = CoreAudio/CoreAudioChannelLayout.cpp; sourceTree = "<group>"; };
-               F5ED9461155D777B00842059 /* CoreAudioChannelLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioChannelLayout.h; path = CoreAudio/CoreAudioChannelLayout.h; sourceTree = "<group>"; };
-               F5ED9494155D7B9900842059 /* CoreAudioMixMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioMixMap.cpp; path = CoreAudio/CoreAudioMixMap.cpp; sourceTree = "<group>"; };
-               F5ED9495155D7B9900842059 /* CoreAudioMixMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioMixMap.h; path = CoreAudio/CoreAudioMixMap.h; sourceTree = "<group>"; };
-               F5ED94A9155D7F8000842059 /* CoreAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioUnit.cpp; path = CoreAudio/CoreAudioUnit.cpp; sourceTree = "<group>"; };
-               F5ED94AA155D7F8000842059 /* CoreAudioUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioUnit.h; path = CoreAudio/CoreAudioUnit.h; sourceTree = "<group>"; };
-               F5ED9507155D855200842059 /* CoreAudioGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioGraph.cpp; path = CoreAudio/CoreAudioGraph.cpp; sourceTree = "<group>"; };
-               F5ED9508155D855200842059 /* CoreAudioGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioGraph.h; path = CoreAudio/CoreAudioGraph.h; sourceTree = "<group>"; };
                F5EDC48A1651A6F900B852D8 /* GroupUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GroupUtils.cpp; sourceTree = "<group>"; };
                F5EDC48B1651A6F900B852D8 /* GroupUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupUtils.h; sourceTree = "<group>"; };
                F5F240EB110A4F76009126C6 /* CrystalHD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrystalHD.cpp; sourceTree = "<group>"; };
                F5F240EC110A4F76009126C6 /* CrystalHD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrystalHD.h; sourceTree = "<group>"; };
                F5F244631110DC6B009126C6 /* FileOperationJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileOperationJob.h; sourceTree = "<group>"; };
                F5F244641110DC6B009126C6 /* FileOperationJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileOperationJob.cpp; sourceTree = "<group>"; };
-               F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDAudioCodecPassthroughFFmpeg.cpp; sourceTree = "<group>"; };
-               F5F245D91112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudioCodecPassthroughFFmpeg.h; sourceTree = "<group>"; };
                F5F245EC1112C9AB009126C6 /* FileUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUtils.cpp; sourceTree = "<group>"; };
                F5F245ED1112C9AB009126C6 /* FileUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUtils.h; sourceTree = "<group>"; };
                F5F2EF490E593E0D0092C37F /* DVDFileInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DVDFileInfo.h; sourceTree = "<group>"; };
                        path = info;
                        sourceTree = "<group>";
                };
+               7C8AE7FE189DE3A700C33786 /* osx */ = {
+                       isa = PBXGroup;
+                       children = (
+                               7C8AE849189DE3CD00C33786 /* CoreAudioChannelLayout.cpp */,
+                               7C8AE844189DE3CD00C33786 /* CoreAudioChannelLayout.h */,
+                               7C8AE84A189DE3CD00C33786 /* CoreAudioDevice.cpp */,
+                               7C8AE845189DE3CD00C33786 /* CoreAudioDevice.h */,
+                               7C8AE84B189DE3CD00C33786 /* CoreAudioHardware.cpp */,
+                               7C8AE846189DE3CD00C33786 /* CoreAudioHardware.h */,
+                               7C8AE852189DE47400C33786 /* CoreAudioHelpers.cpp */,
+                               7C8AE853189DE47700C33786 /* CoreAudioHelpers.h */,
+                               7C8AE84C189DE3CD00C33786 /* CoreAudioStream.cpp */,
+                               7C8AE847189DE3CD00C33786 /* CoreAudioStream.h */,
+                       );
+                       name = osx;
+                       sourceTree = "<group>";
+               };
                810C9F5F0D67BCC80095F5DD /* MediaConnect */ = {
                        isa = PBXGroup;
                        children = (
                                DFB65F6C15373AE7006B8FF1 /* Engines */,
                                DFB65F8815373AE7006B8FF1 /* Interfaces */,
                                DFB65FA215373AE7006B8FF1 /* Utils */,
+                               F5CC22851814F7B5006B5E91 /* Sinks */,
                                DFB65F6515373AE7006B8FF1 /* AEFactory.cpp */,
                                DFB65F6615373AE7006B8FF1 /* AEFactory.h */,
+                               F5CC230A18150118006B5E91 /* AESinkFactory.cpp */,
+                               F5CC230B18150118006B5E91 /* AESinkFactory.h */,
                        );
                        path = AudioEngine;
                        sourceTree = "<group>";
                DFB65F6C15373AE7006B8FF1 /* Engines */ = {
                        isa = PBXGroup;
                        children = (
-                               F5ED9362155CECC800842059 /* CoreAudio */,
+                               F5CC22D21814FF3B006B5E91 /* ActiveAE */,
                        );
                        path = Engines;
                        sourceTree = "<group>";
                                E38E15120D25F9F900618676 /* DVDAudioCodecLPcm.h */,
                                DFB6610615374E80006B8FF1 /* DVDAudioCodecPassthrough.cpp */,
                                DFB6610715374E80006B8FF1 /* DVDAudioCodecPassthrough.h */,
-                               F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */,
-                               F5F245D91112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.h */,
                                E38E15150D25F9F900618676 /* DVDAudioCodecPcm.cpp */,
                                E38E15160D25F9F900618676 /* DVDAudioCodecPcm.h */,
                        );
                                F5F240EB110A4F76009126C6 /* CrystalHD.cpp */,
                                F5F240EC110A4F76009126C6 /* CrystalHD.h */,
                                E38E153B0D25F9F900618676 /* DllLibMpeg2.h */,
+                               F597B05A18A804E0005AADAE /* DVDVideoCodec.cpp */,
                                E38E153C0D25F9F900618676 /* DVDVideoCodec.h */,
                                F595994410E9F322004B58B3 /* DVDVideoCodecCrystalHD.cpp */,
                                F595994310E9F322004B58B3 /* DVDVideoCodecCrystalHD.h */,
                E38E1E220D25F9FD00618676 /* utils */ = {
                        isa = PBXGroup;
                        children = (
+                               F5CC22FB18150065006B5E91 /* ActorProtocol.cpp */,
+                               F5CC22FC18150065006B5E91 /* ActorProtocol.h */,
                                E38E1E230D25F9FD00618676 /* AlarmClock.cpp */,
                                E38E1E240D25F9FD00618676 /* AlarmClock.h */,
                                F5A9D3081097C9370050490F /* AliasShortcutUtils.cpp */,
                                36A9443C15821E2800727135 /* DatabaseUtils.h */,
                                7CC30E8816296078003E7579 /* EdenVideoArtUpdater.cpp */,
                                7CC30E8916296078003E7579 /* EdenVideoArtUpdater.h */,
+                               F5CC2302181500B1006B5E91 /* EndianSwap.cpp */,
                                436B38F3106628850049AB3B /* EndianSwap.h */,
                                DF529BAC1741697B00523FB4 /* Environment.cpp */,
                                DF529BAD1741697B00523FB4 /* Environment.h */,
                        path = "json-rpc";
                        sourceTree = "<group>";
                };
+               F5CC22851814F7B5006B5E91 /* Sinks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               7C8AE7FE189DE3A700C33786 /* osx */,
+                               F5CC228C1814F7F7006B5E91 /* AESinkDARWINIOS.cpp */,
+                               F5CC228D1814F7F7006B5E91 /* AESinkDARWINIOS.h */,
+                               F5CC22891814F7E9006B5E91 /* AESinkDARWINOSX.cpp */,
+                               F5CC228A1814F7E9006B5E91 /* AESinkDARWINOSX.h */,
+                               F5CC234518150277006B5E91 /* AESinkNULL.cpp */,
+                               F5CC234618150277006B5E91 /* AESinkNULL.h */,
+                               F5CC238618150768006B5E91 /* AESinkProfiler.cpp */,
+                               F5CC238718150768006B5E91 /* AESinkProfiler.h */,
+                       );
+                       name = Sinks;
+                       sourceTree = "<group>";
+               };
+               F5CC22D21814FF3B006B5E91 /* ActiveAE */ = {
+                       isa = PBXGroup;
+                       children = (
+                               F5CC22D31814FF3B006B5E91 /* ActiveAE.cpp */,
+                               F5CC22D41814FF3B006B5E91 /* ActiveAE.h */,
+                               F5CC22D51814FF3B006B5E91 /* ActiveAEBuffer.cpp */,
+                               F5CC22D61814FF3B006B5E91 /* ActiveAEBuffer.h */,
+                               F5CC22D71814FF3B006B5E91 /* ActiveAEResample.cpp */,
+                               F5CC22D81814FF3B006B5E91 /* ActiveAEResample.h */,
+                               F5CC22D91814FF3B006B5E91 /* ActiveAESink.cpp */,
+                               F5CC22DA1814FF3B006B5E91 /* ActiveAESink.h */,
+                               F5CC22DB1814FF3B006B5E91 /* ActiveAESound.cpp */,
+                               F5CC22DC1814FF3B006B5E91 /* ActiveAESound.h */,
+                               F5CC22DD1814FF3B006B5E91 /* ActiveAEStream.cpp */,
+                               F5CC22DE1814FF3B006B5E91 /* ActiveAEStream.h */,
+                       );
+                       path = ActiveAE;
+                       sourceTree = "<group>";
+               };
                F5E1050C140AA38000175026 /* peripherals */ = {
                        isa = PBXGroup;
                        children = (
                        name = playercorefactory;
                        sourceTree = "<group>";
                };
-               F5ED9362155CECC800842059 /* CoreAudio */ = {
-                       isa = PBXGroup;
-                       children = (
-                               DFB65F6D15373AE7006B8FF1 /* CoreAudioAE.cpp */,
-                               DFB65F6E15373AE7006B8FF1 /* CoreAudioAE.h */,
-                               DFB65F6F15373AE7006B8FF1 /* CoreAudioAEHAL.cpp */,
-                               DFB65F7015373AE7006B8FF1 /* CoreAudioAEHAL.h */,
-                               DFB65F7115373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp */,
-                               DFB65F7215373AE7006B8FF1 /* CoreAudioAEHALIOS.h */,
-                               DFB65F7315373AE7006B8FF1 /* CoreAudioAEHALOSX.cpp */,
-                               DFB65F7415373AE7006B8FF1 /* CoreAudioAEHALOSX.h */,
-                               DFB65F7515373AE7006B8FF1 /* CoreAudioAESound.cpp */,
-                               DFB65F7615373AE7006B8FF1 /* CoreAudioAESound.h */,
-                               DFB65F7715373AE7006B8FF1 /* CoreAudioAEStream.cpp */,
-                               DFB65F7815373AE7006B8FF1 /* CoreAudioAEStream.h */,
-                               F5ED9460155D777B00842059 /* CoreAudioChannelLayout.cpp */,
-                               F5ED9461155D777B00842059 /* CoreAudioChannelLayout.h */,
-                               F5ED942A155D729500842059 /* CoreAudioDevice.cpp */,
-                               F5ED942B155D729500842059 /* CoreAudioDevice.h */,
-                               F5ED9507155D855200842059 /* CoreAudioGraph.cpp */,
-                               F5ED9508155D855200842059 /* CoreAudioGraph.h */,
-                               F5ED942C155D729500842059 /* CoreAudioHardware.cpp */,
-                               F5ED942D155D729500842059 /* CoreAudioHardware.h */,
-                               F5ED9494155D7B9900842059 /* CoreAudioMixMap.cpp */,
-                               F5ED9495155D7B9900842059 /* CoreAudioMixMap.h */,
-                               F5ED943C155D743700842059 /* CoreAudioStream.cpp */,
-                               F5ED943D155D743700842059 /* CoreAudioStream.h */,
-                               F5ED94A9155D7F8000842059 /* CoreAudioUnit.cpp */,
-                               F5ED94AA155D7F8000842059 /* CoreAudioUnit.h */,
-                               DFB65F7A15373AE7006B8FF1 /* ICoreAudioAEHAL.h */,
-                               DFB65F7B15373AE7006B8FF1 /* ICoreAudioSource.h */,
-                       );
-                       name = CoreAudio;
-                       sourceTree = "<group>";
-               };
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
                                E38E20440D25F9FD00618676 /* DirectoryNodeTop100.cpp in Sources */,
                                E38E20460D25F9FD00618676 /* DirectoryNodeYearAlbum.cpp in Sources */,
                                E38E20470D25F9FD00618676 /* DirectoryNodeYearSong.cpp in Sources */,
+                               F597B05B18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */,
                                E38E20490D25F9FD00618676 /* QueryParams.cpp in Sources */,
                                E38E204A0D25F9FD00618676 /* MusicDatabaseDirectory.cpp in Sources */,
                                E38E204B0D25F9FD00618676 /* MusicSearchDirectory.cpp in Sources */,
                                F5DC8801110A46C700EE1B15 /* ModplugCodec.cpp in Sources */,
                                F5F240EF110A4F76009126C6 /* CrystalHD.cpp in Sources */,
                                F5F244651110DC6B009126C6 /* FileOperationJob.cpp in Sources */,
-                               F5F245DA1112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */,
                                F5F245EE1112C9AB009126C6 /* FileUtils.cpp in Sources */,
                                F5A7A702112893E50059D6AA /* AnnouncementManager.cpp in Sources */,
                                F5A7A85B112908F00059D6AA /* WebServer.cpp in Sources */,
                                F5ED908E15538E2300842059 /* POUtils.cpp in Sources */,
                                DFB65FB515373AE7006B8FF1 /* AEFactory.cpp in Sources */,
                                DFB65FB715373AE7006B8FF1 /* AEEncoderFFmpeg.cpp in Sources */,
-                               DFB65FB815373AE7006B8FF1 /* CoreAudioAE.cpp in Sources */,
-                               DFB65FB915373AE7006B8FF1 /* CoreAudioAEHAL.cpp in Sources */,
-                               DFB65FBA15373AE7006B8FF1 /* CoreAudioAEHALIOS.cpp in Sources */,
-                               DFB65FBB15373AE7006B8FF1 /* CoreAudioAEHALOSX.cpp in Sources */,
-                               DFB65FBC15373AE7006B8FF1 /* CoreAudioAESound.cpp in Sources */,
-                               DFB65FBD15373AE7006B8FF1 /* CoreAudioAEStream.cpp in Sources */,
                                DFB65FCC15373AE7006B8FF1 /* AEBitstreamPacker.cpp in Sources */,
                                DFB65FCD15373AE7006B8FF1 /* AEBuffer.cpp in Sources */,
                                DFB65FCE15373AE7006B8FF1 /* AEChannelInfo.cpp in Sources */,
                                DFB65FD415373AE7006B8FF1 /* AEWAVLoader.cpp in Sources */,
                                DFB6610915374E80006B8FF1 /* DVDAudioCodecPassthrough.cpp in Sources */,
                                7C0B98A4154B79C30065A238 /* AEDeviceInfo.cpp in Sources */,
-                               F5ED942E155D729500842059 /* CoreAudioDevice.cpp in Sources */,
-                               F5ED942F155D729500842059 /* CoreAudioHardware.cpp in Sources */,
-                               F5ED943E155D743700842059 /* CoreAudioStream.cpp in Sources */,
-                               F5ED9462155D777B00842059 /* CoreAudioChannelLayout.cpp in Sources */,
-                               F5ED9496155D7B9900842059 /* CoreAudioMixMap.cpp in Sources */,
-                               F5ED94AB155D7F8000842059 /* CoreAudioUnit.cpp in Sources */,
-                               F5ED9509155D855200842059 /* CoreAudioGraph.cpp in Sources */,
                                7C6EB330155BD1D40080368A /* ImageFile.cpp in Sources */,
                                7C6EB6FA155F32C30080368A /* HTTPImageHandler.cpp in Sources */,
                                C84828C0156CFCD8005A996F /* PVRClient.cpp in Sources */,
                                7C1409A9184015C9009F9411 /* InfoExpression.cpp in Sources */,
                                AE32174218313ADF0003FAFC /* XSLTUtils.cpp in Sources */,
                                7C15DCBC1892481400FCE564 /* InfoBool.cpp in Sources */,
+                               F5CC228B1814F7E9006B5E91 /* AESinkDARWINOSX.cpp in Sources */,
+                               F5CC22EB1814FF3B006B5E91 /* ActiveAE.cpp in Sources */,
+                               F5CC22EC1814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */,
+                               F5CC22ED1814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */,
+                               F5CC22EE1814FF3B006B5E91 /* ActiveAESink.cpp in Sources */,
+                               F5CC22EF1814FF3B006B5E91 /* ActiveAESound.cpp in Sources */,
+                               F5CC22F01814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */,
+                               F5CC22FF18150065006B5E91 /* ActorProtocol.cpp in Sources */,
+                               F5CC2305181500B1006B5E91 /* EndianSwap.cpp in Sources */,
+                               F5CC230E18150118006B5E91 /* AESinkFactory.cpp in Sources */,
+                               F5CC234918150277006B5E91 /* AESinkNULL.cpp in Sources */,
+                               F5CC238A18150768006B5E91 /* AESinkProfiler.cpp in Sources */,
+                               7C8AE84E189DE3CD00C33786 /* CoreAudioChannelLayout.cpp in Sources */,
+                               7C8AE84F189DE3CD00C33786 /* CoreAudioDevice.cpp in Sources */,
+                               7C8AE850189DE3CD00C33786 /* CoreAudioHardware.cpp in Sources */,
+                               7C8AE851189DE3CD00C33786 /* CoreAudioStream.cpp in Sources */,
+                               7C8AE854189DE47F00C33786 /* CoreAudioHelpers.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                DFF0F13617528350002DA3A4 /* Exception.cpp in Sources */,
                                DFF0F13717528350002DA3A4 /* ilog.cpp in Sources */,
                                DFF0F13817528350002DA3A4 /* AEEncoderFFmpeg.cpp in Sources */,
-                               DFF0F13917528350002DA3A4 /* CoreAudioAE.cpp in Sources */,
-                               DFF0F13A17528350002DA3A4 /* CoreAudioAEHAL.cpp in Sources */,
-                               DFF0F13B17528350002DA3A4 /* CoreAudioAEHALIOS.cpp in Sources */,
-                               DFF0F13C17528350002DA3A4 /* CoreAudioAESound.cpp in Sources */,
-                               DFF0F13D17528350002DA3A4 /* CoreAudioAEStream.cpp in Sources */,
                                DFF0F13E17528350002DA3A4 /* AEBitstreamPacker.cpp in Sources */,
                                DFF0F13F17528350002DA3A4 /* AEBuffer.cpp in Sources */,
                                DFF0F14017528350002DA3A4 /* AEChannelInfo.cpp in Sources */,
                                DFF0F15917528350002DA3A4 /* DVDAudioCodecLibMad.cpp in Sources */,
                                DFF0F15A17528350002DA3A4 /* DVDAudioCodecLPcm.cpp in Sources */,
                                DFF0F15B17528350002DA3A4 /* DVDAudioCodecPassthrough.cpp in Sources */,
-                               DFF0F15C17528350002DA3A4 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */,
                                DFF0F15D17528350002DA3A4 /* DVDAudioCodecPcm.cpp in Sources */,
                                DFF0F15E17528350002DA3A4 /* DVDOverlayCodec.cpp in Sources */,
                                DFF0F15F17528350002DA3A4 /* DVDOverlayCodecCC.cpp in Sources */,
                                DFF0F2C417528350002DA3A4 /* TextureGL.cpp in Sources */,
                                DFF0F2C517528350002DA3A4 /* TextureManager.cpp in Sources */,
                                DFF0F2C617528350002DA3A4 /* VisibleEffect.cpp in Sources */,
+                               F597B05D18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */,
                                DFF0F2C717528350002DA3A4 /* XBTF.cpp in Sources */,
                                DFF0F2C817528350002DA3A4 /* XBTFReader.cpp in Sources */,
                                DFF0F2C917528350002DA3A4 /* GenericTouchActionHandler.cpp in Sources */,
                                7C1409AB184015C9009F9411 /* InfoExpression.cpp in Sources */,
                                AE32174318313AE10003FAFC /* XSLTUtils.cpp in Sources */,
                                7C15DCBE1892481400FCE564 /* InfoBool.cpp in Sources */,
+                               F5CC228F1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */,
+                               F5CC22E51814FF3B006B5E91 /* ActiveAE.cpp in Sources */,
+                               F5CC22E61814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */,
+                               F5CC22E71814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */,
+                               F5CC22E81814FF3B006B5E91 /* ActiveAESink.cpp in Sources */,
+                               F5CC22E91814FF3B006B5E91 /* ActiveAESound.cpp in Sources */,
+                               F5CC22EA1814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */,
+                               F5CC22FE18150065006B5E91 /* ActorProtocol.cpp in Sources */,
+                               F5CC2304181500B1006B5E91 /* EndianSwap.cpp in Sources */,
+                               F5CC230D18150118006B5E91 /* AESinkFactory.cpp in Sources */,
+                               F5CC234818150277006B5E91 /* AESinkNULL.cpp in Sources */,
+                               F5CC238918150768006B5E91 /* AESinkProfiler.cpp in Sources */,
+                               DF374B2518AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E4991196174E5CEB00741B6D /* Exception.cpp in Sources */,
                                E4991197174E5CEB00741B6D /* ilog.cpp in Sources */,
                                E4991198174E5CF600741B6D /* AEEncoderFFmpeg.cpp in Sources */,
-                               E4991199174E5CFA00741B6D /* CoreAudioAE.cpp in Sources */,
-                               E499119A174E5CFA00741B6D /* CoreAudioAEHAL.cpp in Sources */,
-                               E499119B174E5CFA00741B6D /* CoreAudioAEHALIOS.cpp in Sources */,
-                               E499119D174E5CFA00741B6D /* CoreAudioAESound.cpp in Sources */,
-                               E499119E174E5CFA00741B6D /* CoreAudioAEStream.cpp in Sources */,
                                E49911A6174E5CFE00741B6D /* AEBitstreamPacker.cpp in Sources */,
                                E49911A7174E5CFE00741B6D /* AEBuffer.cpp in Sources */,
                                E49911A8174E5CFE00741B6D /* AEChannelInfo.cpp in Sources */,
                                E49911C1174E5D2500741B6D /* DVDAudioCodecLibMad.cpp in Sources */,
                                E49911C2174E5D2500741B6D /* DVDAudioCodecLPcm.cpp in Sources */,
                                E49911C3174E5D2500741B6D /* DVDAudioCodecPassthrough.cpp in Sources */,
-                               E49911C4174E5D2500741B6D /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */,
                                E49911C5174E5D2500741B6D /* DVDAudioCodecPcm.cpp in Sources */,
                                E49911C6174E5D2500741B6D /* DVDOverlayCodec.cpp in Sources */,
                                E49911C7174E5D2500741B6D /* DVDOverlayCodecCC.cpp in Sources */,
                                E49911E1174E5D3700741B6D /* DVDInputStreamHTSP.cpp in Sources */,
                                E49911E2174E5D3700741B6D /* DVDInputStreamHttp.cpp in Sources */,
                                E49911E3174E5D3700741B6D /* DVDInputStreamMemory.cpp in Sources */,
+                               F597B05C18A804E0005AADAE /* DVDVideoCodec.cpp in Sources */,
                                E49911E4174E5D3700741B6D /* DVDInputStreamNavigator.cpp in Sources */,
                                E49911E5174E5D3700741B6D /* DVDInputStreamPVRManager.cpp in Sources */,
                                E49911E6174E5D3700741B6D /* DVDInputStreamRTMP.cpp in Sources */,
                                7C1409AA184015C9009F9411 /* InfoExpression.cpp in Sources */,
                                AE4E87A717354C4A00D15206 /* XSLTUtils.cpp in Sources */,
                                7C15DCBD1892481400FCE564 /* InfoBool.cpp in Sources */,
+                               F5CC228E1814F7F7006B5E91 /* AESinkDARWINIOS.cpp in Sources */,
+                               F5CC22DF1814FF3B006B5E91 /* ActiveAE.cpp in Sources */,
+                               F5CC22E01814FF3B006B5E91 /* ActiveAEBuffer.cpp in Sources */,
+                               F5CC22E11814FF3B006B5E91 /* ActiveAEResample.cpp in Sources */,
+                               F5CC22E21814FF3B006B5E91 /* ActiveAESink.cpp in Sources */,
+                               F5CC22E31814FF3B006B5E91 /* ActiveAESound.cpp in Sources */,
+                               F5CC22E41814FF3B006B5E91 /* ActiveAEStream.cpp in Sources */,
+                               F5CC22FD18150065006B5E91 /* ActorProtocol.cpp in Sources */,
+                               F5CC2303181500B1006B5E91 /* EndianSwap.cpp in Sources */,
+                               F5CC230C18150118006B5E91 /* AESinkFactory.cpp in Sources */,
+                               F5CC234718150277006B5E91 /* AESinkNULL.cpp in Sources */,
+                               F5CC238818150768006B5E91 /* AESinkProfiler.cpp in Sources */,
+                               DF374B2418AC2BA20076B514 /* CoreAudioHelpers.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                        "-lswresample",
                                        "-lswscale",
                                        "-ltag",
+                                       "-lxslt",
+                                       "-lxml2",
                                        "-L$XBMC_DEPENDS/lib/mysql",
                                        "-lmysqlclient",
-                                       "-lxslt",
-                                       "-lmpeg2",
                                );
                                PLIST_FILE_OUTPUT_FORMAT = xml;
                                PREBINDING = NO;
                                        "-lswresample",
                                        "-lswscale",
                                        "-ltag",
+                                       "-lxslt",
+                                       "-lxml2",
                                        "-L$XBMC_DEPENDS/lib/mysql",
                                        "-lmysqlclient",
-                                       "-lxslt",
-                                       "-lmpeg2",
                                );
                                PLIST_FILE_OUTPUT_FORMAT = xml;
                                PREBINDING = NO;
index a2d5a99..6c27a39 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.pvr-android.xbmc.org"
                name="XBMC.org PVR Add-ons"
-               version="1.1.2"
+               version="1.1.3"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -28,6 +28,8 @@
                <summary lang="et">Paigalda videosalvesti lisasid lehelt XBMC.org</summary>
                <summary lang="fr_CA">Installer l'extension du magnétoscope numérique depuis XBMC.org</summary>
                <summary lang="gl">Instalar Engadidos de PVR dende XBMC.org</summary>
+               <summary lang="he">התקן הרחבות PVR מ-XBMC.org</summary>
+               <summary lang="hr">Instaliraj PVR dodatke s XBMC.org</summary>
                <summary lang="hu">PVR kiegészítők telepítése az XBMC.org-ról</summary>
                <summary lang="ko">XBMC.org에서 PVR 추가기능 설치</summary>
                <summary lang="lt">Įdiekite PVR priedą iš XBMC.org</summary>
@@ -40,8 +42,9 @@
                <summary lang="sl">Namestite dodatke PVR z XBMC.org</summary>
                <summary lang="sv">Installera PVR-tillägg från XBMC.org</summary>
                <summary lang="tg">Насб кардани барномаи иловагии PVR аз XBMC.org</summary>
+               <summary lang="tr">XBMC.org'dan PVR Eklentilerini Yükle</summary>
                <summary lang="zh">从 XBMC.org 安装 PVR 插件</summary>
-               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org.[CR] Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR] Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="de">Lade und installiere PVR Add-Ons aus dem offiziellen XBMC.org Add-On Depot.[CR]  Durch die Nutzung des offiziellen Depots profitieren Sie vom umfangreichen Datei-Verteilsystem, welches hilft schneller Downloads in Ihrer Nähe bereitzustellen.[CR] Alle Add-Ons dieses Depots wurden grundlegender Prüfungen unterzogen, sollte ein Add-On dennoch Fehler haben oder nicht funktionieren melden Sie dies bitte an das Team XBMC, damit die nötigen Schritte eingeleitet werden können.</description>
                <description lang="el">Λήψη και εγκατάσταση πρόσθετων από το επίσημο αποθετήριο του XBMC.org.[CR]  Χρησιμοποιώντας το Επίσημο Αποθετήριο μπορείτε να εκμεταλλευτείτε τους εκτεταμένους διακομιστές αρχείων μας για ταχύτερες λήψεις από μία κοντινή σας περιοχή.[CR]  Όλα τα πρόσθετα σε αυτό το αποθετήριο έχουν περάσει τις στοιχειώδεις δοκιμές, αν βρείτε ένα κατεστραμμένο ή ανενεργό πρόσθετο παρακαλούμε να το αναφέρετε στην Ομάδα XBMC ούτως ώστε να ληφθούν οι απαραίτητες ενέργειες.</description>
                <description lang="en">Download and install PVR add-ons from the Official XBMC.org add-on repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All add-ons on this repository have under gone basic testing, if you find a broken or not working add-on please report it to Team XBMC so we can take any action needed.</description>
@@ -52,6 +55,7 @@
                <description lang="et">Lae alla ja installi videosalvesti lisasid ametlikust XBMC.org hoidlast.[CR]  Ametliku hoidla kasutamise eeliseks on võimalus kasutada meie ulatuslikku failide peegelteenust laadides faile sulle kõige lähemast serverist.[CR]  Kõik lisad selles hoidlas on läbinud elementaarse testimise. Siiski, kui sa leiad vigase või mittetöötava lisa, siis palun teavita sellest XBMC meeskonda, et me saaksime vajaliku abi osutada.</description>
                <description lang="fr_CA">Télécharger et installer l'extension du magnétoscope numérique depuis le dépôt officiel de XBMC.org.[CR] En utilisant le dépôt officiel vous pourrez bénéficier de notre service étendu de miroir de fichiers favorisant des téléchargements plus rapides depuis une région proche de vous.[CR] Toutes les extensions de ce dépôt ont subit des tests de base. Si vous trouvez une extension non fonctionnelle ou brisée, veuillez la rapporter à l'équipe XBMC afin que nous puissions agir.</description>
                <description lang="gl">Descargar e instalar Engadidos de PVR dende o repositorio oficial de XBMC.org.[CR] Empregando o repositorio oficial, vostede poderá disfrutar das vantaxes do seu extenso servizo de replicación de ficheiros para axudar a descargas rápidas dende unha rexión preto a vostede.[CR] Tódolos Engadidos deste repositorio pasaron por comprobacións básicas. Se atopa algún Engadido roto ou non funcional, por favor reporteo ó equipo de XBMC para que poidan actuar en consecuencia.</description>
+               <description lang="hr">Preuzmite i instalirajte PVR dodatke sa službenog XBMC.org repozitorija dodataka.[CR]  Korištenjm službenog repozitorija biti ćete u mogućnosti iskoristiti prednost našeg zrcalnog poslužitelja u svrhu bržeg preuzimanja iz regije bliže vama.[CR]  Svi dodaci na ovom repozitoriju prošli su osnovno testiranje. Ako pronađete slomljeni ili dodatak koji ne radi, prijavite ga XBMC timu da ga možemo popraviti.</description>
                <description lang="hu">PVR Kiegészítők letöltése és telepítése a hivatalos XBMC.org tárolóhelyről.[CR] A hivatalos tárolóhely használatával kihasználhatod szerteágazó tükör-kiszolgáló hálózatunkat, ami segít a gyorsabb letöltésben egy hozzád közelebb eső körzet használatával.[CR]  Minden kiegészítő ezen a tárolóhelyen átment egy alaptesztelésen. Ha mégis hibás vagy nem működő kiegészítőt találsz, kérünk jelezd az XBMC csapatnak, hogy megtegyük a szükséges lépéseket.</description>
                <description lang="ko">공식 XBMC.org 추가기능 저장소에서 PVR 추가기능을 다운로드하여 설치합니다.[CR] 공식 저장소를 사용하면 파일 미러링 서비스를 통해 사용자와 가까운 곳에서 빠르게 다운로드할 수 있습니다.[CR] 저장소의 모든 추가기능은 기본 테스트를 거치지만 작동이 되지 않거나 손상된 추가기능을 발견하면 필요한 조치를 취할 수 있게 Team XBMC로 알려주시기 바랍니다.</description>
                <description lang="lt">Atsisiųskite ir įdiekite PVR priedą iš oficialios XBMC.org priedų saugyklos. [Cr] Naudojant oficialią saugyklą galėsite pasinaudoti mūsų  failų Veidrodine saugyklos paslauga katra padės jums greičiau parsisiųsti iš artimiausios vietos šalia jūsų. [CR] Visi priedai šioje saugykloje yra perėję pagrindinį testavimą, jei atsisiuntėte neveikiantį ar/arba sugadintą priedą praneškite 'Team XBMC', kad galėtume imtis visų būtinų priemonių klaidai ištaisyti.</description>
@@ -64,6 +68,7 @@
                <description lang="sl">Prenos in namestitev dodatkov PVR iz uradnega skladišča XBMC.org.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi XBMC, da bomo lahko odpravili napake.</description>
                <description lang="sv">Ladda ner och installera PVR-tillägg från det officiella XBMC.org tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som hjälper dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team XBMC så att vi kan vidta nödvändiga åtgärder.</description>
                <description lang="tg">Барномаҳои иловагии PVR-ро аз анбори нармафзори расмии XBMC.org боргирӣ кунед ва насб кунед.[CR]  Агар анбори нармафзори расмиро истифода баред, метавонед нармафзори иловагиро аз серверҳои наздиктарин ба шумо боргирӣ намоед.[CR]  Ҳамаи нармафзори анбори зикршуда аз санҷиши асосӣ мегузаранд, ва агар шумо ягон барномаи иловагии вайроншуда ё ғайрифаъолро пайдо кунед, метавонед дар бораи он гузоришро ба Гурӯҳи кории XBMC фиристонед, то ки барномасозон тавонанд камбудиҳои пайдошударо ҳал кунанд.</description>
+               <description lang="tr">PVR Eklentilerini Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装 PVR 插件。[CR] 通过官方程序库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有失效或不能正常工作的插件,请向 XBMC 开发团队报告,以便及时处理。</description>
                <disclaimer lang="af">Die XBMC span het nie al die byvoegsels in die kodebank gemaak nie en is nie verantwoordelik vir hulle inhoud nie</disclaimer>
                <disclaimer lang="ar">فريق برنامج إكس بى إم سى لم يُصنِع جميع اﻹضافات فى هذا المستودع وغير مسؤول عن ما قد تسببه لك</disclaimer>
index de5e46a..cec9135 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.pvr-ios.xbmc.org"
                name="XBMC.org PVR Add-ons"
-               version="1.1.2"
+               version="1.1.3"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -28,6 +28,8 @@
                <summary lang="et">Paigalda videosalvesti lisasid lehelt XBMC.org</summary>
                <summary lang="fr_CA">Installer l'extension du magnétoscope numérique depuis XBMC.org</summary>
                <summary lang="gl">Instalar Engadidos de PVR dende XBMC.org</summary>
+               <summary lang="he">התקן הרחבות PVR מ-XBMC.org</summary>
+               <summary lang="hr">Instaliraj PVR dodatke s XBMC.org</summary>
                <summary lang="hu">PVR kiegészítők telepítése az XBMC.org-ról</summary>
                <summary lang="ko">XBMC.org에서 PVR 추가기능 설치</summary>
                <summary lang="lt">Įdiekite PVR priedą iš XBMC.org</summary>
@@ -40,8 +42,9 @@
                <summary lang="sl">Namestite dodatke PVR z XBMC.org</summary>
                <summary lang="sv">Installera PVR-tillägg från XBMC.org</summary>
                <summary lang="tg">Насб кардани барномаи иловагии PVR аз XBMC.org</summary>
+               <summary lang="tr">XBMC.org'dan PVR Eklentilerini Yükle</summary>
                <summary lang="zh">从 XBMC.org 安装 PVR 插件</summary>
-               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org.[CR] Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR] Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="de">Lade und installiere PVR Add-Ons aus dem offiziellen XBMC.org Add-On Depot.[CR]  Durch die Nutzung des offiziellen Depots profitieren Sie vom umfangreichen Datei-Verteilsystem, welches hilft schneller Downloads in Ihrer Nähe bereitzustellen.[CR] Alle Add-Ons dieses Depots wurden grundlegender Prüfungen unterzogen, sollte ein Add-On dennoch Fehler haben oder nicht funktionieren melden Sie dies bitte an das Team XBMC, damit die nötigen Schritte eingeleitet werden können.</description>
                <description lang="el">Λήψη και εγκατάσταση πρόσθετων από το επίσημο αποθετήριο του XBMC.org.[CR]  Χρησιμοποιώντας το Επίσημο Αποθετήριο μπορείτε να εκμεταλλευτείτε τους εκτεταμένους διακομιστές αρχείων μας για ταχύτερες λήψεις από μία κοντινή σας περιοχή.[CR]  Όλα τα πρόσθετα σε αυτό το αποθετήριο έχουν περάσει τις στοιχειώδεις δοκιμές, αν βρείτε ένα κατεστραμμένο ή ανενεργό πρόσθετο παρακαλούμε να το αναφέρετε στην Ομάδα XBMC ούτως ώστε να ληφθούν οι απαραίτητες ενέργειες.</description>
                <description lang="en">Download and install PVR add-ons from the Official XBMC.org add-on repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All add-ons on this repository have under gone basic testing, if you find a broken or not working add-on please report it to Team XBMC so we can take any action needed.</description>
@@ -52,6 +55,7 @@
                <description lang="et">Lae alla ja installi videosalvesti lisasid ametlikust XBMC.org hoidlast.[CR]  Ametliku hoidla kasutamise eeliseks on võimalus kasutada meie ulatuslikku failide peegelteenust laadides faile sulle kõige lähemast serverist.[CR]  Kõik lisad selles hoidlas on läbinud elementaarse testimise. Siiski, kui sa leiad vigase või mittetöötava lisa, siis palun teavita sellest XBMC meeskonda, et me saaksime vajaliku abi osutada.</description>
                <description lang="fr_CA">Télécharger et installer l'extension du magnétoscope numérique depuis le dépôt officiel de XBMC.org.[CR] En utilisant le dépôt officiel vous pourrez bénéficier de notre service étendu de miroir de fichiers favorisant des téléchargements plus rapides depuis une région proche de vous.[CR] Toutes les extensions de ce dépôt ont subit des tests de base. Si vous trouvez une extension non fonctionnelle ou brisée, veuillez la rapporter à l'équipe XBMC afin que nous puissions agir.</description>
                <description lang="gl">Descargar e instalar Engadidos de PVR dende o repositorio oficial de XBMC.org.[CR] Empregando o repositorio oficial, vostede poderá disfrutar das vantaxes do seu extenso servizo de replicación de ficheiros para axudar a descargas rápidas dende unha rexión preto a vostede.[CR] Tódolos Engadidos deste repositorio pasaron por comprobacións básicas. Se atopa algún Engadido roto ou non funcional, por favor reporteo ó equipo de XBMC para que poidan actuar en consecuencia.</description>
+               <description lang="hr">reuzmite i instalirajte PVR dodatke sa službenog XBMC.org repozitorija dodataka.[CR]  Korištenjm službenog repozitorija biti ćete u mogućnosti iskoristiti prednost našeg zrcalnog poslužitelja u svrhu bržeg preuzimanja iz regije bliže vama.[CR]  Svi dodaci na ovom repozitoriju prošli su osnovno testiranje. Ako pronađete slomljeni ili dodatak koji ne radi, prijavite ga XBMC timu da ga možemo popraviti.</description>
                <description lang="hu">PVR Kiegészítők letöltése és telepítése a hivatalos XBMC.org tárolóhelyről.[CR] A hivatalos tárolóhely használatával kihasználhatod szerteágazó tükör-kiszolgáló hálózatunkat, ami segít a gyorsabb letöltésben egy hozzád közelebb eső körzet használatával.[CR]  Minden kiegészítő ezen a tárolóhelyen átment egy alaptesztelésen. Ha mégis hibás vagy nem működő kiegészítőt találsz, kérünk jelezd az XBMC csapatnak, hogy megtegyük a szükséges lépéseket.</description>
                <description lang="ko">공식 XBMC.org 추가기능 저장소에서 PVR 추가기능을 다운로드하여 설치합니다.[CR] 공식 저장소를 사용하면 파일 미러링 서비스를 통해 사용자와 가까운 곳에서 빠르게 다운로드할 수 있습니다.[CR] 저장소의 모든 추가기능은 기본 테스트를 거치지만 작동이 되지 않거나 손상된 추가기능을 발견하면 필요한 조치를 취할 수 있게 Team XBMC로 알려주시기 바랍니다.</description>
                <description lang="lt">Atsisiųskite ir įdiekite PVR priedą iš oficialios XBMC.org priedų saugyklos. [Cr] Naudojant oficialią saugyklą galėsite pasinaudoti mūsų  failų Veidrodine saugyklos paslauga katra padės jums greičiau parsisiųsti iš artimiausios vietos šalia jūsų. [CR] Visi priedai šioje saugykloje yra perėję pagrindinį testavimą, jei atsisiuntėte neveikiantį ar/arba sugadintą priedą praneškite 'Team XBMC', kad galėtume imtis visų būtinų priemonių klaidai ištaisyti.</description>
@@ -64,6 +68,7 @@
                <description lang="sl">Prenos in namestitev dodatkov PVR iz uradnega skladišča XBMC.org.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi XBMC, da bomo lahko odpravili napake.</description>
                <description lang="sv">Ladda ner och installera PVR-tillägg från det officiella XBMC.org tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som hjälper dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team XBMC så att vi kan vidta nödvändiga åtgärder.</description>
                <description lang="tg">Барномаҳои иловагии PVR-ро аз анбори нармафзори расмии XBMC.org боргирӣ кунед ва насб кунед.[CR]  Агар анбори нармафзори расмиро истифода баред, метавонед нармафзори иловагиро аз серверҳои наздиктарин ба шумо боргирӣ намоед.[CR]  Ҳамаи нармафзори анбори зикршуда аз санҷиши асосӣ мегузаранд, ва агар шумо ягон барномаи иловагии вайроншуда ё ғайрифаъолро пайдо кунед, метавонед дар бораи он гузоришро ба Гурӯҳи кории XBMC фиристонед, то ки барномасозон тавонанд камбудиҳои пайдошударо ҳал кунанд.</description>
+               <description lang="tr">PVR Eklentilerini Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装 PVR 插件。[CR] 通过官方程序库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有失效或不能正常工作的插件,请向 XBMC 开发团队报告,以便及时处理。</description>
                <disclaimer lang="af">Die XBMC span het nie al die byvoegsels in die kodebank gemaak nie en is nie verantwoordelik vir hulle inhoud nie</disclaimer>
                <disclaimer lang="ar">فريق برنامج إكس بى إم سى لم يُصنِع جميع اﻹضافات فى هذا المستودع وغير مسؤول عن ما قد تسببه لك</disclaimer>
index b03961c..142a042 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.pvr-osx32.xbmc.org"
                name="XBMC.org PVR Add-ons"
-               version="1.1.2"
+               version="1.1.3"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -28,6 +28,8 @@
                <summary lang="et">Paigalda videosalvesti lisasid lehelt XBMC.org</summary>
                <summary lang="fr_CA">Installer l'extension du magnétoscope numérique depuis XBMC.org</summary>
                <summary lang="gl">Instalar Engadidos de PVR dende XBMC.org</summary>
+               <summary lang="he">התקן הרחבות PVR מ-XBMC.org</summary>
+               <summary lang="hr">Instaliraj PVR dodatke s XBMC.org</summary>
                <summary lang="hu">PVR kiegészítők telepítése az XBMC.org-ról</summary>
                <summary lang="ko">XBMC.org에서 PVR 추가기능 설치</summary>
                <summary lang="lt">Įdiekite PVR priedą iš XBMC.org</summary>
@@ -40,8 +42,9 @@
                <summary lang="sl">Namestite dodatke PVR z XBMC.org</summary>
                <summary lang="sv">Installera PVR-tillägg från XBMC.org</summary>
                <summary lang="tg">Насб кардани барномаи иловагии PVR аз XBMC.org</summary>
+               <summary lang="tr">XBMC.org'dan PVR Eklentilerini Yükle</summary>
                <summary lang="zh">从 XBMC.org 安装 PVR 插件</summary>
-               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org.[CR] Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR] Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="de">Lade und installiere PVR Add-Ons aus dem offiziellen XBMC.org Add-On Depot.[CR]  Durch die Nutzung des offiziellen Depots profitieren Sie vom umfangreichen Datei-Verteilsystem, welches hilft schneller Downloads in Ihrer Nähe bereitzustellen.[CR] Alle Add-Ons dieses Depots wurden grundlegender Prüfungen unterzogen, sollte ein Add-On dennoch Fehler haben oder nicht funktionieren melden Sie dies bitte an das Team XBMC, damit die nötigen Schritte eingeleitet werden können.</description>
                <description lang="el">Λήψη και εγκατάσταση πρόσθετων από το επίσημο αποθετήριο του XBMC.org.[CR]  Χρησιμοποιώντας το Επίσημο Αποθετήριο μπορείτε να εκμεταλλευτείτε τους εκτεταμένους διακομιστές αρχείων μας για ταχύτερες λήψεις από μία κοντινή σας περιοχή.[CR]  Όλα τα πρόσθετα σε αυτό το αποθετήριο έχουν περάσει τις στοιχειώδεις δοκιμές, αν βρείτε ένα κατεστραμμένο ή ανενεργό πρόσθετο παρακαλούμε να το αναφέρετε στην Ομάδα XBMC ούτως ώστε να ληφθούν οι απαραίτητες ενέργειες.</description>
                <description lang="en">Download and install PVR add-ons from the Official XBMC.org add-on repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All add-ons on this repository have under gone basic testing, if you find a broken or not working add-on please report it to Team XBMC so we can take any action needed.</description>
@@ -52,6 +55,7 @@
                <description lang="et">Lae alla ja installi videosalvesti lisasid ametlikust XBMC.org hoidlast.[CR]  Ametliku hoidla kasutamise eeliseks on võimalus kasutada meie ulatuslikku failide peegelteenust laadides faile sulle kõige lähemast serverist.[CR]  Kõik lisad selles hoidlas on läbinud elementaarse testimise. Siiski, kui sa leiad vigase või mittetöötava lisa, siis palun teavita sellest XBMC meeskonda, et me saaksime vajaliku abi osutada.</description>
                <description lang="fr_CA">Télécharger et installer l'extension du magnétoscope numérique depuis le dépôt officiel de XBMC.org.[CR] En utilisant le dépôt officiel vous pourrez bénéficier de notre service étendu de miroir de fichiers favorisant des téléchargements plus rapides depuis une région proche de vous.[CR] Toutes les extensions de ce dépôt ont subit des tests de base. Si vous trouvez une extension non fonctionnelle ou brisée, veuillez la rapporter à l'équipe XBMC afin que nous puissions agir.</description>
                <description lang="gl">Descargar e instalar Engadidos de PVR dende o repositorio oficial de XBMC.org.[CR] Empregando o repositorio oficial, vostede poderá disfrutar das vantaxes do seu extenso servizo de replicación de ficheiros para axudar a descargas rápidas dende unha rexión preto a vostede.[CR] Tódolos Engadidos deste repositorio pasaron por comprobacións básicas. Se atopa algún Engadido roto ou non funcional, por favor reporteo ó equipo de XBMC para que poidan actuar en consecuencia.</description>
+               <description lang="hr">reuzmite i instalirajte PVR dodatke sa službenog XBMC.org repozitorija dodataka.[CR]  Korištenjm službenog repozitorija biti ćete u mogućnosti iskoristiti prednost našeg zrcalnog poslužitelja u svrhu bržeg preuzimanja iz regije bliže vama.[CR]  Svi dodaci na ovom repozitoriju prošli su osnovno testiranje. Ako pronađete slomljeni ili dodatak koji ne radi, prijavite ga XBMC timu da ga možemo popraviti.</description>
                <description lang="hu">PVR Kiegészítők letöltése és telepítése a hivatalos XBMC.org tárolóhelyről.[CR] A hivatalos tárolóhely használatával kihasználhatod szerteágazó tükör-kiszolgáló hálózatunkat, ami segít a gyorsabb letöltésben egy hozzád közelebb eső körzet használatával.[CR]  Minden kiegészítő ezen a tárolóhelyen átment egy alaptesztelésen. Ha mégis hibás vagy nem működő kiegészítőt találsz, kérünk jelezd az XBMC csapatnak, hogy megtegyük a szükséges lépéseket.</description>
                <description lang="ko">공식 XBMC.org 추가기능 저장소에서 PVR 추가기능을 다운로드하여 설치합니다.[CR] 공식 저장소를 사용하면 파일 미러링 서비스를 통해 사용자와 가까운 곳에서 빠르게 다운로드할 수 있습니다.[CR] 저장소의 모든 추가기능은 기본 테스트를 거치지만 작동이 되지 않거나 손상된 추가기능을 발견하면 필요한 조치를 취할 수 있게 Team XBMC로 알려주시기 바랍니다.</description>
                <description lang="lt">Atsisiųskite ir įdiekite PVR priedą iš oficialios XBMC.org priedų saugyklos. [Cr] Naudojant oficialią saugyklą galėsite pasinaudoti mūsų  failų Veidrodine saugyklos paslauga katra padės jums greičiau parsisiųsti iš artimiausios vietos šalia jūsų. [CR] Visi priedai šioje saugykloje yra perėję pagrindinį testavimą, jei atsisiuntėte neveikiantį ar/arba sugadintą priedą praneškite 'Team XBMC', kad galėtume imtis visų būtinų priemonių klaidai ištaisyti.</description>
@@ -64,6 +68,7 @@
                <description lang="sl">Prenos in namestitev dodatkov PVR iz uradnega skladišča XBMC.org.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi XBMC, da bomo lahko odpravili napake.</description>
                <description lang="sv">Ladda ner och installera PVR-tillägg från det officiella XBMC.org tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som hjälper dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team XBMC så att vi kan vidta nödvändiga åtgärder.</description>
                <description lang="tg">Барномаҳои иловагии PVR-ро аз анбори нармафзори расмии XBMC.org боргирӣ кунед ва насб кунед.[CR]  Агар анбори нармафзори расмиро истифода баред, метавонед нармафзори иловагиро аз серверҳои наздиктарин ба шумо боргирӣ намоед.[CR]  Ҳамаи нармафзори анбори зикршуда аз санҷиши асосӣ мегузаранд, ва агар шумо ягон барномаи иловагии вайроншуда ё ғайрифаъолро пайдо кунед, метавонед дар бораи он гузоришро ба Гурӯҳи кории XBMC фиристонед, то ки барномасозон тавонанд камбудиҳои пайдошударо ҳал кунанд.</description>
+               <description lang="tr">PVR Eklentilerini Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装 PVR 插件。[CR] 通过官方程序库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有失效或不能正常工作的插件,请向 XBMC 开发团队报告,以便及时处理。</description>
                <disclaimer lang="af">Die XBMC span het nie al die byvoegsels in die kodebank gemaak nie en is nie verantwoordelik vir hulle inhoud nie</disclaimer>
                <disclaimer lang="ar">فريق برنامج إكس بى إم سى لم يُصنِع جميع اﻹضافات فى هذا المستودع وغير مسؤول عن ما قد تسببه لك</disclaimer>
index b1287f0..901d1ed 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.pvr-osx64.xbmc.org"
                name="XBMC.org PVR Add-ons"
-               version="1.0.2"
+               version="1.0.3"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -28,6 +28,8 @@
                <summary lang="et">Paigalda videosalvesti lisasid lehelt XBMC.org</summary>
                <summary lang="fr_CA">Installer l'extension du magnétoscope numérique depuis XBMC.org</summary>
                <summary lang="gl">Instalar Engadidos de PVR dende XBMC.org</summary>
+               <summary lang="he">התקן הרחבות PVR מ-XBMC.org</summary>
+               <summary lang="hr">Instaliraj PVR dodatke s XBMC.org</summary>
                <summary lang="hu">PVR kiegészítők telepítése az XBMC.org-ról</summary>
                <summary lang="ko">XBMC.org에서 PVR 추가기능 설치</summary>
                <summary lang="lt">Įdiekite PVR priedą iš XBMC.org</summary>
@@ -40,8 +42,9 @@
                <summary lang="sl">Namestite dodatke PVR z XBMC.org</summary>
                <summary lang="sv">Installera PVR-tillägg från XBMC.org</summary>
                <summary lang="tg">Насб кардани барномаи иловагии PVR аз XBMC.org</summary>
+               <summary lang="tr">XBMC.org'dan PVR Eklentilerini Yükle</summary>
                <summary lang="zh">从 XBMC.org 安装 PVR 插件</summary>
-               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org.[CR] Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR] Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="de">Lade und installiere PVR Add-Ons aus dem offiziellen XBMC.org Add-On Depot.[CR]  Durch die Nutzung des offiziellen Depots profitieren Sie vom umfangreichen Datei-Verteilsystem, welches hilft schneller Downloads in Ihrer Nähe bereitzustellen.[CR] Alle Add-Ons dieses Depots wurden grundlegender Prüfungen unterzogen, sollte ein Add-On dennoch Fehler haben oder nicht funktionieren melden Sie dies bitte an das Team XBMC, damit die nötigen Schritte eingeleitet werden können.</description>
                <description lang="el">Λήψη και εγκατάσταση πρόσθετων από το επίσημο αποθετήριο του XBMC.org.[CR]  Χρησιμοποιώντας το Επίσημο Αποθετήριο μπορείτε να εκμεταλλευτείτε τους εκτεταμένους διακομιστές αρχείων μας για ταχύτερες λήψεις από μία κοντινή σας περιοχή.[CR]  Όλα τα πρόσθετα σε αυτό το αποθετήριο έχουν περάσει τις στοιχειώδεις δοκιμές, αν βρείτε ένα κατεστραμμένο ή ανενεργό πρόσθετο παρακαλούμε να το αναφέρετε στην Ομάδα XBMC ούτως ώστε να ληφθούν οι απαραίτητες ενέργειες.</description>
                <description lang="en">Download and install PVR add-ons from the Official XBMC.org add-on repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All add-ons on this repository have under gone basic testing, if you find a broken or not working add-on please report it to Team XBMC so we can take any action needed.</description>
@@ -52,6 +55,7 @@
                <description lang="et">Lae alla ja installi videosalvesti lisasid ametlikust XBMC.org hoidlast.[CR]  Ametliku hoidla kasutamise eeliseks on võimalus kasutada meie ulatuslikku failide peegelteenust laadides faile sulle kõige lähemast serverist.[CR]  Kõik lisad selles hoidlas on läbinud elementaarse testimise. Siiski, kui sa leiad vigase või mittetöötava lisa, siis palun teavita sellest XBMC meeskonda, et me saaksime vajaliku abi osutada.</description>
                <description lang="fr_CA">Télécharger et installer l'extension du magnétoscope numérique depuis le dépôt officiel de XBMC.org.[CR] En utilisant le dépôt officiel vous pourrez bénéficier de notre service étendu de miroir de fichiers favorisant des téléchargements plus rapides depuis une région proche de vous.[CR] Toutes les extensions de ce dépôt ont subit des tests de base. Si vous trouvez une extension non fonctionnelle ou brisée, veuillez la rapporter à l'équipe XBMC afin que nous puissions agir.</description>
                <description lang="gl">Descargar e instalar Engadidos de PVR dende o repositorio oficial de XBMC.org.[CR] Empregando o repositorio oficial, vostede poderá disfrutar das vantaxes do seu extenso servizo de replicación de ficheiros para axudar a descargas rápidas dende unha rexión preto a vostede.[CR] Tódolos Engadidos deste repositorio pasaron por comprobacións básicas. Se atopa algún Engadido roto ou non funcional, por favor reporteo ó equipo de XBMC para que poidan actuar en consecuencia.</description>
+               <description lang="hr">Preuzmite i instalirajte PVR dodatke sa službenog XBMC.org repozitorija dodataka.[CR]  Korištenjm službenog repozitorija biti ćete u mogućnosti iskoristiti prednost našeg zrcalnog poslužitelja u svrhu bržeg preuzimanja iz regije bliže vama.[CR]  Svi dodaci na ovom repozitoriju prošli su osnovno testiranje. Ako pronađete slomljeni ili dodatak koji ne radi, prijavite ga XBMC timu da ga možemo popraviti.</description>
                <description lang="hu">PVR Kiegészítők letöltése és telepítése a hivatalos XBMC.org tárolóhelyről.[CR] A hivatalos tárolóhely használatával kihasználhatod szerteágazó tükör-kiszolgáló hálózatunkat, ami segít a gyorsabb letöltésben egy hozzád közelebb eső körzet használatával.[CR]  Minden kiegészítő ezen a tárolóhelyen átment egy alaptesztelésen. Ha mégis hibás vagy nem működő kiegészítőt találsz, kérünk jelezd az XBMC csapatnak, hogy megtegyük a szükséges lépéseket.</description>
                <description lang="ko">공식 XBMC.org 추가기능 저장소에서 PVR 추가기능을 다운로드하여 설치합니다.[CR] 공식 저장소를 사용하면 파일 미러링 서비스를 통해 사용자와 가까운 곳에서 빠르게 다운로드할 수 있습니다.[CR] 저장소의 모든 추가기능은 기본 테스트를 거치지만 작동이 되지 않거나 손상된 추가기능을 발견하면 필요한 조치를 취할 수 있게 Team XBMC로 알려주시기 바랍니다.</description>
                <description lang="lt">Atsisiųskite ir įdiekite PVR priedą iš oficialios XBMC.org priedų saugyklos. [Cr] Naudojant oficialią saugyklą galėsite pasinaudoti mūsų  failų Veidrodine saugyklos paslauga katra padės jums greičiau parsisiųsti iš artimiausios vietos šalia jūsų. [CR] Visi priedai šioje saugykloje yra perėję pagrindinį testavimą, jei atsisiuntėte neveikiantį ar/arba sugadintą priedą praneškite 'Team XBMC', kad galėtume imtis visų būtinų priemonių klaidai ištaisyti.</description>
@@ -64,6 +68,7 @@
                <description lang="sl">Prenos in namestitev dodatkov PVR iz uradnega skladišča XBMC.org.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi XBMC, da bomo lahko odpravili napake.</description>
                <description lang="sv">Ladda ner och installera PVR-tillägg från det officiella XBMC.org tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som hjälper dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team XBMC så att vi kan vidta nödvändiga åtgärder.</description>
                <description lang="tg">Барномаҳои иловагии PVR-ро аз анбори нармафзори расмии XBMC.org боргирӣ кунед ва насб кунед.[CR]  Агар анбори нармафзори расмиро истифода баред, метавонед нармафзори иловагиро аз серверҳои наздиктарин ба шумо боргирӣ намоед.[CR]  Ҳамаи нармафзори анбори зикршуда аз санҷиши асосӣ мегузаранд, ва агар шумо ягон барномаи иловагии вайроншуда ё ғайрифаъолро пайдо кунед, метавонед дар бораи он гузоришро ба Гурӯҳи кории XBMC фиристонед, то ки барномасозон тавонанд камбудиҳои пайдошударо ҳал кунанд.</description>
+               <description lang="tr">PVR Eklentilerini Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装 PVR 插件。[CR] 通过官方程序库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有失效或不能正常工作的插件,请向 XBMC 开发团队报告,以便及时处理。</description>
                <disclaimer lang="af">Die XBMC span het nie al die byvoegsels in die kodebank gemaak nie en is nie verantwoordelik vir hulle inhoud nie</disclaimer>
                <disclaimer lang="ar">فريق برنامج إكس بى إم سى لم يُصنِع جميع اﻹضافات فى هذا المستودع وغير مسؤول عن ما قد تسببه لك</disclaimer>
index e432137..931ba70 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.pvr-win32.xbmc.org"
                name="XBMC.org PVR Add-ons"
-               version="1.1.2"
+               version="1.1.3"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -28,6 +28,8 @@
                <summary lang="et">Paigalda videosalvesti lisasid lehelt XBMC.org</summary>
                <summary lang="fr_CA">Installer l'extension du magnétoscope numérique depuis XBMC.org</summary>
                <summary lang="gl">Instalar Engadidos de PVR dende XBMC.org</summary>
+               <summary lang="he">התקן הרחבות PVR מ-XBMC.org</summary>
+               <summary lang="hr">Instaliraj PVR dodatke s XBMC.org</summary>
                <summary lang="hu">PVR kiegészítők telepítése az XBMC.org-ról</summary>
                <summary lang="ko">XBMC.org에서 PVR 추가기능 설치</summary>
                <summary lang="lt">Įdiekite PVR priedą iš XBMC.org</summary>
@@ -40,8 +42,9 @@
                <summary lang="sl">Namestite dodatke PVR z XBMC.org</summary>
                <summary lang="sv">Installera PVR-tillägg från XBMC.org</summary>
                <summary lang="tg">Насб кардани барномаи иловагии PVR аз XBMC.org</summary>
+               <summary lang="tr">XBMC.org'dan PVR Eklentilerini Yükle</summary>
                <summary lang="zh">从 XBMC.org 安装 PVR 插件</summary>
-               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org.[CR] Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR] Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира PVR добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="de">Lade und installiere PVR Add-Ons aus dem offiziellen XBMC.org Add-On Depot.[CR]  Durch die Nutzung des offiziellen Depots profitieren Sie vom umfangreichen Datei-Verteilsystem, welches hilft schneller Downloads in Ihrer Nähe bereitzustellen.[CR] Alle Add-Ons dieses Depots wurden grundlegender Prüfungen unterzogen, sollte ein Add-On dennoch Fehler haben oder nicht funktionieren melden Sie dies bitte an das Team XBMC, damit die nötigen Schritte eingeleitet werden können.</description>
                <description lang="el">Λήψη και εγκατάσταση πρόσθετων από το επίσημο αποθετήριο του XBMC.org.[CR]  Χρησιμοποιώντας το Επίσημο Αποθετήριο μπορείτε να εκμεταλλευτείτε τους εκτεταμένους διακομιστές αρχείων μας για ταχύτερες λήψεις από μία κοντινή σας περιοχή.[CR]  Όλα τα πρόσθετα σε αυτό το αποθετήριο έχουν περάσει τις στοιχειώδεις δοκιμές, αν βρείτε ένα κατεστραμμένο ή ανενεργό πρόσθετο παρακαλούμε να το αναφέρετε στην Ομάδα XBMC ούτως ώστε να ληφθούν οι απαραίτητες ενέργειες.</description>
                <description lang="en">Download and install PVR add-ons from the Official XBMC.org add-on repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All add-ons on this repository have under gone basic testing, if you find a broken or not working add-on please report it to Team XBMC so we can take any action needed.</description>
@@ -52,6 +55,7 @@
                <description lang="et">Lae alla ja installi videosalvesti lisasid ametlikust XBMC.org hoidlast.[CR]  Ametliku hoidla kasutamise eeliseks on võimalus kasutada meie ulatuslikku failide peegelteenust laadides faile sulle kõige lähemast serverist.[CR]  Kõik lisad selles hoidlas on läbinud elementaarse testimise. Siiski, kui sa leiad vigase või mittetöötava lisa, siis palun teavita sellest XBMC meeskonda, et me saaksime vajaliku abi osutada.</description>
                <description lang="fr_CA">Télécharger et installer l'extension du magnétoscope numérique depuis le dépôt officiel de XBMC.org.[CR] En utilisant le dépôt officiel vous pourrez bénéficier de notre service étendu de miroir de fichiers favorisant des téléchargements plus rapides depuis une région proche de vous.[CR] Toutes les extensions de ce dépôt ont subit des tests de base. Si vous trouvez une extension non fonctionnelle ou brisée, veuillez la rapporter à l'équipe XBMC afin que nous puissions agir.</description>
                <description lang="gl">Descargar e instalar Engadidos de PVR dende o repositorio oficial de XBMC.org.[CR] Empregando o repositorio oficial, vostede poderá disfrutar das vantaxes do seu extenso servizo de replicación de ficheiros para axudar a descargas rápidas dende unha rexión preto a vostede.[CR] Tódolos Engadidos deste repositorio pasaron por comprobacións básicas. Se atopa algún Engadido roto ou non funcional, por favor reporteo ó equipo de XBMC para que poidan actuar en consecuencia.</description>
+               <description lang="hr">Preuzmite i instalirajte PVR dodatke sa službenog XBMC.org repozitorija dodataka.[CR]  Korištenjm službenog repozitorija biti ćete u mogućnosti iskoristiti prednost našeg zrcalnog poslužitelja u svrhu bržeg preuzimanja iz regije bliže vama.[CR]  Svi dodaci na ovom repozitoriju prošli su osnovno testiranje. Ako pronađete slomljeni ili dodatak koji ne radi, prijavite ga XBMC timu da ga možemo popraviti.</description>
                <description lang="hu">PVR Kiegészítők letöltése és telepítése a hivatalos XBMC.org tárolóhelyről.[CR] A hivatalos tárolóhely használatával kihasználhatod szerteágazó tükör-kiszolgáló hálózatunkat, ami segít a gyorsabb letöltésben egy hozzád közelebb eső körzet használatával.[CR]  Minden kiegészítő ezen a tárolóhelyen átment egy alaptesztelésen. Ha mégis hibás vagy nem működő kiegészítőt találsz, kérünk jelezd az XBMC csapatnak, hogy megtegyük a szükséges lépéseket.</description>
                <description lang="ko">공식 XBMC.org 추가기능 저장소에서 PVR 추가기능을 다운로드하여 설치합니다.[CR] 공식 저장소를 사용하면 파일 미러링 서비스를 통해 사용자와 가까운 곳에서 빠르게 다운로드할 수 있습니다.[CR] 저장소의 모든 추가기능은 기본 테스트를 거치지만 작동이 되지 않거나 손상된 추가기능을 발견하면 필요한 조치를 취할 수 있게 Team XBMC로 알려주시기 바랍니다.</description>
                <description lang="lt">Atsisiųskite ir įdiekite PVR priedą iš oficialios XBMC.org priedų saugyklos. [Cr] Naudojant oficialią saugyklą galėsite pasinaudoti mūsų  failų Veidrodine saugyklos paslauga katra padės jums greičiau parsisiųsti iš artimiausios vietos šalia jūsų. [CR] Visi priedai šioje saugykloje yra perėję pagrindinį testavimą, jei atsisiuntėte neveikiantį ar/arba sugadintą priedą praneškite 'Team XBMC', kad galėtume imtis visų būtinų priemonių klaidai ištaisyti.</description>
@@ -64,6 +68,7 @@
                <description lang="sl">Prenos in namestitev dodatkov PVR iz uradnega skladišča XBMC.org.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi XBMC, da bomo lahko odpravili napake.</description>
                <description lang="sv">Ladda ner och installera PVR-tillägg från det officiella XBMC.org tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som hjälper dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team XBMC så att vi kan vidta nödvändiga åtgärder.</description>
                <description lang="tg">Барномаҳои иловагии PVR-ро аз анбори нармафзори расмии XBMC.org боргирӣ кунед ва насб кунед.[CR]  Агар анбори нармафзори расмиро истифода баред, метавонед нармафзори иловагиро аз серверҳои наздиктарин ба шумо боргирӣ намоед.[CR]  Ҳамаи нармафзори анбори зикршуда аз санҷиши асосӣ мегузаранд, ва агар шумо ягон барномаи иловагии вайроншуда ё ғайрифаъолро пайдо кунед, метавонед дар бораи он гузоришро ба Гурӯҳи кории XBMC фиристонед, то ки барномасозон тавонанд камбудиҳои пайдошударо ҳал кунанд.</description>
+               <description lang="tr">PVR Eklentilerini Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装 PVR 插件。[CR] 通过官方程序库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有失效或不能正常工作的插件,请向 XBMC 开发团队报告,以便及时处理。</description>
                <disclaimer lang="af">Die XBMC span het nie al die byvoegsels in die kodebank gemaak nie en is nie verantwoordelik vir hulle inhoud nie</disclaimer>
                <disclaimer lang="ar">فريق برنامج إكس بى إم سى لم يُصنِع جميع اﻹضافات فى هذا المستودع وغير مسؤول عن ما قد تسببه لك</disclaimer>
index e6b7209..bb67cfc 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.xbmc.org"
                name="XBMC.org Add-ons"
-               version="2.1.18"
+               version="2.1.19"
                provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.addon" version="12.0.0"/>
@@ -78,7 +78,7 @@
                <description lang="af">Aflaai en installeer byvoegsels vanaf die Amptelike XBMC.org byvoegsel kodebank.[CR] Deur die amptelike Kodebank te gebruik trek jy voordeel van ons uitgebreide lêer spieël diens wat jou help vinniger aflaai vanaf 'n gebied naby aan jou.[CR] Alle byvoegsels in die kodebank het basiese toetsing ondergaan, as jy 'n gebreekte of nie werkende byvoegsel vind rapporteer dit asseblief aan die XBMC Span sodat ons die nodige stappe kan neem.</description>
                <description lang="ar">حمل و ثبت الإضافات من موقع XBMC.org مستودع الإضافات الرسمي. [CR]  باستخدام المستودع الرسمي ستكون قادر على أخذ ميزة من خدمة مراة ملف الواسعة لمساعدتك بالحصول على تحكيل أسرع من منطقة أنت قريب منها. جميع الإضافات في هذا المستودع تخضع لاختبار أساسي, إذا وجدت إضافة معطوية أو لاتعمل الرجاء الإبلاغ عنها لفريق XBMC لنتمكن من اتخاذ أي إجراء لازم.</description>
                <description lang="be">Download and install add-ons from the Official XBMC.org addon repository.[CR]  By using the official Repository you will be able to take advantage of our extensive file mirror service to help get you faster downloads from a region close to you.[CR]  All addons on this repository have under gone basic testing, if you find a broken or not working addon please report it to Team XBMC so we can take any action needed.</description>
-               <description lang="bg">Сваля и инсталира добавки от официалното хранилище за добавки на XBMC.org.[CR]  Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър в район близък до Вас.[CR]  Добавките от хранилището са преминали през няколко основни теста, но въпреки това ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
+               <description lang="bg">Сваля и инсталира добавки от официалното хранилище за добавки на XBMC.org. Ползвайки добавката ще се възползвате от системата ни от огледални сървъри - за да сваляте с висока скорост, от сървър близък до Вас. Добавките от хранилището са минали няколко теста, но ако се натъкнете на неработеща или проблемна добавка, моля уведомете екипа на XBMC, за да бъдат предприети необходимите действия.</description>
                <description lang="ca">Baixa i instal·la complements des del repositori oficial de XBMC.org.[CR]Utilitzant el repositori oficial, podràs aprofitar els avantatges del nostre sistema de miralls per ajudar-te a tenir unes descarregues més ràpides des d'una regió propera a tu.[CR] Tots els complements d'aquest repositori han passat per un testeig bàsic, així que si trobeu algun complement que no funcioni correctament, si us plau digueu-ho a l'equip de l'XBMC per què puguin dur a terme les accions pertinents.</description>
                <description lang="cs">Stáhnout a nainstalovat rozšíření z oficiálního repozitáře XBMC.org. [CR]  Použitím oficiálního repozitáře získáte rozsáhlý systém zrcadel, který vám umožní rychlé stažení z blízkého regionu.[CR]  Všechna rozšíření v repozitáři prošla základním testováním. Pokud najdete rozbité, nebo nefunkční, rozšíření nahlaste jej týmu XBMC, abychom mohli dle potřeby zakročit.</description>
                <description lang="cy">Llwytho i lawr a gosod ychwanegion o storfa ychwanegion Swyddogol XBMC.org.{CR}Drwy ddefnyddio'r Storfa swyddogol bydd modd i chi gymryd mantais o'n gwasanaeth drychau ffeiliau i'ch cynorthwyoi lwytho i lawr yn gyflym o ardal yn agos i chi.[CR] Mae pob ychwnaegyn yn y storfa hwn wedi eu profi'n fras, os ydych yn canfod ychwanegyn sydd wedi torri  neu ddim yn gweithio yna hysbyswch Team XBMC fel bod modd i ni weithredu.</description>
                <description lang="ta_IN">அதிகாரப்பூர்வ XBMC.org துணை பயன் களஞ்சியத்திலிருந்து துணை பயன்களை பதிவிறக்கம் மற்றும் நிறுவல் செய்யலாம். [CR] அதிகாரப்பூர்வ களஞ்சியத்தை பயன்படுத்துவதால் நீங்கள் உங்கள் இருப்பிடத்திருக்கு அருகாமையில் உள்ள களஞ்சியத்தில் இருந்து சீக்கிரமாக சேவைகளை பெறமுடியும்.[CR] இங்குள்ள அணைத்து துணை பயன்களும் நன்கு பரிசொதிக்கபட்டவை, சரியாக இயங்கவில்லை என்றால் XBMC குழுவிடம் சொல்லவும்.</description>
                <description lang="tg">Барномаҳои иловагиро аз анбори нармафзори XBMC.org боргирӣ кунед ва насб намоед.[CR]  Аз истифодаи анбори нармафзори расмии мо ба шумо имконият пайдо мешавад, ки тавонед шароити мусофидро аз хидмати оинаи файлии васеъ ба даст оред ва нармафзори лозимиро аз сервери минтакаи ба шумо наздиктар бо суръати баланд боргирӣ кунед.[CR]  Ҳамаи барномаҳо аз анбори нармафзори мо дар ҳолати санҷишӣ мебошанд, бинобар ин агар ягон барномаи иловагии нуқсондор ё вайроншударо ёбед, лутфан дар бораи он барнома ва нуқсон пайдошуда ба гурӯҳи кории XBMC гузориш диҳед, то ин ки мо тавонем ҳамаи камбудиҳои барномаҳои моро ҳал кунем.</description>
                <description lang="th">ดาวน์โหลดและติดตั้งส่วนเสริม จากแหล่งข้อมูลโปรแกรมของ XBMC.org อย่างเป็นทางการ.[CR]  โดยการใช้งานแหล่งข้อมูลโปรแกรมอย่างเป็นทางการ คุณสามารถใช้ประโยชน์จากบริการแฟ้มมิเรอร์ที่กว้างขวางของเรา ที่จะช่วยให้การดาวน์โหลดของคุณเร็วขึ้นจากภูมิภาคที่ใกล้ที่สุด.[CR]  ส่วนเสริม ทั้งหมดในแหล่งเก็บข้อมูลนี้ อยู่ภายใต้การทดสอบขั้นพื้นฐานแล้ว ถ้าคุณพบส่วนเสริมที่เสียหายหรือไม่ทำงาน กรุณาแจ้งทีมงาน XBMC เพื่อให้เราสามารถดำเนินการใด ๆ ที่จำเป็น.</description>
-               <description lang="tr">Eklentileri Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Buyazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
+               <description lang="tr">Eklentileri Resmi XBMC.org eklenti deposundan indir ve yükle.[CR]Resmi yazılım depomuzu kullanarak size en yakın bölgeden en hızlı biçimde indirme yapmanızı sağlayacak gelişkin dosya aynalama servisini kullanma avantajını elde edeceksiniz.[CR]Bu yazılım deposundaki tüm eklentiler temel testlerden geçerler, şayet hatalı ya da çalışmayan bir eklenti bulur iseniz lütfen düzeltilmesi için bu durumu XBMC Takımına bildiriniz.</description>
                <description lang="uk">Завантажити і встановити додатки з Офіційного репозиторію додатків XBMC.org.[CR]  Використовуючи Офіційний Репозиторій ви отримаєте перевагу надану нашими дзеркальними серверами, які забезпечать вам швидке завантаження із найближчого до вас регіону.[CR]  Всі додатки в цьому Репозиторії пройшли лише базове тестування. Якщо ви знайшли зламаний або непрацюючий додаток, будь-ласка повідомте про це Команду XBMC щоб ми могли вжити потрібних заходів.</description>
                <description lang="vi">Tải về và cài đặt add-on từ kho addon chính thức của XBMC.[CR]  Khi sử dụng kho chứa này bạn sẽ hưởng lợi từ dịch vụ tạo nguồn của chúng tôi, giúp bạn có thể tải về nhanh hơn từ vùng địa lý gần bạn.[CR]  Tất cả addon trên kho chứa này đã được thông qua bài kiểm tra cơ bản, nếu bạn phát hiện ra một addon không hoạt động xin vui lòng báo cáo lại nó cho đội ngũ XBMC để chúng tôi có thể kịp thời xử lý.</description>
                <description lang="zh">从官方 XBMC.org 插件库下载和安装插件。[CR] 通过官方插件库你将能利用我们广泛的镜像服务优势,使你能够就近下载资源。[CR] 官方库中的所有插件都经过了基本的测试,如果你发现有损坏或不能正常工作的插件请向 XBMC 开发团队报告,以便及时处理。</description>
index 879504b..faf25f1 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="screensaver.rsxs.euphoria"
-  version="1.0.14"
+  version="1.0.15"
   name="Euphoria"
   provider-name="mogumbo, Team XBMC">
   <requires>
index e969bec..166dc6e 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="screensaver.rsxs.plasma"
-  version="1.0.14"
+  version="1.0.15"
   name="Plasma"
   provider-name="mogumbo, Team XBMC">
   <requires>
index 711c825..59bd6b0 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="screensaver.rsxs.solarwinds"
-  version="1.0.14"
+  version="1.0.15"
   name="Solarwinds"
   provider-name="mogumbo, Team XBMC">
   <requires>
index 1aee042..dee5661 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="screensaver.xbmc.builtin.black"
        name="Black"
-       version="1.0.14"
+       version="1.0.15"
        provider-name="Team XBMC">
   <extension point="xbmc.ui.screensaver" library=""/>
   <extension point="xbmc.addon.metadata">
index d43041c..afb4dd1 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="screensaver.xbmc.builtin.dim"
        name="Dim"
-       version="1.0.14"
+       version="1.0.15"
        provider-name="Team XBMC">
   <extension point="xbmc.ui.screensaver" library=""/>
   <extension point="xbmc.addon.metadata">
index b3485f0..1ba81fa 100644 (file)
@@ -7,7 +7,7 @@
        <controls>
                <control type="group">
                        <visible>player.chaptercount + Window.IsVisible(FullScreenVideo)</visible>
-                       <left>665r</left>
+                       <left>705r</left>
                        <top>-6</top>
                        <include>VisibleFadeEffect</include>
                        <control type="image">
@@ -46,7 +46,7 @@
                        </control>
                </control>
                <control type="group">
-                       <left>520r</left>
+                       <left>560r</left>
                        <top>-6</top>
                        <control type="image">
                                <left>0</left>
index 55270a5..2124b24 100644 (file)
                                <description>Fake button for mouse control</description>
                                <left>880</left>
                                <top>0</top>
-                               <width>20</width>
+                               <width>80</width>
                                <height>720</height>
                                <label>-</label>
                                <font>-</font>
                                <texturenofocus>-</texturenofocus>
                                <texturefocus>-</texturefocus>
                                <visible>true</visible>
+                               <onfocus>SetFocus(150)</onfocus>
                        </control>
                        <control type="image">
                                <description>media info background image</description>
                                </control>
                                <control type="group" id="130">
                                        <control type="grouplist">
-                                               <left>20</left>
-                                               <top>660</top>
-                                               <width>305</width>
-                                               <height>40</height>
-                                               <align>right</align>
+                                               <left>50</left>
+                                               <top>659</top>
+                                               <width>605</width>
+                                               <height>30</height>
                                                <orientation>horizontal</orientation>
                                                <itemgap>5</itemgap>
                                                <control type="image">
-                                                       <width>40</width>
-                                                       <height>40</height>
+                                                       <width>30</width>
+                                                       <height>30</height>
                                                        <texture>DefaultIconInfo.png</texture>
                                                </control>
                                                <control type="label">
                                                        <description>notification</description>
-                                                       <width min="10" max="260">auto</width>
-                                                       <height>40</height>
+                                                       <width min="10" max="560">auto</width>
+                                                       <height>30</height>
                                                        <font>font13</font>
                                                        <textcolor>white</textcolor>
-                                                       <label>31413</label>
+                                                       <label>$LOCALIZE[31413]</label>
                                                        <aligny>center</aligny>
-                                                       <wrapmultiline>true</wrapmultiline>
                                                </control>
                                        </control>
                                </control>
index c811612..21903c6 100644 (file)
@@ -73,7 +73,7 @@
                                <itemgap>-1</itemgap>
                                <onleft>5</onleft>
                                <onright>5</onright>
-                               <onup>20</onup>
+                               <onup>3</onup>
                                <ondown>20</ondown>
                        </control>
                        <control type="button" id="20">
index 6e2aa3a..fb5d377 100644 (file)
                                <onright>31</onright>
                                <onup>10</onup>
                                <ondown>10</ondown>
+                               <onback>9000</onback> 
                                <rulerlayout height="35" width="40">
                                        <control type="label" id="2">
                                                <left>10</left>
index 37223f0..32f7461 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="skin.confluence"
-  version="2.2.8"
+  version="2.2.9"
   name="Confluence"
   provider-name="Jezz_X, Team XBMC">
   <requires>
index 3d19627..aadb9bb 100644 (file)
@@ -1,3 +1,7 @@
+[B]2.2.9[/B]
+
+- Updated language files from Transifex
+
 [B]2.2.8[/B]
 
 - Updated language files from Transifex
index a05f205..65c15db 100644 (file)
@@ -230,7 +230,7 @@ msgstr "Afficher la visualisation en cours de lecture en arrière-plan"
 
 msgctxt "#31126"
 msgid "Play TV theme songs in video library (TvTunes add-on)"
-msgstr "Jouer les génériques TV dans la médiathèque vidéo (extension TvTunes)"
+msgstr "Jouer les génériques TV de vidéothèque (extension TvTunes)"
 
 msgctxt "#31127"
 msgid "TvTunes"
@@ -442,11 +442,11 @@ msgstr "[B]CONFIGURATION DES PARAMÈTRES APPARENCE[/B][CR][CR]Changer le thème
 
 msgctxt "#31401"
 msgid "[B]CONFIGURE VIDEO SETTINGS[/B][CR][CR]Manage your video library · Set video playback options · Change video listing options[CR]Set subtitle fonts"
-msgstr "[B]CONFIGURATION DES PARAMÈTRES VIDÉO[/B][CR][CR]Gérer votre médiathèque vidéo · Définir les options de lecture · Changer les options des listes de vidéos[CR]Définir la police des sous-titres"
+msgstr "[B]CONFIGURATION DES PARAMÈTRES VIDÉO[/B][CR][CR]Gérer votre vidéothèque · Définir les options de lecture · Changer les options des listes de vidéos[CR]Définir la police des sous-titres"
 
 msgctxt "#31402"
 msgid "[B]CONFIGURE MUSIC SETTINGS[/B][CR][CR]Manage your music library · Set music playback options · Change music listing options[CR]Setup song submission · Set karaoke options"
-msgstr "[B]CONFIGURATION DES PARAMÈTRES MUSIQUE[/B][CR][CR]Gérer votre médiathèque musique · Définir les options de lecture · Changer les options des listes de musique[CR]Paramétrer les soumissions de chansons · Définir les options karaoké"
+msgstr "[B]CONFIGURATION DES PARAMÈTRES MUSIQUE[/B][CR][CR]Gérer votre musithèque musique · Définir les options de lecture · Changer les options des listes de musique[CR]Paramétrer les soumissions de chansons · Définir les options karaoké"
 
 msgctxt "#31403"
 msgid "[B]CONFIGURE PICTURE SETTINGS[/B][CR][CR]Set picture listing options · Configure slideshows"
index f1b0160..bfe581d 100644 (file)
@@ -116,6 +116,10 @@ msgctxt "#31046"
 msgid "SEEKING"
 msgstr "בחיפוש"
 
+msgctxt "#31048"
+msgid "Visualisation Presets"
+msgstr "קביעוני חיזוי"
+
 msgctxt "#31049"
 msgid "End Time"
 msgstr "זמן סיום"
@@ -220,6 +224,10 @@ msgctxt "#31124"
 msgid "Show Background \"Now Playing\" Video"
 msgstr "הצג ברקע \"מנגן כעת\" וידאו"
 
+msgctxt "#31125"
+msgid "Show Background \"Now Playing\" Visualisation"
+msgstr "הצג חיזוי \"מנגן עכשיו\" ברקע"
+
 msgctxt "#31126"
 msgid "Play TV theme songs in video library (TvTunes add-on)"
 msgstr "נגן נעימות של סדרות טלוויזיה בספריית סדרות הטלווויזיה (תוסף TvTunes)"
@@ -232,6 +240,10 @@ msgctxt "#31128"
 msgid "Lyrics"
 msgstr "מילות שירים"
 
+msgctxt "#31129"
+msgid "Hide Fanart in full screen visualisation"
+msgstr "הסתר חיזוי פאנארט במסך מלא"
+
 msgctxt "#31132"
 msgid "Lyrics Add-on"
 msgstr "תוספי מילים לשירים"
@@ -468,10 +480,18 @@ msgctxt "#31413"
 msgid "Local subtitle available"
 msgstr "כתובית מקומית זמינה"
 
+msgctxt "#31420"
+msgid "Login"
+msgstr "כניסה"
+
 msgctxt "#31421"
 msgid "Select your XBMC user Profile[CR]to login and continue"
 msgstr "בחר בפרופיל משתמש XBMC [CR]שלך כדי להתחבר ולהמשיך"
 
+msgctxt "#31422"
+msgid "Show or hide the login screen at startup."
+msgstr "הצג או הסתר מסך התחברות בהפעלה."
+
 msgctxt "#31423"
 msgid "Select the profile that will be used at startup when the login screen is disabled."
 msgstr "בחר פרופיל שישמש כברירת מחדל"
@@ -566,7 +586,7 @@ msgstr "סרטים"
 
 msgctxt "#31955"
 msgid "TV SHOWS"
-msgstr "ת×\9b× ×\99×\95ת ×\98×\9c×\95×\95×\99×\96×\99×\94"
+msgstr "ס×\93ר×\95ת"
 
 msgctxt "#31956"
 msgid "MUSIC"
index 46b9fdb..c0e0022 100644 (file)
@@ -494,7 +494,7 @@ msgstr "Izberite vaš XBMC uporabniški profil[CR]za prijavo in nadaljujte"
 
 msgctxt "#31422"
 msgid "Show or hide the login screen at startup."
-msgstr "Ob zagonu prikaži ali skrij okno za prijavo."
+msgstr "Ob zagonu prikažite ali skrijte okno za prijavo."
 
 msgctxt "#31423"
 msgid "Select the profile that will be used at startup when the login screen is disabled."
index afe2567..42ffdcc 100644 (file)
@@ -590,7 +590,7 @@ msgstr "FİLMLER"
 
 msgctxt "#31955"
 msgid "TV SHOWS"
-msgstr "TV ŞOVLARI"
+msgstr "TV PROGRAMLARI"
 
 msgctxt "#31956"
 msgid "MUSIC"
index 558552d..35fa612 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.dxspectrum"
-  version="1.0.14"
+  version="1.0.15"
   name="DirectX Spectrum"
   provider-name="Team XBMC">
   <extension
index b676126..49eed33 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.fishbmc"
-  version="4.0.3"
+  version="4.0.4"
   name="FishBMC"
   provider-name="26elf">
   <extension
     <summary lang="et">Laine- ja uduefektidega visuaal</summary>
     <summary lang="fr_CA">Visualisation à effet de vague et flou</summary>
     <summary lang="gl">Unha visualización con Ondas e efectos de Desenfoque</summary>
+    <summary lang="he">חיזוי מציג אפקטי גלים וטשטוש</summary>
+    <summary lang="hr">Vizualizacija prikazuje valove i zamućene efekte</summary>
     <summary lang="hu">A vizualizáció Hullámokat és Elmosás Effekteket mutat.</summary>
     <summary lang="it">Visualizzazione mostrando Onde e Sfumature</summary>
     <summary lang="nl">Visualisatie waarbij Golven en Blur effecten worden getoond </summary>
+    <summary lang="pl">Wizualizacja prezentuje efekty fali i rozmycia</summary>
     <summary lang="pt">Uma visualização com Ondas e Efeitos de Desfocagem</summary>
     <summary lang="pt_BR">Visualização mostrando Ondas e Efeitos Borrados</summary>
     <summary lang="sk">Vizualizácia zobrazujúca vlnky a efekty rozmazania</summary>
     <description lang="et">fishBMC baseerub fische visualiseerimistööriistal. Põhiprintsiibiks on: joonista laine ja määri see ettenähtud suundades laiali. fische sisaldab lisaks veel edasijõudnud rütmituvastajat, garanteerides nii vaatajale suurepärase elamuse. </description>
     <description lang="fr_CA">fishBMX est basé sur fische, un outil de visualisation audio autonome. Le principe de base est : dessiner la forme de l'onde et altère le dessin suivant des vecteurs prédéfinis. Cependant fische incorpore aussi une détection améliorée du tempo, ce qui garantie une expérience visuelle de qualité</description>
     <description lang="gl">fishBMC está baseado en fische, unha ferramenta autónoma de visualización de sons. O principio básico é: debuxar as formas de onda e pintalas ao longo dos vectores predefinidos. E posíbel que fische tamén incorpore detección avanzada de golpes, que realmente garante unha grande experiencia visual.</description>
+    <description lang="he">fishBMC מבוסס על fische, כלי לחיזוי סאונד. העקרון הבסיסי הוא: צייר צורת גל ומרח את הציור לאורך הוקטורים המוגדרים מראש. אבל fische הוא גם שילוב מקצועי של זיהוי מקצבים, אשר מעניק חווית חיזוי נהדרת.</description>
+    <description lang="hr">fishBMC je temeljen na fische, samostalnom alatu zvučne vizualizacije. Osnovno načelo je: iscrtati valni oblik i razmazati crtež unaprijed određenim vektorima. Međutim fische isto uključuje napredno otkrivanje taktova, koje uistinu jamči sjajno vizualno iskustvo.</description>
     <description lang="hu">fishBMC a fische-n alapul, egy önálló hangvizualizációs eszköz. A fő célkitűzése: a hanghullám kirajzolása és előre megadott vektorok szerinti módosítása. Viszont a fische szintén alkalmaz egy haladó ütemérzékelőt, ami tényleg garantálja a nagyszerű vizuális élményt.</description>
     <description lang="it">fishBMC si basa su fische, uno strumento di visualizzazione del suono standalone. Il principio di base è: disegnare la forma d'onda e spalmare il disegno lungo i vettori predefiniti. Tuttavia fische incorpora anche il rilevamento di battito avanzato, che garantisce un'ottima esperienza visiva.</description>
     <description lang="lt">fishBMC is based on fische, a standalone sound visualisation tool. The basic principle is: draw the waveform and smear the drawing along predefined vectors. However fische also incorporates advanced beat detection, which really guarantees a great visual experience.</description>
     <description lang="nl">FishBMC is gebaseerd op fische, een zelfstandige geluidsvisualisatie tool. Het basis principe is: Teken de golfvorm en veeg de tekening rondom voor ingestelde richting. Echter fische brengt eveneens geavanceerde beat detectie, wat echt een grote visuele beleving garandeerd.</description>
+    <description lang="pl">fishBMC bazuje na fische, samodzielne narzędzie do wizualizacji muzyki. Podstawową zasadą jest generowanie wykresu fali i rozmazywanie go wzdłuż zdefiniowanych wektorów. Ponadto fische zawiera również zaawansowaną detekcję rytmu, co gwarantuje wspaniałe wrażenia wizualne.</description>
     <description lang="pt">O fishBMC é baseado no fische, uma ferramenta autónoma de visualização de sons. O princípio básico é desenhar a onda e deformar o desenho através de vectores pré-definidos. No entanto, o fische também incorpora detecção avançada de ritmos, garantindo uma excelente experiência visual.</description>
     <description lang="pt_BR">fishBMC é baseado no fische, uma ferramenta de visualização de som independente. O princípio básico é: desenhar a forma de onda e esmaecer o desenho ao longo de vetores pré-definidos. Entretanto fische também incorpora detecção avançada de batidas, o que realmente garante uma grande experiência visual.</description>
     <description lang="sk">fishBMC je založený na fische, samostatnom nástroji na vizualizáciu. Základným princípom je: nakresliť priebeh signálu a rozmazať kresbu pozdĺž predefinovaných vektorov. Navyše fische obsahuje aj pokročilú detekciu rytmu, čo garantuje skutočný vizuálny zážitok.</description>
     <disclaimer lang="et">kui see midagi lõhub, siis võid tükid endale jätta</disclaimer>
     <disclaimer lang="fr_CA">Si ça brise, vous gardez les morceaux.</disclaimer>
     <disclaimer lang="gl">Se isto estraga algunha cousa, pode quedar cas pezas.</disclaimer>
+    <disclaimer lang="hr">Ako ovo slomi nešto, komadići ostaju vama.</disclaimer>
     <disclaimer lang="hu">Ha ez összetör valamit attól a darabok még a tieid maradnak.</disclaimer>
     <disclaimer lang="it">se si rompe qualcosa, i cocci sono vostri.</disclaimer>
     <disclaimer lang="lt">Jei tai sugenda nieko, gabaliukai lieka tavo.</disclaimer>
     <disclaimer lang="nl">Gebruik maken van deze visualisatie is op eigen risico.</disclaimer>
+    <disclaimer lang="pl">Jeśli to rozbije cokolwiek, kawałki pozostaną Twoje.</disclaimer>
     <disclaimer lang="pt">Se isto quebrar alguma coisa, pode ficar com as peças.</disclaimer>
     <disclaimer lang="pt_BR">se isto quebrar algo, as peças serão suas.</disclaimer>
     <disclaimer lang="sk">Ak toto niečo rozbije, kúsky vám ostanú.</disclaimer>
index ed74356..bf8e624 100644 (file)
@@ -1,3 +1,6 @@
+2014-02-17:
+        Updated language files from Transifex
+
 2014-02-02:
         Updated language files from Transifex
 
index daea571..9064feb 100644 (file)
@@ -16,30 +16,50 @@ msgstr ""
 "Language: hr\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
+msgctxt "#30000"
+msgid "Detail [CPU intensive]"
+msgstr "Pojedinosti [CPU intenzivno]"
+
 msgctxt "#30001"
 msgid "Low"
-msgstr "Niska"
+msgstr "Nisko"
 
 msgctxt "#30002"
 msgid "Normal"
-msgstr "Normalan"
+msgstr "Normalno"
 
 msgctxt "#30003"
 msgid "High"
-msgstr "Visoka"
+msgstr "Visoko"
 
 msgctxt "#30004"
 msgid "Extreme"
 msgstr "Ekstremno"
 
+msgctxt "#30005"
+msgid "Nervous Mode [more mode changes]"
+msgstr "Nervozan način [više promjena načina]"
+
+msgctxt "#30006"
+msgid "Speed [skip some frames]"
+msgstr "Brže [preskoči neke sličice]"
+
+msgctxt "#30007"
+msgid "Very Low"
+msgstr "Vrlo nisko"
+
 msgctxt "#30008"
 msgid "Low"
-msgstr "Niska"
+msgstr "Nisko"
 
 msgctxt "#30009"
 msgid "Normal"
-msgstr "Normalan"
+msgstr "Normalno"
 
 msgctxt "#30010"
 msgid "High"
-msgstr "Visoka"
+msgstr "Visoko"
+
+msgctxt "#30011"
+msgid "Use a Persistence File [faster startup]"
+msgstr "Koristi stalnu datoteku [brže pokretanje]"
index a3722a4..d4b68c7 100644 (file)
@@ -32,6 +32,10 @@ msgctxt "#30004"
 msgid "Extreme"
 msgstr "קיצוני"
 
+msgctxt "#30007"
+msgid "Very Low"
+msgstr "נמוך מאוד"
+
 msgctxt "#30008"
 msgid "Low"
 msgstr "נמוך"
index 44091d4..450c7e7 100644 (file)
@@ -32,9 +32,21 @@ msgctxt "#30004"
 msgid "Extreme"
 msgstr "최대"
 
+msgctxt "#30005"
+msgid "Nervous Mode [more mode changes]"
+msgstr "과민성 모드 [잦은 모드 변경]"
+
+msgctxt "#30006"
+msgid "Speed [skip some frames]"
+msgstr "속도 [프레임 건너 뜀]"
+
+msgctxt "#30007"
+msgid "Very Low"
+msgstr "매우 낮음"
+
 msgctxt "#30008"
 msgid "Low"
-msgstr "최저"
+msgstr "낮음"
 
 msgctxt "#30009"
 msgid "Normal"
index 6c77c96..8f08d09 100644 (file)
@@ -18,7 +18,7 @@ msgstr ""
 
 msgctxt "#30000"
 msgid "Detail [CPU intensive]"
-msgstr "Obciążenie [CPU]"
+msgstr "Szczegółowe [silne obciążenie procesora]"
 
 msgctxt "#30001"
 msgid "Low"
@@ -59,3 +59,7 @@ msgstr "Zwykły"
 msgctxt "#30010"
 msgid "High"
 msgstr "Wysoka"
+
+msgctxt "#30011"
+msgid "Use a Persistence File [faster startup]"
+msgstr "Zapisuj do pliku [szybsze uruchomienie]"
index 88502e7..5b12101 100644 (file)
@@ -16,6 +16,10 @@ msgstr ""
 "Language: sv\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+msgctxt "#30000"
+msgid "Detail [CPU intensive]"
+msgstr "Detalj [CPU-intensiv]"
+
 msgctxt "#30001"
 msgid "Low"
 msgstr "Låg"
@@ -32,6 +36,18 @@ msgctxt "#30004"
 msgid "Extreme"
 msgstr "Extrem"
 
+msgctxt "#30005"
+msgid "Nervous Mode [more mode changes]"
+msgstr "Nervöst läge [fler lägesbyten]"
+
+msgctxt "#30006"
+msgid "Speed [skip some frames]"
+msgstr "Snabb [hoppar över några bildrutor]"
+
+msgctxt "#30007"
+msgid "Very Low"
+msgstr "Väldigt låg"
+
 msgctxt "#30008"
 msgid "Low"
 msgstr "Låg"
index 037ed20..e7fbf10 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.glspectrum"
-  version="1.0.14"
+  version="1.0.15"
   name="OpenGL Spectrum"
   provider-name="Team XBMC">
   <extension
index be0504a..00d8926 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.milkdrop"
-  version="1.0.14"
+  version="1.0.15"
   name="MilkDrop"
   provider-name="Team XBMC">
   <extension
index c205b0e..3477226 100644 (file)
@@ -22,7 +22,7 @@ msgstr "Automatic Blend Time"
 
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "Time Between Presets"
+msgstr "זמן בין קביעונים"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
@@ -54,27 +54,27 @@ msgstr "הפעל סטריאו 3D"
 
 msgctxt "#30009"
 msgid "Preset Pack"
-msgstr "Preset Pack"
+msgstr "חבילת קביעונים"
 
 msgctxt "#30010"
 msgid "User Preset Folder        "
-msgstr "User Preset Folder        "
+msgstr "תיקית קביעוני משתמש"
 
 msgctxt "#30011"
 msgid "Preset Shuffle Mode"
-msgstr "Preset Shuffle Mode"
+msgstr "קביעון מצב מעורבב"
 
 msgctxt "#30020"
 msgid "WA51 Presets"
-msgstr "WA51 Presets"
+msgstr "קביעוני WA51"
 
 msgctxt "#30021"
 msgid "Winamp Presets"
-msgstr "Winamp Presets"
+msgstr "קביעוני Winamp"
 
 msgctxt "#30022"
 msgid "User Defined Preset Folder"
-msgstr "User Defined Preset Folder"
+msgstr "תיקית קביעוני הגדרת משתמש"
 
 msgctxt "#30050"
 msgid "%2.0f secs"
index a0fd6c8..9723f61 100644 (file)
@@ -22,7 +22,7 @@ msgstr "Otomatik Karıştırma Zamanı"
 
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "Ön Ayarlar Arasındaki Zaman"
+msgstr "Önayarlar Arasındaki Zaman"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
@@ -58,7 +58,7 @@ msgstr "Önayar Paketi"
 
 msgctxt "#30010"
 msgid "User Preset Folder        "
-msgstr "Kullanıcı Ön Ayar Klasörü"
+msgstr "Kullanıcı Önayar Klasörü"
 
 msgctxt "#30011"
 msgid "Preset Shuffle Mode"
@@ -66,15 +66,15 @@ msgstr "Karıştırma Modunu Önayarla"
 
 msgctxt "#30020"
 msgid "WA51 Presets"
-msgstr "WA51 Ön Ayarları"
+msgstr "WA51 Önayarları"
 
 msgctxt "#30021"
 msgid "Winamp Presets"
-msgstr "Winamp Ön Ayarları"
+msgstr "Winamp Önayarları"
 
 msgctxt "#30022"
 msgid "User Defined Preset Folder"
-msgstr "Kullanıcı Tanımlı Ön Ayar Klasörü"
+msgstr "Kullanıcı Tanımlı Önayar Klasörü"
 
 msgctxt "#30050"
 msgid "%2.0f secs"
index ec3b1df..7466623 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.projectm"
-  version="1.0.15"
+  version="1.0.16"
   name="projectM"
   provider-name="Team XBMC">
   <extension
index 909e288..63d21a9 100644 (file)
@@ -38,7 +38,7 @@ msgstr "מקסימום"
 
 msgctxt "#30005"
 msgid "Shuffle Mode"
-msgstr "×\9eצ×\91 ×\90קר×\90×\99"
+msgstr "×\9eצ×\91 ×\9e×¢×\95ר×\91×\91"
 
 msgctxt "#30006"
 msgid "Smooth Preset Duration"
@@ -46,7 +46,7 @@ msgstr "Smooth Preset Duration"
 
 msgctxt "#30007"
 msgid "Preset Duration"
-msgstr "Preset Duration"
+msgstr "משך קביעון"
 
 msgctxt "#30008"
 msgid "Beat Sensitivity"
@@ -54,7 +54,7 @@ msgstr "רגישות קצב"
 
 msgctxt "#30009"
 msgid "Preset Pack"
-msgstr "Preset Pack"
+msgstr "חבילת קביעונים"
 
 msgctxt "#30010"
 msgid "Default Pack"
@@ -62,11 +62,11 @@ msgstr "ערכת ברירת מחדל"
 
 msgctxt "#30011"
 msgid "User Defined Preset Folder"
-msgstr "User Defined Preset Folder"
+msgstr "תיקית קביעוני הגדרת משתמש"
 
 msgctxt "#30012"
 msgid "User Preset Folder"
-msgstr "User Preset Folder"
+msgstr "תיקית קביעוני משתמש"
 
 msgctxt "#30050"
 msgid "%2.0f secs"
index bbc5ee8..7ee0484 100644 (file)
@@ -42,11 +42,11 @@ msgstr "Karıştırma Modu"
 
 msgctxt "#30006"
 msgid "Smooth Preset Duration"
-msgstr "Akıcı Ön Ayar Süresi"
+msgstr "Akıcı Önayar Süresi"
 
 msgctxt "#30007"
 msgid "Preset Duration"
-msgstr "Ön Ayar Süresi"
+msgstr "Önayar Süresi"
 
 msgctxt "#30008"
 msgid "Beat Sensitivity"
@@ -62,11 +62,11 @@ msgstr "Varsayılan Paket"
 
 msgctxt "#30011"
 msgid "User Defined Preset Folder"
-msgstr "Kullanıcı Tanımlı Ön Ayar Klasörü"
+msgstr "Kullanıcı Tanımlı Önayar Klasörü"
 
 msgctxt "#30012"
 msgid "User Preset Folder"
-msgstr "Kullanıcı Ön Ayar Klasörü"
+msgstr "Kullanıcı Önayar Klasörü"
 
 msgctxt "#30050"
 msgid "%2.0f secs"
index 8f81a18..dbb2486 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.vortex"
-  version="1.0.2"
+  version="1.0.3"
   name="Vortex"
   provider-name="Team XBMC">
   <extension
     <summary lang="et">Vortex visuaal XBOX-i paketist</summary>
     <summary lang="fr_CA">Visualisation Vortex du paquet XBOX</summary>
     <summary lang="gl">Visualización Vortex do paquete XBOX</summary>
+    <summary lang="hr">Vortex vizualizacija iz XBOX paketa</summary>
     <summary lang="hu">Vortex vizualizáció az XBOX csomagból</summary>
+    <summary lang="ko">XBOX 패키지의 Vortex 시각화</summary>
     <summary lang="nl">Vortex Visualisatie van XBOX verpakking</summary>
     <summary lang="pl">Wizualizacja Vortex z pakietu XBOX</summary>
     <summary lang="pt">Visualização Vortex do pacote XBOX</summary>
     <summary lang="pt_BR">Visualização Vortex do pacote XBOX</summary>
     <summary lang="sk">Vortex vizualizácia z XBOX balíčku</summary>
     <summary lang="sl">Vizualizacija Vortex iz paketa XBOX</summary>
+    <summary lang="sv">Vortex Visualization från XBOX-paketet</summary>
     <summary lang="tg">Таҷассуми Vortex аз бастаи XBOX</summary>
+    <summary lang="tr">XBOX paketinden Vortex Görsel Öğe</summary>
     <summary lang="zh">来自 XBOX 组件包的旋涡可视化效果</summary>
     <platform>windx</platform>
   </extension>
index d96dd1e..71ffc2d 100644 (file)
@@ -16,18 +16,46 @@ msgstr ""
 "Language: hr\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
+msgctxt "#30000"
+msgid "Random Presets"
+msgstr "Naizmjenični predložci"
+
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "Vrijeme izmeÄ\91u predloÅ¡ka"
+msgstr "Vrijeme izmeÄ\91u predložka"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
 msgstr "Dodatno naizmjenično vrijeme"
 
+msgctxt "#30003"
+msgid "Lock Preset"
+msgstr "Zaključaj predložak"
+
+msgctxt "#30004"
+msgid "Enable Transitions"
+msgstr "Omogući prijelaz"
+
+msgctxt "#30005"
+msgid "Stop first preset"
+msgstr "Zaustavi prvi predložak"
+
+msgctxt "#30006"
+msgid "Show FPS"
+msgstr "Prikaži Sl/Sek"
+
+msgctxt "#30007"
+msgid "Show debug console"
+msgstr "Prikaži konzolu otklanjanja grešaka"
+
+msgctxt "#30008"
+msgid "Show audio analysis"
+msgstr "Prikaži zvučnu analizu"
+
 msgctxt "#30050"
 msgid "%2.0f secs"
-msgstr "%2.0f sekundi"
+msgstr "%2.0f sek"
 
 msgctxt "#30051"
 msgid "%2.0f fps"
-msgstr "%2.0f fps"
+msgstr "%2.0f sl/sek"
index c4938f2..e7af64b 100644 (file)
@@ -16,18 +16,42 @@ msgstr ""
 "Language: he\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+msgctxt "#30000"
+msgid "Random Presets"
+msgstr "קביעונים אקראים"
+
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "Time Between Presets"
+msgstr "זמן בין קביעונים"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
 msgstr "Additional Random Time"
 
+msgctxt "#30003"
+msgid "Lock Preset"
+msgstr "נעל קביעון"
+
+msgctxt "#30004"
+msgid "Enable Transitions"
+msgstr "הפעל מעברים"
+
+msgctxt "#30005"
+msgid "Stop first preset"
+msgstr "עצור קביעון ראשון"
+
 msgctxt "#30006"
 msgid "Show FPS"
 msgstr "הצג FPS"
 
+msgctxt "#30007"
+msgid "Show debug console"
+msgstr "הצג קונסולת debug"
+
+msgctxt "#30008"
+msgid "Show audio analysis"
+msgstr "הצג ניתוח אודיו"
+
 msgctxt "#30050"
 msgid "%2.0f secs"
 msgstr "%2.0f שניות"
index 8f76faf..1328d5a 100644 (file)
@@ -16,14 +16,42 @@ msgstr ""
 "Language: ko\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 
+msgctxt "#30000"
+msgid "Random Presets"
+msgstr "무작위 프리셋"
+
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "프리셋사이 간격"
+msgstr "프리셋 사이 간격"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
 msgstr "추가적 랜덤 간격"
 
+msgctxt "#30003"
+msgid "Lock Preset"
+msgstr "프리셋 잠금"
+
+msgctxt "#30004"
+msgid "Enable Transitions"
+msgstr "전환효과 사용"
+
+msgctxt "#30005"
+msgid "Stop first preset"
+msgstr "첫번째 프리셋 정지"
+
+msgctxt "#30006"
+msgid "Show FPS"
+msgstr "FPS 보기"
+
+msgctxt "#30007"
+msgid "Show debug console"
+msgstr "디버그 콘솔 보기"
+
+msgctxt "#30008"
+msgid "Show audio analysis"
+msgstr "오디오 분석 보기"
+
 msgctxt "#30050"
 msgid "%2.0f secs"
 msgstr "%2.0f 초"
index e6778c1..4cca685 100644 (file)
@@ -16,6 +16,10 @@ msgstr ""
 "Language: sv\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
+msgctxt "#30000"
+msgid "Random Presets"
+msgstr "Slumpmässiga förval"
+
 msgctxt "#30001"
 msgid "Time Between Presets"
 msgstr "Tid mellan förval"
@@ -24,6 +28,30 @@ msgctxt "#30002"
 msgid "Additional Random Time"
 msgstr "Extra slumpmässig tid"
 
+msgctxt "#30003"
+msgid "Lock Preset"
+msgstr "Lås förval"
+
+msgctxt "#30004"
+msgid "Enable Transitions"
+msgstr "Aktivera övergångar"
+
+msgctxt "#30005"
+msgid "Stop first preset"
+msgstr "Stoppa första förvalet"
+
+msgctxt "#30006"
+msgid "Show FPS"
+msgstr "Visa FPS"
+
+msgctxt "#30007"
+msgid "Show debug console"
+msgstr "Visa debugkonsol"
+
+msgctxt "#30008"
+msgid "Show audio analysis"
+msgstr "Visa audioanalys"
+
 msgctxt "#30050"
 msgid "%2.0f secs"
 msgstr "%2.0f sek"
index 2aff8fe..2df1c4f 100644 (file)
@@ -16,13 +16,41 @@ msgstr ""
 "Language: tr\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 
+msgctxt "#30000"
+msgid "Random Presets"
+msgstr "Rastgele Önayarlar"
+
 msgctxt "#30001"
 msgid "Time Between Presets"
-msgstr "Ön Ayarlar Arasındaki Zaman"
+msgstr "Önayarlar Arasındaki Zaman"
 
 msgctxt "#30002"
 msgid "Additional Random Time"
-msgstr "İlave Rasgele Zaman"
+msgstr "İlave Rastgele Zaman"
+
+msgctxt "#30003"
+msgid "Lock Preset"
+msgstr "Önayarları Kilitle"
+
+msgctxt "#30004"
+msgid "Enable Transitions"
+msgstr "Geçişleri Etkinleştir"
+
+msgctxt "#30005"
+msgid "Stop first preset"
+msgstr "İlk önayarı durdur"
+
+msgctxt "#30006"
+msgid "Show FPS"
+msgstr "FPS'yi göster"
+
+msgctxt "#30007"
+msgid "Show debug console"
+msgstr "Hata ayıklama konsolunu göster"
+
+msgctxt "#30008"
+msgid "Show audio analysis"
+msgstr "Ses analizlerini göster"
 
 msgctxt "#30050"
 msgid "%2.0f secs"
index fad0fd3..8ad0219 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="visualization.waveform"
-  version="1.0.14"
+  version="1.0.15"
   name="Waveform"
   provider-name="MrC">
   <extension
index 3b2a881..4517f23 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon
   id="webinterface.default"
-  version="2.2.8"
+  version="2.2.9"
   name="Default"
   provider-name="Team XBMC">
   <requires>
index 9cd3ec0..225d7b3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.debug" version="0.1.11" provider-name="Team XBMC" name="Log">
+<addon id="xbmc.debug" version="0.1.12" provider-name="Team XBMC" name="Log">
   <backwards-compatibility abi="0.1"/>
   <requires>
     <c-pluff version="0.1"/>
@@ -27,6 +27,7 @@
     <summary lang="is">Viðbót til þess að bæta skráningu á sérsniði</summary>
     <summary lang="it">Addon per migliorare la personalizzazione di logging</summary>
     <summary lang="ja">ログのカスタマイズ性をより良くするアドオン</summary>
+    <summary lang="ko">로깅 개인화를 향상시켜주는 에드온</summary>
     <summary lang="lt">Priedų registravimo adaptacija</summary>
     <summary lang="lv">Pievienojumprogramma, ierakstījumu žurnalā pielāgošanai</summary>
     <summary lang="my">logging စိတ်ကြိုက်ပြုပြင် မှုကို တိုးတက်စေသော Addon</summary>
@@ -41,7 +42,7 @@
     <summary lang="sv">Tillägg för att förbättra loggningen av anpassningsmöjligheterna</summary>
     <summary lang="ta_IN">தனிப்பயனாக்கு பதிவை மேம்படுத்துவதற்கான துணை-பயன்</summary>
     <summary lang="tg">Барномаи иловагӣ барои такмили танзимоти воридшавӣ</summary>
-    <summary lang="tr">Kayıt defteri kişiselleştirmesini geliştirmek için eklenti</summary>
+    <summary lang="tr">Günlük kişiselleştirilebilirliğini geliştirmek için eklenti</summary>
     <summary lang="zh">增强日志定制功能的插件</summary>
     <summary lang="zh_TW">用以改善記錄檔之客製性靈活度的外掛</summary>
     <platform>all</platform>
index 671b5df..66ea9cf 100644 (file)
@@ -18,24 +18,24 @@ msgstr ""
 
 msgctxt "#30000"
 msgid "Verbose logging for SMB library"
-msgstr "SMB kütüphanesi için ayrıntılı kayıt tutma"
+msgstr "SMB kütüphanesi için ayrıntılı günlük"
 
 msgctxt "#30001"
 msgid "Verbose logging for CURL library (http, dav)"
-msgstr "CURL (http, dav) kütüphanesi için ayrıntılı kayıt tutma"
+msgstr "CURL kütüphanesi (http, dav) için ayrıntılı günlük"
 
 msgctxt "#30002"
 msgid "Verbose logging for CMYTH library"
-msgstr "CMYTH kütüphanesi için ayrıntılı kayıt tutma"
+msgstr "CMYTH kütüphanesi için ayrıntılı günlük"
 
 msgctxt "#30003"
 msgid "Verbose logging for FFMPEG libraries"
-msgstr "FFMPEG kütüphanesi için ayrıntılı kayıt tutma"
+msgstr "FFMPEG kütüphaneleri için ayrıntılı günlük"
 
 msgctxt "#30004"
 msgid "Verbose logging for RTMP library"
-msgstr "RTMP kütüphanesi için ayrıntılı kayıt tutma"
+msgstr "RTMP kütüphanesi için ayrıntılı günlük"
 
 msgctxt "#30005"
 msgid "Verbose logging for DBUS calls"
-msgstr "DBUS çağrıları için ayrıntılı kayıt tutma"
+msgstr "DBUS çağrıları için ayrıntılı günlük"
index dfbcee0..f368ffc 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <addon id="xbmc.gui" version="5.0.1" provider-name="Team XBMC">
-  <backwards-compatibility abi="4.00"/>
+  <backwards-compatibility abi="5.0.0"/>
   <requires>
     <import addon="xbmc.core" version="0.1.0"/>
   </requires>
index 48980d1..7390167 100644 (file)
@@ -18,6 +18,9 @@ tolower(){
   echo "$@" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
 }
 
+# workaround for autotools that don't set this
+abs_top_srcdir=${abs_top_srcdir=$(cd $srcdir; pwd)}
+
 # check for enabling additional players
 AC_DEFUN([XB_ADD_PLAYER],
 [
@@ -137,7 +140,7 @@ wayland_disabled="== Wayland disabled. =="
 x11_enabled="== X11 enabled. =="
 x11_disabled="== X11 disabled. =="
 pulse_not_found="== Could not find libpulse. PulseAudio support disabled. =="
-pulse_disabled="== PulseAudio support manually disabled. =="
+pulse_disabled="== PulseAudio support disabled. =="
 dvdcss_enabled="== DVDCSS support enabled. =="
 dvdcss_disabled="== DVDCSS support disabled. =="
 hal_not_found="== Could not find hal. HAL support disabled. =="
@@ -756,7 +759,7 @@ AC_CHECK_PROG(HAVE_GIT,git,"yes","no",)
 if test "$GIT_REV" = ""; then
   if test -f VERSION ; then
     GIT_REV=$(awk 'END{print substr($1,1,16)}' VERSION)
-  elif test "$HAVE_GIT" = "yes"; then
+  elif test "$HAVE_GIT" = "yes" -a -d ${abs_top_srcdir}/.git; then
     GIT_REV=$(git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h %ci" HEAD | awk '{gsub("-", "");print $2"-"$1}')
   else
     GIT_REV="Unknown"
@@ -1101,6 +1104,11 @@ AC_CHECK_HEADER([FLAC/stream_decoder.h],, AC_MSG_ERROR($missing_library))
 # we need to check for the header because if it exists we set the openssl
 # and gcrypt MT callback hooks. This is mostly so that libcurl operates 
 # in MT manner correctly.
+AC_MSG_CHECKING([for CRYPTO_set_locking_callback(0)])
+AC_TRY_LINK([],[CRYPTO_set_locking_callback(0);],
+                [have_curl_static=yes],
+                [have_curl_static=no])
+AC_MSG_RESULT($have_curl_static)
 AC_CHECK_HEADER([openssl/crypto.h], AC_DEFINE([HAVE_OPENSSL],[1],[Define if we have openssl]),)
 AC_CHECK_HEADER([gcrypt.h], gcrypt_headers_available=yes,gcrypt_headers_available=no)
 if test "$gcrypt_headers_available" = "yes"; then
@@ -1255,12 +1263,7 @@ XB_FIND_SONAME([VORBIS],      [vorbis])
 XB_FIND_SONAME([VORBISFILE],  [vorbisfile])
 XB_FIND_SONAME([MODPLUG],     [modplug])
 XB_FIND_SONAME([ASS],         [ass])
-
-#link statically against mpeg2 on ios  because of ios7
-#crash & burn if dyloaded
-if test "$ARCH" != "arm-osx" ; then
-  XB_FIND_SONAME([MPEG2],       [mpeg2])
-fi
+XB_FIND_SONAME([MPEG2],       [mpeg2])
 
 # Audio encoders
 if test "x$use_libmp3lame" != "xno"; then
@@ -1325,17 +1328,17 @@ if test "x$use_pulse" != "xno"; then
     fi
     USE_PULSE=0
   else
-    AC_CHECK_LIB([pulse],[main],,pulse_found="no")
-    AC_CHECK_LIB([pulse-simple],[main],,pulse_found="no")
-
-    if test "x$pulse_found" != "xno"; then
-      USE_PULSE=1
-    elif test "x$use_pulse" = "xyes"; then
-      AC_MSG_ERROR($pulse_not_found)
-    else
-      use_pulse=no
-      USE_PULSE=0
-      AC_MSG_RESULT($pulse_not_found)
+    PKG_CHECK_MODULES([PULSE], [libpulse >= 1.0],
+      [INCLUDES="$INCLUDES $PULSE_CFLAGS"; LIBS="$LIBS $PULSE_LIBS"; USE_PULSE=1;
+        HAVE_LIBPULSE=1; AC_DEFINE([HAVE_LIBPULSE],[1],[Pulse audio enabled])],
+      [pulse_found="no"; USE_PULSE=0; HAVE_LIBPULSE=0])
+
+    if test "$pulse_found" = "no"; then
+      if test "x$use_pulse" = "xyes"; then
+        AC_MSG_ERROR($pulse_not_found)
+      else
+        AC_MSG_RESULT($pulse_disabled)
+      fi
     fi
   fi
 else
@@ -1518,6 +1521,11 @@ else
   AC_DEFINE([HAVE_LIBSSH], [1], [Whether to use libSSH library.])
 fi
 
+# libcurl
+if test "x$have_curl_static" = "xyes"; then
+  AC_DEFINE([HAS_CURL_STATIC], [1], [Whether OpenSSL inside libcurl is static.])
+fi
+
 # libRTMP
 if test "$use_librtmp" != "no"; then
   AC_CHECK_HEADERS([librtmp/log.h librtmp/amf.h librtmp/rtmp.h],,
@@ -2641,6 +2649,7 @@ AC_SUBST(USE_LIBAFPCLIENT)
 AC_SUBST(USE_AIRPLAY)
 AC_SUBST(USE_OPENMAX)
 AC_SUBST(USE_PULSE)
+AC_SUBST(HAVE_LIBPULSE)
 AC_SUBST(USE_XRANDR)
 AC_SUBST(USE_ALSA)
 AC_SUBST(USE_TEXTUREPACKER)
@@ -2864,7 +2873,6 @@ XB_CONFIG_MODULE([lib/libdvd/libdvdread], [
     --disable-strip \
     --disable-opts \
     --cc="$CC" &&
-  $MAKE dvdread-config &&
   mkdir -p `pwd`/../includes/dvdread
   cp `pwd`/../libdvdread/src/*.h `pwd`/../includes/dvdread
   cp `pwd`/../libdvdread/src/dvdread/*.h `pwd`/../includes/dvdread
@@ -2874,7 +2882,7 @@ XB_CONFIG_MODULE([lib/libdvd/libdvdnav], [
   ./configure2 \
     --extra-cflags="$CFLAGS $DVDREAD_CFLAGS -I`pwd`/../includes $DROID_DVDLIB_SEEK64" \
     --extra-ldflags="-L`pwd`/../libdvdread/obj" \
-    --with-dvdread-config="`pwd`/../libdvdread/obj/dvdread-config" \
+    --with-dvdread-config="`pwd`/../dvdread-config" \
     --prefix="${prefix}" --includedir="${includedir}" --libdir="${libdir}" --datadir="${datadir}" \
     --host=$host_alias \
     --build=$build_alias \
index 318f9c0..dbb7574 100644 (file)
@@ -6733,10 +6733,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motorry"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fiksheid &amp; Gesondheid"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Kook"
@@ -6757,10 +6753,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Oorspronklike Taal"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Swart &amp; Wit"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Ongepubliseer"
@@ -9809,6 +9801,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Aantal kanale"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 7cf59b3..0999f07 100644 (file)
@@ -6817,10 +6817,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motorizim"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitnes & Shëndetësi"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Gatim"
@@ -6841,10 +6837,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Gjuha origjinale"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Zi &amp; Bardh"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "I pabotuar"
@@ -9893,6 +9885,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Numri i kanaleve"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index cc1085e..2f31aa1 100644 (file)
@@ -5473,6 +5473,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "የጣቢያዎች ቁጥር "
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index f6ed3a7..b14fd23 100644 (file)
@@ -9573,6 +9573,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "عدد القنوات"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 54fac5a..119c9a4 100644 (file)
@@ -1841,6 +1841,10 @@ msgctxt "#24027"
 msgid "Weather"
 msgstr "Hava durumu"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanalların sayısı"
+
 msgctxt "#35502"
 msgid "Name"
 msgstr "Ad"
index ae978f0..3611536 100644 (file)
@@ -6333,10 +6333,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motorra"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Kirola eta osasuna"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Sukaldaritza"
@@ -6357,10 +6353,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Jatorriko hizkuntza"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Txuri-beltza"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Argitaratu gabea"
@@ -9385,6 +9377,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanal kopurua"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 7e72bde..0924897 100644 (file)
@@ -6989,10 +6989,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motoring"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Health"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cooking"
@@ -7013,10 +7009,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Original Language"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Black &amp; White"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Unpublished"
@@ -10145,6 +10137,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Колькасьць каналаў"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 2b93905..518fd72 100644 (file)
@@ -8753,6 +8753,10 @@ msgctxt "#34003"
 msgid "DXVA2"
 msgstr "DXVA"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Broj kanala"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 6ee8b1f..7d22353 100644 (file)
@@ -771,7 +771,7 @@ msgstr "Вертикално отместване"
 
 msgctxt "#226"
 msgid "Test patterns..."
-msgstr "Тест на моделите..."
+msgstr "Тестови модели за калибриране..."
 
 msgctxt "#227"
 msgid "Lookup audio CD track names from freedb.org"
@@ -1191,7 +1191,11 @@ msgstr "Настройки на извеждането"
 
 msgctxt "#338"
 msgid "Fixed"
-msgstr "Фиксирана"
+msgstr "Фиксирани"
+
+msgctxt "#339"
+msgid "Optimized"
+msgstr "Оптимални"
 
 msgctxt "#340"
 msgid "Various artists"
@@ -1501,9 +1505,13 @@ msgctxt "#419"
 msgid "High"
 msgstr "Макс"
 
+msgctxt "#420"
+msgid "Best Match"
+msgstr "Най-съвпадащи"
+
 msgctxt "#421"
 msgid "Keep audio device alive"
-msgstr "Поддържай аудио устройството включено"
+msgstr "Поддържай аудио устройството включено..."
 
 msgctxt "#422"
 msgid "Delete album info"
@@ -2587,11 +2595,11 @@ msgstr "Светло син"
 
 msgctxt "#764"
 msgid "Yellow green"
-msgstr "Жълтозелен"
+msgstr "Жълто-зелен"
 
 msgctxt "#765"
 msgid "Cyan"
-msgstr "Синьозелен"
+msgstr "Синьо-зелен"
 
 msgctxt "#766"
 msgid "Light grey"
@@ -2629,6 +2637,10 @@ msgctxt "#777"
 msgid "Wireless password"
 msgstr "Парола на безжична мрежа"
 
+msgctxt "#778"
+msgid "Wireless security"
+msgstr "Защита на безжичната мрежа"
+
 msgctxt "#779"
 msgid "Save and apply network interface settings"
 msgstr "Запиши и приложи настройките на мрежовия интерфейс"
@@ -2965,6 +2977,10 @@ msgctxt "#1184"
 msgid "SOCKS5"
 msgstr "SOCKS5"
 
+msgctxt "#1185"
+msgid "SOCKS5 with remote dns resolving"
+msgstr "SOCKS5 с отдалечено dns разрешаване"
+
 msgctxt "#1200"
 msgid "SMB client"
 msgstr "SMB клиент"
@@ -3459,7 +3475,7 @@ msgstr "Не е налична помощ"
 
 msgctxt "#10045"
 msgid "Resets all the visible settings to their default values."
-msgstr "Нулира всички видими настройки към стандартните им стойности"
+msgstr "Нулира всички видими настройки към стандартните им стойности."
 
 msgctxt "#10046"
 msgid "No categories available"
@@ -3811,7 +3827,7 @@ msgstr "Обработване на %s"
 
 msgctxt "#12351"
 msgid "The art cache in your video library needs updating."
-msgstr "Ð\9dеобÑ\85одимо Ðµ Ð°ÐºÑ\82Ñ\83ализиÑ\80ане Ð½Ð° ÐºÐµÑ\88а Ð½Ð° ÐºÐ°Ñ\80Ñ\82инкиÑ\82е Ð¾Ñ\82 Ð²Ð¸Ð´ÐµÐ¾ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ\82екаÑ\82а."
+msgstr "Ð\9dеобÑ\85одимо Ðµ ÐºÐµÑ\88а Ð½Ð° ÐºÐ°Ñ\80Ñ\82инкиÑ\82е Ð¾Ñ\82 Ð²Ð¸Ð´ÐµÐ¾ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ\82екаÑ\82а Ð´Ð° Ð±Ñ\8aде Ð°ÐºÑ\82Ñ\83ализиÑ\80ан."
 
 msgctxt "#12352"
 msgid "No downloading is needed."
@@ -4159,7 +4175,7 @@ msgstr "Затъмнени екрани"
 
 msgctxt "#13140"
 msgid "Active connections detected!"
-msgstr "Ð\97аÑ\81еÑ\87ени са активни връзки!"
+msgstr "Ð\9eÑ\82кÑ\80иÑ\82и са активни връзки!"
 
 msgctxt "#13141"
 msgid "If you proceed, you might not be able to control XBMC"
@@ -4771,7 +4787,7 @@ msgstr "Метод за рендване"
 
 msgctxt "#13416"
 msgid "Auto detect"
-msgstr "Ð\90вÑ\82омаÑ\82иÑ\87но Ð·Ð°Ñ\81иÑ\87ане"
+msgstr "Ð\90вÑ\82омаÑ\82иÑ\87но Ð¾Ñ\82кÑ\80иване"
 
 msgctxt "#13417"
 msgid "Basic shaders (ARB)"
@@ -5803,7 +5819,7 @@ msgstr "Внасяне на EPG от клиентите"
 
 msgctxt "#19005"
 msgid "PVR stream information"
-msgstr "Информация за PVR протокола"
+msgstr "Информация за PVR потока"
 
 msgctxt "#19006"
 msgid "Receiving device"
@@ -5831,7 +5847,7 @@ msgstr "UNC"
 
 msgctxt "#19012"
 msgid "PVR Backend"
-msgstr "PVR сървър"
+msgstr "PVR бек енд"
 
 msgctxt "#19013"
 msgid "Free to air"
@@ -5847,12 +5863,16 @@ msgstr "Шифроване"
 
 msgctxt "#19016"
 msgid "PVR Backend %i - %s"
-msgstr "PVR сървър %i - %s"
+msgstr "PVR бек енд %i - %s"
 
 msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Записи от ТВ"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Папка с икони на канали"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Канали"
@@ -6029,6 +6049,10 @@ msgctxt "#19064"
 msgid "Go to end"
 msgstr "Отиди в края"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Икона на канала"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Събитието вече се записва"
@@ -6223,7 +6247,7 @@ msgstr "Само отворени канали"
 
 msgctxt "#19124"
 msgid "Ignore present timers"
-msgstr "Игнорирай съществуващите таймери"
+msgstr "Игнорирай съществуващите броячи"
 
 msgctxt "#19125"
 msgid "Ignore present recordings"
@@ -6515,7 +6539,7 @@ msgstr "Въведете име на новия канал"
 
 msgctxt "#19209"
 msgid "XBMC virtual backend"
-msgstr "Виртуален сървър XBMC"
+msgstr "XBMC виртуален бек енд"
 
 msgctxt "#19210"
 msgid "Client"
@@ -6531,7 +6555,7 @@ msgstr "В списъка има промени "
 
 msgctxt "#19213"
 msgid "Select backend"
-msgstr "Ð\98збеÑ\80еÑ\82е Ñ\81Ñ\8aÑ\80вÑ\8aÑ\80"
+msgstr "Ð\98збеÑ\80и Ð±ÐµÐº ÐµÐ½Ð´"
 
 msgctxt "#19214"
 msgid "Enter a valid URL for the new channel"
@@ -6539,7 +6563,7 @@ msgstr "Въведете валиден адрес на новия канал"
 
 msgctxt "#19215"
 msgid "The PVR backend does not support timers."
-msgstr "PVR сървъра не поддържа таймери."
+msgstr "PVR бек енда не поддържа броячи."
 
 msgctxt "#19216"
 msgid "All radio channels"
@@ -6619,7 +6643,7 @@ msgstr "Стартиране на фонови процеси"
 
 msgctxt "#19241"
 msgid "The PVR manager has been enabled without any"
-msgstr "PVR мениджъра е включен без"
+msgstr "PVR мениджъра е включен без каквото и да е"
 
 msgctxt "#19245"
 msgid "Set wakeup command (cmd [timestamp])"
@@ -6651,7 +6675,7 @@ msgstr "Актуализиране на EPG информацията"
 
 msgctxt "#19254"
 msgid "EPG update failed for channel"
-msgstr "Ð\9dе Ð±Ðµ Ð°ÐºÑ\82Ñ\83ализиÑ\80ан EPG за канала"
+msgstr "Ð\9dе Ð±Ðµ Ð¾Ð±Ð½Ð¾Ð²Ðµн EPG за канала"
 
 msgctxt "#19255"
 msgid "Start recording"
@@ -6745,6 +6769,22 @@ msgctxt "#19280"
 msgid "Client specific settings"
 msgstr "Настройки, специфични за клиента"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Текуща икона"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Няма икона"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Избери икона"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Преглед за икона"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Друго/Нейзвестно"
@@ -6969,10 +7009,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Авто Мото"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Фитнес и здраве"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Готвене"
@@ -7901,6 +7937,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Сканиране на албумите чрез \"%s\""
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Сюжет на филм"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Възпроизведи част..."
@@ -8537,6 +8577,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Премахни споделения медиен ресурс"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Персонална папка за субтитри"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Премести и промени папката за субтитри"
@@ -8905,6 +8949,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "смесено"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Позиция за субтитрите на екрана"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Фиксирана"
@@ -8943,7 +8991,7 @@ msgstr "Предимство на външните субтитри"
 
 msgctxt "#21601"
 msgid "Prefer external subtitles to internal ones"
-msgstr "XBMC ще зарежда външните субтитри вместо вградените, когато и двата вида са налични"
+msgstr "XBMC ще зарежда външните субтитри вместо вградените, когато и двата вида са налични."
 
 msgctxt "#21602"
 msgid "(External)"
@@ -9807,7 +9855,7 @@ msgstr "Активирай режима \"На  пауза\" при търсен
 
 msgctxt "#24106"
 msgid "If not saved to movie folder subtitles will be downloaded to custom subtitle folder"
-msgstr "Ако не се съхраняват в папките на отделните филми, свалените субтитри ще бъдат записвани в зададената папка."
+msgstr "Ð\90ко Ð½Ðµ Ñ\81е Ñ\81Ñ\8aÑ\85Ñ\80анÑ\8fваÑ\82 Ð² Ð¿Ð°Ð¿ÐºÐ¸Ñ\82е Ð½Ð° Ð¾Ñ\82делниÑ\82е Ñ\84илми, Ñ\81валениÑ\82е Ñ\81Ñ\83бÑ\82иÑ\82Ñ\80и Ñ\89е Ð±Ñ\8aдаÑ\82 Ð·Ð°Ð¿Ð¸Ñ\81вани Ð² Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð°Ñ\82а Ð¿ÐµÑ\80Ñ\81онална Ð¿Ð°Ð¿ÐºÐ°."
 
 msgctxt "#24107"
 msgid "Searching for subtitles ..."
@@ -9861,6 +9909,10 @@ msgctxt "#24119"
 msgid "Select service that will be used as default to search for Movie subtitles"
 msgstr "Изберете коя услуга да се ползва при стандартно търсене на субтитри за филм"
 
+msgctxt "#24120"
+msgid "Manual search string"
+msgstr "Ръчно търсене"
+
 msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Въведете низ за търсене"
@@ -9893,6 +9945,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Изберете елемент за възпроизвеждане"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Глави: %u - Времетраене: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Възпроизвеждането на Blu-ray диска се провали"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Менюто на този Blu-ray диск не от поддържаните видове"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Режим \"Библиотека\""
@@ -10215,7 +10279,7 @@ msgstr "Комуникация с отдалечен сървър"
 
 msgctxt "#33200"
 msgid "Detected New Connection"
-msgstr "Ð\97аÑ\81еÑ\87ена е нова връзка"
+msgstr "Ð\9eÑ\82кÑ\80иÑ\82а е нова връзка"
 
 msgctxt "#34000"
 msgid "Lame"
@@ -10249,6 +10313,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Брой на каналите"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10291,7 +10359,7 @@ msgstr "7.1"
 
 msgctxt "#34111"
 msgid "Select the behaviour when no sound is required for either playback or GUI sounds. [Always] - continuous inaudible signal is output, this keeps the receiving audio device alive for any new sounds, however this might also block sound from other applications. [1- 10 Minutes] - same as Always except that after the selected period of time audio enters a suspended state [Off] - audio output enters a suspended state. Note - sounds can be missed if audio enters suspended state."
-msgstr "Изберете поведение когато не се възпроизвежда звук. [Винаги] - непрекъснато извеждане на сигнал, който не можете да чуете. Така приемника няма да се изключи и ще бъде в готовност веднага да възпроизвежда при необходимост, но може да доведе до блокиране на звука от други приложения. [1- 10 минути] - действа като [Винаги], но след избрания период от време преустановява извеждането на сигнал. [Изключено] - аудио извода се привежда в суспендирано суспендирано състояние. БЕЛЕЖКА: при последните два режима е възможно да пропуснете част от възпроизведения материал - докато приемника се приведе в работен режим от суспендирано/изключено състояние!"
+msgstr "...когато не се възпроизвежда звук. [Винаги] - чрез непрекъснато извеждане на сигнал, който не можете да чуете. Приемникът няма да се изключи и остава в готовност да възпроизвежда при необходимост, но може да блокира звука от други приложения. [1-10 минути] - действа като [Винаги], но след избрания период преустановява извеждането на сигнал. [Изключено] - аудио извода се привежда в суспендирано суспендирано състояние. БЕЛЕЖКА: при последните два режима е възможно да пропуснете част от възпроизведения материал - докато приемника се приведе в работен режим от суспендирано/изключено състояние!"
 
 msgctxt "#34120"
 msgid "Play GUI sounds"
@@ -10511,7 +10579,7 @@ msgstr "Събуждане на устройства при деактивира
 
 msgctxt "#36011"
 msgid "Could not detect the CEC com port. Set it up manually."
-msgstr "Не мога да открия  порт CEC. Настройте ръчно."
+msgstr "CEC порта не може да бъде открит. Настройте го ръчно."
 
 msgctxt "#36012"
 msgid "Could not initialise the CEC adaptor. Please check your settings."
@@ -10659,7 +10727,7 @@ msgstr "Преоразмерява графичния интерфейс."
 
 msgctxt "#36109"
 msgid "Select the media window that XBMC displays on startup."
-msgstr "Ð\9fÑ\80и Ñ\81Ñ\82аÑ\80Ñ\82иÑ\80ане Ð½Ð°  XBMC ÐºÐ¾Ñ\8f Ð¾Ñ\82 Ð½Ð°Ñ\87алниÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86и Ð´Ð° Ñ\81е Ð¾Ñ\82воÑ\80и."
+msgstr "Ð\9eпÑ\80еделÑ\8f ÐºÐ¾Ð¹ Ð¿Ñ\80озоÑ\80еÑ\86 Ð´Ð° Ð±Ñ\8aде Ð¾Ñ\82воÑ\80Ñ\8fн Ð°Ð²Ñ\82омаÑ\82иÑ\87но, Ð¿Ñ\80и Ñ\81Ñ\82аÑ\80Ñ\82иÑ\80ане Ð½Ð°  XBMC."
 
 msgctxt "#36110"
 msgid "Select or disable the sound scheme used in the User Interface."
@@ -10667,7 +10735,7 @@ msgstr "Изберете пакет от звуци, който да се пол
 
 msgctxt "#36111"
 msgid "Turn this off to remove the scrolling RSS news ticker."
-msgstr "Ð\98зклÑ\8eÑ\87еÑ\82е Ð¸ Ð»ÐµÐ½Ñ\82аÑ\82а (оÑ\82 Ð´Ñ\8aноÑ\82о Ð½Ð° ÐµÐºÑ\80ана) Ñ\81 Ð½Ð¾Ð²Ð¸Ð½Ð¸ Ð¾Ñ\82 RSS ÐµÐ¼Ð¸Ñ\81ии Ñ\89е Ð¸Ð·Ñ\87езне."
+msgstr "Ð\98зклÑ\8eÑ\87ва Ð¸ Ð¿Ñ\80емаÑ\85ва Ñ\82екÑ\81Ñ\82оваÑ\82а Ð»ÐµÐ½Ñ\82аÑ\82а (оÑ\82 Ð´Ñ\8aноÑ\82о Ð½Ð° ÐµÐºÑ\80ана) Ñ\81 Ð½Ð¾Ð²Ð¸Ð½Ð¸ Ð¾Ñ\82 RSS ÐµÐ¼Ð¸Ñ\81ии."
 
 msgctxt "#36112"
 msgid "Edit the RSS feeds."
@@ -10703,7 +10771,7 @@ msgstr "Изберете стандартен аудио запис, за слу
 
 msgctxt "#36120"
 msgid "Select the default subtitles when different languages are available."
-msgstr "Ð\98збеÑ\80еÑ\82е Ñ\81Ñ\82андаÑ\80Ñ\82ни Ñ\81Ñ\83бÑ\82иÑ\82Ñ\80и, за случаите когато са налични субтитри на различни езици."
+msgstr "Ð\9eпÑ\80еделÑ\8f Ñ\81Ñ\82андаÑ\80Ñ\82ен ÐµÐ·Ð¸Ðº Ð·Ð° Ñ\81Ñ\83бÑ\82иÑ\82Ñ\80иÑ\82е, за случаите когато са налични субтитри на различни езици."
 
 msgctxt "#36121"
 msgid "No info available yet."
@@ -10723,11 +10791,11 @@ msgstr "Разрешава изтриването и преименуванет
 
 msgctxt "#36126"
 msgid "Show the add source button from root sections of the user interface."
-msgstr "Ð\98зобÑ\80азÑ\8fва Ð±Ñ\83Ñ\82он Ð·Ð° Ð´Ð¾Ð±Ð°Ð²Ñ\8fне Ð½Ð° Ð¸Ð·Ñ\82оÑ\87ниÑ\86и (\"Ð\94обави Ñ\81нимки...\", \"Ð\94обави Ð²Ð¸Ð´ÐµÐ¾\" Ð¸ Ð\94обави Ð¼Ñ\83зика...\") Ð² Ñ\81пиÑ\81Ñ\8aÑ\86иÑ\82е Ñ\81 Ñ\84айлове Ð½Ð° Ñ\81Ñ\8aоÑ\82веÑ\82ниÑ\82е Ñ\81екÑ\86ии (Снимки, Видео и Музика)."
+msgstr "Ð\98зобÑ\80азÑ\8fва Ð±Ñ\83Ñ\82он Ð·Ð° Ð´Ð¾Ð±Ð°Ð²Ñ\8fне Ð½Ð° Ð¸Ð·Ñ\82оÑ\87ниÑ\86и (\"Ð\94обави Ñ\81нимки...\", \"Ð\94обави Ð²Ð¸Ð´ÐµÐ¾\" Ð¸ Ð\94обави Ð¼Ñ\83зика...\") Ð² Ñ\81пиÑ\81Ñ\8aÑ\86иÑ\82е Ñ\81 Ñ\84айлове Ð½Ð° Ñ\81Ñ\8aоÑ\82веÑ\82ниÑ\82е Ñ\80аздели (Снимки, Видео и Музика)."
 
 msgctxt "#36127"
 msgid "Show hidden files and directories."
-msgstr "Показва скритите папки и файлове."
+msgstr "Прави видими скритите папки и файлове."
 
 msgctxt "#36128"
 msgid "No info available yet."
@@ -10735,7 +10803,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36129"
 msgid "Set the amount of idle time required before displaying the screensaver."
-msgstr "Ð\97адава ÐºÐ¾Ð»Ð¸Ñ\87еÑ\81Ñ\82воÑ\82о Ð²Ñ\80еме Ð±ÐµÐ·Ð´ÐµÐ¹Ñ\81Ñ\82вие Ñ\81лед ÐºÐ¾ÐµÑ\82о се задейства скрийнсейвъра."
+msgstr "Ð\9eпÑ\80еделÑ\8f Ñ\81лед ÐºÐ¾Ð»ÐºÐ¾ Ð²Ñ\80еме Ð½Ð° Ð±ÐµÐ·Ð´ÐµÐ¹Ñ\81Ñ\82вие Ð´Ð° се задейства скрийнсейвъра."
 
 msgctxt "#36130"
 msgid "Select the screensaver. XBMC will force the 'Dim' screensaver when fullscreen video playback is paused or a dialogue box is active."
@@ -10807,7 +10875,7 @@ msgstr "Проверява за нови медийни файлове при в
 
 msgctxt "#36147"
 msgid "Hide the library scanning progress bar during scans."
-msgstr "Ð\9fÑ\80и Ð°ÐºÑ\82Ñ\83ализиÑ\80ане на библиотеката ще скрива лентата с прогреса на сканирането."
+msgstr "Ð\9fÑ\80и Ð¾Ð±Ð½Ð¾Ð²Ñ\8fване на библиотеката ще скрива лентата с прогреса на сканирането."
 
 msgctxt "#36148"
 msgid "Remove items from your library that can't be found (either renamed, deleted, or on removable storage that is currently unplugged)."
@@ -10899,7 +10967,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36174"
 msgid "Enable Teletext when watching a live TV stream."
-msgstr "Активиране на функцията \"Телетекст\" при гледане на телевизионни потоци (телевизия на живо)."
+msgstr "Активира функцията \"Телетекст\" при гледане на телевизионни потоци (телевизия на живо)."
 
 msgctxt "#36176"
 msgid "No info available yet."
@@ -10927,7 +10995,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36182"
 msgid "Enables direct playback of videos that are in folders, without having to open those folders first, as well as displaying multi-part video files as single items in non-library views."
-msgstr "Позволява директното възпроизвеждане на видео материал, разделен в отделни папки без да се налага да ги отваряте предварително. Също така ще доведе до представянето на видео материалите разделени в няколко файла като един, единствен елемент когато преглеждате файловете (тоест не ползвате Библиотеката)"
+msgstr "Позволява директното възпроизвеждане на видео материал, разделен в отделни папки без да се налага да ги отваряте предварително. Също така ще доведе до представянето на видео материалите разделени в няколко файла като един, единствен елемент когато преглеждате файловете (тоест не ползвате Библиотеката)."
 
 msgctxt "#36183"
 msgid "Removes the title, genre etc nodes from the library view. Selecting a category takes you straight to the title view."
@@ -10967,7 +11035,7 @@ msgstr "Задайте директорията, която да съхраня
 
 msgctxt "#36192"
 msgid "Location of subtitles on the screen."
-msgstr "Позициониране на субтитрите на екрана."
+msgstr "Позиция за субтитрите на екрана."
 
 msgctxt "#36193"
 msgid "No info available yet."
@@ -10975,7 +11043,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36194"
 msgid "Autorun DVD video when inserted in drive."
-msgstr "Ð\90вÑ\82омаÑ\82иÑ\87но Ñ\81Ñ\82аÑ\80Ñ\82иÑ\80а възпроизвеждането при поставяне на DVD диск в оптичното устройство."
+msgstr "СÑ\82аÑ\80Ñ\82иÑ\80а Ð°Ð²Ñ\82омаÑ\82иÑ\87но възпроизвеждането при поставяне на DVD диск в оптичното устройство."
 
 msgctxt "#36195"
 msgid "Force a region for DVD playback."
@@ -11203,7 +11271,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36283"
 msgid "Autorun CDs when inserted in drive."
-msgstr "Ð\92Ñ\8aзпÑ\80оизвежда Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð´Ð¸Ñ\81ковеÑ\82е при поставянето им в дисковото устройство."
+msgstr "Ð\97апоÑ\87ва Ð´Ð° Ð²Ñ\8aзпÑ\80оизвежда Ð´Ð¸Ñ\81ковеÑ\82е Ð°Ð²Ñ\82омаÑ\82иÑ\87но, при поставянето им в дисковото устройство."
 
 msgctxt "#36284"
 msgid "Read the information belonging to an audio CD from an internet database."
@@ -11355,7 +11423,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36323"
 msgid "Enable the UPnP server. This will allow you to stream media to any UPnP client."
-msgstr "Ð\92клÑ\8eÑ\87ва UPnP Ñ\81Ñ\8aÑ\80вÑ\8aÑ\80а Ð½Ð° XBMC. Ð¢Ð¾Ð²Ð° Ñ\89е Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð¿Ð¾Ñ\82оÑ\87ноÑ\82о Ð¿Ñ\80едаване Ð½Ð° Ð¼ÐµÐ´Ð¸Ð¹Ð½Ð¸ Ñ\84айлове (Ñ\81 Ñ\86ел Ð²Ñ\8aзпÑ\80оизвеждане Ð½Ð° Ð¾Ñ\82далеÑ\87ени Ñ\83Ñ\81Ñ\82Ñ\80ойÑ\81Ñ\82ва) ÐºÑ\8aм UPnP ÐºÐ»Ð¸ÐµÐ½Ñ\82и."
+msgstr "Ð\92клÑ\8eÑ\87ва UPnP Ñ\81Ñ\8aÑ\80вÑ\8aÑ\80а Ð½Ð° XBMC. Ð¢Ð¾Ð²Ð° Ñ\89е Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð²Ñ\8aзпÑ\80оизвеждане Ð½Ð° Ð¾Ñ\82далеÑ\87ени Ñ\83Ñ\81Ñ\82Ñ\80ойÑ\81Ñ\82ва (вÑ\81еки Ð½Ð°Ð»Ð¸Ñ\87ен UPnP ÐºÐ»Ð¸ÐµÐ½Ñ\82)."
 
 msgctxt "#36324"
 msgid "When a manual or automatical library update occurs, notify UPnP clients."
@@ -11367,7 +11435,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36326"
 msgid "Enable the UPnP client. This will allow you to stream media from any UPnP server with a control point and control playback from that server."
-msgstr "Ð\92клÑ\8eÑ\87ва UPnP ÐºÐ»Ð¸ÐµÐ½Ñ\82а Ð½Ð° XBMC. Ð¢Ð¾Ð²Ð° Ñ\89е Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð¿Ð¾Ñ\82оÑ\87ноÑ\82о Ð¿Ñ\80иемане Ð½Ð° Ð¼ÐµÐ´Ð¸Ð¹Ð½Ð¸ Ñ\84айлове, Ñ\81 Ñ\86ел Ð»Ð¾ÐºÐ°Ð»Ð½Ð¾ Ð²Ñ\8aзпÑ\80оизвеждане, Ð¾Ñ\82 UPnP сървър (посредством UPnP контролна точка)."
+msgstr "Ð\92клÑ\8eÑ\87ва UPnP ÐºÐ»Ð¸ÐµÐ½Ñ\82а Ð½Ð° XBMC. Ð¢Ð¾Ð²Ð° Ñ\89е Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð»Ð¾ÐºÐ°Ð»Ð½Ð¾ Ð²Ñ\8aзпÑ\80оизвеждане Ð½Ð° Ñ\84айлове Ð¾Ñ\82 Ð²Ñ\81еки Ð½Ð°Ð»Ð¸Ñ\87ен UPnP сървър (посредством UPnP контролна точка)."
 
 msgctxt "#36327"
 msgid "No info available yet."
@@ -11397,6 +11465,10 @@ msgctxt "#36333"
 msgid "No info available yet."
 msgstr "Все още не е налична информация."
 
+msgctxt "#36334"
+msgid "Allow programs on this computer to control XBMC via the Web Interface or the JSON-RPC interface protocol."
+msgstr "Разрешава на програми от компютъра да контролират XBMC (посредством уеб интерфейс или протокола JSON-RPC)."
+
 msgctxt "#36335"
 msgid "No info available yet."
 msgstr "Все още не е налична информация."
@@ -11459,7 +11531,7 @@ msgstr "Все още не е налична информация."
 
 msgctxt "#36350"
 msgid "Automatically send 'Wake-On-Lan' to server(s) right before trying to access shared files or services."
-msgstr "Преди изискването на споделени файлове/услуги изпраща команда за събуждане по LAN (Wake-on-LAN или просто \"Отдалечено събуждане\") до сървърите, които ги споделят ."
+msgstr "Преди изискването на споделени файлове/услуги изпраща команда за събуждане по LAN (Wake-on-LAN или просто \"Отдалечено събуждане\") до сървърите, които ги споделят."
 
 msgctxt "#36351"
 msgid "No info available yet."
@@ -11493,6 +11565,10 @@ msgctxt "#36360"
 msgid "No info available yet."
 msgstr "Все още не е налична информация."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Посочете колко канала поддържа аудио връзката или броя на озвучителните тела, ако ползвате аналогова връзка. Настройката се пренебрегва се ползва режим с директно предаване на звука. Бележка: SPDIF поддържа 2,0 канала, но въпреки това може да предава многоканален аудио сигнал чрез формат който може да бъде предаван директно."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Увеличава AC3 потоците които са смесени до 2 канала (крайният резултат обикновено са 2 тихи канала, които се нуждаят от усилване)"
@@ -11507,7 +11583,7 @@ msgstr "Изберете опцията ако приемникът Ви мож
 
 msgctxt "#36367"
 msgid "Select the maximum number of audio channels/speakers available for audio decoded. If optical/coax digital outputs are used this must be set to 2.0"
-msgstr "Ð\97адайÑ\82е Ð¼Ð°ÐºÑ\81ималниÑ\8f Ð±Ñ\80ой Ð½Ð°Ð»Ð¸Ñ\87ни Ð°Ñ\83дио ÐºÐ°Ð½Ð°Ð»Ð¸/виÑ\81окоговоÑ\80иÑ\82ели Ð·Ð° Ð²Ñ\8aзпÑ\80оизвеждане Ð½Ð° Ð°Ñ\83дио Ñ\81игнала. Ако извеждате сигнала посредством оптичен или коаксиален изход е необходимо да зададете стойност 2.0"
+msgstr "Ð\97адайÑ\82е Ð¼Ð°ÐºÑ\81ималниÑ\8f Ð±Ñ\80ой Ð½Ð°Ð»Ð¸Ñ\87ни Ð°Ñ\83дио ÐºÐ°Ð½Ð°Ð»Ð¸/виÑ\81окоговоÑ\80иÑ\82ели Ð·Ð° Ð²Ñ\8aзпÑ\80оизвеждане Ð½Ð° Ð´ÐµÐºÐ¾Ð´Ð¸Ñ\80аниÑ\8f Ð°Ñ\83дио Ñ\81игнал. Ако извеждате сигнала посредством оптичен или коаксиален изход е необходимо да зададете стойност 2.0"
 
 msgctxt "#36368"
 msgid "Select to enable the passthrough audio options for playback of encoded audio such as Dolby Digital."
@@ -11745,18 +11821,42 @@ msgctxt "#36504"
 msgid "Side by side"
 msgstr "Отляво/Отдясно"
 
+msgctxt "#36505"
+msgid "Anaglyph Red/Cyan"
+msgstr "Anaglyph червено/синьо-зелено"
+
+msgctxt "#36506"
+msgid "Anaglyph Green/Magenta"
+msgstr "Anaglyph зелено/пурпур (маджента)"
+
 msgctxt "#36507"
 msgid "Interlaced"
 msgstr "Презредово"
 
+msgctxt "#36509"
+msgid "Monoscopic - 2D"
+msgstr "Моноскопичен - 2D"
+
+msgctxt "#36520"
+msgid "Playback mode of stereoscopic videos"
+msgstr "Режим за стереоскопичните видеа"
+
 msgctxt "#36521"
 msgid "Ask me"
 msgstr "Запитване"
 
+msgctxt "#36522"
+msgid "Use preferred mode"
+msgstr "Предпочитания режим"
+
 msgctxt "#36524"
 msgid "Preferred mode"
 msgstr "Предпочитан режим"
 
+msgctxt "#36525"
+msgid "Same as movie (autodetect)"
+msgstr "Според филма (автоматично откриване)"
+
 msgctxt "#36526"
 msgid "Disable stereoscopic mode when playback is stopped"
 msgstr "Изключи стереоскопичния режим при спиране на възпроизвеждането"
@@ -11813,9 +11913,13 @@ msgctxt "#36544"
 msgid "Enable hardware decoding of video files."
 msgstr "Включва хардуерното декодиране на видео файлове."
 
+msgctxt "#36545"
+msgid "Subtitle stereoscopic depth"
+msgstr "Стереоскопична дълбочина на субтитрите"
+
 msgctxt "#37000"
 msgid "(Visually Impaired)"
-msgstr "(Ð\97а Ð³Ð»Ñ\83Ñ\85и)"
+msgstr "(УвÑ\80едено Ð·Ñ\80ение)"
 
 msgctxt "#37001"
 msgid "(Directors Comments)"
@@ -11831,7 +11935,7 @@ msgstr "(CC)"
 
 msgctxt "#37012"
 msgid "(Forced)"
-msgstr "(Ð\97адÑ\8aлжиÑ\82елно)"
+msgstr "(Ð\9dалагане)"
 
 msgctxt "#37013"
 msgid "(Directors Comments)"
@@ -11860,3 +11964,11 @@ msgstr "Усилвай централния канал при смесване 
 msgctxt "#37019"
 msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
 msgstr "Системните клавиши като PrintScreen (PrtScr), Alt-Tab и клавишите за контрол на звука ще бъда активни и по време на режим \"На цял екран\"."
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP плеър"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Да бъде ли спряно възпроизвеждането на отдалеченото устройство?"
index 80d15a7..6502605 100644 (file)
@@ -4057,10 +4057,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "မူလဘာသာစကား"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Black &amp; White"
-
 msgctxt "#19680"
 msgid "Comedy"
 msgstr "ဟာ"
@@ -5545,6 +5541,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "ချယ်နယ်များအရေအတွက်"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "၂.၀"
index bf07c22..32df707 100644 (file)
@@ -7249,10 +7249,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobilisme"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Salut"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cuina"
@@ -7273,10 +7269,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Idioma original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Blanc i negre"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "No publicat"
@@ -10517,6 +10509,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canals"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 2fa3414..21feb93 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "选择目标目录"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "立体声上混"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "声道数"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "详细日志..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "启用杜比数字编码转换"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "清理资料库"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "允许硬件加速(MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "允许框架多线程解码"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "影音同步方式"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "电视录像"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "有频道图标的文件夹"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "频道"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "默认电子节目单窗口"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "频道图标"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "此事件已录制。"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "按确定确认频道切换"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "当前图标"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "无图标"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "选择图标"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "浏览图标"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "其他/未知"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "驾驶"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "健身与健康"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "烹饪"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "原始语言"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "黑白"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "未发行"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "以%s扫描专辑"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "电影剧情"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "分段播放..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "移除媒体共享"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "自定义字幕目录"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "电影和备选字幕目录"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "混合"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "字幕在屏幕上的位置"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "固定"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "选择播放项目"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "章节:%u - 时长:%s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "蓝光碟播放失败"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "不支持此光盘的蓝光菜单"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "资料库模式"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2(FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "声道数"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "选择音频输出特性设置:[固定] - 输出特性总是为指定采样率和扬声器配置;[最佳匹配] - 输出特性总是尽可能匹配音源特性;[优化] - 输出特性在播放开始时设定而忽略之后音源特性的变化。"
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "选择连接的音频设备支持的声道数,或连接的模拟接口的扬声器数。本设置不针对直通音频。注意 - SPDIF 仅支持2.0声道但仍然能通过直通输出支持的格式输出多声道音频。"
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "增大混缩为2声道的 AC3 音频流音量。"
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "选择以启用将双声道立体声上混为多声道以匹配扬声器数量。"
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "当你的功放能解码 AC3 音频流时选择此项。"
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "启用 AMLogic 解码器的视频硬解码"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "使用框架多线程解码而非硬件加速解码(没有默认的单线程模式可靠)。"
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "设置当一个电子节目单项被选中时的动作:[显示上下文菜单] 将触发上下文菜单让你选择更多动作;[切换到频道] 将立即转到相应频道;[显示信息] 将显示剧情介绍等详细信息;[录像] 将创建一个所选项目的录像定时器。"
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "录像"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "当音频输出设备仅支持杜比数字5.1多声道音频时选择此项,这将允许 AAC5.1 或 FLAC5.1 等多声道音频以5.1环绕声播放。注意 - 编码转换可能导致声音质量降低"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "立体模式(当前)"
@@ -12484,3 +12556,11 @@ msgstr "启用高色深艺术图片"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "设置用户界面分辨率限制"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP 播放器"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "要停止远程设备上的播放吗?"
index 640e432..60e2b53 100644 (file)
@@ -2389,6 +2389,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "詳細記錄..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "啟用杜比數位轉碼"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "清除音樂資料庫"
@@ -3713,6 +3717,10 @@ msgctxt "#12006"
 msgid "Audio visualisation"
 msgstr "音效視覺效果"
 
+msgctxt "#12008"
+msgid "File stacking dialogue"
+msgstr "檔案堆疊對話框"
+
 msgctxt "#12009"
 msgid "Rebuild index..."
 msgstr "重建目錄索引…"
@@ -3869,6 +3877,10 @@ msgctxt "#12346"
 msgid "Password retry limit exceeded."
 msgstr "已達密碼重試次數限制。"
 
+msgctxt "#12347"
+msgid "The system will now power down."
+msgstr "系統將要立刻關閉電源。"
+
 msgctxt "#12348"
 msgid "Item locked"
 msgstr "項目被鎖定"
@@ -4213,6 +4225,10 @@ msgctxt "#13121"
 msgid "VDPAU HQ Upscaling level"
 msgstr "VDPAU 高品質倍線等級"
 
+msgctxt "#13122"
+msgid "VDPAU Studio level colour conversion"
+msgstr "VDPAU 視聽室等級色彩轉換"
+
 msgctxt "#13130"
 msgid "Blank other displays"
 msgstr "顯示空白"
@@ -4925,6 +4941,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "允許硬體加速 (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "允許多執行緒解碼"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "影音同步方式"
@@ -5933,6 +5953,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "電視錄影"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "頻道圖示的資料夾"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "頻道"
@@ -6121,6 +6145,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "預設的電子節目表視窗"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "頻道圖示"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "這個事件已經錄製"
@@ -6697,6 +6725,10 @@ msgctxt "#19222"
 msgid "EPG"
 msgstr "電子節目表"
 
+msgctxt "#19223"
+msgid "No PVR Add-on could be enabled. Check your settings or the log for more info."
+msgstr "沒有 PVR 附加元件可以被啟用。請檢查你的設定或者查閱日誌以取得更多資訊。"
+
 msgctxt "#19224"
 msgid "Recording aborted"
 msgstr "錄影已放棄"
@@ -6737,6 +6769,10 @@ msgctxt "#19233"
 msgid "Display a notification on timer updates"
 msgstr "定時器更新時顯示通知"
 
+msgctxt "#19234"
+msgid "Use backend channels numbers (only works with 1 enabled PVR Add-on)"
+msgstr "使用後端頻道號碼(只適用於1個已啟用的 PVR 附加元件)"
+
 msgctxt "#19235"
 msgid "PVR manager is starting up"
 msgstr "PVR 管理員啟動中"
@@ -6757,10 +6793,18 @@ msgctxt "#19239"
 msgid "Starting background threads"
 msgstr "開始背景執行緒"
 
+msgctxt "#19240"
+msgid "No PVR Add-on enabled"
+msgstr "沒有啟用任何 PVR 附加元件"
+
 msgctxt "#19241"
 msgid "The PVR manager has been enabled without any"
 msgstr "PVR 管理員已啟用,但沒有啟用任何"
 
+msgctxt "#19242"
+msgid "enabled PVR Add-on. Enable at least one Add-on"
+msgstr "啟用的 PVR 附加元件。請至少啟用一個附加元件。"
+
 msgctxt "#19243"
 msgid "in order to use the PVR functionality."
 msgstr "請至少啟用一個附加元件。"
@@ -6917,6 +6961,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "轉台時需要按「確定」確認"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "目前的圖示"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "無圖示"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "選擇圖示"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "瀏覽圖示"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "其他/未知"
@@ -7201,10 +7261,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "駕駛"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "健身與健康"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "烹飪"
@@ -7225,10 +7281,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "其他語言"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "黑白"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "未發行的"
@@ -8785,6 +8837,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "移除媒體共享"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "自訂字幕資料夾"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "電影和替代字幕資料夾"
@@ -9153,6 +9209,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "混合"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "字幕在螢幕中的位置"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "固定"
@@ -10149,6 +10209,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "選擇播放項目"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "章節:%u - 長度:%s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "播放藍光光碟失敗"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "不支援這片藍光光碟的選單"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "資料庫模式"
@@ -10505,6 +10577,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows 媒體音效 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "通道數"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11677,10 +11753,18 @@ msgctxt "#36331"
 msgid "Define webserver password."
 msgstr "設定網頁伺服器的密碼。"
 
+msgctxt "#36332"
+msgid "Select between web interfaces installed via the Add-on Manager."
+msgstr "從附加元件管理員選擇一個已安裝的網頁介面。"
+
 msgctxt "#36333"
 msgid "No info available yet."
 msgstr "無可用資訊。"
 
+msgctxt "#36334"
+msgid "Allow programs on this computer to control XBMC via the Web Interface or the JSON-RPC interface protocol."
+msgstr "允許這個電腦上的程式透過網路介面或者 JSON-RPC 介面協定控制 XBMC。"
+
 msgctxt "#36335"
 msgid "No info available yet."
 msgstr "無可用資訊。"
@@ -11753,6 +11837,14 @@ msgctxt "#36353"
 msgid "No info available yet."
 msgstr "無可用資訊。"
 
+msgctxt "#36354"
+msgid "The main benefit is for multi-screen configurations, so XBMC can be used without automatically minimising other applications. Uses a bit more resources and playback may be slightly less smooth."
+msgstr "主要好處是在有多螢幕的情況下,不用將其他應用程式最小化就可以使用 XBMC。這會使用稍微多一點資源,且播放時可能會稍微不那麼流暢。"
+
+msgctxt "#36355"
+msgid "In a multi-screen configuration, the screens where XBMC is not displayed are blacked out."
+msgstr "在多螢幕設置中,用來顯示 XBMC 以外的螢幕會變全黑。"
+
 msgctxt "#36359"
 msgid "No info available yet."
 msgstr "無可用資訊。"
@@ -11957,6 +12049,10 @@ msgctxt "#36420"
 msgid "No info available yet."
 msgstr "無可用資訊。"
 
+msgctxt "#36421"
+msgid "Bypassing VDPAU mixer saves resources on low power systems but slightly reduces picture quality"
+msgstr "略過 VDPAU 混合器可在較低端的系統上節省資源但會稍微降低圖像的品質"
+
 msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "啟用 AMLogic 硬體解碼。"
@@ -11997,6 +12093,14 @@ msgctxt "#36507"
 msgid "Interlaced"
 msgstr "交錯掃描"
 
+msgctxt "#36508"
+msgid "Hardware Based"
+msgstr "基於硬體"
+
+msgctxt "#36509"
+msgid "Monoscopic - 2D"
+msgstr "2D"
+
 msgctxt "#36520"
 msgid "Playback mode of stereoscopic videos"
 msgstr "3D 立體影片的播放模式"
@@ -12005,6 +12109,10 @@ msgctxt "#36521"
 msgid "Ask me"
 msgstr "問我"
 
+msgctxt "#36522"
+msgid "Use preferred mode"
+msgstr "使用偏好的模式"
+
 msgctxt "#36524"
 msgid "Preferred mode"
 msgstr "偏好的模式"
@@ -12025,6 +12133,10 @@ msgctxt "#36528"
 msgid "Select stereoscopic mode"
 msgstr "選擇 3D 立體模式"
 
+msgctxt "#36529"
+msgid "Mono (2D)"
+msgstr "2D"
+
 msgctxt "#36530"
 msgid "Preferred mode"
 msgstr "偏好的模式"
@@ -12041,6 +12153,10 @@ msgctxt "#36535"
 msgid "Stereoscopic mode of video"
 msgstr "影片的 3D 立體模式"
 
+msgctxt "#36536"
+msgid "Stereoscopic mode inverted"
+msgstr "相反的 3D 立體模式"
+
 msgctxt "#36537"
 msgid "No info available yet."
 msgstr "無可用資訊。"
@@ -12124,3 +12240,11 @@ msgstr "在全螢幕時啟用如 printscreen、alt-tab 和音量控制等系統
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "設定使用者介面的解析度限制"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP 播放器"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "你想要停止遠端裝置上的播放嗎?"
index 70ea894..f512d51 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Odaberi odredišni direktorij"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo razdvajanje"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Broj kanala"
@@ -1191,7 +1195,7 @@ msgstr "Izlazno podešavanje"
 
 msgctxt "#338"
 msgid "Fixed"
-msgstr "Fiksni"
+msgstr "Fiksno"
 
 msgctxt "#339"
 msgid "Optimized"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Verbalno zapisivanje..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Omogući Dolby Digital transkôdiranje"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Čišćenje popisa izvođenja"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Dopusti hardversko ubrzanje (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Omogući više-nizno dekôdiranje"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Način usklađivanja Zvuka/Slike"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV snimanje"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Mapa s ikonama programa"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Programi"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Zadani EPG prozor"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Ikone programa"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Ovaj događaj se već snima."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Potvrdi prebacivanje programa pritiskom na 'U redu'"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Trenutna ikona"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Nema ikone"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Odaberi ikonu"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Potraži ikonu"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Ostalo/Nepoznato"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobili"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness i zdravlje"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Kuhanje"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Izvorni jezik"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Crno i bijelo"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Neobjavljeno"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Pretraživanje albuma pomoću %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Kratak sadržaj filma"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Reproduciraj dio..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Odstrani dijeljenje medija"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Prilagođena mapa podnaslova"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Film i alternativni direktorij podnaslova"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "izmješano"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Položaj podnaslova na zaslonu"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fiksni"
@@ -10211,7 +10251,7 @@ msgstr "Odaberite uslugu koja će se koristiti kao zadana za podnaslove filmova"
 
 msgctxt "#24120"
 msgid "Manual search string"
-msgstr "Upiši string za pretraživanje"
+msgstr "Prilagođeni zahtjev za pretraživanje"
 
 msgctxt "#24121"
 msgid "Enter search string"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Odaberi stavku reprodukcije"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Poglavlja: %u - trajanje: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Neuspjela reprodukcija Blu-ray diska"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Izbornik ovog Blu-ray diska nije podržan"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Način zbirke"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Broj programa"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Odaberite kako su svojstva zvučnog izlaza postavljena: [Nepromjenjivo] - izlazna svojstva su postavljena na određeno uzrokovanje i podešavanja zvučnika svo vrijeme; [Najbolje odgovarajuće] - izlazna svojstva su postavljena da se uvijek što bliže podudraju svojstivima izvora koliko je to moguće; [Optimizirano] - izlazna svojstva su postavljena na početku reprodukcije i neće se promijeniti ako se svojstva izvora promijene."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Odaberite broj kanala podržan zvučnim povezivanjem ili brojem zvučnika ako je spojeno analognim povezivanjem. Ove postavke ne obuhvaćaju izlaz zvuka. Napomena - SPDIF podržava samo 2.0 kanale ali još uvijek može slati višekanalni zvuk koristeći format podržan na izlazu."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Pojačaj AC3 streamove koji su pretvoreni u 2 kanala."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Odaberite za omogućavanje razdvajanja 2-kanalnog zvuka na broj zvučnih kanala određenih postavkama zvučnika."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Odaberite ovu mogućnost ako je vaš prijemnik sposoban dekôdirati AC3 zvučne zapise."
@@ -12257,6 +12321,18 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Omogući hardversko dekôdiranje video datoteka koristeći AMLogic dekôder."
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Koristi dekôdiranje sličica-više-nizno umjesto dekôdiranja hardverskim ubrzanjem (manje pouzdano od jedno-niznog načina)."
+
+msgctxt "#36424"
+msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
+msgstr "Odaberite što će se dogoditi kada je EPG stavka odabrana: [Prikaži kontekstualni izbornik] će uključiti kontekstualni izbornik iz kojega možete odabrati dodatne radnje; [Prebaci na program] odmah će prebaciti na pripadajući program; [Prikaži informacije] će pokazati opširne informacije sa sadržajem emisija i dodatnim mogućnostima; [Snimaj] će zakazati snimanje za odabranu stavku."
+
+msgctxt "#36425"
+msgid "Show context menu"
+msgstr "Prikaži kontekstualni izbornik"
+
 msgctxt "#36426"
 msgid "Switch to channel"
 msgstr "Prebaci na program"
@@ -12269,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Snimaj"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Odaberite ovo ako izlazno zvučno povezivanje samo podržava višekanalni zvuk poput Dolby Digitala 5.1, ovo omogućuje slušanje višekanalnog zvuka poput AAC5.1 ili FLAC5.1 na 5.1 surround zvuku. Napomena - transkôdiranje može prouzročiti slabiju kvalitetu zvuka"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Stereoskopski način (trenutno)"
@@ -12413,6 +12493,14 @@ msgctxt "#36546"
 msgid "Sets the visual depth of subtitles for stereoscopic videos. The higher the value, the closer the subtitles will appear to the viewer."
 msgstr "Postavite vizualnu dubinu podnaslova za stereoskopske video snimke. Ako je veća vrijednost, podnaslovi će biti bliži gledatelju."
 
+msgctxt "#36547"
+msgid "Use higher quality textures for covers and fanart (uses more memory)"
+msgstr "Koristi višu kvalitetu tekstura za slike omota (koristi više memorije)"
+
+msgctxt "#36548"
+msgid "Limits resolution of GUI to save memory. Does not affect video playback. Use 1080 for unlimited. Requires restart."
+msgstr "Ograničava razlučivost GUI sučelja u svrhu štednje memorije. Ne utječe na video reprodukciju. Koristi 1080 za neograničeno. Potrebno je ponovno pokretanje."
+
 msgctxt "#37000"
 msgid "(Visually Impaired)"
 msgstr "(slabovidno)"
@@ -12460,3 +12548,19 @@ msgstr "Pojačaj središnji kanal pri spajanju kanala zvuka"
 msgctxt "#37019"
 msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
 msgstr "Omogućava tipke sustava poput 'Print Screen', 'Alt-Tab' i tipke glasnoće zvuka u cjelozaslonskom prikazu"
+
+msgctxt "#37020"
+msgid "Enable higher colour depth artwork"
+msgstr "Omogući višu dubinu boja slika omota"
+
+msgctxt "#37021"
+msgid "Set GUI resolution limit"
+msgstr "Postavi ograničenje razlučivosti GUI sučelja"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP reproduktor"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Želite li zaustaviti reprodukciju na udaljenom uređaju?"
index c827f66..4a3a64b 100644 (file)
@@ -6925,10 +6925,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motorismus"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness a zdraví"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Vaření"
@@ -6949,10 +6945,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Původní jazyk"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Černobílý"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Nepublikovaný"
@@ -10029,6 +10021,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Počet kanálů"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index efad187..41a7e06 100644 (file)
@@ -6989,10 +6989,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motor"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Sundhed"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Madlavning"
@@ -7013,10 +7009,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Oprindeligt sprog"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Sort &amp; Hvid"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Ikke udgivet"
@@ -10145,6 +10137,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Antal lydkanaler"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11225,6 +11221,10 @@ msgctxt "#36307"
 msgid "Automatically generate picture thumbnails when entering picture folder."
 msgstr "Automatisk genererer miniature billeder, når en mappe med billeder åbnes."
 
+msgctxt "#36308"
+msgid "Pictures will automatically rotate according to information in the EXIF tag, if found."
+msgstr "Billeder roteres automatisk i forhold til tilgængelig EXIF information hvis fundet."
+
 msgctxt "#36310"
 msgid "No info available yet."
 msgstr "Ingen information tilgængelig endnu."
index d35d7b4..fce7644 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Selecteer doelmap"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Aantal kanalen"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Uitgebreide logging..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Activeer Dolby Digitaal Transcodering"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Bibliotheek opschonen"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Hardwareversnelling toestaan (mediacodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Sta Frame-multi-threaded decodering toe"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "A/V-synchronisatiemethode"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV opnames"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Folder met kanaal iconen"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanalen"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Standaard TV gids"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanaal iconen"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Dit programma wordt al opgenomen"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Bevestig kanaalwisselingen met de OK-toets"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Huidig icoon"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Geen icoon"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Kies icoon"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Zoek naar icoon"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Anders/Onbekend"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Autorijden"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Gezondheid"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Koken"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Oude talen"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Zwart/Wit"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Niet gepubliceerd"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Scannen van albums met %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Film plot"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Afspelen deel..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Gedeelde media verwijderen"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Aangepaste ondertitel map"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Video - alternatieve ondertitelmap"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "gemixed"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Ondertitel locatie op scherm"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Vast"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Selecteer afspeel item"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Hoofdstukken: %u - duur: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Blu-ray disc afspelen mislukt"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Het menu van deze Blu-ray disc wordt niet ondersteund"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Bibliotheekmodus"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Aantal kanalen"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Selecteer hoe de eigenschappen van de geluidsuitvoer zijn ingesteld: [Vast] - uitvoer eigenschappen zijn ingesteld naar de gespecificeerde sampling rate & speaker configuratie ten alle tijde; [Beste overeenkomst] - uitvoereigenschappen zijn zo ingesteld dat ze altijd zo dicht mogelijk overeenkomen met de broneigenschappen als mogelijk; [Geoptimaliseerd] - uitvoereigenschappen zijn ingesteld bij het begin van afspelen en zullen niet veranderen als de eigenschappen van de bron veranderen."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Selecteer het aantal kanalen dat wordt ondersteunt door de audio-aansluiting, of het aantal luidsprekers, indien aangesloten op analoge aansluitingen. Deze instelling is niet van toepassing op audio passthrough. PS - SPDIF ondersteunt alleen 2.0 kanalen, maar kan nog steeds meerkanaals audio doorsturen via een formaat dat ondersteunt wordt door passthrough."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Versterk AC3 geluid dat gedownmixt werd naar 2 kanalen."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Selecteer om upmixing te activeren van 2-kanaals stereobronnen naar het aantal geluidskanalen gespecificeerd door de speaker configuratie."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Kies deze optie als uw ontvanger Dolby Digital / AC3 digitaal geluid kan decoderen."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Schakel Hardware video decodering in met gebruik van AMLogic decoder"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Gebruik frame-multi-threaded decodering wanneer hardware versnelde decodering niet werkt of is gedeactiveerd. (Minder betrouwbaar dan de standaard single thread modus)"
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Selecteer wat er moet gebeuren wanneer een EPG item is geselecteerd: [Toon context menu] zal het contextuele menu activeren van waaruit je vervolgacties kan kiezen; [Verander naar kanaal] Zal gelijk afstemmen naar het gerealteerde kanaal; [Toon informatie] zal een gedetailleerd informatiescherm tonen met plot en vervolgopties; [Opnemen] Zal een opname timer creëren voor het geselecteerde item."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Opnemen"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Selecteer deze optie als de audio-out  alleen multikanaals audio ondersteunt zoals Dolby Digitaal 5.1, dit staat multikanaals audio toe zoals AAC5.1 of FLAC5.1 om te beluisteren in 5.1 surround sound. PS - transcoderen kan leiden tot een vermindering van de geluidskwaliteit"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Stereoscopische modus (huidig)"
@@ -12484,3 +12556,11 @@ msgstr "Activeer een hogere kleurdiepte voor artwork"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Stel GUI resolutielimiet in"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP speler"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Wilt u afspelen stoppen op het externe apparaat?"
diff --git a/language/English (Australia)/langinfo.xml b/language/English (Australia)/langinfo.xml
new file mode 100644 (file)
index 0000000..b4ccaba
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!-- Possible values for <charsets>                     -->
+<!-- ==============================                     -->
+<!--                                                    -->
+<!-- ISO-Charsets:                                      -->
+<!-- ISO-8859-1 - Western Europe (ISO)                  -->
+<!-- ISO-8859-2 - Central Europe (ISO)                  -->
+<!-- ISO-8859-3 - South Europe (ISO)                    -->
+<!-- ISO-8859-4 - Baltic (ISO)                          -->
+<!-- ISO-8859-5 - Cyrillic (ISO)                        -->
+<!-- ISO-8859-6 - Arabic (ISO)                          -->
+<!-- ISO-8859-7 - Greek (ISO)                           -->
+<!-- ISO-8859-8 - Hebrew (ISO)                          -->
+<!-- ISO-8859-9 - Turkish (ISO)                         -->
+<!--                                                    -->
+<!-- Windows Charsets:                                  -->
+<!-- CP1250 - Central Europe (Windows)                  -->
+<!-- CP1251 - Cyrillic (Windows)                        -->
+<!-- CP1252 - Western Europe (Windows)                  -->
+<!-- CP1253 - Greek (Windows)                           -->
+<!-- CP1254 - Turkish (Windows)                         -->
+<!-- CP1255 - Hebrew (Windows)                          -->
+<!-- CP1256 - Arabic (Windows)                          -->
+<!-- CP1257 - Baltic (Windows)                          -->
+<!-- CP1258 - Vietnamesse (Windows)                     -->
+<!-- CP874  - Thai (Windows)                            -->
+<!-- CP949  - Korean                                    -->
+<!--                                                    -->
+<!-- Others:                                            -->
+<!-- GBK        - Chinese Simplified (GBK)              -->
+<!-- BIG5       - Chinese Traditional (Big5)            -->
+<!-- BIG5-HKSCS - Hong Kong (Big5-HKSCS)                -->
+<!-- SHIFT_JIS  - Japanese (Shift-JIS)                  -->
+<!--                                                    -->
+<!-- Link: (Country-Codepage comparison)                -->
+<!-- http://www.science.co.il/Language/Locale-Codes.asp -->
+<!--                                                    -->
+<!-- Possible values for <dvd>                          -->
+<!-- =========================                          -->
+<!-- Language codes expected are two character          -->
+<!-- codes as defined in ISO639.                        -->
+<!--                                                    -->
+<!-- Link:                                              -->
+<!-- http://etext.virginia.edu/tei/iso639.html          -->
+
+
+
+<language locale="en">
+  <charsets>
+    <gui>CP1252</gui>
+    <subtitle>CP1252</subtitle>
+  </charsets>
+
+  <dvd>
+    <menu>en</menu>
+    <audio>en</audio>
+    <subtitle>en</subtitle>
+  </dvd>
+
+  <regions>
+    <region name="Australia (12h)" locale="AU">
+      <dateshort>DD/MM/YYYY</dateshort>
+      <datelong>DDDD, D MMMM YYYY</datelong>
+      <time symbolAM="AM" symbolPM="PM">h:mm:ss xx</time>
+      <tempunit>C</tempunit>
+      <speedunit>kmh</speedunit>
+      <timezone>GMT</timezone>
+    </region>
+    <region name="Australia (24h)" locale="AU">
+      <dateshort>DD/MM/YYYY</dateshort>
+      <datelong>DDDD, D MMMM YYYY</datelong>
+      <time symbolAM="AM" symbolPM="PM">H:mm:ss</time>
+      <tempunit>C</tempunit>
+      <speedunit>kmh</speedunit>
+      <timezone>GMT</timezone>
+    </region>
+  </regions>
+
+  <sorttokens>
+    <token>The</token>
+  </sorttokens>
+</language>
index 21dc66c..25f2a5a 100644 (file)
@@ -7249,10 +7249,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motoring"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Health"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cooking"
@@ -7273,10 +7269,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Original Language"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Black &amp; White"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Unpublished"
@@ -10517,6 +10509,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Number of channels"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 4df7d2e..e443e7b 100755 (executable)
@@ -5646,7 +5646,7 @@ msgid "Scan for new content"
 msgstr ""
 
 msgctxt "#13350"
-msgid "Now playing..."
+msgid "Current playlist"
 msgstr ""
 
 msgctxt "#13351"
@@ -6000,7 +6000,79 @@ msgctxt "#13440"
 msgid "Allow frame-multi-threaded decoding"
 msgstr ""
 
-#empty strings from id 13441 to 13499
+#. Description of Mpeg-2 Codec for VDPAU
+#: system/settings/settings.xml
+msgctxt "#13441"
+msgid "Use Mpeg-2 VDPAU"
+msgstr ""
+
+#. Description of setting #13441 'Use Mpeg-2 VDPAU'
+#: system/settings/settings.xml
+msgctxt "#13442"
+msgid "Enable this option to use hardware acceleration for Mpeg-(1/2) codecs. If disabled the CPU will be used instead. Older Radeon Cards tend to segfault with this enabled."
+msgstr ""
+
+#. Description of Mpeg-4 Codec for VDPAU
+#: system/settings/settings.xml
+msgctxt "#13443"
+msgid "Use Mpeg-4 VDPAU"
+msgstr ""
+
+#. Description of setting #13443 'Use Mpeg-4 VDPAU'
+#: system/settings/settings.xml
+msgctxt "#13444"
+msgid "Enable this option to use hardware acceleration for the Mpeg-4 codec. If disabled the CPU will be used instead. Some ION Hardware has problems with this being enabled by default."
+msgstr ""
+
+#. Description of VC-1 Codec for VDPAU
+#: system/settings/settings.xml
+msgctxt "#13445"
+msgid "Use VC-1 VDPAU"
+msgstr ""
+
+#. Description of setting #13445 'Use VC-1 VDPAU'
+#: system/settings/settings.xml
+msgctxt "#13446"
+msgid "Enable this option to use hardware acceleration for VC-1 based codecs. If disabled the CPU will be used instead. AMD Hardware with VDPAU cannot decode VC-1 Simple."
+msgstr ""
+
+#. Description of Mpeg-2 Codec for VAAPI
+#: system/settings/settings.xml
+msgctxt "#13447"
+msgid "Use Mpeg-2 VAAPI"
+msgstr ""
+
+#. Description of setting #13447 'Use Mpeg-2 VAAPI'
+#: system/settings/settings.xml
+msgctxt "#13448"
+msgid "Enable this option to use hardware acceleration for Mpeg-(1/2) codecs. If disabled the CPU will be used instead. Some Mpeg-2 Videos might have green artifacts."
+msgstr ""
+
+#. Description of Mpeg-4 Codec for VAAPI
+#: system/settings/settings.xm
+msgctxt "#13449"
+msgid "Use Mpeg-4 VAAPI"
+msgstr ""
+
+#. Description of setting #13449 'Use Mpeg-4 VAAPI'
+#: system/settings/settings.xml
+msgctxt "#13450"
+msgid "Enable this option to use hardware acceleration for the Mpeg-4 codec. If disabled the CPU will be used instead."
+msgstr ""
+
+#. Description of VC-1 Codec for VAAPI
+#: system/settings/settings.xm
+msgctxt "#13451"
+msgid "Use VC-1 VAAPI"
+msgstr ""
+
+#. Description of setting #13451 'Use VC-1 VAAPI'
+#: system/settings/settings.xml
+msgctxt "#13452"
+msgid "Enable this option to use hardware acceleration for VC-1 based codecs. If disabled the CPU will be used instead. Especially VC-1 Interlaced fails hard on Intel hardware."
+msgstr ""
+
+#empty strings from id 13453 to 13499
 
 #: system/settings/settings.xml
 msgctxt "#13500"
@@ -11760,12 +11832,19 @@ msgctxt "#24022"
 msgid "Enable"
 msgstr ""
 
+#. Defines the state of the add-on in the add-on manager window
 #: xbmc/filesystem/AddonsDirectory.cpp
 msgctxt "#24023"
+msgid "Disabled"
+msgstr ""
+
+#. Used as an error message (triggered from content dialog) on disabled scrapers
+#: xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+msgctxt "#24024"
 msgid "Add-on disabled"
 msgstr ""
 
-#empty strings from id 24024 to 24026
+#empty strings from id 24025 to 24026
 
 #: xbmc/addons/addon.cpp
 msgctxt "#24027"
@@ -12151,7 +12230,12 @@ msgctxt "#24121"
 msgid "Enter search string"
 msgstr ""
 
-#empty strings from id 24122 to 24999
+#: xbmc/filesystem/AddonDirectory.cpp
+msgctxt "#24122"
+msgid "Update all"
+msgstr ""
+
+#empty strings from id 24123 to 24999
 
 msgctxt "#25000"
 msgid "Notifications"
@@ -15084,3 +15168,8 @@ msgstr ""
 msgctxt "#37023"
 msgid "Do you wish to stop playback on the remote device?"
 msgstr ""
+
+#: system/settings/rbp.xml
+msgctxt "#37024"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - Not recommended on Pi as this requires a lot of CPU."
+msgstr ""
index 5aa52c8..6ba00e3 100644 (file)
@@ -3889,6 +3889,10 @@ msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Tajpi Search String"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Nombro de kanaloj"
+
 msgctxt "#34123"
 msgid "Never"
 msgstr "Never"
index 94c83aa..972cbbe 100644 (file)
@@ -7037,10 +7037,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Moto"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Tervis"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Kokandus"
@@ -7061,10 +7057,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Algupärane keel"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Must &amp; Valge"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Avaldamata"
@@ -8119,7 +8111,7 @@ msgstr "Osa"
 
 msgctxt "#20360"
 msgid "Episodes"
-msgstr "Osad"
+msgstr "Osa"
 
 msgctxt "#20361"
 msgid "Loading episode details"
@@ -10209,6 +10201,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanalite arv"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 7d27266..c998c67 100644 (file)
@@ -5561,10 +5561,6 @@ msgctxt "#19645"
 msgid "Tourism/Travel"
 msgstr "Ferðavinna og ferðing"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Rørsla og heilsa"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Matgerð"
@@ -5577,10 +5573,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Uppruna mál"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Svart og hvítt"
-
 msgctxt "#19664"
 msgid "Live Broadcast"
 msgstr "Beinleiðis sendingar"
@@ -8245,6 +8237,10 @@ msgctxt "#33200"
 msgid "Detected New Connection"
 msgstr "Fann nýggja íbinding"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Tal av kanalum"
+
 msgctxt "#34120"
 msgid "Play GUI sounds"
 msgstr "Spæl GUI ljóð"
index 4f9d949..477f72c 100644 (file)
@@ -7005,10 +7005,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Autoilu"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Kuntoilu ja terveys"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Ruuanlaitto"
@@ -7029,10 +7025,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Alkuperäisellä kielellä"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Mustavalkoinen"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Julkaisematon"
@@ -10133,6 +10125,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanavien määrä"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
diff --git a/language/French (Canada)/langinfo.xml b/language/French (Canada)/langinfo.xml
new file mode 100644 (file)
index 0000000..91c1277
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!-- About Timezone and daylight saving time - (DST) / SUMMER TIME. -->
+<!-- Link:                                                -->
+<!-- http://www.worldtimezone.com/ -->
+
+<language locale="fr">
+  <charsets>
+    <gui>CP1252</gui>
+    <subtitle>CP1252</subtitle>
+  </charsets>
+
+  <dvd>
+    <menu>fr</menu>
+    <audio>fr</audio>
+    <subtitle>fr</subtitle>
+  </dvd>
+
+  <regions>
+    <region name="Canada" locale="CA">
+      <dateshort>DD/MM/YYYY</dateshort>
+      <datelong>DDDD D MMMM YYYY</datelong>
+      <time symbolAM="" symbolPM="">H:mm:ss</time>
+      <tempunit>C</tempunit>
+      <speedunit>kmh</speedunit>
+      <timezone>EST</timezone>
+    </region>
+  </regions>
+
+  <sorttokens>
+    <token>The</token>
+    <token>Le</token>
+    <token>La</token>
+    <token>Les</token>
+    <token>Un</token>
+    <token>Une</token>
+    <token>Des</token>
+    <token separators="'">L</token>
+  </sorttokens>
+</language>
+
index c8090a6..4ac07d5 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Choisir le répertoire de destination"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Surmixage stéréo"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Nombre de canaux"
@@ -1559,7 +1563,7 @@ msgstr "Pas de cache"
 
 msgctxt "#432"
 msgid "Remove movie from library"
-msgstr "Enlever le film de la médiathèque"
+msgstr "Enlever le film de la vidéothèque"
 
 msgctxt "#433"
 msgid "Really remove '%s'?"
@@ -2323,11 +2327,11 @@ msgstr "Retirer de la médiathèque"
 
 msgctxt "#647"
 msgid "Export video library"
-msgstr "Exporter la médiathèque vidéo"
+msgstr "Exporter la vidéothèque"
 
 msgctxt "#648"
 msgid "Import video library"
-msgstr "Importer une médiathèque vidéo"
+msgstr "Importer une vidéothèque"
 
 msgctxt "#649"
 msgid "Importing"
@@ -2401,13 +2405,17 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Journalisation bavarde..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Activer le transcodage « Dolby Digital »"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Épurement de la médiathèque"
 
 msgctxt "#701"
 msgid "Removing old songs from the library"
-msgstr "Suppression des anciens morceaux de la médiathèque"
+msgstr "Suppression des anciens morceaux de la musithèque"
 
 msgctxt "#702"
 msgid "This path has been scanned before"
@@ -2743,7 +2751,7 @@ msgstr "Mise-à-jour de la médiathèque"
 
 msgctxt "#800"
 msgid "Music library needs to rescan tags from files."
-msgstr "La médiathèque doit à nouveau obtenir les balises à partir des fichiers."
+msgstr "La musithèque doit à nouveau obtenir les balises à partir des fichiers."
 
 msgctxt "#801"
 msgid "Would you like to scan now?"
@@ -3651,7 +3659,7 @@ msgstr "Musique/Fichiers"
 
 msgctxt "#10502"
 msgid "Music/Library"
-msgstr "Musique/Médiathèque"
+msgstr "Musique/Musithèque"
 
 msgctxt "#10503"
 msgid "Playlist editor"
@@ -3691,7 +3699,7 @@ msgstr "Informations du système"
 
 msgctxt "#10516"
 msgid "Music - Library"
-msgstr "Musique - Médiathèque"
+msgstr "Musique - Musithèque"
 
 msgctxt "#10517"
 msgid "Now Playing - Music"
@@ -3907,7 +3915,7 @@ msgstr "Élément verrouillé"
 
 msgctxt "#12349"
 msgid "Updating video library art"
-msgstr "Mise à jour des illustrations de la médiathèque vidéo"
+msgstr "Mise à jour des illustrations de la vidéothèque"
 
 msgctxt "#12350"
 msgid "Processing %s"
@@ -3915,7 +3923,7 @@ msgstr "Traitement de %s"
 
 msgctxt "#12351"
 msgid "The art cache in your video library needs updating."
-msgstr "Besoin de mise à jour du cache des illustrations de la médiathèque vidéo."
+msgstr "Besoin de mise à jour du cache des illustrations de la vidéothèque"
 
 msgctxt "#12352"
 msgid "No downloading is needed."
@@ -4675,7 +4683,7 @@ msgstr "Information sur l'album"
 
 msgctxt "#13352"
 msgid "Scan item to library"
-msgstr "Balayer les éléments vers la médiathèque"
+msgstr "Intégrer à la musithèque"
 
 msgctxt "#13353"
 msgid "Stop scanning"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Autoriser l'accélération matérielle (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Permettre le décodage image-multifil"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Méthode de synchro. A/V"
@@ -5183,7 +5195,7 @@ msgstr "Changer le code de zone 3"
 
 msgctxt "#14022"
 msgid "Library"
-msgstr "Médiathèque"
+msgstr "Musithèque"
 
 msgctxt "#14023"
 msgid "No TV"
@@ -5495,7 +5507,7 @@ msgstr "Mot de passe"
 
 msgctxt "#15100"
 msgid "Library"
-msgstr "Médiathèque"
+msgstr "Musithèque"
 
 msgctxt "#15101"
 msgid "Database"
@@ -5695,7 +5707,7 @@ msgstr "Mode fête interrompu."
 
 msgctxt "#16031"
 msgid "No matching songs in the library."
-msgstr "Aucun morceau correspondant dans la médiathèque."
+msgstr "Aucun morceau correspondant dans la musithèque."
 
 msgctxt "#16032"
 msgid "Could not initialise database."
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Enregistrements TV"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Dossier avec icônes de chaînes"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Chaînes"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Fenêtre du GEP par défaut"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Icônes de chaînes"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Cet événement est déjà en cours d'enregistrement"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Confirmer le changement de chaîne en appuyant sur OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Icône de chaîne"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Aucune icône"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Choisir une icône"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Rechercher des icônes"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Autre/Inconnu"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobile"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Conditionnement physique et santé"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cuisine"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Langue d'origine"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Noir et blanc"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Non publié"
@@ -8083,11 +8111,11 @@ msgstr "Changer le récupérateur"
 
 msgctxt "#20196"
 msgid "Export music library"
-msgstr "Exporter la médiathèque musicale"
+msgstr "Exporter la musithèque"
 
 msgctxt "#20197"
 msgid "Import music library"
-msgstr "Importer une médiathèque musicale"
+msgstr "Importer une musithèque"
 
 msgctxt "#20198"
 msgid "No artist found!"
@@ -8211,7 +8239,7 @@ msgstr "Inconnu ou embarqué (protégé)"
 
 msgctxt "#20314"
 msgid "Videos - Library"
-msgstr "Vidéos - Médiathèque"
+msgstr "Vidéos - Vidéothèque"
 
 msgctxt "#20316"
 msgid "Sort by: ID"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Analyse des albums avec %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Intrigue du film"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Lecture partie..."
@@ -8391,11 +8423,11 @@ msgstr "Chargement des détails des épisodes"
 
 msgctxt "#20362"
 msgid "Remove episode from library"
-msgstr "Retirer l'épisode de la médiathèque"
+msgstr "Retirer l'épisode de la vidéothèque"
 
 msgctxt "#20363"
 msgid "Remove TV show from library"
-msgstr "Retirer l'émission de la médiathèque"
+msgstr "Retirer l'émission de la vidéothèque"
 
 msgctxt "#20364"
 msgid "TV show"
@@ -8511,7 +8543,7 @@ msgstr "Vidéos musicales"
 
 msgctxt "#20392"
 msgid "Remove music video from library"
-msgstr "Retirer la vidéo musicale de la médiathèque"
+msgstr "Retirer la vidéo musicale de la vidéothèque"
 
 msgctxt "#20393"
 msgid "Music video information"
@@ -8551,7 +8583,7 @@ msgstr "Lire la vidéo musicale"
 
 msgctxt "#20402"
 msgid "Download actor thumbnails when adding to library"
-msgstr "Télécharger les imagettes d'acteur lors de l'ajout à la médiathèque"
+msgstr "Télécharger les imagettes d'acteur lors de l'ajout à la vidéothèque"
 
 msgctxt "#20403"
 msgid "Set actor thumb"
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Enlever le partage média"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Dossier personnalisé des sous-titres"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Répertoire du film & des sous-titres alternatifs"
@@ -8951,7 +8987,7 @@ msgstr "Activer les barres de défilement"
 
 msgctxt "#21384"
 msgid "Make watched filtering a toggle in video library"
-msgstr "Activer le filtre Masquer vue dans la médiathèque"
+msgstr "Activer le filtre Masquer vue dans la vidéothèque"
 
 msgctxt "#21385"
 msgid "Open"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mélangé"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Emplacement des sous-titres à l'écran"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fixe"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Choisir l'élément à lire"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Chapitres : %u -durée : %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Échec lors de la lecture du disque Blu-ray"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Le menu de ce disque Blu-ray n'est pas pris en charge"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Mode médiathèque"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Nombre de canaux"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11139,7 +11195,7 @@ msgstr "Pas d'information actuellement disponible."
 
 msgctxt "#36141"
 msgid "Show plot information for unwatched media in the Video Library."
-msgstr "Afficher le résumé pour les média non vus de la bibliothèque Vidéo"
+msgstr "Afficher le résumé pour les média non vus de la vidéothèque"
 
 msgctxt "#36142"
 msgid "No info available yet."
@@ -11171,11 +11227,11 @@ msgstr "Retirer les éléments de votre bibliothèque qui n'ont pas pu être tro
 
 msgctxt "#36149"
 msgid "Export the Video Library database to XML files. This will optionally overwrite your current XML files."
-msgstr "Exporter la base de données de la bibliothèque Vidéo au format XML. Cela peut potentiellement écraser les fichiers XML déjà présents."
+msgstr "Exporter la base de données de la vidéothèque au format XML. Cela peut potentiellement écraser les fichiers XML déjà présents."
 
 msgctxt "#36150"
 msgid "Import a XML file into the Video Library database."
-msgstr "Importer un fichier XML vers la base de données de la bibliothèque Vidéo."
+msgstr "Importer un fichier XML vers la base de données de la vidéothèque."
 
 msgctxt "#36151"
 msgid "No info available yet."
@@ -11375,7 +11431,7 @@ msgstr "Sélectionner la source d'information par défaut pour les séries TV. V
 
 msgctxt "#36200"
 msgid "Default scraper used for adding music videos to your library."
-msgstr "Scraper par défaut utilisé pour ajouter les vidéos musicales dans votre bibliothèque."
+msgstr "Scraper par défaut utilisé pour ajouter les vidéos musicales dans votre vidéothèque."
 
 msgctxt "#36201"
 msgid "No info available yet."
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Sélectionner commet les propriétés de la sortie audio seront positionnées : [Fixe] - les propriétés de sortie sont positionnées pour le taux d'échantillonnage spécifié et les configuration des enceintes une fois pour toute ; [Meilleure correspondance] - les propriétés de sortie sont positionnées pour être toujours le plus proche possible de la source ; [Optimisé] - les propriétés de sortie sont positionnées au début de la lecture et ne changeront pas si les propriétés de la source changent."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Choisir le nombre de canaux pris en charge par la connexion audio, ou le nombre de haut-parleurs dans le cas de connexions analogues. Ce paramètre ne s'applique pas à l'audio passthrough. Note : SPDIF prend en charge seulement les canaux 2.0 mais peut quand même fournir une sortie audio multiplexée en utilisant un format pris en charge par passthrough."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Amplifier les flux AC3 qui ont été réduit à 2 voies."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Choisir pour activer le surmixage de 2 canaux audio vers le nombre de canaux audio spécifiés par la configuration des haut-parleurs."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Sélectionner cette option si votre récepteur est capable de décoder les flux AC3."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Activer le décodage vidéo matériel en utilisant le décodeur AMLogic"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Utiliser le décodage image-multifil au lieu du décodage accéléré par le matériel (moins fiable que le mode par défaut à un exétron) "
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Choisir ce qu'il se passera quand un élément du GEP est sélectionné : [Afficher le menu contextuel] l'activera vous permettant de choisir d'autres actions; [Changer de chaîne] syntonisera instantanément la chaîne; [Afficher les informations] affichera les informations détaillées avec l'histoire et d'autres options; [Enregistrer] créera une minuterie d'enregistrement pour l'élément choisi."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Enregistrer"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Choisir ceci si la connexion de sortie audio ne prend en charge que l'audio multiplexé tel que « Dolby Digital 5.0 ». Ceci permet d'écouter de l'audio multiplexé tel que AAC 5.1 ou Flac 5.1 en son ambiophonique 5.1. Note : le transcodage peut entraîner une réduction de la qualité sonore."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Mode stéréoscopique (actuel)"
@@ -12484,3 +12556,11 @@ msgstr "Activer les illustrations à plus grande profondeur de couleurs"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Définir une limite de résolution de l'interface utilisateur"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Lecteur UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Désirez-vous arrêter la lecture sur le périphérique distant?"
index 6dc7179..5cd5c39 100644 (file)
@@ -7293,10 +7293,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobile"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness et Santé"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cuisine"
@@ -7317,10 +7313,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Langue d'origine"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Noir et Blanc"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Non publié"
@@ -10601,6 +10593,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Nombre de canaux"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index b5a58f7..be350e2 100644 (file)
@@ -7281,10 +7281,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobilismo"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Estado físico e Saúde"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cociña"
@@ -7305,10 +7301,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Idioma Orixinal"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Branco e Negro"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Sen publicar"
@@ -10577,6 +10569,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canles"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 5454a1e..4c5aaba 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Zielordner wählen"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Anzahl der Kanäle"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Ausführliches loggen..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Dolby Digital Umwandlung einschalten"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Bibliothek wird bereinigt"
@@ -5997,6 +6005,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV Aufnahmen"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Verzeichnis mit Kanal-Icons"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanäle"
@@ -6185,6 +6197,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Standard EPG-Fenster"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanal-Icons"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Dieses Ereignis wird bereits aufgenommen."
@@ -7009,6 +7025,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Kanalwechsel durch Drücken von OK bestätigen"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Aktuelles Icon"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Kein Icon"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Icon auswählen"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Nach Icon browsen"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Andere/Unbekannt"
@@ -7293,10 +7325,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Auto"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness und Gesundheit"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Kochen"
@@ -7317,10 +7345,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Originalsprache"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Schwarz-weiß"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Unveröffentlicht"
@@ -8237,6 +8261,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Durchsuche Alben mit %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Handlung"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Einzelteil spielen..."
@@ -8881,6 +8909,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Quelle entfernen"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Angepasstes Untertitel-Verzeichnis"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Video- & alternatives Untertitel-Verzeichnis"
@@ -9249,6 +9281,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "gemischt"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Untertitelposition auf dem Bildschirm"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fest eingestellt"
@@ -10245,6 +10281,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Wähle Eintrag für Wiedergabe"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Kapitel: %u - Dauer: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Blu-ray Wiedergabe nicht möglich"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Das Menü der Blu-ray wird nicht unterstützt"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Datenbankmodus"
@@ -10601,6 +10649,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Anzahl der Kanäle"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,6 +12073,10 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Legen Sie das Verhalten der Ton-Ausgabe fest: [Fest eingestellt] - Ausgabe verwendet stets die festgelegte Sampling-Rate und Lautsprecherkonfiguration; [Beste Übereinstimmung] - Ausgabe wird stets so gut wie möglich an das Quell-Format angepasst; [Optimiert] - Ausgabe wird einmalig zu Beginn der Wiedergabe konfiguriert und gleicht sich während dieser nicht mehr einem geänderten Quell-Format an."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Anzahl der Kanäle auswählen, die durch die Audioverbindung unterstützt werden, oder die Anzahl der Lautsprecher bei analoger Verbindung. Diese Einstellung gilt nicht für Passthrough-Audio. Hinweis - SPDIF unterstützt nur 2.0 Kanäle, kann jedoch noch Multikanal-Audio ausgeben, wenn ein Format verwendet wird, das von Passthrough unterstützt wird."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Verstärke AC3-Spuren die auf 2-Kanäle reduziert wurden."
@@ -12277,6 +12333,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Aufnehmen"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Auswählen, wenn der Audio-Ausgang nur Multikanal-Ton als Dolby Digital 5.1 unterstützt, dies ermöglicht Multikanal-Ton wie AAC5.1 oder FLAC5.1 als 5.1 Surround-Sound zu hören. Hinweis - Umwandlung kann zur Reduzierung der Tonqualität führen."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Stereoskopischer Modus (aktuell)"
@@ -12484,3 +12544,11 @@ msgstr "Höhere Farbtiefe in Grafiken verwenden"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Maximale Auflösung der Benutzeroberfläche"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP-Abspieler"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Möchten Sie die Wiedergabe anhalten für das Remote-Gerät?"
index 650a090..5659456 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Επιλογή φακέλου προορισμού"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Στερεοφωνικό upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Αριθμός καναλιών"
@@ -1223,7 +1227,7 @@ msgstr "Έτος"
 
 msgctxt "#346"
 msgid "Normalize levels on downmix"
-msgstr "Εξισορρόπηση των επιπέδων κατά τον υποβιβασμό καναλιών"
+msgstr "Εξισορρόπηση των επιπέδων κατά το downmix"
 
 msgctxt "#347"
 msgid "DTS-HD capable receiver"
@@ -1979,7 +1983,7 @@ msgstr "Δεν υπάρχει βιογραφία γι' αυτόν τον καλ
 
 msgctxt "#548"
 msgid "Downmix multichannel audio to stereo"
-msgstr "Υποβιβασμός πολυκάναλου ήχου σε στερεοφωνικό"
+msgstr "Downmix πολυκάναλου ήχου σε στερεοφωνικό"
 
 msgctxt "#550"
 msgid "Sort by: %s"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Αναλυτική καταγραφή..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Ενεργοποίηση Διακωδικοποίησης Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Εκκαθάριση συλλογής"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Χρήση επιτάχυνσης υλικού (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Να επιτρέπεται η πολυνηματική αποκωδικοποίηση καρέ"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Μέθοδος συγχρονισμού A/V"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Τηλεοπτικές εγγραφές"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Φάκελος εικονιδίων καναλιών"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Κανάλια"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Προεπιλεγμένο παράθυρο EPG"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Εικονίδια καναλιών"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Γίνεται ήδη εγγραφή αυτού του γεγονότος"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Επιβεβαίωση αλλαγής καναλιού πιέζοντας 'Επιλογή'"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Τρέχον εικονίδιο"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Κανένα εικονίδιο"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Επιλογή εικονιδίου"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Αναζήτηση εικονιδίου"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Άλλο/Άγνωστο"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Μηχανοκίνηση"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Φυσική Κατάσταση &amp; Υγεία"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Μαγειρική"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Αρχική Γλώσσα"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Μαύρο &amp; Άσπρο"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Αδημοσίευτο"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Σάρωση άλμπουμ με %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Πλοκή ταινίας"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Αναπαραγωγή κομματιού..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Αφαίρεση κοινόχρηστων πολυμέσων"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Προσαρμοσμένος φάκελος υποτίτλων"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Ταινία & εναλλακτικός φάκελος υποτίτλων"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "ανάμικτα"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Τοποθεσία υποτίτλου στην οθόνη"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Σταθερή"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Επιλογή αντικειμένου για αναπαραγωγή"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Κεφάλαια: %u - διάρκεια: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Αποτυχία αναπαραγωγής Δίσκου Blu-ray"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Το μενού αυτού του Δίσκου Blu-ray δεν υποστηρίζεται"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Λειτουργία Συλλογής"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Ήχος Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Αριθμός καναλιών"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,9 +12077,17 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Επιλογή της μεθόδου ορισμού των ιδιοτήτων της εξόδου ήχου: [Σταθερή] - οι ιδιότητες της εξόδου ορίζονται πάντα στον καθορισμένο ρυθμό δειγματοληψίας & τη διαμόρφωση των ηχείων. [Καλύτερη Αντιστοιχία] - οι ιδιότητες της εξόδου ορίζονται πάντα να είναι κατά το δυνατόν πιο κοντά στις ιδιότητες της πηγής. [Βελτιστοποιημένο] - οι ιδιότητες της εξόδου ορίζονται κατά την έναρξη της αναπαραγωγής, και δεν αλλάζουν ακόμα και αν αλλάξουν οι ιδιότητες της πηγής."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Επιλογή του αριθμού των καναλιών που υποστηρίζονται από τη σύνδεση του ήχου, ή του πλήθους των ηχείων αν είναι αναλογική σύνδεση. Αυτή η ρύθμιση δεν εφαρμόζεται στη διέλευση ήχου. Σημείωση - το SPDIF υποστηρίζει μόνο ήχο 2.0 καναλιών, αλλά μπορεί, παρ'όλα αυτά, να αποδίδει πολυκάναλο χρησιμοποιώντας μορφοποίηση που υποστηρίζεται από τη διέλευση."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
-msgstr "Ενίσχυση των ροών AC3 που έχουν υποστεί υποβιβαστεί σε 2 κανάλια."
+msgstr "Ενίσχυση των ροών AC3 που έχουν υποστεί downmix σε 2 κανάλια."
+
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Επιλογή για να γίνεται upmix του 2-κάναλου ήχου στο πλήθος των καναλιών ήχου που ορίζεται από τη διαμόρφωση των ηχείων."
 
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Ενεργοποίηση αποκωδικοποίησης υλικού AMLogic των αρχείων βίντεο"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Χρήση πολυνηματικής αποκωδικοποίησης καρέ αντί αποκωδικοποίησης υλικού (λιγότερο αξιόπιστη από την προεπιλεγμένη λειτουργία)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Ορισμός της ενέργειας όταν έχει επιλεγεί ένα αντικείμενο EPG: Η [Εμφάνιση μενού επιλογών] θα ενεργοποιήσει το αντίστοιχο μενού από όπου μπορείτε να επιλέξετε περαιτέρω ενέργειες. Η [Μετάβαση σε κανάλι] θα αλλάξει άμεσα το κανάλι σε αυτό που θέλετε. Η [Προβολή πληροφοριών] θα εμφανίσει αναλυτικές πληροφορίες, συμπεριλαμβανομένης της πλοκής και επιπλέον επιλογών. Η [Εγγραφή] θα ενεργοποιήσει ένα χρονοδιακόπτη εγγραφής για το επιλεγμένο αντικείμενο."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Εγγραφή"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Επιλογή αυτής της ρύθμισης αν η σύνδεση της εξόδου ήχου υποστηρίζει μόνο πολυκάναλο ήχο όπως το Dolby Digital 5.1. Με αυτόν τον τρόπο μπορεί να αποδοθεί πολυκάναλος ήχος όπως AAC5.1 ή FLAC5.1 σε μορφή 5.1 surround sound. Σημείωση - η διακωδικοποίηση ενδέχεται να οδηγήσει σε μείωση της ποιότητας του ήχου"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Στερεοσκοπική προβολή (τρέχουσα)"
@@ -12371,7 +12443,7 @@ msgstr "Όπως η ταινία"
 
 msgctxt "#36533"
 msgid "Select how audio is downmixed, for example from 5.1 to 2.0: [Enabled] maintains the dynamic range of the original audio source when downmixed however volume will be lower [Disabled] maintains volume level of the original audio source however the dynamic range is compressed. Note - Dynamic range is the difference between the quietest and loudest sounds in a audio source."
-msgstr "Επιλογή του τρόπου με τον οποίο θα γίνεται ο υποβιβασμός καναλιών του ήχου, π.χ. από 5.1 σε 2.0: Το [Ενεργό] διατηρεί το δυναμικό εύρος της αρχικής ηχητικής πηγής κατά τον υποβιβασμό, εντούτοις η ένταση θα είναι πιο χαμηλή. Το [Ανενεργό] διατηρεί την ένταση του ήχου της αρχικής ηχητικής πηγής, εντούτοις το δυναμικό εύρος συμπιέζεται. Σημείωση: Το δυναμικό εύρος είναι η διαφορά ανάμεσα στον πιο έντονο και τον πιο αχνό ήχο σε μια ηχητική πηγή."
+msgstr "Επιλογή του τρόπου με τον οποίο θα γίνεται ο υποβιβασμός καναλιών του ήχου (downmix), π.χ. από 5.1 σε 2.0: Το [Ενεργό] διατηρεί το δυναμικό εύρος της αρχικής ηχητικής πηγής κατά το downmix, εντούτοις η ένταση θα είναι πιο χαμηλή. Το [Ανενεργό] διατηρεί την ένταση του ήχου της αρχικής ηχητικής πηγής, εντούτοις το δυναμικό εύρος συμπιέζεται. Σημείωση: Το δυναμικό εύρος είναι η διαφορά ανάμεσα στον πιο έντονο και τον πιο αχνό ήχο σε μια ηχητική πηγή."
 
 msgctxt "#36535"
 msgid "Stereoscopic mode of video"
@@ -12407,7 +12479,7 @@ msgstr "Έξοδος ήχου και στην αναλογική (ακουστι
 
 msgctxt "#36543"
 msgid "Enable this to make dialogue louder compared to background sounds when downmixing multichannel audio"
-msgstr "Ενεργοποιήστε το για αύξηση της έντασης του διαλόγου σε σχέση με τους ήχους υποβάθρου κατά τον υποβιβασμό πολυκάναλου ήχου"
+msgstr "Ενεργοποιήστε το για αύξηση της έντασης του διαλόγου σε σχέση με τους ήχους υποβάθρου κατά το downmix πολυκάναλου ήχου"
 
 msgctxt "#36544"
 msgid "Enable hardware decoding of video files."
@@ -12471,7 +12543,7 @@ msgstr "Διπλή έξοδος ήχου"
 
 msgctxt "#37018"
 msgid "Boost centre channel when downmixing"
-msgstr "Ενίσχυση του κεντρικού καναλιού κατά τον υποβιβασμό καναλιών"
+msgstr "Ενίσχυση του κεντρικού καναλιού κατά το downmix"
 
 msgctxt "#37019"
 msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
@@ -12484,3 +12556,11 @@ msgstr "Ενεργοποίηση εικόνων υψηλότερου χρωμα
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Ορισμός ορίου ανάλυσης του Περιβάλλοντος Εργασίας"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Αναπαραγωγέας UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Να διακοπεί η αναπαραγωγή στην απομακρυσμένη συσκευή;"
index 02025e3..e3b0d77 100644 (file)
@@ -775,7 +775,7 @@ msgstr "חפש את שמות רצועות הדיסק ב freedb.org"
 
 msgctxt "#228"
 msgid "Shuffle playlist on load"
-msgstr "רש×\99×\9eת ×\94ש×\9e×¢×\94 ×\90קר×\90×\99ת בעת הטעינה"
+msgstr "רש×\99×\9eת ×\94ש×\9e×¢×\94 ×\9e×¢×\95ר×\91×\91ת בעת הטעינה"
 
 msgctxt "#229"
 msgid "HDD spindown time"
@@ -865,6 +865,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "בחר ספרית יעד"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "מספר ערוצים"
@@ -1221,6 +1225,10 @@ msgctxt "#347"
 msgid "DTS-HD capable receiver"
 msgstr "מקלט עם תמיכה ב־DTS-HD"
 
+msgctxt "#348"
+msgid "Enable passthrough"
+msgstr "הפעל passthrough"
+
 msgctxt "#349"
 msgid "TrueHD capable receiver"
 msgstr "מקלט עם תמיכה ב־TrueHD"
@@ -1817,6 +1825,10 @@ msgctxt "#507"
 msgid "Sort by: Usage"
 msgstr "מיין לפי : שימוש"
 
+msgctxt "#510"
+msgid "Enable visualisations"
+msgstr "הפעל חיזוי"
+
 msgctxt "#511"
 msgid "Enable video mode switching"
 msgstr "אפשר החלפת מצב וידאו"
@@ -2905,6 +2917,10 @@ msgctxt "#1043"
 msgid "Program Add-ons"
 msgstr "הרחבות תוכנות"
 
+msgctxt "#1044"
+msgid "Set plug-in thumb"
+msgstr "הגדר תמונה ממוזערת לתוסף"
+
 msgctxt "#1045"
 msgid "Add-on settings"
 msgstr "הגדרות הרחבה"
@@ -3485,6 +3501,10 @@ msgctxt "#10039"
 msgid "Expert"
 msgstr "מומחה"
 
+msgctxt "#10040"
+msgid "Add-on browser"
+msgstr "דפדפן הרחבה"
+
 msgctxt "#10041"
 msgid "Reset above settings to default"
 msgstr "אפס הגדרות במסך זה לברירת מחדל"
@@ -4469,6 +4489,10 @@ msgctxt "#13318"
 msgid "Recursive slideshow"
 msgstr "מצגת תמונות רקורסיבית"
 
+msgctxt "#13319"
+msgid "Randomise"
+msgstr "אקראי"
+
 msgctxt "#13320"
 msgid "Stereo"
 msgstr "סטריאו"
@@ -4681,10 +4705,22 @@ msgctxt "#13388"
 msgid "Preset"
 msgstr "קביעון"
 
+msgctxt "#13389"
+msgid "There are no presets available\nfor this visualisation"
+msgstr "אין קביעונים קיימים\nעבור חיזוי זה"
+
+msgctxt "#13390"
+msgid "There are no settings available\nfor this visualisation"
+msgstr "אין הגדרות קיימות\nעבור חיזוי זה"
+
 msgctxt "#13391"
 msgid "Eject/Load"
 msgstr "הוצאה/טעינה"
 
+msgctxt "#13392"
+msgid "Use visualisation if playing audio"
+msgstr "השתמש בחיזוי בניגון אודיו"
+
 msgctxt "#13393"
 msgid "Calculate size"
 msgstr "חשב גודל"
@@ -4949,6 +4985,14 @@ msgctxt "#13553"
 msgid "%.1f Seconds"
 msgstr "%.1f שניות"
 
+msgctxt "#13554"
+msgid "%d Minute"
+msgstr "%d דקה"
+
+msgctxt "#13555"
+msgid "%d Minutes"
+msgstr "%d דקות"
+
 msgctxt "#13600"
 msgid "Apple remote"
 msgstr "APPLE שלט"
@@ -5857,6 +5901,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "הקלטת טלוויזיה"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "תיקיה עם סמלי ערוץ"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "ערוצים"
@@ -6045,6 +6093,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "חלון לוח שידורים ברירת מחדל"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "סמלי ערוץ"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "הארוע כבר נמצא בהקלטה."
@@ -6177,6 +6229,14 @@ msgctxt "#19099"
 msgid "Service"
 msgstr "שירות"
 
+msgctxt "#19100"
+msgid "Mux"
+msgstr "Mux"
+
+msgctxt "#19101"
+msgid "Provider"
+msgstr "ספק"
+
 msgctxt "#19102"
 msgid "Please switch to another channel."
 msgstr "אנא החלף לערוץ אחר."
@@ -6661,6 +6721,10 @@ msgctxt "#19233"
 msgid "Display a notification on timer updates"
 msgstr "הצג הודעה על עדכון תזמון הקלטה"
 
+msgctxt "#19234"
+msgid "Use backend channels numbers (only works with 1 enabled PVR Add-on)"
+msgstr "השתמש במספרי ערוצים מממשק אחורי (עובד רק אם הרחבה 1 של PVR מופעלת)"
+
 msgctxt "#19235"
 msgid "PVR manager is starting up"
 msgstr "מנהל PVR מאתחל"
@@ -6681,10 +6745,18 @@ msgctxt "#19239"
 msgid "Starting background threads"
 msgstr "מתחיל מחרוזות ברקע"
 
+msgctxt "#19240"
+msgid "No PVR Add-on enabled"
+msgstr "אין הרחבת PVR מופעלת"
+
 msgctxt "#19241"
 msgid "The PVR manager has been enabled without any"
 msgstr "מנהל PVR אותחל ללא כל תוסף PVR."
 
+msgctxt "#19242"
+msgid "enabled PVR Add-on. Enable at least one Add-on"
+msgstr "הרחבת PVR מופעלת. הפעל לפחות הרחבה אחת"
+
 msgctxt "#19243"
 msgid "in order to use the PVR functionality."
 msgstr "על מנת להשתמש בפונקציית PVR "
@@ -6805,6 +6877,10 @@ msgctxt "#19272"
 msgid "You need a tuner, backend software, and an"
 msgstr "אתה צריך כרטיס טלוויזיה,תוכנת ממשק אחורי, ובנוסף"
 
+msgctxt "#19273"
+msgid "Add-on for the backend to be able to use PVR."
+msgstr "הרחבה עבור ממשק אחורי שתאפשר שימוש ב-PVR."
+
 msgctxt "#19274"
 msgid "Please visit xbmc.org/pvr to learn more."
 msgstr "בבקשה בקר בxbmc.org/pvr ע\"מ ללמוד יותר."
@@ -6837,6 +6913,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "אשרר בטול מעברים ע״י לחיצה על אישור"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "סמל נוכחי"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "ללא סמל"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "בחר סמל"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "עיין לסמל"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "אחר\\לא ידוע"
@@ -7121,10 +7213,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "נהיגה"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "כושר &amp;בריאות"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "בישול"
@@ -7145,10 +7233,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "שפה מקורית"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "שחור ולבן"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "לא פורסם"
@@ -7917,6 +8001,10 @@ msgctxt "#20199"
 msgid "Downloading artist info failed"
 msgstr "הורדת פרטי אמן נכשלה"
 
+msgctxt "#20220"
+msgid "Override song tags with online information"
+msgstr "דרוס תגיות שיר עם מידע מהאינטרנט"
+
 msgctxt "#20240"
 msgid "Android music"
 msgstr "מוזיקה מונפשת"
@@ -8049,6 +8137,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "סורק אלבומים תוך שימוש ב %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "תקציר סרט"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "נגן חלק..."
@@ -8489,6 +8581,10 @@ msgctxt "#20434"
 msgid "Sets"
 msgstr "מארזים"
 
+msgctxt "#20435"
+msgid "Combine split video items"
+msgstr "אחד פריטי וידאו מפוצלים"
+
 msgctxt "#20436"
 msgid "Export actor thumbs?"
 msgstr "לייצא תמונות ממוזערות לשחקנים"
@@ -8685,6 +8781,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "הסר סיתוף מדיה"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "תיקית כתוביות מותאמת אישית"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "ספריית סרט ותרגום חלופי"
@@ -9053,6 +9153,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "מעורבב"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "מיקום כתובית על המסך"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "מקובע"
@@ -9085,6 +9189,18 @@ msgctxt "#21469"
 msgid "%s to %s"
 msgstr "%s עד %s"
 
+msgctxt "#21600"
+msgid "Prefer external subtitles"
+msgstr "העדף כתוביות חיצוניות"
+
+msgctxt "#21601"
+msgid "Prefer external subtitles to internal ones"
+msgstr "העדף כתוביות חיצוניות מאשר פנימיות."
+
+msgctxt "#21602"
+msgid "(External)"
+msgstr "(חיצוני)"
+
 msgctxt "#21800"
 msgid "File name"
 msgstr "שם קובץ"
@@ -9769,6 +9885,10 @@ msgctxt "#24045"
 msgid "Add-on does not have the correct structure"
 msgstr "להרחבה אין את המבנה הנכון"
 
+msgctxt "#24046"
+msgid "%s is used by the following installed Add-on(s)"
+msgstr "ההרחבה(ות) להלן עושות שימוש ב-%s"
+
 msgctxt "#24047"
 msgid "This Add-on cannot be uninstalled"
 msgstr "לא ניתן להסיר הרחבה זו"
@@ -9777,6 +9897,10 @@ msgctxt "#24048"
 msgid "Rollback"
 msgstr "חזור לאחור"
 
+msgctxt "#24049"
+msgid "Incompatible"
+msgstr "איננו תואם"
+
 msgctxt "#24050"
 msgid "Available Add-ons"
 msgstr "הרחבות קיימות"
@@ -9961,6 +10085,10 @@ msgctxt "#24116"
 msgid "Default TV Service"
 msgstr "שירות טלוויזיה ברירת מחדל"
 
+msgctxt "#24117"
+msgid "Select service that will be used as default to search for TV Show subtitles"
+msgstr "בחר שירות כברירת מחדל עבור חיפוש כתוביות לסדרות."
+
 msgctxt "#24118"
 msgid "Default Movie Service"
 msgstr "שירות סרטים ברירת מחדל"
@@ -10001,6 +10129,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "בחר פריט השמעה"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "פרקים: %u - משך: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "ניגון דיסק Blu-ray נכשל"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "התפריט של דיסק Blu-ray הזה לא נתמך"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "מצב ספריה"
@@ -10077,6 +10217,10 @@ msgctxt "#33016"
 msgid "Clips"
 msgstr "קליפים"
 
+msgctxt "#33017"
+msgid "Restart plug-in to enable"
+msgstr "אתחל תוסף כדי להפעיל"
+
 msgctxt "#33018"
 msgid "Tonight"
 msgstr "הלילה"
@@ -10353,6 +10497,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "מספר ערוצים"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10537,6 +10685,10 @@ msgctxt "#35102"
 msgid "Disable joystick when this device is present"
 msgstr "לנטרל את הג׳ויסטיק כאשר התקן זה קיים"
 
+msgctxt "#35103"
+msgid "Enable system keys in fullscreen"
+msgstr "הפעל מפתחות מערכת במסך מלא"
+
 msgctxt "#35500"
 msgid "Location"
 msgstr "מיקום"
@@ -10797,6 +10949,10 @@ msgctxt "#36132"
 msgid "Preview the selected screensaver."
 msgstr "תצוגה מקדימה של שומר המסך."
 
+msgctxt "#36133"
+msgid "If music is being played, XBMC will start the selected visualisation instead of displaying the screensaver."
+msgstr "אם מוזיקה מנוגנת, XBMC יתחיל את החיזוי הנבחר ובמקום להציג שומר מסך."
+
 msgctxt "#36134"
 msgid "Dim the display when media is paused. Not valid for the 'Dim' screensaver mode."
 msgstr "עמעם את התצוגה כאשר הוידאו נעצר"
@@ -10933,6 +11089,10 @@ msgctxt "#36178"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
 
+msgctxt "#36180"
+msgid "Extract thumbnails and information, such as codecs and aspect ratio, to display in Library Mode."
+msgstr "חלץ תמונות ממוזערות ומידע, כמו מקודדים ויחס רוחב גובה, כדי להציג במצב ספריה."
+
 msgctxt "#36181"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11001,6 +11161,22 @@ msgctxt "#36202"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
 
+msgctxt "#36204"
+msgid "Import channel groups from the PVR backend (if supported). Will delete user created groups if they're not found on the backend."
+msgstr "ייבא קבוצת ערוצים מממשק אחורי PVR (אם נתמך). ימחק קבוצות משתמש שלא קיימות בממשק אחורי."
+
+msgctxt "#36206"
+msgid "Use numbering from the backend, instead of configuring them manually over XBMC."
+msgstr "השתמש במספור מתוך ממשק אחורי, במקום הגדרה ידנית בתוך XBMC."
+
+msgctxt "#36208"
+msgid "Instruct the backend to search for channels (if supported)."
+msgstr "הנחה את הממשק האחורי לחפש בערוצים (אם נתמך)."
+
+msgctxt "#36209"
+msgid "Delete channel/EPG database and reimport the data from the backend afterwards."
+msgstr "מחק מסד נתונים של ערוצים/לוח שידורים ולאחר מכן ייבא מחדש מידע מממשק אחורי."
+
 msgctxt "#36210"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11037,10 +11213,22 @@ msgctxt "#36218"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
 
+msgctxt "#36220"
+msgid "Number of days of EPG data to import from backends. Defaults to 3 days."
+msgstr "מספר ימי לוח השידורים אשר לייבא מממשק אחורי. ברירת מחדל היא 3 ימים."
+
+msgctxt "#36221"
+msgid "Time between EPG data imports from backends. Defaults to 120 minutes."
+msgstr "זמן בין ייבוא לוח השידורים מממשק אחורי. ברירת מחדל היא 120 דקות."
+
 msgctxt "#36222"
 msgid "Do not import EPG data while playing TV to minimise CPU usage."
 msgstr "אל תייבא לוח שידורים בעת צפייה בטלוויזיה כדי למזער שימוש במעבד."
 
+msgctxt "#36225"
+msgid "Delete the EPG database in xbmc and reimport the data afterwards from the backend."
+msgstr "מחק מסד נתונים של לוח שידורים מתוך XBMC ולאחר מכן ייבא מחדש מידע מממשק אחורי."
+
 msgctxt "#36226"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11053,6 +11241,10 @@ msgctxt "#36228"
 msgid "Show the last viewed channel if switching to live tv."
 msgstr "הצג את הערוץ האחרון שנצפה כשמעבירים לטלוויזיה."
 
+msgctxt "#36229"
+msgid "Display signal quality information in the codec information window (if supported by the Add-on and backend)."
+msgstr "הצג מידע על אות איכות בחלון מידע מקודד (אם נתמך ע\"י ההרחבה והממשק אחורי)"
+
 msgctxt "#36230"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11065,6 +11257,26 @@ msgctxt "#36233"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
 
+msgctxt "#36235"
+msgid "Priority of the recording. Higher number means higher priority. Defaults to 50. Not supported by all Add-ons and backends."
+msgstr "עדיפות ההקלטה. מספר גבוה אומר עדיפות גבוהה. ברירת מחדל היא 50. לא נתמך בכל ההרחבות וממשקים אחוריים."
+
+msgctxt "#36236"
+msgid "Delete recording after this time. Defaults to 99 days. Not supported by all Add-ons and backends."
+msgstr "מחק הקלטה לאחר זמן זה. ברירת מחדל היא 99 ימים. לא נתמך בכל ההרחבות וממשקים אחוריים."
+
+msgctxt "#36237"
+msgid "Start recordings before the actual time. Defaults to 2 minutes. Not supported by all Add-ons and backends."
+msgstr "התחל הקלטה לפני הזמן האמיתי. ברירת מחדל היא 2 דקות. לא נתמך בכל ההרחבות וממשקים אחוריים."
+
+msgctxt "#36238"
+msgid "End recordings after the actual time. Defaults to 10 minutes. Not supported by all Add-ons and backends."
+msgstr "סיים הקלטה לאחר הזמן האמיתי. ברירת מחדל היא 10 דקות. לא נתמך בכל ההרחבות וממשקים אחוריים."
+
+msgctxt "#36239"
+msgid "Display a notification when timers are added, finished or removed by the backend."
+msgstr "הצג הודעה כאשר תזמונים מתווספים, מסתיימים או נמחקים ע\"י הממשק האחורי."
+
 msgctxt "#36240"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11385,6 +11597,10 @@ msgctxt "#36370"
 msgid "Select this option if your receiver is capable of decoding DTS-HD streams."
 msgstr "יש לבחור באפשרות זאת אם המקלט שלך מסוגל לקודד תזרימי DTS-HD."
 
+msgctxt "#36373"
+msgid "Configure how interface sounds are handled, such as menu navigation and important notifications."
+msgstr "הגדר איך צלילי הממשק יופעלו, כמו ניווט תפריט והודעות חשובות."
+
 msgctxt "#36374"
 msgid "No info available yet."
 msgstr "אין מידע זמין כעת."
@@ -11597,6 +11813,10 @@ msgctxt "#36524"
 msgid "Preferred mode"
 msgstr "מצב מועדף"
 
+msgctxt "#36525"
+msgid "Same as movie (autodetect)"
+msgstr "כמו הסרט (אוטומטית)"
+
 msgctxt "#36528"
 msgid "Select stereoscopic mode"
 msgstr "בחר מצב סטריאוסקופי"
@@ -11613,6 +11833,10 @@ msgctxt "#36531"
 msgid "Select alternate mode..."
 msgstr "בחר מצב חלופי..."
 
+msgctxt "#36532"
+msgid "Same as movie"
+msgstr "כמו הסרט"
+
 msgctxt "#36535"
 msgid "Stereoscopic mode of video"
 msgstr "מצב סטריאוסקופי של וידאו"
@@ -11681,6 +11905,18 @@ msgctxt "#37017"
 msgid "Dual audio output"
 msgstr "פלט אודיו כפול"
 
+msgctxt "#37020"
+msgid "Enable higher colour depth artwork"
+msgstr "הפעל עומק צבע גבוה לגרפיקה"
+
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "הגדר הגבלת רזולוצית GUI"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "נגן UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "האם ברצונך להפסיק את הניגון במכשיר המרוחק?"
index f65a543..3524dfb 100644 (file)
@@ -3233,6 +3233,10 @@ msgctxt "#33068"
 msgid "Background"
 msgstr "पृष्ठभूमि"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "मर्गें की संख्या"
+
 msgctxt "#35502"
 msgid "Name"
 msgstr "नाम"
index a9e9470..026fcfd 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Célkönyvtár választása"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Sztereó felkonvertálás"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Csatornák száma"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Bőbeszédű naplózás..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Dolby Digital átkódolás engedélyezése"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Médiatár tisztítása"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Hardvergyorsítás engedélyezése (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Többesszálú dekódolás engedélyezése"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Hang/Kép szinkron ehhez"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV felvételek"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Mappa csatorna ikonokkal"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Csatornák"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Alapértelmezett EPG ablak"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Csatorna ikonok"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Ez az esemény már felvétel alatt van."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Csatornaváltások megerősítése az OK billentyűvel"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Jelenlegi ikon"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Nincs ikon"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Ikon választás"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Ikon keresése"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Más/Ismeretlen"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Autózás"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitnesz &amp; Egészség"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Főzés"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Eredeti nyelv"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Fekete &amp; Fehér"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Kiadatlan"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Albumok keresése a %s használatával"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Filmelőzetes"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Rész lejátszása..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Médiamegosztás eltávolítása"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Egyedi felirat mappa"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Film és alternatív felirat mappa"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "kevert"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Felirat elhelyezkedése a képernyőn"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Rögzített"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Lejátszandó elem kiválasztása"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Fejezetek: %u - időtartam: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Blu-ray Lemez lejátszás sikertelen"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "A Blu-ray Lemez menüje nem támogatott"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Médiatár mód"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Csatornák száma"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Hangkimenet tulajdonságainak kiválasztása: [Rögzített] - kimenet beállítása egy megadott bitrátára és hangszóró konfigurációra minden esetben; [Legjobb Egyezés] - kimenet tulajdonságai mindig a lehető legközelebbi beállítást használja a forráshoz képest; [Optimális] - a kimeneti beállítások a lejátszás megkezdésekor kerülnek beállításra és nem változik ha forrás tulajdonságai megváltoznak."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Támogatott hangcsatornák számának megadása, vagy ahány analóg hangszóró csatlakoztatva van a rendszerhez. Ez a beállítás nincs hatással az adatként átadott hangfolyamra. Megjegyzés - SPDIF csak 2.0 csatornát támogat de át tud adni többcsatornás audió folyamot hangadatként."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "A 2 csatornára lekevert AC3 hangfolyamok erősítése."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Felkonvertálás engedélyezése a 2 csatornás sztereó hangfolyamhoz a hangfal beállításoknál megadott többcsatornás hangfalkonfigurációra."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Válassza ki ezt az opciót ha az erősítője képes az AC3 hangsáv dekódolására."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Engedélyezi az AMLogic hardvergyorsítást"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Többszálas dekódolás használata a hardveres gyorsítású dekódolás helyett. (kevésbé megbízható mint az alap egyszálú üzemmód)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Válassza ki mi történjen ha egy EPG elem kiválasztásra kerül: [Tartalom menü mutatása] megnyitja a tatalom menüt ahonnan további műveletek hajthatóak végre; [Váltás csatornára] azonnal átvált a hivatkozott csatornára; [Infó mutatása] megjeleníti a tartalominfókat és egyéb opciókat; [Felvétel] létrehoz egy felvételidőzítőt a kiválasztott elemre."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Felvétel"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Ez a beállítás akkor szükséges ha a hangkimenet csak a Dolby Digital 5.1-et támogatja, ezzel lehetővé válik egyéb többcsatornás hangfolyam átvitele is úgymint AAC5.1 vagy FLAC5.1 többcsatornásként. Megjegyzés - az átkódolás hangminőség csökkenést okozhat"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Sztereógráf mód (aktuális)"
@@ -12484,3 +12556,11 @@ msgstr "Nagyobb színmélységű képek használata"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "GUI felbontás limitálása"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP Lejátszó"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Megszakítja a lejátszást a távoli eszközön?"
index 7e0e3d5..e62d720 100644 (file)
@@ -8641,6 +8641,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Fjöldi rása"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index d23b03c..f718fc6 100644 (file)
@@ -6989,10 +6989,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motor"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Kebugaran &amp; Kesehatan"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Memasak"
@@ -7013,10 +7009,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Bahasa Asli"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Hitam &amp; Putih"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Tak Dipublikasi"
@@ -10145,6 +10137,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Jumlah saluran"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index ab8e971..b3e9a19 100644 (file)
@@ -7285,10 +7285,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobilismo"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; salute"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cucina"
@@ -7309,10 +7305,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Lingua Originale"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Bianco e nero"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Non pubblicato"
@@ -10581,6 +10573,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Numero di canali"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 5ff4ac0..eb246a7 100644 (file)
@@ -6981,10 +6981,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "クルマ"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "フィットネス &amp; 健康"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "クッキング"
@@ -7005,10 +7001,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "オリジナル言語"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "白黒"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "非公開"
@@ -10109,6 +10101,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media オーディオ 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "チャンネル数"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 847323f..aae3d96 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "대상 디렉터리 선택"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "스테레오 업믹스"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "채널수"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "자세한 정보 로깅"
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "돌비 디지털 트랜스코딩 사용"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "라이브러리 정리"
@@ -4133,6 +4141,10 @@ msgctxt "#13030"
 msgid "Waiting for server to wake up..."
 msgstr "서버가 깨어나기를 기다리는 중..."
 
+msgctxt "#13031"
+msgid "Extended wait for server to wake up..."
+msgstr "서버가 깨어나기를 기다리는 중 (연장)..."
+
 msgctxt "#13032"
 msgid "Waiting for services to launch..."
 msgstr "서비스 시작을 기다리는 중..."
@@ -4957,6 +4969,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "하드웨어 가속 허용 (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "프레임-멀티-스레드 디코딩 허용"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "A/V 동기 방식"
@@ -5981,6 +5997,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV 녹화"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "채널 아이콘 폴더"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "채널"
@@ -6169,6 +6189,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "기본 EPG 윈도우"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "채널 아이콘"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "이 이벤트는 이미 녹화중입니다."
@@ -6989,6 +7013,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "확인을 눌러 채널 전환 확인"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "현재 아이콘"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "아이콘 없음"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "아이콘 선택"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "아이콘 찾기"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "기타/알 수 없음"
@@ -7273,10 +7313,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "운전"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "피트니스와 건강"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "요리"
@@ -7297,10 +7333,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "원래 언어"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "흑백"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "미발표"
@@ -8217,6 +8249,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "%s로 앨범 검색중"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "영화 줄거리"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "부분 재생..."
@@ -8861,6 +8897,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "미디어 공유 제거"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "사용자 자막 폴더"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "영화 & 추가 자막 디렉터리"
@@ -9229,6 +9269,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "섞기"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "화면의 자막 위치"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "고정"
@@ -10225,6 +10269,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "재생 항목 선택"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "챕터: %u - 재생시간: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "블루레이 디스크 재생 실패"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "이 블루레이 디스크의 메뉴는 지원하지 않습니다."
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "라이브러리 모드"
@@ -10581,6 +10637,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "윈도우 미디어 오디오 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "채널수"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11513,6 +11573,14 @@ msgctxt "#36240"
 msgid "No info available yet."
 msgstr "아직 사용 가능한 정보가 없습니다."
 
+msgctxt "#36245"
+msgid "Execute the wakeup command every day at the given time."
+msgstr "매일 주어진 시각에 깨우기 명령을 실행합니다."
+
+msgctxt "#36246"
+msgid "When to execute the daily wakeup command."
+msgstr "매일 깨우기 명령을 실행할 시각."
+
 msgctxt "#36247"
 msgid "No info available yet."
 msgstr "아직 사용 가능한 정보가 없습니다."
@@ -11521,6 +11589,14 @@ msgctxt "#36248"
 msgid "Asks for a pin code to access parental locked channels. Channels can be marked as locked in the channels editor on the general tab. Parental locked channels can not be played or recorded without entering a pin code, and the EPG information is hidden for those channels."
 msgstr "자녀 보호 잠금이 된 채널에 접근할 때 비밀번호를 물어봅니다. 일반 채널 편집기의 일반 탭에서 잠금 표시를 할 수 습니다. 자녀 보호 잠금 채널은 비밀번호를 입력하지 않으면 시청 또는 녹화를 할 수 없으며 EPG 정보를 숨깁니다."
 
+msgctxt "#36249"
+msgid "Enter a new pin code to unlock parental locked channels."
+msgstr "자녀보호로 잠긴 채널을 해제하기 위한 새로운 비밀번호를 입력하세요."
+
+msgctxt "#36250"
+msgid "Ask for the pin code again when trying to access a parental locked channel and the code hasn't been asked for this duration. Defaults to 300 seconds."
+msgstr "자녀보호 채널에 접근할 때 비밀번호를 입력하여야 하고 입력 후 정해진 시간 동안 비밀번호를 다시 요청하지 않습니다. 기본값은 300초입니다."
+
 msgctxt "#36251"
 msgid "No info available yet."
 msgstr "아직 사용 가능한 정보가 없습니다."
@@ -11965,10 +12041,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "오디오 출력 특성을 선택합니다: [고정] - 항상 지정한 샘플레이트와 스피커 설정으로 출력합니다; [소스에 맞춤] - 출력 특성이 소스 특성에 가능한 가장 근접하게 항상 설정됩니다; [최적] - 재생이 시작될 때 출력 특성이 설정되고 소스의 특성이 변경되어도 바뀌지 않습니다."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "오디오 연결에서 지원하는 채널 수, 또는 아날로그 연결일 경우 스피커 수를 선택합니다. 주의 - SPDIF는 2.0 채널만 지원합니다. 그러나 패스스루를 지원하는 포맷을 사용하여 멀티채널 출력을 사용할 수 있습니다."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "2 채널로 다운믹스한 AC3 스트림을 증폭합니다."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "2 채널 오디오를  스피커 설정에서 지정한 오디오 채널 수 대로 업믹스합니다."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "리시버가 AC3 디코딩을 지원하면 선택합니다."
@@ -11995,7 +12079,7 @@ msgstr "리시버가 DTS-HD 디코딩을 지원하면 선택합니다."
 
 msgctxt "#36371"
 msgid "Select the device to be used for playback of audio that has been decoded such as mp3"
-msgstr "리시버가 mp3 등의 오디오를 지원하면 선택합니다."
+msgstr "mp3 같은 디코딩된 오디오 재생에 사용할 장치를 선택합니다."
 
 msgctxt "#36372"
 msgid "Select the device to be used for playback of encoded formats, these are any of the formats below in the 'capable receiver' options."
@@ -12197,6 +12281,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "AMLogic 디코더를 사용하여 비디오를 하드웨어 디코드합니다."
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "하드웨어 가속 디코딩 대신 프레임-멀티-스레드 디코딩을 사용합니다. (기본 단일 스레드 모드에 비해 신뢰도가 떨어집니다)"
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "EPG 항목을 선택했을 때의 동작입니다: [컨텍스트 메뉴 표시] 는 해당 항목에서 선택할 수 있는 추가 동작을 컨텍스트 메뉴로 보여줍니다; [채널로  변경] 관련 채널로 이동하여 시청합니다; [정보 보기] 줄거리와 추가 옵션을 포함하는 상세 정보를 보여줍니다; [녹화] 선택한 항목을 예약 녹화합니다."
@@ -12217,6 +12305,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "녹화"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "오디오 출력 연결이 돌비 디지털 5.1 다중 채널 오디오만 지원하는 경우 이 옵션을 선택하면 AAC 5.1, FLAC 5.1 같은 다중 채널 오디오를 5.1 서라운드 음향으로 들을 수 있습니다. 주의 - 트랜스코딩은 음질이 낮아질 수 있습니다."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "3D 모드 (현재)"
@@ -12424,3 +12516,11 @@ msgstr "고품질 아트워크 사용"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "GUI 해상도 제한 설정"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP 플레이어"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "원격 장치에서 재생을 중지하겠습니까?"
index 829231e..9f36a29 100644 (file)
@@ -1835,7 +1835,7 @@ msgstr "Pārslēgt mediju"
 
 msgctxt "#524"
 msgid "Select playlist"
-msgstr "Izvēlēties spēļsarakstu"
+msgstr "Atlasīt spēļsarakstu"
 
 msgctxt "#525"
 msgid "New playlist..."
@@ -1859,7 +1859,7 @@ msgstr "Kļūda: nosaukums dublējas"
 
 msgctxt "#530"
 msgid "Select genre"
-msgstr "Izvēlēties žanru"
+msgstr "Atlasīt žanru"
 
 msgctxt "#531"
 msgid "New genre"
@@ -3589,6 +3589,10 @@ msgctxt "#10524"
 msgid "Movie info"
 msgstr "Filmas info"
 
+msgctxt "#12000"
+msgid "Select dialogue"
+msgstr "Atlasiet dialogu"
+
 msgctxt "#12001"
 msgid "Music/Info"
 msgstr "Mūzika/Info"
@@ -6467,7 +6471,7 @@ msgstr "Šis saraksts satur izmaiņas"
 
 msgctxt "#19213"
 msgid "Select backend"
-msgstr "Izvēlēties aizmugursistēmu"
+msgstr "Atlasīt aizmugursistēmu"
 
 msgctxt "#19214"
 msgid "Enter a valid URL for the new channel"
@@ -6997,10 +7001,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Autosports"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness un veselība"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Ēdiena gatavošana"
@@ -7021,10 +7021,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Oriģinālvaloda"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Melns un balts"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Nepublicēts"
@@ -8043,7 +8039,7 @@ msgstr "Ielādē direktorijā info par sērijām"
 
 msgctxt "#20356"
 msgid "Select TV show:"
-msgstr "Izvēlēties TV pārraidi:"
+msgstr "Atlasīt TV pārraidi:"
 
 msgctxt "#20357"
 msgid "Enter the TV show name"
@@ -8125,6 +8121,18 @@ msgctxt "#20376"
 msgid "Original title"
 msgstr "Oriģinālnosaukums"
 
+msgctxt "#20379"
+msgid "Selected folder contains a single TV show"
+msgstr "Atlasītā mape satur vienu TV pārraidi"
+
+msgctxt "#20380"
+msgid "Exclude selected folder from scans"
+msgstr "Neiekļaut atlasīto mapi skenēšanā"
+
+msgctxt "#20383"
+msgid "Selected folder contains a single video"
+msgstr "Atlasītā mape satur vienu video"
+
 msgctxt "#20413"
 msgid "Get fanart"
 msgstr "Fanu māksla"
@@ -8145,6 +8153,14 @@ msgctxt "#20462"
 msgid "New tag..."
 msgstr "Jauns tags..."
 
+msgctxt "#20464"
+msgid "Select %s"
+msgstr "Atlasīts %s"
+
+msgctxt "#20466"
+msgid "Select movie set"
+msgstr "Atlasīt filmu kopumu"
+
 msgctxt "#21359"
 msgid "Add media share..."
 msgstr "Pievieno mediju koplietojumu..."
@@ -8205,6 +8221,10 @@ msgctxt "#21875"
 msgid "Country"
 msgstr "Valsts"
 
+msgctxt "#21890"
+msgid "Select artist"
+msgstr "Atlasīt izpildītāju"
+
 msgctxt "#22002"
 msgid "DNS suffix"
 msgstr "DNS suffikss"
@@ -8241,10 +8261,18 @@ msgctxt "#22036"
 msgid "Import karaoke titles..."
 msgstr "Importēt karaoke titrus..."
 
+msgctxt "#22037"
+msgid "Show song selector automatically"
+msgstr "Automātiski rādīt dziesmas izvēlētāju"
+
 msgctxt "#22038"
 msgid "Export karaoke titles..."
 msgstr "Eksportēt karaoke titrus..."
 
+msgctxt "#22079"
+msgid "Default select action"
+msgstr "Noklusētā atlasīšanas darbība"
+
 msgctxt "#22082"
 msgid "More..."
 msgstr "Vairāk..."
@@ -8299,7 +8327,7 @@ msgstr "Ievadiet meklējamo virkni"
 
 msgctxt "#25002"
 msgid "Select from all titles ..."
-msgstr "Izvēlēties no visiem nosaukumiem ..."
+msgstr "Atlasīt no visiem nosaukumiem ..."
 
 msgctxt "#33021"
 msgid "Precipitation"
@@ -8341,6 +8369,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanālu skaits"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -8425,6 +8457,46 @@ msgctxt "#36037"
 msgid "TV"
 msgstr "TV"
 
+msgctxt "#36109"
+msgid "Select the media window that XBMC displays on startup."
+msgstr "Atlasīt mediju logu, ko XBMC parāda palažoties."
+
+msgctxt "#36110"
+msgid "Select or disable the sound scheme used in the User Interface."
+msgstr "Atlasiet vai izslēdziet skaņas shēmu, ko izmanto lietotāja saskarne."
+
+msgctxt "#36115"
+msgid "Select the formats for temperature, time and date. The available options depend on the selected language."
+msgstr "Atlasiet temperatūras, laika un datuma formātu. Pieejamās opcijas ir atkarīgas no izvēlētās valodas."
+
+msgctxt "#36117"
+msgid "Select country location."
+msgstr "Atlasiet valsts atrašanās vietu."
+
+msgctxt "#36118"
+msgid "Select your current timezone."
+msgstr "Atlasiet savu pašreizējo laika joslu."
+
+msgctxt "#36119"
+msgid "Select the default audio track when different language tracks are available."
+msgstr "Atlasiet noklusēto audio celiņu, ja pieejami dažādi valodu celiņi."
+
+msgctxt "#36120"
+msgid "Select the default subtitles when different languages are available."
+msgstr "Atlasiet noklusētos subtitrus, ja pieejami subtitri dažādās valodās."
+
+msgctxt "#36130"
+msgid "Select the screensaver. XBMC will force the 'Dim' screensaver when fullscreen video playback is paused or a dialogue box is active."
+msgstr "Atlasiet ekrānsaudzētāju. XBMC forsēs ekrānsaudzētāju \"Izdzist\", ja pilnekrāna video būs pauze vai būs aktivizēts dialoga logs."
+
+msgctxt "#36132"
+msgid "Preview the selected screensaver."
+msgstr "Atlasītā ekrānsaudzētāja priekšapskate."
+
+msgctxt "#36152"
+msgid "Enable automatic playback of the next file in the list of the selected item."
+msgstr "Ieslēgt automātiskui nākamā faila atskaņošanu spēļsarakstā, kurā atlasīts ieraksts."
+
 msgctxt "#36167"
 msgid "Audio has to stay in sync, this can either be done by resampling, skipping/duplicating packets, or adjusting the clock if it gets out of sync too far."
 msgstr "Audio jāpaliek sinhronam. To var panākt ar pārsemplošanu, pakešu izlaišanu/dublēšanu vai arī, regulējot pulksteni, ja sinhronums zaudēts pārāk daudz."
@@ -8445,10 +8517,22 @@ msgctxt "#36250"
 msgid "Ask for the pin code again when trying to access a parental locked channel and the code hasn't been asked for this duration. Defaults to 300 seconds."
 msgstr "Atkārtoti prasīt pin kodu, piekļūstot vecāku slēgtajiem kanāliem, ja kods nav bijis prasīts šo laika sprīdi. Noklusējums ir 300 sekundes. "
 
+msgctxt "#36273"
+msgid "Select the visualisation that will be displayed while listening to music."
+msgstr "Atlasiet vizualizāciju, kuru attēlot, kamēr klausās mūziku."
+
+msgctxt "#36297"
+msgid "Select the font colour used during karoake."
+msgstr "Atlasiet fonta krāsu, ko lieto karaokes laikā."
+
 msgctxt "#36358"
 msgid "Test patterns for display hardware calibration."
 msgstr "Testē musturus ekrāna aparatūras kalibrēšanai."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Atlasiet, cik kanālus atbalsta audio savienojums vai cik skaļruņu ir pieslēgti ar analogajiem savienojumiem. Šo iestatījumu nepiemēro caurspēlējošam audio. Piezīme - SPDIF atbalsta tikai 2.0 kanālus, taču tik un tā spēj izvadīt daudzkanālu audio, izmantojot formātu, kuru atbalsta caurspēlēšanai."
+
 msgctxt "#36391"
 msgid "Turn debug logging on or off. Useful for troubleshooting."
 msgstr "Ieslēgt vai izslēgt atkļūdošanas reģistrēšanu. Noder problēmu risināšanai."
@@ -8473,6 +8557,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Ierakstīt"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Atlasiet šo, ja audio izejas savienojums atbalsta tikai daudzkanālu audio ar Dolby Digital 5.1 - tas ļaus daudzkanālu audio AAC5.1 vai FLAC5.1 formātā klausīties ar 5.1 visaptverošu skaņu. Piezīme - pārkodēšana var samazināt skaņas kvalitāti"
+
 msgctxt "#36502"
 msgid "None"
 msgstr "Nav"
@@ -8480,3 +8568,7 @@ msgstr "Nav"
 msgctxt "#36531"
 msgid "Select alternate mode..."
 msgstr "Izvēlēties alternatīvo režīmu..."
+
+msgctxt "#37016"
+msgid "Select this option if your receiver is capable of decoding E-AC3 streams."
+msgstr "Atlasiet šo opciju, ja Jūsu atskaņotājs spēj dekodēt E-AC3 straumes."
index af5852c..71ea89d 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Pasirinkite paskirties katalogą"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Kanalų skaičius"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Išsami registracija ..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Įjungti Dolby Digital perkodavimą"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Bibliotekos išvalymas"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Leisti aparatūros spartinimą (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Leisti kelių kadrų dekodavimą"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "A/V sinchronizavimo metodas"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV įrašai"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Aplankas su kanalų piktogramomis"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanalai"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Numatytasis EPG langas"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanalų piktogramos"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Šis įvykis jau įrašytas."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Patvirtinti kanalų jungiklius paspaudus 'OK'"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Dabartinė piktograma"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Nėra piktogramos"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Pasirinkti piktogramą"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Naršyti piktogramą"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Kitas/Nežinomas"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobiliai"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Sportas ir Sveikata"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Maisto gaminimas"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Originali kalba"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Juoda ir Balta"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Nepublikuota"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Nuskaityti 'albumai' naudojant %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Filmo siužetas"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Atkūrti dalį(-is)..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Pašalinti medijos dalinimą"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Pasirinktinis subtitrų aplankas"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Filmai ir pakaitinis subtitrų katalogas"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mišrus"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Subtitrų vieta ekrane"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fiksuotas"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Pasirinkite elementą atkūrimui"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Skyriai: %u - trukmė: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Blu-ray disko atkūrimas nepavyko"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Šio Blu-ray disko meniu nepalaikomas"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Bibliotekos režimas"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanalų skaičius"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Pasirinkti, kai garso išvesties savybės yra nustatytos: [Fiksuotas] - išėjimo savybės yra nustatyti į nurodytą garsiakalbių konfigūraciją [Geriausias atitikimas] - išėjimo savybės yra nustatytos kaip yra; [Optimizuotas] - išėjimo savybės buvo nustatyti atkūrimo pradžioje ir nesikeičia."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Pasirinkite kanalų skaičių kurie palaiko garso jungtis  norint sujungti analoginių jungčių skaičius. Ši nuostata netaikoma tranzitinio ryšio garsui. Pastaba - SPDIF palaiko tik 2,0 kanalus, tačiau vis tiek galima daugiakanalė garso išvestis."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Didinti AC3 srautus, kurie buvo downmixed į 2 kanalus."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Pasirinkite, kad upmixing iš 2 kanalų garso, garso kanalais gaunamą garsiakalbio konfigūraciją nurodytų skaičiais."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Pasirinkti šią parinktį, jei jūsų imtuvas gali dekoduoti AC3 srautus."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Įjungti, aparatinės įrangos video dekodavimas naudojant AMLogic dekoderį"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Naudokite kadro lygiagretų dekodavimą vietoj aparatūros paspartinto dekodavimo (mažiau patikimas nei numatytasis vienos gijos režimu)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Pasirinkite atitikimus, kai EPG elementas yra pasirinktas: [Rodyti kontekstinį menių] suaktyvins kontekstinį menių, kur jūs galite pasirinkti tolimensius veiksmus; [Perjungti kanalą], iš karto paleis atitinkamą kanalą; [Rodyti informaciją] bus rodoma siužetų išsami informacija, pasirinktinai tolimesni variantai; [Record] sukurs pasirinkto elemento įrašymo laikmatį."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Įrašas"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Pasirinkite, - jei iš garso jungties  palaikomas tik daugiakanalis garsas pvz.: kaip Dolby Digital 5.1, tai veikia kaip daugiakanalis garsas pvz.: AAC5.1 ar/arba FLAC5.1 ir galima išklausyti kaip  5.1 erdvinį garsą. Pastaba - perkodavimas gali sukelti garso kokybės trugdžius, garso srauto mažėjimą ir t.t.."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Stereoskopinis režimas (dabartinis)"
@@ -12484,3 +12556,11 @@ msgstr "Įjungti didesnį spalvų gylį 'artwork'"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Nustatyti GUI raiškos ribas(-ą)"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP grotuvas"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Ar norite sustabdyti nuotolinio prietaiso atkūrimą?"
index c3d39a3..d8bd2e1 100644 (file)
@@ -8221,6 +8221,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Број на канали"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 8bcf014..aca935e 100644 (file)
@@ -1565,6 +1565,10 @@ msgctxt "#33081"
 msgid "This file is stacked, select the part you want to play from."
 msgstr "Fail ini disusun tindan. Pilih bahagian yang anda ingin mainkan."
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Jumlah saluran"
+
 msgctxt "#34122"
 msgid "Always"
 msgstr "Sentiasa"
index 0d4bc7e..ec93b56 100644 (file)
@@ -5961,6 +5961,10 @@ msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Daħħal Search String"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Numru ta' kanali"
+
 msgctxt "#34123"
 msgid "Never"
 msgstr "Qatt"
index 3bde209..d23e4ca 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Velg destinasjonsmappe"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo oppmiks"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Antall kanaler"
@@ -1185,10 +1189,18 @@ msgctxt "#336"
 msgid "Framerate conversion"
 msgstr "Konverter bildefrekvens"
 
+msgctxt "#337"
+msgid "Output configuration"
+msgstr "Konfigurer utgangssignal"
+
 msgctxt "#338"
 msgid "Fixed"
 msgstr "Låst"
 
+msgctxt "#339"
+msgid "Optimized"
+msgstr "Optimert"
+
 msgctxt "#340"
 msgid "Various artists"
 msgstr "Diverse artister"
@@ -1213,10 +1225,18 @@ msgctxt "#345"
 msgid "Year"
 msgstr "År"
 
+msgctxt "#346"
+msgid "Normalize levels on downmix"
+msgstr "Normaliser nivåer ved nedmiks"
+
 msgctxt "#347"
 msgid "DTS-HD capable receiver"
 msgstr "Receiver kan ta imot DTS-HD"
 
+msgctxt "#348"
+msgid "Enable passthrough"
+msgstr "Aktiver passthrough"
+
 msgctxt "#349"
 msgid "TrueHD capable receiver"
 msgstr "Receiver kan ta imot TrueHD"
@@ -1493,6 +1513,14 @@ msgctxt "#419"
 msgid "High"
 msgstr "Høy"
 
+msgctxt "#420"
+msgid "Best Match"
+msgstr "Beste treff"
+
+msgctxt "#421"
+msgid "Keep audio device alive"
+msgstr "Hold lydenheten i live"
+
 msgctxt "#422"
 msgid "Delete album info"
 msgstr "Slett albuminformasjon"
@@ -1637,6 +1665,10 @@ msgctxt "#457"
 msgid "Switch view"
 msgstr "Skift visning"
 
+msgctxt "#458"
+msgid "Limit sampling rate (kHz)"
+msgstr "Begrens samlingsraten (kHz)"
+
 msgctxt "#459"
 msgid "Subs"
 msgstr "Undertekster"
@@ -2253,6 +2285,10 @@ msgctxt "#636"
 msgid "Custom"
 msgstr "Egendefinert"
 
+msgctxt "#637"
+msgid "ReplayGain"
+msgstr "ReplayGain"
+
 msgctxt "#638"
 msgid "ReplayGain volume adjustments"
 msgstr "Replay Gain-modus"
@@ -2265,6 +2301,18 @@ msgctxt "#640"
 msgid "Use album levels"
 msgstr "Bruk albumnivåer"
 
+msgctxt "#641"
+msgid "PreAmp Level - ReplayGained files"
+msgstr "PreAmp-nivå - Filer med ReplayGain"
+
+msgctxt "#642"
+msgid "PreAmp Level - Non ReplayGained files"
+msgstr "PreAmp-nivå - Filer uten ReplayGain"
+
+msgctxt "#643"
+msgid "Avoid clipping on ReplayGained files"
+msgstr "Unngå klipping i filer med Replay Gain"
+
 msgctxt "#644"
 msgid "Crop black bars"
 msgstr "Fjern sorte felt"
@@ -2357,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Omstendig logging..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Aktiver Dolby Digital transkoding"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Renser bibliotek"
@@ -2901,6 +2953,10 @@ msgctxt "#1043"
 msgid "Program Add-ons"
 msgstr "Programtillegg"
 
+msgctxt "#1044"
+msgid "Set plug-in thumb"
+msgstr "Fastsett miniatyrutvidelse"
+
 msgctxt "#1045"
 msgid "Add-on settings"
 msgstr "Innstillinger for tillegg"
@@ -3509,6 +3565,10 @@ msgctxt "#10046"
 msgid "No categories available"
 msgstr "Ingen kategorier tilgjengelig"
 
+msgctxt "#10047"
+msgid "Try changing the setting level to see additional categories and settings."
+msgstr "Forsøk å bytte innstillingsnivået for å gjøre ytterligere kategorier og innstillinger synlige."
+
 msgctxt "#10100"
 msgid "Yes/No dialogue"
 msgstr "Ja/Nei dialog"
@@ -4501,6 +4561,10 @@ msgctxt "#13318"
 msgid "Recursive slideshow"
 msgstr "Rekursiv lysbildefremvisning"
 
+msgctxt "#13319"
+msgid "Randomise"
+msgstr "Gjør tilfeldig"
+
 msgctxt "#13320"
 msgid "Stereo"
 msgstr "Stereo"
@@ -4905,6 +4969,10 @@ msgctxt "#13436"
 msgid "Allow hardware acceleration (libstagefright)"
 msgstr "Tillat maskinvareakselerasjon (libstagefright)"
 
+msgctxt "#13437"
+msgid "Prefer VDPAU Video Mixer"
+msgstr "Foretrekk VDPAU-videomikser "
+
 msgctxt "#13438"
 msgid "Allow hardware acceleration (amcodec)"
 msgstr "Tillat maskinvareakselerasjon (amcodec)"
@@ -4929,6 +4997,10 @@ msgctxt "#13503"
 msgid "Video clock (Resample audio)"
 msgstr "Videoklokking (resample lyd)"
 
+msgctxt "#13504"
+msgid "Maximum speedup/slowdown amount (%)"
+msgstr "Maksimum fremskyndelses-/forsinkelsesmengde (%)"
+
 msgctxt "#13505"
 msgid "Resample quality"
 msgstr "Resamplingskvalitet"
@@ -4993,6 +5065,10 @@ msgctxt "#13553"
 msgid "%.1f Seconds"
 msgstr "%.1f sekunder"
 
+msgctxt "#13554"
+msgid "%d Minute"
+msgstr "%d minutt"
+
 msgctxt "#13555"
 msgid "%d Minutes"
 msgstr "%d minutter"
@@ -5397,6 +5473,18 @@ msgctxt "#14100"
 msgid "Stop ripping CD"
 msgstr "Stop CD-ripping"
 
+msgctxt "#15012"
+msgid "Unavailable source"
+msgstr "Utilgjengelig kilde"
+
+msgctxt "#15013"
+msgid "What would you like to do with media items from %s"
+msgstr "Hva ønsker du å gjøre med medie-element fra %s"
+
+msgctxt "#15014"
+msgid "Keep"
+msgstr "Behold"
+
 msgctxt "#15015"
 msgid "Remove"
 msgstr "Fjern"
@@ -5617,6 +5705,10 @@ msgctxt "#16031"
 msgid "No matching songs in the library."
 msgstr "Ingen samsvarende låter i bibliotek."
 
+msgctxt "#16032"
+msgid "Could not initialise database."
+msgstr "Kunne ikke initialisere database."
+
 msgctxt "#16033"
 msgid "Could not open database."
 msgstr "Kunne ikke åpne databasen."
@@ -5677,6 +5769,10 @@ msgctxt "#16105"
 msgid "Edit title"
 msgstr "Rediger tittel"
 
+msgctxt "#16106"
+msgid "Manage..."
+msgstr "Administrere..."
+
 msgctxt "#16107"
 msgid "Edit sort title"
 msgstr "Rediger sorter tittel"
@@ -5769,6 +5865,10 @@ msgctxt "#16314"
 msgid "Inverse Telecine"
 msgstr "Omvendt telecine"
 
+msgctxt "#16315"
+msgid "Lanczos3 optimised"
+msgstr "Lanczos3 optimert"
+
 msgctxt "#16316"
 msgid "Auto"
 msgstr "Automatisk"
@@ -5797,10 +5897,22 @@ msgctxt "#16322"
 msgid "Spline36"
 msgstr "Spline36"
 
+msgctxt "#16323"
+msgid "Spline36 optimised"
+msgstr "Spline36 optimert"
+
 msgctxt "#16324"
 msgid "Software Blend"
 msgstr "Software Blend"
 
+msgctxt "#16325"
+msgid "VDPAU - Bob"
+msgstr "VDPAU - Bob"
+
+msgctxt "#16326"
+msgid "DXVA-HD"
+msgstr "DXVA-HD"
+
 msgctxt "#16400"
 msgid "Post-processing"
 msgstr "Post-prosessering"
@@ -5893,6 +6005,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV-opptak"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Mappe med kanalikoner"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanaler"
@@ -6081,6 +6197,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Standard EPG-vindu"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanalikoner"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Denne hendelsen blir allerede tatt opp"
@@ -6205,6 +6325,18 @@ msgctxt "#19098"
 msgid "Warning"
 msgstr "Advarsel"
 
+msgctxt "#19099"
+msgid "Service"
+msgstr "Tjeneste"
+
+msgctxt "#19100"
+msgid "Mux"
+msgstr "Mux"
+
+msgctxt "#19101"
+msgid "Provider"
+msgstr "Tilbyder"
+
 msgctxt "#19102"
 msgid "Please switch to another channel."
 msgstr "Vennligst bytt til en annen kanal"
@@ -6681,6 +6813,10 @@ msgctxt "#19229"
 msgid "Close channel OSD after switching channels"
 msgstr "Lukk kanal-OSD etter kanalbytte"
 
+msgctxt "#19230"
+msgid "Prevent EPG updates during playback"
+msgstr "Hindre EPG-oppdateringer under avspilling"
+
 msgctxt "#19231"
 msgid "Always use the channel order from the backend(s)"
 msgstr "Bruk alltid kanalrekkefølge fra kulisseklient(er)"
@@ -6695,7 +6831,7 @@ msgstr "Vis notifikasjon ved tidsuroppdateringer"
 
 msgctxt "#19234"
 msgid "Use backend channels numbers (only works with 1 enabled PVR Add-on)"
-msgstr "Bruk kanalnumre fra backend (fungerer kun med 1 aktivert PVR add-on)"
+msgstr "Bruk kanalnumre fra kulisseklient (fungerer kun med 1 aktivert PVR-tillegg)"
 
 msgctxt "#19235"
 msgid "PVR manager is starting up"
@@ -6725,6 +6861,10 @@ msgctxt "#19241"
 msgid "The PVR manager has been enabled without any"
 msgstr "PVR-behandleren er blitt aktivert uten et"
 
+msgctxt "#19242"
+msgid "enabled PVR Add-on. Enable at least one Add-on"
+msgstr "aktiver PVR-tillegg. Aktiver minst ett tillegg"
+
 msgctxt "#19243"
 msgid "in order to use the PVR functionality."
 msgstr "for å bruke PVR-funksjonaliteten."
@@ -6845,6 +6985,10 @@ msgctxt "#19272"
 msgid "You need a tuner, backend software, and an"
 msgstr "Du trenger en tuner, kulisseklientprogramvare, og et"
 
+msgctxt "#19273"
+msgid "Add-on for the backend to be able to use PVR."
+msgstr "Tillegg for at kulisseklienten skal kunne bruke PVR"
+
 msgctxt "#19274"
 msgid "Please visit xbmc.org/pvr to learn more."
 msgstr "Vennligst besøk xbmc.org/pvr for mer informasjon."
@@ -6877,6 +7021,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Bekreft kanalbytte ved å trykke OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Gjeldende ikon"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Intet ikon"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Velg ikon"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Bla etter ikon"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Annet/Ukjent"
@@ -7161,10 +7321,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motor"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Helse &amp; velvære"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Matlaging"
@@ -7185,10 +7341,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Orginalspråk"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Sort &amp; Hvitt"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Upublisert"
@@ -7965,6 +8117,10 @@ msgctxt "#20199"
 msgid "Downloading artist info failed"
 msgstr "Nedlasting av artistinformasjon mislyktes"
 
+msgctxt "#20220"
+msgid "Override song tags with online information"
+msgstr "Tilsidesett sangknagg med nettinfomasjon"
+
 msgctxt "#20240"
 msgid "Android music"
 msgstr "Androidmusikk"
@@ -8097,6 +8253,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Skanner album ved hjelp av %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Filmhandling"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Spill av del..."
@@ -8625,6 +8785,10 @@ msgctxt "#20455"
 msgid "Listeners"
 msgstr "Lyttere"
 
+msgctxt "#20456"
+msgid "Flatten library hierarchy"
+msgstr "Flat ut bibliotekshierarkiet"
+
 msgctxt "#20457"
 msgid "Movie set"
 msgstr "Filmsamling"
@@ -8737,6 +8901,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Fjern delt mediaressurs"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Egendefinert undertekstmappe"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Film & alternativ mappe for undertekst"
@@ -9105,6 +9273,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mikset"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Undertekstplassering på skjermen"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Låst"
@@ -9137,6 +9309,10 @@ msgctxt "#21469"
 msgid "%s to %s"
 msgstr "%s til %s"
 
+msgctxt "#21600"
+msgid "Prefer external subtitles"
+msgstr "Foretrekk eksterne undertekster"
+
 msgctxt "#21601"
 msgid "Prefer external subtitles to internal ones"
 msgstr "Foretrekk eksterne undertekster fremfor interne"
@@ -9825,18 +10001,30 @@ msgctxt "#24043"
 msgid "Available Updates"
 msgstr "Tilgjengelige oppdateringer"
 
+msgctxt "#24044"
+msgid "Dependencies not met. Please contact Add-on author."
+msgstr "Avhangigheter er ikke tilfredstilt. Vennligst kontakt tilleggsforfatteren."
+
 msgctxt "#24045"
 msgid "Add-on does not have the correct structure"
 msgstr "Tillegg har ikke den korrekte strukturen"
 
+msgctxt "#24046"
+msgid "%s is used by the following installed Add-on(s)"
+msgstr "%s er benyttet av følgende installerte tillegg(er)"
+
 msgctxt "#24047"
 msgid "This Add-on cannot be uninstalled"
-msgstr "Dette tillegget kan ikke fjernes"
+msgstr "Dette tillegget kan ikke avinstalleres"
 
 msgctxt "#24048"
 msgid "Rollback"
 msgstr "Tilbakestill"
 
+msgctxt "#24049"
+msgid "Incompatible"
+msgstr "Uforenelig"
+
 msgctxt "#24050"
 msgid "Available Add-ons"
 msgstr "Tilgjengelige tillegg"
@@ -9953,6 +10141,10 @@ msgctxt "#24095"
 msgid "(blacklisted)"
 msgstr "(svartelistet)"
 
+msgctxt "#24096"
+msgid "Add-on is incompatible or has been marked broken in repository."
+msgstr "Tillegg er uforenelig eller har blitt markert ødelagt i pakkebrønn."
+
 msgctxt "#24097"
 msgid "Would you like to disable it on your system?"
 msgstr "Ønsker du å deaktivere det på ditt system?"
@@ -9981,10 +10173,18 @@ msgctxt "#24103"
 msgid "Skin is missing some files"
 msgstr "Skallet mangler noen filer"
 
+msgctxt "#24104"
+msgid "Add-on is incompatible due to unmet dependencies."
+msgstr "Tillegg er uforenelig på grunn av uinnfridde avhengigheter."
+
 msgctxt "#24105"
 msgid "Pause when searching for subtitles"
 msgstr "Sett på pause ved søk etter undertekster"
 
+msgctxt "#24106"
+msgid "If not saved to movie folder subtitles will be downloaded to custom subtitle folder"
+msgstr "Hvis undertitler ikke blir lagret i filmmappe så vil de lastes ned til egendefinert undertittelmappe"
+
 msgctxt "#24107"
 msgid "Searching for subtitles ..."
 msgstr "Søker etter undertekster ..."
@@ -10001,10 +10201,46 @@ msgctxt "#24110"
 msgid "Downloading subtitles ..."
 msgstr "Laster ned undertekster ..."
 
+msgctxt "#24111"
+msgid "Languages to download subtitles for"
+msgstr "Språk å laste ned undertitler for"
+
+msgctxt "#24112"
+msgid "Set languages to use when searching for subtitles. Not all subtitle services will use all languages."
+msgstr "Oppgi språkene som skal brukes ved undertekstsøk. Ikke alle underteksttjenestene har alle språk."
+
 msgctxt "#24113"
 msgid "Failed to download subtitle"
 msgstr "Kunne ikke laste ned undertekst"
 
+msgctxt "#24114"
+msgid "No subtitle services installed"
+msgstr "Ingen undertitteltjeneste er installert"
+
+msgctxt "#24115"
+msgid "Save subtitles to movie folder"
+msgstr "Lagre undertekster til filmmappe"
+
+msgctxt "#24116"
+msgid "Default TV Service"
+msgstr "Standard TV-tjeneste"
+
+msgctxt "#24117"
+msgid "Select service that will be used as default to search for TV Show subtitles"
+msgstr "Velg tjeneste som vil bli brukt som standard for å søke etter TV-serieundertekster"
+
+msgctxt "#24118"
+msgid "Default Movie Service"
+msgstr "Standard filmtjeneste"
+
+msgctxt "#24119"
+msgid "Select service that will be used as default to search for Movie subtitles"
+msgstr "Velg tjenesten som vil bli brukt som standard for å søke etter filmundertekster"
+
+msgctxt "#24120"
+msgid "Manual search string"
+msgstr "Manuell søkestreng"
+
 msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Skriv inn søketekst"
@@ -10037,6 +10273,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Velg avspillingsoppføring"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Kapittel: %u - varighet: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Avspilling av Blu-ray plate mislyktes"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Menyen til denne Blu-ray platen er ikke støttet"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Biblioteksmodus"
@@ -10113,6 +10361,10 @@ msgctxt "#33016"
 msgid "Clips"
 msgstr "Klipp"
 
+msgctxt "#33017"
+msgid "Restart plug-in to enable"
+msgstr "Start utvidelse på nytt for å aktivere"
+
 msgctxt "#33018"
 msgid "Tonight"
 msgstr "I kveld"
@@ -10389,6 +10641,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Antall kanaler"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10445,6 +10701,26 @@ msgctxt "#34123"
 msgid "Never"
 msgstr "Aldri"
 
+msgctxt "#34124"
+msgid "44.1"
+msgstr "44,1"
+
+msgctxt "#34125"
+msgid "48.0"
+msgstr "48,0"
+
+msgctxt "#34126"
+msgid "88.2"
+msgstr "88,2"
+
+msgctxt "#34127"
+msgid "96.0"
+msgstr "96,0"
+
+msgctxt "#34128"
+msgid "192.0"
+msgstr "192,0"
+
 msgctxt "#34201"
 msgid "Can't find a next item to play"
 msgstr "Kan ikke finne neste oppføring å spille av"
@@ -10557,6 +10833,10 @@ msgctxt "#35102"
 msgid "Disable joystick when this device is present"
 msgstr "Deaktiver styrepinne når denne enheten er tilkoblet"
 
+msgctxt "#35103"
+msgid "Enable system keys in fullscreen"
+msgstr "Aktiver systemtaster i fullskjerm"
+
 msgctxt "#35500"
 msgid "Location"
 msgstr "Lokasjon"
@@ -11005,6 +11285,10 @@ msgctxt "#36167"
 msgid "Audio has to stay in sync, this can either be done by resampling, skipping/duplicating packets, or adjusting the clock if it gets out of sync too far."
 msgstr "Lyd må være synkronisert, dette kan enten gjøres ved å gjensample, hoppe over/duplisere pakker, eller ved å juster klokken hvis lyden havner for mye i utakt."
 
+msgctxt "#36168"
+msgid "Maximum video speed adjust to match actual screen refresh rate."
+msgstr "Avpass maksimum videohastighetjustering til skjermoppdateringsfrekvens."
+
 msgctxt "#36170"
 msgid "Allow video player to ignoring aspect ratio by a certain amount to fill a larger amount of the screen with video."
 msgstr "Tillat videospilleren til en viss grad å ignorere en del av formatforholdet for å kunne fylle en større del av skjermen."
@@ -11013,6 +11297,10 @@ msgctxt "#36171"
 msgid "Select the zoom level that 4:3 videos are shown on widescreen displays."
 msgstr "Velg hvordan 4:3-videoer skaleres på widescreen-skjermer."
 
+msgctxt "#36172"
+msgid "VDPAU studio level conversion provides a way for advanced applications like XBMC to influence the colour space conversion."
+msgstr "VDPAU studionivåkonvertering gjør det mulig for avanserte programmer som XBMC å påvirke fargeromkonverteringen."
+
 msgctxt "#36173"
 msgid "No info available yet."
 msgstr "Ingen informasjon tilgjengelig enda."
@@ -11197,6 +11485,10 @@ msgctxt "#36219"
 msgid "Default EPG window to show. Defaults to Timeline."
 msgstr "Viser standard EPG-vindu. Bruker tidslinjevisning som standard."
 
+msgctxt "#36220"
+msgid "Number of days of EPG data to import from backends. Defaults to 3 days."
+msgstr "Antall dager med EPG-informasjon som skal hentes fra kulisseklienter. Standarden er 3 dager."
+
 msgctxt "#36221"
 msgid "Time between EPG data imports from backends. Defaults to 120 minutes."
 msgstr "Tid mellom datahentinger fra kulisseklienten. Standarden er 120 minutter."
@@ -11231,7 +11523,7 @@ msgstr "Vis den sist sette kanalen hvis det byttes til Live-TV."
 
 msgctxt "#36229"
 msgid "Display signal quality information in the codec information window (if supported by the Add-on and backend)."
-msgstr "Vis informasjon om signalkvaliteten i kodekinformasjonsvinduet (hvis støttet av tillegget og tjenerdelen)"
+msgstr "Vis informasjon om signalkvaliteten i kodekinformasjonsvinduet (hvis støttet av tillegget og kulisseklient)"
 
 msgctxt "#36230"
 msgid "No info available yet."
@@ -11255,19 +11547,19 @@ msgstr "Varigheten på opptakene når opptaksknappen trykkes, eller når et nytt
 
 msgctxt "#36235"
 msgid "Priority of the recording. Higher number means higher priority. Defaults to 50. Not supported by all Add-ons and backends."
-msgstr "Opptaksprioritet. Et høyere tall betyr en høyere prioritet. Standarden er 50. Ikke støttet av alle tillegg og tjenerdeler."
+msgstr "Opptaksprioritet. Et høyere tall betyr en høyere prioritet. Standarden er 50. Ikke støttet av alle tillegg og kulisseklienter."
 
 msgctxt "#36236"
 msgid "Delete recording after this time. Defaults to 99 days. Not supported by all Add-ons and backends."
-msgstr "Slett opptak etter denne perioden. Standarden er 99 dager. Ikke støttet av alle tillegg og tjenerdeler."
+msgstr "Slett opptak etter denne perioden. Standarden er 99 dager. Ikke støttet av alle tillegg og kulisseklienter."
 
 msgctxt "#36237"
 msgid "Start recordings before the actual time. Defaults to 2 minutes. Not supported by all Add-ons and backends."
-msgstr "Start opptaket før det fastsatte tidspunktet. Standarden er 2 minutter. Ikke støttet av alle tillegg og tjenerdeler."
+msgstr "Start opptaket før det fastsatte tidspunktet. Standarden er 2 minutter. Ikke støttet av alle tillegg og kulisseklienter."
 
 msgctxt "#36238"
 msgid "End recordings after the actual time. Defaults to 10 minutes. Not supported by all Add-ons and backends."
-msgstr "Avslutt opptak etter det fastsatte tidspunktet.. Standarden er 10 minutter. Ikke støttet av alle tillegg eller tjenerdeler."
+msgstr "Avslutt opptak etter det fastsatte tidspunktet. Standarden er 10 minutter. Ikke støttet av alle tillegg eller kulisseklienter."
 
 msgctxt "#36239"
 msgid "Display a notification when timers are added, finished or removed by the backend."
@@ -11381,6 +11673,10 @@ msgctxt "#36266"
 msgid "When songs are added to a playlist they are queued instead of playback starting immediately."
 msgstr "Når låter blir lagt til en spilleliste blir de lagt i kø istedenfor å spilles av med en gang."
 
+msgctxt "#36267"
+msgid "XBMC will read the ReplayGain information encoded in your audio files by a program such as MP3Gain and normalise the sound levels accordingly."
+msgstr "XBMC vil lese ReplayGain-informasjonen som er innkoded i dine lydfiler ved å benytte et program slik som MP3Gain og deretter normalisere lydnivået."
+
 msgctxt "#36268"
 msgid "Default is 89dB per standard. Change with caution."
 msgstr "Standard er 89dB. Utvis forsiktighet ved endring."
@@ -11401,6 +11697,10 @@ msgctxt "#36272"
 msgid "Allow crassfading to occur when both tracks are from the same album."
 msgstr "Tillat at det tones ut mellom spor som er fra det samme albumet."
 
+msgctxt "#36273"
+msgid "Select the visualisation that will be displayed while listening to music."
+msgstr "Velg visualiseringen som vil bli vist mens musikk spilles av."
+
 msgctxt "#36274"
 msgid "Read the tag information from song files. For large directories this can slow down read time, especially over a network."
 msgstr "Les knagginformasjonen fra låtfiler. For store mapper kan dette øke lesetiden betraktelig, spesielt over et nettverk."
@@ -11591,7 +11891,7 @@ msgstr "Ingen informasjon tilgjengelig enda."
 
 msgctxt "#36321"
 msgid "Display name of the XBMC installation when using various network services."
-msgstr "Vis navnet til XBMC-innstallasjonen når forskjellige nettverktjenere benyttes."
+msgstr "Vis navnet til XBMC-installasjonen når forskjellige nettverktjenere benyttes."
 
 msgctxt "#36322"
 msgid "No info available yet."
@@ -11721,6 +12021,10 @@ msgctxt "#36353"
 msgid "No info available yet."
 msgstr "Ingen informasjon tilgjengelig enda."
 
+msgctxt "#36354"
+msgid "The main benefit is for multi-screen configurations, so XBMC can be used without automatically minimising other applications. Uses a bit more resources and playback may be slightly less smooth."
+msgstr "Hovedfordelen er for flerskjermskonfigurasjoner, slik at XMBC kan brukes uten å automatisk minimere andre applikasjoner. Dette bruker litt flere ressurser og kan resultere i litt ujevn avspilling."
+
 msgctxt "#36355"
 msgid "In a multi-screen configuration, the screens where XBMC is not displayed are blacked out."
 msgstr "I en flerskjermskonfigurasjon blir skjermene hvor XBMC ikke vises mørklagt."
@@ -11757,6 +12061,10 @@ msgctxt "#36366"
 msgid "Select this option if your receiver is capable of decoding DTS streams."
 msgstr "Velg dette alternativet hvis receiveren din er i stand til å utkode DTS-strømmer."
 
+msgctxt "#36368"
+msgid "Select to enable the passthrough audio options for playback of encoded audio such as Dolby Digital."
+msgstr "Velg for å aktivere passthrough-lydalternativene for avspilling av innkoded lyd slik som Dolby Digital."
+
 msgctxt "#36369"
 msgid "Select this option if your receiver is capable of decoding TrueHD streams."
 msgstr "Velg dette alternativet hvis receiveren din er i stand til å utkode TrueHD-strømmer."
@@ -11961,14 +12269,38 @@ msgctxt "#36420"
 msgid "No info available yet."
 msgstr "Ingen informasjon tilgjengelig enda."
 
+msgctxt "#36421"
+msgid "Bypassing VDPAU mixer saves resources on low power systems but slightly reduces picture quality"
+msgstr "Å gå utenom VDPAU-mikser sparer ressurser på svake systemer, men gjør bildekvaliteten litt dårligere"
+
+msgctxt "#36422"
+msgid "Enable hardware video decode using AMLogic decoder"
+msgstr "Aktiver maskinvareutkoding ved bruk av AMLogic-utkoder"
+
+msgctxt "#36425"
+msgid "Show context menu"
+msgstr "Vis kontekstmeny"
+
 msgctxt "#36426"
 msgid "Switch to channel"
 msgstr "Bytt til kanal"
 
+msgctxt "#36427"
+msgid "Show information"
+msgstr "Vis informasjon"
+
 msgctxt "#36428"
 msgid "Record"
 msgstr "Opptak"
 
+msgctxt "#36500"
+msgid "Stereoscopic mode (current)"
+msgstr "Stereoskopisk mudus (gjeldende)"
+
+msgctxt "#36501"
+msgid "Stereoscopic mode"
+msgstr "Stereoskopisk modus"
+
 msgctxt "#36502"
 msgid "None"
 msgstr "Ingen"
@@ -11981,10 +12313,30 @@ msgctxt "#36504"
 msgid "Side by side"
 msgstr "Side ved side"
 
+msgctxt "#36505"
+msgid "Anaglyph Red/Cyan"
+msgstr "Anaglyf Rød/Cyan"
+
+msgctxt "#36506"
+msgid "Anaglyph Green/Magenta"
+msgstr "Anaglyf Grønn/Magenta"
+
+msgctxt "#36507"
+msgid "Interlaced"
+msgstr "Sammenflettet"
+
 msgctxt "#36508"
 msgid "Hardware Based"
 msgstr "Maskinvare-basert"
 
+msgctxt "#36509"
+msgid "Monoscopic - 2D"
+msgstr "Monoskopisk - 2D"
+
+msgctxt "#36520"
+msgid "Playback mode of stereoscopic videos"
+msgstr "Avspillingsmodus for stereoskopiske videoer"
+
 msgctxt "#36521"
 msgid "Ask me"
 msgstr "Spør meg"
@@ -12001,6 +12353,18 @@ msgctxt "#36525"
 msgid "Same as movie (autodetect)"
 msgstr "Same som film (auto-oppdaget)"
 
+msgctxt "#36526"
+msgid "Disable stereoscopic mode when playback is stopped"
+msgstr "Deaktiver stereoskopisk modus når avspillingen er stoppet"
+
+msgctxt "#36527"
+msgid "This video is stereoscopic. Select playback mode"
+msgstr "Denne videoen er stereoskopisk - Velg avspillingsmodus"
+
+msgctxt "#36528"
+msgid "Select stereoscopic mode"
+msgstr "Velg stereoskopisk modus"
+
 msgctxt "#36529"
 msgid "Mono (2D)"
 msgstr "Mono (2D)"
@@ -12017,6 +12381,14 @@ msgctxt "#36532"
 msgid "Same as movie"
 msgstr "Same som film"
 
+msgctxt "#36535"
+msgid "Stereoscopic mode of video"
+msgstr "Videoens stereoskopiske modus"
+
+msgctxt "#36536"
+msgid "Stereoscopic mode inverted"
+msgstr "Invertert stereoskopisk modus"
+
 msgctxt "#36537"
 msgid "No info available yet."
 msgstr "Ingen informasjon tilgjengelig enda."
@@ -12037,10 +12409,26 @@ msgctxt "#36541"
 msgid "Allows volume control from AirPlay clients."
 msgstr "Tillat volumkontroll fra AirPlay-enheter"
 
+msgctxt "#36542"
+msgid "Output to both analogue (headphones) and HDMI"
+msgstr "Send utgangssignal til både analoge (hodetelefoner) og HDMI"
+
+msgctxt "#36543"
+msgid "Enable this to make dialogue louder compared to background sounds when downmixing multichannel audio"
+msgstr "Aktiver denne for å gjøre dialoger høyere sammenlignet med bakgrunnslyder når flerkanalslyd nedmikses"
+
 msgctxt "#36544"
 msgid "Enable hardware decoding of video files."
 msgstr "Aktiver maskinvareavkoding av videofiler."
 
+msgctxt "#36545"
+msgid "Subtitle stereoscopic depth"
+msgstr "Stereoskopisk dybde på undertekster"
+
+msgctxt "#36546"
+msgid "Sets the visual depth of subtitles for stereoscopic videos. The higher the value, the closer the subtitles will appear to the viewer."
+msgstr "Fastsetter den visuelle dybden til undertekster for stereoskopiske videoer. Dess høyere verdi, dess nærmere vil undertekstene fremstå for seeren."
+
 msgctxt "#37000"
 msgid "(Visually Impaired)"
 msgstr "(Nedsatt syn)"
@@ -12081,6 +12469,26 @@ msgctxt "#37017"
 msgid "Dual audio output"
 msgstr "Dobbel lydutgang"
 
+msgctxt "#37018"
+msgid "Boost centre channel when downmixing"
+msgstr "Forsterk midtkanalen ved nedmiksing"
+
 msgctxt "#37019"
 msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
 msgstr "Aktiverer systemtaster som PrintScreen, Alt-Tab og volumtaster i fullskjermmodus"
+
+msgctxt "#37020"
+msgid "Enable higher colour depth artwork"
+msgstr "Aktiver kunstverk med høyere fargedybde"
+
+msgctxt "#37021"
+msgid "Set GUI resolution limit"
+msgstr "Oppgi GUI-oppløsningsgrense"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP-spiller"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Ønsker du å stoppe avspillingen på den eksterne enheten?"
index c4c360a..91913c0 100644 (file)
@@ -6549,6 +6549,10 @@ msgctxt "#33081"
 msgid "This file is stacked, select the part you want to play from."
 msgstr "این فایل چند بخشی است, قسمت مورد نظر را برای پخش انتخاب کنید."
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "تعداد کانال ها"
+
 msgctxt "#34122"
 msgid "Always"
 msgstr "همیشه"
index c177dc3..0ec67d1 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Wybierz folder docelowy"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Miksowanie stereo"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Ilość kanałów"
@@ -1839,7 +1843,7 @@ msgstr "Włącz wizualizacje"
 
 msgctxt "#511"
 msgid "Enable video mode switching"
-msgstr "Tryb wyświetlania w zależności od regionu gry"
+msgstr "Zezwalaj na zmianę trybu wyświetlania"
 
 msgctxt "#512"
 msgid "Startup window"
@@ -2219,7 +2223,7 @@ msgstr "częstotliwość próbkowania"
 
 msgctxt "#614"
 msgid "Virtual folder"
-msgstr "Wirtualny katalog "
+msgstr "Folder wirtualny"
 
 msgctxt "#620"
 msgid "Audio CDs"
@@ -2351,7 +2355,7 @@ msgstr "Aktualizuj bibliotekę"
 
 msgctxt "#654"
 msgid "Show debug info"
-msgstr "Pokaż logi (debug)"
+msgstr "Pokazuj logi trybu debugowania"
 
 msgctxt "#655"
 msgid "Browse for executable"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Pełna rejestracja ..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Transkodowanie Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Czyszczenie bazy danych"
@@ -3131,7 +3139,7 @@ msgstr "Rozgłoś usługi do innych systemów przez Zeroconf"
 
 msgctxt "#1269"
 msgid "Allow volume control"
-msgstr "Zezwól sterować głośnością "
+msgstr "Zezwalaj na sterowanie głośnością"
 
 msgctxt "#1270"
 msgid "Allow XBMC to receive AirPlay content"
@@ -3527,7 +3535,7 @@ msgstr "Zaawansowany"
 
 msgctxt "#10039"
 msgid "Expert"
-msgstr "Ekspert"
+msgstr "Ekspercki"
 
 msgctxt "#10040"
 msgid "Add-on browser"
@@ -4879,7 +4887,7 @@ msgstr "Metoda renderowania"
 
 msgctxt "#13416"
 msgid "Auto detect"
-msgstr "Wykryj automatycznie"
+msgstr "Wykrywaj automatycznie"
 
 msgctxt "#13417"
 msgid "Basic shaders (ARB)"
@@ -4915,27 +4923,27 @@ msgstr "Użyj obiektów buforu pikselowego"
 
 msgctxt "#13425"
 msgid "Allow hardware acceleration (VDPAU)"
-msgstr "Sprzętowa akceleracja (VDPAU)"
+msgstr "Zezwalaj na sprzętową akcelerację (VDPAU)"
 
 msgctxt "#13426"
 msgid "Allow hardware acceleration (VAAPI)"
-msgstr "Sprzętowa akceleracja (VAAPI)"
+msgstr "Zezwalaj na sprzętową akcelerację (VAAPI)"
 
 msgctxt "#13427"
 msgid "Allow hardware acceleration (DXVA2)"
-msgstr "Sprzętowa akceleracja (DXVA2)"
+msgstr "Zezwalaj na sprzętową akcelerację (DXVA2)"
 
 msgctxt "#13428"
 msgid "Allow hardware acceleration (CrystalHD)"
-msgstr "Sprzętowa akceleracja (CrystalHD)"
+msgstr "Zezwalaj na sprzętową akcelerację (CrystalHD)"
 
 msgctxt "#13429"
 msgid "Allow hardware acceleration (VDADecoder)"
-msgstr "Sprzętowa akceleracja (VDADecoder)"
+msgstr "Zezwalaj na sprzętową akcelerację (VDADecoder)"
 
 msgctxt "#13430"
 msgid "Allow hardware acceleration (OpenMax)"
-msgstr "Sprzętowa akceleracja (OpenMax)"
+msgstr "Zezwalaj na sprzętową akcelerację (OpenMax)"
 
 msgctxt "#13431"
 msgid "Pixel Shaders"
@@ -4947,7 +4955,7 @@ msgstr "Zezwól na akceleracją sprzętową (Video Toolbox)"
 
 msgctxt "#13433"
 msgid "Play the next video automatically"
-msgstr "Automatycznie odtwórz następne wideo"
+msgstr "Automatycznie odtwarzaj następne wideo"
 
 msgctxt "#13434"
 msgid "Play only this"
@@ -4959,7 +4967,7 @@ msgstr "Włącz Skalery HQ dla skalowania ponad"
 
 msgctxt "#13436"
 msgid "Allow hardware acceleration (libstagefright)"
-msgstr "Dopuszczaj akcelerację sprzętową (libstagefright) "
+msgstr "Zezwalaj na akcelerację sprzętową (libstagefright)"
 
 msgctxt "#13437"
 msgid "Prefer VDPAU Video Mixer"
@@ -4967,11 +4975,15 @@ msgstr "Preferuj VDPAU Video Mixer"
 
 msgctxt "#13438"
 msgid "Allow hardware acceleration (amcodec)"
-msgstr "Sprzętowa akceleracja (amcodec)"
+msgstr "Zezwalaj na sprzętową akcelerację (amcodec)"
 
 msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
-msgstr "Sprzętowa akceleracja (MediaCodec)"
+msgstr "Zezwalaj na sprzętową akcelerację (MediaCodec)"
+
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Zezwalaj na dekodowanie wielowątkowe"
 
 msgctxt "#13500"
 msgid "A/V sync method"
@@ -5403,7 +5415,7 @@ msgstr "Używaj pełnego okna zamiast pełnego ekranu"
 
 msgctxt "#14084"
 msgid "Queue songs on selection"
-msgstr "Zaznaczone utwory dodawaj do kolejki"
+msgstr "Dodawaj zaznaczone utwory do kolejki"
 
 msgctxt "#14086"
 msgid "Playback"
@@ -5451,7 +5463,7 @@ msgstr "Zgraj zawartość"
 
 msgctxt "#14097"
 msgid "Audio CD Insert Action"
-msgstr "Akcja po włożeniu płyty audio"
+msgstr "Czynność wykonywana po włożeniu płyty CD"
 
 msgctxt "#14098"
 msgid "Play"
@@ -5631,7 +5643,7 @@ msgstr "Wpisz nową nazwę pliku"
 
 msgctxt "#16014"
 msgid "Enter folder name"
-msgstr "Wpisz nazwę folderu"
+msgstr "Wprowadź nazwę folderu"
 
 msgctxt "#16015"
 msgid "Enter directory"
@@ -5927,7 +5939,7 @@ msgstr "%i dni"
 
 msgctxt "#19000"
 msgid "Switch to channel"
-msgstr "Wybierz kanał"
+msgstr "Przełącz kanał"
 
 msgctxt "#19001"
 msgid "Separate the search words by using AND, OR and/or NOT."
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Nagrania"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Folder z ikonami kanałów"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanały"
@@ -6071,7 +6087,7 @@ msgstr "Nie można odtworzyc nagrania. Sprawdź plik log."
 
 msgctxt "#19037"
 msgid "Show signal quality"
-msgstr "Pokaż jakośc sygnału"
+msgstr "Pokazuj jakość sygnału"
 
 msgctxt "#19038"
 msgid "Not supported by the PVR backend."
@@ -6095,7 +6111,7 @@ msgstr "Na pewno chcesz zmienić nazwę zaplanowanego nagrania?"
 
 msgctxt "#19043"
 msgid "Recording"
-msgstr "Nagranie"
+msgstr "Nagrywanie"
 
 msgctxt "#19044"
 msgid "Please check your configuration or check the log for details."
@@ -6123,11 +6139,11 @@ msgstr "Pokaż kanał"
 
 msgctxt "#19050"
 msgid "Show visible channels"
-msgstr "Pokaż widoczne kanały"
+msgstr "Pokazuj widoczne kanały"
 
 msgctxt "#19051"
 msgid "Show hidden channels"
-msgstr "Pokaż ukryte kanały"
+msgstr "Pokazuj ukryte kanały"
 
 msgctxt "#19052"
 msgid "Move channel to:"
@@ -6183,7 +6199,11 @@ msgstr "Przejdź na koniec"
 
 msgctxt "#19065"
 msgid "Default EPG window"
-msgstr "Domyślne okno Przewodnika TV"
+msgstr "Domyślny tryb Przewodnika TV"
+
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Ikony kanałów"
 
 msgctxt "#19067"
 msgid "This event is already being recorded."
@@ -6211,7 +6231,7 @@ msgstr "Nie przechowuj danych Przewodnika TV w bazie"
 
 msgctxt "#19073"
 msgid "Delay channel switch"
-msgstr "Opóźnienie zmiany kanału"
+msgstr "Opóźniaj zmiany kanału o"
 
 msgctxt "#19074"
 msgid "Active:"
@@ -6317,17 +6337,21 @@ msgctxt "#19099"
 msgid "Service"
 msgstr "Usługa"
 
+msgctxt "#19100"
+msgid "Mux"
+msgstr "Mux"
+
 msgctxt "#19101"
 msgid "Provider"
 msgstr "Dostawca"
 
 msgctxt "#19102"
 msgid "Please switch to another channel."
-msgstr "Proszę zmień na inny kanał."
+msgstr "Proszę przełącz na inny kanał."
 
 msgctxt "#19104"
 msgid "Enter the name of the folder for the recording"
-msgstr "Wpisz nazwę folderu dla nagrań"
+msgstr "Wprowadź nazwę folderu dla nagrań"
 
 msgctxt "#19106"
 msgid "Next timer on"
@@ -6559,7 +6583,7 @@ msgstr "Szukaj brakujących ikon"
 
 msgctxt "#19169"
 msgid "Hide video information box"
-msgstr "Ukryj informacje o wideo"
+msgstr "Ukrywaj informacje o wideo"
 
 msgctxt "#19170"
 msgid "Timeout when starting playback"
@@ -6595,7 +6619,7 @@ msgstr "Odtwarzanie"
 
 msgctxt "#19178"
 msgid "Show channel information when switching channels"
-msgstr "Pokaż informację o kanale podczas zmiany kanału"
+msgstr "Pokazuj informację o kanale podczas zmiany kanału"
 
 msgctxt "#19179"
 msgid "Automatically hide channel information"
@@ -6615,7 +6639,7 @@ msgstr "Liczba dni wyświetlanych w Przewodniku TV"
 
 msgctxt "#19184"
 msgid "Channel information duration"
-msgstr "Długość wyświetlania informacji o kanale"
+msgstr "Okres wyświetlania informacji o kanale"
 
 msgctxt "#19185"
 msgid "Reset the PVR database"
@@ -6635,7 +6659,7 @@ msgstr "Resetowanie Przewodnika TV"
 
 msgctxt "#19189"
 msgid "Continue last channel on startup"
-msgstr "Wznów ostatnio oglądany kanał przy starcie"
+msgstr "Odtwarzaj ostatnio oglądany kanał przy starcie"
 
 msgctxt "#19190"
 msgid "Minimised"
@@ -6659,11 +6683,11 @@ msgstr "Kontynuować?"
 
 msgctxt "#19195"
 msgid "Client actions"
-msgstr "Akcje klienta"
+msgstr "Czynności klienta"
 
 msgctxt "#19196"
 msgid "PVR client specific actions"
-msgstr "Szczególne akcje klienta PVR"
+msgstr "Specyficzne operacje klienta PVR"
 
 msgctxt "#19197"
 msgid "Recording started on: %s"
@@ -6795,7 +6819,7 @@ msgstr "Nagranie usunięte"
 
 msgctxt "#19229"
 msgid "Close channel OSD after switching channels"
-msgstr "Zamknij menu OSD po przełączeniu kanału"
+msgstr "Zamknij menu ekranowe po zmianie kanału"
 
 msgctxt "#19230"
 msgid "Prevent EPG updates during playback"
@@ -6811,11 +6835,11 @@ msgstr "Wyczyść rezultaty wyszukiwania"
 
 msgctxt "#19233"
 msgid "Display a notification on timer updates"
-msgstr "Wyświetl powiadomienie przy zmianie zaplanowanych zadań"
+msgstr "Wyświetlaj powiadomienie przy zmianie zaplanowanych zadań"
 
 msgctxt "#19234"
 msgid "Use backend channels numbers (only works with 1 enabled PVR Add-on)"
-msgstr "Używaj numerów kanałów z serwera (działa tylko przy jednej włączonej wtyczce PVR)"
+msgstr "Używaj numerów kanałów z serwera (tylko 1 wtyczka PVR)"
 
 msgctxt "#19235"
 msgid "PVR manager is starting up"
@@ -6847,7 +6871,7 @@ msgstr "Menedżer PVR został uruchomiony bez jakichkolwiek"
 
 msgctxt "#19242"
 msgid "enabled PVR Add-on. Enable at least one Add-on"
-msgstr "Włącz wtyczkę PVR. Włącz przynajmniej jeden dodatek"
+msgstr "Włącz przynajmniej jedną wtyczkę PVR, aby oglądać telewizję."
 
 msgctxt "#19243"
 msgid "in order to use the PVR functionality."
@@ -6863,7 +6887,7 @@ msgstr "Ustaw polecenie wzbudzenia (cmd [timestamp])"
 
 msgctxt "#19246"
 msgid "Wakeup before recording"
-msgstr "Obudź przed nagrywaniem"
+msgstr "Wybudzaj przed nagrywaniem"
 
 msgctxt "#19247"
 msgid "Daily wakeup"
@@ -6999,11 +7023,27 @@ msgstr "Specyfikacja klienta"
 
 msgctxt "#19280"
 msgid "Client specific settings"
-msgstr "Ustawienia specyficzne klienta"
+msgstr "Specyficzne ustawienia klienta"
 
 msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
-msgstr "Potwierdź przełączanie kanałów przyciskiem OK"
+msgstr "Potwierdzaj zmianę kanału przyciskiem OK"
+
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Bieżąca ikona"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Brak ikony"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Wybierz ikonę "
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Znajdź ikonę"
 
 msgctxt "#19499"
 msgid "Other/Unknown"
@@ -7289,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motoryzacja"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Zdrowie"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Gotowanie"
@@ -7313,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Język oryginalny"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Czarno-białe"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Niepublikowane"
@@ -7375,15 +7407,15 @@ msgstr "Zewnętrzny odtwarzacz DVD"
 
 msgctxt "#20003"
 msgid "Trainers folder"
-msgstr "Folder z trainerami"
+msgstr "Folder zwiastunów"
 
 msgctxt "#20004"
 msgid "Screenshot folder"
-msgstr "Folder ze zrzutami ekranu"
+msgstr "Folder zrzutów ekranu"
 
 msgctxt "#20006"
 msgid "Playlists folder"
-msgstr "Folder z playlistami"
+msgstr "Folder list odtwarzania"
 
 msgctxt "#20007"
 msgid "Recordings"
@@ -7575,7 +7607,7 @@ msgstr "Profil zablokowany"
 
 msgctxt "#20069"
 msgid "Could not create folder"
-msgstr "Nie mo utworzyć folderu"
+msgstr "Nie można utworzyć folderu"
 
 msgctxt "#20070"
 msgid "Profile directory"
@@ -7871,7 +7903,7 @@ msgstr "Wprowadź hasło dla"
 
 msgctxt "#20144"
 msgid "Shutdown timer"
-msgstr "Planowane zamykanie"
+msgstr "Planowane zamknięcie"
 
 msgctxt "#20145"
 msgid "Shutdown interval (in minutes)"
@@ -7899,7 +7931,7 @@ msgstr "Zaplanuj zamknięcie"
 
 msgctxt "#20151"
 msgid "Cancel shutdown timer"
-msgstr "Anuluj zaplanowane zamknięcie"
+msgstr "Anuluj zamknięcie"
 
 msgctxt "#20152"
 msgid "Lock preferences for %s"
@@ -8051,7 +8083,7 @@ msgstr "Rozgłoś aktualizację biblioteki przez UPnP"
 
 msgctxt "#20189"
 msgid "Enable auto scrolling for plot & review"
-msgstr "Automatyczne przewijanie opisu i fabuły"
+msgstr "Automatyczne przewijanie fabuły i recenzji"
 
 msgctxt "#20190"
 msgid "Custom"
@@ -8063,7 +8095,7 @@ msgstr "Włącz logowanie (debug)"
 
 msgctxt "#20192"
 msgid "Download additional information during updates"
-msgstr "Pobierz dodatkowe informacje w czasie aktualizacji"
+msgstr "Pobieraj dodatkowe informacje podczas aktualizacji"
 
 msgctxt "#20193"
 msgid "Default service for album information"
@@ -8191,7 +8223,7 @@ msgstr "Kanały RSS"
 
 msgctxt "#20307"
 msgid "Secondary DNS"
-msgstr "Dodatkowe DNS"
+msgstr "Alternatywny DNS"
 
 msgctxt "#20308"
 msgid "DHCP server:"
@@ -8233,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Przeszukiwanie albumów przy użyciu %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Fabuła filmu"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Odtwarzaj część..."
@@ -8255,7 +8291,7 @@ msgstr "Wskaż folder docelowy"
 
 msgctxt "#20329"
 msgid "Movies are in separate folders that match the movie title"
-msgstr "Filmy są w oddzielnych folderach, z nazwami tytułu filmu"
+msgstr "Filmy są w oddzielnych folderach o nazwach z tytułem filmu"
 
 msgctxt "#20330"
 msgid "Use folder names for lookups"
@@ -8399,7 +8435,7 @@ msgstr "Serial"
 
 msgctxt "#20365"
 msgid "Episode plot"
-msgstr "Opis odcinka"
+msgstr "Fabuła odcinka"
 
 msgctxt "#20366"
 msgid "* All seasons"
@@ -8407,7 +8443,7 @@ msgstr "* Wszystkie sezony"
 
 msgctxt "#20367"
 msgid "Hide watched"
-msgstr "Ukryj oglądane"
+msgstr "Ukrywaj oglądane"
 
 msgctxt "#20368"
 msgid "Prod code"
@@ -8415,7 +8451,7 @@ msgstr "Kod Prod."
 
 msgctxt "#20369"
 msgid "Show plot for unwatched items"
-msgstr "Pokazuj opis dla nieoglądanych pozycji"
+msgstr "Pokazuj fabułę dla nieoglądanych pozycji"
 
 msgctxt "#20370"
 msgid "* Hidden to prevent spoilers *"
@@ -8587,7 +8623,7 @@ msgstr "Tylko tytuły"
 
 msgctxt "#20412"
 msgid "Flatten TV shows"
-msgstr "Pomiń podział na sezony"
+msgstr "Pomijaj podział na sezony"
 
 msgctxt "#20413"
 msgid "Get fanart"
@@ -8615,7 +8651,7 @@ msgstr "Autorzy"
 
 msgctxt "#20419"
 msgid "Replace file names with library titles"
-msgstr "Pokaż metadane w widoku plików"
+msgstr "Pokazuj metadane w widoku plików"
 
 msgctxt "#20420"
 msgid "Never"
@@ -8683,7 +8719,7 @@ msgstr "Połącz podzielone elementy wideo "
 
 msgctxt "#20436"
 msgid "Export actor thumbs?"
-msgstr "Eksportuj ikony aktorów"
+msgstr "Eksportować zdjęcia aktorów?"
 
 msgctxt "#20437"
 msgid "Choose fanart"
@@ -8763,7 +8799,7 @@ msgstr "Słuchaczy"
 
 msgctxt "#20456"
 msgid "Flatten library hierarchy"
-msgstr "Spłaszcz hierarchię biblioteki "
+msgstr "Spłaszczaj hierarchię biblioteki "
 
 msgctxt "#20457"
 msgid "Movie set"
@@ -8877,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Usuń udział"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Globalny folder napisów"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Filmy i alternatywny folder dla napisów"
@@ -8887,7 +8927,7 @@ msgstr "Zastępuj czcionki w napisach ASS/SSA"
 
 msgctxt "#21369"
 msgid "Enable mouse and Touch Screen support"
-msgstr "Włącz obsługę myszy"
+msgstr "Włącz obsługę myszy i ekranów dotykowych"
 
 msgctxt "#21370"
 msgid "Play navigation sounds during media playback"
@@ -8939,7 +8979,7 @@ msgstr "Wprowadź nazwę nowej playlisty"
 
 msgctxt "#21382"
 msgid "Show \"Add source\" buttons in file lists"
-msgstr "Pokaż przycisk \"Dodaj źródło\" w liście plików"
+msgstr "Pokazuj przycisk \"Dodaj źródło\" w liście plików"
 
 msgctxt "#21383"
 msgid "Enable scrollbars"
@@ -9245,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "miksowane"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Położenie napisów na ekranie "
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Stałe"
@@ -9603,7 +9647,7 @@ msgstr "Aktualizuj bibliotekę na starcie"
 
 msgctxt "#22001"
 msgid "Hide progress of library updates"
-msgstr "Ukryj postęp aktualizacji biblioteki"
+msgstr "Ukrywaj postęp aktualizacji biblioteki"
 
 msgctxt "#22002"
 msgid "DNS suffix"
@@ -9683,7 +9727,7 @@ msgstr "Program"
 
 msgctxt "#22021"
 msgid "Allowed error in aspect ratio to minimise black bars"
-msgstr "Dopuszczaj błąd w proporcji obrazu i minimalizuj czarne pasy"
+msgstr "Dopuszczaj błąd w proporcji obrazu minimalizując czarne pasy"
 
 msgctxt "#22022"
 msgid "Show video files in listings"
@@ -9711,7 +9755,7 @@ msgstr "Kolory"
 
 msgctxt "#22033"
 msgid "Charset"
-msgstr " parametr Charset"
+msgstr "Zestaw znaków"
 
 msgctxt "#22034"
 msgid "Export karaoke titles as HTML"
@@ -9755,7 +9799,7 @@ msgstr "czarno/biała"
 
 msgctxt "#22079"
 msgid "Default select action"
-msgstr "Domyślna akcja wyboru"
+msgstr "Domyślna czynność po wybraniu"
 
 msgctxt "#22080"
 msgid "Choose"
@@ -9971,7 +10015,7 @@ msgstr "Dostępne aktualizacje"
 
 msgctxt "#24044"
 msgid "Dependencies not met. Please contact Add-on author."
-msgstr "Zależności nie zostały spełnione. Proszę skontaktować się z autorem dodatku."
+msgstr "Zależności nie zostały spełnione. Proszę skontaktować się z autorem wtyczki."
 
 msgctxt "#24045"
 msgid "Add-on does not have the correct structure"
@@ -10143,15 +10187,15 @@ msgstr "W skórze brakuje części plików"
 
 msgctxt "#24104"
 msgid "Add-on is incompatible due to unmet dependencies."
-msgstr "Dodatek jest niekompatybilny z powodu niespełniania zależności."
+msgstr "Wtyczka jest niekompatybilna z powodu niespełniania zależności."
 
 msgctxt "#24105"
 msgid "Pause when searching for subtitles"
-msgstr "Zatrzymaj odtwarzanie podczas wyszukiwania napisów"
+msgstr "Zatrzymuj odtwarzanie podczas wyszukiwania napisów"
 
 msgctxt "#24106"
 msgid "If not saved to movie folder subtitles will be downloaded to custom subtitle folder"
-msgstr "Napisy zostaną ściągnięte do domyślnego katalogu, chyba że zostaną zapisane do katalogu z filmem"
+msgstr "Jeśli napisy nie zostaną zapisane w folderze z filmem, to zostaną zapisane wybranym folderze globalnym"
 
 msgctxt "#24107"
 msgid "Searching for subtitles ..."
@@ -10175,7 +10219,7 @@ msgstr "Pobieraj napisy dla następujących języków:"
 
 msgctxt "#24112"
 msgid "Set languages to use when searching for subtitles. Not all subtitle services will use all languages."
-msgstr "Wybierz języki, które będą używane podczas wyszukiwania napisów. "
+msgstr "Wybierz języki, które będą używane podczas wyszukiwania napisów.  Nie wszystkie serwisy udostępniają napisy dla wszystkich języków."
 
 msgctxt "#24113"
 msgid "Failed to download subtitle"
@@ -10187,7 +10231,7 @@ msgstr "Nie zainstalowano serwisów napisów"
 
 msgctxt "#24115"
 msgid "Save subtitles to movie folder"
-msgstr "Zapisuj napisy w folderze filmu"
+msgstr "Zapisuj napisy w folderze z filmem"
 
 msgctxt "#24116"
 msgid "Default TV Service"
@@ -10219,7 +10263,7 @@ msgstr "Powiadomienia"
 
 msgctxt "#25001"
 msgid "Hide foreign"
-msgstr "Ukryj obcokrajowe"
+msgstr "Ukrywaj zagraniczne"
 
 msgctxt "#25002"
 msgid "Select from all titles ..."
@@ -10227,7 +10271,7 @@ msgstr "Wybierz ze wszystkich tytułów..."
 
 msgctxt "#25003"
 msgid "Show bluray menus"
-msgstr "Pokaż menu dysku bluray"
+msgstr "Pokazuj menu dysku Blu-ray"
 
 msgctxt "#25004"
 msgid "Play main title: %d"
@@ -10241,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Wybierz pozycję do odtwarzania"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Rozdziały: %u - czas trwania: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Odtwarzanie płyty Blu-ray nie powiodło się"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Menu tego Blu-ray nie jest obsługiwane"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Tryb biblioteki"
@@ -10597,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2) "
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Ilość kanałów"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10855,7 +10915,7 @@ msgstr "Włącz tryb czuwania w urządzeniach, kiedy aktywny jest wygaszacz ekra
 
 msgctxt "#36010"
 msgid "Wake devices when deactivating screensaver"
-msgstr "Obudź urządzenia podczas deaktywowania wygaszacza ekranu"
+msgstr "Wybudzaj urządzenia podczas opuszczania wygaszacza ekranu"
 
 msgctxt "#36011"
 msgid "Could not detect the CEC com port. Set it up manually."
@@ -10971,7 +11031,7 @@ msgstr "* Folder"
 
 msgctxt "#36042"
 msgid "Use limited colour range (16-235)"
-msgstr "Korzystaj z ograniczonego zakresu kolorów (16-235)"
+msgstr "Używaj z ograniczonego zakresu kolorów (16-235)"
 
 msgctxt "#36101"
 msgid "Change the look and feel of the User Interface."
@@ -11063,7 +11123,7 @@ msgstr "Wyświetl (..) element w listach w folderze nadrzędnym."
 
 msgctxt "#36123"
 msgid "Show file extensions on media files. For example, 'You Enjoy Myself.mp3' would be simply be shown as 'You Enjoy Myself'."
-msgstr "Pokaż rozszerzenia plików multimedialnych. Na przykład, \"Ciężka kosiarka.mp3\" zostanie określone jako \"Ciężka kosiarka\"."
+msgstr "Pokazuj rozszerzenia plików multimedialnych. Na przykład, \"Innuendo.mp3\" zostanie określone jako \"Innuendo\"."
 
 msgctxt "#36124"
 msgid "Ignore certain tokens during sort operations. For example, 'The Simpsons' would simply be sorted as 'Simpsons'. To configure tokens, see http://wiki.xbmc.org/index.php?title=Settings/Appearance."
@@ -11079,7 +11139,7 @@ msgstr "Wyświetl przycisk \"Dodaj źródło\" w głównej sekcji interfejsu uż
 
 msgctxt "#36127"
 msgid "Show hidden files and directories."
-msgstr "Ukryj niewidoczne pliki i katalogi."
+msgstr "Ukrywaj niewidoczne pliki i katalogi."
 
 msgctxt "#36128"
 msgid "No info available yet."
@@ -11135,7 +11195,7 @@ msgstr "Brak dostępnych informacji ."
 
 msgctxt "#36141"
 msgid "Show plot information for unwatched media in the Video Library."
-msgstr "Pokaż informacje o fabule dla niewidzianych multimediów w Bilbiotece Wideo."
+msgstr "Pokazuj informację o fabule dla nieoglądanych multimediów w Bibliotece Wideo."
 
 msgctxt "#36142"
 msgid "No info available yet."
@@ -11143,7 +11203,7 @@ msgstr "Brak dostępnych informacji ."
 
 msgctxt "#36143"
 msgid "Get thumbnails for actors when scanning media."
-msgstr "Pobierz zdjęcia aktorów podczas skanowania mediów."
+msgstr "Pobieraj zdjęcia aktorów podczas skanowania mediów."
 
 msgctxt "#36144"
 msgid "Remove the TV show season node, toggles between 'If only one season' (default), 'Always' and 'Never'."
@@ -11159,7 +11219,7 @@ msgstr "Uaktualnianie biblioteki podczas uruchomienia XBMC."
 
 msgctxt "#36147"
 msgid "Hide the library scanning progress bar during scans."
-msgstr "Ukrywanie postępu uaktualniania biblioteki."
+msgstr "Ukrywaj pasek postęp aktualizacji biblioteki."
 
 msgctxt "#36148"
 msgid "Remove items from your library that can't be found (either renamed, deleted, or on removable storage that is currently unplugged)."
@@ -11231,7 +11291,7 @@ msgstr "."
 
 msgctxt "#36165"
 msgid "Pause for a small amount of time during a refresh rate change. Activate to automatically set the refresh rate which is best matched with the video that is playing. This potentially allows for perfectly smooth video reproduction, as video material can be recorded in a variety of frame rates which need to be properly matched by the refresh rate of the display in order to be displayed smoothly."
-msgstr "Pauza przy małym czasie podczas zmiany częstotliwości odświeżania. Aktywuj, aby automatycznie ustawić częstotliwość odświeżania, która jest najlepiej dopasowana do odtwarzanego filmu. Ta funkcja potencjalnie pozwala na idealnie gładkie odtwarzanie wideo, jako że materiały wideo mogą być nagrywane z różną częstotliwością klatek, które muszą być odpowiednio dopasowane do częstotliwości odświeżania ekranu, aby być wyświetlane płynnie."
+msgstr "Zatrzymuje odtwarzanie podczas zmiany częstotliwości odświeżania. Aktywuj, aby automatycznie ustawić częstotliwość odświeżania, która jest najlepiej dopasowana do odtwarzanego filmu. Ta funkcja potencjalnie pozwala na idealnie gładkie odtwarzanie wideo, jako że materiały wideo mogą być nagrywane z różną częstotliwością klatek, które muszą być odpowiednio dopasowane do częstotliwości odświeżania ekranu, aby być wyświetlane płynnie."
 
 msgctxt "#36166"
 msgid "Synchronise the video to the refresh rate of the monitor."
@@ -11279,7 +11339,7 @@ msgstr "Brak dostępnych informacji ."
 
 msgctxt "#36177"
 msgid "Toggle between Choose, Play (default), Resume and Show Information. Choose will select an item, e.g. open a directory in files mode. Resume will automatically resume videos from the last position that you were viewing them, even after restarting the system."
-msgstr "Wybór pomiędzy dostępnymi funkcjami: 'Określ', 'Odtwarzaj' (domyślnie), 'Wznów' i 'Pokaż informacje'. 'Określ' - wybierze wskazany element, np. otworzy katalog w trybie plików. 'Wznów' - automatycznie wznowi wideo z ostatniej oglądanej pozycji, nawet po ponownym uruchomieniu systemu."
+msgstr "Wybór pomiędzy dostępnymi funkcjami: 'Określ', 'Odtwórz' (domyślnie), 'Wznów' i 'Pokaż informacje'. 'Określ' - wybierze wskazany element, np. otworzy katalog w trybie plików. 'Wznów' - automatycznie wznowi wideo z ostatniej oglądanej pozycji, nawet po ponownym uruchomieniu systemu."
 
 msgctxt "#36178"
 msgid "No info available yet."
@@ -11291,7 +11351,7 @@ msgstr "Gdy plik jest skanowany i dodawany do biblioteki wyświetli się tytuł
 
 msgctxt "#36180"
 msgid "Extract thumbnails and information, such as codecs and aspect ratio, to display in Library Mode."
-msgstr "Pobieranie grafik i informacji, takich jak kodeki i proporcje obrazu do wyświetlania w trybie biblioteki."
+msgstr "Pobieranie miniatur i informacji, takich jak kodeki i proporcje obrazu wyświetlanych w trybie biblioteki."
 
 msgctxt "#36181"
 msgid "No info available yet."
@@ -11387,7 +11447,7 @@ msgstr "Włącz osobistą cyfrową nagrywarkę (PVR) w funkcjach w XBMC. Wymagan
 
 msgctxt "#36204"
 msgid "Import channel groups from the PVR backend (if supported). Will delete user created groups if they're not found on the backend."
-msgstr "Importuj grupy kanałów z serwera PVR (jeśli jest obsługiwane). Funkcja usunie wszystkie grupy utworzone przez użytkownika, jeśli nie są one zapisane w bazie."
+msgstr "Importuj grupy kanałów z serwera PVR (jeśli wspierane). Funkcja usunie wszystkie grupy utworzone przez użytkownika, jeśli nie są one zapisane w bazie."
 
 msgctxt "#36205"
 msgid "Sort the channels by channel number on the server, but uses XBMC's own numbering for channels."
@@ -11403,7 +11463,7 @@ msgstr "Skożystaj z menedżera kanału, który umożliwia zmianę kolejności k
 
 msgctxt "#36208"
 msgid "Instruct the backend to search for channels (if supported)."
-msgstr "Wymuzaj na serwerze PVR wyszukiwanie kanałów (jeśli obsługiwane)."
+msgstr "Wymuszaj na serwerze PVR wyszukiwanie kanałów (jeśli wspierane)."
 
 msgctxt "#36209"
 msgid "Delete channel/EPG database and reimport the data from the backend afterwards."
@@ -11447,7 +11507,7 @@ msgstr "Brak dostępnych informacji."
 
 msgctxt "#36219"
 msgid "Default EPG window to show. Defaults to Timeline."
-msgstr "Domyślny wyświetlany tryb Przewodnika TV. Domyślnie oś czasowa."
+msgstr "Tryb wyświetlania Przewodnika TV. Domyślnie oś czasowa."
 
 msgctxt "#36220"
 msgid "Number of days of EPG data to import from backends. Defaults to 3 days."
@@ -11467,7 +11527,7 @@ msgstr "Domyślnie dane Przewodnika TV są przechowywane w lokalnej bazie danych
 
 msgctxt "#36224"
 msgid "Hide \"no information available\" labels when no EPG data can be retrieved for a channel."
-msgstr "Ukryj komunikat \"Brak dostępnych informacji\", gdy brak informacji o kanale w Przewodniku TV."
+msgstr "Ukrywaj komunikat \"Brak dostępnych informacji\", gdy brak informacji o kanale w Przewodniku TV."
 
 msgctxt "#36225"
 msgid "Delete the EPG database in xbmc and reimport the data afterwards from the backend."
@@ -11483,11 +11543,11 @@ msgstr "Wyświetl strumień wybranego kanału w oknie zamiast na pełnym ekranie
 
 msgctxt "#36228"
 msgid "Show the last viewed channel if switching to live tv."
-msgstr "Pokaż ostatnio oglądane kanały przy wejsciu w Telewizję."
+msgstr "Pokazuj ostatnio oglądany kanał przy wejściu do Telewizji."
 
 msgctxt "#36229"
 msgid "Display signal quality information in the codec information window (if supported by the Add-on and backend)."
-msgstr "Wyświetlaj informację o jakości sygnału w oknie informacyjnym kodeka (jeśli obsługiwane przez wtyczkę i serwer)."
+msgstr "Wyświetlaj informację o jakości sygnału w oknie informacyjnym kodeka (jeśli wspierane przez wtyczkę i serwer)."
 
 msgctxt "#36230"
 msgid "No info available yet."
@@ -11495,7 +11555,7 @@ msgstr "Brak dostępnych informacji."
 
 msgctxt "#36231"
 msgid "Pressing a number button in full screen mode will automatically switch to the channel number that was entered after 1 second."
-msgstr "Naciśnięcie przycisku numerycznego w trybie pełnoekranowym automatycznie przełączy numer kanału, który został wprowadzony po 1 sekundzie."
+msgstr "Naciśnięcie przycisku numerycznego w trybie pełnoekranowym przełączy po 1 sekundzie na wybrany kanał."
 
 msgctxt "#36232"
 msgid "No info available yet."
@@ -11595,7 +11655,7 @@ msgstr "Ustal, czy artyści, którzy pojawiają się tylko na kompilacjach są w
 
 msgctxt "#36256"
 msgid "Automatically fetch album and artist information via scrapers during scan."
-msgstr "Automatycznie pobierz informacje o albumie i artyście podczas skanowania."
+msgstr "Automatycznie pobieraj informacje o albumie i artyście podczas skanowania."
 
 msgctxt "#36257"
 msgid "Select the default album information source"
@@ -11603,7 +11663,7 @@ msgstr "Wybierz domyślne źródło informacji o albumach."
 
 msgctxt "#36258"
 msgid "Select the default artist information source. See the Add-ons Manager for options."
-msgstr "Wybierz domyślne źródło informacji o artyście. Więcej opcji w menedżerze dodatków."
+msgstr "Wybierz domyślne źródło informacji o artyście. Więcej opcji w menedżerze wtyczek."
 
 msgctxt "#36259"
 msgid "Check for new and removed media files on XBMC startup."
@@ -11695,7 +11755,7 @@ msgstr "Brak dostępnych informacji."
 
 msgctxt "#36281"
 msgid "XBMC will search for thumbs on remote shares and optical media. This can often slow down the listing of network folders."
-msgstr "XBMC wyszuka grafiki w folderach sieciowych i nośnikach optycznych. Może spowolnić dostęp do listy folderów sieciowych."
+msgstr "XBMC wyszuka miniatur w folderach sieciowych i nośnikach optycznych. Może spowolnić dostęp do listy folderów sieciowych."
 
 msgctxt "#36282"
 msgid "No info available yet."
@@ -11799,11 +11859,11 @@ msgstr "Jeśli istnieją informacje EXIF (data, czas, aparat, itp.), to zostaną
 
 msgctxt "#36307"
 msgid "Automatically generate picture thumbnails when entering picture folder."
-msgstr "Automatyczne generowanie miniaturek obrazu przy wejściu w folder zdjęć."
+msgstr "Automatyczne generowanie miniaturek obrazu przy wejściu do folderu zdjęć."
 
 msgctxt "#36308"
 msgid "Pictures will automatically rotate according to information in the EXIF tag, if found."
-msgstr "Zdjęcia będą automatycznie się obracać według informacji w znaczniku EXIF."
+msgstr "Zdjęcia będą automatycznie obracane według informacji w znaczniku EXIF."
 
 msgctxt "#36309"
 msgid "Show video media in picture file lists, since most digital cameras nowadays have video recording capabilities."
@@ -11843,7 +11903,7 @@ msgstr "Wybierz do trzech lokalizacji miejsc, dla których pogoda może być wy
 
 msgctxt "#36318"
 msgid "Specify the default weather information source. See the Add-ons Manager for options."
-msgstr "Określ domyślne źródło informacji pogodowych. Więcej opcji w menedżer dodatków."
+msgstr "Określ domyślne źródło informacji pogodowych. Więcej opcji w menedżerze wtyczek."
 
 msgctxt "#36319"
 msgid "No info available yet."
@@ -11899,7 +11959,7 @@ msgstr "Zdefiniuj hasło serwera."
 
 msgctxt "#36332"
 msgid "Select between web interfaces installed via the Add-on Manager."
-msgstr "Wybierz między zainstalowanymi interfejsami internetowymi za pomocą menedżera dodatków."
+msgstr "Wybierz między zainstalowanymi interfejsami internetowymi za pomocą menedżera wtyczek."
 
 msgctxt "#36333"
 msgid "No info available yet."
@@ -11991,7 +12051,7 @@ msgstr "Główna korzyść z konfiguracji multi-ekranowej jest, że XBMC może b
 
 msgctxt "#36355"
 msgid "In a multi-screen configuration, the screens where XBMC is not displayed are blacked out."
-msgstr "W konfiguracji multi-ekranowej, ekrany gdzie XBMC nie jest wyświetlany są zaciemnione."
+msgstr "W konfiguracji z wieloma ekranami, ekrany gdzie XBMC nie jest wyświetlany są wygaszane."
 
 msgctxt "#36356"
 msgid "Eliminate vertical tearing."
@@ -12003,7 +12063,7 @@ msgstr "Kalibracja interfejsu użytkownika, dostosowująca funkcję Overscan. U
 
 msgctxt "#36358"
 msgid "Test patterns for display hardware calibration."
-msgstr "Wzory testowe dla sprzętowej kalibracji wyświetlacza."
+msgstr "Wzorce testowe dla sprzętowej kalibracji wyświetlacza."
 
 msgctxt "#36359"
 msgid "No info available yet."
@@ -12013,17 +12073,29 @@ msgctxt "#36360"
 msgid "No info available yet."
 msgstr "Brak dostępnych informacji."
 
+msgctxt "#36361"
+msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
+msgstr "Wybierz ustawienie wyjścia audio: [Stałe] - właściwości wyjścia są ustawione na stałą częstotliwość próbkowania i konfigurację głośników za każdym razem; [Najlepsze dopasowanie] - właściwości wyjścia są dobierane najlepiej jak to możliwe do właściwości źródła; [Zoptymalizowane] - właściwości wyjścia są ustawiane na początku odtwarzania i pozostają niezmienne nawet po zmianie właściwości źródła."
+
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Określ liczbę kanałów wspieranych przez podłączone urządzenie audio lub liczbę głośników podłączonych do złącz analogowych. To ustawienie nie ma wpływu na ustawienie przepuszczania dźwięku. Uwaga - złącze SPDIF wspiera tylko kanały w systemie 2.0, ale umożliwia przepuszczanie wspieranych formatów wielokanałowych."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Wzmocnij strumienie AC3 zmiksowane do 2 kanałów."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Wybierz, aby włączyć miksowanie dźwięku 2 kanałowego do liczby kanałów określonych w konfiguracji głośników."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
-msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające potrafi dekodować strumienie AC3."
+msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające wspiera dekodowanie strumieni AC3."
 
 msgctxt "#36366"
 msgid "Select this option if your receiver is capable of decoding DTS streams."
-msgstr "Wybierz tę opcję, jeśli Twój interfejs jest zdolny do dekodowania strumieni DTS."
+msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające wspiera dekodowanie strumieni DTS."
 
 msgctxt "#36367"
 msgid "Select the maximum number of audio channels/speakers available for audio decoded. If optical/coax digital outputs are used this must be set to 2.0"
@@ -12035,11 +12107,11 @@ msgstr "Wybierz, aby włączyć funkcję przepuszczania zakodowanego dźwięku n
 
 msgctxt "#36369"
 msgid "Select this option if your receiver is capable of decoding TrueHD streams."
-msgstr "Wybierz tę opcję, jeśli Twój interfejs jest zdolny do dekodowania strumieni TrueHD."
+msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające wspiera dekodowanie strumieni TrueHD."
 
 msgctxt "#36370"
 msgid "Select this option if your receiver is capable of decoding DTS-HD streams."
-msgstr "Wybierz tę opcję, jeśli Twój interfejs jest zdolny do dekodowania strumieni DTS-HD."
+msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające wspiera dekodowanie strumieni DTS-HD."
 
 msgctxt "#36371"
 msgid "Select the device to be used for playback of audio that has been decoded such as mp3"
@@ -12051,7 +12123,7 @@ msgstr "Wybierz interfejs, którego używasz do odtwarzania zdekodowanych format
 
 msgctxt "#36373"
 msgid "Configure how interface sounds are handled, such as menu navigation and important notifications."
-msgstr "Określ, jakie dodatkowe funkcje nawigacji w menu obsługuje Twój interfejs."
+msgstr "Określ sposób obsługi dźwięków interfejsu użytkownika takich, jak nawigacja i powiadomienia."
 
 msgctxt "#36374"
 msgid "No info available yet."
@@ -12107,7 +12179,7 @@ msgstr "Jeżeli masz ograniczoną przepustowość łącza, XBMC będzie starał
 
 msgctxt "#36387"
 msgid "Turn off display when idle. Useful for TVs that turn off when there is no display signal detected, but you don't want to suspend/shutdown the whole computer."
-msgstr "Wyłączaj wyświetlacz w trybie bezczynności. Zapobiega wyłączaniu się niektórych telewizorów przy braku sygnału wejściowego, gdy nie chcesz uśpić/wyłączyć komputera."
+msgstr "Wstrzymaj wyświetlanie w trybie bezczynności. Zapobiega wyłączaniu się niektórych telewizorów przy braku sygnału wejściowego, gdy nie chcesz uśpić/wyłączyć komputera."
 
 msgctxt "#36388"
 msgid "No info available yet."
@@ -12119,7 +12191,7 @@ msgstr "Określ czas bezczynności przed zamknięciem XBMC."
 
 msgctxt "#36390"
 msgid "Define what action XBMC should do when it has been idle for a long period of time."
-msgstr "Określ jakie działania XBMC powinien podjąć podczas długiej bezczynności."
+msgstr "Określ czynność jaką XBMC powinien wykonać po długim czasie bezczynności."
 
 msgctxt "#36391"
 msgid "Turn debug logging on or off. Useful for troubleshooting."
@@ -12249,25 +12321,33 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Włącz sprzętowe dekodowanie wideo dekodera AMLogic"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Używaj wielowątkowego dekodowania zamiast dekodowania wykorzystującego akcelerację sprzętową (mniej stabilne niż domyślny tryb jednowątkowy)"
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
-msgstr "Określ akcję wykonywaną po wybraniu pozycji w Przewodniku TV: [Pokazuj menu] wyświetli menu kontekstowe z dodatkowymi akcjami; [Wybierz kanał] przełączy natychmiast na wybrany kanał; [Pokazuj informacje] wyświetli szczegółowe informacje z fabułą i dodatkowymi opcjami; [Nagrywaj] stworzy zaplanowane nagrywanie wybranej pozycji."
+msgstr "Wybierz czynność wykonywaną po wybraniu pozycji w Przewodniku TV: [Pokaż menu] wyświetli menu kontekstowe z dodatkowymi akcjami; [Przełącz kanał] przełączy natychmiast na wybrany kanał; [Pokaż informacje] wyświetli szczegółowe informacje z fabułą i dodatkowymi opcjami; [Nagraj] stworzy zaplanowane nagrywanie wybranej pozycji."
 
 msgctxt "#36425"
 msgid "Show context menu"
-msgstr "Pokaż menu kontekstowe"
+msgstr "Pokaż menu"
 
 msgctxt "#36426"
 msgid "Switch to channel"
-msgstr "Wybierz kanał"
+msgstr "Przełącz kanał"
 
 msgctxt "#36427"
 msgid "Show information"
-msgstr "Pokaż informację"
+msgstr "Pokaż informacje"
 
 msgctxt "#36428"
 msgid "Record"
-msgstr "Nagrywaj"
+msgstr "Nagraj"
+
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Zaznacz tę opcję, jeśli podłączone urządzenie audio wspiera dźwięk wielokanałowy tylko w formacie Dolby Digital 5.1. Umożliwi to odtwarzanie dźwięku w formatach AAC5.1 i FLAC5.1 w systemie dźwięku przestrzennego 5.1.  Uwaga - transkodowanie może prowadzić do obniżenia jakości dźwięku."
 
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
@@ -12279,7 +12359,7 @@ msgstr "Tryb stereoskopowy "
 
 msgctxt "#36502"
 msgid "None"
-msgstr "Żaden "
+msgstr "Brak"
 
 msgctxt "#36503"
 msgid "Over/Under"
@@ -12361,6 +12441,10 @@ msgctxt "#36532"
 msgid "Same as movie"
 msgstr "Tak samo jak film "
 
+msgctxt "#36533"
+msgid "Select how audio is downmixed, for example from 5.1 to 2.0: [Enabled] maintains the dynamic range of the original audio source when downmixed however volume will be lower [Disabled] maintains volume level of the original audio source however the dynamic range is compressed. Note - Dynamic range is the difference between the quietest and loudest sounds in a audio source."
+msgstr "Wybierz jak dźwięk jest miksowane w dół, na przykład z 5.1 do 2.0: [Włączone] utrzymuje podczas miksowania rozpiętość tonalna pierwotnego źródła dźwięku, ale obniża poziom głośności; [Wyłączone] utrzymuje poziom głośności oryginalnego źródła dźwięku, ale rozpiętość tonalna będzie mniejsza. Uwaga - rozpiętość tonalna jest różnicą pomiędzy najcichszym i najgłośniejszym tonem w źródle dźwięku."
+
 msgctxt "#36535"
 msgid "Stereoscopic mode of video"
 msgstr "Stereoskopowy tryb wideo "
@@ -12387,7 +12471,7 @@ msgstr "Brak dostępnych informacji. "
 
 msgctxt "#36541"
 msgid "Allows volume control from AirPlay clients."
-msgstr "Zezwól na regulację głośności za pośrednictwem klientów AirPlay. "
+msgstr "Zezwalaj klientom AirPlay  na regulację głośności. "
 
 msgctxt "#36542"
 msgid "Output to both analogue (headphones) and HDMI"
@@ -12451,7 +12535,7 @@ msgstr "Znajdź w"
 
 msgctxt "#37016"
 msgid "Select this option if your receiver is capable of decoding E-AC3 streams."
-msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające potrafi dekodować strumienie AC3."
+msgstr "Wybierz tę opcję, jeśli urządzenie odtwarzające wspiera dekodowanie strumieni E-AC3."
 
 msgctxt "#37017"
 msgid "Dual audio output"
@@ -12467,8 +12551,16 @@ msgstr "Włącza klawisze systemowe takie jak Print Screen, Alt-Tab i regulacji
 
 msgctxt "#37020"
 msgid "Enable higher colour depth artwork"
-msgstr "Włącz większą głębie koloru grafik"
+msgstr "Zwiększaj głębię koloru grafik"
 
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
-msgstr "Limit rozdzielczości interfejsu"
+msgstr "Ustaw limit rozdzielczości interfejsu"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Klient UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Chcesz zatrzymać odtwarzanie na zdalnym urządzeniu?"
index d87b1fe..209ee3d 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Selecionar diretório de destino"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Estéreo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Número de canais"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Log detalhado..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Ativar transcodificação Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Limpando a coleção"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Permitir aceleração por hardware (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Permitir decodificação de múltiplos segmentos de frames"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Método de syncronização de A/V"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Gravações da TV"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Pasta padrão para logos de canais PVR"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Canais"
@@ -6183,7 +6199,11 @@ msgstr "Ir para o fim"
 
 msgctxt "#19065"
 msgid "Default EPG window"
-msgstr "Janela padrão EPG"
+msgstr "Janela padrão do EPG"
+
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Logos dos canais"
 
 msgctxt "#19067"
 msgid "This event is already being recorded."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Confirme a troca de canais pressionando ok"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Logo Atual"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Sem logo do canal"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Escolha o logo do canal"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Procurar por logo do canal"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Outro/Desconhecido"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motores"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Saúde e Fitness"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cozinhando"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Língua Original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Preto &amp; Branco"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Não publicado"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Buscando músicas com %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Enredo do filme"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Reproduzir parte..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Remover compartilhamento de mídia"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Pasta de legendas customizada"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Filme & diretório de legenda alternativo"
@@ -8911,7 +8947,7 @@ msgstr "Saída de vídeo"
 
 msgctxt "#21374"
 msgid "Video aspect"
-msgstr "Relação de aspecto"
+msgstr "Aspecto de vídeo"
 
 msgctxt "#21375"
 msgid "Normal"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "Mixado"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Local da Legenda na tela"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fixado"
@@ -9687,7 +9727,7 @@ msgstr "Guia"
 
 msgctxt "#22021"
 msgid "Allowed error in aspect ratio to minimise black bars"
-msgstr "Permitir erro na relação de aspecto para minimizar as barras pretas"
+msgstr "Permitir Erro na relação de aspecto para minimizar barras pretas"
 
 msgctxt "#22022"
 msgid "Show video files in listings"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Selecione item que será reproduzido"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Capítulos: %u - duração: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Reprodução do Blu-ray falhou"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "O menu para este disco Blu-ray não é suportado atualmente"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Modo de coleção"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canais"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11255,7 +11311,7 @@ msgstr "Selecione a qualidade de reamostragem para casos em que a saída de áud
 
 msgctxt "#36170"
 msgid "Allow video player to ignoring aspect ratio by a certain amount to fill a larger amount of the screen with video."
-msgstr "Permitir que o reprodutor de vídeo ignore relação de aspecto até uma certa quantidade, de modo a preencher com o vídeo uma área maior da tela."
+msgstr "Permitir que o reprodutor de vídeo ignore relação de aspecto até uma certa quantidade, de modo a preencher com o vídeo uma área maior da tela."
 
 msgctxt "#36171"
 msgid "Select the zoom level that 4:3 videos are shown on widescreen displays."
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Selecione como as propriedades de saída de áudio são definidas: [fixo] - propriedades de saída são definidas pela taxa de amostragem especificada e configuração dos alto-falantes e irão ser iguais em todos os momentos [Melhor Compatibilidade] - propriedades de saída serão ajustados para respeitarem as características das fontes, sempre que possível; [Otimizado] - propriedades de saída são definidas no início da reprodução e não irão mudar se ocorrerem alterações nas fontes."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Selecione o número de canais suportado pela conexão de áudio, ou o número de alto-falantes se conectado via analógica. Este ajuste não se aplica ao áudio passthrough. Nota - SPDIF suporta 2.0 canais somente, mas ainda pode levar áudio multicanal usando um formato suportado pelo passthrough."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Ampliar os fluxos AC3 que foram misturados para 2 canais"
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Selecione para ativar upmixing de fonte de 2 canais de áudio para o número de canais de áudio especificados na configuração de alto-falantes."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Selecione esta opção se o seu receiver consegue decodificar trilhas AC3."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Ativar decodificação de vídeo por hardware usando decoder AMLogic"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Usar a decodificação de segmentos múltiplos ao invés da decodificação acelerada via hardware. (Menos confiável do que o modo padrão de decodificação única)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "lecione o que vai acontecer quando um item é selecionado EPG: [Mostrar menu de contexto] irá acionar o menu contextual aonde você poderá escolher novas ações; [Mudar para o canal] irá imediatamente sintonizar o canal selecionado; [Mostrar informações] irá mostrar informações detalhadas como enredo e outras opções; [Gravar] criará um temporizador de gravação para o item selecionado."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Gravar"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Selecione isto se a conexão de saída de áudio somente suporte áudio multicanal como Dolby Digital 5.1. Isso permite áudio áudio multicanal, como AAC5.1 ou FLAC5.1 serem ouvidos em som surround 5.1. Nota - transcodificar pode gerar uma redução na qualidade do som"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Modo estereoscópico (atual)"
@@ -12484,3 +12556,11 @@ msgstr "Ativar maior profundidade nas cores dos artworks"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Setar o limite para resolução da interface gráfica"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP Player"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Deseja parar a reprodução no dispositivo remoto?"
index ec0de3d..a1dc94b 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Seleccionar pasta de destino"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Remistura estéreo aumentada"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Número de canais"
@@ -1423,7 +1427,7 @@ msgstr "Névoa"
 
 msgctxt "#396"
 msgid "Select location"
-msgstr "Seleccione o local"
+msgstr "Local"
 
 msgctxt "#397"
 msgid "Refresh time"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Registo Verbose..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Activar transcodificação Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Limpando a Biblioteca"
@@ -3695,11 +3703,11 @@ msgstr "Música - Biblioteca"
 
 msgctxt "#10517"
 msgid "Now Playing - Music"
-msgstr "A reproduzir - Música"
+msgstr "Em reprodução - Música"
 
 msgctxt "#10522"
 msgid "Now Playing - Videos"
-msgstr "A reproduzir - Vídeo"
+msgstr "Em reprodução - Vídeo"
 
 msgctxt "#10523"
 msgid "Album info"
@@ -4667,7 +4675,7 @@ msgstr "Procurar novo conteúdo"
 
 msgctxt "#13350"
 msgid "Now playing..."
-msgstr "A reproduzir agora..."
+msgstr "Em reprodução..."
 
 msgctxt "#13351"
 msgid "Album information"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Permitir aceleração por hardware (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Activar descodificação de frames multi-tarefa"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Método de sincronia A/V"
@@ -5019,7 +5031,7 @@ msgstr "Sincronizar vídeo com ecrã"
 
 msgctxt "#13511"
 msgid "Choose art"
-msgstr "Escolher imagem"
+msgstr "Imagem"
 
 msgctxt "#13512"
 msgid "Current art"
@@ -5599,7 +5611,7 @@ msgstr "Pesquisa Internet"
 
 msgctxt "#16003"
 msgid "Player"
-msgstr "Reprodutor"
+msgstr "Leitor"
 
 msgctxt "#16004"
 msgid "Play media from disc"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Gravações de TV"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Pasta com ícones de canais"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Canais"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Janela padrão de PVR"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Ícones de canais"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Este evento já está a ser gravado"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Confirmar mudanças de canal premindo OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Ícone actual"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Sem ícone"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Escolher ícone"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Procurar ícone"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Outro/Desconhecido"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Desportos Motorizados"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Forma Física/Saúde"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Culinária"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Idioma original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Preto / Branco"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Não editado"
@@ -7371,11 +7399,11 @@ msgstr "Pasta para guardar músicas"
 
 msgctxt "#20001"
 msgid "Use external DVD player"
-msgstr "Usar reprodutor DVD externo"
+msgstr "Usar leitor DVD externo"
 
 msgctxt "#20002"
 msgid "External DVD player"
-msgstr "Reprodutor DVD externo"
+msgstr "Leitor DVD externo"
 
 msgctxt "#20003"
 msgid "Trainers folder"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Pesquisando álbuns em %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Enredo do filme"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Reproduzir parte ..."
@@ -8863,7 +8895,7 @@ msgstr "Partilhar vídeos e música através de UPnP"
 
 msgctxt "#21361"
 msgid "Look for remote UPnP players"
-msgstr "Procurar reprodutores UPnP remotos"
+msgstr "Procurar leitores UPnP remotos"
 
 msgctxt "#21362"
 msgid "Bookmark created"
@@ -8881,13 +8913,17 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Remover partilha de conteúdo"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Pasta de legendas personalizada"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Pasta alternativa de vídeo e legendas"
 
 msgctxt "#21368"
 msgid "Override ASS/SSA subtitles fonts"
-msgstr "Ignorar os tipos de letra em legendas ASS/SSA"
+msgstr "Ignorar tipos de letra em legendas ASS/SSA"
 
 msgctxt "#21369"
 msgid "Enable mouse and Touch Screen support"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mistura"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Posição das legendas no ecrã"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fixa"
@@ -9563,7 +9603,7 @@ msgstr "Escolha o artista"
 
 msgctxt "#21891"
 msgid "Artist information"
-msgstr "Informação do artista"
+msgstr "Informação de artista"
 
 msgctxt "#21892"
 msgid "Instruments"
@@ -9807,11 +9847,11 @@ msgstr "Colocar a escala do Teletexto como 4:3"
 
 msgctxt "#23100"
 msgid "External Player Active"
-msgstr "Reprodutor externo activo"
+msgstr "Leitor externo activo"
 
 msgctxt "#23101"
 msgid "Click OK to terminate the player"
-msgstr "Seleccione OK para encerrar o reprodutor"
+msgstr "Seleccione OK para encerrar o leitor"
 
 msgctxt "#23104"
 msgid "Click OK when playback has ended"
@@ -9879,7 +9919,7 @@ msgstr "Informação de álbuns"
 
 msgctxt "#24017"
 msgid "Artist information"
-msgstr "Informação do artista"
+msgstr "Informação de artista"
 
 msgctxt "#24018"
 msgid "Services"
@@ -10151,7 +10191,7 @@ msgstr "O add-on é incompatível devido a dependências não encontradas."
 
 msgctxt "#24105"
 msgid "Pause when searching for subtitles"
-msgstr "Pausas ao procurar legendas"
+msgstr "Pausar ao procurar legendas"
 
 msgctxt "#24106"
 msgid "If not saved to movie folder subtitles will be downloaded to custom subtitle folder"
@@ -10211,7 +10251,7 @@ msgstr "Escolher o serviço que será usado como padrão ao procurar legendas de
 
 msgctxt "#24120"
 msgid "Manual search string"
-msgstr "Expressão de busca manual"
+msgstr "Procura manual"
 
 msgctxt "#24121"
 msgid "Enter search string"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Escolher item de reprodução"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Capítulos: %u - duração: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "A reprodução do disco Blu-ray falhou"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "O menu deste disco Blu-ray não é suportado"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Modo de Biblioteca"
@@ -10311,7 +10363,7 @@ msgstr "Longo"
 
 msgctxt "#33014"
 msgid "Use DVD player instead of regular player"
-msgstr "Usar reprodutor de DVD em vez do reprodutor normal"
+msgstr "Usar leitor de DVD em vez do leitor normal"
 
 msgctxt "#33015"
 msgid "Ask for download before playing video"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Áudio Windows Media 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canais"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11255,7 +11311,7 @@ msgstr "Seleccionar a qualidade de remasterização para casos em que a saída d
 
 msgctxt "#36170"
 msgid "Allow video player to ignoring aspect ratio by a certain amount to fill a larger amount of the screen with video."
-msgstr "Permitir que o reprodutor de vídeo ignore o rácio de aspecto por uma certa quantidade, de modo a preencher uma área maior do ecrã com o vídeo."
+msgstr "Permitir que o leitor de vídeo ignore o rácio de aspecto por uma certa quantidade, de modo a preencher uma área maior do ecrã com o vídeo."
 
 msgctxt "#36171"
 msgid "Select the zoom level that 4:3 videos are shown on widescreen displays."
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Seleccionar como as propriedades da saída de áudio são definidas: [Fixa] - as propriedades de saída são definidas para a mesma taxa de amostragem e configuração de colunas em todos os momentos; [Melhor Correspondência] - as propriedades de saída são definidas para serem sempre uma correspondência o mais aproximada possível às propriedades da fonte; [Optimizado] - as propriedades de saída são definidas no início da reprodução e não serão alteradas se as propriedades da fonte mudarem."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Seleccionar o número de canais suportados pela ligação áudio, ou o número de colunas disponível através de ligação analógica. Esta definição não se aplica a áudio de passagem. Nota - a ligação SPDIF suporta apenas 2.0 canais, mas mesmo assim pode emitir áudio multi-canal usando um formato suportado pelo áudio de passagem."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Aumentar volume em pistas AC3 que foram remisturadas para 2 canais."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Seleccionar para activar a remistura aumentada de 2 canais de áudio para o número de canais áudio especificados na configuração das colunas."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Seleccione esta opção se o seu receptor consegue descodificar pistas AC3."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Activa a descodificação por hardware com o descodificador AMLogic"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Usar descodificação de frames multi-tarefa em vez de descodificação por hardware (menos fiável do que o modo padrão de tarefa única)"
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Seleccionar o que acontece quando um item do EPG é seleccionado: [Exibir Menu de Contexto] irá exibir o menu de contexto, de onde poderá escolher outras acções.; [Mudar Para Canal] irá sintonizar imediatamente o canal relacionado; [Exibir Informação] exibirá informação detalhada, com argumento e mais opções; [Gravar] irá criar um temporizador de gravação para o item seleccionado."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Gravar"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Seleccionar se a ligação de saída áudio suporta apenas áudio multi-canal como o Dolby Digital 5.1. Isto permite que o áudio multi-canal como o AAC5.1 ou o FLAC5.1 possa ser ouvido em som surround 5.1. Nota - a transcodificação pode resultar numa menor qualidade de som."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Modo estereoscópico (actual)"
@@ -12484,3 +12556,11 @@ msgstr "Activar artwork com maior profundidade de cor"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Definir limite de resolução da interface"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Leitor UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Quer parar a reprodução no dispositivo remoto?"
index e4c8a65..f24626b 100644 (file)
@@ -6741,10 +6741,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automobilism"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness și sănătate"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Gătit"
@@ -6765,10 +6761,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Limbă originală"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Alb-negru"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Nepublicat"
@@ -9817,6 +9809,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Număr de canale"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 8ef2117..17e637f 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Выберите папку назначения"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Стерео на все каналы"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Количество каналов"
@@ -4973,6 +4977,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Включить аппаратное ускорение (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Многопоточное декодирование видео"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Синхронизация А/В"
@@ -7293,10 +7301,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Авто-мото"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Фитнес и здоровье"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Кулинария"
@@ -7317,10 +7321,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Оригинальный язык"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Ч/Б"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Неопубликованное"
@@ -10601,6 +10601,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Количество каналов"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 342cd0a..64a2ead 100644 (file)
@@ -7485,6 +7485,10 @@ msgctxt "#34003"
 msgid "DXVA2"
 msgstr "DXVA"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Број канала"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index c73b8c9..4b16020 100644 (file)
@@ -7681,6 +7681,10 @@ msgctxt "#34003"
 msgid "DXVA2"
 msgstr "DXVA"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Broj kanala"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index dcb637f..706670d 100644 (file)
@@ -7285,10 +7285,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motorizmus"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Zdravie a fitness"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Varenie"
@@ -7309,10 +7305,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "V pôvodnom znení"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Čiernobiely"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Nepublikovaný"
@@ -10581,6 +10573,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Počet kanálov"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index c5f74ab..d142fd5 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Izberite ciljno mapo"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Stereo upmix"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Število kanalov"
@@ -2389,6 +2393,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Podrobno zapisovanje ..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Omogoči Dolby Digital transcoding"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Čiščenje knjižnice"
@@ -4229,6 +4237,10 @@ msgctxt "#13121"
 msgid "VDPAU HQ Upscaling level"
 msgstr "Nivo zviševanja ločljivosti VDPAU HQ"
 
+msgctxt "#13122"
+msgid "VDPAU Studio level colour conversion"
+msgstr "VDPAU Studijska stopnja pretvorba barv"
+
 msgctxt "#13123"
 msgid "Keep skin?"
 msgstr "Ali želite obdržati preobleko?"
@@ -4941,6 +4953,10 @@ msgctxt "#13436"
 msgid "Allow hardware acceleration (libstagefright)"
 msgstr "Dovoli strojno pospeševanje (libstagefright)"
 
+msgctxt "#13437"
+msgid "Prefer VDPAU Video Mixer"
+msgstr "Raje uporabi VDPAU Video mešalnik"
+
 msgctxt "#13438"
 msgid "Allow hardware acceleration (amcodec)"
 msgstr "Dovoli strojno pospeševanje (amcodec)"
@@ -4949,6 +4965,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Dovoli strojno pospeševanje (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Omogoči okvirno večnivojsko dekodiranje"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Metoda sinhroniziranja A/V"
@@ -5969,6 +5989,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV posnetki"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Mapa z ikonami kanala"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Programi"
@@ -6157,6 +6181,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Privzeto okno EPG"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Ikone kanala"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Ta dogodek se že snema."
@@ -6973,6 +7001,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Potrdi preklop programov s pritiskom na OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Trenutna ikona"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Brez ikone"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Izberite ikono"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Prebrskajte za ikono"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Drugo/Neznano"
@@ -7257,10 +7301,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Avtomobilizem"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Kondicija &amp; Zdravje"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Kuhanje"
@@ -7281,10 +7321,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Jezik izvirnika"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Črno-belo"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Neobjavljeno"
@@ -8197,6 +8233,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Pregledujem albume z %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Zgodba filma"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Predvajaj odlomek ..."
@@ -8841,6 +8881,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Odstrani skupno rabo"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Poljubna mapa za podnapise"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Mapa s filmom & dodatnimi podnapisi"
@@ -9209,6 +9253,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mešano"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Položaj podnapisov na ekranu"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fiksno"
@@ -10169,6 +10217,10 @@ msgctxt "#24119"
 msgid "Select service that will be used as default to search for Movie subtitles"
 msgstr "Izberite storitev, ki se bo uporabljala kot privzeta za iskanje podnapisov za filme"
 
+msgctxt "#24120"
+msgid "Manual search string"
+msgstr "Ročno iskalni niz"
+
 msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Vnesite iskalni niz"
@@ -10201,6 +10253,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Izberite predmet predvajanja"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Poglavja: %u - trajanje: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Predvajanje Blu-ray diska je spodletelo"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Meni tega Blu-ray diska ni podprt"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Način knjižnice"
@@ -10557,6 +10621,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Število kanalov"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -11377,6 +11445,10 @@ msgctxt "#36219"
 msgid "Default EPG window to show. Defaults to Timeline."
 msgstr "Privzeto prikazano okno programskega vodiča. Privzeta vrednost je časovnica."
 
+msgctxt "#36220"
+msgid "Number of days of EPG data to import from backends. Defaults to 3 days."
+msgstr "Število dni programskega vodiča, ki se uvozi iz hrbtenice. Privzeta vrednost je 3 dni."
+
 msgctxt "#36221"
 msgid "Time between EPG data imports from backends. Defaults to 120 minutes."
 msgstr "Čas med posameznimi uvozi programskega vodiča iz hrbtenic. Privzeta vrednost je 120 minut."
@@ -11873,6 +11945,10 @@ msgctxt "#36356"
 msgid "Eliminate vertical tearing."
 msgstr "Odpravi vertikalno solzenje."
 
+msgctxt "#36357"
+msgid "Calibrate the User Interface by adjusting the overscan. Use this tool if the image being displayed is too large or small for your display."
+msgstr "Umerjanje uporabniškega vmesnika s spreminjanjem vrednosti prekrivanja. To orodje uporabite, če je prikazana slika prevelika ali premajhna za vaš zaslon."
+
 msgctxt "#36358"
 msgid "Test patterns for display hardware calibration."
 msgstr "Testni vzorec za umerjanje strojne opreme."
@@ -11985,6 +12061,10 @@ msgctxt "#36393"
 msgid "Folder used to save screenshots taken within XBMC."
 msgstr "Mapa za shranjevanje namiznih slik, zajetih z XBMC-jem."
 
+msgctxt "#36394"
+msgid "Specify additional libraries to be included in the debug log."
+msgstr "Določite dodatne knjižnice ki bodo vključene  v razhroščevalni zapisnik."
+
 msgctxt "#36396"
 msgid "Define the PIN code used for the master lock."
 msgstr "Določite PIN kodo, ki se uporablja za glavni zaklep."
@@ -12237,6 +12317,10 @@ msgctxt "#36546"
 msgid "Sets the visual depth of subtitles for stereoscopic videos. The higher the value, the closer the subtitles will appear to the viewer."
 msgstr "Nastavi vizualno globino podnapisov za stereoskopske video posnetke.Višja kot je vrednost, bližje bodo vidni podnapisi."
 
+msgctxt "#36547"
+msgid "Use higher quality textures for covers and fanart (uses more memory)"
+msgstr "Uporabi višjo kakovost teksture za ovitke in grafike (uporablja več pomnilnika)"
+
 msgctxt "#36548"
 msgid "Limits resolution of GUI to save memory. Does not affect video playback. Use 1080 for unlimited. Requires restart."
 msgstr "Omeji ločljivost grafičnega uporabniškega vmesnika za prihranitev pomnilnika. Ne vpliva na predvajanje videa. Uporabite 1080 za neomejeno. Zahteva ponovni zagon."
@@ -12296,3 +12380,11 @@ msgstr "Omogoči grafično podobo z višjo barvno globino"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Nastavi omejitev ločljivosti grafičnega uporabniškega vmesnika"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP Predvajalnik"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Želite ustaviti predvajanje na oddaljeni napravi?"
index 9b64b8a..6251875 100644 (file)
@@ -6737,10 +6737,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automovilismo"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Salud"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cocina"
@@ -6761,10 +6757,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Idioma Original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Blanco &amp; Negro"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Inédito"
@@ -9813,6 +9805,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canales"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 09ea4b0..94db478 100644 (file)
@@ -7157,10 +7157,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automovilismo"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Ejercicio &amp; Salud"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cocina"
@@ -7181,10 +7177,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Lenguaje Original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Blanco &amp; Negro"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Inedito"
@@ -10349,6 +10341,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canales"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index a5ee533..da73c1c 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Seleccione el directorio destino"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Mezcla estereo"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Número de canales"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Registro detallado..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Habilitar transcodificación digital Dolby "
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Limpiar la colección"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Permitir aceleración de hardware (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Permitir decodificación multihilo"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Método sincronización de A/V"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Grabaciones de TV"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Carpeta con iconos de canales"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Canales"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Vista de EPG por defecto"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Iconos de canal"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Este evento ya se está grabando."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Confirmar el cambio de canal pulsando OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Icono actual"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Sin icono"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Elegir icono"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Buscar por icono"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Otros/Desconocido"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Automovilismo"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; Salud"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Cocina"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Idioma Original"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Blanco &amp; Negro"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Inédito"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Analizando la música usando %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Sinopsis de película"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Reproducir fragmento..."
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Eliminar recurso compartido"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Carpeta personalizada de subtítulos"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Directorio de los subtítulos de películas y otros"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "mezclado"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Ubicación de los subtítulos en la pantalla"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fijo"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Seleccione elemento a reproducir"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Capítulos: %u - duración: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Fallo en la reproducción del disco Blu-ray"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "El menú de este disco Blu-ray no está soportado"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Modo Colección"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Número de canales"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Seleccionar como se establecen las opciones de salida de audio: [Fijo] - las propiedades de salida se establecen a una frecuencia de muestreo especificada y a la configuración de los altavoces siempre; [Mejor opción] - las propiedades de salida se establecen para parecerse lo más posible a las propiedades de la fuente; [Optimizado] - las propiedades de salida se establecen al inicio de la reproducción y no cambiarán aunque varien las propiedades de la fuente de sonido-"
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Seleccione el número de canales soportados por la conexión de audio, o el número de altavoces si están conectados mediante conexiones analógicas. Este ajuste no se aplica en passthrough.\nNota - SPDIF soporta canales 2.0 solamente, pero se puede sacar audio multicanal usando un formato soportado por passthrough."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Amplificar streams AC3 que han sido reducidos a 2 canales."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Seleccionar para permitir mezclado de 2 canales de audio para el número de canales de audio especificados por la configuración de altavoces."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Selecciona esta opción si tu receptor puede decodificar streams AC3."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Habilitar decodificación de vídeo por hardware usando decodificador AMLogic."
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Utilice decodificación multi-hilo en lugar de decodificación acelerada por hardware (menos fiable que el modo de un solo hilo por defecto)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Seleccione lo que sucederá cuando un elemento de la EPG está seleccionado: [Mostrar menú contextual] activará el menú contextual desde el que puede elegir otras acciones; [Cambiar a canal] instantáneamente sintonice el canal correspondiente; [Mostrar información] mostrará información detallada con el argumento y otras opciones; [Record] creará un temporizador de grabación para el elemento seleccionado."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Grabar"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Seleccione esta opción si la salida de audio de la conexión sólo es compatible con audio multicanal como Dolby Digital 5.1, esto permite que el audio multicanal como AAC5.1 o FLAC5.1  se escuche en sonido envolvente 5.1.\nNota - la transcodificación puede conducir a una reducción en la calidad de sonido"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Modo 3D (actual)"
@@ -12484,3 +12556,11 @@ msgstr "Habilitar mayor profundidad de color en artwork"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Establecer resolución de la interfaz de usuario"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Reproducir UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "¿Desea detener la reproducción en el dispositivo remoto?"
index fb1cf0f..b57e911 100644 (file)
@@ -1185,6 +1185,10 @@ msgctxt "#336"
 msgid "Framerate conversion"
 msgstr "Justera bildfrekvens"
 
+msgctxt "#337"
+msgid "Output configuration"
+msgstr "Konfiguration av utsignal"
+
 msgctxt "#338"
 msgid "Fixed"
 msgstr "Fast"
@@ -2397,6 +2401,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Detaljerad loggning..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Aktivera Dolby Digital-transkodning"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Städar bibliotek"
@@ -5885,6 +5893,10 @@ msgctxt "#16325"
 msgid "VDPAU - Bob"
 msgstr "VDPAU - Bob"
 
+msgctxt "#16326"
+msgid "DXVA-HD"
+msgstr "DXVA-HD"
+
 msgctxt "#16400"
 msgid "Post-processing"
 msgstr "Efterbearbetning"
@@ -5977,6 +5989,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV-inspelningar"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Mapp med kanalikoner"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanaler"
@@ -6165,6 +6181,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Standard EPG-fönster"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanalikoner"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Denna händelse spelas redan in."
@@ -6981,6 +7001,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Bekräfta kanalbyte genom att trycka OK"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Nuvarande ikon"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Ingen ikon"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Välj ikon"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Bläddra bland ikoner"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Annan/Okänd"
@@ -7265,10 +7301,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Trafik"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitness &amp; hälsa"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Matlagning"
@@ -7289,10 +7321,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Originalspråk"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Svart/vit"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Opublicerat"
@@ -8201,6 +8229,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Skannar album med %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Filmhandling"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Spela del..."
@@ -9213,6 +9245,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "blandad"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Undertextens placering på skärmen"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Fast"
@@ -10137,6 +10173,10 @@ msgctxt "#24111"
 msgid "Languages to download subtitles for"
 msgstr "Språk att ladda ner undertexter för"
 
+msgctxt "#24112"
+msgid "Set languages to use when searching for subtitles. Not all subtitle services will use all languages."
+msgstr "Välj språk som används vid undertextsökningar. Alla undertexttjänster stöder inte alla språk."
+
 msgctxt "#24113"
 msgid "Failed to download subtitle"
 msgstr "Misslyckades att ladda ner undertexter"
@@ -10149,6 +10189,18 @@ msgctxt "#24115"
 msgid "Save subtitles to movie folder"
 msgstr "Spara undertexter till film-mappen"
 
+msgctxt "#24116"
+msgid "Default TV Service"
+msgstr "Standard-TV-service"
+
+msgctxt "#24118"
+msgid "Default Movie Service"
+msgstr "Standard-filmservice"
+
+msgctxt "#24120"
+msgid "Manual search string"
+msgstr "Manuell söksträng"
+
 msgctxt "#24121"
 msgid "Enter search string"
 msgstr "Ange söksträng"
@@ -10181,6 +10233,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Välj uppspelningsobjekt"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Kapitel: %u - Längd: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Uppspelning av Blu-ray misslyckades"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Menyn på den här Blu-ray-skivan stöds inte"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Biblioteksläge"
@@ -10537,6 +10601,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Antal kanaler"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10725,6 +10793,10 @@ msgctxt "#35102"
 msgid "Disable joystick when this device is present"
 msgstr "Inaktivera joystick när denna enhet är närvarande"
 
+msgctxt "#35103"
+msgid "Enable system keys in fullscreen"
+msgstr "Tillåt systemknappar att användas i fullskärmsläge"
+
 msgctxt "#35500"
 msgid "Location"
 msgstr "Plats"
@@ -12344,3 +12416,15 @@ msgstr "Dubbel ljudutgång"
 msgctxt "#37018"
 msgid "Boost centre channel when downmixing"
 msgstr "Höj centerkanalen vid nedmixing"
+
+msgctxt "#37019"
+msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
+msgstr "Tillåt systemknappar som PrtScn, Alt-Tab och volymknappar att användas i fullskärmsläge"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP-spelare"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Vill du stoppa fjärruppspelning?"
index d429bb3..ba3d540 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "Интихоби директорияи ҷои таъинот"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "Омезиши стереоӣ"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "Миқдори шабакаҳо"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "Сабти рӯйдодҳои ботафсил..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "Фаъол кардани рамзгузории Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "Поксозии китобхона…"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "Фаъол кардани шитоби сахтафзор (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "Иҷозат додани рамзкушоии видео бо якҷанд ҷараён"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "Усули ҳамоҳангсозии A/V"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "Сабтҳои ТВ"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Ҷузвдон бо нишонаҳои шабакаҳо"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Шабакаҳо"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Равзанаи EPG-и пешфарз"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Нишонаҳои шабакаҳо"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Ин рӯйдод аллакай сабт шуда истодааст."
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Тасдиқ кардани гузаришҳо ба шабакаҳо бо зеркунии тугмаи \"ОК\""
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Нишонаи ҷорӣ"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Бе нишона"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Интихоби нишона"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Тамошо кардани нишона"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Дигар/Номаълум"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Авто-мото"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Фитнес ва саломатӣ"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Хӯрокпазӣ"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Забони аслӣ"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Сиёҳу сафед"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Нашрнашуда"
@@ -8237,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Ҷустуҷӯи албомҳо ба воситаи %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Сужети филм"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "Пахш кардани қисм…"
@@ -8881,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Тоза кардани манбаи медиа"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Ҷузвдони зерунвонҳои фармоишӣ"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Директорияи филмҳо ва зерунвонҳои иловагӣ"
@@ -9249,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "омехташуда"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Ҷойгиршавии зерунвонҳо дар экран"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Таъйиншуда"
@@ -10245,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Интихоби объект барои пахш"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Фаслҳо: %u - давомнокӣ: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Пахши диски Blu-ray қатъ шудааст"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Менюи диски Blu-ray дастгирӣ намешавад"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Ҳолати китобхона"
@@ -10601,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Аудиои Windows Media 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Миқдори шабакаҳо"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12021,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "Интихоб кунед, ки чӣ тавр хусусиятҳои барориши аудио кор мекунанд: [Fixed] - хусусиятҳои барориш ҳамеша басомади садои муайян ва танзимоти динамикҳоро истифода мекунад; [Best Match] - хусусиятҳои барориш ҳамеша хуусиятҳои манбаро истифода мекунанд; [Optimized] - хусусиятҳои барориш дар оғози пахш танзим мешаванд ва тағйир дода намешавнд, агар хусусиятҳои манба тағйир дода нашаванд."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "Миқдори шабакаҳоеро, ки бо пайвасти аудиоӣ дастгирӣ мешавад, интихоб кунед, ё миқдори динамикҳоеро, ки ба пайвастҳои аналогӣ пайваст шудаанд, интихоб намоед. Ин танзимот ба интиқоли аудиоӣ тааллуқ надорад. Тавзеҳ: SPDIF танҳо шабакаҳои 2.0-ро дастгирӣ мекунад, вале метавонад аудиоро бо якчанд шабака тавассути интиқоли форматҳои мувофиқ пахш кунад."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "Афзудани баландии садои роҳчаҳои AC3 ҳангоми омезиши шабака то сатҳи стерео (2 шабака)."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "Интихоб кунед, агар хоҳед, ки омезиши аудиоиро бо 2 шабака барои миқдори шабакаҳои аудиоии муайяншуда дар танзимоти динамикҳо фаъол кунед."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "Ин имконотро интихоб кунед, агар ресивери шумо тавонад ҷараёнҳои AC3-ро рамзкушоӣ кунад."
@@ -12257,6 +12321,10 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "Фаъол кардани рамзгузори сахтафзории видеоӣ тавассути рамзгузори AMLogic."
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "Истифодаи рамзкушоии видео бо якчанд ҷараён ба ивази рамзкушоии сахтафзории тез (нисбат ба ҳолати видеои як ҷараёни пешфарз ин имконият бо устувори пасттар аст)."
+
 msgctxt "#36424"
 msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
 msgstr "Амалро барои объекти интихобшудаи EPG интихоб намоед: [Намоиши менюи марбут] менюи марбутро барои интихоби амалҳои иловагӣ намоиш медиҳад; [Гузариш ба канал] канали марбутро дарҳол танзим мекунад; [Намоиши иттилоот] иттилооти ботафсилро бо сужет ва имконоти иловагӣ намоиш медиҳад; [Сабт] вақтсанҷи сабтро барои объекти интихобшуда оғоз мекунад."
@@ -12277,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "Сабт"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "Ин имконро интихоб кунед, агар барориши пайвасти аудиоӣ, аудиоро бо якчанд шабака, монанди Dolby Digital 5.1 дастгирӣ кунад, ин имкон ба аудио бо якчанд шабака, монанди AAC5.1 ё FLAC5.1 иҷозат медиҳад, то ки тавонад дар садои гирдогирди 5.1 пахш карда шавад. Тавзеҳ: рамзгузори метавонад сифати садоро паст кунад."
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "Ҳолати стереоскопӣ (ҷорӣ)"
@@ -12484,3 +12556,11 @@ msgstr "Фаъол кардани тасвирзҳо бо ранги қаъри
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Танзими ҳудуди возеҳии интерфейси графикӣ"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "Плеери UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Шумо мехоҳед, ки пахшро дар дастгоҳи дурдаст манъ кунед?"
index a23ff2b..c33d18b 100644 (file)
@@ -6985,10 +6985,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "மோட்டாரிங்கு"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "உடற்பயிற்சி & உடல்நலம்"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "சமையல்"
@@ -7009,10 +7005,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "அசல் மொழி"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "கருப்பு &amp; வெள்ளை"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "வெளியிடப்படாத"
@@ -10141,6 +10133,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "தடங்களின் எண்ணிக்கை"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 58c3f44..09d0193 100644 (file)
@@ -869,6 +869,10 @@ msgctxt "#251"
 msgid "Select destination directory"
 msgstr "เลือกไดเร็คทอรีเป้าหมาย"
 
+msgctxt "#252"
+msgid "Stereo upmix"
+msgstr "ขยายช่องสัญญาณ สเตอริโอ"
+
 msgctxt "#253"
 msgid "Number of channels"
 msgstr "จำนวนของช่อง"
@@ -2401,6 +2405,10 @@ msgctxt "#666"
 msgid "Verbose logging..."
 msgstr "บันทึก โดยละเอียด..."
 
+msgctxt "#667"
+msgid "Enable Dolby Digital transcoding"
+msgstr "เปิดใช้ ส่งผ่านการเข้ารหัส Dolby Digital"
+
 msgctxt "#700"
 msgid "Cleaning up library"
 msgstr "ทำความสะอาดคลังข้อมูล"
@@ -4973,6 +4981,10 @@ msgctxt "#13439"
 msgid "Allow hardware acceleration (MediaCodec)"
 msgstr "เปิดใช้การเร่งความเร็วฮาร์ดแวร์ (MediaCodec)"
 
+msgctxt "#13440"
+msgid "Allow frame-multi-threaded decoding"
+msgstr "ยอมให้ใช้การถอดรหัส แบบหลายงานต่อเฟรม"
+
 msgctxt "#13500"
 msgid "A/V sync method"
 msgstr "กระบวนการ A/V sync"
@@ -5997,6 +6009,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "บันทึกทีวี"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "โฟลเดอร์ที่มีไอคอนช่องรายการ"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "ช่องสัญญาณ"
@@ -6185,6 +6201,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "ค่าเริ่มต้น หน้าต่าง EPG"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "ไอคอน ช่องรายการ"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "เหตุการณ์นี้ได้ถูกบันทึกไว้แล้ว"
@@ -7009,6 +7029,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "ยืนยันการเปลี่ยนช่อง โดยการกด ตกลง"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "ไอคอน ปัจจุบัน"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "ไม่มี ไอคอน"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "เลือก ไอคอน"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "เรียกดูไอคอน"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "อื่น ๆ / ไม่ทราบ"
@@ -7293,10 +7329,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "ยานยนต์"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "ออกกำลัง &amp; สุขภาพ"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "ทำอาหาร"
@@ -7317,10 +7349,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "ภาษาต้นฉบับ"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "ขาว &amp; ดำ"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "ไม่ถูกเผยแพร่"
@@ -8101,6 +8129,10 @@ msgctxt "#20220"
 msgid "Override song tags with online information"
 msgstr "แทนที่ tags เพลง ด้วยข้อมูลแบบออนไลน์"
 
+msgctxt "#20221"
+msgid "With this enabled, any information that is downloaded for albums and artists will override anything you have set in your song tags, such as genres, year, song artists etc. Useful if you have MusicBrainz identifiers in your song tags."
+msgstr "ด้วยการเปิดใช้ส่วนนี้, ทุกข้อมูลที่ถูกดาวน์โหลดสำหรับอัลบั้มและศิลปิน จะแทนที่ทุกอย่างที่คุณกำหนดไว้ในแท็กเพลง, อย่างเช่น ประเภท, ปี, ศิลปินเพลง อื่นๆ. มีประโยชน์ถ้าคุณมีการระบุไอดีของ MusicBrainz ในแท็กเพลงของคุณ."
+
 msgctxt "#20240"
 msgid "Android music"
 msgstr "เพลง Android"
@@ -8233,6 +8265,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "สำรวจอัลบั้มโดยใช้ %s"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "เรื่องย่อ ภาพยนตร์"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "ส่วนที่เล่น"
@@ -8877,6 +8913,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "สื่อที่แบ่งปัน"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "โฟลเดอร์คำบรรยายที่กำหนดเอง"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "ไดเร็กทอรี่ภาพยนต์ & คำบรรยายสำรอง"
@@ -9245,6 +9285,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "ผสม"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "ตำแหน่งของคำบรรยายบนหน้าจอ"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "ค่าแน่นอน"
@@ -10241,6 +10285,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "เลือกรายการที่เล่น"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "ที่คั่นหน้า: %u - ช่วงเวลา: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "การเล่น แผ่นบลูเรย์ ล้มเหลว"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "ไม่รองรับเมนูของแผ่นบลูเรย์นี้"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "โหมดคลังข้อมูล"
@@ -10597,6 +10653,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "เสียง Windows Media 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "จำนวนของช่อง"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -12017,10 +12077,18 @@ msgctxt "#36361"
 msgid "Select how the properties of the audio output are set: [Fixed] - output properties are set to the specified sampling rate & speaker configuration at all times; [Best Match] - output properties are set to always be as close a match to the source properties as possible; [Optimized] - output properties are set at the start of playback and will not change if the properties of the source changes."
 msgstr "เลือกวิธีการกำหนดค่าคุณสมบัติของสัญญาณเสียงออก: [ค่าแน่นอน] - คุณสมบัติการส่งสัญญาณออกจะถูกกำหนดเป็นอัตราสุ่มและการตั้งค่าลำโพงที่ระบุไว้ตลอด; [ตรงกันที่สุด] - คุณสมบัติการส่งสัญญาณออก มีการปรับอยู่เสมอ ให้ใกล้เคียงตรงกับคุณสมบัติต้นฉบับเท่าที่เป็นไปได้; [ปรับให้เหมาะสม] - คุณสมบัติการส่งสัญญาณออก จะปรับตอนเริ่มการเล่นและจะไม่เปลี่ยน แม้คุณสมบัติของต้นฉบับมีการเปลี่ยนแปลง."
 
+msgctxt "#36362"
+msgid "Select the number of channels supported by the audio connection, or the number of speakers if connected by analog connections. This setting does not apply to passthrough audio. Note - SPDIF supports 2.0 channels only but can still output multichannel audio using a format supported by passthrough."
+msgstr "เลือกจำนวนของช่องสัญญาณ ที่รองรับในการเชื่อมต่อสัญญาณเสียง, หรือจำนวนของลำโพง ในกรณีที่ใช้การเชื่อมต่อแบบอนาล็อก. การตั้งค่านี้จะไม่ถูกใช้ในการส่งผ่านเสียง. ข้อควรจำ - SPDIF รองรับ 2.0 ช่องสัญญาณ เท่านั้น แต่ยังคงสามารถส่งออกหลายช่องสัญญาณ โดยใช้รูปแบบการเข้ารหัสที่รองรับโดย การส่งผ่านเสียง."
+
 msgctxt "#36363"
 msgid "Boost AC3 streams that have been downmixed to 2 channels."
 msgstr "เพิ่มระดับเสียงของกระแสสัญญาณ AC3 ที่ได้ถูกรวมลงมาเป็น 2 ช่องเสียง."
 
+msgctxt "#36364"
+msgid "Select to enable upmixing of 2 channel audio to the number of audio channels specified by the speaker configuration."
+msgstr "เลือกเพื่อเปิดใช้ การแยกกระจายเสียง 2 ช่องสัญญาณ ไปตามจำนวนช่องสัญญาณเสียงที่ระบุ โดยการกำหนดค่าของลำโพง."
+
 msgctxt "#36365"
 msgid "Select this option if your receiver is capable of decoding AC3 streams."
 msgstr "เลือกตัวเลือกนี้ ถ้าเครื่องรับของคุณสามารถถอดรหัส กระแสเสียง AC3."
@@ -12253,6 +12321,14 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "เปิดใช้ การถอดรหัสด้วยฮาร์ดแวร์ โดยใช้ตัวถอดรหัส AMLogic"
 
+msgctxt "#36423"
+msgid "Use frame-multi-threaded decoding instead of hardware accelerated decoding (less reliable than default single thread mode)."
+msgstr "ใช้การถอดรหัสหลายงานในแต่ละเฟรม แทนการถอดรหัสแบบเร่งความเร็วด้วยฮาร์ดแวร์ (เชื่อถือได้น้อยกว่าค่าเริ่มต้นคือ โหมดงานเดี่ยว)"
+
+msgctxt "#36424"
+msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
+msgstr "เลือกการกระทำเมื่อรายการ EPG ถูกเลือก: [แสดงเมนูเนื้อหา] จะเปิดเมนูเนื้อหาจากการกระทำที่คุณสามารถเลือกใช้ต่อไป; [เปลียนไปยังช่องรายการ] จะปรับไปยังช่องรายการนั้นทันที; [แสดงข้อมูล] จะแสดงรายละเอียด ที่ประกอบด้วยเนื้อเรื่องย่อและตัวเลือกเพิ่มเติม; [บันทึก] จะสร้างตัวตั้งเวลาบันทึก สำหรับรายการที่เลือก."
+
 msgctxt "#36425"
 msgid "Show context menu"
 msgstr "แสดงเมนูเนื้อหา"
@@ -12269,6 +12345,10 @@ msgctxt "#36428"
 msgid "Record"
 msgstr "บันทึก"
 
+msgctxt "#36429"
+msgid "Select this if the audio out connection only supports multichannel audio as Dolby Digital 5.1, this allows multichannel audio such as AAC5.1 or FLAC5.1 to be listened to in 5.1 surround sound. Note - transcoding can lead to a reduction in sound quality"
+msgstr "เลือกส่วนนี้ ถ้าการเชื่อมต่อสัญญาณเสียงออก  รองรับการเชื่อมต่อหลายช่องสัญญาณเสียงแบบ Dolby Digital 5.1 เท่านั้น, ซึ่งจะทำให้เสียงหลายช่องสัญญาณ เช่น AAC5.1 or FLAC5.1 สามารถรับฟังได้ในแบบ 5.1 รอบทิศทาง. ข้อควรจำ - การแปลงสัญญาณอาจทำให้คุณภาพของเสียงลดลง"
+
 msgctxt "#36500"
 msgid "Stereoscopic mode (current)"
 msgstr "โหมดภาพสามมิติ (ปัจจุบัน)"
@@ -12417,6 +12497,10 @@ msgctxt "#36547"
 msgid "Use higher quality textures for covers and fanart (uses more memory)"
 msgstr "ใช้พื้นผิวคุณภาพสูงขึ้น สำหรับปกและแฟนอาร์ต (ใช้หน่วยความจำมากขึ้น)"
 
+msgctxt "#36548"
+msgid "Limits resolution of GUI to save memory. Does not affect video playback. Use 1080 for unlimited. Requires restart."
+msgstr "จำกัดความละเอียดของ GUI เพื่อประหยัดหน่วยความจำ. ไม่ส่งผลกับการเล่นวิดีโอ. ใช้ 1080 เพื่อไม่จำกัด. จำเป็นต้องเริ่มระบบใหม่."
+
 msgctxt "#37000"
 msgid "(Visually Impaired)"
 msgstr "(มีปัญหาทางสายตา)"
@@ -12465,6 +12549,18 @@ msgctxt "#37019"
 msgid "Enables system keys like printscreen, alt-tab and volume keys when in fullscreen"
 msgstr "เปิดใช้งานคีย์ของระบบ อย่าง printscreen, alt-tab และปุ่มปรับเสียง เมื่ออยู่ในเต็มหน้าจอ"
 
+msgctxt "#37020"
+msgid "Enable higher colour depth artwork"
+msgstr "เปิดใช้ ความลึกของระดับสีที่สูงขึ้น สำหรับงานศิลป์"
+
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "กำหนด ความละเอียด GUI แบบจำกัด"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "ตัวเล่น UPnP"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "คุณต้องการที่จะหยุดการเล่น บนอุปกรณ์ระยะไกล ใช่หรือไม่?"
index a7f37f3..597ccc9 100644 (file)
@@ -1923,7 +1923,7 @@ msgstr "Büyük liste"
 
 msgctxt "#538"
 msgid "Big icons"
-msgstr "Büyük simge"
+msgstr "Büyük simgeler"
 
 msgctxt "#539"
 msgid "Wide"
@@ -2067,7 +2067,7 @@ msgstr "Ülke"
 
 msgctxt "#575"
 msgid "In progress"
-msgstr "İşlem sürüyor"
+msgstr "Devam ediyor"
 
 msgctxt "#576"
 msgid "Times played"
@@ -2383,7 +2383,7 @@ msgstr "Sıkıştırma düzeyi"
 
 msgctxt "#666"
 msgid "Verbose logging..."
-msgstr "Ayrıntılı kayıt tutma..."
+msgstr "Ayrıntılı günlük..."
 
 msgctxt "#700"
 msgid "Cleaning up library"
@@ -2839,7 +2839,7 @@ msgstr "%s kaynağını ekle"
 
 msgctxt "#1021"
 msgid "Enter the paths or browse for the media locations."
-msgstr "Yolları girin veya ortam konumlarına gözatın."
+msgstr "Yolları gir veya ortam konumlarına gözat."
 
 msgctxt "#1022"
 msgid "Enter a name for this media Source."
@@ -4933,6 +4933,10 @@ msgctxt "#13434"
 msgid "Play only this"
 msgstr "Sadece bunu oynat"
 
+msgctxt "#13435"
+msgid "Enable HQ Scalers for scalings above"
+msgstr "Yukarıdaki ölçeklendirmeler için Yüksek Kalite Ölçekleyiciyi etkinleştir"
+
 msgctxt "#13436"
 msgid "Allow hardware acceleration (libstagefright)"
 msgstr "Donanımsal hızlandırmasına izin ver (libstagefright)"
@@ -5119,7 +5123,7 @@ msgstr "Küçük resim görünümüne otomatik değiştirmeyi etkinleştir"
 
 msgctxt "#14012"
 msgid "- Use large icons"
-msgstr "- Büyük simge kullan"
+msgstr "- Büyük simgeleri kullan"
 
 msgctxt "#14013"
 msgid "- Switch based on"
@@ -5441,6 +5445,18 @@ msgctxt "#14100"
 msgid "Stop ripping CD"
 msgstr "CD kopyalamayı durdur"
 
+msgctxt "#15012"
+msgid "Unavailable source"
+msgstr "Kullanılamayan kaynak"
+
+msgctxt "#15013"
+msgid "What would you like to do with media items from %s"
+msgstr "%s ortam öğeleri ile ne yapmak istiyor sunuz?"
+
+msgctxt "#15014"
+msgid "Keep"
+msgstr "Sakla"
+
 msgctxt "#15015"
 msgid "Remove"
 msgstr "Kaldır"
@@ -5961,6 +5977,10 @@ msgctxt "#19017"
 msgid "TV recordings"
 msgstr "TV kayıtları"
 
+msgctxt "#19018"
+msgid "Folder with channel icons"
+msgstr "Kanal simgelerini içeren klasör"
+
 msgctxt "#19019"
 msgid "Channels"
 msgstr "Kanallar"
@@ -6149,6 +6169,10 @@ msgctxt "#19065"
 msgid "Default EPG window"
 msgstr "Varsayılan EPG penceresi"
 
+msgctxt "#19066"
+msgid "Channel icons"
+msgstr "Kanal simgeleri"
+
 msgctxt "#19067"
 msgid "This event is already being recorded."
 msgstr "Bu olay zaten kaydedilmektedir."
@@ -6161,6 +6185,10 @@ msgctxt "#19069"
 msgid "EPG"
 msgstr "EPG"
 
+msgctxt "#19070"
+msgid "Go to now"
+msgstr "Şimdi git"
+
 msgctxt "#19071"
 msgid "EPG update interval"
 msgstr "EPG güncelleme aralığı"
@@ -6957,6 +6985,22 @@ msgctxt "#19281"
 msgid "Confirm channel switches by pressing OK"
 msgstr "Kanal değiştirmeyi OK'e basarak onaylayın"
 
+msgctxt "#19282"
+msgid "Current icon"
+msgstr "Varsayılan simge"
+
+msgctxt "#19283"
+msgid "No icon"
+msgstr "Simge yok"
+
+msgctxt "#19284"
+msgid "Choose icon"
+msgstr "Simge seç"
+
+msgctxt "#19285"
+msgid "Browse for icon"
+msgstr "Simgeye Gözat"
+
 msgctxt "#19499"
 msgid "Other/Unknown"
 msgstr "Diğer/Bilinmeyen"
@@ -7241,10 +7285,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Motor"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Spor ve Sağlık"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Yemek Pişirme"
@@ -7265,10 +7305,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Özgün Dil"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Siyah ve Beyaz"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Yayımdan kaldırıldı"
@@ -8045,6 +8081,14 @@ msgctxt "#20199"
 msgid "Downloading artist info failed"
 msgstr "Sanatçı bilgisi indirilemedi"
 
+msgctxt "#20220"
+msgid "Override song tags with online information"
+msgstr "Çevrimiçi bilgiyi kullanarak şarkı etiketlerinin üzerine yaz"
+
+msgctxt "#20221"
+msgid "With this enabled, any information that is downloaded for albums and artists will override anything you have set in your song tags, such as genres, year, song artists etc. Useful if you have MusicBrainz identifiers in your song tags."
+msgstr "Bu etkinleştirildiğinde, albümler ve sanatçılar için indirilen herhangi bir bilgi, sizin ayarladığınız türler, yıl, sanatçı, tarz vb. gibi şarkı etiketlerinizin üzerine yazılır. Eğer şarkı etiketlerinde MusicBrainz tanımlayıcıları varsa yararlıdır."
+
 msgctxt "#20240"
 msgid "Android music"
 msgstr "Android müzik"
@@ -8177,6 +8221,10 @@ msgctxt "#20321"
 msgid "Scanning albums using %s"
 msgstr "Albümler %s kullanılarak taranıyor"
 
+msgctxt "#20323"
+msgid "Movie plot"
+msgstr "Film içeriği"
+
 msgctxt "#20324"
 msgid "Play part..."
 msgstr "...Bölümü oynat"
@@ -8705,13 +8753,17 @@ msgctxt "#20455"
 msgid "Listeners"
 msgstr "Dinleyiciler"
 
+msgctxt "#20456"
+msgid "Flatten library hierarchy"
+msgstr "Kitaplık hiyerarşisini düzleştir"
+
 msgctxt "#20457"
 msgid "Movie set"
 msgstr "Film kümesi"
 
 msgctxt "#20458"
 msgid "Group movies in sets"
-msgstr "Group movies in sets"
+msgstr "Kümelerin içindeki filmleri grupla"
 
 msgctxt "#20459"
 msgid "Tags"
@@ -8817,6 +8869,10 @@ msgctxt "#21365"
 msgid "Remove media share"
 msgstr "Ortam paylaşımını kaldır"
 
+msgctxt "#21366"
+msgid "Custom subtitle folder"
+msgstr "Özel altyazı klasörü"
+
 msgctxt "#21367"
 msgid "Movie & alternate subtitle directory"
 msgstr "Film ve alternatif altyazı klasörü"
@@ -9185,6 +9241,10 @@ msgctxt "#21459"
 msgid "mixed"
 msgstr "karışık"
 
+msgctxt "#21460"
+msgid "Subtitle location on screen"
+msgstr "Altyazının ekrandaki konumu"
+
 msgctxt "#21461"
 msgid "Fixed"
 msgstr "Sabit"
@@ -10097,6 +10157,14 @@ msgctxt "#24110"
 msgid "Downloading subtitles ..."
 msgstr "Altyazılar indiriliyor..."
 
+msgctxt "#24111"
+msgid "Languages to download subtitles for"
+msgstr "Altyazıları indirmek için diller:"
+
+msgctxt "#24112"
+msgid "Set languages to use when searching for subtitles. Not all subtitle services will use all languages."
+msgstr "Altyazıları ararken kullanılacak dilleri ayarlayın. Bütün altyazı hizmetleri her dili desteklemez."
+
 msgctxt "#24113"
 msgid "Failed to download subtitle"
 msgstr "Altyazı indirilemedi"
@@ -10113,10 +10181,18 @@ msgctxt "#24116"
 msgid "Default TV Service"
 msgstr "Varsayılan TV Hizmeti"
 
+msgctxt "#24117"
+msgid "Select service that will be used as default to search for TV Show subtitles"
+msgstr "TV Programı altyazılarını aramak için kullanılacak varsayılan hizmeti seçin."
+
 msgctxt "#24118"
 msgid "Default Movie Service"
 msgstr "Varsayılan Film Hizmeti"
 
+msgctxt "#24119"
+msgid "Select service that will be used as default to search for Movie subtitles"
+msgstr "Film altyazılarını aramak için kullanılacak varsayılan hizmeti seçin."
+
 msgctxt "#24120"
 msgid "Manual search string"
 msgstr "El ile arama dizesi"
@@ -10153,6 +10229,18 @@ msgctxt "#25006"
 msgid "Select playback item"
 msgstr "Çalınacak öğeyi seç"
 
+msgctxt "#25007"
+msgid "Chapters: %u - duration: %s"
+msgstr "Bölümler: %u - süre: %s"
+
+msgctxt "#25008"
+msgid "Blu-ray Disc playback failed"
+msgstr "Blu-ray Disk çalma başarısız"
+
+msgctxt "#25009"
+msgid "The menu of this Blu-ray Disc is not supported"
+msgstr "Bu Blu-ray Disk menüsü desteklenmiyor"
+
 msgctxt "#29800"
 msgid "Library Mode"
 msgstr "Kitaplık Modu"
@@ -10509,6 +10597,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Windows Media Audio 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanal sayısı"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
@@ -10647,7 +10739,7 @@ msgstr "Enter için 1 parmakla tek dokunma"
 
 msgctxt "#34408"
 msgid "2 finger single tap or 1 finger long press for contextmenu"
-msgstr "Kısayol menüsü için 2 parmakla tek dokunma veya 1 parmakla uzun bas"
+msgstr "İçerik menüsü için 2 parmakla tek dokunma veya 1 parmakla uzun bas"
 
 msgctxt "#35000"
 msgid "Peripherals"
@@ -10979,7 +11071,7 @@ msgstr "Sıralama işlemleri sırasında bazı belirteçleri yoksay. Örneğin,
 
 msgctxt "#36125"
 msgid "Allow files to be deleted and renamed through the user interface, via the contextual menu (press C on a keyboard, for example, to bring up this menu)."
-msgstr "Kullanıcı arayüzünden dosyaları silmeyi ve yeniden adlandırmayı etkin kıl. (klavyeden C'ye basın)"
+msgstr "İçerik menüsü aracılığıyla, kullanıcı arabirimi üzerinden dosyaları silmeye ve yeniden adlandırmaya izin ver. (bu menüyü getirmek için klavyeden C'ye basın)"
 
 msgctxt "#36126"
 msgid "Show the add source button from root sections of the user interface."
@@ -11005,6 +11097,10 @@ msgctxt "#36132"
 msgid "Preview the selected screensaver."
 msgstr "Seçilen ekran koruyucuyu göster."
 
+msgctxt "#36134"
+msgid "Dim the display when media is paused. Not valid for the 'Dim' screensaver mode."
+msgstr "Medya duraklatıldığında ekranı karart. Karartma ekran koruyucu modu için geçerli değil."
+
 msgctxt "#36135"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
@@ -11041,6 +11137,14 @@ msgctxt "#36143"
 msgid "Get thumbnails for actors when scanning media."
 msgstr "Medya taranırken aktör küçük resimlerini al."
 
+msgctxt "#36144"
+msgid "Remove the TV show season node, toggles between 'If only one season' (default), 'Always' and 'Never'."
+msgstr "TV Programı sezon düğümünü kaldır,  'Yalnızca bir sezon ise' (varsayılan) ile 'Her zaman' ve 'Asla' arasında geçiş yapar."
+
+msgctxt "#36145"
+msgid "Group movies into 'Movie sets' when browsing the movie library."
+msgstr "Film kitaplığına göz atarken 'Film kümeleri'ndeki filmleri grupla."
+
 msgctxt "#36146"
 msgid "Check for new media files on XBMC startup."
 msgstr "XBMC başlatılırken yeni medya dosyalarını kontrol et."
@@ -11229,6 +11333,18 @@ msgctxt "#36202"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
 
+msgctxt "#36203"
+msgid "Enable the Personal Video Recorder (PVR) features in XBMC. This requires that at least one PVR Add-on is installed."
+msgstr "XBMC'nin Kişisel Video Kaydedici (PVR) özelliklerini etkinleştir. En az bir PVR eklentisinin yüklü olması gerekir."
+
+msgctxt "#36204"
+msgid "Import channel groups from the PVR backend (if supported). Will delete user created groups if they're not found on the backend."
+msgstr "Kanal guruplarını PVR arka uçtan al (destekleniyorsa). Eğer arka uçta bulunmuyorsa kullanıcının oluşturduğu guruplar silinir."
+
+msgctxt "#36205"
+msgid "Sort the channels by channel number on the server, but uses XBMC's own numbering for channels."
+msgstr "Kanalları sunucudaki kanal numarasına göre sırala, fakat kanallar için XBMC'nin kendi numaralandırmasını kullanır."
+
 msgctxt "#36206"
 msgid "Use numbering from the backend, instead of configuring them manually over XBMC."
 msgstr "XBMC üzerinde el ile yapılandırmak yerine arka uç numaralarını kullan."
@@ -11237,9 +11353,13 @@ msgctxt "#36207"
 msgid "Open the channel manager, which allows modifying the channel order, channel name, icon, etc."
 msgstr "Kanal sırası, kanal ismi, simge vb. değiştirmeye izin veren kanal yöneticisini aç."
 
+msgctxt "#36208"
+msgid "Instruct the backend to search for channels (if supported)."
+msgstr "Kanalları aramak için arka uça talimat ver (destekleniyorsa)."
+
 msgctxt "#36209"
 msgid "Delete channel/EPG database and reimport the data from the backend afterwards."
-msgstr "Kanal ve EPG veritabanını silin ve sonra verileri arka uçtan yeniden alın."
+msgstr "Kanal ve EPG veritabanını sil ve sonra veriyi arka uçtan tekrar al."
 
 msgctxt "#36210"
 msgid "No info available yet."
@@ -11281,6 +11401,14 @@ msgctxt "#36219"
 msgid "Default EPG window to show. Defaults to Timeline."
 msgstr "Varsayılan EPG penceresini göstermek için. Varsayılan: Zaman çizelgesi"
 
+msgctxt "#36220"
+msgid "Number of days of EPG data to import from backends. Defaults to 3 days."
+msgstr "EPG verisini arka uçtan alma gün sayısı. Varsayılan 3 gün."
+
+msgctxt "#36221"
+msgid "Time between EPG data imports from backends. Defaults to 120 minutes."
+msgstr "EPG verisini arka uçtan alma süresi. Varsayılan 120 dakika."
+
 msgctxt "#36222"
 msgid "Do not import EPG data while playing TV to minimise CPU usage."
 msgstr "CPU kullanımını azaltmak için TV oynatılırken EPG verilerini alma."
@@ -11289,6 +11417,14 @@ msgctxt "#36223"
 msgid "By default, EPG data is stored in a local database to speed up importing when XBMC is restarted."
 msgstr "EPG verisi, varsayılan olarak XBMC yeniden başlatıldığında EPG verisinin alınmasını hızlandırmak için yerel veritabanında depolanır."
 
+msgctxt "#36224"
+msgid "Hide \"no information available\" labels when no EPG data can be retrieved for a channel."
+msgstr "Kanal için EPG verisi alınamaz ise 'hiçbir bilgi yok' etiketlerini gizle."
+
+msgctxt "#36225"
+msgid "Delete the EPG database in xbmc and reimport the data afterwards from the backend."
+msgstr "XBMC'nin içindeki EPG veritabanını sil ve sonra veriyi arka uçtan tekrar al."
+
 msgctxt "#36226"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
@@ -11301,6 +11437,10 @@ msgctxt "#36228"
 msgid "Show the last viewed channel if switching to live tv."
 msgstr "Canlı TV ye geçildiğinde son seyredilen kanala geç."
 
+msgctxt "#36229"
+msgid "Display signal quality information in the codec information window (if supported by the Add-on and backend)."
+msgstr "Codec bilgisi penceresinde sinyal kalitesi bilgisini göster (eklenti ve arka uç tarafından destekleniyorsa)."
+
 msgctxt "#36230"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
@@ -11317,6 +11457,22 @@ msgctxt "#36233"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
 
+msgctxt "#36235"
+msgid "Priority of the recording. Higher number means higher priority. Defaults to 50. Not supported by all Add-ons and backends."
+msgstr "Kayıt önceliği. Daha yüksek bir sayı daha yüksek öncelik anlamına gelir. Varsayılan değer 50. Bütün eklentiler ve arka uçlar tarafından desteklenmez."
+
+msgctxt "#36236"
+msgid "Delete recording after this time. Defaults to 99 days. Not supported by all Add-ons and backends."
+msgstr "Kayıdı bu zamandan sonra sil. Varsayılan değer 99 gün. Bütün eklentiler ve arka uçlar tarafından desteklenmez."
+
+msgctxt "#36237"
+msgid "Start recordings before the actual time. Defaults to 2 minutes. Not supported by all Add-ons and backends."
+msgstr "Gerçek zamanından önce kayıtları başlat. Varsayılan değer 2 dakika. Bütün eklentiler ve arka uçlar tarafından desteklenmez."
+
+msgctxt "#36238"
+msgid "End recordings after the actual time. Defaults to 10 minutes. Not supported by all Add-ons and backends."
+msgstr "Gerçek zamanından sonra kayıtları durdur. Varsayılan değer 10 dakika. Bütün eklentiler ve arka uçlar tarafından desteklenmez."
+
 msgctxt "#36240"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
@@ -11379,7 +11535,7 @@ msgstr "MüzikKıtaplığı veritabanını XML dosyasına dışa aktar. Bu iste
 
 msgctxt "#36263"
 msgid "Import a XML file into the Music Library database."
-msgstr "XML dosyasındanMüzik Kitaplığı veritabanı içine aktar."
+msgstr "XML dosyasından Müzik Kitaplığı veritabanı içine aktar."
 
 msgctxt "#36264"
 msgid "No info available yet."
@@ -11429,6 +11585,10 @@ msgctxt "#36283"
 msgid "Autorun CDs when inserted in drive."
 msgstr "CD lerin sürücüye konulduklarında otomatik olarak başlatır."
 
+msgctxt "#36286"
+msgid "Tags: [B]%N[/B]: TrackNumber, [B]%S[/B]: DiscNumber, [B]%A[/B]: Artist, [B]%T[/B]: Title, [B]%B[/B]: Album, [B]%G[/B]: Genre, [B]%Y[/B]: Year, [B]%F[/B]: FileName, [B]%D[/B]: Duration, [B]%J[/B]: Date, [B]%R[/B]: Rating, [B]%I[/B]: FileSize."
+msgstr "Etiketler: [B]%N[/B]: ParçaNumarası, [B]%S[/B]: DiskNumarası, [B]%A[/B]: Artist, [B]%T[/B]: Başlık, [B]%B[/B]: Albüm, [B]%G[/B]: Tarz, [B]%Y[/B]: Yıl, [B]%F[/B]: DosyaAdı, [B]%D[/B]: Süre, [B]%J[/B]: Tarih, [B]%R[/B]: Derecelendirme, [B]%I[/B]: DosyaBoyutu."
+
 msgctxt "#36290"
 msgid "For FLAC define compression level, default 5"
 msgstr "FLAC için sıkıştırma düzeyini belirleyiniz, geçerli değer 5 dir."
@@ -11701,6 +11861,10 @@ msgctxt "#36370"
 msgid "Select this option if your receiver is capable of decoding DTS-HD streams."
 msgstr "Eğer alıcınız DTS-HD çözme desteğine sahipse bu seçeneği seçin."
 
+msgctxt "#36373"
+msgid "Configure how interface sounds are handled, such as menu navigation and important notifications."
+msgstr "Menü gezintisi ve önemli bildirimler gibi arayüz seslerinin nasıl işlendiğini yapılandır."
+
 msgctxt "#36374"
 msgid "No info available yet."
 msgstr "Bilgi mevcut değil."
@@ -11755,7 +11919,7 @@ msgstr "Uzun bir süre boşta kaldığında XBMC'nin ne yapması gerektiğini ta
 
 msgctxt "#36391"
 msgid "Turn debug logging on or off. Useful for troubleshooting."
-msgstr "Hata ayıklamayı aç ya da kapat. Sorun giderme için kullanışlıdır."
+msgstr "Hata ayıklama günlüğünü aç veya kapat. Sorun giderme için kullanışlıdır."
 
 msgctxt "#36392"
 msgid "No info available yet."
@@ -11877,6 +12041,14 @@ msgctxt "#36422"
 msgid "Enable hardware video decode using AMLogic decoder"
 msgstr "AMLogic kod çözücü kullanarak donanımsal video çözücüyü etkinleştir"
 
+msgctxt "#36424"
+msgid "Select what will happen when an EPG item is selected: [Show context menu] will trigger the contextual menu from where you can choose further actions; [Switch to channel] will instantly tune to the related channel; [Show information] will display a detailed information with plot and further options; [Record] will create a recording timer for the selected item."
+msgstr "Bir EPG öğesi seçildiğinde ne olacağını seçin: [İçerik menüsünü göster] daha fazla eylem seçebileceğiniz içerik menüsünü tetikler; [Kanal değiştir] ilgili kanala ağnında geçer; [Bilgileri görüntüle] içerik ile ayrıntılı bilgi ve daha fazla seçenek gösterir; [Kayıt] seçili öğe için bir kayıt zamanlayıcısı yaratır."
+
+msgctxt "#36425"
+msgid "Show context menu"
+msgstr "İçerik menüsünü göster"
+
 msgctxt "#36426"
 msgid "Switch to channel"
 msgstr "Kanal değiştir"
@@ -12013,6 +12185,14 @@ msgctxt "#36544"
 msgid "Enable hardware decoding of video files."
 msgstr "Video dosyalarının donanımsal çözülmesini etkinleştir."
 
+msgctxt "#36545"
+msgid "Subtitle stereoscopic depth"
+msgstr "Stereoskopik altyazı derinliği"
+
+msgctxt "#36546"
+msgid "Sets the visual depth of subtitles for stereoscopic videos. The higher the value, the closer the subtitles will appear to the viewer."
+msgstr "Stereoskopik videolar için altyazı görsel derinliğini ayarlar. Değer ne kadar yüksek olursa altyazı izleyiciye daha yakın görünecektir."
+
 msgctxt "#36547"
 msgid "Use higher quality textures for covers and fanart (uses more memory)"
 msgstr "Kapaklar ve fanart için yüksek kaliteli dokular kullan (daha fazla bellek kullanır)"
@@ -12060,3 +12240,11 @@ msgstr "Daha yüksek artwork renk derinliğini etkinleştir"
 msgctxt "#37021"
 msgid "Set GUI resolution limit"
 msgstr "Grafik Kullanıcı Arabirimi çözünürlük sınırını ayarla"
+
+msgctxt "#37022"
+msgid "UPnP Player"
+msgstr "UPnP Oynatıcı"
+
+msgctxt "#37023"
+msgid "Do you wish to stop playback on the remote device?"
+msgstr "Uzak aygıttaki oynatımı durdurmak istiyor musunuz?"
index fc68957..7f9d70d 100644 (file)
@@ -7017,10 +7017,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Авто/мото"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Здоров'я та фітнес"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Кулінарія"
@@ -7041,10 +7037,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Оригінальна мова"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Ч-Б"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Неопубліковане"
@@ -10157,6 +10149,10 @@ msgctxt "#34005"
 msgid "Flac"
 msgstr "Flac"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Кількість каналів"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 2aae32d..0d36763 100644 (file)
@@ -3597,10 +3597,6 @@ msgctxt "#19645"
 msgid "Tourism/Travel"
 msgstr "Sayohat/Safar"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitnes va Sog'liq"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Pazandalik"
@@ -3609,10 +3605,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Asl til"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Qora va oq"
-
 msgctxt "#19676"
 msgid "Drama"
 msgstr "Drama"
@@ -4081,6 +4073,10 @@ msgctxt "#33063"
 msgid "Options"
 msgstr "Parametrlar"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Kanallar soni"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index c5f92f0..d48d1d0 100644 (file)
@@ -1069,6 +1069,10 @@ msgctxt "#33081"
 msgid "This file is stacked, select the part you want to play from."
 msgstr "Tập tin này bị lỗi, hãy chọn một phần khác để phát."
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Số kênh"
+
 msgctxt "#35000"
 msgid "Peripherals"
 msgstr "Peripherals"
index cf299e4..3ce3442 100644 (file)
@@ -5321,10 +5321,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Ngôn ngữ gốc"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Đen trắng"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Chưa phát hành"
@@ -6529,6 +6525,10 @@ msgctxt "#33200"
 msgid "Detected New Connection"
 msgstr "Phát hiện kết nối mới"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Số lượng kênh"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index 44c9e45..c4bad56 100644 (file)
@@ -6885,10 +6885,6 @@ msgctxt "#19647"
 msgid "Motoring"
 msgstr "Moduro"
 
-msgctxt "#19648"
-msgid "Fitness &amp; Health"
-msgstr "Fitrwydd ac Iechyd"
-
 msgctxt "#19649"
 msgid "Cooking"
 msgstr "Coginio"
@@ -6909,10 +6905,6 @@ msgctxt "#19661"
 msgid "Original Language"
 msgstr "Iaith Wreiddiol"
 
-msgctxt "#19662"
-msgid "Black &amp; White"
-msgstr "Du a Gwyn"
-
 msgctxt "#19663"
 msgid "Unpublished"
 msgstr "Heb eu cyhoeddi"
@@ -9981,6 +9973,10 @@ msgctxt "#34007"
 msgid "Windows Media Audio 2 (FFmpeg wmav2)"
 msgstr "Sain Windows Media 2 (FFmpeg wmav2)"
 
+msgctxt "#34100"
+msgid "Number of channels"
+msgstr "Nifer o sianeli"
+
 msgctxt "#34101"
 msgid "2.0"
 msgstr "2.0"
index ced60c3..e441afb 100644 (file)
@@ -837,6 +837,9 @@ int DCR_CLASS dcr_ljpeg_diff (DCRAW* p, struct dcr_decode *dindex)
 {
        int len, diff;
 
+       if (!dindex)
+               longjmp (p->failure, 2);
+
        while (dindex->branch[0])
                dindex = dindex->branch[dcr_getbits(p, 1)];
        len = dindex->leaf;
@@ -894,6 +897,10 @@ void DCR_CLASS dcr_lossless_jpeg_load_raw(DCRAW* p)
        ushort *rp;
 
        if (!dcr_ljpeg_start (p,&jh, 0)) return;
+
+       if (jh.wide<1 || jh.high<1 || jh.clrs<1 || jh.bits<1)
+               longjmp (p->failure, 2);
+
        jwide = jh.wide * jh.clrs;
 
        for (jrow=0; jrow < jh.high; jrow++) {
@@ -922,6 +929,8 @@ void DCR_CLASS dcr_lossless_jpeg_load_raw(DCRAW* p)
                        }
                        if (++col >= p->raw_width)
                                col = (row++,0);
+                       if (row >= p->raw_height)
+                               longjmp (p->failure, 3);
                }
        }
        free (jh.row);
@@ -4973,6 +4982,7 @@ int DCR_CLASS dcr_parse_tiff_ifd (DCRAW* p, int base)
                                p->data_offset = dcr_get4(p)+base;
                                ifd++;  break;
                        }
+                       if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
                        while (len--) {
                                i = dcr_ftell(p->obj_);
                                dcr_fseek(p->obj_, dcr_get4(p)+base, SEEK_SET);
@@ -5161,7 +5171,7 @@ guess_cfa_pc:
                case 50714:                     /* BlackLevel */
                case 50715:                     /* BlackLevelDeltaH */
                case 50716:                     /* BlackLevelDeltaV */
-                       for (dblack=i=0; i < (int)len; i++)
+                       for (dblack=i=0; i < (int)len && i < 65536; i++)
                                dblack += dcr_getreal(p, type);
                        p->black += (unsigned int)(dblack/len + 0.5);
                        break;
@@ -5275,9 +5285,11 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
        if (p->thumb_offset) {
                dcr_fseek(p->obj_, p->thumb_offset, SEEK_SET);
                if (dcr_ljpeg_start (p,&jh, 1)) {
-                       p->thumb_misc   = jh.bits;
-                       p->thumb_width  = jh.wide;
-                       p->thumb_height = jh.high;
+                       if ((unsigned)jh.bits<17 && (unsigned)jh.wide < 0x10000 && (unsigned)jh.high < 0x10000) {
+                               p->thumb_misc   = jh.bits;
+                               p->thumb_width  = jh.wide;
+                               p->thumb_height = jh.high;
+                       }
                }
        }
        for (i=0; i < (int)p->tiff_nifds; i++) {
@@ -5285,6 +5297,8 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
                        max_samp = p->tiff_ifd[i].samples;
                if (max_samp > 3) max_samp = 3;
                if ((p->tiff_ifd[i].comp != 6 || p->tiff_ifd[i].samples != 3) &&
+                       (unsigned)(p->tiff_ifd[i].width | p->tiff_ifd[i].height) < 0x10000 &&
+                       (unsigned)p->tiff_ifd[i].bps < 33 && (unsigned)p->tiff_ifd[i].samples < 13 &&
                        p->tiff_ifd[i].width*p->tiff_ifd[i].height > p->raw_width*p->raw_height) {
                        p->raw_width     = p->tiff_ifd[i].width;
                        p->raw_height    = p->tiff_ifd[i].height;
@@ -5348,6 +5362,8 @@ void DCR_CLASS dcr_parse_tiff (DCRAW* p, int base)
        if (p->tiff_bps == 8 && p->tiff_samples == 4) p->is_raw = 0;
        for (i=0; i < (int)p->tiff_nifds; i++)
                if (i != raw && p->tiff_ifd[i].samples == max_samp &&
+                       p->tiff_ifd[i].bps>0 && p->tiff_ifd[i].bps < 33 &&
+                       (unsigned)(p->tiff_ifd[i].width | p->tiff_ifd[i].height) < 0x10000 &&
                        p->tiff_ifd[i].width * p->tiff_ifd[i].height / SQR(p->tiff_ifd[i].bps+1) >
                        (int)(p->thumb_width *       p->thumb_height / SQR(p->thumb_misc+1))) {
                        p->thumb_width  = p->tiff_ifd[i].width;
index 4f229a3..7a03614 100644 (file)
@@ -40,6 +40,15 @@ static void fill_picture_parameters(AVCodecContext *avctx,
     const Picture *current_picture = s->current_picture_ptr;
     BYTE bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type == 1;
     BYTE bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && v->bi_type == 0;
+    int intcomp = 0;
+
+    // determine if intensity compensation is needed
+    if (s->pict_type == AV_PICTURE_TYPE_P) {
+      if ((v->fcm == ILACE_FRAME && v->intcomp) || (v->fcm != ILACE_FRAME && v->mv_mode == MV_PMODE_INTENSITY_COMP)) {
+        if (v->lumscale != 32 || v->lumshift != 0 || (s->picture_structure != PICT_FRAME && (v->lumscale2 != 32 && v->lumshift2 != 0)))
+          intcomp = 1;
+      }
+    }
 
     memset(pp, 0, sizeof(*pp));
     pp->wDecodedPictureIndex    =
@@ -76,7 +85,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
     pp->bBidirectionalAveragingMode = (1                                           << 7) |
                                       ((ctx->cfg->ConfigIntraResidUnsigned != 0)   << 6) |
                                       ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
-                                      ((v->lumscale != 32 || v->lumshift != 0)     << 4) |
+                                      (intcomp                                     << 4) |
                                       ((v->profile == PROFILE_ADVANCED)            << 3);
     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
                                         (1                                       << 2) |
@@ -126,15 +135,25 @@ static void fill_picture_parameters(AVCodecContext *avctx,
                                   (v->range_mapuv_flag << 3) |
                                   (v->range_mapuv          );
     pp->bPicBinPB               = 0;
-    pp->bMV_RPS                 = 0;
-    pp->bReservedBits           = 0;
+    pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+    pp->bReservedBits           = v->pq;
     if (s->picture_structure == PICT_FRAME) {
-        pp->wBitstreamFcodes        = v->lumscale;
-        pp->wBitstreamPCEelements   = v->lumshift;
+        if (intcomp) {
+            pp->wBitstreamFcodes      = v->lumscale;
+            pp->wBitstreamPCEelements = v->lumshift;
+        } else {
+            pp->wBitstreamFcodes      = 32;
+            pp->wBitstreamPCEelements = 0;
+        }
     } else {
         /* Syntax: (top_field_param << 8) | bottom_field_param */
-        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
-        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
+        if (intcomp) {
+            pp->wBitstreamFcodes      = (v->lumscale << 8) | v->lumscale2;
+            pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift2;
+        } else {
+            pp->wBitstreamFcodes      = (32 << 8) | 32;
+            pp->wBitstreamPCEelements = 0;
+        }
     }
     pp->bBitstreamConcealmentNeed   = 0;
     pp->bBitstreamConcealmentMethod = 0;
@@ -152,8 +171,8 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
     slice->dwSliceBitsInBuffer = 8 * size;
     slice->dwSliceDataLocation = position;
     slice->bStartCodeBitOffset = 0;
-    slice->bReservedBits       = 0;
-    slice->wMBbitOffset        = get_bits_count(&s->gb);
+    slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+    slice->wMBbitOffset        = v->p_frame_skipped ? 0xffff : get_bits_count(&s->gb);
     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
     slice->wQuantizerScaleCode = v->pq;
     slice->wBadSliceChopping   = 0;
index a6a7bac..e2e90a8 100644 (file)
@@ -303,6 +303,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
         v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
         return decode_sequence_header_adv(v, gb);
     } else {
+           v->chromaformat = 1;
         v->zz_8x4 = ff_wmv2_scantableA;
         v->zz_4x8 = ff_wmv2_scantableB;
         v->res_y411   = get_bits1(gb);
diff --git a/lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch b/lib/ffmpeg/patches/0063-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-1.patch
new file mode 100644 (file)
index 0000000..4492ccb
--- /dev/null
@@ -0,0 +1,26 @@
+From 8abdf46b380562d4716a78174076b1e67ae1f8da Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:48 +0100
+Subject: [PATCH] dxva2_vc1: set refdist value according to spec
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 2e9a00e..6ff5765 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -122,7 +122,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+                                   (v->range_mapuv_flag << 3) |
+                                   (v->range_mapuv          );
+     pp->bPicBinPB               = 0;
+-    pp->bMV_RPS                 = 0;
++    pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+     pp->bReservedBits           = 0;
+     if (s->picture_structure == PICT_FRAME) {
+         pp->wBitstreamFcodes        = v->lumscale;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch b/lib/ffmpeg/patches/0064-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-2.patch
new file mode 100644 (file)
index 0000000..9886068
--- /dev/null
@@ -0,0 +1,26 @@
+From 3021d1be9ef1f863f880b5c667025936b45da065 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:49 +0100
+Subject: [PATCH] dxva2_vc1: set bfraction in slice info according to spec
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 6ff5765..33309b1 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -148,7 +148,7 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
+     slice->dwSliceBitsInBuffer = 8 * size;
+     slice->dwSliceDataLocation = position;
+     slice->bStartCodeBitOffset = 0;
+-    slice->bReservedBits       = 0;
++    slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+     slice->wMBbitOffset        = get_bits_count(&s->gb);
+     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
+     slice->wQuantizerScaleCode = v->pq;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch b/lib/ffmpeg/patches/0065-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-3.patch
new file mode 100644 (file)
index 0000000..7e575e6
--- /dev/null
@@ -0,0 +1,26 @@
+From e1facd3f8198fc4bfd54f3a4097e66513e6bf3e4 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:50 +0100
+Subject: [PATCH] dxva2_vc1: set PQUANT as described by the 2010 spec update
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 33309b1..bf4e8e0 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -123,7 +123,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+                                   (v->range_mapuv          );
+     pp->bPicBinPB               = 0;
+     pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+-    pp->bReservedBits           = 0;
++    pp->bReservedBits           = v->pq;
+     if (s->picture_structure == PICT_FRAME) {
+         pp->wBitstreamFcodes        = v->lumscale;
+         pp->wBitstreamPCEelements   = v->lumshift;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch b/lib/ffmpeg/patches/0066-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-4.patch
new file mode 100644 (file)
index 0000000..6df4296
--- /dev/null
@@ -0,0 +1,28 @@
+From 719f1ce5fb41493fe10edca1ba9223fa601b6165 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:51 +0100
+Subject: [PATCH] vc1: set chromaformat = 1 for simple/main profile
+
+1 is the only valid value for VC-1/WMV3, and setting it here makes sure
+no invalid value is send to a hw accelerator, for example.
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/vc1.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/vc1.c b/xbmc/lib/ffmpeg/libavcodec/vc1.c
+index fb33e6f..f8d3162 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/vc1.c
+@@ -293,6 +293,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
+         v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
+         return decode_sequence_header_adv(v, gb);
+     } else {
++        v->chromaformat = 1;
+         v->zz_8x4 = ff_wmv2_scantableA;
+         v->zz_4x8 = ff_wmv2_scantableB;
+         v->res_y411   = get_bits1(gb);
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch b/lib/ffmpeg/patches/0067-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-5.patch
new file mode 100644 (file)
index 0000000..e4a17bb
--- /dev/null
@@ -0,0 +1,73 @@
+From c5562890c7c3e495a1995bfa64f730806020e8d6 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:52 +0100
+Subject: [PATCH] dxva2_vc1: fix signaling of intensity compensation values
+
+lumscale/lumshift don't get reset back to their default values if
+intensity compensation is not active, and a wrong signaling here can
+cause playback issues.
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index bf4e8e0..995b3e3 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -38,6 +38,15 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+ {
+     const MpegEncContext *s = &v->s;
+     const Picture *current_picture = s->current_picture_ptr;
++    int intcomp = 0;
++
++    // determine if intensity compensation is needed
++    if (s->pict_type == AV_PICTURE_TYPE_P) {
++      if ((v->fcm == ILACE_FRAME && v->intcomp) || (v->fcm != ILACE_FRAME && v->mv_mode == MV_PMODE_INTENSITY_COMP)) {
++        if (v->lumscale != 32 || v->lumshift != 0 || (s->picture_structure != PICT_FRAME && (v->lumscale2 != 32 && v->lumshift2 != 0)))
++          intcomp = 1;
++      }
++    }
+     memset(pp, 0, sizeof(*pp));
+     pp->wDecodedPictureIndex    =
+@@ -74,7 +83,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+     pp->bBidirectionalAveragingMode = (1                                           << 7) |
+                                       ((ctx->cfg->ConfigIntraResidUnsigned != 0)   << 6) |
+                                       ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
+-                                      ((v->lumscale != 32 || v->lumshift != 0)     << 4) |
++                                      (intcomp                                     << 4) |
+                                       ((v->profile == PROFILE_ADVANCED)            << 3);
+     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
+                                         (1                                       << 2) |
+@@ -125,12 +134,22 @@ static void fill_picture_parameters(AVCodecContext *avctx,
+     pp->bMV_RPS                 = (v->fcm == ILACE_FIELD && pp->bPicBackwardPrediction) ? v->refdist + 9 : 0;
+     pp->bReservedBits           = v->pq;
+     if (s->picture_structure == PICT_FRAME) {
+-        pp->wBitstreamFcodes        = v->lumscale;
+-        pp->wBitstreamPCEelements   = v->lumshift;
++        if (intcomp) {
++            pp->wBitstreamFcodes      = v->lumscale;
++            pp->wBitstreamPCEelements = v->lumshift;
++        } else {
++            pp->wBitstreamFcodes      = 32;
++            pp->wBitstreamPCEelements = 0;
++        }
+     } else {
+         /* Syntax: (top_field_param << 8) | bottom_field_param */
+-        pp->wBitstreamFcodes        = (v->lumscale << 8) | v->lumscale;
+-        pp->wBitstreamPCEelements   = (v->lumshift << 8) | v->lumshift;
++        if (intcomp) {
++            pp->wBitstreamFcodes      = (v->lumscale << 8) | v->lumscale2;
++            pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift2;
++        } else {
++            pp->wBitstreamFcodes      = (32 << 8) | 32;
++            pp->wBitstreamPCEelements = 0;
++        }
+     }
+     pp->bBitstreamConcealmentNeed   = 0;
+     pp->bBitstreamConcealmentMethod = 0;
+-- 
+1.8.5.1
+
diff --git a/lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch b/lib/ffmpeg/patches/0068-ffmpeg-backport-vc1-dxva2-improvements-intel-compat-6.patch
new file mode 100644 (file)
index 0000000..44a4e50
--- /dev/null
@@ -0,0 +1,25 @@
+From 3d8eeea62009a85c88ee4a630da4d6037920aa6e Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Thu, 12 Dec 2013 21:12:53 +0100
+Subject: [PATCH] dxva2_vc1: signal skipped p frames
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+index 995b3e3..a86d7cd 100644
+--- a/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
++++ b/xbmc/lib/ffmpeg/libavcodec/dxva2_vc1.c
+@@ -168,7 +168,7 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
+     slice->dwSliceDataLocation = position;
+     slice->bStartCodeBitOffset = 0;
+     slice->bReservedBits       = (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) ? v->bfraction_lut_index + 9 : 0;
+-    slice->wMBbitOffset        = get_bits_count(&s->gb);
++    slice->wMBbitOffset        = v->p_frame_skipped ? 0xffff : get_bits_count(&s->gb);
+     slice->wNumberMBsInSlice   = s->mb_width * s->mb_height; /* XXX We assume 1 slice */
+     slice->wQuantizerScaleCode = v->pq;
+     slice->wBadSliceChopping   = 0;
+-- 
+1.8.5.1
diff --git a/lib/libUPnP/patches/0001-platinum-add-custom-Makefile.in.patch b/lib/libUPnP/patches/0001-platinum-add-custom-Makefile.in.patch
new file mode 100644 (file)
index 0000000..a4e62cd
--- /dev/null
@@ -0,0 +1,116 @@
+From 7e2edf03681ee3f4446d11894d126206e486f3a0 Mon Sep 17 00:00:00 2001
+From: montellese <montellese@xbmc.org>
+Date: Thu, 9 Jan 2014 21:23:53 +0100
+Subject: [PATCH 01/21] platinum: add custom Makefile.in
+
+---
+ lib/libUPnP/Makefile.in | 97 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 97 insertions(+)
+ create mode 100644 lib/libUPnP/Makefile.in
+
+diff --git a/lib/libUPnP/Makefile.in b/lib/libUPnP/Makefile.in
+new file mode 100644
+index 0000000..e1f9462
+--- /dev/null
++++ b/lib/libUPnP/Makefile.in
+@@ -0,0 +1,97 @@
++ARCH=@ARCH@
++
++ifeq (@USE_UPNP@, 1)
++SRCS= Platinum/Source/Core/PltAction.cpp \
++      Platinum/Source/Core/PltArgument.cpp \
++      Platinum/Source/Core/PltConstants.cpp \
++      Platinum/Source/Core/PltCtrlPoint.cpp \
++      Platinum/Source/Core/PltCtrlPointTask.cpp \
++      Platinum/Source/Core/PltDatagramStream.cpp \
++      Platinum/Source/Core/PltDeviceData.cpp \
++      Platinum/Source/Core/PltDeviceHost.cpp \
++      Platinum/Source/Core/PltEvent.cpp \
++      Platinum/Source/Core/PltHttp.cpp \
++      Platinum/Source/Core/PltHttpClientTask.cpp \
++      Platinum/Source/Core/PltHttpServer.cpp \
++      Platinum/Source/Core/PltHttpServerTask.cpp \
++      Platinum/Source/Core/PltIconsData.cpp \
++      Platinum/Source/Core/PltMimeType.cpp \
++      Platinum/Source/Core/PltProtocolInfo.cpp \
++      Platinum/Source/Core/PltService.cpp \
++      Platinum/Source/Core/PltSsdp.cpp \
++      Platinum/Source/Core/PltStateVariable.cpp \
++      Platinum/Source/Core/PltTaskManager.cpp \
++      Platinum/Source/Core/PltThreadTask.cpp \
++      Platinum/Source/Core/PltUPnP.cpp \
++      Platinum/Source/Devices/MediaServer/PltDidl.cpp \
++      Platinum/Source/Devices/MediaServer/PltFileMediaServer.cpp \
++      Platinum/Source/Devices/MediaServer/PltMediaBrowser.cpp \
++      Platinum/Source/Devices/MediaServer/PltMediaCache.cpp \
++      Platinum/Source/Devices/MediaServer/PltMediaItem.cpp \
++      Platinum/Source/Devices/MediaServer/PltMediaServer.cpp \
++      Platinum/Source/Devices/MediaServer/ConnectionManagerSCPD.cpp \
++      Platinum/Source/Devices/MediaServer/ContentDirectorySCPD.cpp \
++      Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp \
++      Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp \
++      Neptune/Source/Core/Neptune.cpp \
++      Neptune/Source/Core/NptBase64.cpp \
++      Neptune/Source/Core/NptBufferedStreams.cpp \
++      Neptune/Source/Core/NptCommon.cpp \
++      Neptune/Source/Core/NptDataBuffer.cpp \
++      Neptune/Source/Core/NptDebug.cpp \
++      Neptune/Source/Core/NptFile.cpp \
++      Neptune/Source/Core/NptHash.cpp \
++      Neptune/Source/Core/NptHttp.cpp \
++      Neptune/Source/Core/NptList.cpp \
++      Neptune/Source/Core/NptMessaging.cpp \
++      Neptune/Source/Core/NptNetwork.cpp \
++      Neptune/Source/Core/NptQueue.cpp \
++      Neptune/Source/Core/NptRingBuffer.cpp \
++      Neptune/Source/Core/NptSimpleMessageQueue.cpp \
++      Neptune/Source/Core/NptSockets.cpp \
++      Neptune/Source/Core/NptStreams.cpp \
++      Neptune/Source/Core/NptStrings.cpp \
++      Neptune/Source/Core/NptSystem.cpp \
++      Neptune/Source/Core/NptThreads.cpp \
++      Neptune/Source/Core/NptTime.cpp \
++      Neptune/Source/Core/NptUri.cpp \
++      Neptune/Source/Core/NptUtils.cpp \
++      Neptune/Source/Core/NptXml.cpp \
++      Neptune/Source/System/Bsd/NptBsdSockets.cpp \
++      Neptune/Source/System/Bsd/NptBsdNetwork.cpp \
++      Neptune/Source/System/Posix/NptPosixSystem.cpp \
++      Neptune/Source/System/Posix/NptSelectableMessageQueue.cpp \
++      Neptune/Source/System/Posix/NptPosixQueue.cpp \
++      Neptune/Source/System/Posix/NptPosixThreads.cpp \
++      Neptune/Source/System/Posix/NptPosixTime.cpp \
++      Neptune/Source/System/StdC/NptStdcDebug.cpp \
++      Neptune/Source/System/StdC/NptStdcEnvironment.cpp \
++      Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp \
++      Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp \
++      Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp \
++      Platinum/Source/Devices/MediaRenderer/RdrConnectionManagerSCPD.cpp \
++      Platinum/Source/Devices/MediaRenderer/RenderingControlSCPD.cpp \
++      Platinum/Source/Devices/MediaConnect/X_MS_MediaReceiverRegistrarSCPD.cpp \
++      Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp \
++
++ifeq ($(findstring osx,$(ARCH)),osx)
++
++.SUFFIXES : .m .mm
++
++SRCS+= Neptune/Source/System/Apple/NptAppleAutoreleasePool.mm
++SRCS+= Neptune/Source/System/Cocoa/NptCocoaEnviroment.mm
++
++else
++
++SRCS+= Neptune/Source/System/Posix/NptPosixEnvironment.cpp
++
++endif
++
++INCLUDES=-I./Neptune/Source/Core -I./Platinum/Source/Core -I./Platinum/Source/Platinum -I./Platinum/Source/Devices/MediaConnect -I./Platinum/Source/Devices/MediaRenderer -I./Platinum/Source/Devices/MediaServer -I./Neptune/Source/System/Posix -I./Platinum/Source/Extras
++
++LIB=libupnp.a
++
++include ../../Makefile.include
++-include $(filter %.P, $(OBJS:.o=.P))
++
++endif
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0002-UPnP-Platinum-log-allowed-values-with-state-variable.patch b/lib/libUPnP/patches/0002-UPnP-Platinum-log-allowed-values-with-state-variable.patch
new file mode 100644 (file)
index 0000000..05d8d6b
--- /dev/null
@@ -0,0 +1,39 @@
+From 58d8b1df5f6c631bd43c1bcda810a786c23de9ac Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Wed, 6 Jun 2012 17:04:31 +0100
+Subject: [PATCH 02/21] [UPnP] Platinum - log allowed values with state
+ variable errors
+
+---
+ lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+index 5dd2d61..229e304 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+@@ -197,12 +197,16 @@ PLT_StateVariable::ValidateValue(const char* value)
+             NPT_List<NPT_String>::Iterator val = values.GetFirstItem();
+             while (val) {
+                 val->Trim(" ");
+-                              if (!m_AllowedValues.Find(NPT_StringFinder(*val))) {
+-                                      NPT_LOG_WARNING_2("Invalid value of %s for state variable %s", 
+-                                              (const char*)*val,
+-                                              (const char*)m_Name);
++                if (!m_AllowedValues.Find(NPT_StringFinder(*val))) {
++                    NPT_LOG_WARNING_2("Invalid value of %s for state variable %s",
++                        (const char*)*val,
++                        (const char*)m_Name);
++                    for (unsigned long i=0; i < m_AllowedValues.GetItemCount(); i++) {
++                        NPT_String *val = *m_AllowedValues.GetItem(i);
++                        NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val);
++                    }
+                     return NPT_ERROR_INVALID_PARAMETERS;
+-                              }
++                }
+                 ++val;
+             }
+         }
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0003-UPnP-reinstated-changed-make-sure-Neptune-threads-ar.patch b/lib/libUPnP/patches/0003-UPnP-reinstated-changed-make-sure-Neptune-threads-ar.patch
new file mode 100644 (file)
index 0000000..ab199df
--- /dev/null
@@ -0,0 +1,46 @@
+From 922c1b38eddeca181acfba39c17e28819e8e18da Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Wed, 6 Jun 2012 19:22:09 +0100
+Subject: [PATCH] [UPnP] reinstated: 'changed: make sure Neptune threads are
+ named' by elupus @ 42d7b6b9180f634f988e12673de655228233b305
+
+---
+ .../Source/System/Win32/NptWin32Threads.cpp        | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
+index bd32fb3..aca91a1 100644
+--- a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
++++ b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
+@@ -506,6 +506,28 @@ NPT_Win32Thread::EntryPoint(void* argument)
+     NPT_System::GetCurrentTimeStamp(now);
+     NPT_System::SetRandomSeed((NPT_UInt32)(now.ToNanos()) + ::GetCurrentThreadId());
++    // set a default name
++    #pragma pack(push,8)
++    struct THREADNAME_INFO
++    {
++      DWORD  dwType;     // must be 0x1000
++      LPCSTR szName;     // pointer to name (in same addr space)
++      DWORD  dwThreadID; // thread ID (-1 caller thread)
++      DWORD  dwFlags;    // reserved for future use, most be zero
++    } info;
++    #pragma pack(pop)
++    info.dwType     = 0x1000;
++    info.szName     = "Neptune Thread";
++    info.dwThreadID = GetCurrentThreadId();
++    info.dwFlags    = 0;
++    __try
++    {
++      RaiseException(0x406d1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
++    }
++    __except(EXCEPTION_EXECUTE_HANDLER)
++    {
++    }
++
+     // run the thread 
+     thread->Run();
+     
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0004-UPnP-reinstated-fixed-upnp-server-s-http-server-woul.patch b/lib/libUPnP/patches/0004-UPnP-reinstated-fixed-upnp-server-s-http-server-woul.patch
new file mode 100644 (file)
index 0000000..c5355a1
--- /dev/null
@@ -0,0 +1,36 @@
+From e332ca20095fccfea9478650120c37f03fb500fd Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Wed, 6 Jun 2012 18:02:16 +0100
+Subject: [PATCH 03/21] [UPnP] reinstated: 'fixed: upnp server's http server
+ would not provide content length on HEAD requests' by
+ elupus @ 9cbcf5063c3af350d385f1992017f6883f37a8e0
+
+---
+ lib/libUPnP/Platinum/Source/Core/PltHttpServerTask.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltHttpServerTask.cpp b/lib/libUPnP/Platinum/Source/Core/PltHttpServerTask.cpp
+index 11a7ac0..7ffed7e 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltHttpServerTask.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltHttpServerTask.cpp
+@@ -279,7 +279,7 @@ PLT_HttpServerSocketTask::Write(NPT_HttpResponse* response,
+     // get the request entity to set additional headers
+     NPT_InputStreamReference body_stream;
+     NPT_HttpEntity* entity = response->GetEntity();
+-    if (entity && NPT_SUCCEEDED(entity->GetInputStream(body_stream))) {
++    if (entity) {
+         // set the content length if known
+         if (entity->ContentLengthIsKnown()) {
+             headers.SetHeader(NPT_HTTP_HEADER_CONTENT_LENGTH, 
+@@ -341,7 +341,7 @@ PLT_HttpServerSocketTask::Write(NPT_HttpResponse* response,
+     NPT_CHECK_WARNING(output_stream->WriteFully(header_stream.GetData(), header_stream.GetDataSize()));
+     // send response body if any
+-    if (!headers_only && !body_stream.IsNull()) {
++    if (!headers_only && NPT_SUCCEEDED(entity->GetInputStream(body_stream)) && !body_stream.IsNull()) {
+         NPT_CHECK_WARNING(NPT_StreamToStreamCopy(
+             *body_stream.AsPointer(), 
+             *output_stream.AsPointer(),
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0005-UPnP-reinstated-UPnP-use-server-provided-item-count-.patch b/lib/libUPnP/patches/0005-UPnP-reinstated-UPnP-use-server-provided-item-count-.patch
new file mode 100644 (file)
index 0000000..ed7d3cc
--- /dev/null
@@ -0,0 +1,96 @@
+From db5f6f17dad070f8046a80bf6077914b7fe86182 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Wed, 6 Jun 2012 18:40:00 +0100
+Subject: [PATCH 07/21] [UPnP] reinstated: '[UPnP] use server provided item
+ count to iterate browse req' by elupus @
+ cb110ea28b7506cb31d6ab4fd347fad1c96ec9ed
+
+all other modifications to libPlatinum/Neptune since codiqs last commit have
+been checked and are not required / have been included upstream
+
+the following patches therefore do not need to be reinstated:
+
+5e5156bde70bb4250c9d912e43656a19d008f110
+4df0a4cb1cd059f585de289a10ab915ce1bd95a8
+a6eaa587174f73c0fdd7a5130774772c7d475fec
+964b08aed02ee52d7f88250409b4e3fdd0363be3
+2f70d124f75d76813e48ecc26ffd9aa3625072aa
+299d326314619aa3a085f2c026e55860a75b3a5c
+5bbf59fbc049325ec4205fadaa0903a753b866ee
+370c8366ed83115558e4dcb00561207854c4f971
+755f17fe4353b7047ca04c16b7461d1ef3b8ed1b
+20c1ed61030f7a5bada60821507f29e54821b1a9
+0b11444d6e405fa17e73ef0abc9ceba25a559cce
+f96d966e7575b4d9f7c864ad153dd9fb968344c9
+99479c384176fd3f82d518506e560ba08ad57e40
+347aa55b6c55e2801ff7a421e8bcc02ce0314cab
+a1993bf0380b9ced60c39064833435e458aa5434
+f13f20aaa9493d58264c55f2a5b2cafd09435b0e
+95df1d019cb7ea64a6f748a9104db1ecd666af42
+887728b93d0a8cddd6a08bfddc4079f4c2ae82f8
+66d2daf7bd90f7be2cb4cdbc5088488627953e3f
+ec70e260e95becc5bfcd86512b245776ef9653ea
+296435b9a9262b23b49cbfb2302e36e730f292e7
+99e0a1eaf18ed07625143e4fadc6eb027f822857
+588a66a55067433ade77769a39c81552a995b38d
+3fd25488ba88b30cfa0f5b834bbde91a21f05a73
+---
+ .../Source/Devices/MediaServer/PltSyncMediaBrowser.cpp   | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+index 2bd23f8..091ae00 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+@@ -36,6 +36,7 @@
+ |   includes
+ +---------------------------------------------------------------------*/
+ #include "PltSyncMediaBrowser.h"
++#include <algorithm>
+ NPT_SET_LOCAL_LOGGER("platinum.media.server.syncbrowser")
+@@ -239,6 +240,7 @@ PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference&      device,
+ {
+     NPT_Result res = NPT_FAILURE;
+     NPT_Int32  index = start;
++    NPT_UInt32 count = 0;
+     
+     // only cache metadata or if starting from 0 and asking for maximum
+     bool cache = m_UseCache && (metadata || (start == 0 && max_results == 0));
+@@ -270,9 +272,15 @@ PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference&      device,
+         }
+         // server returned no more, bail now
+-        if (browse_data->info.items->GetItemCount() == 0)
++        if (browse_data->info.nr == 0)
+             break;
++        if (browse_data->info.nr != browse_data->info.items->GetItemCount()) {
++            NPT_LOG_WARNING_2("Server returned unexpected number of items (%d vs %d)",
++                              browse_data->info.nr, browse_data->info.items->GetItemCount());
++        }
++        count += std::max<NPT_UInt32>(browse_data->info.nr, browse_data->info.items->GetItemCount());
++
+         if (list.IsNull()) {
+             list = browse_data->info.items;
+         } else {
+@@ -290,12 +298,12 @@ PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference&      device,
+         // Unless we were told to stop after reaching a certain amount to avoid
+         // length delays
+         // (some servers may return a total matches out of whack at some point too)
+-        if ((browse_data->info.tm && browse_data->info.tm <= list->GetItemCount()) ||
+-            (max_results && list->GetItemCount() >= max_results))
++        if ((browse_data->info.tm && browse_data->info.tm <= count) ||
++            (max_results && count >= max_results))
+             break;
+         // ask for the next chunk of entries
+-        index = list->GetItemCount();
++        index = count;
+     } while(1);
+ done:
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0006-upnp-report-and-support-proper-mimetypes-for-matrosk.patch b/lib/libUPnP/patches/0006-upnp-report-and-support-proper-mimetypes-for-matrosk.patch
new file mode 100644 (file)
index 0000000..6f2e932
--- /dev/null
@@ -0,0 +1,39 @@
+From 404163dca7899d7dfb3b64d65b83adc7d9eeb173 Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@ecce.se>
+Date: Tue, 25 Sep 2012 23:32:48 +0200
+Subject: [PATCH] upnp: report and support proper mimetypes for matroska
+
+---
+ lib/libUPnP/Neptune/Source/Core/NptHttp.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/lib/libUPnP/Neptune/Source/Core/NptHttp.cpp b/lib/libUPnP/Neptune/Source/Core/NptHttp.cpp
+index a756fd8..07586f9 100644
+--- a/lib/libUPnP/Neptune/Source/Core/NptHttp.cpp
++++ b/lib/libUPnP/Neptune/Source/Core/NptHttp.cpp
+@@ -2880,12 +2880,14 @@ NPT_HttpFileRequestHandler_DefaultFileTypeMap[] = {
+     {"aif",  "audio/x-aiff"},
+     {"aifc", "audio/x-aiff"},
+     {"aiff", "audio/x-aiff"},
++    {"mka",  "audio/x-matroska"},
+     {"mpa",  "audio/mpeg"},
+     {"mp2",  "audio/mpeg"},
+     {"mp3",  "audio/mpeg"},
+     {"m4a",  "audio/mp4"},
+     {"wma",  "audio/x-ms-wma"},
+     {"wav",  "audio/x-wav"},
++    {"mkv",  "video/x-matroska"},
+     {"mpeg", "video/mpeg"},
+     {"mpg",  "video/mpeg"},
+     {"mp4",  "video/mp4"},
+@@ -2898,6 +2900,7 @@ NPT_HttpFileRequestHandler_DefaultFileTypeMap[] = {
+     {"wtv",  "video/x-ms-wmv"},
+     {"asf",  "video/x-ms-asf"},
+     {"mkv",  "video/x-matroska"},
++    {"mk3d", "video/x-matroska-3d"},
+     {"flv",  "video/x-flv"},
+     {"avi",  "video/x-msvideo"},
+     {"divx", "video/x-msvideo"},
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0007-UPnP-Platinum-should-also-support-sort-criterias-in-.patch b/lib/libUPnP/patches/0007-UPnP-Platinum-should-also-support-sort-criterias-in-.patch
new file mode 100644 (file)
index 0000000..c6c06bb
--- /dev/null
@@ -0,0 +1,26 @@
+From d5a14410bcc80340a29879fc2351865c45e373fc Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Fri, 14 Sep 2012 11:12:03 +0100
+Subject: [PATCH 08/21] [UPnP] Platinum should also support sort criterias in
+ format res@<property>
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+index 990869a..5b01b54 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+@@ -336,6 +336,8 @@ PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
+     NPT_List<NPT_String>::Iterator property = list.GetFirstItem();
+     while (property) {
+         NPT_List<NPT_String> parsed_property = (*property).Split(":");
++        if (parsed_property.GetItemCount() != 2)
++          parsed_property = (*property).Split("@");
+         if (parsed_property.GetItemCount() != 2 || 
+             (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) {
+             NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars());
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0008-Platinum-allow-some-statevariables-to-reset-to-defau.patch b/lib/libUPnP/patches/0008-Platinum-allow-some-statevariables-to-reset-to-defau.patch
new file mode 100644 (file)
index 0000000..4dd7683
--- /dev/null
@@ -0,0 +1,151 @@
+From ad0db59a112ff4cf62ffc18c9565e48b90c4e4e2 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Tue, 9 Oct 2012 10:14:39 +0100
+Subject: [PATCH 04/21] Platinum: allow some statevariables to reset to
+ default value after sending completed (needed for
+ ContainerUpdateIDs usage)
+
+---
+ lib/libUPnP/Platinum/Source/Core/PltService.cpp       | 11 +++++++++--
+ lib/libUPnP/Platinum/Source/Core/PltService.h         |  3 ++-
+ lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp | 16 ++++++++++++++--
+ lib/libUPnP/Platinum/Source/Core/PltStateVariable.h   | 10 +++++++++-
+ 4 files changed, 34 insertions(+), 6 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltService.cpp b/lib/libUPnP/Platinum/Source/Core/PltService.cpp
+index 3280b15..62bdc49 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltService.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltService.cpp
+@@ -460,14 +460,14 @@ PLT_Service::IsSubscribable()
+ |   PLT_Service::SetStateVariable
+ +---------------------------------------------------------------------*/
+ NPT_Result
+-PLT_Service::SetStateVariable(const char* name, const char* value)
++PLT_Service::SetStateVariable(const char* name, const char* value, const bool clearonsend /*=false*/)
+ {
+     PLT_StateVariable* stateVariable = NULL;
+     NPT_ContainerFind(m_StateVars, PLT_StateVariableNameFinder(name), stateVariable);
+     if (stateVariable == NULL)
+         return NPT_FAILURE;
+-    return stateVariable->SetValue(value);
++    return stateVariable->SetValue(value, clearonsend);
+ }
+ /*----------------------------------------------------------------------
+@@ -838,6 +838,13 @@ PLT_Service::NotifyChanged()
+         delete sub;
+     }
++    // some state variables must be cleared immediatly after sending
++    iter = vars_ready.GetFirstItem();
++    while (iter) {
++      PLT_StateVariable* var = *iter;
++      var->OnSendCompleted();
++      ++iter;
++    }
+     return NPT_SUCCESS;
+ }
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltService.h b/lib/libUPnP/Platinum/Source/Core/PltService.h
+index c03a552..9bd4d12 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltService.h
++++ b/lib/libUPnP/Platinum/Source/Core/PltService.h
+@@ -216,8 +216,9 @@ public:
+      when necessary.
+      @param name state variable name
+      @param value new State Variable value.
++     @param clearonsend whether the State Variable should clear immediatly in ::OnSendingCompleted
+      */
+-    NPT_Result SetStateVariable(const char* name, const char* value);
++    NPT_Result SetStateVariable(const char* name, const char* value, const bool clearonsend = false);
+     
+     /**
+      Certain state variables notifications must not be sent faster than a certain 
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+index 229e304..47aeb5a 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+@@ -48,7 +48,8 @@ NPT_SET_LOCAL_LOGGER("platinum.core.statevariable")
+ PLT_StateVariable::PLT_StateVariable(PLT_Service* service) : 
+     m_Service(service), 
+     m_AllowedValueRange(NULL),
+-    m_IsSendingEventsIndirectly(true)
++    m_IsSendingEventsIndirectly(true),
++    m_ShouldClearOnSend(false)
+ {
+ }
+@@ -145,7 +146,7 @@ PLT_StateVariable::SetRate(NPT_TimeInterval rate)
+ |   PLT_StateVariable::SetValue
+ +---------------------------------------------------------------------*/
+ NPT_Result
+-PLT_StateVariable::SetValue(const char* value)
++PLT_StateVariable::SetValue(const char* value, const bool clearonsend /*=false*/)
+ {
+     if (value == NULL) {
+         return NPT_FAILURE;
+@@ -159,6 +160,7 @@ PLT_StateVariable::SetValue(const char* value)
+         }
+         m_Value = value;
++        m_ShouldClearOnSend = clearonsend;
+         m_Service->AddChanged(this); 
+     }
+@@ -183,6 +185,16 @@ PLT_StateVariable::IsReadyToPublish()
+ }
+ /*----------------------------------------------------------------------
++|   PLT_StateVariable::OnSendCompleted
+++---------------------------------------------------------------------*/
++void
++PLT_StateVariable::OnSendCompleted()
++{
++  if(m_ShouldClearOnSend)
++      m_Value = m_DefaultValue;
++}
++
++/*----------------------------------------------------------------------
+ |   PLT_StateVariable::ValidateValue
+ +---------------------------------------------------------------------*/
+ NPT_Result
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.h b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.h
+index 46ec9e9..465e95c 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.h
++++ b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.h
+@@ -115,8 +115,9 @@ public:
+      it is an allowed value. Once the value is validated, it is marked for eventing by
+      calling the PLT_Service AddChanged function.
+      @param value new state variable value. Can be a comma separated list of values.
++     @param clearonsend whether the statevariable should be cleared immediatly after sending
+      */
+-    NPT_Result SetValue(const char* value);
++    NPT_Result SetValue(const char* value, const bool clearonsend = false);
+     
+     /**
+      Validate the new value of the state variable.
+@@ -173,6 +174,12 @@ protected:
+     bool IsReadyToPublish();
+     
+     /**
++     * If this statevariable should clear after sending to all subscribers, clears the value without
++     * eventing the change
++     */
++    void OnSendCompleted();
++
++    /**
+      Serialize the state variable into xml.
+      */
+       NPT_Result Serialize(NPT_XmlElementNode& node);
+@@ -189,6 +196,7 @@ protected:
+     NPT_String              m_DefaultValue;
+     bool                    m_IsSendingEvents;
+     bool                    m_IsSendingEventsIndirectly;
++    bool                    m_ShouldClearOnSend;
+     NPT_TimeInterval        m_Rate;
+     NPT_TimeStamp           m_LastEvent;
+     NPT_Array<NPT_String*>  m_AllowedValues;
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0009-UPnP-add-support-for-upnp-lastPlaybackPosition-upnp-.patch b/lib/libUPnP/patches/0009-UPnP-add-support-for-upnp-lastPlaybackPosition-upnp-.patch
new file mode 100644 (file)
index 0000000..1c7e200
--- /dev/null
@@ -0,0 +1,96 @@
+From e36e418d536733d04dc4cbab2ee520a31e4cfe69 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Mon, 30 Jul 2012 13:02:34 +0100
+Subject: [PATCH 09/21] [UPnP] add support for upnp:lastPlaybackPosition,
+ upnp:lastPlaybackTime and upnp:playbackCount
+
+---
+ .../Source/Devices/MediaServer/PltMediaItem.cpp    | 43 ++++++++++++++++++++++
+ .../Source/Devices/MediaServer/PltMediaItem.h      |  3 ++
+ 2 files changed, 46 insertions(+)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 5b974e8..214f13d 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -183,6 +183,9 @@ PLT_MediaObject::Reset()
+     m_ExtraInfo.artist_discography_uri = "";
+     m_MiscInfo.original_track_number = 0;
++    m_MiscInfo.last_position         = 0;
++    m_MiscInfo.last_time             = "";
++    m_MiscInfo.play_count            = -1;
+     m_MiscInfo.dvdregioncode           = 0;
+     m_MiscInfo.toc                                     = "";
+     m_MiscInfo.user_annotation                 = "";
+@@ -317,6 +320,27 @@ PLT_MediaObject::ToDidl(NPT_UInt32 mask, NPT_String& didl)
+         didl += "</upnp:originalTrackNumber>";
+     }
++    // last playback position
++    if (m_MiscInfo.last_position > 0) {
++        didl += "<upnp:lastPlaybackPosition>";
++        didl += NPT_String::FromInteger(m_MiscInfo.last_position);
++        didl += "</upnp:lastPlaybackPosition>";
++    }
++
++    // last playback datetime
++    if (!m_MiscInfo.last_time.IsEmpty()) {
++        didl += "<upnp:lastPlaybackTime>";
++        PLT_Didl::AppendXmlEscape(didl, m_MiscInfo.last_time);
++        didl += "</upnp:lastPlaybackTime>";
++    }
++
++    // playcount
++    if (m_MiscInfo.play_count > -1) {
++        didl += "<upnp:playbackCount>";
++        didl += NPT_String::FromInteger(m_MiscInfo.play_count);
++        didl += "</upnp:playbackCount>";
++    }
++
+     // program title
+     if (mask & PLT_FILTER_MASK_PROGRAMTITLE && !m_Recorded.program_title.IsEmpty()) {
+         didl += "<upnp:programTitle>";
+@@ -511,6 +535,25 @@ PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
+     if (NPT_FAILED(str.ToInteger(value))) value = 0;
+     m_MiscInfo.original_track_number = value;
++    PLT_XmlHelper::GetChildText(entry, "lastPlaybackPosition", str, didl_namespace_upnp);
++    if (NPT_FAILED(str.ToInteger(value))) value = 0;
++    m_MiscInfo.last_position = value;
++
++    PLT_XmlHelper::GetChildText(entry, "lastPlaybackTime", m_MiscInfo.last_time, didl_namespace_dc, 256);
++    NPT_String parsed_last_time;
++    for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
++        NPT_DateTime date;
++        if (NPT_SUCCEEDED(date.FromString(m_MiscInfo.last_time, (NPT_DateTime::Format)format))) {
++            parsed_last_time = date.ToString((NPT_DateTime::Format)format);
++            break;
++        }
++    }
++    m_MiscInfo.last_time = parsed_last_time;
++
++    PLT_XmlHelper::GetChildText(entry, "playbackCount", str, didl_namespace_upnp);
++    if (NPT_FAILED(str.ToInteger(value))) value = -1;
++    m_MiscInfo.play_count = value;
++
+     children.Clear();
+     PLT_XmlHelper::GetChildren(entry, children, "res");
+     for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) {
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+index 3ebc3b0..8261244 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+@@ -130,6 +130,9 @@ typedef struct {
+     NPT_UInt32 original_track_number;
+     NPT_String toc;
+     NPT_String user_annotation; //TODO: can be multiple
++    NPT_UInt32 last_position;
++    NPT_String last_time;
++    NPT_Int32  play_count;
+ } PLT_MiscInfo;
+ typedef struct {
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0010-Platinum-use-PersonRole-for-directors.-Also-fixes-Fr.patch b/lib/libUPnP/patches/0010-Platinum-use-PersonRole-for-directors.-Also-fixes-Fr.patch
new file mode 100644 (file)
index 0000000..6389f7a
--- /dev/null
@@ -0,0 +1,129 @@
+From b4bfe2c005f264691f77982127790e45fe6ac51d Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Sun, 7 Oct 2012 10:46:54 +0100
+Subject: [PATCH 10/21] Platinum: use PersonRole for directors. Also fixes
+ ::FromDidl for authors, actors, directors -
+ previously duplicate entries were present
+
+---
+ .../Platinum/Source/Devices/MediaServer/PltDidl.h  | 40 ++++++++++++----------
+ .../Source/Devices/MediaServer/PltMediaItem.cpp    | 12 +++++++
+ .../Source/Devices/MediaServer/PltMediaItem.h      |  2 +-
+ 3 files changed, 34 insertions(+), 20 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+index f6eaf14..c50d450 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+@@ -61,28 +61,29 @@
+ #define PLT_FILTER_MASK_ORIGINALTRACK               0x00000100
+ #define PLT_FILTER_MASK_ACTOR                       0x00000200
+ #define PLT_FILTER_MASK_AUTHOR                      0x00000400
+-#define PLT_FILTER_MASK_DATE                        0x00000800
+-#define PLT_FILTER_MASK_PROGRAMTITLE                0x00001000
+-#define PLT_FILTER_MASK_SERIESTITLE                 0x00002000
+-#define PLT_FILTER_MASK_EPISODE                     0x00004000
+-#define PLT_FILTER_MASK_TITLE                       0x00008000
++#define PLT_FILTER_MASK_DIRECTOR                    0x00000800
++#define PLT_FILTER_MASK_DATE                        0x00001000
++#define PLT_FILTER_MASK_PROGRAMTITLE                0x00002000
++#define PLT_FILTER_MASK_SERIESTITLE                 0x00004000
++#define PLT_FILTER_MASK_EPISODE                     0x00008000
++#define PLT_FILTER_MASK_TITLE                       0x00010000
+-#define PLT_FILTER_MASK_RES                         0x00010000
+-#define PLT_FILTER_MASK_RES_DURATION                0x00020000
+-#define PLT_FILTER_MASK_RES_SIZE                    0x00040000
+-#define PLT_FILTER_MASK_RES_PROTECTION              0x00080000
+-#define PLT_FILTER_MASK_RES_RESOLUTION              0x00100000
+-#define PLT_FILTER_MASK_RES_BITRATE                 0x00200000
+-#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           0x00400000
+-#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS                   0x00800000
+-#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY                   0x01000000
++#define PLT_FILTER_MASK_RES                         0x00020000
++#define PLT_FILTER_MASK_RES_DURATION                0x00040000
++#define PLT_FILTER_MASK_RES_SIZE                    0x00080000
++#define PLT_FILTER_MASK_RES_PROTECTION              0x00100000
++#define PLT_FILTER_MASK_RES_RESOLUTION              0x00200000
++#define PLT_FILTER_MASK_RES_BITRATE                 0x00400000
++#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           0x00800000
++#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS         0x01000000
++#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY         0x02000000
+-#define PLT_FILTER_MASK_LONGDESCRIPTION             0x02000000
+-#define PLT_FILTER_MASK_ICON                        0x04000000
++#define PLT_FILTER_MASK_LONGDESCRIPTION             0x04000000
++#define PLT_FILTER_MASK_ICON                        0x08000000
+-#define PLT_FILTER_MASK_TOC                                                   0x02000000
+-#define PLT_FILTER_MASK_SEARCHCLASS                                   0x04000000
+-#define PLT_FILTER_MASK_REFID                       0x08000000
++#define PLT_FILTER_MASK_TOC                         0x10000000
++#define PLT_FILTER_MASK_SEARCHCLASS                 0x20000000
++#define PLT_FILTER_MASK_REFID                       0x40000000
+ #define PLT_FILTER_FIELD_TITLE                      "dc:title"
+ #define PLT_FILTER_FIELD_CREATOR                    "dc:creator"
+@@ -90,6 +91,7 @@
+ #define PLT_FILTER_FIELD_ARTIST                     "upnp:artist"
+ #define PLT_FILTER_FIELD_ACTOR                      "upnp:actor"
+ #define PLT_FILTER_FIELD_AUTHOR                     "upnp:author"
++#define PLT_FILTER_FIELD_DIRECTOR                   "upnp:director"
+ #define PLT_FILTER_FIELD_ALBUM                      "upnp:album"
+ #define PLT_FILTER_FIELD_GENRE                      "upnp:genre"
+ #define PLT_FILTER_FIELD_ALBUMARTURI                "upnp:albumArtURI"
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 214f13d..64437d2 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -253,6 +253,11 @@ PLT_MediaObject::ToDidl(NPT_UInt32 mask, NPT_String& didl)
+         m_People.authors.ToDidl(didl, "author");
+     }
+     
++    // director
++    if (mask & PLT_FILTER_MASK_DIRECTOR) {
++        m_People.directors.ToDidl(didl, "director");
++    }
++
+     // album
+     if ((mask & PLT_FILTER_MASK_ALBUM) && !m_Affiliation.album.IsEmpty()) {
+         didl += "<upnp:album>";
+@@ -489,15 +494,22 @@ PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
+     m_Title = m_Title.SubString(0, 256);    
+     m_ObjectClass.type =  m_ObjectClass.type.SubString(0, 256);
++    children.Clear();
+     PLT_XmlHelper::GetChildren(entry, children, "artist", didl_namespace_upnp);
+     m_People.artists.FromDidl(children);
+     
++    children.Clear();
+     PLT_XmlHelper::GetChildren(entry, children, "author", didl_namespace_upnp);
+     m_People.authors.FromDidl(children);
+     
++    children.Clear();
+     PLT_XmlHelper::GetChildren(entry, children, "actors", didl_namespace_upnp);
+     m_People.actors.FromDidl(children);
++    children.Clear();
++    PLT_XmlHelper::GetChildren(entry, children, "director", didl_namespace_upnp);
++    m_People.directors.FromDidl(children);
++
+     PLT_XmlHelper::GetChildText(entry, "album", m_Affiliation.album, didl_namespace_upnp, 256);
+     PLT_XmlHelper::GetChildText(entry, "programTitle", m_Recorded.program_title, didl_namespace_upnp);
+     PLT_XmlHelper::GetChildText(entry, "seriesTitle", m_Recorded.series_title, didl_namespace_upnp);
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+index 8261244..84704b1 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+@@ -91,7 +91,7 @@ typedef struct {
+     PLT_PersonRoles actors;
+     PLT_PersonRoles authors;
+     NPT_String      producer; //TODO: can be multiple
+-    NPT_String      director; //TODO: can be multiple
++    PLT_PersonRoles directors;
+     NPT_String      publisher; //TODO: can be multiple
+     NPT_String      contributor; // should match m_Creator (dc:creator) //TODO: can be multiple
+ } PLT_PeopleInfo;
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0011-UPnP-support-video-ratings.patch b/lib/libUPnP/patches/0011-UPnP-support-video-ratings.patch
new file mode 100644 (file)
index 0000000..ec6201b
--- /dev/null
@@ -0,0 +1,66 @@
+From 8e9605a51d2d05c6f8784eed86e5764506bc57b2 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Sat, 6 Oct 2012 23:35:52 +0100
+Subject: [PATCH 11/21] [UPnP] support video ratings
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h        | 8 +++++---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp | 8 ++++++++
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+index c50d450..8d9704f 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+@@ -80,10 +80,11 @@
+ #define PLT_FILTER_MASK_LONGDESCRIPTION             0x04000000
+ #define PLT_FILTER_MASK_ICON                        0x08000000
++#define PLT_FILTER_MASK_RATING                      0x10000000
+-#define PLT_FILTER_MASK_TOC                         0x10000000
+-#define PLT_FILTER_MASK_SEARCHCLASS                 0x20000000
+-#define PLT_FILTER_MASK_REFID                       0x40000000
++#define PLT_FILTER_MASK_TOC                         0x20000000
++#define PLT_FILTER_MASK_SEARCHCLASS                 0x40000000
++#define PLT_FILTER_MASK_REFID                       0x80000000
+ #define PLT_FILTER_FIELD_TITLE                      "dc:title"
+ #define PLT_FILTER_FIELD_CREATOR                    "dc:creator"
+@@ -99,6 +100,7 @@
+ #define PLT_FILTER_FIELD_DESCRIPTION                "dc:description"
+ #define PLT_FILTER_FIELD_LONGDESCRIPTION            "upnp:longDescription"
+ #define PLT_FILTER_FIELD_ICON                       "upnp:icon"
++#define PLT_FILTER_FIELD_RATING                     "upnp:rating"
+ #define PLT_FILTER_FIELD_ORIGINALTRACK              "upnp:originalTrackNumber"
+ #define PLT_FILTER_FIELD_PROGRAMTITLE               "upnp:programTitle"
+ #define PLT_FILTER_FIELD_SERIESTITLE                "upnp:seriesTitle"
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 64437d2..0a55eef 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -318,6 +318,13 @@ PLT_MediaObject::ToDidl(NPT_UInt32 mask, NPT_String& didl)
+         didl += "</upnp:icon>";
+     }
++    // rating
++    if ((mask & PLT_FILTER_MASK_RATING) && !m_Description.rating.IsEmpty()) {
++        didl += "<upnp:rating>";
++        PLT_Didl::AppendXmlEscape(didl, m_Description.rating);
++        didl += "</upnp:rating>";
++    }
++
+     // original track number
+     if ((mask & PLT_FILTER_MASK_ORIGINALTRACK) && m_MiscInfo.original_track_number > 0) {
+         didl += "<upnp:originalTrackNumber>";
+@@ -529,6 +536,7 @@ PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
+     PLT_XmlHelper::GetChildText(entry, "description", m_Description.description, didl_namespace_dc);
+     PLT_XmlHelper::GetChildText(entry, "longDescription", m_Description.long_description, didl_namespace_upnp);
+     PLT_XmlHelper::GetChildText(entry, "icon", m_Description.icon_uri, didl_namespace_upnp);
++    PLT_XmlHelper::GetChildText(entry, "rating", m_Description.rating, didl_namespace_upnp);
+       PLT_XmlHelper::GetChildText(entry, "toc", m_MiscInfo.toc, didl_namespace_upnp);
+     
+     // album arts
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0012-UPnP-increase-number-of-requested-items-per-iteratio.patch b/lib/libUPnP/patches/0012-UPnP-increase-number-of-requested-items-per-iteratio.patch
new file mode 100644 (file)
index 0000000..48604a0
--- /dev/null
@@ -0,0 +1,26 @@
+From 76de0e319e443f8fde00979682280005930ffcf9 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Thu, 11 Oct 2012 13:22:35 +0100
+Subject: [PATCH 12/21] [UPnP] increase number of requested items per
+ iteration. gives 2-3 times speed up.
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+index 091ae00..bea1064 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+@@ -262,7 +262,7 @@ PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference&      device,
+             device,
+             (const char*)object_id,
+             index,
+-            metadata?1:30, // DLNA recommendations for browsing children is no more than 30 at a time
++            metadata?1:200, // DLNA recommendations for browsing children is no more than 30 at a time
+             metadata);                
+         NPT_CHECK_LABEL_WARNING(res, done);
+         
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0013-upnp-fixes-support-for-filtering-by-the-extended-pro.patch b/lib/libUPnP/patches/0013-upnp-fixes-support-for-filtering-by-the-extended-pro.patch
new file mode 100644 (file)
index 0000000..5a6113e
--- /dev/null
@@ -0,0 +1,71 @@
+From 3f9fff2f4372991836c1691d8c5fb2a91424c2aa Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Thu, 25 Oct 2012 11:59:46 +0100
+Subject: [PATCH 13/21] upnp: fixes support for filtering by the extended
+ properties we need
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp         | 6 ++++++
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp    | 1 +
+ .../Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h       | 2 +-
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+index 2c20b25..6ad2ec4 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+@@ -92,6 +92,8 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+             mask |= PLT_FILTER_MASK_ARTIST;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ACTOR, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_ACTOR;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DIRECTOR, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_DIRECTOR;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_AUTHOR, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_AUTHOR;       
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DATE, len, true) == 0) {
+@@ -105,6 +107,8 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+             mask |= PLT_FILTER_MASK_ALBUMARTURI;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_DESCRIPTION, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_DESCRIPTION;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LONGDESCRIPTION, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_LONGDESCRIPTION;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ORIGINALTRACK, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_ORIGINALTRACK;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SEARCHABLE, len, true) == 0) {
+@@ -123,6 +127,8 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+             mask |= PLT_FILTER_MASK_SERIESTITLE;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_EPISODE, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_EPISODE;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RATING, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_RATING;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_RES;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_RES_DURATION, len, true) == 0 ||
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 0a55eef..01cf13f 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -171,6 +171,7 @@ PLT_MediaObject::Reset()
+     m_People.actors.Clear();
+     m_People.artists.Clear();    
+     m_People.authors.Clear();
++    m_People.directors.Clear();
+     m_Affiliation.album     = "";
+     m_Affiliation.genres.Clear();
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
+index e628af9..5722b82 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
+@@ -118,7 +118,7 @@ protected:
+                           NPT_Int32                index, 
+                           NPT_Int32                count,
+                           bool                     browse_metadata = false,
+-                          const char*              filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:album,upnp:artist,upnp:author,searchable,childCount", // explicitely specify res otherwise WMP won't return a URL!
++                          const char*              filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,searchable,childCount", // explicitely specify res otherwise WMP won't return a URL!
+                           const char*              sort = "");
+ private:
+     NPT_Result Find(const char* ip, PLT_DeviceDataReference& device);
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0014-Platinum-switch-to-NPT_UInt64-for-bitmask-flags.patch b/lib/libUPnP/patches/0014-Platinum-switch-to-NPT_UInt64-for-bitmask-flags.patch
new file mode 100644 (file)
index 0000000..873a6cd
--- /dev/null
@@ -0,0 +1,212 @@
+From 5e3cec1f974afc902a916e3cfb931c584d61245b Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Fri, 26 Oct 2012 12:30:04 +0100
+Subject: [PATCH 14/21] Platinum: switch to NPT_UInt64 for bitmask flags
+
+---
+ .../Source/Devices/MediaServer/PltDidl.cpp         |  6 +-
+ .../Platinum/Source/Devices/MediaServer/PltDidl.h  | 68 +++++++++++-----------
+ .../Source/Devices/MediaServer/PltMediaItem.cpp    |  6 +-
+ .../Source/Devices/MediaServer/PltMediaItem.h      |  6 +-
+ .../Devices/MediaServer/PltSyncMediaBrowser.h      |  2 +-
+ 5 files changed, 44 insertions(+), 44 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+index 6ad2ec4..6f72dda 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+@@ -56,7 +56,7 @@ const char* didl_namespace_dlna = "urn:schemas-dlna-org:metadata-1-0/";
+ /*----------------------------------------------------------------------
+ |   PLT_Didl::ConvertFilterToMask
+ +---------------------------------------------------------------------*/
+-NPT_UInt32 
++NPT_UInt64
+ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+ {
+     // easy out
+@@ -66,7 +66,7 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+     // a given DIDL property (or set of properties).  
+     // These fields are or start with: upnp:, @, res@, res, dc:, container@
+-    NPT_UInt32  mask = 0;
++    NPT_UInt64  mask = 0;
+     const char* s = filter;
+     int         i = 0;
+@@ -301,7 +301,7 @@ PLT_Didl::ParseTimeStamp(const NPT_String& timestamp, NPT_UInt32& seconds)
+ NPT_Result
+ PLT_Didl::ToDidl(PLT_MediaObject& object, const NPT_String& filter, NPT_String& didl)
+ {
+-    NPT_UInt32 mask = ConvertFilterToMask(filter);
++    NPT_UInt64 mask = ConvertFilterToMask(filter);
+     // Allocate enough space for the didl
+     didl.Reserve(2048);
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+index 8d9704f..29ce9ca 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+@@ -48,43 +48,43 @@
+ /*----------------------------------------------------------------------
+ |   constants
+ +---------------------------------------------------------------------*/
+-#define PLT_FILTER_MASK_ALL                         0xFFFFFFFF
++#define PLT_FILTER_MASK_ALL                         0xFFFFFFFFFFFFFFFF
+-#define PLT_FILTER_MASK_CREATOR                     0x00000001
+-#define PLT_FILTER_MASK_ARTIST                      0x00000002
+-#define PLT_FILTER_MASK_ALBUM                       0x00000004
+-#define PLT_FILTER_MASK_GENRE                       0x00000008
+-#define PLT_FILTER_MASK_ALBUMARTURI                 0x00000010
+-#define PLT_FILTER_MASK_DESCRIPTION                 0x00000020
+-#define PLT_FILTER_MASK_SEARCHABLE                  0x00000040
+-#define PLT_FILTER_MASK_CHILDCOUNT                  0x00000080
+-#define PLT_FILTER_MASK_ORIGINALTRACK               0x00000100
+-#define PLT_FILTER_MASK_ACTOR                       0x00000200
+-#define PLT_FILTER_MASK_AUTHOR                      0x00000400
+-#define PLT_FILTER_MASK_DIRECTOR                    0x00000800
+-#define PLT_FILTER_MASK_DATE                        0x00001000
+-#define PLT_FILTER_MASK_PROGRAMTITLE                0x00002000
+-#define PLT_FILTER_MASK_SERIESTITLE                 0x00004000
+-#define PLT_FILTER_MASK_EPISODE                     0x00008000
+-#define PLT_FILTER_MASK_TITLE                       0x00010000
++#define PLT_FILTER_MASK_CREATOR                     0x0000000000000001
++#define PLT_FILTER_MASK_ARTIST                      0x0000000000000002
++#define PLT_FILTER_MASK_ALBUM                       0x0000000000000004
++#define PLT_FILTER_MASK_GENRE                       0x0000000000000008
++#define PLT_FILTER_MASK_ALBUMARTURI                 0x0000000000000010
++#define PLT_FILTER_MASK_DESCRIPTION                 0x0000000000000020
++#define PLT_FILTER_MASK_SEARCHABLE                  0x0000000000000040
++#define PLT_FILTER_MASK_CHILDCOUNT                  0x0000000000000080
++#define PLT_FILTER_MASK_ORIGINALTRACK               0x0000000000000100
++#define PLT_FILTER_MASK_ACTOR                       0x0000000000000200
++#define PLT_FILTER_MASK_AUTHOR                      0x0000000000000400
++#define PLT_FILTER_MASK_DIRECTOR                    0x0000000000000800
++#define PLT_FILTER_MASK_DATE                        0x0000000000001000
++#define PLT_FILTER_MASK_PROGRAMTITLE                0x0000000000002000
++#define PLT_FILTER_MASK_SERIESTITLE                 0x0000000000004000
++#define PLT_FILTER_MASK_EPISODE                     0x0000000000008000
++#define PLT_FILTER_MASK_TITLE                       0x0000000000010000
+-#define PLT_FILTER_MASK_RES                         0x00020000
+-#define PLT_FILTER_MASK_RES_DURATION                0x00040000
+-#define PLT_FILTER_MASK_RES_SIZE                    0x00080000
+-#define PLT_FILTER_MASK_RES_PROTECTION              0x00100000
+-#define PLT_FILTER_MASK_RES_RESOLUTION              0x00200000
+-#define PLT_FILTER_MASK_RES_BITRATE                 0x00400000
+-#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           0x00800000
+-#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS         0x01000000
+-#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY         0x02000000
++#define PLT_FILTER_MASK_RES                         0x0000000000020000
++#define PLT_FILTER_MASK_RES_DURATION                0x0000000000040000
++#define PLT_FILTER_MASK_RES_SIZE                    0x0000000000080000
++#define PLT_FILTER_MASK_RES_PROTECTION              0x0000000000100000
++#define PLT_FILTER_MASK_RES_RESOLUTION              0x0000000000200000
++#define PLT_FILTER_MASK_RES_BITRATE                 0x0000000000400000
++#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           0x0000000000800000
++#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS         0x0000000001000000
++#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY         0x0000000002000000
+-#define PLT_FILTER_MASK_LONGDESCRIPTION             0x04000000
+-#define PLT_FILTER_MASK_ICON                        0x08000000
+-#define PLT_FILTER_MASK_RATING                      0x10000000
++#define PLT_FILTER_MASK_LONGDESCRIPTION             0x0000000004000000
++#define PLT_FILTER_MASK_ICON                        0x0000000008000000
++#define PLT_FILTER_MASK_RATING                      0x0000000010000000
+-#define PLT_FILTER_MASK_TOC                         0x20000000
+-#define PLT_FILTER_MASK_SEARCHCLASS                 0x40000000
+-#define PLT_FILTER_MASK_REFID                       0x80000000
++#define PLT_FILTER_MASK_TOC                         0x0000000020000000
++#define PLT_FILTER_MASK_SEARCHCLASS                 0x0000000040000000
++#define PLT_FILTER_MASK_REFID                       0x0000000080000000
+ #define PLT_FILTER_FIELD_TITLE                      "dc:title"
+ #define PLT_FILTER_FIELD_CREATOR                    "dc:creator"
+@@ -156,7 +156,7 @@ public:
+         return res;
+     }
+-    static NPT_UInt32  ConvertFilterToMask(const NPT_String& filter);
++    static NPT_UInt64  ConvertFilterToMask(const NPT_String& filter);
+ };
+ #endif /* _PLT_DIDL_H_ */
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 01cf13f..a3561fd 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -215,7 +215,7 @@ PLT_MediaObject::ToDidl(const NPT_String& filter, NPT_String& didl)
+ |   PLT_MediaObject::ToDidl
+ +---------------------------------------------------------------------*/
+ NPT_Result
+-PLT_MediaObject::ToDidl(NPT_UInt32 mask, NPT_String& didl)
++PLT_MediaObject::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+ {
+     // title is required
+     didl += "<dc:title>";
+@@ -683,7 +683,7 @@ PLT_MediaItem::ToDidl(const NPT_String& filter, NPT_String& didl)
+ |   PLT_MediaItem::ToDidl
+ +---------------------------------------------------------------------*/
+ NPT_Result
+-PLT_MediaItem::ToDidl(NPT_UInt32 mask, NPT_String& didl)
++PLT_MediaItem::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+ {
+     didl += "<item id=\"";
+@@ -774,7 +774,7 @@ PLT_MediaContainer::ToDidl(const NPT_String& filter, NPT_String& didl)
+ |   PLT_MediaContainer::ToDidl
+ +---------------------------------------------------------------------*/
+ NPT_Result
+-PLT_MediaContainer::ToDidl(NPT_UInt32 mask, NPT_String& didl)
++PLT_MediaContainer::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+ {
+       // container id property
+     didl += "<container id=\"";
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+index 84704b1..6cd597d 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
+@@ -196,7 +196,7 @@ public:
+     virtual NPT_Result Reset();
+     virtual NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl);
+-    virtual NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl);
++    virtual NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl);
+     virtual NPT_Result FromDidl(NPT_XmlElementNode* entry);
+ public:
+@@ -248,7 +248,7 @@ public:
+     // PLT_MediaObject methods
+     NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl);
+-    NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl);
++    NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl);
+     NPT_Result FromDidl(NPT_XmlElementNode* entry);
+ };
+@@ -271,7 +271,7 @@ public:
+     // PLT_MediaObject methods
+     NPT_Result Reset();
+     NPT_Result ToDidl(const NPT_String& filter, NPT_String& didl);
+-    NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl);
++    NPT_Result ToDidl(NPT_UInt64 mask, NPT_String& didl);
+     NPT_Result FromDidl(NPT_XmlElementNode* entry);
+ public:
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
+index 5722b82..e83a73b 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
+@@ -118,7 +118,7 @@ protected:
+                           NPT_Int32                index, 
+                           NPT_Int32                count,
+                           bool                     browse_metadata = false,
+-                          const char*              filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,searchable,childCount", // explicitely specify res otherwise WMP won't return a URL!
++                          const char*              filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,searchable,childCount", // explicitely specify res otherwise WMP won't return a URL!
+                           const char*              sort = "");
+ private:
+     NPT_Result Find(const char* ip, PLT_DeviceDataReference& device);
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0015-Platinum-fix-missing-filtering-for-extra-metadata.patch b/lib/libUPnP/patches/0015-Platinum-fix-missing-filtering-for-extra-metadata.patch
new file mode 100644 (file)
index 0000000..6664604
--- /dev/null
@@ -0,0 +1,85 @@
+From 9f4aff60ebe92e98df47ae61e243af1a845c1c42 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Fri, 26 Oct 2012 12:57:58 +0100
+Subject: [PATCH 15/21] Platinum: fix missing filtering for extra metadata
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp      | 6 ++++++
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h        | 7 +++++++
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp | 6 +++---
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+index 6f72dda..73f9ed2 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
+@@ -111,6 +111,12 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
+             mask |= PLT_FILTER_MASK_LONGDESCRIPTION;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_ORIGINALTRACK, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_ORIGINALTRACK;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LASTPOSITION, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_LASTPOSITION;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_LASTPLAYBACK, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_LASTPLAYBACK;
++        } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_PLAYCOUNT, len, true) == 0) {
++            mask |= PLT_FILTER_MASK_PLAYCOUNT;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SEARCHABLE, len, true) == 0) {
+             mask |= PLT_FILTER_MASK_SEARCHABLE;
+         } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_SEARCHCLASS, len, true) == 0) {
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+index 29ce9ca..9af9725 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+@@ -86,6 +86,10 @@
+ #define PLT_FILTER_MASK_SEARCHCLASS                 0x0000000040000000
+ #define PLT_FILTER_MASK_REFID                       0x0000000080000000
++#define PLT_FILTER_MASK_LASTPOSITION                0x0000000100000000
++#define PLT_FILTER_MASK_LASTPLAYBACK                0x0000000200000000
++#define PLT_FILTER_MASK_PLAYCOUNT                   0x0000000400000000
++
+ #define PLT_FILTER_FIELD_TITLE                      "dc:title"
+ #define PLT_FILTER_FIELD_CREATOR                    "dc:creator"
+ #define PLT_FILTER_FIELD_DATE                       "dc:date"
+@@ -105,6 +109,9 @@
+ #define PLT_FILTER_FIELD_PROGRAMTITLE               "upnp:programTitle"
+ #define PLT_FILTER_FIELD_SERIESTITLE                "upnp:seriesTitle"
+ #define PLT_FILTER_FIELD_EPISODE                    "upnp:episodeNumber"
++#define PLT_FILTER_FIELD_LASTPOSITION               "upnp:lastPlaybackPosition"
++#define PLT_FILTER_FIELD_LASTPLAYBACK               "upnp:lastPlaybackTime"
++#define PLT_FILTER_FIELD_PLAYCOUNT                  "upnp:playbackCount"
+ #define PLT_FILTER_FIELD_SEARCHCLASS                          "upnp:searchClass"
+ #define PLT_FILTER_FIELD_SEARCHABLE                 "@searchable"
+ #define PLT_FILTER_FIELD_CHILDCOUNT                 "@childcount"
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index a3561fd..3856001 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -334,21 +334,21 @@ PLT_MediaObject::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+     }
+     // last playback position
+-    if (m_MiscInfo.last_position > 0) {
++    if (mask & PLT_FILTER_MASK_LASTPOSITION && m_MiscInfo.last_position > 0) {
+         didl += "<upnp:lastPlaybackPosition>";
+         didl += NPT_String::FromInteger(m_MiscInfo.last_position);
+         didl += "</upnp:lastPlaybackPosition>";
+     }
+     // last playback datetime
+-    if (!m_MiscInfo.last_time.IsEmpty()) {
++    if (mask & PLT_FILTER_MASK_LASTPLAYBACK && !m_MiscInfo.last_time.IsEmpty()) {
+         didl += "<upnp:lastPlaybackTime>";
+         PLT_Didl::AppendXmlEscape(didl, m_MiscInfo.last_time);
+         didl += "</upnp:lastPlaybackTime>";
+     }
+     // playcount
+-    if (m_MiscInfo.play_count > -1) {
++    if (mask & PLT_FILTER_MASK_PLAYCOUNT && m_MiscInfo.play_count > -1) {
+         didl += "<upnp:playbackCount>";
+         didl += NPT_String::FromInteger(m_MiscInfo.play_count);
+         didl += "</upnp:playbackCount>";
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0016-osx-fix-compilation-by-using-the-right-suffix-for-64.patch b/lib/libUPnP/patches/0016-osx-fix-compilation-by-using-the-right-suffix-for-64.patch
new file mode 100644 (file)
index 0000000..3c24bff
--- /dev/null
@@ -0,0 +1,101 @@
+From 152462afb82c13dd2a723f1c256c07e86457ccc3 Mon Sep 17 00:00:00 2001
+From: Memphiz <memphis@machzwo.de>
+Date: Fri, 26 Oct 2012 18:08:59 +0200
+Subject: [PATCH 16/21] [osx] - fix compilation by using the right suffix for
+ 64bit constants
+
+---
+ .../Platinum/Source/Devices/MediaServer/PltDidl.h  | 72 +++++++++++-----------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+index 9af9725..59d1605 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
+@@ -48,47 +48,47 @@
+ /*----------------------------------------------------------------------
+ |   constants
+ +---------------------------------------------------------------------*/
+-#define PLT_FILTER_MASK_ALL                         0xFFFFFFFFFFFFFFFF
++#define PLT_FILTER_MASK_ALL                         NPT_UINT64_C(0xFFFFFFFFFFFFFFFF)
+-#define PLT_FILTER_MASK_CREATOR                     0x0000000000000001
+-#define PLT_FILTER_MASK_ARTIST                      0x0000000000000002
+-#define PLT_FILTER_MASK_ALBUM                       0x0000000000000004
+-#define PLT_FILTER_MASK_GENRE                       0x0000000000000008
+-#define PLT_FILTER_MASK_ALBUMARTURI                 0x0000000000000010
+-#define PLT_FILTER_MASK_DESCRIPTION                 0x0000000000000020
+-#define PLT_FILTER_MASK_SEARCHABLE                  0x0000000000000040
+-#define PLT_FILTER_MASK_CHILDCOUNT                  0x0000000000000080
+-#define PLT_FILTER_MASK_ORIGINALTRACK               0x0000000000000100
+-#define PLT_FILTER_MASK_ACTOR                       0x0000000000000200
+-#define PLT_FILTER_MASK_AUTHOR                      0x0000000000000400
+-#define PLT_FILTER_MASK_DIRECTOR                    0x0000000000000800
+-#define PLT_FILTER_MASK_DATE                        0x0000000000001000
+-#define PLT_FILTER_MASK_PROGRAMTITLE                0x0000000000002000
+-#define PLT_FILTER_MASK_SERIESTITLE                 0x0000000000004000
+-#define PLT_FILTER_MASK_EPISODE                     0x0000000000008000
+-#define PLT_FILTER_MASK_TITLE                       0x0000000000010000
++#define PLT_FILTER_MASK_CREATOR                     NPT_UINT64_C(0x0000000000000001)
++#define PLT_FILTER_MASK_ARTIST                      NPT_UINT64_C(0x0000000000000002)
++#define PLT_FILTER_MASK_ALBUM                       NPT_UINT64_C(0x0000000000000004)
++#define PLT_FILTER_MASK_GENRE                       NPT_UINT64_C(0x0000000000000008)
++#define PLT_FILTER_MASK_ALBUMARTURI                 NPT_UINT64_C(0x0000000000000010)
++#define PLT_FILTER_MASK_DESCRIPTION                 NPT_UINT64_C(0x0000000000000020)
++#define PLT_FILTER_MASK_SEARCHABLE                  NPT_UINT64_C(0x0000000000000040)
++#define PLT_FILTER_MASK_CHILDCOUNT                  NPT_UINT64_C(0x0000000000000080)
++#define PLT_FILTER_MASK_ORIGINALTRACK               NPT_UINT64_C(0x0000000000000100)
++#define PLT_FILTER_MASK_ACTOR                       NPT_UINT64_C(0x0000000000000200)
++#define PLT_FILTER_MASK_AUTHOR                      NPT_UINT64_C(0x0000000000000400)
++#define PLT_FILTER_MASK_DIRECTOR                    NPT_UINT64_C(0x0000000000000800)
++#define PLT_FILTER_MASK_DATE                        NPT_UINT64_C(0x0000000000001000)
++#define PLT_FILTER_MASK_PROGRAMTITLE                NPT_UINT64_C(0x0000000000002000)
++#define PLT_FILTER_MASK_SERIESTITLE                 NPT_UINT64_C(0x0000000000004000)
++#define PLT_FILTER_MASK_EPISODE                     NPT_UINT64_C(0x0000000000008000)
++#define PLT_FILTER_MASK_TITLE                       NPT_UINT64_C(0x0000000000010000)
+-#define PLT_FILTER_MASK_RES                         0x0000000000020000
+-#define PLT_FILTER_MASK_RES_DURATION                0x0000000000040000
+-#define PLT_FILTER_MASK_RES_SIZE                    0x0000000000080000
+-#define PLT_FILTER_MASK_RES_PROTECTION              0x0000000000100000
+-#define PLT_FILTER_MASK_RES_RESOLUTION              0x0000000000200000
+-#define PLT_FILTER_MASK_RES_BITRATE                 0x0000000000400000
+-#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           0x0000000000800000
+-#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS         0x0000000001000000
+-#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY         0x0000000002000000
++#define PLT_FILTER_MASK_RES                         NPT_UINT64_C(0x0000000000020000)
++#define PLT_FILTER_MASK_RES_DURATION                NPT_UINT64_C(0x0000000000040000)
++#define PLT_FILTER_MASK_RES_SIZE                    NPT_UINT64_C(0x0000000000080000)
++#define PLT_FILTER_MASK_RES_PROTECTION              NPT_UINT64_C(0x0000000000100000)
++#define PLT_FILTER_MASK_RES_RESOLUTION              NPT_UINT64_C(0x0000000000200000)
++#define PLT_FILTER_MASK_RES_BITRATE                 NPT_UINT64_C(0x0000000000400000)
++#define PLT_FILTER_MASK_RES_BITSPERSAMPLE           NPT_UINT64_C(0x0000000000800000)
++#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS         NPT_UINT64_C(0x0000000001000000)
++#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY         NPT_UINT64_C(0x0000000002000000)
+-#define PLT_FILTER_MASK_LONGDESCRIPTION             0x0000000004000000
+-#define PLT_FILTER_MASK_ICON                        0x0000000008000000
+-#define PLT_FILTER_MASK_RATING                      0x0000000010000000
++#define PLT_FILTER_MASK_LONGDESCRIPTION             NPT_UINT64_C(0x0000000004000000)
++#define PLT_FILTER_MASK_ICON                        NPT_UINT64_C(0x0000000008000000)
++#define PLT_FILTER_MASK_RATING                      NPT_UINT64_C(0x0000000010000000)
+-#define PLT_FILTER_MASK_TOC                         0x0000000020000000
+-#define PLT_FILTER_MASK_SEARCHCLASS                 0x0000000040000000
+-#define PLT_FILTER_MASK_REFID                       0x0000000080000000
++#define PLT_FILTER_MASK_TOC                         NPT_UINT64_C(0x0000000020000000)
++#define PLT_FILTER_MASK_SEARCHCLASS                 NPT_UINT64_C(0x0000000040000000)
++#define PLT_FILTER_MASK_REFID                       NPT_UINT64_C(0x0000000080000000)
+-#define PLT_FILTER_MASK_LASTPOSITION                0x0000000100000000
+-#define PLT_FILTER_MASK_LASTPLAYBACK                0x0000000200000000
+-#define PLT_FILTER_MASK_PLAYCOUNT                   0x0000000400000000
++#define PLT_FILTER_MASK_LASTPOSITION                NPT_UINT64_C(0x0000000100000000)
++#define PLT_FILTER_MASK_LASTPLAYBACK                NPT_UINT64_C(0x0000000200000000)
++#define PLT_FILTER_MASK_PLAYCOUNT                   NPT_UINT64_C(0x0000000400000000)
+ #define PLT_FILTER_FIELD_TITLE                      "dc:title"
+ #define PLT_FILTER_FIELD_CREATOR                    "dc:creator"
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0017-Platinum-don-t-disregard-PLT_MediaObjects-only-for-l.patch b/lib/libUPnP/patches/0017-Platinum-don-t-disregard-PLT_MediaObjects-only-for-l.patch
new file mode 100644 (file)
index 0000000..3e83fd1
--- /dev/null
@@ -0,0 +1,32 @@
+From 3d0063a78b969478fe6965e31aa5dd4d8f5b45d9 Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@ecce.se>
+Date: Sat, 19 Jan 2013 19:00:30 +0100
+Subject: [PATCH 17/21] Platinum: don't disregard PLT_MediaObjects only for
+ lacking resources
+
+This could cause us to misscount the number of media objects in a upnp
+browse request, and re-request items we already had in list giving
+us duplicated items in lists.
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index 3856001..f4d793d 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -723,11 +723,6 @@ PLT_MediaItem::FromDidl(NPT_XmlElementNode* entry)
+     }
+     NPT_Result result = PLT_MediaObject::FromDidl(entry);
+-    
+-    // make sure we have at least one valid resource
+-    if (m_Resources.GetItemCount() == 0) {
+-        NPT_CHECK_SEVERE(NPT_ERROR_INVALID_PARAMETERS);
+-    }
+     return result;
+ }
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0018-Platinum-add-SetNextAVTransportURI-support-to-media-.patch b/lib/libUPnP/patches/0018-Platinum-add-SetNextAVTransportURI-support-to-media-.patch
new file mode 100644 (file)
index 0000000..7cd46de
--- /dev/null
@@ -0,0 +1,2063 @@
+From a3e34ef19a3dd3751b382374cfed64ac55765cde Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@ecce.se>
+Date: Sun, 4 Nov 2012 17:23:18 +0100
+Subject: [PATCH 18/21] Platinum: add SetNextAVTransportURI support to media
+ renderer base
+
+---
+ .../Devices/MediaRenderer/AVTransportSCPD.cpp      | 1889 ++++++++++----------
+ .../Devices/MediaRenderer/AVTransportSCPD.xml      |   20 +
+ .../Devices/MediaRenderer/PltMediaController.cpp   |   12 +-
+ .../Devices/MediaRenderer/PltMediaController.h     |    5 +
+ .../Devices/MediaRenderer/PltMediaRenderer.cpp     |   30 +
+ .../Devices/MediaRenderer/PltMediaRenderer.h       |    2 +
+ 6 files changed, 1016 insertions(+), 942 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp
+index 1c1fa44..64014ed 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.cpp
+@@ -40,944 +40,957 @@
+ /*----------------------------------------------------------------------
+ |   globals
+ +---------------------------------------------------------------------*/
+-NPT_UInt8 RDR_AVTransportSCPD[18725] =
++NPT_UInt8 RDR_AVTransportSCPD[] =
+ {
+-  0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 
+-  0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A, 
+-  0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 
+-  0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 
+-  0x65, 0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 
+-  0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 
+-  0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 
+-  0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 
+-  0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
+-  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 
+-  0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 
+-  0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 
+-  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 
+-  0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 
+-  0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 
+-  0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 
+-  0x69, 0x62, 0x6C, 0x65, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 
+-  0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 
+-  0x65, 0x63, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 
+-  0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 
+-  0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 
+-  0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 
+-  0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x49, 
+-  0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 
+-  0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x72, 0x54, 0x72, 
+-  0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 
+-  0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x4F, 
+-  0x66, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 
+-  0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 
+-  0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 
+-  0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
+-  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 
+-  0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 
+-  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 
+-  0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 
+-  0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
+-  0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 
+-  0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 
+-  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x57, 0x72, 0x69, 0x74, 0x65, 
+-  0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 
+-  0x64, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x47, 0x65, 0x74, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 
+-  0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
+-  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 
+-  0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x72, 0x65, 
+-  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 
+-  0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 
+-  0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 
+-  0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 
+-  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 
+-  0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
+-  0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x54, 0x69, 0x6D, 0x65, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 
+-  0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x54, 0x69, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 
+-  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 
+-  0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 
+-  0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x43, 0x6F, 0x75, 
+-  0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 
+-  0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 
+-  0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
+-  0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 
+-  0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 
+-  0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 
+-  0x73, 0x70, 0x6F, 0x72, 0x74, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 
+-  0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 
+-  0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 
+-  0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 
+-  0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 
+-  0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 
+-  0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 
+-  0x64, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x65, 0x74, 
+-  0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 
+-  0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 
+-  0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 
+-  0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
+-  0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x52, 0x65, 0x63, 0x6F, 0x72, 
+-  0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
+-  0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 
+-  0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 
+-  0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x50, 0x61, 0x75, 0x73, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 
+-  0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 
+-  0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 
+-  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
+-  0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
+-  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 
+-  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 
+-  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 
+-  0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6F, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 
+-  0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x65, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 
+-  0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 
+-  0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 
+-  0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x6E, 0x69, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 
+-  0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 
+-  0x65, 0x65, 0x6B, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 
+-  0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x41, 0x56, 0x54, 0x72, 
+-  0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 
+-  0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 
+-  0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 
+-  0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 
+-  0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x53, 0x65, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 
+-  0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 
+-  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
+-  0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
+-  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x77, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
+-  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 
+-  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
+-  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 
+-  0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 
+-  0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 
+-  0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 
+-  0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x52, 0x4D, 0x41, 0x4C, 0x3C, 0x2F, 
+-  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x5F, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 
+-  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 
+-  0x5F, 0x41, 0x4C, 0x4C, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 
+-  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 0x46, 0x46, 0x4C, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 
+-  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 
+-  0x46, 0x46, 0x4C, 0x45, 0x5F, 0x4E, 0x4F, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 0x6C, 
+-  0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x52, 0x4D, 0x41, 0x4C, 0x3C, 0x2F, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 
+-  0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 
+-  0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 
+-  0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 
+-  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 
+-  0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 
+-  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 
+-  0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4C, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 
+-  0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 
+-  0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 
+-  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 
+-  0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 
+-  0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 
+-  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 
+-  0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 
+-  0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 
+-  0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x52, 0x65, 
+-  0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 
+-  0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 
+-  0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 
+-  0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 
+-  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 
+-  0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 
+-  0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 
+-  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 
+-  0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 
+-  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 
+-  0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 
+-  0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 
+-  0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 
+-  0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
+-  0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 
+-  0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 
+-  0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 
+-  0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 
+-  0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 
+-  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 
+-  0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 
+-  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x41, 
+-  0x55, 0x53, 0x45, 0x44, 0x5F, 0x50, 0x4C, 0x41, 0x59, 0x42, 0x41, 0x43, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x4C, 0x41, 0x59, 
+-  0x49, 0x4E, 0x47, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 
+-  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x4E, 0x53, 0x49, 0x54, 0x49, 0x4F, 0x4E, 0x49, 0x4E, 0x47, 0x3C, 
+-  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 
+-  0x65, 0x3E, 0x4E, 0x4F, 0x5F, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x5F, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4E, 0x54, 0x3C, 0x2F, 
+-  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 
+-  0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 
+-  0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 
+-  0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 
+-  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 
+-  0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 
+-  0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 
+-  0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 
+-  0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 
+-  0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 
+-  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 
+-  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 
+-  0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 
+-  0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 
+-  0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3C, 0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x31, 0x3C, 0x2F, 
+-  0x73, 0x74, 0x65, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 
+-  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x6F, 
+-  0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 
+-  0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 
+-  0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 
+-  0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 
+-  0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 
+-  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 
+-  0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 
+-  0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x4E, 0x45, 0x3C, 
+-  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 
+-  0x65, 0x3E, 0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 
+-  0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 
+-  0x48, 0x44, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 
+-  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 
+-  0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 
+-  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 
+-  0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x57, 0x72, 
+-  0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 
+-  0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 
+-  0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 
+-  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 
+-  0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 
+-  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 
+-  0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x50, 
+-  0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 
+-  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 
+-  0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 
+-  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x4E, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 
+-  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 
+-  0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 
+-  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x48, 0x44, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 
+-  0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 
+-  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 
+-  0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 
+-  0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 
+-  0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 
+-  0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x4F, 0x66, 0x54, 
+-  0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 
+-  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 
+-  0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3C, 
+-  0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 
+-  0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 
+-  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 
+-  0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 
+-  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x52, 0x45, 0x4C, 0x5F, 0x54, 0x49, 0x4D, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 
+-  0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 
+-  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x43, 0x4B, 0x5F, 0x4E, 0x52, 
+-  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 
+-  0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 
+-  0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 
+-  0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 
+-  0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 
+-  0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 
+-  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 
+-  0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 
+-  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 
+-  0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 
+-  0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 
+-  0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4F, 0x4B, 0x3C, 0x2F, 
+-  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x5F, 0x4F, 0x43, 0x43, 0x55, 0x52, 0x52, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 
+-  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
+-  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 
+-  0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 
+-  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 
+-  0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 
+-  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 
+-  0x31, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 
+-  0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x65, 0x72, 
+-  0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x73, 
+-  0x63, 0x70, 0x64, 0x3E, 0x00
++  0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20,
++  0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C,
++  0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 0x65,
++  0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
++  0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F,
++  0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E,
++  0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56,
++  0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69,
++  0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72,
++  0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74,
++  0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
++  0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
++  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
++  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43,
++  0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
++  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69,
++  0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E,
++  0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
++  0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
++  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B, 0x53,
++  0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F,
++  0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D,
++  0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x51,
++  0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6F,
++  0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D,
++  0x6F, 0x64, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
++  0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E,
++  0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x4E, 0x72, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
++  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65,
++  0x72, 0x4F, 0x66, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
++  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F,
++  0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74,
++  0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74,
++  0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72,
++  0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72,
++  0x65, 0x6E, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
++  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44,
++  0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55,
++  0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
++  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
++  0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E,
++  0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
++  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D,
++  0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50,
++  0x6C, 0x61, 0x79, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74,
++  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79,
++  0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x72,
++  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D,
++  0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75,
++  0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67,
++  0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x57,
++  0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
++  0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
++  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x63,
++  0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
++  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47,
++  0x65, 0x74, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
++  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69,
++  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73,
++  0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54,
++  0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75,
++  0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72,
++  0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B,
++  0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
++  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
++  0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
++  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D,
++  0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54,
++  0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
++  0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E,
++  0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x52, 0x65, 0x6C, 0x54, 0x69, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
++  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74,
++  0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75,
++  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x54, 0x69, 0x6D, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69,
++  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
++  0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x43, 0x6F, 0x75, 0x6E,
++  0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6F, 0x75, 0x6E,
++  0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x62,
++  0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F,
++  0x6E, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74,
++  0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x49, 0x6E, 0x66, 0x6F, 0x3C, 0x2F, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
++  0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49,
++  0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C,
++  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
++  0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E,
++  0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C,
++  0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x53, 0x70,
++  0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74,
++  0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50,
++  0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x53,
++  0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72,
++  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
++  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
++  0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
++  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F,
++  0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
++  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x51, 0x75, 0x61,
++  0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
++  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
++  0x6E, 0x74, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C,
++  0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65,
++  0x78, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E,
++  0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F,
++  0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F,
++  0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x61, 0x75, 0x73, 0x65, 0x3C,
++  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61,
++  0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69,
++  0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50,
++  0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65,
++  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C,
++  0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49,
++  0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E,
++  0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69,
++  0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74,
++  0x50, 0x6C, 0x61, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6F, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
++  0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49,
++  0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x65, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69,
++  0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
++  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61,
++  0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x6E, 0x69,
++  0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65,
++  0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x61,
++  0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E,
++  0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45,
++  0x5F, 0x53, 0x65, 0x65, 0x6B, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64,
++  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69,
++  0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
++  0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72,
++  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65,
++  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41,
++  0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44,
++  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x55,
++  0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F,
++  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55,
++  0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
++  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E,
++  0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x56,
++  0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
++  0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53,
++  0x65, 0x74, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72,
++  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x6E, 0x73, 0x74,
++  0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
++  0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74,
++  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65,
++  0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x72, 0x65,
++  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44,
++  0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C,
++  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73,
++  0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C,
++  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65,
++  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69,
++  0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x74, 0x50, 0x6C, 0x61,
++  0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
++  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
++  0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
++  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
++  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x77, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64,
++  0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64,
++  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F,
++  0x64, 0x65, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
++  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x53, 0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63,
++  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61,
++  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41,
++  0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3C, 0x2F,
++  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75,
++  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67,
++  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61,
++  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69,
++  0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65,
++  0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
++  0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x50, 0x6C, 0x61, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
++  0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
++  0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x52, 0x4D, 0x41, 0x4C,
++  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x5F, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
++  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54,
++  0x5F, 0x41, 0x4C, 0x4C, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 0x46, 0x46, 0x4C, 0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
++  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x48, 0x55, 0x46, 0x46,
++  0x4C, 0x45, 0x5F, 0x4E, 0x4F, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
++  0x4F, 0x52, 0x4D, 0x41, 0x4C, 0x3C, 0x2F, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69,
++  0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63,
++  0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
++  0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
++  0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49,
++  0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
++  0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
++  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
++  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4C, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6E,
++  0x67, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74,
++  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74,
++  0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61,
++  0x6D, 0x65, 0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69, 0x74,
++  0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61,
++  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
++  0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
++  0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x55, 0x52, 0x49, 0x3C,
++  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74,
++  0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
++  0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
++  0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
++  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
++  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74,
++  0x79, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F,
++  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
++  0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C,
++  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69,
++  0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
++  0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
++  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
++  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69,
++  0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
++  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x52, 0x65, 0x6C, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x50, 0x6F, 0x73, 0x69,
++  0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61,
++  0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65,
++  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D,
++  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65,
++  0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79,
++  0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56,
++  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22,
++  0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
++  0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73,
++  0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69,
++  0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
++  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x53, 0x54, 0x4F, 0x50, 0x50, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
++  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x41, 0x55,
++  0x53, 0x45, 0x44, 0x5F, 0x50, 0x4C, 0x41, 0x59, 0x42, 0x41, 0x43, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
++  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x50, 0x4C, 0x41, 0x59, 0x49, 0x4E,
++  0x47, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
++  0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x4E, 0x53, 0x49, 0x54, 0x49, 0x4F, 0x4E, 0x49, 0x4E, 0x47, 0x3C, 0x2F, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F,
++  0x5F, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x5F, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4E, 0x54, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F,
++  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65,
++  0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70,
++  0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74,
++  0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x55, 0x52, 0x49, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
++  0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69,
++  0x62, 0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x51, 0x75, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65,
++  0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64,
++  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61,
++  0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61,
++  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61,
++  0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72,
++  0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F,
++  0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75,
++  0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34,
++  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75,
++  0x6D, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35,
++  0x3C, 0x2F, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x31, 0x3C, 0x2F, 0x73, 0x74, 0x65, 0x70, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74,
++  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74,
++  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E,
++  0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E,
++  0x61, 0x6D, 0x65, 0x3E, 0x41, 0x62, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6D, 0x65, 0x50, 0x6F, 0x73, 0x69,
++  0x74, 0x69, 0x6F, 0x6E, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64,
++  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61,
++  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73,
++  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65,
++  0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x78, 0x74, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74,
++  0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74,
++  0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
++  0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6C, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6B,
++  0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
++  0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
++  0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61,
++  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x4E, 0x45, 0x3C, 0x2F, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x55, 0x4E,
++  0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
++  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
++  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x48, 0x44, 0x44, 0x3C, 0x2F, 0x61,
++  0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
++  0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
++  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45,
++  0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70,
++  0x6F, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
++  0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
++  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x4D, 0x65, 0x64,
++  0x69, 0x75, 0x6D, 0x57, 0x72, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
++  0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50,
++  0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
++  0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
++  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E,
++  0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x50, 0x6C, 0x61,
++  0x79, 0x62, 0x61, 0x63, 0x6B, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61, 0x3C, 0x2F, 0x6E,
++  0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
++  0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E, 0x4F, 0x4E, 0x45,
++  0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x3E, 0x55, 0x4E, 0x4B, 0x4E, 0x4F, 0x57, 0x4E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61,
++  0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x43, 0x44, 0x2D, 0x44, 0x41, 0x3C, 0x2F, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x48, 0x44,
++  0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
++  0x75, 0x65, 0x3E, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
++  0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C,
++  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73,
++  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x56, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F,
++  0x72, 0x74, 0x55, 0x52, 0x49, 0x4D, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
++  0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
++  0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72,
++  0x4F, 0x66, 0x54, 0x72, 0x61, 0x63, 0x6B, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F,
++  0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E,
++  0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x36, 0x35, 0x35, 0x33, 0x35, 0x3C, 0x2F,
++  0x6D, 0x61, 0x78, 0x69, 0x6D, 0x75, 0x6D, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47,
++  0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x4D, 0x6F, 0x64, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65,
++  0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x52, 0x45, 0x4C, 0x5F, 0x54, 0x49, 0x4D,
++  0x45, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C,
++  0x75, 0x65, 0x3E, 0x54, 0x52, 0x41, 0x43, 0x4B, 0x5F, 0x4E, 0x52, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C,
++  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20,
++  0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59,
++  0x50, 0x45, 0x5F, 0x53, 0x65, 0x65, 0x6B, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E,
++  0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E,
++  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C,
++  0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x50, 0x6F, 0x73, 0x73, 0x69, 0x62,
++  0x6C, 0x65, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x4D, 0x65, 0x64, 0x69, 0x61,
++  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61,
++  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54,
++  0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
++  0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4E,
++  0x4F, 0x54, 0x5F, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x4D, 0x45, 0x4E, 0x54, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F,
++  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
++  0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73,
++  0x70, 0x6F, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72,
++  0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73,
++  0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F,
++  0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x4F, 0x4B, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
++  0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x45, 0x52, 0x52, 0x4F, 0x52, 0x5F, 0x4F,
++  0x43, 0x43, 0x55, 0x52, 0x52, 0x45, 0x44, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75,
++  0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65,
++  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F,
++  0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64,
++  0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x50, 0x6C, 0x61,
++  0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x20, 0x20, 0x20, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C,
++  0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
++  0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20,
++  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56,
++  0x61, 0x6C, 0x75, 0x65, 0x3E, 0x31, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65,
++  0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64,
++  0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
++  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73,
++  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x3C, 0x2F,
++  0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
+ };
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml
+index 63a3ee9..f9ee988 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/AVTransportSCPD.xml
+@@ -281,6 +281,26 @@
+          </argumentList>
+       </action>
+       <action>
++         <name>SetNextAVTransportURI</name>
++         <argumentList>
++            <argument>
++               <name>InstanceID</name>
++               <direction>in</direction>
++               <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
++            </argument>
++            <argument>
++               <name>NextURI</name>
++               <direction>in</direction>
++               <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
++            </argument>
++            <argument>
++               <name>NextURIMetaData</name>
++               <direction>in</direction>
++               <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
++            </argument>
++         </argumentList>
++      </action>
++      <action>
+          <name>SetPlayMode</name>
+          <argumentList>
+             <argument>
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp
+index 638a6cb..520145c 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp
+@@ -562,10 +562,10 @@ PLT_MediaController::SetNextAVTransportURI(PLT_DeviceDataReference& device,
+ {
+     PLT_ActionReference action;
+     NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(
+-                                               device, 
+-                                               "urn:schemas-upnp-org:service:AVTransport:1", 
+-                                               "SetNextAVTransportURI", 
+-                                               action));
++        device,
++        "urn:schemas-upnp-org:service:AVTransport:1",
++        "SetNextAVTransportURI",
++        action));
+     
+     // set the uri
+     if (NPT_FAILED(action->SetArgumentValue("NextURI", next_uri))) {
+@@ -867,6 +867,10 @@ PLT_MediaController::OnActionResponse(NPT_Result           res,
+         if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+         m_Delegate->OnSetAVTransportURIResult(res, device, userdata);
+     }
++    else if (actionName.Compare("SetNextAVTransportURI", true) == 0) {
++      if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
++      m_Delegate->OnSetNextAVTransportURIResult(res, device, userdata);
++    }
+     else if (actionName.Compare("SetPlayMode", true) == 0) {
+         if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE;
+         m_Delegate->OnSetPlayModeResult(res, device, userdata);
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h
+index f5f0615..c91ce64 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.h
+@@ -176,6 +176,11 @@ public:
+         PLT_DeviceDataReference& /* device */,
+         void*                    /* userdata */) {}
++    virtual void OnSetNextAVTransportURIResult(
++        NPT_Result               /* res */,
++        PLT_DeviceDataReference& /* device */,
++        void*                    /* userdata */) {}
++
+     virtual void OnSetPlayModeResult(
+         NPT_Result               /* res */,
+         PLT_DeviceDataReference& /* device */,
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp
+index 6c9653d..80e04f5 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.cpp
+@@ -249,6 +249,9 @@ PLT_MediaRenderer::OnAction(PLT_ActionReference&          action,
+     if (name.Compare("SetAVTransportURI", true) == 0) {
+         return OnSetAVTransportURI(action);
+     }
++    if (name.Compare("SetNextAVTransportURI", true) == 0) {
++        return OnSetNextAVTransportURI(action);
++    }
+     if (name.Compare("SetPlayMode", true) == 0) {
+         return OnSetPlayMode(action);
+     }
+@@ -417,6 +420,33 @@ PLT_MediaRenderer::OnSetAVTransportURI(PLT_ActionReference& action)
+ }
+ /*----------------------------------------------------------------------
++ |   PLT_MediaRenderer::OnSetAVTransportURI
++ +---------------------------------------------------------------------*/
++NPT_Result
++PLT_MediaRenderer::OnSetNextAVTransportURI(PLT_ActionReference& action)
++{
++  if (m_Delegate) {
++    return m_Delegate->OnSetNextAVTransportURI(action);
++  }
++
++  // default implementation is using state variable
++  NPT_String uri;
++  NPT_CHECK_WARNING(action->GetArgumentValue("NextURI", uri));
++
++  NPT_String metadata;
++  NPT_CHECK_WARNING(action->GetArgumentValue("NextURIMetaData", metadata));
++
++  PLT_Service* serviceAVT;
++  NPT_CHECK_WARNING(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", serviceAVT));
++
++  // update service state variables
++  serviceAVT->SetStateVariable("NextAVTransportURI", uri);
++  serviceAVT->SetStateVariable("NextAVTransportURIMetaData", metadata);
++
++  return NPT_SUCCESS;
++}
++
++/*----------------------------------------------------------------------
+ |   PLT_MediaRenderer::OnSetPlayMode
+ +---------------------------------------------------------------------*/
+ NPT_Result
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h
+index d596838..bc0ac32 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaRenderer.h
+@@ -59,6 +59,7 @@ public:
+     virtual NPT_Result OnSeek(PLT_ActionReference& action) = 0;
+     virtual NPT_Result OnStop(PLT_ActionReference& action) = 0;
+     virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action) = 0;
++    virtual NPT_Result OnSetNextAVTransportURI(PLT_ActionReference& action) = 0;
+     virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action) = 0;
+     // RenderingControl
+@@ -102,6 +103,7 @@ protected:
+     virtual NPT_Result OnSeek(PLT_ActionReference& action);
+     virtual NPT_Result OnStop(PLT_ActionReference& action);
+     virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action);
++    virtual NPT_Result OnSetNextAVTransportURI(PLT_ActionReference& action);
+     virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action);
+     // RenderingControl
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0019-upnp-add-support-for-UpdateObject-action-to-Platinum.patch b/lib/libUPnP/patches/0019-upnp-add-support-for-UpdateObject-action-to-Platinum.patch
new file mode 100644 (file)
index 0000000..6e2681b
--- /dev/null
@@ -0,0 +1,996 @@
+From 515003179e48e958d0bf7ce6d5045ff1c7d09ab4 Mon Sep 17 00:00:00 2001
+From: Alasdair Campbell <alcoheca@gmail.com>
+Date: Wed, 3 Apr 2013 13:07:13 +0100
+Subject: [PATCH 19/21] upnp: add support for UpdateObject action to Platinum
+
+---
+ .../MediaServer/ContentDirectorywSearchSCPD.cpp    | 760 +++++++++++----------
+ .../MediaServer/ContentDirectorywSearchSCPD.xml    |  26 +-
+ .../Source/Devices/MediaServer/PltMediaServer.cpp  | 107 +++
+ .../Source/Devices/MediaServer/PltMediaServer.h    |   9 +
+ 4 files changed, 548 insertions(+), 354 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp
+index 4fb91d8..3e8cc89 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.cpp
+@@ -40,360 +40,414 @@
+ /*----------------------------------------------------------------------
+ |   globals
+ +---------------------------------------------------------------------*/
+-NPT_UInt8 MS_ContentDirectorywSearchSCPD[7058] =
++NPT_UInt8 MS_ContentDirectorywSearchSCPD[8121] =
+ {
+   0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 
+-  0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0D, 0x0A, 
+-  0x3C, 0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 
+-  0x65, 0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 
+-  0x65, 0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A, 
+-  0x6F, 0x72, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 
+-  0x6E, 0x6F, 0x72, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x42, 
+-  0x72, 0x6F, 0x77, 0x73, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62, 
+-  0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 
+-  0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
+-  0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 
+-  0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 
+-  0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 
+-  0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 
+-  0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 
+-  0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 
+-  0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6F, 0x75, 
+-  0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
+-  0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 
+-  0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 
+-  0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 
+-  0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 
+-  0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 
+-  0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 
+-  0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 
+-  0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 
+-  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
+-  0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 
+-  0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
+-  0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
+-  0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
+-  0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
+-  0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 
+-  0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 
+-  0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 
+-  0x72, 0x74, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 
+-  0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x72, 
+-  0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 
+-  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 
+-  0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 
+-  0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 
+-  0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 
+-  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 
+-  0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x49, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 
+-  0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
+-  0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74, 
+-  0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 
+-  0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 
+-  0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 
+-  0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 
+-  0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 
+-  0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 
+-  0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 
+-  0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x72, 
+-  0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
+-  0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 
+-  0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
+-  0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 
+-  0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 
+-  0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
+-  0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 
+-  0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 
+-  0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
+-  0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6F, 0x75, 0x6E, 0x74, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
+-  0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 
+-  0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
+-  0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 
+-  0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 
+-  0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
+-  0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 
+-  0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 
+-  0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
+-  0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 
+-  0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
+-  0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 
+-  0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
+-  0x54, 0x6F, 0x74, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 
+-  0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 
+-  0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 
+-  0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 
+-  0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
+-  0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 
+-  0x59, 0x50, 0x45, 0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
+-  0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
+-  0x65, 0x6E, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 
+-  0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
+-  0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 
+-  0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 
+-  0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 
+-  0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 
+-  0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 
+-  0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 
+-  0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
+-  0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x4D, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 
+-  0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 
+-  0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x44, 0x69, 0x72, 
+-  0x65, 0x63, 0x74, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 0x6E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 
+-  0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 
+-  0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 
+-  0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 
+-  0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 
+-  0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 
+-  0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 
+-  0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 
+-  0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 
+-  0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 
+-  0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 
+-  0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
+-  0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 
+-  0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 
+-  0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
+-  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 
+-  0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
+-  0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 
+-  0x50, 0x45, 0x5F, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 
+-  0x61, 0x6D, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 
+-  0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x20, 0x20, 0x20, 
+-  0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 
+-  0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 
+-  0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 
+-  0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 
+-  0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 
+-  0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
+-  0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
+-  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
+-  0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
+-  0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
+-  0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 
+-  0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
+-  0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 
+-  0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 
+-  0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 
+-  0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 
+-  0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 
+-  0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
+-  0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 
+-  0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 
+-  0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 
+-  0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 
+-  0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 
+-  0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 
+-  0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 
+-  0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
+-  0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 
+-  0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 
+-  0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 
+-  0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
+-  0x3E, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 
+-  0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0D, 0x0A, 0x09, 0x09, 
+-  0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 
+-  0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 
+-  0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 
+-  0x79, 0x70, 0x65, 0x3E, 0x20, 0x0D, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
+-  0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 
+-  0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x00
++0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x75, 0x74, 0x66, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 
++0x73, 0x63, 0x70, 0x64, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3D, 0x22, 0x75, 0x72, 0x6E, 0x3A, 0x73, 0x63, 0x68, 0x65, 
++0x6D, 0x61, 0x73, 0x2D, 0x75, 0x70, 0x6E, 0x70, 0x2D, 0x6F, 0x72, 0x67, 0x3A, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 
++0x2D, 0x31, 0x2D, 0x30, 0x22, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 
++0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 0x31, 0x3C, 0x2F, 0x6D, 0x61, 0x6A, 0x6F, 0x72, 0x3E, 
++0x20, 0x0A, 0x09, 0x09, 0x3C, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 0x30, 0x3C, 0x2F, 0x6D, 0x69, 0x6E, 0x6F, 0x72, 0x3E, 
++0x20, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x3C, 
++0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 
++0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x3C, 0x2F, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 
++0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 
++0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
++0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 
++0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 
++0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
++0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 
++0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
++0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 
++0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 
++0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
++0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 
++0x67, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
++0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 
++0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 
++0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 
++0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 
++0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 
++0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x74, 
++0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 
++0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 
++0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
++0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 
++0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 
++0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 
++0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
++0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 
++0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
++0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
++0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 
++0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 
++0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
++0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
++0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
++0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
++0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 
++0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
++0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 
++0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 
++0x65, 0x72, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 
++0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 
++0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 
++0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 
++0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74, 
++0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 
++0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 
++0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 
++0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
++0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 
++0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 
++0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 
++0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
++0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 
++0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 
++0x45, 0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
++0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 
++0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
++0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 
++0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x47, 0x65, 0x74, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 
++0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 
++0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x73, 
++0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 
++0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
++0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
++0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 
++0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
++0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 
++0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 
++0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 
++0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 
++0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 
++0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
++0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 
++0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x49, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 
++0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 
++0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x79, 
++0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 
++0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 
++0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 
++0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 
++0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 
++0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 
++0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x09, 0x09, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 
++0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x72, 0x65, 0x6C, 0x61, 
++0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x53, 0x65, 0x61, 
++0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
++0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x09, 0x09, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 
++0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x61, 
++0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 
++0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3C, 0x2F, 0x6E, 0x61, 
++0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 
++0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 
++0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 
++0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
++0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 
++0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
++0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 
++0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 
++0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
++0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x61, 
++0x72, 0x63, 0x68, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
++0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
++0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x46, 0x69, 0x6C, 0x74, 
++0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
++0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 
++0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 
++0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 
++0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x67, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
++0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 
++0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
++0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 
++0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 
++0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 
++0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
++0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 
++0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
++0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 
++0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 
++0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 
++0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 
++0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 
++0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 
++0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 
++0x69, 0x61, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
++0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 
++0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
++0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
++0x5F, 0x52, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
++0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 
++0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x52, 0x65, 
++0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 
++0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 
++0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
++0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x54, 0x6F, 0x74, 0x61, 0x6C, 0x4D, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 
++0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 
++0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
++0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 
++0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
++0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 
++0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 
++0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
++0x3E, 0x6F, 0x75, 0x74, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 
++0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
++0x5F, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 
++0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
++0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 
++0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 
++0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 
++0x74, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4F, 0x62, 0x6A, 0x65, 
++0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 
++0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 
++0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
++0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 
++0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
++0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 
++0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x43, 0x75, 0x72, 0x72, 
++0x65, 0x6E, 0x74, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 
++0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 
++0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
++0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x54, 0x61, 
++0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 
++0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x4E, 0x65, 0x77, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3C, 0x2F, 
++0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x69, 0x6E, 0x3C, 
++0x2F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x72, 0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 
++0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 
++0x54, 0x59, 0x50, 0x45, 0x5F, 0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x72, 
++0x65, 0x6C, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 
++0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 
++0x65, 0x6E, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x61, 0x72, 0x67, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x4C, 
++0x69, 0x73, 0x74, 0x3E, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
++0x20, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x0A, 0x09, 0x3C, 0x2F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 
++0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 
++0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
++0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 
++0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 
++0x5F, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x46, 0x6C, 0x61, 0x67, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 
++0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 
++0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 
++0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x4D, 0x65, 
++0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
++0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x3C, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 
++0x3E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x68, 0x69, 0x6C, 0x64, 0x72, 0x65, 
++0x6E, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x2F, 0x61, 0x6C, 0x6C, 0x6F, 0x77, 0x65, 0x64, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3E, 
++0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 
++0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 
++0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 
++0x61, 0x6D, 0x65, 0x3E, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 
++0x44, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 
++0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
++0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
++0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 
++0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 
++0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 
++0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 
++0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 
++0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 
++0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 
++0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 
++0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 
++0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 
++0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 
++0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 
++0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 
++0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 
++0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 
++0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 
++0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 
++0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 
++0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 
++0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 
++0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 
++0x72, 0x69, 0x74, 0x65, 0x72, 0x69, 0x61, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
++0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 
++0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
++0x62, 0x6C, 0x65, 0x3E, 0x20, 0x20, 0x20, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 
++0x69, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 
++0x22, 0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x6F, 0x72, 0x74, 0x43, 0x61, 0x70, 0x61, 
++0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 
++0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 
++0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
++0x61, 0x62, 0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 
++0x3E, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 
++0x45, 0x5F, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 
++0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 
++0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 
++0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 0x09, 
++0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x4F, 0x62, 
++0x6A, 0x65, 0x63, 0x74, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
++0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 
++0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
++0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
++0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 
++0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x75, 0x69, 0x34, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 
++0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
++0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
++0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 
++0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x52, 
++0x65, 0x73, 0x75, 0x6C, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 
++0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 
++0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 
++0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 
++0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 0x09, 
++0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 
++0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
++0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 
++0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
++0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
++0x46, 0x69, 0x6C, 0x74, 0x65, 0x72, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x09, 0x3C, 0x64, 
++0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 0x2F, 0x64, 0x61, 0x74, 0x61, 
++0x54, 0x79, 0x70, 0x65, 0x3E, 0x20, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 
++0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x73, 0x74, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 
++0x6C, 0x65, 0x20, 0x73, 0x65, 0x6E, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x73, 0x3D, 0x22, 0x6E, 0x6F, 0x22, 0x3E, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x41, 0x5F, 0x41, 0x52, 0x47, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 
++0x54, 0x61, 0x67, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x4C, 0x69, 0x73, 0x74, 0x3C, 0x2F, 0x6E, 0x61, 0x6D, 0x65, 0x3E, 0x0A, 
++0x09, 0x09, 0x09, 0x3C, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3C, 
++0x2F, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3E, 0x0A, 0x09, 0x09, 0x3C, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x65, 
++0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x09, 0x3C, 0x2F, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 
++0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x0A, 0x3C, 0x2F, 0x73, 0x63, 0x70, 0x64, 0x3E, 0x0A, 
++0x00
+ };
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml
+index 056a641..cba42e5 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/ContentDirectorywSearchSCPD.xml
+@@ -145,6 +145,26 @@
+                 </argument>
+             </argumentList>
+         </action>
++              <action>
++                        <name>UpdateObject</name>
++                        <argumentList>
++                                <argument>
++                                        <name>ObjectID</name>
++                                        <direction>in</direction>
++                                        <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable>
++                                </argument>
++                                <argument>
++                                        <name>CurrentTagValue</name>
++                                        <direction>in</direction>
++                                        <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable>
++                                </argument>
++                                <argument>
++                                        <name>NewTagValue</name>
++                                        <direction>in</direction>
++                                        <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable>
++                                </argument>
++                        </argumentList>
++                </action>
+       </actionList>
+       <serviceStateTable>
+               <stateVariable sendEvents="no">
+@@ -203,5 +223,9 @@
+                       <name>A_ARG_TYPE_Filter</name> 
+                       <dataType>string</dataType> 
+               </stateVariable>
++              <stateVariable sendEvents="no">
++                      <name>A_ARG_TYPE_TagValueList</name>
++                      <dataType>string</dataType>
++              </stateVariable>
+       </serviceStateTable>
+-</scpd>
+\ No newline at end of file
++</scpd>
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+index 5b01b54..6b484f6 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+@@ -163,6 +163,9 @@ PLT_MediaServer::OnAction(PLT_ActionReference&          action,
+     if (name.Compare("Search", true) == 0) {
+         return OnSearch(action, context);
+     }
++    if (name.Compare("UpdateObject", true) == 0) {
++        return OnUpdate(action, context);
++    }
+     if (name.Compare("GetSystemUpdateID", true) == 0) {
+         return OnGetSystemUpdateID(action, context);
+     }
+@@ -350,6 +353,59 @@ PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
+ }
+ /*----------------------------------------------------------------------
++|   PLT_MediaServer::ParseTagList
+++---------------------------------------------------------------------*/
++NPT_Result
++PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags)
++{
++    // reset output params first
++    tags.Clear();
++
++    NPT_List<NPT_String> split = updates.Split(",");
++    NPT_XmlNode*        node = NULL;
++    NPT_XmlElementNode* didl_partial = NULL;
++    NPT_XmlParser       parser;
++
++    // as these are single name value pairs, separated by commas we wrap in a tag
++    // to create a valid tree
++    NPT_String xml("<TagValueList>");
++    for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) {
++        NPT_String& element = (*entry);
++        if (element.IsEmpty())
++           xml.Append("<empty>empty</empty>");
++        else
++           xml.Append(element);
++    }
++    xml.Append("</TagValueList>");
++
++    NPT_LOG_FINE("Parsing TagList...");
++    NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
++    if (!node || !node->AsElementNode()) {
++        NPT_LOG_SEVERE("Invalid node type");
++        goto cleanup;
++    }
++
++    didl_partial = node->AsElementNode();
++    if (didl_partial->GetTag().Compare("TagValueList", true)) {
++        NPT_LOG_SEVERE("Invalid node tag");
++        goto cleanup;
++    }
++
++    for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) {
++        NPT_XmlElementNode* child = (*children)->AsElementNode();
++        if (!child) continue;
++        tags[child->GetTag()] = *child->GetText();
++    }
++
++    return NPT_SUCCESS;
++
++cleanup:
++    if (node) delete node;
++    return NPT_FAILURE;
++}
++
++
++/*----------------------------------------------------------------------
+ |   PLT_MediaServer::OnBrowse
+ +---------------------------------------------------------------------*/
+ NPT_Result
+@@ -523,6 +579,57 @@ PLT_MediaServer::OnSearch(PLT_ActionReference&          action,
+ }
+ /*----------------------------------------------------------------------
++|   PLT_MediaServer::OnUpdate
+++---------------------------------------------------------------------*/
++NPT_Result
++PLT_MediaServer::OnUpdate(PLT_ActionReference&          action,
++                          const PLT_HttpRequestContext& context)
++{
++    if (!m_Delegate)
++        return NPT_ERROR_NOT_IMPLEMENTED;
++
++    int err;
++    const char* msg = NULL;
++
++    NPT_String object_id, current_xml, new_xml;
++    NPT_Map<NPT_String,NPT_String> curr_values;
++    NPT_Map<NPT_String,NPT_String> new_values;
++
++    NPT_CHECK_LABEL(action->GetArgumentValue("ObjectID", object_id), args);
++    NPT_CHECK_LABEL(object_id.IsEmpty(),args);
++    NPT_CHECK_LABEL(action->GetArgumentValue("CurrentTagValue", current_xml), args);
++    NPT_CHECK_LABEL(action->GetArgumentValue("NewTagValue",  new_xml), args);
++
++    if (NPT_FAILED(ParseTagList(current_xml, curr_values))) {
++        err = 702;
++        msg = "Invalid currentTagvalue";
++        goto failure;
++    }
++    if (NPT_FAILED(ParseTagList(new_xml, new_values))) {
++        err = 703;
++        msg = "Invalid newTagValue";
++        goto failure;
++    }
++
++    if (curr_values.GetEntryCount() != new_values.GetEntryCount()) {
++        err = 706;
++        msg = "Paramater mismatch";
++        goto failure;
++    }
++
++    return m_Delegate->OnUpdateObject(action, object_id, curr_values, new_values, context);
++
++args:
++    err = 402;
++    msg = "Invalid args";
++
++failure:
++    NPT_LOG_WARNING(msg);
++    action->SetError(err, msg);
++    return NPT_FAILURE;
++}
++
++/*----------------------------------------------------------------------
+ |   PLT_MediaServer::OnBrowseMetadata
+ +---------------------------------------------------------------------*/
+ NPT_Result 
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h
+index fb4f9f3..6af8aa1 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.h
+@@ -87,6 +87,12 @@ public:
+                                          NPT_UInt32                    /*requested_count*/,
+                                          const char*                   /*sort_criteria*/, 
+                                          const PLT_HttpRequestContext& /*context*/) = 0;
++    virtual NPT_Result OnUpdateObject(PLT_ActionReference&             /*action*/,
++                                      const char*                      /*object_id*/,
++                                      NPT_Map<NPT_String,NPT_String>&  /*current_vals*/,
++                                      NPT_Map<NPT_String,NPT_String>&  /*new_vals*/,
++                                      const PLT_HttpRequestContext&    /*context*/) = 0;
++
+     virtual NPT_Result ProcessFileRequest(NPT_HttpRequest&              /*request*/,
+                                           const NPT_HttpRequestContext& /*context*/,
+                                           NPT_HttpResponse&             /*response*/) = 0;
+@@ -111,6 +117,7 @@ public:
+     // class methods
+     static NPT_Result ParseBrowseFlag(const char* str, BrowseFlags& flag);
+     static NPT_Result ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list);
++    static NPT_Result ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags);
+     // constructor
+     PLT_MediaServer(const char*  friendly_name,
+@@ -155,6 +162,8 @@ protected:
+                                 const PLT_HttpRequestContext& context);
+     virtual NPT_Result OnSearch(PLT_ActionReference&          action, 
+                                 const PLT_HttpRequestContext& context);
++    virtual NPT_Result OnUpdate(PLT_ActionReference&          action,
++                                const PLT_HttpRequestContext& context);
+     // overridable methods
+     virtual NPT_Result OnBrowseMetadata(PLT_ActionReference&          action, 
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0020-fixed-compiler-warning-about-unused-var.patch b/lib/libUPnP/patches/0020-fixed-compiler-warning-about-unused-var.patch
new file mode 100644 (file)
index 0000000..696836f
--- /dev/null
@@ -0,0 +1,32 @@
+From a6e9c50f338587e9c38790896fcf38350f1d2eb6 Mon Sep 17 00:00:00 2001
+From: davilla <davilla@4pi.com>
+Date: Thu, 11 Apr 2013 13:22:36 -0400
+Subject: [PATCH 05/21] fixed compiler warning about unused var
+
+---
+ lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+index 47aeb5a..7b46539 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+@@ -210,6 +210,7 @@ PLT_StateVariable::ValidateValue(const char* value)
+             while (val) {
+                 val->Trim(" ");
+                 if (!m_AllowedValues.Find(NPT_StringFinder(*val))) {
++#if defined(NPT_CONFIG_ENABLE_LOGGING)
+                     NPT_LOG_WARNING_2("Invalid value of %s for state variable %s",
+                         (const char*)*val,
+                         (const char*)m_Name);
+@@ -217,6 +218,7 @@ PLT_StateVariable::ValidateValue(const char* value)
+                         NPT_String *val = *m_AllowedValues.GetItem(i);
+                         NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val);
+                     }
++#endif
+                     return NPT_ERROR_INVALID_PARAMETERS;
+                 }
+                 ++val;
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0021-platinum-fix-shadowed-local-var.patch b/lib/libUPnP/patches/0021-platinum-fix-shadowed-local-var.patch
new file mode 100644 (file)
index 0000000..201377e
--- /dev/null
@@ -0,0 +1,27 @@
+From dc013f1ce379537617080a93ccb155ab1dc2f24a Mon Sep 17 00:00:00 2001
+From: Memphiz <memphis@machzwo.de>
+Date: Sat, 25 May 2013 23:06:14 +0200
+Subject: [PATCH 06/21] [platinum] - fix shadowed local var
+
+---
+ lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+index 7b46539..a8eb4e2 100644
+--- a/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
++++ b/lib/libUPnP/Platinum/Source/Core/PltStateVariable.cpp
+@@ -215,8 +215,8 @@ PLT_StateVariable::ValidateValue(const char* value)
+                         (const char*)*val,
+                         (const char*)m_Name);
+                     for (unsigned long i=0; i < m_AllowedValues.GetItemCount(); i++) {
+-                        NPT_String *val = *m_AllowedValues.GetItem(i);
+-                        NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val);
++                        NPT_String *val2 = *m_AllowedValues.GetItem(i);
++                        NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val2);
+                     }
+ #endif
+                     return NPT_ERROR_INVALID_PARAMETERS;
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0022-fixed-compiler-warning.-album_art-is-never-used.patch b/lib/libUPnP/patches/0022-fixed-compiler-warning.-album_art-is-never-used.patch
new file mode 100644 (file)
index 0000000..af7dd0d
--- /dev/null
@@ -0,0 +1,24 @@
+From 98087a7b2cb969961a96ecfc4169164079a19602 Mon Sep 17 00:00:00 2001
+From: "S. Davilla" <davilla@4pi.com>
+Date: Thu, 31 Oct 2013 20:35:00 -0400
+Subject: [PATCH 20/21] fixed, compiler warning. album_art is never used
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index f4d793d..d6986be 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -282,7 +282,6 @@ PLT_MediaObject::ToDidl(NPT_UInt64 mask, NPT_String& didl)
+     // album art URI
+     if ((mask & PLT_FILTER_MASK_ALBUMARTURI) && m_ExtraInfo.album_arts.GetItemCount()) {
+-        NPT_List<PLT_AlbumArtInfo>::Iterator album_art = m_ExtraInfo.album_arts.GetFirstItem();
+         for (NPT_List<PLT_AlbumArtInfo>::Iterator iter = m_ExtraInfo.album_arts.GetFirstItem();
+              iter;
+              iter++) {
+-- 
+1.7.11.msysgit.0
+
diff --git a/lib/libUPnP/patches/0023-platinum-fix-parsing-of-upnp-actor-in-PltMediaItem.patch b/lib/libUPnP/patches/0023-platinum-fix-parsing-of-upnp-actor-in-PltMediaItem.patch
new file mode 100644 (file)
index 0000000..94a93fe
--- /dev/null
@@ -0,0 +1,25 @@
+From fda8d4192ae53f3f2ac10ba6dd9fa0ae5ebbb083 Mon Sep 17 00:00:00 2001
+From: montellese <montellese@xbmc.org>
+Date: Fri, 27 Dec 2013 13:02:01 +0100
+Subject: [PATCH 21/21] platinum: fix parsing of upnp:actor in PltMediaItem
+
+---
+ lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+index d6986be..a6566eb 100644
+--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
++++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
+@@ -510,7 +510,7 @@ PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
+     m_People.authors.FromDidl(children);
+     
+     children.Clear();
+-    PLT_XmlHelper::GetChildren(entry, children, "actors", didl_namespace_upnp);
++    PLT_XmlHelper::GetChildren(entry, children, "actor", didl_namespace_upnp);
+     m_People.actors.FromDidl(children);
+     children.Clear();
+-- 
+1.7.11.msysgit.0
+
index d87c1ea..4385541 100644 (file)
@@ -25,7 +25,7 @@ ifeq ($(OSTYPE),Darwin)
   LDFLAGS=-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -L/opt/local/lib
   CPPFLAGS=-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -I /opt/local/include
 else
-  prefix=/usr
+  prefix=/usr/local
 endif
 
 ifeq ($(OSTYPE),Darwin)
index ed00ad0..3babd83 100644 (file)
@@ -64,7 +64,7 @@ echo "***** Building libdvdnav *****"
       --disable-shared \
       --enable-static \
       --extra-cflags="-D_XBMC -DNDEBUG -I`pwd`/../includes" \
-      --with-dvdread-config="`pwd`/../libdvdread/obj/dvdread-config" \
+      --with-dvdread-config="`pwd`/../dvdread-config" \
       --disable-debug
 mkdir -p ../includes/dvdnav
 cp ../libdvdnav/src/dvdnav/*.h ../includes/dvdnav
diff --git a/lib/libdvd/dvdread-config b/lib/libdvd/dvdread-config
new file mode 100755 (executable)
index 0000000..b28b1ca
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# this configfile is based on the original libdvdread config
+# 'dvdread-config' but stripped down to not output the include
+# and libdirs to not break crosscompiling with including
+# system includes and libraries
+
+prefix=/usr
+dvdreadlib="-ldvdread"
+
+usage()
+{
+       cat <<EOF
+Usage: dvdread-config [OPTIONS] [LIBRARIES]
+Options:
+       [--prefix[=DIR]]
+        [--libs]
+       [--cflags]
+EOF
+       exit $1
+}
+
+if test $# -eq 0; then
+       usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "$echo_prefix" = "yes"; then
+       echo $prefix
+fi
+
+if test "$echo_cflags" = "yes"; then
+      echo $extracflags
+fi
+
+if test "$echo_libs" = "yes"; then
+      echo $dvdreadlib
+fi
index 51ce1de..faac351 100644 (file)
@@ -5,6 +5,7 @@ w32api-4.0.3-1-mingw32-dev.tar.lzma         http://mirrors.xbmc.org/build-deps/w
 gcc-core-4.6.2-1-mingw32-bin.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
 gcc-c++-4.6.2-1-mingw32-bin.tar.lzma        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
 libstdc++-4.6.2-1-mingw32-dll-6.tar.lzma    http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
+libgcc-4.6.2-1-mingw32-dll-1.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
 binutils-2.22-1-mingw32-bin.tar.lzma        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GNU-Binutils/binutils-2.22/
 yasm-1.2.0-win32.exe                        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://www.tortall.net/projects/yasm/releases/
 dlfcn-win32-static-r19.tar.bz2              http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://code.google.com/p/dlfcn-win32/downloads/list
@@ -21,6 +22,7 @@ plibc-0.1.6.zip                             http://mirrors.xbmc.org/build-deps/w
 pthreads-w32-2.9.0-mingw32-pre-20110507-2-dev.tar.lzma   http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/pthreads-w32/pthreads-w32-2.9.0-pre-20110507-2/pthreads-w32-2.9.0-mingw32-pre-20110507-2-dev.tar.lzma
 libpthreadgc-2.9.0-mingw32-pre-20110507-2-dll-2.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/    http://downloads.sourceforge.net/project/mingw/MinGW/Base/pthreads-w32/pthreads-w32-2.9.0-pre-20110507-2/libpthreadgc-2.9.0-mingw32-pre-20110507-2-dll-2.tar.lzma
 gettext-0.17-1-mingw32-dev.tar.lzma         http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/gettext/gettext-0.17-1/gettext-0.17-1-mingw32-dev.tar.lzma
+libgettextpo-0.17-1-mingw32-dll-0.tar.lzma  http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/gettext/gettext-0.17-1/libgettextpo-0.17-1-mingw32-dll-0.tar.lzma
 libintl-0.17-1-mingw32-dll-8.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/gettext/gettext-0.17-1/
 libiconv-1.13.1-1-mingw32-dll-2.tar.lzma    http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/libiconv/libiconv-1.13.1-1/
 libiconv-1.13.1-1-mingw32-dev.tar.lzma      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/libiconv/libiconv-1.13.1-1/
diff --git a/project/BuildDependencies/scripts/harfbuzz_d.bat b/project/BuildDependencies/scripts/harfbuzz_d.bat
deleted file mode 100644 (file)
index 1692411..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO ON
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\harfbuzz_d.txt
-
-CALL dlextract.bat harfbuzz %FILES%
-
-cd %TMP_PATH%
-
-xcopy harfbuzz-0.7.0\include\* "%CUR_PATH%\include\" /E /Q /I /Y
-copy  harfbuzz-0.7.0\lib\harfbuzz.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/harfbuzz_d.txt b/project/BuildDependencies/scripts/harfbuzz_d.txt
deleted file mode 100644 (file)
index a323f03..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename                   mirror of the file
-harfbuzz-0.7.0.7z    http://mirrors.xbmc.org/build-deps/win32/
index 3d9875c..0b1c0c6 100644 (file)
     <ClCompile Include="..\..\xbmc\cores\AudioEngine\Utils\AEWAVLoader.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthrough.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\CrystalHD.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodec.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxBXA.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxCDDA.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxPVRClient.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecFFmpeg.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLibMad.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.cpp" />
-    <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecCrystalHD.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecFFmpeg.cpp" />
     <ClInclude Include="..\..\xbmc\view\ViewDatabase.h" />
     <ClInclude Include="..\..\xbmc\view\ViewState.h" />
     <ClInclude Include="..\..\xbmc\view\ViewStateSettings.h" />
+    <ClInclude Include="..\..\xbmc\win32\IMMNotificationClient.h" />
     <ClInclude Include="..\..\xbmc\win32\pch.h" />
     <ClInclude Include="..\..\xbmc\win32\PlatformDefs.h" />
     <ClInclude Include="..\..\xbmc\XBDateTime.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecFFmpeg.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLibMad.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.h" />
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DllLibMpeg2.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodec.h" />
     </VisualStudio>
   </ProjectExtensions>
   <Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project>
+</Project>
\ No newline at end of file
index b5e72d9..829f053 100644 (file)
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.cpp">
       <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.cpp">
-      <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.cpp">
       <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\utils\XSLTUtils.cpp">
       <Filter>utils</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodec.cpp">
+      <Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\xbmc\win32\pch.h">
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.h">
       <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.h">
-      <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.h">
       <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\utils\XSLTUtils.h">
       <Filter>utils</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\IMMNotificationClient.h">
+      <Filter>win32</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
       <Filter>interfaces\swig</Filter>
     </None>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
index 699c24f..0845795 100644 (file)
@@ -9,7 +9,7 @@ SET DEPS_DIR=..\BuildDependencies
 SET TMP_DIR=%DEPS_DIR%\tmp
 
 SET LIBNAME=xbmc-pvr-addons
-SET VERSION=af29425b1e171419d72fb3a0475a10f4a862f0b7
+SET VERSION=71e5b8c1da7acf726d00bde30da8554662cf97e1
 SET SOURCE=%LIBNAME%
 SET GIT_URL=git://github.com/opdenkamp/%LIBNAME%.git
 SET SOURCE_DIR=%TMP_DIR%\%SOURCE%
index 735e9b1..1b6dc14 100644 (file)
 
        <remote device="linux-input-layer">
        <altname>cx23885_remote</altname>
-       <altname>devinput</altname>
                <left>KEY_LEFT</left>
                <right>KEY_RIGHT</right>
                <up>KEY_UP</up>
                <mypictures>yellow</mypictures>
                <myvideo>blue</myvideo>
        </remote>
+
+       <remote device="devinput">
+               <left>KEY_LEFT</left>
+               <right>KEY_RIGHT</right>
+               <up>KEY_UP</up>
+               <down>KEY_DOWN</down>
+               <select>KEY_OK</select>
+               <enter>KEY_ENTER</enter>
+               <clear>KEY_DELETE</clear>
+               <start>KEY_MEDIA</start>
+               <back>KEY_EXIT</back>
+               <record>KEY_RECORD</record>
+               <play>KEY_PLAY</play>
+               <pause>KEY_PAUSE</pause>
+               <stop>KEY_STOP</stop>
+               <forward>KEY_FASTFORWARD</forward>
+               <reverse>KEY_REWIND</reverse>
+               <volumeplus>KEY_VOLUMEUP</volumeplus>
+               <volumeminus>KEY_VOLUMEDOWN</volumeminus>
+               <channelplus>KEY_CHANNELUP</channelplus>
+               <channelminus>KEY_CHANNELDOWN</channelminus>
+               <skipplus>KEY_NEXT</skipplus>
+               <skipminus>KEY_PREVIOUS</skipminus>
+               <title>KEY_EPG</title>
+               <subtitle>KEY_SUBTITLE</subtitle>
+               <language>KEY_LANGUAGE</language>
+               <info>KEY_INFO</info>
+               <display>KEY_ZOOM</display>
+               <mute>KEY_MUTE</mute>
+               <power>KEY_POWER</power>
+               <eject>KEY_EJECT</eject>
+               <menu>KEY_DVD</menu>
+               <menu>KEY_MENU</menu>
+               <myvideo>KEY_VIDEO</myvideo>
+               <mymusic>KEY_AUDIO</mymusic>
+               <mypictures>KEY_CAMERA</mypictures>
+               <mytv>KEY_TUNER</mytv>
+               <teletext>KEY_TEXT</teletext>
+               <one>KEY_NUMERIC_1</one>
+               <two>KEY_NUMERIC_2</two>
+               <three>KEY_NUMERIC_3</three>
+               <four>KEY_NUMERIC_4</four>
+               <five>KEY_NUMERIC_5</five>
+               <six>KEY_NUMERIC_6</six>
+               <seven>KEY_NUMERIC_7</seven>
+               <eight>KEY_NUMERIC_8</eight>
+               <nine>KEY_NUMERIC_9</nine>
+               <zero>KEY_NUMERIC_0</zero>
+               <star>KEY_NUMERIC_STAR</star>
+               <hash>KEY_NUMERIC_POUND</hash>
+               <red>KEY_RED</red>
+               <green>KEY_GREEN</green>
+               <yellow>KEY_YELLOW</yellow>
+               <blue>KEY_BLUE</blue>
+               <recordedtv>KEY_PVR</recordedtv> 
+               <liveradio>KEY_RADIO</liveradio> 
+       </remote>
 </lircmap>
index 7d0061f..aff1fcd 100644 (file)
@@ -59,7 +59,7 @@
       <skipminus>SkipPrevious</skipminus>
       <display>FullScreen</display>
       <start>PreviousMenu</start>
-      <record>Screenshot</record>
+      <record>Record</record>
       <volumeplus>VolumeUp</volumeplus>
       <volumeminus>VolumeDown</volumeminus>
       <mute>Mute</mute>
   </Favourites>
   <FullscreenLiveTV>
     <remote>
-      <left>PreviousChannelGroup</left>
-      <right>NextChannelGroup</right>
+      <left>StepBack</left>
+      <right>StepForward</right>
       <up>ChannelUp</up>
       <down>ChannelDown</down>
     </remote>
index 1a132a7..584e4a4 100644 (file)
@@ -11,7 +11,7 @@
         <setting id="audiooutput.channels" help="36367" />
       </group>
       <group id="3">
-        <setting id="audiooutput.ac3transcode">
+        <setting id="audiooutput.eac3passthrough">
           <visible>false</visible>
         </setting>
         <setting id="audiooutput.truehdpassthrough">
index 9d03d79..1d67f9b 100644 (file)
           <default>Default</default>
           <visible>false</visible>
         </setting>
-        <setting id="audiooutput.ac3passthrough">
-          <requirement>IsAppleTV2</requirement>
-        </setting>
-        <setting id="audiooutput.dtspassthrough">
-          <requirement>IsAppleTV2</requirement>
-        </setting>
-        <setting id="audiooutput.truehdpassthrough">
-          <visible>false</visible>
-        </setting>
-        <setting id="audiooutput.dtshdpassthrough">
-          <visible>false</visible>
-        </setting>
       </group>
     </category>
     <category id="input">
index b5d5b7b..290d809 100644 (file)
         </setting>
       </group>
       <group id="3">
-        <setting id="audiooutput.truehdpassthrough">
-          <visible>false</visible>
-        </setting>
-        <setting id="audiooutput.dtshdpassthrough">
-          <visible>false</visible>
+        <setting id="audiooutput.ac3transcode" help="37024">
         </setting>
       </group>
     </category>
index c7ef591..51ebd16 100644 (file)
           </dependencies>
           <control type="toggle" />
         </setting>
+        <setting id="videoplayer.usevdpaumpeg2" type="boolean" parent="videoplayer.usevdpau" label="13441" help="13442">
+          <requirement>HAVE_LIBVDPAU</requirement>
+          <level>3</level>
+          <default>true</default>
+          <dependencies>
+            <dependency type="enable" setting="videoplayer.usevdpau" operator="is">true</dependency> <!-- USE VDPAU -->
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevdpaumpeg2" operator="is">true</dependency>
+          </dependencies>
+          <control type="toggle" />
+        </setting>
+        <setting id="videoplayer.usevdpaumpeg4" type="boolean" parent="videoplayer.usevdpau" label="13443" help="13444">
+          <requirement>HAVE_LIBVDPAU</requirement>
+          <level>3</level>
+          <default>false</default>
+          <dependencies>
+            <dependency type="enable" setting="videoplayer.usevdpau" operator="is">true</dependency> <!-- USE VDPAU -->
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevdpaumpeg4" operator="is">true</dependency>
+          </dependencies>
+          <control type="toggle" />
+        </setting>
+        <setting id="videoplayer.usevdpauvc1" type="boolean" parent="videoplayer.usevdpau" label="13445" help="13446">
+          <requirement>HAVE_LIBVDPAU</requirement>
+          <level>3</level>
+          <default>true</default>
+          <dependencies>
+            <dependency type="enable" setting="videoplayer.usevdpau" operator="is">true</dependency> <!-- USE VDPAU -->
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevdpauvc1" operator="is">true</dependency>
+          </dependencies>
+          <control type="toggle" />
+        </setting>
         <setting id="videoplayer.usevaapi" type="boolean" label="13426" help="36156">
           <requirement>HAVE_LIBVA</requirement>
           <dependencies>
           <default>true</default>
           <control type="toggle" />
         </setting>
+       <setting id="videoplayer.usevaapimpeg2" type="boolean" parent="videoplayer.usevaapi" label="13447" help="13448">
+          <requirement>HAVE_LIBVA</requirement>
+          <dependencies>
+            <dependency type="visible" setting="videoplayer.usevaapi" operator="is">true</dependency>
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevaapimpeg2" operator="is">true</dependency>
+          </dependencies>
+          <level>3</level>
+          <default>true</default>
+          <control type="toggle" />
+        </setting>
+        <setting id="videoplayer.usevaapimpeg4" type="boolean" parent="videoplayer.usevaapi" label="13449" help="13450">
+          <requirement>HAVE_LIBVA</requirement>
+          <dependencies>
+            <dependency type="visible" setting="videoplayer.usevaapi" operator="is">true</dependency>
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevaapimpeg4" operator="is">true</dependency>
+          </dependencies>
+          <level>3</level>
+          <default>true</default>
+          <control type="toggle" />
+        </setting>
+        <setting id="videoplayer.usevaapivc1" type="boolean" parent="videoplayer.usevaapi" label="13451" help="13452">
+          <requirement>HAVE_LIBVA</requirement>
+          <dependencies>
+            <dependency type="visible" setting="videoplayer.usevaapi" operator="is">true</dependency>
+            <dependency type="visible" on="property" name="codecoptionvisible" setting="videoplayer.usevaapivc1" operator="is">true</dependency>
+          </dependencies>
+          <level>3</level>
+          <default>false</default>
+          <control type="toggle" />
+        </setting>
         <setting id="videoplayer.usedxva2" type="boolean" label="13427" help="36158">
           <requirement>HasDXVA2</requirement>
           <dependencies>
       <requirement>HAS_ZEROCONF</requirement>
       <group id="1">
         <setting id="services.zeroconf" type="boolean" label="1260" help="36342">
-          <level>2</level>
+          <level>1</level>
           <default>true</default>
           <control type="toggle" />
         </setting>
         </setting>
         <setting id="audiooutput.ac3transcode" type="boolean" label="667" help="36429">
           <level>2</level>
-          <default>true</default>
+          <default>false</default>
           <dependencies>
             <dependency type="visible">
               <and>
             <dependency type="visible">
               <and>
                 <condition setting="audiooutput.passthrough" operator="is">true</condition>
-                <condition on="property" name="aesettingvisible" setting="audiooutput.config">audiooutput.passthrough</condition>
+                <condition on="property" name="aesettingvisible" setting="audiooutput.config">audiooutput.eac3passthrough</condition>
+                <condition on="property" name="aesettingvisible" setting="audiooutput.passthroughdevice">audiooutput.eac3passthrough</condition>
               </and>
             </dependency>
           </dependencies>
     <category id="masterlock" label="12360" help="36395">
       <access>CheckMasterLock</access>
       <group id="1">
-        <setting id="masterlock.lockcode" type="string" label="20100" help="36396">
+        <setting id="masterlock.lockcode" type="action" label="20100" help="36396">
           <level>2</level>
-          <default>-</default>
           <control type="button" format="action">
             <hidevalue>true</hidevalue>
           </control>
index fce8da1..987f974 100644 (file)
@@ -48,7 +48,7 @@
       <group id="1">
         <setting id="audiooutput.audiodevice" type="string" label="545" help="36371">
           <level>1</level>
-          <default>DirectSound:default</default>
+          <default>DIRECTSOUND:default</default>
           <constraints>
             <options>audiodevices</options>
           </constraints>
@@ -58,7 +58,7 @@
       <group id="3">
         <setting id="audiooutput.passthroughdevice" type="string" label="546" help="36372">
           <level>2</level>
-          <default>DirectSound:default</default>
+          <default>DIRECTSOUND:default</default>
           <constraints>
             <options>audiodevicespassthrough</options>
           </constraints>
index 2bead97..db99670 100644 (file)
@@ -23,6 +23,7 @@ prefix="@prefix@"
 exec_prefix="@exec_prefix@"
 datarootdir="@datarootdir@"
 LIBDIR="@libdir@"
+CRASHLOG_DIR=${CRASHLOG_DIR:-$HOME}
 
 # Check for some options used by this script
 while [ "$#" -gt "0" ]
@@ -52,7 +53,7 @@ single_stacktrace()
 
 print_crash_report()
 {
-  FILE="$HOME/xbmc_crashlog-`date +%Y%m%d_%H%M%S`.log"
+  FILE="$CRASHLOG_DIR/xbmc_crashlog-`date +%Y%m%d_%H%M%S`.log"
   echo "############## XBMC CRASH LOG ###############" >> $FILE
   echo >> $FILE
   echo "################ SYSTEM INFO ################" >> $FILE
diff --git a/tools/buildsteps/linux32/run-tests b/tools/buildsteps/linux32/run-tests
new file mode 100755 (executable)
index 0000000..429e094
--- /dev/null
@@ -0,0 +1,9 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=linux32
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+cd $WORKSPACE;make -j$BUILDTHREADS testsuite
+cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml
+awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml
+rm gtestresults.xml
+mv gtestresults-skipped.xml gtestresults.xml
diff --git a/tools/buildsteps/linux64/run-tests b/tools/buildsteps/linux64/run-tests
new file mode 100755 (executable)
index 0000000..43469c3
--- /dev/null
@@ -0,0 +1,9 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=linux64
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+cd $WORKSPACE;make -j$BUILDTHREADS testsuite
+cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml
+awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml
+rm gtestresults.xml
+mv gtestresults-skipped.xml gtestresults.xml
diff --git a/tools/buildsteps/osx32/run-tests b/tools/buildsteps/osx32/run-tests
new file mode 100755 (executable)
index 0000000..a77fb81
--- /dev/null
@@ -0,0 +1,9 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=osx32
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+cd $WORKSPACE;make -j$BUILDTHREADS testsuite
+cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml
+awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml
+rm gtestresults.xml
+mv gtestresults-skipped.xml gtestresults.xml
diff --git a/tools/buildsteps/osx64/run-tests b/tools/buildsteps/osx64/run-tests
new file mode 100755 (executable)
index 0000000..b3113e3
--- /dev/null
@@ -0,0 +1,9 @@
+WORKSPACE=${WORKSPACE:-$( cd $(dirname $0)/../../.. ; pwd -P )}
+XBMC_PLATFORM_DIR=osx64
+. $WORKSPACE/tools/buildsteps/defaultenv
+
+cd $WORKSPACE;make -j$BUILDTHREADS testsuite
+cd $WORKSPACE;./xbmc-test --gtest_output=xml:gtestresults.xml
+awk '{ if ($1 == "<testcase" && match($0, "notrun")) print substr($0,0,length($0)-2) "><skipped/></testcase>"; else print $0;}' gtestresults.xml > gtestresults-skipped.xml
+rm gtestresults.xml
+mv gtestresults-skipped.xml gtestresults.xml
index e6e4202..47ae4d6 100644 (file)
@@ -40,6 +40,6 @@ COPY_PHASE_STRIP = NO
 DEAD_CODE_STRIPPING = NO
 OTHER_CPLUSPLUSFLAGS = $(inherited) $(OTHER_CFLAGS) -Wreorder
 
-OTHER_LDFLAGS = $(XBMC_OTHER_LDFLAGS_COMMON) -lmpeg2 -weak_framework VideoToolbox
+OTHER_LDFLAGS = $(XBMC_OTHER_LDFLAGS_COMMON) -weak_framework VideoToolbox
 
 GCC_PREPROCESSOR_DEFINITIONS = TARGET_DARWIN_IOS $(XBMC_GCC_PREPROCESSOR_DEFINITIONS_COMMON)
index e46d57c..f38482a 100644 (file)
@@ -24,6 +24,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
 ifeq (arm, $(findstring arm, $(CPU)))
        cd $(PLATFORM); patch -p0 < ../fix_shared_ptr_multithread.patch
 endif
+       cd $(PLATFORM); patch -p1 < ../fix-self-assignment-warnings.patch
        cd $(PLATFORM); ./bootstrap.sh --prefix=$(PREFIX)
 
 .installed-$(PLATFORM): $(PLATFORM)
diff --git a/tools/depends/target/boost/fix-self-assignment-warnings.patch b/tools/depends/target/boost/fix-self-assignment-warnings.patch
new file mode 100644 (file)
index 0000000..647e01c
--- /dev/null
@@ -0,0 +1,61 @@
+--- a/boost/concept_check.hpp
++++ b/boost/concept_check.hpp
+@@ -136,20 +136,21 @@ namespace boost
+   {
+     BOOST_CONCEPT_USAGE(Assignable) {
+ #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+-      a = a;             // require assignment operator
++      a = b;             // require assignment operator
+ #endif
+-      const_constraints(a);
++      const_constraints(b);
+     }
+    private:
+-    void const_constraints(const TT& b) {
++    void const_constraints(const TT& x) {
+ #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+-      a = b;              // const required for argument to assignment
++      a = x;              // const required for argument to assignment
+ #else
+-      ignore_unused_variable_warning(b);
++      ignore_unused_variable_warning(x);
+ #endif
+     }
+    private:
+     TT a;
++    TT b;
+   };
+   
+@@ -180,22 +181,23 @@ namespace boost
+   BOOST_concept(SGIAssignable,(TT))
+   {
+     BOOST_CONCEPT_USAGE(SGIAssignable) {
+-      TT b(a);
++      TT c(a);
+ #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+-      a = a;              // require assignment operator
++      a = b;              // require assignment operator
+ #endif
+-      const_constraints(a);
+-      ignore_unused_variable_warning(b);
++      const_constraints(b);
++      ignore_unused_variable_warning(c);
+     }
+    private:
+-    void const_constraints(const TT& b) {
+-      TT c(b);
++    void const_constraints(const TT& x) {
++      TT c(x);
+ #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+-      a = b;              // const required for argument to assignment
++      a = x;              // const required for argument to assignment
+ #endif
+       ignore_unused_variable_warning(c);
+     }
+     TT a;
++    TT b;
+   };
+ #if (defined _MSC_VER)
+ # pragma warning( pop )
+
diff --git a/tools/depends/target/curl/0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch b/tools/depends/target/curl/0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
new file mode 100644 (file)
index 0000000..7855f42
--- /dev/null
@@ -0,0 +1,83 @@
+From c44d45db86b880df5facd6b560491e03530f876e Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Fri, 23 Mar 2012 23:42:37 +0100
+Subject: [PATCH] HTTP: reset expected DL/UL sizes on redirects
+
+With FOLLOWLOCATION enabled. When a 3xx page is downloaded and the
+download size was known (like with a Content-Length header), but the
+subsequent URL (transfered after the 3xx page) was chunked encoded, then
+the previous "known download size" would linger and cause the progress
+meter to get incorrect information, ie the former value would remain
+being sent in. This could easily result in downloads that were WAY
+larger than "expected" and would cause >100% outputs with the curl
+command line tool.
+
+Test case 599 was created and it was used to repeat the bug and then
+verify the fix.
+
+Bug: http://curl.haxx.se/bug/view.cgi?id=3510057
+Reported by: Michael Wallner
+---
+ lib/progress.c             |  9 +++--
+ lib/progress.h             |  4 +--
+ lib/transfer.c             |  2 +-
+ tests/data/Makefile.am     |  2 +-
+ tests/data/test599         | 83 +++++++++++++++++++++++++++++++++++++++++++
+ tests/libtest/Makefile.inc |  4 ++-
+ tests/libtest/lib599.c     | 88 ++++++++++++++++++++++++++++++++++++++++++++++
+ 7 files changed, 184 insertions(+), 8 deletions(-)
+ create mode 100644 tests/data/test599
+ create mode 100644 tests/libtest/lib599.c
+
+diff --git a/lib/progress.c b/lib/progress.c
+index 1eeb780..4c9a63a 100644
+--- a/lib/progress.c
++++ b/lib/progress.c
+@@ -146,13 +146,16 @@ void Curl_pgrsDone(struct connectdata *conn)
+   data->progress.speeder_c = 0; /* reset the progress meter display */
+ }
+-/* reset all times except redirect */
+-void Curl_pgrsResetTimes(struct SessionHandle *data)
++/* reset all times except redirect, and reset the known transfer sizes */
++void Curl_pgrsResetTimesSizes(struct SessionHandle *data)
+ {
+   data->progress.t_nslookup = 0.0;
+   data->progress.t_connect = 0.0;
+   data->progress.t_pretransfer = 0.0;
+   data->progress.t_starttransfer = 0.0;
++
++  Curl_pgrsSetDownloadSize(data, 0);
++  Curl_pgrsSetUploadSize(data, 0);
+ }
+ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
+diff --git a/lib/progress.h b/lib/progress.h
+index f5cc540..a41d5f9 100644
+--- a/lib/progress.h
++++ b/lib/progress.h
+@@ -46,7 +46,7 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size);
+ void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size);
+ void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size);
+ int Curl_pgrsUpdate(struct connectdata *);
+-void Curl_pgrsResetTimes(struct SessionHandle *data);
++void Curl_pgrsResetTimesSizes(struct SessionHandle *data);
+ void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
+diff --git a/lib/transfer.c b/lib/transfer.c
+index d6061be..d872719 100644
+--- a/lib/transfer.c
++++ b/lib/transfer.c
+@@ -1924,7 +1924,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
+     break;
+   }
+   Curl_pgrsTime(data, TIMER_REDIRECT);
+-  Curl_pgrsResetTimes(data);
++  Curl_pgrsResetTimesSizes(data);
+   return CURLE_OK;
+ #endif /* CURL_DISABLE_HTTP */
+-- 
+1.8.4.3
+
index 7dcf848..f81c012 100644 (file)
@@ -1,5 +1,5 @@
 include ../../Makefile.include
-DEPS= ../../Makefile.include Makefile
+DEPS= ../../Makefile.include Makefile 0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
 
 # lib name, version
 LIBNAME=curl
@@ -22,6 +22,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); patch -p1 < ../0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
        cd $(PLATFORM); $(CONFIGURE)
 
 $(LIBDYLIB): $(PLATFORM)
index 2f92e5c..e55de5b 100644 (file)
@@ -7,4 +7,4 @@
 -AC_C_ALWAYS_INLINE
  AC_C_RESTRICT
  AC_C_BUILTIN_EXPECT
- AC_C_BIGENDIAN
\ No newline at end of file
+ AC_C_BIGENDIAN
diff --git a/tools/depends/target/libmpeg2/05-upstream-motion_comp_arm_s.S-is-not-PIC-enough.patch b/tools/depends/target/libmpeg2/05-upstream-motion_comp_arm_s.S-is-not-PIC-enough.patch
new file mode 100644 (file)
index 0000000..aa28ed8
--- /dev/null
@@ -0,0 +1,132 @@
+Index: libmpeg2/motion_comp_arm_s.S
+===================================================================
+--- libmpeg2/motion_comp_arm_s.S       (revision 1205)
++++ libmpeg2/motion_comp_arm_s.S       (working copy)
+@@ -29,9 +29,13 @@
+       pld [r1]
+         stmfd sp!, {r4-r11, lr} @ R14 is also called LR
+       and r4, r1, #3
+-      adr r5, MC_put_o_16_arm_align_jt
+-      add r5, r5, r4, lsl #2
+-      ldr pc, [r5]
++      ldrb r4, [pc, r4]
++      add pc, pc, r4, lsl #2
++      .byte (MC_put_o_16_arm_align0 - 0f)>>2
++      .byte (MC_put_o_16_arm_align1 - 0f)>>2
++      .byte (MC_put_o_16_arm_align2 - 0f)>>2
++      .byte (MC_put_o_16_arm_align3 - 0f)>>2
++0:
+ MC_put_o_16_arm_align0:
+       ldmia r1, {r4-r7}
+@@ -75,11 +79,6 @@
+ 1:    PROC(24)
+       bne 1b
+         ldmfd sp!, {r4-r11, pc} @@ update PC with LR content.
+-MC_put_o_16_arm_align_jt:
+-      .word MC_put_o_16_arm_align0
+-      .word MC_put_o_16_arm_align1
+-      .word MC_put_o_16_arm_align2
+-      .word MC_put_o_16_arm_align3
+ @ ----------------------------------------------------------------
+       .align
+@@ -89,9 +88,14 @@
+       pld [r1]
+         stmfd sp!, {r4-r10, lr} @ R14 is also called LR
+       and r4, r1, #3
+-      adr r5, MC_put_o_8_arm_align_jt
+-      add r5, r5, r4, lsl #2
+-      ldr pc, [r5]
++      ldrb r4, [pc, r4]
++      add pc, pc, r4, lsl #2
++      .byte (MC_put_o_8_arm_align0 - 0f)>>2
++      .byte (MC_put_o_8_arm_align1 - 0f)>>2
++      .byte (MC_put_o_8_arm_align2 - 0f)>>2
++      .byte (MC_put_o_8_arm_align3 - 0f)>>2
++0:
++
+ MC_put_o_8_arm_align0:
+       ldmia r1, {r4-r5}
+       add r1, r1, r2
+@@ -133,12 +137,6 @@
+       bne 1b
+         ldmfd sp!, {r4-r10, pc} @@ update PC with LR content.
+-MC_put_o_8_arm_align_jt:
+-      .word MC_put_o_8_arm_align0
+-      .word MC_put_o_8_arm_align1
+-      .word MC_put_o_8_arm_align2
+-      .word MC_put_o_8_arm_align3
+-
+ @ ----------------------------------------------------------------
+ .macro        AVG_PW rW1, rW2
+       mov \rW2, \rW2, lsl #24
+@@ -157,12 +155,17 @@
+       @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
+       pld [r1]
+         stmfd sp!, {r4-r11,lr} @ R14 is also called LR
++      ldr r11, 0f
+       and r4, r1, #3
+-      adr r5, MC_put_x_16_arm_align_jt
+-      ldr r11, [r5]
+       mvn r12, r11
+-      add r5, r5, r4, lsl #2
+-      ldr pc, [r5, #4]
++      ldrb r4, [pc, r4]
++      add pc, pc, r4, lsl #2
++      .byte (MC_put_x_16_arm_align0 - 0f)>>2
++      .byte (MC_put_x_16_arm_align1 - 0f)>>2
++      .byte (MC_put_x_16_arm_align2 - 0f)>>2
++      .byte (MC_put_x_16_arm_align3 - 0f)>>2
++0:
++        .word 0x01010101
+ .macro        ADJ_ALIGN_QW shift, R0, R1, R2, R3, R4
+       mov \R0, \R0, lsr #(\shift)
+@@ -235,12 +238,6 @@
+       add r0, r0, r2
+       bne 1b
+         ldmfd sp!, {r4-r11,pc} @@ update PC with LR content.
+-MC_put_x_16_arm_align_jt:
+-      .word 0x01010101
+-      .word MC_put_x_16_arm_align0
+-      .word MC_put_x_16_arm_align1
+-      .word MC_put_x_16_arm_align2
+-      .word MC_put_x_16_arm_align3
+ @ ----------------------------------------------------------------
+       .align
+@@ -249,12 +246,17 @@
+       @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
+       pld [r1]
+         stmfd sp!, {r4-r11,lr} @ R14 is also called LR
++      ldr r11, 0f
+       and r4, r1, #3
+-      adr r5, MC_put_x_8_arm_align_jt
+-      ldr r11, [r5]
+       mvn r12, r11
+-      add r5, r5, r4, lsl #2
+-      ldr pc, [r5, #4]
++      ldrb r4, [pc, r4]
++      add pc, pc, r4, lsl #2
++      .byte (MC_put_x_8_arm_align0 - 0f)>>2
++      .byte (MC_put_x_8_arm_align1 - 0f)>>2
++      .byte (MC_put_x_8_arm_align2 - 0f)>>2
++      .byte (MC_put_x_8_arm_align3 - 0f)>>2
++0:
++        .word 0x01010101
+ .macro        ADJ_ALIGN_DW shift, R0, R1, R2
+       mov \R0, \R0, lsr #(\shift)
+@@ -315,9 +317,3 @@
+       add r0, r0, r2
+       bne 1b
+         ldmfd sp!, {r4-r11,pc} @@ update PC with LR content.
+-MC_put_x_8_arm_align_jt:
+-      .word 0x01010101
+-      .word MC_put_x_8_arm_align0
+-      .word MC_put_x_8_arm_align1
+-      .word MC_put_x_8_arm_align2
+-      .word MC_put_x_8_arm_align3
+
index bdefc33..54eba7c 100644 (file)
@@ -29,6 +29,7 @@ ifeq ($(OS),ios)
        cd $(PLATFORM); patch -p1 < ../03-config-fix.patch
 endif
        cd $(PLATFORM); patch -p1 < ../04-clang-fix.patch
+       cd $(PLATFORM); patch -p0 < ../05-upstream-motion_comp_arm_s.S-is-not-PIC-enough.patch
        cd $(PLATFORM); $(AUTORECONF) -vif
        cd $(PLATFORM); $(CONFIGURE)
 
@@ -51,11 +52,6 @@ ifeq ($(OS),android)
        -$(READELF) --dynamic $(PREFIX)/lib/libxbmpeg2convert.so | grep ibrary
        #
 endif
-#on ios we link statically against libmpeg2 because of crash&burn since ios7 - 
-#so remove the dylib so the linker doesn't see it
-ifeq ($(OS),ios)
-       rm -f $(PREFIX)/lib/libmpeg2.la $(PREFIX)/lib/libmpeg2.dylib $(PREFIX)/lib/libmpeg2.0.dylib
-endif
        touch $@
 
 clean:
index 36128de..601d325 100644 (file)
@@ -2,7 +2,7 @@ include ../../Makefile.include
 #DEPS= ../../Makefile.include Makefile
 
 LIBNAME=xbmc-pvr-addons
-VERSION=af29425b1e171419d72fb3a0475a10f4a862f0b7
+VERSION=71e5b8c1da7acf726d00bde30da8554662cf97e1
 GIT_DIR=$(TARBALLS_LOCATION)/$(LIBNAME).git
 BASE_URL=git://github.com/opdenkamp/$(LIBNAME).git
 DYLIB=$(PLATFORM)/addons/pvr.demo/.libs/libpvrdemo-addon.so
index e851294..265881f 100644 (file)
@@ -515,23 +515,66 @@ bool CApplication::OnEvent(XBMC_Event& newEvent)
       return g_application.OnAppCommand(newEvent.appcommand.action);
     case XBMC_TOUCH:
     {
-      int windowId = g_windowManager.GetActiveWindow() & WINDOW_ID_MASK;
-
       if (newEvent.touch.action == ACTION_TOUCH_TAP)
       { // Send a mouse motion event with no dx,dy for getting the current guiitem selected
         g_application.OnAction(CAction(ACTION_MOUSE_MOVE, 0, newEvent.touch.x, newEvent.touch.y, 0, 0));
       }
       int actionId = 0;
       if (newEvent.touch.action == ACTION_GESTURE_BEGIN || newEvent.touch.action == ACTION_GESTURE_END)
-      {
         actionId = newEvent.touch.action;
-        windowId = WINDOW_INVALID;
+      else
+      {
+        int iWin = g_windowManager.GetActiveWindow() & WINDOW_ID_MASK;
+        // change this if we have a dialog up
+        if (g_windowManager.HasModalDialog())
+        {
+          iWin = g_windowManager.GetTopMostModalDialogID() & WINDOW_ID_MASK;
+        }
+        if (iWin == WINDOW_DIALOG_FULLSCREEN_INFO)
+        { // fullscreen info dialog - special case
+          CButtonTranslator::GetInstance().TranslateTouchAction(iWin, newEvent.touch.action, newEvent.touch.pointers, actionId);
+          if (actionId <= 0)
+            iWin = WINDOW_FULLSCREEN_VIDEO;  // fallthrough to the main window
+        }
+        if (actionId <= 0)
+        {
+          if (iWin == WINDOW_FULLSCREEN_VIDEO)
+          {
+            // current active window is full screen video.
+            if (g_application.m_pPlayer->IsInMenu())
+            {
+              // if player is in some sort of menu, (ie DVDMENU) map buttons differently
+              CButtonTranslator::GetInstance().TranslateTouchAction(WINDOW_VIDEO_MENU, newEvent.touch.action, newEvent.touch.pointers, actionId);
+            }
+            else if (g_PVRManager.IsStarted() && g_application.CurrentFileItem().HasPVRChannelInfoTag())
+            {
+              // check for PVR specific keymaps in FULLSCREEN_VIDEO window
+              CButtonTranslator::GetInstance().TranslateTouchAction(WINDOW_FULLSCREEN_LIVETV, newEvent.touch.action, newEvent.touch.pointers, actionId);
+
+              // if no PVR specific action/mapping is found, fall back to default
+              if (actionId <= 0)
+                CButtonTranslator::GetInstance().TranslateTouchAction(iWin, newEvent.touch.action, newEvent.touch.pointers, actionId);
+            }
+            else
+            {
+              // in any other case use the fullscreen window section of keymap.xml to map key->action
+              CButtonTranslator::GetInstance().TranslateTouchAction(iWin, newEvent.touch.action, newEvent.touch.pointers, actionId);
+            }
+          }
+          else  // iWin != WINDOW_FULLSCREEN_VIDEO
+            CButtonTranslator::GetInstance().TranslateTouchAction(iWin, newEvent.touch.action, newEvent.touch.pointers, actionId);
+        }
       }
-      else if (!CButtonTranslator::GetInstance().TranslateTouchAction(newEvent.touch.action, newEvent.touch.pointers, windowId, actionId) ||
-          actionId <= 0)
+
+      if (actionId <= 0)
         return false;
 
-      CApplicationMessenger::Get().SendAction(CAction(actionId, 0, newEvent.touch.x, newEvent.touch.y, newEvent.touch.x2, newEvent.touch.y2), windowId, false);
+      if ((actionId >= ACTION_TOUCH_TAP && actionId <= ACTION_GESTURE_END)
+          || (actionId >= ACTION_MOUSE_START && actionId <= ACTION_MOUSE_END) )
+        CApplicationMessenger::Get().SendAction(CAction(actionId, 0, newEvent.touch.x, newEvent.touch.y, newEvent.touch.x2, newEvent.touch.y2), WINDOW_INVALID, false);
+      else
+        CApplicationMessenger::Get().SendAction(CAction(actionId), WINDOW_INVALID, false);
+
       // Post an unfocus message for touch device after the action.
       if (newEvent.touch.action == ACTION_GESTURE_END || newEvent.touch.action == ACTION_TOUCH_TAP)
       {
@@ -540,6 +583,13 @@ bool CApplication::OnEvent(XBMC_Event& newEvent)
       }
       break;
     }
+    case XBMC_SETFOCUS:
+      // Reset the screensaver
+      g_application.ResetScreenSaver();
+      g_application.WakeUpScreenSaverAndDPMS();
+      // Send a mouse motion event with no dx,dy for getting the current guiitem selected
+      g_application.OnAction(CAction(ACTION_MOUSE_MOVE, 0, newEvent.focus.x, newEvent.focus.y, 0, 0));
+      break;
   }
   return true;
 }
@@ -1577,9 +1627,12 @@ void CApplication::OnSettingChanged(const CSetting *setting)
   {
     // if the skin changes and the current theme is not the default one, reset
     // the theme to the default value (which will also change lookandfeel.skincolors
-    // which in turn will reload the skin
+    // which in turn will reload the skin.  Similarly, if the current skin font is not
+    // the default, reset it as well.
     if (settingId == "lookandfeel.skin" && CSettings::Get().GetString("lookandfeel.skintheme") != "SKINDEFAULT")
       CSettings::Get().SetString("lookandfeel.skintheme", "SKINDEFAULT");
+    else if (settingId == "lookandfeel.skin" && CSettings::Get().GetString("lookandfeel.font") != "Default")
+      CSettings::Get().SetString("lookandfeel.font", "Default");
     else
     {
       std::string builtin("ReloadSkin");
@@ -2748,6 +2801,13 @@ bool CApplication::OnAction(const CAction &action)
       }
     }
 
+    // record current file
+    if (action.GetID() == ACTION_RECORD)
+    {
+      if (m_pPlayer->CanRecord())
+        m_pPlayer->Record(!m_pPlayer->IsRecording());
+    }
+
     if (m_playerController->OnAction(action))
       return true;
   }
@@ -5216,6 +5276,14 @@ CFileItem& CApplication::CurrentFileItem()
   return *m_itemCurrentFile;
 }
 
+CFileItem& CApplication::CurrentUnstackedItem()
+{
+  if (m_itemCurrentFile->IsStack() && m_currentStack->Size() > 0)
+    return *(*m_currentStack)[m_currentStackPosition];
+  else
+    return *m_itemCurrentFile;
+}
+
 void CApplication::ShowVolumeBar(const CAction *action)
 {
   CGUIDialog *volumeBar = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VOLUME_BAR);
index a0e20b4..e3a26c5 100644 (file)
@@ -156,6 +156,7 @@ public:
   void ReloadSkin(bool confirm = false);
   const CStdString& CurrentFile();
   CFileItem& CurrentFileItem();
+  CFileItem& CurrentUnstackedItem();
   virtual bool OnMessage(CGUIMessage& message);
   PLAYERCOREID GetCurrentPlayer();
   virtual void OnPlayBackEnded();
index 34dbc18..3524e89 100644 (file)
@@ -38,6 +38,7 @@
 #include "FileItem.h"
 #include "guilib/GUIDialog.h"
 #include "guilib/Key.h"
+#include "guilib/GUIKeyboardFactory.h"
 #include "GUIInfoManager.h"
 #include "utils/Splash.h"
 #include "cores/IPlayer.h"
@@ -1261,6 +1262,21 @@ void CApplicationMessenger::SendGUIMessage(const CGUIMessage &message, int windo
   SendMessage(tMsg, waitResult);
 }
 
+void CApplicationMessenger::SendText(const std::string &aTextString, bool closeKeyboard /* = false */)
+{
+  if (CGUIKeyboardFactory::SendTextToActiveKeyboard(aTextString, closeKeyboard))
+    return;
+
+  CGUIWindow *window = g_windowManager.GetWindow(g_windowManager.GetFocusedWindow());
+  if (!window)
+    return;
+
+  CGUIMessage msg(GUI_MSG_SET_TEXT, 0, 0);
+  msg.SetLabel(aTextString);
+  msg.SetParam1(closeKeyboard ? 1 : 0);
+  SendGUIMessage(msg, window->GetID());
+}
+
 vector<CStdString> CApplicationMessenger::GetInfoLabels(const vector<CStdString> &properties)
 {
   vector<CStdString> infoLabels;
index 6457087..e62c772 100644 (file)
@@ -235,6 +235,9 @@ public:
   void ActivateWindow(int windowID, const std::vector<CStdString> &params, bool swappingWindows);
   void SendAction(const CAction &action, int windowID = WINDOW_INVALID, bool waitResult=true);
 
+  //! \brief Send text to currently focused window / keyboard.
+  void SendText(const std::string &aTextString, bool closeKeyboard = false);
+
   /*! \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.
index f72f51c..5619054 100644 (file)
@@ -127,25 +127,16 @@ bool CCueDocument::Parse(const CStdString &strFile)
     else if (StringUtils::StartsWithNoCase(strLine,"TITLE"))
     {
       if (m_iTotalTracks == -1) // No tracks yet
-        ExtractQuoteInfo(strLine, m_strAlbum);
-      else if (!ExtractQuoteInfo(strLine, m_Track[m_iTotalTracks].strTitle))
-      {
-        // lets manage tracks titles without quotes
-        CStdString titleNoQuote = strLine.substr(5);
-        StringUtils::TrimLeft(titleNoQuote);
-        if (!titleNoQuote.empty())
-        {
-          g_charsetConverter.unknownToUTF8(titleNoQuote);
-          m_Track[m_iTotalTracks].strTitle = titleNoQuote;
-        }
-      }
+        m_strAlbum = ExtractInfo(strLine.substr(5));
+      else
+        m_Track[m_iTotalTracks].strTitle = ExtractInfo(strLine.substr(5));
     }
     else if (StringUtils::StartsWithNoCase(strLine,"PERFORMER"))
     {
       if (m_iTotalTracks == -1) // No tracks yet
-        ExtractQuoteInfo(strLine, m_strArtist);
+        m_strArtist = ExtractInfo(strLine.substr(9));
       else // New Artist for this track
-        ExtractQuoteInfo(strLine, m_Track[m_iTotalTracks].strArtist);
+        m_Track[m_iTotalTracks].strArtist = ExtractInfo(strLine.substr(9));
     }
     else if (StringUtils::StartsWithNoCase(strLine,"TRACK"))
     {
@@ -176,7 +167,7 @@ bool CCueDocument::Parse(const CStdString &strFile)
       if(strCurrentFile.size() > 0)
         bCurrentFileChanged = true;
 
-      ExtractQuoteInfo(strLine, strCurrentFile);
+      strCurrentFile = ExtractInfo(strLine.substr(4));
 
       // Resolve absolute paths (if needed).
       if (strCurrentFile.length() > 0)
@@ -190,16 +181,7 @@ bool CCueDocument::Parse(const CStdString &strFile)
     }
     else if (StringUtils::StartsWithNoCase(strLine,"REM GENRE"))
     {
-      if (!ExtractQuoteInfo(strLine, m_strGenre))
-      {
-        CStdString genreNoQuote = strLine.substr(9);
-        StringUtils::TrimLeft(genreNoQuote);
-        if (!genreNoQuote.empty())
-        {
-          g_charsetConverter.unknownToUTF8(genreNoQuote);
-          m_strGenre = genreNoQuote;
-        }
-      }
+      m_strGenre = ExtractInfo(strLine.substr(9));
     }
     else if (StringUtils::StartsWithNoCase(strLine,"REM REPLAYGAIN_ALBUM_GAIN"))
       m_replayGainAlbumGain = (float)atof(strLine.substr(26).c_str());
@@ -299,19 +281,26 @@ bool CCueDocument::ReadNextLine(CStdString &szLine)
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
-// Function: ExtractQuoteInfo()
+// Function: ExtractInfo()
 // Extracts the information in quotes from the string line, returning it in quote
 ////////////////////////////////////////////////////////////////////////////////////
-bool CCueDocument::ExtractQuoteInfo(const CStdString &line, CStdString &quote)
+CStdString CCueDocument::ExtractInfo(const CStdString &line)
 {
-  quote.clear();
   size_t left = line.find('\"');
-  if (left == std::string::npos) return false;
-  size_t right = line.find('\"', left + 1);
-  if (right == std::string::npos) return false;
-  quote = line.substr(left + 1, right - left - 1);
-  g_charsetConverter.unknownToUTF8(quote);
-  return true;
+  if (left != std::string::npos)
+  {
+    size_t right = line.find('\"', left + 1);
+    if (right != std::string::npos)
+    {
+      CStdString text = line.substr(left + 1, right - left - 1);
+      g_charsetConverter.unknownToUTF8(text);
+      return text;
+    }
+  }
+  CStdString text = line;
+  StringUtils::Trim(text);
+  g_charsetConverter.unknownToUTF8(text);
+  return text;
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
index 01d28e7..650ffd2 100644 (file)
@@ -79,7 +79,7 @@ private:
   std::vector<CCueTrack> m_Track;
 
   bool ReadNextLine(CStdString &strLine);
-  bool ExtractQuoteInfo(const CStdString &line, CStdString &quote);
+  CStdString ExtractInfo(const CStdString &line);
   int ExtractTimeFromIndex(const CStdString &index);
   int ExtractNumericInfo(const CStdString &info);
   bool ResolvePath(CStdString &strPath, const CStdString &strBase);
index 34d27fa..6916b60 100644 (file)
@@ -161,41 +161,32 @@ bool CTextureDatabase::Open()
   return CDatabase::Open();
 }
 
-bool CTextureDatabase::CreateTables()
+void CTextureDatabase::CreateTables()
 {
-  try
-  {
-    CDatabase::CreateTables();
+  CLog::Log(LOGINFO, "create texture table");
+  m_pDS->exec("CREATE TABLE texture (id integer primary key, url text, cachedurl text, imagehash text, lasthashcheck text)");
 
-    CLog::Log(LOGINFO, "create texture table");
-    m_pDS->exec("CREATE TABLE texture (id integer primary key, url text, cachedurl text, imagehash text, lasthashcheck text)");
+  CLog::Log(LOGINFO, "create sizes table, index,  and trigger");
+  m_pDS->exec("CREATE TABLE sizes (idtexture integer, size integer, width integer, height integer, usecount integer, lastusetime text)");
 
-    CLog::Log(LOGINFO, "create textures index");
-    m_pDS->exec("CREATE INDEX idxTexture ON texture(url)");
-
-    CLog::Log(LOGINFO, "create sizes table, index,  and trigger");
-    m_pDS->exec("CREATE TABLE sizes (idtexture integer, size integer, width integer, height integer, usecount integer, lastusetime text)");
-    m_pDS->exec("CREATE INDEX idxSize ON sizes(idtexture, size)");
-    m_pDS->exec("CREATE INDEX idxSize2 ON sizes(idtexture, width, height)");
-    m_pDS->exec("CREATE TRIGGER textureDelete AFTER delete ON texture FOR EACH ROW BEGIN delete from sizes where sizes.idtexture=old.id; END");
-
-    CLog::Log(LOGINFO, "create path table");
-    m_pDS->exec("CREATE TABLE path (id integer primary key, url text, type text, texture text)\n");
-
-    // TODO: Should the path index be a covering index? (we need only retrieve texture)
-    CLog::Log(LOGINFO, "create path index");
-    m_pDS->exec("CREATE INDEX idxPath ON path(url, type)");
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "%s unable to create tables", __FUNCTION__);
-    return false;
-  }
+  CLog::Log(LOGINFO, "create path table");
+  m_pDS->exec("CREATE TABLE path (id integer primary key, url text, type text, texture text)\n");
+}
 
-  return true;
+void CTextureDatabase::CreateAnalytics()
+{
+  CLog::Log(LOGINFO, "%s creating indices", __FUNCTION__);
+  m_pDS->exec("CREATE INDEX idxTexture ON texture(url)");
+  m_pDS->exec("CREATE INDEX idxSize ON sizes(idtexture, size)");
+  m_pDS->exec("CREATE INDEX idxSize2 ON sizes(idtexture, width, height)");
+  // TODO: Should the path index be a covering index? (we need only retrieve texture)
+  m_pDS->exec("CREATE INDEX idxPath ON path(url, type)");
+
+  CLog::Log(LOGINFO, "%s creating triggers", __FUNCTION__);
+  m_pDS->exec("CREATE TRIGGER textureDelete AFTER delete ON texture FOR EACH ROW BEGIN delete from sizes where sizes.idtexture=old.id; END");
 }
 
-bool CTextureDatabase::UpdateOldVersion(int version)
+void CTextureDatabase::UpdateTables(int version)
 {
   if (version < 7)
   { // update all old thumb://foo urls to image://foo?size=thumb
@@ -223,24 +214,18 @@ bool CTextureDatabase::UpdateOldVersion(int version)
   }
   if (version < 9)
   { // get rid of the old path table and add the type column
-    m_pDS->dropIndex("path", "idxPath");
-    m_pDS->exec("DROP TABLE path");
+    m_pDS->exec("DROP TABLE IF EXISTS path");
     m_pDS->exec("CREATE TABLE path (id integer primary key, urlhash integer, url text, type text, texture text)\n");
-    m_pDS->exec("CREATE INDEX idxPath ON path(urlhash, type)");
   }
   if (version < 10)
   { // get rid of urlhash in both tables...
-    m_pDS->dropIndex("path", "idxPath");
-    m_pDS->exec("DROP TABLE path");
+    m_pDS->exec("DROP TABLE IF EXISTS path");
     m_pDS->exec("CREATE TABLE path (id integer primary key, url text, type text, texture text)\n");
-    m_pDS->exec("CREATE INDEX idxPath ON path(url, type)");
 
-    m_pDS->dropIndex("texture", "idxTexture");
     m_pDS->exec("CREATE TEMPORARY TABLE texture_backup(id,url,cachedurl,usecount,lastusetime,imagehash,lasthashcheck)");
     m_pDS->exec("INSERT INTO texture_backup SELECT id,url,cachedurl,usecount,lastusetime,imagehash,lasthashcheck FROM texture");
     m_pDS->exec("DROP TABLE texture");
     m_pDS->exec("CREATE TABLE texture (id integer primary key, url text, cachedurl text, usecount integer, lastusetime text, imagehash text, lasthashcheck text)");
-    m_pDS->exec("CREATE INDEX idxTexture ON texture(url)");
     m_pDS->exec("INSERT INTO texture SELECT * FROM texture_backup");
     m_pDS->exec("DROP TABLE texture_backup");
   }
@@ -250,18 +235,10 @@ bool CTextureDatabase::UpdateOldVersion(int version)
   }
   if (version < 12)
   { // create new sizes table and move usecount info to it.
-    m_pDS->exec("DROP TABLE texture");
+    m_pDS->exec("DROP TABLE IF EXISTS texture");
     m_pDS->exec("CREATE TABLE texture (id integer primary key, url text, cachedurl text, imagehash text, lasthashcheck text)");
-    m_pDS->exec("CREATE INDEX idxTexture ON texture(url)");
     m_pDS->exec("CREATE TABLE sizes (idtexture integer, size integer, width integer, height integer, usecount integer, lastusetime text)");
-    m_pDS->exec("CREATE INDEX idxSize ON sizes(idtexture, size)");
-    m_pDS->exec("CREATE TRIGGER textureDelete AFTER delete ON texture FOR EACH ROW BEGIN delete from sizes where sizes.idtexture=old.id; END");
   }
-  if (version < 13)
-  { // index for updateusecount
-    m_pDS->exec("CREATE INDEX idxSize2 ON sizes(idtexture, width, height)");
-  }
-  return true;
 }
 
 bool CTextureDatabase::IncrementUseCount(const CTextureDetails &details)
index 75aa45c..77207cb 100644 (file)
@@ -123,8 +123,9 @@ protected:
    */
   unsigned int GetURLHash(const CStdString &url) const;
 
-  virtual bool CreateTables();
-  virtual bool UpdateOldVersion(int version);
-  virtual int GetMinVersion() const { return 13; };
+  virtual void CreateTables();
+  virtual void CreateAnalytics();
+  virtual void UpdateTables(int version);
+  virtual int GetSchemaVersion() const { return 13; };
   const char *GetBaseDBName() const { return "Textures"; };
 };
index 8d48b1d..b2bd057 100644 (file)
@@ -634,7 +634,8 @@ CStdString CURL::GetWithoutFilename() const
     strURL += m_strDomain;
     strURL += ";";
   }
-  else if (m_strUserName != "")
+
+  if (m_strUserName != "")
   {
     strURL += Encode(m_strUserName);
     if (m_strPassword != "")
index 524895a..bb1d0f0 100644 (file)
@@ -44,88 +44,61 @@ bool CAddonDatabase::Open()
   return CDatabase::Open();
 }
 
-bool CAddonDatabase::CreateTables()
+void CAddonDatabase::CreateTables()
 {
-  try
-  {
-    CDatabase::CreateTables();
-
-    CLog::Log(LOGINFO, "create addon table");
-    m_pDS->exec("CREATE TABLE addon (id integer primary key, type text,"
-                "name text, summary text, description text, stars integer,"
-                "path text, addonID text, icon text, version text, "
-                "changelog text, fanart text, author text, disclaimer text,"
-                "minversion text)\n");
-
-    CLog::Log(LOGINFO, "create addon index");
-    m_pDS->exec("CREATE INDEX idxAddon ON addon(addonID)");
-
-    CLog::Log(LOGINFO, "create addonextra table");
-    m_pDS->exec("CREATE TABLE addonextra (id integer, key text, value text)\n");
+  CLog::Log(LOGINFO, "create addon table");
+  m_pDS->exec("CREATE TABLE addon (id integer primary key, type text,"
+              "name text, summary text, description text, stars integer,"
+              "path text, addonID text, icon text, version text, "
+              "changelog text, fanart text, author text, disclaimer text,"
+              "minversion text)\n");
 
-    CLog::Log(LOGINFO, "create addonextra index");
-    m_pDS->exec("CREATE INDEX idxAddonExtra ON addonextra(id)");
+  CLog::Log(LOGINFO, "create addonextra table");
+  m_pDS->exec("CREATE TABLE addonextra (id integer, key text, value text)\n");
 
-    CLog::Log(LOGINFO, "create dependencies table");
-    m_pDS->exec("CREATE TABLE dependencies (id integer, addon text, version text, optional boolean)\n");
-    m_pDS->exec("CREATE INDEX idxDependencies ON dependencies(id)");
+  CLog::Log(LOGINFO, "create dependencies table");
+  m_pDS->exec("CREATE TABLE dependencies (id integer, addon text, version text, optional boolean)\n");
 
-    CLog::Log(LOGINFO, "create repo table");
-    m_pDS->exec("CREATE TABLE repo (id integer primary key, addonID text,"
-                "checksum text, lastcheck text)\n");
+  CLog::Log(LOGINFO, "create repo table");
+  m_pDS->exec("CREATE TABLE repo (id integer primary key, addonID text,"
+              "checksum text, lastcheck text)\n");
 
-    CLog::Log(LOGINFO, "create addonlinkrepo table");
-    m_pDS->exec("CREATE TABLE addonlinkrepo (idRepo integer, idAddon integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_1 ON addonlinkrepo ( idAddon, idRepo )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_2 ON addonlinkrepo ( idRepo, idAddon )\n");
+  CLog::Log(LOGINFO, "create addonlinkrepo table");
+  m_pDS->exec("CREATE TABLE addonlinkrepo (idRepo integer, idAddon integer)\n");
 
-    CLog::Log(LOGINFO, "create disabled table");
-    m_pDS->exec("CREATE TABLE disabled (id integer primary key, addonID text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxDisabled ON disabled(addonID)");
+  CLog::Log(LOGINFO, "create disabled table");
+  m_pDS->exec("CREATE TABLE disabled (id integer primary key, addonID text)\n");
 
-    CLog::Log(LOGINFO, "create broken table");
-    m_pDS->exec("CREATE TABLE broken (id integer primary key, addonID text, reason text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxBroken ON broken(addonID)");
+  CLog::Log(LOGINFO, "create broken table");
+  m_pDS->exec("CREATE TABLE broken (id integer primary key, addonID text, reason text)\n");
 
-    CLog::Log(LOGINFO, "create blacklist table");
-    m_pDS->exec("CREATE TABLE blacklist (id integer primary key, addonID text, version text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxBlack ON blacklist(addonID)");
+  CLog::Log(LOGINFO, "create blacklist table");
+  m_pDS->exec("CREATE TABLE blacklist (id integer primary key, addonID text, version text)\n");
 
-    CLog::Log(LOGINFO, "create package table");
-    m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxPackage ON package(filename)");
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "%s unable to create tables", __FUNCTION__);
-    return false;
-  }
+  CLog::Log(LOGINFO, "create package table");
+  m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n");
+}
 
-  return true;
+void CAddonDatabase::CreateAnalytics()
+{
+  CLog::Log(LOGINFO, "%s creating indicies", __FUNCTION__);
+  m_pDS->exec("CREATE INDEX idxAddon ON addon(addonID)");
+  m_pDS->exec("CREATE INDEX idxAddonExtra ON addonextra(id)");
+  m_pDS->exec("CREATE INDEX idxDependencies ON dependencies(id)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_1 ON addonlinkrepo ( idAddon, idRepo )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_addonlinkrepo_2 ON addonlinkrepo ( idRepo, idAddon )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX idxDisabled ON disabled(addonID)");
+  m_pDS->exec("CREATE UNIQUE INDEX idxBroken ON broken(addonID)");
+  m_pDS->exec("CREATE UNIQUE INDEX idxBlack ON blacklist(addonID)");
+  m_pDS->exec("CREATE UNIQUE INDEX idxPackage ON package(filename)");
 }
 
-bool CAddonDatabase::UpdateOldVersion(int version)
+void CAddonDatabase::UpdateTables(int version)
 {
-  if (version < 13)
-  {
-    m_pDS->exec("CREATE TABLE dependencies (id integer, addon text, version text, optional boolean)\n");
-    m_pDS->exec("CREATE INDEX idxDependencies ON dependencies(id)");
-  }
-  if (version < 14)
-  {
-    m_pDS->exec("ALTER TABLE addon add minversion text");
-  }
-  if (version < 15)
-  {
-    m_pDS->exec("CREATE TABLE blacklist (id integer primary key, addonID text, version text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxBlack ON blacklist(addonID)");
-  }
   if (version < 16)
   {
     m_pDS->exec("CREATE TABLE package (id integer primary key, addonID text, filename text, hash text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxPackage ON package(filename)");
   }
-  return true;
 }
 
 int CAddonDatabase::AddAddon(const AddonPtr& addon,
index 0901a0b..1556e05 100644 (file)
@@ -135,9 +135,11 @@ public:
   */
   bool RemovePackage(const CStdString& packageFileName);
 protected:
-  virtual bool CreateTables();
-  virtual bool UpdateOldVersion(int version);
-  virtual int GetMinVersion() const { return 16; }
+  virtual void CreateTables();
+  virtual void CreateAnalytics();
+  virtual void UpdateTables(int version);
+  virtual int GetMinSchemaVersion() const { return 15; }
+  virtual int GetSchemaVersion() const { return 16; }
   const char *GetBaseDBName() const { return "Addons"; }
 
   bool GetAddon(int id, ADDON::AddonPtr& addon);
index ccc8fdf..e87d299 100644 (file)
@@ -733,7 +733,10 @@ void CAddonInstallJob::OnPostInstall(bool reloadAddon)
         toast->ResetTimer();
         toast->Close(true);
       }
-      CSettings::Get().SetString("lookandfeel.skin",m_addon->ID().c_str());
+      if (CSettings::Get().GetString("lookandfeel.skin") == m_addon->ID())
+        CApplicationMessenger::Get().ExecBuiltIn("ReloadSkin", true);
+      else
+        CSettings::Get().SetString("lookandfeel.skin",m_addon->ID().c_str());
     }
   }
 
index fb968eb..b5ddb88 100644 (file)
@@ -371,13 +371,13 @@ bool CAddonMgr::ReloadSettings(const CStdString &id)
   return false;
 }
 
-bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/)
+bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool getLocalVersion /*= false*/)
 {
   CSingleLock lock(m_critSection);
   for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i)
   {
     VECADDONS temp;
-    if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled))
+    if (CAddonMgr::Get().GetAddons((TYPE)i, temp, true))
     {
       AddonPtr repoAddon;
       for (unsigned int j = 0; j < temp.size(); j++)
@@ -396,17 +396,21 @@ bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/)
         if (temp[j]->Version() < repoAddon->Version() &&
             !m_database.IsAddonBlacklisted(temp[j]->ID(),
                                            repoAddon->Version().c_str()))
+        {
+          if (getLocalVersion)
+            repoAddon->Props().version = temp[j]->Version();
           addons.push_back(repoAddon);
+        }
       }
     }
   }
   return !addons.empty();
 }
 
-bool CAddonMgr::HasOutdatedAddons(bool enabled /*= true*/)
+bool CAddonMgr::HasOutdatedAddons()
 {
   VECADDONS dummy;
-  return GetAllOutdatedAddons(dummy,enabled);
+  return GetAllOutdatedAddons(dummy);
 }
 
 bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */)
index 7349966..8beef1f 100644 (file)
@@ -99,15 +99,14 @@ namespace ADDON
     bool ReloadSettings(const CStdString &id);
     /*! \brief Get all addons with available updates
      \param addons List to fill with all outdated addons
-     \param enabled Whether to get only enabled or disabled addons
+     \param getLocalVersion Whether to get the local addon version or the addon verion from the repository
      \return True if there are outdated addons otherwise false
      */
-    bool GetAllOutdatedAddons(VECADDONS &addons, bool enabled = true);
+    bool GetAllOutdatedAddons(VECADDONS &addons, bool getLocalVersion = false);
     /*! \brief Checks if there is any addon with available updates
-     \param enabled Whether to check only enabled or disabled addons
      \return True if there are outdated addons otherwise false
      */
-    bool HasOutdatedAddons(bool enabled = true);
+    bool HasOutdatedAddons();
     CStdString GetString(const CStdString &id, const int number);
 
     const char *GetTranslatedString(const cp_cfg_element_t *root, const char *tag);
index d3156df..4d966b9 100644 (file)
@@ -23,6 +23,7 @@
 #include "addons/Repository.h"
 #include "GUIDialogAddonInfo.h"
 #include "GUIDialogAddonSettings.h"
+#include "dialogs/GUIDialogBusy.h"
 #include "dialogs/GUIDialogYesNo.h"
 #include "dialogs/GUIDialogSelect.h"
 #include "dialogs/GUIDialogFileBrowser.h"
@@ -208,6 +209,20 @@ bool CGUIWindowAddonBrowser::OnContextButton(int itemNumber,
   return CGUIMediaWindow::OnContextButton(itemNumber, button);
 }
 
+class UpdateAddons : public IRunnable
+{
+  virtual void Run()
+  {
+    VECADDONS addons;
+    CAddonMgr::Get().GetAllOutdatedAddons(addons, true); // get local
+    for (VECADDONS::iterator i = addons.begin(); i != addons.end(); ++i)
+    {
+      CStdString referer = StringUtils::Format("Referer=%s-%s.zip",(*i)->ID().c_str(),(*i)->Version().c_str());
+      CAddonInstaller::Get().Install((*i)->ID(), true, referer); // force install
+    }
+  }
+};
+
 bool CGUIWindowAddonBrowser::OnClick(int iItem)
 {
   CFileItemPtr item = m_vecItems->Get(iItem);
@@ -222,6 +237,14 @@ bool CGUIWindowAddonBrowser::OnClick(int iItem)
       CAddonInstaller::Get().InstallFromZip(path);
     return true;
   }
+  if (item->GetPath() == "addons://update_all/")
+  {
+    // fire off a threaded update of all addons
+    UpdateAddons updater;
+    if (CGUIDialogBusy::Wait(&updater))
+      return Update("addons://downloading/");
+    return true;
+  }
   if (!item->m_bIsFolder)
   {
     // cancel a downloading job
index a6daf8d..e83de95 100644 (file)
@@ -252,6 +252,7 @@ bool CRepositoryUpdateJob::DoWork()
   CTextureDatabase textureDB;
   textureDB.Open();
   textureDB.BeginMultipleExecute();
+  VECADDONS notifications;
   for (map<string, AddonPtr>::const_iterator i = addons.begin(); i != addons.end(); ++i)
   {
     // manager told us to feck off
@@ -287,12 +288,8 @@ bool CRepositoryUpdateJob::DoWork()
         else
           CAddonInstaller::Get().Install(addon->ID(), true, referer);
       }
-      else if (CSettings::Get().GetBool("general.addonnotifications"))
-      {
-        CGUIDialogKaiToast::QueueNotification(addon->Icon(),
-                                              g_localizeStrings.Get(24061),
-                                              addon->Name(),TOAST_DISPLAY_TIME,false,TOAST_DISPLAY_TIME);
-      }
+      else
+        notifications.push_back(addon);
     }
 
     // Check if we should mark the add-on as broken.  We may have a newer version
@@ -320,6 +317,17 @@ bool CRepositoryUpdateJob::DoWork()
   }
   database.CommitMultipleExecute();
   textureDB.CommitMultipleExecute();
+  if (!notifications.empty() && CSettings::Get().GetBool("general.addonnotifications"))
+  {
+    if (notifications.size() == 1)
+      CGUIDialogKaiToast::QueueNotification(notifications[0]->Icon(),
+                                            g_localizeStrings.Get(24061),
+                                            notifications[0]->Name(),TOAST_DISPLAY_TIME,false,TOAST_DISPLAY_TIME);
+    else
+      CGUIDialogKaiToast::QueueNotification("",
+                                            g_localizeStrings.Get(24001),
+                                            g_localizeStrings.Get(24061),TOAST_DISPLAY_TIME,false,TOAST_DISPLAY_TIME);
+  }
 
   return true;
 }
index 1b95381..e598df3 100644 (file)
@@ -46,6 +46,7 @@
 #include "ApplicationMessenger.h"
 #include "utils/StringUtils.h"
 #include "AppParamParser.h"
+#include "XbmcContext.h"
 #include <android/bitmap.h>
 #include "android/jni/JNIThreading.h"
 #include "android/jni/BroadcastReceiver.h"
@@ -251,7 +252,8 @@ void CXBMCApp::run()
   int status = 0;
 
   SetupEnv();
-  
+  XBMC::Context context;
+
   m_initialVolume = GetSystemVolume();
 
   CJNIIntent startIntent = getIntent();
index 3094bdf..17ebcc9 100644 (file)
 #include "AEFactory.h"
 #include "Utils/AEUtil.h"
 
-#if defined(TARGET_DARWIN)
-  #include "Engines/CoreAudio/CoreAudioAE.h"
-  #include "settings/lib/SettingsManager.h"
-#else
-  #include "Engines/ActiveAE/ActiveAE.h"
-#endif
+#include "Engines/ActiveAE/ActiveAE.h"
 
 #include "guilib/LocalizeStrings.h"
 #include "settings/lib/Setting.h"
@@ -45,11 +40,7 @@ IAE *CAEFactory::GetEngine()
 
 bool CAEFactory::LoadEngine()
 {
-#if defined(TARGET_DARWIN)
-  return CAEFactory::LoadEngine(AE_ENGINE_COREAUDIO);
-#else
   return CAEFactory::LoadEngine(AE_ENGINE_ACTIVE);
-#endif
 }
 
 bool CAEFactory::LoadEngine(enum AEEngine engine)
@@ -61,11 +52,7 @@ bool CAEFactory::LoadEngine(enum AEEngine engine)
   switch(engine)
   {
     case AE_ENGINE_NULL     :
-#if defined(TARGET_DARWIN)
-    case AE_ENGINE_COREAUDIO: AE = new CCoreAudioAE(); break;
-#else
     case AE_ENGINE_ACTIVE   : AE = new ActiveAE::CActiveAE(); break;
-#endif
     default:
       return false;
   }
@@ -355,12 +342,10 @@ void CAEFactory::SettingOptionsAudioDevicesFillerGeneral(const CSetting *setting
   bool foundValue = false;
   AEDeviceList sinkList;
   EnumerateOutputDevices(sinkList, passthrough);
-#if !defined(TARGET_DARWIN)
   if (sinkList.size() == 0)
     list.push_back(std::make_pair("Error - no devices found", "error"));
   else
   {
-#endif
     for (AEDeviceList::const_iterator sink = sinkList.begin(); sink != sinkList.end(); ++sink)
     {
       if (sink == sinkList.begin())
@@ -371,9 +356,7 @@ void CAEFactory::SettingOptionsAudioDevicesFillerGeneral(const CSetting *setting
       if (StringUtils::EqualsNoCase(current, sink->second))
         foundValue = true;
     }
-#if !defined(TARGET_DARWIN)
   }
-#endif
 
   if (!foundValue)
     current = firstDevice;
@@ -404,3 +387,9 @@ void CAEFactory::KeepConfiguration(unsigned int millis)
   if (AE)
     AE->KeepConfiguration(millis);
 }
+
+void CAEFactory::DeviceChange()
+{
+  if (AE)
+    AE->DeviceChange();
+}
index 9a340cc..1d55513 100644 (file)
@@ -76,6 +76,7 @@ public:
   static void SettingOptionsAudioStreamsilenceFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current);
   static bool IsSettingVisible(const std::string &condition, const std::string &value, const std::string &settingId);
   static void KeepConfiguration(unsigned int millis);
+  static void DeviceChange();
 
   static void RegisterAudioCallback(IAudioCallback* pCallback);
   static void UnregisterAudioCallback();
index 7b515aa..128010e 100644 (file)
   #include "Sinks/AESinkAUDIOTRACK.h"
 #elif defined(TARGET_RASPBERRY_PI)
   #include "Sinks/AESinkPi.h"
+#elif defined(TARGET_DARWIN_IOS)
+  #include "Sinks/AESinkDARWINIOS.h"
+#elif defined(TARGET_DARWIN_OSX)
+  #include "Sinks/AESinkDARWINOSX.h"
 #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
   #if defined(HAS_ALSA)
     #include "Sinks/AESinkALSA.h"
@@ -62,6 +66,10 @@ void CAESinkFactory::ParseDevice(std::string &device, std::string &driver)
         driver == "AUDIOTRACK"  ||
 #elif defined(TARGET_RASPBERRY_PI)
         driver == "PI"          ||
+#elif defined(TARGET_DARWIN_IOS)
+        driver == "DARWINIOS"  ||
+#elif defined(TARGET_DARWIN_OSX)
+        driver == "DARWINOSX"  ||
 #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
   #if defined(HAS_ALSA)
         driver == "ALSA"        ||
@@ -97,6 +105,10 @@ IAESink *CAESinkFactory::TrySink(std::string &driver, std::string &device, AEAud
   sink = new CAESinkAUDIOTRACK();
 #elif defined(TARGET_RASPBERRY_PI)
   sink = new CAESinkPi();
+#elif defined(TARGET_DARWIN_IOS)
+  sink = new CAESinkDARWINIOS();
+#elif defined(TARGET_DARWIN_OSX)
+  sink = new CAESinkDARWINOSX();
 #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
   #if defined(HAS_PULSEAUDIO)
   else if (driver == "PULSE")
@@ -148,7 +160,7 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
 #if defined(TARGET_WINDOWS)
 
   info.m_deviceInfoList.clear();
-  info.m_sinkName = "DirectSound";
+  info.m_sinkName = "DIRECTSOUND";
   CAESinkDirectSound::EnumerateDevicesEx(info.m_deviceInfoList, force);
   if(!info.m_deviceInfoList.empty())
     list.push_back(info);
@@ -175,6 +187,22 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
   if(!info.m_deviceInfoList.empty())
     list.push_back(info);
 
+#elif defined(TARGET_DARWIN_IOS)
+
+  info.m_deviceInfoList.clear();
+  info.m_sinkName = "DARWINIOS";
+  CAESinkDARWINIOS::EnumerateDevicesEx(info.m_deviceInfoList, force);
+  if(!info.m_deviceInfoList.empty())
+    list.push_back(info);
+
+#elif defined(TARGET_DARWIN_OSX)
+
+  info.m_deviceInfoList.clear();
+  info.m_sinkName = "DARWINOSX";
+  CAESinkDARWINOSX::EnumerateDevicesEx(info.m_deviceInfoList, force);
+  if(!info.m_deviceInfoList.empty())
+    list.push_back(info);
+
 #elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
   // check if user wants us to do something specific
   if (getenv("AE_SINK"))
index fc6a964..c871ee8 100644 (file)
@@ -425,6 +425,36 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
           }
           msg->Reply(CActiveAEControlProtocol::ACC);
           return;
+        case CActiveAEControlProtocol::DEVICECHANGE:
+          time_t now;
+          time(&now);
+          while (!m_extLastDeviceChange.empty() && (now - m_extLastDeviceChange.front() > 0))
+          {
+            m_extLastDeviceChange.pop();
+          }
+          if (m_extLastDeviceChange.size() > 2)
+          {
+            CLog::Log(LOGWARNING,"CActiveAE - received %ld device change events within one second", m_extLastDeviceChange.size());
+            return;
+          }
+          m_extLastDeviceChange.push(now);
+          UnconfigureSink();
+          m_sink.EnumerateSinkList(true);
+          LoadSettings();
+          m_extError = false;
+          Configure();
+          if (!m_extError)
+          {
+            m_state = AE_TOP_CONFIGURED_PLAY;
+            m_extTimeout = 0;
+          }
+          else
+          {
+            m_state = AE_TOP_ERROR;
+            m_extTimeout = 500;
+          }
+          m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
+          return;
         case CActiveAEControlProtocol::PAUSESTREAM:
           CActiveAEStream *stream;
           stream = *(CActiveAEStream**)msg->data;
@@ -649,7 +679,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
       break;
 
     case AE_TOP_CONFIGURED_IDLE:
-      if (port == NULL) // timeout
+      if (port == &m_controlPort)
       {
         switch (signal)
         {
@@ -667,6 +697,14 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg)
           m_state = AE_TOP_CONFIGURED_PLAY;
           m_extTimeout = 0;
           return;
+        default:
+          break;
+        }
+      }
+      else if (port == NULL) // timeout
+      {
+        switch (signal)
+        {
         case CActiveAEControlProtocol::TIMEOUT:
           ResampleSounds();
           ClearDiscardedBuffers();
@@ -922,6 +960,11 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt)
   if (m_streams.empty())
   {
     inputFormat = m_sinkFormat;
+    if (m_sinkFormat.m_channelLayout.Count() > m_sinkRequestFormat.m_channelLayout.Count())
+    {
+      inputFormat.m_channelLayout = m_sinkRequestFormat.m_channelLayout;
+      inputFormat.m_channelLayout.ResolveChannels(m_sinkFormat.m_channelLayout);
+    }
     inputFormat.m_dataFormat = AE_FMT_FLOAT;
     inputFormat.m_frameSize = inputFormat.m_channelLayout.Count() *
                               (CAEUtil::DataFormatToBits(inputFormat.m_dataFormat) >> 3);
@@ -1015,6 +1058,16 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt)
       outputFormat.m_dataFormat = AE_FMT_FLOAT;
       outputFormat.m_frameSize = outputFormat.m_channelLayout.Count() *
                                  (CAEUtil::DataFormatToBits(outputFormat.m_dataFormat) >> 3);
+
+      // due to channel ordering of the driver, a sink may return more channels than
+      // requested, i.e. 2.1 request returns FL,FR,BL,BR,FC,LFE for ALSA
+      // in this case we need to downmix to requested format
+      if (m_sinkFormat.m_channelLayout.Count() > m_sinkRequestFormat.m_channelLayout.Count())
+      {
+        outputFormat.m_channelLayout = m_sinkRequestFormat.m_channelLayout;
+        outputFormat.m_channelLayout.ResolveChannels(m_sinkFormat.m_channelLayout);
+      }
+
       // TODO: adjust to decoder
       sinkInputFormat = outputFormat;
     }
@@ -2060,7 +2113,7 @@ bool CActiveAE::Initialize()
   Message *reply;
   if (m_controlPort.SendOutMessageSync(CActiveAEControlProtocol::INIT,
                                                  &reply,
-                                                 5000))
+                                                 10000))
   {
     bool success = reply->signal == CActiveAEControlProtocol::ACC;
     reply->Release();
@@ -2123,17 +2176,9 @@ void CActiveAE::OnSettingsChange(const std::string& setting)
 
 bool CActiveAE::SupportsRaw(AEDataFormat format)
 {
-  if (!m_sink.HasPassthroughDevice())
+  if (!m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), format))
     return false;
 
-  // those formats require HDMI
-  if (format == AE_FMT_DTSHD || format == AE_FMT_TRUEHD)
-  {
-    if(m_sink.GetDeviceType(CSettings::Get().GetString("audiooutput.passthroughdevice")) != AE_DEVTYPE_HDMI)
-      return false;
-  }
-
-  // TODO: check ELD?
   return true;
 }
 
@@ -2171,16 +2216,20 @@ bool CActiveAE::IsSettingVisible(const std::string &settingId)
   }
   else if (settingId == "audiooutput.truehdpassthrough")
   {
-    if (m_sink.HasPassthroughDevice() &&
-        CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED &&
-        m_sink.GetDeviceType(CSettings::Get().GetString("audiooutput.passthroughdevice")) == AE_DEVTYPE_HDMI)
+    if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_TRUEHD) &&
+        CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
       return true;
   }
   else if (settingId == "audiooutput.dtshdpassthrough")
   {
-    if (m_sink.HasPassthroughDevice() &&
-        CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED &&
-        m_sink.GetDeviceType(CSettings::Get().GetString("audiooutput.passthroughdevice")) == AE_DEVTYPE_HDMI)
+    if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_DTSHD) &&
+        CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
+      return true;
+  }
+  else if (settingId == "audiooutput.eac3passthrough")
+  {
+    if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_EAC3) &&
+        CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
       return true;
   }
   else if (settingId == "audiooutput.stereoupmix")
@@ -2273,6 +2322,11 @@ void CActiveAE::KeepConfiguration(unsigned int millis)
   m_controlPort.SendOutMessage(CActiveAEControlProtocol::KEEPCONFIG, &timeMs, sizeof(unsigned int));
 }
 
+void CActiveAE::DeviceChange()
+{
+  m_controlPort.SendOutMessage(CActiveAEControlProtocol::DEVICECHANGE);
+}
+
 void CActiveAE::OnLostDevice()
 {
   Message *reply;
index debc8e1..225c694 100644 (file)
@@ -28,6 +28,7 @@
 #include "cores/AudioEngine/Interfaces/AESound.h"
 #include "cores/AudioEngine/AEFactory.h"
 #include "guilib/DispResource.h"
+#include <queue>
 
 // ffmpeg
 #include "DllAvFormat.h"
@@ -73,6 +74,7 @@ public:
     INIT = 0,
     RECONFIGURE,
     SUSPEND,
+    DEVICECHANGE,
     MUTE,
     VOLUME,
     PAUSESTREAM,
@@ -224,6 +226,7 @@ public:
   virtual bool SupportsQualityLevel(enum AEQuality level);
   virtual bool IsSettingVisible(const std::string &settingId);
   virtual void KeepConfiguration(unsigned int millis);
+  virtual void DeviceChange();
 
   virtual void RegisterAudioCallback(IAudioCallback* pCallback);
   virtual void UnregisterAudioCallback();
@@ -292,6 +295,7 @@ protected:
   XbmcThreads::EndTime m_extDrainTimer;
   unsigned int m_extKeepConfig;
   bool m_extDeferData;
+  std::queue<time_t> m_extLastDeviceChange;
 
   enum
   {
index 55e2ca9..679f7d6 100644 (file)
@@ -107,6 +107,33 @@ bool CActiveAESink::HasPassthroughDevice()
   return false;
 }
 
+bool CActiveAESink::SupportsFormat(const std::string &device, AEDataFormat format)
+{
+  std::string dev = device;
+  std::string dri;
+  CAESinkFactory::ParseDevice(dev, dri);
+  for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
+  {
+    if (dri == itt->m_sinkName)
+    {
+      for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
+      {
+        CAEDeviceInfo& info = *itt2;
+        if (info.m_deviceName == dev)
+        {
+          AEDataFormatList::iterator itt3;
+          itt3 = find(info.m_dataFormats.begin(), info.m_dataFormats.end(), format);
+          if (itt3 != info.m_dataFormats.end())
+            return true;
+          else
+            return false;
+        }
+      }
+    }
+  }
+  return false;
+}
+
 enum SINK_STATES
 {
   S_TOP = 0,                      // 0
@@ -520,13 +547,13 @@ void CActiveAESink::EnumerateSinkList(bool force)
   if (!m_sinkInfoList.empty() && !force)
     return;
 
-  unsigned int c_retry = 5;
+  unsigned int c_retry = 4;
   m_sinkInfoList.clear();
   CAESinkFactory::EnumerateEx(m_sinkInfoList);
   while(m_sinkInfoList.size() == 0 && c_retry > 0)
   {
     CLog::Log(LOGNOTICE, "No Devices found - retry: %d", c_retry);
-    Sleep(2000);
+    Sleep(1500);
     c_retry--;
     // retry the enumeration
     CAESinkFactory::EnumerateEx(m_sinkInfoList, true);
index d62b863..420b966 100644 (file)
@@ -97,6 +97,7 @@ public:
   void Dispose();
   AEDeviceType GetDeviceType(const std::string &device);
   bool HasPassthroughDevice();
+  bool SupportsFormat(const std::string &device, AEDataFormat format);
   CSinkControlProtocol m_controlPort;
   CSinkDataProtocol m_dataPort;
 
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.cpp
deleted file mode 100644 (file)
index 1cd49cb..0000000
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#include "CoreAudioAE.h"
-
-#include "CoreAudioAEStream.h"
-#include "CoreAudioAESound.h"
-#include "Application.h"
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "settings/AdvancedSettings.h"
-#include "settings/Settings.h"
-#include "threads/SingleLock.h"
-#include "utils/EndianSwap.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "utils/MathUtils.h"
-#include "threads/SystemClock.h"
-
-#define DELAY_FRAME_TIME  20
-#define BUFFERSIZE        16416
-
-// on darwin when the devicelist changes
-// reinit by calling opencoreaudio with the last engine parameters 
-// (this will fallback to default
-// device when our current output device vanishes
-// and on the other hand will go back to that device
-// if it re-appears).
-#if defined(TARGET_DARWIN_OSX)
-OSStatus deviceChangedCB( AudioObjectID                       inObjectID,
-                          UInt32                              inNumberAddresses,
-                          const AudioObjectPropertyAddress    inAddresses[],
-                          void*                               inClientData)
-{
-  CCoreAudioAE *pEngine = (CCoreAudioAE *)inClientData;
-  if (pEngine->GetHAL())
-  {
-    pEngine->AudioDevicesChanged();
-    CLog::Log(LOGDEBUG, "CCoreAudioAE - audiodevicelist changed!");
-  }
-  return noErr;
-}
-
-void RegisterDeviceChangedCB(bool bRegister, void *ref)
-{
-  OSStatus ret = noErr;
-  const AudioObjectPropertyAddress inAdr = 
-  {  
-    kAudioHardwarePropertyDevices,
-    kAudioObjectPropertyScopeGlobal,
-    kAudioObjectPropertyElementMaster 
-  };
-  
-  if (bRegister)
-    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-  else
-    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioAE::Deinitialize - error %s a listener callback for device changes!", bRegister?"attaching":"removing");   
-}
-#else//ios
-void RegisterDeviceChangedCB(bool bRegister, void *ref){}
-#endif
-
-CCoreAudioAE::CCoreAudioAE() :
-  m_Initialized        (false         ),
-  m_deviceLost         (false         ),
-  m_callbackRunning    (false         ),
-  m_lastStreamFormat   (AE_FMT_INVALID),
-  m_lastChLayoutCount  (0             ),
-  m_lastSampleRate     (0             ),
-  m_chLayoutCount      (0             ),
-  m_rawPassthrough     (false         ),
-  m_volume             (1.0f          ),
-  m_volumeBeforeMute   (1.0f          ),
-  m_muted              (false         ),
-  m_soundMode          (AE_SOUND_OFF  ),
-  m_streamsPlaying     (false         ),
-  m_isSuspended        (false         ),
-  m_softSuspend        (false         ),
-  m_softSuspendTimer   (0             )
-{
-  HAL = new CCoreAudioAEHAL;
-  
-  RegisterDeviceChangedCB(true, this);
-}
-
-CCoreAudioAE::~CCoreAudioAE()
-{
-  RegisterDeviceChangedCB(false, this);
-  Shutdown();
-}
-
-void CCoreAudioAE::Shutdown()
-{
-  CSingleLock engineLock(m_engineLock);
-
-  Stop();
-
-  Deinitialize();
-
-  /* free the streams */
-  CSingleLock streamLock(m_streamLock);
-  while (!m_streams.empty())
-  {
-    CCoreAudioAEStream *s = m_streams.front();
-    m_sounds.pop_front();
-    delete s;
-  }
-
-  /* free the sounds */
-  CSingleLock soundLock(m_soundLock);
-  while (!m_sounds.empty())
-  {
-    CCoreAudioAESound *s = m_sounds.front();
-    m_sounds.pop_front();
-    delete s;
-  }
-
-  delete HAL;
-  HAL = NULL;
-}
-
-void CCoreAudioAE::AudioDevicesChanged()
-{
-  if (!m_Initialized && !m_deviceLost)
-    return;
-
-  CSingleLock engineLock(m_engineLock);
-
-  // re-check initialized since it can have changed when we waited and grabbed the lock
-  if (!m_Initialized && !m_deviceLost)
-    return;
-
-  OpenCoreAudio(m_lastSampleRate, COREAUDIO_IS_RAW(m_lastStreamFormat), m_lastStreamFormat, m_transcode);
-
-  // when we tried to open the default device or the last device
-  // again there was an error preventing us from doing it (mostly
-  // the device couldn't be found) - in that case
-  // mark our device as lost and hope that another callback
-  // for changed device list fires (e.x. device reappears)
-  if (!m_Initialized)
-      m_deviceLost = true;
-  else
-      m_deviceLost = false;
-}
-
-bool CCoreAudioAE::Initialize()
-{
-  CSingleLock engineLock(m_engineLock);
-
-  Stop();
-
-  Deinitialize();
-
-  bool ret = OpenCoreAudio(44100, false, AE_FMT_FLOAT, false);
-  m_lastSampleRate = 44100;
-  m_lastStreamFormat = AE_FMT_FLOAT;
-
-  Start();
-
-  return ret;
-}
-
-bool CCoreAudioAE::OpenCoreAudio(unsigned int sampleRate, bool forceRaw,
-  enum AEDataFormat rawDataFormat, bool forceTranscode)
-{
-  unsigned int maxChannelCountInStreams = 0;
-  // remove any deleted streams
-  CSingleLock streamLock(m_streamLock);
-  for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end();)
-  {
-    CCoreAudioAEStream *stream = *itt;
-    if (stream->IsDestroyed())
-    {
-      itt = m_streams.erase(itt);
-      delete stream;
-      continue;
-    }
-    else
-    {
-      // close all converter
-      stream->CloseConverter();
-    }
-
-    if (stream->GetChannelCount() > maxChannelCountInStreams)
-        maxChannelCountInStreams = stream->GetChannelCount();
-
-    ++itt;
-  }
-
-  /* override the sample rate based on the oldest stream if there is one */
-  if (!m_streams.empty())
-    sampleRate = m_streams.front()->GetSampleRate();
-
-  if (forceRaw)
-    m_rawPassthrough = true;
-  else
-    m_rawPassthrough = !m_streams.empty() && m_streams.front()->IsRaw();
-  streamLock.Leave();
-    
-  if (m_rawPassthrough)
-    CLog::Log(LOGINFO, "CCoreAudioAE::OpenCoreAudio - RAW passthrough enabled");
-
-  m_transcode = forceTranscode;
-  
-  if (m_transcode)
-    CLog::Log(LOGINFO, "CCoreAudioAE::OpenCoreAudio - transcode to ac3 enabled");
-  
-  std::string m_outputDevice =  CSettings::Get().GetString("audiooutput.audiodevice");
-
-  // on iOS devices we set fixed to two channels.
-  m_stdChLayout = AE_CH_LAYOUT_2_0;
-#if defined(TARGET_DARWIN_OSX)
-  switch (CSettings::Get().GetInt("audiooutput.channels"))
-  {
-    default:
-    case  0: m_stdChLayout = AE_CH_LAYOUT_2_0; break; /* do not allow 1_0 output */
-    case  1: m_stdChLayout = AE_CH_LAYOUT_2_0; break;
-    case  2: m_stdChLayout = AE_CH_LAYOUT_2_1; break;
-    case  3: m_stdChLayout = AE_CH_LAYOUT_3_0; break;
-    case  4: m_stdChLayout = AE_CH_LAYOUT_3_1; break;
-    case  5: m_stdChLayout = AE_CH_LAYOUT_4_0; break;
-    case  6: m_stdChLayout = AE_CH_LAYOUT_4_1; break;
-    case  7: m_stdChLayout = AE_CH_LAYOUT_5_0; break;
-    case  8: m_stdChLayout = AE_CH_LAYOUT_5_1; break;
-    case  9: m_stdChLayout = AE_CH_LAYOUT_7_0; break;
-    case 10: m_stdChLayout = AE_CH_LAYOUT_7_1; break;
-  }
-#endif
-
-  // setup the desired format
-  m_format.m_channelLayout = CAEChannelInfo(m_stdChLayout);
-
-  // if there is an audio resample rate set, use it.
-  if (CSettings::Get().GetInt("audiooutput.config") == AE_CONFIG_FIXED && !m_rawPassthrough)
-  {
-    sampleRate = CSettings::Get().GetInt("audiooutput.samplerate");
-    CLog::Log(LOGINFO, "CCoreAudioAE::passthrough - Forcing samplerate to %d", sampleRate);
-  }
-
-  if (m_rawPassthrough && !m_transcode)
-  {
-    switch (rawDataFormat)
-    {
-      case AE_FMT_AC3:
-      case AE_FMT_DTS:
-        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0);
-        m_format.m_sampleRate   = 48000;
-        m_format.m_dataFormat   = AE_FMT_S16NE;
-        break;
-      case AE_FMT_EAC3:
-        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0);
-        m_format.m_sampleRate   = 192000;
-        m_format.m_dataFormat   = AE_FMT_S16NE;
-        break;
-      case AE_FMT_DTSHD:
-      case AE_FMT_TRUEHD:
-        m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1);
-        m_format.m_sampleRate   = 192000;
-        m_format.m_dataFormat   = AE_FMT_S16NE;
-        break;
-      case AE_FMT_LPCM:
-        // audio midi setup can be setup to 2.0 or 7.1
-        // if we have the number of max channels from streams we use that for
-        // selecting either 2.0 or 7.1 setup depending on that.
-        // This allows DPII modes on amps for enhancing stereo sound
-        // (when switching to 7.1 - all 8 channels will be pushed out preventing most amps
-        // to switch to DPII mode)
-        if (maxChannelCountInStreams == 1 || maxChannelCountInStreams == 2)
-          m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0);
-        else
-          m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1);
-        m_format.m_sampleRate   = sampleRate;
-        m_format.m_dataFormat   = AE_FMT_FLOAT;
-        break;
-      default:
-        break;
-    }
-  }
-  else if (m_transcode)
-  {
-    // transcode is to ac3 only, do we copy the ac3 settings from above
-    m_format.m_channelLayout    = CAEChannelInfo(AE_CH_LAYOUT_2_0);
-    m_format.m_sampleRate       = 48000;
-    m_format.m_dataFormat       = AE_FMT_S16NE;
-  }
-  else
-  {
-    m_format.m_sampleRate       = sampleRate;
-    m_format.m_channelLayout    = CAEChannelInfo(m_stdChLayout);
-    m_format.m_dataFormat       = AE_FMT_FLOAT;
-  }
-
-  m_format.m_encodedRate = 0;
-
-  if (m_outputDevice.empty())
-    m_outputDevice = "default";
-
-  AEAudioFormat initformat = m_format;
-
-  // initialize audio hardware
-  m_Initialized = HAL->Initialize(this, m_rawPassthrough || m_transcode, initformat, m_transcode ? AE_FMT_AC3 : rawDataFormat, m_outputDevice, m_volume);
-
-  unsigned int bps         = CAEUtil::DataFormatToBits(m_format.m_dataFormat);
-  m_chLayoutCount          = m_format.m_channelLayout.Count();
-  m_format.m_frameSize     = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize;
-  //m_format.m_frames        = (unsigned int)(((float)m_format.m_sampleRate / 1000.0f) * (float)DELAY_FRAME_TIME);
-  //m_format.m_frameSamples  = m_format.m_frames * m_format.m_channelLayout.Count();
-
-  if ((initformat.m_channelLayout.Count() != m_chLayoutCount) && !m_rawPassthrough && !m_transcode)
-  {
-    /* readjust parameters. hardware didn't accept channel count*/
-    CLog::Log(LOGINFO, "CCoreAudioAE::Initialize: Setup channels (%d) greater than possible hardware channels (%d).",
-              m_chLayoutCount, initformat.m_channelLayout.Count());
-
-    m_format.m_channelLayout = CAEChannelInfo(initformat.m_channelLayout);
-    m_chLayoutCount          = m_format.m_channelLayout.Count();
-    m_format.m_frameSize     = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize;
-    //m_format.m_frameSamples  = m_format.m_frames * m_format.m_channelLayout.Count();
-  }
-
-  CLog::Log(LOGINFO, "CCoreAudioAE::Initialize:");
-  CLog::Log(LOGINFO, "  Output Device : %s", m_outputDevice.c_str());
-  CLog::Log(LOGINFO, "  Sample Rate   : %d", m_format.m_sampleRate);
-  CLog::Log(LOGINFO, "  Sample Format : %s", CAEUtil::DataFormatToStr(m_format.m_dataFormat));
-  CLog::Log(LOGINFO, "  Channel Count : %d", m_chLayoutCount);
-  CLog::Log(LOGINFO, "  Channel Layout: %s", ((std::string)m_format.m_channelLayout).c_str());
-  CLog::Log(LOGINFO, "  Frame Size    : %d", m_format.m_frameSize);
-  CLog::Log(LOGINFO, "  Volume Level  : %f", m_volume);
-  CLog::Log(LOGINFO, "  Passthrough   : %d", m_rawPassthrough);
-  CLog::Log(LOGINFO, "  Transcode     : %d", m_transcode);
-
-  CSingleLock soundLock(m_soundLock);
-  StopAllSounds();
-
-  // re-init sounds and unlock
-  for (SoundList::iterator itt = m_sounds.begin(); itt != m_sounds.end(); ++itt)
-    (*itt)->Initialize();
-
-  soundLock.Leave();
-
-  // if we are not in m_rawPassthrough reinit the streams
-  if (!m_rawPassthrough)
-  {
-    /* re-init streams */
-    streamLock.Enter();
-    for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end(); ++itt)
-      (*itt)->Initialize();
-    streamLock.Leave();
-  }
-
-  return m_Initialized;
-}
-
-void CCoreAudioAE::Deinitialize()
-{
-  if (!m_Initialized)
-    return;
-
-  // close all open converters
-  CSingleLock streamLock(m_streamLock);
-  for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end();++itt)
-    (*itt)->CloseConverter();
-  streamLock.Leave();
-
-  m_Initialized = false;
-
-  CSingleLock callbackLock(m_callbackLock);
-
-  /*
-  while(m_callbackRunning)
-    Sleep(100);
-  */
-
-  HAL->Deinitialize();
-}
-
-void CCoreAudioAE::OnSettingsChange(const std::string& setting)
-{
-  if (setting == "audiooutput.dontnormalizelevels")
-  {
-    // re-init streams remapper
-    CSingleLock streamLock(m_streamLock);
-    for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end(); ++itt)
-      (*itt)->InitializeRemap();
-    streamLock.Leave();
-  }
-
-  if (setting == "audiooutput.passthroughdevice" ||
-      setting == "audiooutput.custompassthrough" ||
-      setting == "audiooutput.audiodevice"       ||
-      setting == "audiooutput.customdevice"      ||
-      setting == "audiooutput.ac3passthrough"    ||
-      setting == "audiooutput.eac3passthrough"   ||
-      setting == "audiooutput.dtspassthrough"    ||
-      setting == "audiooutput.channels"          ||
-      setting == "audiooutput.samplerate"        ||
-      setting == "audiooutput.config"            ||
-      setting == "audiooutput.passthrough"        )
-  {
-    // only reinit the engine if we not
-    // suspended (resume will initialize
-    // us again in that case)
-    if (!m_isSuspended)
-      Initialize();
-  }
-}
-
-unsigned int CCoreAudioAE::GetSampleRate()
-{
-  return m_format.m_sampleRate;
-}
-
-unsigned int CCoreAudioAE::GetEncodedSampleRate()
-{
-  return m_format.m_encodedRate;
-}
-
-CAEChannelInfo CCoreAudioAE::GetChannelLayout()
-{
-  return m_format.m_channelLayout;
-}
-
-unsigned int CCoreAudioAE::GetChannelCount()
-{
-  return m_chLayoutCount;
-}
-
-enum AEDataFormat CCoreAudioAE::GetDataFormat()
-{
-  return m_format.m_dataFormat;
-}
-
-AEAudioFormat CCoreAudioAE::GetAudioFormat()
-{
-  return m_format;
-}
-
-double CCoreAudioAE::GetDelay()
-{
-  return HAL->GetDelay();
-}
-
-float CCoreAudioAE::GetVolume()
-{
-  return m_volume;
-}
-
-void CCoreAudioAE::SetVolume(float volume)
-{
-  if (m_rawPassthrough)
-    return;
-
-  m_volume = volume;
-  // track volume if we are not muted
-  // we need this because m_volume is init'ed via
-  // SetVolume and need to also init m_volumeBeforeMute.
-  if (!m_muted)
-    m_volumeBeforeMute = volume;
-
-  HAL->SetVolume(m_volume);
-}
-
-void CCoreAudioAE::SetMute(const bool enabled)
-{
-  m_muted = enabled;
-  if(m_muted)
-  {
-    m_volumeBeforeMute = m_volume;
-    SetVolume(VOLUME_MINIMUM);
-  }
-  else
-  {
-    SetVolume(m_volumeBeforeMute);
-  }
-}
-
-bool CCoreAudioAE::IsMuted()
-{
-  return m_muted;
-}
-
-bool CCoreAudioAE::IsSuspended()
-{
-  return m_isSuspended;
-}
-
-void CCoreAudioAE::SetSoundMode(const int mode)
-{
-  m_soundMode = mode;
-
-  /* stop all currently playing sounds if they are being turned off */
-  if (mode == AE_SOUND_OFF || (mode == AE_SOUND_IDLE && m_streamsPlaying))
-    StopAllSounds();
-}
-
-bool CCoreAudioAE::SupportsRaw(AEDataFormat format)
-{
-  switch(format)
-  {
-    case AE_FMT_AC3:
-    case AE_FMT_DTS:
-    case AE_FMT_EAC3:
-    case AE_FMT_LPCM:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool CCoreAudioAE::IsSettingVisible(const std::string &settingId)
-{
-  if (settingId == "audiooutput.samplerate")
-  {
-    if (CSettings::Get().GetInt("audiooutput.config") == AE_CONFIG_FIXED)
-      return true;
-    else
-      return false;
-  }
-  else if (settingId == "audiooutput.stereoupmix")
-  {
-    if (CSettings::Get().GetInt("audiooutput.channels") > AE_CH_LAYOUT_2_0)
-      return true;
-  }
-
-  return true;
-}
-
-CCoreAudioAEHAL* CCoreAudioAE::GetHAL()
-{
-  return HAL;
-}
-
-IAEStream* CCoreAudioAE::MakeStream(enum AEDataFormat dataFormat,
-  unsigned int sampleRate, unsigned int encodedSamplerate, CAEChannelInfo channelLayout, unsigned int options)
-{
-  // if we are suspended we don't
-  // want anyone to mess with us
-  if (m_isSuspended && !m_softSuspend)
-#if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV)
-    Resume();
-#else
-    return NULL;
-#endif
-
-  CAEChannelInfo channelInfo(channelLayout);
-  CLog::Log(LOGINFO, "CCoreAudioAE::MakeStream - %s, %u, %u, %s",
-    CAEUtil::DataFormatToStr(dataFormat), sampleRate, encodedSamplerate, ((std::string)channelInfo).c_str());
-
-  bool multichannelpcm = CSettings::Get().GetInt("audiooutput.channels") > AE_CH_LAYOUT_2_0; //if more then 2 channels are set - assume lpcm capability
-#if defined(TARGET_DARWIN_IOS)
-  multichannelpcm = false;
-#endif
-  // determine if we need to transcode this audio
-  // when we're called, we'll either get the audio in an encoded form (COREAUDIO_IS_RAW==true)
-  // that we can passthrough based on user options, or we'll get it unencoded
-  // if it's unencoded, and is 5.1, we'll transcode it to AC3 if possible
-  bool transcode = CSettings::Get().GetBool("audiooutput.passthrough") && CSettings::Get().GetBool("audiooutput.ac3passthrough") && !multichannelpcm &&
-                   !COREAUDIO_IS_RAW(dataFormat) &&
-                  (channelInfo.Count() == 6);
-  
-  CCoreAudioAEStream *stream = new CCoreAudioAEStream(dataFormat, sampleRate, encodedSamplerate, channelLayout, options, transcode);
-  CSingleLock streamLock(m_streamLock);
-  m_streams.push_back(stream);
-  streamLock.Leave();
-
-  if ((options & AESTREAM_PAUSED) == 0)
-    Stop();
-
-  // reinit the engine if pcm format changes or always on raw format or always on transcode
-  if (m_Initialized && ( m_lastStreamFormat != dataFormat ||
-                         m_lastChLayoutCount != channelLayout.Count() ||
-                         m_lastSampleRate != sampleRate ||
-                         COREAUDIO_IS_RAW(dataFormat) ||
-                         transcode))
-  {
-    CSingleLock engineLock(m_engineLock);
-    Stop();
-    Deinitialize();
-    m_Initialized = OpenCoreAudio(sampleRate, COREAUDIO_IS_RAW(dataFormat), dataFormat, transcode);
-    m_lastStreamFormat = dataFormat;
-    m_lastChLayoutCount = channelLayout.Count();
-    m_lastSampleRate = sampleRate;
-  }
-
-  /* if the stream was not initialized, do it now */
-  if (!stream->IsValid())
-    stream->Initialize();
-
-  if ((options & AESTREAM_PAUSED) == 0)  
-    Start();
-
-  m_streamsPlaying = true;
-
-  return stream;
-}
-
-IAEStream* CCoreAudioAE::FreeStream(IAEStream *stream)
-{
-  CSingleLock streamLock(m_streamLock);
-  /* ensure the stream still exists */
-  for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end(); )
-  {
-    CCoreAudioAEStream *del = *itt;
-    if (*itt == stream)
-    {
-      itt = m_streams.erase(itt);
-      delete (CCoreAudioAEStream *)stream;
-    }
-    else if (del->IsDestroyed())
-    {
-      itt = m_streams.erase(itt);
-      delete del;
-    }
-    else
-    {
-      ++itt;
-    }
-
-  }
-  m_streamsPlaying = !m_streams.empty();
-
-  streamLock.Leave();
-
-  // When we have been in passthrough mode and are not suspended,
-  // reinit the hardware to come back to anlog out
-  if (/*m_streams.empty() || */ m_rawPassthrough && !m_isSuspended)
-  {
-    CLog::Log(LOGINFO, "CCoreAudioAE::FreeStream Reinit, no streams left" );
-    Initialize();
-  }
-
-  return NULL;
-}
-
-void CCoreAudioAE::PlaySound(IAESound *sound)
-{
-  if (m_soundMode == AE_SOUND_OFF || (m_soundMode == AE_SOUND_IDLE && m_streamsPlaying) || (m_isSuspended && !m_softSuspend))
-    return;
-
-  float *samples = ((CCoreAudioAESound*)sound)->GetSamples();
-  if (!samples && !m_Initialized)
-    return;
-
-  /* add the sound to the play list */
-  CSingleLock soundSampleLock(m_soundSampleLock);
-  SoundState ss = {
-    ((CCoreAudioAESound*)sound),
-    samples,
-    ((CCoreAudioAESound*)sound)->GetSampleCount()
-  };
-  m_playing_sounds.push_back(ss);
-}
-
-void CCoreAudioAE::StopSound(IAESound *sound)
-{
-  CSingleLock lock(m_soundSampleLock);
-  for (SoundStateList::iterator itt = m_playing_sounds.begin(); itt != m_playing_sounds.end(); )
-  {
-    if ((*itt).owner == sound)
-    {
-      (*itt).owner->ReleaseSamples();
-      itt = m_playing_sounds.erase(itt);
-    }
-    else
-      ++itt;
-  }
-}
-
-IAESound *CCoreAudioAE::MakeSound(const std::string& file)
-{
-  // we don't make sounds
-  // when suspended
-  if (m_isSuspended)
-    return NULL;
-
-  CSingleLock soundLock(m_soundLock);
-
-  // first check if we have the file cached
-  for (SoundList::iterator itt = m_sounds.begin(); itt != m_sounds.end(); ++itt)
-  {
-    if ((*itt)->GetFileName() == file)
-      return *itt;
-  }
-
-  CCoreAudioAESound *sound = new CCoreAudioAESound(file);
-  if (!sound->Initialize())
-  {
-    delete sound;
-    return NULL;
-  }
-
-  m_sounds.push_back(sound);
-  return sound;
-}
-
-void CCoreAudioAE::FreeSound(IAESound *sound)
-{
-  if (!sound)
-    return;
-
-  sound->Stop();
-  CSingleLock soundLock(m_soundLock);
-  for (SoundList::iterator itt = m_sounds.begin(); itt != m_sounds.end(); ++itt)
-    if (*itt == sound)
-    {
-      m_sounds.erase(itt);
-      break;
-    }
-
-  delete (CCoreAudioAESound*)sound;
-}
-
-void CCoreAudioAE::StopAllSounds()
-{
-  CSingleLock lock(m_soundSampleLock);
-  while (!m_playing_sounds.empty())
-  {
-    SoundState *ss = &(*m_playing_sounds.begin());
-    m_playing_sounds.pop_front();
-    ss->owner->ReleaseSamples();
-  }
-}
-
-void CCoreAudioAE::MixSounds(float *buffer, unsigned int samples)
-{
-  if (!m_Initialized)
-    return;
-
-  SoundStateList::iterator itt;
-
-  CSingleLock lock(m_soundSampleLock);
-  for (itt = m_playing_sounds.begin(); itt != m_playing_sounds.end(); )
-  {
-    SoundState *ss = &(*itt);
-
-    // no more frames, so remove it from the list
-    if (ss->sampleCount == 0)
-    {
-      ss->owner->ReleaseSamples();
-      itt = m_playing_sounds.erase(itt);
-      continue;
-    }
-
-    unsigned int mixSamples = std::min(ss->sampleCount, samples);
-    float volume = ss->owner->GetVolume();
-
-    for (unsigned int i = 0; i < mixSamples; ++i)
-      buffer[i] = (buffer[i] + (ss->samples[i] * volume));
-
-    ss->sampleCount -= mixSamples;
-    ss->samples     += mixSamples;
-
-    ++itt;
-  }
-}
-
-void CCoreAudioAE::GarbageCollect()
-{
-#if defined(TARGET_DARWIN_OSX)
-  if (CSettings::Get().GetInt("audiooutput.streamsilence") != 0)
-    return;
-  
-  if (!m_streamsPlaying && m_playing_sounds.empty())
-  {
-    if (!m_softSuspend)
-    {
-      m_softSuspend = true;
-      m_softSuspendTimer = XbmcThreads::SystemClockMillis() + 10000; //10.0 second delay for softSuspend
-    }
-  }
-  else
-  {
-    if (m_isSuspended)
-    {
-      CSingleLock engineLock(m_engineLock);
-      CLog::Log(LOGDEBUG, "CCoreAudioAE::GarbageCollect - Acquire CA HAL.");
-      Start();
-      m_isSuspended = false;
-    }
-    m_softSuspend = false;
-  }
-  
-  unsigned int curSystemClock = XbmcThreads::SystemClockMillis();
-  if (!m_isSuspended && m_softSuspend && curSystemClock > m_softSuspendTimer)
-  {
-    Suspend();// locks m_engineLock internally
-    CLog::Log(LOGDEBUG, "CCoreAudioAE::GarbageCollect - Release CA HAL.");
-  }
-#endif // TARGET_DARWIN_OSX
-}
-
-void CCoreAudioAE::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
-{
-  if (m_isSuspended && !m_softSuspend)
-    return;
-
-  HAL->EnumerateOutputDevices(devices, passthrough);
-}
-
-void CCoreAudioAE::Start()
-{
-  if (!m_Initialized)
-    return;
-
-  HAL->Start();
-}
-
-void CCoreAudioAE::Stop()
-{
-  if (!m_Initialized)
-    return;
-
-  HAL->Stop();
-}
-
-bool CCoreAudioAE::Suspend()
-{
-  CSingleLock engineLock(m_engineLock);
-  CLog::Log(LOGDEBUG, "CCoreAudioAE::Suspend - Suspending AE processing");
-  m_isSuspended = true;
-  // stop all gui sounds
-  StopAllSounds();
-  // stop the CA thread
-  Stop();
-
-  return true;
-}
-
-bool CCoreAudioAE::Resume()
-{
-  // fire up the engine again
-  bool ret = Initialize();
-  CLog::Log(LOGDEBUG, "CCoreAudioAE::Resume - Resuming AE processing");
-  m_isSuspended = false;
-
-  return ret;
-}
-
-//***********************************************************************************************
-// Rendering Methods
-//***********************************************************************************************
-OSStatus CCoreAudioAE::OnRender(AudioUnitRenderActionFlags *actionFlags,
-  const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
-  UInt32 frames = inNumberFrames;
-
-  unsigned int rSamples = frames * m_chLayoutCount;
-  int size = frames * m_format.m_frameSize;
-  //int size = frames * HAL->m_BytesPerFrame;
-
-  for (UInt32 i = 0; i < ioData->mNumberBuffers; i++)
-    bzero(ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
-
-  if (!m_Initialized)
-  {
-    m_callbackRunning = false;
-    return noErr;
-  }
-
-  CSingleLock callbackLock(m_callbackLock);
-
-  m_callbackRunning = true;
-
-  /*
-  CSingleLock streamLock(m_streamLock);
-  // Remove any destroyed stream
-  if (!m_streams.empty())
-  {
-    for(StreamList::iterator itt = m_streams.begin(); itt != m_streams.end();)
-    {
-      CCoreAudioAEStream *stream = *itt;
-
-      if (stream->IsDestroyed())
-      {
-        itt = m_streams.erase(itt);
-        delete stream;
-        continue;
-      }
-      ++itt;
-    }
-  }
-  streamLock.Leave();
-  */
-
-  // when not in passthrough output mix sounds
-  if (!m_rawPassthrough && m_soundMode != AE_SOUND_OFF)
-  {
-    MixSounds((float *)ioData->mBuffers[0].mData, rSamples);
-    ioData->mBuffers[0].mDataByteSize = size;
-    if (!size && actionFlags)
-      *actionFlags |=  kAudioUnitRenderAction_OutputIsSilence;
-  }
-
-  m_callbackRunning = false;
-
-  return noErr;
-}
-
-// Static Callback from AudioUnit
-OSStatus CCoreAudioAE::Render(AudioUnitRenderActionFlags* actionFlags,
-  const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList)
-{
-  OSStatus ret = OnRender(actionFlags, pTimeStamp, busNumber, frameCount, pBufList);
-
-  return ret;
-}
-
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAE.h
deleted file mode 100644 (file)
index 3f465c4..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 <list>
-#include <map>
-
-#include "system.h"
-
-#include "cores/AudioEngine/Interfaces/AE.h"
-#include "ICoreAudioAEHAL.h"
-#include "ICoreAudioSource.h"
-#include "CoreAudioAEStream.h"
-#include "CoreAudioAESound.h"
-#include "threads/CriticalSection.h"
-
-#if defined(TARGET_DARWIN_IOS)
-#include "CoreAudioAEHALIOS.h"
-#else
-#include "CoreAudioAEHALOSX.h"
-#endif
-
-#define COREAUDIO_IS_RAW(x) \
-(                           \
-  (x) == AE_FMT_AC3   ||    \
-  (x) == AE_FMT_DTS   ||    \
-  (x) == AE_FMT_LPCM  ||    \
-  (x) == AE_FMT_EAC3  ||    \
-  (x) == AE_FMT_DTSHD ||    \
-  (x) == AE_FMT_TRUEHD      \
-)
-
-#if defined(TARGET_DARWIN_IOS)
-# define CCoreAudioAEHAL CCoreAudioAEHALIOS
-#else
-# define CCoreAudioAEHAL CCoreAudioAEHALOSX
-#endif
-
-class CCoreAudioAEStream;
-class CCoreAudioAESound;
-class CCoreAudioAEEventThread;
-
-class CCoreAudioAE : public IAE, public ICoreAudioSource
-{
-protected:
-  friend class CAEFactory;
-  CCoreAudioAE();
-  virtual ~CCoreAudioAE();
-
-  // Give the HAL access to the engine
-  friend class CCoreAudioAEHAL;
-  CCoreAudioAEHAL  *HAL;
-
-public:
-  virtual void      Shutdown();
-
-  virtual bool      Initialize();
-  virtual void      OnSettingsChange(const std::string& setting);
-
-  virtual bool      Suspend(); /* Suspend output and de-initialize "hog-mode" sink for external players and power savings */
-  virtual bool      Resume();  /* Resume ouput and re-initialize sink after Suspend() above */
-  virtual bool      IsSuspended(); /* Returns true if in Suspend mode - used by players */
-
-  unsigned int      GetSampleRate();
-  unsigned int      GetEncodedSampleRate();
-  CAEChannelInfo    GetChannelLayout();
-  unsigned int      GetChannelCount();
-  enum AEDataFormat GetDataFormat();
-  AEAudioFormat     GetAudioFormat();
-
-  virtual double    GetDelay();
-  virtual float     GetVolume();
-  virtual void      SetVolume(float volume);
-  virtual void      SetMute(const bool enabled);
-  virtual bool      IsMuted();
-  virtual void      SetSoundMode(const int mode);
-  virtual bool      SupportsRaw(AEDataFormat format);
-  virtual bool      IsSettingVisible(const std::string &settingId);
-  virtual bool      SupportsDrain() { return true; }
-
-  CCoreAudioAEHAL*  GetHAL();
-
-  // returns a new stream for data in the specified format
-  virtual IAEStream* MakeStream(enum AEDataFormat dataFormat,
-    unsigned int sampleRate,unsigned int encodedSamplerate,
-    CAEChannelInfo channelLayout, unsigned int options = 0);
-
-  virtual IAEStream* FreeStream(IAEStream *stream);
-
-  // returns a new sound object
-  virtual IAESound* MakeSound(const std::string& file);
-  void              StopAllSounds();
-  virtual void      FreeSound(IAESound *sound);
-  virtual void      PlaySound(IAESound *sound);
-  virtual void      StopSound(IAESound *sound);
-  void              MixSounds(float *buffer, unsigned int samples);
-
-  // free's sounds that have expired
-  virtual void      GarbageCollect();
-
-  virtual void      EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
-
-  virtual OSStatus  Render(AudioUnitRenderActionFlags* actionFlags,
-    const AudioTimeStamp* pTimeStamp, UInt32 busNumber,
-    UInt32 frameCount, AudioBufferList* pBufList);
-    
-  void AudioDevicesChanged();
-
-
-private:
-  CCriticalSection  m_callbackLock;
-  CCriticalSection  m_engineLock;
-  CCriticalSection  m_streamLock;
-  CCriticalSection  m_soundLock;
-  CCriticalSection  m_soundSampleLock;
-
-  // currently playing sounds
-  typedef struct {
-    CCoreAudioAESound *owner;
-    float             *samples;
-    unsigned int      sampleCount;
-  } SoundState;
-
-  typedef std::list<CCoreAudioAEStream*> StreamList;
-  typedef std::list<CCoreAudioAESound* > SoundList;
-  typedef std::list<SoundState         > SoundStateList;
-
-  StreamList        m_streams;
-  SoundList         m_sounds;
-  SoundStateList    m_playing_sounds;
-
-  // Prevent multiple init/deinit
-  bool              m_Initialized;
-  bool              m_deviceLost;
-  bool              m_callbackRunning;
-
-  AEAudioFormat     m_format;
-  enum AEDataFormat m_lastStreamFormat;
-  unsigned int      m_lastChLayoutCount;
-  unsigned int      m_lastSampleRate;
-  unsigned int      m_chLayoutCount;
-  bool              m_rawPassthrough;
-  bool              m_transcode;
-
-  enum AEStdChLayout m_stdChLayout;
-
-  bool              OpenCoreAudio(unsigned int sampleRate, bool forceRaw, enum AEDataFormat rawDataFormat, bool forceTranscode);
-  void              Deinitialize();
-  void              Start();
-  void              Stop();
-
-  OSStatus          OnRender(AudioUnitRenderActionFlags *actionFlags,
-                      const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
-                      UInt32 inNumberFrames, AudioBufferList *ioData);
-
-  float             m_volume;
-  float             m_volumeBeforeMute;
-  bool              m_muted;
-  int               m_soundMode;
-  bool              m_streamsPlaying;
-  bool              m_isSuspended;
-  bool              m_softSuspend;
-  unsigned int      m_softSuspendTimer;
-};
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.cpp
deleted file mode 100644 (file)
index 50bd3d5..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioAEHAL.h"
-#include "CoreAudioAE.h"
-#include "utils/log.h"
-
-#include <sstream>
-
-// Helper Functions
-std::string GetError(OSStatus error)
-{
-  char buffer[128];
-  *(UInt32 *)(buffer + 1) = CFSwapInt32HostToBig(error);
-  if (isprint(buffer[1]) && isprint(buffer[2]) &&
-      isprint(buffer[3]) && isprint(buffer[4]))
-  {
-    buffer[0] = buffer[5] = '\'';
-    buffer[6] = '\0';
-  }
-  else
-  {
-    // no, format it as an integer
-    sprintf(buffer, "%d", (int)error);
-  }
-  return std::string(buffer);
-}
-
-const char* StreamDescriptionToString(AudioStreamBasicDescription desc, std::string &str)
-{
-  char fourCC[5] = {
-    (desc.mFormatID >> 24) & 0xFF,
-    (desc.mFormatID >> 16) & 0xFF,
-    (desc.mFormatID >>  8) & 0xFF,
-     desc.mFormatID        & 0xFF,
-    0
-  };
-
-  std::stringstream sstr; 
-  switch (desc.mFormatID)
-  {
-    case kAudioFormatLinearPCM:
-      sstr  << "["
-            << fourCC
-            << "] "
-            << ((desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "Mixable " )
-            << ((desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? "Non-" : "" )
-            << "Interleaved "
-            << desc.mChannelsPerFrame
-            << " Channel "
-            << desc.mBitsPerChannel
-            << "-bit "
-            << ((desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Floating Point " : "Signed Integer ")
-            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
-            << " ("
-            << (UInt32)desc.mSampleRate
-            << "Hz)";
-      str = sstr.str();
-      break;
-    case kAudioFormatAC3:
-      sstr  << "["
-            << fourCC
-            << "] "
-            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
-            << " AC-3/DTS ("
-            << (UInt32)desc.mSampleRate
-            << "Hz)";
-      str = sstr.str();                
-      break;
-    case kAudioFormat60958AC3:
-      sstr  << "["
-            << fourCC
-            << "] AC-3/DTS for S/PDIF "
-            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
-            << " ("
-            << (UInt32)desc.mSampleRate
-            << "Hz)";
-      str = sstr.str();
-      break;
-    default:
-      sstr  << "["
-            << fourCC
-            << "]";
-      break;
-  }
-  return str.c_str();
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHAL.h
deleted file mode 100644 (file)
index df2dd57..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 <string>
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/AudioToolbox.h>
-
-// Helper Functions
-std::string GetError(OSStatus error);
-const char* StreamDescriptionToString(AudioStreamBasicDescription desc, std::string &str);
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.cpp
deleted file mode 100644 (file)
index 045c1d8..0000000
+++ /dev/null
@@ -1,1342 +0,0 @@
-/*
- *      Copyright (C) 2011-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/>.
- *
- */
-
-#if defined(TARGET_DARWIN_IOS)
-#include "system.h"
-
-#include "CoreAudioAEHALIOS.h"
-
-#include "xbmc/cores/AudioEngine/Utils/AEUtil.h"
-#include "AEFactory.h"
-#include "CoreAudioAE.h"
-#include "utils/log.h"
-
-#include <math.h>
-
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
-// use the maximum frames per slice allows audio play when the screen is locked
-#define BUFFERED_FRAMES 4096
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CIOSCoreAudioHardware
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-AudioComponentInstance CIOSCoreAudioHardware::FindAudioDevice(std::string searchName)
-{
-  if (!searchName.length())
-    return 0;
-
-  AudioComponentInstance defaultDevice = GetDefaultOutputDevice();
-
-  return defaultDevice;
-}
-
-AudioComponentInstance CIOSCoreAudioHardware::GetDefaultOutputDevice()
-{
-  AudioComponentInstance ret = (AudioComponentInstance)1;
-
-  return ret;
-}
-
-UInt32 CIOSCoreAudioHardware::GetOutputDevices(IOSCoreAudioDeviceList* pList)
-{
-  if (!pList)
-    return 0;
-
-  return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CCoreAudioUnit
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoreAudioUnit::CCoreAudioUnit() :
-m_pSource         (NULL         ),
-m_audioUnit       (NULL         ),
-m_audioNode       (NULL         ),
-m_audioGraph      (NULL         ),
-m_Initialized     (false        ),
-m_renderProc      (NULL         ),
-m_busNumber       (INVALID_BUS  )
-{
-}
-
-CCoreAudioUnit::~CCoreAudioUnit()
-{
-  Close();
-}
-
-bool CCoreAudioUnit::Open(AUGraph audioGraph, AudioComponentDescription desc)
-{
-  if (m_audioUnit)
-    Close();
-
-  OSStatus ret;
-
-  m_Initialized = false;
-
-  ret = AUGraphAddNode(audioGraph, &desc, &m_audioNode);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error add m_outputNode. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  ret = AUGraphNodeInfo(audioGraph, m_audioNode, NULL, &m_audioUnit);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error getting m_outputNode. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_audioGraph  = audioGraph;
-  m_Initialized = true;
-
-  Start();
-
-  return true;
-}
-
-bool CCoreAudioUnit::Open(AUGraph audioGraph, OSType type, OSType subType, OSType manufacturer)
-{
-  AudioComponentDescription desc;
-  desc.componentType = type;
-  desc.componentSubType = subType;
-  desc.componentManufacturer = manufacturer;
-  desc.componentFlags = 0;
-  desc.componentFlagsMask = 0;
-  return Open(audioGraph, desc);
-}
-
-void CCoreAudioUnit::Close()
-{
-  if (!m_Initialized && !m_audioUnit)
-    return;
-
-  if (m_renderProc)
-    SetInputSource(NULL);
-
-  Stop();
-
-  if (m_busNumber != INVALID_BUS)
-  {
-    OSStatus ret = AUGraphDisconnectNodeInput(m_audioGraph, m_audioNode, m_busNumber);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioUnit::Close: Unable to disconnect AudioUnit. Error = %s", GetError(ret).c_str());
-    }
-
-    ret = AUGraphRemoveNode(m_audioGraph, m_audioNode);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioUnit::Close: Unable to disconnect AudioUnit. Error = %s", GetError(ret).c_str());
-    }
-  }
-
-  AUGraphUpdate(m_audioGraph, NULL);
-
-  m_Initialized = false;
-  m_audioUnit = NULL;
-  m_audioNode = NULL;
-  m_pSource = NULL;
-}
-
-bool CCoreAudioUnit::GetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus)
-{
-  if (!m_audioUnit || !pDesc)
-    return false;
-
-  UInt32 size = sizeof(AudioStreamBasicDescription);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope, bus, pDesc, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetFormat: Unable to get AudioUnit format. Bus : %d Scope : %d : Error = %s", (int)scope, (int)bus, GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::SetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus)
-{
-  if (!m_audioUnit || !pDesc)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope, bus, pDesc, sizeof(AudioStreamBasicDescription));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetFormat: Unable to set AudioUnit format. Bus : %d Scope : %d : Error = %s", (int)scope, (int)bus, GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::SetMaxFramesPerSlice(UInt32 maxFrames)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFrames, sizeof(UInt32));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetMaxFramesPerSlice: Unable to set AudioUnit max frames per slice. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::SetInputSource(ICoreAudioSource* pSource)
-{
-  m_pSource = pSource;
-  if (pSource)
-    return SetRenderProc();
-  else
-    return RemoveRenderProc();
-}
-
-bool CCoreAudioUnit::SetRenderProc()
-{
-  if (!m_audioUnit || m_renderProc)
-    return false;
-
-  AURenderCallbackStruct callbackInfo;
-  callbackInfo.inputProc = RenderCallback; // Function to be called each time the AudioUnit needs data
-  callbackInfo.inputProcRefCon = this; // Pointer to be returned in the callback proc
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback,
-                                      kAudioUnitScope_Input, 0, &callbackInfo, sizeof(AURenderCallbackStruct));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetRenderProc: Unable to set AudioUnit render callback. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_renderProc = RenderCallback;
-
-  return true;
-}
-
-bool CCoreAudioUnit::RemoveRenderProc()
-{
-  if (!m_audioUnit || !m_renderProc)
-    return false;
-
-
-  AURenderCallbackStruct callbackInfo;
-  callbackInfo.inputProc = nil;
-  callbackInfo.inputProcRefCon = nil;
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback,
-                                      kAudioUnitScope_Input, 0, &callbackInfo, sizeof(AURenderCallbackStruct));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::RemoveRenderProc: Unable to remove AudioUnit render callback. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_renderProc = NULL;
-
-  Sleep(100);
-
-  return true;
-}
-
-OSStatus CCoreAudioUnit::RenderCallback(void *inRefCon,
-                                        AudioUnitRenderActionFlags *ioActionFlags,
-                                        const AudioTimeStamp *inTimeStamp,
-                                        UInt32 inBusNumber,
-                                        UInt32 inNumberFrames,
-                                        AudioBufferList *ioData)
-{
-  OSStatus ret = noErr;
-  CCoreAudioUnit *audioUnit = (CCoreAudioUnit*)inRefCon;
-
-  if (audioUnit->m_pSource)
-  {
-    ret = audioUnit->m_pSource->Render(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
-  }
-  else
-  {
-    ioData->mBuffers[0].mDataByteSize = 0;
-    if (ioActionFlags)
-      *ioActionFlags |=  kAudioUnitRenderAction_OutputIsSilence;
-  }
-
-
-  return ret;
-}
-
-void CCoreAudioUnit::GetFormatDesc(AEAudioFormat format,
-                                   AudioStreamBasicDescription *streamDesc)
-{
-  unsigned int bps = CAEUtil::DataFormatToBits(format.m_dataFormat);
-
-  // Set the input stream format for the AudioUnit
-  // We use the default DefaultOuput AudioUnit, so we only can set the input stream format.
-  // The autput format is automaticaly set to the input format.
-  streamDesc->mFormatID = kAudioFormatLinearPCM;            //  Data encoding format
-  streamDesc->mFormatFlags = kLinearPCMFormatFlagIsPacked;
-  switch (format.m_dataFormat)
-  {
-    case AE_FMT_FLOAT:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsFloat;
-      break;
-    case AE_FMT_S16NE:
-    case AE_FMT_AC3:
-    case AE_FMT_DTS:
-    case AE_FMT_DTSHD:
-    case AE_FMT_TRUEHD:
-    case AE_FMT_EAC3:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      break;
-    case AE_FMT_S16LE:
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      break;
-    case AE_FMT_S16BE:
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsBigEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      break;
-    default:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      break;
-  }
-  streamDesc->mChannelsPerFrame = format.m_channelLayout.Count();               // Number of interleaved audiochannels
-  streamDesc->mSampleRate = (Float64)format.m_sampleRate;                       //  the sample rate of the audio stream
-  streamDesc->mBitsPerChannel = bps;                                            // Number of bits per sample, per channel
-  streamDesc->mBytesPerFrame = (bps>>3) * format.m_channelLayout.Count();       // Size of a frame == 1 sample per channel
-  streamDesc->mFramesPerPacket = 1;                                             // The smallest amount of indivisible data. Always 1 for uncompressed audio
-  streamDesc->mBytesPerPacket = streamDesc->mBytesPerFrame * streamDesc->mFramesPerPacket;
-  streamDesc->mReserved = 0;
-}
-
-float CCoreAudioUnit::GetLatency()
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  //kAudioSessionProperty_CurrentHardwareIOBufferDuration
-  //kAudioSessionProperty_CurrentHardwareOutputLatency
-
-  Float32 preferredBufferSize = 0.0f;
-  UInt32 size = sizeof(preferredBufferSize);
-  AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputLatency, &size, &preferredBufferSize);
-  return preferredBufferSize;
-}
-
-bool CCoreAudioUnit::SetSampleRate(Float64 sampleRate, AudioUnitScope scope, AudioUnitElement bus)
-{
-  if (!m_audioUnit)
-    return false;
-
-  UInt32 size = sizeof(Float64);
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SampleRate, scope, bus, &sampleRate, size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetSampleRate: Unable to set AudioUnit format. Bus : %d Scope : %d : Error = %s", (int)scope, (int)bus, GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::Stop()
-{
-  if (!m_audioUnit)
-    return false;
-
-  AudioOutputUnitStop(m_audioUnit);
-
-  return true;
-}
-
-bool CCoreAudioUnit::Start()
-{
-  if (!m_audioUnit)
-    return false;
-
-  AudioOutputUnitStart(m_audioUnit);
-
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CAUOutputDevice
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CAUOutputDevice::CAUOutputDevice()
-{
-}
-
-CAUOutputDevice::~CAUOutputDevice()
-{
-}
-
-/*
-Float32 CAUOutputDevice::GetCurrentVolume()
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float32 volPct = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit,  kHALOutputParam_Volume, kAudioUnitScope_Global, 0, &volPct);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetCurrentVolume: Unable to get AudioUnit volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return volPct;
-}
-
-bool CAUOutputDevice::SetCurrentVolume(Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit, kHALOutputParam_Volume,
-                                       kAudioUnitScope_Global, 0, vol, 0);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetCurrentVolume: Unable to set AudioUnit volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-*/
-
-UInt32 CAUOutputDevice::GetBufferFrameSize()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  return BUFFERED_FRAMES;
-}
-
-bool CAUOutputDevice::EnableInputOuput()
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret;
-  UInt32 enable;
-  UInt32 hasio;
-  UInt32 size=sizeof(UInt32);
-
-  ret = AudioUnitGetProperty(m_audioUnit,kAudioOutputUnitProperty_HasIO,kAudioUnitScope_Input, 1, &hasio, &size);
-
-  if (hasio)
-  {
-    enable = 1;
-    ret =  AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &enable, sizeof(enable));
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CAUOutputDevice::EnableInputOuput:: Unable to enable input on bus 1. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-
-    enable = 1;
-    ret = AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &enable, sizeof(enable));
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CAUOutputDevice::EnableInputOuput:: Unable to disable output on bus 0. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-  }
-
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CAUMultiChannelMixer
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CAUMultiChannelMixer::CAUMultiChannelMixer()
-{
-}
-
-CAUMultiChannelMixer::~CAUMultiChannelMixer()
-{
-
-}
-
-UInt32 CAUMultiChannelMixer::GetInputBusCount()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  UInt32 busCount = 0;
-  UInt32 size = sizeof(busCount);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &busCount, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::GetInputBusCount: Unable to get input bus count. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-  return busCount;
-}
-
-bool CAUMultiChannelMixer::SetInputBusFormat(UInt32 busCount, AudioStreamBasicDescription *pFormat)
-{
-  if (!m_audioUnit)
-    return false;
-
-  for (UInt32 i = 0; i < busCount; i++)
-  {
-    if (!SetFormat(pFormat, kAudioUnitScope_Input, i))
-      return false;
-  }
-
-  return true;
-}
-
-bool CAUMultiChannelMixer::SetInputBusCount(UInt32 busCount)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &busCount, sizeof(UInt32));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::SetInputBusCount: Unable to set input bus count. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-UInt32 CAUMultiChannelMixer::GetOutputBusCount()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  UInt32 busCount = 0;
-  UInt32 size = sizeof(busCount);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Output, 0, &busCount, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::GetOutputBusCount: Unable to get output bus count. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-  return busCount;
-}
-
-bool CAUMultiChannelMixer::SetOutputBusCount(UInt32 busCount)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Output, 0, &busCount, sizeof(UInt32));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::SetOutputBusCount: Unable to set output bus count. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-Float32 CAUMultiChannelMixer::GetCurrentVolume()
-{
-
-  if (!m_audioUnit)
-    return false;
-
-  Float32 volPct = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, kInputBus, &volPct);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::GetCurrentVolume: Unable to get Mixer volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return volPct;
-
-}
-
-bool CAUMultiChannelMixer::SetCurrentVolume(Float32 vol)
-{
-
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Output, kOutputBus, vol, 0);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMultiChannelMixer::SetCurrentVolume: Unable to set Mixer volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CCoreAudioGraph
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoreAudioGraph::CCoreAudioGraph() :
-m_audioGraph    (NULL ),
-m_audioUnit     (NULL ),
-m_mixerUnit     (NULL ),
-m_inputUnit     (NULL ),
-m_initialized   (false),
-m_allowMixing   (false)
-{
-  for (int i = 0; i < MAX_CONNECTION_LIMIT; i++)
-  {
-    m_reservedBusNumber[i] = false;
-  }
-}
-
-CCoreAudioGraph::~CCoreAudioGraph()
-{
-  Close();
-}
-
-bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing, float initVolume)
-{
-  OSStatus ret;
-
-  AudioStreamBasicDescription inputFormat;
-  AudioStreamBasicDescription outputFormat;
-
-  m_allowMixing   = allowMixing;
-
-  ret = NewAUGraph(&m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error create audio grpah. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  ret = AUGraphOpen(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error open audio grpah. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  // get output unit
-  if (m_audioUnit)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error audio unit already open. double call ?");
-    return false;
-  }
-
-  m_audioUnit = new CAUOutputDevice();
-  if (!m_audioUnit->Open(m_audioGraph, kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple))
-    return false;
-
-  UInt32 bufferFrames = m_audioUnit->GetBufferFrameSize();
-
-  if (!m_audioUnit->EnableInputOuput())
-    return false;
-
-  m_audioUnit->SetMaxFramesPerSlice(bufferFrames);
-
-  m_audioUnit->GetFormatDesc(format, &inputFormat);
-
-  //if(!allowMixing)
-  //{
-    if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus))
-      return false;
-
-    if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Output, kInputBus))
-      return false;
-  //}
-
-  if (allowMixing)
-  {
-    // get mixer unit
-    if (m_mixerUnit)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?");
-      return false;
-    }
-
-    m_mixerUnit = new CAUMultiChannelMixer();
-
-    if (!m_mixerUnit->Open(m_audioGraph, kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple))
-      return false;
-
-    m_mixerUnit->SetMaxFramesPerSlice(bufferFrames);
-
-    // set number of input buses
-    if (!m_mixerUnit->SetInputBusCount(MAX_CONNECTION_LIMIT))
-      return false;
-
-    //if(!m_mixerUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus))
-    //  return false;
-
-    m_mixerUnit->SetBus(0);
-
-    if (!m_audioUnit->GetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus))
-      return false;
-
-    /*
-    if(!m_mixerUnit->SetInputBusFormat(MAX_CONNECTION_LIMIT, &outputFormat))
-      return false;
-    */
-
-    ret =  AUGraphConnectNodeInput(m_audioGraph, m_mixerUnit->GetNode(), 0, m_audioUnit->GetNode(), 0);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error connecting m_m_mixerNode. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-
-    // get output unit
-    if (m_inputUnit)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?");
-      return false;
-    }
-
-    m_inputUnit = new CAUOutputDevice();
-
-    if (!m_inputUnit->Open(m_audioGraph, kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple))
-      return false;
-
-    m_inputUnit->SetMaxFramesPerSlice(bufferFrames);
-
-    if (!m_inputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus))
-      return false;
-
-    /*
-    if(!m_inputUnit->SetFormat(&outputFormat, kAudioUnitScope_Output, kOutputBus))
-      return false;
-    */
-
-    // configure output unit
-    int busNumber = GetFreeBus();
-
-    ret = AUGraphConnectNodeInput(m_audioGraph, m_inputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error connecting m_converterNode. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-
-    m_inputUnit->SetBus(busNumber);
-
-    ret = AUGraphUpdate(m_audioGraph, NULL);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error update graph. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-    ret = AUGraphInitialize(m_audioGraph);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error initialize graph. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-
-    // Regenerate audio format and copy format for the Output AU
-  }
-
-  ret = AUGraphUpdate(m_audioGraph, NULL);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error update graph. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  std::string formatString;
-  AudioStreamBasicDescription inputDesc_end, outputDesc_end;
-  m_audioUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-  m_audioUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kInputBus);
-  CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format  %s", StreamDescriptionToString(inputDesc_end, formatString));
-  CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString));
-
-  if (m_mixerUnit)
-  {
-    m_mixerUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-    m_mixerUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus);
-    CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format  %s", StreamDescriptionToString(inputDesc_end, formatString));
-    CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString));
-  }
-
-  if (m_inputUnit)
-  {
-    m_inputUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-    m_inputUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus);
-    CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format  %s", StreamDescriptionToString(inputDesc_end, formatString));
-    CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString));
-  }
-
-  ret = AUGraphInitialize(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error initialize graph. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  SetCurrentVolume(initVolume);
-
-  SetInputSource(pSource);
-
-  ShowGraph();
-
-  return Start();
-}
-
-bool CCoreAudioGraph::Close()
-{
-  if (!m_audioGraph)
-    return false;
-
-  OSStatus ret;
-
-  Stop();
-
-  SetInputSource(NULL);
-
-  while (!m_auUnitList.empty())
-  {
-    CAUOutputDevice *d = m_auUnitList.front();
-    m_auUnitList.pop_front();
-    ReleaseBus(d->GetBus());
-    d->Close();
-    delete d;
-  }
-
-  if (m_inputUnit)
-  {
-    ReleaseBus(m_inputUnit->GetBus());
-    m_inputUnit->Close();
-    delete m_inputUnit;
-    m_inputUnit = NULL;
-  }
-
-  if (m_mixerUnit)
-  {
-    m_mixerUnit->Close();
-    delete m_mixerUnit;
-    m_mixerUnit = NULL;
-  }
-
-  if (m_audioUnit)
-  {
-    m_audioUnit->Close();
-    delete m_audioUnit;
-    m_audioUnit = NULL;
-  }
-
-  ret = AUGraphUninitialize(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error unitialize. Error = %s", GetError(ret).c_str());
-  }
-
-  ret = AUGraphClose(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error close. Error = %s", GetError(ret).c_str());
-  }
-
-  ret = DisposeAUGraph(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error dispose. Error = %s", GetError(ret).c_str());
-  }
-
-  return true;
-}
-
-bool CCoreAudioGraph::Start()
-{
-  if (!m_audioGraph)
-    return false;
-
-  OSStatus ret;
-  Boolean isRunning = false;
-
-  ret = AUGraphIsRunning(m_audioGraph, &isRunning);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Start: Audio graph not running. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  if (!isRunning)
-  {
-
-    if (m_audioUnit)
-      m_audioUnit->Start();
-    if (m_mixerUnit)
-      m_mixerUnit->Start();
-    if (m_inputUnit)
-      m_inputUnit->Start();
-
-    ret = AUGraphStart(m_audioGraph);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Start: Error starting audio graph. Error = %s", GetError(ret).c_str());
-    }
-    ShowGraph();
-  }
-
-  return true;
-}
-
-bool CCoreAudioGraph::Stop()
-{
-  if (!m_audioGraph)
-    return false;
-
-  OSStatus ret;
-  Boolean isRunning = false;
-
-  ret = AUGraphIsRunning(m_audioGraph, &isRunning);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Stop: Audio graph not running. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  if (isRunning)
-  {
-
-    if (m_inputUnit)
-      m_inputUnit->Stop();
-    if (m_mixerUnit)
-      m_mixerUnit->Stop();
-    if (m_audioUnit)
-      m_audioUnit->Stop();
-
-    ret = AUGraphStop(m_audioGraph);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Stop: Error stopping audio graph. Error = %s", GetError(ret).c_str());
-    }
-  }
-
-  return true;
-}
-
-bool CCoreAudioGraph::SetInputSource(ICoreAudioSource* pSource)
-{
-  if (m_inputUnit)
-    return m_inputUnit->SetInputSource(pSource);
-  else if (m_audioUnit)
-    return m_audioUnit->SetInputSource(pSource);
-
-  return false;
-}
-
-bool CCoreAudioGraph::SetCurrentVolume(Float32 vol)
-{
-  if (!m_mixerUnit)
-    return false;
-
-  return m_mixerUnit->SetCurrentVolume(vol);
-}
-
-CAUOutputDevice *CCoreAudioGraph::DestroyUnit(CAUOutputDevice *outputUnit)
-{
-  if (!outputUnit)
-    return NULL;
-
-  Stop();
-
-  for (AUUnitList::iterator itt = m_auUnitList.begin(); itt != m_auUnitList.end(); ++itt)
-    if (*itt == outputUnit)
-    {
-      m_auUnitList.erase(itt);
-      break;
-    }
-
-  ReleaseBus(outputUnit->GetBus());
-  outputUnit->Close();
-  delete outputUnit;
-
-  AUGraphUpdate(m_audioGraph, NULL);
-
-  printf("Remove unit\n\n");
-  ShowGraph();
-  printf("\n");
-
-  Start();
-
-  return NULL;
-}
-
-CAUOutputDevice *CCoreAudioGraph::CreateUnit(AEAudioFormat &format)
-{
-  if (!m_audioUnit || !m_mixerUnit)
-    return NULL;
-
-  std::string formatString;
-  AudioStreamBasicDescription inputFormat;
-  AudioStreamBasicDescription outputFormat;
-
-  OSStatus ret;
-
-  int busNumber = GetFreeBus();
-  if (busNumber == INVALID_BUS)
-    return  NULL;
-
-  // create output unit
-  CAUOutputDevice *outputUnit = new CAUOutputDevice();
-  if (!outputUnit->Open(m_audioGraph, kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple))
-    goto error;
-  
-  outputUnit->SetMaxFramesPerSlice(m_audioUnit->GetBufferFrameSize());
-
-  m_audioUnit->GetFormatDesc(format, &inputFormat);
-
-  // get the format frm the mixer
-  if (!m_mixerUnit->GetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus))
-    goto error;
-
-  if (!outputUnit->SetFormat(&outputFormat, kAudioUnitScope_Output, kOutputBus))
-    goto error;
-
-  if (!outputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus))
-    goto error;
-
-  ret = AUGraphConnectNodeInput(m_audioGraph, outputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::CreateUnit: Error connecting outputUnit. Error = %s", GetError(ret).c_str());
-    goto error;
-  }
-
-  // TODO: setup mixmap, get free bus number for connection
-
-  outputUnit->SetBus(busNumber);
-
-  AUGraphUpdate(m_audioGraph, NULL);
-
-  printf("Add unit\n\n");
-  ShowGraph();
-  printf("\n");
-
-  CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format  %s", StreamDescriptionToString(inputFormat, formatString));
-  CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputFormat, formatString));
-
-  m_auUnitList.push_back(outputUnit);
-
-  return outputUnit;
-
-error:
-  delete outputUnit;
-  return NULL;
-}
-
-int CCoreAudioGraph::GetFreeBus()
-{
-  for (int i = 0; i < MAX_CONNECTION_LIMIT; i++)
-  {
-    if (!m_reservedBusNumber[i])
-    {
-      m_reservedBusNumber[i] = true;
-      return i;
-    }
-  }
-  return INVALID_BUS;
-}
-
-void CCoreAudioGraph::ReleaseBus(int busNumber)
-{
-  if (busNumber > MAX_CONNECTION_LIMIT || busNumber < 0)
-    return;
-
-  m_reservedBusNumber[busNumber] = false;
-}
-
-bool CCoreAudioGraph::IsBusFree(int busNumber)
-{
-  if (busNumber > MAX_CONNECTION_LIMIT || busNumber < 0)
-    return false;
-  return m_reservedBusNumber[busNumber];
-}
-
-int CCoreAudioGraph::GetMixerChannelOffset(int busNumber)
-{
-  if (!m_mixerUnit)
-    return 0;
-
-  int offset = 0;
-  AudioStreamBasicDescription fmt;
-
-  for (int i = 0; i < busNumber; i++)
-  {
-    memset(&fmt, 0x0, sizeof(fmt));
-    m_mixerUnit->GetFormat(&fmt, kAudioUnitScope_Input, busNumber);
-    offset += fmt.mChannelsPerFrame;
-  }
-  return offset;
-}
-
-void CCoreAudioGraph::ShowGraph()
-{
-  CAShow(m_audioGraph);
-}
-
-float CCoreAudioGraph::GetLatency()
-{
-  float delay = 0.0f;
-
-  if (m_audioUnit)
-    delay += m_audioUnit->GetLatency();
-
-  return delay;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CCoreAudioAEHALIOS
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoreAudioAEHALIOS::CCoreAudioAEHALIOS() :
-m_audioGraph        (NULL   ),
-m_Initialized       (false  ),
-m_Passthrough       (false  ),
-m_allowMixing       (false  ),
-m_encoded           (false  ),
-m_initVolume        (1.0f   ),
-m_NumLatencyFrames  (0      ),
-m_OutputBufferIndex (0      ),
-m_ae                (NULL   )
-{
-}
-
-CCoreAudioAEHALIOS::~CCoreAudioAEHALIOS()
-{
-  Deinitialize();
-
-  delete m_audioGraph;
-}
-
-bool CCoreAudioAEHALIOS::InitializePCM(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing)
-{
-
-  if (m_audioGraph)
-  {
-    m_audioGraph->Close();
-    delete m_audioGraph;
-  }
-  m_audioGraph = new CCoreAudioGraph();
-
-  if (!m_audioGraph)
-    return false;
-
-  if (!m_audioGraph->Open(pSource, format, allowMixing, m_initVolume))
-  {
-    CLog::Log(LOGERROR, "CCoreAudioAEHALIOS::Initialize: Unable to initialize audio due a missconfiguration. Try 2.0 speaker configuration.");
-    return false;
-  }
-
-  m_NumLatencyFrames = 0;
-
-  m_allowMixing = allowMixing;
-
-  return true;
-}
-
-bool CCoreAudioAEHALIOS::InitializePCMEncoded(ICoreAudioSource *pSource, AEAudioFormat &format)
-{
-  if (!InitializePCM(pSource, format, false))
-    return false;
-
-  return true;
-}
-
-bool CCoreAudioAEHALIOS::Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device, float initVolume)
-{
-  m_ae = (CCoreAudioAE *)ae;
-
-  if (!m_ae)
-    return false;
-
-  m_initformat          = format;
-  m_Passthrough         = passThrough;
-  m_encoded             = false;
-  m_OutputBufferIndex   = 0;
-  m_rawDataFormat       = rawDataFormat;
-  m_initVolume          = initVolume;
-
-  if (format.m_channelLayout.Count() == 0)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioAEHALIOS::Initialize - Unable to open the requested channel layout");
-    return false;
-  }
-
-  if (device.find("CoreAudio:"))
-    device.erase(0, strlen("CoreAudio:"));
-
-  // If this is a passthrough (AC3/DTS) stream, attempt to handle it natively
-  if (m_Passthrough)
-  {
-    m_encoded = false;
-  }
-
-  // If this is a PCM stream, or we failed to handle a passthrough stream natively,
-  // prepare the standard interleaved PCM interface
-  if (!m_encoded)
-  {
-    // If we are here and this is a passthrough stream, native handling failed.
-    // Try to handle it as IEC61937 data over straight PCM (DD-Wav)
-    bool configured = false;
-    if (m_Passthrough)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioAEHALIOS::Initialize: No suitable AC3 output format found. Attempting DD-Wav.");
-      configured = InitializePCMEncoded(ae, format);
-    }
-    else
-    {
-      // Standard PCM data
-      configured = InitializePCM(ae, format, true);
-    }
-
-    if (!configured) // No suitable output format was able to be configured
-      return false;
-  }
-
-  if (m_audioGraph)
-    m_audioGraph->ShowGraph();
-
-  m_Initialized = true;
-
-  return true;
-}
-
-CAUOutputDevice *CCoreAudioAEHALIOS::DestroyUnit(CAUOutputDevice *outputUnit)
-{
-  if (m_audioGraph && outputUnit)
-    return m_audioGraph->DestroyUnit(outputUnit);
-
-  return NULL;
-}
-
-CAUOutputDevice *CCoreAudioAEHALIOS::CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format)
-{
-  CAUOutputDevice *outputUnit = NULL;
-
-  // when HAL is using a mixer, the input is routed through converter units.
-  // therefore we create a converter unit attach the source and give it back.
-  if (m_allowMixing && m_audioGraph)
-  {
-    outputUnit = m_audioGraph->CreateUnit(format);
-
-    if (pSource && outputUnit)
-      outputUnit->SetInputSource(pSource);
-  }
-
-  return outputUnit;
-}
-
-void CCoreAudioAEHALIOS::Deinitialize()
-{
-  if (!m_Initialized)
-    return;
-
-  Stop();
-
-  //if (m_encoded)
-
-  if (m_audioGraph)
-    m_audioGraph->SetInputSource(NULL);
-
-  if (m_audioGraph)
-  {
-    //m_audioGraph->Close();
-    delete m_audioGraph;
-  }
-  m_audioGraph = NULL;
-
-  m_NumLatencyFrames = 0;
-  m_OutputBufferIndex = 0;
-
-  m_Initialized = false;
-  m_Passthrough = false;
-}
-
-void CCoreAudioAEHALIOS::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
-{
-  IOSCoreAudioDeviceList deviceList;
-  CIOSCoreAudioHardware::GetOutputDevices(&deviceList);
-
-  // Add default output device if GetOutputDevices return nothing
-  devices.push_back(AEDevice("Default", "IOSCoreAudio:default"));
-
-  std::string deviceName;
-  for (int i = 0; !deviceList.empty(); i++)
-  {
-    std::string deviceName_Internal = std::string("IOSCoreAudio:") + deviceName;
-    devices.push_back(AEDevice(deviceName, deviceName_Internal));
-
-    deviceList.pop_front();
-
-  }
-}
-
-void CCoreAudioAEHALIOS::Stop()
-{
-  if (!m_Initialized)
-    return;
-
-  m_audioGraph->Stop();
-}
-
-bool CCoreAudioAEHALIOS::Start()
-{
-  if (!m_Initialized)
-    return false;
-
-  m_audioGraph->Start();
-
-  return true;
-}
-
-void CCoreAudioAEHALIOS::SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format)
-{
-  if (!m_Initialized)
-    return;
-
-  // when HAL is initialized encoded we use directIO
-  // when HAL is not in encoded mode and there is no mixer attach source the audio unit
-  // when mixing is allowed in HAL, HAL is working with converter units where we attach the source.
-
-  if (!m_encoded && !m_allowMixing)
-  {
-    // register render callback for the audio unit
-    m_audioGraph->SetInputSource(pSource);
-  }
-
-  if (m_audioGraph)
-    m_audioGraph->ShowGraph();
-
-}
-
-double CCoreAudioAEHALIOS::GetDelay()
-{
-  /*
-  float delay;
-
-  delay = (float)(m_NumLatencyFrames) / (m_initformat.m_sampleRate);
-
-  return delay;
-  */
-
-  return (double)(BUFFERED_FRAMES) / (double)(m_initformat.m_sampleRate);
-}
-
-void  CCoreAudioAEHALIOS::SetVolume(float volume)
-{
-  if (!m_encoded)
-    m_audioGraph->SetCurrentVolume(volume);
-}
-
-unsigned int CCoreAudioAEHALIOS::GetBufferIndex()
-{
-  return m_OutputBufferIndex;
-}
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALIOS.h
deleted file mode 100644 (file)
index 3e39fb4..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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/>.
- *
- */
-
-#if defined(TARGET_DARWIN_IOS)
-
-#include <list>
-#include <vector>
-
-#include "ICoreAudioAEHAL.h"
-#include "CoreAudioAEHAL.h"
-#include "utils/StdString.h"
-
-#include <AudioUnit/AudioUnit.h>
-#include <AudioUnit/AudioUnitProperties.h>
-#include <AudioToolbox/AudioToolbox.h>
-#include <AudioToolbox/AudioServices.h>
-#include <CoreAudio/CoreAudioTypes.h>
-
-#define kOutputBus 0
-#define kInputBus 1
-#define MAX_CONNECTION_LIMIT  8
-#define INVALID_BUS -1
-
-// Forward declarations
-class CCoreAudioAE;
-class CIOSCoreAudioConverter;
-
-typedef std::list<AudioComponentInstance> IOSCoreAudioDeviceList;
-
-// There is only one AudioSystemObject instance system-side.
-// Therefore, all CIOSCoreAudioHardware methods are static
-class CIOSCoreAudioHardware
-{
-public:
-  static AudioComponentInstance FindAudioDevice(std::string deviceName);
-  static AudioComponentInstance GetDefaultOutputDevice();
-  static UInt32 GetOutputDevices(IOSCoreAudioDeviceList* pList);
-};
-
-class CCoreAudioUnit
-{
-public:
-  CCoreAudioUnit();
-  virtual ~CCoreAudioUnit();
-
-  virtual bool Open(AUGraph audioGraph, AudioComponentDescription desc);
-  virtual bool Open(AUGraph audioGraph, OSType type, OSType subType, OSType manufacturer);
-  virtual void Close();
-  virtual bool SetInputSource(ICoreAudioSource* pSource);
-  virtual bool IsInitialized() {return m_Initialized;}
-  virtual bool GetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus);
-  virtual bool SetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus);
-  virtual bool SetMaxFramesPerSlice(UInt32 maxFrames);
-  virtual void GetFormatDesc(AEAudioFormat format, AudioStreamBasicDescription *streamDesc);
-  virtual float GetLatency();
-  virtual bool SetSampleRate(Float64 sampleRate, AudioUnitScope scope, AudioUnitElement bus);
-  virtual bool Stop();
-  virtual bool Start();
-  virtual AudioUnit   GetUnit  (){return m_audioUnit;}
-  virtual AUGraph     GetGraph (){return m_audioGraph;}
-  virtual AUNode      GetNode  (){return m_audioNode;}
-  virtual int         GetBus   (){return m_busNumber;}
-  virtual void        SetBus   (int busNumber){m_busNumber = busNumber;}
-protected:
-  bool SetRenderProc();
-  bool RemoveRenderProc();
-  static OSStatus RenderCallback(void *inRefCon,
-                                 AudioUnitRenderActionFlags *ioActionFlags,
-                                 const AudioTimeStamp *inTimeStamp,
-                                 UInt32 inBusNumber,
-                                 UInt32 inNumberFrames,
-                                 AudioBufferList *ioData);
-  ICoreAudioSource*   m_pSource;
-  AudioUnit           m_audioUnit;
-  AUNode              m_audioNode;
-  AUGraph             m_audioGraph;
-  bool                m_Initialized;
-  AURenderCallback    m_renderProc;
-  int                 m_busNumber;
-};
-
-class CAUOutputDevice : public CCoreAudioUnit
-{
-public:
-  CAUOutputDevice();
-  virtual ~CAUOutputDevice();
-  UInt32 GetBufferFrameSize();
-
-  /*
-  Float32 GetCurrentVolume();
-  bool SetCurrentVolume(Float32 vol);
-  */
-  bool EnableInputOuput();
-};
-
-class CAUMultiChannelMixer : public CAUOutputDevice
-{
-public:
-  CAUMultiChannelMixer();
-  virtual ~CAUMultiChannelMixer();
-
-  UInt32 GetInputBusCount();
-  bool SetInputBusFormat(UInt32 busCount, AudioStreamBasicDescription *pFormat);
-  bool SetInputBusCount(UInt32 busCount);
-  UInt32 GetOutputBusCount();
-  bool SetOutputBusCount(UInt32 busCount);
-
-  Float32 GetCurrentVolume();
-  bool SetCurrentVolume(Float32 vol);
-};
-
-class CCoreAudioGraph
-{
-private:
-  AUGraph           m_audioGraph;
-
-  CAUOutputDevice  *m_audioUnit;
-  CAUMultiChannelMixer   *m_mixerUnit;
-  CAUOutputDevice  *m_inputUnit;
-
-  int m_reservedBusNumber[MAX_CONNECTION_LIMIT];
-  bool              m_initialized;
-  bool              m_allowMixing;
-
-  typedef std::list<CAUOutputDevice*> AUUnitList;
-  AUUnitList        m_auUnitList;
-
-public:
-  CCoreAudioGraph();
-  ~CCoreAudioGraph();
-
-  bool Open(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing, float initVolume);
-  bool Close();
-  bool Start();
-  bool Stop();
-  bool SetInputSource(ICoreAudioSource* pSource);
-  bool SetCurrentVolume(Float32 vol);
-  CAUOutputDevice *DestroyUnit(CAUOutputDevice *outputUnit);
-  CAUOutputDevice *CreateUnit(AEAudioFormat &format);
-  int GetFreeBus();
-  void ReleaseBus(int busNumber);
-  bool IsBusFree(int busNumber);
-  int GetMixerChannelOffset(int busNumber);
-  void ShowGraph();
-  float GetLatency();
-};
-
-class CCoreAudioAEHALIOS : public ICoreAudioAEHAL
-{
-protected:
-  CCoreAudioGraph  *m_audioGraph;
-  bool              m_Initialized;
-  bool              m_Passthrough;
-  AEAudioFormat     m_initformat;
-  bool              m_allowMixing;
-  bool              m_encoded;
-  AEDataFormat      m_rawDataFormat;
-  float             m_initVolume;
-public:
-  unsigned int      m_NumLatencyFrames;
-  unsigned int      m_OutputBufferIndex;
-  CCoreAudioAE     *m_ae;
-
-  CCoreAudioAEHALIOS();
-  virtual ~CCoreAudioAEHALIOS();
-
-  virtual bool   InitializePCM(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing);
-  virtual bool   InitializePCMEncoded(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual bool   Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device, float initVolume);
-  virtual void   Deinitialize();
-  virtual void   EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
-  virtual void   SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual void   Stop();
-  virtual bool   Start();
-  virtual double GetDelay();
-  virtual void   SetVolume(float volume);
-  virtual unsigned int GetBufferIndex();
-  virtual CAUOutputDevice *DestroyUnit(CAUOutputDevice *outputUnit);
-  virtual CAUOutputDevice *CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual bool  AllowMixing() { return m_allowMixing; }
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.cpp
deleted file mode 100644 (file)
index 10025bb..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- *      Copyright (C) 2011-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/>.
- *
- */
-
-#ifdef TARGET_DARWIN_OSX
-
-#include "system.h"
-
-#include "CoreAudioAEHALOSX.h"
-
-#include "CoreAudioAE.h"
-#include "CoreAudioAEHAL.h"
-#include "CoreAudioUnit.h"
-#include "CoreAudioDevice.h"
-#include "CoreAudioGraph.h"
-#include "CoreAudioMixMap.h"
-#include "CoreAudioHardware.h"
-#include "CoreAudioChannelLayout.h"
-
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "utils/log.h"
-#include "settings/Settings.h"
-
-CCoreAudioAEHALOSX::CCoreAudioAEHALOSX() :
-  m_audioGraph        (NULL   ),
-  m_Initialized       (false  ),
-  m_Passthrough       (false  ),
-  m_allowMixing       (false  ),
-  m_encoded           (false  ),
-  m_initVolume        (1.0f   ),
-  m_NumLatencyFrames  (0      ),
-  m_OutputBufferIndex (0      ),
-  m_ae                (NULL   )
-{
-  m_AudioDevice   = new CCoreAudioDevice();
-  m_OutputStream  = new CCoreAudioStream();
-
-  SInt32 major, minor;
-  Gestalt(gestaltSystemVersionMajor, &major);
-  Gestalt(gestaltSystemVersionMinor, &minor);
-
-  // By default, kAudioHardwarePropertyRunLoop points at the process's main thread on SnowLeopard,
-  // If your process lacks such a run loop, you can set kAudioHardwarePropertyRunLoop to NULL which
-  // tells the HAL to run it's own thread for notifications (which was the default prior to SnowLeopard).
-  // So tell the HAL to use its own thread for similar behavior under all supported versions of OSX.
-  if (major == 10 && minor >= 6)
-  {
-    CFRunLoopRef theRunLoop = NULL;
-    AudioObjectPropertyAddress theAddress = {
-      kAudioHardwarePropertyRunLoop,
-      kAudioObjectPropertyScopeGlobal,
-      kAudioObjectPropertyElementMaster
-    };
-    OSStatus theError = AudioObjectSetPropertyData(kAudioObjectSystemObject,
-      &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
-    if (theError != noErr)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioAE::constructor: kAudioHardwarePropertyRunLoop error.");
-    }
-  }
-}
-
-CCoreAudioAEHALOSX::~CCoreAudioAEHALOSX()
-{
-  Deinitialize();
-
-  delete m_audioGraph;
-  delete m_AudioDevice;
-  delete m_OutputStream;
-}
-
-bool CCoreAudioAEHALOSX::InitializePCM(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing, AudioDeviceID outputDevice, bool encoded)
-{
-  if (m_audioGraph)
-    m_audioGraph->Close(), delete m_audioGraph;
-  m_audioGraph = new CCoreAudioGraph();
-  if (!m_audioGraph)
-    return false;
-
-  AudioChannelLayoutTag layout = g_LayoutMap[ CSettings::Get().GetInt("audiooutput.channels") ];
-  // force optical/coax to 2.0 output channels
-  if (!m_Passthrough && CSettings::Get().GetInt("audiooutput.channels") ==  AE_CH_LAYOUT_2_0)
-    layout = g_LayoutMap[1];
-
-  if (!m_audioGraph->Open(pSource, format, outputDevice, allowMixing, layout, m_initVolume, encoded ))
-  {
-    CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::Initialize: "
-      "Unable to initialize audio due a missconfiguration. Try 2.0 speaker configuration.");
-    return false;
-  }
-
-  m_NumLatencyFrames = m_AudioDevice->GetNumLatencyFrames();
-
-  m_allowMixing = allowMixing;
-
-  return true;
-}
-
-bool CCoreAudioAEHALOSX::InitializePCMEncoded(ICoreAudioSource *pSource, AEAudioFormat &format, AudioDeviceID outputDevice)
-{
-  // Prevent any other application from using this device.
-  m_AudioDevice->SetHogStatus(true);
-  // Try to disable mixing support. Effectiveness depends on the device.
-  m_AudioDevice->SetMixingSupport(false);
-  // Set the Sample Rate as defined by the spec.
-  m_AudioDevice->SetNominalSampleRate((float)format.m_sampleRate);
-
-  if (!InitializePCM(pSource, format, false, outputDevice, true))
-    return false;
-
-  return true;
-}
-
-bool CCoreAudioAEHALOSX::InitializeEncoded(AudioDeviceID outputDevice, AEAudioFormat &format)
-{
-  std::string formatString;
-  AudioStreamID outputStream = 0;
-  AudioStreamBasicDescription outputFormat = {0};
-
-  // Fetch a list of the streams defined by the output device
-  UInt32 streamIndex = 0;
-  AudioStreamIdList streams;
-  m_AudioDevice->GetStreams(&streams);
-
-  m_OutputBufferIndex = 0;
-
-  while (!streams.empty())
-  {
-    // Get the next stream
-    CCoreAudioStream stream;
-    stream.Open(streams.front());
-    streams.pop_front(); // We copied it, now we are done with it
-
-    // Probe physical formats
-    StreamFormatList physicalFormats;
-    stream.GetAvailablePhysicalFormats(&physicalFormats);
-    while (!physicalFormats.empty())
-    {
-      AudioStreamRangedDescription& desc = physicalFormats.front();
-      CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded:    "
-        "Considering Physical Format: %s", StreamDescriptionToString(desc.mFormat, formatString));
-
-      if (m_rawDataFormat == AE_FMT_LPCM   || m_rawDataFormat == AE_FMT_DTSHD ||
-          m_rawDataFormat == AE_FMT_TRUEHD || m_rawDataFormat == AE_FMT_EAC3)
-      {
-        // check pcm output formats
-        unsigned int bps = CAEUtil::DataFormatToBits(AE_FMT_S16NE);
-        if (desc.mFormat.mChannelsPerFrame == m_initformat.m_channelLayout.Count() &&
-            desc.mFormat.mBitsPerChannel == bps &&
-            desc.mFormat.mSampleRate == m_initformat.m_sampleRate )
-        {
-          outputFormat = desc.mFormat; // Select this format
-          m_OutputBufferIndex = streamIndex;
-          outputStream = stream.GetId();
-          break;
-        }
-      }
-      else
-      {
-        // check encoded formats
-        if (desc.mFormat.mFormatID == kAudioFormat60958AC3 || desc.mFormat.mFormatID == 'IAC3')
-        {
-          if (desc.mFormat.mChannelsPerFrame == m_initformat.m_channelLayout.Count() &&
-              desc.mFormat.mSampleRate == m_initformat.m_sampleRate )
-          {
-            outputFormat = desc.mFormat; // Select this format
-            m_OutputBufferIndex = streamIndex;
-            outputStream = stream.GetId();
-            break;
-          }
-        }
-      }
-      physicalFormats.pop_front();
-    }
-
-    // TODO: How do we determine if this is the right stream (not just the right format) to use?
-    if (outputFormat.mFormatID)
-      break; // We found a suitable format. No need to continue.
-    streamIndex++;
-  }
-
-  if (!outputFormat.mFormatID) // No match found
-  {
-    CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-      "Unable to identify suitable output format.");
-    return false;
-  }
-
-  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-    "Selected stream[%u] - id: 0x%04X, Physical Format: %s",
-    m_OutputBufferIndex, (uint)outputStream, StreamDescriptionToString(outputFormat, formatString));
-
-  // TODO: Auto hogging sets this for us. Figure out how/when to turn it off or use it
-  // It appears that leaving this set will aslo restore the previous stream format when the
-  // Application exits. If auto hogging is set and we try to set hog mode, we will deadlock
-  // From the SDK docs: "If the AudioDevice is in a non-mixable mode, the HAL will automatically take hog mode on behalf of the first process to start an IOProc."
-
-  // Lock down the device.  This MUST be done PRIOR to switching to a non-mixable format, if it is done at all
-  // If it is attempted after the format change, there is a high likelihood of a deadlock
-  // We may need to do this sooner to enable mix-disable (i.e. before setting the stream format)
-
-  // Auto-Hog does not always un-hog the device when changing back to a mixable mode.
-  // Handle this on our own until it is fixed.
-  CCoreAudioHardware::SetAutoHogMode(false);
-  bool autoHog = CCoreAudioHardware::GetAutoHogMode();
-  CLog::Log(LOGDEBUG, " CoreAudioRenderer::InitializeEncoded: "
-    "Auto 'hog' mode is set to '%s'.", autoHog ? "On" : "Off");
-  if (!autoHog) // Try to handle this ourselves
-  {
-    // Hog the device if it is not set to be done automatically
-    m_AudioDevice->SetHogStatus(true);
-    // Try to disable mixing. If we cannot, it may not be a problem
-    m_AudioDevice->SetMixingSupport(false);
-  }
-
-  m_NumLatencyFrames = m_AudioDevice->GetNumLatencyFrames();
-
-  // Configure the output stream object, this is the one we will keep
-  m_OutputStream->Open(outputStream);
-
-  AudioStreamBasicDescription virtualFormat;
-  m_OutputStream->GetVirtualFormat(&virtualFormat);
-  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-    "Previous Virtual Format: %s", StreamDescriptionToString(virtualFormat, formatString));
-
-  AudioStreamBasicDescription previousPhysicalFormat;
-  m_OutputStream->GetPhysicalFormat(&previousPhysicalFormat);
-  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-    "Previous Physical Format: %s", StreamDescriptionToString(previousPhysicalFormat, formatString));
-
-  // Set the active format (the old one will be reverted when we close)
-  m_OutputStream->SetPhysicalFormat(&outputFormat);
-  m_NumLatencyFrames += m_OutputStream->GetNumLatencyFrames();
-
-  m_OutputStream->GetVirtualFormat(&virtualFormat);
-  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-    "New Virtual Format: %s", StreamDescriptionToString(virtualFormat, formatString));
-  CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::InitializeEncoded: "
-    "New Physical Format: %s", StreamDescriptionToString(outputFormat, formatString));
-
-  m_allowMixing = false;
-
-  return true;
-}
-
-bool CCoreAudioAEHALOSX::Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device, float initVolume)
-{
-  // Reset all the devices to a default 'non-hog' and mixable format.
-  // If we don't do this we may be unable to find the Default Output device.
-  // (e.g. if we crashed last time leaving it stuck in AC-3 mode)
-
-  CCoreAudioHardware::ResetAudioDevices();
-
-  m_ae = (CCoreAudioAE*)ae;
-  if (!m_ae)
-    return false;
-
-  m_initformat          = format;
-  m_rawDataFormat       = rawDataFormat;
-  m_Passthrough         = passThrough;
-  m_encoded             = false;
-  m_OutputBufferIndex   = 0;
-  m_initVolume          = initVolume;
-
-  if (format.m_channelLayout.Count() == 0)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioAEHALOSX::Initialize - "
-      "Unable to open the requested channel layout");
-    return false;
-  }
-
-  if (device.find("CoreAudio:") != std::string::npos)
-    device.erase(0, strlen("CoreAudio:"));
-
-  AudioDeviceID outputDevice = CCoreAudioHardware::FindAudioDevice(device);
-  if (!outputDevice)
-  {
-    // Fall back to the default device if no match is found
-    CLog::Log(LOGWARNING, "CCoreAudioAEHALOSX::Initialize: "
-      "Unable to locate configured device, falling-back to the system default.");
-    outputDevice = CCoreAudioHardware::GetDefaultOutputDevice();
-    if (!outputDevice) // Not a lot to be done with no device. TODO: Should we just grab the first existing device?
-      return false;
-  }
-
-  // Attach our output object to the device
-  m_AudioDevice->Open(outputDevice);
-  m_AudioDevice->SetHogStatus(false);
-  m_AudioDevice->SetMixingSupport(true);
-
-  // If this is a passthrough (AC3/DTS) stream, attempt to handle it natively
-  if (m_Passthrough)
-    m_encoded = InitializeEncoded(outputDevice, format);
-
-  // If this is a PCM stream, or we failed to handle a passthrough stream natively,
-  // prepare the standard interleaved PCM interface
-  if (!m_encoded)
-  {
-    // If we are here and this is a passthrough stream, native handling failed.
-    // Try to handle it as IEC61937 data over straight PCM (DD-Wav)
-    bool configured = false;
-    if (m_Passthrough)
-    {
-      CLog::Log(LOGDEBUG, "CCoreAudioAEHALOSX::Initialize: "
-        "No suitable AC3 output format found. Attempting DD-Wav.");
-      configured = InitializePCMEncoded(ae, format, outputDevice);
-    }
-    else
-    {
-      // Standard PCM data
-      configured = InitializePCM(ae, format, true, outputDevice);
-    }
-
-    // No suitable output format was able to be configured
-    if (!configured)
-      return false;
-  }
-
-  m_Initialized = true;
-
-  return true;
-}
-
-CAUOutputDevice *CCoreAudioAEHALOSX::DestroyUnit(CAUOutputDevice *outputUnit)
-{
-  if (m_audioGraph && outputUnit)
-    return m_audioGraph->DestroyUnit(outputUnit);
-
-  return NULL;
-}
-
-CAUOutputDevice *CCoreAudioAEHALOSX::CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format)
-{
-  CAUOutputDevice *outputUnit = NULL;
-
-  // when HAL is using a mixer, the input is routed through converter units.
-  // therefore we create a converter unit attach the source and give it back.
-  if (m_allowMixing && m_audioGraph)
-  {
-    outputUnit = m_audioGraph->CreateUnit(format);
-
-    if (pSource && outputUnit)
-      outputUnit->SetInputSource(pSource);
-  }
-
-  return outputUnit;
-}
-
-void CCoreAudioAEHALOSX::Deinitialize()
-{
-  if (!m_Initialized)
-    return;
-
-  Stop();
-
-  if (m_encoded)
-    m_AudioDevice->SetInputSource(NULL, 0, 0);
-
-  if (m_audioGraph)
-    m_audioGraph->SetInputSource(NULL);
-
-  m_OutputStream->Close();
-  m_AudioDevice->Close();
-
-  if (m_audioGraph)
-  {
-    //m_audioGraph->Close();
-    delete m_audioGraph;
-  }
-  m_audioGraph = NULL;
-
-  m_NumLatencyFrames = 0;
-  m_OutputBufferIndex = 0;
-
-  m_Initialized = false;
-  m_Passthrough = false;
-}
-
-void CCoreAudioAEHALOSX::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
-{
-  CoreAudioDeviceList deviceList;
-  CCoreAudioHardware::GetOutputDevices(&deviceList);
-
-  devices.push_back(AEDevice("Default", "CoreAudio:default"));
-
-  std::string deviceName;
-  for (int i = 0; !deviceList.empty(); i++)
-  {
-    CCoreAudioDevice device(deviceList.front());
-    deviceName = device.GetName();
-
-    std::string deviceName_Internal = std::string("CoreAudio:");
-    deviceName_Internal.append(deviceName);
-    devices.push_back(AEDevice(deviceName, deviceName_Internal));
-
-    deviceList.pop_front();
-  }
-}
-
-void CCoreAudioAEHALOSX::Stop()
-{
-  if (!m_Initialized)
-    return;
-
-  if (m_encoded)
-    m_AudioDevice->Stop();
-  else
-    m_audioGraph->Stop();
-}
-
-bool CCoreAudioAEHALOSX::Start()
-{
-  if (!m_Initialized)
-    return false;
-
-  if (m_encoded)
-    m_AudioDevice->Start();
-  else
-    m_audioGraph->Start();
-
-  return true;
-}
-
-void CCoreAudioAEHALOSX::SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format)
-{
-  if (!m_Initialized)
-    return;
-
-  // when HAL is initialized encoded we use directIO
-  // when HAL is not in encoded mode and there is no mixer attach source the audio unit
-  // when mixing is allowed in HAL, HAL is working with converter units where we attach the source.
-
-  if (m_encoded)
-  {
-    // register directcallback for the audio HAL
-    // direct render callback need to know the framesize and buffer index
-    if (pSource)
-      m_AudioDevice->SetInputSource(pSource, format.m_frameSize, m_OutputBufferIndex);
-    else
-      m_AudioDevice->SetInputSource(pSource, 0, 0);
-  }
-  else if (!m_encoded && !m_allowMixing)
-  {
-    // register render callback for the audio unit
-    m_audioGraph->SetInputSource(pSource);
-  }
-}
-
-double CCoreAudioAEHALOSX::GetDelay()
-{
-  return (double)(m_NumLatencyFrames) / (m_initformat.m_sampleRate);
-}
-
-void CCoreAudioAEHALOSX::SetVolume(float volume)
-{
-  if (m_encoded || m_Passthrough)
-    return;
-
-  m_audioGraph->SetCurrentVolume(volume);
-}
-
-unsigned int CCoreAudioAEHALOSX::GetBufferIndex()
-{
-  return m_OutputBufferIndex;
-}
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEHALOSX.h
deleted file mode 100644 (file)
index c96a4e1..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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/>.
- *
- */
-
-#if defined(TARGET_DARWIN_OSX)
-
-#include "ICoreAudioAEHAL.h"
-#include "ICoreAudioSource.h"
-
-#include <CoreAudio/CoreAudio.h>
-
-// Forward declarations
-class CCoreAudioAE;
-class CCoreAudioGraph;
-class CCoreAudioDevice;
-class CCoreAudioStream;
-
-class CAUOutputDevice;
-
-class CCoreAudioAEHALOSX : public ICoreAudioAEHAL
-{
-protected:
-  CCoreAudioGraph  *m_audioGraph;
-  CCoreAudioDevice *m_AudioDevice;
-  CCoreAudioStream *m_OutputStream;
-  bool              m_Initialized;
-  bool              m_Passthrough;
-  AEAudioFormat     m_initformat;
-  bool              m_allowMixing;
-  bool              m_encoded;
-  AEDataFormat      m_rawDataFormat;
-  float             m_initVolume;
-public:
-  unsigned int      m_NumLatencyFrames;
-  unsigned int      m_OutputBufferIndex;
-  CCoreAudioAE     *m_ae;
-
-  CCoreAudioAEHALOSX();
-  virtual ~CCoreAudioAEHALOSX();
-
-  virtual bool  InitializePCM(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing, AudioDeviceID outputDevice, bool encoded = false);
-  virtual bool  InitializePCMEncoded(ICoreAudioSource *pSource, AEAudioFormat &format, AudioDeviceID outputDevice);
-  virtual bool  InitializeEncoded(AudioDeviceID outputDevice, AEAudioFormat &format);
-  virtual bool  Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device, float initVolume);
-  virtual void  Deinitialize();
-  virtual void  EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
-  virtual void  SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual void  Stop();
-  virtual bool  Start();
-  virtual double GetDelay();
-  virtual void  SetVolume(float volume);
-  virtual unsigned int GetBufferIndex();
-  virtual CAUOutputDevice* DestroyUnit(CAUOutputDevice *outputUnit);
-  virtual CAUOutputDevice* CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual bool  AllowMixing() { return m_allowMixing; }
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.cpp
deleted file mode 100644 (file)
index e57f263..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *      Copyright (C) 2011-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 <samplerate.h>
-
-#include "CoreAudioAESound.h"
-
-#include "CoreAudioAE.h"
-#include "threads/SingleLock.h"
-#include "cores/AudioEngine/AEFactory.h"
-#include "cores/AudioEngine/Utils/AEAudioFormat.h"
-#include "cores/AudioEngine/Interfaces/AESound.h"
-#include "cores/AudioEngine/Utils/AEConvert.h"
-#include "cores/AudioEngine/Utils/AERemap.h"
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "utils/log.h"
-#include "utils/EndianSwap.h"
-
-/* typecast AE to CCoreAudioAE */
-#define AE (*(CCoreAudioAE*)CAEFactory::GetEngine())
-
-CCoreAudioAESound::CCoreAudioAESound(const std::string &filename) :
-  IAESound         (filename),
-  m_filename       (filename),
-  m_volume         (1.0f    ),
-  m_inUse          (0       )
-{
-  m_wavLoader.Load(filename);
-}
-
-CCoreAudioAESound::~CCoreAudioAESound()
-{
-  DeInitialize();
-}
-
-
-std::string CCoreAudioAESound::GetFileName()
-{
-  return m_filename;
-}
-
-void CCoreAudioAESound::DeInitialize()
-{
-}
-
-bool CCoreAudioAESound::Initialize()
-{
-  if (!m_wavLoader.IsValid())
-    return false;
-
-  return m_wavLoader.Initialize(
-    AE.GetSampleRate   (),
-    AE.GetChannelLayout(),
-    AE_CH_LAYOUT_INVALID
-  );
-}
-
-void CCoreAudioAESound::SetVolume(float volume)
-{
-  m_volume = std::max(0.0f, std::min(1.0f, volume));
-}
-
-float CCoreAudioAESound::GetVolume()
-{
-  return m_volume;
-}
-
-unsigned int CCoreAudioAESound::GetSampleCount()
-{
-  CSingleLock cs(m_critSection);
-  if (m_wavLoader.IsValid())
-    return m_wavLoader.GetSampleCount();
-  return 0;
-}
-
-float* CCoreAudioAESound::GetSamples()
-{
-  CSingleLock cs(m_critSection);
-  if (!m_wavLoader.IsValid())
-    return NULL;
-
-  ++m_inUse;
-  return m_wavLoader.GetSamples();
-}
-
-void CCoreAudioAESound::ReleaseSamples()
-{
-  CSingleLock cs(m_critSection);
-  if(m_inUse > 0)
-    --m_inUse;
-}
-
-bool CCoreAudioAESound::IsPlaying()
-{
-  CSingleLock cs(m_critSection);
-  return (m_inUse > 0);
-}
-
-void CCoreAudioAESound::Play()
-{
-  AE.PlaySound(this);
-}
-
-void CCoreAudioAESound::Stop()
-{
-  AE.StopSound(this);
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAESound.h
deleted file mode 100644 (file)
index 68fdb2a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "cores/AudioEngine/Interfaces/AESound.h"
-#include "cores/AudioEngine/Utils/AEWAVLoader.h"
-#include "threads/CriticalSection.h"
-
-class CCoreAudioAESound : public IAESound
-{
-public:
-  CCoreAudioAESound(const std::string &filename);
-  virtual ~CCoreAudioAESound();
-
-  virtual std::string GetFileName();
-  virtual void    DeInitialize();
-  virtual bool    Initialize();
-
-  virtual void    Play();
-  virtual void    Stop();
-  virtual bool    IsPlaying();
-
-  virtual void    SetVolume(float volume);
-  virtual float   GetVolume();
-
-  unsigned int    GetSampleCount();
-
-  /* ReleaseSamples must be called for each time GetSamples has been called */
-  virtual float*  GetSamples();
-  void            ReleaseSamples();
-
-private:
-  CCriticalSection m_critSection;
-  std::string      m_filename;
-  CAEWAVLoader     m_wavLoader;
-  float            m_volume;
-  int              m_inUse;
-};
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.cpp
deleted file mode 100644 (file)
index 581daf9..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#include "CoreAudioAE.h"
-#include "CoreAudioAEStream.h"
-
-#include "xbmc/cores/AudioEngine/Interfaces/AE.h"
-#include "xbmc/cores/AudioEngine/AEFactory.h"
-#include "xbmc/cores/AudioEngine/Utils/AEUtil.h"
-#include "xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.h"
-#include "settings/Settings.h"
-#include "threads/SingleLock.h"
-#include "settings/AdvancedSettings.h"
-#include "utils/MathUtils.h"
-#include "utils/log.h"
-
-
-
-// typecast AE to CCoreAudioAE
-#define AE (*(CCoreAudioAE*)CAEFactory::GetEngine())
-
-void CheckOutputBufferSize(void **buffer, int *oldSize, int newSize)
-{
-  if (newSize > *oldSize)
-  {
-    if (*buffer)
-      _aligned_free(*buffer);
-    *buffer = _aligned_malloc(newSize, 16);
-    *oldSize = newSize;
-  }
-  memset(*buffer, 0x0, *oldSize);
-}
-
-using namespace std;
-
-template <class AudioDataType>
-static inline void _Upmix(AudioDataType *input,
-  unsigned int channelsInput, AudioDataType *output,
-  unsigned int channelsOutput, unsigned int frames)
-{
-  unsigned int unused = channelsOutput - channelsInput;
-  AudioDataType *_input  = input;
-  AudioDataType *_output = output;
-
-  for (unsigned int i = 0; i < frames; i++)
-  {
-    // get input channels
-    for(unsigned int j = 0; j < channelsInput; j++)
-      *_output++ = *_input++;
-    // set unused channels
-    for(unsigned int j = 0; j < unused; j++)
-      *_output++ = 0;
-  }
-}
-
-void CCoreAudioAEStream::Upmix(void *input,
-  unsigned int channelsInput,  void *output,
-  unsigned int channelsOutput, unsigned int frames, AEDataFormat dataFormat)
-{
-  // input channels must be less than output channels
-  if (channelsInput >= channelsOutput)
-    return;
-
-  switch (CAEUtil::DataFormatToBits(dataFormat))
-  {
-    case 8:  _Upmix ( (unsigned char *) input, channelsInput, (unsigned char *) output, channelsOutput, frames ); break;
-    case 16: _Upmix ( (short         *) input, channelsInput, (short         *) output, channelsOutput, frames ); break;
-    case 32: _Upmix ( (float         *) input, channelsInput, (float         *) output, channelsOutput, frames ); break;
-    default: _Upmix ( (int           *) input, channelsInput, (int           *) output, channelsOutput, frames ); break;
-  }
-}
-
-CCoreAudioAEStream::CCoreAudioAEStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSamplerate, CAEChannelInfo channelLayout, unsigned int options, bool transcode) :
-  m_outputUnit      (NULL ),
-  m_valid           (false),
-  m_delete          (false),
-  m_volume          (1.0f ),
-  m_rgain           (1.0f ),
-  m_slave           (NULL ),
-  m_convertFn       (NULL ),
-  m_Buffer          (NULL ),
-  m_convertBuffer   (NULL ),
-  m_ssrc            (NULL ),
-  m_draining        (false),
-  m_AvgBytesPerSec  (0    ),
-  m_audioCallback   (NULL ),
-  m_fadeRunning     (false),
-  m_frameSize       (0    ),
-  m_doRemap         (true ),
-  m_firstInput      (true ),
-  m_flushRequested  (false),
-  m_encoder         (NULL )
-{
-  m_ssrcData.data_out             = NULL;
-  m_transcode                     = transcode;
-
-  if (!transcode)
-  {
-    m_rawDataFormat                 = dataFormat;
-    m_StreamFormat.m_dataFormat     = dataFormat;
-    m_StreamFormat.m_sampleRate     = sampleRate;
-    m_StreamFormat.m_encodedRate    = 0;  //we don't support this
-    m_StreamFormat.m_channelLayout  = channelLayout;
-    m_isRaw                         = COREAUDIO_IS_RAW(dataFormat);
-  }
-  else
-  {
-    m_rawDataFormat                 = AE_FMT_AC3;
-    m_StreamFormat.m_dataFormat     = AE_FMT_AC3;
-    m_StreamFormat.m_sampleRate     = 48000;
-    m_StreamFormat.m_encodedRate    = 0;  
-    enum AEChannel ac3Layout[3] = {AE_CH_RAW, AE_CH_RAW, AE_CH_NULL};
-    m_StreamFormat.m_channelLayout  = ac3Layout;
-    m_isRaw                         = true;
-    
-    // setup encoder format
-    m_encoderFormat.m_dataFormat    = dataFormat;
-    m_encoderFormat.m_sampleRate    = sampleRate;
-    m_encoderFormat.m_encodedRate   = 0;
-    m_encoderFormat.m_channelLayout = channelLayout;
-    m_encoderFormat.m_frames        = 0;
-    m_encoderFormat.m_frameSamples  = 0;
-    m_encoderFormat.m_frameSize     = 0;
-  }
-  
-  m_incomingFormat                = dataFormat;
-  m_chLayoutCountStream           = m_StreamFormat.m_channelLayout.Count();
-  m_StreamFormat.m_frameSize      = (CAEUtil::DataFormatToBits(m_rawDataFormat) >> 3) * m_chLayoutCountStream;
-  m_OutputFormat                  = AE.GetAudioFormat();
-  m_chLayoutCountOutput           = m_OutputFormat.m_channelLayout.Count();
-
-  //m_forceResample                 = (options & AESTREAM_FORCE_RESAMPLE) != 0;
-  m_paused                        = (options & AESTREAM_PAUSED) != 0;
-
-  m_vizRemapBufferSize            = m_remapBufferSize = /*m_resampleBufferSize = */ m_upmixBufferSize = m_convertBufferSize = 16*1024;
-  m_convertBuffer                 = (float   *)_aligned_malloc(m_convertBufferSize,16);
-  //m_resampleBuffer                = (float   *)_aligned_malloc(m_resampleBufferSize,16);
-  m_upmixBuffer                   = (uint8_t *)_aligned_malloc(m_upmixBufferSize,16);
-  m_remapBuffer                   = (uint8_t *)_aligned_malloc(m_remapBufferSize,16);
-  m_vizRemapBuffer                = (uint8_t *)_aligned_malloc(m_vizRemapBufferSize,16);
-
-  m_limiter.SetSamplerate(AE.GetSampleRate());
-}
-
-CCoreAudioAEStream::~CCoreAudioAEStream()
-{
-  CloseConverter();
-
-  m_delete = true;
-  m_valid = false;
-
-  InternalFlush();
-
-  _aligned_free(m_convertBuffer); m_convertBuffer = NULL;
-  //_aligned_free(m_resampleBuffer); m_resampleBuffer = NULL;
-  _aligned_free(m_remapBuffer); m_remapBuffer = NULL;
-  _aligned_free(m_vizRemapBuffer); m_vizRemapBuffer = NULL;
-  _aligned_free(m_upmixBuffer); m_upmixBuffer = NULL;
-
-  delete m_Buffer; m_Buffer = NULL;
-
-  delete m_encoder;
-  m_encoder = NULL;
-  ResetEncoder();
-  
-  m_unencodedBuffer.DeAlloc();
-  
-  /*
-  if (m_resample)
-  {
-    _aligned_free(m_ssrcData.data_out);
-    src_delete(m_ssrc);
-    m_ssrc = NULL;
-  }
-  */
-
-  CLog::Log(LOGDEBUG, "CCoreAudioAEStream::~CCoreAudioAEStream - Destructed");
-}
-
-void CCoreAudioAEStream::InitializeRemap()
-{
-  if (!m_isRaw)
-  {
-    if (m_OutputFormat.m_channelLayout != AE.GetChannelLayout())
-    {
-      m_OutputFormat            = AE.GetAudioFormat();
-      m_chLayoutCountOutput     = m_OutputFormat.m_channelLayout.Count();
-      m_OutputBytesPerSample    = (CAEUtil::DataFormatToBits(m_OutputFormat.m_dataFormat) >> 3);
-
-      // re-init the remappers
-      m_remap   .Initialize(m_StreamFormat.m_channelLayout, m_OutputFormat.m_channelLayout, false);
-      m_vizRemap.Initialize(m_StreamFormat.m_channelLayout, CAEChannelInfo(AE_CH_LAYOUT_2_0), false, true);
-
-      InternalFlush();
-    }
-  }
-}
-
-void CCoreAudioAEStream::ReinitConverter()
-{
-  CloseConverter();
-  OpenConverter();
-}
-
-// The source logic is in the HAL. The only thing we have to do here
-// is to allocate the convrter and set the direct input call.
-void CCoreAudioAEStream::CloseConverter()
-{
-  // we have a converter, delete it
-  if (m_outputUnit)
-    m_outputUnit = (CAUOutputDevice *) AE.GetHAL()->DestroyUnit(m_outputUnit);
-
-  // it is save to unregister any direct input. the HAL takes care about it.
-  AE.GetHAL()->SetDirectInput(NULL, m_OutputFormat);
-}
-
-void CCoreAudioAEStream::OpenConverter()
-{
-  // we always allocate a converter
-  // the HAL decides if we get converter.
-  // if there is already a converter delete it.
-  if (m_outputUnit)
-    m_outputUnit = (CAUOutputDevice *) AE.GetHAL()->DestroyUnit(m_outputUnit);
-
-  AEAudioFormat format = m_OutputFormat;
-
-  format.m_sampleRate = m_StreamFormat.m_sampleRate;
-  m_outputUnit = (CAUOutputDevice *) AE.GetHAL()->CreateUnit(this, format);
-
-  // it is safe to register any direct input. the HAL takes care about it.
-  AE.GetHAL()->SetDirectInput(this, m_OutputFormat);
-}
-
-void CCoreAudioAEStream::Initialize()
-{
-  if (m_valid)
-    InternalFlush();
-
-  m_OutputFormat = AE.GetAudioFormat();
-  m_chLayoutCountOutput = m_OutputFormat.m_channelLayout.Count();
-
-  if (m_rawDataFormat == AE_FMT_LPCM)
-    m_OutputBytesPerSample = (CAEUtil::DataFormatToBits(AE_FMT_FLOAT) >> 3);
-  else
-    m_OutputBytesPerSample = (CAEUtil::DataFormatToBits(m_OutputFormat.m_dataFormat) >> 3);
-
-  if (m_isRaw || m_transcode)
-  {
-    // we are raw or transcode, which means we need to work in the output format
-    if (m_rawDataFormat != AE_FMT_LPCM)
-    {
-      m_StreamFormat = AE.GetAudioFormat();
-      m_chLayoutCountStream = m_StreamFormat.m_channelLayout.Count();
-    }
-    m_StreamBytesPerSample = (CAEUtil::DataFormatToBits(m_StreamFormat.m_dataFormat) >> 3);
-    m_doRemap = false;
-  }
-  else
-  {
-    if (!m_chLayoutCountStream)
-    {
-      m_valid = false;
-      return;
-    }
-    // Work around a bug in TrueHD and DTSHD deliver
-    if (m_StreamFormat.m_dataFormat == AE_FMT_TRUEHD || m_StreamFormat.m_dataFormat == AE_FMT_DTSHD)
-      m_StreamBytesPerSample = (CAEUtil::DataFormatToBits(AE_FMT_S16NE) >> 3);
-    else
-      m_StreamBytesPerSample = (CAEUtil::DataFormatToBits(m_StreamFormat.m_dataFormat) >> 3);
-    m_StreamFormat.m_frameSize = m_StreamBytesPerSample * m_chLayoutCountStream;
-  }
-
-  if (!m_isRaw)
-  {
-    if (!m_remap.Initialize(m_StreamFormat.m_channelLayout, m_OutputFormat.m_channelLayout, false))
-    {
-      m_valid = false;
-      return;
-    }
-
-    m_doRemap  = m_chLayoutCountStream != 2;
-
-    if (!m_vizRemap.Initialize(m_OutputFormat.m_channelLayout, CAEChannelInfo(AE_CH_LAYOUT_2_0), false, true))
-    {
-      m_valid = false;
-      return;
-    }
-  }
-
-  // only try to convert if we're not in AE_FMT_FLOAT and (we're not raw or we are transcoding)
-  m_convert =
-    (m_StreamFormat.m_dataFormat != AE_FMT_FLOAT && !m_isRaw)
-    ||
-    (m_incomingFormat != AE_FMT_FLOAT && m_transcode);
-  
-  
-  //m_resample = false; //(m_StreamFormat.m_sampleRate != m_OutputFormat.m_sampleRate) && !m_isRaw;
-
-  // if we need to convert, set it up
-  if (m_convert)
-  {
-    // get the conversion function and allocate a buffer for the data
-    CLog::Log(LOGDEBUG, "CCoreAudioAEStream::CCoreAudioAEStream - Converting from %s to AE_FMT_FLOAT", CAEUtil::DataFormatToStr(m_StreamFormat.m_dataFormat));
-    
-    if (!m_transcode)
-      m_convertFn = CAEConvert::ToFloat(m_StreamFormat.m_dataFormat);
-    else
-      m_convertFn = CAEConvert::ToFloat(m_incomingFormat);
-
-    if (!m_convertFn)
-      m_valid = false;
-  }
-  
-  // if we need to transcode, set it up
-  if (m_transcode)
-  {    
-    m_unencodedBuffer.Empty();
-
-    if (!m_encoder || !m_encoder->IsCompatible(m_encoderFormat))
-      SetupEncoder();
-  }
-
-  // if we need to resample, set it up
-  /*
-  if (m_resample)
-  {
-    int err;
-    m_ssrc                   = src_new(SRC_SINC_MEDIUM_QUALITY, m_chLayoutCountStream, &err);
-    m_ssrcData.src_ratio     = (double)m_OutputFormat.m_sampleRate / (double)m_StreamFormat.m_sampleRate;
-    m_ssrcData.data_in       = m_convertBuffer;
-    m_ssrcData.end_of_input  = 0;
-  }
-  */
-
-  // m_AvgBytesPerSec is calculated based on the output format.
-  // we have to keep in mind that we convert our data to the output format
-  m_AvgBytesPerSec = m_OutputFormat.m_frameSize * m_OutputFormat.m_sampleRate;
-
-  delete m_Buffer;
-  m_Buffer = new AERingBuffer(m_AvgBytesPerSec);
-
-  m_fadeRunning = false;
-
-  OpenConverter();
-
-  m_valid = true;
-}
-
-void CCoreAudioAEStream::Destroy()
-{
-  m_valid  = false;
-  m_delete = true;
-  InternalFlush();
-}
-
-unsigned int CCoreAudioAEStream::AddData(void *data, unsigned int size)
-{
-  unsigned int frames   = size / m_StreamFormat.m_frameSize;
-  unsigned int samples  = size / m_StreamBytesPerSample;
-  uint8_t     *adddata  = (uint8_t *)data;
-  unsigned int addsize  = size;
-  unsigned int channelsInBuffer = m_chLayoutCountStream;
-
-  if (m_flushRequested && m_paused)
-    InternalFlush();
-
-  if (!m_valid || size == 0 || data == NULL || !m_Buffer || m_flushRequested)
-    return 0;
-
-  // if the stream is draining
-  if (m_draining)
-  {
-    // if the stream has finished draining, cork it
-    if (m_Buffer && m_Buffer->GetReadSize() == 0)
-      m_draining = false;
-    else
-      return 0;
-  }
-
-  // convert the data if we need to
-  if (m_convert)
-  {
-    CheckOutputBufferSize((void **)&m_convertBuffer, &m_convertBufferSize, frames * channelsInBuffer  * m_OutputBytesPerSample);
-
-    samples = m_convertFn(adddata, size / m_StreamBytesPerSample, m_convertBuffer);
-    frames  = samples / channelsInBuffer;
-    addsize = frames * channelsInBuffer * m_OutputBytesPerSample;
-    adddata = (uint8_t *)m_convertBuffer;
-  }
-  else
-  {
-    samples = size / m_StreamBytesPerSample;
-    adddata = (uint8_t *)data;
-    addsize = size;
-  }
-
-  if (samples == 0)
-    return 0;
-
-  // transcode if we need to
-  if (m_transcode && m_encoder)
-  {
-    // put adddata in the unencodedBuffer
-    if (m_unencodedBuffer.Free() < addsize)
-      m_unencodedBuffer.ReAlloc(m_unencodedBuffer.Used() + addsize);
-    
-    m_unencodedBuffer.Push(adddata, addsize);
-    
-    unsigned int block = m_encoderFormat.m_frames * m_encoderFormat.m_frameSize;
-    
-    // only try to encode if we have enough data
-    if (m_unencodedBuffer.Used() >= block)
-    {
-        frames = m_encoder->Encode((float *)m_unencodedBuffer.Raw(block), m_encoderFormat.m_frames);
-        m_unencodedBuffer.Shift(NULL, frames * m_encoderFormat.m_frameSize);
-        addsize = m_encoder->GetData(&adddata);
-        samples = addsize / m_OutputBytesPerSample;
-    }
-    else
-      // return size here or whoever calling us will block if we return 0
-      // we have essentially been successful, because we add the audio to our buffer to encode
-      return size;
-  }
-
-  if (samples == 0)
-    return 0;
-
-
-  // resample it if we need to
-  /*
-  if (m_resample)
-  {
-    unsigned int resample_frames = samples / m_chLayoutCountStream;
-
-    CheckOutputBufferSize((void **)&m_resampleBuffer, &m_resampleBufferSize,
-                          resample_frames * std::ceil(m_ssrcData.src_ratio) * sizeof(float) * 2);
-
-    m_ssrcData.input_frames   = resample_frames;
-    m_ssrcData.output_frames  = resample_frames * std::ceil(m_ssrcData.src_ratio);
-    m_ssrcData.data_in        = (float *)adddata;
-    m_ssrcData.data_out       = m_resampleBuffer;
-
-    if (src_process(m_ssrc, &m_ssrcData) != 0)
-      return 0;
-
-    frames    = m_ssrcData.output_frames_gen;
-    samples   = frames * m_chLayoutCountStream;
-    adddata   = (uint8_t *)m_ssrcData.data_out;
-  }
-  else
-  {
-    frames    = samples / m_chLayoutCountStream;
-    samples   = frames * m_chLayoutCountStream;
-  }
-  */
-
-  if (m_doRemap)
-  {
-    addsize = frames * m_OutputBytesPerSample * m_chLayoutCountOutput;
-    CheckOutputBufferSize((void **)&m_remapBuffer, &m_remapBufferSize, addsize);
-
-    // downmix/remap the data
-    m_remap.Remap((float *)adddata, (float *)m_remapBuffer, frames);
-    adddata = (uint8_t *)m_remapBuffer;
-    channelsInBuffer = m_OutputFormat.m_channelLayout.Count();
-  }
-
-  // upmix the ouput to output channels
-  if ( (!m_isRaw || m_rawDataFormat == AE_FMT_LPCM) && (m_chLayoutCountOutput > channelsInBuffer) )
-  {
-    CheckOutputBufferSize((void **)&m_upmixBuffer, &m_upmixBufferSize, frames * m_chLayoutCountOutput  * sizeof(float));
-    Upmix(adddata, channelsInBuffer, m_upmixBuffer, m_chLayoutCountOutput, frames, m_OutputFormat.m_dataFormat);
-    adddata = m_upmixBuffer;
-    addsize = frames * m_chLayoutCountOutput *  sizeof(float);
-  }
-
-  unsigned int total_ms_sleep = 0;
-  unsigned int room = m_Buffer->GetWriteSize();
-  while (addsize > room && !m_paused && total_ms_sleep < 100)
-  {
-    // we got deleted
-    if (!m_valid || !m_Buffer || m_draining )
-      return 0;
-
-    unsigned int ms_sleep_time = (1000 * room) / m_AvgBytesPerSec;
-    if (ms_sleep_time == 0)
-      ms_sleep_time++;
-
-    // sleep until we have space (estimated) or 1ms min
-    Sleep(ms_sleep_time);
-    total_ms_sleep += ms_sleep_time;
-
-    room = m_Buffer->GetWriteSize();
-  }
-
-  if (addsize > room)
-    size = 0;
-  else
-    m_Buffer->Write(adddata, addsize);
-
-  // still only return size to indicate success
-  // we likely wrote something !size to m_Buffer, but our called doesn't realy care
-  return size;
-}
-
-// this is only called on the context of the coreaudio thread!
-unsigned int CCoreAudioAEStream::GetFrames(uint8_t *buffer, unsigned int size)
-{
-  // if we have been deleted
-  if (!m_valid || m_delete || !m_Buffer || m_paused)
-    return 0;
-  
-  if (m_flushRequested)
-  {
-    InternalFlush();
-    return 0;
-  }
-
-  unsigned int readsize = std::min(m_Buffer->GetReadSize(), size);
-  m_Buffer->Read(buffer, readsize);
-
-  if (!m_isRaw)
-  {
-    float *floatBuffer   = (float *)buffer;
-    unsigned int samples = readsize / m_OutputBytesPerSample;
-    unsigned int frames         = samples / m_chLayoutCountOutput;
-
-    // we have a frame, if we have a viz we need to hand the data to it.
-    // Keep in mind that our buffer is already in output format.
-    // So we remap output format to viz format !!!
-    if (m_OutputFormat.m_dataFormat == AE_FMT_FLOAT)
-    {
-      // TODO : Why the hell is vizdata limited ?
-      unsigned int samplesClamped = (samples > 512) ? 512 : samples;
-      if (samplesClamped)
-      {
-        // Viz channel count is 2
-        CheckOutputBufferSize((void **)&m_vizRemapBuffer, &m_vizRemapBufferSize, frames * 2 * sizeof(float));
-
-        m_vizRemap.Remap(floatBuffer, (float*)m_vizRemapBuffer, frames);
-        if (m_audioCallback)
-          m_audioCallback->OnAudioData((float *)m_vizRemapBuffer, samplesClamped);
-      }
-    }
-
-    // if we are fading
-    if (m_fadeRunning)
-    {
-      // TODO: check if we correctly respect the amount of our blockoperation
-      m_volume += (m_fadeStep * ((float)readsize / (float)m_OutputFormat.m_frameSize));
-      m_volume  = std::min(1.0f, std::max(0.0f, m_volume));
-      if (m_fadeDirUp)
-      {
-        if (m_volume >= m_fadeTarget)
-          m_fadeRunning = false;
-      }
-      else
-      {
-        if (m_volume <= m_fadeTarget)
-          m_fadeRunning = false;
-      }
-    }
-    
-    if (m_volume < 1.0f)
-    {
-#ifdef __SSE__
-      CAEUtil::SSEMulArray(floatBuffer, m_volume, samples);
-#else
-      for(unsigned int i = 0; i < samples; i++)
-        floatBuffer[i] *= m_volume;
-#endif
-      CAEUtil::ClampArray(floatBuffer, samples);
-    }
-    // apply volume amplification by using the sogt limiter
-    // TODO - maybe reinvent the coreaudio compressor for this after frodo
-    else if (GetAmplification() != 1.0f)
-    {
-      for(unsigned int i = 0; i < frames; i++)
-      {
-        int frameIdx = i*m_chLayoutCountOutput;
-        float amplification = RunLimiter(&floatBuffer[frameIdx], m_chLayoutCountOutput);
-        float *frameStart = &floatBuffer[frameIdx];
-#ifdef __SSE___
-        CAEUtil::SSEMulArray(frameStart, amplification, m_chLayoutCountOutput);
-#else
-        for(unsigned int n = 0; n < m_chLayoutCountOutput; n++)
-          frameStart[n] *= amplification;
-#endif
-        
-      }
-    }
-  }
-
-  return readsize;
-}
-
-const unsigned int CCoreAudioAEStream::GetFrameSize() const
-{
-  return m_OutputFormat.m_frameSize;
-}
-
-unsigned int CCoreAudioAEStream::GetSpace()
-{
-  if (!m_valid || m_draining)
-    return 0;
-
-  return m_Buffer->GetWriteSize() / m_OutputBytesPerSample  * m_StreamBytesPerSample;
-}
-
-double CCoreAudioAEStream::GetDelay()
-{
-  if (m_delete || !m_Buffer || m_flushRequested)
-    return 0.0f;
-
-  double delayBuffer = (double)(m_Buffer->GetReadSize()) / (double)m_AvgBytesPerSec;
-  double delayTranscoder = 0.0;
-  
-  if (m_transcode)
-    delayTranscoder = (double)(m_unencodedBuffer.Used()) / (double)(m_encoderFormat.m_frameSize * m_encoderFormat.m_sampleRate);
-    
-  return AE.GetDelay() + delayBuffer + delayTranscoder;
-}
-
-bool CCoreAudioAEStream::IsBuffering()
-{
-  return (m_Buffer->GetReadSize() == 0 && m_unencodedBuffer.Used() == 0);
-}
-
-double CCoreAudioAEStream::GetCacheTime()
-{
-  if (m_delete || !m_Buffer || m_flushRequested)
-    return 0.0f;
-  double delayBuffer = (double)(m_Buffer->GetReadSize()) / (double)m_AvgBytesPerSec;
-  double delayTranscoder = 0.0;
-  
-  if (m_transcode)
-    delayTranscoder = (double)(m_unencodedBuffer.Used()) / (double)(m_encoderFormat.m_frameSize * m_encoderFormat.m_sampleRate);
-  
-  return AE.GetDelay() + delayBuffer + delayTranscoder;
-}
-
-double CCoreAudioAEStream::GetCacheTotal()
-{
-  if (m_delete || !m_Buffer)
-    return 0.0f;
-
-  return (double)m_Buffer->GetMaxSize() / (double)m_AvgBytesPerSec;
-}
-
-
-bool CCoreAudioAEStream::IsPaused()
-{
-  return m_paused;
-}
-
-bool CCoreAudioAEStream::IsDraining()
-{
-  return m_draining;
-}
-
-bool CCoreAudioAEStream::IsDestroyed()
-{
-  return m_delete;
-}
-
-bool CCoreAudioAEStream::IsValid()
-{
-  return m_valid;
-}
-
-void CCoreAudioAEStream::Pause()
-{
-  m_paused = true;
-}
-
-void CCoreAudioAEStream::Resume()
-{
-#if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV)
-  if (CAEFactory::IsSuspended())
-    CAEFactory::Resume();
-#endif
-  m_paused = false;
-}
-
-void CCoreAudioAEStream::Drain(bool wait)
-{
-  m_draining = true;
-}
-
-bool CCoreAudioAEStream::IsDrained()
-{
-  return m_Buffer->GetReadSize() == 0;
-}
-
-void CCoreAudioAEStream::Flush()
-{
-  if (m_Buffer)
-    m_flushRequested = true;
-}
-
-float CCoreAudioAEStream::GetVolume()
-{
-  return m_volume;
-}
-
-float CCoreAudioAEStream::GetReplayGain()
-{
-  return m_rgain;
-}
-
-void  CCoreAudioAEStream::SetVolume(float volume)
-{
-  m_volume = std::max( 0.0f, std::min(1.0f, volume));
-}
-
-void  CCoreAudioAEStream::SetReplayGain(float factor)
-{
-  m_rgain  = std::max(-1.0f, std::max(1.0f, factor));
-}
-
-void CCoreAudioAEStream::InternalFlush()
-{
-  // reset the resampler
-  /*
-  if (m_resample) {
-    m_ssrcData.end_of_input = 0;
-    src_reset(m_ssrc);
-  }
-  */
-
-  // Read the buffer empty to avoid Reset
-  // Reset is not lock free.
-  if (m_Buffer)
-  {
-    unsigned int readsize = m_Buffer->GetReadSize();
-    if (readsize)
-    {
-      uint8_t *buffer = (uint8_t *)_aligned_malloc(readsize, 16);
-      m_Buffer->Read(buffer, readsize);
-      _aligned_free(buffer);
-    }
-
-    // if we are draining and are out of packets, tell the slave to resume
-    if (m_draining && m_slave)
-    {
-      m_slave->Resume();
-      m_slave = NULL;
-    }
-  }
-
-  m_flushRequested = false;
-  //if (m_Buffer)
-  //  m_Buffer->Reset();
-}
-
-const unsigned int CCoreAudioAEStream::GetChannelCount() const
-{
-  return m_chLayoutCountStream;
-}
-
-const unsigned int CCoreAudioAEStream::GetSampleRate() const
-{
-  return m_StreamFormat.m_sampleRate;
-}
-
-const unsigned int CCoreAudioAEStream::GetEncodedSampleRate() const
-{
-  return m_StreamFormat.m_encodedRate;
-}
-
-const enum AEDataFormat CCoreAudioAEStream::GetDataFormat() const
-{
-  return m_StreamFormat.m_dataFormat;
-}
-
-const bool CCoreAudioAEStream::IsRaw() const
-{
-  return m_isRaw;
-}
-
-double CCoreAudioAEStream::GetResampleRatio()
-{
-  /*
-  if (!m_resample)
-   return 1.0f;
-
-  double ret = m_ssrcData.src_ratio;
-  return ret;
-  */
-
-  return 1.0f;
-}
-
-bool CCoreAudioAEStream::SetResampleRatio(double ratio)
-{
-  return false;
-  /*
-  if (!m_resample)
-    return;
-
-  src_set_ratio(m_ssrc, ratio);
-  m_ssrcData.src_ratio = ratio;
-  */
-}
-
-void CCoreAudioAEStream::RegisterAudioCallback(IAudioCallback* pCallback)
-{
-  m_audioCallback = pCallback;
-  if (m_audioCallback)
-    m_audioCallback->OnInitialize(2, m_StreamFormat.m_sampleRate, 32);
-}
-
-void CCoreAudioAEStream::UnRegisterAudioCallback()
-{
-  m_audioCallback = NULL;
-}
-
-void CCoreAudioAEStream::FadeVolume(float from, float target, unsigned int time)
-{
-  if (m_isRaw)
-  {
-    m_fadeRunning = false;
-  }
-  else
-  {
-    float delta   = target - from;
-    m_fadeDirUp   = target > from;
-    m_fadeTarget  = target;
-    m_fadeStep    = delta / (((float)m_OutputFormat.m_sampleRate / 1000.0f) * (float)time);
-    m_fadeRunning = true;
-  }
-}
-
-bool CCoreAudioAEStream::IsFading()
-{
-  return m_fadeRunning;
-}
-
-void CCoreAudioAEStream::RegisterSlave(IAEStream *stream)
-{
-  m_slave = stream;
-}
-
-OSStatus CCoreAudioAEStream::Render(AudioUnitRenderActionFlags* actionFlags,
-  const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList)
-{
-  OSStatus ret = OnRender(actionFlags, pTimeStamp, busNumber, frameCount, pBufList);
-  return ret;
-}
-
-OSStatus CCoreAudioAEStream::OnRender(AudioUnitRenderActionFlags *ioActionFlags,
-  const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
-  // if we have no valid data output silence
-  if (!m_valid || m_delete || !m_Buffer || m_firstInput || m_paused)
-  {
-       for (UInt32 i = 0; i < ioData->mNumberBuffers; i++)
-      bzero(ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
-    if (ioActionFlags)
-      *ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
-    m_firstInput = false;
-    return noErr;
-  }
-
-  unsigned int size = inNumberFrames * m_OutputFormat.m_frameSize;
-  //unsigned int size = inNumberFrames * m_StreamFormat.m_frameSize;
-
-  // the index is important if we run encoded
-  unsigned int outputBufferIndex = AE.GetHAL()->GetBufferIndex();
-
-  ioData->mBuffers[outputBufferIndex].mDataByteSize  = GetFrames(
-    (uint8_t*)ioData->mBuffers[outputBufferIndex].mData, size);
-  if (!ioData->mBuffers[outputBufferIndex].mDataByteSize && ioActionFlags)
-    *ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
-
-  return noErr;
-}
-
-void CCoreAudioAEStream::ResetEncoder()
-{
-  if (m_encoder)
-    m_encoder->Reset();
-  m_unencodedBuffer.Empty();
-}
-
-bool CCoreAudioAEStream::SetupEncoder()
-{
-  ResetEncoder();
-  delete m_encoder;
-  m_encoder = NULL;
-  
-  if (!m_transcode)
-    return false;
-  
-  m_encoder = new CAEEncoderFFmpeg();
-  if (m_encoder && m_encoder->Initialize(m_encoderFormat))
-    return true;
-  
-  delete m_encoder;
-  m_encoder = NULL;
-  return false;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioAEStream.h
deleted file mode 100644 (file)
index ebb7201..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 <samplerate.h>
-#include <list>
-
-#include "ICoreAudioSource.h"
-#include "cores/AudioEngine/Utils/AEAudioFormat.h"
-#include "cores/AudioEngine/Interfaces/AEStream.h"
-#include "cores/AudioEngine/Utils/AEConvert.h"
-#include "cores/AudioEngine/Utils/AERemap.h"
-#include "cores/AudioEngine/Utils/AELimiter.h"
-#include "cores/AudioEngine/Utils/AERingBuffer.h"
-#include "cores/AudioEngine/Utils/AEBuffer.h"
-
-#if defined(TARGET_DARWIN_IOS)
-# include "CoreAudioAEHALIOS.h"
-#else
-# include "CoreAudioAEHALOSX.h"
-#endif
-
-class AERingBuffer;
-class CoreAudioRingBuffer;
-class IAEEncoder;
-
-class CCoreAudioAEStream : public IAEStream, public ICoreAudioSource
-{
-protected:
-  friend class CCoreAudioAE;
-  CCoreAudioAEStream(enum AEDataFormat format, unsigned int sampleRate, unsigned int encodedSamplerate, CAEChannelInfo channelLayout, unsigned int options, bool transcode);
-  virtual ~CCoreAudioAEStream();
-
-  CAUOutputDevice    *m_outputUnit;
-
-public:
-  void ReinitConverter();
-  void CloseConverter();
-  void OpenConverter();
-
-  void Initialize();
-  void InitializeRemap();
-  virtual void Destroy();
-
-  virtual const unsigned int GetFrameSize() const;
-  virtual unsigned int GetSpace();
-  virtual unsigned int AddData(void *data, unsigned int size);
-  unsigned int GetFrames(uint8_t *buffer, unsigned int size);
-  virtual double GetDelay();
-  virtual bool   IsBuffering();
-  virtual double GetCacheTime();
-  virtual double GetCacheTotal();
-
-  bool IsPaused();
-  virtual bool IsDraining();
-  virtual bool IsDrained();
-  bool IsDestroyed();
-  bool IsValid();
-
-  virtual void Pause();
-  virtual void Resume();
-  virtual void Drain(bool wait);
-  virtual void Flush();
-
-  virtual float GetVolume();
-  virtual float GetReplayGain();
-  virtual float GetAmplification() { return m_limiter.GetAmplification(); }
-  virtual void  SetVolume(float volume);
-  virtual void  SetReplayGain(float factor);
-  virtual void  SetAmplification(float amplify){ m_limiter.SetAmplification(amplify); }
-  
-  virtual float RunLimiter(float* frame, int channels) { return m_limiter.Run(&frame, channels); }
-
-  virtual const unsigned int      GetChannelCount() const;
-  virtual const unsigned int      GetSampleRate() const;
-  virtual const unsigned int      GetEncodedSampleRate() const;
-  virtual const enum AEDataFormat GetDataFormat() const;
-  virtual const bool              IsRaw() const;
-
-  /* for dynamic sample rate changes (smoothvideo) */
-  virtual double GetResampleRatio();
-  virtual bool   SetResampleRatio(double ratio);
-
-  virtual void RegisterAudioCallback(IAudioCallback* pCallback);
-  virtual void UnRegisterAudioCallback();
-
-  virtual void FadeVolume(float from, float to, unsigned int time);
-  virtual bool IsFading();
-  virtual void RegisterSlave(IAEStream *stream);
-
-  OSStatus Render(AudioUnitRenderActionFlags* actionFlags, 
-    const AudioTimeStamp* pTimeStamp, 
-    UInt32 busNumber, 
-    UInt32 frameCount, 
-    AudioBufferList* pBufList);
-
-private:
-  void InternalFlush();
-  void ResetEncoder();
-  bool SetupEncoder();
-
-  OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, 
-    const AudioTimeStamp *inTimeStamp, 
-    UInt32 inBusNumber, 
-    UInt32 inNumberFrames, 
-    AudioBufferList *ioData);
-
-  AEDataFormat            m_rawDataFormat;          /* the format we're output if we're outputting in raw mode */
-  AEDataFormat            m_incomingFormat;         /* the format of the stream being sent to us */
-
-  AEAudioFormat           m_OutputFormat;
-  unsigned int            m_chLayoutCountOutput;
-  AEAudioFormat           m_StreamFormat;
-  unsigned int            m_chLayoutCountStream;
-  unsigned int            m_StreamBytesPerSample;
-  unsigned int            m_OutputBytesPerSample;
-
-  //bool                    m_forceResample; /* true if we are to force resample even when the rates match */
-  //bool                    m_resample;      /* true if the audio needs to be resampled  */
-  bool                    m_transcode;     /* true if we need to transcode to ac3 */
-  bool                    m_convert;       /* true if the bitspersample needs converting */
-  bool                    m_valid;         /* true if the stream is valid */
-  bool                    m_delete;        /* true if CCoreAudioAE is to free this object */
-  CAERemap                m_remap;         /* the remapper */
-  float                   m_volume;        /* the volume level */
-  float                   m_rgain;         /* replay gain level */
-  CAELimiter              m_limiter;       /* volume amplification/limiter*/
-  IAEStream               *m_slave;        /* slave aestream */
-
-  CAEConvert::AEConvertToFn m_convertFn;
-
-  AERingBuffer           *m_Buffer;
-  float                  *m_convertBuffer;      /* buffer for converted data */
-  int                     m_convertBufferSize;
-  //float                  *m_resampleBuffer;     /* buffer for resample data */
-  //int                     m_resampleBufferSize;
-  uint8_t                *m_upmixBuffer;        /* buffer for remap data */
-  int                     m_upmixBufferSize;
-  uint8_t                *m_remapBuffer;        /* buffer for remap data */
-  int                     m_remapBufferSize;
-  uint8_t                *m_vizRemapBuffer;     /* buffer for remap data */
-  int                     m_vizRemapBufferSize;
-
-  SRC_STATE              *m_ssrc;
-  SRC_DATA                m_ssrcData;
-  bool                    m_paused;
-  bool                    m_draining;
-  unsigned int            m_AvgBytesPerSec;
-
-  /* vizualization internals */
-  CAERemap                m_vizRemap;
-  IAudioCallback         *m_audioCallback;
-
-  /* fade values */
-  bool              m_fadeRunning;
-  bool              m_fadeDirUp;
-  float             m_fadeStep;
-  float             m_fadeTarget;
-  unsigned int      m_fadeTime;
-  bool              m_isRaw;
-  unsigned int      m_frameSize;
-  bool              m_doRemap;
-  void              Upmix(void *input, unsigned int channelsInput, void *output, unsigned int channelsOutput, unsigned int frames, AEDataFormat dataFormat);
-  bool              m_firstInput;
-  bool              m_flushRequested;
-  
-  /* the encoder */
-  AEAudioFormat     m_encoderFormat;
-  IAEEncoder       *m_encoder;
-  CAEBuffer         m_unencodedBuffer;          /* this spools up the data before we encode it */
-};
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.cpp
deleted file mode 100644 (file)
index 8abecfa..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioChannelLayout.h"
-
-#include <AudioToolbox/AudioToolbox.h>
-
-#define MAX_CHANNEL_LABEL 15
-
-const char* g_ChannelLabels[] =
-{
-  "Unused",           // kAudioChannelLabel_Unused
-  "Left",             // kAudioChannelLabel_Left
-  "Right",            // kAudioChannelLabel_Right
-  "Center",           // kAudioChannelLabel_Center
-  "LFE",              // kAudioChannelLabel_LFEScreen
-  "Side Left",        // kAudioChannelLabel_LeftSurround
-  "Side Right",       // kAudioChannelLabel_RightSurround
-  "Left Center",      // kAudioChannelLabel_LeftCenter
-  "Right Center",     // kAudioChannelLabel_RightCenter
-  "Back Center",      // kAudioChannelLabel_CenterSurround
-  "Back Left",        // kAudioChannelLabel_LeftSurroundDirect
-  "Back Right",       // kAudioChannelLabel_RightSurroundDirect
-  "Top Center",       // kAudioChannelLabel_TopCenterSurround
-  "Top Back Left",    // kAudioChannelLabel_VerticalHeightLeft
-  "Top Back Center",  // kAudioChannelLabel_VerticalHeightCenter
-  "Top Back Right",   // kAudioChannelLabel_VerticalHeightRight
-};
-
-CCoreAudioChannelLayout::CCoreAudioChannelLayout() :
-  m_pLayout(NULL)
-{
-}
-
-CCoreAudioChannelLayout::CCoreAudioChannelLayout(AudioChannelLayout& layout) :
-m_pLayout(NULL)
-{
-  CopyLayout(layout);
-}
-
-CCoreAudioChannelLayout::~CCoreAudioChannelLayout()
-{
-  free(m_pLayout);
-}
-
-bool CCoreAudioChannelLayout::CopyLayout(AudioChannelLayout& layout)
-{
-  enum {
-    kVariableLengthArray_deprecated = 1
-  };
-
-    free(m_pLayout);
-  m_pLayout = NULL;
-
-  // This method always produces a layout with a ChannelDescriptions structure
-
-  OSStatus ret = 0;
-  UInt32 channels = GetChannelCountForLayout(layout);
-  UInt32 size = sizeof(AudioChannelLayout) + (channels - kVariableLengthArray_deprecated) * sizeof(AudioChannelDescription);
-
-  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
-  {
-    // We can copy the whole layout
-    m_pLayout = (AudioChannelLayout*)malloc(size);
-    memcpy(m_pLayout, &layout, size);
-  }
-  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
-  {
-    // Deconstruct the bitmap to get the layout
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize);
-    m_pLayout = (AudioChannelLayout*)malloc(propSize);
-    ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, m_pLayout);
-    m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
-  }
-  else
-  {
-    // Convert the known layout to a custom layout
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize);
-    m_pLayout = (AudioChannelLayout*)malloc(propSize);
-    ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, m_pLayout);
-    m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
-  }
-
-  return (ret == noErr);
-}
-
-UInt32 CCoreAudioChannelLayout::GetChannelCountForLayout(AudioChannelLayout& layout)
-{
-  UInt32 channels = 0;
-  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
-  {
-    // Channels are in fixed-order('USB Order'), any combination
-    UInt32 bitmap = layout.mChannelBitmap;
-    for (UInt32 c = 0; c < (sizeof(layout.mChannelBitmap) << 3); c++)
-    {
-      if (bitmap & 0x1)
-        channels++;
-      bitmap >>= 1;
-    }
-  }
-  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
-  {
-    // Channels are in any order, any combination
-    channels = layout.mNumberChannelDescriptions;
-  }
-  else
-  {
-    // Channels are in a predefined order and combination
-    channels = AudioChannelLayoutTag_GetNumberOfChannels(layout.mChannelLayoutTag);
-  }
-
-  return channels;
-}
-
-const char* CCoreAudioChannelLayout::ChannelLabelToString(UInt32 label)
-{
-  if (label > MAX_CHANNEL_LABEL)
-    return "Unknown";
-  return g_ChannelLabels[label];
-}
-
-const char* CCoreAudioChannelLayout::ChannelLayoutToString(AudioChannelLayout& layout, std::string& str)
-{
-  AudioChannelLayout* pLayout = NULL;
-
-  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
-  {
-    pLayout = &layout;
-  }
-  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
-  {
-    // Deconstruct the bitmap to get the layout
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap,
-      sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize);
-    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
-    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
-      sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, pLayout);
-  }
-  else
-  {
-    // Predefinied layout 'tag'
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize);
-    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
-    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, pLayout);
-  }
-
-  for (UInt32 c = 0; c < pLayout->mNumberChannelDescriptions; c++)
-  {
-    str += "[";
-    str += ChannelLabelToString(pLayout->mChannelDescriptions[c].mChannelLabel);
-    str += "] ";
-  }
-
-  if (layout.mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
-    free(pLayout);
-
-  return str.c_str();
-}
-
-bool CCoreAudioChannelLayout::AllChannelUnknown()
-{
-  AudioChannelLayout* pLayout = NULL;
-
-  if (!m_pLayout)
-    return false;
-
-  if (m_pLayout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
-  {
-    pLayout = m_pLayout;
-  }
-  else if (m_pLayout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
-  {
-    // Deconstruct the bitmap to get the layout
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap,
-      sizeof(m_pLayout->mChannelBitmap), &m_pLayout->mChannelBitmap, &propSize);
-    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
-    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
-      sizeof(m_pLayout->mChannelBitmap), &m_pLayout->mChannelBitmap, &propSize, pLayout);
-  }
-  else
-  {
-    // Predefinied layout 'tag'
-    UInt32 propSize = 0;
-    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(m_pLayout->mChannelLayoutTag), &m_pLayout->mChannelLayoutTag, &propSize);
-    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
-    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
-      sizeof(m_pLayout->mChannelLayoutTag), &m_pLayout->mChannelLayoutTag, &propSize, pLayout);
-  }
-
-  for (UInt32 c = 0; c < pLayout->mNumberChannelDescriptions; c++)
-  {
-    if (pLayout->mChannelDescriptions[c].mChannelLabel != kAudioChannelLabel_Unknown)
-    {
-      return false;
-    }
-  }
-
-  if (m_pLayout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
-    free(pLayout);
-
-  return true;
-}
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioChannelLayout.h
deleted file mode 100644 (file)
index cf95c83..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-#include <list>
-#include <vector>
-#include <string>
-
-#include <CoreAudio/CoreAudio.h>
-
-typedef std::vector<SInt32> CoreAudioChannelList;
-typedef std::list<AudioChannelLayoutTag> AudioChannelLayoutList;
-
-const AudioChannelLayoutTag g_LayoutMap[] =
-{
-  kAudioChannelLayoutTag_Stereo,            // PCM_LAYOUT_2_0 = 0,
-  kAudioChannelLayoutTag_Stereo,            // PCM_LAYOUT_2_0 = 0,
-  kAudioChannelLayoutTag_DVD_4,             // PCM_LAYOUT_2_1,
-  kAudioChannelLayoutTag_MPEG_3_0_A,        // PCM_LAYOUT_3_0,
-  kAudioChannelLayoutTag_DVD_10,            // PCM_LAYOUT_3_1,
-  kAudioChannelLayoutTag_DVD_3,             // PCM_LAYOUT_4_0,
-  kAudioChannelLayoutTag_DVD_6,             // PCM_LAYOUT_4_1,
-  kAudioChannelLayoutTag_MPEG_5_0_A,        // PCM_LAYOUT_5_0,
-  kAudioChannelLayoutTag_MPEG_5_1_A,        // PCM_LAYOUT_5_1,
-  kAudioChannelLayoutTag_AudioUnit_7_0,     // PCM_LAYOUT_7_0, ** This layout may be incorrect...no content to testß˚ **
-  kAudioChannelLayoutTag_MPEG_7_1_A,        // PCM_LAYOUT_7_1
-};
-
-const AudioChannelLabel g_LabelMap[] =
-{
-  kAudioChannelLabel_Unused,                // PCM_FRONT_LEFT,
-  kAudioChannelLabel_Left,                  // PCM_FRONT_LEFT,
-  kAudioChannelLabel_Right,                 // PCM_FRONT_RIGHT,
-  kAudioChannelLabel_Center,                // PCM_FRONT_CENTER,
-  kAudioChannelLabel_LFEScreen,             // PCM_LOW_FREQUENCY,
-  kAudioChannelLabel_LeftSurroundDirect,    // PCM_BACK_LEFT, *** This is incorrect, but has been changed to match dvdplayer
-  kAudioChannelLabel_RightSurroundDirect,   // PCM_BACK_RIGHT, *** This is incorrect, but has been changed to match dvdplayer
-  kAudioChannelLabel_LeftCenter,            // PCM_FRONT_LEFT_OF_CENTER,
-  kAudioChannelLabel_RightCenter,           // PCM_FRONT_RIGHT_OF_CENTER,
-  kAudioChannelLabel_CenterSurround,        // PCM_BACK_CENTER,
-  kAudioChannelLabel_LeftSurround,          // PCM_SIDE_LEFT, *** This is incorrect, but has been changed to match dvdplayer
-  kAudioChannelLabel_RightSurround,         // PCM_SIDE_RIGHT, *** This is incorrect, but has been changed to match dvdplayer
-  kAudioChannelLabel_VerticalHeightLeft,    // PCM_TOP_FRONT_LEFT,
-  kAudioChannelLabel_VerticalHeightRight,   // PCM_TOP_FRONT_RIGHT,
-  kAudioChannelLabel_VerticalHeightCenter,  // PCM_TOP_FRONT_CENTER,
-  kAudioChannelLabel_TopCenterSurround,     // PCM_TOP_CENTER,
-  kAudioChannelLabel_TopBackLeft,           // PCM_TOP_BACK_LEFT,
-  kAudioChannelLabel_TopBackRight,          // PCM_TOP_BACK_RIGHT,
-  kAudioChannelLabel_TopBackCenter          // PCM_TOP_BACK_CENTER
-};
-
-class CCoreAudioChannelLayout
-{
-public:
-  CCoreAudioChannelLayout();
-  CCoreAudioChannelLayout(AudioChannelLayout &layout);
-  virtual ~CCoreAudioChannelLayout();
-
-  operator AudioChannelLayout*() {return m_pLayout;}
-
-  bool                CopyLayout(AudioChannelLayout &layout);
-  static UInt32       GetChannelCountForLayout(AudioChannelLayout &layout);
-  static const char*  ChannelLabelToString(UInt32 label);
-  static const char*  ChannelLayoutToString(AudioChannelLayout &layout, std::string &str);
-  bool                AllChannelUnknown();
-protected:
-  AudioChannelLayout* m_pLayout;
-};
-
-#endif
\ No newline at end of file
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.cpp
deleted file mode 100644 (file)
index a03673f..0000000
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioDevice.h"
-#include "CoreAudioAEHAL.h"
-#include "CoreAudioChannelLayout.h"
-#include "CoreAudioHardware.h"
-#include "utils/log.h"
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CCoreAudioDevice
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoreAudioDevice::CCoreAudioDevice()  :
-  m_Started             (false    ),
-  m_pSource             (NULL     ),
-  m_DeviceId            (0        ),
-  m_MixerRestore        (-1       ),
-  m_IoProc              (NULL     ),
-  m_ObjectListenerProc  (NULL     ),
-  m_SampleRateRestore   (0.0f     ),
-  m_HogPid              (-1       ),
-  m_frameSize           (0        ),
-  m_OutputBufferIndex   (0        ),
-  m_BufferSizeRestore   (0        )
-{
-}
-
-CCoreAudioDevice::CCoreAudioDevice(AudioDeviceID deviceId) :
-  m_Started             (false    ),
-  m_pSource             (NULL     ),
-  m_DeviceId            (deviceId ),
-  m_MixerRestore        (-1       ),
-  m_IoProc              (NULL     ),
-  m_ObjectListenerProc  (NULL     ),
-  m_SampleRateRestore   (0.0f     ),
-  m_HogPid              (-1       ),
-  m_frameSize           (0        ),
-  m_OutputBufferIndex   (0        ),
-  m_BufferSizeRestore   (0        )
-{
-}
-
-CCoreAudioDevice::~CCoreAudioDevice()
-{
-  Close();
-}
-
-bool CCoreAudioDevice::Open(AudioDeviceID deviceId)
-{
-  m_DeviceId = deviceId;
-  m_BufferSizeRestore = GetBufferSize();
-  return true;
-}
-
-void CCoreAudioDevice::Close()
-{
-  if (!m_DeviceId)
-    return;
-
-  // Stop the device if it was started
-  Stop();
-
-  // Unregister the IOProc if we have one
-  if (m_IoProc)
-    SetInputSource(NULL, 0, 0);
-
-  SetHogStatus(false);
-  CCoreAudioHardware::SetAutoHogMode(false);
-
-  if (m_MixerRestore > -1) // We changed the mixer status
-    SetMixingSupport((m_MixerRestore ? true : false));
-  m_MixerRestore = -1;
-
-  if (m_SampleRateRestore != 0.0f)
-    SetNominalSampleRate(m_SampleRateRestore);
-
-  if (m_BufferSizeRestore && m_BufferSizeRestore != GetBufferSize())
-  {
-    SetBufferSize(m_BufferSizeRestore);
-    m_BufferSizeRestore = 0;
-  }
-
-  m_IoProc = NULL;
-  m_pSource = NULL;
-  m_DeviceId = 0;
-  m_ObjectListenerProc = NULL;
-}
-
-void CCoreAudioDevice::Start()
-{
-  if (!m_DeviceId || m_Started)
-    return;
-
-  OSStatus ret = AudioDeviceStart(m_DeviceId, m_IoProc);
-  if (ret)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::Start: "
-      "Unable to start device. Error = %s", GetError(ret).c_str());
-  else
-    m_Started = true;
-}
-
-void CCoreAudioDevice::Stop()
-{
-  if (!m_DeviceId || !m_Started)
-    return;
-
-  OSStatus ret = AudioDeviceStop(m_DeviceId, m_IoProc);
-  if (ret)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::Stop: "
-      "Unable to stop device. Error = %s", GetError(ret).c_str());
-  m_Started = false;
-}
-
-void CCoreAudioDevice::RemoveObjectListenerProc(AudioObjectPropertyListenerProc callback, void* pClientData)
-{
-  if (!m_DeviceId)
-    return;
-
-  AudioObjectPropertyAddress audioProperty;
-  audioProperty.mSelector = kAudioObjectPropertySelectorWildcard;
-  audioProperty.mScope = kAudioObjectPropertyScopeWildcard;
-  audioProperty.mElement = kAudioObjectPropertyElementWildcard;
-
-  OSStatus ret = AudioObjectRemovePropertyListener(m_DeviceId, &audioProperty, callback, pClientData);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::RemoveObjectListenerProc: "
-      "Unable to set ObjectListener callback. Error = %s", GetError(ret).c_str());
-  }
-  m_ObjectListenerProc = NULL;
-}
-
-bool CCoreAudioDevice::SetObjectListenerProc(AudioObjectPropertyListenerProc callback, void* pClientData)
-{
-  // Allow only one ObjectListener at a time
-  if (!m_DeviceId || m_ObjectListenerProc)
-    return false;
-
-  AudioObjectPropertyAddress audioProperty;
-  audioProperty.mSelector = kAudioObjectPropertySelectorWildcard;
-  audioProperty.mScope = kAudioObjectPropertyScopeWildcard;
-  audioProperty.mElement = kAudioObjectPropertyElementWildcard;
-
-  OSStatus ret = AudioObjectAddPropertyListener(m_DeviceId, &audioProperty, callback, pClientData);
-
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetObjectListenerProc: "
-      "Unable to remove ObjectListener callback. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_ObjectListenerProc = callback;
-  return true;
-}
-
-bool CCoreAudioDevice::SetInputSource(ICoreAudioSource* pSource, unsigned int frameSize, unsigned int outputBufferIndex)
-{
-  m_pSource   = pSource;
-  m_frameSize = frameSize;
-  m_OutputBufferIndex = outputBufferIndex;
-
-  if (pSource)
-    return AddIOProc();
-  else
-    return RemoveIOProc();
-}
-
-bool CCoreAudioDevice::AddIOProc()
-{
-  // Allow only one IOProc at a time
-  if (!m_DeviceId || m_IoProc)
-    return false;
-
-  OSStatus ret = AudioDeviceCreateIOProcID(m_DeviceId, DirectRenderCallback, this, &m_IoProc);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::AddIOProc: "
-      "Unable to add IOProc. Error = %s", GetError(ret).c_str());
-    m_IoProc = NULL;
-    return false;
-  }
-
-  Start();
-
-  return true;
-}
-
-bool CCoreAudioDevice::RemoveIOProc()
-{
-  if (!m_DeviceId || !m_IoProc)
-    return false;
-
-  Stop();
-
-  OSStatus ret = AudioDeviceDestroyIOProcID(m_DeviceId, m_IoProc);
-  if (ret)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::RemoveIOProc: "
-      "Unable to remove IOProc. Error = %s", GetError(ret).c_str());
-
-  m_IoProc = NULL; // Clear the reference no matter what
-  m_pSource = NULL;
-
-  Sleep(100);
-
-  return true;
-}
-
-std::string CCoreAudioDevice::GetName()
-{
-  if (!m_DeviceId)
-    return NULL;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
-
-  UInt32 propertySize;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
-  if (ret != noErr)
-    return NULL;
-
-  std::string name = "";
-  char *buff = new char[propertySize + 1];
-  buff[propertySize] = 0x00;
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, buff);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::GetName: "
-      "Unable to get device name - id: 0x%04x. Error = %s", (uint)m_DeviceId, GetError(ret).c_str());
-  }
-  else
-  {
-    name = buff;
-  }
-  delete[] buff;
-
-
-  return name;
-}
-
-UInt32 CCoreAudioDevice::GetTotalOutputChannels()
-{
-  UInt32 channels = 0;
-
-  if (!m_DeviceId)
-    return channels;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration;
-
-  UInt32 size = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &size);
-  if (ret != noErr)
-    return channels;
-
-  AudioBufferList* pList = (AudioBufferList*)malloc(size);
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, pList);
-  if (ret == noErr)
-  {
-    for(UInt32 buffer = 0; buffer < pList->mNumberBuffers; ++buffer)
-      channels += pList->mBuffers[buffer].mNumberChannels;
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::GetTotalOutputChannels: "
-      "Unable to get total device output channels - id: 0x%04x. Error = %s",
-      (uint)m_DeviceId, GetError(ret).c_str());
-  }
-
-  free(pList);
-
-  return channels;
-}
-
-bool CCoreAudioDevice::GetStreams(AudioStreamIdList* pList)
-{
-  if (!pList || !m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyStreams;
-
-  UInt32  propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
-  if (ret != noErr)
-    return false;
-
-  UInt32 streamCount = propertySize / sizeof(AudioStreamID);
-  AudioStreamID* pStreamList = new AudioStreamID[streamCount];
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pStreamList);
-  if (ret == noErr)
-  {
-    for (UInt32 stream = 0; stream < streamCount; stream++)
-      pList->push_back(pStreamList[stream]);
-  }
-  delete[] pStreamList;
-
-  return ret == noErr;
-}
-
-
-bool CCoreAudioDevice::IsRunning()
-{
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyDeviceIsRunning;
-
-  UInt32 isRunning = 0;
-  UInt32 propertySize = sizeof(isRunning);
-  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &isRunning);
-  if (ret != noErr)
-    return false;
-
-  return isRunning != 0;
-}
-
-bool CCoreAudioDevice::SetHogStatus(bool hog)
-{
-  // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode
-  // is a toggle and the only way to tell if you do get hog mode is to compare
-  // the returned pid against getpid, if the match, you have hog mode, if not you don't.
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyHogMode;
-
-  if (hog)
-  {
-    // Not already set
-    if (m_HogPid == -1)
-    {
-      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid);
-
-      // even if setting hogmode was successfull our PID might not get written
-      // into m_HogPid (so it stays -1). Readback hogstatus for judging if we
-      // had success on getting hog status
-      // We do this only when AudioObjectSetPropertyData didn't set m_HogPid because
-      // it seems that in the other cases the GetHogStatus could return -1
-      // which would overwrite our valid m_HogPid again
-      // Man we should never touch this shit again ;)
-      if (m_HogPid == -1)
-        m_HogPid = GetHogStatus();
-
-      if (ret || m_HogPid != getpid())
-      {
-        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
-          "Unable to set 'hog' status. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-    }
-  }
-  else
-  {
-    // Currently Set
-    if (m_HogPid > -1)
-    {
-      pid_t hogPid = -1;
-      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid);
-      if (ret || hogPid == getpid())
-      {
-        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
-          "Unable to release 'hog' status. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-      // Reset internal state
-      m_HogPid = hogPid;
-    }
-  }
-  return true;
-}
-
-pid_t CCoreAudioDevice::GetHogStatus()
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyHogMode;
-
-  pid_t hogPid = -1;
-  UInt32 size = sizeof(hogPid);
-  AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, &hogPid);
-
-  return hogPid;
-}
-
-bool CCoreAudioDevice::SetMixingSupport(UInt32 mix)
-{
-  if (!m_DeviceId)
-    return false;
-
-  if (!GetMixingSupport())
-    return false;
-
-  int restore = -1;
-  if (m_MixerRestore == -1)
-  {
-    // This is our first change to this setting. Store the original setting for restore
-    restore = (GetMixingSupport() ? 1 : 0);
-  }
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertySupportsMixing;
-
-  UInt32 mixEnable = mix ? 1 : 0;
-  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(mixEnable), &mixEnable);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetMixingSupport: "
-      "Unable to set MixingSupport to %s. Error = %s", mix ? "'On'" : "'Off'", GetError(ret).c_str());
-    return false;
-  }
-  if (m_MixerRestore == -1)
-    m_MixerRestore = restore;
-  return true;
-}
-
-bool CCoreAudioDevice::GetMixingSupport()
-{
-  if (!m_DeviceId)
-    return false;
-
-  UInt32    size;
-  UInt32    mix = 0;
-  Boolean   writable = false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertySupportsMixing;
-
-  if( AudioObjectHasProperty( m_DeviceId, &propertyAddress ) )
-  {
-    OSStatus ret = AudioObjectIsPropertySettable(m_DeviceId, &propertyAddress, &writable);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioDevice::SupportsMixing: "
-        "Unable to get propertyinfo mixing support. Error = %s", GetError(ret).c_str());
-      writable = false;
-    }
-
-    if (writable)
-    {
-      size = sizeof(mix);
-      ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, &mix);
-      if (ret != noErr)
-        mix = 0;
-    }
-  }
-  CLog::Log(LOGERROR, "CCoreAudioDevice::SupportsMixing: "
-    "Device mixing support : %s.", mix ? "'Yes'" : "'No'");
-
-  return (mix > 0);
-}
-
-bool CCoreAudioDevice::SetCurrentVolume(Float32 vol)
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kHALOutputParam_Volume;
-
-  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float32), &vol);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetCurrentVolume: "
-      "Unable to set AudioUnit volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioDevice::GetPreferredChannelLayout(CCoreAudioChannelLayout& layout)
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyPreferredChannelLayout;
-
-  UInt32 propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
-  if (ret)
-    return false;
-
-  void* pBuf = malloc(propertySize);
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pBuf);
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::GetPreferredChannelLayout: "
-      "Unable to retrieve preferred channel layout. Error = %s", GetError(ret).c_str());
-  else
-  {
-    // Copy the result into the caller's instance
-    layout.CopyLayout(*((AudioChannelLayout*)pBuf));
-  }
-  free(pBuf);
-  return (ret == noErr);
-}
-
-bool CCoreAudioDevice::GetDataSources(CoreAudioDataSourceList* pList)
-{
-  if (!pList || !m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyDataSources;
-
-  UInt32 propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
-  if (ret != noErr)
-    return false;
-
-  UInt32  sources = propertySize / sizeof(UInt32);
-  UInt32* pSources = new UInt32[sources];
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pSources);
-  if (ret == noErr)
-  {
-    for (UInt32 i = 0; i < sources; i++)
-      pList->push_back(pSources[i]);
-  }
-  delete[] pSources;
-  return (!ret);
-}
-
-Float64 CCoreAudioDevice::GetNominalSampleRate()
-{
-  if (!m_DeviceId)
-    return 0.0f;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
-
-  Float64 sampleRate = 0.0f;
-  UInt32  propertySize = sizeof(Float64);
-  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &sampleRate);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::GetNominalSampleRate: "
-      "Unable to retrieve current device sample rate. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return sampleRate;
-}
-
-bool CCoreAudioDevice::SetNominalSampleRate(Float64 sampleRate)
-{
-  if (!m_DeviceId || sampleRate == 0.0f)
-    return false;
-
-  Float64 currentRate = GetNominalSampleRate();
-  if (currentRate == sampleRate)
-    return true; //No need to change
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
-
-  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float64), &sampleRate);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetNominalSampleRate: "
-      "Unable to set current device sample rate to %0.0f. Error = %s",
-      (float)sampleRate, GetError(ret).c_str());
-    return false;
-  }
-  if (m_SampleRateRestore == 0.0f)
-    m_SampleRateRestore = currentRate;
-
-  return true;
-}
-
-UInt32 CCoreAudioDevice::GetNumLatencyFrames()
-{
-  UInt32 num_latency_frames = 0;
-  if (!m_DeviceId)
-    return 0;
-
-  // number of frames of latency in the AudioDevice
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyLatency;
-
-  UInt32 i_param = 0;
-  UInt32 i_param_size = sizeof(uint32_t);
-  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
-  if (ret == noErr)
-    num_latency_frames += i_param;
-
-  // number of frames in the IO buffers
-  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
-  if (ret == noErr)
-    num_latency_frames += i_param;
-
-  // number for frames in ahead the current hardware position that is safe to do IO
-  propertyAddress.mSelector = kAudioDevicePropertySafetyOffset;
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
-  if (ret == noErr)
-    num_latency_frames += i_param;
-
-  return (num_latency_frames);
-}
-
-UInt32 CCoreAudioDevice::GetBufferSize()
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
-
-  UInt32 size = 0;
-  UInt32 propertySize = sizeof(size);
-  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &size);
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::GetBufferSize: "
-      "Unable to retrieve buffer size. Error = %s", GetError(ret).c_str());
-  return size;
-}
-
-bool CCoreAudioDevice::SetBufferSize(UInt32 size)
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
-
-  UInt32 propertySize = sizeof(size);
-  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, propertySize, &size);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: "
-      "Unable to set buffer size. Error = %s", GetError(ret).c_str());
-  }
-
-  if (GetBufferSize() != size)
-    CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: Buffer size change not applied.");
-
-  return (ret == noErr);
-}
-
-OSStatus CCoreAudioDevice::DirectRenderCallback(AudioDeviceID inDevice,
-  const AudioTimeStamp  *inNow,
-  const AudioBufferList *inInputData,
-  const AudioTimeStamp  *inInputTime,
-  AudioBufferList       *outOutputData,
-  const AudioTimeStamp  *inOutputTime,
-  void                  *inClientData)
-{
-  OSStatus ret = noErr;
-  CCoreAudioDevice *audioDevice = (CCoreAudioDevice*)inClientData;
-
-  if (audioDevice->m_pSource && audioDevice->m_frameSize)
-  {
-    UInt32 frames = outOutputData->mBuffers[audioDevice->m_OutputBufferIndex].mDataByteSize / audioDevice->m_frameSize;
-    ret = audioDevice->m_pSource->Render(NULL, inInputTime, 0, frames, outOutputData);
-  }
-  else
-  {
-    outOutputData->mBuffers[audioDevice->m_OutputBufferIndex].mDataByteSize = 0;
-  }
-
-  return ret;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioDevice.h
deleted file mode 100644 (file)
index b94a256..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-
-#include <string>
-
-#include "ICoreAudioSource.h"
-#include "CoreAudioStream.h"
-
-#include <CoreAudio/CoreAudio.h>
-
-typedef std::list<UInt32> CoreAudioDataSourceList;
-typedef std::list<AudioDeviceID> CoreAudioDeviceList;
-
-class CCoreAudioChannelLayout;
-
-class CCoreAudioDevice
-{
-public:
-  CCoreAudioDevice();
-  CCoreAudioDevice(AudioDeviceID deviceId);
-  virtual ~CCoreAudioDevice();
-  
-  bool          Open(AudioDeviceID deviceId);
-  void          Close();
-  
-  void          Start();
-  void          Stop();
-  void          RemoveObjectListenerProc(AudioObjectPropertyListenerProc callback, void *pClientData);
-  bool          SetObjectListenerProc(AudioObjectPropertyListenerProc callback, void *pClientData);
-  
-  AudioDeviceID GetId() {return m_DeviceId;}
-  std::string   GetName();
-  UInt32        GetTotalOutputChannels();
-  bool          GetStreams(AudioStreamIdList *pList);
-  bool          IsRunning();
-  bool          SetHogStatus(bool hog);
-  pid_t         GetHogStatus();
-  bool          SetMixingSupport(UInt32 mix);
-  bool          GetMixingSupport();
-  bool          SetCurrentVolume(Float32 vol);
-  bool          GetPreferredChannelLayout(CCoreAudioChannelLayout &layout);
-  bool          GetDataSources(CoreAudioDataSourceList *pList);
-  Float64       GetNominalSampleRate();
-  bool          SetNominalSampleRate(Float64 sampleRate);
-  UInt32        GetNumLatencyFrames();
-  UInt32        GetBufferSize();
-  bool          SetBufferSize(UInt32 size);
-
-  virtual bool  SetInputSource(ICoreAudioSource *pSource, unsigned int frameSize, unsigned int outputBufferIndex);
-protected:
-  bool          AddIOProc();
-  bool          RemoveIOProc();
-
-  static OSStatus DirectRenderCallback(AudioDeviceID inDevice, 
-    const AudioTimeStamp *inNow, const AudioBufferList *inInputData, const AudioTimeStamp *inInputTime, 
-    AudioBufferList *outOutputData, const AudioTimeStamp *inOutputTime, void *inClientData);
-
-  bool              m_Started;
-  ICoreAudioSource *m_pSource;
-  AudioDeviceID     m_DeviceId;
-  int               m_MixerRestore;
-  AudioDeviceIOProc m_IoProc;
-  AudioObjectPropertyListenerProc m_ObjectListenerProc;
-  
-  Float64           m_SampleRateRestore;
-  pid_t             m_HogPid;
-  unsigned int      m_frameSize;
-  unsigned int      m_OutputBufferIndex;
-  unsigned int      m_BufferSizeRestore;
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.cpp
deleted file mode 100644 (file)
index e55e300..0000000
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioGraph.h"
-
-#include "CoreAudioAEHAL.h"
-#include "CoreAudioMixMap.h"
-#include "CoreAudioUnit.h"
-
-#include "utils/log.h"
-#include "utils/SystemInfo.h"
-
-CCoreAudioGraph::CCoreAudioGraph() :
-  m_audioGraph    (NULL ),
-  m_inputUnit     (NULL ),
-  m_audioUnit     (NULL ),
-  m_mixerUnit     (NULL ),
-  m_initialized   (false),
-  m_deviceId      (NULL ),
-  m_allowMixing   (false),
-  m_mixMap        (NULL )
-{
-  for (int i = 0; i < MAX_CONNECTION_LIMIT; i++)
-  {
-    m_reservedBusNumber[i] = false;
-  }
-}
-
-CCoreAudioGraph::~CCoreAudioGraph()
-{
-  Close();
-
-  delete m_mixMap;
-}
-
-bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format,
-  AudioDeviceID deviceId, bool allowMixing, AudioChannelLayoutTag layoutTag, float initVolume, bool encoded)
-{
-  AudioStreamBasicDescription fmt = {0};
-  AudioStreamBasicDescription inputFormat = {0};
-  AudioStreamBasicDescription outputFormat = {0};
-
-  m_deviceId = deviceId;
-  m_allowMixing = allowMixing;
-
-  OSStatus ret = NewAUGraph(&m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error create audio grpah. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  ret = AUGraphOpen(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error open audio grpah. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  // get output unit
-  if (m_audioUnit)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error audio unit already open. double call ?");
-    return false;
-  }
-
-  m_audioUnit = new CAUOutputDevice();
-  if (!m_audioUnit->Open(m_audioGraph,
-    kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple))
-    return false;
-  m_audioUnit->SetBus(GetFreeBus());
-
-  m_audioUnit->GetFormatDesc(format, &inputFormat, &fmt, encoded);
-
-  if (!m_audioUnit->EnableInputOuput())
-    return false;
-
-  if (!m_audioUnit->SetCurrentDevice(deviceId))
-    return false;
-
-  SetCurrentVolume(initVolume);
-
-  if (allowMixing)
-  {
-    delete m_mixMap;
-    m_mixMap = CCoreAudioMixMap::CreateMixMap(m_audioUnit, format, layoutTag);
-
-    if (m_mixMap && m_mixMap->IsValid())
-    {
-      // maximum input channel ber input bus
-      //fmt.mChannelsPerFrame = MAXIMUM_MIXER_CHANNELS;
-
-      // get output unit
-      if (m_inputUnit)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?");
-        return false;
-      }
-
-      m_inputUnit = new CAUOutputDevice();
-
-      if (!m_inputUnit->Open(m_audioGraph,
-        kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple))
-        return false;
-
-      if (!m_inputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus))
-        return false;
-
-      if (!m_inputUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus))
-        return false;
-
-      // get mixer unit
-      if (m_mixerUnit)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?");
-        return false;
-      }
-
-      m_mixerUnit = new CAUMatrixMixer();
-
-      if (!m_mixerUnit->Open(m_audioGraph,
-        kAudioUnitType_Mixer, kAudioUnitSubType_MatrixMixer, kAudioUnitManufacturer_Apple))
-        return false;
-
-      // set number of input buses
-      if (!m_mixerUnit->SetInputBusCount(MAX_CONNECTION_LIMIT))
-        return false;
-
-      // set number of output buses
-      if (!m_mixerUnit->SetOutputBusCount(1))
-        return false;
-
-      if (!m_mixerUnit->SetInputBusFormat(MAX_CONNECTION_LIMIT, &fmt))
-        return false;
-
-      // Update format structure to reflect the desired format from the mixer
-      // The output format of the mixer is identical to the input format, except for the channel count
-      AudioStreamBasicDescription mixOutput(fmt);
-      mixOutput.mChannelsPerFrame = m_mixMap->GetOutputChannels();
-
-      if (!m_mixerUnit->SetFormat(&mixOutput, kAudioUnitScope_Output, kOutputBus))
-        return false;
-
-      ret =  AUGraphConnectNodeInput(m_audioGraph, m_mixerUnit->GetNode(), 0, m_audioUnit->GetNode(), 0);
-      if (ret)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-          "Error connecting m_m_mixerNode. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-
-      m_mixerUnit->SetBus(0);
-
-      // configure output unit
-      int busNumber = GetFreeBus();
-
-      ret = AUGraphConnectNodeInput(m_audioGraph, m_inputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber);
-      if (ret)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-          "Error connecting m_converterNode. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-
-      m_inputUnit->SetBus(busNumber);
-
-      ret = AUGraphUpdate(m_audioGraph, NULL);
-      if (ret)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-          "Error update graph. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-      ret = AUGraphInitialize(m_audioGraph);
-      if (ret)
-      {
-        CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-          "Error initialize graph. Error = %s", GetError(ret).c_str());
-        return false;
-      }
-
-      UInt32 inputNumber = m_inputUnit->GetBus();
-      int channelOffset = GetMixerChannelOffset(inputNumber);
-      if (!CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &fmt, &mixOutput, channelOffset))
-        return false;
-
-      // Regenerate audio format and copy format for the Output AU
-      outputFormat = mixOutput;
-    }
-    else
-    {
-      outputFormat = inputFormat;
-    }
-
-  }
-  else
-  {
-    outputFormat = inputFormat;
-  }
-
-  if (!m_audioUnit->SetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus))
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error setting input format on audio device. Channel count %d, set it to %d",
-      (int)outputFormat.mChannelsPerFrame, format.m_channelLayout.Count());
-    outputFormat.mChannelsPerFrame = format.m_channelLayout.Count();
-    if (!m_audioUnit->SetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus))
-      return false;
-  }
-
-  std::string formatString;
-  // asume we are in dd-wave mode
-  if (!m_inputUnit)
-  {
-    if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Output, kInputBus))
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-        "Error setting Device Output Stream Format %s",
-        StreamDescriptionToString(inputFormat, formatString));
-    }
-  }
-
-  ret = AUGraphUpdate(m_audioGraph, NULL);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error update graph. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  AudioStreamBasicDescription inputDesc_end, outputDesc_end;
-  m_audioUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-  m_audioUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kInputBus);
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: audioUnit, Input Stream Format  %s",
-    StreamDescriptionToString(inputDesc_end, formatString));
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: audioUnit, Output Stream Format %s",
-    StreamDescriptionToString(outputDesc_end, formatString));
-
-  if (m_mixerUnit)
-  {
-    m_mixerUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-    m_mixerUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus);
-    CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: mixerUnit, Input Stream Format  %s",
-      StreamDescriptionToString(inputDesc_end, formatString));
-    CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: mixerUnit, Output Stream Format %s",
-      StreamDescriptionToString(outputDesc_end, formatString));
-  }
-
-  if (m_inputUnit)
-  {
-    m_inputUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus);
-    m_inputUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus);
-    CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: inputUnit, Input Stream Format  %s",
-      StreamDescriptionToString(inputDesc_end, formatString));
-    CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: inputUnit, Output Stream Format %s",
-      StreamDescriptionToString(outputDesc_end, formatString));
-  }
-
-  ret = AUGraphInitialize(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error initialize graph. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  UInt32 bufferFrames = m_audioUnit->GetBufferFrameSize();
-  if (!m_audioUnit->SetMaxFramesPerSlice(bufferFrames))
-    return false;
-
-  SetInputSource(pSource);
-
-  return Start();
-}
-
-bool CCoreAudioGraph::Close()
-{
-  if (!m_audioGraph)
-    return false;
-
-  Stop();
-
-  SetInputSource(NULL);
-
-  while (!m_auUnitList.empty())
-  {
-    CAUOutputDevice *d = m_auUnitList.front();
-    m_auUnitList.pop_front();
-    ReleaseBus(d->GetBus());
-    d->SetInputSource(NULL);
-    d->Close();
-    delete d;
-  }
-
-  if (m_inputUnit)
-  {
-    ReleaseBus(m_inputUnit->GetBus());
-    m_inputUnit->Close();
-    delete m_inputUnit;
-    m_inputUnit = NULL;
-  }
-
-  if (m_mixerUnit)
-  {
-    m_mixerUnit->Close();
-    delete m_mixerUnit;
-    m_mixerUnit = NULL;
-  }
-
-  if (m_audioUnit)
-  {
-    m_audioUnit->Close();
-    delete m_audioUnit;
-    m_audioUnit = NULL;
-  }
-
-  OSStatus ret = AUGraphUninitialize(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: "
-      "Error unitialize. Error = %s", GetError(ret).c_str());
-  }
-
-  ret = AUGraphClose(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: "
-      "Error close. Error = %s", GetError(ret).c_str());
-  }
-
-  ret = DisposeAUGraph(m_audioGraph);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Close: "
-      "Error dispose. Error = %s", GetError(ret).c_str());
-  }
-
-  return true;
-}
-
-bool CCoreAudioGraph::Start()
-{
-  if (!m_audioGraph)
-    return false;
-
-  Boolean isRunning = false;
-  OSStatus ret = AUGraphIsRunning(m_audioGraph, &isRunning);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Start: "
-      "Audio graph not running. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  if (!isRunning)
-  {
-    if (m_audioUnit)
-      m_audioUnit->Start();
-    if (m_mixerUnit)
-      m_mixerUnit->Start();
-    if (m_inputUnit)
-      m_inputUnit->Start();
-
-    ret = AUGraphStart(m_audioGraph);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Start: "
-        "Error starting audio graph. Error = %s", GetError(ret).c_str());
-    }
-  }
-
-  return true;
-}
-
-bool CCoreAudioGraph::Stop()
-{
-  if (!m_audioGraph)
-    return false;
-
-  Boolean isRunning = false;
-  OSStatus ret = AUGraphIsRunning(m_audioGraph, &isRunning);
-  if (ret)
-  {
-    if (m_inputUnit)
-      m_inputUnit->Stop();
-    if (m_mixerUnit)
-      m_mixerUnit->Stop();
-    if (m_audioUnit)
-      m_audioUnit->Stop();
-
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Stop: "
-      "Audio graph not running. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  if (isRunning)
-  {
-    ret = AUGraphStop(m_audioGraph);
-    if (ret)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioGraph::Stop: "
-        "Error stopping audio graph. Error = %s", GetError(ret).c_str());
-    }
-  }
-
-  return true;
-}
-
-AudioChannelLayoutTag CCoreAudioGraph::GetChannelLayoutTag(int layout)
-{
-  return g_LayoutMap[layout];
-}
-
-bool CCoreAudioGraph::SetInputSource(ICoreAudioSource* pSource)
-{
-  if (m_inputUnit)
-    return m_inputUnit->SetInputSource(pSource);
-  else if (m_audioUnit)
-    return m_audioUnit->SetInputSource(pSource);
-
-  return false;
-}
-
-bool CCoreAudioGraph::SetCurrentVolume(Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  return m_audioUnit->SetCurrentVolume(vol);
-}
-
-CAUOutputDevice *CCoreAudioGraph::DestroyUnit(CAUOutputDevice *outputUnit)
-{
-  if (!outputUnit)
-    return NULL;
-
-  Stop();
-
-  for (AUUnitList::iterator itt = m_auUnitList.begin(); itt != m_auUnitList.end(); ++itt)
-  {
-    if (*itt == outputUnit)
-    {
-      m_auUnitList.erase(itt);
-      break;
-    }
-  }
-
-  ReleaseBus(outputUnit->GetBus());
-  outputUnit->SetInputSource(NULL);
-  outputUnit->Close();
-  delete outputUnit;
-
-  AUGraphUpdate(m_audioGraph, NULL);
-
-  Start();
-
-  return NULL;
-}
-
-CAUOutputDevice *CCoreAudioGraph::CreateUnit(AEAudioFormat &format)
-{
-  if (!m_audioUnit || !m_mixerUnit)
-    return NULL;
-
-  AudioStreamBasicDescription fmt = {0};
-  AudioStreamBasicDescription inputFormat = {0};
-  AudioStreamBasicDescription outputFormat = {0};
-
-  int busNumber = GetFreeBus();
-  if (busNumber == INVALID_BUS)
-    return  NULL;
-
-  OSStatus ret;
-  // create output unit
-  CAUOutputDevice *outputUnit = new CAUOutputDevice();
-  if (!outputUnit->Open(m_audioGraph,
-    kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple))
-    goto error;
-
-  m_audioUnit->GetFormatDesc(format, &inputFormat, &fmt);
-
-  // get the format frm the mixer
-  if (!m_mixerUnit->GetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus))
-    goto error;
-
-  if (!outputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus))
-    goto error;
-
-  if (!outputUnit->SetFormat(&outputFormat, kAudioUnitScope_Output, kOutputBus))
-    goto error;
-
-  ret = AUGraphConnectNodeInput(m_audioGraph, outputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::CreateUnit: "
-      "Error connecting outputUnit. Error = %s", GetError(ret).c_str());
-    goto error;
-  }
-
-  // TODO: setup mixmap, get free bus number for connection
-
-  outputUnit->SetBus(busNumber);
-
-  if (m_mixMap || m_mixMap->IsValid())
-  {
-    UInt32 inputNumber = outputUnit->GetBus();
-    int channelOffset = GetMixerChannelOffset(inputNumber);
-    CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &inputFormat, &fmt, channelOffset);
-  }
-
-  AUGraphUpdate(m_audioGraph, NULL);
-  m_auUnitList.push_back(outputUnit);
-
-  return outputUnit;
-
-error:
-  delete outputUnit;
-  return NULL;
-}
-
-int CCoreAudioGraph::GetFreeBus()
-{
-  for (int i = 0; i < MAX_CONNECTION_LIMIT; i++)
-  {
-    if (!m_reservedBusNumber[i])
-    {
-      m_reservedBusNumber[i] = true;
-      return i;
-    }
-  }
-  return INVALID_BUS;
-}
-
-void CCoreAudioGraph::ReleaseBus(int busNumber)
-{
-  if (busNumber > MAX_CONNECTION_LIMIT || busNumber < 0)
-    return;
-
-  m_reservedBusNumber[busNumber] = false;
-}
-
-bool CCoreAudioGraph::IsBusFree(int busNumber)
-{
-  if (busNumber > MAX_CONNECTION_LIMIT || busNumber < 0)
-    return false;
-  return m_reservedBusNumber[busNumber];
-}
-
-int CCoreAudioGraph::GetMixerChannelOffset(int busNumber)
-{
-  if (!m_mixerUnit)
-    return 0;
-
-  int offset = 0;
-  AudioStreamBasicDescription fmt = {0};
-
-  for (int i = 0; i < busNumber; i++)
-  {
-    memset(&fmt, 0x0, sizeof(fmt));
-    m_mixerUnit->GetFormat(&fmt, kAudioUnitScope_Input, busNumber);
-    offset += fmt.mChannelsPerFrame;
-  }
-  return offset;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioGraph.h
deleted file mode 100644 (file)
index d704ac6..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-#include <list>
-
-#include "ICoreAudioSource.h"
-#include <AudioToolbox/AUGraph.h>
-#include <CoreAudio/CoreAudio.h>
-
-#define MAX_CONNECTION_LIMIT   8
-#define MAXIMUM_MIXER_CHANNELS 9
-
-class CAUMatrixMixer;
-class CAUOutputDevice;
-class CCoreAudioMixMap;
-
-class CCoreAudioGraph
-{
-public:
-  CCoreAudioGraph();
-  ~CCoreAudioGraph();
-
-  bool             Open(ICoreAudioSource *pSource, AEAudioFormat &format, AudioDeviceID deviceId,
-                     bool allowMixing, AudioChannelLayoutTag layoutTag, float initVolume, bool encoded);
-  bool             Close();
-  bool             Start();
-  bool             Stop();
-  static AudioChannelLayoutTag GetChannelLayoutTag(int layout);
-  bool             SetInputSource(ICoreAudioSource *pSource);
-  bool             SetCurrentVolume(Float32 vol);
-  CAUOutputDevice* DestroyUnit(CAUOutputDevice *outputUnit);
-  CAUOutputDevice* CreateUnit(AEAudioFormat &format);
-  int              GetFreeBus();
-  void             ReleaseBus(int busNumber);
-  bool             IsBusFree(int busNumber);
-  int              GetMixerChannelOffset(int busNumber);
-
-private:
-  AUGraph           m_audioGraph;
-
-  CAUOutputDevice  *m_inputUnit;
-  CAUOutputDevice  *m_audioUnit;
-  CAUMatrixMixer   *m_mixerUnit;
-
-  int               m_reservedBusNumber[MAX_CONNECTION_LIMIT];
-  bool              m_initialized;
-  AudioDeviceID     m_deviceId;
-  bool              m_allowMixing;
-  CCoreAudioMixMap *m_mixMap;
-
-  typedef std::list<CAUOutputDevice*> AUUnitList;
-  AUUnitList        m_auUnitList;
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.cpp
deleted file mode 100644 (file)
index 5198444..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioHardware.h"
-
-#include "CoreAudioAEHAL.h"
-#include "utils/log.h"
-#include "osx/DarwinUtils.h"
-
-bool CCoreAudioHardware::GetAutoHogMode()
-{
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioHardwarePropertyHogModeIsAllowed; 
-
-  UInt32 val = 0;
-  UInt32 size = sizeof(val);
-  OSStatus ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &val); 
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::GetAutoHogMode: "
-      "Unable to get auto 'hog' mode. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return (val == 1);
-}
-
-void CCoreAudioHardware::SetAutoHogMode(bool enable)
-{
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioHardwarePropertyHogModeIsAllowed; 
-
-  UInt32 val = enable ? 1 : 0;
-  UInt32 size = sizeof(val);
-  OSStatus ret = AudioObjectSetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &val); 
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioHardware::SetAutoHogMode: "
-      "Unable to set auto 'hog' mode. Error = %s", GetError(ret).c_str());
-}
-
-void CCoreAudioHardware::ResetAudioDevices()
-{
-  CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetAudioDevices resetting our devices to LPCM");
-  CoreAudioDeviceList list;
-  if (GetOutputDevices(&list))
-  {
-    for (CoreAudioDeviceList::iterator it = list.begin(); it != list.end(); it ++)
-    {
-      CCoreAudioDevice device = *it;
-
-      AudioStreamIdList streams;
-      if (device.GetStreams(&streams))
-      {
-        CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetAudioDevices %lu streams for device %s", streams.size(), device.GetName().c_str());
-        for (AudioStreamIdList::iterator ait = streams.begin(); ait != streams.end(); ait ++)
-          ResetStream(*ait);
-      }
-    }
-  }
-}
-
-void CCoreAudioHardware::ResetStream(AudioStreamID streamId)
-{
-  CCoreAudioStream stream;
-  stream.Open(streamId);
-  
-  AudioStreamBasicDescription desc;
-  if (stream.GetPhysicalFormat(&desc))
-  {
-    if (desc.mFormatID == 'IAC3' || desc.mFormatID == kAudioFormat60958AC3)
-    {
-      CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetStream stream 0x%x is in encoded format.. setting to LPCM", (unsigned int)streamId);
-
-      StreamFormatList availableFormats;
-      if (stream.GetAvailablePhysicalFormats(&availableFormats))
-      {
-        for (StreamFormatList::iterator fmtIt = availableFormats.begin(); fmtIt != availableFormats.end() ; fmtIt ++)
-        {
-          AudioStreamRangedDescription fmtDesc = *fmtIt;
-          if (fmtDesc.mFormat.mFormatID == kAudioFormatLinearPCM)
-          {
-            AudioStreamBasicDescription newFmt = { 0 };
-            newFmt = fmtDesc.mFormat;
-
-            if (stream.SetPhysicalFormat(&newFmt))
-              break;
-          }
-        }
-      }
-    }
-  }
-
-  stream.Close(false);
-}
-
-AudioDeviceID CCoreAudioHardware::FindAudioDevice(const std::string &searchName)
-{
-  AudioDeviceID deviceId = 0;
-
-  if (!searchName.length())
-    return deviceId;
-
-  std::string searchNameLowerCase = searchName;
-  std::transform(searchNameLowerCase.begin(), searchNameLowerCase.end(), searchNameLowerCase.begin(), ::tolower );
-  if (searchNameLowerCase.compare("default") == 0)
-  {
-    AudioDeviceID defaultDevice = GetDefaultOutputDevice();
-    CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: "
-      "Returning default device [0x%04x].", (uint)defaultDevice);
-    return defaultDevice;
-  }
-  CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: "
-    "Searching for device - %s.", searchName.c_str());
-
-  // Obtain a list of all available audio devices
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioHardwarePropertyDevices; 
-
-  UInt32 size = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size); 
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::FindAudioDevice: "
-      "Unable to retrieve the size of the list of available devices. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-
-  size_t deviceCount = size / sizeof(AudioDeviceID);
-  AudioDeviceID* pDevices = new AudioDeviceID[deviceCount];
-  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, pDevices);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::FindAudioDevice: "
-      "Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str());
-    delete[] pDevices;
-    return 0;
-  }
-
-  // Attempt to locate the requested device
-  std::string deviceName;
-  for (size_t dev = 0; dev < deviceCount; dev++)
-  {
-    CCoreAudioDevice device;
-    device.Open((pDevices[dev]));
-    deviceName = device.GetName();
-    std::transform( deviceName.begin(), deviceName.end(), deviceName.begin(), ::tolower );
-    if (searchNameLowerCase.compare(deviceName) == 0)
-      deviceId = pDevices[dev];
-    if (deviceId)
-      break;
-  }
-  delete[] pDevices;
-
-  return deviceId;
-}
-
-AudioDeviceID CCoreAudioHardware::GetDefaultOutputDevice()
-{
-  AudioDeviceID deviceId = 0;
-  static AudioDeviceID lastDeviceId = 0;
-
-  AudioObjectPropertyAddress  propertyAddress;
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal;
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
-  
-  UInt32 size = sizeof(AudioDeviceID);
-  OSStatus ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &deviceId);
-
-  // outputDevice is set to 0 if there is no audio device available
-  // or if the default device is set to an encoded format
-  if (ret != noErr || !deviceId) 
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::GetDefaultOutputDevice:"
-      " Unable to identify default output device. Error = %s", GetError(ret).c_str());
-    // if there was no error and no deviceId was returned
-    // return the last known default device
-    if (ret == noErr && !deviceId)
-      return lastDeviceId;
-    else
-      return 0;
-  }
-  
-  lastDeviceId = deviceId;
-
-  return deviceId;
-}
-
-void CCoreAudioHardware::GetOutputDeviceName(std::string& name)
-{
-  name = "Default";
-  AudioDeviceID deviceId = GetDefaultOutputDevice();
-
-  if (deviceId)
-  {
-    AudioObjectPropertyAddress  propertyAddress;
-    propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal;
-    propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-    propertyAddress.mSelector = kAudioObjectPropertyName;
-
-    CFStringRef theDeviceName = NULL;
-    UInt32 propertySize = sizeof(CFStringRef);
-    OSStatus ret = AudioObjectGetPropertyData(deviceId, &propertyAddress, 0, NULL, &propertySize, &theDeviceName); 
-    if (ret != noErr)
-      return;
-
-    DarwinCFStringRefToUTF8String(theDeviceName, name);
-
-    CFRelease(theDeviceName);
-  }
-}
-
-UInt32 CCoreAudioHardware::GetOutputDevices(CoreAudioDeviceList *pList)
-{
-  UInt32 found = 0;
-  if (!pList)
-    return found;
-
-  // Obtain a list of all available audio devices
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioHardwarePropertyDevices; 
-
-  UInt32 size = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size); 
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::GetOutputDevices:"
-      " Unable to retrieve the size of the list of available devices. Error = %s", GetError(ret).c_str());
-    return found;
-  }
-
-  size_t deviceCount = size / sizeof(AudioDeviceID);
-  AudioDeviceID* pDevices = new AudioDeviceID[deviceCount];
-  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, pDevices);
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioHardware::GetOutputDevices:"
-      " Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str());
-  else
-  {
-    for (size_t dev = 0; dev < deviceCount; dev++)
-    {
-      CCoreAudioDevice device(pDevices[dev]);
-      if (device.GetTotalOutputChannels() == 0)
-        continue;
-      found++;
-      pList->push_back(pDevices[dev]);
-    }
-  }
-  delete[] pDevices;
-
-  return found;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.h
deleted file mode 100644 (file)
index 95d33f6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-
-#include "CoreAudioDevice.h"
-
-// There is only one AudioSystemObject instance system-side.
-// Therefore, all CCoreAudioHardware methods are static
-class CCoreAudioHardware
-{
-public:
-  static bool           GetAutoHogMode();
-  static void           SetAutoHogMode(bool enable);
-  static AudioStreamBasicDescription* FormatsList(AudioStreamID stream);
-  static AudioStreamID* StreamsList(AudioDeviceID device);
-  static void           ResetAudioDevices();
-  static void           ResetStream(AudioStreamID streamId);
-  static AudioDeviceID  FindAudioDevice(const std::string &deviceName);
-  static AudioDeviceID  GetDefaultOutputDevice();
-  static void           GetOutputDeviceName(std::string &name);
-  static UInt32         GetOutputDevices(CoreAudioDeviceList *pList);
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.cpp
deleted file mode 100644 (file)
index b045ed0..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioMixMap.h"
-
-#include "CoreAudioUnit.h"
-#include "CoreAudioAEHAL.h"
-#include "utils/log.h"
-
-
-#include <AudioToolbox/AudioToolbox.h>
-#include <sstream>
-
-CCoreAudioMixMap::CCoreAudioMixMap() :
-  m_isValid(false)
-{
-  m_pMap = (Float32*)calloc(sizeof(AudioChannelLayout), 1);
-}
-
-CCoreAudioMixMap::CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout) :
-  m_isValid(false)
-{
-  Rebuild(inLayout, outLayout);
-}
-
-CCoreAudioMixMap::~CCoreAudioMixMap()
-{
-  free(m_pMap);
-  m_pMap = NULL;
-}
-
-void CCoreAudioMixMap::Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout)
-{
-  // map[in][out] = mix-level of input_channel[in] into output_channel[out]
-
-  free(m_pMap);
-  m_pMap = NULL;
-
-  m_inChannels  = CCoreAudioChannelLayout::GetChannelCountForLayout(inLayout);
-  m_outChannels = CCoreAudioChannelLayout::GetChannelCountForLayout(outLayout);
-
-  // Try to find a 'well-known' matrix
-  const AudioChannelLayout* layouts[] = {&inLayout, &outLayout};
-  UInt32 propSize = 0;
-  AudioFormatGetPropertyInfo(kAudioFormatProperty_MatrixMixMap,
-    sizeof(layouts), layouts, &propSize);
-  m_pMap = (Float32*)calloc(1,propSize);
-
-  // Try and get a predefined mixmap
-  OSStatus ret = AudioFormatGetProperty(kAudioFormatProperty_MatrixMixMap,
-    sizeof(layouts), layouts, &propSize, m_pMap);
-  if (ret)
-  {
-    // If we for some reason don't find a predefined matrix let's build a diagonal matrix,
-    // basically guessing here, but we need to have a mixmap that matches the output and input
-    CLog::Log(LOGDEBUG, "CCoreAudioMixMap::CreateMap: No pre-defined mapping from %d to %d channels, building diagonal matrix.", m_inChannels, m_outChannels);
-    for (UInt32 chan = 0; chan < std::min(m_inChannels, m_outChannels); ++chan)
-    {
-      Float32 *vol = m_pMap + (chan * m_outChannels + chan);
-      CLog::Log(LOGDEBUG, "CCoreAudioMixMap::Rebuild %d = %f", chan, *vol);
-      *vol = 1.;
-    }
-  }
-  m_isValid = true;
-}
-
-CCoreAudioMixMap *CCoreAudioMixMap::CreateMixMap(CAUOutputDevice  *audioUnit, AEAudioFormat &format, AudioChannelLayoutTag layoutTag)
-{
-  if (!audioUnit)
-    return NULL;
-
-  AudioStreamBasicDescription fmt;
-  AudioStreamBasicDescription inputFormat;
-
-  // get the stream input format
-  audioUnit->GetFormatDesc(format, &inputFormat, &fmt);
-
-  unsigned int channels = format.m_channelLayout.Count();
-  CAEChannelInfo channelLayout = format.m_channelLayout;
-  bool hasLFE = false;
-  // Convert XBMC input channel layout format to CoreAudio layout format
-  AudioChannelLayout* pInLayout = (AudioChannelLayout*)malloc(sizeof(AudioChannelLayout) + sizeof(AudioChannelDescription) * channels);
-  pInLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
-  pInLayout->mChannelBitmap = 0;
-  pInLayout->mNumberChannelDescriptions = channels;
-  for (unsigned int chan=0; chan < channels; chan++)
-  {
-    AudioChannelDescription* pDesc = &pInLayout->mChannelDescriptions[chan];
-    // Convert from XBMC channel tag to CoreAudio channel tag
-    pDesc->mChannelLabel = g_LabelMap[(unsigned int)channelLayout[chan]];
-    pDesc->mChannelFlags = kAudioChannelFlags_AllOff;
-    pDesc->mCoordinates[0] = 0.0f;
-    pDesc->mCoordinates[1] = 0.0f;
-    pDesc->mCoordinates[2] = 0.0f;
-    if (pDesc->mChannelLabel == kAudioChannelLabel_LFEScreen)
-      hasLFE = true;
-  }
-  // HACK: Fix broken channel layouts coming from some aac sources
-  // that include rear channel but no side channels.
-  // 5.1 streams should include front and side channels.
-  // Rear channels are added by 6.1 and 7.1, so any 5.1
-  // source that claims to have rear channels is wrong.
-  if (inputFormat.mChannelsPerFrame == 6 && hasLFE)
-  {
-    // Check for 5.1 configuration (as best we can without getting too silly)
-    for (unsigned int chan=0; chan < inputFormat.mChannelsPerFrame; chan++)
-    {
-      AudioChannelDescription* pDesc = &pInLayout->mChannelDescriptions[chan];
-      if (pDesc->mChannelLabel == kAudioChannelLabel_LeftSurround || pDesc->mChannelLabel == kAudioChannelLabel_RightSurround)
-        break; // Required condition cannot be true
-
-      if (pDesc->mChannelLabel == kAudioChannelLabel_LeftSurroundDirect)
-      {
-        // Change [Back Left] to [Side Left]
-        pDesc->mChannelLabel = kAudioChannelLabel_LeftSurround;
-        CLog::Log(LOGINFO, "CCoreAudioGraph::CreateMixMap: "
-          "Detected faulty input channel map...fixing(Back Left-->Side Left)");
-      }
-      if (pDesc->mChannelLabel == kAudioChannelLabel_RightSurroundDirect)
-      {
-        // Change [Back Left] to [Side Left]
-        pDesc->mChannelLabel = kAudioChannelLabel_RightSurround;
-        CLog::Log(LOGINFO, "CCoreAudioGraph::CreateMixMap: "
-          "Detected faulty input channel map...fixing(Back Right-->Side Right)");
-      }
-    }
-  }
-
-  CCoreAudioChannelLayout sourceLayout(*pInLayout);
-  free(pInLayout);
-  pInLayout = NULL;
-
-  std::string strInLayout;
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::CreateMixMap: Source Stream Layout: %s",
-    CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)sourceLayout, strInLayout));
-
-  // Get User-Configured (XBMC) Speaker Configuration
-  AudioChannelLayout guiLayout;
-  guiLayout.mChannelLayoutTag = layoutTag;
-  CCoreAudioChannelLayout userLayout(guiLayout);
-  std::string strUserLayout;
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::CreateMixMap: User-Configured Speaker Layout: %s",
-    CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)userLayout, strUserLayout));
-
-  // Get OS-Configured (Audio MIDI Setup) Speaker Configuration (Channel Layout)
-  CCoreAudioChannelLayout deviceLayout;
-  if (!audioUnit->GetPreferredChannelLayout(deviceLayout))
-    return NULL;
-
-  // When all channels on the output device are unknown take the gui layout
-  //if(deviceLayout.AllChannelUnknown())
-  //  deviceLayout.CopyLayout(guiLayout);
-
-  std::string strOutLayout;
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::CreateMixMap: Output Device Layout: %s",
-    CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)deviceLayout, strOutLayout));
-
-  // TODO:
-  // Reconcile the OS and GUI layout configurations. Clamp to the minimum number of speakers
-  // For each OS-defined output, see if it exists in the GUI configuration
-  // If it does, add it to the 'union' layout (bitmap?)
-  // User may have configured 5.1 in GUI, but only 2.0 in OS
-  // Resulting layout would be {FL, FR}
-  // User may have configured 2.0 in GUI, and 5.1 in OS
-  // Resulting layout would be {FL, FR}
-
-  // Correct any configuration incompatibilities
-  //if (CCoreAudioChannelLayout::GetChannelCountForLayout(guiLayout) < CCoreAudioChannelLayout::GetChannelCountForLayout(deviceLayout))
-  //  deviceLayout.CopyLayout(guiLayout);
-
-  // TODO: Skip matrix mixer if input/output are compatible
-  CCoreAudioMixMap *mixMap = new CCoreAudioMixMap();
-  mixMap->Rebuild(*sourceLayout, *(AudioChannelLayout*)deviceLayout);
-  return mixMap;
-}
-
-bool CCoreAudioMixMap::SetMixingMatrix(CAUMatrixMixer *mixerUnit,
-  CCoreAudioMixMap *mixMap, AudioStreamBasicDescription *inputFormat,
-  AudioStreamBasicDescription *fmt, int channelOffset)
-{
-  if (!mixerUnit || !inputFormat || !fmt)
-    return false;
-
-  // Fetch the mixing unit size
-  UInt32 dims[2];
-  UInt32 size = sizeof(dims);
-  AudioUnitGetProperty(mixerUnit->GetUnit(),
-    kAudioUnitProperty_MatrixDimensions, kAudioUnitScope_Global, 0, dims, &size);
-
-  if(inputFormat->mChannelsPerFrame + channelOffset > dims[0])
-  {
-    CLog::Log(LOGERROR, "CCoreAudioMixMap::SetMixingMatrix - input format doesn't fit mixer size %u+%u > %u"
-                      , inputFormat->mChannelsPerFrame, channelOffset, dims[0]);
-    return false;
-  }
-
-  if(fmt->mChannelsPerFrame > dims[1])
-  {
-    CLog::Log(LOGERROR, "CCoreAudioMixMap::SetMixingMatrix - ouput format doesn't fit mixer size %u > %u"
-              , fmt->mChannelsPerFrame, dims[1]);
-    return false;
-  }
-
-  if(fmt->mChannelsPerFrame < dims[1])
-  {
-    CLog::Log(LOGWARNING, "CCoreAudioMixMap::SetMixingMatrix - ouput format doesn't specify all outputs %u < %u"
-              , fmt->mChannelsPerFrame, dims[1]);
-  }
-
-  // Configure the mixing matrix
-  // The return from kAudioFormatProperty_MatrixMixMap (See Rebuild above) 
-  // is a Float32* which is laid out like this:
-  //
-  // mapping 2 chan -> 2 chan
-  // 1 0 0 1
-  //
-  // or better represented in a tow dimensional array:
-  //
-  // 1 0
-  // 0 1
-  //
-  // mapping 6 chan -> 6 chan:
-  // 1 0 0 0 0 0
-  // 0 1 0 0 0 0
-  // 0 0 1 0 0 0
-  // ....
-
-  Float32* val = (Float32*)*mixMap;
-  for (UInt32 i = 0; i < inputFormat->mChannelsPerFrame; ++i)
-  {
-    UInt32 j = 0;
-    std::stringstream layoutStr;
-    for (; j < fmt->mChannelsPerFrame; ++j)
-    {
-      Float32 *vol = val + (i * mixMap->m_outChannels + j);
-      layoutStr << *vol << ", ";
-      AudioUnitSetParameter(mixerUnit->GetUnit(),
-        kMatrixMixerParam_Volume, kAudioUnitScope_Global, ( (i + channelOffset) << 16 ) | j, *vol, 0);
-    }
-    // zero out additional outputs from this input
-    for (; j < dims[1]; ++j)
-    {
-      AudioUnitSetParameter(mixerUnit->GetUnit(),
-        kMatrixMixerParam_Volume, kAudioUnitScope_Global, ( (i + channelOffset) << 16 ) | j, 0.0f, 0);
-      layoutStr << "0, ";
-    }
-
-    CLog::Log(LOGDEBUG, "CCoreAudioMixMap::SetMixingMatrix channel %d = [%s]", i, layoutStr.str().c_str());
-  }
-
-  CLog::Log(LOGDEBUG, "CCoreAudioGraph::Open: "
-    "Mixer Output Format: %d channels, %0.1f kHz, %d bits, %d bytes per frame",
-    (int)fmt->mChannelsPerFrame, fmt->mSampleRate / 1000.0f, (int)fmt->mBitsPerChannel, (int)fmt->mBytesPerFrame);
-
-  if (!mixerUnit->InitMatrixMixerVolumes())
-    return false;
-
-  return true;
-}
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioMixMap.h
deleted file mode 100644 (file)
index a24de7f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-
-#include "cores/AudioEngine/Utils/AEAudioFormat.h"
-
-#include <CoreAudio/CoreAudio.h>
-
-class CAUMatrixMixer;
-class CAUOutputDevice;
-
-class CCoreAudioMixMap
-{
-public:
-  CCoreAudioMixMap();
-  CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout);
-  virtual ~CCoreAudioMixMap();
-
-  operator Float32*() const {return m_pMap;}
-
-  const Float32*  GetBuffer()         {return m_pMap;}
-  UInt32          GetInputChannels()  {return m_inChannels;}
-  UInt32          GetOutputChannels() {return m_outChannels;}
-  bool            IsValid() {return m_isValid;}
-  void            Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout);
-  static          CCoreAudioMixMap *CreateMixMap(CAUOutputDevice *audioUnit,
-                    AEAudioFormat &format, AudioChannelLayoutTag layoutTag);
-  static bool     SetMixingMatrix(CAUMatrixMixer *mixerUnit, CCoreAudioMixMap *mixMap,
-                    AudioStreamBasicDescription *inputFormat, AudioStreamBasicDescription *fmt, int channelOffset);
-private:
-  Float32         *m_pMap;
-  UInt32          m_inChannels;
-  UInt32          m_outChannels;
-  bool            m_isValid;
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.cpp
deleted file mode 100644 (file)
index 0e25987..0000000
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioStream.h"
-
-#include "CoreAudioAEHAL.h"
-#include "utils/log.h"
-#include "utils/StdString.h"
-
-CCoreAudioStream::CCoreAudioStream() :
-  m_StreamId  (0    )
-{
-  m_OriginalVirtualFormat.mFormatID = 0;
-  m_OriginalPhysicalFormat.mFormatID = 0;
-}
-
-CCoreAudioStream::~CCoreAudioStream()
-{
-  Close();
-}
-
-bool CCoreAudioStream::Open(AudioStreamID streamId)
-{
-  m_StreamId = streamId;
-  CLog::Log(LOGDEBUG, "CCoreAudioStream::Open: Opened stream 0x%04x.", (uint)m_StreamId);
-
-  // watch for physical property changes.
-  AudioObjectPropertyAddress propertyAOPA;
-  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
-  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
-  propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
-  if (AudioObjectAddPropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioStream::Open: couldn't set up a physical property listener.");
-
-  // watch for virtual property changes.
-  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
-  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
-  propertyAOPA.mSelector = kAudioStreamPropertyVirtualFormat;
-  if (AudioObjectAddPropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioStream::Open: couldn't set up a virtual property listener.");
-
-  return true;
-}
-
-// TODO: Should it even be possible to change both the 
-// physical and virtual formats, since the devices do it themselves?
-void CCoreAudioStream::Close(bool restore)
-{
-  if (!m_StreamId)
-    return;
-
-  std::string formatString;
-
-  // remove the physical/virtual property listeners before we make changes
-  // that will trigger callbacks that we do not care about.
-  AudioObjectPropertyAddress propertyAOPA;
-  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
-  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
-  propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
-  if (AudioObjectRemovePropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
-    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Couldn't remove property listener.");
-
-  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
-  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
-  propertyAOPA.mSelector = kAudioStreamPropertyVirtualFormat;
-  if (AudioObjectRemovePropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
-    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Couldn't remove property listener.");
-
-  // Revert any format changes we made
-  if (restore && m_OriginalVirtualFormat.mFormatID && m_StreamId)
-  {
-    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: "
-      "Restoring original virtual format for stream 0x%04x. (%s)",
-      (uint)m_StreamId, StreamDescriptionToString(m_OriginalVirtualFormat, formatString));
-    AudioStreamBasicDescription setFormat = m_OriginalVirtualFormat;
-    SetVirtualFormat(&setFormat);
-  }
-  if (restore && m_OriginalPhysicalFormat.mFormatID && m_StreamId)
-  {
-    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: "
-      "Restoring original physical format for stream 0x%04x. (%s)",
-      (uint)m_StreamId, StreamDescriptionToString(m_OriginalPhysicalFormat, formatString));
-    AudioStreamBasicDescription setFormat = m_OriginalPhysicalFormat;
-    SetPhysicalFormat(&setFormat);
-  }
-
-  m_OriginalVirtualFormat.mFormatID  = 0;
-  m_OriginalPhysicalFormat.mFormatID = 0;
-  CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Closed stream 0x%04x.", (uint)m_StreamId);
-  m_StreamId = 0;
-}
-
-UInt32 CCoreAudioStream::GetDirection()
-{
-  if (!m_StreamId)
-    return 0;
-
-  UInt32 val = 0;
-  UInt32 size = sizeof(UInt32);
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyDirection; 
-
-  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, &val); 
-  if (ret)
-    return 0;
-
-  return val;
-}
-
-UInt32 CCoreAudioStream::GetTerminalType()
-{
-  if (!m_StreamId)
-    return 0;
-
-  UInt32 val = 0;
-  UInt32 size = sizeof(UInt32);
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyTerminalType; 
-
-  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, &val); 
-  if (ret)
-    return 0;
-  return val;
-}
-
-UInt32 CCoreAudioStream::GetNumLatencyFrames()
-{
-  if (!m_StreamId)
-    return 0;
-
-  UInt32 i_param_size = sizeof(uint32_t);
-  UInt32 i_param, num_latency_frames = 0;
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyLatency; 
-
-  // number of frames of latency in the AudioStream
-  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &i_param_size, &i_param); 
-  if (ret == noErr)
-  {
-    num_latency_frames += i_param;
-  }
-
-  return num_latency_frames;
-}
-
-bool CCoreAudioStream::GetVirtualFormat(AudioStreamBasicDescription* pDesc)
-{
-  if (!pDesc || !m_StreamId)
-    return false;
-
-  UInt32 size = sizeof(AudioStreamBasicDescription);
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; 
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_StreamId, &propertyAddress, 0, NULL, &size); 
-  if (ret)
-    return false;
-
-  ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, pDesc); 
-  if (ret)
-    return false;
-  return true;
-}
-
-bool CCoreAudioStream::SetVirtualFormat(AudioStreamBasicDescription* pDesc)
-{
-  if (!pDesc || !m_StreamId)
-    return false;
-
-  std::string formatString;
-
-  if (!m_OriginalVirtualFormat.mFormatID)
-  {
-    // Store the original format (as we found it) so that it can be restored later
-    if (!GetVirtualFormat(&m_OriginalVirtualFormat))
-    {
-      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
-        "Unable to retrieve current virtual format for stream 0x%04x.", (uint)m_StreamId);
-      return false;
-    }
-  }
-  m_virtual_format_event.Reset();
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; 
-
-  UInt32 propertySize = sizeof(AudioStreamBasicDescription);
-  OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); 
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
-      "Unable to set virtual format for stream 0x%04x. Error = %s",
-      (uint)m_StreamId, GetError(ret).c_str());
-    return false;
-  }
-
-  // The AudioStreamSetProperty is not only asynchronious,
-  // it is also not Atomic, in its behaviour.
-  // Therefore we check 5 times before we really give up.
-  // FIXME: failing isn't actually implemented yet.
-  for (int i = 0; i < 10; ++i)
-  {
-    AudioStreamBasicDescription checkVirtualFormat;
-    if (!GetVirtualFormat(&checkVirtualFormat))
-    {
-      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
-        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
-      return false;
-    }
-    if (checkVirtualFormat.mSampleRate == pDesc->mSampleRate &&
-        checkVirtualFormat.mFormatID == pDesc->mFormatID &&
-        checkVirtualFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
-    {
-      // The right format is now active.
-      CLog::Log(LOGDEBUG, "CCoreAudioStream::SetVirtualFormat: "
-        "Virtual format for stream 0x%04x. now active (%s)",
-        (uint)m_StreamId, StreamDescriptionToString(checkVirtualFormat, formatString));
-      break;
-    }
-    m_virtual_format_event.WaitMSec(100);
-  }
-  return true;
-}
-
-bool CCoreAudioStream::GetPhysicalFormat(AudioStreamBasicDescription* pDesc)
-{
-  if (!pDesc || !m_StreamId)
-    return false;
-
-  UInt32 size = sizeof(AudioStreamBasicDescription);
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; 
-
-  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, pDesc); 
-  if (ret)
-    return false;
-  return true;
-}
-
-bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc)
-{
-  if (!pDesc || !m_StreamId)
-    return false;
-
-  std::string formatString;
-
-  if (!m_OriginalPhysicalFormat.mFormatID)
-  {
-    // Store the original format (as we found it) so that it can be restored later
-    if (!GetPhysicalFormat(&m_OriginalPhysicalFormat))
-    {
-      CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
-        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
-      return false;
-    }
-  }
-  m_physical_format_event.Reset();
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; 
-
-  UInt32 propertySize = sizeof(AudioStreamBasicDescription);
-  OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); 
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
-      "Unable to set physical format for stream 0x%04x. Error = %s",
-      (uint)m_StreamId, GetError(ret).c_str());
-    return false;
-  }
-
-  // The AudioStreamSetProperty is not only asynchronious,
-  // it is also not Atomic, in its behaviour.
-  // Therefore we check 5 times before we really give up.
-  // FIXME: failing isn't actually implemented yet.
-  for(int i = 0; i < 10; ++i)
-  {
-    AudioStreamBasicDescription checkPhysicalFormat;
-    if (!GetPhysicalFormat(&checkPhysicalFormat))
-    {
-      CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
-        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
-      return false;
-    }
-    if (checkPhysicalFormat.mSampleRate == pDesc->mSampleRate &&
-        checkPhysicalFormat.mFormatID   == pDesc->mFormatID   &&
-        checkPhysicalFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
-    {
-      // The right format is now active.
-      CLog::Log(LOGDEBUG, "CCoreAudioStream::SetPhysicalFormat: "
-        "Physical format for stream 0x%04x. now active (%s)",
-        (uint)m_StreamId, StreamDescriptionToString(checkPhysicalFormat, formatString));
-      break;
-    }
-    m_physical_format_event.WaitMSec(100);
-  }
-
-  return true;
-}
-
-bool CCoreAudioStream::GetAvailableVirtualFormats(StreamFormatList* pList)
-{
-  if (!pList || !m_StreamId)
-    return false;
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyAvailableVirtualFormats; 
-
-  UInt32 propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_StreamId, &propertyAddress, 0, NULL, &propertySize); 
-  if (ret)
-    return false;
-
-  UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription);
-  AudioStreamRangedDescription *pFormatList = new AudioStreamRangedDescription[formatCount];
-  ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &propertySize, pFormatList); 
-  if (!ret)
-  {
-    for (UInt32 format = 0; format < formatCount; format++)
-      pList->push_back(pFormatList[format]);
-  }
-  delete[] pFormatList;
-  return (ret == noErr);
-}
-
-bool CCoreAudioStream::GetAvailablePhysicalFormats(StreamFormatList* pList)
-{
-  if (!pList || !m_StreamId)
-    return false;
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
-  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
-  propertyAddress.mSelector = kAudioStreamPropertyAvailablePhysicalFormats; 
-
-  UInt32 propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_StreamId, &propertyAddress, 0, NULL, &propertySize); 
-  if (ret)
-    return false;
-
-  UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription);
-  AudioStreamRangedDescription *pFormatList = new AudioStreamRangedDescription[formatCount];
-  ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &propertySize, pFormatList); 
-  if (!ret)
-  {
-    for (UInt32 format = 0; format < formatCount; format++)
-      pList->push_back(pFormatList[format]);
-  }
-  delete[] pFormatList;
-  return (ret == noErr);
-}
-
-OSStatus CCoreAudioStream::HardwareStreamListener(AudioObjectID inObjectID,
-  UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void *inClientData)
-{
-  CCoreAudioStream *ca_stream = (CCoreAudioStream*)inClientData;
-
-  for (UInt32 i = 0; i < inNumberAddresses; i++)
-  {
-    if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat)
-    {
-      AudioStreamBasicDescription actualFormat;
-      UInt32 propertySize = sizeof(AudioStreamBasicDescription);
-      // hardware physical format has changed.
-      if (AudioObjectGetPropertyData(ca_stream->m_StreamId, &inAddresses[i], 0, NULL, &propertySize, &actualFormat) == noErr)
-      {
-        CStdString formatString;
-        CLog::Log(LOGINFO, "CCoreAudioStream::HardwareStreamListener: "
-          "Hardware physical format changed to %s", StreamDescriptionToString(actualFormat, formatString));
-        ca_stream->m_physical_format_event.Set();
-      }
-    }
-    else if (inAddresses[i].mSelector == kAudioStreamPropertyVirtualFormat)
-    {
-      // hardware virtual format has changed.
-      AudioStreamBasicDescription actualFormat;
-      UInt32 propertySize = sizeof(AudioStreamBasicDescription);
-      if (AudioObjectGetPropertyData(ca_stream->m_StreamId, &inAddresses[i], 0, NULL, &propertySize, &actualFormat) == noErr)
-      {
-        CStdString formatString;
-        CLog::Log(LOGINFO, "CCoreAudioStream::HardwareStreamListener: "
-          "Hardware virtual format changed to %s", StreamDescriptionToString(actualFormat, formatString));
-        ca_stream->m_virtual_format_event.Set();
-      }
-    }
-  }
-
-  return noErr;
-}
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioStream.h
deleted file mode 100644 (file)
index 008800e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-
-#include "threads/Thread.h"
-#include <CoreAudio/CoreAudio.h>
-
-#include <list>
-
-typedef std::list<AudioStreamID> AudioStreamIdList;
-typedef std::list<AudioStreamRangedDescription> StreamFormatList;
-
-class CCoreAudioStream
-{
-public:
-  CCoreAudioStream();
-  virtual ~CCoreAudioStream();
-  
-  bool    Open(AudioStreamID streamId);
-  void    Close(bool restore = true);
-  
-  AudioStreamID GetId() {return m_StreamId;}
-  UInt32  GetDirection();
-  UInt32  GetTerminalType();
-  UInt32  GetNumLatencyFrames();
-  bool    GetVirtualFormat(AudioStreamBasicDescription *pDesc);
-  bool    GetPhysicalFormat(AudioStreamBasicDescription *pDesc);
-  bool    SetVirtualFormat(AudioStreamBasicDescription *pDesc);
-  bool    SetPhysicalFormat(AudioStreamBasicDescription *pDesc);
-  bool    GetAvailableVirtualFormats(StreamFormatList *pList);
-  bool    GetAvailablePhysicalFormats(StreamFormatList *pList);
-  
-protected:
-  static OSStatus HardwareStreamListener(AudioObjectID inObjectID,
-    UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void* inClientData);
-
-  CEvent m_virtual_format_event;
-  CEvent m_physical_format_event;
-
-
-  AudioStreamID m_StreamId;
-  AudioStreamBasicDescription m_OriginalVirtualFormat;  
-  AudioStreamBasicDescription m_OriginalPhysicalFormat;  
-};
-
-#endif
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.cpp b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.cpp
deleted file mode 100644 (file)
index 03b2fdc..0000000
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- *      Copyright (C) 2011-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 "CoreAudioUnit.h"
-
-#include "CoreAudioAEHAL.h"
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "utils/log.h"
-
-#include <AudioToolbox/AUGraph.h>
-
-CCoreAudioUnit::CCoreAudioUnit() :
-  m_pSource         (NULL         ),
-  m_audioUnit       (NULL         ),
-  m_audioNode       (NULL         ),
-  m_audioGraph      (NULL         ),
-  m_Initialized     (false        ),
-  m_renderProc      (NULL         ),
-  m_busNumber       (INVALID_BUS  )
-{
-}
-
-CCoreAudioUnit::~CCoreAudioUnit()
-{
-  Close();
-}
-
-bool CCoreAudioUnit::Open(AUGraph audioGraph, AudioComponentDescription desc)
-{
-  if (m_audioUnit)
-    Close();
-
-  OSStatus ret;
-
-  m_Initialized = false;
-
-  ret = AUGraphAddNode(audioGraph, &desc, &m_audioNode);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error add m_outputNode. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  ret = AUGraphNodeInfo(audioGraph, m_audioNode, 0, &m_audioUnit);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioGraph::Open: "
-      "Error getting m_outputNode. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_audioGraph  = audioGraph;
-  m_Initialized = true;
-
-  return true;
-}
-
-bool CCoreAudioUnit::Open(AUGraph audioGraph, OSType type, OSType subType, OSType manufacturer)
-{
-  AudioComponentDescription desc = {0};
-  desc.componentType = type;
-  desc.componentSubType = subType;
-  desc.componentManufacturer = manufacturer;
-
-  return Open(audioGraph, desc);
-}
-
-void CCoreAudioUnit::Close()
-{
-  if (!m_Initialized && !m_audioUnit)
-    return;
-
-  if (m_renderProc)
-    SetInputSource(NULL);
-
-  Stop();
-  if (m_busNumber != INVALID_BUS)
-  {
-    OSStatus ret = AUGraphDisconnectNodeInput(m_audioGraph, m_audioNode, m_busNumber);
-    if (ret && ret != kAUGraphErr_NodeNotFound)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioUnit::Close: "
-        "Unable to disconnect AudioUnit. Error = %s", GetError(ret).c_str());
-    }
-
-    ret = AUGraphRemoveNode(m_audioGraph, m_audioNode);
-    if (ret != noErr)
-    {
-      CLog::Log(LOGERROR, "CCoreAudioUnit::Close: "
-        "Unable to remove AudioUnit. Error = %s", GetError(ret).c_str());
-    }
-  }
-
-  AUGraphUpdate(m_audioGraph, NULL);
-
-  m_Initialized = false;
-  m_audioUnit = NULL;
-  m_audioNode = NULL;
-  m_pSource = NULL;
-}
-
-bool CCoreAudioUnit::GetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus)
-{
-  if (!m_audioUnit || !pDesc)
-    return false;
-
-  UInt32 size = sizeof(AudioStreamBasicDescription);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_StreamFormat, scope, bus, pDesc, &size);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetFormat: "
-      "Unable to get AudioUnit format. Bus : %d Scope : %d : Error = %s",
-        (int)bus, (int)scope, GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::SetFormat(AudioStreamBasicDescription* pDesc, AudioUnitScope scope, AudioUnitElement bus)
-{
-  if (!m_audioUnit || !pDesc)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit,
-    kAudioUnitProperty_StreamFormat, scope, bus, pDesc, sizeof(AudioStreamBasicDescription));
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetFormat: "
-      "Unable to set AudioUnit format. Bus : %d Scope : %d : Error = %s",
-       (int)bus, (int)scope, GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::SetMaxFramesPerSlice(UInt32 maxFrames)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit,
-    kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFrames, sizeof(UInt32));
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetMaxFramesPerSlice: "
-      "Unable to set AudioUnit max frames per slice. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-bool CCoreAudioUnit::GetSupportedChannelLayouts(AudioChannelLayoutList* pLayouts)
-{
-  if (!m_audioUnit || !pLayouts)
-    return false;
-
-  UInt32 propSize = 0;
-  Boolean writable = false;
-  OSStatus ret = AudioUnitGetPropertyInfo(m_audioUnit,
-    kAudioUnitProperty_SupportedChannelLayoutTags, kAudioUnitScope_Input, 0, &propSize, &writable);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetSupportedChannelLayouts: "
-      "Unable to retrieve supported channel layout property info. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  UInt32 layoutCount = propSize / sizeof(AudioChannelLayoutTag);
-  AudioChannelLayoutTag* pSuppLayouts = new AudioChannelLayoutTag[layoutCount];
-  ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_SupportedChannelLayoutTags, kAudioUnitScope_Output, 0, pSuppLayouts, &propSize);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetSupportedChannelLayouts: "
-      "Unable to retrieve supported channel layouts. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  for (UInt32 layout = 0; layout < layoutCount; layout++)
-    pLayouts->push_back(pSuppLayouts[layout]);
-  delete[] pSuppLayouts;
-  return true;
-}
-
-bool CCoreAudioUnit::SetInputSource(ICoreAudioSource* pSource)
-{
-  m_pSource = pSource;
-  if (pSource)
-    return SetRenderProc();
-  else
-    return RemoveRenderProc();
-}
-
-bool CCoreAudioUnit::SetRenderProc()
-{
-  if (!m_audioUnit || m_renderProc)
-    return false;
-
-  AURenderCallbackStruct callbackInfo;
-  callbackInfo.inputProc = RenderCallback; // Function to be called each time the AudioUnit needs data
-  callbackInfo.inputProcRefCon = this; // Pointer to be returned in the callback proc
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback,
-    kAudioUnitScope_Input, 0, &callbackInfo, sizeof(AURenderCallbackStruct));
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetRenderProc: "
-      "Unable to set AudioUnit render callback. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_renderProc = RenderCallback;
-
-  return true;
-}
-
-bool CCoreAudioUnit::RemoveRenderProc()
-{
-  if (!m_audioUnit || !m_renderProc)
-    return false;
-
-  AudioUnitInitialize(m_audioUnit);
-
-  AURenderCallbackStruct callbackInfo;
-  callbackInfo.inputProc = nil;
-  callbackInfo.inputProcRefCon = nil;
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback,
-    kAudioUnitScope_Input, 0, &callbackInfo, sizeof(AURenderCallbackStruct));
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::RemoveRenderProc: "
-      "Unable to remove AudioUnit render callback. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_renderProc = NULL;
-  Sleep(100);
-
-  return true;
-}
-
-OSStatus CCoreAudioUnit::RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
-  const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
-  OSStatus ret = noErr;
-  CCoreAudioUnit *audioUnit = (CCoreAudioUnit*)inRefCon;
-
-  if (audioUnit->m_pSource)
-  {
-    ret = audioUnit->m_pSource->Render(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
-  }
-  else
-  {
-    ioData->mBuffers[0].mDataByteSize = 0;
-    if (ioActionFlags)
-      *ioActionFlags |=  kAudioUnitRenderAction_OutputIsSilence;
-  }
-
-
-  return ret;
-}
-
-void CCoreAudioUnit::GetFormatDesc(AEAudioFormat format,
-  AudioStreamBasicDescription *streamDesc, AudioStreamBasicDescription *coreaudioDesc, bool encoded)
-{
-  unsigned int bps = CAEUtil::DataFormatToBits(format.m_dataFormat);
-
-  // Set the input stream format for the AudioUnit
-  // We use the default DefaultOuput AudioUnit, so we only can set the input stream format.
-  // The autput format is automaticaly set to the input format.
-  streamDesc->mFormatID = kAudioFormatLinearPCM;            //  Data encoding format
-  streamDesc->mFormatFlags = kLinearPCMFormatFlagIsPacked;
-  switch (format.m_dataFormat)
-  {
-    case AE_FMT_FLOAT:
-    case AE_FMT_LPCM:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsFloat;
-      break;
-    case AE_FMT_AC3:
-    case AE_FMT_DTS:
-    case AE_FMT_DTSHD:
-    case AE_FMT_TRUEHD:
-    case AE_FMT_EAC3:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      streamDesc->mFormatFlags |= kAudioFormatFlagsAudioUnitCanonical;
-      break;
-    case AE_FMT_S16LE:
-      if (encoded)
-        streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      else
-        streamDesc->mFormatFlags |= kAudioFormatFlagsAudioUnitCanonical;
-      break;
-    case AE_FMT_S16BE:
-      streamDesc->mFormatFlags |= kAudioFormatFlagIsBigEndian;
-      if (encoded)
-        streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      else
-        streamDesc->mFormatFlags |= kAudioFormatFlagsAudioUnitCanonical;
-      break;
-    default:
-      streamDesc->mFormatFlags |= kAudioFormatFlagsNativeEndian;
-      if (encoded)
-        streamDesc->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-      else
-        streamDesc->mFormatFlags |= kAudioFormatFlagsAudioUnitCanonical;
-      break;
-  }
-  streamDesc->mChannelsPerFrame = format.m_channelLayout.Count();               // Number of interleaved audiochannels
-  streamDesc->mSampleRate = (Float64)format.m_sampleRate;                       //  the sample rate of the audio stream
-  streamDesc->mBitsPerChannel = bps;                                            // Number of bits per sample, per channel
-  streamDesc->mBytesPerFrame = (bps>>3) * format.m_channelLayout.Count();       // Size of a frame == 1 sample per channel
-  streamDesc->mFramesPerPacket = 1;                                             // The smallest amount of indivisible data. Always 1 for uncompressed audio
-  streamDesc->mBytesPerPacket = streamDesc->mBytesPerFrame * streamDesc->mFramesPerPacket;
-  streamDesc->mReserved = 0;
-
-  // Audio units use noninterleaved 32-bit floating point
-  //  linear PCM data for input and output, ...except in the 
-  // case of an audio unit that is a data format converter,
-  // which converts to or from this format.
-  coreaudioDesc->mFormatID = kAudioFormatLinearPCM;
-  coreaudioDesc->mFormatFlags = kAudioFormatFlagsNativeEndian |
-    kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
-  switch (format.m_dataFormat)
-  {
-    case AE_FMT_FLOAT:
-      coreaudioDesc->mFormatFlags |= kAudioFormatFlagIsFloat;
-    default:
-      coreaudioDesc->mFormatFlags |= kAudioFormatFlagsAudioUnitCanonical;
-      break;
-  }
-  coreaudioDesc->mBitsPerChannel   = bps; //sizeof(Float32)<<3;
-  coreaudioDesc->mSampleRate       = (Float64)format.m_sampleRate;;
-  coreaudioDesc->mFramesPerPacket  = 1;
-  coreaudioDesc->mChannelsPerFrame = streamDesc->mChannelsPerFrame;
-  coreaudioDesc->mBytesPerFrame    = (bps>>3); //sizeof(Float32);
-  coreaudioDesc->mBytesPerPacket   = (bps>>3); //sizeof(Float32);
-}
-
-float CCoreAudioUnit::GetLatency()
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float64 latency;
-  UInt32 size = sizeof(latency);
-
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, &latency, &size);
-
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetLatency: "
-      "Unable to set AudioUnit latency. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-
-  return latency;
-}
-
-bool CCoreAudioUnit::Stop()
-{
-  if (!m_audioUnit)
-    return false;
-
-  AudioOutputUnitStop(m_audioUnit);
-
-  return true;
-}
-
-bool CCoreAudioUnit::Start()
-{
-  if (!m_audioUnit)
-    return false;
-
-  AudioOutputUnitStart(m_audioUnit);
-
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CAUOutputDevice
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CAUOutputDevice::CAUOutputDevice() :
-  m_DeviceId    (NULL )
-{
-}
-
-CAUOutputDevice::~CAUOutputDevice()
-{
-}
-
-bool CAUOutputDevice::SetCurrentDevice(AudioDeviceID deviceId)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_CurrentDevice,
-    kAudioUnitScope_Global, kOutputBus, &deviceId, sizeof(AudioDeviceID));
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetCurrentDevice: "
-      "Unable to set current device. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  m_DeviceId = deviceId;
-
-  return true;
-}
-
-bool CAUOutputDevice::GetChannelMap(CoreAudioChannelList* pChannelMap)
-{
-  if (!m_audioUnit)
-    return false;
-
-  UInt32 size = 0;
-  Boolean writable = false;
-  AudioUnitGetPropertyInfo(m_audioUnit,
-    kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 0, &size, &writable);
-
-  UInt32 channels = size/sizeof(SInt32);
-  SInt32* pMap = new SInt32[channels];
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 0, pMap, &size);
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetInputChannelMap: "
-      "Unable to retrieve AudioUnit input channel map. Error = %s", GetError(ret).c_str());
-  else
-    for (UInt32 i = 0; i < channels; i++)
-      pChannelMap->push_back(pMap[i]);
-  delete[] pMap;
-  return (!ret);
-}
-
-bool CAUOutputDevice::SetChannelMap(CoreAudioChannelList* pChannelMap)
-{
-  // The number of array elements must match the
-  // number of output channels provided by the device
-  if (!m_audioUnit || !pChannelMap)
-    return false;
-
-  UInt32 channels = pChannelMap->size();
-  UInt32 size = sizeof(SInt32) * channels;
-  SInt32* pMap = new SInt32[channels];
-  for (UInt32 i = 0; i < channels; i++)
-    pMap[i] = (*pChannelMap)[i];
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit,
-    kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 0, pMap, size);
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetBufferFrameSize: "
-      "Unable to get current device's buffer size. Error = %s", GetError(ret).c_str());
-  delete[] pMap;
-  return (!ret);
-}
-
-Float32 CAUOutputDevice::GetCurrentVolume()
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float32 volPct = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit,
-    kHALOutputParam_Volume, kAudioUnitScope_Global, 0, &volPct);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetCurrentVolume: "
-      "Unable to get AudioUnit volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return volPct;
-}
-
-bool CAUOutputDevice::SetCurrentVolume(Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit, kHALOutputParam_Volume,
-    kAudioUnitScope_Global, 0, vol, 0);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::SetCurrentVolume: "
-      "Unable to set AudioUnit volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-UInt32 CAUOutputDevice::GetBufferFrameSize()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  UInt32 bufferSize = 0;
-  UInt32 size = sizeof(UInt32);
-
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Input, 0, &bufferSize, &size);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioUnit::GetBufferFrameSize: "
-      "Unable to get current device's buffer size. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-  return bufferSize;
-}
-
-bool CAUOutputDevice::EnableInputOuput()
-{
-  if (!m_audioUnit)
-    return false;
-
-  UInt32 hasio;
-  UInt32 size=sizeof(UInt32);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioOutputUnitProperty_HasIO,kAudioUnitScope_Input, 1, &hasio, &size);
-
-  if (hasio)
-  {
-    UInt32 enable;
-    enable = 0;
-    ret =  AudioUnitSetProperty(m_audioUnit,
-      kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &enable, sizeof(enable));
-    if (ret != noErr)
-    {
-      CLog::Log(LOGERROR, "CAUOutputDevice::EnableInputOuput:: "
-        "Unable to enable input on bus 1. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-
-    enable = 1;
-    ret = AudioUnitSetProperty(m_audioUnit,
-      kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &enable, sizeof(enable));
-    if (ret != noErr)
-    {
-      CLog::Log(LOGERROR, "CAUOutputDevice::EnableInputOuput:: "
-        "Unable to disable output on bus 0. Error = %s", GetError(ret).c_str());
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool CAUOutputDevice::GetPreferredChannelLayout(CCoreAudioChannelLayout& layout)
-{
-  if (!m_DeviceId)
-    return false;
-
-  AudioObjectPropertyAddress propertyAddress; 
-  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput; 
-  propertyAddress.mElement  = 0;
-  propertyAddress.mSelector = kAudioDevicePropertyPreferredChannelLayout; 
-  if (!AudioObjectHasProperty(m_DeviceId, &propertyAddress)) 
-    return false;
-
-  UInt32 propertySize = 0;
-  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize); 
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CAUOutputDevice::GetPreferredChannelLayout: "
-      "Unable to retrieve preferred channel layout size. Error = %s", GetError(ret).c_str());
-
-  void *pBuf = malloc(propertySize);
-  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pBuf); 
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CAUOutputDevice::GetPreferredChannelLayout: "
-      "Unable to retrieve preferred channel layout. Error = %s", GetError(ret).c_str());
-  else
-  {
-    // Copy the result into the caller's instance
-    layout.CopyLayout(*((AudioChannelLayout*)pBuf));
-  }
-  free(pBuf);
-  return (ret == noErr);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// CAUMatrixMixer
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CAUMatrixMixer::CAUMatrixMixer()
-{
-}
-
-CAUMatrixMixer::~CAUMatrixMixer()
-{
-}
-
-bool CAUMatrixMixer::InitMatrixMixerVolumes()
-{
-  // Fetch thechannel configuration
-  UInt32 dims[2];
-  UInt32 size = sizeof(dims);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_MatrixDimensions, kAudioUnitScope_Global, 0, dims, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::Initialize:: "
-      "Get matrix dimesion. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-
-  // Initialize global, input, and output levels
-  if (!SetGlobalVolume(1.0f))
-    return false;
-  for (UInt32 i = 0; i < dims[0]; i++)
-    if (!SetInputVolume(i, 1.0f))
-      return false;
-  for (UInt32 i = 0; i < dims[1]; i++)
-    if (!SetOutputVolume(i, 1.0f))
-      return false;
-
-  return true;
-}
-
-UInt32 CAUMatrixMixer::GetInputBusCount()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  UInt32 busCount = 0;
-  UInt32 size = sizeof(busCount);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &busCount, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::GetInputBusCount: "
-      "Unable to get input bus count. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-  return busCount;
-}
-
-bool CAUMatrixMixer::SetInputBusFormat(UInt32 busCount, AudioStreamBasicDescription *pFormat)
-{
-  if (!m_audioUnit)
-    return false;
-
-  UInt32 enable = 1;
-  for (UInt32 i = 0; i < busCount; i++)
-  {
-    AudioUnitSetParameter(m_audioUnit, kMatrixMixerParam_Enable, kAudioUnitScope_Input, i, enable, 0);
-    if (!SetFormat(pFormat, kAudioUnitScope_Input, i))
-      return false;
-  }
-
-  return true;
-}
-
-bool CAUMatrixMixer::SetInputBusCount(UInt32 busCount)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit,
-    kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &busCount, sizeof(UInt32));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::SetInputBusCount: "
-      "Unable to set input bus count. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-UInt32 CAUMatrixMixer::GetOutputBusCount()
-{
-  if (!m_audioUnit)
-    return 0;
-
-  UInt32 busCount = 0;
-  UInt32 size = sizeof(busCount);
-  OSStatus ret = AudioUnitGetProperty(m_audioUnit,
-    kAudioUnitProperty_ElementCount, kAudioUnitScope_Output, 0, &busCount, &size);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::GetOutputBusCount: "
-      "Unable to get output bus count. Error = %s", GetError(ret).c_str());
-    return 0;
-  }
-  return busCount;
-}
-
-bool CAUMatrixMixer::SetOutputBusCount(UInt32 busCount)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetProperty(m_audioUnit,
-    kAudioUnitProperty_BusCount, kAudioUnitScope_Output, 0, &busCount, sizeof(UInt32));
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::SetOutputBusCount: "
-      "Unable to set output bus count. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-Float32 CAUMatrixMixer::GetGlobalVolume()
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float32 vol = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Global, 0xFFFFFFFF, &vol);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::GetGlobalVolume: "
-      "Unable to get global volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return vol;
-}
-
-bool CAUMatrixMixer::SetGlobalVolume(Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Global, 0xFFFFFFFF, vol, 0);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::SetGlobalVolume: "
-      "Unable to set global volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-Float32 CAUMatrixMixer::GetInputVolume(UInt32 element)
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float32 vol = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Input, element, &vol);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::GetInputVolume: "
-      "Unable to get input volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return vol;
-}
-
-bool CAUMatrixMixer::SetInputVolume(UInt32 element, Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Input, element, vol, 0);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::SetInputVolume: "
-      "Unable to set input volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
-Float32 CAUMatrixMixer::GetOutputVolume(UInt32 element)
-{
-  if (!m_audioUnit)
-    return 0.0f;
-
-  Float32 vol = 0.0f;
-  OSStatus ret = AudioUnitGetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Output, element, &vol);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::GetOutputVolume: "
-      "Unable to get output volume. Error = %s", GetError(ret).c_str());
-    return 0.0f;
-  }
-  return vol;
-}
-
-bool CAUMatrixMixer::SetOutputVolume(UInt32 element, Float32 vol)
-{
-  if (!m_audioUnit)
-    return false;
-
-  OSStatus ret = AudioUnitSetParameter(m_audioUnit,
-    kMatrixMixerParam_Volume, kAudioUnitScope_Output, element, vol, 0);
-  if (ret)
-  {
-    CLog::Log(LOGERROR, "CAUMatrixMixer::SetOutputVolume: "
-      "Unable to set output volume. Error = %s", GetError(ret).c_str());
-    return false;
-  }
-  return true;
-}
-
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioUnit.h
deleted file mode 100644 (file)
index d300a18..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "system.h"
-
-#if defined(TARGET_DARWIN_OSX)
-
-#define INVALID_BUS -1
-#define kOutputBus 0
-#define kInputBus 1
-
-#include "ICoreAudioSource.h"
-#include "CoreAudioChannelLayout.h"
-
-#include <AudioToolbox/AUGraph.h>
-#include <CoreAudio/CoreAudio.h>
-#include <CoreServices/CoreServices.h>
-
-class CCoreAudioUnit
-{
-public:
-  CCoreAudioUnit();
-  virtual ~CCoreAudioUnit();
-  
-  virtual bool      Open(AUGraph audioGraph, AudioComponentDescription desc);
-  virtual bool      Open(AUGraph audioGraph, OSType type, OSType subType, OSType manufacturer);
-  virtual void      Close();
-  virtual bool      SetInputSource(ICoreAudioSource *pSource);
-  virtual bool      IsInitialized() {return m_Initialized;}
-  virtual bool      GetFormat(AudioStreamBasicDescription *pDesc, AudioUnitScope scope, AudioUnitElement bus);    
-  virtual bool      SetFormat(AudioStreamBasicDescription *pDesc, AudioUnitScope scope, AudioUnitElement bus);
-  virtual bool      SetMaxFramesPerSlice(UInt32 maxFrames);
-  virtual bool      GetSupportedChannelLayouts(AudioChannelLayoutList* pLayouts);
-  virtual void      GetFormatDesc(AEAudioFormat format, 
-                      AudioStreamBasicDescription *streamDesc, AudioStreamBasicDescription *coreaudioDesc, bool encoded = false);
-  virtual float     GetLatency();
-  virtual bool      Stop();
-  virtual bool      Start();
-  virtual AudioUnit GetUnit  (){return m_audioUnit;}
-  virtual AUGraph   GetGraph (){return m_audioGraph;}
-  virtual AUNode    GetNode  (){return m_audioNode;}
-  virtual int       GetBus   (){return m_busNumber;}
-  virtual void      SetBus   (int busNumber){m_busNumber = busNumber;}
-  
-protected:
-  bool SetRenderProc();
-  bool RemoveRenderProc();
-  static OSStatus RenderCallback(void *inRefCon, 
-    AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp, 
-    UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
-
-  ICoreAudioSource*   m_pSource;
-  AudioUnit           m_audioUnit;
-  AUNode              m_audioNode;
-  AUGraph             m_audioGraph;
-  bool                m_Initialized;
-  AURenderCallback    m_renderProc;
-  int                 m_busNumber;
-};
-
-class CAUOutputDevice : public CCoreAudioUnit
-{
-public:
-  CAUOutputDevice();
-  virtual ~CAUOutputDevice();
-
-  bool            SetCurrentDevice(AudioDeviceID deviceId);
-  bool            GetChannelMap(CoreAudioChannelList *pChannelMap);
-  bool            SetChannelMap(CoreAudioChannelList *pChannelMap);
-  UInt32          GetBufferFrameSize();
-  
-  Float32         GetCurrentVolume();
-  bool            SetCurrentVolume(Float32 vol);
-  bool            EnableInputOuput();
-  virtual bool    GetPreferredChannelLayout(CCoreAudioChannelLayout &layout);
-
-protected:
-  AudioDeviceID   m_DeviceId;
-};
-
-class CAUMatrixMixer : public CAUOutputDevice
-{
-public:
-  CAUMatrixMixer();
-  virtual ~CAUMatrixMixer();
-
-  bool            InitMatrixMixerVolumes();
-  
-  UInt32          GetInputBusCount();
-  bool            SetInputBusFormat(UInt32 busCount, AudioStreamBasicDescription *pFormat);
-  bool            SetInputBusCount(UInt32 busCount);
-  UInt32          GetOutputBusCount();
-  bool            SetOutputBusCount(UInt32 busCount);
-  
-  Float32         GetGlobalVolume();
-  bool            SetGlobalVolume(Float32 vol);
-  Float32         GetInputVolume(UInt32 element);
-  bool            SetInputVolume(UInt32 element, Float32 vol);
-  Float32         GetOutputVolume(UInt32 element);
-  bool            SetOutputVolume(UInt32 element, Float32 vol);
-};
-
-#endif
\ No newline at end of file
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioAEHAL.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioAEHAL.h
deleted file mode 100644 (file)
index 9c6936c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 "cores/AudioEngine/Utils/AEAudioFormat.h"
-#include "cores/AudioEngine/Interfaces/AE.h"
-#include "ICoreAudioSource.h"
-
-class ICoreAudioAEHAL;
-class CAUOutputDevice;
-
-/**
- * ICoreAudioAEHAL Interface
- */
-class ICoreAudioAEHAL
-{
-protected:
-  ICoreAudioAEHAL() {}
-  virtual ~ICoreAudioAEHAL() {}
-
-public:
-  virtual bool   Initialize(ICoreAudioSource *ae, bool passThrough, AEAudioFormat &format, AEDataFormat rawDataFormat, std::string &device, float initVolume) = 0;
-  virtual void   Deinitialize() = 0;
-  virtual void   EnumerateOutputDevices(AEDeviceList &devices, bool passthrough) = 0;
-  //virtual CAUOutputDevice *DestroyUnit(CAUOutputDevice *outputUnit);
-  //virtual CAUOutputDevice *CreateUnit(ICoreAudioSource *pSource, AEAudioFormat &format);
-  //virtual void  SetDirectInput(ICoreAudioSource *pSource, AEAudioFormat &format);
-  virtual void   Stop() = 0;
-  virtual bool   Start() = 0;
-  virtual double GetDelay() = 0;
-  virtual void   SetVolume(float volume) = 0;
-};
diff --git a/xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioSource.h b/xbmc/cores/AudioEngine/Engines/CoreAudio/ICoreAudioSource.h
deleted file mode 100644 (file)
index 5930ec2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011-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 <AudioUnit/AudioUnit.h>
-
-#include "cores/AudioEngine/Utils/AEAudioFormat.h"
-#include "cores/AudioEngine/Interfaces/AE.h"
-#include "utils/StdString.h"
-
-class ICoreAudioSource;
-
-/**
- * ICoreAudioSource Interface
- */
-class ICoreAudioSource
-{
-private:
-  std::string        m_inputName;
-  AudioUnitElement  m_inputBus;
-public:
-  // Function to request rendered data from a data source
-  virtual OSStatus Render(AudioUnitRenderActionFlags* actionFlags, 
-                          const AudioTimeStamp* pTimeStamp, 
-                          UInt32 busNumber, 
-                          UInt32 frameCount, 
-                          AudioBufferList* pBufList) = 0;
-  //std::string InputName() { return m_inputName; };
-  //void InputName(std::string inputName) { m_inputName = inputName; };
-
-  //AudioUnitElement InputBus() { return m_inputBus; };
-  //void InputBus(AudioUnitElement inputBus) { m_inputBus = m_inputBus; };
-};
index f91dc4c..dd32897 100644 (file)
@@ -232,5 +232,10 @@ public:
    * @param millis time for which old configuration should be kept
    */
   virtual void KeepConfiguration(unsigned int millis) {return; }
+
+  /**
+   * Instruct AE to re-initialize, e.g. after ELD change event
+   */
+  virtual void DeviceChange() {return; }
 };
 
index 3815a16..c22c87e 100644 (file)
@@ -20,21 +20,6 @@ CXXFLAGS += -D__STDC_LIMIT_MACROS
 
 SRCS  = AEFactory.cpp
 
-ifeq ($(findstring osx,@ARCH@),osx)
-SRCS += Engines/CoreAudio/CoreAudioAE.cpp
-SRCS += Engines/CoreAudio/CoreAudioAEHAL.cpp
-SRCS += Engines/CoreAudio/CoreAudioAEHALOSX.cpp
-SRCS += Engines/CoreAudio/CoreAudioAESound.cpp
-SRCS += Engines/CoreAudio/CoreAudioAEStream.cpp
-SRCS += Engines/CoreAudio/CoreAudioChannelLayout.cpp
-SRCS += Engines/CoreAudio/CoreAudioDevice.cpp
-SRCS += Engines/CoreAudio/CoreAudioGraph.cpp
-SRCS += Engines/CoreAudio/CoreAudioHardware.cpp
-SRCS += Engines/CoreAudio/CoreAudioMixMap.cpp
-SRCS += Engines/CoreAudio/CoreAudioStream.cpp
-SRCS += Engines/CoreAudio/CoreAudioUnit.cpp
-else
-
 SRCS += AESinkFactory.cpp
 SRCS += Sinks/AESinkNULL.cpp
 SRCS += Sinks/AESinkProfiler.cpp
@@ -50,6 +35,15 @@ SRCS += Engines/ActiveAE/ActiveAEBuffer.cpp
 
 ifeq (@USE_ANDROID@,1)
 SRCS += Sinks/AESinkAUDIOTRACK.cpp
+else ifeq ($(findstring ios,@ARCH@),ios)
+SRCS += Sinks/AESinkDARWINIOS.cpp
+else ifeq ($(findstring osx,@ARCH@),osx)
+SRCS += Sinks/AESinkDARWINOSX.cpp
+SRCS += Sinks/osx/CoreAudioChannelCount.cpp
+SRCS += Sinks/osx/CoreAudioDevice.cpp
+SRCS += Sinks/osx/CoreAudioHardware.cpp
+SRCS += Sinks/osx/CoreAudioHelpers.cpp
+SRCS += Sinks/osx/CoreAudioStream.cpp
 else
 SRCS += Sinks/AESinkALSA.cpp
 SRCS += Sinks/AESinkOSS.cpp
@@ -57,7 +51,6 @@ ifeq (@USE_PULSE@,1)
 SRCS += Sinks/AESinkPULSE.cpp
 endif
 endif
-endif
 
 SRCS += Utils/AEChannelInfo.cpp
 SRCS += Utils/AEBuffer.cpp
index c9ab554..c4f59a8 100644 (file)
@@ -973,6 +973,18 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev
             /* snd_hctl_close also closes ctlhandle */
             snd_hctl_close(hctl);
 
+            // regarding data formats we don't trust ELD
+            // push all passthrough formats to the list
+            AEDataFormatList::iterator it;
+            for (enum AEDataFormat i = AE_FMT_MAX; i > AE_FMT_INVALID; i = (enum AEDataFormat)((int)i - 1))
+            {
+              if (!AE_IS_RAW(i))
+                continue;
+              it = find(info.m_dataFormats.begin(), info.m_dataFormats.end(), i);
+              if (it == info.m_dataFormats.end())
+                info.m_dataFormats.push_back(i);
+            }
+
             if (badHDMI)
             {
               /* 
@@ -997,6 +1009,9 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev
       if (!info.m_displayNameExtra.empty())
         info.m_displayNameExtra += ' ';
       info.m_displayNameExtra += "S/PDIF";
+
+      info.m_dataFormats.push_back(AE_FMT_AC3);
+      info.m_dataFormats.push_back(AE_FMT_DTS);
     }
     else if (info.m_displayNameExtra.empty())
     {
index 46a0f3a..d34c507 100644 (file)
@@ -260,7 +260,11 @@ void CAESinkAUDIOTRACK::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
 #if defined(HAS_LIBAMCODEC)
   // AML devices can do passthough
   if (aml_present())
+  {
     m_info.m_deviceType = AE_DEVTYPE_HDMI;
+    m_info.m_dataFormats.push_back(AE_FMT_AC3);
+    m_info.m_dataFormats.push_back(AE_FMT_DTS);
+  }
 #endif
   m_info.m_deviceName = "AudioTrack";
   m_info.m_displayName = "android";
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp
new file mode 100644 (file)
index 0000000..fa49cba
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+ *      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/>.
+ *
+ */
+
+#include "cores/AudioEngine/Sinks/AESinkDARWINIOS.h"
+#include "cores/AudioEngine/Utils/AEUtil.h"
+#include "cores/AudioEngine/Utils/AERingBuffer.h"
+#include "cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h"
+#include "osx/DarwinUtils.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+#include "threads/Condition.h"
+#include "windowing/WindowingFactory.h"
+
+#include <sstream>
+#include <AudioToolbox/AudioToolbox.h>
+
+#define CA_MAX_CHANNELS 8
+static enum AEChannel CAChannelMap[CA_MAX_CHANNELS + 1] = {
+  AE_CH_FL , AE_CH_FR , AE_CH_BL , AE_CH_BR , AE_CH_FC , AE_CH_LFE , AE_CH_SL , AE_CH_SR ,
+  AE_CH_NULL
+};
+
+/***************************************************************************************/
+/***************************************************************************************/
+#if DO_440HZ_TONE_TEST
+static void SineWaveGeneratorInitWithFrequency(SineWaveGenerator *ctx, double frequency, double samplerate)
+{
+  // Given:
+  //   frequency in cycles per second
+  //   2*PI radians per sine wave cycle
+  //   sample rate in samples per second
+  //
+  // Then:
+  //   cycles     radians     seconds     radians
+  //   ------  *  -------  *  -------  =  -------
+  //   second      cycle      sample      sample
+  ctx->currentPhase = 0.0;
+  ctx->phaseIncrement = frequency * 2*M_PI / samplerate;
+}
+
+static int16_t SineWaveGeneratorNextSampleInt16(SineWaveGenerator *ctx)
+{
+  int16_t sample = INT16_MAX * sinf(ctx->currentPhase);
+
+  ctx->currentPhase += ctx->phaseIncrement;
+  // Keep the value between 0 and 2*M_PI
+  while (ctx->currentPhase > 2*M_PI)
+    ctx->currentPhase -= 2*M_PI;
+
+  return sample / 4;
+}
+static float SineWaveGeneratorNextSampleFloat(SineWaveGenerator *ctx)
+{
+  float sample = MAXFLOAT * sinf(ctx->currentPhase);
+  
+  ctx->currentPhase += ctx->phaseIncrement;
+  // Keep the value between 0 and 2*M_PI
+  while (ctx->currentPhase > 2*M_PI)
+    ctx->currentPhase -= 2*M_PI;
+  
+  return sample / 4;
+}
+#endif
+
+/***************************************************************************************/
+/***************************************************************************************/
+class CAAudioUnitSink
+{
+  public:
+    CAAudioUnitSink();
+   ~CAAudioUnitSink();
+
+    bool         open(AudioStreamBasicDescription outputFormat);
+    bool         close();
+    bool         play(bool mute);
+    bool         mute(bool mute);
+    bool         pause();
+    void         drain();
+    double       getDelay();
+    double       cacheSize();
+    unsigned int write(uint8_t *data, unsigned int byte_count);
+    unsigned int chunkSize() { return m_bufferDuration * m_sampleRate; }
+    unsigned int getRealisedSampleRate() { return m_outputFormat.mSampleRate; }
+    static Float64 getCoreAudioRealisedSampleRate();
+
+  private:
+    void         setCoreAudioBuffersize();
+    bool         setCoreAudioInputFormat();
+    void         setCoreAudioPreferredSampleRate();
+    bool         setupAudio();
+    bool         checkAudioRoute();
+    bool         checkSessionProperties();
+    bool         activateAudioSession();
+    void         deactivateAudioSession();
+    // callbacks
+    static void sessionPropertyCallback(void *inClientData,
+                  AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData);
+
+    static void sessionInterruptionCallback(void *inClientData, UInt32 inInterruption);
+
+    static OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
+                  const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames,
+                  AudioBufferList *ioData);
+
+    bool                m_setup;
+    bool                m_initialized;
+    bool                m_activated;
+    AudioUnit           m_audioUnit;
+    AudioStreamBasicDescription m_outputFormat;
+    AERingBuffer       *m_buffer;
+
+    bool                m_mute;
+    Float32             m_outputVolume;
+    Float32             m_outputLatency;
+    Float32             m_bufferDuration;
+
+    unsigned int        m_sampleRate;
+    unsigned int        m_frameSize;
+    unsigned int        m_frames;
+
+    bool                m_playing;
+    bool                m_playing_saved;
+    volatile bool       m_started;
+};
+
+CAAudioUnitSink::CAAudioUnitSink()
+: m_initialized(false)
+, m_activated(false)
+, m_buffer(NULL)
+, m_playing(false)
+, m_playing_saved(false)
+, m_started(false)
+{
+}
+
+CAAudioUnitSink::~CAAudioUnitSink()
+{
+  close();
+}
+
+bool CAAudioUnitSink::open(AudioStreamBasicDescription outputFormat)
+{
+  m_mute          = false;
+  m_setup         = false;
+  m_outputFormat  = outputFormat;
+  m_outputLatency = 0.0;
+  m_bufferDuration= 0.0;
+  m_outputVolume  = 1.0;
+  m_sampleRate    = (unsigned int)outputFormat.mSampleRate;
+  m_frameSize     = outputFormat.mChannelsPerFrame * outputFormat.mBitsPerChannel / 8;
+
+  /* TODO: Reduce the size of this buffer, pre-calculate the size based on how large
+           the buffers are that CA calls us with in the renderCallback - perhaps call
+           the checkSessionProperties() before running this? */
+  m_buffer = new AERingBuffer(16384);
+
+  return setupAudio();
+}
+
+bool CAAudioUnitSink::close()
+{
+  deactivateAudioSession();
+  
+  delete m_buffer;
+  m_buffer = NULL;
+
+  m_started = false;
+  return true;
+}
+
+bool CAAudioUnitSink::play(bool mute)
+{    
+  if (!m_playing)
+  {
+    if (activateAudioSession())
+    {
+      CAAudioUnitSink::mute(mute);
+      m_playing = !AudioOutputUnitStart(m_audioUnit);
+    }
+  }
+
+  return m_playing;
+}
+
+bool CAAudioUnitSink::mute(bool mute)
+{
+  m_mute = mute;
+
+  return true;
+}
+
+bool CAAudioUnitSink::pause()
+{      
+  if (m_playing)
+    m_playing = AudioOutputUnitStop(m_audioUnit);
+
+  return m_playing;
+}
+
+double CAAudioUnitSink::getDelay()
+{
+  double delay = (double)m_buffer->GetReadSize() / m_frameSize;
+  delay /= m_sampleRate;
+  delay += m_bufferDuration + m_outputLatency;
+
+  return delay;
+}
+
+double CAAudioUnitSink::cacheSize()
+{
+  return (double)m_buffer->GetMaxSize() / (double)(m_frameSize * m_sampleRate);
+}
+
+CCriticalSection mutex;
+XbmcThreads::ConditionVariable condVar;
+
+unsigned int CAAudioUnitSink::write(uint8_t *data, unsigned int frames)
+{
+  if (m_buffer->GetWriteSize() < frames * m_frameSize)
+  { // no space to write - wait for a bit
+    CSingleLock lock(mutex);
+    if (!m_started)
+      condVar.wait(lock);
+    else
+      condVar.wait(lock, 900 * frames / m_sampleRate);
+  }
+
+  unsigned int write_frames = std::min(frames, m_buffer->GetWriteSize() / m_frameSize);
+  if (write_frames)
+    m_buffer->Write(data, write_frames * m_frameSize);
+  
+  return write_frames;
+}
+
+void CAAudioUnitSink::drain()
+{
+  CCriticalSection mutex;
+  unsigned int bytes = m_buffer->GetReadSize();
+  while (bytes)
+  {
+    CSingleLock lock(mutex);
+    condVar.wait(mutex, 900 * bytes / (m_sampleRate * m_frameSize));
+    bytes = m_buffer->GetReadSize();
+  }
+}
+
+void CAAudioUnitSink::setCoreAudioBuffersize()
+{
+#if !TARGET_IPHONE_SIMULATOR
+  OSStatus status = noErr;
+  // set the buffer size, this affects the number of samples
+  // that get rendered every time the audio callback is fired.
+  Float32 preferredBufferSize = 512 * m_outputFormat.mChannelsPerFrame / m_outputFormat.mSampleRate;
+  CLog::Log(LOGNOTICE, "%s setting buffer duration to %f", __PRETTY_FUNCTION__, preferredBufferSize);
+  status = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,
+                                   sizeof(preferredBufferSize), &preferredBufferSize);
+  if (status != noErr)
+    CLog::Log(LOGWARNING, "%s preferredBufferSize couldn't be set (error: %d)", __PRETTY_FUNCTION__, (int)status);
+#endif
+}
+
+bool CAAudioUnitSink::setCoreAudioInputFormat()
+{
+  // Set the output stream format
+  UInt32 ioDataSize = sizeof(AudioStreamBasicDescription);
+  OSStatus status = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat,
+                                kAudioUnitScope_Input, 0, &m_outputFormat, ioDataSize);
+  if (status != noErr)
+  {
+    CLog::Log(LOGERROR, "%s error setting stream format on audioUnit (error: %d)", __PRETTY_FUNCTION__, (int)status);
+    return false;
+  }
+  return true;
+}
+
+void CAAudioUnitSink::setCoreAudioPreferredSampleRate()
+{
+  Float64 preferredSampleRate = m_outputFormat.mSampleRate;
+  CLog::Log(LOGNOTICE, "%s requesting hw samplerate %f", __PRETTY_FUNCTION__, preferredSampleRate);
+  OSStatus status = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate,
+                                   sizeof(preferredSampleRate), &preferredSampleRate);
+  if (status != noErr)
+    CLog::Log(LOGWARNING, "%s preferredSampleRate couldn't be set (error: %d)", __PRETTY_FUNCTION__, (int)status);
+}
+
+Float64 CAAudioUnitSink::getCoreAudioRealisedSampleRate()
+{
+  Float64 outputSampleRate = 0.0;
+  UInt32 ioDataSize = sizeof(outputSampleRate);
+  if (AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate,
+                              &ioDataSize, &outputSampleRate) != noErr)
+    CLog::Log(LOGERROR, "%s: error getting CurrentHardwareSampleRate", __FUNCTION__);
+  return outputSampleRate;
+}
+
+bool CAAudioUnitSink::setupAudio()
+{
+  OSStatus status = noErr;
+  if (m_setup && m_audioUnit)
+    return true;
+
+  // Audio Session Setup
+  UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
+  status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
+                                   sizeof(sessionCategory), &sessionCategory);
+  if (status != noErr)
+  {
+    CLog::Log(LOGERROR, "%s error setting sessioncategory (error: %d)", __PRETTY_FUNCTION__, (int)status);
+    return false;
+  }
+
+  AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,
+    sessionPropertyCallback, this);
+
+  AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume,
+    sessionPropertyCallback, this);
+  if (AudioSessionSetActive(true) != noErr)
+    return false;
+
+  // Audio Unit Setup
+  // Describe a default output unit.
+  AudioComponentDescription description = {};
+  description.componentType = kAudioUnitType_Output;
+  description.componentSubType = kAudioUnitSubType_RemoteIO;
+  description.componentManufacturer = kAudioUnitManufacturer_Apple;
+
+  // Get component
+  AudioComponent component;
+  component = AudioComponentFindNext(NULL, &description);
+  status = AudioComponentInstanceNew(component, &m_audioUnit);
+  if (status != noErr)
+  {
+    CLog::Log(LOGERROR, "%s error creating audioUnit (error: %d)", __PRETTY_FUNCTION__, (int)status);
+    return false;
+  }
+  
+  setCoreAudioPreferredSampleRate();
+       // Get the output samplerate for knowing what was setup in reality
+  Float64 realisedSampleRate = getCoreAudioRealisedSampleRate();
+  if (m_outputFormat.mSampleRate != realisedSampleRate)
+  {
+    CLog::Log(LOGNOTICE, "%s couldn't set requested samplerate %d, coreaudio will resample to %d instead", __PRETTY_FUNCTION__, (int)m_outputFormat.mSampleRate, (int)realisedSampleRate);
+    // if we don't ca to resample - but instead let activeae resample -
+    // reflect the realised samplerate to the outputformat here
+    // well maybe it is handy in the future - as of writing this
+    // ca was about 6 times faster then activeae ;)
+    //m_outputFormat.mSampleRate = realisedSampleRate;
+    //m_sampleRate = realisedSampleRate;
+  }
+
+  setCoreAudioBuffersize();
+  if (!setCoreAudioInputFormat())
+    return false;
+
+  // Attach a render callback on the unit
+  AURenderCallbackStruct callbackStruct = {};
+  callbackStruct.inputProc = renderCallback;
+  callbackStruct.inputProcRefCon = this;
+  status = AudioUnitSetProperty(m_audioUnit,
+                                kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+                                0, &callbackStruct, sizeof(callbackStruct));
+  if (status != noErr)
+  {
+    CLog::Log(LOGERROR, "%s error setting render callback for audioUnit (error: %d)", __PRETTY_FUNCTION__, (int)status);
+    return false;
+  }
+
+  status = AudioUnitInitialize(m_audioUnit);
+       if (status != noErr)
+  {
+    CLog::Log(LOGERROR, "%s error initializing audioUnit (error: %d)", __PRETTY_FUNCTION__, (int)status);
+    return false;
+  }
+
+  checkSessionProperties();
+
+  m_setup = true;
+  std::string formatString;
+  CLog::Log(LOGNOTICE, "%s setup audio format: %s", __PRETTY_FUNCTION__, StreamDescriptionToString(m_outputFormat, formatString));
+
+  return m_setup;
+}
+
+bool CAAudioUnitSink::checkAudioRoute()
+{
+  // why do we need to know the audio route ?
+  CFStringRef route;
+  UInt32 propertySize = sizeof(CFStringRef);
+  if (AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route) != noErr)
+    return false;
+
+  return true;
+}
+
+bool CAAudioUnitSink::checkSessionProperties()
+{
+  checkAudioRoute();
+
+  UInt32 ioDataSize;
+  ioDataSize = sizeof(m_outputVolume);
+  if (AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume,
+    &ioDataSize, &m_outputVolume) != noErr)
+    CLog::Log(LOGERROR, "%s: error getting CurrentHardwareOutputVolume", __FUNCTION__);
+
+  ioDataSize = sizeof(m_outputLatency);
+  if (AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputLatency,
+    &ioDataSize, &m_outputLatency) != noErr)
+    CLog::Log(LOGERROR, "%s: error getting CurrentHardwareOutputLatency", __FUNCTION__);
+
+  ioDataSize = sizeof(m_bufferDuration);
+  if (AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration,
+    &ioDataSize, &m_bufferDuration) != noErr)
+    CLog::Log(LOGERROR, "%s: error getting CurrentHardwareIOBufferDuration", __FUNCTION__);
+   
+  CLog::Log(LOGDEBUG, "%s: volume = %f, latency = %f, buffer = %f", __FUNCTION__, m_outputVolume, m_outputLatency, m_bufferDuration);
+  return true;
+}
+
+bool CAAudioUnitSink::activateAudioSession()
+{
+  if (!m_activated)
+  {
+    if (!m_initialized)
+    {
+      OSStatus osstat = AudioSessionInitialize(NULL, kCFRunLoopDefaultMode, sessionInterruptionCallback, this);
+      if (osstat == kAudioSessionNoError || osstat == kAudioSessionAlreadyInitialized)
+        m_initialized = true;
+      else
+      {
+        CLog::Log(LOGERROR, "%s error initializing audio session (error: %d)", __PRETTY_FUNCTION__, (int)osstat);
+        return false;
+      }
+    }
+    if (checkAudioRoute() && setupAudio())
+      m_activated = true;
+  }
+
+  return m_activated;
+}
+
+void CAAudioUnitSink::deactivateAudioSession()
+{
+  if (m_activated)
+  {
+    pause();
+    AudioUnitUninitialize(m_audioUnit);
+    AudioComponentInstanceDispose(m_audioUnit), m_audioUnit = NULL;
+    AudioSessionSetActive(false);
+    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange,
+      sessionPropertyCallback, this);
+    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume,
+      sessionPropertyCallback, this);
+
+    m_setup = false;
+    m_activated = false;
+  }
+}
+
+void CAAudioUnitSink::sessionPropertyCallback(void *inClientData,
+  AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData)
+{
+  CAAudioUnitSink *sink = (CAAudioUnitSink*)inClientData;
+
+  if (inID == kAudioSessionProperty_AudioRouteChange)
+  {
+    if (sink->checkAudioRoute())
+      sink->checkSessionProperties();
+  }
+  else if (inID == kAudioSessionProperty_CurrentHardwareOutputVolume)
+  {
+    if (inData && inDataSize == 4)
+      sink->m_outputVolume = *(float*)inData;
+  }
+}
+
+void CAAudioUnitSink::sessionInterruptionCallback(void *inClientData, UInt32 inInterruption)
+{    
+  CAAudioUnitSink *sink = (CAAudioUnitSink*)inClientData;
+
+  if (inInterruption == kAudioSessionBeginInterruption)
+  {
+    CLog::Log(LOGDEBUG, "Bgn interuption");
+    sink->m_playing_saved = sink->m_playing;
+    sink->pause();
+  }
+  else if (inInterruption == kAudioSessionEndInterruption)
+  {
+    CLog::Log(LOGDEBUG, "End interuption");
+    if (sink->m_playing_saved)
+    {
+      sink->m_playing_saved = false;
+      sink->play(sink->m_mute);
+    }
+  }
+}
+
+OSStatus CAAudioUnitSink::renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
+  const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
+{
+  CAAudioUnitSink *sink = (CAAudioUnitSink*)inRefCon;
+
+  sink->m_started = true;
+
+  for (unsigned int i = 0; i < ioData->mNumberBuffers; i++)
+  {
+    // buffers come from CA already zero'd, so just copy what is wanted
+    unsigned int wanted = ioData->mBuffers[i].mDataByteSize;
+    unsigned int bytes = std::min(sink->m_buffer->GetReadSize(), wanted);
+    sink->m_buffer->Read((unsigned char*)ioData->mBuffers[i].mData, bytes);
+    if (bytes != wanted)
+      CLog::Log(LOGERROR, "%s: %sFLOW (%i vs %i) bytes", __FUNCTION__, bytes > wanted ? "OVER" : "UNDER", bytes, wanted);
+  }
+  // tell the sink we're good for more data
+  condVar.notifyAll();
+
+  return noErr;
+}
+
+/***************************************************************************************/
+/***************************************************************************************/
+static void EnumerateDevices(AEDeviceInfoList &list)
+{
+  CAEDeviceInfo device;
+
+  device.m_deviceName = "default";
+  device.m_displayName = "Default";
+  device.m_displayNameExtra = "";
+#if defined(TARGET_DARWIN_IOS_ATV2)
+  device.m_deviceType = AE_DEVTYPE_IEC958;
+  device.m_dataFormats.push_back(AE_FMT_AC3);
+  device.m_dataFormats.push_back(AE_FMT_DTS);
+#else
+  // TODO screen changing on ios needs to call
+  // devices changed once this is available in activae
+  if (g_Windowing.GetCurrentScreen() > 0)
+  {
+    device.m_deviceType = AE_DEVTYPE_IEC958; //allow passthrough for tvout
+    device.m_dataFormats.push_back(AE_FMT_AC3);
+    device.m_dataFormats.push_back(AE_FMT_DTS);
+  }
+  else
+    device.m_deviceType = AE_DEVTYPE_PCM;
+#endif
+
+  // add channel info
+  CAEChannelInfo channel_info;
+  for (UInt32 chan = 0; chan < 2; ++chan)
+  {
+    if (!device.m_channels.HasChannel(CAChannelMap[chan]))
+      device.m_channels += CAChannelMap[chan];
+    channel_info += CAChannelMap[chan];
+  }
+
+  // there are more supported ( one of those 2 gets resampled
+  // by coreaudio anyway) - but for keeping it save ignore
+  // the others...
+  device.m_sampleRates.push_back(44100);
+  device.m_sampleRates.push_back(48000);
+
+  device.m_dataFormats.push_back(AE_FMT_S16LE);
+  //device.m_dataFormats.push_back(AE_FMT_S24LE3);
+  //device.m_dataFormats.push_back(AE_FMT_S32LE);
+  // AE_FMT_FLOAT is 3% slower on atv2
+  // then S16LE - so leave it out for now
+  //device.m_dataFormats.push_back(AE_FMT_FLOAT);
+
+  CLog::Log(LOGDEBUG, "EnumerateDevices:Device(%s)" , device.m_deviceName.c_str());
+
+  list.push_back(device);
+}
+
+/***************************************************************************************/
+/***************************************************************************************/
+AEDeviceInfoList CAESinkDARWINIOS::m_devices;
+
+CAESinkDARWINIOS::CAESinkDARWINIOS()
+:   m_audioSink(NULL)
+{
+}
+
+CAESinkDARWINIOS::~CAESinkDARWINIOS()
+{
+}
+
+bool CAESinkDARWINIOS::Initialize(AEAudioFormat &format, std::string &device)
+{
+  bool found = false;
+  bool forceRaw = false;
+
+  std::string devicelower = device;
+  StringUtils::ToLower(devicelower);
+  for (size_t i = 0; i < m_devices.size(); i++)
+  {
+    if (devicelower.find(m_devices[i].m_deviceName) != std::string::npos)
+    {
+      m_info = m_devices[i];
+      found = true;
+      break;
+    }
+  }
+  
+  if (!found)
+    return false;
+
+  AudioStreamBasicDescription audioFormat = {};
+
+  // AE_FMT_FLOAT is 3% slower on atv2
+  // then S16LE - so leave it out for now
+  // just leave the code commented in here
+  // as it might come handy at some point maybe ...
+  //if (format.m_dataFormat == AE_FMT_FLOAT)
+  //  audioFormat.mFormatFlags    |= kLinearPCMFormatFlagIsFloat;
+  //else// this will be selected when AE wants AC3 or DTS or anything other then float
+  {
+    audioFormat.mFormatFlags    |= kLinearPCMFormatFlagIsSignedInteger;
+    if (AE_IS_RAW(format.m_dataFormat))
+      forceRaw = true;
+    format.m_dataFormat = AE_FMT_S16LE;
+  }
+
+  format.m_channelLayout = m_info.m_channels;
+  format.m_frameSize = format.m_channelLayout.Count() * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
+
+  
+  audioFormat.mFormatID = kAudioFormatLinearPCM;
+  switch(format.m_sampleRate)
+  {
+    case 11025:
+    case 22050:
+    case 44100:
+    case 88200:
+    case 176400:
+      audioFormat.mSampleRate = 44100;
+      break;
+    default:
+    case 8000:
+    case 12000:
+    case 16000:
+    case 24000:
+    case 32000:
+    case 48000:
+    case 96000:
+    case 192000:
+    case 384000:
+      audioFormat.mSampleRate = 48000;
+      break;
+  }
+  
+  if (forceRaw)//make sure input and output samplerate match for preventing resampling
+    audioFormat.mSampleRate = CAAudioUnitSink::getCoreAudioRealisedSampleRate();
+  
+  audioFormat.mFramesPerPacket = 1;
+  audioFormat.mChannelsPerFrame= 2;// ios only supports 2 channels
+  audioFormat.mBitsPerChannel  = CAEUtil::DataFormatToBits(format.m_dataFormat);
+  audioFormat.mBytesPerFrame   = format.m_frameSize;
+  audioFormat.mBytesPerPacket  = audioFormat.mBytesPerFrame * audioFormat.mFramesPerPacket;
+  audioFormat.mFormatFlags    |= kLinearPCMFormatFlagIsPacked;
+  
+#if DO_440HZ_TONE_TEST
+  SineWaveGeneratorInitWithFrequency(&m_SineWaveGenerator, 440.0, audioFormat.mSampleRate);
+#endif
+
+  m_audioSink = new CAAudioUnitSink;
+  m_audioSink->open(audioFormat);
+
+  format.m_frames = m_audioSink->chunkSize();
+  format.m_frameSamples = format.m_frames * audioFormat.mChannelsPerFrame;
+  // reset to the realised samplerate
+  format.m_sampleRate = m_audioSink->getRealisedSampleRate();
+  m_format = format;
+
+  m_volume_changed = false;
+  m_audioSink->play(false);
+
+  return true;
+}
+
+void CAESinkDARWINIOS::Deinitialize()
+{
+  delete m_audioSink;
+  m_audioSink = NULL;
+}
+
+bool CAESinkDARWINIOS::IsCompatible(const AEAudioFormat &format, const std::string &device)
+{
+  return ((m_format.m_sampleRate    == format.m_sampleRate) &&
+          (m_format.m_dataFormat    == format.m_dataFormat) &&
+          (m_format.m_channelLayout == format.m_channelLayout));
+}
+
+double CAESinkDARWINIOS::GetDelay()
+{
+  if (m_audioSink)
+    return m_audioSink->getDelay();
+  return 0.0;
+}
+
+double CAESinkDARWINIOS::GetCacheTotal()
+{
+  if (m_audioSink)
+    return m_audioSink->cacheSize();
+  return 0.0;
+}
+
+unsigned int CAESinkDARWINIOS::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
+{
+  
+#if DO_440HZ_TONE_TEST
+  if (m_format.m_dataFormat == AE_FMT_FLOAT)
+  {
+    float *samples = (float*)data;
+    for (unsigned int j = 0; j < frames ; j++)
+    {
+      float sample = SineWaveGeneratorNextSampleFloat(&m_SineWaveGenerator);
+      *samples++ = sample;
+      *samples++ = sample;
+    }
+    
+  }
+  else
+  {
+    int16_t *samples = (int16_t*)data;
+    for (unsigned int j = 0; j < frames ; j++)
+    {
+      int16_t sample = SineWaveGeneratorNextSampleInt16(&m_SineWaveGenerator);
+      *samples++ = sample;
+      *samples++ = sample;
+    }
+  }
+#endif
+  if (m_audioSink)
+    return m_audioSink->write(data, frames);
+  return 0;
+}
+
+void CAESinkDARWINIOS::Drain()
+{
+  if (m_audioSink)
+    m_audioSink->drain();
+}
+
+bool CAESinkDARWINIOS::HasVolume()
+{
+  return false;
+}
+
+void  CAESinkDARWINIOS::SetVolume(float scale)
+{
+  // CoreAudio uses fixed steps, reverse scale back to percent
+  float gain = CAEUtil::ScaleToGain(scale);
+  m_volume = CAEUtil::GainToPercent(gain);
+  m_volume_changed = true;
+}
+
+void CAESinkDARWINIOS::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
+{
+  m_devices.clear();
+  EnumerateDevices(m_devices);
+  list = m_devices;
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.h b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.h
new file mode 100644 (file)
index 0000000..f1fec67
--- /dev/null
@@ -0,0 +1,68 @@
+#pragma once
+/*
+ *      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/>.
+ *
+ */
+
+#include "cores/AudioEngine/Interfaces/AESink.h"
+#include "cores/AudioEngine/Utils/AEDeviceInfo.h"
+
+#define DO_440HZ_TONE_TEST 0
+
+#if DO_440HZ_TONE_TEST
+typedef struct {
+  float currentPhase;
+  float phaseIncrement;
+} SineWaveGenerator;
+#endif
+
+class AERingBuffer;
+class CAAudioUnitSink;
+
+class CAESinkDARWINIOS : public IAESink
+{
+public:
+  virtual const char *GetName() { return "DARWINIOS"; }
+
+  CAESinkDARWINIOS();
+  virtual ~CAESinkDARWINIOS();
+
+  virtual bool Initialize(AEAudioFormat &format, std::string &device);
+  virtual void Deinitialize();
+  virtual bool IsCompatible(const AEAudioFormat &format, const std::string &device);
+
+  virtual double       GetDelay        ();
+  virtual double       GetCacheTotal   ();
+  virtual unsigned int AddPackets      (uint8_t *data, unsigned int frames, bool hasAudio, bool blocking = false);
+  virtual void         Drain           ();
+  virtual bool         HasVolume       ();
+  virtual void         SetVolume       (float scale);
+  static void          EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
+
+private:
+  static AEDeviceInfoList m_devices;
+  CAEDeviceInfo      m_info;
+  AEAudioFormat      m_format;
+  double             m_volume;
+  bool               m_volume_changed;
+
+  CAAudioUnitSink   *m_audioSink;
+#if DO_440HZ_TONE_TEST
+  SineWaveGenerator  m_SineWaveGenerator;
+#endif
+};
\ No newline at end of file
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp
new file mode 100644 (file)
index 0000000..ad914d8
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ *      Copyright (C) 2005-2014 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 "cores/AudioEngine/AEFactory.h"
+#include "cores/AudioEngine/Sinks/AESinkDARWINOSX.h"
+#include "cores/AudioEngine/Utils/AEUtil.h"
+#include "cores/AudioEngine/Utils/AERingBuffer.h"
+#include "cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h"
+#include "cores/AudioEngine/Sinks/osx/CoreAudioHardware.h"
+#include "osx/DarwinUtils.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+#include "threads/Condition.h"
+#include "threads/CriticalSection.h"
+
+#include <sstream>
+
+#define CA_MAX_CHANNELS 8
+static enum AEChannel CAChannelMap[CA_MAX_CHANNELS + 1] = {
+  AE_CH_FL , AE_CH_FR , AE_CH_BL , AE_CH_BR , AE_CH_FC , AE_CH_LFE , AE_CH_SL , AE_CH_SR ,
+  AE_CH_NULL
+};
+
+static bool HasSampleRate(const AESampleRateList &list, const unsigned int samplerate)
+{
+  for (size_t i = 0; i < list.size(); ++i)
+  {
+    if (list[i] == samplerate)
+      return true;
+  }
+  return false;
+}
+
+static bool HasDataFormat(const AEDataFormatList &list, const enum AEDataFormat format)
+{
+  for (size_t i = 0; i < list.size(); ++i)
+  {
+    if (list[i] == format)
+      return true;
+  }
+  return false;
+}
+
+typedef std::vector< std::pair<AudioDeviceID, CAEDeviceInfo> > CADeviceList;
+
+static void EnumerateDevices(CADeviceList &list)
+{
+  CAEDeviceInfo device;
+
+  std::string defaultDeviceName;
+  CCoreAudioHardware::GetOutputDeviceName(defaultDeviceName);
+
+  CoreAudioDeviceList deviceIDList;
+  CCoreAudioHardware::GetOutputDevices(&deviceIDList);
+  while (!deviceIDList.empty())
+  {
+    AudioDeviceID deviceID = deviceIDList.front();
+    CCoreAudioDevice caDevice(deviceID);
+
+    device.m_channels.Reset();
+    device.m_dataFormats.clear();
+    device.m_sampleRates.clear();
+
+    device.m_deviceType = AE_DEVTYPE_PCM;
+    device.m_deviceName = caDevice.GetName();
+    device.m_displayName = device.m_deviceName;
+    device.m_displayNameExtra = "";
+
+    if (device.m_deviceName.find("HDMI") != std::string::npos)
+      device.m_deviceType = AE_DEVTYPE_HDMI;
+
+    CLog::Log(LOGDEBUG, "EnumerateDevices:Device(%s)" , device.m_deviceName.c_str());
+    AudioStreamIdList streams;
+    if (caDevice.GetStreams(&streams))
+    {
+      for (AudioStreamIdList::iterator j = streams.begin(); j != streams.end(); ++j)
+      {
+        StreamFormatList streams;
+        if (CCoreAudioStream::GetAvailablePhysicalFormats(*j, &streams))
+        {
+          for (StreamFormatList::iterator i = streams.begin(); i != streams.end(); ++i)
+          {
+            AudioStreamBasicDescription desc = i->mFormat;
+            std::string formatString;
+            CLog::Log(LOGDEBUG, "EnumerateDevices:Format(%s)" ,
+                                StreamDescriptionToString(desc, formatString));
+            // add stream format info
+            switch (desc.mFormatID)
+            {
+              case kAudioFormatAC3:
+              case kAudioFormat60958AC3:
+                if (!HasDataFormat(device.m_dataFormats, AE_FMT_AC3))
+                  device.m_dataFormats.push_back(AE_FMT_AC3);
+                if (!HasDataFormat(device.m_dataFormats, AE_FMT_DTS))
+                  device.m_dataFormats.push_back(AE_FMT_DTS);
+                // if we are not hdmi, this is an S/PDIF device
+                if (device.m_deviceType != AE_DEVTYPE_HDMI)
+                  device.m_deviceType = AE_DEVTYPE_IEC958;
+                break;
+              default:
+                AEDataFormat format = AE_FMT_INVALID;
+                switch(desc.mBitsPerChannel)
+                {
+                  case 16:
+                    if (desc.mFormatFlags & kAudioFormatFlagIsBigEndian)
+                      format = AE_FMT_S16BE;
+                    else
+                    {
+                      /* Passthrough is possible with a 2ch digital output */
+                      if (desc.mChannelsPerFrame == 2 && CCoreAudioStream::IsDigitalOuptut(*j))
+                      {
+                        if (desc.mSampleRate == 48000)
+                        {
+                          if (!HasDataFormat(device.m_dataFormats, AE_FMT_AC3))
+                            device.m_dataFormats.push_back(AE_FMT_AC3);
+                          if (!HasDataFormat(device.m_dataFormats, AE_FMT_DTS))
+                            device.m_dataFormats.push_back(AE_FMT_DTS);
+                        }
+                        else if (desc.mSampleRate == 192000)
+                        {
+                          if (!HasDataFormat(device.m_dataFormats, AE_FMT_EAC3))
+                            device.m_dataFormats.push_back(AE_FMT_EAC3);
+                        }
+                      }
+                      format = AE_FMT_S16LE;
+                    }
+                    break;
+                  case 24:
+                    if (desc.mFormatFlags & kAudioFormatFlagIsBigEndian)
+                      format = AE_FMT_S24BE3;
+                    else
+                      format = AE_FMT_S24LE3;
+                    break;
+                  case 32:
+                    if (desc.mFormatFlags & kAudioFormatFlagIsFloat)
+                      format = AE_FMT_FLOAT;
+                    else
+                    {
+                      if (desc.mFormatFlags & kAudioFormatFlagIsBigEndian)
+                        format = AE_FMT_S32BE;
+                      else
+                        format = AE_FMT_S32LE;
+                    }
+                    break;
+                }
+                if (format != AE_FMT_INVALID && !HasDataFormat(device.m_dataFormats, format))
+                  device.m_dataFormats.push_back(format);
+                break;
+            }
+
+            // add channel info
+            CAEChannelInfo channel_info;
+            for (UInt32 chan = 0; chan < CA_MAX_CHANNELS && chan < desc.mChannelsPerFrame; ++chan)
+            {
+              if (!device.m_channels.HasChannel(CAChannelMap[chan]))
+                device.m_channels += CAChannelMap[chan];
+              channel_info += CAChannelMap[chan];
+            }
+
+            // add sample rate info
+            if (!HasSampleRate(device.m_sampleRates, desc.mSampleRate))
+              device.m_sampleRates.push_back(desc.mSampleRate);
+          }
+        }
+      }
+    }
+
+    list.push_back(std::make_pair(deviceID, device));
+    //in the first place of the list add the default device
+    //with name "default" - if this is selected
+    //we will output to whatever osx claims to be default
+    //(allows transition from headphones to speaker and stuff
+    //like that
+    if(defaultDeviceName == device.m_deviceName)
+    {
+      device.m_deviceName = "default";
+      device.m_displayName = "Default";
+      list.insert(list.begin(), std::make_pair(deviceID, device));
+    }
+
+    deviceIDList.pop_front();
+  }
+}
+
+/* static, threadsafe access to the device list */
+static CADeviceList     s_devices;
+static CCriticalSection s_devicesLock;
+
+static void EnumerateDevices()
+{
+  CADeviceList devices;
+  EnumerateDevices(devices);
+  {
+    CSingleLock lock(s_devicesLock);
+    s_devices = devices;
+  }
+}
+
+static CADeviceList GetDevices()
+{
+  CADeviceList list;
+  {
+    CSingleLock lock(s_devicesLock);
+    list = s_devices;
+  }
+  return list;
+}
+
+OSStatus deviceChangedCB(AudioObjectID                       inObjectID,
+                         UInt32                              inNumberAddresses,
+                         const AudioObjectPropertyAddress    inAddresses[],
+                         void*                               inClientData)
+{
+  CLog::Log(LOGDEBUG, "CoreAudio: audiodevicelist changed - reenumerating");
+  CAEFactory::DeviceChange();
+  CLog::Log(LOGDEBUG, "CoreAudio: audiodevicelist changed - done");
+  return noErr;
+}
+
+void RegisterDeviceChangedCB(bool bRegister, void *ref)
+{
+  OSStatus ret = noErr;
+  const AudioObjectPropertyAddress inAdr =
+  {
+    kAudioHardwarePropertyDevices,
+    kAudioObjectPropertyScopeGlobal,
+    kAudioObjectPropertyElementMaster
+  };
+
+  if (bRegister)
+    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
+  else
+    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
+
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioAE::Deinitialize - error %s a listener callback for device changes!", bRegister?"attaching":"removing");
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////
+CAESinkDARWINOSX::CAESinkDARWINOSX()
+: m_latentFrames(0), m_outputBitstream(false), m_outputBuffer(NULL), m_buffer(NULL)
+{
+  // By default, kAudioHardwarePropertyRunLoop points at the process's main thread on SnowLeopard,
+  // If your process lacks such a run loop, you can set kAudioHardwarePropertyRunLoop to NULL which
+  // tells the HAL to run it's own thread for notifications (which was the default prior to SnowLeopard).
+  // So tell the HAL to use its own thread for similar behavior under all supported versions of OSX.
+  CFRunLoopRef theRunLoop = NULL;
+  AudioObjectPropertyAddress theAddress = {
+    kAudioHardwarePropertyRunLoop,
+    kAudioObjectPropertyScopeGlobal,
+    kAudioObjectPropertyElementMaster
+  };
+  OSStatus theError = AudioObjectSetPropertyData(kAudioObjectSystemObject,
+                                                 &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
+  if (theError != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioAE::constructor: kAudioHardwarePropertyRunLoop error.");
+  }
+  RegisterDeviceChangedCB(true, this);
+  m_started = false;
+}
+
+CAESinkDARWINOSX::~CAESinkDARWINOSX()
+{
+  RegisterDeviceChangedCB(false, this);
+}
+
+float ScoreStream(const AudioStreamBasicDescription &desc, const AEAudioFormat &format)
+{
+  float score = 0;
+  if (format.m_dataFormat == AE_FMT_AC3 ||
+      format.m_dataFormat == AE_FMT_DTS)
+  {
+    if (desc.mFormatID == kAudioFormat60958AC3 ||
+        desc.mFormatID == 'IAC3' ||
+        desc.mFormatID == kAudioFormatAC3)
+    {
+      if (desc.mSampleRate == format.m_sampleRate &&
+          desc.mBitsPerChannel == CAEUtil::DataFormatToBits(format.m_dataFormat) &&
+          desc.mChannelsPerFrame == format.m_channelLayout.Count())
+      {
+        // perfect match
+        score = FLT_MAX;
+      }
+    }
+  }
+  if (format.m_dataFormat == AE_FMT_AC3 ||
+      format.m_dataFormat == AE_FMT_DTS ||
+      format.m_dataFormat == AE_FMT_EAC3)
+  { // we should be able to bistreaming in PCM if the samplerate, bitdepth and channels match
+    if (desc.mSampleRate       == format.m_sampleRate                            &&
+        desc.mBitsPerChannel   == CAEUtil::DataFormatToBits(format.m_dataFormat) &&
+        desc.mChannelsPerFrame == format.m_channelLayout.Count()                 &&
+        desc.mFormatID         == kAudioFormatLinearPCM)
+    {
+      score = FLT_MAX / 2;
+    }
+  }
+  else
+  { // non-passthrough, whatever works is fine
+    if (desc.mFormatID == kAudioFormatLinearPCM)
+    {
+      if (desc.mSampleRate == format.m_sampleRate)
+        score += 10;
+      else if (desc.mSampleRate > format.m_sampleRate)
+        score += 1;
+      if (desc.mChannelsPerFrame == format.m_channelLayout.Count())
+        score += 5;
+      else if (desc.mChannelsPerFrame > format.m_channelLayout.Count())
+        score += 1;
+      if (format.m_dataFormat == AE_FMT_FLOAT)
+      { // for float, prefer the highest bitdepth we have
+        if (desc.mBitsPerChannel >= 16)
+          score += (desc.mBitsPerChannel / 8);
+      }
+      else
+      {
+        if (desc.mBitsPerChannel == CAEUtil::DataFormatToBits(format.m_dataFormat))
+          score += 5;
+        else if (desc.mBitsPerChannel == CAEUtil::DataFormatToBits(format.m_dataFormat))
+          score += 1;
+      }
+    }
+  }
+  return score;
+}
+
+bool CAESinkDARWINOSX::Initialize(AEAudioFormat &format, std::string &device)
+{
+  AudioDeviceID deviceID = 0;
+  CADeviceList devices = GetDevices();
+  if (StringUtils::EqualsNoCase(device, "default"))
+  {
+    CCoreAudioHardware::GetOutputDeviceName(device);
+    CLog::Log(LOGNOTICE, "%s: Opening default device %s", __PRETTY_FUNCTION__, device.c_str());
+  }
+      
+  for (size_t i = 0; i < devices.size(); i++)
+  {
+    if (device.find(devices[i].second.m_deviceName) != std::string::npos)
+    {
+      m_info = devices[i].second;
+      deviceID = devices[i].first;
+      break;
+    }
+  }
+  if (!deviceID)
+  {
+    CLog::Log(LOGERROR, "%s: Unable to find device %s", __FUNCTION__, device.c_str());
+    return false;
+  }
+
+  m_device.Open(deviceID);
+
+  // Fetch a list of the streams defined by the output device
+  AudioStreamIdList streams;
+  m_device.GetStreams(&streams);
+
+  CLog::Log(LOGDEBUG, "%s: Finding stream for format %s", __FUNCTION__, CAEUtil::DataFormatToStr(format.m_dataFormat));
+
+  bool                        passthrough  = false;
+  UInt32                      outputIndex  = 0;
+  float                       outputScore  = 0;
+  AudioStreamBasicDescription outputFormat = {0};
+  AudioStreamID               outputStream = 0;
+
+  /* The theory is to score based on
+   1. Matching passthrough characteristics (i.e. passthrough flag)
+   2. Matching sample rate.
+   3. Matching bits per channel (or higher).
+   4. Matching number of channels (or higher).
+   */
+  UInt32 index = 0;
+  for (AudioStreamIdList::const_iterator i = streams.begin(); i != streams.end(); ++i)
+  {
+    // Probe physical formats
+    StreamFormatList formats;
+    CCoreAudioStream::GetAvailablePhysicalFormats(*i, &formats);
+    for (StreamFormatList::const_iterator j = formats.begin(); j != formats.end(); ++j)
+    {
+      const AudioStreamBasicDescription &desc = j->mFormat;
+
+      float score = ScoreStream(desc, format);
+
+      std::string formatString;
+      CLog::Log(LOGDEBUG, "%s: Physical Format: %s rated %f", __FUNCTION__, StreamDescriptionToString(desc, formatString), score);
+
+      if (score > outputScore)
+      {
+        passthrough  = score > 1000;
+        outputScore  = score;
+        outputFormat = desc;
+        outputStream = *i;
+        outputIndex  = index;
+      }
+    }
+    index++;
+  }
+
+  if (!outputFormat.mFormatID)
+  {
+    CLog::Log(LOGERROR, "%s, Unable to find suitable stream", __FUNCTION__);
+    return false;
+  }
+
+  /* Update our AE format */
+  format.m_sampleRate    = outputFormat.mSampleRate;
+  if (outputFormat.mChannelsPerFrame != format.m_channelLayout.Count())
+  { /* update the channel count.  We assume that they're layed out as given in CAChannelMap.
+       if they're not, this is plain wrong */
+    format.m_channelLayout.Reset();
+    for (unsigned int i = 0; i < outputFormat.mChannelsPerFrame; i++)
+      format.m_channelLayout += CAChannelMap[i];
+  }
+
+  m_outputBitstream   = passthrough && outputFormat.mFormatID == kAudioFormatLinearPCM;
+
+  std::string formatString;
+  CLog::Log(LOGDEBUG, "%s: Selected stream[%u] - id: 0x%04X, Physical Format: %s %s", __FUNCTION__, outputIndex, outputStream, StreamDescriptionToString(outputFormat, formatString), m_outputBitstream ? "bitstreamed passthrough" : "");
+
+  SetHogMode(passthrough);
+
+  // Configure the output stream object
+  m_outputStream.Open(outputStream);
+
+  AudioStreamBasicDescription virtualFormat, previousPhysicalFormat;
+  m_outputStream.GetVirtualFormat(&virtualFormat);
+  m_outputStream.GetPhysicalFormat(&previousPhysicalFormat);
+  CLog::Log(LOGDEBUG, "%s: Previous Virtual Format: %s", __FUNCTION__, StreamDescriptionToString(virtualFormat, formatString));
+  CLog::Log(LOGDEBUG, "%s: Previous Physical Format: %s", __FUNCTION__, StreamDescriptionToString(previousPhysicalFormat, formatString));
+
+  m_outputStream.SetPhysicalFormat(&outputFormat); // Set the active format (the old one will be reverted when we close)
+  m_outputStream.GetVirtualFormat(&virtualFormat);
+  CLog::Log(LOGDEBUG, "%s: New Virtual Format: %s", __FUNCTION__, StreamDescriptionToString(virtualFormat, formatString));
+  CLog::Log(LOGDEBUG, "%s: New Physical Format: %s", __FUNCTION__, StreamDescriptionToString(outputFormat, formatString));
+
+  m_latentFrames = m_device.GetNumLatencyFrames();
+  m_latentFrames += m_outputStream.GetNumLatencyFrames();
+
+  /* TODO: Should we use the virtual format to determine our data format? */
+  format.m_frameSize     = format.m_channelLayout.Count() * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
+  format.m_frames        = m_device.GetBufferSize();
+  format.m_frameSamples  = format.m_frames * format.m_channelLayout.Count();
+
+  if (m_outputBitstream)
+  {
+    m_outputBuffer = new int16_t[format.m_frameSamples];
+    /* TODO: Do we need this? */
+    m_device.SetNominalSampleRate(format.m_sampleRate);
+  }
+
+  unsigned int num_buffers = 4;
+  m_buffer = new AERingBuffer(num_buffers * format.m_frames * format.m_frameSize);
+  CLog::Log(LOGDEBUG, "%s: using buffer size: %u (%f ms)", __FUNCTION__, m_buffer->GetMaxSize(), (float)m_buffer->GetMaxSize() / (format.m_sampleRate * format.m_frameSize));
+
+  m_format = format;
+  if (passthrough)
+    format.m_dataFormat = AE_FMT_S16NE;
+  else
+    format.m_dataFormat = AE_FMT_FLOAT;
+
+  // Register for data request callbacks from the driver and start
+  m_device.AddIOProc(renderCallback, this);
+  m_device.Start();
+  return true;
+}
+
+void CAESinkDARWINOSX::SetHogMode(bool on)
+{
+  // TODO: Auto hogging sets this for us. Figure out how/when to turn it off or use it
+  // It appears that leaving this set will aslo restore the previous stream format when the
+  // Application exits. If auto hogging is set and we try to set hog mode, we will deadlock
+  // From the SDK docs: "If the AudioDevice is in a non-mixable mode, the HAL will automatically take hog mode on behalf of the first process to start an IOProc."
+
+  // Lock down the device.  This MUST be done PRIOR to switching to a non-mixable format, if it is done at all
+  // If it is attempted after the format change, there is a high likelihood of a deadlock
+  // We may need to do this sooner to enable mix-disable (i.e. before setting the stream format)
+  if (on)
+  {
+    // Auto-Hog does not always un-hog the device when changing back to a mixable mode.
+    // Handle this on our own until it is fixed.
+    CCoreAudioHardware::SetAutoHogMode(false);
+    bool autoHog = CCoreAudioHardware::GetAutoHogMode();
+    CLog::Log(LOGDEBUG, " CoreAudioRenderer::InitializeEncoded: "
+              "Auto 'hog' mode is set to '%s'.", autoHog ? "On" : "Off");
+    if (autoHog)
+      return;
+  }
+  m_device.SetHogStatus(on);
+  m_device.SetMixingSupport(!on);
+}
+
+void CAESinkDARWINOSX::Deinitialize()
+{
+  m_device.Stop();
+  m_device.RemoveIOProc();
+
+  m_outputStream.Close();
+  m_device.Close();
+  if (m_buffer)
+  {
+    delete m_buffer;
+    m_buffer = NULL;
+  }
+  m_outputBitstream = false;
+
+  delete[] m_outputBuffer;
+  m_outputBuffer = NULL;
+
+  m_started = false;
+}
+
+bool CAESinkDARWINOSX::IsCompatible(const AEAudioFormat &format, const std::string &device)
+{
+  return ((m_format.m_sampleRate    == format.m_sampleRate) &&
+          (m_format.m_dataFormat    == format.m_dataFormat) &&
+          (m_format.m_channelLayout == format.m_channelLayout));
+}
+
+double CAESinkDARWINOSX::GetDelay()
+{
+  if (m_buffer)
+  {
+    // Calculate the duration of the data in the cache
+    double delay = (double)m_buffer->GetReadSize() / (double)m_format.m_frameSize;
+    delay += (double)m_latentFrames;
+    delay /= (double)m_format.m_sampleRate;
+    return delay;
+  }
+  return 0.0;
+}
+
+double CAESinkDARWINOSX::GetCacheTotal()
+{
+  return (double)m_buffer->GetMaxSize() / (double)(m_format.m_frameSize * m_format.m_sampleRate);
+}
+
+CCriticalSection mutex;
+XbmcThreads::ConditionVariable condVar;
+
+unsigned int CAESinkDARWINOSX::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
+{
+  if (m_buffer->GetWriteSize() < frames * m_format.m_frameSize)
+  { // no space to write - wait for a bit
+    CSingleLock lock(mutex);
+    if (!m_started)
+      condVar.wait(lock);
+    else
+      condVar.wait(lock, 900 * frames / m_format.m_sampleRate);
+  }
+
+  unsigned int write_frames = std::min(frames, m_buffer->GetWriteSize() / m_format.m_frameSize);
+  if (write_frames)
+    m_buffer->Write(data, write_frames * m_format.m_frameSize);
+
+  return write_frames;
+}
+
+void CAESinkDARWINOSX::Drain()
+{
+  CCriticalSection mutex;
+  int bytes = m_buffer->GetReadSize();
+  while (bytes)
+  {
+    CSingleLock lock(mutex);
+    condVar.wait(mutex, 900 * bytes / (m_format.m_sampleRate * m_format.m_frameSize));
+    bytes = m_buffer->GetReadSize();
+  }
+}
+
+void CAESinkDARWINOSX::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
+{
+  EnumerateDevices();
+  list.clear();
+  for (CADeviceList::const_iterator i = s_devices.begin(); i != s_devices.end(); ++i)
+    list.push_back(i->second);
+}
+
+OSStatus CAESinkDARWINOSX::renderCallback(AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData)
+{
+  CAESinkDARWINOSX *sink = (CAESinkDARWINOSX*)inClientData;
+
+  sink->m_started = true;
+  for (unsigned int i = 0; i < outOutputData->mNumberBuffers; i++)
+  {
+    if (sink->m_outputBitstream)
+    {
+      /* HACK for bitstreaming AC3/DTS via PCM.
+       We reverse the float->S16LE conversion done in the stream or device */
+      static const float mul = 1.0f / (INT16_MAX + 1);
+
+      unsigned int wanted = std::min(outOutputData->mBuffers[i].mDataByteSize / sizeof(float), (size_t)sink->m_format.m_frameSamples)  * sizeof(int16_t);
+      if (wanted <= sink->m_buffer->GetReadSize())
+      {
+        sink->m_buffer->Read((unsigned char *)sink->m_outputBuffer, wanted);
+        int16_t *src = sink->m_outputBuffer;
+        float  *dest = (float*)outOutputData->mBuffers[i].mData;
+        for (unsigned int i = 0; i < wanted / 2; i++)
+          *dest++ = *src++ * mul;
+      }
+    }
+    else
+    {
+      /* buffers appear to come from CA already zero'd, so just copy what is wanted */
+      unsigned int wanted = outOutputData->mBuffers[i].mDataByteSize;
+      unsigned int bytes = std::min(sink->m_buffer->GetReadSize(), wanted);
+      sink->m_buffer->Read((unsigned char*)outOutputData->mBuffers[i].mData, bytes);
+      if (bytes != wanted)
+        CLog::Log(LOGERROR, "%s: %sFLOW (%i vs %i) bytes", __FUNCTION__, bytes > wanted ? "OVER" : "UNDER", bytes, wanted);
+    }
+
+    // tell the sink we're good for more data
+    condVar.notifyAll();
+  }
+  return noErr;
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.h b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.h
new file mode 100644 (file)
index 0000000..5872c17
--- /dev/null
@@ -0,0 +1,65 @@
+#pragma once
+/*
+ *      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/>.
+ *
+ */
+
+#include "cores/AudioEngine/Interfaces/AESink.h"
+#include "cores/AudioEngine/Utils/AEDeviceInfo.h"
+#include "cores/AudioEngine/Sinks/osx/CoreAudioDevice.h"
+#include "cores/AudioEngine/Sinks/osx/CoreAudioStream.h"
+
+class AERingBuffer;
+
+class CAESinkDARWINOSX : public IAESink
+{
+public:
+  virtual const char *GetName() { return "DARWINOSX"; }
+
+  CAESinkDARWINOSX();
+  virtual ~CAESinkDARWINOSX();
+
+  virtual bool Initialize(AEAudioFormat &format, std::string &device);
+  virtual void Deinitialize();
+  virtual bool IsCompatible(const AEAudioFormat &format, const std::string &device);
+
+  virtual double       GetDelay        ();
+  virtual double       GetCacheTotal   ();
+  virtual unsigned int AddPackets      (uint8_t *data, unsigned int frames, bool hasAudio, bool blocking = false);
+  virtual void         Drain           ();
+  static void          EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
+
+private:
+  static OSStatus renderCallback(AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData);
+  void SetHogMode(bool on);
+
+  CAEDeviceInfo      m_info;
+  AEAudioFormat      m_format;
+
+  volatile bool      m_draining;
+
+  CCoreAudioDevice   m_device;
+  CCoreAudioStream   m_outputStream;
+  unsigned int       m_latentFrames;
+
+  bool               m_outputBitstream;   ///< true if we're bistreaming into a LinearPCM stream rather than AC3 stream.
+  int16_t           *m_outputBuffer;      ///< buffer for bitstreaming
+
+  AERingBuffer      *m_buffer;
+  volatile bool      m_started;     // set once we get a callback from CoreAudio, which can take a little while.
+};
index 9ebb61e..2b57961 100644 (file)
@@ -21,9 +21,8 @@
 #define INITGUID
 
 #include "AESinkDirectSound.h"
-#include "utils/Log.h"
+#include "utils/log.h"
 #include <initguid.h>
-#include <Mmreg.h>
 #include <list>
 #include "threads/SingleLock.h"
 #include "threads/SystemClock.h"
@@ -233,10 +232,10 @@ bool CAESinkDirectSound::Initialize(AEAudioFormat &format, std::string &device)
 
   m_AvgBytesPerSec = wfxex.Format.nAvgBytesPerSec;
 
-  unsigned int uiFrameCount = (int)(format.m_sampleRate * 0.01); //default to 10ms chunks
+  unsigned int uiFrameCount = (int)(format.m_sampleRate * 0.015); //default to 15ms chunks
   m_dwFrameSize = wfxex.Format.nBlockAlign;
   m_dwChunkSize = m_dwFrameSize * uiFrameCount;
-  m_dwBufferLen = m_dwChunkSize * 12; //120ms total buffer
+  m_dwBufferLen = m_dwChunkSize * 12; //180ms total buffer
 
   // fill in the secondary sound buffer descriptor
   DSBUFFERDESC dsbdesc;
@@ -550,6 +549,8 @@ void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bo
       deviceInfo.m_channels = layoutsByChCount[std::max(std::min(smpwfxex->nChannels, (WORD) DS_SPEAKER_COUNT), (WORD) 2)];
       deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_FLOAT));
       deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3));
+      // DTS is played with the same infrastructure as AC3
+      deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_DTS));
       deviceInfo.m_sampleRates.push_back(std::min(smpwfxex->nSamplesPerSec, (DWORD) 192000));
     }
     else
@@ -563,7 +564,7 @@ void CAESinkDirectSound::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bo
 
     deviceInfo.m_deviceName       = strDevName;
     deviceInfo.m_displayName      = strWinDevType.append(strFriendlyName);
-    deviceInfo.m_displayNameExtra = std::string("DirectSound: ").append(strFriendlyName);
+    deviceInfo.m_displayNameExtra = std::string("DIRECTSOUND: ").append(strFriendlyName);
     deviceInfo.m_deviceType       = aeDeviceType;
 
     deviceInfoList.push_back(deviceInfo);
index 417a151..2564e54 100644 (file)
@@ -29,7 +29,7 @@
 class CAESinkDirectSound : public IAESink
 {
 public:
-  virtual const char *GetName() { return "DirectSound"; }
+  virtual const char *GetName() { return "DIRECTSOUND"; }
 
   CAESinkDirectSound();
   virtual ~CAESinkDirectSound();
index d227b2d..127fc62 100644 (file)
@@ -189,6 +189,34 @@ static void StreamLatencyUpdateCallback(pa_stream *s, void *userdata)
   pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
   pa_threaded_mainloop_signal(m, 0);
 }
+
+static void SinkChangedCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
+{
+  CAESinkPULSE* p = (CAESinkPULSE*) userdata;
+  if(!p)
+    return;
+
+  CSingleLock lock(p->m_sec);
+  if (p->IsInitialized())
+  {
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
+    {
+       CLog::Log(LOGDEBUG, "Sink appeared");
+       CAEFactory::DeviceChange();
+    }
+    else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
+    {
+      CLog::Log(LOGDEBUG, "Sink removed");
+      CAEFactory::DeviceChange();
+    }
+    else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE)
+    {
+      CLog::Log(LOGDEBUG, "Sink changed");
+      //CAEFactory::DeviceChange();
+    }    
+  }
+}
+
 struct SinkInfoStruct
 {
   AEDeviceInfoList *list;
@@ -390,6 +418,7 @@ static void SinkInfoRequestCallback(pa_context *c, const pa_sink_info *i, int eo
 CAESinkPULSE::CAESinkPULSE()
 {
   m_IsAllocated = false;
+  m_passthrough = false;
   m_MainLoop = NULL;
   m_BytesPerSecond = 0;
   m_BufferSize = 0;
@@ -405,7 +434,11 @@ CAESinkPULSE::~CAESinkPULSE()
 
 bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
 {
-  m_IsAllocated = false;
+  {
+    CSingleLock lock(m_sec);
+    m_IsAllocated = false;
+  }
+  m_passthrough = false;
   m_BytesPerSecond = 0;
   m_BufferSize = 0;
   m_Channels = 0;
@@ -421,12 +454,22 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
 
   pa_threaded_mainloop_lock(m_MainLoop);
 
+  {
+    // Register Callback for Sink changes
+    CSingleLock lock(m_sec);
+    pa_context_set_subscribe_callback(m_Context, SinkChangedCallback, this);
+    const pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SINK;
+    pa_operation *op = pa_context_subscribe(m_Context, mask, NULL, this);
+    if (op != NULL)
+      pa_operation_unref(op);
+  }
+
   struct pa_channel_map map;
   pa_channel_map_init(&map);
 
-  bool passthrough = AE_IS_RAW(format.m_dataFormat);
+  m_passthrough = AE_IS_RAW(format.m_dataFormat);
 
-  if(passthrough)
+  if(m_passthrough)
   {
     map.channels = 2;
     format.m_channelLayout = AE_CH_LAYOUT_2_0;
@@ -445,7 +488,7 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
   pa_format_info *info[1];
   info[0] = pa_format_info_new();
   info[0]->encoding = AEFormatToPulseEncoding(format.m_dataFormat);
-  if(!passthrough)
+  if(!m_passthrough)
   {
     pa_format_info_set_sample_format(info[0], AEFormatToPulseFormat(format.m_dataFormat));
     pa_format_info_set_channel_map(info[0], &map);
@@ -454,7 +497,7 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
 
   // PA requires m_encodedRate in order to do EAC3
   unsigned int samplerate;
-  if (passthrough)
+  if (m_passthrough)
   {
     if (format.m_encodedRate == 0)
     {
@@ -551,7 +594,7 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
     buffer_attr.fragsize = (uint32_t) latency;
   }
 
-  if (pa_stream_connect_playback(m_Stream, isDefaultDevice ? NULL : device.c_str(), sinkStruct.isHWDevice ? &buffer_attr : NULL, ((pa_stream_flags)(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY)), &m_Volume, NULL) < 0)
+  if (pa_stream_connect_playback(m_Stream, isDefaultDevice ? NULL : device.c_str(), sinkStruct.isHWDevice ? &buffer_attr : NULL, ((pa_stream_flags)(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY)), m_passthrough ? NULL : &m_Volume, NULL) < 0)
   {
     CLog::Log(LOGERROR, "PulseAudio: Failed to connect stream to output");
     pa_threaded_mainloop_unlock(m_MainLoop);
@@ -593,21 +636,26 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
   }
 
   pa_threaded_mainloop_unlock(m_MainLoop);
-
-  m_IsAllocated = true;
+  
   format.m_frameSize = frameSize;
   format.m_frameSamples = format.m_frames * format.m_channelLayout.Count();
   m_format = format;
-  format.m_dataFormat = passthrough ? AE_FMT_S16NE : format.m_dataFormat;
+  format.m_dataFormat = m_passthrough ? AE_FMT_S16NE : format.m_dataFormat;
 
   Pause(false);
+  {
+    CSingleLock lock(m_sec);
+    m_IsAllocated = true;
+  }
 
   return true;
 }
 
 void CAESinkPULSE::Deinitialize()
 {
+  CSingleLock lock(m_sec);
   m_IsAllocated = false;
+  m_passthrough = false;
 
   if (m_Stream)
     Drain();
@@ -706,7 +754,7 @@ void CAESinkPULSE::Drain()
 
 void CAESinkPULSE::SetVolume(float volume)
 {
-  if (m_IsAllocated)
+  if (m_IsAllocated && !m_passthrough)
   {
     pa_threaded_mainloop_lock(m_MainLoop);
     pa_volume_t pavolume = pa_sw_volume_from_linear(volume);
@@ -761,6 +809,12 @@ void CAESinkPULSE::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
   }
 }
 
+bool CAESinkPULSE::IsInitialized()
+{
+ CSingleLock lock(m_sec);
+ return m_IsAllocated; 
+}
+
 bool CAESinkPULSE::Pause(bool pause)
 {
   pa_threaded_mainloop_lock(m_MainLoop);
index 2992d81..39fda73 100644 (file)
 #include "system.h"
 
 #include "cores/AudioEngine/Interfaces/AESink.h"
+#include "cores/AudioEngine/AEFactory.h"
 #include "Utils/AEDeviceInfo.h"
 #include "Utils/AEUtil.h"
 #include <pulse/pulseaudio.h>
+#include "threads/CriticalSection.h"
 
 class CAESinkPULSE : public IAESink
 {
@@ -46,12 +48,15 @@ public:
   virtual void SetVolume(float volume);
 
   static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
+  bool IsInitialized();
+  CCriticalSection m_sec;
 private:
   bool Pause(bool pause);
   static inline bool WaitForOperation(pa_operation *op, pa_threaded_mainloop *mainloop, const char *LogEntry);
   static bool SetupContext(const char *host, pa_context **context, pa_threaded_mainloop **mainloop);
 
   bool m_IsAllocated;
+  bool m_passthrough;
 
   AEAudioFormat m_format;
   unsigned int m_BytesPerSecond;
index 54c8ac8..d52c6f1 100644 (file)
@@ -284,6 +284,9 @@ void CAESinkPi::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
   m_info.m_channels += AE_CH_FR;
   m_info.m_sampleRates.push_back(48000);
   m_info.m_dataFormats.push_back(AE_FMT_S16LE);
+  m_info.m_dataFormats.push_back(AE_FMT_AC3);
+  m_info.m_dataFormats.push_back(AE_FMT_DTS);
+  m_info.m_dataFormats.push_back(AE_FMT_EAC3);
 
   list.push_back(m_info);
 
index cc3804a..ea477b6 100644 (file)
@@ -22,7 +22,6 @@
 #include <Audioclient.h>
 #include <avrt.h>
 #include <initguid.h>
-#include <Mmreg.h>
 #include <stdint.h>
 
 #include "cores/AudioEngine/Utils/AEUtil.h"
@@ -34,7 +33,6 @@
 #include "utils/CharsetConverter.h"
 #include "cores/AudioEngine/Utils/AEDeviceInfo.h"
 #include <Mmreg.h>
-#include <mmdeviceapi.h>
 #include "utils/StringUtils.h"
 
 #pragma comment(lib, "Avrt.lib")
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.cpp
new file mode 100644 (file)
index 0000000..8abecfa
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ *      Copyright (C) 2011-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 "CoreAudioChannelLayout.h"
+
+#include <AudioToolbox/AudioToolbox.h>
+
+#define MAX_CHANNEL_LABEL 15
+
+const char* g_ChannelLabels[] =
+{
+  "Unused",           // kAudioChannelLabel_Unused
+  "Left",             // kAudioChannelLabel_Left
+  "Right",            // kAudioChannelLabel_Right
+  "Center",           // kAudioChannelLabel_Center
+  "LFE",              // kAudioChannelLabel_LFEScreen
+  "Side Left",        // kAudioChannelLabel_LeftSurround
+  "Side Right",       // kAudioChannelLabel_RightSurround
+  "Left Center",      // kAudioChannelLabel_LeftCenter
+  "Right Center",     // kAudioChannelLabel_RightCenter
+  "Back Center",      // kAudioChannelLabel_CenterSurround
+  "Back Left",        // kAudioChannelLabel_LeftSurroundDirect
+  "Back Right",       // kAudioChannelLabel_RightSurroundDirect
+  "Top Center",       // kAudioChannelLabel_TopCenterSurround
+  "Top Back Left",    // kAudioChannelLabel_VerticalHeightLeft
+  "Top Back Center",  // kAudioChannelLabel_VerticalHeightCenter
+  "Top Back Right",   // kAudioChannelLabel_VerticalHeightRight
+};
+
+CCoreAudioChannelLayout::CCoreAudioChannelLayout() :
+  m_pLayout(NULL)
+{
+}
+
+CCoreAudioChannelLayout::CCoreAudioChannelLayout(AudioChannelLayout& layout) :
+m_pLayout(NULL)
+{
+  CopyLayout(layout);
+}
+
+CCoreAudioChannelLayout::~CCoreAudioChannelLayout()
+{
+  free(m_pLayout);
+}
+
+bool CCoreAudioChannelLayout::CopyLayout(AudioChannelLayout& layout)
+{
+  enum {
+    kVariableLengthArray_deprecated = 1
+  };
+
+    free(m_pLayout);
+  m_pLayout = NULL;
+
+  // This method always produces a layout with a ChannelDescriptions structure
+
+  OSStatus ret = 0;
+  UInt32 channels = GetChannelCountForLayout(layout);
+  UInt32 size = sizeof(AudioChannelLayout) + (channels - kVariableLengthArray_deprecated) * sizeof(AudioChannelDescription);
+
+  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+  {
+    // We can copy the whole layout
+    m_pLayout = (AudioChannelLayout*)malloc(size);
+    memcpy(m_pLayout, &layout, size);
+  }
+  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+  {
+    // Deconstruct the bitmap to get the layout
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize);
+    m_pLayout = (AudioChannelLayout*)malloc(propSize);
+    ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, m_pLayout);
+    m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+  }
+  else
+  {
+    // Convert the known layout to a custom layout
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize);
+    m_pLayout = (AudioChannelLayout*)malloc(propSize);
+    ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, m_pLayout);
+    m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+  }
+
+  return (ret == noErr);
+}
+
+UInt32 CCoreAudioChannelLayout::GetChannelCountForLayout(AudioChannelLayout& layout)
+{
+  UInt32 channels = 0;
+  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+  {
+    // Channels are in fixed-order('USB Order'), any combination
+    UInt32 bitmap = layout.mChannelBitmap;
+    for (UInt32 c = 0; c < (sizeof(layout.mChannelBitmap) << 3); c++)
+    {
+      if (bitmap & 0x1)
+        channels++;
+      bitmap >>= 1;
+    }
+  }
+  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+  {
+    // Channels are in any order, any combination
+    channels = layout.mNumberChannelDescriptions;
+  }
+  else
+  {
+    // Channels are in a predefined order and combination
+    channels = AudioChannelLayoutTag_GetNumberOfChannels(layout.mChannelLayoutTag);
+  }
+
+  return channels;
+}
+
+const char* CCoreAudioChannelLayout::ChannelLabelToString(UInt32 label)
+{
+  if (label > MAX_CHANNEL_LABEL)
+    return "Unknown";
+  return g_ChannelLabels[label];
+}
+
+const char* CCoreAudioChannelLayout::ChannelLayoutToString(AudioChannelLayout& layout, std::string& str)
+{
+  AudioChannelLayout* pLayout = NULL;
+
+  if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+  {
+    pLayout = &layout;
+  }
+  else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+  {
+    // Deconstruct the bitmap to get the layout
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap,
+      sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize);
+    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
+    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
+      sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, pLayout);
+  }
+  else
+  {
+    // Predefinied layout 'tag'
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize);
+    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
+    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, pLayout);
+  }
+
+  for (UInt32 c = 0; c < pLayout->mNumberChannelDescriptions; c++)
+  {
+    str += "[";
+    str += ChannelLabelToString(pLayout->mChannelDescriptions[c].mChannelLabel);
+    str += "] ";
+  }
+
+  if (layout.mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
+    free(pLayout);
+
+  return str.c_str();
+}
+
+bool CCoreAudioChannelLayout::AllChannelUnknown()
+{
+  AudioChannelLayout* pLayout = NULL;
+
+  if (!m_pLayout)
+    return false;
+
+  if (m_pLayout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+  {
+    pLayout = m_pLayout;
+  }
+  else if (m_pLayout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+  {
+    // Deconstruct the bitmap to get the layout
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap,
+      sizeof(m_pLayout->mChannelBitmap), &m_pLayout->mChannelBitmap, &propSize);
+    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
+    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
+      sizeof(m_pLayout->mChannelBitmap), &m_pLayout->mChannelBitmap, &propSize, pLayout);
+  }
+  else
+  {
+    // Predefinied layout 'tag'
+    UInt32 propSize = 0;
+    AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(m_pLayout->mChannelLayoutTag), &m_pLayout->mChannelLayoutTag, &propSize);
+    pLayout = (AudioChannelLayout*)calloc(propSize, 1);
+    AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
+      sizeof(m_pLayout->mChannelLayoutTag), &m_pLayout->mChannelLayoutTag, &propSize, pLayout);
+  }
+
+  for (UInt32 c = 0; c < pLayout->mNumberChannelDescriptions; c++)
+  {
+    if (pLayout->mChannelDescriptions[c].mChannelLabel != kAudioChannelLabel_Unknown)
+    {
+      return false;
+    }
+  }
+
+  if (m_pLayout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
+    free(pLayout);
+
+  return true;
+}
+
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioChannelLayout.h
new file mode 100644 (file)
index 0000000..cf95c83
--- /dev/null
@@ -0,0 +1,90 @@
+#pragma once
+/*
+ *      Copyright (C) 2011-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 "system.h"
+
+#if defined(TARGET_DARWIN_OSX)
+#include <list>
+#include <vector>
+#include <string>
+
+#include <CoreAudio/CoreAudio.h>
+
+typedef std::vector<SInt32> CoreAudioChannelList;
+typedef std::list<AudioChannelLayoutTag> AudioChannelLayoutList;
+
+const AudioChannelLayoutTag g_LayoutMap[] =
+{
+  kAudioChannelLayoutTag_Stereo,            // PCM_LAYOUT_2_0 = 0,
+  kAudioChannelLayoutTag_Stereo,            // PCM_LAYOUT_2_0 = 0,
+  kAudioChannelLayoutTag_DVD_4,             // PCM_LAYOUT_2_1,
+  kAudioChannelLayoutTag_MPEG_3_0_A,        // PCM_LAYOUT_3_0,
+  kAudioChannelLayoutTag_DVD_10,            // PCM_LAYOUT_3_1,
+  kAudioChannelLayoutTag_DVD_3,             // PCM_LAYOUT_4_0,
+  kAudioChannelLayoutTag_DVD_6,             // PCM_LAYOUT_4_1,
+  kAudioChannelLayoutTag_MPEG_5_0_A,        // PCM_LAYOUT_5_0,
+  kAudioChannelLayoutTag_MPEG_5_1_A,        // PCM_LAYOUT_5_1,
+  kAudioChannelLayoutTag_AudioUnit_7_0,     // PCM_LAYOUT_7_0, ** This layout may be incorrect...no content to testß˚ **
+  kAudioChannelLayoutTag_MPEG_7_1_A,        // PCM_LAYOUT_7_1
+};
+
+const AudioChannelLabel g_LabelMap[] =
+{
+  kAudioChannelLabel_Unused,                // PCM_FRONT_LEFT,
+  kAudioChannelLabel_Left,                  // PCM_FRONT_LEFT,
+  kAudioChannelLabel_Right,                 // PCM_FRONT_RIGHT,
+  kAudioChannelLabel_Center,                // PCM_FRONT_CENTER,
+  kAudioChannelLabel_LFEScreen,             // PCM_LOW_FREQUENCY,
+  kAudioChannelLabel_LeftSurroundDirect,    // PCM_BACK_LEFT, *** This is incorrect, but has been changed to match dvdplayer
+  kAudioChannelLabel_RightSurroundDirect,   // PCM_BACK_RIGHT, *** This is incorrect, but has been changed to match dvdplayer
+  kAudioChannelLabel_LeftCenter,            // PCM_FRONT_LEFT_OF_CENTER,
+  kAudioChannelLabel_RightCenter,           // PCM_FRONT_RIGHT_OF_CENTER,
+  kAudioChannelLabel_CenterSurround,        // PCM_BACK_CENTER,
+  kAudioChannelLabel_LeftSurround,          // PCM_SIDE_LEFT, *** This is incorrect, but has been changed to match dvdplayer
+  kAudioChannelLabel_RightSurround,         // PCM_SIDE_RIGHT, *** This is incorrect, but has been changed to match dvdplayer
+  kAudioChannelLabel_VerticalHeightLeft,    // PCM_TOP_FRONT_LEFT,
+  kAudioChannelLabel_VerticalHeightRight,   // PCM_TOP_FRONT_RIGHT,
+  kAudioChannelLabel_VerticalHeightCenter,  // PCM_TOP_FRONT_CENTER,
+  kAudioChannelLabel_TopCenterSurround,     // PCM_TOP_CENTER,
+  kAudioChannelLabel_TopBackLeft,           // PCM_TOP_BACK_LEFT,
+  kAudioChannelLabel_TopBackRight,          // PCM_TOP_BACK_RIGHT,
+  kAudioChannelLabel_TopBackCenter          // PCM_TOP_BACK_CENTER
+};
+
+class CCoreAudioChannelLayout
+{
+public:
+  CCoreAudioChannelLayout();
+  CCoreAudioChannelLayout(AudioChannelLayout &layout);
+  virtual ~CCoreAudioChannelLayout();
+
+  operator AudioChannelLayout*() {return m_pLayout;}
+
+  bool                CopyLayout(AudioChannelLayout &layout);
+  static UInt32       GetChannelCountForLayout(AudioChannelLayout &layout);
+  static const char*  ChannelLabelToString(UInt32 label);
+  static const char*  ChannelLayoutToString(AudioChannelLayout &layout, std::string &str);
+  bool                AllChannelUnknown();
+protected:
+  AudioChannelLayout* m_pLayout;
+};
+
+#endif
\ No newline at end of file
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.cpp
new file mode 100644 (file)
index 0000000..937e561
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ *      Copyright (C) 2011-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 "CoreAudioDevice.h"
+#include "CoreAudioHelpers.h"
+#include "CoreAudioChannelLayout.h"
+#include "CoreAudioHardware.h"
+#include "utils/log.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CCoreAudioDevice
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoreAudioDevice::CCoreAudioDevice()  :
+  m_Started             (false    ),
+  m_DeviceId            (0        ),
+  m_MixerRestore        (-1       ),
+  m_IoProc              (NULL     ),
+  m_ObjectListenerProc  (NULL     ),
+  m_SampleRateRestore   (0.0f     ),
+  m_HogPid              (-1       ),
+  m_frameSize           (0        ),
+  m_OutputBufferIndex   (0        ),
+  m_BufferSizeRestore   (0        )
+{
+}
+
+CCoreAudioDevice::CCoreAudioDevice(AudioDeviceID deviceId) :
+  m_Started             (false    ),
+  m_DeviceId            (deviceId ),
+  m_MixerRestore        (-1       ),
+  m_IoProc              (NULL     ),
+  m_ObjectListenerProc  (NULL     ),
+  m_SampleRateRestore   (0.0f     ),
+  m_HogPid              (-1       ),
+  m_frameSize           (0        ),
+  m_OutputBufferIndex   (0        ),
+  m_BufferSizeRestore   (0        )
+{
+}
+
+CCoreAudioDevice::~CCoreAudioDevice()
+{
+  Close();
+}
+
+bool CCoreAudioDevice::Open(AudioDeviceID deviceId)
+{
+  m_DeviceId = deviceId;
+  m_BufferSizeRestore = GetBufferSize();
+  return true;
+}
+
+void CCoreAudioDevice::Close()
+{
+  if (!m_DeviceId)
+    return;
+
+  // Stop the device if it was started
+  Stop();
+
+  // Unregister the IOProc if we have one
+  RemoveIOProc();
+
+  SetHogStatus(false);
+  CCoreAudioHardware::SetAutoHogMode(false);
+
+  if (m_MixerRestore > -1) // We changed the mixer status
+    SetMixingSupport((m_MixerRestore ? true : false));
+  m_MixerRestore = -1;
+
+  if (m_SampleRateRestore != 0.0f)
+    SetNominalSampleRate(m_SampleRateRestore);
+
+  if (m_BufferSizeRestore && m_BufferSizeRestore != GetBufferSize())
+  {
+    SetBufferSize(m_BufferSizeRestore);
+    m_BufferSizeRestore = 0;
+  }
+
+  m_IoProc = NULL;
+  m_DeviceId = 0;
+  m_ObjectListenerProc = NULL;
+}
+
+void CCoreAudioDevice::Start()
+{
+  if (!m_DeviceId || m_Started)
+    return;
+
+  OSStatus ret = AudioDeviceStart(m_DeviceId, m_IoProc);
+  if (ret)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::Start: "
+      "Unable to start device. Error = %s", GetError(ret).c_str());
+  else
+    m_Started = true;
+}
+
+void CCoreAudioDevice::Stop()
+{
+  if (!m_DeviceId || !m_Started)
+    return;
+
+  OSStatus ret = AudioDeviceStop(m_DeviceId, m_IoProc);
+  if (ret)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::Stop: "
+      "Unable to stop device. Error = %s", GetError(ret).c_str());
+  m_Started = false;
+}
+
+void CCoreAudioDevice::RemoveObjectListenerProc(AudioObjectPropertyListenerProc callback, void* pClientData)
+{
+  if (!m_DeviceId)
+    return;
+
+  AudioObjectPropertyAddress audioProperty;
+  audioProperty.mSelector = kAudioObjectPropertySelectorWildcard;
+  audioProperty.mScope = kAudioObjectPropertyScopeWildcard;
+  audioProperty.mElement = kAudioObjectPropertyElementWildcard;
+
+  OSStatus ret = AudioObjectRemovePropertyListener(m_DeviceId, &audioProperty, callback, pClientData);
+  if (ret)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::RemoveObjectListenerProc: "
+      "Unable to set ObjectListener callback. Error = %s", GetError(ret).c_str());
+  }
+  m_ObjectListenerProc = NULL;
+}
+
+bool CCoreAudioDevice::SetObjectListenerProc(AudioObjectPropertyListenerProc callback, void* pClientData)
+{
+  // Allow only one ObjectListener at a time
+  if (!m_DeviceId || m_ObjectListenerProc)
+    return false;
+
+  AudioObjectPropertyAddress audioProperty;
+  audioProperty.mSelector = kAudioObjectPropertySelectorWildcard;
+  audioProperty.mScope = kAudioObjectPropertyScopeWildcard;
+  audioProperty.mElement = kAudioObjectPropertyElementWildcard;
+
+  OSStatus ret = AudioObjectAddPropertyListener(m_DeviceId, &audioProperty, callback, pClientData);
+
+  if (ret)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetObjectListenerProc: "
+      "Unable to remove ObjectListener callback. Error = %s", GetError(ret).c_str());
+    return false;
+  }
+
+  m_ObjectListenerProc = callback;
+  return true;
+}
+bool CCoreAudioDevice::AddIOProc(AudioDeviceIOProc ioProc, void* pCallbackData)
+{
+  // Allow only one IOProc at a time
+  if (!m_DeviceId || m_IoProc)
+    return false;
+
+  OSStatus ret = AudioDeviceCreateIOProcID(m_DeviceId, ioProc, pCallbackData, &m_IoProc);
+  if (ret)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::AddIOProc: "
+      "Unable to add IOProc. Error = %s", GetError(ret).c_str());
+    m_IoProc = NULL;
+    return false;
+  }
+
+  Start();
+
+  return true;
+}
+
+bool CCoreAudioDevice::RemoveIOProc()
+{
+  if (!m_DeviceId || !m_IoProc)
+    return false;
+
+  Stop();
+
+  OSStatus ret = AudioDeviceDestroyIOProcID(m_DeviceId, m_IoProc);
+  if (ret)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::RemoveIOProc: "
+      "Unable to remove IOProc. Error = %s", GetError(ret).c_str());
+
+  m_IoProc = NULL; // Clear the reference no matter what
+
+  Sleep(100);
+
+  return true;
+}
+
+std::string CCoreAudioDevice::GetName()
+{
+  if (!m_DeviceId)
+    return "";
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyDeviceName;
+
+  UInt32 propertySize;
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
+  if (ret != noErr)
+    return "";
+
+  std::string name;
+  char *buff = new char[propertySize + 1];
+  buff[propertySize] = 0x00;
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, buff);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::GetName: "
+      "Unable to get device name - id: 0x%04x. Error = %s", (uint)m_DeviceId, GetError(ret).c_str());
+  }
+  else
+  {
+    name = buff;
+    name.erase(name.find_last_not_of(" ") + 1);
+  }
+  delete[] buff;
+
+  return name;
+}
+
+UInt32 CCoreAudioDevice::GetTotalOutputChannels()
+{
+  UInt32 channels = 0;
+
+  if (!m_DeviceId)
+    return channels;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration;
+
+  UInt32 size = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &size);
+  if (ret != noErr)
+    return channels;
+
+  AudioBufferList* pList = (AudioBufferList*)malloc(size);
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, pList);
+  if (ret == noErr)
+  {
+    for(UInt32 buffer = 0; buffer < pList->mNumberBuffers; ++buffer)
+      channels += pList->mBuffers[buffer].mNumberChannels;
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::GetTotalOutputChannels: "
+      "Unable to get total device output channels - id: 0x%04x. Error = %s",
+      (uint)m_DeviceId, GetError(ret).c_str());
+  }
+
+  free(pList);
+
+  return channels;
+}
+
+bool CCoreAudioDevice::GetStreams(AudioStreamIdList* pList)
+{
+  if (!pList || !m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyStreams;
+
+  UInt32  propertySize = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
+  if (ret != noErr)
+    return false;
+
+  UInt32 streamCount = propertySize / sizeof(AudioStreamID);
+  AudioStreamID* pStreamList = new AudioStreamID[streamCount];
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pStreamList);
+  if (ret == noErr)
+  {
+    for (UInt32 stream = 0; stream < streamCount; stream++)
+      pList->push_back(pStreamList[stream]);
+  }
+  delete[] pStreamList;
+
+  return ret == noErr;
+}
+
+
+bool CCoreAudioDevice::IsRunning()
+{
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyDeviceIsRunning;
+
+  UInt32 isRunning = 0;
+  UInt32 propertySize = sizeof(isRunning);
+  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &isRunning);
+  if (ret != noErr)
+    return false;
+
+  return isRunning != 0;
+}
+
+bool CCoreAudioDevice::SetHogStatus(bool hog)
+{
+  // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode
+  // is a toggle and the only way to tell if you do get hog mode is to compare
+  // the returned pid against getpid, if the match, you have hog mode, if not you don't.
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyHogMode;
+
+  if (hog)
+  {
+    // Not already set
+    if (m_HogPid == -1)
+    {
+      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(m_HogPid), &m_HogPid);
+
+      // even if setting hogmode was successfull our PID might not get written
+      // into m_HogPid (so it stays -1). Readback hogstatus for judging if we
+      // had success on getting hog status
+      // We do this only when AudioObjectSetPropertyData didn't set m_HogPid because
+      // it seems that in the other cases the GetHogStatus could return -1
+      // which would overwrite our valid m_HogPid again
+      // Man we should never touch this shit again ;)
+      if (m_HogPid == -1)
+        m_HogPid = GetHogStatus();
+
+      if (ret || m_HogPid != getpid())
+      {
+        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
+          "Unable to set 'hog' status. Error = %s", GetError(ret).c_str());
+        return false;
+      }
+    }
+  }
+  else
+  {
+    // Currently Set
+    if (m_HogPid > -1)
+    {
+      pid_t hogPid = -1;
+      OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(hogPid), &hogPid);
+      if (ret || hogPid == getpid())
+      {
+        CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: "
+          "Unable to release 'hog' status. Error = %s", GetError(ret).c_str());
+        return false;
+      }
+      // Reset internal state
+      m_HogPid = hogPid;
+    }
+  }
+  return true;
+}
+
+pid_t CCoreAudioDevice::GetHogStatus()
+{
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyHogMode;
+
+  pid_t hogPid = -1;
+  UInt32 size = sizeof(hogPid);
+  AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, &hogPid);
+
+  return hogPid;
+}
+
+bool CCoreAudioDevice::SetMixingSupport(UInt32 mix)
+{
+  if (!m_DeviceId)
+    return false;
+
+  if (!GetMixingSupport())
+    return false;
+
+  int restore = -1;
+  if (m_MixerRestore == -1)
+  {
+    // This is our first change to this setting. Store the original setting for restore
+    restore = (GetMixingSupport() ? 1 : 0);
+  }
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertySupportsMixing;
+
+  UInt32 mixEnable = mix ? 1 : 0;
+  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(mixEnable), &mixEnable);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetMixingSupport: "
+      "Unable to set MixingSupport to %s. Error = %s", mix ? "'On'" : "'Off'", GetError(ret).c_str());
+    return false;
+  }
+  if (m_MixerRestore == -1)
+    m_MixerRestore = restore;
+  return true;
+}
+
+bool CCoreAudioDevice::GetMixingSupport()
+{
+  if (!m_DeviceId)
+    return false;
+
+  UInt32    size;
+  UInt32    mix = 0;
+  Boolean   writable = false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertySupportsMixing;
+
+  if( AudioObjectHasProperty( m_DeviceId, &propertyAddress ) )
+  {
+    OSStatus ret = AudioObjectIsPropertySettable(m_DeviceId, &propertyAddress, &writable);
+    if (ret)
+    {
+      CLog::Log(LOGERROR, "CCoreAudioDevice::SupportsMixing: "
+        "Unable to get propertyinfo mixing support. Error = %s", GetError(ret).c_str());
+      writable = false;
+    }
+
+    if (writable)
+    {
+      size = sizeof(mix);
+      ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &size, &mix);
+      if (ret != noErr)
+        mix = 0;
+    }
+  }
+  CLog::Log(LOGDEBUG, "CCoreAudioDevice::SupportsMixing: "
+    "Device mixing support : %s.", mix ? "'Yes'" : "'No'");
+
+  return (mix > 0);
+}
+
+bool CCoreAudioDevice::SetCurrentVolume(Float32 vol)
+{
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kHALOutputParam_Volume;
+
+  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float32), &vol);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetCurrentVolume: "
+      "Unable to set AudioUnit volume. Error = %s", GetError(ret).c_str());
+    return false;
+  }
+  return true;
+}
+
+bool CCoreAudioDevice::GetPreferredChannelLayout(CCoreAudioChannelLayout& layout)
+{
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyPreferredChannelLayout;
+
+  UInt32 propertySize = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
+  if (ret)
+    return false;
+
+  void* pBuf = malloc(propertySize);
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pBuf);
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::GetPreferredChannelLayout: "
+      "Unable to retrieve preferred channel layout. Error = %s", GetError(ret).c_str());
+  else
+  {
+    // Copy the result into the caller's instance
+    layout.CopyLayout(*((AudioChannelLayout*)pBuf));
+  }
+  free(pBuf);
+  return (ret == noErr);
+}
+
+bool CCoreAudioDevice::GetDataSources(CoreAudioDataSourceList* pList)
+{
+  if (!pList || !m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyDataSources;
+
+  UInt32 propertySize = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_DeviceId, &propertyAddress, 0, NULL, &propertySize);
+  if (ret != noErr)
+    return false;
+
+  UInt32  sources = propertySize / sizeof(UInt32);
+  UInt32* pSources = new UInt32[sources];
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, pSources);
+  if (ret == noErr)
+  {
+    for (UInt32 i = 0; i < sources; i++)
+      pList->push_back(pSources[i]);
+  }
+  delete[] pSources;
+  return (!ret);
+}
+
+Float64 CCoreAudioDevice::GetNominalSampleRate()
+{
+  if (!m_DeviceId)
+    return 0.0f;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
+
+  Float64 sampleRate = 0.0f;
+  UInt32  propertySize = sizeof(Float64);
+  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &sampleRate);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::GetNominalSampleRate: "
+      "Unable to retrieve current device sample rate. Error = %s", GetError(ret).c_str());
+    return 0.0f;
+  }
+  return sampleRate;
+}
+
+bool CCoreAudioDevice::SetNominalSampleRate(Float64 sampleRate)
+{
+  if (!m_DeviceId || sampleRate == 0.0f)
+    return false;
+
+  Float64 currentRate = GetNominalSampleRate();
+  if (currentRate == sampleRate)
+    return true; //No need to change
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
+
+  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, sizeof(Float64), &sampleRate);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetNominalSampleRate: "
+      "Unable to set current device sample rate to %0.0f. Error = %s",
+      (float)sampleRate, GetError(ret).c_str());
+    return false;
+  }
+  if (m_SampleRateRestore == 0.0f)
+    m_SampleRateRestore = currentRate;
+
+  return true;
+}
+
+UInt32 CCoreAudioDevice::GetNumLatencyFrames()
+{
+  UInt32 num_latency_frames = 0;
+  if (!m_DeviceId)
+    return 0;
+
+  // number of frames of latency in the AudioDevice
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyLatency;
+
+  UInt32 i_param = 0;
+  UInt32 i_param_size = sizeof(uint32_t);
+  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
+  if (ret == noErr)
+    num_latency_frames += i_param;
+
+  // number of frames in the IO buffers
+  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
+  if (ret == noErr)
+    num_latency_frames += i_param;
+
+  // number for frames in ahead the current hardware position that is safe to do IO
+  propertyAddress.mSelector = kAudioDevicePropertySafetyOffset;
+  ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &i_param_size, &i_param);
+  if (ret == noErr)
+    num_latency_frames += i_param;
+
+  return (num_latency_frames);
+}
+
+UInt32 CCoreAudioDevice::GetBufferSize()
+{
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
+
+  UInt32 size = 0;
+  UInt32 propertySize = sizeof(size);
+  OSStatus ret = AudioObjectGetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, &propertySize, &size);
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::GetBufferSize: "
+      "Unable to retrieve buffer size. Error = %s", GetError(ret).c_str());
+  return size;
+}
+
+bool CCoreAudioDevice::SetBufferSize(UInt32 size)
+{
+  if (!m_DeviceId)
+    return false;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioDevicePropertyScopeOutput;
+  propertyAddress.mElement  = 0;
+  propertyAddress.mSelector = kAudioDevicePropertyBufferFrameSize;
+
+  UInt32 propertySize = sizeof(size);
+  OSStatus ret = AudioObjectSetPropertyData(m_DeviceId, &propertyAddress, 0, NULL, propertySize, &size);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: "
+      "Unable to set buffer size. Error = %s", GetError(ret).c_str());
+  }
+
+  if (GetBufferSize() != size)
+    CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: Buffer size change not applied.");
+
+  return (ret == noErr);
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.h
new file mode 100644 (file)
index 0000000..dcd5bf6
--- /dev/null
@@ -0,0 +1,87 @@
+#pragma once
+/*
+ *      Copyright (C) 2011-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 "system.h"
+
+#if defined(TARGET_DARWIN_OSX)
+
+#include <string>
+
+#include "cores/AudioEngine/Sinks/osx/CoreAudioStream.h"
+
+#include <CoreAudio/CoreAudio.h>
+
+typedef std::list<UInt32> CoreAudioDataSourceList;
+typedef std::list<AudioDeviceID> CoreAudioDeviceList;
+
+class CCoreAudioChannelLayout;
+
+class CCoreAudioDevice
+{
+public:
+  CCoreAudioDevice();
+  CCoreAudioDevice(AudioDeviceID deviceId);
+  virtual ~CCoreAudioDevice();
+  
+  bool          Open(AudioDeviceID deviceId);
+  void          Close();
+  
+  void          Start();
+  void          Stop();
+  void          RemoveObjectListenerProc(AudioObjectPropertyListenerProc callback, void *pClientData);
+  bool          SetObjectListenerProc(AudioObjectPropertyListenerProc callback, void *pClientData);
+  
+  AudioDeviceID GetId() {return m_DeviceId;}
+  std::string   GetName();
+  UInt32        GetTotalOutputChannels();
+  bool          GetStreams(AudioStreamIdList *pList);
+  bool          IsRunning();
+  bool          SetHogStatus(bool hog);
+  pid_t         GetHogStatus();
+  bool          SetMixingSupport(UInt32 mix);
+  bool          GetMixingSupport();
+  bool          SetCurrentVolume(Float32 vol);
+  bool          GetPreferredChannelLayout(CCoreAudioChannelLayout &layout);
+  bool          GetDataSources(CoreAudioDataSourceList *pList);
+  Float64       GetNominalSampleRate();
+  bool          SetNominalSampleRate(Float64 sampleRate);
+  UInt32        GetNumLatencyFrames();
+  UInt32        GetBufferSize();
+  bool          SetBufferSize(UInt32 size);
+
+  bool          AddIOProc(AudioDeviceIOProc ioProc, void* pCallbackData);
+  bool          RemoveIOProc();
+protected:
+
+  bool              m_Started;
+  AudioDeviceID     m_DeviceId;
+  int               m_MixerRestore;
+  AudioDeviceIOProc m_IoProc;
+  AudioObjectPropertyListenerProc m_ObjectListenerProc;
+  
+  Float64           m_SampleRateRestore;
+  pid_t             m_HogPid;
+  unsigned int      m_frameSize;
+  unsigned int      m_OutputBufferIndex;
+  unsigned int      m_BufferSizeRestore;
+};
+
+#endif
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.cpp
new file mode 100644 (file)
index 0000000..51cba80
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ *      Copyright (C) 2011-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 "CoreAudioHardware.h"
+
+#include "CoreAudioHelpers.h"
+#include "utils/log.h"
+#include "osx/DarwinUtils.h"
+
+bool CCoreAudioHardware::GetAutoHogMode()
+{
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioHardwarePropertyHogModeIsAllowed; 
+
+  UInt32 val = 0;
+  UInt32 size = sizeof(val);
+  OSStatus ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &val); 
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioHardware::GetAutoHogMode: "
+      "Unable to get auto 'hog' mode. Error = %s", GetError(ret).c_str());
+    return false;
+  }
+  return (val == 1);
+}
+
+void CCoreAudioHardware::SetAutoHogMode(bool enable)
+{
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioHardwarePropertyHogModeIsAllowed; 
+
+  UInt32 val = enable ? 1 : 0;
+  UInt32 size = sizeof(val);
+  OSStatus ret = AudioObjectSetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &val); 
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioHardware::SetAutoHogMode: "
+      "Unable to set auto 'hog' mode. Error = %s", GetError(ret).c_str());
+}
+
+void CCoreAudioHardware::ResetAudioDevices()
+{
+  CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetAudioDevices resetting our devices to LPCM");
+  CoreAudioDeviceList list;
+  if (GetOutputDevices(&list))
+  {
+    for (CoreAudioDeviceList::iterator it = list.begin(); it != list.end(); it ++)
+    {
+      CCoreAudioDevice device = *it;
+
+      AudioStreamIdList streams;
+      if (device.GetStreams(&streams))
+      {
+        CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetAudioDevices %lu streams for device %s", streams.size(), device.GetName().c_str());
+        for (AudioStreamIdList::iterator ait = streams.begin(); ait != streams.end(); ait ++)
+          ResetStream(*ait);
+      }
+    }
+  }
+}
+
+void CCoreAudioHardware::ResetStream(AudioStreamID streamId)
+{
+  CCoreAudioStream stream;
+  stream.Open(streamId);
+  
+  AudioStreamBasicDescription desc;
+  if (stream.GetPhysicalFormat(&desc))
+  {
+    if (desc.mFormatID == 'IAC3' || desc.mFormatID == kAudioFormat60958AC3)
+    {
+      CLog::Log(LOGDEBUG, "CCoreAudioHardware::ResetStream stream 0x%x is in encoded format.. setting to LPCM", (unsigned int)streamId);
+
+      StreamFormatList availableFormats;
+      if (stream.GetAvailablePhysicalFormats(&availableFormats))
+      {
+        for (StreamFormatList::iterator fmtIt = availableFormats.begin(); fmtIt != availableFormats.end() ; fmtIt ++)
+        {
+          AudioStreamRangedDescription fmtDesc = *fmtIt;
+          if (fmtDesc.mFormat.mFormatID == kAudioFormatLinearPCM)
+          {
+            AudioStreamBasicDescription newFmt = { 0 };
+            newFmt = fmtDesc.mFormat;
+
+            if (stream.SetPhysicalFormat(&newFmt))
+              break;
+          }
+        }
+      }
+    }
+  }
+
+  stream.Close(false);
+}
+
+AudioDeviceID CCoreAudioHardware::FindAudioDevice(const std::string &searchName)
+{
+  AudioDeviceID deviceId = 0;
+
+  if (!searchName.length())
+    return deviceId;
+
+  std::string searchNameLowerCase = searchName;
+  std::transform(searchNameLowerCase.begin(), searchNameLowerCase.end(), searchNameLowerCase.begin(), ::tolower );
+  if (searchNameLowerCase.compare("default") == 0)
+  {
+    AudioDeviceID defaultDevice = GetDefaultOutputDevice();
+    CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: "
+      "Returning default device [0x%04x].", (uint)defaultDevice);
+    return defaultDevice;
+  }
+  CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: "
+    "Searching for device - %s.", searchName.c_str());
+
+  // Obtain a list of all available audio devices
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioHardwarePropertyDevices; 
+
+  UInt32 size = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size); 
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioHardware::FindAudioDevice: "
+      "Unable to retrieve the size of the list of available devices. Error = %s", GetError(ret).c_str());
+    return 0;
+  }
+
+  size_t deviceCount = size / sizeof(AudioDeviceID);
+  AudioDeviceID* pDevices = new AudioDeviceID[deviceCount];
+  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, pDevices);
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioHardware::FindAudioDevice: "
+      "Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str());
+    delete[] pDevices;
+    return 0;
+  }
+
+  // Attempt to locate the requested device
+  std::string deviceName;
+  for (size_t dev = 0; dev < deviceCount; dev++)
+  {
+    CCoreAudioDevice device;
+    device.Open((pDevices[dev]));
+    deviceName = device.GetName();
+    std::transform( deviceName.begin(), deviceName.end(), deviceName.begin(), ::tolower );
+    if (searchNameLowerCase.compare(deviceName) == 0)
+      deviceId = pDevices[dev];
+    if (deviceId)
+      break;
+  }
+  delete[] pDevices;
+
+  return deviceId;
+}
+
+AudioDeviceID CCoreAudioHardware::GetDefaultOutputDevice()
+{
+  AudioDeviceID deviceId = 0;
+  static AudioDeviceID lastDeviceId = 0;
+
+  AudioObjectPropertyAddress  propertyAddress;
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal;
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+  
+  UInt32 size = sizeof(AudioDeviceID);
+  OSStatus ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &deviceId);
+
+  // outputDevice is set to 0 if there is no audio device available
+  // or if the default device is set to an encoded format
+  if (ret != noErr || !deviceId) 
+  {
+    CLog::Log(LOGERROR, "CCoreAudioHardware::GetDefaultOutputDevice:"
+      " Unable to identify default output device. Error = %s", GetError(ret).c_str());
+    // if there was no error and no deviceId was returned
+    // return the last known default device
+    if (ret == noErr && !deviceId)
+      return lastDeviceId;
+    else
+      return 0;
+  }
+  
+  lastDeviceId = deviceId;
+
+  return deviceId;
+}
+
+void CCoreAudioHardware::GetOutputDeviceName(std::string& name)
+{
+  name = "Default";
+  AudioDeviceID deviceId = GetDefaultOutputDevice();
+
+  if (deviceId)
+  {
+    AudioObjectPropertyAddress  propertyAddress;
+    propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal;
+    propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+    propertyAddress.mSelector = kAudioObjectPropertyName;
+
+    CFStringRef theDeviceName = NULL;
+    UInt32 propertySize = sizeof(CFStringRef);
+    OSStatus ret = AudioObjectGetPropertyData(deviceId, &propertyAddress, 0, NULL, &propertySize, &theDeviceName); 
+    if (ret != noErr)
+      return;
+
+    DarwinCFStringRefToUTF8String(theDeviceName, name);
+
+    CFRelease(theDeviceName);
+  }
+}
+
+UInt32 CCoreAudioHardware::GetOutputDevices(CoreAudioDeviceList *pList)
+{
+  UInt32 found = 0;
+  if (!pList)
+    return found;
+
+  // Obtain a list of all available audio devices
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioHardwarePropertyDevices; 
+
+  UInt32 size = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size); 
+  if (ret != noErr)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioHardware::GetOutputDevices:"
+      " Unable to retrieve the size of the list of available devices. Error = %s", GetError(ret).c_str());
+    return found;
+  }
+
+  size_t deviceCount = size / sizeof(AudioDeviceID);
+  AudioDeviceID* pDevices = new AudioDeviceID[deviceCount];
+  ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, pDevices);
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioHardware::GetOutputDevices:"
+      " Unable to retrieve the list of available devices. Error = %s", GetError(ret).c_str());
+  else
+  {
+    for (size_t dev = 0; dev < deviceCount; dev++)
+    {
+      CCoreAudioDevice device(pDevices[dev]);
+      if (device.GetTotalOutputChannels() == 0)
+        continue;
+      found++;
+      pList->push_back(pDevices[dev]);
+    }
+  }
+  delete[] pDevices;
+
+  return found;
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHardware.h
new file mode 100644 (file)
index 0000000..7762eb1
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma once
+/*
+ *      Copyright (C) 2011-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 "system.h"
+
+#if defined(TARGET_DARWIN_OSX)
+
+#include "cores/AudioEngine/Sinks/osx/CoreAudioDevice.h"
+
+// There is only one AudioSystemObject instance system-side.
+// Therefore, all CCoreAudioHardware methods are static
+class CCoreAudioHardware
+{
+public:
+  static bool           GetAutoHogMode();
+  static void           SetAutoHogMode(bool enable);
+  static AudioStreamBasicDescription* FormatsList(AudioStreamID stream);
+  static AudioStreamID* StreamsList(AudioDeviceID device);
+  static void           ResetAudioDevices();
+  static void           ResetStream(AudioStreamID streamId);
+  static AudioDeviceID  FindAudioDevice(const std::string &deviceName);
+  static AudioDeviceID  GetDefaultOutputDevice();
+  static void           GetOutputDeviceName(std::string &name);
+  static UInt32         GetOutputDevices(CoreAudioDeviceList *pList);
+};
+
+#endif
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.cpp
new file mode 100644 (file)
index 0000000..e8355d7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *      Copyright (C) 2011-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 "CoreAudioHelpers.h"
+
+#include <sstream>
+
+// Helper Functions
+std::string GetError(OSStatus error)
+{
+  char buffer[128];
+  *(UInt32 *)(buffer + 1) = CFSwapInt32HostToBig(error);
+  if (isprint(buffer[1]) && isprint(buffer[2]) &&
+      isprint(buffer[3]) && isprint(buffer[4]))
+  {
+    buffer[0] = buffer[5] = '\'';
+    buffer[6] = '\0';
+  }
+  else
+  {
+    // no, format it as an integer
+    sprintf(buffer, "%d", (int)error);
+  }
+  return std::string(buffer);
+}
+
+const char* StreamDescriptionToString(AudioStreamBasicDescription desc, std::string &str)
+{
+  char fourCC[5] = {
+    (desc.mFormatID >> 24) & 0xFF,
+    (desc.mFormatID >> 16) & 0xFF,
+    (desc.mFormatID >>  8) & 0xFF,
+     desc.mFormatID        & 0xFF,
+    0
+  };
+
+  std::stringstream sstr; 
+  switch (desc.mFormatID)
+  {
+    case kAudioFormatLinearPCM:
+      sstr  << "["
+            << fourCC
+            << "] "
+            << ((desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "Mixable " )
+            << ((desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? "Non-" : "" )
+            << "Interleaved "
+            << desc.mChannelsPerFrame
+            << " Channel "
+            << desc.mBitsPerChannel
+            << "-bit "
+            << ((desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Floating Point " : "Signed Integer ")
+            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
+            << " ("
+            << (UInt32)desc.mSampleRate
+            << "Hz)";
+      str = sstr.str();
+      break;
+    case kAudioFormatAC3:
+      sstr  << "["
+            << fourCC
+            << "] "
+            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
+            << " AC-3/DTS ("
+            << (UInt32)desc.mSampleRate
+            << "Hz)";
+      str = sstr.str();                
+      break;
+    case kAudioFormat60958AC3:
+      sstr  << "["
+            << fourCC
+            << "] AC-3/DTS for S/PDIF "
+            << ((desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE")
+            << " ("
+            << (UInt32)desc.mSampleRate
+            << "Hz)";
+      str = sstr.str();
+      break;
+    default:
+      sstr  << "["
+            << fourCC
+            << "]";
+      break;
+  }
+  return str.c_str();
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioHelpers.h
new file mode 100644 (file)
index 0000000..5233565
--- /dev/null
@@ -0,0 +1,27 @@
+#pragma once
+/*
+ *      Copyright (C) 2011-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 <string>
+#include <AudioToolbox/AudioToolbox.h>
+
+// Helper Functions
+std::string GetError(OSStatus error);
+const char* StreamDescriptionToString(AudioStreamBasicDescription desc, std::string &str);
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.cpp
new file mode 100644 (file)
index 0000000..4b7a579
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ *      Copyright (C) 2011-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 "CoreAudioStream.h"
+
+#include "CoreAudioHelpers.h"
+#include "utils/log.h"
+#include "utils/StdString.h"
+
+CCoreAudioStream::CCoreAudioStream() :
+  m_StreamId  (0    )
+{
+  m_OriginalVirtualFormat.mFormatID = 0;
+  m_OriginalPhysicalFormat.mFormatID = 0;
+}
+
+CCoreAudioStream::~CCoreAudioStream()
+{
+  Close();
+}
+
+bool CCoreAudioStream::Open(AudioStreamID streamId)
+{
+  m_StreamId = streamId;
+  CLog::Log(LOGDEBUG, "CCoreAudioStream::Open: Opened stream 0x%04x.", (uint)m_StreamId);
+
+  // watch for physical property changes.
+  AudioObjectPropertyAddress propertyAOPA;
+  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
+  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
+  propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
+  if (AudioObjectAddPropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioStream::Open: couldn't set up a physical property listener.");
+
+  // watch for virtual property changes.
+  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
+  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
+  propertyAOPA.mSelector = kAudioStreamPropertyVirtualFormat;
+  if (AudioObjectAddPropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioStream::Open: couldn't set up a virtual property listener.");
+
+  return true;
+}
+
+// TODO: Should it even be possible to change both the 
+// physical and virtual formats, since the devices do it themselves?
+void CCoreAudioStream::Close(bool restore)
+{
+  if (!m_StreamId)
+    return;
+
+  std::string formatString;
+
+  // remove the physical/virtual property listeners before we make changes
+  // that will trigger callbacks that we do not care about.
+  AudioObjectPropertyAddress propertyAOPA;
+  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
+  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
+  propertyAOPA.mSelector = kAudioStreamPropertyPhysicalFormat;
+  if (AudioObjectRemovePropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
+    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Couldn't remove property listener.");
+
+  propertyAOPA.mScope    = kAudioObjectPropertyScopeGlobal;
+  propertyAOPA.mElement  = kAudioObjectPropertyElementMaster;  
+  propertyAOPA.mSelector = kAudioStreamPropertyVirtualFormat;
+  if (AudioObjectRemovePropertyListener(m_StreamId, &propertyAOPA, HardwareStreamListener, this) != noErr)
+    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Couldn't remove property listener.");
+
+  // Revert any format changes we made
+  if (restore && m_OriginalVirtualFormat.mFormatID && m_StreamId)
+  {
+    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: "
+      "Restoring original virtual format for stream 0x%04x. (%s)",
+      (uint)m_StreamId, StreamDescriptionToString(m_OriginalVirtualFormat, formatString));
+    AudioStreamBasicDescription setFormat = m_OriginalVirtualFormat;
+    SetVirtualFormat(&setFormat);
+  }
+  if (restore && m_OriginalPhysicalFormat.mFormatID && m_StreamId)
+  {
+    CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: "
+      "Restoring original physical format for stream 0x%04x. (%s)",
+      (uint)m_StreamId, StreamDescriptionToString(m_OriginalPhysicalFormat, formatString));
+    AudioStreamBasicDescription setFormat = m_OriginalPhysicalFormat;
+    SetPhysicalFormat(&setFormat);
+  }
+
+  m_OriginalVirtualFormat.mFormatID  = 0;
+  m_OriginalPhysicalFormat.mFormatID = 0;
+  CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Closed stream 0x%04x.", (uint)m_StreamId);
+  m_StreamId = 0;
+}
+
+UInt32 CCoreAudioStream::GetDirection()
+{
+  if (!m_StreamId)
+    return 0;
+
+  UInt32 val = 0;
+  UInt32 size = sizeof(UInt32);
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyDirection; 
+
+  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, &val); 
+  if (ret)
+    return 0;
+
+  return val;
+}
+
+bool CCoreAudioStream::IsDigitalOuptut(AudioStreamID id)
+{
+  UInt32 type = GetTerminalType(id);
+  return (type == kAudioStreamTerminalTypeDigitalAudioInterface ||
+          type == kAudioStreamTerminalTypeDisplayPort ||
+          type == kAudioStreamTerminalTypeHDMI);
+}
+
+UInt32 CCoreAudioStream::GetTerminalType(AudioStreamID id)
+{
+  if (!id)
+    return 0;
+
+  UInt32 val = 0;
+  UInt32 size = sizeof(UInt32);
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyTerminalType; 
+
+  OSStatus ret = AudioObjectGetPropertyData(id, &propertyAddress, 0, NULL, &size, &val);
+  if (ret)
+    return 0;
+  return val;
+}
+
+UInt32 CCoreAudioStream::GetNumLatencyFrames()
+{
+  if (!m_StreamId)
+    return 0;
+
+  UInt32 i_param_size = sizeof(uint32_t);
+  UInt32 i_param, num_latency_frames = 0;
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyLatency; 
+
+  // number of frames of latency in the AudioStream
+  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &i_param_size, &i_param); 
+  if (ret == noErr)
+  {
+    num_latency_frames += i_param;
+  }
+
+  return num_latency_frames;
+}
+
+bool CCoreAudioStream::GetVirtualFormat(AudioStreamBasicDescription* pDesc)
+{
+  if (!pDesc || !m_StreamId)
+    return false;
+
+  UInt32 size = sizeof(AudioStreamBasicDescription);
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; 
+  OSStatus ret = AudioObjectGetPropertyDataSize(m_StreamId, &propertyAddress, 0, NULL, &size); 
+  if (ret)
+    return false;
+
+  ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, pDesc); 
+  if (ret)
+    return false;
+  return true;
+}
+
+bool CCoreAudioStream::SetVirtualFormat(AudioStreamBasicDescription* pDesc)
+{
+  if (!pDesc || !m_StreamId)
+    return false;
+
+  std::string formatString;
+
+  if (!m_OriginalVirtualFormat.mFormatID)
+  {
+    // Store the original format (as we found it) so that it can be restored later
+    if (!GetVirtualFormat(&m_OriginalVirtualFormat))
+    {
+      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
+        "Unable to retrieve current virtual format for stream 0x%04x.", (uint)m_StreamId);
+      return false;
+    }
+  }
+  m_virtual_format_event.Reset();
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyVirtualFormat; 
+
+  UInt32 propertySize = sizeof(AudioStreamBasicDescription);
+  OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); 
+  if (ret)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
+      "Unable to set virtual format for stream 0x%04x. Error = %s",
+      (uint)m_StreamId, GetError(ret).c_str());
+    return false;
+  }
+
+  // The AudioStreamSetProperty is not only asynchronious,
+  // it is also not Atomic, in its behaviour.
+  // Therefore we check 5 times before we really give up.
+  // FIXME: failing isn't actually implemented yet.
+  for (int i = 0; i < 10; ++i)
+  {
+    AudioStreamBasicDescription checkVirtualFormat;
+    if (!GetVirtualFormat(&checkVirtualFormat))
+    {
+      CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: "
+        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
+      return false;
+    }
+    if (checkVirtualFormat.mSampleRate == pDesc->mSampleRate &&
+        checkVirtualFormat.mFormatID == pDesc->mFormatID &&
+        checkVirtualFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
+    {
+      // The right format is now active.
+      CLog::Log(LOGDEBUG, "CCoreAudioStream::SetVirtualFormat: "
+        "Virtual format for stream 0x%04x. now active (%s)",
+        (uint)m_StreamId, StreamDescriptionToString(checkVirtualFormat, formatString));
+      break;
+    }
+    m_virtual_format_event.WaitMSec(100);
+  }
+  return true;
+}
+
+bool CCoreAudioStream::GetPhysicalFormat(AudioStreamBasicDescription* pDesc)
+{
+  if (!pDesc || !m_StreamId)
+    return false;
+
+  UInt32 size = sizeof(AudioStreamBasicDescription);
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; 
+
+  OSStatus ret = AudioObjectGetPropertyData(m_StreamId, &propertyAddress, 0, NULL, &size, pDesc); 
+  if (ret)
+    return false;
+  return true;
+}
+
+bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc)
+{
+  if (!pDesc || !m_StreamId)
+    return false;
+
+  std::string formatString;
+
+  if (!m_OriginalPhysicalFormat.mFormatID)
+  {
+    // Store the original format (as we found it) so that it can be restored later
+    if (!GetPhysicalFormat(&m_OriginalPhysicalFormat))
+    {
+      CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
+        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
+      return false;
+    }
+  }
+  m_physical_format_event.Reset();
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyPhysicalFormat; 
+
+  UInt32 propertySize = sizeof(AudioStreamBasicDescription);
+  OSStatus ret = AudioObjectSetPropertyData(m_StreamId, &propertyAddress, 0, NULL, propertySize, pDesc); 
+  if (ret)
+  {
+    CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
+      "Unable to set physical format for stream 0x%04x. Error = %s",
+      (uint)m_StreamId, GetError(ret).c_str());
+    return false;
+  }
+
+  // The AudioStreamSetProperty is not only asynchronious,
+  // it is also not Atomic, in its behaviour.
+  // Therefore we check 5 times before we really give up.
+  // FIXME: failing isn't actually implemented yet.
+  for(int i = 0; i < 10; ++i)
+  {
+    AudioStreamBasicDescription checkPhysicalFormat;
+    if (!GetPhysicalFormat(&checkPhysicalFormat))
+    {
+      CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: "
+        "Unable to retrieve current physical format for stream 0x%04x.", (uint)m_StreamId);
+      return false;
+    }
+    if (checkPhysicalFormat.mSampleRate == pDesc->mSampleRate &&
+        checkPhysicalFormat.mFormatID   == pDesc->mFormatID   &&
+        checkPhysicalFormat.mFramesPerPacket == pDesc->mFramesPerPacket)
+    {
+      // The right format is now active.
+      CLog::Log(LOGDEBUG, "CCoreAudioStream::SetPhysicalFormat: "
+        "Physical format for stream 0x%04x. now active (%s)",
+        (uint)m_StreamId, StreamDescriptionToString(checkPhysicalFormat, formatString));
+      break;
+    }
+    m_physical_format_event.WaitMSec(100);
+  }
+
+  return true;
+}
+
+bool CCoreAudioStream::GetAvailableVirtualFormats(StreamFormatList* pList)
+{
+  return GetAvailableVirtualFormats(m_StreamId, pList);
+}
+
+bool CCoreAudioStream::GetAvailableVirtualFormats(AudioStreamID id, StreamFormatList* pList)
+{
+  if (!pList || !id)
+    return false;
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyAvailableVirtualFormats; 
+
+  UInt32 propertySize = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(id, &propertyAddress, 0, NULL, &propertySize);
+  if (ret)
+    return false;
+
+  UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription);
+  AudioStreamRangedDescription *pFormatList = new AudioStreamRangedDescription[formatCount];
+  ret = AudioObjectGetPropertyData(id, &propertyAddress, 0, NULL, &propertySize, pFormatList);
+  if (!ret)
+  {
+    for (UInt32 format = 0; format < formatCount; format++)
+      pList->push_back(pFormatList[format]);
+  }
+  delete[] pFormatList;
+  return (ret == noErr);
+}
+
+bool CCoreAudioStream::GetAvailablePhysicalFormats(StreamFormatList* pList)
+{
+  return GetAvailablePhysicalFormats(m_StreamId, pList);
+}
+
+bool CCoreAudioStream::GetAvailablePhysicalFormats(AudioStreamID id, StreamFormatList* pList)
+{
+  if (!pList || !id)
+    return false;
+
+  AudioObjectPropertyAddress propertyAddress; 
+  propertyAddress.mScope    = kAudioObjectPropertyScopeGlobal; 
+  propertyAddress.mElement  = kAudioObjectPropertyElementMaster;
+  propertyAddress.mSelector = kAudioStreamPropertyAvailablePhysicalFormats; 
+
+  UInt32 propertySize = 0;
+  OSStatus ret = AudioObjectGetPropertyDataSize(id, &propertyAddress, 0, NULL, &propertySize);
+  if (ret)
+    return false;
+
+  UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription);
+  AudioStreamRangedDescription *pFormatList = new AudioStreamRangedDescription[formatCount];
+  ret = AudioObjectGetPropertyData(id, &propertyAddress, 0, NULL, &propertySize, pFormatList);
+  if (!ret)
+  {
+    for (UInt32 format = 0; format < formatCount; format++)
+      pList->push_back(pFormatList[format]);
+  }
+  delete[] pFormatList;
+  return (ret == noErr);
+}
+
+OSStatus CCoreAudioStream::HardwareStreamListener(AudioObjectID inObjectID,
+  UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void *inClientData)
+{
+  CCoreAudioStream *ca_stream = (CCoreAudioStream*)inClientData;
+
+  for (UInt32 i = 0; i < inNumberAddresses; i++)
+  {
+    if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat)
+    {
+      AudioStreamBasicDescription actualFormat;
+      UInt32 propertySize = sizeof(AudioStreamBasicDescription);
+      // hardware physical format has changed.
+      if (AudioObjectGetPropertyData(ca_stream->m_StreamId, &inAddresses[i], 0, NULL, &propertySize, &actualFormat) == noErr)
+      {
+        CStdString formatString;
+        CLog::Log(LOGINFO, "CCoreAudioStream::HardwareStreamListener: "
+          "Hardware physical format changed to %s", StreamDescriptionToString(actualFormat, formatString));
+        ca_stream->m_physical_format_event.Set();
+      }
+    }
+    else if (inAddresses[i].mSelector == kAudioStreamPropertyVirtualFormat)
+    {
+      // hardware virtual format has changed.
+      AudioStreamBasicDescription actualFormat;
+      UInt32 propertySize = sizeof(AudioStreamBasicDescription);
+      if (AudioObjectGetPropertyData(ca_stream->m_StreamId, &inAddresses[i], 0, NULL, &propertySize, &actualFormat) == noErr)
+      {
+        CStdString formatString;
+        CLog::Log(LOGINFO, "CCoreAudioStream::HardwareStreamListener: "
+          "Hardware virtual format changed to %s", StreamDescriptionToString(actualFormat, formatString));
+        ca_stream->m_virtual_format_event.Set();
+      }
+    }
+  }
+
+  return noErr;
+}
diff --git a/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h b/xbmc/cores/AudioEngine/Sinks/osx/CoreAudioStream.h
new file mode 100644 (file)
index 0000000..3f3d1d0
--- /dev/null
@@ -0,0 +1,69 @@
+#pragma once
+/*
+ *      Copyright (C) 2011-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 "system.h"
+
+#if defined(TARGET_DARWIN_OSX)
+
+#include "threads/Event.h"
+#include <CoreAudio/CoreAudio.h>
+
+#include <list>
+
+typedef std::list<AudioStreamID> AudioStreamIdList;
+typedef std::list<AudioStreamRangedDescription> StreamFormatList;
+
+class CCoreAudioStream
+{
+public:
+  CCoreAudioStream();
+  virtual ~CCoreAudioStream();
+  
+  bool    Open(AudioStreamID streamId);
+  void    Close(bool restore = true);
+
+  AudioStreamID GetId() {return m_StreamId;}
+  UInt32  GetDirection();
+  static UInt32 GetTerminalType(AudioStreamID id);
+  UInt32  GetNumLatencyFrames();
+  bool    GetVirtualFormat(AudioStreamBasicDescription *pDesc);
+  bool    GetPhysicalFormat(AudioStreamBasicDescription *pDesc);
+  bool    SetVirtualFormat(AudioStreamBasicDescription *pDesc);
+  bool    SetPhysicalFormat(AudioStreamBasicDescription *pDesc);
+  bool    GetAvailableVirtualFormats(StreamFormatList *pList);
+  bool    GetAvailablePhysicalFormats(StreamFormatList *pList);
+  static bool GetAvailableVirtualFormats(AudioStreamID id, StreamFormatList *pList);
+  static bool GetAvailablePhysicalFormats(AudioStreamID id, StreamFormatList *pList);
+  static bool IsDigitalOuptut(AudioStreamID id);
+
+protected:
+  static OSStatus HardwareStreamListener(AudioObjectID inObjectID,
+    UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void* inClientData);
+
+  CEvent m_virtual_format_event;
+  CEvent m_physical_format_event;
+
+  AudioStreamID m_StreamId;
+  AudioStreamBasicDescription m_OriginalVirtualFormat;  
+  AudioStreamBasicDescription m_OriginalPhysicalFormat;
+};
+
+#endif
index 0ecaecf..f37d090 100644 (file)
@@ -48,6 +48,7 @@
 #include "RenderCapture.h"
 #include "RenderFormats.h"
 #include "cores/IPlayer.h"
+#include "cores/dvdplayer/DVDCodecs/DVDCodecUtils.h"
 
 #ifdef HAVE_LIBVDPAU
 #include "cores/dvdplayer/DVDCodecs/Video/VDPAU.h"
@@ -742,6 +743,7 @@ unsigned int CLinuxRendererGL::PreInit()
 
   m_iYV12RenderBuffer = 0;
 
+  m_formats.clear();
   m_formats.push_back(RENDER_FMT_YUV420P);
   GLint size;
   glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_LUMINANCE16, NP2(1920), NP2(1080), 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, NULL);
@@ -3115,9 +3117,11 @@ void CLinuxRendererGL::ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsign
   int      srcStride[4] = {};
   int      srcFormat    = -1;
 
-  if (m_format == RENDER_FMT_YUV420P)
+  if (m_format == RENDER_FMT_YUV420P ||
+      m_format == RENDER_FMT_YUV420P10 ||
+      m_format == RENDER_FMT_YUV420P16)
   {
-    srcFormat = PIX_FMT_YUV420P;
+    srcFormat = CDVDCodecUtils::PixfmtFromEFormat(m_format);
     for (int i = 0; i < 3; i++)
     {
       src[i]       = im->plane[i];
index 452a958..c7f24fe 100644 (file)
@@ -588,6 +588,7 @@ unsigned int CLinuxRendererGLES::PreInit()
   m_iYV12RenderBuffer = 0;
   m_NumYV12Buffers = 2;
 
+  m_formats.clear();
   m_formats.push_back(RENDER_FMT_YUV420P);
   m_formats.push_back(RENDER_FMT_NV12);
   m_formats.push_back(RENDER_FMT_BYPASS);
@@ -1482,10 +1483,10 @@ void CLinuxRendererGLES::RenderSurfaceTexture(int index, int field)
   }
 
   // Set texture coordinates (MediaCodec is flipped in y)
-  tex[0][0] = tex[3][0] = 0.0f;
-  tex[0][1] = tex[1][1] = 1.0f;
-  tex[1][0] = tex[2][0] = 1.0f;
-  tex[2][1] = tex[3][1] = 0.0f;
+  tex[0][0] = tex[3][0] = plane.rect.x1;
+  tex[0][1] = tex[1][1] = plane.rect.y2;
+  tex[1][0] = tex[2][0] = plane.rect.x2;
+  tex[2][1] = tex[3][1] = plane.rect.y1;
 
   for(int i = 0; i < 4; i++)
   {
@@ -2454,6 +2455,27 @@ void CLinuxRendererGLES::DeleteSurfaceTexture(int index)
 }
 bool CLinuxRendererGLES::CreateSurfaceTexture(int index)
 {
+  YV12Image &im     = m_buffers[index].image;
+  YUVFIELDS &fields = m_buffers[index].fields;
+  YUVPLANE  &plane  = fields[0][0];
+
+  memset(&im    , 0, sizeof(im));
+  memset(&fields, 0, sizeof(fields));
+
+  im.height = m_sourceHeight;
+  im.width  = m_sourceWidth;
+
+  plane.texwidth  = im.width;
+  plane.texheight = im.height;
+  plane.pixpertex_x = 1;
+  plane.pixpertex_y = 1;
+
+  if(m_renderMethod & RENDER_POT)
+  {
+    plane.texwidth  = NP2(plane.texwidth);
+    plane.texheight = NP2(plane.texheight);
+  }
+
   return true;
 }
 
index 62f1e86..e6a2d81 100644 (file)
@@ -35,6 +35,7 @@
 #include "settings/DisplaySettings.h"
 #include "threads/SingleLock.h"
 #include "utils/MathUtils.h"
+#include "OverlayRendererUtil.h"
 #include "OverlayRendererGUI.h"
 #if defined(HAS_GL) || defined(HAS_GLES)
 #include "OverlayRendererGL.h"
@@ -274,6 +275,8 @@ void CRenderer::Render(COverlay* o)
 
   }
 
+  state.x += GetStereoscopicDepth();
+
   o->Render(state);
 }
 
index bd56d8b..7575a10 100644 (file)
@@ -166,7 +166,7 @@ void COverlayText::Render(OVERLAY::SRenderState &state)
   mat.m[0][3] = rd.x1;
   mat.m[1][3] = rd.y1;
 
-  float x = state.x + GetStereoscopicDepth(), y = state.y;
+  float x = state.x, y = state.y;
   mat.InverseTransformPosition(x, y);
 
   g_graphicsContext.SetTransform(mat, 1.0f, 1.0f);
index 07e1ca1..72478ab 100644 (file)
@@ -299,9 +299,14 @@ bool convert_quad(ASS_Image* images, SQuads& quads)
 
 int GetStereoscopicDepth()
 {
-  int depth = CSettings::Get().GetInt("subtitles.stereoscopicdepth");
-  if (depth && g_graphicsContext.GetStereoMode() && g_graphicsContext.GetStereoMode() != RENDER_STEREO_MODE_MONO)
+  int depth = 0;
+
+  if(g_graphicsContext.GetStereoMode() != RENDER_STEREO_MODE_MONO
+  && g_graphicsContext.GetStereoMode() != RENDER_STEREO_MODE_OFF)
+  {
+    depth  = CSettings::Get().GetInt("subtitles.stereoscopicdepth");
     depth *= (g_graphicsContext.GetStereoView() == RENDER_STEREO_VIEW_LEFT ? 1 : -1);
+  }
 
   return depth;
 }
index f619cba..17e9415 100644 (file)
@@ -203,6 +203,10 @@ bool CWinShader::Execute(std::vector<LPDIRECT3DSURFACE9> *vecRT, unsigned int ve
     oldRT->Release();
   }
 
+  // MSDN says: Setting a new render target will cause the viewport 
+  // to be set to the full size of the new render target.
+  // So we need restore our viewport
+  g_Windowing.RestoreViewPort();
   return true;
 }
 
@@ -769,6 +773,10 @@ bool CConvolutionShaderSeparable::ClearIntermediateRenderTarget()
   currentRT->Release();
   intermediateRT->Release();
 
+  // MSDN says: Setting a new render target will cause the viewport 
+  // to be set to the full size of the new render target.
+  // So we need restore our viewport
+  g_Windowing.RestoreViewPort();
   return true;
 }
 
index 7c4ac0d..48794a7 100644 (file)
@@ -140,10 +140,11 @@ void CWinRenderer::SelectRenderMethod()
   {
     CLog::Log(LOGNOTICE, "D3D: rendering method forced to DXVA processor");
     m_renderMethod = RENDER_DXVA;
-    if (!m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
+    if (!m_processor || !m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
     {
       CLog::Log(LOGNOTICE, "D3D: unable to open DXVA processor");
-      m_processor->Close();
+      if (m_processor)  
+        m_processor->Close();
       m_renderMethod = RENDER_INVALID;
     }
   }
@@ -155,13 +156,16 @@ void CWinRenderer::SelectRenderMethod()
     {
       case RENDER_METHOD_DXVAHD:
       case RENDER_METHOD_DXVA:
-        m_renderMethod = RENDER_DXVA;
-        if (m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
-            break;
-        else
+        if (!m_processor || !m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
         {
           CLog::Log(LOGNOTICE, "D3D: unable to open DXVA processor");
-          m_processor->Close();
+          if (m_processor)
+            m_processor->Close();
+        }
+        else
+        {
+          m_renderMethod = RENDER_DXVA;
+          break;
         }
       // Drop through to pixel shader
       case RENDER_METHOD_AUTO:
@@ -392,20 +396,14 @@ unsigned int CWinRenderer::PreInit()
 
   g_Windowing.Get3DDevice()->GetDeviceCaps(&m_deviceCaps);
 
+  m_formats.clear();
   m_formats.push_back(RENDER_FMT_YUV420P);
-  if(g_Windowing.IsTextureFormatOk(D3DFMT_L16, 0))
-  {
-    m_formats.push_back(RENDER_FMT_YUV420P10);
-    m_formats.push_back(RENDER_FMT_YUV420P16);
-  }
-  m_formats.push_back(RENDER_FMT_NV12);
-  m_formats.push_back(RENDER_FMT_YUYV422);
-  m_formats.push_back(RENDER_FMT_UYVY422);
 
   m_iRequestedMethod = CSettings::Get().GetInt("videoplayer.rendermethod");
 
-  if (g_advancedSettings.m_DXVAForceProcessorRenderer || m_iRequestedMethod == RENDER_METHOD_DXVA
-      || m_iRequestedMethod == RENDER_METHOD_DXVAHD)
+  if (g_advancedSettings.m_DXVAForceProcessorRenderer
+  ||  m_iRequestedMethod == RENDER_METHOD_DXVA
+  ||  m_iRequestedMethod == RENDER_METHOD_DXVAHD)
   {
     if (m_iRequestedMethod != RENDER_METHOD_DXVA && CSysInfo::IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7))
     {
@@ -414,18 +412,30 @@ unsigned int CWinRenderer::PreInit()
       {
         CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA-HD processor - skipping");
         SAFE_DELETE(m_processor);
-        m_processor = new DXVA::CProcessor();
       }
-      else
-        return 0;
     }
-    else
+    if (!m_processor)
+    {
       m_processor = new DXVA::CProcessor();
-
-    if (!m_processor->PreInit())
-      CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA2 processor - skipping");
+      if (!m_processor->PreInit())
+      {
+        CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA2 processor - skipping");
+        SAFE_DELETE(m_processor);
+      }
+    }
+  }
+  // allow other color spaces besides YV12 in case DXVA rendering is not used or not available
+  if (!m_processor || (m_iRequestedMethod != RENDER_METHOD_DXVA && m_iRequestedMethod != RENDER_METHOD_DXVAHD))
+  {
+    if (g_Windowing.IsTextureFormatOk(D3DFMT_L16, 0))
+    {
+      m_formats.push_back(RENDER_FMT_YUV420P10);
+      m_formats.push_back(RENDER_FMT_YUV420P16);
+    }
+    m_formats.push_back(RENDER_FMT_NV12);
+    m_formats.push_back(RENDER_FMT_YUYV422);
+    m_formats.push_back(RENDER_FMT_UYVY422);
   }
-
   return 0;
 }
 
@@ -951,6 +961,11 @@ void CWinRenderer::Stage1()
     // Restore the render target
     pD3DDevice->SetRenderTarget(0, oldRT);
 
+    // MSDN says: Setting a new render target will cause the viewport 
+    // to be set to the full size of the new render target.
+    // So we need restore our viewport
+    g_Windowing.RestoreViewPort();
+
     oldRT->Release();
     newRT->Release();
   }
index 2453c65..af897fe 100644 (file)
@@ -45,8 +45,6 @@ CDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg() : CDVDAudioCodec()
   m_channels = 0;
   m_layout = 0;
   
-  m_bLpcmMode = false;
-
   m_pFrame1 = NULL;
   m_iSampleFormat = AV_SAMPLE_FMT_NONE;
 }
@@ -73,11 +71,6 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
     return false;
   }
 
-#if defined(TARGET_DARWIN_OSX)
-  if (CSettings::Get().GetInt("audiooutput.channels") >  AE_CH_LAYOUT_2_0)
-    m_bLpcmMode = true;
-#endif
-
   m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec);
   m_pCodecContext->debug_mv = 0;
   m_pCodecContext->debug = 0;
@@ -198,7 +191,7 @@ int CDVDAudioCodecFFmpeg::Decode(uint8_t* pData, int iSize)
     default:
       convert = true;
   }
-  if(m_bLpcmMode || convert)
+  if(convert)
     ConvertToFloat();
 
   return iBytesUsed;
@@ -310,25 +303,18 @@ int CDVDAudioCodecFFmpeg::GetEncodedSampleRate()
 
 enum AEDataFormat CDVDAudioCodecFFmpeg::GetDataFormat()
 {
-  if(m_bLpcmMode)
-  {
-    return AE_FMT_LPCM;
-  }
-  else
+  switch(m_pCodecContext->sample_fmt)
   {
-    switch(m_pCodecContext->sample_fmt)
-    {
-      case AV_SAMPLE_FMT_U8 : return AE_FMT_U8;
-      case AV_SAMPLE_FMT_S16: return AE_FMT_S16NE;
-      case AV_SAMPLE_FMT_S32: return AE_FMT_S32NE;
-      case AV_SAMPLE_FMT_FLT: return AE_FMT_FLOAT;
-      case AV_SAMPLE_FMT_DBL: return AE_FMT_DOUBLE;
-      case AV_SAMPLE_FMT_NONE:
-        CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::GetDataFormat - invalid data format");
-        return AE_FMT_INVALID;
-      default:
-        return AE_FMT_FLOAT;
-    }
+    case AV_SAMPLE_FMT_U8 : return AE_FMT_U8;
+    case AV_SAMPLE_FMT_S16: return AE_FMT_S16NE;
+    case AV_SAMPLE_FMT_S32: return AE_FMT_S32NE;
+    case AV_SAMPLE_FMT_FLT: return AE_FMT_FLOAT;
+    case AV_SAMPLE_FMT_DBL: return AE_FMT_DOUBLE;
+    case AV_SAMPLE_FMT_NONE:
+      CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::GetDataFormat - invalid data format");
+      return AE_FMT_INVALID;
+    default:
+      return AE_FMT_FLOAT;
   }
 }
 
index ab461ab..1646e00 100644 (file)
@@ -50,7 +50,6 @@ protected:
   SwrContext*         m_pConvert;
   enum AVSampleFormat m_iSampleFormat;  
   CAEChannelInfo      m_channelLayout;
-  bool                m_bLpcmMode;
 
   AVFrame* m_pFrame1;
   int      m_iBufferSize1;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp
deleted file mode 100644 (file)
index f49b5b5..0000000
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- *      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/>.
- *
- */
-
-#include "DVDAudioCodecPassthroughFFmpeg.h"
-#include "DVDCodecs/DVDCodecs.h"
-#include "DVDStreamInfo.h"
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#include "settings/MediaSettings.h"
-#include "settings/Settings.h"
-#include "utils/log.h"
-#include "cores/AudioEngine/AEFactory.h"
-
-//These values are forced to allow spdif out
-#define OUT_SAMPLESIZE 16
-#define OUT_CHANNELS   2
-#define OUT_SAMPLERATE 48000
-
-/* Lookup tables */
-static const uint16_t AC3Bitrates[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640};
-static const uint16_t AC3FSCod   [] = {48000, 44100, 32000, 0};
-
-static const uint16_t DTSFSCod   [] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 0, 0};
-
-#define NULL_MUXER(muxer) \
-  muxer.m_pFormat    = NULL; \
-  muxer.m_pStream    = NULL; \
-  muxer.m_OutputSize = 0; \
-  muxer.m_Consumed   = 0; \
-  muxer.m_Buffer     = NULL; \
-  muxer.m_BufferSize = 0;
-
-CDVDAudioCodecPassthroughFFmpeg::CDVDAudioCodecPassthroughFFmpeg(void)
-{
-  NULL_MUXER(m_SPDIF);
-  NULL_MUXER(m_ADTS );
-
-  m_pSyncFrame   = NULL;
-  m_Needed       = 0;
-  m_NeededUsed   = 0;
-  m_SampleRate   = 0;
-
-  m_Codec        = NULL;
-
-  /* make enough room for at-least two audio frames */
-  m_DecodeSize   = 0;
-  m_DecodeBuffer = NULL;
-  m_bSupportsAC3Out = false;
-  m_bSupportsDTSOut = false;
-  m_bSupportsAACOut = false;
-  m_LostSync = false;
-  
-}
-
-CDVDAudioCodecPassthroughFFmpeg::~CDVDAudioCodecPassthroughFFmpeg(void)
-{
-  Dispose();
-}
-
-/*===================== MUXER FUNCTIONS ========================*/
-bool CDVDAudioCodecPassthroughFFmpeg::SetupMuxer(CDVDStreamInfo &hints, CStdString muxerName, Muxer &muxer)
-{
-  CLog::Log(LOGINFO, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Trying to setup %s muxer", muxerName.c_str());
-
-  /* get the muxer */
-  AVOutputFormat *fOut = NULL;
-
-  fOut = m_dllAvFormat.av_guess_format(muxerName.c_str(), NULL, NULL);
-  if (!fOut)
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to get the FFmpeg %s muxer", muxerName.c_str());
-    Dispose();
-    return false;
-  }
-
-  /* allocate a the format context */
-  muxer.m_pFormat = m_dllAvFormat.avformat_alloc_context();
-  if (!muxer.m_pFormat)
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate AVFormat context");
-    Dispose();
-    return false;
-  }
-
-  muxer.m_pFormat->oformat = fOut;
-
-  /* allocate a put_byte struct so we can grab the output */
-  muxer.m_pFormat->pb = m_dllAvFormat.avio_alloc_context(muxer.m_BCBuffer, sizeof(muxer.m_BCBuffer), AVIO_FLAG_READ, &muxer,  NULL, MuxerReadPacket, NULL);
-  if (!muxer.m_pFormat->pb)
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate ByteIOContext");
-    Dispose();
-    return false;
-  }
-
-  /* this is streamed, no file, and ignore the index */
-  muxer.m_pFormat->pb->seekable      = 0;
-  muxer.m_pFormat->flags            |= AVFMT_NOFILE | AVFMT_FLAG_IGNIDX;
-  muxer.m_pFormat->bit_rate          = hints.bitrate;
-
-  /* While this is strictly only needed on big-endian systems, we do it on
-   * both to avoid as much dead code as possible.
-   * CoreAudio (at least on the cases we've seen) wants IEC 61937 in
-   * little-endian format even on big-endian systems. */
-#if defined(WORDS_BIGENDIAN) && !defined(TARGET_DARWIN)
-  const char *spdifFlags = "+be";
-#else
-  const char *spdifFlags = "-be";
-#endif
-
-  /* request output of wanted endianness */
-  if (!fOut->priv_class || m_dllAvUtil.av_opt_set(muxer.m_pFormat->priv_data, "spdif_flags", spdifFlags, 0) != 0)
-  {
-#if defined(WORDS_BIGENDIAN) && !defined(TARGET_DARWIN)
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Unable to set big-endian stream mode (FFmpeg too old?), disabling passthrough");
-    Dispose();
-    return false;
-#endif
-  }
-
-  /* add a stream to it */
-  muxer.m_pStream = m_dllAvFormat.avformat_new_stream(muxer.m_pFormat, NULL);
-  if (!muxer.m_pStream)
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to allocate AVStream context");
-    Dispose();
-    return false;
-  }
-
-
-  /* set the stream's parameters */
-  m_SampleRate = hints.samplerate;
-  if(!m_SampleRate && hints.codec == AV_CODEC_ID_AC3)
-    m_SampleRate = 48000;
-
-  AVCodecContext *codec = muxer.m_pStream->codec;
-  codec->codec_type     = AVMEDIA_TYPE_AUDIO;
-  codec->codec_id       = hints.codec;
-  codec->sample_rate    = m_SampleRate;
-  codec->sample_fmt     = AV_SAMPLE_FMT_S16;
-  codec->channels       = hints.channels;
-  codec->bit_rate       = hints.bitrate;
-  codec->extradata      = new uint8_t[hints.extrasize];
-  codec->extradata_size = hints.extrasize;
-  memcpy(codec->extradata, hints.extradata, hints.extrasize);
-
-  muxer.m_WroteHeader = m_dllAvFormat.avformat_write_header(muxer.m_pFormat, NULL) == 0;
-  if (!muxer.m_WroteHeader)
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - Failed to write the frame header");
-    return false;
-  }
-
-  CLog::Log(LOGINFO, "CDVDAudioCodecPassthroughFFmpeg::SetupMuxer - %s muxer ready", muxerName.c_str());
-  return true;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::MuxerReadPacket(void *opaque, uint8_t *buf, int buf_size)
-{
-  /* create a new packet and push it into our output buffer */
-  DataPacket *packet = new DataPacket();
-  packet->size       = buf_size;
-  packet->data       = new uint8_t[buf_size];
-  memcpy(packet->data, buf, buf_size);
-
-  Muxer *muxer = (Muxer*)opaque;
-  muxer->m_OutputBuffer.push_back(packet);
-  muxer->m_OutputSize += buf_size;
-
-  /* return how much we wrote to our buffer */
-  return buf_size;
-}
-
-void CDVDAudioCodecPassthroughFFmpeg::WriteFrame(Muxer &muxer, uint8_t *pData, int iSize)
-{
-  AVPacket pkt;
-  m_dllAvCodec.av_init_packet(&pkt);
-  pkt.data = pData;
-  pkt.size = iSize;
-
-  muxer.m_Consumed += iSize;
-  if (m_dllAvFormat.av_write_frame(muxer.m_pFormat, &pkt) < 0)
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::WriteFrame - Failed to write the frame data");
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetMuxerData(Muxer &muxer, uint8_t** dst)
-{
-  int size;
-  if(muxer.m_OutputSize)
-  {
-    /* check if the buffer is allocated */
-    if (muxer.m_Buffer)
-    {
-      /* only re-allocate the buffer it is too small */
-      if (muxer.m_BufferSize < muxer.m_OutputSize)
-      {
-        delete[] muxer.m_Buffer;
-        muxer.m_Buffer = new uint8_t[muxer.m_OutputSize];
-        muxer.m_BufferSize = muxer.m_OutputSize;
-      }
-    }
-    else
-    {
-      /* allocate the buffer */
-      muxer.m_Buffer     = new uint8_t[muxer.m_OutputSize];
-      muxer.m_BufferSize = muxer.m_OutputSize;
-    }
-
-    /* fill the buffer with the output data */
-    uint8_t *offset;
-    offset = muxer.m_Buffer;
-    while(!muxer.m_OutputBuffer.empty())
-    {
-      DataPacket* packet = muxer.m_OutputBuffer.front();
-      muxer.m_OutputBuffer.pop_front();
-
-      memcpy(offset, packet->data, packet->size);
-      offset += packet->size;
-
-      delete[] packet->data;
-      delete   packet;
-    }
-
-    *dst = muxer.m_Buffer;
-    size = muxer.m_OutputSize;
-    muxer.m_OutputSize = 0;
-    muxer.m_Consumed = 0;
-    return size;
-  }
-  else
-    return 0;
-}
-
-void CDVDAudioCodecPassthroughFFmpeg::ResetMuxer(Muxer &muxer)
-{
-  muxer.m_OutputSize = 0;
-  muxer.m_Consumed   = 0;
-  while(!muxer.m_OutputBuffer.empty())
-  {
-    DataPacket* packet = muxer.m_OutputBuffer.front();
-    muxer.m_OutputBuffer.pop_front();
-    delete[] packet->data;
-    delete   packet;
-  }
-}
-
-void CDVDAudioCodecPassthroughFFmpeg::DisposeMuxer(Muxer &muxer)
-{
-  ResetMuxer(muxer);
-  delete[] muxer.m_Buffer;
-  muxer.m_Buffer     = NULL;
-  muxer.m_BufferSize = 0;
-  if (muxer.m_pFormat)
-  {
-    if (muxer.m_WroteHeader)
-      m_dllAvFormat.av_write_trailer(muxer.m_pFormat);
-    muxer.m_WroteHeader = false;
-    if (muxer.m_pStream)
-      delete[] muxer.m_pStream->codec->extradata;
-    m_dllAvUtil.av_freep(&muxer.m_pFormat->pb);
-    m_dllAvUtil.av_freep(&muxer.m_pFormat);
-    m_dllAvUtil.av_freep(&muxer.m_pStream);
-  }
-}
-/*===================== END MUXER FUNCTIONS ========================*/
-
-bool CDVDAudioCodecPassthroughFFmpeg::SupportsFormat(CDVDStreamInfo &hints)
-{
-  m_pSyncFrame = NULL;
-
-       if (m_bSupportsAC3Out && hints.codec == AV_CODEC_ID_AC3) m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncAC3;
-  else if (m_bSupportsDTSOut && hints.codec == AV_CODEC_ID_DTS) m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncDTS;
-  else if (m_bSupportsAACOut && hints.codec == AV_CODEC_ID_AAC) m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncAAC;
-  else return false;
-
-  return true;
-}
-
-bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
-{
-  // TODO - move this stuff somewhere else
-  bool m_bSupportsAC3Out    = CAEFactory::SupportsRaw(AE_FMT_AC3);
-  bool m_bSupportsEAC3Out   = CAEFactory::SupportsRaw(AE_FMT_EAC3);
-  bool m_bSupportsDTSOut    = CAEFactory::SupportsRaw(AE_FMT_DTS);
-
-  if ((hints.codec == AV_CODEC_ID_AC3 && !m_bSupportsAC3Out) ||
-      (hints.codec == AV_CODEC_ID_EAC3 && !m_bSupportsEAC3Out) ||
-      (hints.codec == AV_CODEC_ID_DTS && !m_bSupportsDTSOut))
-  {
-    return false;
-  }
-
-  // TODO - this is only valid for video files, and should be moved somewhere else
-  if( hints.channels == 2 && CMediaSettings::Get().GetCurrentVideoSettings().m_OutputToAllSpeakers )
-  {
-    CLog::Log(LOGINFO, "CDVDAudioCodecPassthroughFFmpeg::Open - disabled passthrough due to video OTAS");
-    return false;
-  }
-
-  // TODO - some soundcards do support other sample rates, but they are quite uncommon
-  if( hints.samplerate > 0 && hints.samplerate != 48000 )
-  {
-    CLog::Log(LOGINFO, "CDVDAudioCodecPassthroughFFmpeg::Open - disabled passthrough due to sample rate not being 48000");
-    return false;
-  }
-
-  if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load())
-    return false;
-
-  m_dllAvFormat.av_register_all();
-
-  /* see if the muxer supports our codec (see spdif.c for supported formats) */
-  if (!SupportsFormat(hints))
-  {
-    CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::Open - FFmpeg SPDIF muxer does not support this codec");
-    Dispose();
-    return false;
-  }
-  else
-  {
-    /* aac needs to be wrapped into ADTS frames */
-    if (hints.codec == AV_CODEC_ID_AAC)
-      if (!SetupMuxer(hints, "adts", m_ADTS))
-      {
-        CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::Open - Unable to setup ADTS muxer");
-        Dispose();
-        return false;
-      }
-
-    m_Codec   = NULL;
-  }
-
-  if (!SetupMuxer(hints, "spdif", m_SPDIF))
-    return false;
-
-  Reset();
-
-  /* we will check the first packet's crc */
-  m_LostSync = true;
-
-  m_codec = hints.codec;
-
-  return true;
-}
-
-void CDVDAudioCodecPassthroughFFmpeg::Dispose()
-{
-  Reset();
-
-  DisposeMuxer(m_SPDIF);
-  DisposeMuxer(m_ADTS );
-
-  if (m_DecodeBuffer)
-  {
-    _aligned_free(m_DecodeBuffer);
-    m_DecodeBuffer = NULL;
-  }
-
-  delete m_Codec;
-  m_Codec   = NULL;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::Decode(uint8_t* pData, int iSize)
-{
-  unsigned int used, fSize;
-  fSize = iSize;
-
-  /* if we are muxing into ADTS (AAC) */
-  int adts_used = 0;
-  if (m_ADTS.m_pFormat)
-  {
-    adts_used = iSize;
-    WriteFrame(m_ADTS, pData, iSize);
-    iSize = GetMuxerData(m_ADTS, &pData);
-  }
-
-  used = 0;
-  while(iSize > 0)
-  {
-    /* skip data until we can sync and know how much we need */
-    if (m_Needed == 0)
-    {
-      /* if we have a sync function for this codec */
-      if (m_pSyncFrame)
-      {
-       int skip = (this->*m_pSyncFrame)(pData, iSize, &m_Needed);
-       if (skip > 0)
-       {
-         /* we lost sync, so invalidate our buffer */
-         m_NeededUsed = 0;
-         return used + skip;
-       }
-      }
-      else
-        m_Needed = iSize;
-    }
-
-    if(m_SPDIF.m_pStream->codec->sample_rate != m_SampleRate)
-    {
-     CLog::Log(LOGDEBUG, "CDVDAudioCodecPassthroughFFmpeg::Decode - stream changed sample rate from %d to %d"
-                       , m_SPDIF.m_pStream->codec->sample_rate
-                       , m_SampleRate);
-     m_SPDIF.m_pStream->codec->sample_rate = m_SampleRate;
-    }
-
-    /* check for bad parsing */
-    assert(m_Needed > 0);
-
-    /* append one block or less of data */
-    int copy;
-    int room = sizeof(m_NeededBuffer) - m_NeededUsed;
-    int need = m_Needed - m_NeededUsed;
-    copy = room  > need ? need : room;
-    copy = iSize > copy ? copy : iSize;
-    memcpy(m_NeededBuffer + m_NeededUsed, pData, copy);
-
-    m_NeededUsed += copy;
-    used         += copy;
-    iSize        -= copy;
-    pData        += copy;
-
-    /* if we have enough data in the buffer, write it out */
-    if (m_NeededUsed == m_Needed)
-    {
-      WriteFrame(m_SPDIF, m_NeededBuffer, m_Needed);
-      m_NeededUsed = 0;
-      m_Needed     = 0;
-    }
-  }
-
-  /* return how much data we copied */
-  if (m_ADTS.m_pFormat)
-    return adts_used;
-  else
-    return used;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetData(uint8_t** dst)
-{
-  return GetMuxerData(m_SPDIF, dst);
-}
-
-void CDVDAudioCodecPassthroughFFmpeg::Reset()
-{
-  m_DecodeSize = 0;
-  m_LostSync   = true;
-  m_Needed     = 0;
-  m_NeededUsed = 0;
-
-  ResetMuxer(m_SPDIF);
-  ResetMuxer(m_ADTS );
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetChannels()
-{
-  //Can't return correct channels here as this is used to keep sync.
-  //should probably have some other way to find out this
-  return 2;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetSampleRate()
-{
-  return m_SPDIF.m_pStream->codec->sample_rate;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetEncodedSampleRate()
-{
-  return m_SPDIF.m_pStream->codec->sample_rate;
-}
-
-enum AEDataFormat CDVDAudioCodecPassthroughFFmpeg::GetDataFormat()
-{
-  switch(m_codec)
-  {
-    case AV_CODEC_ID_AC3:      return AE_FMT_AC3;
-    case AV_CODEC_ID_DTS:      return AE_FMT_DTS;
-    default:
-      return AE_FMT_INVALID; //Unknown stream type
-  }
-}
-
-
-int CDVDAudioCodecPassthroughFFmpeg::GetBitsPerSample()
-{
-  return OUT_SAMPLESIZE;
-}
-
-int CDVDAudioCodecPassthroughFFmpeg::GetBufferSize()
-{
-  if (m_Codec)
-    return m_Codec->GetBufferSize();
-  else
-    return m_SPDIF.m_Consumed + m_ADTS.m_Consumed + m_NeededUsed;
-}
-
-/* ========================== SYNC FUNCTIONS ========================== */
-unsigned int CDVDAudioCodecPassthroughFFmpeg::SyncAC3(uint8_t* pData, unsigned int iSize, unsigned int *fSize)
-{
-  unsigned int skip = 0;
-  for(skip = 0; iSize - skip > 6; ++skip, ++pData)
-  {
-    /* search for an ac3 sync word */
-    if(pData[0] != 0x0b || pData[1] != 0x77)
-      continue;
-    uint8_t fscod      = pData[4] >> 6;
-    uint8_t frmsizecod = pData[4] & 0x3F;
-    uint8_t bsid       = pData[5] >> 3;
-
-    /* sanity checks on the header */
-    if (
-        fscod      ==   3 ||
-        frmsizecod >   37 ||
-        bsid       > 0x11
-    ) continue;
-
-    /* get the details we need to check crc1 and framesize */
-    uint16_t     bitrate   = AC3Bitrates[frmsizecod >> 1];
-    unsigned int framesize = 0;
-    switch(fscod)
-    {
-      case 0: framesize = bitrate * 2; break;
-      case 1: framesize = (320 * bitrate / 147 + (frmsizecod & 1 ? 1 : 0)); break;
-      case 2: framesize = bitrate * 4; break;
-    }
-
-    *fSize = framesize * 2;
-    m_SampleRate = AC3FSCod[fscod];
-
-    /* dont do extensive testing if we have not lost sync */
-    if (!m_LostSync && skip == 0)
-      return 0;
-
-    unsigned int crc_size;
-    /* if we have enough data, validate the entire packet, else try to validate crc2 (5/8 of the packet) */
-    if (framesize <= iSize - skip)
-         crc_size = framesize - 1;
-    else crc_size = (framesize >> 1) + (framesize >> 3) - 1;
-
-    if (crc_size <= iSize - skip)
-      if(m_dllAvUtil.av_crc(m_dllAvUtil.av_crc_get_table(AV_CRC_16_ANSI), 0, &pData[2], crc_size * 2))
-        continue;
-
-    /* if we get here, we can sync */
-    m_LostSync = false;
-    return skip;
-  }
-
-  /* if we get here, the entire packet is invalid and we have lost sync */
-  m_LostSync = true;
-  return iSize;
-}
-
-unsigned int CDVDAudioCodecPassthroughFFmpeg::SyncDTS(uint8_t* pData, unsigned int iSize, unsigned int *fSize)
-{
-  unsigned int skip;
-  unsigned int srCode;
-  bool littleEndian;
-
-  for(skip = 0; iSize - skip > 8; ++skip, ++pData)
-  {
-    /* 16bit le */ if (pData[0] == 0x7F && pData[1] == 0xFE && pData[2] == 0x80 && pData[3] == 0x01                                                 ) littleEndian = true ; else
-    /* 14bit le */ if (pData[0] == 0x1F && pData[1] == 0xFF && pData[2] == 0xE8 && pData[3] == 0x00 && pData[4] == 0x07 && (pData[5] & 0xF0) == 0xF0) littleEndian = true ; else
-    /* 16bit be */ if (pData[1] == 0x7F && pData[0] == 0xFE && pData[3] == 0x80 && pData[2] == 0x01                                                 ) littleEndian = false; else
-    /* 14bit be */ if (pData[1] == 0x1F && pData[0] == 0xFF && pData[3] == 0xE8 && pData[2] == 0x00 && pData[5] == 0x07 && (pData[4] & 0xF0) == 0xF0) littleEndian = false; else
-      continue;
-
-    if (littleEndian)
-    {
-      /* if it is not a termination frame, check the next 6 bits are set */
-      if ((pData[4] & 0x80) == 0x80 && (pData[4] & 0x7C) != 0x7C)
-        continue;
-
-      /* get the frame size */
-      *fSize = ((((pData[5] & 0x3) << 8 | pData[6]) << 4) | ((pData[7] & 0xF0) >> 4)) + 1;
-      srCode = (pData[8] & 0x3C) >> 2;
-   }
-   else
-   {
-      /* if it is not a termination frame, check the next 6 bits are set */
-      if ((pData[5] & 0x80) == 0x80 && (pData[5] & 0x7C) != 0x7C)
-        continue;
-
-      /* get the frame size */
-      *fSize = ((((pData[4] & 0x3) << 8 | pData[7]) << 4) | ((pData[6] & 0xF0) >> 4)) + 1;
-      srCode = (pData[9] & 0x3C) >> 2;
-   }
-
-    /* make sure the framesize is sane */
-    if (*fSize < 96 || *fSize > 16384)
-      continue;
-
-    m_SampleRate = DTSFSCod[srCode];
-    m_LostSync = false;
-    return skip;
-  }
-
-  m_LostSync = true;
-  return iSize;
-}
-
-unsigned int CDVDAudioCodecPassthroughFFmpeg::SyncAAC(uint8_t* pData, unsigned int iSize, unsigned int *fSize)
-{
-  unsigned int skip;
-  for(skip = 0; iSize - skip > 5; ++skip, ++pData)
-  {
-    if (pData[0] != 0xFF || (pData[1] & 0xF0) != 0xF0)
-      continue;
-
-    *fSize = (pData[3] & 0x03) << 11 | pData[4] << 3 | (pData[5] & 0xE0) >> 5;
-    if (*fSize < 7)
-      continue;
-
-    m_LostSync = false;
-    return skip;
-  }
-
-  m_LostSync = true;
-  return iSize;
-}
-/* ========================== END SYNC FUNCTIONS ========================== */
-
-
-CAEChannelInfo CDVDAudioCodecPassthroughFFmpeg::GetChannelMap()
-{
-  static enum AEChannel map[2][9] = {
-    {AE_CH_RAW, AE_CH_RAW, AE_CH_NULL},
-    {AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_NULL}
-  };
-
-  return map[0];
-}
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h
deleted file mode 100644 (file)
index 16facb4..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-/*
- *      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/>.
- *
- */
-
-#include <list>
-#include "system.h"
-#include "DllAvFormat.h"
-#include "DllAvCodec.h"
-#include "DllAvUtil.h"
-
-#include "DVDAudioCodec.h"
-
-class CDVDAudioCodecPassthroughFFmpeg : public CDVDAudioCodec
-{
-public:
-  CDVDAudioCodecPassthroughFFmpeg();
-  virtual ~CDVDAudioCodecPassthroughFFmpeg();
-
-  virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
-  virtual void Dispose();
-  virtual int Decode(uint8_t* pData, int iSize);
-  virtual int GetData(uint8_t** dst);
-  virtual void Reset();
-  virtual int GetChannels();
-  virtual CAEChannelInfo GetChannelMap();
-  virtual int  GetSampleRate();
-  virtual int  GetEncodedSampleRate();
-  virtual enum AEDataFormat GetDataFormat();
-  virtual int GetBitsPerSample();
-  virtual bool NeedPassthrough() { return true; }
-  virtual const char* GetName()  { return "PassthroughFFmpeg"; }
-  virtual int GetBufferSize();
-private:
-  DllAvFormat m_dllAvFormat;
-  DllAvUtil   m_dllAvUtil;
-  DllAvCodec  m_dllAvCodec;
-
-  typedef struct
-  {
-    int      size;
-    uint8_t *data;
-  } DataPacket;
-
-  typedef struct
-  {
-    AVFormatContext       *m_pFormat;
-    AVStream              *m_pStream;
-    std::list<DataPacket*> m_OutputBuffer;
-    unsigned int           m_OutputSize;
-    bool                   m_WroteHeader;
-    unsigned char          m_BCBuffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
-    unsigned int           m_Consumed;
-    unsigned int           m_BufferSize;
-    uint8_t               *m_Buffer;
-  } Muxer;
-
-  Muxer      m_SPDIF, m_ADTS;
-  bool       SetupMuxer(CDVDStreamInfo &hints, CStdString muxerName, Muxer &muxer);
-  static int MuxerReadPacket(void *opaque, uint8_t *buf, int buf_size);
-  void       WriteFrame(Muxer &muxer, uint8_t *pData, int iSize);
-  int        GetMuxerData(Muxer &muxer, uint8_t** dst);
-  void       ResetMuxer(Muxer &muxer);
-  void       DisposeMuxer(Muxer &muxer);
-
-  bool m_bSupportsAC3Out;
-  bool m_bSupportsDTSOut;
-  bool m_bSupportsAACOut;
-
-  CDVDAudioCodec   *m_Codec;
-  uint8_t          *m_DecodeBuffer;
-  unsigned int      m_DecodeSize;
-  bool SupportsFormat(CDVDStreamInfo &hints);
-
-  uint8_t      m_NeededBuffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
-  unsigned int m_NeededUsed;
-  unsigned int m_Needed;
-  bool         m_LostSync;
-  int          m_SampleRate;
-  AVCodecID    m_codec;
-
-  unsigned int (CDVDAudioCodecPassthroughFFmpeg::*m_pSyncFrame)(uint8_t* pData, unsigned int iSize, unsigned int *fSize);
-  unsigned int SyncAC3(uint8_t* pData, unsigned int iSize, unsigned int *fSize);
-  unsigned int SyncDTS(uint8_t* pData, unsigned int iSize, unsigned int *fSize);
-  unsigned int SyncAAC(uint8_t* pData, unsigned int iSize, unsigned int *fSize);
-};
-
index f7ca072..1446b96 100644 (file)
@@ -8,10 +8,6 @@ SRCS += DVDAudioCodecLPcm.cpp
 SRCS += DVDAudioCodecPassthrough.cpp
 SRCS += DVDAudioCodecPcm.cpp
 
-ifeq ($(findstring osx,@ARCH@),osx)
-SRCS += DVDAudioCodecPassthroughFFmpeg.cpp
-endif
-
 LIB=Audio.a
 
 include @abs_top_srcdir@/Makefile.include
index 3e105d3..a7445d3 100644 (file)
@@ -51,9 +51,6 @@
 #include "Audio/DVDAudioCodecLibMad.h"
 #include "Audio/DVDAudioCodecPcm.h"
 #include "Audio/DVDAudioCodecLPcm.h"
-#if defined(TARGET_DARWIN_OSX) || defined(TARGET_DARWIN_IOS)
-#include "Audio/DVDAudioCodecPassthroughFFmpeg.h"
-#endif
 #include "Audio/DVDAudioCodecPassthrough.h"
 #include "Overlay/DVDOverlayCodecSSA.h"
 #include "Overlay/DVDOverlayCodecText.h"
@@ -332,18 +329,6 @@ CDVDAudioCodec* CDVDFactoryCodec::CreateAudioCodec( CDVDStreamInfo &hint)
   CDVDCodecOptions options;
 
   // try passthrough first
-#if defined(TARGET_DARWIN_OSX) || defined(TARGET_DARWIN_IOS)
-  switch(hint.codec)
-  {
-    case AV_CODEC_ID_AC3:
-    case AV_CODEC_ID_DTS:
-      pCodec = OpenCodec( new CDVDAudioCodecPassthroughFFmpeg(), hint, options );
-      if( pCodec ) return pCodec;
-      break;
-    default:
-      break;
-  }
-#endif
   pCodec = OpenCodec( new CDVDAudioCodecPassthrough(), hint, options );
   if( pCodec ) return pCodec;
 
index a973389..87ea050 100644 (file)
@@ -24,6 +24,7 @@
 #include "DynamicDll.h"
 
 #include "cores/dvdplayer/DVDClock.h"
+#include "cores/VideoRenderers/RenderFlags.h"
 #include "cores/VideoRenderers/RenderManager.h"
 #include "guilib/GraphicContext.h"
 #include "settings/MediaSettings.h"
@@ -241,6 +242,14 @@ public:
 //-----------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------
 // AppContext - Application state
+#define MODE_3D_DISABLE         0x00000000
+#define MODE_3D_LR              0x00000101
+#define MODE_3D_BT              0x00000201
+#define MODE_3D_TO_2D_L         0x00000102
+#define MODE_3D_TO_2D_R         0x00000902
+#define MODE_3D_TO_2D_T         0x00000202
+#define MODE_3D_TO_2D_B         0x00000a02
+
 #define PTS_FREQ        90000
 #define UNIT_FREQ       96000
 #define AV_SYNC_THRESH  PTS_FREQ*30
@@ -1667,7 +1676,6 @@ void CAMLCodec::CloseDecoder()
   aml_set_sysfs_int("/sys/class/tsync/enable", 1);
 
   ShowMainVideo(false);
-
 }
 
 void CAMLCodec::Reset()
@@ -2053,6 +2061,27 @@ void CAMLCodec::GetRenderFeatures(Features &renderFeatures)
   return;
 }
 
+void CAMLCodec::SetVideo3dMode(const int mode3d)
+{
+  aml_set_sysfs_int("/sys/class/ppmgr/ppmgr_3d_mode", mode3d);
+}
+
+std::string CAMLCodec::GetStereoMode()
+{
+  std::string  stereo_mode;
+
+  switch(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoMode)
+  {
+    case RENDER_STEREO_MODE_SPLIT_VERTICAL:   stereo_mode = "left_right"; break;
+    case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: stereo_mode = "top_bottom"; break;
+    default:                                  stereo_mode = m_hints.stereo_mode; break;
+  }
+
+  if(CMediaSettings::Get().GetCurrentVideoSettings().m_StereoInvert)
+    stereo_mode = RenderManager::GetStereoModeInvert(stereo_mode);
+  return stereo_mode;
+}
+
 void CAMLCodec::RenderFeaturesCallBack(const void *ctx, Features &renderFeatures)
 {
   CAMLCodec *codec = (CAMLCodec*)ctx;
@@ -2065,6 +2094,7 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
   // this routine gets called every video frame
   // and is in the context of the renderer thread so
   // do not do anything stupid here.
+  bool update = false;
 
   // video zoom adjustment.
   float zoom = CMediaSettings::Get().GetCurrentVideoSettings().m_CustomZoomAmount;
@@ -2087,13 +2117,38 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
     m_brightness = brightness;
   }
 
-  // check if destination rect or video view mode has changed
-  if ((m_dst_rect != DestRect) || (m_view_mode != CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode))
+  // video view mode
+  int view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
+  if (m_view_mode != view_mode)
+  {
+    m_view_mode = view_mode;
+    update = true;
+  }
+
+  // video stereo mode/view.
+  RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode();
+  if (m_stereo_mode != stereo_mode)
+  {
+    m_stereo_mode = stereo_mode;
+    update = true;
+  }
+  RENDER_STEREO_VIEW stereo_view = g_graphicsContext.GetStereoView();
+  if (m_stereo_view != stereo_view)
+  {
+    // left/right/top/bottom eye,
+    // this might change every other frame.
+    // we do not care but just track it.
+    m_stereo_view = stereo_view;
+  }
+
+  // dest_rect
+  if (m_dst_rect != DestRect)
   {
     m_dst_rect  = DestRect;
-    m_view_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode;
+    update = true;
   }
-  else
+
+  if (!update)
   {
     // mainvideo 'should' be showing already if we get here, make sure.
     ShowMainVideo(true);
@@ -2117,27 +2172,59 @@ void CAMLCodec::SetVideoRect(const CRect &SrcRect, const CRect &DestRect)
     dst_rect.y2 *= yscale;
   }
 
-  ShowMainVideo(false);
+#if 0
+  std::string rectangle = StringUtils::Format("%i,%i,%i,%i",
+    (int)dst_rect.x1, (int)dst_rect.y1,
+    (int)dst_rect.Width(), (int)dst_rect.Height());
+  CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
+  CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_mode(%d)", m_stereo_mode);
+  CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:m_stereo_view(%d)", m_stereo_view);
+#endif
+
+  if (m_stereo_mode == RENDER_STEREO_MODE_MONO)
+  {
+    std::string mode = GetStereoMode();
+    CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:mode(%s)", mode.c_str());
+    if (mode == "left_right")
+      SetVideo3dMode(MODE_3D_TO_2D_L);
+    else if (mode == "right_left")
+      SetVideo3dMode(MODE_3D_TO_2D_R);
+    else if (mode == "top_bottom")
+      SetVideo3dMode(MODE_3D_TO_2D_T);
+    else if (mode == "bottom_top")
+      SetVideo3dMode(MODE_3D_TO_2D_B);
+    else
+      SetVideo3dMode(MODE_3D_DISABLE);
+  }
+  else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_VERTICAL)
+  {
+    dst_rect.x2 *= 2.0;
+    //SetVideo3dMode(MODE_3D_LR);
+    SetVideo3dMode(MODE_3D_DISABLE);
+  }
+  else if (m_stereo_mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL)
+  {
+    dst_rect.y2 *= 2.0;
+    //SetVideo3dMode(MODE_3D_BT);
+    SetVideo3dMode(MODE_3D_DISABLE);
+  }
+  else
+  {
+    SetVideo3dMode(MODE_3D_DISABLE);
+  }
 
   // goofy 0/1 based difference in aml axis coordinates.
   // fix them.
   dst_rect.x2--;
   dst_rect.y2--;
 
-  char video_axis[256] = {0};
+  char video_axis[256] = {};
   sprintf(video_axis, "%d %d %d %d", (int)dst_rect.x1, (int)dst_rect.y1, (int)dst_rect.x2, (int)dst_rect.y2);
+
   aml_set_sysfs_str("/sys/class/video/axis", video_axis);
   // make sure we are in 'full stretch' so we can stretch
   aml_set_sysfs_int("/sys/class/video/screen_mode", 1);
 
-/*
-  CStdString rectangle;
-  rectangle.Format("%i,%i,%i,%i",
-    (int)dst_rect.x1, (int)dst_rect.y1,
-    (int)dst_rect.Width(), (int)dst_rect.Height());
-  CLog::Log(LOGDEBUG, "CAMLCodec::SetVideoRect:dst_rect(%s)", rectangle.c_str());
-*/
-
   // we only get called once gui has changed to something
   // that would show video playback, so show it.
   ShowMainVideo(true);
index 2a01079..35a5c44 100644 (file)
@@ -23,6 +23,7 @@
 #include "cores/dvdplayer/DVDStreamInfo.h"
 #include "cores/VideoRenderers/RenderFeatures.h"
 #include "guilib/Geometry.h"
+#include "rendering/RenderSystem.h"
 #include "threads/Thread.h"
 
 typedef struct am_private_t am_private_t;
@@ -58,6 +59,8 @@ private:
   void          SetVideoBrightness(const int brightness);
   void          SetVideoSaturation(const int saturation);
   void          GetRenderFeatures(Features &renderFeatures);
+  void          SetVideo3dMode(const int mode3d);
+  std::string   GetStereoMode();
   static void   RenderFeaturesCallBack(const void *ctx, Features &renderFeatures);
   void          SetVideoRect(const CRect &SrcRect, const CRect &DestRect);
   static void   RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect);
@@ -79,6 +82,8 @@ private:
 
   CRect            m_dst_rect;
   int              m_view_mode;
+  RENDER_STEREO_MODE m_stereo_mode;
+  RENDER_STEREO_VIEW m_stereo_view;
   float            m_zoom;
   int              m_contrast;
   int              m_brightness;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.cpp
new file mode 100644 (file)
index 0000000..bf69f0a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *      Copyright (C) 2010-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 "DVDVideoCodec.h"
+#include "windowing/WindowingFactory.h"
+#include "settings/Settings.h"
+
+bool CDVDVideoCodec::IsSettingVisible(const std::string &condition, const std::string &value, const std::string &settingId)
+{
+  if (settingId.empty() || value.empty())
+    return false;
+
+  // check if we are running on nvidia hardware
+  std::string gpuvendor = g_Windowing.GetRenderVendor();
+  std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower);
+  bool isNvidia = (gpuvendor.compare(0, 6, "nvidia") == 0);
+  bool isIntel = (gpuvendor.compare(0, 5, "intel") == 0);
+
+  // nvidia does only need mpeg-4 setting
+  if (isNvidia) 
+  {
+    if (settingId == "videoplayer.usevdpaumpeg4")
+      return true;
+
+    return false; //will also hide intel settings on nvidia hardware
+  }
+  else if (isIntel) // intel needs vc1, mpeg-2 and mpeg4 setting
+  {
+    if (settingId == "videoplayer.usevaapimpeg4")
+      return true;
+    if (settingId == "videoplayer.usevaapivc1")
+      return true;
+    if (settingId == "videoplayer.usevaapimpeg2")
+      return true;
+
+    return false; //this will also hide nvidia settings on intel hardware
+  }
+  // if we don't know the hardware we are running on e.g. amd oss vdpau 
+  // or fglrx with xvba-driver we show everything
+  return true;
+}
+
+bool CDVDVideoCodec::IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id)
+{
+  int index = -1;
+  for (unsigned int i = 0; i < size; ++i)
+  {
+    if(map[i].codec == id)
+    {
+      index = (int) i;
+      break;
+    }
+  }
+  if(index > -1)
+    return (!CSettings::Get().GetBool(map[index].setting) || !CDVDVideoCodec::IsSettingVisible("unused", "unused", map[index].setting));
+
+  return false; //don't disable what we don't have
+}
index b78f779..f6751f4 100644 (file)
  */
 
 #include "system.h"
+#include "DllAvFormat.h"
+#include "DllAvCodec.h"
 
 #include <vector>
+#include <string>
 #include "cores/VideoRenderers/RenderFormats.h"
 
+struct DVDCodecAvailableType 
+{
+  AVCodecID codec;
+  const char* setting;
+};
+
 // when modifying these structures, make sure you update all codecs accordingly
 #define FRAME_TYPE_UNDEF 0
 #define FRAME_TYPE_I 1
@@ -263,4 +272,15 @@ public:
    * be retained when calling decode on the next demux packet
    */
   virtual unsigned GetAllowedReferences() { return 0; }
+
+  /**
+   * Hide or Show Settings depending on the currently running hardware 
+   *
+   */
+   static bool IsSettingVisible(const std::string &condition, const std::string &value, const std::string &settingId);
+
+  /**
+  * Interact with user settings so that user disabled codecs are disabled
+  */
+  static bool IsCodecDisabled(DVDCodecAvailableType* map, unsigned int size, AVCodecID id);
 };
index e0cfb0e..a028d5e 100644 (file)
@@ -105,8 +105,7 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
 #endif
 #ifdef HAVE_LIBVA
     // mpeg4 vaapi decoding is disabled
-    if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi") 
-    && (avctx->codec_id != AV_CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) 
+    if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi"))
     {
       VAAPI::CDecoder* dec = new VAAPI::CDecoder();
       if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
index 02952a2..becd55b 100644 (file)
 #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
   #include "config.h"
 #endif
-
-#if defined(TARGET_DARWIN_IOS)
-#define STATIC_LINK 1
-#endif//TARGET_DARWIN_IOS
-
 extern "C" {
 #if defined(TARGET_WINDOWS)
   #include "libmpeg2/mpeg2.h"
@@ -58,31 +53,6 @@ public:
   virtual void mpeg2_skip(mpeg2dec_t * mpeg2dec, int skip)=0;
 };
 
-#if defined(STATIC_LINK)
-//use direct mapping
-class DllLibMpeg2 : public DllDynamic, DllLibMpeg2Interface
-{
-public:
-  virtual ~DllLibMpeg2() {}
-  virtual uint32_t mpeg2_accel (uint32_t accel) { return ::mpeg2_accel(accel); }
-  virtual mpeg2dec_t * mpeg2_init (void) { return ::mpeg2_init(); }
-  virtual const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec) { return ::mpeg2_info(mpeg2dec); }
-  virtual void mpeg2_close (mpeg2dec_t * mpeg2dec) { ::mpeg2_close(mpeg2dec); }
-  virtual void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end) { ::mpeg2_buffer(mpeg2dec, start, end); }
-  virtual void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2){ ::mpeg2_tag_picture(mpeg2dec, tag, tag2); }
-  virtual mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec) { return ::mpeg2_parse(mpeg2dec); }
-  virtual void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset) { return ::mpeg2_reset(mpeg2dec, full_reset); }
-  virtual void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id) { ::mpeg2_set_buf(mpeg2dec, buf, id); }
-  virtual void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf) { ::mpeg2_custom_fbuf(mpeg2dec, custom_fbuf); }
-  virtual int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg) { return ::mpeg2_convert(mpeg2dec, convert, arg); }
-  virtual void mpeg2_skip(mpeg2dec_t * mpeg2dec, int skip) { ::mpeg2_skip(mpeg2dec, skip); }
-  
-  // DLL faking.
-  virtual bool ResolveExports() { return true; }
-  virtual bool Load() { return true; }
-  virtual void Unload() { }
-};
-#else
 class DllLibMpeg2 : public DllDynamic, DllLibMpeg2Interface
 {
   DECLARE_DLL_WRAPPER(DllLibMpeg2, DLL_PATH_LIBMPEG2)
@@ -113,4 +83,3 @@ class DllLibMpeg2 : public DllDynamic, DllLibMpeg2Interface
     RESOLVE_METHOD(mpeg2_skip)
   END_METHOD_RESOLVE()
 };
-#endif//STATIC_LINK
index fdeb98d..8a97889 100644 (file)
@@ -1,6 +1,7 @@
 INCLUDES+=-I@abs_top_srcdir@/xbmc/cores/dvdplayer
 
-SRCS  = DVDVideoCodecFFmpeg.cpp
+SRCS  = DVDVideoCodec.cpp
+SRCS += DVDVideoCodecFFmpeg.cpp
 SRCS += DVDVideoCodecLibMpeg2.cpp
 SRCS += DVDVideoPPFFmpeg.cpp
 
index 3facfce..bfefc9d 100644 (file)
@@ -20,7 +20,6 @@
 #include "system.h"
 #ifdef HAVE_LIBVA
 #include "windowing/WindowingFactory.h"
-#include "settings/Settings.h"
 #include "VAAPI.h"
 #include "DVDVideoCodec.h"
 #include <boost/scoped_array.hpp>
@@ -52,6 +51,16 @@ using namespace std;
 using namespace boost;
 using namespace VAAPI;
 
+// settings codecs mapping
+DVDCodecAvailableType g_vaapi_available[] = {
+  { AV_CODEC_ID_H263, "videoplayer.usevaapimpeg4" },
+  { AV_CODEC_ID_MPEG4, "videoplayer.usevaapimpeg4" },
+  { AV_CODEC_ID_WMV3, "videoplayer.usevaapivc1" },
+  { AV_CODEC_ID_VC1, "videoplayer.usevaapivc1" },
+  { AV_CODEC_ID_MPEG2VIDEO, "videoplayer.usevaapimpeg2" },
+};
+const size_t settings_count = sizeof(g_vaapi_available) / sizeof(DVDCodecAvailableType);
+
 static int compare_version(int major_l, int minor_l, int micro_l, int major_r, int minor_r, int micro_r)
 {
   if(major_l < major_r) return -1;
@@ -269,6 +278,10 @@ void CDecoder::Close()
 
 bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces)
 {
+  // check if user wants to decode this format with VAAPI
+  if (CDVDVideoCodec::IsCodecDisabled(g_vaapi_available, settings_count, avctx->codec_id))
+    return false;
+
   VAEntrypoint entrypoint = VAEntrypointVLD;
   VAProfile    profile;
 
index 277802f..98183a2 100644 (file)
@@ -42,6 +42,16 @@ using namespace VDPAU;
 
 #define ARSIZE(x) (sizeof(x) / sizeof((x)[0]))
 
+// settings codecs mapping
+DVDCodecAvailableType g_vdpau_available[] = {
+  { AV_CODEC_ID_H263, "videoplayer.usevdpaumpeg4" },
+  { AV_CODEC_ID_MPEG4, "videoplayer.usevdpaumpeg4" },
+  { AV_CODEC_ID_WMV3, "videoplayer.usevdpauvc1" },
+  { AV_CODEC_ID_VC1, "videoplayer.usevdpauvc1" },
+  { AV_CODEC_ID_MPEG2VIDEO, "videoplayer.usevdpaumpeg2" },
+};
+const size_t settings_count = sizeof(g_vdpau_available) / sizeof(DVDCodecAvailableType);
+
 CDecoder::Desc decoder_profiles[] = {
 {"MPEG1",        VDP_DECODER_PROFILE_MPEG1},
 {"MPEG2_SIMPLE", VDP_DECODER_PROFILE_MPEG2_SIMPLE},
@@ -483,8 +493,18 @@ CDecoder::CDecoder() : m_vdpauOutput(&m_inMsgEvent)
   m_vdpauConfig.context = 0;
 }
 
-bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces)
+bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat fmt, unsigned int surfaces)
 {
+  // check if user wants to decode this format with VDPAU
+  std::string gpuvendor = g_Windowing.GetRenderVendor();
+  std::transform(gpuvendor.begin(), gpuvendor.end(), gpuvendor.begin(), ::tolower);
+  // nvidia is whitelisted despite for mpeg-4 we need to query user settings
+  if ((gpuvendor.compare(0, 6, "nvidia") != 0)  || (avctx->codec_id == AV_CODEC_ID_MPEG4) || (avctx->codec_id == AV_CODEC_ID_H263))
+  {
+    if (CDVDVideoCodec::IsCodecDisabled(g_vdpau_available, settings_count, avctx->codec_id))
+      return false;
+  }
+
 #ifndef GL_NV_vdpau_interop
   CLog::Log(LOGNOTICE, "VDPAU: compilation without required extension GL_NV_vdpau_interop");
   return false;
@@ -504,9 +524,6 @@ bool CDecoder::Open(AVCodecContext* avctx, const enum PixelFormat, unsigned int
   m_vdpauConfig.numRenderBuffers = surfaces;
   m_decoderThread = CThread::GetCurrentThreadId();
 
-  if ((avctx->codec_id == AV_CODEC_ID_MPEG4) && !g_advancedSettings.m_videoAllowMpeg4VDPAU)
-    return false;
-
   if (!CVDPAUContext::EnsureContext(&m_vdpauConfig.context))
     return false;
 
index 32b3e6a..1146c6f 100644 (file)
@@ -146,7 +146,7 @@ void ff_avutil_log(void* ptr, int level, const char* format, va_list va)
 
 static void ff_flush_avutil_log_buffers(void)
 {
-  CSingleLock lock(DllAvCodec::m_critSection);
+  CSingleLock lock(m_logSection);
 
   /* Loop through the logbuffer list and remove any blank buffers
      If the thread using the buffer is still active, it will just
index c6674ad..97db5cd 100644 (file)
@@ -51,13 +51,14 @@ bool CDVDInputStreamFFmpeg::IsEOF()
 bool CDVDInputStreamFFmpeg::Open(const char* strFile, const std::string& content)
 {
   CFileItem item(strFile, false);
+  std::string selected;
   if (item.IsInternetStream() && item.IsType(".m3u8"))
   {
     // get the available bandwidth and  determine the most appropriate stream
     int bandwidth = CSettings::Get().GetInt("network.bandwidth");
     if(bandwidth <= 0)
       bandwidth = INT_MAX;
-    std::string selected = PLAYLIST::CPlayListM3U::GetBestBandwidthStream(strFile, bandwidth);
+    selected = PLAYLIST::CPlayListM3U::GetBestBandwidthStream(strFile, bandwidth);
     if (selected.compare(strFile) != 0)
     {
       CLog::Log(LOGINFO, "CDVDInputStreamFFmpeg: Auto-selecting %s based on configured bandwidth.", selected.c_str());
index e8f637c..6f2ed0a 100644 (file)
@@ -231,17 +231,27 @@ private:
   bool original;
   bool preferextsubs;
   bool subson;
+  PredicateSubtitleFilter filter;
 public:
   PredicateSubtitlePriority(std::string& lang)
     : audiolang(lang),
       original(StringUtils::EqualsNoCase(CSettings::Get().GetString("locale.subtitlelanguage"), "original")),
       preferextsubs(CSettings::Get().GetBool("subtitles.preferexternal")),
-      subson(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn)
+      subson(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn),
+      filter(lang)
   {
   };
 
+  bool relevant(const SelectionStream& ss) const
+  {
+    return !filter(ss);
+  }
+
   bool operator()(const SelectionStream& lh, const SelectionStream& rh) const
   {
+    PREDICATE_RETURN(relevant(lh)
+                   , relevant(rh));
+
     PREDICATE_RETURN(lh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream
                    , rh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream);
 
@@ -568,17 +578,9 @@ bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
 #endif
 
     Create();
-    if(!m_ready.WaitMSec(g_advancedSettings.m_videoBusyDialogDelay_ms))
-    {
-      CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
-      if(dialog)
-      {
-        dialog->Show();
-        while(!m_ready.WaitMSec(1))
-          g_windowManager.ProcessRenderLoop(false);
-        dialog->Close();
-      }
-    }
+
+    // wait for the ready event
+    CGUIDialogBusy::WaitOnEvent(m_ready, g_advancedSettings.m_videoBusyDialogDelay_ms, false);
 
     // Playback might have been stopped due to some error
     if (m_bStop || m_bAbortRequest)
@@ -810,34 +812,28 @@ void CDVDPlayer::OpenDefaultStreams(bool reset)
     CloseAudioStream(true);
 
   // enable  or disable subtitles
-  SetSubtitleVisible(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
+  bool visible = CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn;
 
   // open subtitle stream
   SelectionStream as = m_SelectionStreams.Get(STREAM_AUDIO, GetAudioStream());
-  PredicateSubtitleFilter psf(as.language);
-  streams = m_SelectionStreams.RemoveIf(STREAM_SUBTITLE, psf);
   PredicateSubtitlePriority psp(as.language);
-  std::stable_sort(streams.begin(), streams.end(), psp);
+  streams = m_SelectionStreams.Get(STREAM_SUBTITLE, psp);
   valid   = false;
   for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
   {
     if(OpenSubtitleStream(it->id, it->source))
     {
       valid = true;
-      if(it->flags & CDemuxStream::FLAG_FORCED)
-        m_dvdPlayerVideo.EnableSubtitle(true);
+      if(!psp.relevant(*it))
+        visible = false;
+      else if(it->flags & CDemuxStream::FLAG_FORCED)
+        visible = true;
     }
   }
   if(!valid)
-  {
     CloseSubtitleStream(true);
-    if (m_pInputStream && !(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY)))
-    {
-      SetSubtitleVisible(false);
-      if (GetSubtitleCount() > 0 && CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream == -1)
-        CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = 0;
-    }
-  }
+
+  SetSubtitleVisibleInternal(visible);
 
   // open teletext stream
   streams = m_SelectionStreams.Get(STREAM_TELETEXT);
@@ -1026,7 +1022,7 @@ void CDVDPlayer::Process()
   if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
   {
     CLog::Log(LOGNOTICE, "DVDPlayer: playing a file with menu's");
-    if(CDVDInputStreamNavigator* nav = dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
+    if(dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
       m_PlayerOptions.starttime = 0;
 
     if(m_PlayerOptions.state.size() > 0)
@@ -1186,7 +1182,7 @@ void CDVDPlayer::Process()
     UpdateApplication(1000);
 
     // make sure we run subtitle process here
-    m_dvdPlayerSubtitle.Process(m_clock.GetClock() + m_State.time_offset - m_dvdPlayerVideo.GetSubtitleDelay());
+    m_dvdPlayerSubtitle.Process(m_clock.GetClock() + m_State.time_offset - m_dvdPlayerVideo.GetSubtitleDelay(), m_State.time_offset);
 
     if (CheckDelayedChannelEntry())
       continue;
@@ -2258,11 +2254,7 @@ void CDVDPlayer::HandleMessages()
       else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE))
       {
         CDVDMsgBool* pValue = (CDVDMsgBool*)pMsg;
-
-        m_dvdPlayerVideo.EnableSubtitle(pValue->m_value);
-
-        if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
-          static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(pValue->m_value);
+        SetSubtitleVisibleInternal(pValue->m_value);
       }
       else if (pMsg->IsType(CDVDMsg::PLAYER_SET_STATE))
       {
@@ -2843,6 +2835,15 @@ void CDVDPlayer::SetSubtitleVisible(bool bVisible)
   m_messenger.Put(new CDVDMsgBool(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE, bVisible));
 }
 
+void CDVDPlayer::SetSubtitleVisibleInternal(bool bVisible)
+{
+  CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn = bVisible;
+  m_dvdPlayerVideo.EnableSubtitle(bVisible);
+
+  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+    static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(bVisible);
+}
+
 int CDVDPlayer::GetAudioStreamCount()
 {
   return m_SelectionStreams.Count(STREAM_AUDIO);
@@ -3181,14 +3182,14 @@ bool CDVDPlayer::AdaptForcedSubtitles()
         if(OpenSubtitleStream(it->id, it->source))
         {
           valid = true;
-          SetSubtitleVisible(true);
+          SetSubtitleVisibleInternal(true);
         }
       }
     }
     if(!valid)
     {
       CloseSubtitleStream(true);
-      SetSubtitleVisible(false);
+      SetSubtitleVisibleInternal(false);
     }
   }
   return valid;
@@ -3482,7 +3483,7 @@ int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
         int iStream = event->physical_wide;
         bool visible = !(iStream & 0x80);
 
-        SetSubtitleVisible(visible);
+        SetSubtitleVisibleInternal(visible);
 
         if (iStream >= 0)
           m_dvd.iSelectedSPUStream = (iStream & ~0x80);
index dfe679f..e2a836b 100644 (file)
@@ -154,14 +154,6 @@ public:
     return streams;
   }
 
-  template<typename Filter>
-  SelectionStreams RemoveIf(StreamType type, Filter filter)
-  {
-    SelectionStreams streams = Get(type);
-    streams.erase(std::remove_if(streams.begin(), streams.end(), filter), streams.end());
-    return streams;
-  }
-
   void             Clear   (StreamType type, StreamSource source);
   int              Source  (StreamSource source, std::string filename);
 
@@ -301,6 +293,7 @@ protected:
   bool ShowPVRChannelInfo();
 
   int  AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
+  void SetSubtitleVisibleInternal(bool bVisible);
 
   /**
    * one of the DVD_PLAYSPEED defines
index bd04114..f98c000 100644 (file)
@@ -198,7 +198,7 @@ void CDVDPlayerSubtitle::CloseStream(bool flush)
     m_pOverlayContainer->Clear();
 }
 
-void CDVDPlayerSubtitle::Process(double pts)
+void CDVDPlayerSubtitle::Process(double pts, double offset)
 {
   CSingleLock lock(m_section);
 
@@ -220,6 +220,10 @@ void CDVDPlayerSubtitle::Process(double pts)
     // add all overlays which fit the pts
     while(pOverlay)
     {
+      pOverlay->iPTSStartTime -= offset;
+      if(pOverlay->iPTSStopTime != 0.0)
+        pOverlay->iPTSStopTime -= offset;
+
       m_pOverlayContainer->Add(pOverlay);
       pOverlay->Release();
       pOverlay = m_pSubtitleFileParser->Parse(pts);
index 2b9cc2b..44bde74 100644 (file)
@@ -38,7 +38,7 @@ public:
   CDVDPlayerSubtitle(CDVDOverlayContainer* pOverlayContainer);
   ~CDVDPlayerSubtitle();
 
-  void Process(double pts);
+  void Process(double pts, double offset);
   void Flush();
   void FindSubtitles(const char* strFilename);
   int GetSubtitleCount();
index 58f32d1..4fbd3bd 100644 (file)
@@ -275,17 +275,27 @@ private:
   bool original;
   bool preferextsubs;
   bool subson;
+  PredicateSubtitleFilter filter;
 public:
   PredicateSubtitlePriority(std::string& lang)
     : audiolang(lang),
       original(StringUtils::EqualsNoCase(CSettings::Get().GetString("locale.subtitlelanguage"), "original")),
       preferextsubs(CSettings::Get().GetBool("subtitles.preferexternal")),
-      subson(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn)
+      subson(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn),
+      filter(lang)
   {
   };
 
+  bool relevant(const OMXSelectionStream& ss) const
+  {
+    return !filter(ss);
+  }
+
   bool operator()(const OMXSelectionStream& lh, const OMXSelectionStream& rh) const
   {
+    PREDICATE_RETURN(relevant(lh)
+                   , relevant(rh));
+
     PREDICATE_RETURN(lh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream
                    , rh.type_index == CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream);
 
@@ -866,34 +876,28 @@ void COMXPlayer::OpenDefaultStreams(bool reset)
     CloseAudioStream(true);
 
   // enable  or disable subtitles
-  SetSubtitleVisible(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
+  bool visible = CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn;
 
   // open subtitle stream
   OMXSelectionStream as = m_SelectionStreams.Get(STREAM_AUDIO, GetAudioStream());
-  PredicateSubtitleFilter psf(as.language);
-  streams = m_SelectionStreams.RemoveIf(STREAM_SUBTITLE, psf);
   PredicateSubtitlePriority psp(as.language);
-  std::stable_sort(streams.begin(), streams.end(), psp);
+  streams = m_SelectionStreams.Get(STREAM_SUBTITLE, psp);
   valid   = false;
   for(OMXSelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
   {
     if(OpenSubtitleStream(it->id, it->source))
     {
       valid = true;
-      if(it->flags & CDemuxStream::FLAG_FORCED)
-        m_omxPlayerVideo.EnableSubtitle(true);
+      if(!psp.relevant(*it))
+        visible = false;
+      else if(it->flags & CDemuxStream::FLAG_FORCED)
+        visible = true;
     }
   }
   if(!valid)
-  {
     CloseSubtitleStream(true);
-    if (m_pInputStream && !(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY)))
-    {
-      SetSubtitleVisible(false);
-      if (GetSubtitleCount() > 0 && CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream == -1)
-        CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream = 0;
-    }
-  }
+
+  SetSubtitleVisibleInternal(visible);
 
   // open teletext stream
   streams = m_SelectionStreams.Get(STREAM_TELETEXT);
@@ -1376,7 +1380,7 @@ void COMXPlayer::Process()
     UpdateApplication(1000);
 
     // make sure we run subtitle process here
-    m_dvdPlayerSubtitle.Process(m_clock.GetClock() - m_omxPlayerVideo.GetSubtitleDelay());
+    m_dvdPlayerSubtitle.Process(m_clock.GetClock() + m_State.time_offset - m_omxPlayerVideo.GetSubtitleDelay(), m_State.time_offset);
 
     // OMX emergency exit
     if(HasAudio() && m_omxPlayerAudio.BadState())
@@ -2497,11 +2501,7 @@ void COMXPlayer::HandleMessages()
       else if (pMsg->IsType(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE))
       {
         CDVDMsgBool* pValue = (CDVDMsgBool*)pMsg;
-
-        m_omxPlayerVideo.EnableSubtitle(pValue->m_value);
-
-        if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
-          static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(pValue->m_value);
+        SetSubtitleVisibleInternal(pValue->m_value);
       }
       else if (pMsg->IsType(CDVDMsg::PLAYER_SET_STATE))
       {
@@ -3101,6 +3101,15 @@ void COMXPlayer::SetSubtitleVisible(bool bVisible)
   m_messenger.Put(new CDVDMsgBool(CDVDMsg::PLAYER_SET_SUBTITLESTREAM_VISIBLE, bVisible));
 }
 
+void COMXPlayer::SetSubtitleVisibleInternal(bool bVisible)
+{
+  CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn = bVisible;
+  m_omxPlayerVideo.EnableSubtitle(bVisible);
+
+  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+    static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->EnableSubtitleStream(bVisible);
+}
+
 int COMXPlayer::GetAudioStreamCount()
 {
   return m_SelectionStreams.Count(STREAM_AUDIO);
@@ -3441,14 +3450,14 @@ bool COMXPlayer::AdaptForcedSubtitles()
         if(OpenSubtitleStream(it->id, it->source))
         {
           valid = true;
-          SetSubtitleVisible(true);
+          SetSubtitleVisibleInternal(true);
         }
       }
     }
     if(!valid)
     {
       CloseSubtitleStream(true);
-      SetSubtitleVisible(false);
+      SetSubtitleVisibleInternal(false);
     }
   }
   return valid;
@@ -3745,7 +3754,7 @@ int COMXPlayer::OnDVDNavResult(void* pData, int iMessage)
         int iStream = event->physical_wide;
         bool visible = !(iStream & 0x80);
 
-        SetSubtitleVisible(visible);
+        SetSubtitleVisibleInternal(visible);
 
         if (iStream >= 0)
           m_dvd.iSelectedSPUStream = (iStream & ~0x80);
index f34764d..778aa12 100644 (file)
@@ -148,14 +148,6 @@ public:
     return streams;
   }
 
-  template<typename Filter>
-  OMXSelectionStreams RemoveIf(StreamType type, Filter filter)
-  {
-    OMXSelectionStreams streams = Get(type);
-    streams.erase(std::remove_if(streams.begin(), streams.end(), filter), streams.end());
-    return streams;
-  }
-
   void             Clear   (StreamType type, StreamSource source);
   int              Source  (StreamSource source, std::string filename);
 
@@ -306,6 +298,7 @@ protected:
   bool ShowPVRChannelInfo();
 
   int  AddSubtitleFile(const std::string& filename, const std::string& subfilename = "", CDemuxStream::EFlags flags = CDemuxStream::FLAG_NONE);
+  void SetSubtitleVisibleInternal(bool bVisible);
 
   /**
    * one of the DVD_PLAYSPEED defines
index 1deb4c9..1d961db 100644 (file)
@@ -212,6 +212,7 @@ bool CDatabase::CommitMultipleExecute()
       return false;
     }
   }
+  CommitTransaction();
   return true;
 }
 
@@ -327,7 +328,7 @@ bool CDatabase::Open(const DatabaseSettings &settings)
   InitSettings(dbSettings);
 
   CStdString dbName = dbSettings.name;
-  dbName += StringUtils::Format("%d", GetMinVersion());
+  dbName += StringUtils::Format("%d", GetSchemaVersion());
   return Connect(dbName, dbSettings, false);
 }
 
@@ -366,11 +367,11 @@ bool CDatabase::Update(const DatabaseSettings &settings)
   DatabaseSettings dbSettings = settings;
   InitSettings(dbSettings);
 
-  int version = GetMinVersion();
+  int version = GetSchemaVersion();
   CStdString latestDb = dbSettings.name;
   latestDb += StringUtils::Format("%d", version);
 
-  while (version >= 0)
+  while (version >= GetMinSchemaVersion())
   {
     CStdString dbName = dbSettings.name;
     if (version)
@@ -379,9 +380,9 @@ bool CDatabase::Update(const DatabaseSettings &settings)
     if (Connect(dbName, dbSettings, false))
     {
       // Database exists, take a copy for our current version (if needed) and reopen that one
-      if (version < GetMinVersion())
+      if (version < GetSchemaVersion())
       {
-        CLog::Log(LOGNOTICE, "Old database found - updating from version %i to %i", version, GetMinVersion());
+        CLog::Log(LOGNOTICE, "Old database found - updating from version %i to %i", version, GetSchemaVersion());
 
         bool copy_fail = false;
 
@@ -489,7 +490,7 @@ bool CDatabase::Connect(const CStdString &dbName, const DatabaseSettings &dbSett
         //  Also set the memory cache size to 16k
         m_pDS->exec("PRAGMA default_cache_size=4096\n");
       }
-      CreateTables();
+      CreateDatabase();
     }
 
     // sqlite3 post connection operations
@@ -523,32 +524,39 @@ int CDatabase::GetDBVersion()
 bool CDatabase::UpdateVersion(const CStdString &dbName)
 {
   int version = GetDBVersion();
-  if (version < GetMinVersion())
+  if (version < GetMinSchemaVersion())
   {
-    CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, GetMinVersion());
-    bool success = false;
+    CLog::Log(LOGERROR, "Can't update database %s from version %i - it's too old", dbName.c_str(), version);
+    return false;
+  }
+  else if (version < GetSchemaVersion())
+  {
+    CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion());
+    bool success = true;
     BeginTransaction();
     try
     {
-      success = UpdateOldVersion(version);
-      if (success)
-        success = UpdateVersionNumber();
+      // drop old analytics, update table(s), recreate analytics, update version
+      m_pDB->drop_analytics();
+      UpdateTables(version);
+      CreateAnalytics();
+      UpdateVersionNumber();
     }
     catch (...)
     {
-      CLog::Log(LOGERROR, "Exception updating database %s from version %i to %i", dbName.c_str(), version, GetMinVersion());
+      CLog::Log(LOGERROR, "Exception updating database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion());
       success = false;
     }
     if (!success)
     {
-      CLog::Log(LOGERROR, "Error updating database %s from version %i to %i", dbName.c_str(), version, GetMinVersion());
+      CLog::Log(LOGERROR, "Error updating database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion());
       RollbackTransaction();
       return false;
     }
     CommitTransaction();
-    CLog::Log(LOGINFO, "Update to version %i successful", GetMinVersion());
+    CLog::Log(LOGINFO, "Update to version %i successful", GetSchemaVersion());
   }
-  else if (version > GetMinVersion())
+  else if (version > GetSchemaVersion())
   {
     CLog::Log(LOGERROR, "Can't open the database %s as it is a NEWER version than what we were expecting?", dbName.c_str());
     return false;
@@ -673,22 +681,33 @@ bool CDatabase::InTransaction()
   return m_pDB->in_transaction();
 }
 
-bool CDatabase::CreateTables()
+bool CDatabase::CreateDatabase()
 {
-
+  BeginTransaction();
+  try
+  {
     CLog::Log(LOGINFO, "creating version table");
     m_pDS->exec("CREATE TABLE version (idVersion integer, iCompressCount integer)\n");
-    CStdString strSQL=PrepareSQL("INSERT INTO version (idVersion,iCompressCount) values(%i,0)\n", GetMinVersion());
+    CStdString strSQL=PrepareSQL("INSERT INTO version (idVersion,iCompressCount) values(%i,0)\n", GetSchemaVersion());
     m_pDS->exec(strSQL.c_str());
 
-    return true;
+    CreateTables();
+    CreateAnalytics();
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR, "%s unable to create database:%i", __FUNCTION__, (int)GetLastError());
+    RollbackTransaction();
+    return false;
+  }
+  CommitTransaction();
+  return true;
 }
 
-bool CDatabase::UpdateVersionNumber()
+void CDatabase::UpdateVersionNumber()
 {
-  CStdString strSQL=PrepareSQL("UPDATE version SET idVersion=%i\n", GetMinVersion());
+  CStdString strSQL=PrepareSQL("UPDATE version SET idVersion=%i\n", GetSchemaVersion());
   m_pDS->exec(strSQL.c_str());
-  return true;
 }
 
 bool CDatabase::BuildSQL(const CStdString &strQuery, const Filter &filter, CStdString &strSQL)
index a270f08..395599d 100644 (file)
@@ -169,11 +169,35 @@ protected:
   uint32_t ComputeCRC(const CStdString &text);
 
   virtual bool Open();
-  virtual bool CreateTables();
-  virtual void CreateViews() {};
-  virtual bool UpdateOldVersion(int version) { return true; };
 
-  virtual int GetMinVersion() const=0;
+  /*! \brief Create database tables and analytics as needed.
+   Calls CreateTables() and CreateAnalytics() on child classes.
+   */
+  bool CreateDatabase();
+
+  /* \brief Create tables for the current database schema.
+   Will be called on database creation.
+   */
+  virtual void CreateTables()=0;
+
+  /* \brief Create views, indices and triggers for the current database schema.
+   Will be called on database creation and database update.
+   */
+  virtual void CreateAnalytics()=0;
+
+  /* \brief Update database tables to the current version.
+   Note that analytics (views, indices, triggers) are not present during this
+   function, so don't rely on them.
+   */
+  virtual void UpdateTables(int version) {};
+
+  /* \brief The minimum schema version that we support updating from.
+   */
+  virtual int GetMinSchemaVersion() const { return 0; };
+
+  /* \brief The current schema version.
+   */
+  virtual int GetSchemaVersion() const=0;
   virtual const char *GetBaseDBName() const=0;
 
   int GetDBVersion();
@@ -190,7 +214,7 @@ protected:
 private:
   void InitSettings(DatabaseSettings &dbSettings);
   bool Connect(const CStdString &dbName, const DatabaseSettings &db, bool create);
-  bool UpdateVersionNumber();
+  void UpdateVersionNumber();
 
   bool m_bMultiWrite; /*!< True if there are any queries in the queue, false otherwise */
   unsigned int m_openCount;
index 96e8d2c..e208aa5 100644 (file)
@@ -138,6 +138,9 @@ public:
 /* \brief copy database */
   virtual int copy(const char *new_name) { return -1; }
 
+/* \brief drop all extra analytics from database */
+  virtual int drop_analytics(void) { return -1; }
+
   virtual bool exists(void) { return false; }
 
 /* virtual methods for transaction */
index 523e621..c186fdf 100644 (file)
@@ -279,35 +279,103 @@ int MysqlDatabase::copy(const char *backup_name) {
       if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
       {
         mysql_free_result(res);
-        throw DbErrors("Can't copy data for table '%s'\nError: %s", row[0], ret);
+        throw DbErrors("Can't copy data for table '%s'\nError: %d", row[0], ret);
       }
     }
     mysql_free_result(res);
 
-    // after table are recreated and repopulated we can recreate views
-    // grab a list of views and their definitions
-    sprintf(sql, "SELECT TABLE_NAME, VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%s'", db.c_str());
-    if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
-      throw DbErrors("Can't determine views to recreate.");
+    // we don't recreate views, indicies, or triggers on copy
+    // as we'll be dropping and recreating them anyway
+  }
+
+  return 1;
+}
 
-    // get list of all views from old DB
-    MYSQL_RES* resViews = mysql_store_result(conn);
+int MysqlDatabase::drop_analytics(void) {
+  if ( !active || conn == NULL)
+    throw DbErrors("Can't clean database: no active connection...");
 
-    if (resViews)
+  char sql[4096];
+  int ret;
+
+  // ensure we're connected to the db we are about to clean from stuff
+  if ( (ret=mysql_select_db(conn, db.c_str())) != MYSQL_OK )
+    throw DbErrors("Can't connect to database: '%s'",db.c_str());
+
+  // getting a list of indexes in the database
+  sprintf(sql, "SELECT DISTINCT table_name, index_name"
+          "  FROM information_schema.statistics"
+          " WHERE index_name != 'PRIMARY' AND"
+          "       table_schema = '%s'", db.c_str());
+  if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
+    throw DbErrors("Can't determine list of indexes to drop.");
+
+  // we will acquire lists here
+  MYSQL_RES* res = mysql_store_result(conn);
+  MYSQL_ROW row;
+
+  if (res)
+  {
+    while ( (row=mysql_fetch_row(res)) != NULL )
     {
-      while ( (row=mysql_fetch_row(resViews)) != NULL )
+      sprintf(sql, "ALTER TABLE %s.%s DROP INDEX %s", db.c_str(), row[0], row[1]);
+
+      if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
       {
-        sprintf(sql, "CREATE VIEW %s.%s AS %s",
-                backup_name, row[0], row[1]);
+        mysql_free_result(res);
+        throw DbErrors("Can't drop index '%s'\nError: %d", row[0], ret);
+      }
+    }
+    mysql_free_result(res);
+  }
 
-        if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
-        {
-          mysql_free_result(resViews);
-          throw DbErrors("Can't create view '%s'\nError: %s", db.c_str(), ret);
-        }
+  // next topic is a views list
+  sprintf(sql, "SELECT table_name"
+          "  FROM information_schema.views"
+          " WHERE table_schema = '%s'", db.c_str());
+  if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
+    throw DbErrors("Can't determine list of views to drop.");
+
+  res = mysql_store_result(conn);
+
+  if (res)
+  {
+    while ( (row=mysql_fetch_row(res)) != NULL )
+    {
+      /* we do not need IF EXISTS because these views are exist */
+      sprintf(sql, "DROP VIEW %s.%s", db.c_str(), row[0]);
+
+      if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
+      {
+        mysql_free_result(res);
+        throw DbErrors("Can't drop view '%s'\nError: %d", row[0], ret);
       }
-      mysql_free_result(resViews);
     }
+    mysql_free_result(res);
+  }
+
+  // triggers
+  sprintf(sql, "SELECT trigger_name"
+          "  FROM information_schema.triggers"
+          " WHERE event_object_schema = '%s'", db.c_str());
+  if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
+    throw DbErrors("Can't determine list of triggers to drop.");
+
+  res = mysql_store_result(conn);
+
+  if (res)
+  {
+    while ( (row=mysql_fetch_row(res)) != NULL )
+    {
+      sprintf(sql, "DROP TRIGGER %s.%s", db.c_str(), row[0]);
+
+      if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
+      {
+        mysql_free_result(res);
+        throw DbErrors("Can't create trigger '%s'\nError: %s", row[0], ret);
+      }
+    }
+    mysql_free_result(res);
   }
 
   return 1;
index aa7f106..fb87b3f 100644 (file)
@@ -69,6 +69,9 @@ public:
 /* \brief copy database */
   virtual int copy(const char *backup_name);
 
+/* \brief drop all extra analytics from database */
+  virtual int drop_analytics(void);
+
   virtual long nextid(const char* seq_name);
 
 /* virtual methods for transaction */
index 1bbd099..1e2dc71 100644 (file)
@@ -81,17 +81,17 @@ int callback(void* res_ptr,int ncol, char** reslt,char** cols)
 
 static int busy_callback(void*, int busyCount)
 {
-       Sleep(100);
-       OutputDebugString("SQLite collision\n");
-       return 1;
+  Sleep(100);
+  OutputDebugString("SQLite collision\n");
+  return 1;
 }
 
 //************* SqliteDatabase implementation ***************
 
 SqliteDatabase::SqliteDatabase() {
 
-  active = false;      
-  _in_transaction = false;             // for transaction
+  active = false;  
+  _in_transaction = false;    // for transaction
 
   error = "Unknown database error";//S_NO_CONNECTION;
   host = "localhost";
@@ -107,7 +107,7 @@ SqliteDatabase::~SqliteDatabase() {
 
 
 Dataset* SqliteDatabase::CreateDataset() const {
-       return new SqliteDataset((SqliteDatabase*)this); 
+  return new SqliteDataset((SqliteDatabase*)this); 
 }
 
 void SqliteDatabase::setHostName(const char *newHost) {
@@ -313,6 +313,48 @@ int SqliteDatabase::copy(const char *backup_name) {
   return rc;
 }
 
+int SqliteDatabase::drop_analytics(void) {
+  // SqliteDatabase::copy used a full database copy, so we have a new version
+  // with all the analytics stuff. We should clean database from everything but data
+  if (active == false)
+    throw DbErrors("Can't drop extras database: no active connection...");
+
+  char sqlcmd[4096];
+  result_set res;
+
+  CLog::Log(LOGDEBUG, "Cleaning indexes from database %s at %s", db.c_str(), host.c_str());
+  sprintf(sqlcmd, "SELECT name FROM sqlite_master WHERE type == 'index'");
+  if ((last_err = sqlite3_exec(conn, sqlcmd, &callback, &res, NULL)) != SQLITE_OK) return DB_UNEXPECTED_RESULT;
+
+  for (size_t i=0; i < res.records.size(); i++) {
+    sprintf(sqlcmd,"DROP INDEX '%s'", res.records[i]->at(0).get_asString().c_str());
+    if ((last_err = sqlite3_exec(conn, sqlcmd, NULL, NULL, NULL) != SQLITE_OK)) return DB_UNEXPECTED_RESULT;
+  }
+  res.clear();
+
+  CLog::Log(LOGDEBUG, "Cleaning views from database %s at %s", db.c_str(), host.c_str());
+  sprintf(sqlcmd, "SELECT name FROM sqlite_master WHERE type == 'view'");
+  if ((last_err = sqlite3_exec(conn, sqlcmd, &callback, &res, NULL)) != SQLITE_OK) return DB_UNEXPECTED_RESULT;
+
+  for (size_t i=0; i < res.records.size(); i++) {
+    sprintf(sqlcmd,"DROP VIEW '%s'", res.records[i]->at(0).get_asString().c_str());
+    if ((last_err = sqlite3_exec(conn, sqlcmd, NULL, NULL, NULL) != SQLITE_OK)) return DB_UNEXPECTED_RESULT;
+  }
+  res.clear();
+
+  CLog::Log(LOGDEBUG, "Cleaning triggers from database %s at %s", db.c_str(), host.c_str());
+  sprintf(sqlcmd, "SELECT name FROM sqlite_master WHERE type == 'trigger'");
+  if ((last_err = sqlite3_exec(conn, sqlcmd, &callback, &res, NULL)) != SQLITE_OK) return DB_UNEXPECTED_RESULT;
+
+  for (size_t i=0; i < res.records.size(); i++) {
+    sprintf(sqlcmd,"DROP TRIGGER '%s'", res.records[i]->at(0).get_asString().c_str());
+    if ((last_err = sqlite3_exec(conn, sqlcmd, NULL, NULL, NULL) != SQLITE_OK)) return DB_UNEXPECTED_RESULT;
+  }
+  // res would be cleared on destruct
+
+  return DB_COMMAND_OK;
+}
+
 int SqliteDatabase::drop() {
   if (active == false) throw DbErrors("Can't drop database: no active connection...");
   disconnect();
@@ -451,19 +493,19 @@ void SqliteDataset::make_query(StringList &_sql) {
 
 
   for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); i++) {
-       query = *i;
-       char* err=NULL; 
-       Dataset::parse_sql(query);
-       if (db->setErr(sqlite3_exec(this->handle(),query.c_str(),NULL,NULL,&err),query.c_str())!=SQLITE_OK) {
-         throw DbErrors(db->getErrorMsg());
-       }
+  query = *i;
+  char* err=NULL; 
+  Dataset::parse_sql(query);
+  if (db->setErr(sqlite3_exec(this->handle(),query.c_str(),NULL,NULL,&err),query.c_str())!=SQLITE_OK) {
+    throw DbErrors(db->getErrorMsg());
+  }
   } // end of for
 
 
   if (db->in_transaction() && autocommit) db->commit_transaction();
 
   active = true;
-  ds_state = dsSelect;         
+  ds_state = dsSelect;    
   if (autorefresh)
     refresh();
 
@@ -588,7 +630,7 @@ int SqliteDataset::exec(const string &sql) {
 }
 
 int SqliteDataset::exec() {
-       return exec(sql);
+  return exec(sql);
 }
 
 const void* SqliteDataset::getExecRes() {
@@ -665,8 +707,8 @@ bool SqliteDataset::query(const string &q){
 }
 
 void SqliteDataset::open(const string &sql) {
-       set_select_sql(sql);
-       open();
+  set_select_sql(sql);
+  open();
 }
 
 void SqliteDataset::open() {
@@ -752,7 +794,7 @@ bool SqliteDataset::seek(int pos) {
   if (ds_state == dsSelect) {
     Dataset::seek(pos);
     fill_fields();
-    return true;       
+    return true;  
     }
   return false;
 }
index 921360f..6b768f0 100644 (file)
@@ -81,6 +81,9 @@ public:
 /* \brief copy database */
   virtual int copy(const char *backup_name);
 
+/* \brief drop all extra analytics from database */
+  virtual int drop_analytics(void);
+
   virtual long nextid(const char* seq_name);
 
 /* virtual methods for transaction */
index 79dba07..e9ba7d3 100644 (file)
 #include "GUIDialogBusy.h"
 #include "guilib/GUIProgressControl.h"
 #include "guilib/GUIWindowManager.h"
+#include "threads/Thread.h"
 
 #define PROGRESS_CONTROL 10
 
+class CBusyWaiter : public CThread
+{
+public:
+  CBusyWaiter(IRunnable *runnable) : CThread(runnable, "waiting")
+  {
+  }
+  
+  bool Wait()
+  {
+    Create();
+    return CGUIDialogBusy::WaitOnEvent(m_done);
+  }
+  
+  virtual void Process()
+  {
+    CThread::Process();
+    m_done.Set();
+  }
+  CEvent  m_done;
+};
+
+bool CGUIDialogBusy::Wait(IRunnable *runnable)
+{
+  if (!runnable)
+    return false;
+  CBusyWaiter waiter(runnable);
+  return waiter.Wait();
+}
+
+bool CGUIDialogBusy::WaitOnEvent(CEvent &event, unsigned int displaytime /* = 100 */, bool allowCancel /* = true */)
+{
+  bool cancelled = false;
+  if (!event.WaitMSec(displaytime))
+  {
+    // throw up the progress
+    CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
+    if (dialog)
+    {
+      dialog->Show();
+      while(!event.WaitMSec(1))
+      {
+        g_windowManager.ProcessRenderLoop(false);
+        if (allowCancel && dialog->IsCanceled())
+        {
+          cancelled = true;
+          break;
+        }
+      }
+      dialog->Close();
+    }
+  }
+  return !cancelled;
+}
+
 CGUIDialogBusy::CGUIDialogBusy(void)
   : CGUIDialog(WINDOW_DIALOG_BUSY, "DialogBusy.xml"), m_bLastVisible(false)
 {
index d839a24..0efc2a5 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "guilib/GUIDialog.h"
 
+class IRunnable;
+class CEvent;
 
 class CGUIDialogBusy: public CGUIDialog
 {
@@ -37,6 +39,23 @@ public:
   void SetProgress(float progress);
 
   bool IsCanceled() { return m_bCanceled; }
+
+  /*! \brief Wait for a runnable to execute off-thread.
+   Creates a thread to run the given runnable, and while waiting
+   it displays the busy dialog.
+   \param runnable the IRunnable to run.
+   \return true if the runnable completes, false if the user cancels early.
+   */
+  static bool Wait(IRunnable *runnable);
+
+  /*! \brief Wait on an event while displaying the busy dialog.
+   Throws up the busy dialog after the given time.
+   \param even the CEvent to wait on.
+   \param displaytime the time in ms to wait prior to showing the busy dialog (defaults to 100ms)
+   \param allowCancel whether the user can cancel the wait, defaults to true.
+   \return true if the event completed, false if cancelled.
+   */
+  static bool WaitOnEvent(CEvent &event, unsigned int timeout = 100, bool allowCancel = true);
 protected:
   virtual void Show_Internal(); // modeless'ish
   bool m_bCanceled;
index 91699a0..e514649 100644 (file)
@@ -37,116 +37,62 @@ bool CEpgDatabase::Open(void)
   return CDatabase::Open(g_advancedSettings.m_databaseEpg);
 }
 
-bool CEpgDatabase::CreateTables(void)
+void CEpgDatabase::CreateTables(void)
 {
-  bool bReturn(false);
-
-  try
-  {
-    CDatabase::CreateTables();
-
-    BeginTransaction();
-
-    CLog::Log(LOGINFO, "EpgDB - %s - creating tables", __FUNCTION__);
-
-    CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE epg ("
-          "idEpg           integer primary key, "
-          "sName           varchar(64),"
-          "sScraperName    varchar(32)"
-        ")"
-    );
-
-    CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE epgtags ("
-          "idBroadcast     integer primary key, "
-          "iBroadcastUid   integer, "
-          "idEpg           integer, "
-          "sTitle          varchar(128), "
-          "sPlotOutline    text, "
-          "sPlot           text, "
-          "iStartTime      integer, "
-          "iEndTime        integer, "
-          "iGenreType      integer, "
-          "iGenreSubType   integer, "
-          "sGenre          varchar(128), "
-          "iFirstAired     integer, "
-          "iParentalRating integer, "
-          "iStarRating     integer, "
-          "bNotify         bool, "
-          "iSeriesId       integer, "
-          "iEpisodeId      integer, "
-          "iEpisodePart    integer, "
-          "sEpisodeName    varchar(128)"
-        ")"
-    );
-    m_pDS->exec("CREATE UNIQUE INDEX idx_epg_idEpg_iStartTime on epgtags(idEpg, iStartTime desc);");
-    m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);");
-
-    CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__);
-    m_pDS->exec("CREATE TABLE lastepgscan ("
-          "idEpg integer primary key, "
-          "sLastScan varchar(20)"
-        ")"
-    );
-
-    CommitTransaction();
-
-    bReturn = true;
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "EpgDB - %s - unable to create EPG tables:%i",
-        __FUNCTION__, (int)GetLastError());
-    RollbackTransaction();
-    bReturn = false;
-  }
-
-  return bReturn;
+  CLog::Log(LOGINFO, "EpgDB - %s - creating tables", __FUNCTION__);
+
+  CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE epg ("
+        "idEpg           integer primary key, "
+        "sName           varchar(64),"
+        "sScraperName    varchar(32)"
+      ")"
+  );
+
+  CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE epgtags ("
+        "idBroadcast     integer primary key, "
+        "iBroadcastUid   integer, "
+        "idEpg           integer, "
+        "sTitle          varchar(128), "
+        "sPlotOutline    text, "
+        "sPlot           text, "
+        "iStartTime      integer, "
+        "iEndTime        integer, "
+        "iGenreType      integer, "
+        "iGenreSubType   integer, "
+        "sGenre          varchar(128), "
+        "iFirstAired     integer, "
+        "iParentalRating integer, "
+        "iStarRating     integer, "
+        "bNotify         bool, "
+        "iSeriesId       integer, "
+        "iEpisodeId      integer, "
+        "iEpisodePart    integer, "
+        "sEpisodeName    varchar(128)"
+      ")"
+  );
+  CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__);
+  m_pDS->exec("CREATE TABLE lastepgscan ("
+        "idEpg integer primary key, "
+        "sLastScan varchar(20)"
+      ")"
+  );
 }
 
-bool CEpgDatabase::UpdateOldVersion(int iVersion)
+void CEpgDatabase::CreateAnalytics()
 {
-  bool bReturn = true;
-
-  if (iVersion < 4)
-  {
-    CLog::Log(LOGERROR, "EpgDB - %s - updating from table versions < 4 not supported. please delete '%s'", __FUNCTION__, GetBaseDBName());
-    return false;
-  }
-
-  BeginTransaction();
-
-  try
-  {
-    if (iVersion < 5)
-      m_pDS->exec("ALTER TABLE epgtags ADD sGenre varchar(128);");
-    if (iVersion < 6)
-    {
-      m_pDS->exec("DROP INDEX idx_epg_iBroadcastUid;");
-      m_pDS->exec("DROP INDEX idx_epg_idEpg;");
-      m_pDS->exec("DROP INDEX idx_epg_iStartTime;");
-      m_pDS->exec("DROP INDEX idx_epg_iEndTime;");
-    }
-    if (iVersion < 7)
-    {
-      m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);");
-    }
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "Error attempting to update the database version!");
-    bReturn = false;
-  }
-
-  if (bReturn)
-    CommitTransaction();
-  else
-    RollbackTransaction();
+  CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__);
+  m_pDS->exec("CREATE UNIQUE INDEX idx_epg_idEpg_iStartTime on epgtags(idEpg, iStartTime desc);");
+  m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);");
+}
 
-  return bReturn;
+void CEpgDatabase::UpdateTables(int iVersion)
+{
+  if (iVersion < 5)
+    m_pDS->exec("ALTER TABLE epgtags ADD sGenre varchar(128);");
 }
 
 bool CEpgDatabase::DeleteEpg(void)
index e8a428b..774dac8 100644 (file)
@@ -53,7 +53,7 @@ namespace EPG
      * @brief Get the minimal database version that is required to operate correctly.
      * @return The minimal database version.
      */
-    virtual int GetMinVersion(void) const { return 7; };
+    virtual int GetSchemaVersion(void) const { return 7; };
 
     /*!
      * @brief Get the default sqlite database filename.
@@ -148,15 +148,19 @@ namespace EPG
   protected:
     /*!
      * @brief Create the EPG database tables.
-     * @return True if the tables were created successfully, false otherwise.
      */
-    virtual bool CreateTables(void);
+    virtual void CreateTables();
+
+    /*!
+     * @brief Create the EPG database analytics.
+     */
+    virtual void CreateAnalytics();
 
     /*!
      * @brief Update an old version of the database.
      * @param version The version to update the database from.
-     * @return True if it was updated successfully, false otherwise.
      */
-    virtual bool UpdateOldVersion(int version);
+    virtual void UpdateTables(int version);
+    virtual int GetMinSchemaVersion() const { return 4; }
   };
 }
index efb994a..71a7175 100644 (file)
@@ -58,6 +58,7 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
 
   VECADDONS addons;
   // get info from repository
+  bool groupAddons = true;
   bool reposAsFolders = true;
   if (path.GetHostName().Equals("enabled"))
   {
@@ -68,6 +69,7 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
   else if (path.GetHostName().Equals("disabled"))
   { // grab all disabled addons, including disabled repositories
     reposAsFolders = false;
+    groupAddons = false;
     CAddonMgr::Get().GetAllAddons(addons, false, true);
     items.SetProperty("reponame",g_localizeStrings.Get(24039));
     items.SetLabel(g_localizeStrings.Get(24039));
@@ -75,12 +77,14 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
   else if (path.GetHostName().Equals("outdated"))
   {
     reposAsFolders = false;
+    groupAddons = false;
     CAddonMgr::Get().GetAllOutdatedAddons(addons);
     items.SetProperty("reponame",g_localizeStrings.Get(24043));
     items.SetLabel(g_localizeStrings.Get(24043));
   }
   else if (path.GetHostName().Equals("repos"))
   {
+    groupAddons = false;
     CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
     items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons
   }
@@ -133,7 +137,7 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
 
   if (path.GetFileName().empty())
   {
-    if (!path.GetHostName().Equals("repos"))
+    if (groupAddons)
     {
       for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
       {
@@ -196,6 +200,13 @@ bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &it
     item->SetLabel(g_localizeStrings.Get(24032));
     items.Add(item);
   }
+  else if (path.GetHostName().Equals("outdated") && items.Size() > 1)
+  {
+    CFileItemPtr item(new CFileItem("addons://update_all/", true));
+    item->SetLabel(g_localizeStrings.Get(24122));
+    item->SetSpecialSort(SortSpecialOnTop);
+    items.Add(item);
+  }
 
   return true;
 }
index 471ed2b..62c8ce2 100644 (file)
 
 #include <assert.h>
 
+#ifdef HAVE_OPENSSL
+#include "threads/Thread.h"
+#include "openssl/crypto.h"
+
+static CCriticalSection** m_sslLockArray = NULL;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void ssl_lock_callback(int mode, int type, char *file, int line)
+{
+  if (!m_sslLockArray)
+    return;
+
+  if (mode & CRYPTO_LOCK)
+    m_sslLockArray[type]->lock();
+  else
+    m_sslLockArray[type]->unlock();
+}
+
+unsigned long ssl_thread_id(void)
+{
+  return (unsigned long)CThread::GetCurrentThreadId();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HAVE_OPENSSL
+
 using namespace XCURL;
 
 /* okey this is damn ugly. our dll loader doesn't allow for postload, preunload functions */
@@ -59,6 +92,16 @@ bool DllLibCurlGlobal::Load()
   /* check idle will clean up the last one */
   g_curlReferences = 2;
 
+#if defined(HAS_CURL_STATIC)
+  // Initialize ssl locking array
+  m_sslLockArray = new CCriticalSection*[CRYPTO_num_locks()];
+  for (int i=0; i<CRYPTO_num_locks(); i++)
+    m_sslLockArray[i] = new CCriticalSection;  
+  crypto_set_id_callback((unsigned long (*)())ssl_thread_id);
+  crypto_set_locking_callback((void (*)(int, int, const char*, int))ssl_lock_callback);
+#endif
+
   return true;
 }
 
@@ -73,6 +116,16 @@ void DllLibCurlGlobal::Unload()
     // close libcurl
     global_cleanup();
 
+#if defined(HAS_CURL_STATIC)
+    // Cleanup ssl locking array
+    crypto_set_id_callback(NULL);
+    crypto_set_locking_callback(NULL);
+    for (int i=0; i<CRYPTO_num_locks(); i++)
+      delete m_sslLockArray[i];
+    delete[] m_sslLockArray;
+#endif
+    
     DllDynamic::Unload();
   }
 
index e169054..05c3cff 100644 (file)
@@ -79,6 +79,10 @@ namespace XCURL
     DEFINE_METHOD2(struct curl_slist*, slist_append, (struct curl_slist * p1, const char * p2))
     DEFINE_METHOD1(void, slist_free_all, (struct curl_slist * p1))
     DEFINE_METHOD1(const char *, easy_strerror, (CURLcode p1))
+#if defined(HAS_CURL_STATIC)
+    DEFINE_METHOD1(void, crypto_set_id_callback, (unsigned long (*p1)(void)))
+    DEFINE_METHOD1(void, crypto_set_locking_callback, (void (*p1)(int, int, const char *, int)))
+#endif
     BEGIN_METHOD_RESOLVE()
       RESOLVE_METHOD_RENAME(curl_global_init, global_init)
       RESOLVE_METHOD_RENAME(curl_global_cleanup, global_cleanup)
@@ -101,6 +105,10 @@ namespace XCURL
       RESOLVE_METHOD_RENAME(curl_multi_cleanup, multi_cleanup)
       RESOLVE_METHOD_RENAME(curl_slist_append, slist_append)
       RESOLVE_METHOD_RENAME(curl_slist_free_all, slist_free_all)
+#if defined(HAS_CURL_STATIC)
+      RESOLVE_METHOD_RENAME(CRYPTO_set_id_callback, crypto_set_id_callback)
+      RESOLVE_METHOD_RENAME(CRYPTO_set_locking_callback, crypto_set_locking_callback)
+#endif
     END_METHOD_RESOLVE()
 
   };
index a1a2c37..38dcb8f 100644 (file)
@@ -29,6 +29,7 @@
 #include "utils/URIUtils.h"
 #include "settings/AdvancedSettings.h"
 #include "video/VideoInfoTag.h"
+#include "music/tags/MusicInfoTag.h"
 #include "URL.h"
 
 namespace XFILE
@@ -201,6 +202,8 @@ CStdString CFavouritesDirectory::GetExecutePath(const CFileItem &item, const std
   {
     if (item.IsVideoDb() && item.HasVideoInfoTag())
       execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetVideoInfoTag()->m_strFileNameAndPath).c_str());
+    else if (item.IsMusicDb() && item.HasMusicInfoTag())
+      execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetMusicInfoTag()->GetURL()).c_str());
     else
       execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetPath()).c_str());
   }
index 2106bc8..e5886fc 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 
-#include "filesystem/NfsFile.h"
+#include "filesystem/NFSFile.h"
 #include "test/TestUtils.h"
 
 #include <errno.h>
index 96fd3fd..59dbf0f 100644 (file)
@@ -29,6 +29,7 @@
 #include "AnimatedGif.h"
 #include "filesystem/SpecialProtocol.h"
 #include "utils/EndianSwap.h"
+#include "utils/log.h"
 
 #ifdef TARGET_WINDOWS
 extern "C" FILE *fopen_utf8(const char *_Filename, const char *_Mode);
@@ -402,6 +403,10 @@ int CAnimatedGifSet::LoadGIF (const char * szFileName)
 
       NextImage->Init(gifid.Width, gifid.Height, LocalColorMap ? (gifid.PackedFields&7) + 1 : GlobalBPP);
 
+      /* verify that all the image is inside the screen dimensions */
+      if (gifid.xPos + gifid.Width > giflsd.ScreenWidth || gifid.yPos + gifid.Height > giflsd.ScreenHeight)
+        return 0;
+
       // Fill NextImage Data
       NextImage->xPos = gifid.xPos;
       NextImage->yPos = gifid.yPos;
@@ -464,6 +469,7 @@ int CAnimatedGifSet::LoadGIF (const char * szFileName)
       else
       {
         delete NextImage;
+        CLog::Log(LOGERROR, "CAnimatedGifSet::LoadGIF: gif file corrupt: %s", szFileName);
         ERRORMSG("GIF File Corrupt");
       }
 
@@ -505,6 +511,8 @@ int LZWDecoder (char * bufIn, char * bufOut,
                 short InitCodeSize, int AlignedWidth,
                 int Width, int Height, const int Interlace)
 {
+  if (InitCodeSize < 1 || InitCodeSize >= LZW_MAXBITS)
+    return 0;
   int n;
   int row = 0, col = 0;    // used to point output if Interlaced
   int nPixels, maxPixels; // Output pixel counter
@@ -520,12 +528,12 @@ int LZWDecoder (char * bufIn, char * bufOut,
   short OutCode;      // Code to output
 
   // Translation Table:
-  short Prefix[4096] = {};    // Prefix: index of another Code
-  unsigned char Suffix[4096] = {};    // Suffix: terminating character
+  short Prefix[LZW_SIZETABLE] = {};    // Prefix: index of another Code
+  unsigned char Suffix[LZW_SIZETABLE] = {};    // Suffix: terminating character
   short FirstEntry;     // Index of first free entry in table
   short NextEntry;     // Index of next free entry in table
 
-  unsigned char OutStack[4097];   // Output buffer
+  unsigned char OutStack[LZW_SIZETABLE + 1];   // Output buffer
   int OutIndex;      // Characters in OutStack
 
   int RowOffset;     // Offset in output buffer for current row
@@ -583,14 +591,14 @@ int LZWDecoder (char * bufIn, char * bufOut,
     // - Table Suffices contain the raw codes to be output
     while (OutCode >= FirstEntry)
     {
-      if (OutIndex > 4096 || OutCode >= 4096)
+      if (OutIndex > LZW_SIZETABLE || OutCode >= LZW_SIZETABLE)
         return 0;
       OutStack[OutIndex++] = Suffix[OutCode]; // Add suffix to Output Stack
       OutCode = Prefix[OutCode];       // Loop with preffix
     }
 
     // NOW OutCode IS A RAW CODE, ADD IT TO OUTPUT STACK.
-    if (OutIndex > 4096)
+    if (OutIndex > LZW_SIZETABLE)
       return 0;
     OutStack[OutIndex++] = (unsigned char) OutCode;
 
@@ -598,18 +606,18 @@ int LZWDecoder (char * bufIn, char * bufOut,
     // (EXCEPT IF PREVIOUS CODE WAS A CLEARCODE)
     if (PrevCode != ClearCode)
     {
+      // Prevent Translation table overflow:
+      if (NextEntry >= LZW_SIZETABLE)
+        return 0;
+
       Prefix[NextEntry] = PrevCode;
       Suffix[NextEntry] = (unsigned char) OutCode;
       NextEntry++;
 
-      // Prevent Translation table overflow:
-      if (NextEntry >= 4096)
-        return 0;
-
       // INCREASE CodeSize IF NextEntry IS INVALID WITH CURRENT CodeSize
       if (NextEntry >= (1 << CodeSize))
       {
-        if (CodeSize < 12) CodeSize++;
+        if (CodeSize < LZW_MAXBITS) CodeSize++;
         else
         {
           ;
index 4739b29..9e65c85 100644 (file)
@@ -37,6 +37,9 @@
 
 #pragma pack(1)
 
+#define LZW_MAXBITS   12
+#define LZW_SIZETABLE (1<<LZW_MAXBITS)
+
 /*!
  \ingroup textures
  \brief
index 24dbeb3..658dc31 100644 (file)
@@ -283,7 +283,7 @@ bool CGUIFixedListContainer::HasPreviousPage() const
 
 bool CGUIFixedListContainer::HasNextPage() const
 {
-  return (GetOffset() != (int)m_items.size() - m_itemsPerPage && (int)m_items.size() >= m_itemsPerPage);
+  return (GetOffset() < (int)m_items.size() - m_itemsPerPage && (int)m_items.size() >= m_itemsPerPage);
 }
 
 int CGUIFixedListContainer::GetCurrentPage() const
index 63ecf85..a7ee668 100644 (file)
@@ -204,7 +204,7 @@ void CGUIFont::DrawScrollingText(float x, float y, const vecColors &colors, colo
   if (!text.size() || ClippedRegionIsEmpty(x, y, maxWidth, alignment))
     return; // nothing to render
 
-  maxWidth = ROUND(maxWidth / g_graphicsContext.GetGUIScaleX());
+  maxWidth = ROUND((maxWidth + scrollInfo.pixelPos) / g_graphicsContext.GetGUIScaleX());
 
   float charWidth = GetCharWidth(scrollInfo.GetCurrentChar(text));
   float offset;
@@ -239,9 +239,9 @@ void CGUIFont::DrawScrollingText(float x, float y, const vecColors &colors, colo
     vecColors shadowColors;
     for (unsigned int i = 0; i < renderColors.size(); i++)
       shadowColors.push_back((renderColors[i] & 0xff000000) != 0 ? shadowColor : 0);
-    m_font->DrawTextInternal(x - offset + 1, y + 1, shadowColors, renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f), scroll);
+    m_font->DrawTextInternal(x - offset + 1, y + 1, shadowColors, renderText, alignment, maxWidth + m_font->GetLineHeight(2.0f), scroll);
   }
-  m_font->DrawTextInternal(x - offset, y, renderColors, renderText, alignment, maxWidth + scrollInfo.pixelPos + m_font->GetLineHeight(2.0f), scroll);
+  m_font->DrawTextInternal(x - offset, y, renderColors, renderText, alignment, maxWidth + m_font->GetLineHeight(2.0f), scroll);
 
   g_graphicsContext.RestoreClipRegion();
 }
index ac4b238..f65d361 100644 (file)
@@ -83,6 +83,8 @@ class CGUIKeyboard : public ITimerCallback
       if (m_idleTimer.IsRunning()) 
         m_idleTimer.Restart();
     }
+
+    virtual bool SetTextToKeyboard(const std::string &text, bool closeKeyboard = false) { return false; }
     
   private:
     CTimer m_idleTimer;
index 822f079..1f6d158 100644 (file)
@@ -34,6 +34,7 @@
 #include "osx/ios/IOSKeyboard.h"
 #endif
 
+CGUIKeyboard *CGUIKeyboardFactory::g_activedKeyboard = NULL;
 FILTERING CGUIKeyboardFactory::m_filtering = FILTERING_NONE;
 
 CGUIKeyboardFactory::CGUIKeyboardFactory(void)
@@ -68,6 +69,14 @@ void CGUIKeyboardFactory::keyTypedCB(CGUIKeyboard *ref, const std::string &typed
   }
 }
 
+bool CGUIKeyboardFactory::SendTextToActiveKeyboard(const std::string &aTextString, bool closeKeyboard /* = false */)
+{
+  if (!g_activedKeyboard)
+    return false;
+  return g_activedKeyboard->SetTextToKeyboard(aTextString, closeKeyboard);
+}
+
+
 // Show keyboard with initial value (aTextString) and replace with result string.
 // Returns: true  - successful display and input (empty result may return true or false depending on parameter)
 //          false - unsuccessful display of the keyboard or cancelled editing
@@ -95,8 +104,10 @@ bool CGUIKeyboardFactory::ShowAndGetInput(CStdString& aTextString, const CVarian
 
   if(kb)
   {
+    g_activedKeyboard = kb;
     kb->startAutoCloseTimer(autoCloseMs);
     confirmed = kb->ShowAndGetInput(keyTypedCB, aTextString, aTextString, headingStr, hiddenInput);
+    g_activedKeyboard = NULL;
     if(needsFreeing)
       delete kb;
   }
index 274f8c7..0b143cd 100644 (file)
@@ -40,7 +40,11 @@ class CGUIKeyboardFactory
     static int  ShowAndVerifyPassword(CStdString& strPassword, const CStdString& strHeading, int iRetries, unsigned int autoCloseMs = 0);
     static bool ShowAndGetFilter(CStdString& aTextString, bool searching, unsigned int autoCloseMs = 0);
 
+    static bool SendTextToActiveKeyboard(const std::string &aTextString, bool closeKeyboard = false);
+
+    static bool isKeyboardActivated() { return g_activedKeyboard != NULL; }
   private:
+    static CGUIKeyboard *g_activedKeyboard;
     static FILTERING m_filtering;
     static void keyTypedCB(CGUIKeyboard *ref, const std::string &typedString);
 };
index b68e08b..712e118 100644 (file)
@@ -113,10 +113,7 @@ void CGUIRSSControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyre
         m_rtl = iter->second.rtl;
         m_vecUrls = iter->second.url;
         m_vecIntervals = iter->second.interval;
-        if (m_scrollInfo.pixelSpeed > 0 && m_rtl)
-          m_scrollInfo.pixelSpeed *= -1;
-        else if (m_scrollInfo.pixelSpeed < 0 && !m_rtl)
-          m_scrollInfo.pixelSpeed *= -1;
+        m_scrollInfo.SetSpeed(m_label.scrollSpeed * (m_rtl ? -1 : 1));
       }
 
       dirty = true;
@@ -149,7 +146,7 @@ void CGUIRSSControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyre
       if ( m_stopped )
         m_scrollInfo.SetSpeed(0);
       else
-        m_scrollInfo.SetSpeed(m_label.scrollSpeed);
+        m_scrollInfo.SetSpeed(m_label.scrollSpeed * (m_rtl ? -1 : 1));
 
       if(m_label.font->UpdateScrollInfo(m_feed, m_scrollInfo))
         dirty = true;
index 20715a9..2fb40e3 100644 (file)
@@ -286,13 +286,13 @@ void CGUIScrollBar::SetFromPosition(const CPoint &point)
 {
   float fPercent;
   if (m_orientation == VERTICAL)
-    fPercent = (point.y - m_guiBackground.GetYPosition() - 0.5f*m_guiBarFocus.GetHeight()) / m_guiBackground.GetHeight();
+    fPercent = (point.y - m_guiBackground.GetYPosition() - 0.5f*m_guiBarFocus.GetHeight()) / (m_guiBackground.GetHeight() - m_guiBarFocus.GetHeight());
   else
-    fPercent = (point.x - m_guiBackground.GetXPosition() - 0.5f*m_guiBarFocus.GetWidth()) / m_guiBackground.GetWidth();
+    fPercent = (point.x - m_guiBackground.GetXPosition() - 0.5f*m_guiBarFocus.GetWidth()) / (m_guiBackground.GetWidth() - m_guiBarFocus.GetWidth());
   if (fPercent < 0) fPercent = 0;
   if (fPercent > 1) fPercent = 1;
 
-  int offset = (int)(floor(fPercent * m_numItems + 0.5f));
+  int offset = (int)(floor(fPercent * (m_numItems - m_pageSize) + 0.5f));
 
   if (m_offset != offset)
   {
index c9d3161..4407d8d 100644 (file)
@@ -242,6 +242,7 @@ static const ActionMapping actions[] =
         {"playpvr"               , ACTION_PVR_PLAY},
         {"playpvrtv"             , ACTION_PVR_PLAY_TV},
         {"playpvrradio"          , ACTION_PVR_PLAY_RADIO},
+        {"record"                , ACTION_RECORD},
 
         // Mouse actions
         {"leftclick"         , ACTION_MOUSE_LEFT_CLICK},
@@ -889,7 +890,7 @@ bool CButtonTranslator::TranslateJoystickString(int window, const char* szDevice
   return (action > 0);
 }
 
-bool CButtonTranslator::TranslateTouchAction(int touchAction, int touchPointers, int &window, int &action)
+bool CButtonTranslator::TranslateTouchAction(int window, int touchAction, int touchPointers, int &action)
 {
   action = 0;
   if (touchPointers <= 0)
@@ -900,10 +901,7 @@ bool CButtonTranslator::TranslateTouchAction(int touchAction, int touchPointers,
 
   action = GetTouchActionCode(window, touchAction);
   if (action <= 0)
-  {
-    window = WINDOW_INVALID;
     action = GetTouchActionCode(-1, touchAction);
-  }
 
   return action > 0;
 }
index e150e91..11ac033 100644 (file)
@@ -98,7 +98,7 @@ public:
                                bool &fullrange);
 #endif
 
-  bool TranslateTouchAction(int touchAction, int touchPointers, int &window, int &action);
+  bool TranslateTouchAction(int window, int touchAction, int touchPointers, int &action);
 
 private:
   typedef std::multimap<uint32_t, CButtonAction> buttonMap; // our button map to fill in
index 0334178..e1ff570 100644 (file)
@@ -115,11 +115,16 @@ void CJoystick::Initialize()
         // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57
         // NOTICE: Enabled Joystick: Microsoft Microsoft® 2.4GHz Transceiver v6.0
         // Details: Total Axis: 37 Total Hats: 0 Total Buttons: 57
+        // also checks if we have at least 1 button, fixes 
+        // NOTICE: Enabled Joystick: ST LIS3LV02DL Accelerometer
+        // Details: Total Axis: 3 Total Hats: 0 Total Buttons: 0
         int num_axis = SDL_JoystickNumAxes(joy);
         int num_buttons = SDL_JoystickNumButtons(joy);
-        if (num_axis > 20 && num_buttons > 50)
-          CLog::Log(LOGNOTICE, "Your Joystick seems to be a Keyboard, ignoring it: %s Axis: %d Buttons: %d", 
-            SDL_JoystickName(i), num_axis, num_buttons);
+        if ((num_axis > 20 && num_buttons > 50) || num_buttons == 0)
+        {
+          CLog::Log(LOGNOTICE, "Ignoring Joystick %s Axis: %d Buttons: %d: invalid device properties",
+           SDL_JoystickName(i), num_axis, num_buttons);
+        }
         else
         {
           m_JoystickNames.push_back(string(SDL_JoystickName(i)));
index c28e287..db57c98 100644 (file)
@@ -184,14 +184,13 @@ void CGenericTouchActionHandler::sendEvent(int actionId, float x, float y, float
 
 void CGenericTouchActionHandler::focusControl(float x, float y)
 {
-  // Send a mouse motion event for getting the current guiitem selected
   XBMC_Event newEvent;
   memset(&newEvent, 0, sizeof(newEvent));
 
-  newEvent.type = XBMC_MOUSEMOTION;
-  newEvent.motion.type = XBMC_MOUSEMOTION;
-  newEvent.motion.x = (uint16_t)x;
-  newEvent.motion.y = (uint16_t)y;
+  newEvent.type = XBMC_SETFOCUS;
+  newEvent.focus.type = XBMC_SETFOCUS;
+  newEvent.focus.x = (uint16_t)x;
+  newEvent.focus.y = (uint16_t)y;
 
   CWinEvents::MessagePush(&newEvent);
 }
index 8669901..b61ddc3 100644 (file)
@@ -569,9 +569,15 @@ int CBuiltins::Execute(const CStdString& execString)
             parameters.insert(parameters.begin(), params.begin() + 1, params.end());
             urlParameters = "?" + StringUtils::JoinString(parameters, "&");
           }
+          else
+          {
+            // Add '/' if addon is run without params (will be removed later so it's safe)
+            // Otherwise there are 2 entries for the same plugin in ViewModesX.db
+            urlParameters = "/";
+          }
 
           if (plugin->Provides(CPluginSource::VIDEO))
-            cmd = StringUtils::Format("ActivateWindow(Video,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
+            cmd = StringUtils::Format("ActivateWindow(Videos,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
           else if (plugin->Provides(CPluginSource::AUDIO))
             cmd = StringUtils::Format("ActivateWindow(Music,plugin://%s%s,return)", addonid.c_str(), urlParameters.c_str());
           else if (plugin->Provides(CPluginSource::EXECUTABLE))
index 55c2d81..4d8d74c 100644 (file)
@@ -313,7 +313,7 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyAddedSongs(const CStdString &method, IT
     amount = 0;
 
   CFileItemList items;
-  if (!musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://", items, (unsigned int)amount))
+  if (!musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://songs/", items, (unsigned int)amount))
     return InternalError;
 
   JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
@@ -359,7 +359,7 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyPlayedSongs(const CStdString &method, I
     return InternalError;
 
   CFileItemList items;
-  if (!musicdatabase.GetRecentlyPlayedAlbumSongs("musicdb://", items))
+  if (!musicdatabase.GetRecentlyPlayedAlbumSongs("musicdb://songs/", items))
     return InternalError;
 
   JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
index e1a871e..3964431 100644 (file)
@@ -304,7 +304,7 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char
           std::string type = item->GetMusicInfoTag()->GetType();
           if (type == "album" || type == "song" || type == "artist")
             object["type"] = type;
-          else
+          else if (!item->m_bIsFolder)
             object["type"] = "song";
         }
         else if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_type.empty())
index 196d4a3..69a6b0d 100644 (file)
@@ -64,14 +64,7 @@ JSONRPC_STATUS CInputOperations::activateWindow(int windowID)
 
 JSONRPC_STATUS CInputOperations::SendText(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  CGUIWindow *window = g_windowManager.GetWindow(g_windowManager.GetFocusedWindow());
-  if (!window)
-    return InternalError;
-
-  CGUIMessage msg(GUI_MSG_SET_TEXT, 0, 0);
-  msg.SetLabel(parameterObject["text"].asString());
-  msg.SetParam1(parameterObject["done"].asBoolean() ? 1 : 0);
-  CApplicationMessenger::Get().SendGUIMessage(msg, window->GetID());
+  CApplicationMessenger::Get().SendText(parameterObject["text"].asString(), parameterObject["done"].asBoolean());
   return ACK;
 }
 
index be7bce6..f639791 100644 (file)
@@ -170,6 +170,12 @@ void CLinuxTimezone::OnSettingChanged(const CSetting *setting)
   }
 }
 
+void CLinuxTimezone::OnSettingsLoaded()
+{
+  SetTimezone(CSettings::Get().GetString("locale.timezone"));
+  CDateTime::ResetTimezoneBias();
+}
+
 vector<CStdString> CLinuxTimezone::GetCounties()
 {
    return m_counties;
index 3adc5b5..393d6ae 100644 (file)
  */
 
 #include "settings/lib/ISettingCallback.h"
+#include "settings/lib/ISettingsHandler.h"
 #include "utils/StdString.h"
 #include <vector>
 #include <map>
 
 class CSetting;
 
-class CLinuxTimezone : public ISettingCallback
+class CLinuxTimezone : public ISettingCallback, public ISettingsHandler
 {
 public:
    CLinuxTimezone();
 
    virtual void OnSettingChanged(const CSetting *setting);
 
+   virtual void OnSettingsLoaded();
+
    CStdString GetOSConfiguredTimezone();
 
    std::vector<CStdString> GetCounties();
index 9191e47..9eddf7b 100644 (file)
 #include "threads/SingleLock.h"
 #include "ApplicationMessenger.h"
 #include "FileItem.h"
+#include "video/VideoThumbLoader.h"
+#include "music/MusicThumbLoader.h"
+#include "pictures/PictureThumbLoader.h"
+#include "boost/make_shared.hpp"
 
 using namespace std;
 using namespace XFILE;
@@ -36,6 +40,14 @@ using namespace XFILE;
 class CDirectoryJob : public CJob
 {
 public:
+  typedef enum
+  {
+    VIDEO,
+    AUDIO,
+    PICTURE,
+    PROGRAM
+  } InfoTagType;
+
   CDirectoryJob(const std::string &url, int parentID) : m_url(url), m_parentID(parentID) { };
   virtual ~CDirectoryJob() {};
 
@@ -63,6 +75,9 @@ public:
         CGUIStaticItemPtr item(new CGUIStaticItem(*items[i]));
         if (item->HasProperty("node.visible"))
           item->SetVisibleCondition(item->GetProperty("node.visible").asString(), m_parentID);
+
+        getThumbLoader(item)->LoadItem(item.get());
+
         m_items.push_back(item);
       }
       m_target = items.GetProperty("node.target").asString();
@@ -70,6 +85,38 @@ public:
     return true;    
   }
 
+  boost::shared_ptr<CThumbLoader> getThumbLoader(CGUIStaticItemPtr &item)
+  {
+    if (item->IsVideo())
+    {
+      initThumbLoader<CVideoThumbLoader>(VIDEO);
+      return m_thumbloaders[VIDEO];
+    }
+    if (item->IsAudio())
+    {
+      initThumbLoader<CMusicThumbLoader>(AUDIO);
+      return m_thumbloaders[AUDIO];
+    }
+    if (item->IsPicture())
+    {
+      initThumbLoader<CPictureThumbLoader>(PICTURE);
+      return m_thumbloaders[PICTURE];
+    }
+    initThumbLoader<CProgramThumbLoader>(PROGRAM);
+    return m_thumbloaders[PROGRAM];
+  }
+  
+  template<class CThumbLoaderClass>
+  void initThumbLoader(InfoTagType type)
+  {
+    if (!m_thumbloaders.count(type))
+    {
+      boost::shared_ptr<CThumbLoader> thumbLoader = boost::make_shared<CThumbLoaderClass>();
+      thumbLoader->OnLoaderStart();
+      m_thumbloaders.insert(make_pair(type, thumbLoader));
+    }
+  }
+
   const std::vector<CGUIStaticItemPtr> &GetItems() const { return m_items; }
   const std::string &GetTarget() const { return m_target; }
 private:
@@ -77,6 +124,7 @@ private:
   std::string m_target;
   int m_parentID;
   std::vector<CGUIStaticItemPtr> m_items;
+  std::map<InfoTagType, boost::shared_ptr<CThumbLoader> > m_thumbloaders;
 };
 
 CDirectoryProvider::CDirectoryProvider(const TiXmlElement *element, int parentID)
index 66d1b25..e5ceccc 100644 (file)
@@ -38,15 +38,43 @@ CAlbum::CAlbum(const CFileItem& item)
   strMusicBrainzAlbumID = tag.GetMusicBrainzAlbumID();
   genre = tag.GetGenre();
   artist = tag.GetAlbumArtist();
-  bool hasMusicBrainzAlbumArtist = !tag.GetMusicBrainzAlbumArtistID().empty();
-  const vector<string>& artists = hasMusicBrainzAlbumArtist ? tag.GetMusicBrainzAlbumArtistID() : tag.GetAlbumArtist();
-  for (vector<string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
-  {
-    CStdString artistName = hasMusicBrainzAlbumArtist && !artist.empty() ? artist[0] : *it;
-    CStdString artistId = hasMusicBrainzAlbumArtist ? *it : StringUtils::EmptyString;
-    CStdString strJoinPhrase = (it == --artists.end() ? "" : g_advancedSettings.m_musicItemSeparator);
-    CArtistCredit artistCredit(artistName, artistId, strJoinPhrase);
-    artistCredits.push_back(artistCredit);
+  if (!tag.GetMusicBrainzAlbumArtistID().empty())
+  { // have musicbrainz artist info, so use it
+    for (size_t i = 0; i < tag.GetMusicBrainzAlbumArtistID().size(); i++)
+    {
+      CStdString artistId = tag.GetMusicBrainzAlbumArtistID()[i];
+      CStdString artistName;
+      /*
+       We try and get the corresponding artist name from the album artist tag.
+       We match on the same index, and if that fails just use the first name we have.
+       If no albumartist exists, try matching on artist if the MBArtistID matches.
+       */
+      if (!artist.empty())
+        artistName = (i < artist.size()) ? artist[i] : artist[0];
+      else if (!tag.GetMusicBrainzArtistID().empty() && !tag.GetArtist().empty())
+      {
+        vector<string>::const_iterator j = std::find(tag.GetMusicBrainzArtistID().begin(), tag.GetMusicBrainzArtistID().end(), artistId);
+        if (j != tag.GetMusicBrainzArtistID().end())
+        { // find corresponding artist
+          size_t d = std::distance(j,tag.GetMusicBrainzArtistID().begin());
+          artistName = (d < tag.GetArtist().size()) ? tag.GetArtist()[d] : tag.GetArtist()[0];
+        }
+      }
+      if (artistName.empty())
+        artistName = artistId;
+      CStdString strJoinPhrase = (i == tag.GetMusicBrainzAlbumArtistID().size()-1) ? "" : g_advancedSettings.m_musicItemSeparator;
+      CArtistCredit artistCredit(artistName, tag.GetMusicBrainzAlbumArtistID()[i], strJoinPhrase);
+      artistCredits.push_back(artistCredit);
+    }
+  }
+  else
+  { // no musicbrainz info, so fill in directly
+    for (vector<string>::const_iterator it = tag.GetAlbumArtist().begin(); it != tag.GetAlbumArtist().end(); ++it)
+    {
+      CStdString strJoinPhrase = (it == --tag.GetAlbumArtist().end() ? "" : g_advancedSettings.m_musicItemSeparator);
+      CArtistCredit artistCredit(*it, "", strJoinPhrase);
+      artistCredits.push_back(artistCredit);
+    }
   }
   iYear = stTime.wYear;
   bCompilation = tag.GetCompilation();
index 0f14c1a..ae1e69d 100644 (file)
@@ -110,175 +110,145 @@ bool CMusicDatabase::Open()
   return CDatabase::Open(g_advancedSettings.m_databaseMusic);
 }
 
-bool CMusicDatabase::CreateTables()
-{
-  BeginTransaction();
-  try
-  {
-    CDatabase::CreateTables();
-
-    CLog::Log(LOGINFO, "create artist table");
-    m_pDS->exec("CREATE TABLE artist ( idArtist integer primary key, "
-                " strArtist varchar(256), strMusicBrainzArtistID text, "
-                " strBorn text, strFormed text, strGenres text, strMoods text, "
-                " strStyles text, strInstruments text, strBiography text, "
-                " strDied text, strDisbanded text, strYearsActive text, "
-                " strImage text, strFanart text, "
-                " lastScraped varchar(20) default NULL, "
-                " dateAdded varchar (20) default NULL)");
-    CLog::Log(LOGINFO, "create album table");
-    m_pDS->exec("CREATE TABLE album (idAlbum integer primary key, "
-                " strAlbum varchar(256), strMusicBrainzAlbumID text, "
-                " strArtists text, strGenres text, "
-                " iYear integer, idThumb integer, "
-                " bCompilation integer not null default '0', "
-                " strMoods text, strStyles text, strThemes text, "
-                " strReview text, strImage text, strLabel text, "
-                " strType text, "
-                " iRating integer, "
-                " lastScraped varchar(20) default NULL, "
-                " dateAdded varchar (20) default NULL)");
-    CLog::Log(LOGINFO, "create album_artist table");
-    m_pDS->exec("CREATE TABLE album_artist ( idArtist integer, idAlbum integer, strJoinPhrase text, boolFeatured integer, iOrder integer, strArtist text )\n");
-    CLog::Log(LOGINFO, "create album_genre table");
-    m_pDS->exec("CREATE TABLE album_genre ( idGenre integer, idAlbum integer, iOrder integer )\n");
-
-    CLog::Log(LOGINFO, "create genre table");
-    m_pDS->exec("CREATE TABLE genre ( idGenre integer primary key, strGenre varchar(256))\n");
-    CLog::Log(LOGINFO, "create path table");
-    m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath varchar(512), strHash text)\n");
-    CLog::Log(LOGINFO, "create song table");
-    m_pDS->exec("CREATE TABLE song ( idSong integer primary key, "
-                " idAlbum integer, idPath integer, "
-                " strArtists text, strGenres text, strTitle varchar(512), "
-                " iTrack integer, iDuration integer, iYear integer, "
-                " dwFileNameCRC text, "
-                " strFileName text, strMusicBrainzTrackID text, "
-                " iTimesPlayed integer, iStartOffset integer, iEndOffset integer, "
-                " idThumb integer, "
-                " lastplayed varchar(20) default NULL, "
-                " rating char default '0', comment text)");
-    CLog::Log(LOGINFO, "create song_artist table");
-    m_pDS->exec("CREATE TABLE song_artist ( idArtist integer, idSong integer, strJoinPhrase text, boolFeatured integer, iOrder integer, strArtist text )\n");
-    CLog::Log(LOGINFO, "create song_genre table");
-    m_pDS->exec("CREATE TABLE song_genre ( idGenre integer, idSong integer, iOrder integer )\n");
-
-    CLog::Log(LOGINFO, "create albuminfosong table");
-    m_pDS->exec("CREATE TABLE albuminfosong ( idAlbumInfoSong integer primary key, idAlbumInfo integer, iTrack integer, strTitle text, iDuration integer)\n");
-
-    CLog::Log(LOGINFO, "create content table");
-    m_pDS->exec("CREATE TABLE content (strPath text, strScraperPath text, strContent text, strSettings text)\n");
-    CLog::Log(LOGINFO, "create discography table");
-    m_pDS->exec("CREATE TABLE discography (idArtist integer, strAlbum text, strYear text)\n");
-
-    CLog::Log(LOGINFO, "create karaokedata table");
-    m_pDS->exec("CREATE TABLE karaokedata ( iKaraNumber integer, idSong integer, iKaraDelay integer, strKaraEncoding text, "
-                "strKaralyrics text, strKaraLyrFileCRC text )\n");
-
-    CLog::Log(LOGINFO, "create album index");
-    m_pDS->exec("CREATE INDEX idxAlbum ON album(strAlbum(255))");
-    CLog::Log(LOGINFO, "create album compilation index");
-    m_pDS->exec("CREATE INDEX idxAlbum_1 ON album(bCompilation)");
-    CLog::Log(LOGINFO, "create unique album name index");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbum_2 ON album(strMusicBrainzAlbumID(36))");
-
-    CLog::Log(LOGINFO, "create album_artist indexes");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_1 ON album_artist ( idAlbum, idArtist )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_2 ON album_artist ( idArtist, idAlbum )\n");
-    m_pDS->exec("CREATE INDEX idxAlbumArtist_3 ON album_artist ( boolFeatured )\n");
-
-    CLog::Log(LOGINFO, "create album_genre indexes");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_1 ON album_genre ( idAlbum, idGenre )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_2 ON album_genre ( idGenre, idAlbum )\n");
-
-    CLog::Log(LOGINFO, "create genre index");
-    m_pDS->exec("CREATE INDEX idxGenre ON genre(strGenre(255))");
-
-    CLog::Log(LOGINFO, "create artist indexes");
-    m_pDS->exec("CREATE INDEX idxArtist ON artist(strArtist(255))");
-    m_pDS->exec("CREATE UNIQUE INDEX idxArtist1 ON artist(strMusicBrainzArtistID(36))");
-
-    CLog::Log(LOGINFO, "create path index");
-    m_pDS->exec("CREATE INDEX idxPath ON path(strPath(255))");
-
-    CLog::Log(LOGINFO, "create song index");
-    m_pDS->exec("CREATE INDEX idxSong ON song(strTitle(255))");
-    CLog::Log(LOGINFO, "create song index1");
-    m_pDS->exec("CREATE INDEX idxSong1 ON song(iTimesPlayed)");
-    CLog::Log(LOGINFO, "create song index2");
-    m_pDS->exec("CREATE INDEX idxSong2 ON song(lastplayed)");
-    CLog::Log(LOGINFO, "create song index3");
-    m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
-    CLog::Log(LOGINFO, "create song index6");
-    m_pDS->exec("CREATE INDEX idxSong6 ON song( idPath, strFileName(255) )");
-    CLog::Log(LOGINFO, "create song index7");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSong7 ON song( idAlbum, strMusicBrainzTrackID(36) )");
-
-    CLog::Log(LOGINFO, "create song_artist indexes");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_1 ON song_artist ( idSong, idArtist )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_2 ON song_artist ( idArtist, idSong )\n");
-    m_pDS->exec("CREATE INDEX idxSongArtist_3 ON song_artist ( boolFeatured )\n");
-
-    CLog::Log(LOGINFO, "create song_genre indexes");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_1 ON song_genre ( idSong, idGenre )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_2 ON song_genre ( idGenre, idSong )\n");
-    //m_pDS->exec("CREATE INDEX idxSong ON song(dwFileNameCRC)");
-
-    CLog::Log(LOGINFO, "create albuminfosong indexes");
-    m_pDS->exec("CREATE INDEX idxAlbumInfoSong_1 ON albuminfosong ( idAlbumInfo )\n");
-
-    CLog::Log(LOGINFO, "create karaokedata index");
-    m_pDS->exec("CREATE INDEX idxKaraNumber on karaokedata(iKaraNumber)");
-    m_pDS->exec("CREATE INDEX idxKarSong on karaokedata(idSong)");
-
-    CLog::Log(LOGINFO, "create discography indexes");
-    m_pDS->exec("CREATE INDEX idxDiscography_1 ON discography ( idArtist )\n");
-
-    CLog::Log(LOGINFO, "create art table and index");
-    m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
-    m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
-
-    CLog::Log(LOGINFO, "create triggers");
-    m_pDS->exec("CREATE TRIGGER tgrDeleteAlbum AFTER delete ON album FOR EACH ROW BEGIN"
-                "  DELETE FROM song WHERE song.idAlbum = old.idAlbum;"
-                "  DELETE FROM album_artist WHERE album_artist.idAlbum = old.idAlbum;"
-                "  DELETE FROM album_genre WHERE album_genre.idAlbum = old.idAlbum;"
-                "  DELETE FROM albuminfosong WHERE albuminfosong.idAlbumInfo=old.idAlbum;"
-                "  DELETE FROM art WHERE media_id=old.idAlbum AND media_type='album';"
-                " END");
-    m_pDS->exec("CREATE TRIGGER tgrDeleteArtist AFTER delete ON artist FOR EACH ROW BEGIN"
-                "  DELETE FROM album_artist WHERE album_artist.idArtist = old.idArtist;"
-                "  DELETE FROM song_artist WHERE song_artist.idArtist = old.idArtist;"
-                "  DELETE FROM discography WHERE discography.idArtist = old.idArtist;"
-                "  DELETE FROM art WHERE media_id=old.idArtist AND media_type='artist';"
-                " END");
-    m_pDS->exec("CREATE TRIGGER tgrDeleteSong AFTER delete ON song FOR EACH ROW BEGIN"
-                "  DELETE FROM song_artist WHERE song_artist.idSong = old.idSong;"
-                "  DELETE FROM song_genre WHERE song_genre.idSong = old.idSong;"
-                "  DELETE FROM karaokedata WHERE karaokedata.idSong = old.idSong;"
-                "  DELETE FROM art WHERE media_id=old.idSong AND media_type='song';"
-                " END");
-
-    // we create views last to ensure all indexes are rolled in
-    CreateViews();
-
-    // Add 'Karaoke' genre
-    AddGenre( "Karaoke" );
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "%s unable to create tables:%i", __FUNCTION__, (int)GetLastError());
-    RollbackTransaction();
-    return false;
-  }
-  CommitTransaction();
-  return true;
+void CMusicDatabase::CreateTables()
+{
+  CLog::Log(LOGINFO, "create artist table");
+  m_pDS->exec("CREATE TABLE artist ( idArtist integer primary key, "
+              " strArtist varchar(256), strMusicBrainzArtistID text, "
+              " strBorn text, strFormed text, strGenres text, strMoods text, "
+              " strStyles text, strInstruments text, strBiography text, "
+              " strDied text, strDisbanded text, strYearsActive text, "
+              " strImage text, strFanart text, "
+              " lastScraped varchar(20) default NULL, "
+              " dateAdded varchar (20) default NULL)");
+  CLog::Log(LOGINFO, "create album table");
+  m_pDS->exec("CREATE TABLE album (idAlbum integer primary key, "
+              " strAlbum varchar(256), strMusicBrainzAlbumID text, "
+              " strArtists text, strGenres text, "
+              " iYear integer, idThumb integer, "
+              " bCompilation integer not null default '0', "
+              " strMoods text, strStyles text, strThemes text, "
+              " strReview text, strImage text, strLabel text, "
+              " strType text, "
+              " iRating integer, "
+              " lastScraped varchar(20) default NULL, "
+              " dateAdded varchar (20) default NULL)");
+  CLog::Log(LOGINFO, "create album_artist table");
+  m_pDS->exec("CREATE TABLE album_artist (idArtist integer, idAlbum integer, strJoinPhrase text, boolFeatured integer, iOrder integer, strArtist text)");
+  CLog::Log(LOGINFO, "create album_genre table");
+  m_pDS->exec("CREATE TABLE album_genre (idGenre integer, idAlbum integer, iOrder integer)");
+
+  CLog::Log(LOGINFO, "create genre table");
+  m_pDS->exec("CREATE TABLE genre (idGenre integer primary key, strGenre varchar(256))");
+  CLog::Log(LOGINFO, "create path table");
+  m_pDS->exec("CREATE TABLE path (idPath integer primary key, strPath varchar(512), strHash text)");
+  CLog::Log(LOGINFO, "create song table");
+  m_pDS->exec("CREATE TABLE song (idSong integer primary key, "
+              " idAlbum integer, idPath integer, "
+              " strArtists text, strGenres text, strTitle varchar(512), "
+              " iTrack integer, iDuration integer, iYear integer, "
+              " dwFileNameCRC text, "
+              " strFileName text, strMusicBrainzTrackID text, "
+              " iTimesPlayed integer, iStartOffset integer, iEndOffset integer, "
+              " idThumb integer, "
+              " lastplayed varchar(20) default NULL, "
+              " rating char default '0', comment text)");
+  CLog::Log(LOGINFO, "create song_artist table");
+  m_pDS->exec("CREATE TABLE song_artist (idArtist integer, idSong integer, strJoinPhrase text, boolFeatured integer, iOrder integer, strArtist text)");
+  CLog::Log(LOGINFO, "create song_genre table");
+  m_pDS->exec("CREATE TABLE song_genre (idGenre integer, idSong integer, iOrder integer)");
+
+  CLog::Log(LOGINFO, "create albuminfosong table");
+  m_pDS->exec("CREATE TABLE albuminfosong (idAlbumInfoSong integer primary key, idAlbumInfo integer, iTrack integer, strTitle text, iDuration integer)");
+
+  CLog::Log(LOGINFO, "create content table");
+  m_pDS->exec("CREATE TABLE content (strPath text, strScraperPath text, strContent text, strSettings text)");
+  CLog::Log(LOGINFO, "create discography table");
+  m_pDS->exec("CREATE TABLE discography (idArtist integer, strAlbum text, strYear text)");
+
+  CLog::Log(LOGINFO, "create karaokedata table");
+  m_pDS->exec("CREATE TABLE karaokedata (iKaraNumber integer, idSong integer, iKaraDelay integer, strKaraEncoding text, "
+              "strKaralyrics text, strKaraLyrFileCRC text)");
+
+  CLog::Log(LOGINFO, "create art table");
+  m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
+
+  // Add 'Karaoke' genre
+  AddGenre( "Karaoke" );
+}
+
+void CMusicDatabase::CreateAnalytics()
+{
+  CLog::Log(LOGINFO, "%s - creating indices", __FUNCTION__);
+  m_pDS->exec("CREATE INDEX idxAlbum ON album(strAlbum(255))");
+  m_pDS->exec("CREATE INDEX idxAlbum_1 ON album(bCompilation)");
+  m_pDS->exec("CREATE UNIQUE INDEX idxAlbum_2 ON album(strMusicBrainzAlbumID(36))");
+
+  m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_1 ON album_artist ( idAlbum, idArtist )");
+  m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_2 ON album_artist ( idArtist, idAlbum )");
+  m_pDS->exec("CREATE INDEX idxAlbumArtist_3 ON album_artist ( boolFeatured )");
+
+  m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_1 ON album_genre ( idAlbum, idGenre )");
+  m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_2 ON album_genre ( idGenre, idAlbum )");
+
+  m_pDS->exec("CREATE INDEX idxGenre ON genre(strGenre(255))");
+
+  m_pDS->exec("CREATE INDEX idxArtist ON artist(strArtist(255))");
+  m_pDS->exec("CREATE UNIQUE INDEX idxArtist1 ON artist(strMusicBrainzArtistID(36))");
+
+  m_pDS->exec("CREATE INDEX idxPath ON path(strPath(255))");
+
+  m_pDS->exec("CREATE INDEX idxSong ON song(strTitle(255))");
+  m_pDS->exec("CREATE INDEX idxSong1 ON song(iTimesPlayed)");
+  m_pDS->exec("CREATE INDEX idxSong2 ON song(lastplayed)");
+  m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
+  m_pDS->exec("CREATE INDEX idxSong6 ON song( idPath, strFileName(255) )");
+  m_pDS->exec("CREATE UNIQUE INDEX idxSong7 ON song( idAlbum, strMusicBrainzTrackID(36) )");
+
+  m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_1 ON song_artist ( idSong, idArtist )");
+  m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_2 ON song_artist ( idArtist, idSong )");
+  m_pDS->exec("CREATE INDEX idxSongArtist_3 ON song_artist ( boolFeatured )");
+
+  m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_1 ON song_genre ( idSong, idGenre )");
+  m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_2 ON song_genre ( idGenre, idSong )");
+
+  m_pDS->exec("CREATE INDEX idxAlbumInfoSong_1 ON albuminfosong ( idAlbumInfo )");
+
+  m_pDS->exec("CREATE INDEX idxKaraNumber on karaokedata(iKaraNumber)");
+  m_pDS->exec("CREATE INDEX idxKarSong on karaokedata(idSong)");
+
+  m_pDS->exec("CREATE INDEX idxDiscography_1 ON discography ( idArtist )");
+
+  m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
+
+  CLog::Log(LOGINFO, "create triggers");
+  m_pDS->exec("CREATE TRIGGER tgrDeleteAlbum AFTER delete ON album FOR EACH ROW BEGIN"
+              "  DELETE FROM song WHERE song.idAlbum = old.idAlbum;"
+              "  DELETE FROM album_artist WHERE album_artist.idAlbum = old.idAlbum;"
+              "  DELETE FROM album_genre WHERE album_genre.idAlbum = old.idAlbum;"
+              "  DELETE FROM albuminfosong WHERE albuminfosong.idAlbumInfo=old.idAlbum;"
+              "  DELETE FROM art WHERE media_id=old.idAlbum AND media_type='album';"
+              " END");
+  m_pDS->exec("CREATE TRIGGER tgrDeleteArtist AFTER delete ON artist FOR EACH ROW BEGIN"
+              "  DELETE FROM album_artist WHERE album_artist.idArtist = old.idArtist;"
+              "  DELETE FROM song_artist WHERE song_artist.idArtist = old.idArtist;"
+              "  DELETE FROM discography WHERE discography.idArtist = old.idArtist;"
+              "  DELETE FROM art WHERE media_id=old.idArtist AND media_type='artist';"
+              " END");
+  m_pDS->exec("CREATE TRIGGER tgrDeleteSong AFTER delete ON song FOR EACH ROW BEGIN"
+              "  DELETE FROM song_artist WHERE song_artist.idSong = old.idSong;"
+              "  DELETE FROM song_genre WHERE song_genre.idSong = old.idSong;"
+              "  DELETE FROM karaokedata WHERE karaokedata.idSong = old.idSong;"
+              "  DELETE FROM art WHERE media_id=old.idSong AND media_type='song';"
+              " END");
+
+  // we create views last to ensure all indexes are rolled in
+  CreateViews();
 }
 
 void CMusicDatabase::CreateViews()
 {
   CLog::Log(LOGINFO, "create song view");
-  m_pDS->exec("DROP VIEW IF EXISTS songview");
   m_pDS->exec("CREATE VIEW songview AS SELECT "
               "        song.idSong AS idSong, "
               "        song.strArtists AS strArtists,"
@@ -306,7 +276,6 @@ void CMusicDatabase::CreateViews()
               "    song.idSong=karaokedata.idSong");
 
   CLog::Log(LOGINFO, "create album view");
-  m_pDS->exec("DROP VIEW IF EXISTS albumview");
   m_pDS->exec("CREATE VIEW albumview AS SELECT "
               "        album.idAlbum AS idAlbum, "
               "        strAlbum, "
@@ -323,11 +292,13 @@ void CMusicDatabase::CreateViews()
               "        album.strImage as strImage, "
               "        iRating, "
               "        bCompilation, "
-              "        (SELECT MIN(iTimesPlayed) AS iTimesPlayed FROM song WHERE song.idAlbum = album.idAlbum)"
-              "   FROM album  ");
+              "        MIN(song.iTimesPlayed) AS iTimesPlayed "
+              "FROM album"
+              " LEFT OUTER JOIN song ON"
+              "   album.idAlbum=song.idAlbum "
+              "GROUP BY album.idAlbum");
 
   CLog::Log(LOGINFO, "create artist view");
-  m_pDS->exec("DROP VIEW IF EXISTS artistview");
   m_pDS->exec("CREATE VIEW artistview AS SELECT"
               "  idArtist, strArtist, "
               "  strMusicBrainzArtistID, "
@@ -337,8 +308,7 @@ void CMusicDatabase::CreateViews()
               "  strYearsActive, strImage, strFanart "
               "FROM artist");
 
-  CLog::Log(LOGINFO, "create albumartistview");
-  m_pDS->exec("DROP VIEW IF EXISTS albumartistview");
+  CLog::Log(LOGINFO, "create albumartist view");
   m_pDS->exec("CREATE VIEW albumartistview AS SELECT"
               "  album_artist.idAlbum AS idAlbum, "
               "  album_artist.idArtist AS idArtist, "
@@ -350,8 +320,8 @@ void CMusicDatabase::CreateViews()
               "FROM album_artist "
               "JOIN artist ON "
               "     album_artist.idArtist = artist.idArtist");
-  CLog::Log(LOGINFO, "create songartistview");
-  m_pDS->exec("DROP VIEW IF EXISTS songartistview");
+
+  CLog::Log(LOGINFO, "create songartist view");
   m_pDS->exec("CREATE VIEW songartistview AS SELECT"
               "  song_artist.idSong AS idSong, "
               "  song_artist.idArtist AS idArtist, "
@@ -1588,7 +1558,7 @@ CSong CMusicDatabase::GetSongFromDataset(const dbiplus::sql_record* const record
   song.albumArtist = StringUtils::Split(record->at(offset + song_strAlbumArtists).get_asString(), g_advancedSettings.m_musicItemSeparator);
 
   // Get filename with full path
-  song.strFileName = URIUtils::AddFileToFolder(record->at(song_strPath).get_asString(), record->at(song_strFileName).get_asString());
+  song.strFileName = URIUtils::AddFileToFolder(record->at(offset + song_strPath).get_asString(), record->at(offset + song_strFileName).get_asString());
   return song;
 }
 
@@ -2997,13 +2967,13 @@ bool CMusicDatabase::GetYearsNav(const CStdString& strBaseDir, CFileItemList& it
     // get data from returned rows
     while (!m_pDS->eof())
     {
-      CFileItemPtr pItem(new CFileItem(m_pDS->fv("iYear").get_asString()));
+      CFileItemPtr pItem(new CFileItem(m_pDS->fv(0).get_asString()));
       SYSTEMTIME stTime;
-      stTime.wYear = (WORD)m_pDS->fv("iYear").get_asInt();
+      stTime.wYear = (WORD)m_pDS->fv(0).get_asInt();
       pItem->GetMusicInfoTag()->SetReleaseDate(stTime);
 
       CMusicDbUrl itemUrl = musicUrl;
-      CStdString strDir = StringUtils::Format("%ld/", m_pDS->fv("iYear").get_asInt());
+      CStdString strDir = StringUtils::Format("%ld/", m_pDS->fv(0).get_asInt());
       itemUrl.AppendPath(strDir);
       pItem->SetPath(itemUrl.ToString());
 
@@ -3585,103 +3555,8 @@ bool CMusicDatabase::GetSongsNav(const CStdString& strBaseDir, CFileItemList& it
   return GetSongsByWhere(musicUrl.ToString(), filter, items, sortDescription);
 }
 
-bool CMusicDatabase::UpdateOldVersion(int version)
-{
-  if (version < 16)
-  {
-    // only if MySQL is used and default character set is not utf8
-    // string data needs to be converted to proper utf8
-    CStdString charset = m_pDS->getDatabase()->getDefaultCharset();
-    if (!m_sqlite && !charset.empty() && charset != "utf8")
-    {
-      map<CStdString, CStdStringArray> tables;
-      map<CStdString, CStdStringArray>::iterator itt;
-      CStdStringArray::iterator itc;
-
-      //columns that need to be converted
-      CStdStringArray c1;
-      c1.push_back("strAlbum");
-      c1.push_back("strExtraArtists");
-      c1.push_back("strExtraGenres");
-      tables.insert(pair<CStdString, CStdStringArray> ("album", c1));
-
-      CStdStringArray c2;
-      c2.push_back("strExtraGenres");
-      c2.push_back("strMoods");
-      c2.push_back("strStyles");
-      c2.push_back("strThemes");
-      c2.push_back("strReview");
-      c2.push_back("strLabel");
-      tables.insert(pair<CStdString, CStdStringArray> ("albuminfo", c2));
-
-      CStdStringArray c3;
-      c3.push_back("strTitle");
-      tables.insert(pair<CStdString, CStdStringArray> ("albuminfosong", c3));
-
-      CStdStringArray c4;
-      c4.push_back("strArtist");
-      tables.insert(pair<CStdString, CStdStringArray> ("artist", c4));
-
-      CStdStringArray c5;
-      c5.push_back("strBorn");
-      c5.push_back("strFormed");
-      c5.push_back("strGenres");
-      c5.push_back("strMoods");
-      c5.push_back("strStyles");
-      c5.push_back("strInstruments");
-      c5.push_back("strBiography");
-      c5.push_back("strDied");
-      c5.push_back("strDisbanded");
-      c5.push_back("strYearsActive");
-      tables.insert(pair<CStdString, CStdStringArray> ("artistinfo", c5));
-
-      CStdStringArray c6;
-      c6.push_back("strAlbum");
-      tables.insert(pair<CStdString, CStdStringArray> ("discography", c6));
-
-      CStdStringArray c7;
-      c7.push_back("strGenre");
-      tables.insert(pair<CStdString, CStdStringArray> ("genre", c7));
-
-      CStdStringArray c8;
-      c8.push_back("strKaraLyrics");
-      tables.insert(pair<CStdString, CStdStringArray> ("karaokedata", c8));
-
-      CStdStringArray c9;
-      c9.push_back("strTitle");
-      c9.push_back("strFilename");
-      c9.push_back("comment");
-      tables.insert(pair<CStdString, CStdStringArray> ("song", c9));
-
-      CStdStringArray c10;
-      c10.push_back("strPath");
-      tables.insert(pair<CStdString, CStdStringArray> ("path", c10));
-
-      for (itt = tables.begin(); itt != tables.end(); ++itt)
-      {
-        CStdString q;
-        q = PrepareSQL("UPDATE `%s` SET", itt->first.c_str());
-        for (itc = itt->second.begin(); itc != itt->second.end(); ++itc)
-        {
-          q += PrepareSQL(" `%s` = CONVERT(CAST(CONVERT(`%s` USING %s) AS BINARY) USING utf8)",
-                          itc->c_str(), itc->c_str(), charset.c_str());
-          if (*itc != itt->second.back())
-          {
-            q += ", ";
-          }
-        }
-        m_pDS->exec(q);
-      }
-    }
-  }
-  if (version < 17)
-  {
-    m_pDS->exec("CREATE INDEX idxAlbum2 ON album(idArtist)");
-    m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
-    m_pDS->exec("CREATE INDEX idxSong4 ON song(idArtist)");
-    m_pDS->exec("CREATE INDEX idxSong5 ON song(idGenre)");
-    m_pDS->exec("CREATE INDEX idxSong6 ON song(idPath)");
-  }
+void CMusicDatabase::UpdateTables(int version)
+{
   if (version < 19)
   {
     int len = g_advancedSettings.m_musicItemSeparator.size() + 1;
@@ -3694,9 +3569,6 @@ bool CMusicDatabase::UpdateOldVersion(int version)
   if (version < 21)
   {
     m_pDS->exec("CREATE TABLE album_artist ( idArtist integer, idAlbum integer, boolFeatured integer, iOrder integer )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_1 ON album_artist ( idAlbum, idArtist )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumArtist_2 ON album_artist ( idArtist, idAlbum )\n");
-    m_pDS->exec("CREATE INDEX idxAlbumArtist_3 ON album_artist ( boolFeatured )\n");
     m_pDS->exec("INSERT INTO album_artist (idArtist, idAlbum, boolFeatured, iOrder) SELECT idArtist, idAlbum, 1, iPosition FROM exartistalbum");
     m_pDS->exec("REPLACE INTO album_artist (idArtist, idAlbum, boolFeatured, iOrder) SELECT idArtist, idAlbum, 0, 0 FROM album");
 
@@ -3704,11 +3576,7 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     strSQL=PrepareSQL("SELECT album.idAlbum AS idAlbum, strExtraArtists,"
                       "  album.idArtist AS idArtist, strArtist FROM album "
                       "  LEFT OUTER JOIN artist ON album.idArtist=artist.idArtist");
-    if (!m_pDS->query(strSQL.c_str()))
-    {
-      CLog::Log(LOGDEBUG, "%s could not upgrade albums table", __FUNCTION__);
-      return false;
-    }
+    m_pDS->query(strSQL.c_str());
 
     VECALBUMS albums;
     while (!m_pDS->eof())
@@ -3737,16 +3605,12 @@ bool CMusicDatabase::UpdateOldVersion(int version)
 
     m_pDS->exec("DROP TABLE album");
     m_pDS->exec("ALTER TABLE album_new RENAME TO album");
-    m_pDS->exec("CREATE INDEX idxAlbum ON album(strAlbum)");
     m_pDS->exec("DROP TABLE IF EXISTS exartistalbum");
   }
 
   if (version < 22)
   {
     m_pDS->exec("CREATE TABLE song_artist ( idArtist integer, idSong integer, boolFeatured integer, iOrder integer )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_1 ON song_artist ( idSong, idArtist )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongArtist_2 ON song_artist ( idArtist, idSong )\n");
-    m_pDS->exec("CREATE INDEX idxSongArtist_3 ON song_artist ( boolFeatured )\n");
     m_pDS->exec("INSERT INTO song_artist (idArtist, idSong, boolFeatured, iOrder) SELECT idArtist, idSong, 1, iPosition FROM exartistsong");
     m_pDS->exec("REPLACE INTO song_artist (idArtist, idSong, boolFeatured, iOrder) SELECT idArtist, idSong, 0, 0 FROM song");
 
@@ -3754,11 +3618,7 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     strSQL=PrepareSQL("SELECT song.idSong AS idSong, strExtraArtists,"
                       "  song.idArtist AS idArtist, strArtist FROM song "
                       "  LEFT OUTER JOIN artist ON song.idArtist=artist.idArtist");
-    if (!m_pDS->query(strSQL.c_str()))
-    {
-      CLog::Log(LOGDEBUG, "%s could not upgrade songs table", __FUNCTION__);
-      return false;
-    }
+    m_pDS->query(strSQL.c_str());
 
     VECSONGS songs;
     while (!m_pDS->eof())
@@ -3787,19 +3647,12 @@ bool CMusicDatabase::UpdateOldVersion(int version)
 
     m_pDS->exec("DROP TABLE song");
     m_pDS->exec("ALTER TABLE song_new RENAME TO song");
-    m_pDS->exec("CREATE INDEX idxSong ON song(strTitle)");
-    m_pDS->exec("CREATE INDEX idxSong1 ON song(iTimesPlayed)");
-    m_pDS->exec("CREATE INDEX idxSong2 ON song(lastplayed)");
-    m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
-    m_pDS->exec("CREATE INDEX idxSong6 ON song(idPath)");
     m_pDS->exec("DROP TABLE IF EXISTS exartistsong");
   }
 
   if (version < 23)
   {
     m_pDS->exec("CREATE TABLE album_genre ( idGenre integer, idAlbum integer, iOrder integer )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_1 ON album_genre ( idAlbum, idGenre )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbumGenre_2 ON album_genre ( idGenre, idAlbum )\n");
     m_pDS->exec("INSERT INTO album_genre ( idGenre, idAlbum, iOrder) SELECT idGenre, idAlbum, iPosition FROM exgenrealbum");
     m_pDS->exec("REPLACE INTO album_genre ( idGenre, idAlbum, iOrder) SELECT idGenre, idAlbum, 0 FROM album");
 
@@ -3807,11 +3660,7 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     strSQL=PrepareSQL("SELECT album.idAlbum AS idAlbum, strExtraGenres,"
                       "  album.idGenre AS idGenre, strGenre FROM album "
                       "  JOIN genre ON album.idGenre=genre.idGenre");
-    if (!m_pDS->query(strSQL.c_str()))
-    {
-      CLog::Log(LOGDEBUG, "%s could not upgrade albums table", __FUNCTION__);
-      return false;
-    }
+    m_pDS->query(strSQL.c_str());
 
     VECALBUMS albums;
     while (!m_pDS->eof())
@@ -3840,15 +3689,12 @@ bool CMusicDatabase::UpdateOldVersion(int version)
 
     m_pDS->exec("DROP TABLE album");
     m_pDS->exec("ALTER TABLE album_new RENAME TO album");
-    m_pDS->exec("CREATE INDEX idxAlbum ON album(strAlbum)");
     m_pDS->exec("DROP TABLE IF EXISTS exgenrealbum");
   }
 
   if (version < 24)
   {
     m_pDS->exec("CREATE TABLE song_genre ( idGenre integer, idSong integer, iOrder integer )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_1 ON song_genre ( idSong, idGenre )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSongGenre_2 ON song_genre ( idGenre, idSong )\n");
     m_pDS->exec("INSERT INTO song_genre ( idGenre, idSong, iOrder) SELECT idGenre, idSong, iPosition FROM exgenresong");
     m_pDS->exec("REPLACE INTO song_genre ( idGenre, idSong, iOrder) SELECT idGenre, idSong, 0 FROM song");
 
@@ -3856,11 +3702,7 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     strSQL=PrepareSQL("SELECT song.idSong AS idSong, strExtraGenres,"
                       "  song.idGenre AS idGenre, strGenre FROM song "
                       "  JOIN genre ON song.idGenre=genre.idGenre");
-    if (!m_pDS->query(strSQL.c_str()))
-    {
-      CLog::Log(LOGDEBUG, "%s could not upgrade songs table", __FUNCTION__);
-      return false;
-    }
+    m_pDS->query(strSQL.c_str());
 
     VECSONGS songs;
     while (!m_pDS->eof())
@@ -3889,32 +3731,22 @@ bool CMusicDatabase::UpdateOldVersion(int version)
 
     m_pDS->exec("DROP TABLE song");
     m_pDS->exec("ALTER TABLE song_new RENAME TO song");
-    m_pDS->exec("CREATE INDEX idxSong ON song(strTitle)");
-    m_pDS->exec("CREATE INDEX idxSong1 ON song(iTimesPlayed)");
-    m_pDS->exec("CREATE INDEX idxSong2 ON song(lastplayed)");
-    m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
-    m_pDS->exec("CREATE INDEX idxSong6 ON song(idPath)");
     m_pDS->exec("DROP TABLE IF EXISTS exgenresong");
   }
 
   if (version < 25)
   {
     m_pDS->exec("ALTER TABLE album ADD bCompilation integer not null default '0'");
-    m_pDS->exec("CREATE INDEX idxAlbum_1 ON album(bCompilation)");
   }
 
   if (version < 26)
   { // add art table
     m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
-    m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
-    m_pDS->exec("CREATE TRIGGER delete_song AFTER DELETE ON song FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idSong AND media_type='song'; END");
-    m_pDS->exec("CREATE TRIGGER delete_album AFTER DELETE ON album FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idAlbum AND media_type='album'; END");
-    m_pDS->exec("CREATE TRIGGER delete_artist AFTER DELETE ON artist FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idArtist AND media_type='artist'; END");
   }
 
   if (version < 27)
   {
-    m_pDS->exec("DROP TABLE thumb");
+    m_pDS->exec("DROP TABLE IF EXISTS thumb");
 
     CMediaSettings::Get().SetMusicNeedsUpdate(27);
     CSettings::Get().Save();
@@ -3951,11 +3783,6 @@ bool CMusicDatabase::UpdateOldVersion(int version)
         m_pDS->exec(PrepareSQL("UPDATE song SET strFileName='%s' WHERE idSong=%d", filename.c_str(), i->first));
     }
   }
-  if (version < 33)
-  {
-    m_pDS->exec("DROP INDEX idxSong6 ON song");
-    m_pDS->exec("CREATE INDEX idxSong6 on song( idPath, strFileName(255) )");
-  }
 
   if (version < 34)
   {
@@ -3966,20 +3793,12 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     
     m_pDS->exec("DROP TABLE song");
     m_pDS->exec("ALTER TABLE song_new RENAME TO song");
-    m_pDS->exec("CREATE INDEX idxSong ON song(strTitle)");
-    m_pDS->exec("CREATE INDEX idxSong1 ON song(iTimesPlayed)");
-    m_pDS->exec("CREATE INDEX idxSong2 ON song(lastplayed)");
-    m_pDS->exec("CREATE INDEX idxSong3 ON song(idAlbum)");
-    m_pDS->exec("CREATE INDEX idxSong6 ON song(idPath)");
-
     m_pDS->exec("UPDATE song SET strMusicBrainzTrackID = NULL");
-    m_pDS->exec("CREATE UNIQUE INDEX idxArtist1 ON artist(strMusicBrainzArtistID(36))");
   }
 
   if (version < 35)
   {
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbum_2 ON album(strMusicBrainzAlbumID(36))");
-    m_pDS->exec("CREATE UNIQUE INDEX idxSong7 ON song( idAlbum, strMusicBrainzTrackID(36) )");
     m_pDS->exec("ALTER TABLE album_artist ADD strJoinPhrase text\n");
     m_pDS->exec("ALTER TABLE song_artist ADD strJoinPhrase text\n");
     CMediaSettings::Get().SetMusicNeedsUpdate(35);
@@ -4007,12 +3826,6 @@ bool CMusicDatabase::UpdateOldVersion(int version)
       }
     }
   }
-  if (version < 37)
-  {
-    m_pDS->exec("DROP INDEX idxSong6 ON song");
-    m_pDS->exec("CREATE INDEX idxSong6 on song( idPath, strFileName(255) )");
-  }
 
   if (version < 39)
   {
@@ -4049,7 +3862,6 @@ bool CMusicDatabase::UpdateOldVersion(int version)
                 " strType, iRating "
                 " FROM album LEFT JOIN albuminfo ON album.idAlbum = albuminfo.idAlbum");
     m_pDS->exec("UPDATE albuminfosong SET idAlbumInfo = (SELECT idAlbum FROM albuminfo WHERE albuminfo.idAlbumInfo = albuminfosong.idAlbumInfo)");
-    m_pDS->exec("CREATE INDEX idxAlbumInfoSong_1 ON albuminfosong ( idAlbumInfo )\n");
     m_pDS->exec(PrepareSQL("UPDATE album_new SET lastScraped='%s' WHERE idAlbum IN (SELECT idAlbum FROM albuminfo)", CDateTime::GetCurrentDateTime().GetAsDBDateTime().c_str()));
     m_pDS->exec("DROP TABLE album");
     m_pDS->exec("DROP TABLE albuminfo");
@@ -4084,7 +3896,6 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     m_pDS->exec("DROP TABLE artist");
     m_pDS->exec("DROP TABLE artistinfo");
     m_pDS->exec("ALTER TABLE artist_new RENAME TO artist");
-    m_pDS->exec("CREATE INDEX idxDiscography_1 ON discography ( idArtist )\n");
   }
   if (version < 42)
   {
@@ -4104,67 +3915,11 @@ bool CMusicDatabase::UpdateOldVersion(int version)
     m_pDS->exec("UPDATE song_artist SET strJoinPhrase = '' WHERE 100*idSong+iOrder IN (SELECT id FROM (SELECT 100*idSong+max(iOrder) AS id FROM song_artist GROUP BY idSong) AS sub)");
     m_pDS->exec("UPDATE album_artist SET strJoinPhrase = '' WHERE 100*idAlbum+iOrder IN (SELECT id FROM (SELECT 100*idAlbum+max(iOrder) AS id FROM album_artist GROUP BY idAlbum) AS sub)");
   }
-  if (version < 43)
-  { // (re)create triggers
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrAlbumSong");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrAlbumArtist");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrAlbumGenre");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrAlbumInfoSong");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrArtistAlbum");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrArtistSong");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrArtistDiscography");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrSongArtist");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrSongGenre");
-    m_pDS->exec("DROP TRIGGER IF EXISTS tgrSongKaraokedata");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_song");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_album");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_artist");
-
-    m_pDS->exec("CREATE TRIGGER delete_album AFTER delete ON album FOR EACH ROW BEGIN"
-                "  DELETE FROM song WHERE song.idAlbum = old.idAlbum;"
-                "  DELETE FROM album_artist WHERE album_artist.idAlbum = old.idAlbum;"
-                "  DELETE FROM album_genre WHERE album_genre.idAlbum = old.idAlbum;"
-                "  DELETE FROM albuminfosong WHERE albuminfosong.idAlbumInfo=old.idAlbum;"
-                "  DELETE FROM art WHERE media_id=old.idAlbum AND media_type='album';"
-                " END");
-    m_pDS->exec("CREATE TRIGGER delete_artist AFTER delete ON artist FOR EACH ROW BEGIN"
-                "  DELETE FROM album_artist WHERE album_artist.idArtist = old.idArtist;"
-                "  DELETE FROM song_artist WHERE song_artist.idArtist = old.idArtist;"
-                "  DELETE FROM discography WHERE discography.idArtist = old.idArtist;"
-                "  DELETE FROM art WHERE media_id=old.idArtist AND media_type='artist';"
-                " END");
-    m_pDS->exec("CREATE TRIGGER delete_song AFTER delete ON song FOR EACH ROW BEGIN"
-                "  DELETE FROM song_artist WHERE song_artist.idSong = old.idSong;"
-                "  DELETE FROM song_genre WHERE song_genre.idSong = old.idSong;"
-                "  DELETE FROM karaokedata WHERE karaokedata.idSong = old.idSong;"
-                "  DELETE FROM art WHERE media_id=old.idSong AND media_type='song';"
-                " END");
-  }
-  if (version < 44)
-  {
-    m_pDS->exec("CREATE INDEX idxAlbum ON album(strAlbum(255))");
-    m_pDS->exec("CREATE INDEX idxAlbum_1 ON album(bCompilation)");
-    m_pDS->exec("CREATE UNIQUE INDEX idxAlbum_2 ON album(strMusicBrainzAlbumID(36))");
-
-    m_pDS->exec("CREATE INDEX idxArtist ON artist(strArtist(255))");
-    m_pDS->exec("CREATE UNIQUE INDEX idxArtist1 ON artist(strMusicBrainzArtistID(36))");
-
-    m_pDS->exec("DROP INDEX idxGenre ON genre");
-    m_pDS->exec("CREATE INDEX idxGenre ON genre(strGenre(255))");
-    m_pDS->exec("DROP INDEX idxPath ON path");
-    m_pDS->exec("CREATE INDEX idxPath ON path(strPath(255))");
-    m_pDS->exec("DROP INDEX idxSong ON song");
-    m_pDS->exec("CREATE INDEX idxSong ON song(strTitle(255))");
-  }
-  // always recreate the views after any table change
-  CreateViews();
-
-  return true;
 }
 
-int CMusicDatabase::GetMinVersion() const
+int CMusicDatabase::GetSchemaVersion() const
 {
-  return 44;
+  return 46;
 }
 
 unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, vector<pair<int,int> > &songIDs)
index 86bd366..4748658 100644 (file)
@@ -468,8 +468,10 @@ protected:
   std::map<CStdString, int> m_thumbCache;
   std::map<CStdString, CAlbum> m_albumCache;
 
-  virtual bool CreateTables();
-  virtual int GetMinVersion() const;
+  virtual void CreateTables();
+  virtual void CreateAnalytics();
+  virtual int GetMinSchemaVersion() const { return 18; }
+  virtual int GetSchemaVersion() const;
 
   const char *GetBaseDBName() const { return "MyMusic"; };
 
@@ -496,7 +498,7 @@ private:
   bool CleanupAlbums();
   bool CleanupArtists();
   bool CleanupGenres();
-  virtual bool UpdateOldVersion(int version);
+  virtual void UpdateTables(int version);
   bool SearchArtists(const CStdString& search, CFileItemList &artists);
   bool SearchAlbums(const CStdString& search, CFileItemList &albums);
   bool SearchSongs(const CStdString& strSearch, CFileItemList &songs);
index 44a2261..2886ab6 100644 (file)
@@ -36,15 +36,33 @@ CSong::CSong(CFileItem& item)
   strTitle = tag.GetTitle();
   genre = tag.GetGenre();
   artist = tag.GetArtist();
-  bool hasMusicBrainzArtist = !tag.GetMusicBrainzArtistID().empty();
-  const vector<string>& artists = hasMusicBrainzArtist ? tag.GetMusicBrainzArtistID() : tag.GetArtist();
-  for (vector<string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
-  {
-    CStdString artistName = hasMusicBrainzArtist && !artist.empty() ? artist[0] : *it;
-    CStdString artistId = hasMusicBrainzArtist ? *it : StringUtils::EmptyString;
-    CStdString strJoinPhrase = (it == --artists.end() ? "" : g_advancedSettings.m_musicItemSeparator);
-    CArtistCredit artistCredit(artistName, artistId, strJoinPhrase);
-    artistCredits.push_back(artistCredit);
+  if (!tag.GetMusicBrainzArtistID().empty())
+  { // have musicbrainz artist info, so use it
+    for (size_t i = 0; i < tag.GetMusicBrainzArtistID().size(); i++)
+    {
+      CStdString artistId = tag.GetMusicBrainzArtistID()[i];
+      CStdString artistName;
+      /*
+       We try and get the corresponding artist name from the album artist tag.
+       We match on the same index, and if that fails just use the first name we have.
+       */
+      if (!artist.empty())
+        artistName = (i < artist.size()) ? artist[i] : artist[0];
+      if (artistName.empty())
+        artistName = artistId;
+      CStdString strJoinPhrase = (i == tag.GetMusicBrainzArtistID().size()-1) ? "" : g_advancedSettings.m_musicItemSeparator;
+      CArtistCredit artistCredit(artistName, artistId, strJoinPhrase);
+      artistCredits.push_back(artistCredit);
+    }
+  }
+  else
+  { // no musicbrainz info, so fill in directly
+    for (vector<string>::const_iterator it = tag.GetArtist().begin(); it != tag.GetArtist().end(); ++it)
+    {
+      CStdString strJoinPhrase = (it == --tag.GetArtist().end() ? "" : g_advancedSettings.m_musicItemSeparator);
+      CArtistCredit artistCredit(*it, "", strJoinPhrase);
+      artistCredits.push_back(artistCredit);
+    }
   }
   strAlbum = tag.GetAlbum();
   albumArtist = tag.GetAlbumArtist();
index 9f7a2cc..0d98f9f 100644 (file)
@@ -29,6 +29,7 @@
 #ifdef TARGET_WINDOWS
 #include "utils/SystemInfo.h"
 #include "win32/WIN32Util.h"
+#include "utils/CharsetConverter.h"
 #endif
 
 /* slightly modified in_ether taken from the etherboot project (http://sourceforge.net/projects/etherboot) */
@@ -162,8 +163,14 @@ CStdString CNetwork::GetHostName(void)
   char hostName[128];
   if (gethostname(hostName, sizeof(hostName)))
     return CStdString("unknown");
-  else
-    return CStdString(hostName);
+
+  std::string hostStr;
+#ifdef TARGET_WINDOWS
+  g_charsetConverter.systemToUtf8(hostName, hostStr);
+#else
+  hostStr = hostName;
+#endif
+  return hostStr;
 }
 
 CNetworkInterface* CNetwork::GetFirstConnectedInterface()
index bbcf286..0b7a3cc 100644 (file)
@@ -356,6 +356,9 @@ bool CWakeOnAccess::WakeUpHost (const CStdString& hostName, const string& custom
 
     bool ret = WakeUpHost(server);
 
+    if (!ret) // extra log if we fail for some reason
+      CLog::Log(LOGWARNING,"WakeOnAccess failed to bring up [%s] - there may be trouble ahead !", hostName.c_str());
+
     TouchHostEntry(hostName);
 
     return ret;
@@ -416,11 +419,12 @@ bool CWakeOnAccess::WakeUpHost(const WakeUpEntry& server)
     }
   }
 
+  // we have ping response ; just add extra wait-for-services before returning if requested
+
   {
     WaitCondition waitObj ; // wait uninteruptable fixed time for services ..
 
-    if (ProgressDialogHelper::Success != dlg.ShowAndWait (waitObj, server.wait_services_sec, LOCALIZED(13032)))
-      return false;
+    dlg.ShowAndWait (waitObj, server.wait_services_sec, LOCALIZED(13032));
 
     CLog::Log(LOGNOTICE,"WakeOnAccess sequence completed, server started");
   }
@@ -635,18 +639,16 @@ void CWakeOnAccess::OnSettingsLoaded()
   LoadFromXML();
 }
 
-void CWakeOnAccess::OnSettingsSaved() const
+void CWakeOnAccess::OnSettingsSaved()
 {
   bool enabled = CSettings::Get().GetBool("powermanagement.wakeonaccess");
 
   if (enabled != IsEnabled())
   {
-    CWakeOnAccess& woa = CWakeOnAccess::Get();
-
-    woa.SetEnabled(enabled);
+    SetEnabled(enabled);
 
     if (enabled)
-      woa.QueueMACDiscoveryForAllRemotes();
+      QueueMACDiscoveryForAllRemotes();
   }
 }
 
index ccd81a4..ca61c02 100644 (file)
@@ -35,7 +35,7 @@ public:
 
   virtual void OnJobComplete(unsigned int jobID, bool success, CJob *job);
   virtual void OnSettingsLoaded();
-  virtual void OnSettingsSaved() const;
+  virtual void OnSettingsSaved();
 
   // struct to keep per host settings
   struct WakeUpEntry
index 72c7e96..c591203 100644 (file)
@@ -250,15 +250,24 @@ int CUPnPPlayer::PlayFile(const CFileItem& file, const CPlayerOptions& options,
   NPT_Cardinal res_index;
   NPT_CHECK_LABEL_SEVERE(m_control->FindBestResource(m_delegate->m_device, *obj, res_index), failed);
 
-
+  // get the transport info to evaluate the TransportState to be able to
+  // determine whether we first need to call Stop()
   timeout.Set(timeout.GetInitialTimeoutValue());
-  /* dlna specifies that a return code of 705 should be returned
-   * if TRANSPORT_STATE is not STOPPED or NO_MEDIA_PRESENT */
-  NPT_CHECK_LABEL_SEVERE(m_control->Stop(m_delegate->m_device
-                                         , m_delegate->m_instance
-                                         , m_delegate), failed);
-  NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed);
-  NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed);
+  NPT_CHECK_LABEL_SEVERE(m_control->GetTransportInfo(m_delegate->m_device
+                                                     , m_delegate->m_instance
+                                                     , m_delegate), failed);
+  NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_traevnt, timeout, dialog), failed);
+
+  if (m_delegate->m_trainfo.cur_transport_state != "NO_MEDIA_PRESENT" &&
+      m_delegate->m_trainfo.cur_transport_state != "STOPPED")
+  {
+    timeout.Set(timeout.GetInitialTimeoutValue());
+    NPT_CHECK_LABEL_SEVERE(m_control->Stop(m_delegate->m_device
+                                           , m_delegate->m_instance
+                                           , m_delegate), failed);
+    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed);
+    NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed);
+  }
 
 
   timeout.Set(timeout.GetInitialTimeoutValue());
index 0c8f552..b3eb934 100644 (file)
@@ -35,6 +35,7 @@
 #include "utils/log.h"
 #include "utils/TimeUtils.h"
 #include "Util.h"
+#include "XbmcContext.h"
 #undef BOOL
 
 #import <QuartzCore/QuartzCore.h>
 - (void) runAnimation:(id) arg
 {
   CCocoaAutoPool outerpool;
+  // set up some xbmc specific relationships
+  XBMC::Context context;
   bool readyToRun = true;
 
   // signal we are alive
index 1fe7f7a..ad2a7cb 100644 (file)
@@ -29,6 +29,7 @@
 #include "Application.h"
 #include "WindowingFactory.h"
 #include "settings/DisplaySettings.h"
+#include "cores/AudioEngine/AEFactory.h"
 #undef BOOL
 
 #import <Foundation/Foundation.h>
@@ -205,6 +206,10 @@ static CEvent screenChangeEvent;
   {
     [self changeScreenSelector:dict];
   }
+
+  // re-enumerate audio devices in that case too
+  // as we might gain passthrough capabilities via HDMI
+  CAEFactory::DeviceChange();
   return true;
 }
 //--------------------------------------------------------------
index cd21b9a..c870a75 100644 (file)
@@ -29,6 +29,7 @@ class CIOSKeyboard : public CGUIKeyboard
     virtual void Cancel();
     void fireCallback(const std::string &str);
     void invalidateCallback(){m_pCharCallback = NULL;}
+    virtual bool SetTextToKeyboard(const std::string &text, bool closeKeyboard = false);
 
   private:
     char_callback_t m_pCharCallback;
index c98ebcc..74c4c7a 100644 (file)
@@ -80,6 +80,14 @@ void CIOSKeyboard::Cancel()
   m_bCanceled = true;
 }
 
+bool CIOSKeyboard::SetTextToKeyboard(const std::string &text, bool closeKeyboard /* = false */)
+{
+  if (!g_pIosKeyboard)
+    return false;
+  [g_pIosKeyboard setKeyboardText:[NSString stringWithUTF8String:text.c_str()] closeKeyboard:closeKeyboard?YES:NO];
+  return true;
+}
+
 //wrap our callback between objc and c++
 void CIOSKeyboard::fireCallback(const std::string &str)
 {
index 8392d2a..834276a 100644 (file)
@@ -43,6 +43,7 @@
 - (void) setHidden:(BOOL)hidden;
 - (void) activate;
 - (void) deactivate;
+- (void) setKeyboardText:(NSString*)aText closeKeyboard:(BOOL)closeKeyboard;
 - (void) textChanged:(NSNotification*)aNotification;
 - (void) setCancelFlag:(bool *)cancelFlag;
 - (void) doDeactivate:(NSDictionary *)dict;
index 8fb6f55..e56cd0a 100644 (file)
@@ -261,6 +261,24 @@ static CEvent keyboardFinishedEvent;
   }
 }
 
+- (void) setKeyboardText:(NSString*)aText closeKeyboard:(BOOL)closeKeyboard
+{
+  LOG(@"%s: %@, %d", __PRETTY_FUNCTION__, aText, closeKeyboard);
+  if([NSThread currentThread] != [NSThread mainThread])
+  {
+    [self performSelectorOnMainThread:@selector(setDefault:) withObject:aText  waitUntilDone:YES];
+  }
+  else
+  {
+    [self setDefault:aText];
+  }
+  if (closeKeyboard)
+  {
+    _confirmed = YES;
+    [self deactivate];
+  }
+}
+
 - (void) setHeading:(NSString *)heading
 {
   if (heading && heading.length > 0) {
index e2cd79e..de67d37 100644 (file)
@@ -21,6 +21,6 @@
 #import <UIKit/UIKit.h>
 #import <AVFoundation/AVFoundation.h>
 
-@interface XBMCApplicationDelegate : NSObject <UIApplicationDelegate, AVAudioSessionDelegate> {
+@interface XBMCApplicationDelegate : NSObject <UIApplicationDelegate> {
 }
 @end
index 91930e8..22a0f00 100644 (file)
@@ -131,26 +131,6 @@ XBMCController *m_xbmcController;
   {
     ELOG(@"AVAudioSession setActive failed: %@", err);
   }
-  [[AVAudioSession sharedInstance] setDelegate:self];
-}
-
-- (void)beginInterruption
-{
-  PRINT_SIGNATURE();
-  [m_xbmcController beginInterruption];
-}
-- (void)endInterruptionWithFlags:(NSUInteger)flags
-{
-  LOG(@"%s: %d", __PRETTY_FUNCTION__, flags);
-  if (flags & AVAudioSessionInterruptionFlags_ShouldResume)
-  {
-    NSError *err = nil;
-    if (![[AVAudioSession sharedInstance] setActive: YES error: &err])
-    {
-      ELOG(@"AVAudioSession::endInterruption setActive failed: %@", err);
-    }
-    [m_xbmcController endInterruption];
-  }
 }
 
 - (void)dealloc
index 80c6789..75fbd65 100644 (file)
@@ -51,7 +51,6 @@ typedef enum
   UIInterfaceOrientation orientation;
   
   bool m_isPlayingBeforeInactive;
-  bool m_isInterrupted;
   UIBackgroundTaskIdentifier m_bgTask;
   NSTimer *m_networkAutoSuspendTimer;
   IOSPlaybackState m_playbackState;
@@ -74,8 +73,6 @@ typedef enum
 - (void) enterBackground;
 - (void) enterForeground;
 - (void) becomeInactive;
-- (void) beginInterruption;
-- (void) endInterruption;
 - (void) setIOSNowPlayingInfo:(NSDictionary *)info;
 - (void) sendKey: (XBMCKey) key;
 - (void) observeDefaultCenterStuff: (NSNotification *) notification;
index 693a5fc..d234d42 100644 (file)
@@ -31,7 +31,6 @@
 #include "MusicInfoTag.h"
 #include "SpecialProtocol.h"
 #include "PlayList.h"
-#include "AEFactory.h"
 #include "ApplicationMessenger.h"
 #include "Application.h"
 #include "interfaces/AnnouncementManager.h"
@@ -192,12 +191,10 @@ void AnnounceBridge(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, con
   }
   else if (msg == "OnPause")
   {
-    CAEFactory::Suspend();
     [g_xbmcController performSelectorOnMainThread:@selector(onPause:) withObject:[dict valueForKey:@"item"]  waitUntilDone:NO];
   }
   else if (msg == "OnStop")
   {
-    CAEFactory::Suspend();
     [g_xbmcController performSelectorOnMainThread:@selector(onStop:) withObject:[dict valueForKey:@"item"]  waitUntilDone:NO];
   }
 }
@@ -388,7 +385,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UITapGestureRecognizer *singleFingerSingleTap = [[UITapGestureRecognizer alloc]
                                                    initWithTarget:self action:@selector(handleSingleFingerSingleTap:)];
 
-  singleFingerSingleTap.delaysTouchesBegan = YES;
+  singleFingerSingleTap.delaysTouchesBegan = NO;
   singleFingerSingleTap.numberOfTapsRequired = 1;
   singleFingerSingleTap.numberOfTouchesRequired = 1;
 
@@ -401,7 +398,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UITapGestureRecognizer *doubleFingerSingleTap = [[UITapGestureRecognizer alloc]
     initWithTarget:self action:@selector(handleDoubleFingerSingleTap:)];  
 
-  doubleFingerSingleTap.delaysTouchesBegan = YES;
+  doubleFingerSingleTap.delaysTouchesBegan = NO;
   doubleFingerSingleTap.numberOfTapsRequired = 1;
   doubleFingerSingleTap.numberOfTouchesRequired = 2;
   [m_glView addGestureRecognizer:doubleFingerSingleTap];
@@ -411,8 +408,8 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UILongPressGestureRecognizer *singleFingerSingleLongTap = [[UILongPressGestureRecognizer alloc]
     initWithTarget:self action:@selector(handleSingleFingerSingleLongTap:)];  
 
-  singleFingerSingleLongTap.delaysTouchesBegan = YES;
-  singleFingerSingleLongTap.delaysTouchesEnded = YES;
+  singleFingerSingleLongTap.delaysTouchesBegan = NO;
+  singleFingerSingleLongTap.delaysTouchesEnded = NO;
   [m_glView addGestureRecognizer:singleFingerSingleLongTap];
   [singleFingerSingleLongTap release];
 
@@ -420,7 +417,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UISwipeGestureRecognizer *swipeLeft2 = [[UISwipeGestureRecognizer alloc]
                                             initWithTarget:self action:@selector(handleSwipe:)];
 
-  swipeLeft2.delaysTouchesBegan = YES;
+  swipeLeft2.delaysTouchesBegan = NO;
   swipeLeft2.numberOfTouchesRequired = 2;
   swipeLeft2.direction = UISwipeGestureRecognizerDirectionLeft;
   swipeLeft2.delegate = self;
@@ -431,7 +428,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
                                           initWithTarget:self action:@selector(handleSwipe:)];
 
-  swipeLeft.delaysTouchesBegan = YES;
+  swipeLeft.delaysTouchesBegan = NO;
   swipeLeft.numberOfTouchesRequired = 1;
   swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
   swipeLeft.delegate = self;
@@ -442,7 +439,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleSwipe:)];
   
-  swipeRight.delaysTouchesBegan = YES;
+  swipeRight.delaysTouchesBegan = NO;
   swipeRight.numberOfTouchesRequired = 1;
   swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
   swipeRight.delegate = self;
@@ -453,7 +450,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleSwipe:)];
   
-  swipeUp.delaysTouchesBegan = YES;
+  swipeUp.delaysTouchesBegan = NO;
   swipeUp.numberOfTouchesRequired = 1;
   swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
   swipeUp.delegate = self;
@@ -464,7 +461,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleSwipe:)];
   
-  swipeDown.delaysTouchesBegan = YES;
+  swipeDown.delaysTouchesBegan = NO;
   swipeDown.numberOfTouchesRequired = 1;
   swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
   swipeDown.delegate = self;
@@ -475,7 +472,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
     initWithTarget:self action:@selector(handlePan:)];
 
-  pan.delaysTouchesBegan = YES;
+  pan.delaysTouchesBegan = NO;
   pan.maximumNumberOfTouches = 1;
   [m_glView addGestureRecognizer:pan];
   [pan release];
@@ -484,7 +481,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]
     initWithTarget:self action:@selector(handlePinch:)];
 
-  pinch.delaysTouchesBegan = YES;
+  pinch.delaysTouchesBegan = NO;
   pinch.delegate = self;
   [m_glView addGestureRecognizer:pinch];
   [pinch release];
@@ -493,7 +490,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleRotate:)];
 
-  rotate.delaysTouchesBegan = YES;
+  rotate.delaysTouchesBegan = NO;
   rotate.delegate = self;
   [m_glView addGestureRecognizer:rotate];
   [rotate release];
@@ -512,7 +509,19 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   [self becomeFirstResponder];
 }
 //--------------------------------------------------------------
--(void)handlePinch:(UIPinchGestureRecognizer*)sender 
+-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+  if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING
+  {
+    UITouch *touch = (UITouch *)[[touches allObjects] objectAtIndex:0];
+    CGPoint point = [touch locationInView:m_glView];
+    point.x *= screenScale;
+    point.y *= screenScale;
+    CGenericTouchActionHandler::Get().OnSingleTouchStart(point.x, point.y);
+  }
+}
+//--------------------------------------------------------------
+-(void)handlePinch:(UIPinchGestureRecognizer*)sender
 {
   if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING
   {
@@ -660,23 +669,6 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   }
 }
 //--------------------------------------------------------------
-- (void)postMouseMotionEvent:(CGPoint)point
-{
-  XBMC_Event newEvent;
-
-  memset(&newEvent, 0, sizeof(newEvent));
-
-  newEvent.type = XBMC_MOUSEMOTION;
-  newEvent.motion.type = XBMC_MOUSEMOTION;
-  newEvent.motion.which = 0;
-  newEvent.motion.state = 0;
-  newEvent.motion.x = point.x;
-  newEvent.motion.y = point.y;
-  newEvent.motion.xrel = 0;
-  newEvent.motion.yrel = 0;
-  CWinEvents::MessagePush(&newEvent);
-}
-//--------------------------------------------------------------
 - (IBAction)handleSingleFingerSingleTap:(UIGestureRecognizer *)sender 
 {
   if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING
@@ -713,7 +705,7 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
     {
       lastGesturePoint = point;
       // mark the control
-      CGenericTouchActionHandler::Get().OnSingleTouchStart((float)point.x, (float)point.y);
+      //CGenericTouchActionHandler::Get().OnSingleTouchStart((float)point.x, (float)point.y);
     }
 
     if (sender.state == UIGestureRecognizerStateEnded)
@@ -737,7 +729,6 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
     return ( nil );
 
   m_isPlayingBeforeInactive = NO;
-  m_isInterrupted = NO;
   m_bgTask = UIBackgroundTaskInvalid;
   m_playbackState = IOS_PLAYBACK_STOPPED;
 
@@ -1057,12 +1048,10 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
     CApplicationMessenger::Get().MediaUnPause();
     m_isPlayingBeforeInactive = NO;
   }
-  m_isInterrupted = NO;
 }
 
 - (void)becomeInactive
 {
-  LOG(@"%s: was interrupted: %d", __PRETTY_FUNCTION__,  m_isInterrupted);
   // if we were interrupted, already paused here
   // else if user background us or lock screen, only pause video here, audio keep playing.
   if (g_application.m_pPlayer->IsPlayingVideo() && !g_application.m_pPlayer->IsPaused())
@@ -1073,20 +1062,6 @@ AnnounceReceiver *AnnounceReceiver::g_announceReceiver = NULL;
   // check whether we need disable network auto suspend.
   [self rescheduleNetworkAutoSuspend];
 }
-
-- (void)beginInterruption
-{
-  PRINT_SIGNATURE();
-  m_isInterrupted = YES;
-  CAEFactory::Suspend();
-}
-
-- (void)endInterruption
-{
-  PRINT_SIGNATURE();
-  if (CAEFactory::IsSuspended())
-    CAEFactory::Resume();
-}
 //--------------------------------------------------------------
 - (void)pauseAnimation
 {
index 12421a2..2b4cf63 100644 (file)
@@ -96,10 +96,10 @@ void CProfilesManager::OnSettingsLoaded()
   CDirectory::Create(URIUtils::AddFileToFolder(strDir,"mixed"));
 }
 
-bool CProfilesManager::OnSettingsSaved()
+void CProfilesManager::OnSettingsSaved()
 {
   // save mastercode
-  return Save();
+  Save();
 }
 
 void CProfilesManager::OnSettingsCleared()
index 5c12c4f..ccaee55 100644 (file)
@@ -33,7 +33,7 @@ public:
   static CProfilesManager& Get();
 
   virtual void OnSettingsLoaded();
-  virtual bool OnSettingsSaved();
+  virtual void OnSettingsSaved();
   virtual void OnSettingsCleared();
 
   bool Load();
index 22cefb3..5110fe6 100644 (file)
@@ -42,242 +42,182 @@ bool CPVRDatabase::Open()
   return CDatabase::Open(g_advancedSettings.m_databaseTV);
 }
 
-bool CPVRDatabase::CreateTables()
+void CPVRDatabase::CreateTables()
 {
-  bool bReturn(false);
-
-  try
-  {
-    if (!CDatabase::CreateTables())
-      return false;
-
-    BeginTransaction();
-    CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__);
-
-    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'clients'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE clients ("
-          "idClient integer primary key, "
-          "sName    varchar(64), "
-          "sUid     varchar(32)"
-        ")"
-    );
-
-    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE channels ("
-          "idChannel            integer primary key, "
-          "iUniqueId            integer, "
-          "bIsRadio             bool, "
-          "bIsHidden            bool, "
-          "bIsUserSetIcon       bool, "
-          "bIsLocked            bool, "
-          "sIconPath            varchar(255), "
-          "sChannelName         varchar(64), "
-          "bIsVirtual           bool, "
-          "bEPGEnabled          bool, "
-          "sEPGScraper          varchar(32), "
-          "iLastWatched         integer,"
-
-          // TODO use mapping table
-          "iClientId            integer, "
-          "iClientChannelNumber integer, "
-          "sInputFormat         varchar(32), "
-          "sStreamURL           varchar(255), "
-          "iEncryptionSystem    integer, "
-
-          "idEpg                integer"
-        ")"
-    );
-    m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);");
-
-    // TODO use a mapping table so multiple backends per channel can be implemented
-    //    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channels_clients'", __FUNCTION__);
-    //    m_pDS->exec(
-    //        "CREATE TABLE map_channels_clients ("
-    //          "idChannel             integer primary key, "
-    //          "idClient              integer, "
-    //          "iClientChannelNumber  integer,"
-    //          "sInputFormat          string,"
-    //          "sStreamURL            string,"
-    //          "iEncryptionSystem     integer"
-    //        ");"
-    //    );
-    //    m_pDS->exec("CREATE UNIQUE INDEX idx_idChannel_idClient on map_channels_clients(idChannel, idClient);");
-
-    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE channelgroups ("
-          "idGroup         integer primary key,"
-          "bIsRadio        bool, "
-          "iGroupType      integer, "
-          "sName           varchar(64)"
-        ")"
-    );
-    m_pDS->exec("CREATE INDEX idx_channelgroups_bIsRadio on channelgroups(bIsRadio);");
-
-    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE map_channelgroups_channels ("
-          "idChannel      integer, "
-          "idGroup        integer, "
-          "iChannelNumber integer"
-        ")"
-    );
-    m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);");
-
-    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelsettings'", __FUNCTION__);
-    m_pDS->exec(
-        "CREATE TABLE channelsettings ("
-          "idChannel            integer primary key, "
-          "iInterlaceMethod     integer, "
-          "iViewMode            integer, "
-          "fCustomZoomAmount    float, "
-          "fPixelRatio          float, "
-          "iAudioStream         integer, "
-          "iSubtitleStream      integer,"
-          "fSubtitleDelay       float, "
-          "bSubtitles           bool, "
-          "fBrightness          float, "
-          "fContrast            float, "
-          "fGamma               float,"
-          "fVolumeAmplification float, "
-          "fAudioDelay          float, "
-          "bOutputToAllSpeakers bool, "
-          "bCrop                bool, "
-          "iCropLeft            integer, "
-          "iCropRight           integer, "
-          "iCropTop             integer, "
-          "iCropBottom          integer, "
-          "fSharpness           float, "
-          "fNoiseReduction      float, "
-          "fCustomVerticalShift float, "
-          "bCustomNonLinStretch bool, "
-          "bPostProcess         bool, "
-          "iScalingMethod       integer, "
-          "iDeinterlaceMode     integer "
-        ")"
-    );
-
-    CommitTransaction();
-    bReturn = true;
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "PVR - %s - unable to create PVR database tables (error %i)", __FUNCTION__, (int)GetLastError());
-    RollbackTransaction();
-    bReturn = false;
-  }
-
-  if (bReturn)
+  CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__);
+
+  CLog::Log(LOGDEBUG, "PVR - %s - creating table 'clients'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE clients ("
+        "idClient integer primary key, "
+        "sName    varchar(64), "
+        "sUid     varchar(32)"
+      ")"
+  );
+
+  CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE channels ("
+        "idChannel            integer primary key, "
+        "iUniqueId            integer, "
+        "bIsRadio             bool, "
+        "bIsHidden            bool, "
+        "bIsUserSetIcon       bool, "
+        "bIsLocked            bool, "
+        "sIconPath            varchar(255), "
+        "sChannelName         varchar(64), "
+        "bIsVirtual           bool, "
+        "bEPGEnabled          bool, "
+        "sEPGScraper          varchar(32), "
+        "iLastWatched         integer,"
+
+        // TODO use mapping table
+        "iClientId            integer, "
+        "iClientChannelNumber integer, "
+        "sInputFormat         varchar(32), "
+        "sStreamURL           varchar(255), "
+        "iEncryptionSystem    integer, "
+
+        "idEpg                integer"
+      ")"
+  );
+
+  // TODO use a mapping table so multiple backends per channel can be implemented
+  //    CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channels_clients'", __FUNCTION__);
+  //    m_pDS->exec(
+  //        "CREATE TABLE map_channels_clients ("
+  //          "idChannel             integer primary key, "
+  //          "idClient              integer, "
+  //          "iClientChannelNumber  integer,"
+  //          "sInputFormat          string,"
+  //          "sStreamURL            string,"
+  //          "iEncryptionSystem     integer"
+  //        ");"
+  //    );
+  //    m_pDS->exec("CREATE UNIQUE INDEX idx_idChannel_idClient on map_channels_clients(idChannel, idClient);");
+
+  CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE channelgroups ("
+        "idGroup         integer primary key,"
+        "bIsRadio        bool, "
+        "iGroupType      integer, "
+        "sName           varchar(64)"
+      ")"
+  );
+
+  CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE map_channelgroups_channels ("
+        "idChannel      integer, "
+        "idGroup        integer, "
+        "iChannelNumber integer"
+      ")"
+  );
+
+  CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelsettings'", __FUNCTION__);
+  m_pDS->exec(
+      "CREATE TABLE channelsettings ("
+        "idChannel            integer primary key, "
+        "iInterlaceMethod     integer, "
+        "iViewMode            integer, "
+        "fCustomZoomAmount    float, "
+        "fPixelRatio          float, "
+        "iAudioStream         integer, "
+        "iSubtitleStream      integer,"
+        "fSubtitleDelay       float, "
+        "bSubtitles           bool, "
+        "fBrightness          float, "
+        "fContrast            float, "
+        "fGamma               float,"
+        "fVolumeAmplification float, "
+        "fAudioDelay          float, "
+        "bOutputToAllSpeakers bool, "
+        "bCrop                bool, "
+        "iCropLeft            integer, "
+        "iCropRight           integer, "
+        "iCropTop             integer, "
+        "iCropBottom          integer, "
+        "fSharpness           float, "
+        "fNoiseReduction      float, "
+        "fCustomVerticalShift float, "
+        "bCustomNonLinStretch bool, "
+        "bPostProcess         bool, "
+        "iScalingMethod       integer, "
+        "iDeinterlaceMode     integer "
+      ")"
+  );
+
+  // disable all PVR add-on when started the first time
+  ADDON::VECADDONS addons;
+  if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true))
+    CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
+  else
   {
-    // disable all PVR add-on when started the first time
-    ADDON::VECADDONS addons;
-    if ((bReturn = CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) == false)
-      CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
-    else
-    {
-      for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
-        CAddonMgr::Get().DisableAddon(it->get()->ID());
-    }
+    for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
+      CAddonMgr::Get().DisableAddon(it->get()->ID());
   }
+}
 
-  return bReturn;
+void CPVRDatabase::CreateAnalytics()
+{
+  CLog::Log(LOGINFO, "%s - creating indices", __FUNCTION__);
+  m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);");
+  m_pDS->exec("CREATE INDEX idx_channelgroups_bIsRadio on channelgroups(bIsRadio);");
+  m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);");
 }
 
-bool CPVRDatabase::UpdateOldVersion(int iVersion)
+void CPVRDatabase::UpdateTables(int iVersion)
 {
-  bool bReturn = true;
+  if (iVersion < 13)
+    m_pDS->exec("ALTER TABLE channels ADD idEpg integer;");
 
-  BeginTransaction();
+  if (iVersion < 14)
+    m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;");
 
-  try
+  if (iVersion < 15)
   {
-    if (iVersion < 11)
-    {
-      CLog::Log(LOGERROR, "PVR - %s - updating from table versions < 11 not supported. please delete '%s'",
-          __FUNCTION__, GetBaseDBName());
-      bReturn = false;
-    }
+    m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;");
+    m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;");
+    m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;");
+  }
+  if (iVersion < 16)
+  {
+    /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */
+  }
+  if (iVersion < 17)
+  {
+    m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer");
+    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force
+    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto
+    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto
+  }
+  if (iVersion < 19)
+  {
+    // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades
+    ADDON::VECADDONS addons;
+    if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true))
+      CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
     else
     {
-      if (iVersion < 12)
-        m_pDS->exec("DROP VIEW vw_last_watched;");
-
-      if (iVersion < 13)
-        m_pDS->exec("ALTER TABLE channels ADD idEpg integer;");
-
-      if (iVersion < 14)
-        m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;");
-
-      if (iVersion < 15)
-      {
-        m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;");
-        m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;");
-        m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;");
-      }
-      if (iVersion < 16)
-      {
-        /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */
-      }
-      if (iVersion < 17)
-      {
-        m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer");
-        m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force
-        m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto
-        m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto
-      }
-      if (iVersion < 18)
-      {
-        m_pDS->exec("DROP INDEX idx_channels_iClientId;");
-        m_pDS->exec("DROP INDEX idx_channels_iLastWatched;");
-        m_pDS->exec("DROP INDEX idx_channels_bIsRadio;");
-        m_pDS->exec("DROP INDEX idx_channels_bIsHidden;");
-        m_pDS->exec("DROP INDEX idx_idChannel_idGroup;");
-        m_pDS->exec("DROP INDEX idx_idGroup_iChannelNumber;");
-        m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);");
-        m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);");
-      }
-      if (iVersion < 19)
+      CAddonDatabase database;
+      database.Open();
+      for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
       {
-        // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades
-        ADDON::VECADDONS addons;
-        if ((bReturn = CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) == false)
-          CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
-        else
-        {
-          CAddonDatabase database;
-          database.Open();
-          for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
-          {
-            if (!database.IsSystemPVRAddonEnabled(it->get()->ID()))
-              CAddonMgr::Get().DisableAddon(it->get()->ID());
-          }
-          database.Close();
-        }
+        if (!database.IsSystemPVRAddonEnabled(it->get()->ID()))
+          CAddonMgr::Get().DisableAddon(it->get()->ID());
       }
-      if (iVersion < 20)
-        m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool");
-
-      if (iVersion < 21)
-        m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer");
-
-      if (iVersion < 22)
-        m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool");
+      database.Close();
     }
   }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "PVR - %s - error attempting to update the database version!", __FUNCTION__);
-    bReturn = false;
-  }
+  if (iVersion < 20)
+    m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool");
 
-  if (bReturn)
-    CommitTransaction();
-  else
-    RollbackTransaction();
+  if (iVersion < 21)
+    m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer");
 
-  return bReturn;
+  if (iVersion < 22)
+    m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool");
 }
 
 int CPVRDatabase::GetLastChannelId(void)
index b2c9c52..1d5f9fa 100644 (file)
@@ -59,7 +59,7 @@ namespace PVR
      * @brief Get the minimal database version that is required to operate correctly.
      * @return The minimal database version.
      */
-    virtual int GetMinVersion() const { return 22; };
+    virtual int GetSchemaVersion() const { return 22; };
 
     /*!
      * @brief Get the default sqlite database filename.
@@ -221,7 +221,8 @@ namespace PVR
      * @brief Create the PVR database tables.
      * @return True if the tables were created successfully, false otherwise.
      */
-    bool CreateTables();
+    void CreateTables();
+    void CreateAnalytics();
 
     bool DeleteChannelsFromGroup(const CPVRChannelGroup &group);
     bool DeleteChannelsFromGroup(const CPVRChannelGroup &group, const std::vector<int> &channelsToDelete);
@@ -233,9 +234,9 @@ namespace PVR
     /*!
      * @brief Update an old version of the database.
      * @param version The version to update the database from.
-     * @return True if it was updated successfully, false otherwise.
      */
-    bool UpdateOldVersion(int version);
+    void UpdateTables(int version);
+    int GetMinSchemaVersion() { return 11; }
 
     bool PersistGroupMembers(CPVRChannelGroup &group);
 
index cc98c43..9a8f7c5 100644 (file)
@@ -1323,10 +1323,8 @@ bool CPVRManager::IsIdle(void) const
     const CDateTime next = m_timers->GetNextEventTime();
     const CDateTimeSpan delta = next - now;
 
-    if (delta < idle)
-    {
+    if (delta <= idle)
       return false;
-    }
   }
 
   return true;
index 2bceb67..fa64eba 100644 (file)
@@ -108,6 +108,7 @@ public:
 
   virtual void SetViewPort(CRect& viewPort) = 0;
   virtual void GetViewPort(CRect& viewPort) = 0;
+  virtual void RestoreViewPort() {};
 
   virtual void SetScissors(const CRect &rect) = 0;
   virtual void ResetScissors() = 0;
index 654c23f..527ba8b 100644 (file)
@@ -954,6 +954,14 @@ void CRenderSystemDX::SetViewPort(CRect& viewPort)
   m_pD3DDevice->SetViewport(&m_viewPort);
 }
 
+void CRenderSystemDX::RestoreViewPort()
+{
+  if (!m_bRenderCreated)
+    return;
+
+  m_pD3DDevice->SetViewport(&m_viewPort);
+}
+
 void CRenderSystemDX::SetScissors(const CRect& rect)
 {
   if (!m_bRenderCreated)
index 197fc8f..0697bed 100644 (file)
@@ -61,6 +61,7 @@ public:
 
   virtual void SetViewPort(CRect& viewPort);
   virtual void GetViewPort(CRect& viewPort);
+  virtual void RestoreViewPort();
 
   virtual void SetScissors(const CRect &rect);
   virtual void ResetScissors();
index 462371e..e21d21e 100644 (file)
@@ -161,8 +161,6 @@ void CAdvancedSettings::Initialize()
   m_videoNonLinStretchRatio = 0.5f;
   m_videoEnableHighQualityHwScalers = false;
   m_videoAutoScaleMaxFps = 30.0f;
-  m_videoAllowMpeg4VDPAU = false;
-  m_videoAllowMpeg4VAAPI = false;  
   m_videoDisableBackgroundDeinterlace = false;
   m_videoCaptureUseOcclusionQuery = -1; //-1 is auto detect
   m_videoVDPAUtelecine = false;
@@ -597,9 +595,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
     XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f);
     XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers);
     XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f);
-    XMLUtils::GetBoolean(pElement,"allowmpeg4vdpau",m_videoAllowMpeg4VDPAU);
     XMLUtils::GetBoolean(pElement,"disablehi10pmultithreading",m_videoDisableHi10pMultithreading);
-    XMLUtils::GetBoolean(pElement,"allowmpeg4vaapi",m_videoAllowMpeg4VAAPI);    
     XMLUtils::GetBoolean(pElement, "disablebackgrounddeinterlace", m_videoDisableBackgroundDeinterlace);
     XMLUtils::GetInt(pElement, "useocclusionquery", m_videoCaptureUseOcclusionQuery, -1, 1);
     XMLUtils::GetBoolean(pElement,"vdpauInvTelecine",m_videoVDPAUtelecine);
@@ -838,11 +834,14 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
   { // read the loglevel setting, so set the setting advanced to hide it in GUI
     // as altering it will do nothing - we don't write to advancedsettings.xml
     XMLUtils::GetInt(pRootElement, "loglevel", m_logLevelHint, LOG_LEVEL_NONE, LOG_LEVEL_MAX);
-    CSettingBool *setting = (CSettingBool *)CSettings::Get().GetSetting("debug.showloginfo");
-    if (setting != NULL)
+    const char* hide = pElement->Attribute("hide");
+    if (hide == NULL || strnicmp("false", hide, 4) != 0)
     {
-      const char* hide;
-      if (!((hide = pElement->Attribute("hide")) && strnicmp("false", hide, 4) == 0))
+      CSetting *setting = CSettings::Get().GetSetting("debug.showloginfo");
+      if (setting != NULL)
+        setting->SetVisible(false);
+      setting = CSettings::Get().GetSetting("debug.setextraloglevel");
+      if (setting != NULL)
         setting->SetVisible(false);
     }
     g_advancedSettings.m_logLevel = std::max(g_advancedSettings.m_logLevel, g_advancedSettings.m_logLevelHint);
index 88d2cde..1e54c93 100644 (file)
@@ -181,8 +181,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
     float m_videoNonLinStretchRatio;
     bool  m_videoEnableHighQualityHwScalers;
     float m_videoAutoScaleMaxFps;
-    bool  m_videoAllowMpeg4VDPAU;
-    bool  m_videoAllowMpeg4VAAPI;
     std::vector<RefreshOverride> m_videoAdjustRefreshOverrides;
     std::vector<RefreshVideoLatency> m_videoRefreshLatency;
     float m_videoDefaultLatency;
index 8cf00f7..892a139 100644 (file)
@@ -29,6 +29,7 @@
 #include "addons/AddonManager.h"
 #include "addons/Skin.h"
 #include "cores/AudioEngine/AEFactory.h"
+#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
 #if defined(HAVE_LIBCRYSTALHD)
 #include "cores/dvdplayer/DVDCodecs/Video/CrystalHD.h"
 #endif // defined(HAVE_LIBCRYSTALHD)
@@ -54,7 +55,6 @@
 #include "network/WakeOnAccess.h"
 #if defined(TARGET_DARWIN_OSX)
 #include "osx/XBMCHelper.h"
-#include "cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.h"
 #endif // defined(TARGET_DARWIN_OSX)
 #if defined(TARGET_DARWIN)
 #include "osx/DarwinUtils.h"
@@ -468,6 +468,9 @@ void CSettings::Uninitialize()
   m_settingsManager->UnregisterSettingsHandler(&CWakeOnAccess::Get());
   m_settingsManager->UnregisterSettingsHandler(&CRssManager::Get());
   m_settingsManager->UnregisterSettingsHandler(&g_application);
+#if defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
+  m_settingsManager->UnregisterSettingsHandler(&g_timezone);
+#endif
 
   m_initialized = false;
 }
@@ -794,14 +797,7 @@ void CSettings::InitializeDefaults()
   #endif
 #endif
 
-#if defined(TARGET_DARWIN)
-  #if !defined(TARGET_DARWIN_IOS)
-  CStdString defaultAudioDeviceName;
-  CCoreAudioHardware::GetOutputDeviceName(defaultAudioDeviceName);
-  ((CSettingString*)m_settingsManager->GetSetting("audiooutput.audiodevice"))->SetDefault(defaultAudioDeviceName);
-  ((CSettingString*)m_settingsManager->GetSetting("audiooutput.passthroughdevice"))->SetDefault(defaultAudioDeviceName);
-  #endif
-#elif !defined(TARGET_WINDOWS)
+#if !defined(TARGET_WINDOWS)
   ((CSettingString*)m_settingsManager->GetSetting("audiooutput.audiodevice"))->SetDefault(CAEFactory::GetDefaultDevice(false));
   ((CSettingString*)m_settingsManager->GetSetting("audiooutput.passthroughdevice"))->SetDefault(CAEFactory::GetDefaultDevice(true));
 #endif
@@ -960,6 +956,7 @@ void CSettings::InitializeConditions()
   m_settingsManager->AddCondition("profilehasvideoslocked", ProfileHasVideosLocked);
   m_settingsManager->AddCondition("profilelockmode", ProfileLockMode);
   m_settingsManager->AddCondition("aesettingvisible", CAEFactory::IsSettingVisible);
+  m_settingsManager->AddCondition("codecoptionvisible", CDVDVideoCodec::IsSettingVisible);
 }
 
 void CSettings::InitializeISettingsHandlers()
@@ -976,6 +973,9 @@ void CSettings::InitializeISettingsHandlers()
   m_settingsManager->RegisterSettingsHandler(&CWakeOnAccess::Get());
   m_settingsManager->RegisterSettingsHandler(&CRssManager::Get());
   m_settingsManager->RegisterSettingsHandler(&g_application);
+#if defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
+  m_settingsManager->RegisterSettingsHandler(&g_timezone);
+#endif
 }
 
 void CSettings::InitializeISubSettings()
index 825c22f..7b5aad3 100644 (file)
@@ -401,7 +401,7 @@ bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSet
     dialog->m_scraper = scraper;
     // toast selected but disabled scrapers
     if (!scraper->Enabled())
-      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(24023), scraper->Name(), 2000, true);
+      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(24024), scraper->Name(), 2000, true);
   }
 
   dialog->m_bScanRecursive = (settings.recurse > 0 && !settings.parent_name) || (settings.recurse > 1 && settings.parent_name);
index b31d88b..3f144c3 100644 (file)
@@ -52,7 +52,7 @@ public:
 
    This callback can be used to trigger saving other settings.
    */
-  virtual void OnSettingsSaved() const { }
+  virtual void OnSettingsSaved() { }
   /*!
    \brief Setting values have been unloaded.
 
index 5106a45..2963a6f 100644 (file)
@@ -1145,7 +1145,8 @@ bool CSettingString::Deserialize(const TiXmlNode *node, bool update /* = false *
 
   // get the default value
   CStdString value;
-  if (XMLUtils::GetString(node, SETTING_XML_ELM_DEFAULT, value) && !value.empty())
+  if (XMLUtils::GetString(node, SETTING_XML_ELM_DEFAULT, value) &&
+     (!value.empty() || m_allowEmpty))
     m_value = m_default = value;
   else if (!update && !m_allowEmpty)
   {
index b2255cb..53334bd 100644 (file)
@@ -860,6 +860,13 @@ bool CSettingsManager::OnSettingsLoading()
   return true;
 }
 
+void CSettingsManager::OnSettingsUnloaded()
+{
+  CSharedLock lock(m_critical);
+  for (SettingsHandlers::const_iterator it = m_settingsHandlers.begin(); it != m_settingsHandlers.end(); ++it)
+    (*it)->OnSettingsUnloaded();
+}
+
 void CSettingsManager::OnSettingsLoaded()
 {
   CSharedLock lock(m_critical);
index ee6c774..30a997f 100644 (file)
@@ -393,6 +393,7 @@ private:
   // implementation of ISettingsHandler
   virtual bool OnSettingsLoading();
   virtual void OnSettingsLoaded();
+  virtual void OnSettingsUnloaded();
   virtual bool OnSettingsSaving() const;
   virtual void OnSettingsSaved() const;
   virtual void OnSettingsCleared();
index 6df8dd2..061afc0 100644 (file)
@@ -133,6 +133,7 @@ void aml_permissions()
     system("su -c chmod 666 /sys/class/video/disable_video");
     system("su -c chmod 666 /sys/class/tsync/pts_pcrscr");
     system("su -c chmod 666 /sys/class/audiodsp/digital_raw");
+    system("su -c chmod 666 /sys/class/ppmgr/ppmgr_3d_mode");
     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
     system("su -c chmod 666 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
index ac5b5eb..9ea07bd 100644 (file)
@@ -251,3 +251,47 @@ void Protocol::Purge()
   while (ReceiveOutMessage(&msg))
     msg->Release();
 }
+
+void Protocol::PurgeIn(int signal)
+{
+  Message *msg;
+  std::queue<Message*> msgs;
+
+  CSingleLock lock(criticalSection);
+
+  while (!inMessages.empty())
+  {
+    msg = inMessages.front();
+    inMessages.pop();
+    if (msg->signal != signal)
+      msgs.push(msg);
+  }
+  while (!msgs.empty())
+  {
+    msg = msgs.front();
+    msgs.pop();
+    inMessages.push(msg);
+  }
+}
+
+void Protocol::PurgeOut(int signal)
+{
+  Message *msg;
+  std::queue<Message*> msgs;
+
+  CSingleLock lock(criticalSection);
+
+  while (!outMessages.empty())
+  {
+    msg = outMessages.front();
+    outMessages.pop();
+    if (msg->signal != signal)
+      msgs.push(msg);
+  }
+  while (!msgs.empty())
+  {
+    msg = msgs.front();
+    msgs.pop();
+    outMessages.push(msg);
+  }
+}
index 336da06..100b1ac 100644 (file)
@@ -69,6 +69,8 @@ public:
   bool ReceiveOutMessage(Message **msg);
   bool ReceiveInMessage(Message **msg);
   void Purge();
+  void PurgeIn(int signal);
+  void PurgeOut(int signal);
   void DeferIn(bool value) {inDefered = value;};
   void DeferOut(bool value) {outDefered = value;};
   void Lock() {criticalSection.lock();};
index 066fc21..e148158 100644 (file)
@@ -611,7 +611,7 @@ extern const LCENTRY g_iso639_1[186] =
   { MAKECODE('\0','\0','m','t'), "Maltese" },
   { MAKECODE('\0','\0','m','y'), "Burmese" },
   { MAKECODE('\0','\0','n','a'), "Nauru" },
-  { MAKECODE('\0','\0','n','b'), "Bokmål, Norwegian" },
+  { MAKECODE('\0','\0','n','b'), "Bokm\xC3\xA5l, Norwegian" },
   { MAKECODE('\0','\0','n','d'), "Ndebele, North" },
   { MAKECODE('\0','\0','n','e'), "Nepali" },
   { MAKECODE('\0','\0','n','g'), "Ndonga" },
@@ -753,7 +753,7 @@ extern const LCENTRY g_iso639_2[538] =
   { MAKECODE('\0','b','i','n'), "Bini" },
   { MAKECODE('\0','b','i','s'), "Bislama" },
   { MAKECODE('\0','b','y','n'), "Blin" },
-  { MAKECODE('\0','n','o','b'), "Bokmål, Norwegian" },
+  { MAKECODE('\0','n','o','b'), "Bokm\xC3\xA5l, Norwegian" },
   { MAKECODE('\0','b','o','s'), "Bosnian" },
   { MAKECODE('\0','b','r','a'), "Braj" },
   { MAKECODE('\0','b','r','e'), "Breton" },
@@ -877,7 +877,7 @@ extern const LCENTRY g_iso639_2[538] =
   { MAKECODE('\0','k','a','l'), "Greenlandic" },
   { MAKECODE('\0','g','r','n'), "Guarani" },
   { MAKECODE('\0','g','u','j'), "Gujarati" },
-  { MAKECODE('\0','g','w','i'), "Gwich´in" },
+  { MAKECODE('\0','g','w','i'), "Gwich\xC2\xB4in" },
   { MAKECODE('\0','h','a','i'), "Haida" },
   { MAKECODE('\0','h','a','t'), "Haitian" },
   { MAKECODE('\0','h','a','t'), "Haitian Creole" },
@@ -1045,7 +1045,7 @@ extern const LCENTRY g_iso639_2[538] =
   { MAKECODE('\0','n','s','o'), "Northern Sotho" },
   { MAKECODE('\0','n','d','e'), "North Ndebele" },
   { MAKECODE('\0','n','o','r'), "Norwegian" },
-  { MAKECODE('\0','n','o','b'), "Norwegian Bokmål" },
+  { MAKECODE('\0','n','o','b'), "Norwegian Bokm\xC3\xA5l" },
   { MAKECODE('\0','n','n','o'), "Norwegian Nynorsk" },
   { MAKECODE('\0','n','u','b'), "Nubian languages" },
   { MAKECODE('\0','n','y','m'), "Nyamwezi" },
@@ -1085,8 +1085,8 @@ extern const LCENTRY g_iso639_2[538] =
   { MAKECODE('\0','p','o','l'), "Polish" },
   { MAKECODE('\0','p','o','r'), "Portuguese" },
   { MAKECODE('\0','p','r','a'), "Prakrit languages" },
-  { MAKECODE('\0','o','c','i'), "Provençal" },
-  { MAKECODE('\0','p','r','o'), "Provençal, Old (to 1500)" },
+  { MAKECODE('\0','o','c','i'), "Proven\xC3\xA7""al" },
+  { MAKECODE('\0','p','r','o'), "Proven\xC3\xA7""al, Old (to 1500)" },
   { MAKECODE('\0','p','a','n'), "Punjabi" },
   { MAKECODE('\0','p','u','s'), "Pushto" },
   { MAKECODE('\0','q','u','e'), "Quechua" },
@@ -1205,7 +1205,7 @@ extern const LCENTRY g_iso639_2[538] =
   { MAKECODE('\0','c','a','t'), "Valencian" },
   { MAKECODE('\0','v','e','n'), "Venda" },
   { MAKECODE('\0','v','i','e'), "Vietnamese" },
-  { MAKECODE('\0','v','o','l'), "Volapük" },
+  { MAKECODE('\0','v','o','l'), "Volap\xC3\xBCk" },
   { MAKECODE('\0','v','o','t'), "Votic" },
   { MAKECODE('\0','w','a','k'), "Wakashan languages" },
   { MAKECODE('\0','w','a','l'), "Walamo" },
index fdd4584..e40c1b4 100644 (file)
@@ -136,15 +136,14 @@ TEST_F(TestCharsetConverter, utf16LEtoW)
   EXPECT_STREQ(refstrw1.c_str(), varstrw1.c_str());
 }
 
-TEST_F(TestCharsetConverter, subtitleCharsetToW)
+TEST_F(TestCharsetConverter, subtitleCharsetToUtf8)
 {
-  varstra1 = "test subtitleCharsetToW";
-  refstrw1 = L"test subtitleCharsetToW";
-  varstrw1.clear();
-  g_charsetConverter.subtitleCharsetToW(varstra1, varstrw1);
+  refstra1 = "test subtitleCharsetToW";
+  varstra1.clear();
+  g_charsetConverter.subtitleCharsetToUtf8(refstra1, varstra1);
 
   /* Assign refstra1 to refstrw1 so that we can compare */
-  EXPECT_STREQ(refstrw1.c_str(), varstrw1.c_str());
+  EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
 }
 
 TEST_F(TestCharsetConverter, utf8ToStringCharset_1)
index 06a1805..54cbdfc 100644 (file)
@@ -474,9 +474,14 @@ CGUIViewStateVideoMovies::CGUIViewStateVideoMovies(const CFileItemList& items) :
 {
   AddSortMethod(SortBySortTitle, 556, LABEL_MASKS("%T", "%R", "%T", "%R"),  // Title, Rating | Title, Rating
     CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
+  AddSortMethod(SortByYear, 562, LABEL_MASKS("%T", "%Y", "%T", "%Y"));  // Title, Year | Title, Year
   AddSortMethod(SortByRating, 563, LABEL_MASKS("%T", "%R", "%T", "%R"));  // Title, Rating | Title, Rating
   AddSortMethod(SortByMPAA, 20074, LABEL_MASKS("%T", "%O"));  // Title, MPAA | empty, empty
-  AddSortMethod(SortByYear, 562, LABEL_MASKS("%T", "%Y", "%T", "%Y"));  // Title, Year | Title, Year
+  AddSortMethod(SortByTime, 180, LABEL_MASKS("%T", "%D"));  // Title, Duration | empty, empty
+  AddSortMethod(SortByDateAdded, 570, LABEL_MASKS("%T", "%a", "%T", "%a"));  // Title, DateAdded | Title, DateAdded
+
+  if (CMediaSettings::Get().GetWatchedMode(items.GetContent()) == WatchedModeAll)
+    AddSortMethod(SortByPlaycount, 567, LABEL_MASKS("%T", "%V", "%T", "%V"));  // Title, Playcount | Title, Playcount
 
   const CViewState *viewState = CViewStateSettings::Get().Get("videonavtitles");
   if (items.IsSmartPlayList() || items.IsLibraryFolder())
@@ -509,7 +514,8 @@ CGUIViewStateVideoMusicVideos::CGUIViewStateVideoMusicVideos(const CFileItemList
   AddSortMethod(SortByArtist, sortAttributes, 557, LABEL_MASKS("%A - %T", "%Y"));  // Artist - Title, Year | empty, empty
   AddSortMethod(SortByAlbum, sortAttributes, 558, LABEL_MASKS("%B - %T", "%Y"));  // Album - Title, Year | empty, empty
 
-  AddSortMethod(SortByPlaycount, 567, LABEL_MASKS("%T", "%V"));  // Title, Playcount | empty, empty
+   if (CMediaSettings::Get().GetWatchedMode(items.GetContent()) == WatchedModeAll)
+    AddSortMethod(SortByPlaycount, 567, LABEL_MASKS("%T", "%V"));  // Title, Playcount | empty, empty
   
   CStdString strTrackLeft=CSettings::Get().GetString("musicfiles.trackformat");
   CStdString strTrackRight=CSettings::Get().GetString("musicfiles.trackformatright");
@@ -538,6 +544,9 @@ CGUIViewStateVideoTVShows::CGUIViewStateVideoTVShows(const CFileItemList& items)
 {
   AddSortMethod(SortBySortTitle, 556, LABEL_MASKS("%T", "%M", "%T", "%M"),  // Title, #Episodes | Title, #Episodes
     CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
+  // NOTE: This uses SortByEpisodeNumber to mean "sort shows by the number of episodes" and uses the label "Episodes"
+  AddSortMethod(SortByEpisodeNumber, 20360, LABEL_MASKS("%L", "%M", "%L", "%M"));  // Label, #Episodes | Label, #Episodes
+  AddSortMethod(SortByLastPlayed, 568, LABEL_MASKS("%T", "%p", "%T", "%p"));  // Title, #Last played | Title, #Last played
   AddSortMethod(SortByYear, 562, LABEL_MASKS("%T", "%Y", "%T", "%Y"));  // Title, Year | Title, Year
 
   const CViewState *viewState = CViewStateSettings::Get().Get("videonavtvshows");
@@ -561,25 +570,32 @@ void CGUIViewStateVideoTVShows::SaveViewState()
 
 CGUIViewStateVideoEpisodes::CGUIViewStateVideoEpisodes(const CFileItemList& items) : CGUIViewStateWindowVideo(items)
 {
-  AddSortMethod(SortByLabel, 551, LABEL_MASKS("%Z - %H. %T","%R"),  // TvShow - Order. Title, Rating | empty, empty
-    CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
   if (0)//params.GetSeason() > -1)
   {
+    AddSortMethod(SortByEpisodeNumber, 20359, LABEL_MASKS("%E. %T","%R"));  // Episode. Title, Rating | empty, empty
     AddSortMethod(SortByRating, 563, LABEL_MASKS("%E. %T", "%R"));  // Episode. Title, Rating | empty, empty
     AddSortMethod(SortByMPAA, 20074, LABEL_MASKS("%E. %T", "%O"));  // Episode. Title, MPAA | empty, empty
-    AddSortMethod(SortByEpisodeNumber, 20359, LABEL_MASKS("%E. %T","%R"));  // Episode. Title, Rating | empty, empty
     AddSortMethod(SortByProductionCode, 20368, LABEL_MASKS("%E. %T","%P", "%E. %T","%P"));  // Episode. Title, Production Code | Episode. Title, Production Code
     AddSortMethod(SortByDate, 552, LABEL_MASKS("%E. %T","%J","E. %T","%J"));  // Episode. Title, Date | Episode. Title, Date
+
+    if (CMediaSettings::Get().GetWatchedMode(items.GetContent()) == WatchedModeAll)
+      AddSortMethod(SortByPlaycount, 567, LABEL_MASKS("%E. %T", "%V"));  // Episode. Title, Playcount | empty, empty
   }
   else
   { // format here is tvshowtitle - season/episode number. episode title
+    AddSortMethod(SortByEpisodeNumber, 20359, LABEL_MASKS("%Z - %H. %T","%R"));  // TvShow - Order. Title, Rating | empty, empty
     AddSortMethod(SortByRating, 563, LABEL_MASKS("%Z - %H. %T", "%R"));  // TvShow - Order. Title, Rating | empty, empty
     AddSortMethod(SortByMPAA, 20074, LABEL_MASKS("%Z - %H. %T", "%O"));  // TvShow - Order. Title, MPAA | empty, empty
-    AddSortMethod(SortByEpisodeNumber, 20359, LABEL_MASKS("%Z - %H. %T","%R"));  // TvShow - Order. Title, Rating | empty, empty
     AddSortMethod(SortByProductionCode, 20368, LABEL_MASKS("%Z - %H. %T","%P"));  // TvShow - Order. Title, Production Code | empty, empty
     AddSortMethod(SortByDate, 552, LABEL_MASKS("%Z - %H. %T","%J"));  // TvShow - Order. Title, Date | empty, empty
+
+    if (CMediaSettings::Get().GetWatchedMode(items.GetContent()) == WatchedModeAll)
+      AddSortMethod(SortByPlaycount, 567, LABEL_MASKS("%H. %T", "%V"));  // Order. Title, Playcount | empty, empty
   }
 
+  AddSortMethod(SortByLabel, 551, LABEL_MASKS("%Z - %H. %T","%R"),  // TvShow - Order. Title, Rating | empty, empty
+    CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
+
   const CViewState *viewState = CViewStateSettings::Get().Get("videonavepisodes");
   if (items.IsSmartPlayList() || items.IsLibraryFolder())
     AddPlaylistOrder(items, LABEL_MASKS("%Z - %H. %T", "%R"));  // TvShow - Order. Title, Rating | empty, empty
index 7d399d1..2db5c2d 100644 (file)
@@ -81,7 +81,160 @@ bool CVideoDatabase::Open()
   return CDatabase::Open(g_advancedSettings.m_databaseVideo);
 }
 
-bool CVideoDatabase::CreateTables()
+void CVideoDatabase::CreateTables()
+{
+  CLog::Log(LOGINFO, "create bookmark table");
+  m_pDS->exec("CREATE TABLE bookmark ( idBookmark integer primary key, idFile integer, timeInSeconds double, totalTimeInSeconds double, thumbNailImage text, player text, playerState text, type integer)\n");
+
+  CLog::Log(LOGINFO, "create settings table");
+  m_pDS->exec("CREATE TABLE settings ( idFile integer, Deinterlace bool,"
+              "ViewMode integer,ZoomAmount float, PixelRatio float, VerticalShift float, AudioStream integer, SubtitleStream integer,"
+              "SubtitleDelay float, SubtitlesOn bool, Brightness float, Contrast float, Gamma float,"
+              "VolumeAmplification float, AudioDelay float, OutputToAllSpeakers bool, ResumeTime integer, Crop bool, CropLeft integer,"
+              "CropRight integer, CropTop integer, CropBottom integer, Sharpness float, NoiseReduction float, NonLinStretch bool, PostProcess bool,"
+              "ScalingMethod integer, DeinterlaceMode integer, StereoMode integer, StereoInvert bool)\n");
+
+  CLog::Log(LOGINFO, "create stacktimes table");
+  m_pDS->exec("CREATE TABLE stacktimes (idFile integer, times text)\n");
+
+  CLog::Log(LOGINFO, "create genre table");
+  m_pDS->exec("CREATE TABLE genre ( idGenre integer primary key, strGenre text)\n");
+
+  CLog::Log(LOGINFO, "create genrelinkmovie table");
+  m_pDS->exec("CREATE TABLE genrelinkmovie ( idGenre integer, idMovie integer)\n");
+
+  CLog::Log(LOGINFO, "create country table");
+  m_pDS->exec("CREATE TABLE country ( idCountry integer primary key, strCountry text)\n");
+
+  CLog::Log(LOGINFO, "create countrylinkmovie table");
+  m_pDS->exec("CREATE TABLE countrylinkmovie ( idCountry integer, idMovie integer)\n");
+
+  CLog::Log(LOGINFO, "create movie table");
+  CStdString columns = "CREATE TABLE movie ( idMovie integer primary key, idFile integer";
+
+  for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
+    columns += StringUtils::Format(",c%02d text", i);
+
+  columns += ", idSet integer)";
+  m_pDS->exec(columns.c_str());
+
+  CLog::Log(LOGINFO, "create actorlinkmovie table");
+  m_pDS->exec("CREATE TABLE actorlinkmovie ( idActor integer, idMovie integer, strRole text, iOrder integer)\n");
+
+  CLog::Log(LOGINFO, "create directorlinkmovie table");
+  m_pDS->exec("CREATE TABLE directorlinkmovie ( idDirector integer, idMovie integer)\n");
+
+  CLog::Log(LOGINFO, "create writerlinkmovie table");
+  m_pDS->exec("CREATE TABLE writerlinkmovie ( idWriter integer, idMovie integer)\n");
+
+  CLog::Log(LOGINFO, "create actors table");
+  m_pDS->exec("CREATE TABLE actors ( idActor integer primary key, strActor text, strThumb text )\n");
+
+  CLog::Log(LOGINFO, "create path table");
+  m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate bool, exclude bool, dateAdded text)");
+
+  CLog::Log(LOGINFO, "create files table");
+  m_pDS->exec("CREATE TABLE files ( idFile integer primary key, idPath integer, strFilename text, playCount integer, lastPlayed text, dateAdded text)");
+
+  CLog::Log(LOGINFO, "create tvshow table");
+  columns = "CREATE TABLE tvshow ( idShow integer primary key";
+
+  for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
+    columns += StringUtils::Format(",c%02d text", i);;
+
+  columns += ")";
+  m_pDS->exec(columns.c_str());
+
+  CLog::Log(LOGINFO, "create directorlinktvshow table");
+  m_pDS->exec("CREATE TABLE directorlinktvshow ( idDirector integer, idShow integer)\n");
+
+  CLog::Log(LOGINFO, "create actorlinktvshow table");
+  m_pDS->exec("CREATE TABLE actorlinktvshow ( idActor integer, idShow integer, strRole text, iOrder integer)\n");
+
+  CLog::Log(LOGINFO, "create studiolinktvshow table");
+  m_pDS->exec("CREATE TABLE studiolinktvshow ( idStudio integer, idShow integer)\n");
+
+  CLog::Log(LOGINFO, "create episode table");
+  columns = "CREATE TABLE episode ( idEpisode integer primary key, idFile integer";
+  for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
+  {
+    CStdString column;
+    if ( i == VIDEODB_ID_EPISODE_SEASON || i == VIDEODB_ID_EPISODE_EPISODE || i == VIDEODB_ID_EPISODE_BOOKMARK)
+      column = StringUtils::Format(",c%02d varchar(24)", i);
+    else
+      column = StringUtils::Format(",c%02d text", i);
+
+    columns += column;
+  }
+  columns += ", idShow integer)";
+  m_pDS->exec(columns.c_str());
+
+  CLog::Log(LOGINFO, "create tvshowlinkpath table");
+  m_pDS->exec("CREATE TABLE tvshowlinkpath (idShow integer, idPath integer)\n");
+
+  CLog::Log(LOGINFO, "create actorlinkepisode table");
+  m_pDS->exec("CREATE TABLE actorlinkepisode ( idActor integer, idEpisode integer, strRole text, iOrder integer)\n");
+
+  CLog::Log(LOGINFO, "create directorlinkepisode table");
+  m_pDS->exec("CREATE TABLE directorlinkepisode ( idDirector integer, idEpisode integer)\n");
+
+  CLog::Log(LOGINFO, "create writerlinkepisode table");
+  m_pDS->exec("CREATE TABLE writerlinkepisode ( idWriter integer, idEpisode integer)\n");
+
+  CLog::Log(LOGINFO, "create genrelinktvshow table");
+  m_pDS->exec("CREATE TABLE genrelinktvshow ( idGenre integer, idShow integer)\n");
+
+  CLog::Log(LOGINFO, "create movielinktvshow table");
+  m_pDS->exec("CREATE TABLE movielinktvshow ( idMovie integer, IdShow integer)\n");
+
+  CLog::Log(LOGINFO, "create studio table");
+  m_pDS->exec("CREATE TABLE studio ( idStudio integer primary key, strStudio text)\n");
+
+  CLog::Log(LOGINFO, "create studiolinkmovie table");
+  m_pDS->exec("CREATE TABLE studiolinkmovie ( idStudio integer, idMovie integer)\n");
+
+  CLog::Log(LOGINFO, "create musicvideo table");
+  columns = "CREATE TABLE musicvideo ( idMVideo integer primary key, idFile integer";
+  for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
+    columns += StringUtils::Format(",c%02d text", i);;
+
+  columns += ")";
+  m_pDS->exec(columns.c_str());
+
+  CLog::Log(LOGINFO, "create artistlinkmusicvideo table");
+  m_pDS->exec("CREATE TABLE artistlinkmusicvideo ( idArtist integer, idMVideo integer)\n");
+
+  CLog::Log(LOGINFO, "create genrelinkmusicvideo table");
+  m_pDS->exec("CREATE TABLE genrelinkmusicvideo ( idGenre integer, idMVideo integer)\n");
+
+  CLog::Log(LOGINFO, "create studiolinkmusicvideo table");
+  m_pDS->exec("CREATE TABLE studiolinkmusicvideo ( idStudio integer, idMVideo integer)\n");
+
+  CLog::Log(LOGINFO, "create directorlinkmusicvideo table");
+  m_pDS->exec("CREATE TABLE directorlinkmusicvideo ( idDirector integer, idMVideo integer)\n");
+
+  CLog::Log(LOGINFO, "create streaminfo table");
+  m_pDS->exec("CREATE TABLE streamdetails (idFile integer, iStreamType integer, "
+    "strVideoCodec text, fVideoAspect float, iVideoWidth integer, iVideoHeight integer, "
+    "strAudioCodec text, iAudioChannels integer, strAudioLanguage text, strSubtitleLanguage text, iVideoDuration integer, strStereoMode text)");
+
+ CLog::Log(LOGINFO, "create sets table");
+  m_pDS->exec("CREATE TABLE sets ( idSet integer primary key, strSet text)\n");
+
+  CLog::Log(LOGINFO, "create seasons table");
+  m_pDS->exec("CREATE TABLE seasons ( idSeason integer primary key, idShow integer, season integer)");
+
+  CLog::Log(LOGINFO, "create art table");
+  m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
+
+  CLog::Log(LOGINFO, "create tag table");
+  m_pDS->exec("CREATE TABLE tag (idTag integer primary key, strTag text)");
+
+  CLog::Log(LOGINFO, "create taglinks table");
+  m_pDS->exec("CREATE TABLE taglinks (idTag integer, idMedia integer, media_type TEXT)");
+}
+
+void CVideoDatabase::CreateAnalytics()
 {
   /* indexes should be added on any columns that are used in in  */
   /* a where or a join. primary key on a column is the same as a */
@@ -94,276 +247,116 @@ bool CVideoDatabase::CreateTables()
   /* advantage of a index that has been created on ( idGenre, idMovie ) */
   /*, hower on on ( idMovie, idGenre ) will be considered for use       */
 
-  BeginTransaction();
-  try
-  {
-    CDatabase::CreateTables();
-
-    CLog::Log(LOGINFO, "create bookmark table");
-    m_pDS->exec("CREATE TABLE bookmark ( idBookmark integer primary key, idFile integer, timeInSeconds double, totalTimeInSeconds double, thumbNailImage text, player text, playerState text, type integer)\n");
-    m_pDS->exec("CREATE INDEX ix_bookmark ON bookmark (idFile, type)");
-
-    CLog::Log(LOGINFO, "create settings table");
-    m_pDS->exec("CREATE TABLE settings ( idFile integer, Deinterlace bool,"
-                "ViewMode integer,ZoomAmount float, PixelRatio float, VerticalShift float, AudioStream integer, SubtitleStream integer,"
-                "SubtitleDelay float, SubtitlesOn bool, Brightness float, Contrast float, Gamma float,"
-                "VolumeAmplification float, AudioDelay float, OutputToAllSpeakers bool, ResumeTime integer, Crop bool, CropLeft integer,"
-                "CropRight integer, CropTop integer, CropBottom integer, Sharpness float, NoiseReduction float, NonLinStretch bool, PostProcess bool,"
-                "ScalingMethod integer, DeinterlaceMode integer, StereoMode integer, StereoInvert bool)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_settings ON settings ( idFile )\n");
-
-    CLog::Log(LOGINFO, "create stacktimes table");
-    m_pDS->exec("CREATE TABLE stacktimes (idFile integer, times text)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_stacktimes ON stacktimes ( idFile )\n");
-
-    CLog::Log(LOGINFO, "create genre table");
-    m_pDS->exec("CREATE TABLE genre ( idGenre integer primary key, strGenre text)\n");
-
-    CLog::Log(LOGINFO, "create genrelinkmovie table");
-    m_pDS->exec("CREATE TABLE genrelinkmovie ( idGenre integer, idMovie integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmovie_1 ON genrelinkmovie ( idGenre, idMovie)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmovie_2 ON genrelinkmovie ( idMovie, idGenre)\n");
-
-    CLog::Log(LOGINFO, "create country table");
-    m_pDS->exec("CREATE TABLE country ( idCountry integer primary key, strCountry text)\n");
-
-    CLog::Log(LOGINFO, "create countrylinkmovie table");
-    m_pDS->exec("CREATE TABLE countrylinkmovie ( idCountry integer, idMovie integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_countrylinkmovie_1 ON countrylinkmovie ( idCountry, idMovie)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_countrylinkmovie_2 ON countrylinkmovie ( idMovie, idCountry)\n");
-
-    CLog::Log(LOGINFO, "create movie table");
-    CStdString columns = "CREATE TABLE movie ( idMovie integer primary key, idFile integer";
-
-    for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
-      columns += StringUtils::Format(",c%02d text", i);
-
-    columns += ", idSet integer)";
-    m_pDS->exec(columns.c_str());
-    m_pDS->exec("CREATE UNIQUE INDEX ix_movie_file_1 ON movie (idFile, idMovie)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_movie_file_2 ON movie (idMovie, idFile)");
-
-    CLog::Log(LOGINFO, "create actorlinkmovie table");
-    m_pDS->exec("CREATE TABLE actorlinkmovie ( idActor integer, idMovie integer, strRole text, iOrder integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkmovie_1 ON actorlinkmovie ( idActor, idMovie )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkmovie_2 ON actorlinkmovie ( idMovie, idActor )\n");
-
-    CLog::Log(LOGINFO, "create directorlinkmovie table");
-    m_pDS->exec("CREATE TABLE directorlinkmovie ( idDirector integer, idMovie integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmovie_1 ON directorlinkmovie ( idDirector, idMovie )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmovie_2 ON directorlinkmovie ( idMovie, idDirector )\n");
-
-    CLog::Log(LOGINFO, "create writerlinkmovie table");
-    m_pDS->exec("CREATE TABLE writerlinkmovie ( idWriter integer, idMovie integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkmovie_1 ON writerlinkmovie ( idWriter, idMovie )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkmovie_2 ON writerlinkmovie ( idMovie, idWriter )\n");
-
-    CLog::Log(LOGINFO, "create actors table");
-    m_pDS->exec("CREATE TABLE actors ( idActor integer primary key, strActor text, strThumb text )\n");
-
-    CLog::Log(LOGINFO, "create path table");
-    m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate bool, exclude bool, dateAdded text)");
-    m_pDS->exec("CREATE INDEX ix_path ON path ( strPath(255) )");
-
-    CLog::Log(LOGINFO, "create files table");
-    m_pDS->exec("CREATE TABLE files ( idFile integer primary key, idPath integer, strFilename text, playCount integer, lastPlayed text, dateAdded text)");
-    m_pDS->exec("CREATE INDEX ix_files ON files ( idPath, strFilename(255) )");
-
-    CLog::Log(LOGINFO, "create tvshow table");
-    columns = "CREATE TABLE tvshow ( idShow integer primary key";
-
-    for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
-      columns += StringUtils::Format(",c%02d text", i);;
-
-    columns += ")";
-    m_pDS->exec(columns.c_str());
-
-    CLog::Log(LOGINFO, "create directorlinktvshow table");
-    m_pDS->exec("CREATE TABLE directorlinktvshow ( idDirector integer, idShow integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinktvshow_1 ON directorlinktvshow ( idDirector, idShow )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinktvshow_2 ON directorlinktvshow ( idShow, idDirector )\n");
-
-    CLog::Log(LOGINFO, "create actorlinktvshow table");
-    m_pDS->exec("CREATE TABLE actorlinktvshow ( idActor integer, idShow integer, strRole text, iOrder integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinktvshow_1 ON actorlinktvshow ( idActor, idShow )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinktvshow_2 ON actorlinktvshow ( idShow, idActor )\n");
-
-    CLog::Log(LOGINFO, "create studiolinktvshow table");
-    m_pDS->exec("CREATE TABLE studiolinktvshow ( idStudio integer, idShow integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinktvshow_1 ON studiolinktvshow ( idStudio, idShow)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinktvshow_2 ON studiolinktvshow ( idShow, idStudio)\n");
-
-    CLog::Log(LOGINFO, "create episode table");
-    columns = "CREATE TABLE episode ( idEpisode integer primary key, idFile integer";
-    for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
-    {
-      CStdString column;
-      if ( i == VIDEODB_ID_EPISODE_SEASON || i == VIDEODB_ID_EPISODE_EPISODE || i == VIDEODB_ID_EPISODE_BOOKMARK)
-        column = StringUtils::Format(",c%02d varchar(24)", i);
-      else
-        column = StringUtils::Format(",c%02d text", i);
-
-      columns += column;
-    }
-    columns += ", idShow integer)";
-    m_pDS->exec(columns.c_str());
-    m_pDS->exec("CREATE UNIQUE INDEX ix_episode_file_1 on episode (idEpisode, idFile)");
-    m_pDS->exec("CREATE UNIQUE INDEX id_episode_file_2 on episode (idFile, idEpisode)");
-    CStdString createColIndex = StringUtils::Format("CREATE INDEX ix_episode_season_episode on episode (c%02d, c%02d)", VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_EPISODE);
-    m_pDS->exec(createColIndex.c_str());
-    createColIndex = StringUtils::Format("CREATE INDEX ix_episode_bookmark on episode (c%02d)", VIDEODB_ID_EPISODE_BOOKMARK);
-    m_pDS->exec(createColIndex.c_str());
-    m_pDS->exec("CREATE INDEX ix_episode_show1 on episode(idEpisode,idShow)");
-    m_pDS->exec("CREATE INDEX ix_episode_show2 on episode(idShow,idEpisode)");
-
-    CLog::Log(LOGINFO, "create tvshowlinkpath table");
-    m_pDS->exec("CREATE TABLE tvshowlinkpath (idShow integer, idPath integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_tvshowlinkpath_1 ON tvshowlinkpath ( idShow, idPath )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_tvshowlinkpath_2 ON tvshowlinkpath ( idPath, idShow )\n");
-
-    CLog::Log(LOGINFO, "create actorlinkepisode table");
-    m_pDS->exec("CREATE TABLE actorlinkepisode ( idActor integer, idEpisode integer, strRole text, iOrder integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkepisode_1 ON actorlinkepisode ( idActor, idEpisode )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkepisode_2 ON actorlinkepisode ( idEpisode, idActor )\n");
-
-    CLog::Log(LOGINFO, "create directorlinkepisode table");
-    m_pDS->exec("CREATE TABLE directorlinkepisode ( idDirector integer, idEpisode integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkepisode_1 ON directorlinkepisode ( idDirector, idEpisode )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkepisode_2 ON directorlinkepisode ( idEpisode, idDirector )\n");
-
-    CLog::Log(LOGINFO, "create writerlinkepisode table");
-    m_pDS->exec("CREATE TABLE writerlinkepisode ( idWriter integer, idEpisode integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkepisode_1 ON writerlinkepisode ( idWriter, idEpisode )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkepisode_2 ON writerlinkepisode ( idEpisode, idWriter )\n");
-
-    CLog::Log(LOGINFO, "create genrelinktvshow table");
-    m_pDS->exec("CREATE TABLE genrelinktvshow ( idGenre integer, idShow integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinktvshow_1 ON genrelinktvshow ( idGenre, idShow)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinktvshow_2 ON genrelinktvshow ( idShow, idGenre)\n");
-
-    CLog::Log(LOGINFO, "create movielinktvshow table");
-    m_pDS->exec("CREATE TABLE movielinktvshow ( idMovie integer, IdShow integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_movielinktvshow_1 ON movielinktvshow ( idShow, idMovie)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_movielinktvshow_2 ON movielinktvshow ( idMovie, idShow)\n");
-
-    CLog::Log(LOGINFO, "create studio table");
-    m_pDS->exec("CREATE TABLE studio ( idStudio integer primary key, strStudio text)\n");
-
-    CLog::Log(LOGINFO, "create studiolinkmovie table");
-    m_pDS->exec("CREATE TABLE studiolinkmovie ( idStudio integer, idMovie integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmovie_1 ON studiolinkmovie ( idStudio, idMovie)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmovie_2 ON studiolinkmovie ( idMovie, idStudio)\n");
-
-    CLog::Log(LOGINFO, "create musicvideo table");
-    columns = "CREATE TABLE musicvideo ( idMVideo integer primary key, idFile integer";
-    for (int i = 0; i < VIDEODB_MAX_COLUMNS; i++)
-      columns += StringUtils::Format(",c%02d text", i);;
-
-    columns += ")";
-    m_pDS->exec(columns.c_str());
-
-    m_pDS->exec("CREATE UNIQUE INDEX ix_musicvideo_file_1 on musicvideo (idMVideo, idFile)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_musicvideo_file_2 on musicvideo (idFile, idMVideo)");
-
-    CLog::Log(LOGINFO, "create artistlinkmusicvideo table");
-    m_pDS->exec("CREATE TABLE artistlinkmusicvideo ( idArtist integer, idMVideo integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_artistlinkmusicvideo_1 ON artistlinkmusicvideo ( idArtist, idMVideo)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_artistlinkmusicvideo_2 ON artistlinkmusicvideo ( idMVideo, idArtist)\n");
-
-    CLog::Log(LOGINFO, "create genrelinkmusicvideo table");
-    m_pDS->exec("CREATE TABLE genrelinkmusicvideo ( idGenre integer, idMVideo integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmusicvideo_1 ON genrelinkmusicvideo ( idGenre, idMVideo)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmusicvideo_2 ON genrelinkmusicvideo ( idMVideo, idGenre)\n");
-
-    CLog::Log(LOGINFO, "create studiolinkmusicvideo table");
-    m_pDS->exec("CREATE TABLE studiolinkmusicvideo ( idStudio integer, idMVideo integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmusicvideo_1 ON studiolinkmusicvideo ( idStudio, idMVideo)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmusicvideo_2 ON studiolinkmusicvideo ( idMVideo, idStudio)\n");
-
-    CLog::Log(LOGINFO, "create directorlinkmusicvideo table");
-    m_pDS->exec("CREATE TABLE directorlinkmusicvideo ( idDirector integer, idMVideo integer)\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmusicvideo_1 ON directorlinkmusicvideo ( idDirector, idMVideo )\n");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmusicvideo_2 ON directorlinkmusicvideo ( idMVideo, idDirector )\n");
-
-    CLog::Log(LOGINFO, "create streaminfo table");
-    m_pDS->exec("CREATE TABLE streamdetails (idFile integer, iStreamType integer, "
-      "strVideoCodec text, fVideoAspect float, iVideoWidth integer, iVideoHeight integer, "
-      "strAudioCodec text, iAudioChannels integer, strAudioLanguage text, strSubtitleLanguage text, iVideoDuration integer, strStereoMode text)");
-    m_pDS->exec("CREATE INDEX ix_streamdetails ON streamdetails (idFile)");
-
-   CLog::Log(LOGINFO, "create sets table");
-    m_pDS->exec("CREATE TABLE sets ( idSet integer primary key, strSet text)\n");
-
-    // create basepath indices
-    m_pDS->exec("CREATE INDEX ixMovieBasePath ON movie ( c23(12) )");
-    m_pDS->exec("CREATE INDEX ixMusicVideoBasePath ON musicvideo ( c14(12) )");
-    m_pDS->exec("CREATE INDEX ixEpisodeBasePath ON episode ( c19(12) )");
-    m_pDS->exec("CREATE INDEX ixTVShowBasePath on tvshow ( c17(12) )");
-
-    CLog::Log(LOGINFO, "create seasons table");
-    m_pDS->exec("CREATE TABLE seasons ( idSeason integer primary key, idShow integer, season integer)");
-    m_pDS->exec("CREATE INDEX ix_seasons ON seasons (idShow, season)");
-
-    CLog::Log(LOGINFO, "create art table");
-    m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
-    m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
+  CLog::Log(LOGINFO, "%s - creating indicies", __FUNCTION__);
+  m_pDS->exec("CREATE INDEX ix_bookmark ON bookmark (idFile, type)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_settings ON settings ( idFile )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_stacktimes ON stacktimes ( idFile )\n");
+  m_pDS->exec("CREATE INDEX ix_path ON path ( strPath(255) )");
+  m_pDS->exec("CREATE INDEX ix_files ON files ( idPath, strFilename(255) )");
+
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmovie_1 ON genrelinkmovie ( idGenre, idMovie)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmovie_2 ON genrelinkmovie ( idMovie, idGenre)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_countrylinkmovie_1 ON countrylinkmovie ( idCountry, idMovie)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_countrylinkmovie_2 ON countrylinkmovie ( idMovie, idCountry)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_movie_file_1 ON movie (idFile, idMovie)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_movie_file_2 ON movie (idMovie, idFile)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkmovie_1 ON actorlinkmovie ( idActor, idMovie )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkmovie_2 ON actorlinkmovie ( idMovie, idActor )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmovie_1 ON directorlinkmovie ( idDirector, idMovie )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmovie_2 ON directorlinkmovie ( idMovie, idDirector )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkmovie_1 ON writerlinkmovie ( idWriter, idMovie )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkmovie_2 ON writerlinkmovie ( idMovie, idWriter )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmovie_1 ON studiolinkmovie ( idStudio, idMovie)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmovie_2 ON studiolinkmovie ( idMovie, idStudio)\n");
+
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinktvshow_1 ON directorlinktvshow ( idDirector, idShow )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinktvshow_2 ON directorlinktvshow ( idShow, idDirector )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinktvshow_1 ON actorlinktvshow ( idActor, idShow )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinktvshow_2 ON actorlinktvshow ( idShow, idActor )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinktvshow_1 ON studiolinktvshow ( idStudio, idShow)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinktvshow_2 ON studiolinktvshow ( idShow, idStudio)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_tvshowlinkpath_1 ON tvshowlinkpath ( idShow, idPath )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_tvshowlinkpath_2 ON tvshowlinkpath ( idPath, idShow )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_movielinktvshow_1 ON movielinktvshow ( idShow, idMovie)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_movielinktvshow_2 ON movielinktvshow ( idMovie, idShow)\n");
+
+  m_pDS->exec("CREATE UNIQUE INDEX ix_episode_file_1 on episode (idEpisode, idFile)");
+  m_pDS->exec("CREATE UNIQUE INDEX id_episode_file_2 on episode (idFile, idEpisode)");
+  CStdString createColIndex = StringUtils::Format("CREATE INDEX ix_episode_season_episode on episode (c%02d, c%02d)", VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_EPISODE);
+  m_pDS->exec(createColIndex.c_str());
+  createColIndex = StringUtils::Format("CREATE INDEX ix_episode_bookmark on episode (c%02d)", VIDEODB_ID_EPISODE_BOOKMARK);
+  m_pDS->exec(createColIndex.c_str());
+  m_pDS->exec("CREATE INDEX ix_episode_show1 on episode(idEpisode,idShow)");
+  m_pDS->exec("CREATE INDEX ix_episode_show2 on episode(idShow,idEpisode)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkepisode_1 ON actorlinkepisode ( idActor, idEpisode )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_actorlinkepisode_2 ON actorlinkepisode ( idEpisode, idActor )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkepisode_1 ON directorlinkepisode ( idDirector, idEpisode )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkepisode_2 ON directorlinkepisode ( idEpisode, idDirector )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkepisode_1 ON writerlinkepisode ( idWriter, idEpisode )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_writerlinkepisode_2 ON writerlinkepisode ( idEpisode, idWriter )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinktvshow_1 ON genrelinktvshow ( idGenre, idShow)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinktvshow_2 ON genrelinktvshow ( idShow, idGenre)\n");
+
+  m_pDS->exec("CREATE UNIQUE INDEX ix_musicvideo_file_1 on musicvideo (idMVideo, idFile)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_musicvideo_file_2 on musicvideo (idFile, idMVideo)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_artistlinkmusicvideo_1 ON artistlinkmusicvideo ( idArtist, idMVideo)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_artistlinkmusicvideo_2 ON artistlinkmusicvideo ( idMVideo, idArtist)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmusicvideo_1 ON genrelinkmusicvideo ( idGenre, idMVideo)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_genrelinkmusicvideo_2 ON genrelinkmusicvideo ( idMVideo, idGenre)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmusicvideo_1 ON studiolinkmusicvideo ( idStudio, idMVideo)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_studiolinkmusicvideo_2 ON studiolinkmusicvideo ( idMVideo, idStudio)\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmusicvideo_1 ON directorlinkmusicvideo ( idDirector, idMVideo )\n");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_directorlinkmusicvideo_2 ON directorlinkmusicvideo ( idMVideo, idDirector )\n");
+
+  m_pDS->exec("CREATE INDEX ixMovieBasePath ON movie ( c23(12) )");
+  m_pDS->exec("CREATE INDEX ixMusicVideoBasePath ON musicvideo ( c14(12) )");
+  m_pDS->exec("CREATE INDEX ixEpisodeBasePath ON episode ( c19(12) )");
+  m_pDS->exec("CREATE INDEX ixTVShowBasePath on tvshow ( c17(12) )");
+
+  m_pDS->exec("CREATE INDEX ix_streamdetails ON streamdetails (idFile)");
+  m_pDS->exec("CREATE INDEX ix_seasons ON seasons (idShow, season)");
+  m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
+
+  m_pDS->exec("CREATE UNIQUE INDEX ix_tag_1 ON tag (strTag(255))");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_1 ON taglinks (idTag, media_type(20), idMedia)");
+  m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_2 ON taglinks (idMedia, media_type(20), idTag)");
+  m_pDS->exec("CREATE INDEX ix_taglinks_3 ON taglinks (media_type(20))");
+
+  CLog::Log(LOGINFO, "%s - creating triggers", __FUNCTION__);
+  m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; "
+              "DELETE FROM taglinks WHERE idMedia=old.idMovie AND media_type='movie'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; "
+              "DELETE FROM taglinks WHERE idMedia=old.idShow AND media_type='tvshow'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; "
+              "DELETE FROM taglinks WHERE idMedia=old.idMVideo AND media_type='musicvideo'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN "
+              "DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); "
+              "END");
+  m_pDS->exec("CREATE TRIGGER delete_tag AFTER DELETE ON taglinks FOR EACH ROW BEGIN "
+              "DELETE FROM tag WHERE idTag=old.idTag AND idTag NOT IN (SELECT DISTINCT idTag FROM taglinks); "
+              "END");
 
-    CLog::Log(LOGINFO, "create tag table");
-    m_pDS->exec("CREATE TABLE tag (idTag integer primary key, strTag text)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_tag_1 ON tag (strTag(255))");
-
-    CLog::Log(LOGINFO, "create taglinks table");
-    m_pDS->exec("CREATE TABLE taglinks (idTag integer, idMedia integer, media_type TEXT)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_1 ON taglinks (idTag, media_type(20), idMedia)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_2 ON taglinks (idMedia, media_type(20), idTag)");
-    m_pDS->exec("CREATE INDEX ix_taglinks_3 ON taglinks (media_type(20))");
-
-    CLog::Log(LOGINFO, "create deletion triggers");
-    m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idMovie AND media_type='movie'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idShow AND media_type='tvshow'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idMVideo AND media_type='musicvideo'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_tag AFTER DELETE ON taglinks FOR EACH ROW BEGIN "
-                "DELETE FROM tag WHERE idTag=old.idTag AND idTag NOT IN (SELECT DISTINCT idTag FROM taglinks); "
-                "END");
-
-    // we create views last to ensure all indexes are rolled in
-    CreateViews();
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "%s unable to create tables:%i", __FUNCTION__, (int)GetLastError());
-    RollbackTransaction();
-    return false;
-  }
-  CommitTransaction();
-  return true;
+  CreateViews();
 }
 
 void CVideoDatabase::CreateViews()
 {
   CLog::Log(LOGINFO, "create episodeview");
-  m_pDS->exec("DROP VIEW IF EXISTS episodeview");
   CStdString episodeview = PrepareSQL("CREATE VIEW episodeview AS SELECT "
                                       "  episode.*,"
                                       "  files.strFileName AS strFileName,"
@@ -393,7 +386,6 @@ void CVideoDatabase::CreateViews()
   m_pDS->exec(episodeview.c_str());
 
   CLog::Log(LOGINFO, "create tvshowview");
-  m_pDS->exec("DROP VIEW IF EXISTS tvshowview");
   CStdString tvshowview = PrepareSQL("CREATE VIEW tvshowview AS SELECT "
                                      "  tvshow.*,"
                                      "  path.strPath AS strPath,"
@@ -415,7 +407,6 @@ void CVideoDatabase::CreateViews()
   m_pDS->exec(tvshowview.c_str());
 
   CLog::Log(LOGINFO, "create musicvideoview");
-  m_pDS->exec("DROP VIEW IF EXISTS musicvideoview");
   m_pDS->exec("CREATE VIEW musicvideoview AS SELECT"
               "  musicvideo.*,"
               "  files.strFileName as strFileName,"
@@ -434,7 +425,6 @@ void CVideoDatabase::CreateViews()
               "    bookmark.idFile=musicvideo.idFile AND bookmark.type=1");
 
   CLog::Log(LOGINFO, "create movieview");
-  m_pDS->exec("DROP VIEW IF EXISTS movieview");
   m_pDS->exec("CREATE VIEW movieview AS SELECT"
               "  movie.*,"
               "  sets.strSet AS strSet,"
@@ -2875,6 +2865,9 @@ void CVideoDatabase::DeleteMovie(const CStdString& strFilenameAndPath, bool bKee
     strSQL=PrepareSQL("delete from countrylinkmovie where idMovie=%i", idMovie);
     m_pDS->exec(strSQL.c_str());
 
+    strSQL=PrepareSQL("delete from writerlinkmovie where idMovie=%i", idMovie);
+    m_pDS->exec(strSQL.c_str());
+
     DeleteStreamDetails(GetFileId(strFilenameAndPath));
 
     // keep the movie table entry, linking to tv shows, and bookmarks
@@ -4157,162 +4150,8 @@ public:
   string media_type;
 };
 
-bool CVideoDatabase::UpdateOldVersion(int iVersion)
+void CVideoDatabase::UpdateTables(int iVersion)
 {
-  if (iVersion < 43)
-  {
-    m_pDS->exec("ALTER TABLE settings ADD VerticalShift float");
-  }
-  if (iVersion < 44)
-  {
-    // only if MySQL is used and default character set is not utf8
-    // string data needs to be converted to proper utf8
-    CStdString charset = m_pDS->getDatabase()->getDefaultCharset();
-    if (!m_sqlite && !charset.empty() && charset != "utf8")
-    {
-      map<CStdString, CStdStringArray> tables;
-      map<CStdString, CStdStringArray>::iterator itt;
-      CStdStringArray::iterator itc;
-
-      // columns that need to be converted
-      // content columns
-      CStdStringArray c_columns;
-      for (int i = 0; i < 22; i++)
-        c_columns.push_back(StringUtils::Format("c%02d", i));
-
-      tables.insert(pair<CStdString, CStdStringArray> ("episode", c_columns));
-      tables.insert(pair<CStdString, CStdStringArray> ("movie", c_columns));
-      tables.insert(pair<CStdString, CStdStringArray> ("musicvideo", c_columns));
-      tables.insert(pair<CStdString, CStdStringArray> ("tvshow", c_columns));
-
-      //common columns
-      CStdStringArray c1;
-      c1.push_back("strRole");
-      tables.insert(pair<CStdString, CStdStringArray> ("actorlinkepisode", c1));
-      tables.insert(pair<CStdString, CStdStringArray> ("actorlinkmovie", c1));
-      tables.insert(pair<CStdString, CStdStringArray> ("actorlinktvshow", c1));
-
-      //remaining columns
-      CStdStringArray c2;
-      c2.push_back("strActor");
-      tables.insert(pair<CStdString, CStdStringArray> ("actors", c2));
-
-      CStdStringArray c3;
-      c3.push_back("strCountry");
-      tables.insert(pair<CStdString, CStdStringArray> ("country", c3));
-
-      CStdStringArray c4;
-      c4.push_back("strFilename");
-      tables.insert(pair<CStdString, CStdStringArray> ("files", c4));
-
-      CStdStringArray c5;
-      c5.push_back("strGenre");
-      tables.insert(pair<CStdString, CStdStringArray> ("genre", c5));
-
-      CStdStringArray c6;
-      c6.push_back("strSet");
-      tables.insert(pair<CStdString, CStdStringArray> ("sets", c6));
-
-      CStdStringArray c7;
-      c7.push_back("strStudio");
-      tables.insert(pair<CStdString, CStdStringArray> ("studio", c7));
-
-      CStdStringArray c8;
-      c8.push_back("strPath");
-      tables.insert(pair<CStdString, CStdStringArray> ("path", c8));
-
-      for (itt = tables.begin(); itt != tables.end(); ++itt)
-      {
-        CStdString q;
-        q = PrepareSQL("UPDATE `%s` SET", itt->first.c_str());
-        for (itc = itt->second.begin(); itc != itt->second.end(); ++itc)
-        {
-          q += PrepareSQL(" `%s` = CONVERT(CAST(CONVERT(`%s` USING %s) AS BINARY) USING utf8)",
-                          itc->c_str(), itc->c_str(), charset.c_str());
-          if (*itc != itt->second.back())
-          {
-            q += ",";
-          }
-        }
-        m_pDS->exec(q);
-      }
-    }
-  }
-  if (iVersion < 45)
-  {
-    m_pDS->exec("ALTER TABLE movie ADD c22 text");
-    m_pDS->exec("ALTER TABLE episode ADD c22 text");
-    m_pDS->exec("ALTER TABLE musicvideo ADD c22 text");
-    m_pDS->exec("ALTER TABLE tvshow ADD c22 text");
-    // Now update our tables
-    UpdateBasePath("movie", "idMovie", VIDEODB_ID_BASEPATH);
-    UpdateBasePath("musicvideo", "idMVideo", VIDEODB_ID_MUSICVIDEO_BASEPATH);
-    UpdateBasePath("episode", "idEpisode", VIDEODB_ID_EPISODE_BASEPATH);
-    UpdateBasePath("tvshow", "idShow", VIDEODB_ID_TV_BASEPATH, true);
-  }
-  if (iVersion < 46)
-  { // add indices for dir entry lookups
-    m_pDS->exec("CREATE INDEX ixMovieBasePath ON movie ( c22(255) )");
-    m_pDS->exec("CREATE INDEX ixMusicVideoBasePath ON musicvideo ( c13(255) )");
-    m_pDS->exec("CREATE INDEX ixEpisodeBasePath ON episode ( c18(255) )");
-    m_pDS->exec("CREATE INDEX ixTVShowBasePath ON tvshow ( c16(255) )");
-  }
-  if (iVersion < 50)
-  {
-    m_pDS->exec("ALTER TABLE settings ADD ScalingMethod integer");
-    m_pDS->exec(PrepareSQL("UPDATE settings set ScalingMethod=%i", CMediaSettings::Get().GetDefaultVideoSettings().m_ScalingMethod));
-  }
-  if (iVersion < 51)
-  {
-    // Add iOrder fields to actorlink* tables to be able to list
-    // actors by importance
-    m_pDS->exec("ALTER TABLE actorlinkmovie ADD iOrder integer");
-    m_pDS->exec("ALTER TABLE actorlinktvshow ADD iOrder integer");
-    m_pDS->exec("ALTER TABLE actorlinkepisode ADD iOrder integer");
-  }
-  if (iVersion < 52)
-  { // Add basepath link to path table for faster content retrieval, and indicies
-    m_pDS->exec("ALTER TABLE movie ADD c23 text");
-    m_pDS->exec("ALTER TABLE episode ADD c23 text");
-    m_pDS->exec("ALTER TABLE musicvideo ADD c23 text");
-    m_pDS->exec("ALTER TABLE tvshow ADD c23 text");
-    m_pDS->dropIndex("movie", "ixMovieBasePath");
-    m_pDS->dropIndex("musicvideo", "ixMusicVideoBasePath");
-    m_pDS->dropIndex("episode", "ixEpisodeBasePath");
-    m_pDS->dropIndex("tvshow", "ixTVShowBasePath");
-    m_pDS->exec("CREATE INDEX ixMovieBasePath ON movie ( c23(12) )");
-    m_pDS->exec("CREATE INDEX ixMusicVideoBasePath ON musicvideo ( c14(12) )");
-    m_pDS->exec("CREATE INDEX ixEpisodeBasePath ON episode ( c19(12) )");
-    m_pDS->exec("CREATE INDEX ixTVShowBasePath ON tvshow ( c17(12) )");
-    // now update the base path links
-    UpdateBasePathID("movie", "idMovie", VIDEODB_ID_BASEPATH, VIDEODB_ID_PARENTPATHID);
-    UpdateBasePathID("musicvideo", "idMVideo", VIDEODB_ID_MUSICVIDEO_BASEPATH, VIDEODB_ID_MUSICVIDEO_PARENTPATHID);
-    UpdateBasePathID("episode", "idEpisode", VIDEODB_ID_EPISODE_BASEPATH, VIDEODB_ID_EPISODE_PARENTPATHID);
-    UpdateBasePathID("tvshow", "idShow", VIDEODB_ID_TV_BASEPATH, VIDEODB_ID_TV_PARENTPATHID);
-  }
-  if (iVersion < 54)
-  { // Change INDEX for bookmark table
-    m_pDS->dropIndex("bookmark", "ix_bookmark");
-    m_pDS->exec("CREATE INDEX ix_bookmark ON bookmark (idFile, type)");
-  }
-  if (iVersion < 55)
-  {
-    m_pDS->exec("ALTER TABLE settings ADD DeinterlaceMode integer");
-    m_pDS->exec("UPDATE settings SET DeinterlaceMode = 2 WHERE Deinterlace NOT IN (0,1)"); // anything other than none: method auto => mode force
-    m_pDS->exec("UPDATE settings SET DeinterlaceMode = 1 WHERE Deinterlace = 1"); // method auto => mode auto
-    m_pDS->exec("UPDATE settings SET DeinterlaceMode = 0, Deinterlace = 1 WHERE Deinterlace = 0"); // method none => mode off, method auto
-  }
-
-  if (iVersion < 59)
-  { // base paths for video_ts and bdmv files was wrong (and inconsistent depending on where and when they were scanned)
-    CStdString where = PrepareSQL(" WHERE files.strFileName LIKE 'VIDEO_TS.IFO' or files.strFileName LIKE 'index.BDMV'");
-    UpdateBasePath("movie", "idMovie", VIDEODB_ID_BASEPATH, false, where);
-    UpdateBasePath("musicvideo", "idMVideo", VIDEODB_ID_MUSICVIDEO_BASEPATH, false, where);
-    UpdateBasePath("episode", "idEpisode", VIDEODB_ID_EPISODE_BASEPATH, false, where);
-    UpdateBasePathID("movie", "idMovie", VIDEODB_ID_BASEPATH, VIDEODB_ID_PARENTPATHID);
-    UpdateBasePathID("musicvideo", "idMVideo", VIDEODB_ID_MUSICVIDEO_BASEPATH, VIDEODB_ID_MUSICVIDEO_PARENTPATHID);
-    UpdateBasePathID("episode", "idEpisode", VIDEODB_ID_EPISODE_BASEPATH, VIDEODB_ID_EPISODE_PARENTPATHID);
-  }
   if (iVersion < 61)
   {
     m_pDS->exec("ALTER TABLE path ADD dateAdded text");
@@ -4321,7 +4160,6 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
   if (iVersion < 62)
   { // add seasons table
     m_pDS->exec("CREATE TABLE seasons ( idSeason integer primary key, idShow integer, season integer)");
-    m_pDS->exec("CREATE INDEX ix_seasons ON seasons (idShow, season)");
     // insert all seasons for each show
     m_pDS->query("SELECT idShow FROM tvshow");
     while (!m_pDS->eof())
@@ -4330,7 +4168,9 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
                                   "  SELECT DISTINCT"
                                   "    idShow,c%02d"
                                   "  FROM"
-                                  "    episodeview"
+                                  "    episode"
+                                  "  JOIN tvshowlinkepisode ON"
+                                  "    episode.idEpisode=tvshowlinkepisode.idEpisode"
                                   "  WHERE idShow=%i", VIDEODB_ID_EPISODE_SEASON, m_pDS->fv(0).get_asInt());
       m_pDS2->exec(sql.c_str());
       // and the "all seasons node"
@@ -4342,14 +4182,6 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
   if (iVersion < 63)
   { // add art table
     m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
-    m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
-    m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; END");
-    m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; END");
-    m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; END");
-    m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; END");
-    m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; END");
-    m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; END");
-    m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); END");
 
     CMediaSettings::Get().SetVideoNeedsUpdate(63);
     CSettings::Get().Save();
@@ -4366,18 +4198,11 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
       m_pDS->next();
     }
     m_pDS->exec("DROP TABLE tvshowlinkepisode");
-    m_pDS->exec("CREATE INDEX ix_episode_show1 on episode(idEpisode,idShow)");
-    m_pDS->exec("CREATE INDEX ix_episode_show2 on episode(idShow,idEpisode)");
   }
   if (iVersion < 67)
   {
     m_pDS->exec("CREATE TABLE tag (idTag integer primary key, strTag text)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_tag_1 ON tag (strTag(255))");
-
     m_pDS->exec("CREATE TABLE taglinks (idTag integer, idMedia integer, media_type TEXT)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_1 ON taglinks (idTag, media_type(20), idMedia)");
-    m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_2 ON taglinks (idMedia, media_type(20), idTag)");
-    m_pDS->exec("CREATE INDEX ix_taglinks_3 ON taglinks (media_type(20))");
   }
   if (iVersion < 68)
   { // add idSet to movie table
@@ -4460,44 +4285,6 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
       }
     }
   }
-  if (iVersion < 73)
-  {
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_movie");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_tvshow");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_musicvideo");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_episode");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_season");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_set");
-    m_pDS->exec("DROP TRIGGER IF EXISTS delete_person");
-
-    m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idMovie AND media_type='movie'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idShow AND media_type='tvshow'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; "
-                "DELETE FROM taglinks WHERE idMedia=old.idMVideo AND media_type='musicvideo'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN "
-                "DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); "
-                "END");
-    m_pDS->exec("CREATE TRIGGER delete_tag AFTER DELETE ON taglinks FOR EACH ROW BEGIN "
-                "DELETE FROM tag WHERE idTag=old.idTag AND idTag NOT IN (SELECT DISTINCT idTag FROM taglinks); "
-                "END");
-  }
   if (iVersion < 74)
   { // update the runtime columns
     vector< pair<string, int> > tables;
@@ -4521,13 +4308,6 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
         m_pDS->exec(PrepareSQL("update %s set c%02d=%d where id%s=%d", (i->first=="mvideo")?"musicvideo":i->first.c_str(), i->second, j->second, i->first.c_str(), j->first));
     }
   }
-  if (iVersion < 75)
-  { // make indices on path, file non-unique (mysql has a prefix index, and prefixes aren't necessarily unique)
-    m_pDS->dropIndex("path", "ix_path");
-    m_pDS->dropIndex("files", "ix_files");
-    m_pDS->exec("CREATE INDEX ix_path ON path ( strPath(255) )");
-    m_pDS->exec("CREATE INDEX ix_files ON files ( idPath, strFilename(255) )");
-  }
   if (iVersion < 76)
   {
     m_pDS->exec("ALTER TABLE settings ADD StereoMode integer");
@@ -4535,15 +4315,11 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
   }
   if (iVersion < 77)
     m_pDS->exec("ALTER TABLE streamdetails ADD strStereoMode text");
-
-  // always recreate the view after any table change
-  CreateViews();
-  return true;
 }
 
-int CVideoDatabase::GetMinVersion() const
+int CVideoDatabase::GetSchemaVersion() const
 {
-  return 77;
+  return 78;
 }
 
 bool CVideoDatabase::LookupByFolders(const CStdString &path, bool shows)
@@ -4556,60 +4332,6 @@ bool CVideoDatabase::LookupByFolders(const CStdString &path, bool shows)
   return settings.parent_name_root; // shows, movies, musicvids
 }
 
-void CVideoDatabase::UpdateBasePath(const char *table, const char *id, int column, bool shows, const CStdString &where)
-{
-  CStdString query;
-  if (shows)
-    query = PrepareSQL("SELECT idShow,path.strPath from tvshowlinkpath join path on tvshowlinkpath.idPath=path.idPath");
-  else
-    query = PrepareSQL("SELECT %s.%s,path.strPath,files.strFileName from %s join files on %s.idFile=files.idFile join path on files.idPath=path.idPath", table, id, table, table);
-  query += where;
-
-  map<CStdString, bool> paths;
-  m_pDS2->query(query.c_str());
-  while (!m_pDS2->eof())
-  {
-    CStdString path(m_pDS2->fv(1).get_asString());
-    map<CStdString, bool>::iterator i = paths.find(path);
-    if (i == paths.end())
-    {
-      paths.insert(make_pair(path, LookupByFolders(path, shows)));
-      i = paths.find(path);
-    }
-    CStdString filename;
-    if (!shows)
-      ConstructPath(filename, path, m_pDS2->fv(2).get_asString());
-    else
-      filename = path;
-    CFileItem item(filename, shows);
-    path = item.GetBaseMoviePath(i->second);
-    CStdString sql = PrepareSQL("UPDATE %s set c%02d='%s' where %s.%s=%i", table, column, path.c_str(), table, id, m_pDS2->fv(0).get_asInt());
-    m_pDS->exec(sql.c_str());
-    m_pDS2->next();
-  }
-  m_pDS2->close();
-}
-
-void CVideoDatabase::UpdateBasePathID(const char *table, const char *id, int column, int idColumn)
-{
-  CStdString query = PrepareSQL("SELECT %s,c%02d from %s", id, column, table);
-  m_pDS2->query(query.c_str());
-  while (!m_pDS2->eof())
-  {
-    int rowID = m_pDS2->fv(0).get_asInt();
-    CStdString path(m_pDS2->fv(1).get_asString());
-    // find the parent path of this item
-    int pathID = AddPath(URIUtils::GetParentPath(path));
-    if (pathID >= 0)
-    {
-      CStdString sql = PrepareSQL("UPDATE %s SET c%02d=%d WHERE %s=%d", table, idColumn, pathID, id, rowID);
-      m_pDS->exec(sql.c_str());
-    }
-    m_pDS2->next();
-  }
-  m_pDS2->close();
-}
-
 bool CVideoDatabase::GetPlayCounts(const CStdString &strPath, CFileItemList &items)
 {
   if(URIUtils::IsMultiPath(strPath))
@@ -7579,7 +7301,7 @@ int CVideoDatabase::GetMatchingMusicVideo(const CStdString& strArtist, const CSt
     else
     { // we want to return the matching musicvideo
       if (CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && !g_passwordManager.bMasterUser)
-        strSQL = PrepareSQL("select musicvideo.idMVideo from musicvideo,files,path,artistlinkmusicvideo,actors where files.idFile=musicvideo.idFile and files.idPath=path.idPath and musicvideo.c%02d like '%s' and musicvideo.c%02d like '%s' and artistlinkmusicvideo.idMVideo=musicvideo.idMVideo and artistlinkmusicvideo.idArtist=actors.idActors and actors.strActor like '%s'",VIDEODB_ID_MUSICVIDEO_ALBUM,strAlbum.c_str(),VIDEODB_ID_MUSICVIDEO_TITLE,strTitle.c_str(),strArtist.c_str());
+        strSQL = PrepareSQL("select musicvideo.idMVideo from musicvideo,files,path,artistlinkmusicvideo,actors where files.idFile=musicvideo.idFile and files.idPath=path.idPath and musicvideo.c%02d like '%s' and musicvideo.c%02d like '%s' and artistlinkmusicvideo.idMVideo=musicvideo.idMVideo and artistlinkmusicvideo.idArtist=actors.idActor and actors.strActor like '%s'",VIDEODB_ID_MUSICVIDEO_ALBUM,strAlbum.c_str(),VIDEODB_ID_MUSICVIDEO_TITLE,strTitle.c_str(),strArtist.c_str());
       else
         strSQL = PrepareSQL("select musicvideo.idMVideo from musicvideo join artistlinkmusicvideo on artistlinkmusicvideo.idMVideo=musicvideo.idMVideo join actors on actors.idActor=artistlinkmusicvideo.idArtist where musicvideo.c%02d like '%s' and musicvideo.c%02d like '%s' and actors.strActor like '%s'",VIDEODB_ID_MUSICVIDEO_ALBUM,strAlbum.c_str(),VIDEODB_ID_MUSICVIDEO_TITLE,strTitle.c_str(),strArtist.c_str());
     }
index 44f94fa..9f84b23 100644 (file)
@@ -68,47 +68,47 @@ namespace VIDEO
 // these defines are based on how many columns we have and which column certain data is going to be in
 // when we do GetDetailsForMovie()
 #define VIDEODB_MAX_COLUMNS 24
-#define VIDEODB_DETAILS_FILEID                 1
-
-#define VIDEODB_DETAILS_MOVIE_SET_ID                   VIDEODB_MAX_COLUMNS + 2
-#define VIDEODB_DETAILS_MOVIE_SET_NAME         VIDEODB_MAX_COLUMNS + 3
-#define VIDEODB_DETAILS_MOVIE_FILE                     VIDEODB_MAX_COLUMNS + 4
-#define VIDEODB_DETAILS_MOVIE_PATH                     VIDEODB_MAX_COLUMNS + 5
-#define VIDEODB_DETAILS_MOVIE_PLAYCOUNT                VIDEODB_MAX_COLUMNS + 6
-#define VIDEODB_DETAILS_MOVIE_LASTPLAYED               VIDEODB_MAX_COLUMNS + 7
-#define VIDEODB_DETAILS_MOVIE_DATEADDED                VIDEODB_MAX_COLUMNS + 8
-#define VIDEODB_DETAILS_MOVIE_RESUME_TIME              VIDEODB_MAX_COLUMNS + 9
-#define VIDEODB_DETAILS_MOVIE_TOTAL_TIME               VIDEODB_MAX_COLUMNS + 10
-
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_ID     VIDEODB_MAX_COLUMNS + 2
-#define VIDEODB_DETAILS_EPISODE_FILE          VIDEODB_MAX_COLUMNS + 3
-#define VIDEODB_DETAILS_EPISODE_PATH          VIDEODB_MAX_COLUMNS + 4
-#define VIDEODB_DETAILS_EPISODE_PLAYCOUNT     VIDEODB_MAX_COLUMNS + 5
-#define VIDEODB_DETAILS_EPISODE_LASTPLAYED    VIDEODB_MAX_COLUMNS + 6
-#define VIDEODB_DETAILS_EPISODE_DATEADDED     VIDEODB_MAX_COLUMNS + 7
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_NAME   VIDEODB_MAX_COLUMNS + 8
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO VIDEODB_MAX_COLUMNS + 9
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED  VIDEODB_MAX_COLUMNS + 10
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA   VIDEODB_MAX_COLUMNS + 11
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_PATH   VIDEODB_MAX_COLUMNS + 12
-#define VIDEODB_DETAILS_EPISODE_RESUME_TIME   VIDEODB_MAX_COLUMNS + 13
-#define VIDEODB_DETAILS_EPISODE_TOTAL_TIME    VIDEODB_MAX_COLUMNS + 14
-#define VIDEODB_DETAILS_EPISODE_SEASON_ID     VIDEODB_MAX_COLUMNS + 15
-                                               
-#define VIDEODB_DETAILS_TVSHOW_PATH            VIDEODB_MAX_COLUMNS + 1
-#define VIDEODB_DETAILS_TVSHOW_DATEADDED               VIDEODB_MAX_COLUMNS + 2
-#define VIDEODB_DETAILS_TVSHOW_LASTPLAYED      VIDEODB_MAX_COLUMNS + 3
-#define VIDEODB_DETAILS_TVSHOW_NUM_EPISODES    VIDEODB_MAX_COLUMNS + 4
-#define VIDEODB_DETAILS_TVSHOW_NUM_WATCHED     VIDEODB_MAX_COLUMNS + 5
-#define VIDEODB_DETAILS_TVSHOW_NUM_SEASONS     VIDEODB_MAX_COLUMNS + 6
-
-#define VIDEODB_DETAILS_MUSICVIDEO_FILE                        VIDEODB_MAX_COLUMNS + 2
-#define VIDEODB_DETAILS_MUSICVIDEO_PATH                        VIDEODB_MAX_COLUMNS + 3
-#define VIDEODB_DETAILS_MUSICVIDEO_PLAYCOUNT           VIDEODB_MAX_COLUMNS + 4
-#define VIDEODB_DETAILS_MUSICVIDEO_LASTPLAYED          VIDEODB_MAX_COLUMNS + 5
-#define VIDEODB_DETAILS_MUSICVIDEO_DATEADDED           VIDEODB_MAX_COLUMNS + 6
-#define VIDEODB_DETAILS_MUSICVIDEO_RESUME_TIME         VIDEODB_MAX_COLUMNS + 7
-#define VIDEODB_DETAILS_MUSICVIDEO_TOTAL_TIME          VIDEODB_MAX_COLUMNS + 8
+#define VIDEODB_DETAILS_FILEID      1
+
+#define VIDEODB_DETAILS_MOVIE_SET_ID            VIDEODB_MAX_COLUMNS + 2
+#define VIDEODB_DETAILS_MOVIE_SET_NAME          VIDEODB_MAX_COLUMNS + 3
+#define VIDEODB_DETAILS_MOVIE_FILE              VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_MOVIE_PATH              VIDEODB_MAX_COLUMNS + 5
+#define VIDEODB_DETAILS_MOVIE_PLAYCOUNT         VIDEODB_MAX_COLUMNS + 6
+#define VIDEODB_DETAILS_MOVIE_LASTPLAYED        VIDEODB_MAX_COLUMNS + 7
+#define VIDEODB_DETAILS_MOVIE_DATEADDED         VIDEODB_MAX_COLUMNS + 8
+#define VIDEODB_DETAILS_MOVIE_RESUME_TIME       VIDEODB_MAX_COLUMNS + 9
+#define VIDEODB_DETAILS_MOVIE_TOTAL_TIME        VIDEODB_MAX_COLUMNS + 10
+
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_ID       VIDEODB_MAX_COLUMNS + 2
+#define VIDEODB_DETAILS_EPISODE_FILE            VIDEODB_MAX_COLUMNS + 3
+#define VIDEODB_DETAILS_EPISODE_PATH            VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_EPISODE_PLAYCOUNT       VIDEODB_MAX_COLUMNS + 5
+#define VIDEODB_DETAILS_EPISODE_LASTPLAYED      VIDEODB_MAX_COLUMNS + 6
+#define VIDEODB_DETAILS_EPISODE_DATEADDED       VIDEODB_MAX_COLUMNS + 7
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_NAME     VIDEODB_MAX_COLUMNS + 8
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO   VIDEODB_MAX_COLUMNS + 9
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED    VIDEODB_MAX_COLUMNS + 10
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA     VIDEODB_MAX_COLUMNS + 11
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_PATH     VIDEODB_MAX_COLUMNS + 12
+#define VIDEODB_DETAILS_EPISODE_RESUME_TIME     VIDEODB_MAX_COLUMNS + 13
+#define VIDEODB_DETAILS_EPISODE_TOTAL_TIME      VIDEODB_MAX_COLUMNS + 14
+#define VIDEODB_DETAILS_EPISODE_SEASON_ID       VIDEODB_MAX_COLUMNS + 15
+
+#define VIDEODB_DETAILS_TVSHOW_PATH             VIDEODB_MAX_COLUMNS + 1
+#define VIDEODB_DETAILS_TVSHOW_DATEADDED        VIDEODB_MAX_COLUMNS + 2
+#define VIDEODB_DETAILS_TVSHOW_LASTPLAYED       VIDEODB_MAX_COLUMNS + 3
+#define VIDEODB_DETAILS_TVSHOW_NUM_EPISODES     VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_TVSHOW_NUM_WATCHED      VIDEODB_MAX_COLUMNS + 5
+#define VIDEODB_DETAILS_TVSHOW_NUM_SEASONS      VIDEODB_MAX_COLUMNS + 6
+
+#define VIDEODB_DETAILS_MUSICVIDEO_FILE         VIDEODB_MAX_COLUMNS + 2
+#define VIDEODB_DETAILS_MUSICVIDEO_PATH         VIDEODB_MAX_COLUMNS + 3
+#define VIDEODB_DETAILS_MUSICVIDEO_PLAYCOUNT    VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_MUSICVIDEO_LASTPLAYED   VIDEODB_MAX_COLUMNS + 5
+#define VIDEODB_DETAILS_MUSICVIDEO_DATEADDED    VIDEODB_MAX_COLUMNS + 6
+#define VIDEODB_DETAILS_MUSICVIDEO_RESUME_TIME  VIDEODB_MAX_COLUMNS + 7
+#define VIDEODB_DETAILS_MUSICVIDEO_TOTAL_TIME   VIDEODB_MAX_COLUMNS + 8
 
 #define VIDEODB_TYPE_STRING 1
 #define VIDEODB_TYPE_INT 2
@@ -785,8 +785,9 @@ protected:
   CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;
 
 private:
-  virtual bool CreateTables();
-  virtual bool UpdateOldVersion(int version);
+  virtual void CreateTables();
+  virtual void CreateAnalytics();
+  virtual void UpdateTables(int version);
 
   /*! \brief (Re)Create the generic database views for movies, tvshows,
      episodes and music videos
@@ -800,32 +801,14 @@ private:
    */
   int RunQuery(const CStdString &sql);
 
-  /*! \brief Update routine for base path of videos
-   Only required for videodb version < 59
-   \param table the table to update
-   \param id the primary id in the given table
-   \param column the basepath column to update
-   \param shows whether we're fetching shows (defaults to false)
-   \param where restrict updating of items that match the where clause
-   */
-  void UpdateBasePath(const char *table, const char *id, int column, bool shows = false, const CStdString &where = "");
-
-  /*! \brief Update routine for base path id of videos
-   Only required for videodb version < 59
-   \param table the table to update
-   \param id the primary id in the given table
-   \param column the column of the basepath
-   \param idColumn the column of the parent path id to update
-   */
-  void UpdateBasePathID(const char *table, const char *id, int column, int idColumn);
-
   /*! \brief Determine whether the path is using lookup using folders
    \param path the path to check
    \param shows whether this path is from a tvshow (defaults to false)
    */
   bool LookupByFolders(const CStdString &path, bool shows = false);
 
-  virtual int GetMinVersion() const;
+  virtual int GetMinSchemaVersion() const { return 60; };
+  virtual int GetSchemaVersion() const;
   virtual int GetExportVersion() const { return 1; };
   const char *GetBaseDBName() const { return "MyVideos"; };
 
index 6bf67a8..162c0a1 100644 (file)
@@ -115,13 +115,13 @@ CGUIDialogSubtitles::~CGUIDialogSubtitles(void)
 
 bool CGUIDialogSubtitles::OnMessage(CGUIMessage& message)
 {
-  if  (message.GetMessage() == GUI_MSG_CLICKED &&
-       (message.GetParam1() == ACTION_SELECT_ITEM ||
-        message.GetParam1() == ACTION_MOUSE_LEFT_CLICK))
+  if (message.GetMessage() == GUI_MSG_CLICKED)
   {
     int iControl = message.GetSenderId();
+    bool selectAction = (message.GetParam1() == ACTION_SELECT_ITEM ||
+                         message.GetParam1() == ACTION_MOUSE_LEFT_CLICK);
 
-    if (iControl == CONTROL_SUBLIST)
+    if (selectAction && iControl == CONTROL_SUBLIST)
     {
       CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SUBLIST);
       OnMessage(msg);
@@ -131,7 +131,7 @@ bool CGUIDialogSubtitles::OnMessage(CGUIMessage& message)
         Download(*m_subtitles->Get(item));
       return true;
     }
-    else if (iControl == CONTROL_SERVICELIST)
+    else if (selectAction && iControl == CONTROL_SERVICELIST)
     {
       CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SERVICELIST);
       OnMessage(msg);
@@ -236,7 +236,7 @@ void CGUIDialogSubtitles::FillServices()
   }
 
   std::string defaultService;
-  const CFileItem &item = g_application.CurrentFileItem();
+  const CFileItem &item = g_application.CurrentUnstackedItem();
   if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS ||
       item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES)
     // Set default service for tv shows
@@ -404,65 +404,97 @@ void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const s
     return;
   }
 
-  CStdString strFileName;
+  // Get (unstacked) path
+  const CStdString &strCurrentFile = g_application.CurrentUnstackedItem().GetPath();
+
+  CStdString strFileName = "TemporarySubs";
+  CStdString strDownloadPath = "special://temp";
   CStdString strDestPath;
-  if (g_application.CurrentFileItem().IsStack())
-  {
-    for (int i = 0; i < items->Size(); i++)
-    {
-//    check for all stack items and match to given subs, item [0] == CD1, item [1] == CD2
-//    CLog::Log(LOGDEBUG, "Stack Subs [%s} Found", vecItems[i]->GetLabel().c_str());
-    }
-  }
-  else if (StringUtils::StartsWith(g_application.CurrentFile(), "http://"))
-  {
-    strFileName = "TemporarySubs";
-    strDestPath = "special://temp/";
-  }
-  else
+
+  CStdString strCurrentFilePath = URIUtils::GetDirectory(strCurrentFile);
+  if (!StringUtils::StartsWith(strCurrentFilePath, "http://"))
   {
-    strFileName = URIUtils::GetFileName(g_application.CurrentFile());
-    if (CSettings::Get().GetBool("subtitles.savetomoviefolder"))
+    CStdString subPath = CSpecialProtocol::TranslatePath("special://subtitles");
+    if (!subPath.empty())
+      strDownloadPath = subPath;
+
+    strFileName = URIUtils::GetFileName(strCurrentFile);
+    if (CSettings::Get().GetBool("subtitles.savetomoviefolder") &&
+        CUtil::SupportsWriteFileOperations(strCurrentFilePath))
     {
-      strDestPath = URIUtils::GetDirectory(g_application.CurrentFile());
-      if (!CUtil::SupportsWriteFileOperations(strDestPath))
-        strDestPath.clear();
-    }
-    if (strDestPath.empty())
-    {
-      if (CSpecialProtocol::TranslatePath("special://subtitles").empty())
-        strDestPath = "special://temp";
-      else
-        strDestPath = "special://subtitles";
+      strDestPath = strCurrentFilePath;
     }
   }
+
+  // Use fallback?
+  if (strDestPath.empty())
+    strDestPath = strDownloadPath;
+
   // Extract the language and appropriate extension
   CStdString strSubLang;
   g_LangCodeExpander.ConvertToTwoCharCode(strSubLang, language);
-  CStdString strUrl = items->Get(0)->GetPath();
-  CStdString strSubExt = URIUtils::GetExtension(strUrl);
-
-  // construct subtitle path
   URIUtils::RemoveExtension(strFileName);
-  CStdString strSubName = StringUtils::Format("%s.%s%s", strFileName.c_str(), strSubLang.c_str(), strSubExt.c_str());
-  CStdString strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubName);
-
-  // and copy the file across
-  CFile::Cache(strUrl, strSubPath);
 
-  // for ".sub" subtitles we check if ".idx" counterpart exists and copy that as well
-  if (strSubExt.Equals(".sub"))
+  // Iterate over all items to transfer
+  for (int i = 0; i < items->Size(); i++)
   {
-    strUrl = URIUtils::ReplaceExtension(strUrl, ".idx");
-    if(CFile::Exists(strUrl))
+    CStdString strUrl = items->Get(i)->GetPath();
+
+    // construct subtitle path
+    CStdString strSubExt = URIUtils::GetExtension(strUrl);
+    CStdString strSubName = StringUtils::Format("%s.%s%s", strFileName.c_str(), strSubLang.c_str(), strSubExt.c_str());
+
+    // Handle URL decoding/slash correction:
+    CStdString strDownloadFile = URIUtils::ChangeBasePath(strCurrentFilePath, strSubName, strDownloadPath);
+    CStdString strDestFile = strDownloadFile;
+
+    if (!CFile::Cache(strUrl, strDownloadFile))
+    {
+      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, strSubName, g_localizeStrings.Get(24113));
+    }
+    else
     {
-      CStdString strSubNameIdx = StringUtils::Format("%s.%s.idx", strFileName.c_str(), strSubLang.c_str());
-      strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubNameIdx);
-      CFile::Cache(strUrl, strSubPath);
+      if (strDestPath != strDownloadPath)
+      {
+        CStdString strTryDestFile = URIUtils::ChangeBasePath(strCurrentFilePath, strSubName, strDestPath);
+
+        /* Copy the file from temp to our final destination, if that fails fallback to download path
+         * (ie. special://subtitles or use special://temp). Note that after the first item strDownloadPath equals strDestpath
+         * so that all remaining items (including the .idx below) are copied directly to their final destination and thus all
+         * items end up in the same folder
+         */
+        CLog::Log(LOGDEBUG, "%s - Saving subtitle %s to %s", __FUNCTION__, strDownloadFile.c_str(), strDestPath.c_str());
+        if (CFile::Cache(strDownloadFile, strTryDestFile))
+        {
+          CFile::Delete(strDownloadFile);
+          strDestFile = strTryDestFile;
+          strDownloadPath = strDestPath; // Update download path so all the other items get directly downloaded to our final destination
+        }
+        else
+        {
+          CLog::Log(LOGWARNING, "%s - Saving of subtitle %s to %s failed. Falling back to %s", __FUNCTION__, strDownloadFile.c_str(), strDestPath.c_str(), strDownloadPath.c_str());
+          strDestPath = strDownloadPath; // Copy failed, use fallback for the rest of the items
+        }
+      }
+
+      // for ".sub" subtitles we check if ".idx" counterpart exists and copy that as well
+      if (strSubExt.Equals(".sub"))
+      {
+        strUrl = URIUtils::ReplaceExtension(strUrl, ".idx");
+        if(CFile::Exists(strUrl))
+        {
+          CStdString strSubNameIdx = StringUtils::Format("%s.%s.idx", strFileName.c_str(), strSubLang.c_str());
+          // Handle URL decoding/slash correction:
+          strDestFile = URIUtils::ChangeBasePath(strCurrentFilePath, strSubNameIdx, strDestPath);
+          CFile::Cache(strUrl, strDestFile);
+        }
+      }
+
+      // FIXME: With multiple files (eg. stacks), select the correct one
+      SetSubtitles(strDestFile);
     }
   }
 
-  SetSubtitles(strSubPath);
   // Close the window
   Close();
 }
index 03f1aa6..17b2420 100644 (file)
@@ -1306,7 +1306,6 @@ bool CGUIDialogVideoInfo::DeleteVideoItem(const CFileItemPtr &item, bool unavail
   if (!DeleteVideoItemFromDatabase(item, unavailable))
     return false;
 
-  bool result = true;
   // check if the user is allowed to delete the actual file as well
   if ((CProfilesManager::Get().GetCurrentProfile().getLockMode() == LOCK_MODE_EVERYONE ||
        !CProfilesManager::Get().GetCurrentProfile().filesLocked() ||
@@ -1335,13 +1334,13 @@ bool CGUIDialogVideoInfo::DeleteVideoItem(const CFileItemPtr &item, bool unavail
       // HACK: stacked files need to be treated as folders in order to be deleted
       if (item->IsStack())
         item->m_bIsFolder = true;
-      result = CFileUtils::DeleteItem(item);
+      CFileUtils::DeleteItem(item);
     }
   }
 
   CUtil::DeleteVideoDatabaseDirectoryCache();
 
-  return result;
+  return true;
 }
 
 bool CGUIDialogVideoInfo::ManageMovieSets(const CFileItemPtr &item)
index 548d0ff..a4f5729 100644 (file)
@@ -518,7 +518,7 @@ EVENT_RESULT CGUIWindowFullScreen::OnMouseEvent(const CPoint &point, const CMous
   {
     return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_BACK, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED;
   }
-  if (event.m_id == ACTION_GESTURE_NOTIFY)
+  if (event.m_id >= ACTION_GESTURE_NOTIFY && event.m_id <= ACTION_GESTURE_END) // gestures
     return EVENT_RESULT_UNHANDLED;
   if (event.m_id != ACTION_MOUSE_MOVE || event.m_offsetX || event.m_offsetY)
   { // some other mouse action has occurred - bring up the OSD
index 37e01d9..60f3ad3 100644 (file)
@@ -285,12 +285,12 @@ bool CGUIWindowVideoNav::GetDirectory(const CStdString &strDirectory, CFileItemL
       VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(items.GetPath());
 
       // perform the flattening logic for tvshows with a single (unwatched) season (+ optional special season)
-      if (node == NODE_TYPE_SEASONS)
+      if (node == NODE_TYPE_SEASONS && !items.IsEmpty())
       {
         int itemsSize = items.GetObjectCount();
         int firstIndex = items.Size() - itemsSize;
         // check if the last item is the "All seasons" item which should be ignored for flattening
-        if (items[items.Size() - 1]->GetVideoInfoTag()->m_iSeason < 0)
+        if (!items[items.Size() - 1]->HasVideoInfoTag() || items[items.Size() - 1]->GetVideoInfoTag()->m_iSeason < 0)
           itemsSize -= 1;
 
         int iFlatten = CSettings::Get().GetInt("videolibrary.flattentvshows");
index 45d79e5..3467fd6 100644 (file)
@@ -48,38 +48,28 @@ bool CViewDatabase::Open()
   return CDatabase::Open();
 }
 
-bool CViewDatabase::CreateTables()
+void CViewDatabase::CreateTables()
 {
-  try
-  {
-    CDatabase::CreateTables();
-
-    CLog::Log(LOGINFO, "create view table");
-    m_pDS->exec("CREATE TABLE view ("
-                  "idView integer primary key,"
-                  "window integer,"
-                  "path text,"
-                  "viewMode integer,"
-                  "sortMethod integer,"
-                  "sortOrder integer,"
-                  "sortAttributes integer,"
-                  "skin text)\n");
-    CLog::Log(LOGINFO, "create view index");
-    m_pDS->exec("CREATE INDEX idxViews ON view(path)");
-    CLog::Log(LOGINFO, "create view - window index");
-    m_pDS->exec("CREATE INDEX idxViewsWindow ON view(window)");
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR, "%s unable to create tables:%u",
-              __FUNCTION__, GetLastError());
-    return false;
-  }
+  CLog::Log(LOGINFO, "create view table");
+  m_pDS->exec("CREATE TABLE view ("
+                "idView integer primary key,"
+                "window integer,"
+                "path text,"
+                "viewMode integer,"
+                "sortMethod integer,"
+                "sortOrder integer,"
+                "sortAttributes integer,"
+                "skin text)\n");
+}
 
-  return true;
+void CViewDatabase::CreateAnalytics()
+{
+  CLog::Log(LOGINFO, "%s - creating indicies", __FUNCTION__);
+  m_pDS->exec("CREATE INDEX idxViews ON view(path)");
+  m_pDS->exec("CREATE INDEX idxViewsWindow ON view(window)");
 }
 
-bool CViewDatabase::UpdateOldVersion(int version)
+void CViewDatabase::UpdateTables(int version)
 {
   if (version < 4)
     m_pDS->exec("alter table view add skin text");
@@ -112,8 +102,6 @@ bool CViewDatabase::UpdateOldVersion(int version)
   {
     // convert the "path" table
     m_pDS->exec("CREATE TABLE tmp_view AS SELECT * FROM view");
-    m_pDS->exec("DROP INDEX idxViews");
-    m_pDS->exec("DROP INDEX idxViewsWindow");
     m_pDS->exec("DROP TABLE view");
 
     m_pDS->exec("CREATE TABLE view ("
@@ -125,8 +113,6 @@ bool CViewDatabase::UpdateOldVersion(int version)
                 "sortOrder integer,"
                 "sortAttributes integer,"
                 "skin text)\n");
-    m_pDS->exec("CREATE INDEX idxViews ON view(path)");
-    m_pDS->exec("CREATE INDEX idxViewsWindow ON view(window)");
     
     m_pDS->query("SELECT * FROM tmp_view");
     while (!m_pDS->eof())
@@ -142,8 +128,6 @@ bool CViewDatabase::UpdateOldVersion(int version)
     }
     m_pDS->exec("DROP TABLE tmp_view");
   }
-
-  return true;
 }
 
 bool CViewDatabase::GetViewState(const CStdString &path, int window, CViewState &state, const CStdString &skin)
index 191a20f..fbe35d3 100644 (file)
@@ -34,8 +34,9 @@ public:
   bool ClearViewStates(int windowID);
 
 protected:
-  virtual bool CreateTables();
-  virtual bool UpdateOldVersion(int version);
-  virtual int GetMinVersion() const { return 6; };
+  virtual void CreateTables();
+  virtual void CreateAnalytics();
+  virtual void UpdateTables(int version);
+  virtual int GetSchemaVersion() const { return 6; };
   const char *GetBaseDBName() const { return "ViewModes"; };
 };
diff --git a/xbmc/win32/IMMNotificationClient.h b/xbmc/win32/IMMNotificationClient.h
new file mode 100644 (file)
index 0000000..aa07537
--- /dev/null
@@ -0,0 +1,167 @@
+//#pragma once
+/*
+ *      Copyright (C) 2014 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 <Audioclient.h>
+#include <mmdeviceapi.h>
+#include "system.h" // for SAFE_RELEASE
+#include "utils/log.h"
+#include "cores/AudioEngine/AEFactory.h"
+
+class CMMNotificationClient : public IMMNotificationClient
+{
+  LONG _cRef;
+  IMMDeviceEnumerator *_pEnumerator;
+
+
+public:
+  CMMNotificationClient() : _cRef(1), _pEnumerator(NULL)
+  {
+  }
+
+  ~CMMNotificationClient()
+  {
+    SAFE_RELEASE(_pEnumerator);
+  }
+
+  // IUnknown methods -- AddRef, Release, and QueryInterface
+
+  ULONG STDMETHODCALLTYPE AddRef()
+  {
+    return InterlockedIncrement(&_cRef);
+  }
+
+  ULONG STDMETHODCALLTYPE Release()
+  {
+    ULONG ulRef = InterlockedDecrement(&_cRef);
+    if (0 == ulRef)
+    {
+      delete this;
+    }
+    return ulRef;
+  }
+
+  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
+  {
+    if (IID_IUnknown == riid)
+    {
+      AddRef();
+      *ppvInterface = (IUnknown*)this;
+    }
+    else if (__uuidof(IMMNotificationClient) == riid)
+    {
+      AddRef();
+      *ppvInterface = (IMMNotificationClient*)this;
+    }
+    else
+    {
+      *ppvInterface = NULL;
+      return E_NOINTERFACE;
+    }
+    return S_OK;
+  }
+
+  // Callback methods for device-event notifications.
+
+  HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
+  {
+    // if the default device changes this function is called four times.
+    // therefore we call CAEFactory::DeviceChange() only for one role.
+    char  *pszFlow = "?????";
+    char  *pszRole = "?????";
+
+    switch (flow)
+    {
+    case eRender:
+      pszFlow = "eRender";
+      break;
+    case eCapture:
+      pszFlow = "eCapture";
+      break;
+    }
+
+    switch (role)
+    {
+    case eConsole:
+      pszRole = "eConsole";
+      break;
+    case eMultimedia:
+      pszRole = "eMultimedia";
+      break;
+    case eCommunications:
+      pszRole = "eCommunications";
+      CAEFactory::DeviceChange();
+      break;
+    }
+
+    CLog::Log(LOGDEBUG, "%s: New default device: flow = %s, role = %s", __FUNCTION__, pszFlow, pszRole);
+    return S_OK;
+  }
+
+  HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
+  {
+    CLog::Log(LOGDEBUG, "%s: Added device: %s", __FUNCTION__, pwstrDeviceId);
+    CAEFactory::DeviceChange();
+    return S_OK;
+  }
+
+  HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
+  {
+    CLog::Log(LOGDEBUG, "%s: Removed device: %s", __FUNCTION__, pwstrDeviceId);
+    CAEFactory::DeviceChange();
+    return S_OK;
+  }
+
+  HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
+  {
+    char  *pszState = "?????";
+
+    switch (dwNewState)
+    {
+    case DEVICE_STATE_ACTIVE:
+      pszState = "ACTIVE";
+      break;
+    case DEVICE_STATE_DISABLED:
+      pszState = "DISABLED";
+      break;
+    case DEVICE_STATE_NOTPRESENT:
+      pszState = "NOTPRESENT";
+      break;
+    case DEVICE_STATE_UNPLUGGED:
+      pszState = "UNPLUGGED";
+      break;
+    }
+    CLog::Log(LOGDEBUG, "%s: New device state is DEVICE_STATE_%s", __FUNCTION__, pszState);
+    CAEFactory::DeviceChange();
+    return S_OK;
+  }
+
+  HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
+  {
+    CLog::Log(LOGDEBUG, "%s: Changed device property of %s is {%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}#%d", 
+              __FUNCTION__, pwstrDeviceId, key.fmtid.Data1, key.fmtid.Data2, key.fmtid.Data3,
+                                           key.fmtid.Data4[0], key.fmtid.Data4[1],
+                                           key.fmtid.Data4[2], key.fmtid.Data4[3],
+                                           key.fmtid.Data4[4], key.fmtid.Data4[5],
+                                           key.fmtid.Data4[6], key.fmtid.Data4[7],
+                                           key.pid);
+    return S_OK;
+  }
+};
\ No newline at end of file
index 97b552e..fa20f4a 100644 (file)
@@ -32,6 +32,8 @@
 #include "GUIInfoManager.h"
 #include "utils/StringUtils.h"
 #include "utils/CPUInfo.h"
+#include <mmdeviceapi.h>
+#include "win32/IMMNotificationClient.h"
 
 #ifndef _DEBUG
 #define XBMC_TRACK_EXCEPTIONS
@@ -221,12 +223,28 @@ INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT )
   }
 #endif
 
+  HRESULT hr = E_FAIL;
+  IMMDeviceEnumerator *pEnumerator = NULL;
+  CMMNotificationClient cMMNC;
+  hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
+  if(SUCCEEDED(hr))
+  {
+    pEnumerator->RegisterEndpointNotificationCallback(&cMMNC);
+    SAFE_RELEASE(pEnumerator);
+  }
+
   g_application.Run();
 
   // clear previously set timer resolution
   timeEndPeriod(1);            
 
   // the end
+  hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
+  if(SUCCEEDED(hr))
+  {
+    pEnumerator->UnregisterEndpointNotificationCallback(&cMMNC);
+    SAFE_RELEASE(pEnumerator);
+  }
   WSACleanup();
   CoUninitialize();
 
index 479fa2b..31667f5 100644 (file)
@@ -68,6 +68,7 @@ typedef enum {
        XBMC_VIDEOEXPOSE,        /* Screen needs to be redrawn */
        XBMC_APPCOMMAND,         /* Media commands, such as WM_APPCOMMAND on Windows for media keys. */
        XBMC_TOUCH,
+       XBMC_SETFOCUS,
        XBMC_USEREVENT,
 
        XBMC_MAXEVENT = 256      /* XBMC_EventType is represented as uchar */
@@ -204,6 +205,12 @@ typedef struct XBMC_TouchEvent {
   int pointers;         /* number of touch pointers */
 } XBMC_TouchEvent;
 
+typedef struct XBMC_SetFocusEvent {
+       unsigned char type;     /* XBMC_SETFOCUS */
+       int x;          /* x position */
+       int y;          /* y position */
+} XBMC_SetFocusEvent;
+
 /* General event structure */
 typedef union XBMC_Event {
   unsigned char type;
@@ -223,6 +230,7 @@ typedef union XBMC_Event {
   XBMC_SysWMEvent syswm;
   XBMC_AppCommandEvent appcommand;
   XBMC_TouchEvent touch;
+  XBMC_SetFocusEvent focus;
 } XBMC_Event;
 
 #endif /* _XBMC_events_h */
index 4c9afd4..0a7ad7f 100644 (file)
@@ -57,6 +57,7 @@ public:
   virtual bool BeginRender();
   virtual bool EndRender();
   virtual int GetNumScreens();    
+  virtual int GetCurrentScreen();
   
           void InitDisplayLink(void);
           void DeinitDisplayLink(void);
index f50b68e..677e464 100644 (file)
@@ -45,6 +45,7 @@
 #else
 #import "ios/XBMCController.h"
 #endif
+#import "osx/IOSScreenManager.h"
 #include "osx/DarwinUtils.h"
 #import <dlfcn.h>
 
@@ -169,6 +170,16 @@ int CWinSystemIOS::GetNumScreens()
   return [[UIScreen screens] count];
 }
 
+int CWinSystemIOS::GetCurrentScreen()
+{
+  int idx = 0;
+  if ([[IOSScreenManager sharedInstance] isExternalScreen])
+  {
+    idx = 1;
+  }
+  return idx;
+}
+
 bool CWinSystemIOS::GetScreenResolution(int* w, int* h, double* fps, int screenIdx)
 {
   // Figure out the screen size. (default to main screen)
index c26fa83..976e7b2 100644 (file)
@@ -798,12 +798,6 @@ bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
   {
     if (m_can_display_switch)
     {
-      // send pre-configuration change now and do not
-      //  wait for switch videomode callback. This gives just
-      //  a little more advanced notice of the display pre-change.
-      if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") != ADJUST_REFRESHRATE_OFF)
-        CheckDisplayChanging(kCGDisplayBeginConfigurationFlag);
-
       // switch videomode
       SwitchToVideoMode(res.iWidth, res.iHeight, res.fRefreshRate, res.iScreen);
       m_lastDisplayNr = res.iScreen;
index d2e13c9..4391de3 100644 (file)
@@ -26,6 +26,7 @@
 #include "settings/DisplaySettings.h"
 #include "settings/Settings.h"
 #include "utils/log.h"
+#include "utils/CharsetConverter.h"
 
 #ifdef TARGET_WINDOWS
 #include <tpcshrd.h>
@@ -356,10 +357,10 @@ RECT CWinSystemWin32::ScreenRect(int screen)
 {
   const MONITOR_DETAILS &details = GetMonitor(screen);
 
-  DEVMODE sDevMode;
+  DEVMODEW sDevMode;
   ZeroMemory(&sDevMode, sizeof(DEVMODE));
   sDevMode.dmSize = sizeof(DEVMODE);
-  if(!EnumDisplaySettings(details.DeviceName, ENUM_CURRENT_SETTINGS, &sDevMode))
+  if(!EnumDisplaySettingsW(details.DeviceNameW.c_str(), ENUM_CURRENT_SETTINGS, &sDevMode))
     CLog::Log(LOGERROR, "%s : EnumDisplaySettings failed with %d", __FUNCTION__, GetLastError());
 
   RECT rc;
@@ -443,12 +444,12 @@ bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res)
 {
   const MONITOR_DETAILS &details = GetMonitor(res.iScreen);
 
-  DEVMODE sDevMode;
+  DEVMODEW sDevMode;
   ZeroMemory(&sDevMode, sizeof(DEVMODE));
   sDevMode.dmSize = sizeof(DEVMODE);
 
   // If we can't read the current resolution or any detail of the resolution is different than res
-  if (!EnumDisplaySettings(details.DeviceName, ENUM_CURRENT_SETTINGS, &sDevMode) ||
+  if (!EnumDisplaySettingsW(details.DeviceNameW.c_str(), ENUM_CURRENT_SETTINGS, &sDevMode) ||
       sDevMode.dmPelsWidth != res.iWidth || sDevMode.dmPelsHeight != res.iHeight ||
       sDevMode.dmDisplayFrequency != (int)res.fRefreshRate ||
       ((sDevMode.dmDisplayFlags & DM_INTERLACED) && !(res.dwFlags & D3DPRESENTFLAG_INTERLACED)) ||
@@ -465,7 +466,7 @@ bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res)
 
     // CDS_FULLSCREEN is for temporary fullscreen mode and prevents icons and windows from moving
     // to fit within the new dimensions of the desktop
-    LONG rc = ChangeDisplaySettingsEx(details.DeviceName, &sDevMode, NULL, CDS_FULLSCREEN, NULL);
+    LONG rc = ChangeDisplaySettingsExW(details.DeviceNameW.c_str(), &sDevMode, NULL, CDS_FULLSCREEN, NULL);
     if (rc != DISP_CHANGE_SUCCESSFUL)
     {
       CLog::Log(LOGERROR, "%s : ChangeDisplaySettingsEx failed with %d", __FUNCTION__, rc);
@@ -540,10 +541,10 @@ void CWinSystemWin32::UpdateResolutions()
   {
     for(int mode = 0;; mode++)
     {
-      DEVMODE devmode;
+      DEVMODEW devmode;
       ZeroMemory(&devmode, sizeof(devmode));
       devmode.dmSize = sizeof(devmode);
-      if(EnumDisplaySettings(m_MonitorsInfo[monitor].DeviceName, mode, &devmode) == 0)
+      if(EnumDisplaySettingsW(m_MonitorsInfo[monitor].DeviceNameW.c_str(), mode, &devmode) == 0)
         break;
       if(devmode.dmBitsPerPel != 32)
         continue;
@@ -583,25 +584,25 @@ void CWinSystemWin32::AddResolution(const RESOLUTION_INFO &res)
 bool CWinSystemWin32::UpdateResolutionsInternal()
 {
 
-  DISPLAY_DEVICE ddAdapter;
+  DISPLAY_DEVICEW ddAdapter;
   ZeroMemory(&ddAdapter, sizeof(ddAdapter));
   ddAdapter.cb = sizeof(ddAdapter);
   DWORD adapter = 0;
 
-  while (EnumDisplayDevices(NULL, adapter, &ddAdapter, 0))
+  while (EnumDisplayDevicesW(NULL, adapter, &ddAdapter, 0))
   {
     // Exclude displays that are not part of the windows desktop. Using them is too different: no windows,
     // direct access with GDI CreateDC() or DirectDraw for example. So it may be possible to play video, but GUI?
     if (!(ddAdapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) && (ddAdapter.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
     {
-      DISPLAY_DEVICE ddMon;
+      DISPLAY_DEVICEW ddMon;
       ZeroMemory(&ddMon, sizeof(ddMon));
       ddMon.cb = sizeof(ddMon);
       bool foundScreen = false;
       DWORD screen = 0;
 
       // Just look for the first active output, we're actually only interested in the information at the adapter level.
-      while (EnumDisplayDevices(ddAdapter.DeviceName, screen, &ddMon, 0))
+      while (EnumDisplayDevicesW(ddAdapter.DeviceName, screen, &ddMon, 0))
       {
         if (ddMon.StateFlags & (DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED))
         {
@@ -615,33 +616,35 @@ bool CWinSystemWin32::UpdateResolutionsInternal()
       // Remoting returns no screens. Handle with a dummy screen.
       if (!foundScreen && screen == 0)
       {
-        lstrcpy(ddMon.DeviceString, _T("Dummy Monitor")); // safe: large static array
+        lstrcpyW(ddMon.DeviceString, L"Dummy Monitor"); // safe: large static array
         foundScreen = true;
       }
 
       if (foundScreen)
       {
-        CLog::Log(LOGNOTICE, "Found screen: %s on %s, adapter %d.", ddMon.DeviceString, ddAdapter.DeviceString, adapter);
+        std::string monitorStr, adapterStr;
+        g_charsetConverter.wToUTF8(ddMon.DeviceString, monitorStr);
+        g_charsetConverter.wToUTF8(ddAdapter.DeviceString, adapterStr);
+        CLog::Log(LOGNOTICE, "Found screen: %s on %s, adapter %d.", monitorStr.c_str(), adapterStr.c_str(), adapter);
 
         // get information about the display's current position and display mode
         // TODO: for Windows 7/Server 2008 and up, Microsoft recommends QueryDisplayConfig() instead, the API used by the control panel.
-        DEVMODE dm;
+        DEVMODEW dm;
         ZeroMemory(&dm, sizeof(dm));
         dm.dmSize = sizeof(dm);
-        if (EnumDisplaySettingsEx(ddAdapter.DeviceName, ENUM_CURRENT_SETTINGS, &dm, 0) == FALSE)
-          EnumDisplaySettingsEx(ddAdapter.DeviceName, ENUM_REGISTRY_SETTINGS, &dm, 0);
+        if (EnumDisplaySettingsExW(ddAdapter.DeviceName, ENUM_CURRENT_SETTINGS, &dm, 0) == FALSE)
+          EnumDisplaySettingsExW(ddAdapter.DeviceName, ENUM_REGISTRY_SETTINGS, &dm, 0);
 
         // get the monitor handle and workspace
         HMONITOR hm = 0;
         POINT pt = { dm.dmPosition.x, dm.dmPosition.y };
         hm = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
 
-        MONITOR_DETAILS md;
-        memset(&md, 0, sizeof(MONITOR_DETAILS));
+        MONITOR_DETAILS md = {};
 
-        strcpy(md.MonitorName, ddMon.DeviceString);
-        strcpy(md.CardName, ddAdapter.DeviceString);
-        strcpy(md.DeviceName, ddAdapter.DeviceName);
+        md.MonitorNameW = ddMon.DeviceString;
+        md.CardNameW = ddAdapter.DeviceString;
+        md.DeviceNameW = ddAdapter.DeviceName;
 
         // width x height @ x,y - bpp - refresh rate
         // note that refresh rate information is not available on Win9x
index 836eba7..245d84c 100644 (file)
@@ -22,6 +22,7 @@
 #define WINDOW_SYSTEM_WIN32_H
 
 #include "windowing/WinSystem.h"
+#include <string>
 
 struct MONITOR_DETAILS
 {
@@ -33,9 +34,9 @@ struct MONITOR_DETAILS
   bool      Interlaced;
 
   HMONITOR  hMonitor;
-  char      MonitorName[128];
-  char      CardName[128];
-  char      DeviceName[128];
+  std::wstring MonitorNameW;
+  std::wstring CardNameW;
+  std::wstring DeviceNameW;
   int       ScreenNumber; // XBMC POV, not Windows. Windows primary is XBMC #0, then each secondary is +1.
 };