mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
First effort to port HUru MKV/WEBM Movie Player to Minkata
Type restructuring for C++98 and build configuration updates. This version compiles successfully, but without webm libraries yet linked in.
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual C++ Express 2010
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AllClient", "AllClient.vcxproj", "{23DA297E-0E5A-5BA8-006F-7C7F5AF694C0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreLib", "..\..\CoreLib\CoreLib.vcxproj", "{83A96477-BAEF-4DB7-8134-AEADF4B2E63F}"
|
||||
@ -222,6 +222,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plPythonPack", "..\plPython
|
||||
{797721D5-0EFE-4912-8F4F-953A71A69B04} = {797721D5-0EFE-4912-8F4F-953A71A69B04}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pfMoviePlayer", "..\..\FeatureLib\pfMoviePlayer\pfMoviePlayer.vcxproj", "{90045C91-576B-4639-8C2F-A6B5B70EC6A1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug_Internal|Win32 = Debug_Internal|Win32
|
||||
@ -1022,6 +1024,14 @@ Global
|
||||
{84868043-5563-435A-A176-76A059653D5C}.Release_Internal|Win32.Build.0 = Release_Internal|Win32
|
||||
{84868043-5563-435A-A176-76A059653D5C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{84868043-5563-435A-A176-76A059653D5C}.Release|Win32.Build.0 = Release|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Debug_Internal|Win32.ActiveCfg = Debug|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Debug_Internal|Win32.Build.0 = Debug|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release_Internal|Win32.ActiveCfg = Release_Internal|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release_Internal|Win32.Build.0 = Release_Internal|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{90045C91-576B-4639-8C2F-A6B5B70EC6A1}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -109,7 +109,7 @@
|
||||
<AdditionalDependencies>winhttp.lib;ws2_32.lib;strmiids.lib;vfw32.lib;version.lib;Rpcrt4.lib;d3dx9.lib;dinput8.lib;dxerr.lib;dxguid.lib;dsound.lib;OpenAL32.lib;libeay32.lib;NxCharacter.lib;PhysXLoader.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;libspeex.lib;libjpeg.lib;zlibd.lib;libpngd.lib;NxCooking.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Debug;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\opus\opus-1.3.1\win32\VS2015\Win32\Release\opus;D:\Users\richards\Desktop\Minkata-build-VS2010\CWE-ou-minkata\MOULOpenSourceClientPlugin\StaticSDKs\Win32\webm\libvpx_build_win32_vs14;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Debug;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib;libcd.lib;libci.lib;libcid.lib;libcmtd.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AssemblyDebug>true</AssemblyDebug>
|
||||
@ -164,7 +164,7 @@
|
||||
<AdditionalDependencies>winhttp.lib;ws2_32.lib;strmiids.lib;vfw32.lib;version.lib;Rpcrt4.lib;d3dx9.lib;dinput8.lib;dxerr.lib;dxguid.lib;dsound.lib;OpenAL32.lib;libeay32.lib;NxCharacter.lib;PhysXLoader.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;libspeex.lib;libjpeg.lib;zlibd.lib;libpngd.lib;NxCooking.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Debug;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\opus\opus-1.3.1\win32\VS2015\Win32\Release\opus;D:\Users\richards\Desktop\Minkata-build-VS2010\CWE-ou-minkata\MOULOpenSourceClientPlugin\StaticSDKs\Win32\webm\libvpx_build_win32_vs14;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Debug;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib;libcd.lib;libci.lib;libcid.lib;libcmtd.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AssemblyDebug>true</AssemblyDebug>
|
||||
@ -199,7 +199,7 @@
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>../../../../Sources/Plasma/CoreLib;../../../../Sources/Plasma/NucleusLib;../../../../Sources/Plasma/NucleusLib/inc;../../../../Sources/Plasma/PubUtilLib;../../../../Sources/Plasma/PubUtilLib/inc;../../../../Sources/Plasma/FeatureLib;../../../../Sources/Plasma/FeatureLib/inc;../../../../SDKs/XPlatform/Cypython-2.3.3/Include;../../../../SDKs/XPlatform/Cypython-2.3.3/PC;../../../../SDKs/XPlatform/Cypython-2.3.3/pyconfig_static;../../../../../StaticSDKs/Win32/DX9.0c/include;../../../../../StaticSDKs/Win32/OpenAL 1.1 with EFX SDK/include;../../../../../StaticSDKs/Win32/OpenSSL/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;PLASMA_USE_WEBM;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
@ -223,7 +223,7 @@
|
||||
<AdditionalDependencies>winhttp.lib;ws2_32.lib;strmiids.lib;vfw32.lib;version.lib;Rpcrt4.lib;d3dx9.lib;dinput8.lib;dxerr.lib;dxguid.lib;dsound.lib;OpenAL32.lib;libeay32.lib;NxCharacter.lib;PhysXLoader.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;libspeex.lib;libjpeg.lib;zlib.lib;libpng.lib;NxCooking.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Release;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\opus\opus-1.3.1\win32\VS2015\Win32\Release\opus;D:\Users\richards\Desktop\Minkata-build-VS2010\CWE-ou-minkata\MOULOpenSourceClientPlugin\StaticSDKs\Win32\webm\libvpx_build_win32_vs14;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Release;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib;libci.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AssemblyDebug>false</AssemblyDebug>
|
||||
@ -258,7 +258,7 @@
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>../../../../Sources/Plasma/CoreLib;../../../../Sources/Plasma/NucleusLib;../../../../Sources/Plasma/NucleusLib/inc;../../../../Sources/Plasma/PubUtilLib;../../../../Sources/Plasma/PubUtilLib/inc;../../../../Sources/Plasma/FeatureLib;../../../../Sources/Plasma/FeatureLib/inc;../../../../SDKs/XPlatform/Cypython-2.3.3/Include;../../../../SDKs/XPlatform/Cypython-2.3.3/PC;../../../../SDKs/XPlatform/Cypython-2.3.3/pyconfig_static;../../../../../StaticSDKs/Win32/DX9.0c/include;../../../../../StaticSDKs/Win32/OpenAL 1.1 with EFX SDK/include;../../../../../StaticSDKs/Win32/OpenSSL/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;PLASMA_EXTERNAL_RELEASE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;PLASMA_EXTERNAL_RELEASE;PLASMA_USE_WEBM;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>
|
||||
@ -283,7 +283,7 @@
|
||||
<AdditionalDependencies>winhttp.lib;ws2_32.lib;strmiids.lib;vfw32.lib;version.lib;Rpcrt4.lib;d3dx9.lib;dinput8.lib;dxerr.lib;dxguid.lib;dsound.lib;OpenAL32.lib;libeay32.lib;NxCharacter.lib;PhysXLoader.lib;libogg_static.lib;libvorbis_static.lib;libvorbisfile_static.lib;libspeex.lib;libjpeg.lib;zlib.lib;libpng.lib;NxCooking.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Release;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\StaticSDKs\Win32\DX9.0c\Lib\x86;..\..\..\..\..\StaticSDKs\Win32\OpenAL 1.1 with EFX SDK\libs\Win32;..\..\..\..\..\StaticSDKs\Win32\OpenSSL\lib;..\..\..\..\..\StaticSDKs\Win32\PhysX\lib\win32;..\..\..\..\..\StaticSDKs\Win32\opus\opus-1.3.1\win32\VS2015\Win32\Release\opus;D:\Users\richards\Desktop\Minkata-build-VS2010\CWE-ou-minkata\MOULOpenSourceClientPlugin\StaticSDKs\Win32\webm\libvpx_build_win32_vs14;..\..\..\..\..\StaticSDKs\Win32\xiph\lib\Release;..\..\..\..\..\StaticSDKs\XPlatform\expat-1.95.7\StaticLibs\Win32;..\..\..\..\..\StaticSDKs\XPlatform\jpeg-8c-rgba;..\..\..\..\..\StaticSDKs\XPlatform\zlib\lib;..\..\..\..\..\StaticSDKs\XPlatform\png\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib;libci.lib;libcmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AssemblyDebug>false</AssemblyDebug>
|
||||
@ -495,6 +495,9 @@
|
||||
<Project>{cd679637-008c-7e09-198f-51059c2b48e8}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\FeatureLib\pfMoviePlayer\pfMoviePlayer.vcxproj">
|
||||
<Project>{90045c91-576b-4639-8c2f-a6b5b70ec6a1}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\FeatureLib\pfPython\pfPython.vcxproj">
|
||||
<Project>{797721d5-0efe-4912-8f4f-953a71a69b04}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
|
@ -115,6 +115,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#include "../plProgressMgr/plProgressMgr.h"
|
||||
#include "../plPipeline/plDTProgressMgr.h"
|
||||
#include "../plPipeline/plBinkPlayer.h"
|
||||
#include "../pfMoviePlayer/plMoviePlayer.h"
|
||||
#include "../plMessage/plMovieMsg.h"
|
||||
|
||||
#include "../plSDL/plSDL.h"
|
||||
@ -273,9 +274,6 @@ hsBool plClient::Shutdown()
|
||||
IKillMovies();
|
||||
|
||||
plgAudioSys::Activate(false);
|
||||
#ifdef USE_BINK_SDK
|
||||
plBinkPlayer::DeInit();
|
||||
#endif
|
||||
//
|
||||
// Get any proxies to commit suicide.
|
||||
plProxyDrawMsg* nuke = TRACKED_NEW plProxyDrawMsg(plProxyDrawMsg::kAllTypes
|
||||
@ -887,8 +885,7 @@ hsBool plClient::IHandleMovieMsg(plMovieMsg* mov)
|
||||
}
|
||||
if( i == fMovies.GetCount() )
|
||||
{
|
||||
|
||||
fMovies.Append(TRACKED_NEW plBinkPlayer);
|
||||
fMovies.Append(new plMoviePlayer);
|
||||
fMovies[i]->SetFileName(mov->GetFileName());
|
||||
}
|
||||
|
||||
@ -930,7 +927,7 @@ hsBool plClient::IHandleMovieMsg(plMovieMsg* mov)
|
||||
fMovies[i]->SetVolume(mov->GetVolume());
|
||||
|
||||
if( mov->GetCmd() & plMovieMsg::kStart )
|
||||
fMovies[i]->Start(fPipeline, fWindowHndl);
|
||||
fMovies[i]->Start();
|
||||
if( mov->GetCmd() & plMovieMsg::kPause )
|
||||
fMovies[i]->Pause(true);
|
||||
if( mov->GetCmd() & plMovieMsg::kResume )
|
||||
@ -1514,14 +1511,10 @@ hsBool plClient::StartInit()
|
||||
|
||||
plgAudioSys::Activate(true);
|
||||
|
||||
#ifdef USE_BINK_SDK
|
||||
plConst(hsScalar) delay(2.f);
|
||||
//commenting out publisher splash for MORE
|
||||
//IPlayIntroBink("avi/intro0.bik", delay, 0.f, 0.f, 1.f, 1.f, 0.75);
|
||||
//if( GetDone() ) return false;
|
||||
IPlayIntroBink("avi/intro1.bik", 0.f, 0.f, 0.f, 1.f, 1.f, 0.75);
|
||||
if( GetDone() ) return false;
|
||||
#endif // USE_BINK_SDK
|
||||
IPlayIntroMovie("avi/intro1.webm", 0.f, 0.f, 0.f, 1.f, 1.f, 0.75);
|
||||
IPlayIntroMovie("avi/URULiveIntro.webm", 0.f, 0.f, 0.f, 1.f, 1.f, 0.75);
|
||||
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plMovieMsg::Index(), GetKey());
|
||||
|
||||
//
|
||||
@ -1984,56 +1977,55 @@ void plClient::IKillMovies()
|
||||
fMovies.Reset();
|
||||
}
|
||||
|
||||
#ifdef USE_BINK_SDK
|
||||
hsBool plClient::IPlayIntroBink(const char* movieName, hsScalar endDelay, hsScalar posX, hsScalar posY, hsScalar scaleX, hsScalar scaleY, hsScalar volume /* = 1.0 */)
|
||||
hsBool plClient::IPlayIntroMovie(const char* movieName, hsScalar endDelay, hsScalar posX, hsScalar posY, hsScalar scaleX, hsScalar scaleY, hsScalar volume /* = 1.0 */)
|
||||
{
|
||||
SetQuitIntro(false);
|
||||
plBinkPlayer player;
|
||||
player.SetPosition(posX, posY);
|
||||
player.SetScale(scaleX, scaleY);
|
||||
player.SetFileName(movieName);
|
||||
player.SetFadeToTime(endDelay);
|
||||
player.SetFadeToColor(hsColorRGBA().Set(0, 0, 0, 1.f));
|
||||
player.SetVolume(volume);
|
||||
bool firstTry = true; // flag to make sure that we don't quit before we even start
|
||||
SetQuitIntro(false);
|
||||
plMoviePlayer player;
|
||||
player.SetPosition(posX, posY);
|
||||
player.SetScale(scaleX, scaleY);
|
||||
player.SetFileName(movieName);
|
||||
player.SetFadeToTime(endDelay);
|
||||
player.SetFadeToColor(hsColorRGBA().Set(0, 0, 0, 1.f));
|
||||
player.SetVolume(volume);
|
||||
bool firstTry = true; // flag to make sure that we don't quit before we even start
|
||||
|
||||
if( player.Start(fPipeline, fWindowHndl) )
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
if( fInstance )
|
||||
fInstance->fMessagePumpProc();
|
||||
if (player.Start())
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (fInstance)
|
||||
fInstance->fMessagePumpProc();
|
||||
|
||||
if( GetDone() )
|
||||
return true;
|
||||
if (firstTry)
|
||||
{
|
||||
firstTry = false;
|
||||
SetQuitIntro(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( GetQuitIntro() )
|
||||
return true;
|
||||
}
|
||||
if (GetDone())
|
||||
return true;
|
||||
if (firstTry)
|
||||
{
|
||||
firstTry = false;
|
||||
SetQuitIntro(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetQuitIntro())
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool done = false;
|
||||
if( !fPipeline->BeginRender() )
|
||||
{
|
||||
fPipeline->ClearRenderTarget();
|
||||
done = !player.NextFrame();
|
||||
bool done = false;
|
||||
if (!fPipeline->BeginRender())
|
||||
{
|
||||
fPipeline->ClearRenderTarget();
|
||||
done = !player.NextFrame();
|
||||
|
||||
fPipeline->EndRender();
|
||||
}
|
||||
fPipeline->RenderScreenElements();
|
||||
fPipeline->EndRender();
|
||||
}
|
||||
|
||||
if( done )
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (done)
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // USE_BINK_SDK
|
||||
|
||||
hsBool plClient::IFlushRenderRequests()
|
||||
{
|
||||
|
@ -79,6 +79,7 @@ class plClientMsg;
|
||||
class plLocation;
|
||||
class plMovieMsg;
|
||||
class plBinkPlayer;
|
||||
class plMoviePlayer;
|
||||
class plPreloaderMsg;
|
||||
class plNetCommAuthMsg;
|
||||
class plAgeLoaded2Msg;
|
||||
@ -150,7 +151,7 @@ protected:
|
||||
int fQuality;
|
||||
|
||||
hsBool fQuitIntro;
|
||||
hsTArray<plBinkPlayer*> fMovies;
|
||||
hsTArray<plMoviePlayer*> fMovies;
|
||||
|
||||
hsBool fPatchGlobalAges;
|
||||
|
||||
@ -191,9 +192,7 @@ protected:
|
||||
void IProcessRenderRequests(hsTArray<plRenderRequest*>& reqs);
|
||||
void IAddRenderRequest(plRenderRequest* req);
|
||||
|
||||
#ifdef USE_BINK_SDK
|
||||
hsBool IPlayIntroBink(const char* movieName, hsScalar endDelay, hsScalar posX, hsScalar posY, hsScalar scaleX, hsScalar scaleY, hsScalar volume = 1.0);
|
||||
#endif // USE_BINK_SDK
|
||||
hsBool IPlayIntroMovie(const char* movieName, hsScalar endDelay, hsScalar posX, hsScalar posY, hsScalar scaleX, hsScalar scaleY, hsScalar volume = 1.0);
|
||||
hsBool IHandleMovieMsg(plMovieMsg* mov);
|
||||
void IKillMovies();
|
||||
void IServiceMovies();
|
||||
|
@ -624,7 +624,7 @@ void LocalizationDatabase::IVerifyElement(const std::wstring &ageName, const std
|
||||
int numLocales = plLocalization::GetNumLocales();
|
||||
for (int curLocale = 0; curLocale <= numLocales; curLocale++)
|
||||
{
|
||||
char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
wchar_t *wName = hsStringToWString(name);
|
||||
languageNames.push_back(wName);
|
||||
delete [] wName;
|
||||
@ -939,7 +939,7 @@ pfLocalizationDataMgr::localizedElement pfLocalizationDataMgr::ICreateLocalizedE
|
||||
|
||||
for (int curLocale = 0; curLocale <= numLocales; curLocale++)
|
||||
{
|
||||
char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
wchar_t *wName = hsStringToWString(name);
|
||||
retVal[wName] = L"";
|
||||
delete [] wName;
|
||||
@ -953,7 +953,7 @@ pfLocalizationDataMgr::localizedElement pfLocalizationDataMgr::ICreateLocalizedE
|
||||
std::wstring pfLocalizationDataMgr::IGetCurrentLanguageName()
|
||||
{
|
||||
std::wstring retVal;
|
||||
char *name = plLocalization::GetLanguageName(plLocalization::GetLanguage());
|
||||
const char *name = plLocalization::GetLanguageName(plLocalization::GetLanguage());
|
||||
wchar_t *wName = hsStringToWString(name);
|
||||
retVal = wName;
|
||||
delete [] wName;
|
||||
@ -969,7 +969,7 @@ std::vector<std::wstring> pfLocalizationDataMgr::IGetAllLanguageNames()
|
||||
|
||||
for (int curLocale = 0; curLocale <= numLocales; curLocale++)
|
||||
{
|
||||
char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
|
||||
wchar_t *wName = hsStringToWString(name);
|
||||
retVal.push_back(wName);
|
||||
delete [] wName;
|
||||
|
@ -0,0 +1,452 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "plMoviePlayer.h"
|
||||
|
||||
#include "hsConfig.h"
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
# define VPX_CODEC_DISABLE_COMPAT 1
|
||||
# include <vpx/vpx_decoder.h>
|
||||
# include <vpx/vp8dx.h>
|
||||
# define iface (vpx_codec_vp9_dx())
|
||||
# include <opus.h>
|
||||
|
||||
# define WEBM_CODECID_VP9 "V_VP9"
|
||||
# define WEBM_CODECID_OPUS "A_OPUS"
|
||||
#endif
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include "hsTimer.h"
|
||||
#include "../plAudio/plWin32VideoSound.h"
|
||||
#include "../plGImage/plMipmap.h"
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
#include "../plPipeline/hsGDeviceRef.h"
|
||||
#include "../plPipeline/plPlates.h"
|
||||
#include "../plResMgr/plLocalization.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
#include "../plFile/plFileUtils.h"
|
||||
|
||||
#include "plPlanarImage.h"
|
||||
#include "webm/mkvreader.hpp"
|
||||
#include "webm/mkvparser.hpp"
|
||||
|
||||
#define SAFE_OP(x, err) \
|
||||
{ \
|
||||
Int64 ret = 0; \
|
||||
ret = x; \
|
||||
if (ret < 0) { \
|
||||
hsAssert(false, "failed to " err); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
|
||||
class VPX
|
||||
{
|
||||
VPX() { }
|
||||
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
public:
|
||||
vpx_codec_ctx_t codec;
|
||||
|
||||
~VPX()
|
||||
{
|
||||
if (vpx_codec_destroy(&codec))
|
||||
hsAssert(false, vpx_codec_error_detail(&codec));
|
||||
}
|
||||
|
||||
static VPX* Create()
|
||||
{
|
||||
VPX* instance = new VPX;
|
||||
if (vpx_codec_dec_init(&instance->codec, iface, nullptr, 0)) {
|
||||
hsAssert(false, vpx_codec_error_detail(&instance->codec));
|
||||
delete instance;
|
||||
return nullptr;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
vpx_image_t* Decode(UInt8* buf, UInt32 size)
|
||||
{
|
||||
if (vpx_codec_decode(&codec, buf, size, nullptr, 0) != VPX_CODEC_OK) {
|
||||
const char* detail = vpx_codec_error_detail(&codec);
|
||||
hsAssert(false, detail ? detail : "unspecified decode error");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
vpx_codec_iter_t iter = nullptr;
|
||||
// ASSUMPTION: only one image per frame
|
||||
// if this proves false, move decoder function into IProcessVideoFrame
|
||||
return vpx_codec_get_frame(&codec, &iter);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
|
||||
class TrackMgr
|
||||
{
|
||||
protected:
|
||||
const mkvparser::Track* fTrack;
|
||||
const mkvparser::BlockEntry* fCurrentBlock;
|
||||
Int32 fStatus;
|
||||
|
||||
public:
|
||||
TrackMgr(const mkvparser::Track* track) : fTrack(track), fCurrentBlock(nullptr), fStatus(0) { }
|
||||
|
||||
const mkvparser::Track* GetTrack() { return fTrack; }
|
||||
|
||||
bool GetFrames(mkvparser::MkvReader* reader, Int64 movieTimeNs, std::vector<blkbuf_t>& frames)
|
||||
{
|
||||
// If we have no block yet, grab the first one
|
||||
if (!fCurrentBlock)
|
||||
fStatus = fTrack->GetFirst(fCurrentBlock);
|
||||
|
||||
// Continue through the blocks until our current movie time
|
||||
while (fCurrentBlock && fStatus == 0) {
|
||||
const mkvparser::Block* block = fCurrentBlock->GetBlock();
|
||||
Int64 time = block->GetTime(fCurrentBlock->GetCluster()) - fTrack->GetCodecDelay();
|
||||
if (time <= movieTimeNs) {
|
||||
// We want to play this block, add it to the frames buffer
|
||||
frames.reserve(frames.size() + block->GetFrameCount());
|
||||
for (Int32 i = 0; i < block->GetFrameCount(); i++) {
|
||||
const mkvparser::Block::Frame data = block->GetFrame(i);
|
||||
UInt8* buf = new UInt8[data.len];
|
||||
data.Read(reader, buf);
|
||||
frames.push_back(std::make_pair(std::auto_ptr<UInt8>(buf), static_cast<Int32>(data.len)));
|
||||
}
|
||||
fStatus = fTrack->GetNext(fCurrentBlock, fCurrentBlock);
|
||||
} else {
|
||||
// We've got all frames that have to play... come back for more later!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // No more blocks... We're done!
|
||||
}
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
|
||||
plMoviePlayer::plMoviePlayer()
|
||||
: fPlate(nullptr),
|
||||
fTexture(nullptr),
|
||||
fReader(nullptr),
|
||||
fMovieTime(0),
|
||||
fLastFrameTime(0),
|
||||
fPosition(hsPoint2()),
|
||||
fPlaying(false),
|
||||
fPaused(false),
|
||||
fMoviePath(nullptr)
|
||||
{
|
||||
fScale.Set(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
plMoviePlayer::~plMoviePlayer()
|
||||
{
|
||||
if (fPlate)
|
||||
// The plPlate owns the Mipmap Texture, so it destroys it for us
|
||||
plPlateManager::Instance().DestroyPlate(fPlate);
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
if (fReader) {
|
||||
fReader->Close();
|
||||
delete fReader;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool plMoviePlayer::IOpenMovie()
|
||||
{
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
if (!plFileUtils::FileExists(fMoviePath)) {
|
||||
plStatusLog::AddLineS("movie.log", "%s: Tried to play a movie that doesn't exist.", fMoviePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// open the movie with libwebm
|
||||
fReader = new mkvparser::MkvReader;
|
||||
SAFE_OP(fReader->Open(fMoviePath), "open movie");
|
||||
|
||||
// opens the segment
|
||||
// it contains everything you ever want to know about the movie
|
||||
long long pos = 0;
|
||||
mkvparser::EBMLHeader ebmlHeader;
|
||||
SAFE_OP(ebmlHeader.Parse(fReader, pos), "read mkv header");
|
||||
mkvparser::Segment* seg;
|
||||
SAFE_OP(mkvparser::Segment::CreateInstance(fReader, pos, seg), "get segment info");
|
||||
SAFE_OP(seg->Load(), "load segment from webm");
|
||||
fSegment.reset(seg);
|
||||
|
||||
// Use first tracks unless another one matches the current game language
|
||||
const mkvparser::Tracks* tracks = fSegment->GetTracks();
|
||||
for (UInt32 i = 0; i < tracks->GetTracksCount(); ++i) {
|
||||
const mkvparser::Track* track = tracks->GetTrackByIndex(i);
|
||||
if (!track)
|
||||
continue;
|
||||
|
||||
switch (track->GetType()) {
|
||||
case mkvparser::Track::kAudio:
|
||||
if (!fAudioTrack.get() || ICheckLanguage(track))
|
||||
fAudioTrack.reset(new TrackMgr(track));
|
||||
break;
|
||||
case mkvparser::Track::kVideo:
|
||||
if (!fVideoTrack.get() || ICheckLanguage(track))
|
||||
fVideoTrack.reset(new TrackMgr(track));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool plMoviePlayer::ILoadAudio()
|
||||
{
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
// Fetch audio track information
|
||||
if (!fAudioTrack.get())
|
||||
return false;
|
||||
const mkvparser::AudioTrack* audio = static_cast<const mkvparser::AudioTrack*>(fAudioTrack->GetTrack());
|
||||
plWAVHeader header;
|
||||
header.fFormatTag = plWAVHeader::kPCMFormatTag;
|
||||
header.fNumChannels = audio->GetChannels();
|
||||
header.fBitsPerSample = audio->GetBitDepth() == 8 ? 8 : 16;
|
||||
header.fNumSamplesPerSec = 48000; // OPUS specs say we shall always decode at 48kHz
|
||||
header.fBlockAlign = header.fNumChannels * header.fBitsPerSample / 8;
|
||||
header.fAvgBytesPerSec = header.fNumSamplesPerSec * header.fBlockAlign;
|
||||
fAudioSound.reset(new plWin32VideoSound(header));
|
||||
|
||||
// Initialize Opus
|
||||
if (strncmp(audio->GetCodecId(), WEBM_CODECID_OPUS, arrsize(WEBM_CODECID_OPUS)) != 0) {
|
||||
plStatusLog::AddLineS("movie.log", "%s: Not an Opus audio track!", fMoviePath);
|
||||
return false;
|
||||
}
|
||||
int error;
|
||||
OpusDecoder* opus = opus_decoder_create(48000, audio->GetChannels(), &error);
|
||||
if (error != OPUS_OK)
|
||||
hsAssert(false, "Error occured initalizing opus");
|
||||
|
||||
// Decode audio track
|
||||
std::vector<blkbuf_t> frames;
|
||||
fAudioTrack->GetFrames(fReader, fSegment->GetDuration(), frames);
|
||||
static const int maxFrameSize = 5760; // for max packet duration at 48kHz
|
||||
std::vector<Int16> decoded;
|
||||
decoded.reserve(frames.size() * audio->GetChannels() * maxFrameSize);
|
||||
|
||||
Int16* frameData = new Int16[maxFrameSize * audio->GetChannels()];
|
||||
for (std::vector<blkbuf_t>::iterator& frame = frames.begin(); frame != frames.end(); frame++) {
|
||||
const std::auto_ptr<UInt8>& buf = frame->first;
|
||||
Int32 size = frame->second;
|
||||
|
||||
int samples = opus_decode(opus, buf.get(), size, frameData, maxFrameSize, 0);
|
||||
if (samples < 0)
|
||||
hsAssert(false, "opus error");
|
||||
for (size_t i = 0; i < samples * audio->GetChannels(); i++)
|
||||
decoded.push_back(frameData[i]);
|
||||
}
|
||||
delete[] frameData;
|
||||
|
||||
fAudioSound->FillSoundBuffer(reinterpret_cast<UInt8*>(decoded.data()), decoded.size() * sizeof(Int16));
|
||||
opus_decoder_destroy(opus);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool plMoviePlayer::ICheckLanguage(const mkvparser::Track* track)
|
||||
{
|
||||
std::set<std::string> codes = plLocalization::GetLanguageCodes(plLocalization::GetLanguage());
|
||||
if (codes.find(track->GetLanguage()) != codes.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void plMoviePlayer::IProcessVideoFrame(const std::vector<blkbuf_t>& frames)
|
||||
{
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
vpx_image_t* img = nullptr;
|
||||
|
||||
// We have to decode all the frames, but we only want to display the most recent one to the user.
|
||||
for (std::vector<blkbuf_t>::const_iterator frame = frames.begin(); frame != frames.end(); frame++) {
|
||||
const std::auto_ptr<UInt8>& buf = frame->first;
|
||||
UInt32 size = static_cast<UInt32>(frame->second);
|
||||
img = fVpx->Decode(buf.get(), size);
|
||||
}
|
||||
|
||||
if (img) {
|
||||
// According to VideoLAN[1], I420 is the most common image format in videos. I am inclined to believe this as our
|
||||
// attemps to convert the common Uru videos use I420 image data. So, as a shortcut, we will only implement that format.
|
||||
// If for some reason we need other formats, please, be my guest!
|
||||
// [1] = http://wiki.videolan.org/YUV#YUV_4:2:0_.28I420.2FJ420.2FYV12.29
|
||||
switch (img->fmt) {
|
||||
case VPX_IMG_FMT_I420:
|
||||
plPlanarImage::Yuv420ToRgba(img->d_w, img->d_h, reinterpret_cast<const Int32*>(img->stride), img->planes, reinterpret_cast<UInt8*>(fTexture->GetImage()));
|
||||
break;
|
||||
|
||||
default:
|
||||
hsAssert(false, "image format");
|
||||
}
|
||||
|
||||
// Flush new data to the device
|
||||
if (fTexture->GetDeviceRef())
|
||||
fTexture->GetDeviceRef()->SetDirty(true);
|
||||
fPlate->SetVisible(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool plMoviePlayer::Start()
|
||||
{
|
||||
if (fPlaying)
|
||||
return false;
|
||||
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
if (!IOpenMovie())
|
||||
return false;
|
||||
hsAssert(fVideoTrack, "nil video track -- expect bad things to happen!");
|
||||
|
||||
// Initialize VPX
|
||||
const mkvparser::VideoTrack* video = static_cast<const mkvparser::VideoTrack*>(fVideoTrack->GetTrack());
|
||||
if (strncmp(video->GetCodecId(), WEBM_CODECID_VP9, arrsize(WEBM_CODECID_VP9)) != 0) {
|
||||
plStatusLog::AddLineS("movie.log", "%s: Not a VP9 video track!", fMoviePath);
|
||||
return false;
|
||||
}
|
||||
if (VPX* vpx = VPX::Create())
|
||||
fVpx.reset(vpx);
|
||||
else
|
||||
return false;
|
||||
|
||||
// Decode the audio track and load it into a sound buffer
|
||||
if (!ILoadAudio())
|
||||
return false;
|
||||
|
||||
fLastFrameTime = static_cast<Int64>(hsTimer::GetMilliSeconds());
|
||||
fAudioSound->Play();
|
||||
fPlaying = true;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif // MOVIE_AVAILABLE
|
||||
}
|
||||
|
||||
void plMoviePlayer::IInitPlate(UInt32 width, UInt32 height)
|
||||
{
|
||||
// Need to figure out scaling based on pipe size.
|
||||
plPlateManager& plateMgr = plPlateManager::Instance();
|
||||
float plateWidth = width * fScale.fX;
|
||||
float plateHeight = height * fScale.fY;
|
||||
if (plateWidth > plateMgr.GetPipeWidth() || plateHeight > plateMgr.GetPipeHeight()) {
|
||||
float scale = std::min(plateMgr.GetPipeWidth() / plateWidth, plateMgr.GetPipeHeight() / plateHeight);
|
||||
plateWidth *= scale;
|
||||
plateHeight *= scale;
|
||||
}
|
||||
plateMgr.CreatePlate(&fPlate, fPosition.fX, fPosition.fY, 0, 0);
|
||||
plateMgr.SetPlatePixelSize(fPlate, plateWidth, plateHeight);
|
||||
fTexture = fPlate->CreateMaterial(width, height, false);
|
||||
}
|
||||
|
||||
bool plMoviePlayer::NextFrame()
|
||||
{
|
||||
if (!fPlaying)
|
||||
return false;
|
||||
|
||||
Int64 frameTime = static_cast<Int64>(hsTimer::GetMilliSeconds());
|
||||
Int64 frameTimeDelta = frameTime - fLastFrameTime;
|
||||
fLastFrameTime = frameTime;
|
||||
|
||||
if (fPaused)
|
||||
return true;
|
||||
|
||||
#ifdef PLASMA_USE_WEBM
|
||||
// Get our current timecode
|
||||
fMovieTime += frameTimeDelta;
|
||||
|
||||
std::vector<blkbuf_t> video;
|
||||
if (fVideoTrack.get() != nullptr || !fVideoTrack->GetFrames(fReader, fMovieTime * 1000000, video)) {
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the pipeline's device was invalidated, the plate will be invalid. Recreate now.
|
||||
if (!fPlate) {
|
||||
const mkvparser::VideoTrack* vt = static_cast<const mkvparser::VideoTrack*>(fVideoTrack->GetTrack());
|
||||
IInitPlate(static_cast<UInt32>(vt->GetWidth()), static_cast<UInt32>(vt->GetHeight()));
|
||||
hsAssert(fPlate, "failed to init plMoviePlayer plate -- bad things will happen!");
|
||||
}
|
||||
|
||||
// Show our mess
|
||||
IProcessVideoFrame(video);
|
||||
fAudioSound->RefreshVolume();
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif // MOVIE_AVAILABLE
|
||||
}
|
||||
|
||||
bool plMoviePlayer::Pause(bool on)
|
||||
{
|
||||
if (!fPlaying)
|
||||
return false;
|
||||
|
||||
fAudioSound->Pause(on);
|
||||
fPaused = on;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool plMoviePlayer::Stop()
|
||||
{
|
||||
fPlaying = false;
|
||||
if (fAudioSound.get() != nullptr)
|
||||
fAudioSound->Stop();
|
||||
if (fPlate)
|
||||
fPlate->SetVisible(false);
|
||||
|
||||
for (std::vector<plMessage*>::iterator cb = fCallbacks.begin(); cb != fCallbacks.end(); cb++)
|
||||
(*cb)->Send();
|
||||
fCallbacks.clear();
|
||||
return true;
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef _plMoviePlayer_inc
|
||||
#define _plMoviePlayer_inc
|
||||
|
||||
#include "HeadSpin.h"
|
||||
#include "hsPoint2.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "../plMessage/plMovieMsg.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace mkvparser
|
||||
{
|
||||
class BlockEntry;
|
||||
class MkvReader;
|
||||
class Segment;
|
||||
class Track;
|
||||
}
|
||||
|
||||
typedef std::pair<std::auto_ptr<UInt8>, UInt32> blkbuf_t;
|
||||
|
||||
class plMoviePlayer
|
||||
{
|
||||
protected:
|
||||
class plPlate* fPlate;
|
||||
class plMipmap* fTexture;
|
||||
|
||||
mkvparser::MkvReader* fReader;
|
||||
std::auto_ptr<mkvparser::Segment> fSegment;
|
||||
std::auto_ptr<class TrackMgr> fAudioTrack, fVideoTrack; // TODO: vector of tracks?
|
||||
std::auto_ptr<class plWin32VideoSound> fAudioSound;
|
||||
std::auto_ptr<class VPX> fVpx;
|
||||
|
||||
UInt64 fMovieTime, fLastFrameTime; // in ms
|
||||
hsPoint2 fPosition, fScale;
|
||||
const char *fMoviePath;
|
||||
|
||||
bool fPlaying;
|
||||
bool fPaused;
|
||||
|
||||
void IInitPlate(UInt32 width, UInt32 height);
|
||||
|
||||
bool IOpenMovie();
|
||||
bool ILoadAudio();
|
||||
bool ICheckLanguage(const mkvparser::Track* track);
|
||||
void IProcessVideoFrame(const std::vector<blkbuf_t>& frames);
|
||||
|
||||
public:
|
||||
plMoviePlayer();
|
||||
~plMoviePlayer();
|
||||
|
||||
bool Start();
|
||||
bool Pause(bool on);
|
||||
bool Stop();
|
||||
bool NextFrame();
|
||||
|
||||
void AddCallback(plMessage* msg) { hsRefCnt_SafeRef(msg); fCallbacks.push_back(msg); }
|
||||
UInt32 GetNumCallbacks() const { return 0; }
|
||||
plMessage* GetCallback(int i) const { return nullptr; }
|
||||
|
||||
const char *GetFileName() const { return fMoviePath; }
|
||||
void SetFileName(const char* filename) { fMoviePath = filename; }
|
||||
|
||||
void SetColor(const hsColorRGBA& c) { }
|
||||
const hsColorRGBA GetColor() const { return hsColorRGBA(); }
|
||||
|
||||
/** The volume is handled by the options menu slider, as of now. */
|
||||
void SetVolume(float v) { }
|
||||
|
||||
hsPoint2 GetPosition() const { return fPosition; }
|
||||
void SetPosition(const hsPoint2& pos) { fPosition = pos; }
|
||||
void SetPosition(float x, float y) { fPosition.Set(x, y); }
|
||||
|
||||
hsPoint2 GetScale() const { return fScale; }
|
||||
void SetScale(const hsPoint2& scale) { fScale = scale; }
|
||||
void SetScale(float x, float y) { fScale.Set(x, y); }
|
||||
|
||||
void SetFadeFromTime(float secs) { }
|
||||
void SetFadeFromColor(hsColorRGBA c) { }
|
||||
|
||||
void SetFadeToTime(float secs) { }
|
||||
void SetFadeToColor(hsColorRGBA c) { }
|
||||
|
||||
private:
|
||||
std::vector<plMessage*> fCallbacks;
|
||||
};
|
||||
|
||||
#endif // _plMoviePlayer_inc
|
@ -0,0 +1,97 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "plPlanarImage.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static UInt8 Clip(UInt32 val) {
|
||||
if (val < 0) {
|
||||
return 0;
|
||||
} else if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
return static_cast<UInt8>(val);
|
||||
}
|
||||
|
||||
#define YG 74 /* static_cast<int8>(1.164 * 64 + 0.5) */
|
||||
|
||||
#define UB 127 /* min(63,static_cast<int8>(2.018 * 64)) */
|
||||
#define UG -25 /* static_cast<int8>(-0.391 * 64 - 0.5) */
|
||||
#define UR 0
|
||||
|
||||
#define VB 0
|
||||
#define VG -52 /* static_cast<int8>(-0.813 * 64 - 0.5) */
|
||||
#define VR 102 /* static_cast<int8>(1.596 * 64 + 0.5) */
|
||||
|
||||
// Bias
|
||||
#define BB UB * 128 + VB * 128
|
||||
#define BG UG * 128 + VG * 128
|
||||
#define BR UR * 128 + VR * 128
|
||||
|
||||
void plPlanarImage::Yuv420ToRgba(UInt32 w, UInt32 h, const Int32* stride, UInt8** planes, UInt8* const dest)
|
||||
{
|
||||
const UInt8* y_src = planes[0];
|
||||
const UInt8* u_src = planes[1];
|
||||
const UInt8* v_src = planes[2];
|
||||
|
||||
for (UInt32 i = 0; i < h; ++i)
|
||||
{
|
||||
for (UInt32 j = 0; j < w; ++j)
|
||||
{
|
||||
size_t y_idx = stride[0] * i + j;
|
||||
size_t u_idx = stride[1] * (i/2) + (j/2);
|
||||
size_t v_idx = stride[2] * (i/2) + (j/2);
|
||||
size_t dest_idx = w * i + j;
|
||||
|
||||
UInt32 y = static_cast<UInt32>(y_src[y_idx]);
|
||||
UInt32 u = static_cast<UInt32>(u_src[u_idx]);
|
||||
UInt32 v = static_cast<UInt32>(v_src[v_idx]);
|
||||
UInt32 y1 = (y - 16) * YG;
|
||||
|
||||
dest[dest_idx*4+0] = Clip(((u * UB + v * VB) - (BB) + y1) >> 6);
|
||||
dest[dest_idx*4+1] = Clip(((u * UG + v * VG) - (BG) + y1) >> 6);
|
||||
dest[dest_idx*4+2] = Clip(((u * UR + v * VR) - (BR) + y1) >> 6);
|
||||
dest[dest_idx*4+3] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef _plPlanarImage_inc
|
||||
#define _plPlanarImage_inc
|
||||
|
||||
#include "HeadSpin.h"
|
||||
|
||||
namespace plPlanarImage
|
||||
{
|
||||
void Yuv420ToRgba(UInt32 w, UInt32 h, const Int32* stride, UInt8** planes, UInt8* const dest);
|
||||
};
|
||||
|
||||
#endif // _plPlanarImage_inc
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,945 @@
|
||||
// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
#ifndef MKVPARSER_HPP
|
||||
#define MKVPARSER_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstddef>
|
||||
|
||||
namespace mkvparser {
|
||||
|
||||
const int E_FILE_FORMAT_INVALID = -2;
|
||||
const int E_BUFFER_NOT_FULL = -3;
|
||||
|
||||
class IMkvReader {
|
||||
public:
|
||||
virtual int Read(long long pos, long len, unsigned char* buf) = 0;
|
||||
virtual int Length(long long* total, long long* available) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IMkvReader();
|
||||
};
|
||||
|
||||
long long GetUIntLength(IMkvReader*, long long, long&);
|
||||
long long ReadUInt(IMkvReader*, long long, long&);
|
||||
long long UnserializeUInt(IMkvReader*, long long pos, long long size);
|
||||
|
||||
long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
|
||||
long UnserializeInt(IMkvReader*, long long pos, long len, long long& result);
|
||||
|
||||
long UnserializeString(IMkvReader*, long long pos, long long size, char*& str);
|
||||
|
||||
long ParseElementHeader(IMkvReader* pReader,
|
||||
long long& pos, // consume id and size fields
|
||||
long long stop, // if you know size of element's parent
|
||||
long long& id, long long& size);
|
||||
|
||||
bool Match(IMkvReader*, long long&, unsigned long, long long&);
|
||||
bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);
|
||||
|
||||
void GetVersion(int& major, int& minor, int& build, int& revision);
|
||||
|
||||
struct EBMLHeader {
|
||||
EBMLHeader();
|
||||
~EBMLHeader();
|
||||
long long m_version;
|
||||
long long m_readVersion;
|
||||
long long m_maxIdLength;
|
||||
long long m_maxSizeLength;
|
||||
char* m_docType;
|
||||
long long m_docTypeVersion;
|
||||
long long m_docTypeReadVersion;
|
||||
|
||||
long long Parse(IMkvReader*, long long&);
|
||||
void Init();
|
||||
};
|
||||
|
||||
class Segment;
|
||||
class Track;
|
||||
class Cluster;
|
||||
|
||||
class Block {
|
||||
Block(const Block&);
|
||||
Block& operator=(const Block&);
|
||||
|
||||
public:
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
|
||||
Block(long long start, long long size, long long discard_padding);
|
||||
~Block();
|
||||
|
||||
long Parse(const Cluster*);
|
||||
|
||||
long long GetTrackNumber() const;
|
||||
long long GetTimeCode(const Cluster*) const; // absolute, but not scaled
|
||||
long long GetTime(const Cluster*) const; // absolute, and scaled (ns)
|
||||
bool IsKey() const;
|
||||
void SetKey(bool);
|
||||
bool IsInvisible() const;
|
||||
|
||||
enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
|
||||
Lacing GetLacing() const;
|
||||
|
||||
int GetFrameCount() const; // to index frames: [0, count)
|
||||
|
||||
struct Frame {
|
||||
long long pos; // absolute offset
|
||||
long len;
|
||||
|
||||
long Read(IMkvReader*, unsigned char*) const;
|
||||
};
|
||||
|
||||
const Frame& GetFrame(int frame_index) const;
|
||||
|
||||
long long GetDiscardPadding() const;
|
||||
|
||||
private:
|
||||
long long m_track; // Track::Number()
|
||||
short m_timecode; // relative to cluster
|
||||
unsigned char m_flags;
|
||||
|
||||
Frame* m_frames;
|
||||
int m_frame_count;
|
||||
|
||||
protected:
|
||||
const long long m_discard_padding;
|
||||
};
|
||||
|
||||
class BlockEntry {
|
||||
BlockEntry(const BlockEntry&);
|
||||
BlockEntry& operator=(const BlockEntry&);
|
||||
|
||||
protected:
|
||||
BlockEntry(Cluster*, long index);
|
||||
|
||||
public:
|
||||
virtual ~BlockEntry();
|
||||
|
||||
bool EOS() const;
|
||||
const Cluster* GetCluster() const;
|
||||
long GetIndex() const;
|
||||
virtual const Block* GetBlock() const = 0;
|
||||
|
||||
enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
|
||||
virtual Kind GetKind() const = 0;
|
||||
|
||||
protected:
|
||||
Cluster* const m_pCluster;
|
||||
const long m_index;
|
||||
};
|
||||
|
||||
class SimpleBlock : public BlockEntry {
|
||||
SimpleBlock(const SimpleBlock&);
|
||||
SimpleBlock& operator=(const SimpleBlock&);
|
||||
|
||||
public:
|
||||
SimpleBlock(Cluster*, long index, long long start, long long size);
|
||||
long Parse();
|
||||
|
||||
Kind GetKind() const;
|
||||
const Block* GetBlock() const;
|
||||
|
||||
protected:
|
||||
Block m_block;
|
||||
};
|
||||
|
||||
class BlockGroup : public BlockEntry {
|
||||
BlockGroup(const BlockGroup&);
|
||||
BlockGroup& operator=(const BlockGroup&);
|
||||
|
||||
public:
|
||||
BlockGroup(Cluster*, long index,
|
||||
long long block_start, // absolute pos of block's payload
|
||||
long long block_size, // size of block's payload
|
||||
long long prev, long long next, long long duration,
|
||||
long long discard_padding);
|
||||
|
||||
long Parse();
|
||||
|
||||
Kind GetKind() const;
|
||||
const Block* GetBlock() const;
|
||||
|
||||
long long GetPrevTimeCode() const; // relative to block's time
|
||||
long long GetNextTimeCode() const; // as above
|
||||
long long GetDurationTimeCode() const;
|
||||
|
||||
private:
|
||||
Block m_block;
|
||||
const long long m_prev;
|
||||
const long long m_next;
|
||||
const long long m_duration;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// ContentEncoding element
|
||||
// Elements used to describe if the track data has been encrypted or
|
||||
// compressed with zlib or header stripping.
|
||||
class ContentEncoding {
|
||||
public:
|
||||
enum { kCTR = 1 };
|
||||
|
||||
ContentEncoding();
|
||||
~ContentEncoding();
|
||||
|
||||
// ContentCompression element names
|
||||
struct ContentCompression {
|
||||
ContentCompression();
|
||||
~ContentCompression();
|
||||
|
||||
unsigned long long algo;
|
||||
unsigned char* settings;
|
||||
long long settings_len;
|
||||
};
|
||||
|
||||
// ContentEncAESSettings element names
|
||||
struct ContentEncAESSettings {
|
||||
ContentEncAESSettings() : cipher_mode(kCTR) {}
|
||||
~ContentEncAESSettings() {}
|
||||
|
||||
unsigned long long cipher_mode;
|
||||
};
|
||||
|
||||
// ContentEncryption element names
|
||||
struct ContentEncryption {
|
||||
ContentEncryption();
|
||||
~ContentEncryption();
|
||||
|
||||
unsigned long long algo;
|
||||
unsigned char* key_id;
|
||||
long long key_id_len;
|
||||
unsigned char* signature;
|
||||
long long signature_len;
|
||||
unsigned char* sig_key_id;
|
||||
long long sig_key_id_len;
|
||||
unsigned long long sig_algo;
|
||||
unsigned long long sig_hash_algo;
|
||||
|
||||
ContentEncAESSettings aes_settings;
|
||||
};
|
||||
|
||||
// Returns ContentCompression represented by |idx|. Returns NULL if |idx|
|
||||
// is out of bounds.
|
||||
const ContentCompression* GetCompressionByIndex(unsigned long idx) const;
|
||||
|
||||
// Returns number of ContentCompression elements in this ContentEncoding
|
||||
// element.
|
||||
unsigned long GetCompressionCount() const;
|
||||
|
||||
// Parses the ContentCompression element from |pReader|. |start| is the
|
||||
// starting offset of the ContentCompression payload. |size| is the size in
|
||||
// bytes of the ContentCompression payload. |compression| is where the parsed
|
||||
// values will be stored.
|
||||
long ParseCompressionEntry(long long start, long long size,
|
||||
IMkvReader* pReader,
|
||||
ContentCompression* compression);
|
||||
|
||||
// Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
|
||||
// is out of bounds.
|
||||
const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
|
||||
|
||||
// Returns number of ContentEncryption elements in this ContentEncoding
|
||||
// element.
|
||||
unsigned long GetEncryptionCount() const;
|
||||
|
||||
// Parses the ContentEncAESSettings element from |pReader|. |start| is the
|
||||
// starting offset of the ContentEncAESSettings payload. |size| is the
|
||||
// size in bytes of the ContentEncAESSettings payload. |encryption| is
|
||||
// where the parsed values will be stored.
|
||||
long ParseContentEncAESSettingsEntry(long long start, long long size,
|
||||
IMkvReader* pReader,
|
||||
ContentEncAESSettings* aes);
|
||||
|
||||
// Parses the ContentEncoding element from |pReader|. |start| is the
|
||||
// starting offset of the ContentEncoding payload. |size| is the size in
|
||||
// bytes of the ContentEncoding payload. Returns true on success.
|
||||
long ParseContentEncodingEntry(long long start, long long size,
|
||||
IMkvReader* pReader);
|
||||
|
||||
// Parses the ContentEncryption element from |pReader|. |start| is the
|
||||
// starting offset of the ContentEncryption payload. |size| is the size in
|
||||
// bytes of the ContentEncryption payload. |encryption| is where the parsed
|
||||
// values will be stored.
|
||||
long ParseEncryptionEntry(long long start, long long size,
|
||||
IMkvReader* pReader, ContentEncryption* encryption);
|
||||
|
||||
unsigned long long encoding_order() const { return encoding_order_; }
|
||||
unsigned long long encoding_scope() const { return encoding_scope_; }
|
||||
unsigned long long encoding_type() const { return encoding_type_; }
|
||||
|
||||
private:
|
||||
// Member variables for list of ContentCompression elements.
|
||||
ContentCompression** compression_entries_;
|
||||
ContentCompression** compression_entries_end_;
|
||||
|
||||
// Member variables for list of ContentEncryption elements.
|
||||
ContentEncryption** encryption_entries_;
|
||||
ContentEncryption** encryption_entries_end_;
|
||||
|
||||
// ContentEncoding element names
|
||||
unsigned long long encoding_order_;
|
||||
unsigned long long encoding_scope_;
|
||||
unsigned long long encoding_type_;
|
||||
|
||||
// LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
|
||||
ContentEncoding(const ContentEncoding&);
|
||||
ContentEncoding& operator=(const ContentEncoding&);
|
||||
};
|
||||
|
||||
class Track {
|
||||
Track(const Track&);
|
||||
Track& operator=(const Track&);
|
||||
|
||||
public:
|
||||
class Info;
|
||||
static long Create(Segment*, const Info&, long long element_start,
|
||||
long long element_size, Track*&);
|
||||
|
||||
enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 };
|
||||
|
||||
Segment* const m_pSegment;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
virtual ~Track();
|
||||
|
||||
long GetType() const;
|
||||
long GetNumber() const;
|
||||
unsigned long long GetUid() const;
|
||||
const char* GetNameAsUTF8() const;
|
||||
const char* GetLanguage() const;
|
||||
const char* GetCodecNameAsUTF8() const;
|
||||
const char* GetCodecId() const;
|
||||
const unsigned char* GetCodecPrivate(size_t&) const;
|
||||
bool GetLacing() const;
|
||||
unsigned long long GetDefaultDuration() const;
|
||||
unsigned long long GetCodecDelay() const;
|
||||
unsigned long long GetSeekPreRoll() const;
|
||||
|
||||
const BlockEntry* GetEOS() const;
|
||||
|
||||
struct Settings {
|
||||
long long start;
|
||||
long long size;
|
||||
};
|
||||
|
||||
class Info {
|
||||
public:
|
||||
Info();
|
||||
~Info();
|
||||
int Copy(Info&) const;
|
||||
void Clear();
|
||||
long type;
|
||||
long number;
|
||||
unsigned long long uid;
|
||||
unsigned long long defaultDuration;
|
||||
unsigned long long codecDelay;
|
||||
unsigned long long seekPreRoll;
|
||||
char* nameAsUTF8;
|
||||
char* language;
|
||||
char* codecId;
|
||||
char* codecNameAsUTF8;
|
||||
unsigned char* codecPrivate;
|
||||
size_t codecPrivateSize;
|
||||
bool lacing;
|
||||
Settings settings;
|
||||
|
||||
private:
|
||||
Info(const Info&);
|
||||
Info& operator=(const Info&);
|
||||
int CopyStr(char* Info::*str, Info&) const;
|
||||
};
|
||||
|
||||
long GetFirst(const BlockEntry*&) const;
|
||||
long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
|
||||
virtual bool VetEntry(const BlockEntry*) const;
|
||||
virtual long Seek(long long time_ns, const BlockEntry*&) const;
|
||||
|
||||
const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
|
||||
unsigned long GetContentEncodingCount() const;
|
||||
|
||||
long ParseContentEncodingsEntry(long long start, long long size);
|
||||
|
||||
protected:
|
||||
Track(Segment*, long long element_start, long long element_size);
|
||||
|
||||
Info m_info;
|
||||
|
||||
class EOSBlock : public BlockEntry {
|
||||
public:
|
||||
EOSBlock();
|
||||
|
||||
Kind GetKind() const;
|
||||
const Block* GetBlock() const;
|
||||
};
|
||||
|
||||
EOSBlock m_eos;
|
||||
|
||||
private:
|
||||
ContentEncoding** content_encoding_entries_;
|
||||
ContentEncoding** content_encoding_entries_end_;
|
||||
};
|
||||
|
||||
class VideoTrack : public Track {
|
||||
VideoTrack(const VideoTrack&);
|
||||
VideoTrack& operator=(const VideoTrack&);
|
||||
|
||||
VideoTrack(Segment*, long long element_start, long long element_size);
|
||||
|
||||
public:
|
||||
static long Parse(Segment*, const Info&, long long element_start,
|
||||
long long element_size, VideoTrack*&);
|
||||
|
||||
long long GetWidth() const;
|
||||
long long GetHeight() const;
|
||||
double GetFrameRate() const;
|
||||
|
||||
bool VetEntry(const BlockEntry*) const;
|
||||
long Seek(long long time_ns, const BlockEntry*&) const;
|
||||
|
||||
private:
|
||||
long long m_width;
|
||||
long long m_height;
|
||||
double m_rate;
|
||||
};
|
||||
|
||||
class AudioTrack : public Track {
|
||||
AudioTrack(const AudioTrack&);
|
||||
AudioTrack& operator=(const AudioTrack&);
|
||||
|
||||
AudioTrack(Segment*, long long element_start, long long element_size);
|
||||
|
||||
public:
|
||||
static long Parse(Segment*, const Info&, long long element_start,
|
||||
long long element_size, AudioTrack*&);
|
||||
|
||||
double GetSamplingRate() const;
|
||||
long long GetChannels() const;
|
||||
long long GetBitDepth() const;
|
||||
|
||||
private:
|
||||
double m_rate;
|
||||
long long m_channels;
|
||||
long long m_bitDepth;
|
||||
};
|
||||
|
||||
class Tracks {
|
||||
Tracks(const Tracks&);
|
||||
Tracks& operator=(const Tracks&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
|
||||
Tracks(Segment*, long long start, long long size, long long element_start,
|
||||
long long element_size);
|
||||
|
||||
~Tracks();
|
||||
|
||||
long Parse();
|
||||
|
||||
unsigned long GetTracksCount() const;
|
||||
|
||||
const Track* GetTrackByNumber(long tn) const;
|
||||
const Track* GetTrackByIndex(unsigned long idx) const;
|
||||
|
||||
private:
|
||||
Track** m_trackEntries;
|
||||
Track** m_trackEntriesEnd;
|
||||
|
||||
long ParseTrackEntry(long long payload_start, long long payload_size,
|
||||
long long element_start, long long element_size,
|
||||
Track*&) const;
|
||||
};
|
||||
|
||||
class Chapters {
|
||||
Chapters(const Chapters&);
|
||||
Chapters& operator=(const Chapters&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
|
||||
Chapters(Segment*, long long payload_start, long long payload_size,
|
||||
long long element_start, long long element_size);
|
||||
|
||||
~Chapters();
|
||||
|
||||
long Parse();
|
||||
|
||||
class Atom;
|
||||
class Edition;
|
||||
|
||||
class Display {
|
||||
friend class Atom;
|
||||
Display();
|
||||
Display(const Display&);
|
||||
~Display();
|
||||
Display& operator=(const Display&);
|
||||
|
||||
public:
|
||||
const char* GetString() const;
|
||||
const char* GetLanguage() const;
|
||||
const char* GetCountry() const;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void ShallowCopy(Display&) const;
|
||||
void Clear();
|
||||
long Parse(IMkvReader*, long long pos, long long size);
|
||||
|
||||
char* m_string;
|
||||
char* m_language;
|
||||
char* m_country;
|
||||
};
|
||||
|
||||
class Atom {
|
||||
friend class Edition;
|
||||
Atom();
|
||||
Atom(const Atom&);
|
||||
~Atom();
|
||||
Atom& operator=(const Atom&);
|
||||
|
||||
public:
|
||||
unsigned long long GetUID() const;
|
||||
const char* GetStringUID() const;
|
||||
|
||||
long long GetStartTimecode() const;
|
||||
long long GetStopTimecode() const;
|
||||
|
||||
long long GetStartTime(const Chapters*) const;
|
||||
long long GetStopTime(const Chapters*) const;
|
||||
|
||||
int GetDisplayCount() const;
|
||||
const Display* GetDisplay(int index) const;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void ShallowCopy(Atom&) const;
|
||||
void Clear();
|
||||
long Parse(IMkvReader*, long long pos, long long size);
|
||||
static long long GetTime(const Chapters*, long long timecode);
|
||||
|
||||
long ParseDisplay(IMkvReader*, long long pos, long long size);
|
||||
bool ExpandDisplaysArray();
|
||||
|
||||
char* m_string_uid;
|
||||
unsigned long long m_uid;
|
||||
long long m_start_timecode;
|
||||
long long m_stop_timecode;
|
||||
|
||||
Display* m_displays;
|
||||
int m_displays_size;
|
||||
int m_displays_count;
|
||||
};
|
||||
|
||||
class Edition {
|
||||
friend class Chapters;
|
||||
Edition();
|
||||
Edition(const Edition&);
|
||||
~Edition();
|
||||
Edition& operator=(const Edition&);
|
||||
|
||||
public:
|
||||
int GetAtomCount() const;
|
||||
const Atom* GetAtom(int index) const;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void ShallowCopy(Edition&) const;
|
||||
void Clear();
|
||||
long Parse(IMkvReader*, long long pos, long long size);
|
||||
|
||||
long ParseAtom(IMkvReader*, long long pos, long long size);
|
||||
bool ExpandAtomsArray();
|
||||
|
||||
Atom* m_atoms;
|
||||
int m_atoms_size;
|
||||
int m_atoms_count;
|
||||
};
|
||||
|
||||
int GetEditionCount() const;
|
||||
const Edition* GetEdition(int index) const;
|
||||
|
||||
private:
|
||||
long ParseEdition(long long pos, long long size);
|
||||
bool ExpandEditionsArray();
|
||||
|
||||
Edition* m_editions;
|
||||
int m_editions_size;
|
||||
int m_editions_count;
|
||||
};
|
||||
|
||||
class SegmentInfo {
|
||||
SegmentInfo(const SegmentInfo&);
|
||||
SegmentInfo& operator=(const SegmentInfo&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
|
||||
SegmentInfo(Segment*, long long start, long long size,
|
||||
long long element_start, long long element_size);
|
||||
|
||||
~SegmentInfo();
|
||||
|
||||
long Parse();
|
||||
|
||||
long long GetTimeCodeScale() const;
|
||||
long long GetDuration() const; // scaled
|
||||
const char* GetMuxingAppAsUTF8() const;
|
||||
const char* GetWritingAppAsUTF8() const;
|
||||
const char* GetTitleAsUTF8() const;
|
||||
|
||||
private:
|
||||
long long m_timecodeScale;
|
||||
double m_duration;
|
||||
char* m_pMuxingAppAsUTF8;
|
||||
char* m_pWritingAppAsUTF8;
|
||||
char* m_pTitleAsUTF8;
|
||||
};
|
||||
|
||||
class SeekHead {
|
||||
SeekHead(const SeekHead&);
|
||||
SeekHead& operator=(const SeekHead&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
|
||||
SeekHead(Segment*, long long start, long long size, long long element_start,
|
||||
long long element_size);
|
||||
|
||||
~SeekHead();
|
||||
|
||||
long Parse();
|
||||
|
||||
struct Entry {
|
||||
// the SeekHead entry payload
|
||||
long long id;
|
||||
long long pos;
|
||||
|
||||
// absolute pos of SeekEntry ID
|
||||
long long element_start;
|
||||
|
||||
// SeekEntry ID size + size size + payload
|
||||
long long element_size;
|
||||
};
|
||||
|
||||
int GetCount() const;
|
||||
const Entry* GetEntry(int idx) const;
|
||||
|
||||
struct VoidElement {
|
||||
// absolute pos of Void ID
|
||||
long long element_start;
|
||||
|
||||
// ID size + size size + payload size
|
||||
long long element_size;
|
||||
};
|
||||
|
||||
int GetVoidElementCount() const;
|
||||
const VoidElement* GetVoidElement(int idx) const;
|
||||
|
||||
private:
|
||||
Entry* m_entries;
|
||||
int m_entry_count;
|
||||
|
||||
VoidElement* m_void_elements;
|
||||
int m_void_element_count;
|
||||
|
||||
static bool ParseEntry(IMkvReader*,
|
||||
long long pos, // payload
|
||||
long long size, Entry*);
|
||||
};
|
||||
|
||||
class Cues;
|
||||
class CuePoint {
|
||||
friend class Cues;
|
||||
|
||||
CuePoint(long, long long);
|
||||
~CuePoint();
|
||||
|
||||
CuePoint(const CuePoint&);
|
||||
CuePoint& operator=(const CuePoint&);
|
||||
|
||||
public:
|
||||
long long m_element_start;
|
||||
long long m_element_size;
|
||||
|
||||
void Load(IMkvReader*);
|
||||
|
||||
long long GetTimeCode() const; // absolute but unscaled
|
||||
long long GetTime(const Segment*) const; // absolute and scaled (ns units)
|
||||
|
||||
struct TrackPosition {
|
||||
long long m_track;
|
||||
long long m_pos; // of cluster
|
||||
long long m_block;
|
||||
// codec_state //defaults to 0
|
||||
// reference = clusters containing req'd referenced blocks
|
||||
// reftime = timecode of the referenced block
|
||||
|
||||
void Parse(IMkvReader*, long long, long long);
|
||||
};
|
||||
|
||||
const TrackPosition* Find(const Track*) const;
|
||||
|
||||
private:
|
||||
const long m_index;
|
||||
long long m_timecode;
|
||||
TrackPosition* m_track_positions;
|
||||
size_t m_track_positions_count;
|
||||
};
|
||||
|
||||
class Cues {
|
||||
friend class Segment;
|
||||
|
||||
Cues(Segment*, long long start, long long size, long long element_start,
|
||||
long long element_size);
|
||||
~Cues();
|
||||
|
||||
Cues(const Cues&);
|
||||
Cues& operator=(const Cues&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
const long long m_element_start;
|
||||
const long long m_element_size;
|
||||
|
||||
bool Find( // lower bound of time_ns
|
||||
long long time_ns, const Track*, const CuePoint*&,
|
||||
const CuePoint::TrackPosition*&) const;
|
||||
|
||||
#if 0
|
||||
bool FindNext( //upper_bound of time_ns
|
||||
long long time_ns,
|
||||
const Track*,
|
||||
const CuePoint*&,
|
||||
const CuePoint::TrackPosition*&) const;
|
||||
#endif
|
||||
|
||||
const CuePoint* GetFirst() const;
|
||||
const CuePoint* GetLast() const;
|
||||
const CuePoint* GetNext(const CuePoint*) const;
|
||||
|
||||
const BlockEntry* GetBlock(const CuePoint*,
|
||||
const CuePoint::TrackPosition*) const;
|
||||
|
||||
bool LoadCuePoint() const;
|
||||
long GetCount() const; // loaded only
|
||||
// long GetTotal() const; //loaded + preloaded
|
||||
bool DoneParsing() const;
|
||||
|
||||
private:
|
||||
void Init() const;
|
||||
void PreloadCuePoint(long&, long long) const;
|
||||
|
||||
mutable CuePoint** m_cue_points;
|
||||
mutable long m_count;
|
||||
mutable long m_preload_count;
|
||||
mutable long long m_pos;
|
||||
};
|
||||
|
||||
class Cluster {
|
||||
friend class Segment;
|
||||
|
||||
Cluster(const Cluster&);
|
||||
Cluster& operator=(const Cluster&);
|
||||
|
||||
public:
|
||||
Segment* const m_pSegment;
|
||||
|
||||
public:
|
||||
static Cluster* Create(Segment*,
|
||||
long index, // index in segment
|
||||
long long off); // offset relative to segment
|
||||
// long long element_size);
|
||||
|
||||
Cluster(); // EndOfStream
|
||||
~Cluster();
|
||||
|
||||
bool EOS() const;
|
||||
|
||||
long long GetTimeCode() const; // absolute, but not scaled
|
||||
long long GetTime() const; // absolute, and scaled (nanosecond units)
|
||||
long long GetFirstTime() const; // time (ns) of first (earliest) block
|
||||
long long GetLastTime() const; // time (ns) of last (latest) block
|
||||
|
||||
long GetFirst(const BlockEntry*&) const;
|
||||
long GetLast(const BlockEntry*&) const;
|
||||
long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
|
||||
|
||||
const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
|
||||
const BlockEntry* GetEntry(const CuePoint&,
|
||||
const CuePoint::TrackPosition&) const;
|
||||
// const BlockEntry* GetMaxKey(const VideoTrack*) const;
|
||||
|
||||
// static bool HasBlockEntries(const Segment*, long long);
|
||||
|
||||
static long HasBlockEntries(const Segment*, long long idoff, long long& pos,
|
||||
long& size);
|
||||
|
||||
long GetEntryCount() const;
|
||||
|
||||
long Load(long long& pos, long& size) const;
|
||||
|
||||
long Parse(long long& pos, long& size) const;
|
||||
long GetEntry(long index, const mkvparser::BlockEntry*&) const;
|
||||
|
||||
protected:
|
||||
Cluster(Segment*, long index, long long element_start);
|
||||
// long long element_size);
|
||||
|
||||
public:
|
||||
const long long m_element_start;
|
||||
long long GetPosition() const; // offset relative to segment
|
||||
|
||||
long GetIndex() const;
|
||||
long long GetElementSize() const;
|
||||
// long long GetPayloadSize() const;
|
||||
|
||||
// long long Unparsed() const;
|
||||
|
||||
private:
|
||||
long m_index;
|
||||
mutable long long m_pos;
|
||||
// mutable long long m_size;
|
||||
mutable long long m_element_size;
|
||||
mutable long long m_timecode;
|
||||
mutable BlockEntry** m_entries;
|
||||
mutable long m_entries_size;
|
||||
mutable long m_entries_count;
|
||||
|
||||
long ParseSimpleBlock(long long, long long&, long&);
|
||||
long ParseBlockGroup(long long, long long&, long&);
|
||||
|
||||
long CreateBlock(long long id, long long pos, long long size,
|
||||
long long discard_padding);
|
||||
long CreateBlockGroup(long long start_offset, long long size,
|
||||
long long discard_padding);
|
||||
long CreateSimpleBlock(long long, long long);
|
||||
};
|
||||
|
||||
class Segment {
|
||||
friend class Cues;
|
||||
friend class Track;
|
||||
friend class VideoTrack;
|
||||
|
||||
Segment(const Segment&);
|
||||
Segment& operator=(const Segment&);
|
||||
|
||||
private:
|
||||
Segment(IMkvReader*, long long elem_start,
|
||||
// long long elem_size,
|
||||
long long pos, long long size);
|
||||
|
||||
public:
|
||||
IMkvReader* const m_pReader;
|
||||
const long long m_element_start;
|
||||
// const long long m_element_size;
|
||||
const long long m_start; // posn of segment payload
|
||||
const long long m_size; // size of segment payload
|
||||
Cluster m_eos; // TODO: make private?
|
||||
|
||||
static long long CreateInstance(IMkvReader*, long long, Segment*&);
|
||||
~Segment();
|
||||
|
||||
long Load(); // loads headers and all clusters
|
||||
|
||||
// for incremental loading
|
||||
// long long Unparsed() const;
|
||||
bool DoneParsing() const;
|
||||
long long ParseHeaders(); // stops when first cluster is found
|
||||
// long FindNextCluster(long long& pos, long& size) const;
|
||||
long LoadCluster(long long& pos, long& size); // load one cluster
|
||||
long LoadCluster();
|
||||
|
||||
long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos,
|
||||
long& size);
|
||||
|
||||
#if 0
|
||||
//This pair parses one cluster, but only changes the state of the
|
||||
//segment object when the cluster is actually added to the index.
|
||||
long ParseCluster(long long& cluster_pos, long long& new_pos) const;
|
||||
bool AddCluster(long long cluster_pos, long long new_pos);
|
||||
#endif
|
||||
|
||||
const SeekHead* GetSeekHead() const;
|
||||
const Tracks* GetTracks() const;
|
||||
const SegmentInfo* GetInfo() const;
|
||||
const Cues* GetCues() const;
|
||||
const Chapters* GetChapters() const;
|
||||
|
||||
long long GetDuration() const;
|
||||
|
||||
unsigned long GetCount() const;
|
||||
const Cluster* GetFirst() const;
|
||||
const Cluster* GetLast() const;
|
||||
const Cluster* GetNext(const Cluster*);
|
||||
|
||||
const Cluster* FindCluster(long long time_nanoseconds) const;
|
||||
// const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
|
||||
|
||||
const Cluster* FindOrPreloadCluster(long long pos);
|
||||
|
||||
long ParseCues(long long cues_off, // offset relative to start of segment
|
||||
long long& parse_pos, long& parse_len);
|
||||
|
||||
private:
|
||||
long long m_pos; // absolute file posn; what has been consumed so far
|
||||
Cluster* m_pUnknownSize;
|
||||
|
||||
SeekHead* m_pSeekHead;
|
||||
SegmentInfo* m_pInfo;
|
||||
Tracks* m_pTracks;
|
||||
Cues* m_pCues;
|
||||
Chapters* m_pChapters;
|
||||
Cluster** m_clusters;
|
||||
long m_clusterCount; // number of entries for which m_index >= 0
|
||||
long m_clusterPreloadCount; // number of entries for which m_index < 0
|
||||
long m_clusterSize; // array size
|
||||
|
||||
long DoLoadCluster(long long&, long&);
|
||||
long DoLoadClusterUnknownSize(long long&, long&);
|
||||
long DoParseNext(const Cluster*&, long long&, long&);
|
||||
|
||||
void AppendCluster(Cluster*);
|
||||
void PreloadCluster(Cluster*, ptrdiff_t);
|
||||
|
||||
// void ParseSeekHead(long long pos, long long size);
|
||||
// void ParseSeekEntry(long long pos, long long size);
|
||||
// void ParseCues(long long);
|
||||
|
||||
const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&);
|
||||
};
|
||||
|
||||
} // end namespace mkvparser
|
||||
|
||||
inline long mkvparser::Segment::LoadCluster() {
|
||||
long long pos;
|
||||
long size;
|
||||
|
||||
return LoadCluster(pos, size);
|
||||
}
|
||||
|
||||
#endif // MKVPARSER_HPP
|
@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
#include "mkvreader.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace mkvparser {
|
||||
|
||||
MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
|
||||
|
||||
MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
|
||||
GetFileSize();
|
||||
}
|
||||
|
||||
MkvReader::~MkvReader() {
|
||||
if (reader_owns_file_)
|
||||
Close();
|
||||
m_file = NULL;
|
||||
}
|
||||
|
||||
int MkvReader::Open(const char* fileName) {
|
||||
if (fileName == NULL)
|
||||
return -1;
|
||||
|
||||
if (m_file)
|
||||
return -1;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
const errno_t e = fopen_s(&m_file, fileName, "rb");
|
||||
|
||||
if (e)
|
||||
return -1; // error
|
||||
#else
|
||||
m_file = fopen(fileName, "rb");
|
||||
|
||||
if (m_file == NULL)
|
||||
return -1;
|
||||
#endif
|
||||
return !GetFileSize();
|
||||
}
|
||||
|
||||
bool MkvReader::GetFileSize() {
|
||||
if (m_file == NULL)
|
||||
return false;
|
||||
#ifdef _MSC_VER
|
||||
int status = _fseeki64(m_file, 0L, SEEK_END);
|
||||
|
||||
if (status)
|
||||
return false; // error
|
||||
|
||||
m_length = _ftelli64(m_file);
|
||||
#else
|
||||
fseek(m_file, 0L, SEEK_END);
|
||||
m_length = ftell(m_file);
|
||||
#endif
|
||||
assert(m_length >= 0);
|
||||
|
||||
if (m_length < 0)
|
||||
return false;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
status = _fseeki64(m_file, 0L, SEEK_SET);
|
||||
|
||||
if (status)
|
||||
return false; // error
|
||||
#else
|
||||
fseek(m_file, 0L, SEEK_SET);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MkvReader::Close() {
|
||||
if (m_file != NULL) {
|
||||
fclose(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int MkvReader::Length(long long* total, long long* available) {
|
||||
if (m_file == NULL)
|
||||
return -1;
|
||||
|
||||
if (total)
|
||||
*total = m_length;
|
||||
|
||||
if (available)
|
||||
*available = m_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MkvReader::Read(long long offset, long len, unsigned char* buffer) {
|
||||
if (m_file == NULL)
|
||||
return -1;
|
||||
|
||||
if (offset < 0)
|
||||
return -1;
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (offset >= m_length)
|
||||
return -1;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
const int status = _fseeki64(m_file, offset, SEEK_SET);
|
||||
|
||||
if (status)
|
||||
return -1; // error
|
||||
#else
|
||||
fseek(m_file, offset, SEEK_SET);
|
||||
#endif
|
||||
|
||||
const size_t size = fread(buffer, 1, len, m_file);
|
||||
|
||||
if (size < size_t(len))
|
||||
return -1; // error
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
} // end namespace mkvparser
|
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
#ifndef MKVREADER_HPP
|
||||
#define MKVREADER_HPP
|
||||
|
||||
#include "mkvparser.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
namespace mkvparser {
|
||||
|
||||
class MkvReader : public IMkvReader {
|
||||
public:
|
||||
MkvReader();
|
||||
explicit MkvReader(FILE* fp);
|
||||
virtual ~MkvReader();
|
||||
|
||||
int Open(const char*);
|
||||
void Close();
|
||||
|
||||
virtual int Read(long long position, long length, unsigned char* buffer);
|
||||
virtual int Length(long long* total, long long* available);
|
||||
|
||||
private:
|
||||
MkvReader(const MkvReader&);
|
||||
MkvReader& operator=(const MkvReader&);
|
||||
|
||||
// Determines the size of the file. This is called either by the constructor
|
||||
// or by the Open function depending on file ownership. Returns true on
|
||||
// success.
|
||||
bool GetFileSize();
|
||||
|
||||
long long m_length;
|
||||
FILE* m_file;
|
||||
bool reader_owns_file_;
|
||||
};
|
||||
|
||||
} // end namespace mkvparser
|
||||
|
||||
#endif // MKVREADER_HPP
|
@ -105,21 +105,10 @@ plDSoundBuffer::~plDSoundBuffer()
|
||||
void plDSoundBuffer::IAllocate( UInt32 size, plWAVHeader &bufferDesc, hsBool enable3D, hsBool tryStatic )
|
||||
{
|
||||
// Create a DSound buffer description
|
||||
fBufferDesc = TRACKED_NEW DSBUFFERDESC;
|
||||
fBufferDesc->dwSize = sizeof( DSBUFFERDESC );
|
||||
|
||||
fBufferDesc->dwBufferBytes = size;
|
||||
fBufferDesc->dwReserved = 0;
|
||||
fBufferDesc = new plWAVHeader;
|
||||
*fBufferDesc = bufferDesc;
|
||||
fBufferSize = size;
|
||||
|
||||
fBufferDesc->lpwfxFormat = TRACKED_NEW WAVEFORMATEX;
|
||||
fBufferDesc->lpwfxFormat->cbSize = 0;
|
||||
fBufferDesc->lpwfxFormat->nAvgBytesPerSec = bufferDesc.fAvgBytesPerSec;
|
||||
fBufferDesc->lpwfxFormat->nBlockAlign = bufferDesc.fBlockAlign;
|
||||
fBufferDesc->lpwfxFormat->nChannels = bufferDesc.fNumChannels;
|
||||
fBufferDesc->lpwfxFormat->nSamplesPerSec = bufferDesc.fNumSamplesPerSec;
|
||||
fBufferDesc->lpwfxFormat->wBitsPerSample = bufferDesc.fBitsPerSample;
|
||||
fBufferDesc->lpwfxFormat->wFormatTag = bufferDesc.fFormatTag;
|
||||
|
||||
// Do we want to try EAX?
|
||||
if( plgAudioSys::UsingEAX() )
|
||||
fEAXSource.Init( this );
|
||||
@ -149,14 +138,9 @@ void plDSoundBuffer::IRelease( void )
|
||||
alGetError();
|
||||
|
||||
memset(streamingBuffers, 0, STREAMING_BUFFERS * sizeof(unsigned));
|
||||
if( fBufferDesc != nil )
|
||||
{
|
||||
delete fBufferDesc->lpwfxFormat;
|
||||
fBufferDesc->lpwfxFormat = nil;
|
||||
}
|
||||
|
||||
delete fBufferDesc;
|
||||
fBufferDesc = nil;
|
||||
fBufferSize = 0;
|
||||
|
||||
fValid = false;
|
||||
plProfile_Dec( NumAllocated );
|
||||
@ -197,7 +181,7 @@ bool plDSoundBuffer::FillBuffer(void *data, unsigned bytes, plWAVHeader *header)
|
||||
source = 0;
|
||||
buffer = 0;
|
||||
|
||||
ALenum format = IGetALFormat(fBufferDesc->lpwfxFormat->wBitsPerSample, fBufferDesc->lpwfxFormat->nChannels);
|
||||
ALenum format = IGetALFormat(fBufferDesc->fBitsPerSample, fBufferDesc->fNumChannels);
|
||||
ALenum error = alGetError();
|
||||
alGenBuffers(1, &buffer);
|
||||
error = alGetError();
|
||||
@ -280,8 +264,8 @@ bool plDSoundBuffer::SetupStreamingSource(plAudioFileReader *stream)
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum format = IGetALFormat(fBufferDesc->lpwfxFormat->wBitsPerSample, fBufferDesc->lpwfxFormat->nChannels);
|
||||
alBufferData( streamingBuffers[i], format, data, size, fBufferDesc->lpwfxFormat->nSamplesPerSec );
|
||||
ALenum format = IGetALFormat(fBufferDesc->fBitsPerSample, fBufferDesc->fNumChannels);
|
||||
alBufferData( streamingBuffers[i], format, data, size, fBufferDesc->fNumSamplesPerSec );
|
||||
if( (error = alGetError()) != AL_NO_ERROR )
|
||||
plStatusLog::AddLineS("audio.log", "alBufferData");
|
||||
}
|
||||
@ -346,8 +330,8 @@ bool plDSoundBuffer::SetupStreamingSource(void *data, unsigned bytes)
|
||||
return false;
|
||||
}
|
||||
|
||||
ALenum format = IGetALFormat(fBufferDesc->lpwfxFormat->wBitsPerSample, fBufferDesc->lpwfxFormat->nChannels);
|
||||
alBufferData( streamingBuffers[i], format, bufferData, size, fBufferDesc->lpwfxFormat->nSamplesPerSec );
|
||||
ALenum format = IGetALFormat(fBufferDesc->fBitsPerSample, fBufferDesc->fNumChannels);
|
||||
alBufferData( streamingBuffers[i], format, bufferData, size, fBufferDesc->fNumSamplesPerSec );
|
||||
if( (error = alGetError()) != AL_NO_ERROR )
|
||||
plStatusLog::AddLineS("audio.log", "alBufferData");
|
||||
}
|
||||
@ -364,7 +348,7 @@ bool plDSoundBuffer::SetupStreamingSource(void *data, unsigned bytes)
|
||||
SetScalarVolume(0);
|
||||
|
||||
alSourcef(source, AL_ROLLOFF_FACTOR, 0.3048);
|
||||
alGetError();
|
||||
error = alGetError();
|
||||
if( error != AL_NO_ERROR )
|
||||
{
|
||||
return false;
|
||||
@ -381,7 +365,7 @@ bool plDSoundBuffer::SetupStreamingSource(void *data, unsigned bytes)
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
int plDSoundBuffer::BuffersProcessed()
|
||||
int plDSoundBuffer::BuffersProcessed( void )
|
||||
{
|
||||
if(alIsSource(source)==AL_FALSE)
|
||||
{
|
||||
@ -399,7 +383,7 @@ int plDSoundBuffer::BuffersProcessed()
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
int plDSoundBuffer::BuffersQueued()
|
||||
int plDSoundBuffer::BuffersQueued( void )
|
||||
{
|
||||
if(alIsSource(source)==AL_FALSE) return 0;
|
||||
ALint queued = 0;
|
||||
@ -450,8 +434,8 @@ bool plDSoundBuffer::StreamingFillBuffer(plAudioFileReader *stream)
|
||||
{ unsigned int size = stream->NumBytesLeft() < STREAM_BUFFER_SIZE ? stream->NumBytesLeft() : STREAM_BUFFER_SIZE;
|
||||
stream->Read(size, data);
|
||||
|
||||
ALenum format = IGetALFormat(fBufferDesc->lpwfxFormat->wBitsPerSample, fBufferDesc->lpwfxFormat->nChannels);
|
||||
alBufferData( bufferId, format, data, size, fBufferDesc->lpwfxFormat->nSamplesPerSec );
|
||||
ALenum format = IGetALFormat(fBufferDesc->fBitsPerSample, fBufferDesc->fNumChannels);
|
||||
alBufferData( bufferId, format, data, size, fBufferDesc->fNumSamplesPerSec );
|
||||
if( (error = alGetError()) != AL_NO_ERROR )
|
||||
{
|
||||
plStatusLog::AddLineS("audio.log", "Failed to copy data to sound buffer %d", error);
|
||||
@ -492,10 +476,9 @@ bool plDSoundBuffer::GetAvailableBufferId(unsigned *bufferId)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool plDSoundBuffer::SetupVoiceSource()
|
||||
bool plDSoundBuffer::SetupVoiceSource( void )
|
||||
{
|
||||
ALenum error;
|
||||
alGetError();
|
||||
ALenum error = alGetError();
|
||||
|
||||
// Generate AL Buffers
|
||||
alGenBuffers( STREAMING_BUFFERS, streamingBuffers );
|
||||
@ -523,13 +506,13 @@ bool plDSoundBuffer::SetupVoiceSource()
|
||||
SetScalarVolume(0);
|
||||
|
||||
alSourcef(source, AL_ROLLOFF_FACTOR, 0.3048);
|
||||
alGetError();
|
||||
error = alGetError();
|
||||
if( error != AL_NO_ERROR )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
alSourcei(source, AL_BUFFER, nil);
|
||||
alGetError();
|
||||
error = alGetError();
|
||||
//alSourcei(source, AL_PITCH, 0);
|
||||
|
||||
// dont queue any buffers here
|
||||
@ -537,7 +520,7 @@ bool plDSoundBuffer::SetupVoiceSource()
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void plDSoundBuffer::UnQueueVoiceBuffers()
|
||||
void plDSoundBuffer::UnQueueVoiceBuffers( void )
|
||||
{
|
||||
unsigned buffersProcessed = BuffersProcessed();
|
||||
if(buffersProcessed)
|
||||
@ -566,8 +549,8 @@ bool plDSoundBuffer::VoiceFillBuffer(void *data, unsigned bytes, unsigned buffer
|
||||
ALenum error;
|
||||
unsigned int size = bytes < STREAM_BUFFER_SIZE ? bytes : STREAM_BUFFER_SIZE;
|
||||
|
||||
ALenum format = IGetALFormat(fBufferDesc->lpwfxFormat->wBitsPerSample, fBufferDesc->lpwfxFormat->nChannels);
|
||||
alBufferData( bufferId, format, data, size, fBufferDesc->lpwfxFormat->nSamplesPerSec );
|
||||
ALenum format = IGetALFormat(fBufferDesc->fBitsPerSample, fBufferDesc->fNumChannels);
|
||||
alBufferData( bufferId, format, data, size, fBufferDesc->fNumSamplesPerSec );
|
||||
if( (error = alGetError()) != AL_NO_ERROR )
|
||||
{
|
||||
plStatusLog::AddLineS("audio.log", "Failed to copy data to sound buffer %d", error);
|
||||
@ -635,6 +618,16 @@ void plDSoundBuffer::Play( void )
|
||||
|
||||
}
|
||||
|
||||
//// Pause ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plDSoundBuffer::Pause( void )
|
||||
{
|
||||
if (!source)
|
||||
return;
|
||||
alSourcePause(source);
|
||||
alGetError();
|
||||
}
|
||||
|
||||
//// Stop ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plDSoundBuffer::Stop( void )
|
||||
@ -692,7 +685,7 @@ void plDSoundBuffer::SetConeOutsideVolume(int vol)
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void plDSoundBuffer::Rewind()
|
||||
void plDSoundBuffer::Rewind( void )
|
||||
{
|
||||
alSourceRewind(source);
|
||||
alGetError();
|
||||
@ -719,17 +712,17 @@ hsBool plDSoundBuffer::IsEAXAccelerated( void ) const
|
||||
|
||||
UInt32 plDSoundBuffer::BytePosToMSecs( UInt32 bytePos ) const
|
||||
{
|
||||
return (UInt32)(bytePos * 1000 / (hsScalar)fBufferDesc->lpwfxFormat->nAvgBytesPerSec);
|
||||
return (UInt32)(bytePos * 1000 / (hsScalar)fBufferDesc->fAvgBytesPerSec);
|
||||
}
|
||||
|
||||
//// GetBufferBytePos ////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 plDSoundBuffer::GetBufferBytePos( hsScalar timeInSecs ) const
|
||||
{
|
||||
hsAssert( fBufferDesc != nil && fBufferDesc->lpwfxFormat != nil, "Nil buffer description when calling GetBufferBytePos()" );
|
||||
hsAssert( fBufferDesc != nil, "Nil buffer description when calling GetBufferBytePos()" );
|
||||
|
||||
UInt32 byte = (UInt32)( timeInSecs * (hsScalar)fBufferDesc->lpwfxFormat->nSamplesPerSec );
|
||||
byte *= fBufferDesc->lpwfxFormat->nBlockAlign;
|
||||
UInt32 byte = (UInt32)( timeInSecs * (hsScalar)fBufferDesc->fNumSamplesPerSec );
|
||||
byte *= fBufferDesc->fBlockAlign;
|
||||
|
||||
return byte;
|
||||
}
|
||||
@ -738,7 +731,7 @@ UInt32 plDSoundBuffer::GetBufferBytePos( hsScalar timeInSecs ) const
|
||||
|
||||
UInt32 plDSoundBuffer::GetLengthInBytes( void ) const
|
||||
{
|
||||
return (UInt32)fBufferDesc->dwBufferBytes;
|
||||
return fBufferSize;
|
||||
}
|
||||
|
||||
//// SetEAXSettings //////////////////////////////////////////////////////////
|
||||
@ -752,7 +745,7 @@ void plDSoundBuffer::SetEAXSettings( plEAXSourceSettings *settings, hsBool forc
|
||||
|
||||
UInt8 plDSoundBuffer::GetBlockAlign( void ) const
|
||||
{
|
||||
return ( fBufferDesc != nil && fBufferDesc->lpwfxFormat != nil ) ? fBufferDesc->lpwfxFormat->nBlockAlign : 0;
|
||||
return ( fBufferDesc != nil ) ? fBufferDesc->fBlockAlign : 0;
|
||||
}
|
||||
|
||||
//// SetScalarVolume /////////////////////////////////////////////////////////
|
||||
@ -769,7 +762,7 @@ void plDSoundBuffer::SetScalarVolume( hsScalar volume )
|
||||
}
|
||||
}
|
||||
|
||||
unsigned plDSoundBuffer::GetByteOffset()
|
||||
unsigned plDSoundBuffer::GetByteOffset( void )
|
||||
{
|
||||
ALint bytes;
|
||||
alGetSourcei(source, AL_BYTE_OFFSET, &bytes);
|
||||
@ -777,7 +770,7 @@ unsigned plDSoundBuffer::GetByteOffset()
|
||||
return bytes;
|
||||
}
|
||||
|
||||
float plDSoundBuffer::GetTimeOffsetSec()
|
||||
float plDSoundBuffer::GetTimeOffsetSec( void )
|
||||
{
|
||||
float time;
|
||||
alGetSourcef(source, AL_SEC_OFFSET, &time);
|
||||
@ -796,4 +789,4 @@ void plDSoundBuffer::SetTimeOffsetBytes(unsigned bytes)
|
||||
alSourcef(source, AL_BYTE_OFFSET, bytes);
|
||||
ALenum error = alGetError();
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,9 +62,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
class plWAVHeader;
|
||||
class plAudioFileReader;
|
||||
|
||||
typedef struct tWAVEFORMATEX WAVEFORMATEX;
|
||||
typedef struct _DSBUFFERDESC DSBUFFERDESC;
|
||||
|
||||
|
||||
// Ported to OpenAL from DirectSound May 2006. Idealy the openal sources would be seperate from this class.
|
||||
// OpenAl sound buffer, and source.
|
||||
@ -74,11 +71,12 @@ public:
|
||||
plDSoundBuffer( UInt32 size, plWAVHeader &bufferDesc, hsBool enable3D, hsBool looping, hsBool tryStatic = false, bool streaming = false );
|
||||
~plDSoundBuffer();
|
||||
|
||||
void Play( void );
|
||||
void Stop( void );
|
||||
void Play();
|
||||
void Stop();
|
||||
void Pause();
|
||||
void Rewind() ;
|
||||
|
||||
UInt32 GetLengthInBytes( void ) const;
|
||||
UInt32 GetLengthInBytes() const;
|
||||
void SetScalarVolume( hsScalar volume ); // Sets the volume, but on a range from 0 to 1
|
||||
|
||||
unsigned GetSource() { return source; }
|
||||
@ -93,10 +91,10 @@ public:
|
||||
void SetMinDistance( int dist);
|
||||
void SetMaxDistance( int dist );
|
||||
|
||||
hsBool IsValid( void ) const { return fValid; }
|
||||
hsBool IsPlaying( void );
|
||||
hsBool IsLooping( void ) const { return fLooping; }
|
||||
hsBool IsEAXAccelerated( void ) const;
|
||||
hsBool IsValid() const { return fValid; }
|
||||
hsBool IsPlaying();
|
||||
hsBool IsLooping() const { return fLooping; }
|
||||
hsBool IsEAXAccelerated() const;
|
||||
|
||||
bool FillBuffer(void *data, unsigned bytes, plWAVHeader *header);
|
||||
|
||||
@ -143,7 +141,8 @@ protected:
|
||||
|
||||
hsTArray<UInt32> fPosNotifys;
|
||||
bool fStreaming;
|
||||
DSBUFFERDESC* fBufferDesc;
|
||||
plWAVHeader* fBufferDesc;
|
||||
UInt32 fBufferSize;
|
||||
|
||||
unsigned buffer; // used if this is not a streaming buffer
|
||||
unsigned streamingBuffers[STREAMING_BUFFERS]; // used if this is a streaming buffer
|
||||
@ -161,7 +160,7 @@ protected:
|
||||
hsScalar fPrevVolume;
|
||||
|
||||
void IAllocate( UInt32 size, plWAVHeader &bufferDesc, hsBool enable3D, hsBool tryStatic );
|
||||
void IRelease( void );
|
||||
void IRelease();
|
||||
int IGetALFormat(unsigned bitsPerSample, unsigned int numChannels);
|
||||
};
|
||||
|
||||
|
@ -163,19 +163,20 @@ public:
|
||||
fLengthInSecs = len; fVolStart = start; fVolEnd = end; fType = type;
|
||||
fStopWhenDone = false;
|
||||
fFadeSoftVol = false;
|
||||
fCurrTime = -1.f;
|
||||
}
|
||||
|
||||
void Read( hsStream *s );
|
||||
void Write( hsStream *s );
|
||||
|
||||
hsScalar InterpValue( void );
|
||||
hsScalar InterpValue();
|
||||
|
||||
protected:
|
||||
hsScalar fCurrTime; // -1 if we aren't active, else it's how far we're into the animation
|
||||
};
|
||||
|
||||
virtual hsBool LoadSound( hsBool is3D ) = 0;
|
||||
hsScalar GetVirtualStartTime( void ) const { return (hsScalar)fVirtualStartTime; }
|
||||
hsScalar GetVirtualStartTime() const { return (hsScalar)fVirtualStartTime; }
|
||||
|
||||
virtual void Play();
|
||||
void SynchedPlay( unsigned bytes );
|
||||
@ -188,16 +189,16 @@ public:
|
||||
virtual int GetMin() const;
|
||||
virtual int GetMax() const;
|
||||
virtual void SetVolume(const float volume);
|
||||
virtual float GetVolume(void) const { return fCurrVolume; }
|
||||
virtual float GetVolume() const { return fCurrVolume; }
|
||||
hsScalar GetMaxVolume() { return fMaxVolume; }
|
||||
virtual hsBool IsPlaying() { return fPlaying; }
|
||||
void SetTime(double t);
|
||||
virtual double GetTime( void ) { return 0.f; }
|
||||
virtual double GetTime() { return 0.f; }
|
||||
virtual void Activate(hsBool forcePlay = false);
|
||||
virtual void DeActivate();
|
||||
virtual void SetLength(double l) { fLength = l; }
|
||||
virtual void SetMuted( hsBool muted );
|
||||
virtual hsBool IsMuted( void ) { return fMuted; }
|
||||
virtual hsBool IsMuted() { return fMuted; }
|
||||
void Disable() { fDistAttenuation = 0; }
|
||||
virtual plSoundMsg* GetStatus(plSoundMsg* pMsg){return NULL;}
|
||||
virtual void SetConeOrientation(hsScalar x, hsScalar y, hsScalar z);
|
||||
@ -210,16 +211,16 @@ public:
|
||||
|
||||
virtual void Update();
|
||||
|
||||
plSoundBuffer * GetDataBuffer( void ) const { return (plSoundBuffer *)fDataBufferKey->ObjectIsLoaded(); }
|
||||
hsScalar QueryCurrVolume( void ) const; // Returns the current volume, attenuated
|
||||
plSoundBuffer * GetDataBuffer() const { return (plSoundBuffer *)fDataBufferKey->ObjectIsLoaded(); }
|
||||
hsScalar QueryCurrVolume() const; // Returns the current volume, attenuated
|
||||
|
||||
const char * GetFileName( void ) const;
|
||||
const char * GetFileName() const;
|
||||
virtual double GetLength();
|
||||
|
||||
void SetProperty( Property prop, hsBool on ) { if( on ) fProperties |= prop; else fProperties &= ~prop; }
|
||||
hsBool IsPropertySet( Property prop ) const { return ( fProperties & prop ) ? true : false; }
|
||||
|
||||
virtual void RefreshVolume( void );
|
||||
virtual void RefreshVolume();
|
||||
|
||||
virtual void SetStartPos(unsigned bytes) = 0;
|
||||
virtual unsigned GetByteOffset(){return 0;}
|
||||
@ -228,7 +229,7 @@ public:
|
||||
virtual void AddCallbacks(plSoundMsg* pMsg) = 0;
|
||||
virtual void RemoveCallbacks(plSoundMsg* pMsg) = 0;
|
||||
|
||||
virtual UInt8 GetChannelSelect( void ) const { return 0; } // Only defined on Win32Sound right now, should be here tho
|
||||
virtual UInt8 GetChannelSelect() const { return 0; } // Only defined on Win32Sound right now, should be here tho
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
@ -246,34 +247,34 @@ public:
|
||||
|
||||
// Type setting and getting, from the Types enum
|
||||
void SetType( UInt8 type ) { fType = type; }
|
||||
UInt8 GetType( void ) const { return fType; }
|
||||
UInt8 GetType() const { return fType; }
|
||||
|
||||
// Priority stuff
|
||||
void SetPriority( UInt8 pri ) { fPriority = pri; }
|
||||
UInt8 GetPriority( void ) const { return fPriority; }
|
||||
UInt8 GetPriority() const { return fPriority; }
|
||||
|
||||
// Visualization
|
||||
virtual plDrawableSpans* CreateProxy(const hsMatrix44& l2w, hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
|
||||
|
||||
// Forced loading/unloading (for when the audio system's LOD just doesn't cut it)
|
||||
virtual void ForceLoad( );
|
||||
virtual void ForceUnload( void );
|
||||
virtual void ForceUnload();
|
||||
|
||||
// Note: ONLY THE AUDIOSYS SHOULD CALL THIS. If you're not the audioSys, get lost.
|
||||
static void SetCurrDebugPlate( const plKey soundKey );
|
||||
|
||||
void RegisterOnAudioSys( void );
|
||||
void UnregisterOnAudioSys( void );
|
||||
void RegisterOnAudioSys();
|
||||
void UnregisterOnAudioSys();
|
||||
|
||||
// Also only for the audio system
|
||||
hsScalar GetVolumeRank( void );
|
||||
void ForceUnregisterFromAudioSys( void );
|
||||
hsScalar GetVolumeRank();
|
||||
void ForceUnregisterFromAudioSys();
|
||||
|
||||
static void SetLoadOnDemand( hsBool activate ) { fLoadOnDemandFlag = activate; }
|
||||
static void SetLoadFromDiskOnDemand( hsBool activate ) { fLoadFromDiskOnDemand = activate; }
|
||||
|
||||
const plEAXSourceSettings &GetEAXSettings( void ) const { return fEAXSettings; }
|
||||
plEAXSourceSettings &GetEAXSettings( void ) { return fEAXSettings; }
|
||||
const plEAXSourceSettings &GetEAXSettings() const { return fEAXSettings; }
|
||||
plEAXSourceSettings &GetEAXSettings() { return fEAXSettings; }
|
||||
virtual StreamType GetStreamType() const { return kNoStream; }
|
||||
virtual void FreeSoundData();
|
||||
|
||||
@ -340,40 +341,40 @@ protected:
|
||||
static hsBool fLoadOnDemandFlag, fLoadFromDiskOnDemand;
|
||||
hsBool fLoading;
|
||||
|
||||
void IUpdateDebugPlate( void );
|
||||
void IUpdateDebugPlate();
|
||||
void IPrintDbgMessage( const char *msg, hsBool isErr = false );
|
||||
|
||||
virtual void ISetActualVolume(const float v) = 0;
|
||||
virtual void IActuallyStop( void );
|
||||
virtual hsBool IActuallyPlaying( void ) = 0;
|
||||
virtual void IActuallyPlay( void ) = 0;
|
||||
virtual void IFreeBuffers( void ) = 0;
|
||||
virtual void ISetActualVolume(float v) = 0;
|
||||
virtual void IActuallyStop();
|
||||
virtual hsBool IActuallyPlaying() = 0;
|
||||
virtual void IActuallyPlay() = 0;
|
||||
virtual void IFreeBuffers() = 0;
|
||||
|
||||
//NOTE: if isIncidental is true the entire sound will be loaded.
|
||||
virtual plSoundBuffer::ELoadReturnVal IPreLoadBuffer( hsBool playWhenLoaded, hsBool isIncidental = false );
|
||||
virtual void ISetActualTime( double t ) = 0;
|
||||
|
||||
virtual hsBool IActuallyLoaded( void ) = 0;
|
||||
virtual hsBool IActuallyLoaded() = 0;
|
||||
virtual void IRefreshEAXSettings( hsBool force = false ) = 0;
|
||||
|
||||
virtual hsScalar IGetChannelVolume( void ) const;
|
||||
virtual hsScalar IGetChannelVolume() const;
|
||||
|
||||
void ISynchToStartTime( void );
|
||||
void ISynchToStartTime();
|
||||
void ISynchedPlay( double virtualStartTime );
|
||||
void IStartFade( plFadeParams *params, hsScalar offsetIntoFade = 0.f );
|
||||
void IStopFade( hsBool shuttingDown = false, hsBool SetVolEnd = true);
|
||||
|
||||
hsBool IWillBeAbleToPlay( void );
|
||||
hsBool IWillBeAbleToPlay();
|
||||
|
||||
void ISetSoftRegion( plSoftVolume *region );
|
||||
hsScalar IAttenuateActualVolume( hsScalar volume ) const;
|
||||
void ISetSoftOcclusionRegion( plSoftVolume *region );
|
||||
|
||||
// Override to make sure the buffer is available before the base class is called
|
||||
virtual void IRefreshParams( void );
|
||||
virtual void IRefreshParams();
|
||||
|
||||
virtual bool ILoadDataBuffer( void );
|
||||
virtual void IUnloadDataBuffer( void );
|
||||
virtual bool ILoadDataBuffer();
|
||||
virtual void IUnloadDataBuffer();
|
||||
|
||||
//virtual void ISetMinDistance( const int m ) = 0;
|
||||
//virtual void ISetMaxDistance( const int m ) = 0;
|
||||
|
@ -0,0 +1,122 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "plWin32VideoSound.h"
|
||||
|
||||
#include "hsResMgr.h"
|
||||
#include "plDSoundBuffer.h"
|
||||
|
||||
static int uniqueID = 0;
|
||||
plWin32VideoSound::plWin32VideoSound(const plWAVHeader& header) : plWin32Sound()
|
||||
{
|
||||
fCurrVolume = 1.0f;
|
||||
fDesiredVol = 1.0f;
|
||||
fSoftVolume = 1.0f;
|
||||
fType = kGUISound;
|
||||
|
||||
fWAVHeader = header;
|
||||
fDSoundBuffer = new plDSoundBuffer(0, fWAVHeader, false, false);
|
||||
|
||||
uniqueID++;
|
||||
|
||||
char keyName[32];
|
||||
StrPrintf(keyName, arrsize(keyName), "VoiceSound_%d", uniqueID);
|
||||
|
||||
hsgResMgr::ResMgr()->NewKey(keyName, this, plLocation::kGlobalFixedLoc);
|
||||
}
|
||||
|
||||
plWin32VideoSound::~plWin32VideoSound()
|
||||
{
|
||||
if (fDSoundBuffer)
|
||||
delete fDSoundBuffer;
|
||||
}
|
||||
|
||||
void plWin32VideoSound::Play()
|
||||
{
|
||||
IActuallyPlay();
|
||||
}
|
||||
|
||||
void plWin32VideoSound::Pause(bool on)
|
||||
{
|
||||
if (on)
|
||||
fDSoundBuffer->Pause();
|
||||
else if (!fReallyPlaying)
|
||||
fDSoundBuffer->Play();
|
||||
fReallyPlaying = !on;
|
||||
}
|
||||
|
||||
void plWin32VideoSound::FillSoundBuffer(void* buffer, size_t size)
|
||||
{
|
||||
fDSoundBuffer->FillBuffer(buffer, size, &fWAVHeader);
|
||||
fDSoundBuffer->SetScalarVolume(1.0f);
|
||||
}
|
||||
|
||||
void plWin32VideoSound::IDerivedActuallyPlay()
|
||||
{
|
||||
if (!fReallyPlaying) {
|
||||
fDSoundBuffer->Play();
|
||||
fReallyPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plWin32VideoSound::LoadSound(hsBool is3D)
|
||||
{
|
||||
hsAssert(false, "unimplemented cause unnecessary for this class");
|
||||
return false;
|
||||
}
|
||||
|
||||
void plWin32VideoSound::SetStartPos(unsigned bytes)
|
||||
{
|
||||
//do nothing
|
||||
hsAssert(false, "unimplemented cause unnecessary for this class");
|
||||
}
|
||||
|
||||
float plWin32VideoSound::GetActualTimeSec()
|
||||
{
|
||||
hsAssert(false, "unimplemented cause unnecessary for this class");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plWin32VideoSound::ISetActualTime(double t)
|
||||
{
|
||||
hsAssert(false, "unimplemented cause unnecessary for this class");
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plWin32VideoSound_h
|
||||
#define plWin32VideoSound_h
|
||||
|
||||
#include "plWin32Sound.h"
|
||||
|
||||
class plWin32VideoSound : public plWin32Sound
|
||||
{
|
||||
public:
|
||||
plWin32VideoSound(const plWAVHeader& header);
|
||||
virtual ~plWin32VideoSound();
|
||||
|
||||
virtual void Play();
|
||||
virtual void Pause(bool on);
|
||||
void FillSoundBuffer(void* buffer, size_t size);
|
||||
|
||||
protected:
|
||||
void IDerivedActuallyPlay();
|
||||
hsBool LoadSound(hsBool is3D);
|
||||
void SetStartPos(unsigned bytes);
|
||||
float GetActualTimeSec();
|
||||
void ISetActualTime(double t);
|
||||
|
||||
plWAVHeader fWAVHeader;
|
||||
};
|
||||
#endif
|
@ -46,7 +46,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
|
||||
plLocalization::Language plLocalization::fLanguage = plLocalization::kEnglish;
|
||||
|
||||
char* plLocalization::fLangTags[] =
|
||||
const char* plLocalization::fLangTags[] =
|
||||
{
|
||||
"_eng", // kEnglish
|
||||
"_fre", // kFrench
|
||||
@ -57,7 +57,23 @@ char* plLocalization::fLangTags[] =
|
||||
};
|
||||
const int kLangTagLen = 4;
|
||||
|
||||
char* plLocalization::fLangNames[] =
|
||||
std::string fLangCodes_en[] = {"eng", "en"};
|
||||
std::string fLangCodes_fr[] = {"fre", "fra", "fr"};
|
||||
std::string fLangCodes_de[] = {"ger", "deu", "de"};
|
||||
std::string fLangCodes_es[] = {"spa", "es"};
|
||||
std::string fLangCodes_it[] = {"ita", "it"};
|
||||
std::string fLangCodes_ja[] = {"jpn", "ja"};
|
||||
const std::set<std::string> plLocalization::fLangCodes[] =
|
||||
{
|
||||
std::set<std::string>(std::begin(fLangCodes_en), std::end(fLangCodes_en)),
|
||||
std::set<std::string>(std::begin(fLangCodes_fr), std::end(fLangCodes_fr)),
|
||||
std::set<std::string>(std::begin(fLangCodes_de), std::end(fLangCodes_de)),
|
||||
std::set<std::string>(std::begin(fLangCodes_es), std::end(fLangCodes_it)),
|
||||
std::set<std::string>(std::begin(fLangCodes_it), std::end(fLangCodes_it)),
|
||||
std::set<std::string>(std::begin(fLangCodes_ja), std::end(fLangCodes_ja))
|
||||
};
|
||||
|
||||
const char* plLocalization::fLangNames[] =
|
||||
{
|
||||
"English", // kEnglish
|
||||
"French", // kFrench
|
||||
|
@ -43,6 +43,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#define plLocalization_h_inc
|
||||
|
||||
#include "hsStlUtils.h"
|
||||
#include <set>
|
||||
|
||||
class plLocalization
|
||||
{
|
||||
@ -75,8 +76,9 @@ public:
|
||||
|
||||
protected:
|
||||
static Language fLanguage;
|
||||
static char* fLangTags[kNumLanguages];
|
||||
static char* fLangNames[kNumLanguages];
|
||||
static const char* fLangTags[kNumLanguages];
|
||||
static const std::set<std::string> fLangCodes[kNumLanguages];
|
||||
static const char* fLangNames[kNumLanguages];
|
||||
static bool fUsesUnicode[kNumLanguages];
|
||||
static encodingTypes fUnicodeEncoding[kNumLanguages];
|
||||
|
||||
@ -89,7 +91,8 @@ public:
|
||||
static void SetLanguage(Language lang) { fLanguage = lang; }
|
||||
static Language GetLanguage() { return fLanguage; }
|
||||
|
||||
static char* GetLanguageName(Language lang) { return fLangNames[lang]; }
|
||||
static const char* GetLanguageName(Language lang) { return fLangNames[lang]; }
|
||||
static std::set<std::string> GetLanguageCodes(Language lang) { return fLangCodes[lang]; }
|
||||
|
||||
static hsBool UsingUnicode() { return fUsesUnicode[fLanguage]; }
|
||||
static encodingTypes UnicodeEncoding() { return fUnicodeEncoding[fLanguage]; }
|
||||
@ -130,4 +133,4 @@ public:
|
||||
static std::vector<std::wstring> StringToLocal(const std::wstring & localizedText);
|
||||
};
|
||||
|
||||
#endif // plLocalization_h_inc
|
||||
#endif // plLocalization_h_inc
|
||||
|
Reference in New Issue
Block a user