diff options
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, '/', ¶ms); -+ 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, ';', ¶ms); -+ 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, ':', ¶ms); -+ 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, ',', ¶ms); -+ 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); } |