aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/library.xbmc.gui/libXBMC_gui.h2
-rw-r--r--addons/skin.confluence/720p/DialogPVRChannelManager.xml106
-rw-r--r--addons/skin.confluence/720p/DialogPVRGuideSearch.xml1
-rw-r--r--addons/skin.confluence/addon.xml2
-rw-r--r--addons/skin.confluence/changelog.txt4
m---------addons/skin.re-touched0
-rw-r--r--addons/xbmc.gui/addon.xml2
-rwxr-xr-xlib/librtmp/darwin_package_librtmp.sh14
-rw-r--r--project/BuildDependencies/DownloadBuildDeps.bat5
-rw-r--r--project/BuildDependencies/scripts/0_package.list26
-rw-r--r--project/BuildDependencies/scripts/fontconfig_d.bat16
-rw-r--r--project/BuildDependencies/scripts/fontconfig_d.txt4
-rw-r--r--project/BuildDependencies/scripts/freetype_d.bat13
-rw-r--r--project/BuildDependencies/scripts/freetype_d.txt2
-rw-r--r--project/BuildDependencies/scripts/get_formed.cmd14
-rw-r--r--project/BuildDependencies/scripts/libbzip2_d.bat13
-rw-r--r--project/BuildDependencies/scripts/libbzip2_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libcdio_d.bat15
-rw-r--r--project/BuildDependencies/scripts/libcdio_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libcec_d.txt3
-rw-r--r--project/BuildDependencies/scripts/libcurl_d.bat17
-rw-r--r--project/BuildDependencies/scripts/libcurl_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libexpat_d.bat16
-rw-r--r--project/BuildDependencies/scripts/libexpat_d.txt3
-rw-r--r--project/BuildDependencies/scripts/libflac_d.bat16
-rw-r--r--project/BuildDependencies/scripts/libflac_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libfribidi_d.bat13
-rw-r--r--project/BuildDependencies/scripts/libfribidi_d.txt2
-rw-r--r--project/BuildDependencies/scripts/liblzo_d.bat13
-rw-r--r--project/BuildDependencies/scripts/liblzo_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libmicrohttpd_d.bat14
-rw-r--r--project/BuildDependencies/scripts/libmicrohttpd_d.txt2
-rw-r--r--project/BuildDependencies/scripts/liboggvorbis_d.bat16
-rw-r--r--project/BuildDependencies/scripts/liboggvorbis_d.txt5
-rw-r--r--project/BuildDependencies/scripts/libplist_d.bat13
-rw-r--r--project/BuildDependencies/scripts/libplist_d.txt2
-rw-r--r--project/BuildDependencies/scripts/librtmp_d.bat13
-rw-r--r--project/BuildDependencies/scripts/librtmp_d.txt2
-rw-r--r--project/BuildDependencies/scripts/libsdl_d.bat17
-rw-r--r--project/BuildDependencies/scripts/libsdl_d.txt3
-rw-r--r--project/BuildDependencies/scripts/swig_d.bat12
-rw-r--r--project/BuildDependencies/scripts/swig_d.txt2
-rw-r--r--project/BuildDependencies/scripts/yajl_d.bat13
-rw-r--r--project/BuildDependencies/scripts/yajl_d.txt2
-rw-r--r--project/BuildDependencies/scripts/zlib_d.bat14
-rw-r--r--project/BuildDependencies/scripts/zlib_d.txt3
-rw-r--r--project/cmake/addons/CMakeLists.txt3
-rw-r--r--project/cmake/addons/depends/CMakeLists.txt129
-rw-r--r--project/cmake/scripts/common/handle-depends.cmake13
-rw-r--r--tools/buildsteps/defaultenv6
-rw-r--r--tools/depends/native/TexturePacker/src/TexturePacker.cpp2
-rw-r--r--tools/depends/native/TexturePacker/src/decoder/GifHelper.cpp21
-rw-r--r--tools/depends/target/curl/0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch83
-rw-r--r--tools/depends/target/curl/Makefile7
-rw-r--r--tools/depends/target/librtmp/Makefile7
-rw-r--r--tools/depends/target/librtmp/librtmp-60-second-fix.patch1913
-rw-r--r--tools/depends/target/librtmp/prefix.patch2
-rw-r--r--xbmc/Autorun.cpp4
-rw-r--r--xbmc/LangInfo.cpp1
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.cpp2
-rw-r--r--xbmc/guilib/GUITextBox.cpp2
-rw-r--r--xbmc/pvr/PVRDatabase.cpp5
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp2
-rw-r--r--xbmc/pvr/addons/PVRClient.h1
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp6
-rw-r--r--xbmc/pvr/channels/PVRChannel.cpp26
-rw-r--r--xbmc/pvr/channels/PVRChannel.h15
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.cpp21
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.h4
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.cpp6
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.h2
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp144
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h3
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp20
-rw-r--r--xbmc/pvr/recordings/PVRRecording.cpp2
-rw-r--r--xbmc/pvr/timers/PVRTimerInfoTag.cpp2
-rw-r--r--xbmc/pvr/timers/PVRTimerInfoTag.h1
-rw-r--r--xbmc/pvr/timers/PVRTimers.cpp3
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRBase.cpp16
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRChannels.cpp24
-rw-r--r--xbmc/storage/linux/UDevProvider.cpp57
-rw-r--r--xbmc/utils/Makefile.in4
-rw-r--r--xbmc/utils/Screenshot.cpp9
-rw-r--r--xbmc/utils/ScreenshotAML.cpp95
-rw-r--r--xbmc/utils/ScreenshotAML.h30
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp12
86 files changed, 429 insertions, 2741 deletions
diff --git a/addons/library.xbmc.gui/libXBMC_gui.h b/addons/library.xbmc.gui/libXBMC_gui.h
index 3b50e9cacb..72f732f0c9 100644
--- a/addons/library.xbmc.gui/libXBMC_gui.h
+++ b/addons/library.xbmc.gui/libXBMC_gui.h
@@ -36,7 +36,7 @@ typedef void* GUIHANDLE;
#endif
/* current ADDONGUI API version */
-#define XBMC_GUI_API_VERSION "5.6.0"
+#define XBMC_GUI_API_VERSION "5.7.0"
/* min. ADDONGUI API version */
#define XBMC_GUI_MIN_API_VERSION "5.3.0"
diff --git a/addons/skin.confluence/720p/DialogPVRChannelManager.xml b/addons/skin.confluence/720p/DialogPVRChannelManager.xml
index 14c1d3e811..71bdb48fbb 100644
--- a/addons/skin.confluence/720p/DialogPVRChannelManager.xml
+++ b/addons/skin.confluence/720p/DialogPVRChannelManager.xml
@@ -267,7 +267,7 @@
<left>0</left>
<top>25</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<textcolor>white</textcolor>
<focusedcolor>white</focusedcolor>
@@ -280,15 +280,15 @@
<label>19074</label>
<onleft>20</onleft>
<onright>9000</onright>
- <onup>33</onup>
+ <onup>30</onup>
<ondown>8</ondown>
</control>
<control type="edit" id="8">
<description>Channel name</description>
<left>0</left>
- <top>65</top>
+ <top>75</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<textcolor>white</textcolor>
<focusedcolor>white</focusedcolor>
@@ -304,9 +304,9 @@
<control type="button" id="9">
<description>Channel logo Button</description>
<left>0</left>
- <top>105</top>
+ <top>125</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<texturefocus border="5">button-focus2.png</texturefocus>
<texturenofocus border="5">button-nofocus.png</texturenofocus>
@@ -318,19 +318,19 @@
</control>
<control type="image" id="10">
<description>Current Channel Icon</description>
- <left>345</left>
- <top>107</top>
- <width>30</width>
- <height>30</height>
+ <left>337</left>
+ <top>128</top>
+ <width>39</width>
+ <height>39</height>
<aspectratio>keep</aspectratio>
<info>ListItem.Property(Icon)</info>
</control>
<control type="radiobutton" id="12">
<description>EPG activated</description>
<left>0</left>
- <top>145</top>
+ <top>175</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<textcolor>white</textcolor>
<focusedcolor>white</focusedcolor>
@@ -349,9 +349,9 @@
<control type="spincontrolex" id="13">
<description>EPG source</description>
<left>0</left>
- <top>185</top>
+ <top>225</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<texturefocus border="5">button-focus2.png</texturefocus>
<texturenofocus border="5">button-nofocus.png</texturenofocus>
@@ -364,9 +364,9 @@
<control type="radiobutton" id="14">
<description>Parental locked</description>
<left>0</left>
- <top>225</top>
+ <top>275</top>
<width>380</width>
- <height>35</height>
+ <height>45</height>
<font>font12</font>
<textcolor>white</textcolor>
<focusedcolor>white</focusedcolor>
@@ -385,7 +385,7 @@
</control>
<control type="group">
<left>490</left>
- <top>360</top>
+ <top>420</top>
<control type="label">
<description>channel options Header</description>
<left>0</left>
@@ -403,8 +403,8 @@
<description>Group Manager Button</description>
<left>0</left>
<top>25</top>
- <width>190</width>
- <height>35</height>
+ <width>380</width>
+ <height>45</height>
<font>font12</font>
<texturefocus border="5">button-focus2.png</texturefocus>
<texturenofocus border="5">button-nofocus.png</texturenofocus>
@@ -413,14 +413,14 @@
<onleft>20</onleft>
<onright>34</onright>
<onup>14</onup>
- <ondown>31</ondown>
+ <ondown>7</ondown>
</control>
<control type="button" id="34">
<description>TV/Radio Button</description>
- <left>195</left>
- <top>25</top>
- <width>185</width>
- <height>35</height>
+ <left>0</left>
+ <top>75</top>
+ <width>380</width>
+ <height>45</height>
<font>font12</font>
<visible>IsEmpty(Window.Property(IsRadio))</visible>
<texturefocus border="5">button-focus2.png</texturefocus>
@@ -430,14 +430,14 @@
<onleft>30</onleft>
<onright>9000</onright>
<onup>14</onup>
- <ondown>31</ondown>
+ <ondown>7</ondown>
</control>
<control type="button" id="34">
<description>TV/Radio Button</description>
- <left>195</left>
- <top>25</top>
- <width>185</width>
- <height>35</height>
+ <left>0</left>
+ <top>75</top>
+ <width>380</width>
+ <height>45</height>
<font>font12</font>
<visible>!IsEmpty(Window.Property(IsRadio))</visible>
<texturefocus border="5">button-focus2.png</texturefocus>
@@ -447,54 +447,6 @@
<onleft>30</onleft>
<onright>9000</onright>
<onup>14</onup>
- <ondown>31</ondown>
- </control>
- <control type="button" id="31">
- <description>Edit channel Button</description>
- <left>0</left>
- <top>65</top>
- <width>380</width>
- <height>35</height>
- <font>font12</font>
- <texturefocus border="5">button-focus2.png</texturefocus>
- <texturenofocus border="5">button-nofocus.png</texturenofocus>
- <align>center</align>
- <label>19203</label>
- <onleft>20</onleft>
- <onright>9000</onright>
- <onup>30</onup>
- <ondown>32</ondown>
- </control>
- <control type="button" id="32">
- <description>Delete channel Button</description>
- <left>0</left>
- <top>105</top>
- <width>380</width>
- <height>35</height>
- <font>font12</font>
- <texturefocus border="5">button-focus2.png</texturefocus>
- <texturenofocus border="5">button-nofocus.png</texturenofocus>
- <align>center</align>
- <label>19211</label>
- <onleft>20</onleft>
- <onright>9000</onright>
- <onup>31</onup>
- <ondown>33</ondown>
- </control>
- <control type="button" id="33">
- <description>New channel Button</description>
- <left>0</left>
- <top>145</top>
- <width>380</width>
- <height>35</height>
- <font>font12</font>
- <texturefocus border="5">button-focus2.png</texturefocus>
- <texturenofocus border="5">button-nofocus.png</texturenofocus>
- <align>center</align>
- <label>19204</label>
- <onleft>20</onleft>
- <onright>9000</onright>
- <onup>32</onup>
<ondown>7</ondown>
</control>
</control>
diff --git a/addons/skin.confluence/720p/DialogPVRGuideSearch.xml b/addons/skin.confluence/720p/DialogPVRGuideSearch.xml
index dedb182d10..96d0e3900a 100644
--- a/addons/skin.confluence/720p/DialogPVRGuideSearch.xml
+++ b/addons/skin.confluence/720p/DialogPVRGuideSearch.xml
@@ -36,7 +36,6 @@
<aligny>center</aligny>
<textcolor>selected</textcolor>
<shadowcolor>black</shadowcolor>
- <visible>!pvr.IsPlayingRadio</visible>
</control>
<control type="button">
<description>Close Window button</description>
diff --git a/addons/skin.confluence/addon.xml b/addons/skin.confluence/addon.xml
index 1b19cffd10..c9182de5cc 100644
--- a/addons/skin.confluence/addon.xml
+++ b/addons/skin.confluence/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="skin.confluence"
- version="2.6.0"
+ version="2.7.0"
name="Confluence"
provider-name="Jezz_X, Team Kodi">
<requires>
diff --git a/addons/skin.confluence/changelog.txt b/addons/skin.confluence/changelog.txt
index 6dbb4c6f41..f5d839e8b0 100644
--- a/addons/skin.confluence/changelog.txt
+++ b/addons/skin.confluence/changelog.txt
@@ -1,3 +1,7 @@
+[B]2.7.0[/B]
+
+- Removed new/edit/delete buttons from the channel manager dialog
+
[B]2.6.0[/B]
- Moved some context menu functionality for PVR channels to the sideblade
diff --git a/addons/skin.re-touched b/addons/skin.re-touched
-Subproject cf9f8e2f3f222becdf6fca00e76197b5d97df34
+Subproject 5735e91eb92462b5a100d0aef0f673c1f7e0d72
diff --git a/addons/xbmc.gui/addon.xml b/addons/xbmc.gui/addon.xml
index 5614e79e2d..bb2351c945 100644
--- a/addons/xbmc.gui/addon.xml
+++ b/addons/xbmc.gui/addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.gui" version="5.6.0" provider-name="Team-Kodi">
+<addon id="xbmc.gui" version="5.7.0" provider-name="Team-Kodi">
<backwards-compatibility abi="5.3.0"/>
<requires>
<import addon="xbmc.core" version="0.1.0"/>
diff --git a/lib/librtmp/darwin_package_librtmp.sh b/lib/librtmp/darwin_package_librtmp.sh
deleted file mode 100755
index 0d39403b86..0000000000
--- a/lib/librtmp/darwin_package_librtmp.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-SRC_LIB_RTMP="/opt/local/lib/librtmp.so.0"
-if [ -e ./system ]; then
- DST_LIB_RTMP="./system/librtmp.so"
-else
- DST_LIB_RTMP="../../system/librtmp.so"
-fi
-
-if [ -f $SRC_LIB_RTMP ]; then
- # copy librtmp into xbmc's system directory, we
- # rename it to librtmp.so and skip the symlinking.
- cp $SRC_LIB_RTMP $DST_LIB_RTMP
-fi
diff --git a/project/BuildDependencies/DownloadBuildDeps.bat b/project/BuildDependencies/DownloadBuildDeps.bat
index 81df45a4bc..e9fdd2e8b5 100644
--- a/project/BuildDependencies/DownloadBuildDeps.bat
+++ b/project/BuildDependencies/DownloadBuildDeps.bat
@@ -28,11 +28,6 @@ md %TMP_PATH%
cd scripts
-FOR /F "tokens=*" %%S IN ('dir /B "*_d.bat"') DO (
- echo running %%S ...
- CALL %%S
-)
-
SET FORMED_OK_FLAG=%TMP_PATH%\got-all-formed-packages
REM Trick to preserve console title
start /b /wait cmd.exe /c get_formed.cmd
diff --git a/project/BuildDependencies/scripts/0_package.list b/project/BuildDependencies/scripts/0_package.list
index 259cafe52b..5a3513fceb 100644
--- a/project/BuildDependencies/scripts/0_package.list
+++ b/project/BuildDependencies/scripts/0_package.list
@@ -5,28 +5,48 @@
; -> sqlite-3.7.12.1-win32\project\BuildDependencies\lib\sqlite3.lib
; -> sqlite-3.7.12.1-win32\system\sqlite3.dll
; -> ...
+;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
boost-1.46.1-headers-win32.7z
+bzip2-1.0.5-win32.7z
dnssd-541-win32.zip
doxygen-1.8.2-win32.7z
+fontconfig-2.8.0-win32.7z
+freetype-2.4.6-win32-3.7z
+giflib-5.0.5p-win32.7z
gnutls-3.2.3-win32.zip
jsonschemabuilder-1.0.0-win32-3.7z
libass-0.10.2-win32.7z
libbluray-0.4.0-win32.zip
+libcdio-0.83-win32-2.7z
libcec-2.2.0-win32-1.7z
+libcurl-7.21.6-win32.7z
+libexpat_2.0.1-win32.7z
+libflac-1.2.1-win32.7z
+libfribidi-0.19.2-win32.7z
libiconv-1.14-win32-vc120.7z
libjpeg-turbo-1.2.0-win32.7z
+liblzo-2.04-win32.7z
+libmicrohttpd-0.4.5-win32-1.7z
libnfs-1.6.2-win32.7z
+libogg-vc100-1.2.0-win32.7z
+libplist-1.7-win32-3.7z
+libpng-1.5.13-win32.7z
+librtmp-20150114-git-a107ce-win32.7z
+libsdl-1.2.10-win32.7z
+libsdl_image-1.2.14-win32.7z
libshairplay-41a66c9-win32.7z
libssh-0.5.0-1-win32.zip
+libvorbis-vc100-1.3.1-win32.7z
libxml2-2.7.8_1-win32.7z
libxslt-1.1.26_1-win32.7z
+libyajl-2.0.1-win32.7z
+libzlib-vc100-1.2.5-win32.7z
mysqlclient-6.1.3-win32-vc120.7z
pcre-8.34-win32-vc120.7z
PIL-1.1.7p-win32.7z
python-2.7.8-win32.7z
sqlite-3.8.6-win32-vc120.7z
+swig-2.0.7-win32-1.7z
taglib-1.9.1-win32-vc120.7z
-tinyxml-2.6.2_3-win32-vc120.7z
-libpng-1.5.13-win32.7z
-giflib-5.0.5p-win32.7z
texturepacker-1.0.0-win32.7z
+tinyxml-2.6.2_3-win32-vc120.7z
diff --git a/project/BuildDependencies/scripts/fontconfig_d.bat b/project/BuildDependencies/scripts/fontconfig_d.bat
deleted file mode 100644
index e8543f0bd5..0000000000
--- a/project/BuildDependencies/scripts/fontconfig_d.bat
+++ /dev/null
@@ -1,16 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\fontconfig_d.txt
-
-CALL dlextract.bat fontconfig %FILES%
-
-cd %TMP_PATH%
-
-xcopy include\fontconfig "%CUR_PATH%\include\fontconfig" /E /Q /I /Y
-copy lib\fontconfig.lib "%CUR_PATH%\lib\" /Y
-rem libfontconfig-1.dll requires libexpat-1.dll which is copied by libexpat_d.bat
-copy bin\libfontconfig-1.dll "%APP_PATH%\system\players\dvdplayer\"
-copy freetype-2.4.6-1-win32\bin\freetype6.dll "%APP_PATH%\system\players\dvdplayer\"
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/fontconfig_d.txt b/project/BuildDependencies/scripts/fontconfig_d.txt
deleted file mode 100644
index bf22b3e189..0000000000
--- a/project/BuildDependencies/scripts/fontconfig_d.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-; filename mirror source of the file
-fontconfig-dev_2.8.0-2_win32.zip http://mirrors.xbmc.org/build-deps/win32/ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies
-fontconfig_2.8.0-2_win32.zip http://mirrors.xbmc.org/build-deps/win32/ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies
-freetype-2.4.6-1-win32.zip http://mirrors.xbmc.org/build-deps/win32/ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies
diff --git a/project/BuildDependencies/scripts/freetype_d.bat b/project/BuildDependencies/scripts/freetype_d.bat
deleted file mode 100644
index 92e62ca5c9..0000000000
--- a/project/BuildDependencies/scripts/freetype_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO ON
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\freetype_d.txt
-
-CALL dlextract.bat freetype %FILES%
-
-cd %TMP_PATH%
-
-xcopy freetype-2.4.6-win32-1\include\* "%CUR_PATH%\include\" /E /Q /I /Y
-copy freetype-2.4.6-win32-1\lib\freetype246MT.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/freetype_d.txt b/project/BuildDependencies/scripts/freetype_d.txt
deleted file mode 100644
index 219cc1ebf4..0000000000
--- a/project/BuildDependencies/scripts/freetype_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror of the file
-freetype-2.4.6-win32-2.7z http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/get_formed.cmd b/project/BuildDependencies/scripts/get_formed.cmd
index ffe44c10e2..f006bb8f0b 100644
--- a/project/BuildDependencies/scripts/get_formed.cmd
+++ b/project/BuildDependencies/scripts/get_formed.cmd
@@ -30,6 +30,8 @@ REM End of main body
:processFile
CALL :setStageName Getting %1...
+SET RetryDownload=YES
+:startDownloadingFile
IF EXIST %1 (
ECHO Using downloaded %1
) ELSE (
@@ -41,7 +43,17 @@ IF EXIST %1 (
CALL :setSubStageName Extracting %1...
copy /b "%1" "%TMP_PATH%" || EXIT /B 5
PUSHD "%TMP_PATH%" || EXIT /B 10
-%ZIP% x %1 || exit /B 6
+%ZIP% x %1 || (
+ IF %RetryDownload%==YES (
+ POPD || EXIT /B 5
+ ECHO WARNNING! Can't extract files from archive %1!
+ ECHO WARNNING! Deleting %1 and will retry downloading.
+ del /f "%1"
+ SET RetryDownload=NO
+ GOTO startDownloadingFile
+ )
+ exit /B 6
+)
dir /A:-D "%~n1\*.*" >NUL 2>NUL && (
CALL :setSubStageName Pre-Cleaning %1...
diff --git a/project/BuildDependencies/scripts/libbzip2_d.bat b/project/BuildDependencies/scripts/libbzip2_d.bat
deleted file mode 100644
index db51924121..0000000000
--- a/project/BuildDependencies/scripts/libbzip2_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libbzip2_d.txt
-
-CALL dlextract.bat libbzip2 %FILES%
-
-cd %TMP_PATH%
-
-copy include\* "%CUR_PATH%\include\" /Y
-copy lib\bzip2.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libbzip2_d.txt b/project/BuildDependencies/scripts/libbzip2_d.txt
deleted file mode 100644
index 245d9eb9f0..0000000000
--- a/project/BuildDependencies/scripts/libbzip2_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror source of the file
-bzip2-1.0.5-lib.zip http://mirrors.xbmc.org/build-deps/win32/ http://downloads.sourceforge.net/project/gnuwin32/bzip2/1.0.5/
diff --git a/project/BuildDependencies/scripts/libcdio_d.bat b/project/BuildDependencies/scripts/libcdio_d.bat
deleted file mode 100644
index 550150771f..0000000000
--- a/project/BuildDependencies/scripts/libcdio_d.bat
+++ /dev/null
@@ -1,15 +0,0 @@
-@ECHO ON
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libcdio_d.txt
-
-CALL dlextract.bat libcdio %FILES%
-
-cd %TMP_PATH%
-
-xcopy libcdio-0.83-win32\include\* "%CUR_PATH%\include\" /E /Q /I /Y
-copy libcdio-0.83-win32\lib\libcdio.dll.lib "%CUR_PATH%\lib\" /Y
-copy libcdio-0.83-win32\bin\libcdio-13.dll "%APP_PATH%\project\Win32BuildSetup\dependencies\" /Y
-copy libcdio-0.83-win32\bin\libiconv-2.dll "%APP_PATH%\project\Win32BuildSetup\dependencies\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libcdio_d.txt b/project/BuildDependencies/scripts/libcdio_d.txt
deleted file mode 100644
index ab52618f98..0000000000
--- a/project/BuildDependencies/scripts/libcdio_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror of the file
-libcdio-0.83-win32.7z http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/libcec_d.txt b/project/BuildDependencies/scripts/libcec_d.txt
deleted file mode 100644
index 3d0265ee05..0000000000
--- a/project/BuildDependencies/scripts/libcec_d.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-; filename source of the file
-
-libcec-2.2.0-win32.zip http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/libcurl_d.bat b/project/BuildDependencies/scripts/libcurl_d.bat
deleted file mode 100644
index 5de849bc63..0000000000
--- a/project/BuildDependencies/scripts/libcurl_d.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libcurl_d.txt
-
-CALL dlextract.bat libcurl %FILES%
-
-cd %TMP_PATH%
-
-rem we are using zlib1.dll from the zlib package
-rem I found no reference to zlib1.dll in any curl dll
-del curl-7.21.6-devel-mingw32\bin\zlib1.dll
-
-xcopy curl-7.21.6-devel-mingw32\include\curl "%CUR_PATH%\include\curl" /E /Q /I /Y
-copy curl-7.21.6-devel-mingw32\bin\*.dll "%APP_PATH%\system\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libcurl_d.txt b/project/BuildDependencies/scripts/libcurl_d.txt
deleted file mode 100644
index 371cf72721..0000000000
--- a/project/BuildDependencies/scripts/libcurl_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror source of the file
-curl-7.21.6-devel-mingw32.zip http://mirrors.xbmc.org/build-deps/win32/ http://www.gknw.de/mirror/curl/win32/old_releases/
diff --git a/project/BuildDependencies/scripts/libexpat_d.bat b/project/BuildDependencies/scripts/libexpat_d.bat
deleted file mode 100644
index 4d5cb61dcd..0000000000
--- a/project/BuildDependencies/scripts/libexpat_d.bat
+++ /dev/null
@@ -1,16 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libexpat_d.txt
-
-CALL dlextract.bat libexpat %FILES%
-
-cd %TMP_PATH%
-
-copy include\* "%CUR_PATH%\include\" /Y
-copy lib\expat.lib "%CUR_PATH%\lib\libexpat.lib" /Y
-copy bin\libexpat-1.dll "%APP_PATH%\system\libexpat.dll"
-rem libexpat-1.dll for libfontconfig-1.dll which is needed for libass.dll
-copy bin\libexpat-1.dll "%APP_PATH%\system\players\dvdplayer\"
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libexpat_d.txt b/project/BuildDependencies/scripts/libexpat_d.txt
deleted file mode 100644
index aea7fe6656..0000000000
--- a/project/BuildDependencies/scripts/libexpat_d.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-; filename mirror source of the file
-expat_2.0.1-1_win32.zip http://mirrors.xbmc.org/build-deps/win32/ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies
-expat-dev_2.0.1-1_win32.zip http://mirrors.xbmc.org/build-deps/win32/ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies
diff --git a/project/BuildDependencies/scripts/libflac_d.bat b/project/BuildDependencies/scripts/libflac_d.bat
deleted file mode 100644
index 17ac8de62b..0000000000
--- a/project/BuildDependencies/scripts/libflac_d.bat
+++ /dev/null
@@ -1,16 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libflac_d.txt
-
-CALL dlextract.bat libflac %FILES%
-
-cd %TMP_PATH%
-
-xcopy include\FLAC "%CUR_PATH%\include\FLAC" /E /Q /I /Y
-copy lib\libFLAC.dll "%APP_PATH%\system\players\paplayer\" /Y
-
-IF EXIST "include\FLAC++" rmdir "include\FLAC++" /S /Q
-IF EXIST "include\ogg" rmdir "include\ogg" /S /Q
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libflac_d.txt b/project/BuildDependencies/scripts/libflac_d.txt
deleted file mode 100644
index eae9a45bb9..0000000000
--- a/project/BuildDependencies/scripts/libflac_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror of the file source of the file
-flac-1.2.1-devel-win.zip http://mirrors.xbmc.org/build-deps/win32/ http://sourceforge.net/projects/flac/files/flac-win/flac-1.2.1-win/
diff --git a/project/BuildDependencies/scripts/libfribidi_d.bat b/project/BuildDependencies/scripts/libfribidi_d.bat
deleted file mode 100644
index 52e918539e..0000000000
--- a/project/BuildDependencies/scripts/libfribidi_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libfribidi_d.txt
-
-CALL dlextract.bat libfribidi %FILES%
-
-cd %TMP_PATH%
-
-xcopy fribidi-0.19.2-lib\include\fribidi "%CUR_PATH%\include\fribidi" /E /Q /I /Y
-copy fribidi-0.19.2-lib\lib\libfribidi.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libfribidi_d.txt b/project/BuildDependencies/scripts/libfribidi_d.txt
deleted file mode 100644
index ae7613dbfe..0000000000
--- a/project/BuildDependencies/scripts/libfribidi_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror source of the file
-fribidi-0.19.2-lib-1.zip http://mirrors.xbmc.org/build-deps/win32/ http://xbmcwindeps.googlecode.com/files/
diff --git a/project/BuildDependencies/scripts/liblzo_d.bat b/project/BuildDependencies/scripts/liblzo_d.bat
deleted file mode 100644
index 4d1a0299f3..0000000000
--- a/project/BuildDependencies/scripts/liblzo_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\liblzo_d.txt
-
-CALL dlextract.bat liblzo %FILES%
-
-cd %TMP_PATH%
-
-xcopy lzo-2.04_win32\include\lzo "%CUR_PATH%\include\lzo" /E /Q /I /Y
-copy lzo-2.04_win32\lib\liblzo2.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/liblzo_d.txt b/project/BuildDependencies/scripts/liblzo_d.txt
deleted file mode 100644
index 12f6647957..0000000000
--- a/project/BuildDependencies/scripts/liblzo_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror of the file source
-lzo-2.04_win32.7z http://mirrors.xbmc.org/build-deps/win32/ http://www.oberhumer.com/opensource/lzo/download/lzo-2.04.tar.gz \ No newline at end of file
diff --git a/project/BuildDependencies/scripts/libmicrohttpd_d.bat b/project/BuildDependencies/scripts/libmicrohttpd_d.bat
deleted file mode 100644
index 7076c87507..0000000000
--- a/project/BuildDependencies/scripts/libmicrohttpd_d.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-@ECHO ON
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libmicrohttpd_d.txt
-
-CALL dlextract.bat libmicrohttpd %FILES%
-
-cd %TMP_PATH%
-
-xcopy libmicrohttpd-0.4.5-win32\include\* "%CUR_PATH%\include" /E /Q /I /Y
-xcopy libmicrohttpd-0.4.5-win32\bin\*.dll "%APP_PATH%\system\webserver" /E /Q /I /Y
-copy libmicrohttpd-0.4.5-win32\lib\libmicrohttpd.dll.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libmicrohttpd_d.txt b/project/BuildDependencies/scripts/libmicrohttpd_d.txt
deleted file mode 100644
index 66fcdbc9f2..0000000000
--- a/project/BuildDependencies/scripts/libmicrohttpd_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename source of the file
-libmicrohttpd-0.4.5-win32.7z http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/liboggvorbis_d.bat b/project/BuildDependencies/scripts/liboggvorbis_d.bat
deleted file mode 100644
index 0de23091dd..0000000000
--- a/project/BuildDependencies/scripts/liboggvorbis_d.bat
+++ /dev/null
@@ -1,16 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\liboggvorbis_d.txt
-
-CALL dlextract.bat liboggvorbis %FILES%
-
-cd %TMP_PATH%
-
-xcopy include\ogg "%CUR_PATH%\include\ogg" /E /Q /I /Y
-xcopy include\vorbis "%CUR_PATH%\include\vorbis" /E /Q /I /Y
-copy bin\ogg.dll "%APP_PATH%\system\cdrip\" /Y
-copy bin\vorbis.dll "%APP_PATH%\system\cdrip\" /Y
-copy bin\vorbisfile.dll "%APP_PATH%\system\players\paplayer\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/liboggvorbis_d.txt b/project/BuildDependencies/scripts/liboggvorbis_d.txt
deleted file mode 100644
index 3270d64472..0000000000
--- a/project/BuildDependencies/scripts/liboggvorbis_d.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-; filename mirror of the file source of the file
-libogg-vc100-1.2.0-bin.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/libogg-vc100-1.2.0-bin.tar.bz2
-libogg-vc100-1.2.0-lib.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/libogg-vc100-1.2.0-lib.tar.bz2
-libvorbis-vc100-1.3.1-bin.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/libvorbis-vc100-1.3.1-bin.tar.bz2
-libvorbis-vc100-1.3.1-lib.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/libvorbis-vc100-1.3.1-lib.tar.bz2 \ No newline at end of file
diff --git a/project/BuildDependencies/scripts/libplist_d.bat b/project/BuildDependencies/scripts/libplist_d.bat
deleted file mode 100644
index 53e3c60809..0000000000
--- a/project/BuildDependencies/scripts/libplist_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libplist_d.txt
-
-CALL dlextract.bat libplist %FILES%
-
-cd %TMP_PATH%
-
-xcopy libplist-1.7-win32-2\include\* "%CUR_PATH%\include\" /E /Q /I /Y
-xcopy libplist-1.7-win32-2\bin\* "%APP_PATH%\system\" /E /Q /I /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/libplist_d.txt b/project/BuildDependencies/scripts/libplist_d.txt
deleted file mode 100644
index affb546b2c..0000000000
--- a/project/BuildDependencies/scripts/libplist_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename source of the file
-libplist-1.7-win32-2.7z http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/librtmp_d.bat b/project/BuildDependencies/scripts/librtmp_d.bat
deleted file mode 100644
index c99e1d6d58..0000000000
--- a/project/BuildDependencies/scripts/librtmp_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\librtmp_d.txt
-
-CALL dlextract.bat librtmp %FILES%
-
-cd %TMP_PATH%
-
-xcopy librtmp-20110723-git-b627335-win32\include\*.h "%CUR_PATH%\include\librtmp\" /E /Q /I /Y
-xcopy librtmp-20110723-git-b627335-win32\lib\*.dll "%APP_PATH%\system\players\dvdplayer\" /E /Q /I /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/librtmp_d.txt b/project/BuildDependencies/scripts/librtmp_d.txt
deleted file mode 100644
index 0b8eef18df..0000000000
--- a/project/BuildDependencies/scripts/librtmp_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename mirror source of the file
-librtmp-20110723-git-b627335-win32.7z http://mirrors.xbmc.org/build-deps/win32/ http://rtmpdump.mplayerhq.hu/
diff --git a/project/BuildDependencies/scripts/libsdl_d.bat b/project/BuildDependencies/scripts/libsdl_d.bat
deleted file mode 100644
index 4f7f0cead5..0000000000
--- a/project/BuildDependencies/scripts/libsdl_d.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\libsdl_d.txt
-
-CALL dlextract.bat libsdl %FILES%
-
-cd %TMP_PATH%
-
-xcopy SDL-1.2.14\include\* "%CUR_PATH%\include\SDL\" /E /Q /I /Y
-copy SDL-1.2.14\lib\SDL.lib "%CUR_PATH%\lib\SDL.lib" /Y
-
-copy SDL_image-1.2.10\include\SDL_image.h "%CUR_PATH%\include\SDL\"
-copy SDL_image-1.2.10\lib\SDL_image.lib "%CUR_PATH%\lib\SDL_image.lib" /Y
-
-
-cd %LOC_PATH% \ No newline at end of file
diff --git a/project/BuildDependencies/scripts/libsdl_d.txt b/project/BuildDependencies/scripts/libsdl_d.txt
deleted file mode 100644
index 4bbfa3136a..0000000000
--- a/project/BuildDependencies/scripts/libsdl_d.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-; filename mirror source of the file
-SDL-devel-1.2.14-VC8.zip http://mirrors.xbmc.org/build-deps/win32/ http://www.libsdl.org/release/
-SDL_image-devel-1.2.10-VC.zip http://mirrors.xbmc.org/build-deps/win32/ http://www.libsdl.org/projects/SDL_image/release/
diff --git a/project/BuildDependencies/scripts/swig_d.bat b/project/BuildDependencies/scripts/swig_d.bat
deleted file mode 100644
index 0c17319152..0000000000
--- a/project/BuildDependencies/scripts/swig_d.bat
+++ /dev/null
@@ -1,12 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\swig_d.txt
-
-CALL dlextract.bat swig %FILES%
-
-cd %TMP_PATH%
-
-xcopy swig-2.0.7-win32\* "%CUR_PATH%\bin\swig" /E /Q /I /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/swig_d.txt b/project/BuildDependencies/scripts/swig_d.txt
deleted file mode 100644
index 58c2bdfa58..0000000000
--- a/project/BuildDependencies/scripts/swig_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename source of the file
-swig-2.0.7-win32.zip http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/yajl_d.bat b/project/BuildDependencies/scripts/yajl_d.bat
deleted file mode 100644
index 946c986e9c..0000000000
--- a/project/BuildDependencies/scripts/yajl_d.bat
+++ /dev/null
@@ -1,13 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\yajl_d.txt
-
-CALL dlextract.bat yajl %FILES%
-
-cd %TMP_PATH%
-
-xcopy yajl_2.0.1_win32-lib\include\yajl "%CUR_PATH%\include\yajl" /E /Q /I /Y
-copy yajl_2.0.1_win32-lib\lib\yajl.lib "%CUR_PATH%\lib\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/yajl_d.txt b/project/BuildDependencies/scripts/yajl_d.txt
deleted file mode 100644
index b5b7723ae6..0000000000
--- a/project/BuildDependencies/scripts/yajl_d.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-; filename source of the file
-yajl_2.0.1_win32-lib.zip http://mirrors.xbmc.org/build-deps/win32/
diff --git a/project/BuildDependencies/scripts/zlib_d.bat b/project/BuildDependencies/scripts/zlib_d.bat
deleted file mode 100644
index f9fb00f458..0000000000
--- a/project/BuildDependencies/scripts/zlib_d.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-@ECHO OFF
-
-SET LOC_PATH=%CD%
-SET FILES=%LOC_PATH%\zlib_d.txt
-
-CALL dlextract.bat zlib %FILES%
-
-cd %TMP_PATH%
-
-xcopy include\* "%CUR_PATH%\include\" /E /Q /I /Y
-copy lib\zlib*.lib "%CUR_PATH%\lib\" /Y
-copy bin\zlib1.dll "%APP_PATH%\system\" /Y
-
-cd %LOC_PATH%
diff --git a/project/BuildDependencies/scripts/zlib_d.txt b/project/BuildDependencies/scripts/zlib_d.txt
deleted file mode 100644
index a48685ff54..0000000000
--- a/project/BuildDependencies/scripts/zlib_d.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-; filename mirror of the file source of the file
-zlib-vc100-1.2.5-bin.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/zlib-vc100-1.2.5-bin.tar.bz2
-zlib-vc100-1.2.5-lib-1.tar.bz2 http://mirrors.xbmc.org/build-deps/win32/ http://winkde.org/pub/kde/ports/win32/releases/stable/4.5.4/zlib-vc100-1.2.5-lib.tar.bz2 \ No newline at end of file
diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt
index 9340d053b5..a578d04a7d 100644
--- a/project/cmake/addons/CMakeLists.txt
+++ b/project/cmake/addons/CMakeLists.txt
@@ -25,7 +25,7 @@ endif()
get_filename_component(APP_ROOT "${APP_ROOT}" ABSOLUTE)
if(NOT BUILD_DIR)
- set(BUILD_DIR "${CMAKE_BINARY_DIR}/build")
+ set(BUILD_DIR "${CMAKE_BINARY_DIR}/build")
else()
file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR)
endif()
@@ -36,6 +36,7 @@ if(NOT DEPENDS_PATH)
else()
file(TO_CMAKE_PATH "${DEPENDS_PATH}" DEPENDS_PATH)
endif()
+get_filename_component(DEPENDS_PATH "${DEPENDS_PATH}" ABSOLUTE)
# make sure CMAKE_PREFIX_PATH is set
if(NOT CMAKE_PREFIX_PATH)
diff --git a/project/cmake/addons/depends/CMakeLists.txt b/project/cmake/addons/depends/CMakeLists.txt
index 7141bc3372..760acf40f1 100644
--- a/project/cmake/addons/depends/CMakeLists.txt
+++ b/project/cmake/addons/depends/CMakeLists.txt
@@ -22,131 +22,16 @@ endif()
get_filename_component(DEPENDS_PATH "${DEPENDS_PATH}" ABSOLUTE)
list(APPEND CMAKE_PREFIX_PATH ${DEPENDS_PATH})
-if(NOT DEPENDS_TO_BUILD)
- set(DEPENDS_TO_BUILD "all")
+if(NOT BUILD_DIR)
+ set(BUILD_DIR "${CMAKE_BINARY_DIR}/build")
else()
- message(STATUS "Building following dependencies: ${DEPENDS_TO_BUILD}")
- separate_arguments(DEPENDS_TO_BUILD)
+ file(TO_CMAKE_PATH "${BUILD_DIR}" BUILD_DIR)
endif()
+get_filename_component(BUILD_DIR "${BUILD_DIR}" ABSOLUTE)
-## handle dependencies with a cmake based buildsystem which need to be downloaded, built and installed
-file(GLOB_RECURSE cmake_input_files ${CORE_SYSTEM_NAME}/cmake/*.txt)
-file(GLOB_RECURSE cmake_input_files2 common/*.txt)
-list(APPEND cmake_input_files ${cmake_input_files2})
-foreach(file ${cmake_input_files})
- if(NOT (file MATCHES CMakeLists.txt OR
- file MATCHES install.txt OR
- file MATCHES noinstall.txt OR
- file MATCHES flags.txt OR
- file MATCHES deps.txt))
- message(STATUS "Processing ${file}")
- file(STRINGS ${file} def)
- separate_arguments(def)
- list(LENGTH def deflength)
- get_filename_component(dir ${file} PATH)
-
- # get the id and url of the dependency
- set(url "")
- if(NOT "${def}" STREQUAL "")
- # read the id and the url from the file
- list(GET def 0 id)
- if(deflength GREATER 1)
- list(GET def 1 url)
- message(STATUS "${id} url: ${url}")
- endif()
- else()
- # read the id from the filename
- get_filename_component(id ${file} NAME_WE)
- endif()
-
- list(FIND DEPENDS_TO_BUILD ${id} idx)
- if(idx GREATER -1 OR DEPENDS_TO_BUILD STREQUAL "all")
- # check if there are any library specific flags that need to be passed on
- if(EXISTS ${dir}/flags.txt})
- file(STRINGS ${dir}/flags.txt extraflags)
- message(STATUS "${id} extraflags: ${extraflags}")
- endif()
-
- set(BUILD_ARGS -DCMAKE_PREFIX_PATH=${DEPENDS_PATH}
- -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
- -DCMAKE_USER_MAKE_RULES_OVERRIDE=${CMAKE_USER_MAKE_RULES_OVERRIDE}
- -DCMAKE_USER_MAKE_RULES_OVERRIDE_CXX=${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX}
- -DCMAKE_INSTALL_PREFIX=${DEPENDS_PATH}
- -DARCH_DEFINES=${ARCH_DEFINES}
- -DENABLE_STATIC=1
- -DBUILD_SHARED_LIBS=0
- "${extraflags}")
-
- if(CMAKE_TOOLCHAIN_FILE)
- list(APPEND BUILD_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
- MESSAGE("toolchain specified")
- MESSAGE(${BUILD_ARGS})
- endif()
-
- # if there's a CMakeLists.txt use it to prepare the build
- if(EXISTS ${dir}/CMakeLists.txt)
- set(PATCH_COMMAND ${CMAKE_COMMAND} -E copy
- ${dir}/CMakeLists.txt
- ${CMAKE_BINARY_DIR}/build/${id}/src/${id})
- else()
- set(PATCH_COMMAND "")
- endif()
-
- # if there's an install.txt use it to properly install the built files
- if(EXISTS ${dir}/install.txt)
- set(INSTALL_COMMAND INSTALL_COMMAND ${CMAKE_COMMAND}
- -DINPUTDIR=${CMAKE_BINARY_DIR}/build/${id}/src/${id}-build/
- -DINPUTFILE=${dir}/install.txt
- -DDESTDIR=${DEPENDS_PATH}
- -DENABLE_STATIC=1
- "${extraflags}"
- -P ${PROJECT_SOURCE_DIR}/install.cmake)
- elseif(EXISTS ${dir}/noinstall.txt)
- set(INSTALL_COMMAND INSTALL_COMMAND "")
- else()
- set(INSTALL_COMMAND "")
- endif()
-
- # prepare the setup of the call to externalproject_add()
- set(EXTERNALPROJECT_SETUP PREFIX build/${id}
- CMAKE_ARGS ${BUILD_ARGS}
- PATCH_COMMAND ${PATCH_COMMAND}
- "${INSTALL_COMMAND}")
-
- # if there's an url defined we need to pass that to externalproject_add()
- if(DEFINED url AND NOT "${url}" STREQUAL "")
- # check if there's a third parameter in the file
- if(deflength GREATER 2)
- # the third parameter is considered as a revision of a git repository
- list(GET def 2 revision)
-
- externalproject_add(${id}
- GIT_REPOSITORY ${url}
- GIT_TAG ${revision}
- "${EXTERNALPROJECT_SETUP}"
- )
- else()
- externalproject_add(${id}
- URL ${url}
- "${EXTERNALPROJECT_SETUP}"
- )
- endif()
- else()
- externalproject_add(${id}
- SOURCE_DIR ${dir}
- "${EXTERNALPROJECT_SETUP}"
- )
- endif()
-
- # check if there's a deps.txt containing dependencies on other libraries
- if(EXISTS ${dir}/deps.txt)
- file(STRINGS ${dir}/deps.txt deps)
- message(STATUS "${id} dependencies: ${deps}")
- add_dependencies(${id} ${deps})
- endif()
- endif()
- endif()
-endforeach()
+## use add_addon_depends to handle the cmake based dependencies
+include(${APP_ROOT}/project/cmake/scripts/common/handle-depends.cmake)
+add_addon_depends(depends "${PROJECT_SOURCE_DIR}")
## if there's a platform-specific sub-directory containing a CMakeLists.txt, add it to the build as well
if(EXISTS ${PROJECT_SOURCE_DIR}/${CORE_SYSTEM_NAME}/CMakeLists.txt)
diff --git a/project/cmake/scripts/common/handle-depends.cmake b/project/cmake/scripts/common/handle-depends.cmake
index e168c9cf81..83d2ae4ff6 100644
--- a/project/cmake/scripts/common/handle-depends.cmake
+++ b/project/cmake/scripts/common/handle-depends.cmake
@@ -104,20 +104,24 @@ function(add_addon_depends addon searchpath)
set(EXTERNALPROJECT_SETUP PREFIX ${BUILD_DIR}/${id}
CMAKE_ARGS ${extraflags} ${BUILD_ARGS}
PATCH_COMMAND ${PATCH_COMMAND}
- ${INSTALL_COMMAND})
+ "${INSTALL_COMMAND}")
# if there's an url defined we need to pass that to externalproject_add()
if(DEFINED url AND NOT "${url}" STREQUAL "")
+ # check if there's a third parameter in the file
if(deflength GREATER 2)
+ # the third parameter is considered as a revision of a git repository
list(GET def 2 revision)
+
externalproject_add(${id}
GIT_REPOSITORY ${url}
GIT_TAG ${revision}
- ${EXTERNALPROJECT_SETUP})
+ "${EXTERNALPROJECT_SETUP}")
else()
if(WIN32)
set(CONFIGURE_COMMAND "")
else()
+ # manually specify the configure command to be able to pass in the custom PKG_CONFIG_PATH
set(CONFIGURE_COMMAND PKG_CONFIG_PATH=${OUTPUT_DIR}/lib/pkgconfig
${CMAKE_COMMAND} -DCMAKE_LIBRARY_PATH=${OUTPUT_DIR}/lib ${extraflags}
${BUILD_DIR}/${id}/src/${id}
@@ -134,13 +138,14 @@ function(add_addon_depends addon searchpath)
URL ${url}
DOWNLOAD_DIR ${BUILD_DIR}/download
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
- ${EXTERNALPROJECT_SETUP})
+ "${EXTERNALPROJECT_SETUP}")
endif()
else()
externalproject_add(${id}
SOURCE_DIR ${dir}
- ${EXTERNALPROJECT_SETUP})
+ "${EXTERNALPROJECT_SETUP}")
endif()
+
if(deps)
add_dependencies(${id} ${deps})
endif()
diff --git a/tools/buildsteps/defaultenv b/tools/buildsteps/defaultenv
index 78ea7a0124..f7baab87d6 100644
--- a/tools/buildsteps/defaultenv
+++ b/tools/buildsteps/defaultenv
@@ -73,12 +73,6 @@ then
Configuration=$DEFAULT_CONFIGURATION
fi
-#clamp release builds to 1 thread only
-if [ "$Configuration" == "Release" ]
-then
- BUILDTHREADS=1
-fi
-
#helper functions
#hash a dir based on the git revision, SDK_PATH, NDK_PATH, NDK_VERSION, SDK_VERSION, TOOLCHAIN TOOLCHAIN_X86 (for droidx86) and XBMC_DEPENDS_ROOT
diff --git a/tools/depends/native/TexturePacker/src/TexturePacker.cpp b/tools/depends/native/TexturePacker/src/TexturePacker.cpp
index a84a4606ef..9d093f280d 100644
--- a/tools/depends/native/TexturePacker/src/TexturePacker.cpp
+++ b/tools/depends/native/TexturePacker/src/TexturePacker.cpp
@@ -385,7 +385,7 @@ int createBundle(const std::string& InputDir, const std::string& OutputFile, dou
{
for (unsigned int j = 0; j < frames.frameList.size(); j++)
{
- printf(" frame %4i ", j);
+ printf(" frame %4i (delay:%4i) ", j, frames.frameList[j].delay);
CXBTFFrame frame = createXBTFFrame(frames.frameList[j].rgbaImage, writer, maxMSE, flags);
frame.SetDuration(frames.frameList[j].delay);
file.GetFrames().push_back(frame);
diff --git a/tools/depends/native/TexturePacker/src/decoder/GifHelper.cpp b/tools/depends/native/TexturePacker/src/decoder/GifHelper.cpp
index 8b65cf613b..45a5a5e784 100644
--- a/tools/depends/native/TexturePacker/src/decoder/GifHelper.cpp
+++ b/tools/depends/native/TexturePacker/src/decoder/GifHelper.cpp
@@ -82,7 +82,12 @@ GifHelper::GifHelper() :
GifHelper::~GifHelper()
{
- int err = DGifCloseFile(m_gif);
+ int err;
+#if GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1
+ DGifCloseFile(m_gif, &err);
+#else
+ err = DGifCloseFile(m_gif);
+#endif
if (err == D_GIF_ERR_CLOSE_FAILED)
{
fprintf(stderr, "Gif::~Gif(): D_GIF_ERR_CLOSE_FAILED\n");
@@ -119,7 +124,7 @@ bool GifHelper::LoadGifMetaData(GifFileType* file)
if (DGifSlurp(m_gif) == GIF_ERROR)
{
#if GIFLIB_MAJOR >= 5
- char* error = GifErrorString(m_gif->Error);
+ const char* error = GifErrorString(m_gif->Error);
if (error)
fprintf(stderr, "Gif::LoadGif(): Could not read file %s - %s\n", m_filename.c_str(), error);
#else
@@ -190,7 +195,7 @@ bool GifHelper::LoadGifMetaData(const char* file)
if (!m_gif)
{
#if GIFLIB_MAJOR >= 5
- char* error = GifErrorString(err);
+ const char* error = GifErrorString(err);
if (error)
fprintf(stderr, "Gif::LoadGif(): Could not open file %s - %s\n", m_filename.c_str(), error);
#else
@@ -248,7 +253,11 @@ bool GifHelper::IsAnimated(const char* file)
{
if (DGifSlurp(gif) && gif->ImageCount > 1)
m_isAnimated = 1;
+#if GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1
+ DGifCloseFile(gif, NULL);
+#else
DGifCloseFile(gif);
+#endif
fclose(gifFile);
}
}
@@ -285,12 +294,12 @@ bool GifHelper::gcbToFrame(GifFrame &frame, unsigned int imgIdx)
frame.m_delay = 0;
frame.m_disposal = 0;
#if GIFLIB_MAJOR >= 5
- if (m_gif->ExtensionBlockCount > 0)
+ if (m_gif->ImageCount > 0)
{
GraphicsControlBlock gcb;
if (!DGifSavedExtensionToGCB(m_gif, imgIdx, &gcb))
{
- char* error = GifErrorString(m_gif->Error);
+ const char* error = GifErrorString(m_gif->Error);
if (error)
fprintf(stderr, "Gif::ExtractFrames(): Could not read GraphicsControlBlock of frame %d - %s\n", imgIdx, error);
else
@@ -495,7 +504,7 @@ bool GifHelper::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize,
if (!m_gif)
{
#if GIFLIB_MAJOR >= 5
- char* error = GifErrorString(err);
+ const char* error = GifErrorString(err);
if (error)
fprintf(stderr, "Gif::LoadImageFromMemory(): Could not open gif from memory - %s\n", error);
#else
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
index 0000000000..7855f428ff
--- /dev/null
+++ b/tools/depends/target/curl/0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
@@ -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
+
diff --git a/tools/depends/target/curl/Makefile b/tools/depends/target/curl/Makefile
index 9ca896c380..d1f01501dc 100644
--- a/tools/depends/target/curl/Makefile
+++ b/tools/depends/target/curl/Makefile
@@ -3,7 +3,11 @@ DEPS= ../../Makefile.include Makefile
# lib name, version
LIBNAME=curl
+ifeq (osx, $(findstring osx, $(OS)))
+VERSION=7.21.6
+else
VERSION=7.39.0
+endif
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.bz2
# configuration settings
@@ -22,6 +26,9 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ifeq (osx, $(findstring osx, $(OS)))
+ cd $(PLATFORM); patch -p1 < ../0001-HTTP-reset-expected-DL-UL-sizes-on-redirects.patch
+endif
cd $(PLATFORM); $(CONFIGURE)
$(LIBDYLIB): $(PLATFORM)
diff --git a/tools/depends/target/librtmp/Makefile b/tools/depends/target/librtmp/Makefile
index 271873e043..15829b4648 100644
--- a/tools/depends/target/librtmp/Makefile
+++ b/tools/depends/target/librtmp/Makefile
@@ -3,7 +3,7 @@ DEPS= ../../Makefile.include Makefile prefix.patch
# lib name, version
LIBNAME=rtmpdump
-VERSION=e0056c51cc1710c9a44d2a2c4e2f344fa9cabcf4
+VERSION=a107cef9b392616dff54fabfd37f985ee2190a6f
SOURCE=$(LIBNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
# configuration settings
@@ -27,7 +27,6 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p0 < ../prefix.patch
- cd $(PLATFORM); patch -p1 < ../librtmp-60-second-fix.patch
cd $(PLATFORM)/librtmp; patch -p0 < ../../libm.patch
sed -i -e 's|CC=|#CC=|' $(PLATFORM)/librtmp/Makefile
sed -i -e 's|LD=|#LD=|' $(PLATFORM)/librtmp/Makefile
@@ -40,8 +39,8 @@ $(LIBDYLIB): $(PLATFORM)
$(MAKE) SYS=$(SYS) prefix=$(PREFIX) -C $(PLATFORM)/librtmp install
ifeq ($(OS),android)
rm -f $(PREFIX)/lib/librtmp.la $(PREFIX)/lib/librtmp.so
- mv -f $(PREFIX)/lib/librtmp.so.0 $(PREFIX)/lib/librtmp.so
- $(RPL) -e "librtmp.so.0" "librtmp.so\x00\x00" $(PREFIX)/lib/librtmp.so
+ mv -f $(PREFIX)/lib/librtmp.so.1 $(PREFIX)/lib/librtmp.so
+ $(RPL) -e "librtmp.so.1" "librtmp.so\x00\x00" $(PREFIX)/lib/librtmp.so
-$(READELF) --dynamic $(PREFIX)/lib/librtmp.so | grep ibrary
endif
touch $@
diff --git a/tools/depends/target/librtmp/librtmp-60-second-fix.patch b/tools/depends/target/librtmp/librtmp-60-second-fix.patch
deleted file mode 100644
index 2914fc1b8e..0000000000
--- a/tools/depends/target/librtmp/librtmp-60-second-fix.patch
+++ /dev/null
@@ -1,1913 +0,0 @@
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index ce84f81..a25bc04 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -610,6 +610,9 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- return -1;
- }
-
-+ if (*pBuffer == AMF_NULL)
-+ bDecodeName = 0;
-+
- if (bDecodeName && nSize < 4)
- { /* at least name (length + at least 1 byte) and 1 byte of data */
- RTMP_Log(RTMP_LOGDEBUG,
-@@ -801,8 +804,8 @@ AMFProp_Dump(AMFObjectProperty *prop)
- }
- else
- {
-- name.av_val = "no-name.";
-- name.av_len = sizeof("no-name.") - 1;
-+ name.av_val = "no-name";
-+ name.av_len = sizeof("no-name") - 1;
- }
- if (name.av_len > 18)
- name.av_len = 18;
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index 9959532..e29587b 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -61,7 +61,7 @@ static int MDH_generate_key(MDH *dh)
- MP_set(&dh->ctx.P, dh->p);
- MP_set(&dh->ctx.G, dh->g);
- dh->ctx.len = 128;
-- dhm_make_public(&dh->ctx, 1024, out, 1, havege_rand, &RTMP_TLS_ctx->hs);
-+ dhm_make_public(&dh->ctx, 1024, out, 1, havege_random, &RTMP_TLS_ctx->hs);
- MP_new(dh->pub_key);
- MP_new(dh->priv_key);
- MP_set(dh->pub_key, &dh->ctx.GX);
-diff --git a/librtmp/handshake.h b/librtmp/handshake.h
-index 0438486..102ba82 100644
---- a/librtmp/handshake.h
-+++ b/librtmp/handshake.h
-@@ -965,8 +965,18 @@ HandShake(RTMP * r, int FP9HandShake)
- __FUNCTION__);
- RTMP_LogHex(RTMP_LOGDEBUG, reply, RTMP_SIG_SIZE);
- #endif
-- if (!WriteN(r, (char *)reply, RTMP_SIG_SIZE))
-- return FALSE;
-+ if (r->Link.CombineConnectPacket)
-+ {
-+ char *HandshakeResponse = malloc(RTMP_SIG_SIZE);
-+ memcpy(HandshakeResponse, (char *) reply, RTMP_SIG_SIZE);
-+ r->Link.HandshakeResponse.av_val = HandshakeResponse;
-+ r->Link.HandshakeResponse.av_len = RTMP_SIG_SIZE;
-+ }
-+ else
-+ {
-+ if (!WriteN(r, (char *) reply, RTMP_SIG_SIZE))
-+ return FALSE;
-+ }
-
- /* 2nd part of handshake */
- if (ReadN(r, (char *)serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
-diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c
-index 9f4e2c0..eeed34c 100644
---- a/librtmp/hashswf.c
-+++ b/librtmp/hashswf.c
-@@ -70,7 +70,7 @@ extern TLS_CTX RTMP_TLS_ctx;
-
- #endif /* CRYPTO */
-
--#define AGENT "Mozilla/5.0"
-+#define AGENT "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0"
-
- HTTPResult
- HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
-@@ -528,7 +528,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
-
- if (strncmp(buf, "url: ", 5))
- continue;
-- if (strncmp(buf + 5, url, hlen))
-+ if (strncmp(buf + 5, url, strlen(buf + 5) - 1))
- continue;
- r1 = strrchr(buf, '/');
- i = strlen(r1);
-diff --git a/librtmp/log.c b/librtmp/log.c
-index 0012985..856e3e4 100644
---- a/librtmp/log.c
-+++ b/librtmp/log.c
-@@ -52,8 +52,8 @@ static void rtmp_log_default(int level, const char *format, va_list vl)
- vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
-
- /* Filter out 'no-name' */
-- if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
-- return;
-+ if (RTMP_debuglevel < RTMP_LOGDEBUG && strstr(str, "no-name") != NULL)
-+ return;
-
- if ( !fmsg ) fmsg = stderr;
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 52d0254..bef37aa 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -27,6 +27,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
-+#include <math.h>
-
- #include "rtmp_sys.h"
- #include "log.h"
-@@ -45,6 +46,7 @@ TLS_CTX RTMP_TLS_ctx;
-
- #define RTMP_SIG_SIZE 1536
- #define RTMP_LARGE_HEADER_SIZE 12
-+#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
-
- static const int packetSize[] = { 12, 8, 4, 1 };
-
-@@ -97,6 +99,9 @@ static int SendFCSubscribe(RTMP *r, AVal *subscribepath);
- static int SendPlay(RTMP *r);
- static int SendBytesReceived(RTMP *r);
- static int SendUsherToken(RTMP *r, AVal *usherToken);
-+static int SendInvoke(RTMP *r, AVal *Command, int queue);
-+static int SendGetStreamLength(RTMP *r);
-+static int strsplit(char *src, int srclen, char delim, char ***params);
-
- #if 0 /* unused */
- static int SendBGHasStream(RTMP *r, double dId, AVal *playpath);
-@@ -259,6 +264,8 @@ RTMP_Init(RTMP *r)
- r->m_fVideoCodecs = 252.0;
- r->Link.timeout = 30;
- r->Link.swfAge = 30;
-+ r->Link.CombineConnectPacket = TRUE;
-+ r->Link.ConnectPacket = FALSE;
- }
-
- void
-@@ -337,6 +344,7 @@ RTMP_SetupStream(RTMP *r,
- AVal *flashVer,
- AVal *subscribepath,
- AVal *usherToken,
-+ AVal *WeebToken,
- int dStart,
- int dStop, int bLiveStream, long int timeout)
- {
-@@ -359,6 +367,8 @@ RTMP_SetupStream(RTMP *r,
- RTMP_Log(RTMP_LOGDEBUG, "subscribepath : %s", subscribepath->av_val);
- if (usherToken && usherToken->av_val)
- RTMP_Log(RTMP_LOGDEBUG, "NetStream.Authenticate.UsherToken : %s", usherToken->av_val);
-+ if (WeebToken && WeebToken->av_val)
-+ RTMP_Log(RTMP_LOGDEBUG, "WeebToken: %s", WeebToken->av_val);
- if (flashVer && flashVer->av_val)
- RTMP_Log(RTMP_LOGDEBUG, "flashVer : %s", flashVer->av_val);
- if (dStart > 0)
-@@ -426,6 +436,8 @@ RTMP_SetupStream(RTMP *r,
- r->Link.subscribepath = *subscribepath;
- if (usherToken && usherToken->av_len)
- r->Link.usherToken = *usherToken;
-+ if (WeebToken && WeebToken->av_len)
-+ r->Link.WeebToken = *WeebToken;
- r->Link.seekTime = dStart;
- r->Link.stopTime = dStop;
- if (bLiveStream)
-@@ -483,14 +495,22 @@ static struct urlopt {
- "Stream is live, no seeking possible" },
- { AVC("subscribe"), OFF(Link.subscribepath), OPT_STR, 0,
- "Stream to subscribe to" },
-- { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0,
-- "Justin.tv authentication token" },
-- { AVC("token"), OFF(Link.token), OPT_STR, 0,
-+ { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0,
-+ "Justin.tv authentication token"},
-+ { AVC("weeb"), OFF(Link.WeebToken), OPT_STR, 0,
-+ "Weeb.tv authentication token"},
-+ { AVC("token"), OFF(Link.token), OPT_STR, 0,
- "Key for SecureToken response" },
- { AVC("swfVfy"), OFF(Link.lFlags), OPT_BOOL, RTMP_LF_SWFV,
- "Perform SWF Verification" },
- { AVC("swfAge"), OFF(Link.swfAge), OPT_INT, 0,
- "Number of days to use cached SWF hash" },
-+#ifdef CRYPTO
-+ { AVC("swfsize"), OFF(Link.swfSize), OPT_INT, 0,
-+ "Size of the decompressed SWF file"},
-+ { AVC("swfhash"), OFF(Link.swfHash), OPT_STR, 0,
-+ "SHA256 hash of the decompressed SWF file"},
-+#endif
- { AVC("start"), OFF(Link.seekTime), OPT_INT, 0,
- "Stream start position in milliseconds" },
- { AVC("stop"), OFF(Link.stopTime), OPT_INT, 0,
-@@ -751,9 +771,16 @@ int RTMP_SetupURL(RTMP *r, char *url)
- }
-
- #ifdef CRYPTO
-- if ((r->Link.lFlags & RTMP_LF_SWFV) && r->Link.swfUrl.av_len)
-- RTMP_HashSWF(r->Link.swfUrl.av_val, &r->Link.SWFSize,
-- (unsigned char *)r->Link.SWFHash, r->Link.swfAge);
-+ RTMP_Log(RTMP_LOGDEBUG, "Khalsa: %d %d %s\n", r->Link.swfSize, r->Link.swfHash.av_len, r->Link.swfHash.av_val);
-+ if (r->Link.swfSize && r->Link.swfHash.av_len)
-+ {
-+ int i, j = 0;
-+ for (i = 0; i < r->Link.swfHash.av_len; i += 2)
-+ r->Link.SWFHash[j++] = (HEX2BIN(r->Link.swfHash.av_val[i]) << 4) | HEX2BIN(r->Link.swfHash.av_val[i + 1]);
-+ r->Link.SWFSize = (uint32_t) r->Link.swfSize;
-+ }
-+ else if ((r->Link.lFlags & RTMP_LF_SWFV) && r->Link.swfUrl.av_len)
-+ RTMP_HashSWF(r->Link.swfUrl.av_val, &r->Link.SWFSize, (unsigned char *) r->Link.SWFHash, r->Link.swfAge);
- #endif
-
- if (r->Link.port == 0)
-@@ -854,6 +881,8 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service)
- }
-
- setsockopt(r->m_sb.sb_socket, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on));
-+ if (r->Link.protocol & RTMP_FEATURE_HTTP)
-+ setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof (on));
-
- return TRUE;
- }
-@@ -1308,8 +1337,24 @@ ReadN(RTMP *r, char *buffer, int n)
- return 0;
- }
- }
-- if (r->m_resplen && !r->m_sb.sb_size)
-- RTMPSockBuf_Fill(&r->m_sb);
-+
-+ // Try to fill the whole buffer. previous buffer needs to be consumed
-+ // completely before receiving new data.
-+ if (r->m_resplen && (r->m_sb.sb_size <= 0))
-+ {
-+ do
-+ {
-+ nBytes = RTMPSockBuf_Fill(&r->m_sb);
-+ if (nBytes == -1)
-+ {
-+ if (!r->m_sb.sb_timedout)
-+ RTMP_Close(r);
-+ return 0;
-+ }
-+ }
-+ while (r->m_resplen && (r->m_sb.sb_size < r->m_resplen) && (nBytes > 0));
-+ }
-+
- avail = r->m_sb.sb_size;
- if (avail > r->m_resplen)
- avail = r->m_resplen;
-@@ -1336,10 +1381,9 @@ ReadN(RTMP *r, char *buffer, int n)
- r->m_sb.sb_size -= nRead;
- nBytes = nRead;
- r->m_nBytesIn += nRead;
-- if (r->m_bSendCounter
-- && r->m_nBytesIn > ( r->m_nBytesInSent + r->m_nClientBW / 10))
-- if (!SendBytesReceived(r))
-- return FALSE;
-+ if (r->m_bSendCounter && r->m_nBytesIn > (r->m_nBytesInSent + r->m_nClientBW / 10))
-+ if (!SendBytesReceived(r))
-+ return FALSE;
- }
- /*RTMP_Log(RTMP_LOGDEBUG, "%s: %d bytes\n", __FUNCTION__, nBytes); */
- #ifdef _DEBUG
-@@ -1390,6 +1434,16 @@ WriteN(RTMP *r, const char *buffer, int n)
- }
- #endif
-
-+ if (r->Link.ConnectPacket)
-+ {
-+ char *ConnectPacket = malloc(r->Link.HandshakeResponse.av_len + n);
-+ memcpy(ConnectPacket, r->Link.HandshakeResponse.av_val, r->Link.HandshakeResponse.av_len);
-+ memcpy(ConnectPacket + r->Link.HandshakeResponse.av_len, ptr, n);
-+ ptr = ConnectPacket;
-+ n += r->Link.HandshakeResponse.av_len;
-+ r->Link.ConnectPacket = FALSE;
-+ }
-+
- while (n > 0)
- {
- int nBytes;
-@@ -1455,6 +1509,9 @@ SendConnectPacket(RTMP *r, RTMPPacket *cp)
- char pbuf[4096], *pend = pbuf + sizeof(pbuf);
- char *enc;
-
-+ if (r->Link.CombineConnectPacket)
-+ r->Link.ConnectPacket = TRUE;
-+
- if (cp)
- return RTMP_SendPacket(r, cp, TRUE);
-
-@@ -1667,7 +1724,7 @@ SendUsherToken(RTMP *r, AVal *usherToken)
- packet.m_hasAbsTimestamp = 0;
- packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
-
-- RTMP_Log(RTMP_LOGDEBUG, "UsherToken: %s", usherToken->av_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "UsherToken: %.*s", usherToken->av_len, usherToken->av_val);
- enc = packet.m_body;
- enc = AMF_EncodeString(enc, pend, &av_NetStream_Authenticate_UsherToken);
- enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-@@ -2096,10 +2153,8 @@ SendPlay(RTMP *r)
- enc = AMF_EncodeNumber(enc, pend, -1000.0);
- else
- {
-- if (r->Link.seekTime > 0.0)
-- enc = AMF_EncodeNumber(enc, pend, r->Link.seekTime); /* resume from here */
-- else
-- enc = AMF_EncodeNumber(enc, pend, 0.0); /*-2000.0);*/ /* recorded as default, -2000.0 is not reliable since that freezes the player if the stream is not found */
-+ if (r->Link.seekTime > 0.0 || r->Link.stopTime)
-+ enc = AMF_EncodeNumber(enc, pend, r->Link.seekTime); /* resume from here */
- }
- if (!enc)
- return FALSE;
-@@ -2215,7 +2270,7 @@ RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject, unsigned int nTime)
- int nSize;
- char *buf;
-
-- RTMP_Log(RTMP_LOGDEBUG, "sending ctrl. type: 0x%04x", (unsigned short)nType);
-+ RTMP_Log(RTMP_LOGDEBUG, "sending ctrl, type: 0x%04x", (unsigned short)nType);
-
- packet.m_nChannel = 0x02; /* control channel (ping) */
- packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
-@@ -2247,8 +2302,8 @@ RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject, unsigned int nTime)
- }
- else if (nType == 0x1A)
- {
-- *buf = nObject & 0xff;
-- }
-+ *buf = nObject & 0xff;
-+ }
- else
- {
- if (nSize > 2)
-@@ -2305,6 +2360,7 @@ AV_clear(RTMP_METHOD *vals, int num)
- free(vals);
- }
-
-+SAVC(onBWCheck);
- SAVC(onBWDone);
- SAVC(onFCSubscribe);
- SAVC(onFCUnsubscribe);
-@@ -2314,24 +2370,26 @@ SAVC(_error);
- SAVC(close);
- SAVC(code);
- SAVC(level);
-+SAVC(description);
- SAVC(onStatus);
- SAVC(playlist_ready);
- static const AVal av_NetStream_Failed = AVC("NetStream.Failed");
- static const AVal av_NetStream_Play_Failed = AVC("NetStream.Play.Failed");
--static const AVal av_NetStream_Play_StreamNotFound =
--AVC("NetStream.Play.StreamNotFound");
--static const AVal av_NetConnection_Connect_InvalidApp =
--AVC("NetConnection.Connect.InvalidApp");
-+static const AVal av_NetStream_Play_StreamNotFound = AVC("NetStream.Play.StreamNotFound");
-+static const AVal av_NetConnection_Connect_InvalidApp = AVC("NetConnection.Connect.InvalidApp");
- static const AVal av_NetStream_Play_Start = AVC("NetStream.Play.Start");
- static const AVal av_NetStream_Play_Complete = AVC("NetStream.Play.Complete");
- static const AVal av_NetStream_Play_Stop = AVC("NetStream.Play.Stop");
- static const AVal av_NetStream_Seek_Notify = AVC("NetStream.Seek.Notify");
- static const AVal av_NetStream_Pause_Notify = AVC("NetStream.Pause.Notify");
--static const AVal av_NetStream_Play_PublishNotify =
--AVC("NetStream.Play.PublishNotify");
--static const AVal av_NetStream_Play_UnpublishNotify =
--AVC("NetStream.Play.UnpublishNotify");
-+static const AVal av_NetStream_Play_PublishNotify = AVC("NetStream.Play.PublishNotify");
-+static const AVal av_NetStream_Play_UnpublishNotify = AVC("NetStream.Play.UnpublishNotify");
- static const AVal av_NetStream_Publish_Start = AVC("NetStream.Publish.Start");
-+static const AVal av_NetConnection_confStream = AVC("NetConnection.confStream");
-+static const AVal av_verifyClient = AVC("verifyClient");
-+static const AVal av_sendStatus = AVC("sendStatus");
-+static const AVal av_getStreamLength = AVC("getStreamLength");
-+static const AVal av_ReceiveCheckPublicStatus = AVC("ReceiveCheckPublicStatus");
-
- /* Returns 0 for OK/Failed/error, 1 for 'Stop or Complete' */
- static int
-@@ -2341,6 +2399,11 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- AVal method;
- double txn;
- int ret = 0, nRes;
-+ char pbuf[256], *pend = pbuf + sizeof (pbuf), *enc, **params = NULL;
-+ char *host = r->Link.hostname.av_len ? r->Link.hostname.av_val : "";
-+ char *pageUrl = r->Link.pageUrl.av_len ? r->Link.pageUrl.av_val : "";
-+ int param_count;
-+ AVal av_Command, av_Response;
- if (body[0] != 0x02) /* make sure it is a string method name we start with */
- {
- RTMP_Log(RTMP_LOGWARNING, "%s, Sanity failed. no string method in invoke packet",
-@@ -2402,23 +2465,137 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- RTMP_SendServerBW(r);
- RTMP_SendCtrl(r, 3, 0, 300);
- }
-- RTMP_SendCreateStream(r);
--
-- if (!(r->Link.protocol & RTMP_FEATURE_WRITE))
-- {
-- /* Authenticate on Justin.tv legacy servers before sending FCSubscribe */
-- if (r->Link.usherToken.av_len)
-- SendUsherToken(r, &r->Link.usherToken);
-- /* Send the FCSubscribe if live stream or if subscribepath is set */
-- if (r->Link.subscribepath.av_len)
-- SendFCSubscribe(r, &r->Link.subscribepath);
-- else if (r->Link.lFlags & RTMP_LF_LIVE)
-- SendFCSubscribe(r, &r->Link.playpath);
-- }
-- }
-+ if (strstr(host, "tv-stream.to") || strstr(pageUrl, "tv-stream.to"))
-+ {
-+ static char auth[] = {'h', 0xC2, 0xA7, '4', 'j', 'h', 'H', '4', '3', 'd'};
-+ AVal av_auth;
-+ SAVC(requestAccess);
-+ av_auth.av_val = auth;
-+ av_auth.av_len = sizeof (auth);
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_requestAccess);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, &av_auth);
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+ SendInvoke(r, &av_Command, FALSE);
-+
-+ SAVC(getConnectionCount);
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_getConnectionCount);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+ SendInvoke(r, &av_Command, FALSE);
-+
-+ SendGetStreamLength(r);
-+ }
-+ else if (strstr(host, "jampo.com.ua") || strstr(pageUrl, "jampo.com.ua"))
-+ {
-+ SendGetStreamLength(r);
-+ }
-+ else if (strstr(host, "streamscene.cc") || strstr(pageUrl, "streamscene.cc")
-+ || strstr(host, "tsboard.tv") || strstr(pageUrl, "teamstream.in"))
-+ {
-+ SAVC(r);
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_r);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+ SendInvoke(r, &av_Command, FALSE);
-+
-+ SendGetStreamLength(r);
-+ }
-+ else if (strstr(host, "chaturbate.com") || strstr(pageUrl, "chaturbate.com"))
-+ {
-+ AVal av_ModelName;
-+ SAVC(CheckPublicStatus);
-+
-+ if (strlen(pageUrl) > 7)
-+ {
-+ strsplit(pageUrl + 7, FALSE, '/', &params);
-+ av_ModelName.av_val = params[1];
-+ av_ModelName.av_len = strlen(params[1]);
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_CheckPublicStatus);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, &av_ModelName);
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+
-+ SendInvoke(r, &av_Command, FALSE);
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "you must specify the pageUrl");
-+ RTMP_Close(r);
-+ }
-+ }
-+ /* Weeb.tv specific authentication */
-+ else if (r->Link.WeebToken.av_len)
-+ {
-+ AVal av_Token, av_Username, av_Password;
-+ SAVC(determineAccess);
-+
-+ param_count = strsplit(r->Link.WeebToken.av_val, FALSE, ';', &params);
-+ if (param_count >= 1)
-+ {
-+ av_Token.av_val = params[0];
-+ av_Token.av_len = strlen(params[0]);
-+ }
-+ if (param_count >= 2)
-+ {
-+ av_Username.av_val = params[1];
-+ av_Username.av_len = strlen(params[1]);
-+ }
-+ if (param_count >= 3)
-+ {
-+ av_Password.av_val = params[2];
-+ av_Password.av_len = strlen(params[2]);
-+ }
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_determineAccess);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, &av_Token);
-+ enc = AMF_EncodeString(enc, pend, &av_Username);
-+ enc = AMF_EncodeString(enc, pend, &av_Password);
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "WeebToken: %s", r->Link.WeebToken.av_val);
-+ SendInvoke(r, &av_Command, FALSE);
-+ }
-+ else
-+ RTMP_SendCreateStream(r);
-+ }
-+ else if (AVMATCH(&methodInvoked, &av_getStreamLength))
-+ {
-+ RTMP_SendCreateStream(r);
-+ }
- else if (AVMATCH(&methodInvoked, &av_createStream))
-- {
-- r->m_stream_id = (int)AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3));
-+ {
-+ r->m_stream_id = (int) AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3));
-+
-+ if (!(r->Link.protocol & RTMP_FEATURE_WRITE))
-+ {
-+ /* Authenticate on Justin.tv legacy servers before sending FCSubscribe */
-+ if (r->Link.usherToken.av_len)
-+ SendUsherToken(r, &r->Link.usherToken);
-+ /* Send the FCSubscribe if live stream or if subscribepath is set */
-+ if (r->Link.subscribepath.av_len)
-+ SendFCSubscribe(r, &r->Link.subscribepath);
-+ else if ((r->Link.lFlags & RTMP_LF_LIVE) && (!r->Link.WeebToken.av_len))
-+ SendFCSubscribe(r, &r->Link.playpath);
-+ }
-
- if (r->Link.protocol & RTMP_FEATURE_WRITE)
- {
-@@ -2441,7 +2618,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- }
- else if (AVMATCH(&method, &av_onBWDone))
- {
-- if (!r->m_nBWCheckCounter)
-+ if (!r->m_nBWCheckCounter)
- SendCheckBW(r);
- }
- else if (AVMATCH(&method, &av_onFCSubscribe))
-@@ -2457,7 +2634,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- {
- SendPong(r, txn);
- }
-- else if (AVMATCH(&method, &av__onbwcheck))
-+ else if (AVMATCH(&method, &av__onbwcheck) || AVMATCH(&method, &av_onBWCheck))
- {
- SendCheckBWResult(r, txn);
- }
-@@ -2473,20 +2650,63 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- }
- else if (AVMATCH(&method, &av__error))
- {
-- RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
-+ double code = 0;
-+ unsigned int parsedPort;
-+ AMFObject obj2;
-+ AMFObjectProperty p;
-+ AVal redirect;
-+ SAVC(ex);
-+ SAVC(redirect);
-+
-+ AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2);
-+ if (RTMP_FindFirstMatchingProperty(&obj2, &av_ex, &p))
-+ {
-+ AMFProp_GetObject(&p, &obj2);
-+ if (RTMP_FindFirstMatchingProperty(&obj2, &av_code, &p))
-+ code = AMFProp_GetNumber(&p);
-+ if (code == 302 && RTMP_FindFirstMatchingProperty(&obj2, &av_redirect, &p))
-+ {
-+ AMFProp_GetString(&p, &redirect);
-+ r->Link.redirected = TRUE;
-+
-+ char *url = malloc(redirect.av_len + sizeof ("/playpath"));
-+ strncpy(url, redirect.av_val, redirect.av_len);
-+ url[redirect.av_len] = '\0';
-+ r->Link.tcUrl.av_val = url;
-+ r->Link.tcUrl.av_len = redirect.av_len;
-+ strcat(url, "/playpath");
-+ RTMP_ParseURL(url, &r->Link.protocol, &r->Link.hostname, &parsedPort, &r->Link.playpath0, &r->Link.app);
-+ r->Link.port = parsedPort;
-+ }
-+ }
-+ if (r->Link.redirected)
-+ RTMP_Log(RTMP_LOGINFO, "rtmp server sent redirect");
-+ else
-+ RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
- }
- else if (AVMATCH(&method, &av_close))
- {
-- RTMP_Log(RTMP_LOGERROR, "rtmp server requested close");
-- RTMP_Close(r);
-+ if (r->Link.redirected)
-+ {
-+ RTMP_Log(RTMP_LOGINFO, "trying to connect with redirected url");
-+ RTMP_Close(r);
-+ r->Link.redirected = FALSE;
-+ RTMP_Connect(r, NULL);
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "rtmp server requested close");
-+ RTMP_Close(r);
-+ }
- }
- else if (AVMATCH(&method, &av_onStatus))
- {
- AMFObject obj2;
-- AVal code, level;
-+ AVal code, level, description;
- AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2);
- AMFProp_GetString(AMF_GetProp(&obj2, &av_code, -1), &code);
- AMFProp_GetString(AMF_GetProp(&obj2, &av_level, -1), &level);
-+ AMFProp_GetString(AMF_GetProp(&obj2, &av_description, -1), &description);
-
- RTMP_Log(RTMP_LOGDEBUG, "%s, onStatus: %s", __FUNCTION__, code.av_val);
- if (AVMATCH(&code, &av_NetStream_Failed)
-@@ -2550,6 +2770,45 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- r->m_pausing = 3;
- }
- }
-+
-+ else if (AVMATCH(&code, &av_NetConnection_confStream))
-+ {
-+#ifdef CRYPTO
-+ static const char hexdig[] = "0123456789abcdef";
-+ SAVC(cf_stream);
-+ int i;
-+ char hash_hex[33] = {0};
-+ unsigned char hash[16];
-+ AVal auth;
-+ param_count = strsplit(description.av_val, description.av_len, ':', &params);
-+ if (param_count >= 3)
-+ {
-+ char *buf = malloc(strlen(params[0]) + r->Link.playpath.av_len + 1);
-+ strcpy(buf, params[0]);
-+ strncat(buf, r->Link.playpath.av_val, r->Link.playpath.av_len);
-+ md5_hash((unsigned char *) buf, strlen(buf), hash);
-+ for (i = 0; i < 16; i++)
-+ {
-+ hash_hex[i * 2] = hexdig[0x0f & (hash[i] >> 4)];
-+ hash_hex[i * 2 + 1] = hexdig[0x0f & (hash[i])];
-+ }
-+ auth.av_val = &hash_hex[atoi(params[1]) - 1];
-+ auth.av_len = atoi(params[2]);
-+ RTMP_Log(RTMP_LOGDEBUG, "Khalsa: %.*s", auth.av_len, auth.av_val);
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_cf_stream);
-+ enc = AMF_EncodeNumber(enc, pend, txn);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, &auth);
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+
-+ SendInvoke(r, &av_Command, FALSE);
-+ free(buf);
-+ }
-+#endif
-+ }
- }
- else if (AVMATCH(&method, &av_playlist_ready))
- {
-@@ -2563,6 +2822,74 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- }
- }
- }
-+ else if (AVMATCH(&method, &av_verifyClient))
-+ {
-+ double VerificationNumber = AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3));
-+ RTMP_Log(RTMP_LOGDEBUG, "VerificationNumber: %.2f", VerificationNumber);
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av__result);
-+ enc = AMF_EncodeNumber(enc, pend, txn);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeNumber(enc, pend, exp(atan(sqrt(VerificationNumber))) + 1);
-+ av_Response.av_val = pbuf;
-+ av_Response.av_len = enc - pbuf;
-+
-+ AMF_Decode(&obj, av_Response.av_val, av_Response.av_len, FALSE);
-+ AMF_Dump(&obj);
-+ SendInvoke(r, &av_Response, FALSE);
-+ }
-+ else if (AVMATCH(&method, &av_sendStatus))
-+ {
-+ if (r->Link.WeebToken.av_len)
-+ {
-+ AVal av_Authorized = AVC("User.hasAccess");
-+ AVal av_TransferLimit = AVC("User.noPremium.limited");
-+ AVal av_UserLimit = AVC("User.noPremium.tooManyUsers");
-+ AVal av_TimeLeft = AVC("timeLeft");
-+ AVal av_Status, av_ReconnectionTime;
-+
-+ AMFObject Status;
-+ AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &Status);
-+ AMFProp_GetString(AMF_GetProp(&Status, &av_code, -1), &av_Status);
-+ RTMP_Log(RTMP_LOGINFO, "%.*s", av_Status.av_len, av_Status.av_val);
-+ if (AVMATCH(&av_Status, &av_Authorized))
-+ {
-+ RTMP_Log(RTMP_LOGINFO, "Weeb.tv authentication successful");
-+ RTMP_SendCreateStream(r);
-+ }
-+ else if (AVMATCH(&av_Status, &av_UserLimit))
-+ {
-+ RTMP_Log(RTMP_LOGINFO, "No free slots available");
-+ RTMP_Close(r);
-+ }
-+ else if (AVMATCH(&av_Status, &av_TransferLimit))
-+ {
-+ AMFProp_GetString(AMF_GetProp(&Status, &av_TimeLeft, -1), &av_ReconnectionTime);
-+ RTMP_Log(RTMP_LOGINFO, "Viewing limit exceeded. try again in %.*s minutes.", av_ReconnectionTime.av_len, av_ReconnectionTime.av_val);
-+ RTMP_Close(r);
-+ }
-+ }
-+ }
-+ else if (AVMATCH(&method, &av_ReceiveCheckPublicStatus))
-+ {
-+ AVal Status;
-+ AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &Status);
-+ strsplit(Status.av_val, Status.av_len, ',', &params);
-+ if (strcmp(params[0], "0") == 0)
-+ {
-+ RTMP_Log(RTMP_LOGINFO, "Model status is %s", params[1]);
-+ RTMP_Close(r);
-+ }
-+ else
-+ {
-+ AVal Playpath;
-+ Playpath.av_val = params[1];
-+ Playpath.av_len = strlen(params[1]);
-+ RTMP_ParsePlaypath(&Playpath, &r->Link.playpath);
-+ RTMP_SendCreateStream(r);
-+ }
-+ }
- else
- {
-
-@@ -2748,7 +3075,7 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet)
- unsigned int tmp;
- if (packet->m_body && packet->m_nBodySize >= 2)
- nType = AMF_DecodeInt16(packet->m_body);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received ctrl. type: %d, len: %d", __FUNCTION__, nType,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received ctrl, type: %d, len: %d", __FUNCTION__, nType,
- packet->m_nBodySize);
- /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */
-
-@@ -2856,15 +3183,15 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet)
- RTMP_Log(RTMP_LOGDEBUG, "%s, SWFVerification ping received: ", __FUNCTION__);
- if (packet->m_nBodySize > 2 && packet->m_body[2] > 0x01)
- {
-- RTMP_Log(RTMP_LOGERROR,
-- "%s: SWFVerification Type %d request not supported! Patches welcome...",
-- __FUNCTION__, packet->m_body[2]);
-+ RTMP_Log(RTMP_LOGERROR,
-+ "%s: SWFVerification Type %d request not supported, attempting to use SWFVerification Type 1! Patches welcome...",
-+ __FUNCTION__, packet->m_body[2]);
- }
- #ifdef CRYPTO
- /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */
-
- /* respond with HMAC SHA256 of decompressed SWF, key is the 30byte player key, also the last 30 bytes of the server handshake are applied */
-- else if (r->Link.SWFSize)
-+ if (r->Link.SWFSize)
- {
- RTMP_SendCtrl(r, 0x1B, 0, 0);
- }
-@@ -3142,8 +3469,18 @@ HandShake(RTMP *r, int FP9HandShake)
- serversig[4], serversig[5], serversig[6], serversig[7]);
-
- /* 2nd part of handshake */
-- if (!WriteN(r, serversig, RTMP_SIG_SIZE))
-- return FALSE;
-+ if (r->Link.CombineConnectPacket)
-+ {
-+ char *HandshakeResponse = malloc(RTMP_SIG_SIZE);
-+ memcpy(HandshakeResponse, (char *) serversig, RTMP_SIG_SIZE);
-+ r->Link.HandshakeResponse.av_val = HandshakeResponse;
-+ r->Link.HandshakeResponse.av_len = RTMP_SIG_SIZE;
-+ }
-+ else
-+ {
-+ if (!WriteN(r, (char *) serversig, RTMP_SIG_SIZE))
-+ return FALSE;
-+ }
-
- if (ReadN(r, serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
- return FALSE;
-@@ -3709,12 +4046,11 @@ HTTP_Post(RTMP *r, RTMPTCmd cmd, const char *buf, int len)
- char hbuf[512];
- int hlen = snprintf(hbuf, sizeof(hbuf), "POST /%s%s/%d HTTP/1.1\r\n"
- "Host: %.*s:%d\r\n"
-- "Accept: */*\r\n"
-- "User-Agent: Shockwave Flash\n"
-- "Connection: Keep-Alive\n"
-+ "User-Agent: Shockwave Flash\r\n"
-+ "Connection: Keep-Alive\r\n"
- "Cache-Control: no-cache\r\n"
-- "Content-type: application/x-fcs\r\n"
-- "Content-length: %d\r\n\r\n", RTMPT_cmds[cmd],
-+ "Content-Type: application/x-fcs\r\n"
-+ "Content-Length: %d\r\n\r\n", RTMPT_cmds[cmd],
- r->m_clientID.av_val ? r->m_clientID.av_val : "",
- r->m_msgCounter, r->Link.hostname.av_len, r->Link.hostname.av_val,
- r->Link.port, len);
-@@ -3749,6 +4085,14 @@ HTTP_read(RTMP *r, int fill)
- if (!ptr)
- return -1;
- ptr += 4;
-+ int resplen = r->m_sb.sb_size - (ptr - r->m_sb.sb_start);
-+ if (hlen < 4096)
-+ while (resplen < hlen)
-+ {
-+ if (RTMPSockBuf_Fill(&r->m_sb) == -1)
-+ return -1;
-+ resplen = r->m_sb.sb_size - (ptr - r->m_sb.sb_start);
-+ }
- r->m_sb.sb_size -= ptr - r->m_sb.sb_start;
- r->m_sb.sb_start = ptr;
- r->m_unackd--;
-@@ -4301,13 +4645,21 @@ fail:
- r->m_read.status = nRead;
- goto fail;
- }
-- /* buffer overflow, fix buffer and give up */
-- if (r->m_read.buf < mybuf || r->m_read.buf > end) {
-- mybuf = realloc(mybuf, cnt + nRead);
-- memcpy(mybuf+cnt, r->m_read.buf, nRead);
-- r->m_read.buf = mybuf+cnt+nRead;
-- break;
-- }
-+ /* buffer overflow, fix buffer and give up */
-+ if (r->m_read.buf < mybuf || r->m_read.buf > end)
-+ {
-+ if (!cnt)
-+ {
-+ mybuf = realloc(mybuf, sizeof (flvHeader) + cnt + nRead);
-+ memcpy(mybuf, flvHeader, sizeof (flvHeader));
-+ cnt += sizeof (flvHeader);
-+ }
-+ else
-+ mybuf = realloc(mybuf, cnt + nRead);
-+ memcpy(mybuf + cnt, r->m_read.buf, nRead);
-+ r->m_read.buf = mybuf + cnt + nRead;
-+ break;
-+ }
- cnt += nRead;
- r->m_read.buf += nRead;
- r->m_read.buflen -= nRead;
-@@ -4458,3 +4810,90 @@ RTMP_Write(RTMP *r, const char *buf, int size)
- }
- return size+s2;
- }
-+
-+static int
-+SendInvoke(RTMP *r, AVal *Command, int queue)
-+{
-+ RTMPPacket packet;
-+ char pbuf[512], *enc;
-+
-+ packet.m_nChannel = 0x03; /* control channel (invoke) */
-+ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
-+ packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
-+ packet.m_nTimeStamp = 0;
-+ packet.m_nInfoField2 = 0;
-+ packet.m_hasAbsTimestamp = 0;
-+ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
-+
-+ enc = packet.m_body;
-+ if (Command->av_len)
-+ {
-+ memcpy(enc, Command->av_val, Command->av_len);
-+ enc += Command->av_len;
-+ }
-+ else
-+ return FALSE;
-+ packet.m_nBodySize = enc - packet.m_body;
-+
-+ return RTMP_SendPacket(r, &packet, queue);
-+}
-+
-+static int
-+strsplit(char *src, int srclen, char delim, char ***params)
-+{
-+ char *sptr, *srcbeg, *srcend, *dstr;
-+ int count = 1, i = 0, len = 0;
-+
-+ if (src == NULL)
-+ return 0;
-+ if (!srclen)
-+ srclen = strlen(src);
-+ srcbeg = src;
-+ srcend = srcbeg + srclen;
-+ sptr = srcbeg;
-+
-+ /* count the delimiters */
-+ while (sptr < srcend)
-+ {
-+ if (*sptr++ == delim)
-+ count++;
-+ }
-+ sptr = srcbeg;
-+ *params = calloc(count, sizeof (size_t));
-+ char **param = *params;
-+
-+ for (i = 0; i < (count - 1); i++)
-+ {
-+ dstr = strchr(sptr, delim);
-+ len = dstr - sptr;
-+ param[i] = calloc(len + 1, sizeof (char));
-+ strncpy(param[i], sptr, len);
-+ sptr += len + 1;
-+ }
-+
-+ /* copy the last string */
-+ if (sptr <= srcend)
-+ {
-+ len = srclen - (sptr - srcbeg);
-+ param[i] = calloc(len + 1, sizeof (char));
-+ strncpy(param[i], sptr, len);
-+ }
-+ return count;
-+}
-+
-+static int
-+SendGetStreamLength(RTMP *r)
-+{
-+ char pbuf[256], *pend = pbuf + sizeof (pbuf), *enc;
-+ AVal av_Command;
-+
-+ enc = pbuf;
-+ enc = AMF_EncodeString(enc, pend, &av_getStreamLength);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, &r->Link.playpath);
-+ av_Command.av_val = pbuf;
-+ av_Command.av_len = enc - pbuf;
-+
-+ return SendInvoke(r, &av_Command, TRUE);
-+}
-diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
-index 6b2ae5b..411b488 100644
---- a/librtmp/rtmp.h
-+++ b/librtmp/rtmp.h
-@@ -150,12 +150,14 @@ extern "C"
- AVal playpath; /* passed in explicitly */
- AVal tcUrl;
- AVal swfUrl;
-+ AVal swfHash;
- AVal pageUrl;
- AVal app;
- AVal auth;
- AVal flashVer;
- AVal subscribepath;
- AVal usherToken;
-+ AVal WeebToken;
- AVal token;
- AMFObject extras;
- int edepth;
-@@ -172,9 +174,15 @@ extern "C"
- int lFlags;
-
- int swfAge;
-+ int swfSize;
-
- int protocol;
-+ int ConnectPacket;
-+ int CombineConnectPacket;
-+ int redirected;
- int timeout; /* connection timeout in seconds */
-+ AVal Extras;
-+ AVal HandshakeResponse;
-
- unsigned short socksport;
- unsigned short port;
-@@ -299,6 +307,7 @@ extern "C"
- AVal *flashVer,
- AVal *subscribepath,
- AVal *usherToken,
-+ AVal *WeebToken,
- int dStart,
- int dStop, int bLiveStream, long int timeout);
-
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index c3fd4a6..1bfb562 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -64,6 +64,7 @@
- #include <polarssl/net.h>
- #include <polarssl/ssl.h>
- #include <polarssl/havege.h>
-+#include <polarssl/md5.h>
- typedef struct tls_ctx {
- havege_state hs;
- ssl_session ssn;
-@@ -71,7 +72,7 @@ typedef struct tls_ctx {
- #define TLS_CTX tls_ctx *
- #define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
- ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\
-- ssl_set_rng(s, havege_rand, &ctx->hs);\
-+ ssl_set_rng(s, havege_random, &ctx->hs);\
- ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
- ssl_set_session(s, 1, 600, &ctx->ssn)
- #define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
-@@ -80,6 +81,7 @@ typedef struct tls_ctx {
- #define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l)
- #define TLS_shutdown(s) ssl_close_notify(s)
- #define TLS_close(s) ssl_free(s); free(s)
-+#define md5_hash(i, ilen, o) md5(i, ilen, o)
-
- #elif defined(USE_GNUTLS)
- #include <gnutls/gnutls.h>
-@@ -95,6 +97,8 @@ typedef struct tls_ctx {
- #define TLS_write(s,b,l) gnutls_record_send(s,b,l)
- #define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR)
- #define TLS_close(s) gnutls_deinit(s)
-+#define md5_hash(i, ilen, o) gnutls_digest_algorithm_t algorithm = GNUTLS_DIG_MD5;\
-+ gnutls_hash_fast(algorithm, i, ilen, o);
-
- #else /* USE_OPENSSL */
- #define TLS_CTX SSL_CTX *
-@@ -105,6 +109,7 @@ typedef struct tls_ctx {
- #define TLS_write(s,b,l) SSL_write(s,b,l)
- #define TLS_shutdown(s) SSL_shutdown(s)
- #define TLS_close(s) SSL_free(s)
-+#define md5_hash(i, ilen, o) MD5(i, ilen, o)
-
- #endif
- #endif
-diff --git a/rtmpdump.c b/rtmpdump.c
-index e52f7d4..7bb0890 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -701,6 +701,8 @@ void usage(char *prog)
- RTMP_LogPrintf
- ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
- RTMP_LogPrintf
-+ ("--weeb|-J string Authentication token for weeb.tv servers\n");
-+ RTMP_LogPrintf
- ("--hashes|-# Display progress with hashes, not with the byte counter\n");
- RTMP_LogPrintf
- ("--buffer|-b Buffer time in milliseconds (default: %u)\n",
-@@ -747,7 +749,8 @@ main(int argc, char **argv)
- AVal hostname = { 0, 0 };
- AVal playpath = { 0, 0 };
- AVal subscribepath = { 0, 0 };
-- AVal usherToken = { 0, 0 }; //Justin.tv auth token
-+ AVal usherToken = { 0, 0 }; // Justin.tv auth token
-+ AVal WeebToken = { 0, 0 }; // Weeb.tv auth token
- int port = -1;
- int protocol = RTMP_PROTOCOL_UNDEFINED;
- int retries = 0;
-@@ -852,12 +855,13 @@ main(int argc, char **argv)
- {"quiet", 0, NULL, 'q'},
- {"verbose", 0, NULL, 'V'},
- {"jtv", 1, NULL, 'j'},
-+ {"weeb", 1, NULL, 'J'},
- {0, 0, 0, 0}
- };
-
- while ((opt =
- getopt_long(argc, argv,
-- "hVveqzRr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
-+ "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:J:",
- longopts, NULL)) != -1)
- {
- switch (opt)
-@@ -1070,6 +1074,9 @@ main(int argc, char **argv)
- case 'j':
- STR2AVAL(usherToken, optarg);
- break;
-+ case 'J':
-+ STR2AVAL(WeebToken, optarg);
-+ break;
- default:
- RTMP_LogPrintf("unknown option: %c\n", opt);
- usage(argv[0]);
-@@ -1161,14 +1168,14 @@ main(int argc, char **argv)
-
- if (tcUrl.av_len == 0)
- {
-- tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) +
-- hostname.av_len + app.av_len + sizeof("://:65535/");
-+ tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) +
-+ hostname.av_len + app.av_len + sizeof ("://:65535/");
- tcUrl.av_val = (char *) malloc(tcUrl.av_len);
-- if (!tcUrl.av_val)
-- return RD_FAILED;
-+ if (!tcUrl.av_val)
-+ return RD_FAILED;
- tcUrl.av_len = snprintf(tcUrl.av_val, tcUrl.av_len, "%s://%.*s:%d/%.*s",
-- RTMPProtocolStringsLower[protocol], hostname.av_len,
-- hostname.av_val, port, app.av_len, app.av_val);
-+ RTMPProtocolStringsLower[protocol], hostname.av_len,
-+ hostname.av_val, port, app.av_len, app.av_val);
- }
-
- int first = 1;
-@@ -1187,7 +1194,7 @@ main(int argc, char **argv)
-
- RTMP_SetupStream(&rtmp, protocol, &hostname, port, &sockshost, &playpath,
- &tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize,
-- &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout);
-+ &flashVer, &subscribepath, &usherToken, &WeebToken, dSeek, dStopOffset, bLiveStream, timeout);
-
- /* Try to keep the stream moving if it pauses on us */
- if (!bLiveStream && !bRealtimeStream && !(protocol & RTMP_FEATURE_HTTP))
-diff --git a/rtmpgw.c b/rtmpgw.c
-index 0cf56bb..cd4396d 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -95,7 +95,8 @@ typedef struct
- AVal flashVer;
- AVal token;
- AVal subscribepath;
-- AVal usherToken; //Justin.tv auth token
-+ AVal usherToken; // Justin.tv auth token
-+ AVal WeebToken; // Weeb.tv auth token
- AVal sockshost;
- AMFObject extras;
- int edepth;
-@@ -553,7 +554,7 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- RTMP_Init(&rtmp);
- RTMP_SetBufferMS(&rtmp, req.bufferTime);
- RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost,
-- &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, dSeek, req.dStopOffset,
-+ &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, &req.WeebToken, dSeek, req.dStopOffset,
- req.bLiveStream, req.timeout);
- /* backward compatibility, we always sent this as true before */
- if (req.auth.av_len)
-@@ -957,6 +958,9 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
- case 'j':
- STR2AVAL(req->usherToken, arg);
- break;
-+ case 'J':
-+ STR2AVAL(req->WeebToken, arg);
-+ break;
- default:
- RTMP_LogPrintf("unknown option: %c, arg: %s\n", opt, arg);
- return FALSE;
-@@ -1028,6 +1032,7 @@ main(int argc, char **argv)
- {"quiet", 0, NULL, 'q'},
- {"verbose", 0, NULL, 'V'},
- {"jtv", 1, NULL, 'j'},
-+ {"weeb", 1, NULL, 'J'},
- {0, 0, 0, 0}
- };
-
-@@ -1040,7 +1045,7 @@ main(int argc, char **argv)
-
- while ((opt =
- getopt_long(argc, argv,
-- "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:", longopts,
-+ "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:J:", longopts,
- NULL)) != -1)
- {
- switch (opt)
-@@ -1103,6 +1108,8 @@ main(int argc, char **argv)
- RTMP_LogPrintf
- ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
- RTMP_LogPrintf
-+ ("--weeb|-J string Authentication token for weeb.tv servers\n");
-+ RTMP_LogPrintf
- ("--buffer|-b Buffer time in milliseconds (default: %u)\n\n",
- defaultRTMPRequest.bufferTime);
-
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index 9aa62f3..9ec8f23 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -96,9 +96,20 @@ STREAMING_SERVER *rtmpServer = 0; // server structure pointer
- STREAMING_SERVER *startStreaming(const char *address, int port);
- void stopStreaming(STREAMING_SERVER * server);
- void AVreplace(AVal *src, const AVal *orig, const AVal *repl);
-+char *strreplace(char *srcstr, int srclen, char *orig, char *repl);
-+int file_exists(const char *fname);
-+int SendCheckBWResponse(RTMP *r, int oldMethodType, int onBWDoneInit);
-+AVal AVcopy(AVal src);
-+AVal StripParams(AVal *src);
-
- static const AVal av_dquote = AVC("\"");
- static const AVal av_escdquote = AVC("\\\"");
-+#ifdef WIN32
-+static const AVal av_caret = AVC("^");
-+static const AVal av_esccaret = AVC("^^");
-+static const AVal av_pipe = AVC("|");
-+static const AVal av_escpipe = AVC("^|");
-+#endif
-
- typedef struct
- {
-@@ -167,6 +178,10 @@ SAVC(level);
- SAVC(code);
- SAVC(description);
- SAVC(secureToken);
-+SAVC(_checkbw);
-+SAVC(_onbwdone);
-+SAVC(checkBandwidth);
-+SAVC(onBWDone);
-
- static int
- SendConnectResult(RTMP *r, double txn)
-@@ -190,7 +205,7 @@ SendConnectResult(RTMP *r, double txn)
- enc = AMF_EncodeNumber(enc, pend, txn);
- *enc++ = AMF_OBJECT;
-
-- STR2AVAL(av, "FMS/3,5,1,525");
-+ STR2AVAL(av, "FMS/3,5,7,7009");
- enc = AMF_EncodeNamedString(enc, pend, &av_fmsVer, &av);
- enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 31.0);
- enc = AMF_EncodeNamedNumber(enc, pend, &av_mode, 1.0);
-@@ -212,7 +227,7 @@ SendConnectResult(RTMP *r, double txn)
- enc = AMF_EncodeNamedString(enc, pend, &av_secureToken, &av);
- #endif
- STR2AVAL(p.p_name, "version");
-- STR2AVAL(p.p_vu.p_aval, "3,5,1,525");
-+ STR2AVAL(p.p_vu.p_aval, "3,5,7,7009");
- p.p_type = AMF_STRING;
- obj.o_num = 1;
- obj.o_props = &p;
-@@ -268,7 +283,7 @@ static int
- SendPlayStart(RTMP *r)
- {
- RTMPPacket packet;
-- char pbuf[512], *pend = pbuf+sizeof(pbuf);
-+ char pbuf[1024], *pend = pbuf + sizeof (pbuf);
-
- packet.m_nChannel = 0x03; // control channel (invoke)
- packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */
-@@ -300,7 +315,7 @@ static int
- SendPlayStop(RTMP *r)
- {
- RTMPPacket packet;
-- char pbuf[512], *pend = pbuf+sizeof(pbuf);
-+ char pbuf[1024], *pend = pbuf + sizeof (pbuf);
-
- packet.m_nChannel = 0x03; // control channel (invoke)
- packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */
-@@ -328,6 +343,49 @@ SendPlayStop(RTMP *r)
- return RTMP_SendPacket(r, &packet, FALSE);
- }
-
-+int
-+SendCheckBWResponse(RTMP *r, int oldMethodType, int onBWDoneInit)
-+{
-+ RTMPPacket packet;
-+ char pbuf[256], *pend = pbuf + sizeof (pbuf);
-+ char *enc;
-+
-+ packet.m_nChannel = 0x03; /* control channel (invoke) */
-+ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
-+ packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
-+ packet.m_nTimeStamp = 0;
-+ packet.m_nInfoField2 = 0;
-+ packet.m_hasAbsTimestamp = 0;
-+ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
-+
-+ enc = packet.m_body;
-+ if (oldMethodType)
-+ {
-+ enc = AMF_EncodeString(enc, pend, &av__onbwdone);
-+ enc = AMF_EncodeNumber(enc, pend, 0);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeNumber(enc, pend, 10240);
-+ enc = AMF_EncodeNumber(enc, pend, 10240);
-+ }
-+ else
-+ {
-+ enc = AMF_EncodeString(enc, pend, &av_onBWDone);
-+ enc = AMF_EncodeNumber(enc, pend, 0);
-+ *enc++ = AMF_NULL;
-+ if (!onBWDoneInit)
-+ {
-+ enc = AMF_EncodeNumber(enc, pend, 10240);
-+ enc = AMF_EncodeNumber(enc, pend, 10240);
-+ enc = AMF_EncodeNumber(enc, pend, 0);
-+ enc = AMF_EncodeNumber(enc, pend, 0);
-+ }
-+ }
-+
-+ packet.m_nBodySize = enc - packet.m_body;
-+
-+ return RTMP_SendPacket(r, &packet, FALSE);
-+}
-+
- static void
- spawn_dumper(int argc, AVal *av, char *cmd)
- {
-@@ -568,6 +626,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- server->arglen += countAMF(&r->Link.extras, &server->argc);
- }
- SendConnectResult(r, txn);
-+ SendCheckBWResponse(r, FALSE, TRUE);
- }
- else if (AVMATCH(&method, &av_createStream))
- {
-@@ -582,10 +641,22 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- AVal usherToken;
- AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &usherToken);
- AVreplace(&usherToken, &av_dquote, &av_escdquote);
-+#ifdef WIN32
-+ AVreplace(&usherToken, &av_caret, &av_esccaret);
-+ AVreplace(&usherToken, &av_pipe, &av_escpipe);
-+#endif
- server->arglen += 6 + usherToken.av_len;
- server->argc += 2;
- r->Link.usherToken = usherToken;
- }
-+ else if (AVMATCH(&method, &av__checkbw))
-+ {
-+ SendCheckBWResponse(r, TRUE, FALSE);
-+ }
-+ else if (AVMATCH(&method, &av_checkBandwidth))
-+ {
-+ SendCheckBWResponse(r, FALSE, FALSE);
-+ }
- else if (AVMATCH(&method, &av_play))
- {
- char *file, *p, *q, *cmd, *ptr;
-@@ -599,6 +670,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- if (obj.o_num > 5)
- r->Link.length = AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 5));
- */
-+ double StartFlag = 0;
-+ AMFObjectProperty *Start = AMF_GetProp(&obj, NULL, 4);
-+ if (!(Start->p_type == AMF_INVALID))
-+ StartFlag = AMFProp_GetNumber(Start);
-+ r->Link.app = AVcopy(r->Link.app);
-+ if (StartFlag == -1000 || strstr(r->Link.app.av_val, "live"))
-+ {
-+ StartFlag = -1000;
-+ server->arglen += 7;
-+ server->argc += 1;
-+ }
- if (r->Link.tcUrl.av_len)
- {
- len = server->arglen + r->Link.playpath.av_len + 4 +
-@@ -616,6 +698,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- argv[argc].av_val = ptr + 1;
- argv[argc++].av_len = 2;
- argv[argc].av_val = ptr + 5;
-+ r->Link.tcUrl = StripParams(&r->Link.tcUrl);
- ptr += sprintf(ptr," -r \"%s\"", r->Link.tcUrl.av_val);
- argv[argc++].av_len = r->Link.tcUrl.av_len;
-
-@@ -640,6 +723,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- argv[argc].av_val = ptr + 1;
- argv[argc++].av_len = 2;
- argv[argc].av_val = ptr + 5;
-+ r->Link.swfUrl = StripParams(&r->Link.swfUrl);
- ptr += sprintf(ptr, " -W \"%s\"", r->Link.swfUrl.av_val);
- argv[argc++].av_len = r->Link.swfUrl.av_len;
- }
-@@ -662,10 +746,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- r->Link.usherToken.av_val = NULL;
- r->Link.usherToken.av_len = 0;
- }
-- if (r->Link.extras.o_num) {
-- ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc);
-- AMF_Reset(&r->Link.extras);
-- }
-+ if (StartFlag == -1000)
-+ {
-+ argv[argc].av_val = ptr + 1;
-+ argv[argc++].av_len = 6;
-+ ptr += sprintf(ptr, " --live");
-+ }
-+ if (r->Link.extras.o_num)
-+ {
-+ ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc);
-+ AMF_Reset(&r->Link.extras);
-+ }
- argv[argc].av_val = ptr + 1;
- argv[argc++].av_len = 2;
- argv[argc].av_val = ptr + 5;
-@@ -673,7 +764,13 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- r->Link.playpath.av_len, r->Link.playpath.av_val);
- argv[argc++].av_len = r->Link.playpath.av_len;
-
-- av = r->Link.playpath;
-+ if (r->Link.playpath.av_len)
-+ av = r->Link.playpath;
-+ else
-+ {
-+ av.av_val = "file";
-+ av.av_len = 4;
-+ }
- /* strip trailing URL parameters */
- q = memchr(av.av_val, '?', av.av_len);
- if (q)
-@@ -725,7 +822,30 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- argv[argc++].av_len = 2;
- argv[argc].av_val = file;
- argv[argc].av_len = av.av_len;
-- ptr += sprintf(ptr, " -o %s", file);
-+#ifdef VLC
-+ char *vlc;
-+ int didAlloc = FALSE;
-+
-+ if (getenv("VLC"))
-+ vlc = getenv("VLC");
-+ else if (getenv("ProgramFiles"))
-+ {
-+ vlc = malloc(512 * sizeof (char));
-+ didAlloc = TRUE;
-+ char *ProgramFiles = getenv("ProgramFiles");
-+ sprintf(vlc, "%s%s", ProgramFiles, " (x86)\\VideoLAN\\VLC\\vlc.exe");
-+ if (!file_exists(vlc))
-+ sprintf(vlc, "%s%s", ProgramFiles, "\\VideoLAN\\VLC\\vlc.exe");
-+ }
-+ else
-+ vlc = "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe";
-+
-+ ptr += sprintf(ptr, " | %s -", vlc);
-+ if (didAlloc)
-+ free(vlc);
-+#else
-+ ptr += sprintf(ptr, " -o %s", file);
-+#endif
- now = RTMP_GetTime();
- if (now - server->filetime < DUPTIME && AVMATCH(&argv[argc], &server->filename))
- {
-@@ -739,7 +859,23 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- server->filetime = now;
- free(server->filename.av_val);
- server->filename = argv[argc++];
-- spawn_dumper(argc, argv, cmd);
-+#ifdef VLC
-+ FILE *vlc_cmdfile = fopen("VLC.bat", "w");
-+ char *vlc_batchcmd = strreplace(cmd, 0, "%", "%%");
-+ fprintf(vlc_cmdfile, "%s\n", vlc_batchcmd);
-+ fclose(vlc_cmdfile);
-+ free(vlc_batchcmd);
-+ spawn_dumper(argc, argv, "VLC.bat");
-+#else
-+ spawn_dumper(argc, argv, cmd);
-+#endif
-+
-+#ifdef WIN32
-+ // Dump command to batch file
-+ FILE *cmdfile = fopen("Command.bat", "a");
-+ fprintf(cmdfile, "%s\n", cmd);
-+ fclose(cmdfile);
-+#endif
- }
-
- free(cmd);
-@@ -1178,3 +1314,115 @@ AVreplace(AVal *src, const AVal *orig, const AVal *repl)
- src->av_val = dest;
- src->av_len = dptr - dest;
- }
-+
-+char *
-+strreplace(char *srcstr, int srclen, char *orig, char *repl)
-+{
-+ char *ptr = NULL, *sptr = srcstr;
-+ int origlen = strlen(orig);
-+ int repllen = strlen(repl);
-+ if (!srclen)
-+ srclen = strlen(srcstr);
-+ char *srcend = srcstr + srclen;
-+ int dstbuffer = srclen / origlen * repllen;
-+ if (dstbuffer < srclen)
-+ dstbuffer = srclen;
-+ char *dststr = calloc(dstbuffer + 1, sizeof (char));
-+ char *dptr = dststr;
-+
-+ if ((ptr = strstr(srcstr, orig)))
-+ {
-+ while (ptr < srcend && (ptr = strstr(sptr, orig)))
-+ {
-+ int len = ptr - sptr;
-+ memcpy(dptr, sptr, len);
-+ sptr += len + origlen;
-+ dptr += len;
-+ memcpy(dptr, repl, repllen);
-+ dptr += repllen;
-+ }
-+ memcpy(dptr, sptr, srcend - sptr);
-+ return dststr;
-+ }
-+
-+ memcpy(dststr, srcstr, srclen);
-+ return dststr;
-+}
-+
-+AVal
-+StripParams(AVal *src)
-+{
-+ AVal str;
-+ if (src->av_val)
-+ {
-+ str.av_val = calloc(src->av_len + 1, sizeof (char));
-+ strncpy(str.av_val, src->av_val, src->av_len);
-+ str.av_len = src->av_len;
-+ char *start = str.av_val;
-+ char *end = start + str.av_len;
-+ char *ptr = start;
-+
-+ while (ptr < end)
-+ {
-+ if (*ptr == '?')
-+ {
-+ str.av_len = ptr - start;
-+ break;
-+ }
-+ ptr++;
-+ }
-+ memset(start + str.av_len, 0, 1);
-+
-+ char *dynamic = strstr(start, "[[DYNAMIC]]");
-+ if (dynamic)
-+ {
-+ dynamic -= 1;
-+ memset(dynamic, 0, 1);
-+ str.av_len = dynamic - start;
-+ end = start + str.av_len;
-+ }
-+
-+ char *import = strstr(start, "[[IMPORT]]");
-+ if (import)
-+ {
-+ str.av_val = import + 11;
-+ strcpy(start, "http://");
-+ str.av_val = strcat(start, str.av_val);
-+ str.av_len = strlen(str.av_val);
-+ }
-+ return str;
-+ }
-+ str = *src;
-+ return str;
-+}
-+
-+int
-+file_exists(const char *fname)
-+{
-+ FILE *file;
-+ if ((file = fopen(fname, "r")))
-+ {
-+ fclose(file);
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+AVal
-+AVcopy(AVal src)
-+{
-+ AVal dst;
-+ if (src.av_len)
-+ {
-+ dst.av_val = malloc(src.av_len + 1);
-+ memcpy(dst.av_val, src.av_val, src.av_len);
-+ dst.av_val[src.av_len] = '\0';
-+ dst.av_len = src.av_len;
-+ }
-+ else
-+ {
-+ dst.av_val = NULL;
-+ dst.av_len = 0;
-+ }
-+ return dst;
-+}
-diff --git a/rtmpsuck.c b/rtmpsuck.c
-index e886179..e80c686 100644
---- a/rtmpsuck.c
-+++ b/rtmpsuck.c
-@@ -143,15 +143,18 @@ SAVC(onStatus);
- SAVC(close);
- static const AVal av_NetStream_Failed = AVC("NetStream.Failed");
- static const AVal av_NetStream_Play_Failed = AVC("NetStream.Play.Failed");
--static const AVal av_NetStream_Play_StreamNotFound =
--AVC("NetStream.Play.StreamNotFound");
--static const AVal av_NetConnection_Connect_InvalidApp =
--AVC("NetConnection.Connect.InvalidApp");
-+static const AVal av_NetStream_Play_StreamNotFound = AVC("NetStream.Play.StreamNotFound");
-+static const AVal av_NetConnection_Connect_InvalidApp = AVC("NetConnection.Connect.InvalidApp");
- static const AVal av_NetStream_Play_Start = AVC("NetStream.Play.Start");
- static const AVal av_NetStream_Play_Complete = AVC("NetStream.Play.Complete");
- static const AVal av_NetStream_Play_Stop = AVC("NetStream.Play.Stop");
-+static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken");
-
- static const char *cst[] = { "client", "server" };
-+char *dumpAMF(AMFObject *obj, char *ptr);
-+char *strreplace(char *srcstr, int srclen, char *orig, char *repl);
-+AVal AVcopy(AVal src);
-+AVal StripParams(AVal *src);
-
- // Returns 0 for OK/Failed/error, 1 for 'Stop or Complete'
- int
-@@ -198,26 +201,28 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- if (cobj.o_props[i].p_type == AMF_STRING)
- {
- pval = cobj.o_props[i].p_vu.p_aval;
-- RTMP_LogPrintf("%.*s: %.*s\n", pname.av_len, pname.av_val, pval.av_len, pval.av_val);
-+ RTMP_LogPrintf("%10.*s : %.*s\n", pname.av_len, pname.av_val, pval.av_len, pval.av_val);
- }
- if (AVMATCH(&pname, &av_app))
- {
-- server->rc.Link.app = pval;
-+ server->rc.Link.app = AVcopy(pval);
- pval.av_val = NULL;
- }
- else if (AVMATCH(&pname, &av_flashVer))
- {
-- server->rc.Link.flashVer = pval;
-+ server->rc.Link.flashVer = AVcopy(pval);
- pval.av_val = NULL;
- }
- else if (AVMATCH(&pname, &av_swfUrl))
- {
- #ifdef CRYPTO
- if (pval.av_val)
-- RTMP_HashSWF(pval.av_val, &server->rc.Link.SWFSize,
-- (unsigned char *)server->rc.Link.SWFHash, 30);
-+ {
-+ AVal swfUrl = StripParams(&pval);
-+ RTMP_HashSWF(swfUrl.av_val, &server->rc.Link.SWFSize, (unsigned char *) server->rc.Link.SWFHash, 30);
-+ }
- #endif
-- server->rc.Link.swfUrl = pval;
-+ server->rc.Link.swfUrl = AVcopy(pval);
- pval.av_val = NULL;
- }
- else if (AVMATCH(&pname, &av_tcUrl))
-@@ -225,7 +230,7 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- char *r1 = NULL, *r2;
- int len;
-
-- server->rc.Link.tcUrl = pval;
-+ server->rc.Link.tcUrl = AVcopy(pval);
- if ((pval.av_val[0] | 0x40) == 'r' &&
- (pval.av_val[1] | 0x40) == 't' &&
- (pval.av_val[2] | 0x40) == 'm' &&
-@@ -267,7 +272,7 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- }
- else if (AVMATCH(&pname, &av_pageUrl))
- {
-- server->rc.Link.pageUrl = pval;
-+ server->rc.Link.pageUrl = AVcopy(pval);
- pval.av_val = NULL;
- }
- else if (AVMATCH(&pname, &av_audioCodecs))
-@@ -287,14 +292,21 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- if (pval.av_val)
- free(pval.av_val);
- }
-+
- if (obj.o_num > 3)
- {
-- if (AMFProp_GetBoolean(&obj.o_props[3]))
-- server->rc.Link.lFlags |= RTMP_LF_AUTH;
-- if (obj.o_num > 4)
-- {
-- AMFProp_GetString(&obj.o_props[4], &server->rc.Link.auth);
-- }
-+ int i = obj.o_num - 3;
-+ server->rc.Link.extras.o_num = i;
-+ server->rc.Link.extras.o_props = malloc(i * sizeof (AMFObjectProperty));
-+ memcpy(server->rc.Link.extras.o_props, obj.o_props + 3, i * sizeof (AMFObjectProperty));
-+ obj.o_num = 3;
-+ }
-+
-+ if (server->rc.Link.extras.o_num)
-+ {
-+ server->rc.Link.Extras.av_val = calloc(1024, sizeof (char));
-+ dumpAMF(&server->rc.Link.extras, server->rc.Link.Extras.av_val);
-+ server->rc.Link.Extras.av_len = strlen(server->rc.Link.Extras.av_val);
- }
-
- if (!RTMP_Connect(&server->rc, pack))
-@@ -303,6 +315,16 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- return 1;
- }
- server->rc.m_bSendCounter = FALSE;
-+
-+ if (server->rc.Link.extras.o_props)
-+ {
-+ AMF_Reset(&server->rc.Link.extras);
-+ }
-+ }
-+ else if (AVMATCH(&method, &av_NetStream_Authenticate_UsherToken))
-+ {
-+ AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &server->rc.Link.usherToken);
-+ RTMP_LogPrintf("%10s : %.*s\n", "usherToken", server->rc.Link.usherToken.av_len, server->rc.Link.usherToken.av_val);
- }
- else if (AVMATCH(&method, &av_play))
- {
-@@ -323,6 +345,14 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- if (!av.av_val)
- goto out;
-
-+ double StartFlag = 0;
-+ AMFObjectProperty *Start = AMF_GetProp(&obj, NULL, 4);
-+ if (!(Start->p_type == AMF_INVALID))
-+ StartFlag = AMFProp_GetNumber(Start);
-+ if (StartFlag == -1000 || strstr(server->rc.Link.app.av_val, "live"))
-+ StartFlag = -1000;
-+ RTMP_LogPrintf("%10s : %s\n", "live", (StartFlag == -1000) ? "yes" : "no");
-+
- /* check for duplicates */
- for (fl = server->f_head; fl; fl=fl->f_next)
- {
-@@ -372,9 +402,51 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b
- for (p=file; *p; p++)
- if (*p == ':')
- *p = '_';
-- RTMP_LogPrintf("Playpath: %.*s\nSaving as: %s\n",
-- server->rc.Link.playpath.av_len, server->rc.Link.playpath.av_val,
-- file);
-+ RTMP_LogPrintf("%10s : %.*s\n%10s : %s\n", "Playpath", server->rc.Link.playpath.av_len,
-+ server->rc.Link.playpath.av_val, "Saving as", file);
-+
-+#ifdef WIN32
-+ // Dump command to batch file
-+ char *cmd = NULL, *ptr = NULL;
-+ AVal swfUrl, tcUrl;
-+
-+ cmd = calloc(2048, sizeof (char));
-+ ptr = cmd;
-+ tcUrl = StripParams(&server->rc.Link.tcUrl);
-+ swfUrl = StripParams(&server->rc.Link.swfUrl);
-+ ptr += sprintf(ptr, "rtmpdump -r \"%.*s\" -a \"%.*s\" -f \"%.*s\" -W \"%.*s\" -p \"%.*s\"",
-+ tcUrl.av_len, tcUrl.av_val,
-+ server->rc.Link.app.av_len, server->rc.Link.app.av_val,
-+ server->rc.Link.flashVer.av_len, server->rc.Link.flashVer.av_val,
-+ swfUrl.av_len, swfUrl.av_val,
-+ server->rc.Link.pageUrl.av_len, server->rc.Link.pageUrl.av_val);
-+
-+ if (server->rc.Link.usherToken.av_val)
-+ {
-+ char *usherToken = strreplace(server->rc.Link.usherToken.av_val, server->rc.Link.usherToken.av_len, "\"", "\\\"");
-+ usherToken = strreplace(usherToken, 0, "^", "^^");
-+ usherToken = strreplace(usherToken, 0, "|", "^|");
-+ ptr += sprintf(ptr, " --jtv \"%s\"", usherToken);
-+ free(usherToken);
-+ }
-+
-+ if (server->rc.Link.Extras.av_len)
-+ {
-+ ptr += sprintf(ptr, "%.*s", server->rc.Link.Extras.av_len, server->rc.Link.Extras.av_val);
-+ }
-+
-+ if (StartFlag == -1000)
-+ ptr += sprintf(ptr, "%s", " --live");
-+ ptr += sprintf(ptr, " -y \"%.*s\"", server->rc.Link.playpath.av_len, server->rc.Link.playpath.av_val);
-+ ptr += sprintf(ptr, " -o \"%s.flv\"\n", file);
-+
-+ FILE *cmdfile = fopen("Command.bat", "a");
-+ fprintf(cmdfile, "%s", cmd);
-+ fclose(cmdfile);
-+
-+ free(cmd);
-+#endif
-+
- out = fopen(file, "wb");
- free(file);
- if (!out)
-@@ -1196,3 +1268,146 @@ main(int argc, char **argv)
- #endif
- return nStatus;
- }
-+
-+char *
-+dumpAMF(AMFObject *obj, char *ptr)
-+{
-+ int i;
-+ const char opt[] = "NBSO Z";
-+
-+ for (i = 0; i < obj->o_num; i++)
-+ {
-+ AMFObjectProperty *p = &obj->o_props[i];
-+ if (p->p_type > 5)
-+ continue;
-+ ptr += sprintf(ptr, " -C ");
-+ if (p->p_name.av_val)
-+ *ptr++ = 'N';
-+ *ptr++ = opt[p->p_type];
-+ *ptr++ = ':';
-+ if (p->p_name.av_val)
-+ ptr += sprintf(ptr, "%.*s:", p->p_name.av_len, p->p_name.av_val);
-+ switch (p->p_type)
-+ {
-+ case AMF_BOOLEAN:
-+ *ptr++ = p->p_vu.p_number != 0 ? '1' : '0';
-+ break;
-+ case AMF_STRING:
-+ memcpy(ptr, p->p_vu.p_aval.av_val, p->p_vu.p_aval.av_len);
-+ ptr += p->p_vu.p_aval.av_len;
-+ break;
-+ case AMF_NUMBER:
-+ ptr += sprintf(ptr, "%f", p->p_vu.p_number);
-+ break;
-+ case AMF_OBJECT:
-+ *ptr++ = '1';
-+ ptr = dumpAMF(&p->p_vu.p_object, ptr);
-+ ptr += sprintf(ptr, " -C O:0");
-+ break;
-+ case AMF_NULL:
-+ default:
-+ break;
-+ }
-+ }
-+ return ptr;
-+}
-+
-+char *
-+strreplace(char *srcstr, int srclen, char *orig, char *repl)
-+{
-+ char *ptr = NULL, *sptr = srcstr;
-+ int origlen = strlen(orig);
-+ int repllen = strlen(repl);
-+ if (!srclen)
-+ srclen = strlen(srcstr);
-+ char *srcend = srcstr + srclen;
-+ int dstbuffer = srclen / origlen * repllen;
-+ if (dstbuffer < srclen)
-+ dstbuffer = srclen;
-+ char *dststr = calloc(dstbuffer + 1, sizeof (char));
-+ char *dptr = dststr;
-+
-+ if ((ptr = strstr(srcstr, orig)))
-+ {
-+ while (ptr < srcend && (ptr = strstr(sptr, orig)))
-+ {
-+ int len = ptr - sptr;
-+ memcpy(dptr, sptr, len);
-+ sptr += len + origlen;
-+ dptr += len;
-+ memcpy(dptr, repl, repllen);
-+ dptr += repllen;
-+ }
-+ memcpy(dptr, sptr, srcend - sptr);
-+ return dststr;
-+ }
-+
-+ memcpy(dststr, srcstr, srclen);
-+ return dststr;
-+}
-+
-+AVal
-+StripParams(AVal *src)
-+{
-+ AVal str;
-+ if (src->av_val)
-+ {
-+ str.av_val = calloc(src->av_len + 1, sizeof (char));
-+ strncpy(str.av_val, src->av_val, src->av_len);
-+ str.av_len = src->av_len;
-+ char *start = str.av_val;
-+ char *end = start + str.av_len;
-+ char *ptr = start;
-+
-+ while (ptr < end)
-+ {
-+ if (*ptr == '?')
-+ {
-+ str.av_len = ptr - start;
-+ break;
-+ }
-+ ptr++;
-+ }
-+ memset(start + str.av_len, 0, 1);
-+
-+ char *dynamic = strstr(start, "[[DYNAMIC]]");
-+ if (dynamic)
-+ {
-+ dynamic -= 1;
-+ memset(dynamic, 0, 1);
-+ str.av_len = dynamic - start;
-+ end = start + str.av_len;
-+ }
-+
-+ char *import = strstr(start, "[[IMPORT]]");
-+ if (import)
-+ {
-+ str.av_val = import + 11;
-+ strcpy(start, "http://");
-+ str.av_val = strcat(start, str.av_val);
-+ str.av_len = strlen(str.av_val);
-+ }
-+ return str;
-+ }
-+ str = *src;
-+ return str;
-+}
-+
-+AVal
-+AVcopy(AVal src)
-+{
-+ AVal dst;
-+ if (src.av_len)
-+ {
-+ dst.av_val = malloc(src.av_len + 1);
-+ memcpy(dst.av_val, src.av_val, src.av_len);
-+ dst.av_val[src.av_len] = '\0';
-+ dst.av_len = src.av_len;
-+ }
-+ else
-+ {
-+ dst.av_val = NULL;
-+ dst.av_len = 0;
-+ }
-+ return dst;
-+}
diff --git a/tools/depends/target/librtmp/prefix.patch b/tools/depends/target/librtmp/prefix.patch
index 198a85cf79..381797217e 100644
--- a/tools/depends/target/librtmp/prefix.patch
+++ b/tools/depends/target/librtmp/prefix.patch
@@ -1,7 +1,7 @@
--- librtmp/Makefile 2010-06-30 15:58:35.000000000 -0400
+++ librtmp/Makefile.2 2011-03-31 16:19:52.813884882 -0400
@@ -1,6 +1,6 @@
- VERSION=v2.3
+ VERSION=v2.4
-prefix=/usr/local
+prefix=$(PREFIX)
diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp
index bb98d3e723..1619de4ee2 100644
--- a/xbmc/Autorun.cpp
+++ b/xbmc/Autorun.cpp
@@ -106,10 +106,8 @@ bool CAutorun::PlayDisc(const std::string& path, bool bypassSettings, bool start
if (mediaPath.empty())
mediaPath = path;
-#ifdef TARGET_WINDOWS
if (mediaPath.empty() || mediaPath == "iso9660://")
- mediaPath = g_mediaManager.TranslateDevicePath("");
-#endif
+ mediaPath = g_mediaManager.GetDiscPath();
const CURL pathToUrl(mediaPath);
auto_ptr<IDirectory> pDir ( CDirectoryFactory::Create( pathToUrl ));
diff --git a/xbmc/LangInfo.cpp b/xbmc/LangInfo.cpp
index 26a6834b80..5831d8d729 100644
--- a/xbmc/LangInfo.cpp
+++ b/xbmc/LangInfo.cpp
@@ -53,6 +53,7 @@ CLangInfo::CRegion::CRegion(const CRegion& region):
m_strLangLocaleName(region.m_strLangLocaleName),
m_strLangLocaleCodeTwoChar(region.m_strLangLocaleCodeTwoChar),
m_strRegionLocaleName(region.m_strRegionLocaleName),
+ m_forceUnicodeFont(region.m_forceUnicodeFont),
m_strName(region.m_strName),
m_strDateFormatLong(region.m_strDateFormatLong),
m_strDateFormatShort(region.m_strDateFormatShort),
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
index b58a4ed917..8a12a6b9a3 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -811,7 +811,7 @@ int CDVDPlayerVideo::GetLevel() const
int datasize = m_messageQueue.GetDataSize();
if (m_pVideoCodec)
datasize += m_pVideoCodec->GetDataSize();
- return min(100, (int)(100 * datasize / (m_messageQueue.GetMaxDataSize() * m_messageQueue.GetMaxTimeSize())));
+ return min(100, MathUtils::round_int((100.0 * datasize) / m_messageQueue.GetMaxDataSize()));
}
else
{
diff --git a/xbmc/guilib/GUITextBox.cpp b/xbmc/guilib/GUITextBox.cpp
index b8a2be4458..cab7bf812e 100644
--- a/xbmc/guilib/GUITextBox.cpp
+++ b/xbmc/guilib/GUITextBox.cpp
@@ -227,7 +227,7 @@ void CGUITextBox::Render()
uint32_t align = m_label.align;
if (m_lines[current].m_text.size() && m_lines[current].m_carriageReturn)
align &= ~XBFONT_JUSTIFIED; // last line of a paragraph shouldn't be justified
- m_font->DrawText(posX, posY + 2, m_colors, m_label.shadowColor, m_lines[current].m_text, align, m_width);
+ m_font->DrawText(posX, posY, m_colors, m_label.shadowColor, m_lines[current].m_text, align, m_width);
posY += m_itemHeight;
current++;
}
diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp
index 5c584efc20..c1465e3f6f 100644
--- a/xbmc/pvr/PVRDatabase.cpp
+++ b/xbmc/pvr/PVRDatabase.cpp
@@ -260,7 +260,6 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results)
channel->m_bIsLocked = m_pDS->fv("bIsLocked").get_asBool();
channel->m_strIconPath = m_pDS->fv("sIconPath").get_asString();
channel->m_strChannelName = m_pDS->fv("sChannelName").get_asString();
- channel->m_bIsVirtual = m_pDS->fv("bIsVirtual").get_asBool();
channel->m_bEPGEnabled = m_pDS->fv("bEPGEnabled").get_asBool();
channel->m_strEPGScraper = m_pDS->fv("sEPGScraper").get_asString();
channel->m_iLastWatched = (time_t) m_pDS->fv("iLastWatched").get_asInt();
@@ -744,7 +743,7 @@ bool CPVRDatabase::Persist(CPVRChannel &channel)
"iClientChannelNumber, iClientSubChannelNumber, sInputFormat, sStreamURL, iEncryptionSystem, idEpg) "
"VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, '%s', '%s', %i, %i)",
channel.UniqueID(), (channel.IsRadio() ? 1 :0), (channel.IsHidden() ? 1 : 0), (channel.IsUserSetIcon() ? 1 : 0), (channel.IsUserSetName() ? 1 : 0), (channel.IsLocked() ? 1 : 0),
- channel.IconPath().c_str(), channel.ChannelName().c_str(), (channel.IsVirtual() ? 1 : 0), (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(),
+ channel.IconPath().c_str(), channel.ChannelName().c_str(), 0, (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(),
channel.ClientChannelNumber(), channel.ClientSubChannelNumber(), channel.InputFormat().c_str(), channel.StreamURL().c_str(), channel.EncryptionSystem(),
channel.EpgID());
}
@@ -757,7 +756,7 @@ bool CPVRDatabase::Persist(CPVRChannel &channel)
"iClientChannelNumber, iClientSubChannelNumber, sInputFormat, sStreamURL, iEncryptionSystem, idChannel, idEpg) "
"VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, '%s', '%s', %i, %i, %i)",
channel.UniqueID(), (channel.IsRadio() ? 1 :0), (channel.IsHidden() ? 1 : 0), (channel.IsUserSetIcon() ? 1 : 0), (channel.IsUserSetName() ? 1 : 0), (channel.IsLocked() ? 1 : 0),
- channel.IconPath().c_str(), channel.ChannelName().c_str(), (channel.IsVirtual() ? 1 : 0), (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(),
+ channel.IconPath().c_str(), channel.ChannelName().c_str(), 0, (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(),
channel.ClientChannelNumber(), channel.ClientSubChannelNumber(), channel.InputFormat().c_str(), channel.StreamURL().c_str(), channel.EncryptionSystem(), channel.ChannelID(),
channel.EpgID());
}
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index 483f137bea..06ff5b0b90 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -142,7 +142,7 @@ void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
ADDON_STATUS CPVRClient::Create(int iClientId)
{
ADDON_STATUS status(ADDON_STATUS_UNKNOWN);
- if (iClientId <= PVR_INVALID_CLIENT_ID || iClientId == PVR_VIRTUAL_CLIENT_ID)
+ if (iClientId <= PVR_INVALID_CLIENT_ID)
return status;
/* ensure that a previous instance is destroyed */
diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h
index a94a150cdd..60f37a7ee1 100644
--- a/xbmc/pvr/addons/PVRClient.h
+++ b/xbmc/pvr/addons/PVRClient.h
@@ -44,7 +44,6 @@ namespace PVR
typedef std::vector<PVR_MENUHOOK> PVR_MENUHOOKS;
typedef boost::shared_ptr<CPVRClient> PVR_CLIENT;
#define PVR_INVALID_CLIENT_ID (-2)
- #define PVR_VIRTUAL_CLIENT_ID (-1)
/*!
* Interface from XBMC to a PVR add-on.
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index c6dd7cf869..e87b5a3ca7 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -110,7 +110,7 @@ int CPVRClients::GetClientId(const AddonPtr client) const
bool CPVRClients::GetClient(int iClientId, PVR_CLIENT &addon) const
{
bool bReturn(false);
- if (iClientId <= PVR_INVALID_CLIENT_ID || iClientId == PVR_VIRTUAL_CLIENT_ID)
+ if (iClientId <= PVR_INVALID_CLIENT_ID)
return bReturn;
CSingleLock lock(m_critSection);
@@ -1182,9 +1182,7 @@ bool CPVRClients::OpenStream(const CPVRChannel &tag, bool bIsSwitchingChannel)
m_playingClientId = tag.ClientID();
m_bIsPlayingLiveTV = true;
- if (tag.ClientID() == PVR_VIRTUAL_CLIENT_ID)
- m_strPlayingClientName = g_localizeStrings.Get(19209);
- else if (!tag.IsVirtual() && client.get())
+ if (client.get())
m_strPlayingClientName = client->GetFriendlyName();
else
m_strPlayingClientName = g_localizeStrings.Get(13205);
diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp
index e8c2cd36cd..2e60f9b353 100644
--- a/xbmc/pvr/channels/PVRChannel.cpp
+++ b/xbmc/pvr/channels/PVRChannel.cpp
@@ -56,7 +56,6 @@ CPVRChannel::CPVRChannel(bool bRadio /* = false */)
m_bIsUserSetIcon = false;
m_bIsUserSetName = false;
m_bIsLocked = false;
- m_bIsVirtual = false;
m_iLastWatched = 0;
m_bChanged = false;
m_iCachedChannelNumber = 0;
@@ -95,7 +94,6 @@ CPVRChannel::CPVRChannel(const PVR_CHANNEL &channel, unsigned int iClientId)
m_iCachedChannelNumber = 0;
m_iCachedSubChannelNumber = 0;
m_iClientId = iClientId;
- m_bIsVirtual = false;
m_iLastWatched = 0;
m_bEPGEnabled = !channel.bIsHidden;
m_strEPGScraper = "client";
@@ -124,7 +122,6 @@ CPVRChannel &CPVRChannel::operator=(const CPVRChannel &channel)
m_bIsLocked = channel.m_bIsLocked;
m_strIconPath = channel.m_strIconPath;
m_strChannelName = channel.m_strChannelName;
- m_bIsVirtual = channel.m_bIsVirtual;
m_iLastWatched = channel.m_iLastWatched;
m_bEPGEnabled = channel.m_bEPGEnabled;
m_strEPGScraper = channel.m_strEPGScraper;
@@ -380,23 +377,6 @@ bool CPVRChannel::SetChannelName(const std::string &strChannelName, bool bIsUser
return false;
}
-bool CPVRChannel::SetVirtual(bool bIsVirtual)
-{
- CSingleLock lock(m_critSection);
-
- if (m_bIsVirtual != bIsVirtual)
- {
- /* update the virtual flag */
- m_bIsVirtual = bIsVirtual;
- SetChanged();
- m_bChanged = true;
-
- return true;
- }
-
- return false;
-}
-
bool CPVRChannel::SetLastWatched(time_t iLastWatched)
{
{
@@ -771,12 +751,6 @@ std::string CPVRChannel::ChannelName(void) const
return m_strChannelName;
}
-bool CPVRChannel::IsVirtual(void) const
-{
- CSingleLock lock(m_critSection);
- return m_bIsVirtual;
-}
-
time_t CPVRChannel::LastWatched(void) const
{
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h
index c0c90991e3..2ea41ed9be 100644
--- a/xbmc/pvr/channels/PVRChannel.h
+++ b/xbmc/pvr/channels/PVRChannel.h
@@ -29,6 +29,8 @@
#include <boost/shared_ptr.hpp>
+#define PVR_INVALID_CHANNEL_UID -1
+
namespace EPG
{
class CEpg;
@@ -216,18 +218,6 @@ namespace PVR
bool SetChannelName(const std::string &strChannelName, bool bIsUserSetName = false);
/*!
- * @return True if this channel is marked as virtual. False if not.
- */
- bool IsVirtual(void) const;
-
- /*!
- * @brief True if this channel is marked as virtual. False if not.
- * @param bIsVirtual The new value.
- * @return True if the something changed, false otherwise.
- */
- bool SetVirtual(bool bIsVirtual);
-
- /*!
* @return Time channel has been watched last.
*/
time_t LastWatched() const;
@@ -480,7 +470,6 @@ namespace PVR
bool m_bIsLocked; /*!< true if channel is locked, false if not */
std::string m_strIconPath; /*!< the path to the icon for this channel */
std::string m_strChannelName; /*!< the name for this channel used by XBMC */
- bool m_bIsVirtual; /*!< true if this channel is marked as virtual, false if not */
time_t m_iLastWatched; /*!< last time channel has been watched */
bool m_bChanged; /*!< true if anything in this entry was changed that needs to be persisted */
unsigned int m_iCachedChannelNumber; /*!< the cached channel number in the selected group */
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp
index cd64147e83..37aa1c4fa7 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -752,8 +752,6 @@ void CPVRChannelGroup::RemoveInvalidChannels(void)
{
bool bDelete = false;
CPVRChannelPtr channel = m_members.at(ptr).channel;
- if (channel->IsVirtual())
- continue;
if (m_members.at(ptr).channel->ClientChannelNumber() <= 0)
{
@@ -1244,16 +1242,17 @@ time_t CPVRChannelGroup::LastWatched(void) const
bool CPVRChannelGroup::SetLastWatched(time_t iLastWatched)
{
+ CSingleLock lock(m_critSection);
+
+ if (m_iLastWatched != iLastWatched)
{
- CSingleLock lock(m_critSection);
+ m_iLastWatched = iLastWatched;
+ lock.Leave();
- if (m_iLastWatched != iLastWatched)
- m_iLastWatched = iLastWatched;
+ /* update the database immediately */
+ if (CPVRDatabase *database = GetPVRDatabase())
+ return database->UpdateLastWatched(*this);
}
-
- /* update the database immediately */
- if (CPVRDatabase *database = GetPVRDatabase())
- return database->UpdateLastWatched(*this);
return false;
}
@@ -1270,7 +1269,7 @@ void CPVRChannelGroup::SetPreventSortAndRenumber(bool bPreventSortAndRenumber /*
m_bPreventSortAndRenumber = bPreventSortAndRenumber;
}
-bool CPVRChannelGroup::UpdateChannel(const CFileItem &item, bool bHidden, bool bVirtual, bool bEPGEnabled, bool bParentalLocked, int iEPGSource, int iChannelNumber, const std::string &strChannelName, const std::string &strIconPath, const std::string &strStreamURL, bool bUserSetIcon)
+bool CPVRChannelGroup::UpdateChannel(const CFileItem &item, bool bHidden, bool bEPGEnabled, bool bParentalLocked, int iEPGSource, int iChannelNumber, const std::string &strChannelName, const std::string &strIconPath, const std::string &strStreamURL, bool bUserSetIcon)
{
if (!item.HasPVRChannelInfoTag())
return false;
@@ -1287,8 +1286,6 @@ bool CPVRChannelGroup::UpdateChannel(const CFileItem &item, bool bHidden, bool b
channel->SetLocked(bParentalLocked);
channel->SetIconPath(strIconPath, bUserSetIcon);
- if (bVirtual)
- channel->SetStreamURL(strStreamURL);
if (iEPGSource == 0)
channel->SetEPGScraper("client");
diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h
index dddd625eac..ab9dd2b52e 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.h
+++ b/xbmc/pvr/channels/PVRChannelGroup.h
@@ -418,12 +418,10 @@ namespace PVR
*/
CDateTime GetLastEPGDate(void) const;
- bool UpdateChannel(const CFileItem &channel, bool bHidden, bool bVirtual, bool bEPGEnabled, bool bParentalLocked, int iEPGSource, int iChannelNumber, const std::string &strChannelName, const std::string &strIconPath, const std::string &strStreamURL, bool bUserSetIcon = false);
+ bool UpdateChannel(const CFileItem &channel, bool bHidden, bool bEPGEnabled, bool bParentalLocked, int iEPGSource, int iChannelNumber, const std::string &strChannelName, const std::string &strIconPath, const std::string &strStreamURL, bool bUserSetIcon = false);
bool ToggleChannelLocked(const CFileItem &channel);
- virtual bool AddNewChannel(const CPVRChannel &channel, unsigned int iChannelNumber = 0) { return false; }
-
/*!
* @brief Get a channel given the channel number on the client.
* @param iUniqueChannelId The unique channel id on the client.
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
index 76184e9517..9b7f970a98 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -289,12 +289,6 @@ CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetLastPlayedGroup(int iChannelI
return groupTV;
}
-bool CPVRChannelGroupsContainer::CreateChannel(const CPVRChannel &channel) const
-{
- return GetGroupAll(channel.IsRadio())->AddNewChannel(channel);
-}
-
-
bool CPVRChannelGroupsContainer::CreateChannelEpgs(void)
{
return m_groupsRadio->CreateChannelEpgs() &&
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.h b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
index 8d7e4cb694..1e5db82a37 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.h
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
@@ -187,8 +187,6 @@ namespace PVR
*/
CPVRChannelGroupPtr GetLastPlayedGroup(int iChannelID = -1) const;
- bool CreateChannel(const CPVRChannel &channel) const;
-
/*!
* @brief Create EPG tags for channels in all internal channel groups.
* @return True if EPG tags were created succesfully.
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
index c02e6c336d..4aaa4e598c 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
@@ -52,9 +52,6 @@
#define RADIOBUTTON_PARENTAL_LOCK 14
#define CONTROL_LIST_CHANNELS 20
#define BUTTON_GROUP_MANAGER 30
-#define BUTTON_EDIT_CHANNEL 31
-#define BUTTON_DELETE_CHANNEL 32
-#define BUTTON_NEW_CHANNEL 33
#define BUTTON_RADIO_TV 34
using namespace PVR;
@@ -418,125 +415,6 @@ bool CGUIDialogPVRChannelManager::OnClickButtonGroupManager(CGUIMessage &message
return true;
}
-bool CGUIDialogPVRChannelManager::OnClickButtonEditChannel(CGUIMessage &message)
-{
- CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
- if (!pItem)
- return false;
-
- if (pItem->GetProperty("Virtual").asBoolean())
- {
- std::string strURL = pItem->GetProperty("StreamURL").asString();
- if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
- pItem->SetProperty("StreamURL", strURL);
- return true;
- }
-
- CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
- return true;
-}
-
-bool CGUIDialogPVRChannelManager::OnClickButtonDeleteChannel(CGUIMessage &message)
-{
- CFileItemPtr pItem = m_channelItems->Get(m_iSelected);
- if (!pItem)
- return false;
-
- CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
- if (!pDialog)
- return true;
-
- pDialog->SetHeading(19211);
- pDialog->SetLine(0, "");
- pDialog->SetLine(1, 750);
- pDialog->SetLine(2, "");
- pDialog->DoModal();
-
- if (pDialog->IsConfirmed())
- {
- if (pItem->GetProperty("Virtual").asBoolean())
- {
- pItem->GetPVRChannelInfoTag()->SetVirtual(true);
- m_channelItems->Remove(m_iSelected);
- m_viewControl.SetItems(*m_channelItems);
- Renumber();
- return true;
- }
- CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
- }
- return true;
-}
-
-bool CGUIDialogPVRChannelManager::OnClickButtonNewChannel(CGUIMessage &message)
-{
- std::vector<long> clients;
-
- CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
- if (!pDlgSelect)
- return false;
-
- pDlgSelect->SetHeading(19213); // Select Client
- pDlgSelect->Add(g_localizeStrings.Get(19209));
- clients.push_back(PVR_VIRTUAL_CLIENT_ID);
-
- PVR_CLIENTMAP clientMap;
- if (g_PVRClients->GetConnectedClients(clientMap) > 0)
- {
- PVR_CLIENTMAP_ITR itr;
- for (itr = clientMap.begin() ; itr != clientMap.end(); itr++)
- {
- clients.push_back((*itr).first);
- pDlgSelect->Add((*itr).second->Name());
- }
- }
- pDlgSelect->DoModal();
-
- int selection = pDlgSelect->GetSelectedLabel();
- if (selection >= 0 && selection <= (int) clients.size())
- {
- int clientID = clients[selection];
- if (clientID == PVR_VIRTUAL_CLIENT_ID)
- {
- std::string strURL = "";
- if (CGUIKeyboardFactory::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false))
- {
- if (!strURL.empty())
- {
- CPVRChannel *newchannel = new CPVRChannel(m_bIsRadio);
- newchannel->SetChannelName(g_localizeStrings.Get(19204));
- newchannel->SetEPGEnabled(false);
- newchannel->SetVirtual(true);
- newchannel->SetStreamURL(strURL);
- newchannel->SetClientID(PVR_VIRTUAL_CLIENT_ID);
- if (g_PVRChannelGroups->CreateChannel(*newchannel))
- g_PVRChannelGroups->GetGroupAll(m_bIsRadio)->Persist();
-
- CFileItemPtr channel(new CFileItem(*newchannel));
- if (channel)
- {
- channel->SetProperty("ActiveChannel", true);
- channel->SetProperty("Name", g_localizeStrings.Get(19204));
- channel->SetProperty("UseEPG", false);
- channel->SetProperty("Icon", newchannel->IconPath());
- channel->SetProperty("EPGSource", (int)0);
- channel->SetProperty("ClientName", g_localizeStrings.Get(19209));
- channel->SetProperty("ParentalLocked", false);
-
- m_channelItems->AddFront(channel, m_iSelected);
- m_viewControl.SetItems(*m_channelItems);
- Renumber();
- }
- }
- }
- }
- else
- {
- CGUIDialogOK::ShowAndGetInput(19033,19038,0,0);
- }
- }
- return true;
-}
-
bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message)
{
int iControl = message.GetSenderId();
@@ -566,12 +444,6 @@ bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message)
return OnClickEPGSourceSpin(message);
case BUTTON_GROUP_MANAGER:
return OnClickButtonGroupManager(message);
- case BUTTON_EDIT_CHANNEL:
- return OnClickButtonEditChannel(message);
- case BUTTON_DELETE_CHANNEL:
- return OnClickButtonDeleteChannel(message);
- case BUTTON_NEW_CHANNEL:
- return OnClickButtonNewChannel(message);
default:
return false;
}
@@ -627,8 +499,6 @@ bool CGUIDialogPVRChannelManager::OnPopupMenu(int iItem)
return false;
buttons.Add(CONTEXT_BUTTON_MOVE, 116); /* Move channel up or down */
- if (pItem->GetProperty("Virtual").asBoolean())
- buttons.Add(CONTEXT_BUTTON_EDIT_SOURCE, 1027); /* Edit virtual channel URL */
int choice = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
@@ -713,17 +583,8 @@ void CGUIDialogPVRChannelManager::Update()
channelFile->SetProperty("ParentalLocked", channel->IsLocked());
channelFile->SetProperty("Number", StringUtils::Format("%i", channel->ChannelNumber()));
- if (channel->IsVirtual())
- {
- channelFile->SetProperty("Virtual", true);
- channelFile->SetProperty("StreamURL", channel->StreamURL());
- }
-
std::string clientName;
- if (channel->ClientID() == PVR_VIRTUAL_CLIENT_ID) /* XBMC internal */
- clientName = g_localizeStrings.Get(19209);
- else
- g_PVRClients->GetClientName(channel->ClientID(), clientName);
+ g_PVRClients->GetClientName(channel->ClientID(), clientName);
channelFile->SetProperty("ClientName", clientName);
m_channelItems->Add(channelFile);
@@ -756,7 +617,6 @@ bool CGUIDialogPVRChannelManager::PersistChannel(CFileItemPtr pItem, CPVRChannel
/* get values from the form */
bool bHidden = !pItem->GetProperty("ActiveChannel").asBoolean();
- bool bVirtual = pItem->GetProperty("Virtual").asBoolean();
bool bEPGEnabled = pItem->GetProperty("UseEPG").asBoolean();
bool bParentalLocked = pItem->GetProperty("ParentalLocked").asBoolean();
int iEPGSource = (int)pItem->GetProperty("EPGSource").asInteger();
@@ -765,7 +625,7 @@ bool CGUIDialogPVRChannelManager::PersistChannel(CFileItemPtr pItem, CPVRChannel
std::string strStreamURL = pItem->GetProperty("StreamURL").asString();
bool bUserSetIcon = pItem->GetProperty("UserSetIcon").asBoolean();
- return group->UpdateChannel(*pItem, bHidden, bVirtual, bEPGEnabled, bParentalLocked, iEPGSource, ++(*iChannelNumber), strChannelName, strIconPath, strStreamURL, bUserSetIcon);
+ return group->UpdateChannel(*pItem, bHidden, bEPGEnabled, bParentalLocked, iEPGSource, ++(*iChannelNumber), strChannelName, strIconPath, strStreamURL, bUserSetIcon);
}
void CGUIDialogPVRChannelManager::SaveList(void)
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h
index faef829f3c..2204c5ed8a 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h
@@ -61,9 +61,6 @@ namespace PVR
virtual bool OnClickButtonUseEPG(CGUIMessage &message);
virtual bool OnClickEPGSourceSpin(CGUIMessage &message);
virtual bool OnClickButtonGroupManager(CGUIMessage &message);
- virtual bool OnClickButtonEditChannel(CGUIMessage &message);
- virtual bool OnClickButtonDeleteChannel(CGUIMessage &message);
- virtual bool OnClickButtonNewChannel(CGUIMessage &message);
virtual bool PersistChannel(CFileItemPtr pItem, CPVRChannelGroupPtr group, unsigned int *iChannelNumber);
virtual void SetItemsUnchanged(void);
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
index 33b9fd519e..d381e13cee 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
@@ -105,15 +105,10 @@ void CGUIDialogPVRTimerSettings::OnSettingChanged(const CSetting *setting)
tag->m_iClientId = channel->ClientID();
tag->m_bIsRadio = channel->IsRadio();
tag->m_iChannelNumber = channel->ChannelNumber();
+
+ // Update channel pointer from above values
+ tag->UpdateChannel();
}
- else
- {
- tag->m_iClientChannelUid = PVR_VIRTUAL_CHANNEL_UID;
- tag->m_iClientId = PVR_VIRTUAL_CLIENT_ID;
- tag->m_iChannelNumber = 0;
- }
- // Update channel pointer from above values
- tag->UpdateChannel();
}
}
else if (settingId == SETTING_TMR_DAY)
@@ -353,11 +348,10 @@ CSetting* CGUIDialogPVRTimerSettings::AddChannelNames(CSettingGroup *group, bool
std::vector< std::pair<std::string, int> > options;
getChannelNames(bRadio, options, m_selectedChannelEntry, true);
- int timerChannelID;
+ // select the correct channel
+ int timerChannelID = 0;
if (m_timerItem->GetPVRTimerInfoTag()->ChannelTag())
timerChannelID = m_timerItem->GetPVRTimerInfoTag()->ChannelTag()->ChannelID();
- else
- timerChannelID = PVR_VIRTUAL_CHANNEL_UID;
for (std::vector< std::pair<std::string, int> >::const_iterator option = options.begin(); option != options.end(); ++option)
{
@@ -449,10 +443,6 @@ void CGUIDialogPVRTimerSettings::getChannelNames(bool bRadio, std::vector< std::
g_PVRChannelGroups->GetGroupAll(bRadio)->GetMembers(channelsList);
int entry = 0;
- list.push_back(std::make_pair("0 dummy", entry));
- if (updateChannelEntries)
- m_channelEntries.insert(std::make_pair(std::make_pair(bRadio, entry), PVR_VIRTUAL_CHANNEL_UID));
- ++entry;
for (int i = 0; i < channelsList.Size(); i++)
{
diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp
index d418f0f010..454455b096 100644
--- a/xbmc/pvr/recordings/PVRRecording.cpp
+++ b/xbmc/pvr/recordings/PVRRecording.cpp
@@ -34,7 +34,7 @@ using namespace PVR;
using namespace EPG;
CPVRRecordingUid::CPVRRecordingUid() :
- m_iClientId(PVR_VIRTUAL_CLIENT_ID)
+ m_iClientId(PVR_INVALID_CLIENT_ID)
{
}
diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.cpp b/xbmc/pvr/timers/PVRTimerInfoTag.cpp
index e97e6bd3f6..96cb5a998d 100644
--- a/xbmc/pvr/timers/PVRTimerInfoTag.cpp
+++ b/xbmc/pvr/timers/PVRTimerInfoTag.cpp
@@ -44,7 +44,7 @@ CPVRTimerInfoTag::CPVRTimerInfoTag(void) :
{
m_iClientId = g_PVRClients->GetFirstConnectedClientID();
m_iClientIndex = -1;
- m_iClientChannelUid = PVR_VIRTUAL_CHANNEL_UID;
+ m_iClientChannelUid = PVR_INVALID_CHANNEL_UID;
m_iPriority = CSettings::Get().GetInt("pvrrecord.defaultpriority");
m_iLifetime = CSettings::Get().GetInt("pvrrecord.defaultlifetime");
m_bIsRepeating = false;
diff --git a/xbmc/pvr/timers/PVRTimerInfoTag.h b/xbmc/pvr/timers/PVRTimerInfoTag.h
index 51c6c5d0b1..9643913860 100644
--- a/xbmc/pvr/timers/PVRTimerInfoTag.h
+++ b/xbmc/pvr/timers/PVRTimerInfoTag.h
@@ -62,7 +62,6 @@ namespace PVR
class CPVRTimerInfoTag;
typedef boost::shared_ptr<PVR::CPVRTimerInfoTag> CPVRTimerInfoTagPtr;
- #define PVR_VIRTUAL_CHANNEL_UID (-1)
class CPVRTimerInfoTag : public ISerializable
{
diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp
index 4084402c88..290218243c 100644
--- a/xbmc/pvr/timers/PVRTimers.cpp
+++ b/xbmc/pvr/timers/PVRTimers.cpp
@@ -667,9 +667,10 @@ CDateTime CPVRTimers::GetNextEventTime(void) const
CFileItemPtr item = GetNextActiveTimer();
if (item && item->HasPVRTimerInfoTag())
{
+ const CDateTimeSpan prestart(0, 0, item->GetPVRTimerInfoTag()->MarginStart(), 0);
const CDateTime start = item->GetPVRTimerInfoTag()->StartAsUTC();
wakeuptime = ((start - idle) > now) ?
- start - prewakeup:
+ start - prestart - prewakeup :
now + idle;
}
diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
index 95d8603daa..5adab71d41 100644
--- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
@@ -531,21 +531,7 @@ bool CGUIWindowPVRBase::ActionInputChannelNumber(int input)
bool CGUIWindowPVRBase::ActionPlayChannel(CFileItem *item)
{
- bool bReturn = false;
-
- if (item->GetPath() == "pvr://channels/.add.channel")
- {
- /* show "add channel" dialog */
- CGUIDialogOK::ShowAndGetInput(19033,0,19038,0);
- bReturn = true;
- }
- else
- {
- /* open channel */
- bReturn = PlayFile(item, CSettings::Get().GetBool("pvrplayback.playminimized"));
- }
-
- return bReturn;
+ return PlayFile(item, CSettings::Get().GetBool("pvrplayback.playminimized"));
}
bool CGUIWindowPVRBase::ActionPlayEpg(CFileItem *item)
diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
index ae82ecc397..c1475e7b75 100644
--- a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
@@ -75,25 +75,17 @@ void CGUIWindowPVRChannels::GetContextButtons(int itemNumber, CContextButtons &b
CFileItemPtr pItem = m_vecItems->Get(itemNumber);
CPVRChannel *channel = pItem->GetPVRChannelInfoTag();
- if (pItem->GetPath() == "pvr://channels/.add.channel")
- {
- /* If yes show only "New Channel" on context menu */
- buttons.Add(CONTEXT_BUTTON_ADD, 19046); /* add new channel */
- }
- else
- {
- buttons.Add(CONTEXT_BUTTON_INFO, 19047); /* channel info */
- buttons.Add(CONTEXT_BUTTON_FIND, 19003); /* find similar program */
- buttons.Add(CONTEXT_BUTTON_RECORD_ITEM, channel->IsRecording() ? 19256 : 19255); /* start/stop recording on channel */
+ buttons.Add(CONTEXT_BUTTON_INFO, 19047); /* channel info */
+ buttons.Add(CONTEXT_BUTTON_FIND, 19003); /* find similar program */
+ buttons.Add(CONTEXT_BUTTON_RECORD_ITEM, channel->IsRecording() ? 19256 : 19255); /* start/stop recording on channel */
- if (g_PVRClients->HasMenuHooks(pItem->GetPVRChannelInfoTag()->ClientID(), PVR_MENUHOOK_CHANNEL))
- buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */
+ if (g_PVRClients->HasMenuHooks(pItem->GetPVRChannelInfoTag()->ClientID(), PVR_MENUHOOK_CHANNEL))
+ buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */
- // Add parent buttons before the Manage button
- CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons);
+ // Add parent buttons before the Manage button
+ CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons);
- buttons.Add(CONTEXT_BUTTON_EDIT, 16106); /* "Manage" submenu */
- }
+ buttons.Add(CONTEXT_BUTTON_EDIT, 16106); /* "Manage" submenu */
}
std::string CGUIWindowPVRChannels::GetDirectoryPath(void)
diff --git a/xbmc/storage/linux/UDevProvider.cpp b/xbmc/storage/linux/UDevProvider.cpp
index 84c931f596..0ca370bbac 100644
--- a/xbmc/storage/linux/UDevProvider.cpp
+++ b/xbmc/storage/linux/UDevProvider.cpp
@@ -138,6 +138,13 @@ void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable)
continue;
}
+ // filter out root partition
+ if (strcmp(mountpoint, "/") == 0)
+ {
+ udev_device_unref(device);
+ continue;
+ }
+
// filter out things mounted on /tmp
if (strstr(mountpoint, "/tmp"))
{
@@ -145,28 +152,42 @@ void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable)
continue;
}
- // look for usb devices on the usb bus, or mounted on /media/usbX (sdcards) or cdroms
+ // look for devices on the usb bus, or mounted on */media/ (sdcards), or optical devices
const char *bus = udev_device_get_property_value(device, "ID_BUS");
- const char *cdrom = udev_device_get_property_value(device, "ID_CDROM");
- if (removable &&
- ((bus && strstr(bus, "usb")) ||
- (cdrom && strstr(cdrom,"1")) ||
- (mountpoint && strstr(mountpoint, "/media/"))))
+ const char *optical = udev_device_get_property_value(device, "ID_CDROM"); // matches also DVD, Blu-ray
+ bool isRemovable = ((bus && strstr(bus, "usb")) ||
+ (optical && strstr(optical,"1")) ||
+ (mountpoint && strstr(mountpoint, "/media/")));
+
+ // filter according to requested device type
+ if (removable != isRemovable)
{
- const char *udev_label = udev_device_get_property_value(device, "ID_FS_LABEL");
- std::string label;
- if (udev_label)
- label = udev_label;
- else
- label = URIUtils::GetFileName(mountpoint);
+ udev_device_unref(device);
+ continue;
+ }
- CMediaSource share;
- share.strName = label;
- share.strPath = mountpoint;
- share.m_ignore = true;
- share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
- AddOrReplace(disks, share);
+ const char *udev_label = udev_device_get_property_value(device, "ID_FS_LABEL");
+ std::string label;
+ if (udev_label)
+ label = udev_label;
+ else
+ label = URIUtils::GetFileName(mountpoint);
+
+ CMediaSource share;
+ share.strName = label;
+ share.strPath = mountpoint;
+ share.m_ignore = true;
+ if (isRemovable)
+ {
+ if (optical)
+ share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
+ else
+ share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
}
+ else
+ share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
+
+ disks.push_back(share);
udev_device_unref(device);
}
udev_enumerate_unref(u_enum);
diff --git a/xbmc/utils/Makefile.in b/xbmc/utils/Makefile.in
index 2d89fcd0aa..c5f229bff5 100644
--- a/xbmc/utils/Makefile.in
+++ b/xbmc/utils/Makefile.in
@@ -85,6 +85,10 @@ ifeq (@USE_OPENGLES@,1)
SRCS += AMLUtils.cpp
endif
+ifeq (@USE_LIBAMCODEC@,1)
+SRCS += ScreenshotAML.cpp
+endif
+
LIB = utils.a
include @abs_top_srcdir@/Makefile.include
diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp
index db73d4aa0b..249410156e 100644
--- a/xbmc/utils/Screenshot.cpp
+++ b/xbmc/utils/Screenshot.cpp
@@ -47,6 +47,10 @@
#include "settings/Settings.h"
#include "settings/windows/GUIControlSettings.h"
+#if defined(HAS_LIBAMCODEC)
+#include "utils/ScreenshotAML.h"
+#endif
+
using namespace std;
using namespace XFILE;
@@ -162,6 +166,11 @@ bool CScreenshotSurface::capture()
}
delete [] surface;
+
+#if defined(HAS_LIBAMCODEC)
+ // Captures the current visible videobuffer and blend it into m_buffer (captured overlay)
+ CScreenshotAML::CaptureVideoFrame(m_buffer, m_width, m_height);
+#endif
#else
//nothing to take a screenshot from
diff --git a/xbmc/utils/ScreenshotAML.cpp b/xbmc/utils/ScreenshotAML.cpp
new file mode 100644
index 0000000000..3e73437d77
--- /dev/null
+++ b/xbmc/utils/ScreenshotAML.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#if defined(HAS_LIBAMCODEC)
+#include "utils/ScreenshotAML.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+
+// taken from linux/amlogic/amports/amvideocap.h - needs to be synced - no changes expected though
+#define AMVIDEOCAP_IOC_MAGIC 'V'
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int)
+#define AMVIDEOCAP_IOW_SET_CANCEL_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x33, int)
+
+// capture format already defaults to GE2D_FORMAT_S24_RGB - no need to pull in all the ge2d headers :)
+
+#define CAPTURE_DEVICEPATH "/dev/amvideocap0"
+
+//the buffer format is BGRA (4 byte)
+void CScreenshotAML::CaptureVideoFrame(unsigned char *buffer, int iWidth, int iHeight, bool bBlendToBuffer)
+{
+ int captureFd = open(CAPTURE_DEVICEPATH, O_RDWR, 0);
+ if (captureFd >= 0)
+ {
+ int buffSize = iWidth * iHeight * 3;
+ int readSize = 0;
+ // videobuffer should be rgb according to docu - but it is bgr ...
+ unsigned char *videoBuffer = new unsigned char[buffSize];
+
+ if (videoBuffer != NULL)
+ {
+ // configure destination
+ ioctl(captureFd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, iWidth);
+ ioctl(captureFd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, iHeight);
+ readSize = pread(captureFd, videoBuffer, buffSize, 0);
+ }
+
+ close(captureFd);
+
+ if (readSize == buffSize)
+ {
+ unsigned char *videoPtr = videoBuffer;
+
+ if (!bBlendToBuffer)
+ {
+ memset(buffer, 0xff, buffSize);
+ }
+
+ for (int processedBytes = 0; processedBytes < buffSize; processedBytes += 3, buffer+=4)
+ {
+ float alpha = buffer[3] / (float)255;
+
+ if (bBlendToBuffer)
+ {
+ //B
+ buffer[0] = alpha * (float)buffer[0] + (1 - alpha) * (float)videoPtr[0];
+ //G
+ buffer[1] = alpha * (float)buffer[1] + (1 - alpha) * (float)videoPtr[1];
+ //R
+ buffer[2] = alpha * (float)buffer[2] + (1 - alpha) * (float)videoPtr[2];
+ //A
+ buffer[3] = 0xff;// we are solid now
+ }
+ else
+ {
+ memcpy(buffer, videoPtr, 3);
+ }
+ videoPtr += 3;
+ }
+ }
+ delete [] videoBuffer;
+ }
+}
+#endif //defined(HAS_LIBAMCODEC)
diff --git a/xbmc/utils/ScreenshotAML.h b/xbmc/utils/ScreenshotAML.h
new file mode 100644
index 0000000000..b2caedc520
--- /dev/null
+++ b/xbmc/utils/ScreenshotAML.h
@@ -0,0 +1,30 @@
+#pragma once
+/*
+ * Copyright (C) 2015 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if defined(HAS_LIBAMCODEC)
+class CScreenshotAML
+{
+ public:
+ // Captures the current visible video framebuffer and blends it into
+ // the passed overlay. The buffer format is BGRA (4 byte)
+ static void CaptureVideoFrame(unsigned char *buffer, int iWidth, int iHeight, bool bBlendToBuffer = true);
+};
+#endif//HAS_LIBAMCODEC
diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
index c77955c737..00139c834b 100644
--- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
@@ -25,7 +25,10 @@
#ifdef HAS_VIDEO_PLAYBACK
#include "cores/VideoRenderers/RenderManager.h"
#include "cores/VideoRenderers/RenderCapture.h"
-#endif
+#if defined(HAS_LIBAMCODEC)
+#include "utils/ScreenshotAML.h"
+#endif//HAS_LIBAMCODEC
+#endif//HAS_VIDEO_PLAYBACK
#include "pictures/Picture.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "view/ViewState.h"
@@ -339,8 +342,13 @@ bool CGUIDialogVideoBookmarks::AddBookmark(CVideoInfoTag* tag)
{
g_renderManager.Capture(thumbnail, width, height, CAPTUREFLAG_IMMEDIATELY);
+#if !defined(HAS_LIBAMCODEC)
if (thumbnail->GetUserState() == CAPTURESTATE_DONE)
{
+#else//HAS_LIBAMCODEC
+ {
+ CScreenshotAML::CaptureVideoFrame(thumbnail->GetPixels(), width, height, false);
+#endif
Crc32 crc;
crc.ComputeFromLowerCase(g_application.CurrentFile());
bookmark.thumbNailImage = StringUtils::Format("%08x_%i.jpg", (unsigned __int32) crc, (int)bookmark.timeInSeconds);
@@ -349,8 +357,10 @@ bool CGUIDialogVideoBookmarks::AddBookmark(CVideoInfoTag* tag)
bookmark.thumbNailImage))
bookmark.thumbNailImage.clear();
}
+#if !defined(HAS_LIBAMCODEC)
else
CLog::Log(LOGERROR,"CGUIDialogVideoBookmarks: failed to create thumbnail");
+#endif
g_renderManager.ReleaseRenderCapture(thumbnail);
}