Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,354 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{77A73D85-7602-42F3-BAC4-8D7F7BFF8659}</ProjectGuid>
<RootNamespace>CPUIdLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.32505.173</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\obj\CPUIdLib\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\obj\CPUIdLib\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\obj\CPUIdLib\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\obj\CPUIdLib\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\libvp6\corelibs\include;..\..\..\libvp6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\libvp6\corelibs\include;..\..\..\libvp6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\..\..\libvp6\corelibs\include;..\..\..\libvp6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\..\..\libvp6\corelibs\include;..\..\..\libvp6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Win32\cid.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="Win32\Wmt_CpuID.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="Win32\cpuid.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="Win32\D9xOSSupXMM.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="Win32\InitXMMReg.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="Win32\TrashXMMreg.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="Win32\VerifyXMMReg.asm">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml /Zi /Zm /Cx /c /coff /Fl"$(IntDir)%(Filename)".lst /Fo "$(IntDir)%(Filename)".obj "%(FullPath)"
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename).obj;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\cdxv\dxv2\dxv2.vcxproj">
<Project>{adac45fd-b93f-40a3-85b2-dbeca1283614}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{8ff77253-bd53-4d72-a4d0-4620071c05d4}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Source Files\Win32">
<UniqueIdentifier>{71967989-d210-421e-9b32-ca6c33a448ee}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Win32\cid.c">
<Filter>Source Files\Win32</Filter>
</ClCompile>
<ClCompile Include="Win32\Wmt_CpuID.cpp">
<Filter>Source Files\Win32</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="Win32\cpuid.asm">
<Filter>Source Files\Win32</Filter>
</CustomBuild>
<CustomBuild Include="Win32\D9xOSSupXMM.asm">
<Filter>Source Files\Win32</Filter>
</CustomBuild>
<CustomBuild Include="Win32\InitXMMReg.asm">
<Filter>Source Files\Win32</Filter>
</CustomBuild>
<CustomBuild Include="Win32\TrashXMMreg.asm">
<Filter>Source Files\Win32</Filter>
</CustomBuild>
<CustomBuild Include="Win32\VerifyXMMReg.asm">
<Filter>Source Files\Win32</Filter>
</CustomBuild>
</ItemGroup>
</Project>
@@ -0,0 +1,99 @@
;//==========================================================================
;//
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;// PURPOSE.
;//
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
;//
;//--------------------------------------------------------------------------
;
; **-Does9xOSSupportXMM
;
; This function will verify if the operating system supports the XMM
; instructions. According to Intel documentation
;
; Intel Architecture
; Software Developer
; Manual
; Volume 1:
; Basic Architecture
;
; The following needs to be true for the OS to suppor the XMM instructions
;
; CR0.EM(bit 2) = 0 (emulation disabled)
; CR4.OSFXSR(bit 9) = 1 (OS supports saving SIMD floating-point state during context
; switches)
;
; * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * *
;
; This function will NOT run on windows NT systems. The function reads control registers
; which are protected under Windows NT. If you attempt to run this function under Windows NT a
; protected mode access violation will be generated.
;
; * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * * * * * N O T E * * *
;
; Assumptions:
; Access to system control registers CR0 and CR4 are not protected
;
; Input:
; None
;
; Output:
; 1 Returned if OS supports XMM instructions
; 0 Returned if OS does not support XMM instructions
;
;
.586
.MODEL flat, SYSCALL, os_dos
.DATA
NAME x86cpuid
PUBLIC Does9xOSSupportXMM_
PUBLIC _Does9xOSSupportXMM
.CODE
; int Does9xOSSupportXMM( void )
Does9xOSSupportXMM_:
_Does9xOSSupportXMM:
push esi ;safety sh*&
push edi
push ebp
push ebx
push ecx
push edx
; check to see if OS supports SIMD instructions
mov edx,cr0
bt edx,2 ; ensure no emulation
jnae NoXMMSupport
mov edx,cr4
bt edx,9 ; OS support SIMD
jnc NoXMMSupport
; we support XMM instructions
mov eax,1
jmp Exit
NoXMMSupport:
; mov eax,0 ; OS does not support XMM instructions
Exit:
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
;************************************************
END
@@ -0,0 +1,100 @@
;//==========================================================================
;//
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;// PURPOSE.
;//
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
;//
;//--------------------------------------------------------------------------
;
; **-InitXMMReg
;
; This function is meant to be run on a Windows NT system to
; try and determine if the OS supports the XMM registers or
; not.
;
; This function is number 1 in a set of three. The other
; functions are...
;
; TrashXMMReg
; VerifyXMMReg
;
; Assumptions:
; None
;
; Input:
; None
;
; Output:
; No return value. But XMM registers
; 0, 1, 2 initilized to a predetermined
; value
;
;
.686P
.XMM
.MODEL flat, SYSCALL, os_dos
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
PUBLIC XMM0Init
PUBLIC XMM1Init
PUBLIC XMM2Init
XMM0Init REAL4 1.1
REAL4 2.2
REAL4 3.3
REAL4 4.4
XMM1Init REAL4 5.5
REAL4 6.6
REAL4 7.7
REAL4 8.8
XMM2Init REAL4 9.9
REAL4 10.10
REAL4 11.11
REAL4 12.12
NAME InitXMMReg
PUBLIC InitXMMReg_
PUBLIC _InitXMMReg
.CODE
; void InitXMMReg( void )
InitXMMReg_:
_InitXMMReg:
push esi ;safety sh*&
push edi
push ebp
push ebx
push ecx
push edx
movaps xmm0,XMM0Init
movaps xmm1,XMM1Init
movaps xmm2,XMM2Init
Exit:
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
;************************************************
END
@@ -0,0 +1,87 @@
;//==========================================================================
;//
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;// PURPOSE.
;//
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
;//
;//--------------------------------------------------------------------------
;
; **-TrashXMMReg
;
; This function is meant to be run on a Windows NT system to
; try and determine if the OS supports the XMM registers or
; not.
;
; This function is number 2 in a set of three. The other
; functions are...
;
; InitXMMReg
; VerifyXMMReg
;
; Assumptions:
; No necessary for this function to work properly but
; IntiXMMReg should have been called to initilize the
; XMM registers to a predetermined value
;
; Input:
; None
;
; Output:
; No return value. But XMM registers
; 0, 1, 2 written to 0's
;
;
.686P
.XMM
.MODEL flat, SYSCALL, os_dos
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
Zeros REAL4 0.0
REAL4 0.0
REAL4 0.0
REAL4 0.0
NAME TrashXMMReg
PUBLIC TrashXMMReg_
PUBLIC _TrashXMMReg
.CODE
; void TrashXMMReg( void )
TrashXMMReg_:
_TrashXMMReg:
push esi ;safety sh*&
push edi
push ebp
push ebx
push ecx
push edx
movaps xmm0,Zeros
movaps xmm1,Zeros
movaps xmm2,Zeros
Exit:
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
;************************************************
END
@@ -0,0 +1,99 @@
;//==========================================================================
;//
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;// PURPOSE.
;//
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
;//
;//--------------------------------------------------------------------------
;
; **-VerifyXMMReg
;
; This function is meant to be run on a Windows NT system to
; try and determine if the OS supports the XMM registers or
; not.
;
; This function is number 3 in a set of three. The other
; functions are...
;
; InitXMMReg
; TrashXMMReg
;
; Assumptions:
; Assumes that InitXMMReg was called to initilize the XMM registers.
; Assumes that TrashXMMReg was called from a different thread to clear
; the values in the XMM registers.
;
; Input:
; None
;
; Output:
; Return 1 (True) if the XMM registers are at the correct values.
; (os supports XMM registers)
;
; Return 0 (False) if the XMM registers are not at the correct values.
; (os does not support the XMM registers)
;
.686P
.XMM
.MODEL flat, SYSCALL, os_dos
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
NAME VerifyXMMReg
PUBLIC VerifyXMMReg_
PUBLIC _VerifyXMMReg
EXTERN XMM0Init:REAL4
EXTERN XMM1Init:REAL4
EXTERN XMM2Init:REAL4
.CODE
; int VerifyXMMReg( void )
VerifyXMMReg_:
_VerifyXMMReg:
push esi ;safety sh*&
push edi
push ebp
push ebx
push ecx
push edx
mov eax,0 ; assume will fail
comiss xmm0,XMM0Init ; check XMM0
jne Exit
comiss xmm1,XMM1Init
jne Exit
comiss xmm2,XMM2Init
jne Exit
mov eax,1 ; OS supports XMM registers
Exit:
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
;************************************************
END
@@ -0,0 +1,149 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
/****************************************************************************
*
* Module Title : Wmt_CpuID.cpp
*
* Description : willamette processor detection functions
*
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#include <excpt.h>
#include <string.h>
extern "C" {
/****************************************************************************
*
* ROUTINE : WillametteNewInstructionSupport()
*
* INPUTS :
*
* OUTPUTS :
*
* RETURNS : retrun true if the processor support willamette new
* instructions, return false otherwise
*
*
* FUNCTION : detect willamette processor
*
* SPECIAL NOTES : None.
*
* ERRORS : None.
*
****************************************************************************/
int WillametteNewInstructionHWSupport()
{
int HWSupport = 0;
char brand[12];
__try
{
__asm
{
lea esi, brand
mov eax, 0
cpuid
mov [esi], ebx
mov [esi+4], edx
mov [esi+8], ecx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(_exception_code())
{
//cout<<endl<<"*******CPUID is not supported**********"<<endl;
return 0;
}
return 0;
}
if(strncmp(brand, "GenuineIntel", 12)!=0)
{
//cout<<endl<<"this is not an intel processor1"<<endl;
return 0;
}
__asm
{
mov eax, 1
cpuid
test edx, 04000000h
jz NotFound
mov [HWSupport], 1
NotFound:
nop
}
return (HWSupport);
}
/****************************************************************************
*
* ROUTINE : WillametteNewInstructionOSSupport()
*
* INPUTS :
*
* OUTPUTS :
*
* RETURNS : retrun true if the OS support willamette new
* instructions, return false otherwise
*
*
* FUNCTION : detect willamette processor
*
* SPECIAL NOTES : None.
*
* ERRORS : None.
*
****************************************************************************/
int WillametteNewInstructionOSSupport()
{
__try
{
__asm xorpd xmm0, xmm0
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(_exception_code())
{
return 0;
}
return 0;
}
return 1;
}
}
+152
View File
@@ -0,0 +1,152 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include <windows.h>
#include <stdarg.h>
#include "cpuidlib.h"
#include "cidasm.h"
#include <process.h>
#include <stdio.h>
extern int WillametteNewInstructionOSSupport();
extern int WillametteNewInstructionHWSupport();
/*
* **-DoesOSSupportXMM
*
* This function will check to see if the operating supports the XMM (Pentium III) instructions
* The XMM functionality adds 8 128-bit registers to the pentium II register set. With the addition
* of the new registers the OS needs to preserve and restore the registers on task switches.
*
* Inputs:
* None
*
* Outputs:
* True returned if the OS supports the XMM instructions.
* False returned if the OS does not suppor the XMM instructions.
*/
int DoesOSSupportXMM( void )
{
OSVERSIONINFO OSInformation; // Data structure where OS version will be filled in
int ReturnValue = FALSE; // Preload to fail
// need to initilize size of OS info structure before calling GetVersionEx
OSInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( !GetVersionEx( &OSInformation ) ) // Get OS information
{
/*
* having trouble getting OS information
* to be safe will return that we do not support XMM
* instructions
*/
// ReturnValue = FALSE;
}
if( OSInformation.dwPlatformId == VER_PLATFORM_WIN32_NT )
// if( 1 )
{
/*
* If we are on a windows NT system we cannot directly
* read the control registers to see if the OS supports
* the XMM instructions. We will just check to see if
* service pack 4 is installed.
*/
int ServicePackNumber;
if( strcmp(OSInformation.szCSDVersion, "" ) != 0 ) // is there a service pack installed?
{
// Yes, get service pack revision
char Junk[132], Junk2[132];
sscanf( OSInformation.szCSDVersion, "%s %s %d", Junk, Junk2, &ServicePackNumber );
}
else
{
ServicePackNumber = 0;
}
if( OSInformation.dwMajorVersion == 4 && // must be versio 4 or greater
ServicePackNumber >= 4 || // must have service pack 4 or greater
OSInformation.dwMajorVersion >=5)
{
ReturnValue = TRUE;
}
else
{
// ReturnValue = FALSE;
}
#if 0
// some handy debugging info if you are desperate
printf("OS Major Revision %d\n", OSInformation.dwMajorVersion );
printf("OS Minor REvision %d\n", OSInformation.dwMinorVersion );
printf("Service Pack Number %d\n", ServicePackNumber );
#endif
}
else
{
/*
* we are on a Windows 9x system.
*/
//if( Does9xOSSupportXMM()) // does the Windows 9x support the XMM instructions?
{
ReturnValue = TRUE; // yup
}
//else
//{
//ReturnValue = FALSE; // Nope, don't support XMM instructions
//}
}
return( ReturnValue );
}
/*
* **-findCPUId
*
* See cpuidlib.h for a detailed description of this function
*/
PROCTYPE findCPUId( void )
{
PROCTYPE CpuType;
// return 0;
// return (PII); // drop to next lowest type of CPU which should be the Pentium II processor
CpuType = getCPUType(); // Get version of processor
// The code to check whether willammete instructions are called attempts to run
// an illegal instruction. Under 98 mplayer crashes the os as soon as the illegal
// instruction is called, so I've disabled it.
if( CpuType == XMM ) // If the CPU supports XMM (Pentium III) instructions
{
// if( DoesOSSupportXMM()) // need to check to see if the OS supports the XMM instructions
{
if( WillametteNewInstructionHWSupport()&&
WillametteNewInstructionOSSupport())
{
CpuType = WMT;
}
}
// else
// {
// os does not support the XMM instructions
// CpuType = PII; // drop to next lowest type of CPU which should be the Pentium II processor
// }
}
return( CpuType );
}
@@ -0,0 +1,280 @@
;//==========================================================================
;//
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
;// PURPOSE.
;//
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
;//
;//--------------------------------------------------------------------------
;
; **-getCPUType
;
; This function will return a code indicating the type of the processor
; that is in the system. If the processor type is unknown the generic
; x86 (Intel 486) type is returned
;
; parts taken from intel's AP-485
;
;put checks for cmov and mmx support ????
;
; Assumptions:
; None
;
; Input:
; None
;
; Output:
; Code for CPU type returned. See cpuidlib.h for the supported
; types.
;
.586
.MODEL flat, SYSCALL, os_dos
.DATA
NAME x86cpuid
PUBLIC getCPUType_
PUBLIC _getCPUType
CPU_ID MACRO
db 0fh ; Hardcoded CPUID instruction
db 0a2h
ENDM
;see cpuidlib.h
X86 EQU 0 ; /* 486, Pentium plain, or any other x86 compatible */
PMMX EQU 1 ; /* Pentium with MMX */
PPRO EQU 2 ; /* Pentium Pro */
PII EQU 3 ; /* Pentium II */
C6X86 EQU 4
C6X86MX EQU 5
AMDK63D EQU 6
AMDK6 EQU 7
AMDK5 EQU 8
XMM EQU 11
WMT EQU 12 ;/* Willamette */
_486 EQU 4h
PENT EQU 50h
PENTMMX EQU 54h
PENTPRO EQU 61h
PENTII EQU 63h
SIMD EQU 25
AMD_K63D EQU 58h
AMD_K6 EQU 56h
AMD_K5 EQU 50h ; K5 has models 0 - 6
_6X86 EQU 52h
_6X86MX EQU 60h
_vendor_id db "------------"
intel_id db "GenuineIntel"
amd_id db "AuthenticAMD"
cyrix_id db "CyrixInstead"
.CODE
getCPUType_:
_getCPUType:
push esi ;safety sh*&
push edi
push ebp
push ebx
push ecx
push edx
;------------------------------------------------
; Intel486 processor check
; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
; which indicates the presence of a processor with the CPUID
; instruction.
;------------------------------------------------
check_80486:
pushfd ; push original EFLAGS
pop eax ; get original EFLAGS
mov ebp,X86 ; rv
mov ecx, eax ; save original EFLAGS
xor eax, 200000h ; flip ID bit in EFLAGS
push eax ; save new EFLAGS value on stack
popfd ; replace current EFLAGS value
pushfd ; get new EFLAGS
pop eax ; store new EFLAGS in EAX
xor eax, ecx ; can not toggle ID bit,
je end_cpu_type486 ; processor=80486
;------------------------------------------------
; Execute CPUID instruction to not determine vendor, family,
; model, stepping and features. For the purpose of this
; code, only the initial set of CPUID information is saved.
;------------------------------------------------
; push ebx ; save registers
; push esi
; push edi
; push edx
; push ecx
; mov ebp,X86 ; rv
mov eax, 0 ; set up for CPUID instruction
CPU_ID ; get and save vendor ID
mov DWORD PTR _vendor_id, ebx
mov DWORD PTR _vendor_id[+4], edx
mov DWORD PTR _vendor_id[+8], ecx
cmp DWORD PTR intel_id, ebx
jne IsProc_AMD
cmp DWORD PTR intel_id[+4], edx
jne end_cpuid_type
cmp DWORD PTR intel_id[+8], ecx
jne end_cpuid_type ; if not equal, not an Intel processor
cmp eax, 1 ; make sure 1 is valid input for CPUID
jl end_cpuid_type ; if not, jump to end
mov eax, 1
CPU_ID ; get family/model/stepping/features
mov ebp,XMM ; assume PIII
bt edx,SIMD ; check for SIMD support
jnae end_cpuid_type
SIMDContinue:
shr eax, 4 ; isolate family and model
mov ebp,PII ; assume PII
and eax,0ffh ;mask out type and reserved
nop
cmp eax,PENTII
jge end_cpuid_type
mov ebp,PPRO
cmp eax,PENTPRO
je end_cpuid_type
mov ebp,PMMX
cmp eax,PENTMMX
je end_cpuid_type
mov ebp,X86
cmp eax,PENT
jge end_cpuid_type
; mov ebp,X86
end_cpuid_type:
mov eax,ebp
;remove these pops ???
; pop edi ; restore registers
; pop esi
; pop ebx
; pop edx
; pop ecx
end_cpu_type:
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
end_cpu_type486:
mov eax,ebp
pop edx ;safety sh*&
pop ecx
pop ebx
pop ebp
pop edi
pop esi
ret
;------------------------------------------------
IsProc_AMD:
cmp DWORD PTR amd_id, ebx
jne IsProc_CYRIX
cmp DWORD PTR amd_id[+4], edx
jne end_cpuid_type
cmp DWORD PTR amd_id[+8], ecx
jne end_cpuid_type ; if not equal, not an AMD processor
cmp eax, 1 ; make sure 1 is valid input for CPUID
jl end_cpuid_type ; if not, jump to end
mov eax, 1
CPU_ID ; get family/model/stepping/features
shr eax, 4 ; isolate family and model
mov ebp,AMDK63D
and eax,0ffh ;mask out type and reserved
nop
cmp eax,AMD_K63D
jge end_cpuid_type
mov ebp,AMDK6
nop
cmp eax,AMD_K6
jge end_cpuid_type
mov ebp,X86
nop
cmp eax,AMD_K5
jge end_cpuid_type
mov ebp,X86
jmp end_cpuid_type
;------------------------------------------------
IsProc_CYRIX:
cmp DWORD PTR cyrix_id, ebx
jne end_cpuid_type
cmp DWORD PTR cyrix_id[+4], edx
jne end_cpuid_type
cmp DWORD PTR cyrix_id[+8], ecx
jne end_cpuid_type ; if not equal, not an CYRIX processor
cmp eax, 1 ; make sure 1 is valid input for CPUID
jl end_cpuid_type ; if not, jump to end
mov eax, 1
CPU_ID ; get family/model/stepping/features
shr eax, 4 ; isolate family and model
mov ebp,C6X86MX
and eax,0ffh ;mask out type and reserved
nop
cmp eax,_6X86MX
je end_cpuid_type
mov ebp,X86
jmp end_cpuid_type
;************************************************
END
+22
View File
@@ -0,0 +1,22 @@
This library contains functions
that will determine the type of CPU that is in your system. See cpuidlib.h for
a more detailed description of the functions that are avaliable.
If you want to use the library all you need to do is to fetch
- cpuidlib.h
- cpuidlib.lib
October 14 1999
Jong Chen
This is the initial revision of the library.
At the moment the code is not fully tested. The code that tests for OS support
of Pentium III instructions has only been tested on systems with OS that
support the Pentium III instructions. It has not been tested in a
configuration where we will detect the the OS will not support the Pentium III
instructions.
@@ -0,0 +1,71 @@
/****************************************************************************
*
* Module Title : Huffman.h
*
* Description : Huffman Coding header file.
*
****************************************************************************/
#ifndef __INC_HUFFMAN_H
#define __INC_HUFFMAN_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "type_aliases.h"
#include "boolhuff.h"
/****************************************************************************
* Module Statics
****************************************************************************/
#define HUFF_LUT_LEVELS 6
/****************************************************************************
* Types
****************************************************************************/
typedef struct _tokenorptr
{
unsigned int selector : 1; // 1 bit selector 0->ptr, 1->token
unsigned int value : 7;
} tokenorptr;
typedef struct _huffnode
{
union
{
char l;
tokenorptr left;
} leftunion;
union
{
char r;
tokenorptr right;
} rightunion;
unsigned char freq;
} HUFF_NODE;
/****************************************************************************
* Data structures
****************************************************************************/
typedef struct _HUFF_TALBE_NODE
{
unsigned short flag :1; // bit 0: 1-Token, 0-Index
unsigned short value :5; // value: the value of the Token or the Index to the huffman tree
unsigned short unused :6; // not used for now
unsigned short length :4; // Huffman code length of the token
} HUFF_TABLE_NODE;
/****************************************************************************
* Functions
****************************************************************************/
extern void VP6_BuildHuffLookupTable ( HUFF_NODE * HuffTreeRoot, UINT16 * HuffTable );
extern void VP6_BuildHuffTree ( HUFF_NODE *hn, unsigned int *counts, int values );
extern void VP6_CreateCodeArray( HUFF_NODE *hn,
int node,
unsigned int *codearray,
unsigned char *lengtharray,
int codevalue,
int codelength );
extern void VP6_EncodeValue ( BOOL_CODER *bc, HUFF_NODE *hn, int value, int length );
#endif
@@ -0,0 +1,34 @@
/****************************************************************************
*
* Module Title : RAW_BUFFER.h
*
* Description : Raw bit manipulation routines header file.
*
****************************************************************************/
#ifndef __INC_RAWBUFFER_H
#define __INC_RAWBUFFER_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "type_aliases.h"
/****************************************************************************
* Typedefs
****************************************************************************/
typedef struct RAW_BUFFER
{
UINT32 pos; // Offset of "current" UINT32 in buffer
INT32 byte_bit_offset; // Offset of next free bit in current UINT8
UINT32 DataBlock;
UINT8 *Buffer;
} RAW_BUFFER;
/****************************************************************************
* Exports
****************************************************************************/
extern void InitAddRawBitsToBuffer ( RAW_BUFFER *buf, UINT8 *Buffer );
extern void AddRawBitsToBuffer( RAW_BUFFER *buf, UINT32 data, UINT32 bits );
extern void EndAddRawBitsToBuffer( RAW_BUFFER *buf );
#endif
@@ -0,0 +1,21 @@
/****************************************************************************
*
* Module Title : SystemDependant.h
*
* Description : Miscellaneous system dependant functions header
*
****************************************************************************/
#ifndef __INC_SYSTEMDEPENDANT_H
#define __INC_SYSTEMDEPENDANT_H
/****************************************************************************
* Exports
****************************************************************************/
extern void VP6_IssueWarning ( char * WarningMessage );
extern void PauseProcess ( unsigned int SleepMs );
// System dynamic memory allocation
char *SytemGlobalAlloc ( unsigned int Size );
void SystemGlobalFree ( char * MemPtr );
#endif
@@ -0,0 +1,100 @@
/****************************************************************************
*
* Module Title : TokenEntropy.h
*
* Description : Entropy coding header file.
*
****************************************************************************/
#ifndef __INC_TOKEN_ENTROPY_H
#define __INC_TOKEN_ENTROPY_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "type_aliases.h"
#include "boolhuff.h"
#include "codec_common.h"
#include "huffman.h"
/****************************************************************************
* Constants
****************************************************************************/
// VP6 hufman table AC bands
#define VP6_AC_BANDS 6
// Tokens Value Extra Bits (range + sign)
#define ZERO_TOKEN 0 //0 Extra Bits 0+0
#define ONE_TOKEN 1 //1 Extra Bits 0+1
#define TWO_TOKEN 2 //2 Extra Bits 0+1
#define THREE_TOKEN 3 //3 Extra Bits 0+1
#define FOUR_TOKEN 4 //4 Extra Bits 0+1
#define DCT_VAL_CATEGORY1 5 //5-6 Extra Bits 1+1
#define DCT_VAL_CATEGORY2 6 //7-10 Extra Bits 2+1
#define DCT_VAL_CATEGORY3 7 //11-26 Extra Bits 4+1
#define DCT_VAL_CATEGORY4 8 //11-26 Extra Bits 5+1
#define DCT_VAL_CATEGORY5 9 //27-58 Extra Bits 5+1
#define DCT_VAL_CATEGORY6 10 //59+ Extra Bits 11+1
#define DCT_EOB_TOKEN 11 //EOB Extra Bits 0+0
#define MAX_ENTROPY_TOKENS (DCT_EOB_TOKEN + 1)
#define ILLEGAL_TOKEN 255
#define DC_TOKEN_CONTEXTS 3 // 00, 0!0, !0!0
#define CONTEXT_NODES (MAX_ENTROPY_TOKENS-7)
#define PREC_CASES 3
#define ZERO_RUN_PROB_CASES 14
#define DC_PROBABILITY_UPDATE_THRESH 100
#define ZERO_CONTEXT_NODE 0
#define EOB_CONTEXT_NODE 1
#define ONE_CONTEXT_NODE 2
#define LOW_VAL_CONTEXT_NODE 3
#define TWO_CONTEXT_NODE 4
#define THREE_CONTEXT_NODE 5
#define HIGH_LOW_CONTEXT_NODE 6
#define CAT_ONE_CONTEXT_NODE 7
#define CAT_THREEFOUR_CONTEXT_NODE 8
#define CAT_THREE_CONTEXT_NODE 9
#define CAT_FIVE_CONTEXT_NODE 10
#define PROB_UPDATE_BASELINE_COST 7
#define MAX_PROB 254
#define DCT_MAX_VALUE 2048
#define ZRL_BANDS 2
#define ZRL_BAND2 6
#define SCAN_ORDER_BANDS 16
#define SCAN_BAND_UPDATE_BITS 4
/****************************************************************************
* Typedefs
****************************************************************************/
typedef struct LineEq
{
INT32 M;
INT32 C;
} LINE_EQ;
/****************************************************************************
* Exports
****************************************************************************/
extern const UINT32 VP6_ProbCost[256];
extern const UINT8 ExtraBitLengths_VP6[MAX_ENTROPY_TOKENS];
extern const UINT32 VP6_DctRangeMinVals[MAX_ENTROPY_TOKENS];
extern const UINT8 VP6_DcUpdateProbs[2][MAX_ENTROPY_TOKENS-1];
extern const UINT8 VP6_AcUpdateProbs[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS-1];
extern const UINT8 VP6_PrevTokenIndex[MAX_ENTROPY_TOKENS];
extern const UINT8 ScanBandUpdateProbs[BLOCK_SIZE];
extern const UINT8 ZrlUpdateProbs[ZRL_BANDS][ZERO_RUN_PROB_CASES];
extern const UINT8 ZeroRunProbDefaults[ZRL_BANDS][ZERO_RUN_PROB_CASES];
extern UINT8 PrecZeroRunLength[BLOCK_SIZE];
#endif
@@ -0,0 +1,67 @@
/****************************************************************************
*
* Module Title : boolhuff.h
*
* Description : Bool Coder header file.
*
****************************************************************************/
#ifndef __INC_BOOLHUFF_H
#define __INC_BOOLHUFF_H
#ifdef NOTNORMALIZED
typedef struct _boolcoder
{
unsigned char *buffer;
unsigned int pos;
union
{
unsigned int value;
unsigned char v[4];
};
unsigned int range;
} BOOL_CODER;
#else
typedef struct
{
unsigned int lowvalue;
unsigned int range;
unsigned int value;
int count;
unsigned int pos;
unsigned char *buffer;
// Variables used to track bit costs without outputing to the bitstream
unsigned int MeasureCost;
unsigned long BitCounter;
} BOOL_CODER;
#endif
// Section cost measaurement stats
//#define MEASURE_SECTION_COSTS 1
#if defined MEASURE_SECTION_COSTS
extern unsigned int Sectionbits[10];
extern unsigned int ActiveSection;
#define HEADER_SECTION 0
#define MODE_SECTION 1
#define MV_SECTION 2
#define CONTEXT_OVERHEADS_SECTION 3
#define DC_SECTION 4
#define AC_SECTION 5
#endif
extern void VP6_StartDecode ( BOOL_CODER *bc, unsigned char *buffer );
extern int VP6_DecodeBool ( BOOL_CODER *bc, int context );
extern int VP6_DecodeBool128 ( BOOL_CODER *bc );
extern void VP6_StopDecode ( BOOL_CODER *bc );
extern void VP6_StartEncode ( BOOL_CODER *bc, unsigned char *buffer );
extern void VP6_EncodeBool ( BOOL_CODER *bc, int x, int context );
extern void VP6_EncodeBool2 ( BOOL_CODER *bc, int x, int context );
extern void VP6_StopEncode ( BOOL_CODER *bc );
#endif
@@ -0,0 +1,607 @@
/****************************************************************************
*
* Module Title : COMPDLL.H
*
* Description : Encoder definitions.
*
*****************************************************************************
*/
#ifndef __INC_COMPDLL_H
#define __INC_COMPDLL_H
#include "codec_common.h"
#include "preprocif.h"
#include "preproc.h"
#include "pbdll.h"
#include "vp60_comp_interface.h"
#include "RawBuffer.h"
#include <stdio.h>
/****************************************************************************
* Module constants.
*****************************************************************************
*/
// Debug/stats code
//#define PSNR_ON
//#define FILE_PSNR
#define MIN_BPB_FACTOR 0.1
#define MAX_BPB_FACTOR 10.0
#define KEY_FRAME_CONTEXT 5
// GF update constants
#define DEFAULT_GF_UPDATE_INTERVAL 8
#define DEFAULT_2PASS_GF_UPDATE_INTERVAL 4
#define MIN_GF_UPDATE_INTERVAL 4
#define MAX_GF_UPDATE_INTERVAL 8
#define GF_UPDATE_MOTION_INTERVAL 48
#define MAX_GF_UPDATE_MOTION 16
#define GF_DEFAULT_MOTION_CMPLX 12
#define GF_MODE_DIST_THRESH1 50
#define GF_MODE_DIST_THRESH2 25
#define GF_MAX_VAR_THRESH 36
#define FIRSTPASS_Q 32
//#define FULLFRAMEFDCT
/****************************************************************************
* Types
*****************************************************************************
*/
typedef struct CONFIG_TYPE2
{
UINT32 TargetBandwidth;
UINT32 OutputFrameRate;
UINT32 FirstFrameQ;
UINT32 BaseQ;
UINT32 WorstQuality; // Worst Quality allowed.
UINT32 ActiveWorstQuality; // Reflects worst quality Currently allowed (specified as an index where 0 is worst quality)
UINT32 ActiveBestQuality; // Reflects best quality currently allowed (specified as an index where 0 is worst quality)
} CONFIG_TYPE2;
typedef enum
{
DCT_COEF_TOKEN,
MODE_TOKEN,
BLOCKMAP_TOKEN,
MV_TOKEN
} TOKENTYPE;
typedef struct _TOKENEXTRA
{
INT32 Token;
UINT32 Extra;
INT32 LastTokenL; // Last token in block LEFT
INT32 LastTokenA; // Last token in block ABOVE
} TOKENEXTRA;
typedef struct LineEq2
{
double M;
double C;
} LINE_EQ2;
typedef struct
{
BLOCK_CONTEXT * AbovePtr;
BLOCK_CONTEXT Above;
BLOCK_CONTEXT * LeftPtr;
BLOCK_CONTEXT Left;
Q_LIST_ENTRY * LastDcPtr;
Q_LIST_ENTRY LastDc;
} MB_DC_CONTEXT;
typedef struct MOTION_STATS
{
UINT32 NumMvs;
UINT32 SumAbsX;
UINT32 SumAbsY;
INT32 SumX;
INT32 SumY;
UINT32 SumXSq;
UINT32 SumYSq;
} MOTION_STATS;
typedef struct
{
double MotionSpeed;
double VarianceX;
double VarianceY;
double PercentGolden;
double PercentMotionY;
double PercentMotion;
double PercentNewMotion;
unsigned int QValue;
double MeanInterError;
double MeanIntraError;
double BitsPerMacroblock;
double SqBitsPerMacroblock;
double PSNR;
int isGolden;
int isKey;
int count;
int frame;
} FIRSTPASS_STATS;
/****************************************************************************
* Imports
****************************************************************************/
extern UINT32 (*FiltBlockBilGetSad)(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
extern UINT32 (*GetSAD16)(UINT8 *, INT32, UINT8 *, INT32, UINT32, UINT32);
extern UINT32 (*GetSadHalfPixel16)(UINT8 *, INT32, UINT8 *, UINT8 *, INT32, UINT32, UINT32);
extern void (*fdct_short) ( INT16 * InputData, INT16 * OutputData );
extern void (*idctc[65])( INT16 *InputData, INT16 *QuantMatrix, INT16 * OutputData );
extern UINT32 (*GetSAD)(UINT8 *, INT32, UINT8 *, INT32, UINT32, UINT32);
extern UINT32 (*GetSadHalfPixel)(UINT8 *, INT32, UINT8 *, UINT8 *, INT32, UINT32, UINT32 );
extern UINT32 (*GetInterError)( UINT8 *, INT32, UINT8 *, UINT8 *, INT32 );
extern UINT32 (*GetIntraError)( UINT8 *, INT32);
extern void (*Sub8)( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconStride );
extern void (*Sub8_128)( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride );
extern void (*Sub8Av2)( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr2, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconStride );
#define HUGE_ERROR (1<<28) // Out of range test value
// Number of search sites for heirachical search (8*steps)+1
// so for (+- 32 pixels) = 5 step = 41 (previously 4 step = 33)
#define MAX_SEARCH_SITES 41
typedef struct CP_INSTANCE * xCP_INST;
typedef struct CP_INSTANCE
{
PB_INSTANCE pb; // playback
CONFIG_TYPE2 Configuration;
YUV_BUFFER_CONFIG InputConfig;
YUV_BUFFER_CONFIG YuvInputData;
INT32 SizeStep;
INT32 LastSizeStep;
INT32 QuickCompress;
BOOL GoldenFrameEnabled;
BOOL InterPrediction;
BOOL MotionCompensation;
BOOL AutoKeyFrameEnabled;
INT32 ForceKeyFrameEvery;
INT32 AutoKeyFrameThreshold;
INT32 LastKeyFrame;
INT32 MinimumDistanceToKeyFrame;
INT32 KeyFrameDataTargetOrig; // Data rate target for key frames
INT32 KeyFrameDataTarget; // Data rate target for key frames
UINT32 KeyFrameFrequency;
BOOL DropFramesAllowed;
BOOL DropFrame;
INT32 DropCount;
INT32 MaxDropCount;
INT32 MaxConsecDroppedFrames;
UINT32 QualitySetting;
UINT32 PreProcFilterLevel;
BOOL AllowSpatialResampling;
UINT8 RdOpt; // 0 - off, 1 - basic rd on, 2 - all rd options on
// Compressor Statistics
double TotErrScore;
UINT32 InterError;
UINT32 LastInterError;
UINT32 LastIntraError;
UINT32 MVErrorPerBit;
UINT32 ErrorPerBit;
UINT32 IntraError;
INT64 KeyFrameCount; // Count of key frames.
INT64 TotKeyFrameBytes;
UINT32 LastKeyFrameSize;
UINT32 PriorKeyFrameSize[KEY_FRAME_CONTEXT];
UINT32 PriorKeyFrameDistance[KEY_FRAME_CONTEXT];
INT32 FrameQuality[6];
int DecoderErrorCode; // Decoder error flag.
INT32 ThreshMapThreshold;
INT32 TotalMotionScore;
INT64 TotalByteCount;
INT32 FixedQ;
// Used for prediction filter selection
UINT32 MotionInterErr;
UINT32 MotionIntraErr;
UINT8 BaselineAlpha;
UINT8 BaselineBicThresh;
// Frame Statistics
INT64 CurrentFrame;
UINT32 LastFrameSize;
UINT32 ThisFrameSize;
BOOL ThisIsFirstFrame;
BOOL ThisIsKeyFrame;
BOOL GfRecoveryFrame;
UINT32 FrameError ;
// Stats for normal inter frames (excludes GFU frames and key frames)
UINT32 NiFrames;
UINT32 NiTotQi;
UINT32 NiAvQi;
INT32 MotionScore;
UINT32 FirstSixthBoundary; // Macro block index marking the first sixth of the image
UINT32 LastSixthBoundary; // Macro block index marking the last sixth of the image
/* Rate Targeting variables */
double BpbCorrectionFactor;
double KeyFrameBpbCorrectionFactor;
double GfuBpbCorrectionFactor;
// Controlling Block Selection
UINT32 MVChangeFactor;
UINT32 FourMvChangeFactor;
UINT32 ExhaustiveSearchThresh;
UINT32 BlockExhaustiveSearchThresh;
UINT32 MinImprovementForFourMV;
UINT32 FourMVThreshold;
UINT32 IntraThresh;
UINT32 MinErrorForMacroBlockMVSearch;
UINT32 MinErrorForBlockMVSearch;
UINT32 MinErrorForGoldenMVSearch;
UINT16 *FrameZeroCountsAlloc;
UINT16 *FrameZeroCounts;
UINT32 FrameNzCount[BLOCK_SIZE][2];
UINT8 NewScanOrderBands[BLOCK_SIZE];
// Frames
YUV_BUFFER_ENTRY *yuv0ptr; // Un-pre-processed raw input (but scaled if appropriate)
YUV_BUFFER_ENTRY *yuv1ptr;
// Token Buffers
TOKENEXTRA *CoeffTokens;
TOKENEXTRA *CoeffTokenPtr;
INT16 LastDC[3];
BOOL_CODER bc;
BOOL_CODER bc2;
UINT8 *DataOutputBuffer;
UINT8 MBCodingMode; // Coding mode flags
INT32 MVPixelOffsetY[MAX_SEARCH_SITES];
UINT32 InterTripOutThresh;
INT32 MVSearchSteps;
INT32 MVOffsetX[MAX_SEARCH_SITES];
INT32 MVOffsetY[MAX_SEARCH_SITES];
INT8 SubPixelXOffset[9]; // Half pixel MV offsets for X
INT8 SubPixelYOffset[9]; // Half pixel MV offsets for Y
Q_LIST_ENTRY *quantized_list;
MOTION_VECTOR MVector;
INT16 *DCT_codes; //Buffer that stores the result of Forward DCT
INT16 *DCTDataBuffer; //Input data buffer for Forward DCT
// Motion compensation related variables
UINT32 MvMaxExtent;
INT32 byte_bit_offset;
UINT32 NearestError[4];
UINT32 NearError[4];
UINT32 ZeroError[4];
UINT32 BestError[4];
UINT32 ErrorBins[128];
xPP_INST pp; // preprocessor
#if defined PSNR_ON
double TotPsnr;
double MinPsnr;
double MaxPsnr;
double TotYPsnr;
double MinYPsnr;
double MaxYPsnr;
double TotUPsnr;
double MinUPsnr;
double MaxUPsnr;
double TotVPsnr;
double MinVPsnr;
double MaxVPsnr;
double TotalSqError;
#endif
#if defined FULLFRAMEFDCT
Q_LIST_ENTRY (*FDCTCoeffs)[64];
#endif
// Structures for entropy contexts
UINT32 FrameDcTokenDist[2][MAX_ENTROPY_TOKENS];
//UINT32 FrameAcTokenDist[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT32 FrameAcTokenDist[PREC_CASES][2][8][16];
// Extra structures needed to decide if we choose huffman and DC / EOB runs
UINT32 FrameDcTokenDist2[2][MAX_ENTROPY_TOKENS];
//UINT32 FrameAcTokenDist2[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT32 FrameAcTokenDist2[PREC_CASES][2][8][16];
// AWG Debug Accumulate token count for entire run
UINT32 CumulativeFrameDcTokenDist[2][MAX_ENTROPY_TOKENS];
UINT32 CumulativeFrameAcTokenDist[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
// Storage for the first frame entropy probabilities.
// These are re-used for all subsequent key frames when we are operating in
// error (drop frame) ressiliant mode.
UINT8 FirstFrameDcProbs[2*(MAX_ENTROPY_TOKENS-1)];
UINT8 FirstFrameAcProbs[2*PREC_CASES*VP6_AC_BANDS*(MAX_ENTROPY_TOKENS-1)];
UINT32 FrameZrlDist[ZRL_BANDS][64];
UINT32 FrameZeroCount[ZRL_BANDS];
UINT8 FrameZrlProbs[ZRL_BANDS][ZERO_RUN_PROB_CASES];
UINT32 FrameZrlBranchHits[ZRL_BANDS][ZERO_RUN_PROB_CASES][2];
// Last token coded this block.
UINT32 MBModeCount[4][MAX_MODES+1];
UINT32 BModeCount[MAX_MODES+1];
UINT32 CountModeSameAsLast[4][MAX_MODES+1];
UINT32 CountModeDiffFrLast[4][MAX_MODES+1];
UINT32 ModeCodeArray[4][MAX_MODES+1][MAX_MODES+1];
UINT8 ModeLengthArray[4][MAX_MODES+1][MAX_MODES+1];
UINT32 MBModeCostBoth[11];
UINT32 MBModeCostNoNear[11];
UINT32 MBModeCostNoNearest[11];
UINT32 BModeCost[11];
UINT32 MvBaselineDist[2][MV_ENTROPY_TOKENS];
UINT32 FrameMvCount;
UINT32 EstModeCost[2][MAX_MODES];
UINT32 EstMVCost[2][MV_ENTROPY_TOKENS];
UINT32 * EstMvCostPtrX;
UINT32 * EstMvCostPtrY;
// Data structure used in re-calculating MV probability nodes
UINT8 NewMvSignProbs[2];
UINT8 NewIsMvShortProb[2];
UINT8 NewMvShortProbs[2][7];
UINT8 NewMvSizeProbs[2][LONG_MV_BITS];
UINT32 NewMvSignHits[2][2];
UINT32 NewIsMvShortHits[2][2];
UINT32 NewMvShortHits[2][7][2];
UINT32 NewMvSizeHits[2][LONG_MV_BITS][2];
UINT32 nExperimentals;
INT32 Experimental[C_SET_EXPERIMENTAL_MAX - C_SET_EXPERIMENTAL_MIN + 1];
// Bandwidth and buffer control variables
INT32 PerFrameBandwidth; // Target for average bandwidth per frame.
INT32 InterFrameTarget; // Average "inter" frame bit target corrected for key frame costs
INT32 ThisFrameTarget; // Modified rate target for this frame
BOOL BufferedMode; // FALSE = Tight buffering (Video Conferencing mode); TRUE = normal buffered/streaming mode.
BOOL ErrorResilliantMode; // A mode used for VC etc. to make the codec more resilliant to dropped frames.
INT32 StartingBufferLevel; // The initial encoder buffer level
INT32 BytesOffTarget; // How far off target are we in repect of target bytes for clip
INT32 OptimalBufferLevel; // The buffer level target we strive to reach / maintain.
INT32 BufferLevel; // Buffer level based upon the max sustainable rate used for rate targeting
INT32 MaxBufferLevel; // The maximum permited value for the buffer level.
INT32 DropFramesWaterMark; // Buffer fullness watermark for forced drop frames.
INT32 ResampleDownWaterMark; // Buffer fullness watermark for downwards spacial re-sampling
INT32 ResampleUpWaterMark; // Buffer fullness watermark where returning to larger image size is consdered
INT32 LastKeyFrameBufferLevel; // Used to monitor changes in buffer level when considering re-sampling.
INT32 Speed;
INT32 CPUUsed;
UINT32 ModeMvCostEstimate; // Running total of cost estimates for modes and MVs in this frame.
// Variables used in regulating cost of new motion vectors based upon an estimate of new MV frequency.
UINT32 FrameNewMvCounter;
UINT32 FrameModeCounter;
UINT32 MvEpbCorrection;
UINT32 LastFrameNewMvUsage; // 0 = Low 9 = High
UINT32 * MbBestErr;
UINT32 EstDcTokenCosts[2][MAX_ENTROPY_TOKENS];
UINT32 EstAcTokenCosts[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT32 EstZrlCosts[ZRL_BANDS][64];
// Data structures used to save and restor MB and DC contexts during rate distortion
MACROBLOCK_INFO CopyMbi;
BLOCK_CONTEXT AboveCopyY[2];
BLOCK_CONTEXT AboveCopyU;
BLOCK_CONTEXT AboveCopyV;
BLOCK_CONTEXT LeftYCopy[2];
BLOCK_CONTEXT LeftUCopy;
BLOCK_CONTEXT LeftVCopy;
Q_LIST_ENTRY LastDcYCopy[3];
Q_LIST_ENTRY LastDcUCopy[3];
Q_LIST_ENTRY LastDcVCopy[3];
MB_DC_CONTEXT MbDcContexts[MAX_MODES][6]; // Per mode, per block position data structure for and MB
UINT32 avgPickModeTime;
UINT32 avgEncodeTime;
UINT32 avgPackVideoTime;
UINT32 ForceHScale;
UINT32 ForceHRatio;
UINT32 ForceVScale;
UINT32 ForceVRatio;
BOOL ForceInternalSize;
PreProcInstance preproc;
// Buffers for output bitstream partitions
UINT8 *OutputBuffer2;
RAW_BUFFER RawBuffer;
// In Huffman mode runs of zeros at DC position & runs
// of EOB at first AC position are used
INT32 CurrentDcZeroRun[2];
TOKENEXTRA *DcZeroRunStartPtr[2];
INT32 CurrentAc1EobRun[2];
TOKENEXTRA *Ac1EobRunStartPtr[2];
// DEBUG
UINT32 HuffCost;
UINT32 CostShannon;
BOOL AllowScanOrderUpdates;
INT32 FrameRateInput;
INT32 FrameRateDropFrames;
INT32 FrameRateDropCount;
// Stats for monitoring frame mode and MV data
UINT32 ModeDist[MAX_MODES];
// Stats collected about the use of motion vectors in the curent frame
MOTION_STATS FrameMvStats;
// Variables used in control of GF update
UINT32 FramesTillGfUpdateDue;
INT32 GfUpdateInterval;
UINT32 GfuMotionSpeed;
UINT32 GfuMotionComplexity;
UINT32 GfuBoost;
UINT32 GfUsage; // GF usage metric
UINT32 LastGfOrKFrameQ;
// variables for 5 region diamond MV search
INT32 DSMVSearchSteps;
INT32 DSMVPixelOffsetY[MAX_SEARCH_SITES];
INT32 DSMVOffsetX[MAX_SEARCH_SITES];
INT32 DSMVOffsetY[MAX_SEARCH_SITES];
// 2 pass stats
INT32 pass;
FIRSTPASS_STATS fps;
FIRSTPASS_STATS fpmss;
FILE *fs;
FILE *ss;
INT32 GoldenFrameBoost;
INT32 MbsSinceGolden;
INT32 OneGoldenFrame;
INT32 KFBoost;
INT32 InterBoostFreq;
INT32 InterBoost;
INT32 GoldenMbsSinceGolden;
INT32 GoldenMbsThisFrame;
INT32 InterErrorb;
INT32 FramesToKey;
double FirstPassPSNR;
INT32 ActualTargetBitRate;
INT32 KFForced;
INT32 NextKFForced;
INT32 CalculatedWorstQ;
INT32 PassedInWorstQ;
// new parameters
BOOL DisableGolden; // disable golden frame updates
BOOL VBMode; // run in variable bandwidth 1 pass mode
BOOL EndUsage; // Local file playback mode / vs streamed
BOOL AutoWorstQ; // Auto adjust worst quality.... 1 pass vbr within buffering constraints
UINT32 BestAllowedQ; // best allowed quality ( save bits by disallowings frames that are too high quality )
INT32 UnderShootPct; // target a percentage of the actual frame to allow for sections that go over
INT32 MaxAllowedDatarate; // maximum the datarate is allowed to go.
INT32 MaximumBufferSize; // maximum buffer size.
BOOL TwoPassVBREnabled; // two pass variable bandwidth enabled
INT32 TwoPassVBRBias; // how variable do we want to target?
INT32 TwoPassVBRMaxSection; // maximum
INT32 TwoPassVBRMinSection; // minimum
INT32 Pass; // which pass of the compression are we running.
double TotalBitsLeftInClip;
double FramesYetToEncode;
double TotalBitsPerMB;
// Prediction mode parameters for VP6.2
UINT8 LastPredictionFilterMode;
UINT8 LastPredictionFilterMvSizeThresh;
UINT32 LastPredictionFilterVarThresh;
UINT8 LastPredictionFilterAlpha;
UINT32 (*FindMvViaSearch)
(xCP_INST cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT8 **BestBlockPtr,
UINT32 BlockSize);
void (*FindBestHalfPixelMv)
(xCP_INST cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT32 BlockSize,
UINT32 *MinError,
UINT8 BitShift);
void (*FindBestQuarterPixelMv)
(xCP_INST cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT32 BlockSize,
UINT32 *MinError,
UINT8 BitShift);
} CP_INSTANCE;
/****************************************************************************
* Exports
****************************************************************************/
UINT32 (*GetMBFrameVertVar)(CP_INSTANCE *cpi);
UINT32 (*GetMBFieldVertVar)(CP_INSTANCE *cpi);
UINT32 (*GetBlockReconErr)(CP_INSTANCE *cpi, UINT32 bp);
/****************************************************************************
* Imports
****************************************************************************/
extern void UpdateFrame(CP_INSTANCE *cpi);
extern UINT32 EncodeData(CP_INSTANCE *cpi);
// Loop optimizations
extern void InitMapArrays();
// Codec
extern void SUB8( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
INT32 SourceStride, INT32 ReconStride );
extern void SUB8_128( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
INT32 SourceStride );
extern void SUB8AV2( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr2, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
INT32 SourceStride, INT32 ReconStride );
extern CP_INSTANCE * CreateCPInstance(void);
extern void DeleteCPInstance(CP_INSTANCE **cpi);
extern void CMachineSpecificConfig(void);
extern void fdct_short_C ( INT16 * InputData, INT16 * OutputData );
extern BOOL EAllocateFragmentInfo(CP_INSTANCE *cpi);
extern BOOL EAllocateFrameInfo(CP_INSTANCE *cpi);
extern void EDeleteFragmentInfo(CP_INSTANCE *cpi);
extern void EDeleteFrameInfo(CP_INSTANCE *cpi);
extern UINT32 PickIntra( CP_INSTANCE *cpi );
extern UINT32 PickModes( CP_INSTANCE *cpi, UINT32 *InterError, UINT32 *IntraError);
extern void ClampAndUpdateQ ( CP_INSTANCE *cpi, UINT32 QIndex);
extern void EncodeFrameMbs(CP_INSTANCE *cpi);
extern void CCONV ChangeEncoderSize(CP_INSTANCE* cpi, UINT32 Width, UINT32 Height);
extern void CopyOrResize(CP_INSTANCE* cpi, BOOL ResetPreproc );
extern UINT32 TokenizeFrag(CP_INSTANCE* cpi, INT16* RawData, UINT32 Plane, BLOCK_CONTEXT* Above, BLOCK_CONTEXT* Left);
extern void PredictScanOrder( CP_INSTANCE *cpi );
extern void BuildScanOrder( PB_INSTANCE *pbi, UINT8 * );
#endif
@@ -0,0 +1,69 @@
/****************************************************************************
*
* Module Title : decodemode.h
*
* Description : Functions for decoding modes and motionvectors
*
****************************************************************************/
#ifndef __INC_DECODEMODE_H
#define __INC_DECODEMODE_H
#ifndef STRICT
#define STRICT /* Strict type checking */
#endif
/****************************************************************************
* Module statics
****************************************************************************/
#define MODETYPES 3
#define MODEVECTORS 16
#define PROBVECTORXMIT 174
#define PROBIDEALXMIT 254
/****************************************************************************
* Typedefs
****************************************************************************/
typedef struct _modeContext
{
UINT8 left;
UINT8 above;
UINT8 last;
} MODE_CONTEXT;
typedef struct _htorp
{
unsigned char selector : 1; // 1 bit selector 0->ptr, 1->token
unsigned char value : 7;
} torp;
typedef struct _hnode
{
torp left;
torp right;
} HNODE;
typedef enum _MODETYPE
{
MACROBLOCK,
NONEAREST_MACROBLOCK,
NONEAR_MACROBLOCK,
BLOCK,
} MODETYPE;
/****************************************************************************
* Exports
****************************************************************************/
extern UINT8 Stats[9][4][4][4];
extern const UINT8 VP6_ModeVq[MODETYPES][MODEVECTORS][MAX_MODES*2];
extern const UINT8 VP6_BaselineXmittedProbs[4][2][MAX_MODES];
extern void VP6_BuildModeTree ( PB_INSTANCE *pbi );
extern void VP6_decodeModeAndMotionVector ( PB_INSTANCE *pbi, UINT32 MBrow, UINT32 MBcol );
/****************************************************************************
* Function Prototypes
****************************************************************************/
INLINE int mbClass(int i);
void VP6_DecodeModeProbs(PB_INSTANCE *pbi);
#endif
@@ -0,0 +1,33 @@
/****************************************************************************
*
* Module Title : decodemv.h
*
* Description : Functions for decoding modes and motionvectors
*
****************************************************************************/
#ifndef __INC_DECODEMV_H
#define __INC_DECODEMV_H
#ifndef STRICT
#define STRICT /* Strict type checking */
#endif
/****************************************************************************
* Module statics
****************************************************************************/
#define MV_NODES 17
/****************************************************************************
* Exports
****************************************************************************/
extern const UINT8 DefaultMvShortProbs[2][7];
extern const UINT8 VP6_MvUpdateProbs[2][MV_NODES];
extern const UINT8 DefaultMvLongProbs[2][LONG_MV_BITS];
extern const UINT8 DefaultIsShortProbs[2];
extern const UINT8 DefaultSignProbs[2];
extern void VP6_FindNearestandNextNearest(PB_INSTANCE* pbi, UINT32 MBrow, UINT32 MBcol, UINT8 Frame, int *type);
extern void VP6_ConfigureMvEntropyDecoder( PB_INSTANCE *pbi, UINT8 FrameType );
extern void VP6_decodeMotionVector( PB_INSTANCE *pbi, MOTION_VECTOR *mv, CODING_MODE Mode );
#endif
@@ -0,0 +1,27 @@
/****************************************************************************
*
* Module Title : MiscCommon.h
*
* Description : Miscellaneous common routines header file
*
*****************************************************************************
*/
#ifndef __MISC_COMMON_H
#define __MISC_COMMON_H
#include "type_aliases.h"
#include "compdll.h"
/****************************************************************************
* Function Prototypes
****************************************************************************/
extern double GetEstimatedBpb( CP_INSTANCE *cpi, UINT32 TargetQIndex );
extern void UpdateBpbCorrectionFactor( CP_INSTANCE *cpi, UINT32 FrameSize );
extern void UpRegulateMB( CP_INSTANCE *cpi, UINT32 RegulationQ, UINT32 SB, UINT32 MB, BOOL NoCheck );
extern void ClampAndUpdateQ ( CP_INSTANCE *cpi, UINT32 QIndex );
extern void RegulateQ( CP_INSTANCE *cpi, INT32 TargetBits );
extern void ConfigureQuality( CP_INSTANCE *cpi, UINT32 QualityValue );
extern void CopyBackExtraFrags(CP_INSTANCE *cpi);
extern void VP6_PredictFilteredBlock(PB_INSTANCE* pbi, INT16* OutputPtr, UINT32 bp);
#endif
@@ -0,0 +1,498 @@
/****************************************************************************
*
* Module Title : pbdll.h
*
* Description : Decoder definition header file.
*
****************************************************************************/
#ifndef __INC_PBDLL_H
#define __INC_PBDLL_H
/****************************************************************************
* Module statics.
****************************************************************************/
#define VAL_RANGE 256 // Must come before header files--REMOVE THIS DEPENDENCY!!
/****************************************************************************
* Header Files
****************************************************************************/
#include "codec_common.h"
#include "huffman.h"
#include "tokenentropy.h"
#include "vfw_pb_interface.h"
#include "postproc_if.h"
#include "vputil_if.h"
#include "quantize.h"
#include "boolhuff.h"
#include "rawbuffer.h"
/****************************************************************************
* MACROS
****************************************************************************/
// Enumeration of how block is coded
// VP6.2 version is >= 8
#define CURRENT_ENCODE_VERSION 8
#define CURRENT_DECODE_VERSION 8
#define SIMPLE_PROFILE 0
#define PROFILE_1 1
#define PROFILE_2 2
#define ADVANCED_PROFILE 3
// Loop filter options
#define NO_LOOP_FILTER 0
#define LOOP_FILTER_BASIC 2
#define LOOP_FILTER_DERING 3
#define UMV_BORDER 48
#define STRIDE_EXTRA (UMV_BORDER * 2)
#define BORDER_MBS (UMV_BORDER>>4)
#define MAX_MV_EXTENT 63 // Max search distance in half pixel increments
#define MV_ENTROPY_TOKENS 511
#define LONG_MV_BITS 8
#define PPROC_QTHRESH 64
#define MAX_MODES 10
#define MAX_NEAREST_ADJ_INDEX 2
#define Y_MVSHIFT 0x2
#define UV_MVSHIFT 0x3
#define Y_MVMODMASK 0x3
#define UV_MVMODMASK 0x7
// INT32 MvShift; // motion vector shift value
// INT32 MvModMask;
// Prediction filter modes:
// Note: when trying to use an enum here we ran into an odd compiler bug in
// the WriteFrameHeader() code. Also an enum type is implicitly an int which
// is a bit big for something that can only have 3 values
#define BILINEAR_ONLY_PM 0
#define BICUBIC_ONLY_PM 1
#define AUTO_SELECT_PM 2
#define DCProbOffset(A,B) \
( (A) * (MAX_ENTROPY_TOKENS-1) \
+ (B) )
#define ACProbOffset(A,B,C,D) \
( (A) * PREC_CASES * VP6_AC_BANDS * (MAX_ENTROPY_TOKENS-1) \
+ (B) * VP6_AC_BANDS * (MAX_ENTROPY_TOKENS-1) \
+ (C) * (MAX_ENTROPY_TOKENS-1) \
+ (D) )
#define DcNodeOffset(A,B,C) \
( (A) * DC_TOKEN_CONTEXTS * CONTEXT_NODES \
+ (B) * CONTEXT_NODES \
+ (C) )
#define MBOffset(row,col) ( (row) * pbi->MBCols + (col) )
/****************************************************************************
* Types
****************************************************************************/
typedef enum
{
CODE_INTER_NO_MV = 0x0, // INTER prediction, (0,0) motion vector implied.
CODE_INTRA = 0x1, // INTRA i.e. no prediction.
CODE_INTER_PLUS_MV = 0x2, // INTER prediction, non zero motion vector.
CODE_INTER_NEAREST_MV = 0x3, // Use Last Motion vector
CODE_INTER_NEAR_MV = 0x4, // Prior last motion vector
CODE_USING_GOLDEN = 0x5, // 'Golden frame' prediction (no MV).
CODE_GOLDEN_MV = 0x6, // 'Golden frame' prediction plus MV.
CODE_INTER_FOURMV = 0x7, // Inter prediction 4MV per macro block.
CODE_GOLD_NEAREST_MV = 0x8, // Use Last Motion vector
CODE_GOLD_NEAR_MV = 0x9, // Prior last motion vector
DO_NOT_CODE = 0x10 // Fake Mode
} CODING_MODE;
typedef struct
{
unsigned int FragCodingMode : 4;
int MVectorX : 8;
int MVectorY : 8;
} FRAG_INFO;
typedef struct _DCINFO
{
Q_LIST_ENTRY dc;
short frame;
} DCINFO;
// defined so i don't have to remember which block goes where
typedef enum
{
TOP_LEFT_Y_BLOCK = 0,
TOP_RIGHT_Y_BLOCK = 1,
BOTTOM_LEFT_Y_BLOCK = 2,
BOTTOM_RIGHT_Y_BLOCK = 3,
U_BLOCK = 4,
V_BLOCK = 5
} BLOCK_POSITION;
// all the information gathered from a block to be used as context in the next block
typedef struct
{
UINT8 Token;
CODING_MODE Mode;
UINT16 Frame;
Q_LIST_ENTRY Dc;
UINT8 unused[3];
} BLOCK_CONTEXT;
// all the contexts maintained for a frame
typedef struct
{
BLOCK_CONTEXT LeftY[2]; // 1 for each block row in a macroblock
BLOCK_CONTEXT LeftU;
BLOCK_CONTEXT LeftV;
BLOCK_CONTEXT *AboveY;
BLOCK_CONTEXT *AboveU;
BLOCK_CONTEXT *AboveV;
// BLOCK_CONTEXT *AboveYAlloc;
// BLOCK_CONTEXT *AboveUAlloc;
// BLOCK_CONTEXT *AboveVAlloc;
Q_LIST_ENTRY LastDcY[4]; // 1 for each frame
Q_LIST_ENTRY LastDcU[4];
Q_LIST_ENTRY LastDcV[4];
} FRAME_CONTEXT;
// Structure to hold last token values at each position in block
typedef UINT8 TOKENBUFFER[256];
typedef struct
{
INT16 *dequantPtr;
INT16 *coeffsPtr;
INT8 *reconPtr;
INT32 MvShift; // motion vector shift value
INT32 MvModMask; // motion vector mod mask
INT32 FrameReconStride; // Stride of the frame
INT32 CurrentReconStride; // pitch of reconstruction
INT32 CurrentSourceStride; // pitch of source (compressor only)
INT32 FrameSourceStride; // Stride of the frame (compressor only)
UINT32 Plane; // plane block is from (compressor only)
BLOCK_CONTEXT *Above; // above block context
BLOCK_CONTEXT *Left; // left block context
Q_LIST_ENTRY *LastDc; // last dc value seen
UINT32 thisRecon; // index for recon
UINT32 Source; // index for source (compressor only)
UINT32 EobPos;
UINT8 *BaselineProbsPtr;
UINT8 *ContextProbsPtr;
UINT8 *AcProbsBasePtr;
UINT8 *DcProbsBasePtr;
UINT8 *DcNodeContextsBasePtr;
UINT8 *ZeroRunProbsBasePtr;
// BOOL_CODER *br;
// INT32 token;
// UINT8 *MergedScanOrder;
// UINT8 *MergedScanOrderPtr;
}BLOCK_DX_INFO;
typedef struct
{
BOOL_CODER *br;
BLOCK_DX_INFO blockDxInfo[6];
CODING_MODE Mode; // mode macroblock coded as
//note: these should be moved into blockDxInfo
CODING_MODE BlockMode[6]; // mode macroblock coded as
MOTION_VECTOR Mv[6]; // one motion vector per block u and v calculated from rest
MOTION_VECTOR NearestInterMVect;// nearest mv in last frame
MOTION_VECTOR NearInterMVect; // near mv in last frame
INT32 NearestMvIndex; // Indicates how neare nearest is.
MOTION_VECTOR NearestGoldMVect; // nearest mv in gold frame
MOTION_VECTOR NearGoldMVect; // near mv in gold frame
INT32 NearestGMvIndex; // Indicates how neare nearest is.
INT32 Interlaced; // is the macroblock interlaced?
// Q_LIST_ENTRY *CoeffsAlloc; // coefficients 64 per frag 4 y in raster order, u then v
} MACROBLOCK_INFO;
// Frame Header type
typedef struct FRAME_HEADER
{
UINT8 *buffer;
UINT32 value;
INT32 bits_available;
UINT32 pos;
} FRAME_HEADER;
typedef struct _BITREADER
{
int bitsinremainder; // # of bits still used in remainder
UINT32 remainder; // remaining bits from original long
const unsigned char * position; // character pointer position within data
} BITREADER;
// Playback Instance Definition
typedef struct PB_INSTANCE
{
MACROBLOCK_INFO mbi; // all the information needed for one macroblock
FRAME_CONTEXT fc; // all of the context information needed for a frame
QUANTIZER *quantizer;
// Should be able to delete these entries when VP5 complete
INT32 CodedBlockIndex;
UINT8 *DataOutputInPtr;
FRAG_INFO *FragInfo;
// FRAG_INFO *FragInfoAlloc;
/* Current access points fopr input and output buffers */
BOOL_CODER br;
BOOL_CODER br2;
BITREADER br3;
// Decoder and Frame Type Information
UINT8 Vp3VersionNo;
UINT8 VpProfile;
UINT32 PostProcessingLevel; /* Perform post processing */
UINT32 ProcessorFrequency; /* CPU frequency */
UINT32 CPUFree;
UINT8 FrameType;
CONFIG_TYPE Configuration; // frame configuration
UINT32 CurrentFrameSize;
UINT32 YPlaneSize;
UINT32 UVPlaneSize;
UINT32 VFragments;
UINT32 HFragments;
UINT32 UnitFragments;
UINT32 YPlaneFragments;
UINT32 UVPlaneFragments;
UINT32 ReconYPlaneSize;
UINT32 ReconUVPlaneSize;
UINT32 YDataOffset;
UINT32 UDataOffset;
UINT32 VDataOffset;
UINT32 ReconYDataOffset;
UINT32 ReconUDataOffset;
UINT32 ReconVDataOffset;
UINT32 MacroBlocks; // Number of Macro-Blocks in Y component
UINT32 MBRows; // Number of rows of MacroBlocks in a Y frame
UINT32 MBCols; // Number of cols of MacroBlocks in a Y frame
UINT32 ScaleWidth;
UINT32 ScaleHeight;
UINT32 OutputWidth;
UINT32 OutputHeight;
// Frame Buffers
YUV_BUFFER_ENTRY *ThisFrameRecon;
// YUV_BUFFER_ENTRY *ThisFrameReconAlloc;
YUV_BUFFER_ENTRY *GoldenFrame;
// YUV_BUFFER_ENTRY *GoldenFrameAlloc;
YUV_BUFFER_ENTRY *LastFrameRecon;
// YUV_BUFFER_ENTRY *LastFrameReconAlloc;
YUV_BUFFER_ENTRY *PostProcessBuffer;
// YUV_BUFFER_ENTRY *PostProcessBufferAlloc;
YUV_BUFFER_ENTRY *ScaleBuffer; /* new buffer for testing new loop filtering scheme */
// YUV_BUFFER_ENTRY *ScaleBufferAlloc;
Q_LIST_ENTRY *quantized_list;
// INT16 *ReconDataBuffer;
INT16 *ReconDataBuffer[6];
// INT16 *ReconDataBufferAlloc;
// UINT8 FragCoefEOB; // Position of last non 0 coef within QFragData
INT16 *TmpReconBuffer;
// INT16 *TmpReconBufferAlloc;
INT16 *TmpDataBuffer;
// INT16 *TmpDataBufferAlloc;
// UINT8 *LoopFilteredBlockAlloc;
UINT8 *LoopFilteredBlock;
void (**idct)(INT16 *InputData, INT16 *QuantMatrix, INT16 * OutputData );
POSTPROC_INST postproc;
TOKENBUFFER LastToken; // LTIndex of tokens at each position in block
CODING_MODE LastMode; // Last Mode decoded;
UINT8 DcProbs[2*(MAX_ENTROPY_TOKENS-1)];
UINT8 AcProbs[2*PREC_CASES*VP6_AC_BANDS*(MAX_ENTROPY_TOKENS-1)];
//3 MAX_ENTROPY_TOKENS-7
// UINT8 DcNodeContexts[2][DC_TOKEN_CONTEXTS][CONTEXT_NODES]; // Plane, Contexts, Node
UINT8 DcNodeContexts[2 * DC_TOKEN_CONTEXTS * CONTEXT_NODES]; // Plane, Contexts, Node
UINT8 ZeroRunProbs[ZRL_BANDS][ZERO_RUN_PROB_CASES];
UINT8 MergedScanOrder[BLOCK_SIZE + 65];
UINT8 ModifiedScanOrder[BLOCK_SIZE];
UINT8 EobOffsetTable[BLOCK_SIZE];
UINT8 ScanBands[BLOCK_SIZE];
UINT8 MBModeProb[11];
UINT8 BModeProb[11];
UINT8 PredictionFilterMode;
UINT8 PredictionFilterMvSizeThresh;
UINT32 PredictionFilterVarThresh;
UINT8 PredictionFilterAlpha;
BOOL RefreshGoldenFrame;
UINT8 Inter00Prob;
UINT32 AvgFrameQIndex;
BOOL testMode;
UINT32 mvNearOffset[16];
int probInterlaced;
char *MBInterlaced;
char *predictionMode;
MOTION_VECTOR *MBMotionVector;
// char *MBInterlacedAlloc;
// char *predictionModeAlloc;
// MOTION_VECTOR *MBMotionVectorAlloc;
UINT8 MvSignProbs[2];
UINT8 IsMvShortProb[2];
UINT8 MvShortProbs[2][7];
UINT8 MvQPelProbs[2];
UINT8 MvHalfPixelProbs[2];
UINT8 MvLowBitProbs[2];
UINT8 MvSizeProbs[2][LONG_MV_BITS];
UINT8 probXmitted[4][2][MAX_MODES];
UINT8 probModeSame[4][MAX_MODES];
UINT8 probMode[4][MAX_MODES][MAX_MODES-1]; // nearest+near,nearest only, nonearest+nonear, 10 preceding modes, 9 nodes
UINT32 maxTimePerFrame;
UINT32 thisDecodeTime;
UINT32 avgDecodeTime;
UINT32 avgPPTime[10];
UINT32 avgBlitTime;
// Does this frame use multiple data streams
// Multistream is implicit for SIMPLE_PROFILE
BOOL MultiStream;
// Huffman code tables for DC, AC & Zero Run Length
UINT32 DcHuffCode[2][MAX_ENTROPY_TOKENS];
UINT8 DcHuffLength[2][MAX_ENTROPY_TOKENS];
UINT32 DcHuffProbs[2][MAX_ENTROPY_TOKENS];
HUFF_NODE DcHuffTree[2][MAX_ENTROPY_TOKENS];
UINT32 AcHuffCode[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT8 AcHuffLength[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT32 AcHuffProbs[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
HUFF_NODE AcHuffTree[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS];
UINT32 ZeroHuffCode[ZRL_BANDS][ZERO_RUN_PROB_CASES];
UINT8 ZeroHuffLength[ZRL_BANDS][ZERO_RUN_PROB_CASES];
UINT32 ZeroHuffProbs[ZRL_BANDS][ZERO_RUN_PROB_CASES];
HUFF_NODE ZeroHuffTree[ZRL_BANDS][ZERO_RUN_PROB_CASES];
/* FAST look-up-table for huffman Trees */
UINT16 DcHuffLUT[2][1<<HUFF_LUT_LEVELS];
UINT16 AcHuffLUT[PREC_CASES][2][VP6_AC_BANDS][1<<HUFF_LUT_LEVELS];
UINT16 ZeroHuffLUT[ZRL_BANDS][1<<HUFF_LUT_LEVELS];
RAW_BUFFER HuffBuffer;
// Second partition buffer details
FRAME_HEADER Header;
UINT32 Buff2Offset;
// Note: Use of huffman codes for DCT data is only allowed
// when using multiple data streams / partitions
BOOL UseHuffman;
// Counters for runs of zeros at DC & EOB at first AC position in Huffman mode
INT32 CurrentDcRunLen[2];
INT32 CurrentAc1RunLen[2];
// Should we do loop filtering.
// In simple profile this is ignored and there is no loop filtering
UINT8 UseLoopFilter;
// Control of dering loop/prediction filter
UINT32 DrCutOff;
UINT32 DrThresh[256];
UINT32 BlackClamp;
UINT32 WhiteClamp;
UINT32 DeInterlaceMode;
UINT32 AddNoiseMode;
} PB_INSTANCE;
/****************************************************************************
* Exports
****************************************************************************/
extern UINT8 LimitVal_VP31[VAL_RANGE * 3];
extern BOOL VP6_ModeUsesMC[MAX_MODES]; // table to indicate if the given mode uses motion estimation
extern const int VP6_Mode2Frame[DO_NOT_CODE];
extern const INT32 VP6_CoeffToBand[65];
extern const UINT8 DefaultNonInterlacedScanBands[BLOCK_SIZE];
extern const UINT8 DefaultInterlacedScanBands[BLOCK_SIZE];
extern PB_INSTANCE *VP6_CreatePBInstance ( void );
extern void VP6_DeletePBInstance ( PB_INSTANCE** );
extern BOOL VP6_LoadFrame ( PB_INSTANCE *pbi );
extern void VP6_SetFrameType ( PB_INSTANCE *pbi, UINT8 FrType );
extern UINT8 VP6_GetFrameType ( PB_INSTANCE *pbi );
extern BOOL VP6_InitFrameDetails ( PB_INSTANCE *pbi );
extern void VP6_ErrorTrap ( PB_INSTANCE *pbi, int ErrorCode );
extern BOOL VP6_AllocateFragmentInfo ( PB_INSTANCE *pbi );
extern BOOL VP6_AllocateFrameInfo ( PB_INSTANCE *pbi, unsigned int FrameSize );
extern void VP6_DeleteFragmentInfo ( PB_INSTANCE *pbi );
extern void VP6_DeleteFrameInfo ( PB_INSTANCE *pbi );
extern void VP6_DMachineSpecificConfig ( void );
extern UINT32 VP6_bitread1 ( BOOL_CODER *br ) ;
extern UINT32 VP6_bitread ( BOOL_CODER *br, int bits );
extern void vp6_appendframe ( PB_INSTANCE *pbi );
extern void VP6_readTSC ( unsigned long *tsc );
extern void VP6_ConfigureContexts ( PB_INSTANCE *pbi );
extern void VP6_ResetAboveContext ( PB_INSTANCE *pbi );
extern void VP6_ResetLeftContext ( PB_INSTANCE *pbi );
extern void VP6_UpdateContext ( PB_INSTANCE *pbi, BLOCK_CONTEXT *c, BLOCK_POSITION bp );
extern void VP6_UpdateContextA ( PB_INSTANCE *pbi, BLOCK_CONTEXT *c, BLOCK_POSITION bp );
extern void VP6_PredictDC ( PB_INSTANCE *pbi, BLOCK_POSITION bp );
extern void VP6_PredictDC_MB ( PB_INSTANCE *pbi );
extern void VP6_ReconstructBlock ( PB_INSTANCE *pbi, BLOCK_POSITION bp );
//extern void VP6_ReconstructMacroBlock ( PB_INSTANCE *pbi);
extern void VP6_PredictFilteredBlock(PB_INSTANCE* pbi, INT16* OutputPtr, UINT32 bp);
#endif
@@ -0,0 +1,65 @@
/****************************************************************************
*
* Module Title : quantize.h
*
* Description : Quantizer header file.
*
****************************************************************************/
#ifndef __INC_QUANTIZE_H
#define __INC_QUANTIZE_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "codec_common.h"
#include "codec_common_interface.h"
/****************************************************************************
* Macros
****************************************************************************/
/****************************************************************************
* Structures
****************************************************************************/
typedef struct
{
UINT32 FrameQIndex; // Quality specified as a table index
UINT32 LastFrameQIndex;
short round[8];
short mult[8];
short zbin[8];
UINT32 QThreshTable[Q_TABLE_SIZE]; // ac quantizer scale values
UINT32 *transIndex; // array to reorder zig zag to idct's ordering
UINT8 quant_index[64]; // array to reorder from raster to zig zag
// used by the dequantizer
Q_LIST_ENTRY * dequant_coeffs[2]; // pointer to current dequantization tables
Q_LIST_ENTRY * dequant_coeffsAlloc[2]; // alloc so we can keep alligned
INT32 QuantCoeffs[2][64]; // Quantizer values table
INT32 QuantRound[2][64]; // Quantizer rounding table
INT32 ZeroBinSize[2][64]; // Quantizer zero bin table
INT32 ZlrZbinCorrections[2][64]; // Zbin corrections based upon zero run length.
} QUANTIZER;
/****************************************************************************
* Exports
****************************************************************************/
extern const UINT8 VP6_QTableSelect[6];
extern const Q_LIST_ENTRY VP6_DcQuant[Q_TABLE_SIZE];
extern void (*VP6_quantize) ( QUANTIZER *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
extern void (*VP6_BuildQuantIndex)( QUANTIZER * pbi);
extern void VP6_InitQTables ( QUANTIZER *pbi, UINT8 Vp3VersionNo );
extern void VP6_UpdateQ ( QUANTIZER *pbi, UINT8 Vp3VersionNo );
extern void VP6_UpdateQC ( QUANTIZER *pbi, UINT8 Vp3VersionNo );
extern QUANTIZER * VP6_CreateQuantizer ( void );
extern void VP6_DeleteQuantizer ( QUANTIZER **pbi );
#endif
@@ -0,0 +1,112 @@
#ifndef vp5d_h
#define vp5d_h 1
// Interface between vp3d.dll and Albany's DXV adaptor/blitter.
// Timothy S. Murphy 13 September 1999.
// The main object "defined" here.
struct VP3decompressor;
// Some conveniences.
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
// FourCC codes. Should agree with microsoft's definition
// sans their stupid types and include files.
typedef ulong FourCC;
#define MakeFourCC( a, b, c, d) ( \
(ulong) (uchar) a \
| (ulong) (uchar) b << 8 \
| (ulong) (uchar) c << 16 \
| (ulong) (uchar) d << 24 \
)
// A temporary fourCC for Eric & I to use til the bit stream stabilizes.
// (Eric - "hurl4cc" should NOT appear anywhere in your code, I just put it
// here so you can check the fourCC representations in memory and files.)
#define hurl4cc MakeFourCC( 'H', 'U', 'R', 'L')
// The actual fourCC for now; similar remarks apply.
#define VP30 1
#if VP30
# define wilk4cc MakeFourCC( 'V', 'P', '3', '0')
#else
# define wilk4cc MakeFourCC( 'W', 'I', 'L', 'K')
#endif
// Array of fourCC codes, has length _and_ is null-terminated.
// As Donald Knuth once said,
// "Some people occasionally like a little extra redundancy sometimes."
typedef struct { const FourCC * codes; uint numCodes;} FourCClist;
// YUV buffer configuration.
typedef struct {
ulong Ywidth, Yheight, UVwidth, UVheight;
long Ystride, UVstride;
const uchar *Ybuf, *Ubuf, *Vbuf;
} YUVbufferLayout;
#if __cplusplus
# define Decompressor VP3decompressor
extern "C" {
#else
# define Decompressor struct VP3decompressor
#endif
#if defined(MACPPC)
#define _stdcall
#endif
// Return array of fourCC codes supported.
const FourCClist * _stdcall VP3DfourCClist();
// Create a decompressor for a particular supported stream type.
// Returns 0 on failure.
Decompressor * _stdcall VP3DcreateDecompressor( FourCC streamType);
void _stdcall VP3DdestroyDecompressor( Decompressor *);
// Advance to next frame, returning reference to updated YUV buffer.
const YUVbufferLayout * _stdcall VP3DnextFrame
(
Decompressor *, const uchar * CXdata, ulong CXdataLengthInBytes
);
void _stdcall VP3DblitBGR(
const Decompressor *, uchar * outRGB, long outStride, long outHeight
);
#if __cplusplus
}
#endif
#undef Decompressor
#endif // vp3d_h
@@ -0,0 +1,31 @@
/****************************************************************************
*
* Module Title : xprintf.h
*
* Description : Debug print interface header file.
*
****************************************************************************/
#ifndef __INC_XPRINTF_H
#define __INC_XPRINTF_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
/****************************************************************************
* Functions
****************************************************************************/
#if __cplusplus
extern "C"
{
#endif
// Display a printf style message on the current video frame
extern int vp6_xprintf(const PB_INSTANCE* ppbi, long pixel, const char* format, ...);
#if __cplusplus
}
#endif
#endif
@@ -0,0 +1,72 @@
## Target to built
TARGET =libvp6e
## TOOLS
CC = ecc
LD = ecc
AR = ar
OBJDUMP = objdump
RM = rm -f
## Directories
TOPDIR =C:\DuckSoft
PRIVATEINCLUDE =${TOPDIR}\private\include
PRIVATEINCLUDE2 =${TOPDIR}\private\include\vp60
CORELIBSINCLUDE =${TOPDIR}\private\corelibs\include
CDXVINCLUDE =${TOPDIR}\private\corelibs\cdxv\include
VP6INCLUDE =${TOPDIR}\private\corelibs\cdxv\vp60\vp60\include
CXGENERIC =${TOPDIR}\private\corelibs\cdxv\vp60\vp60\cx\generic
OBJDIR =${TOPDIR}\ObjectCode\bspvp6e
CURRENTDIR =${TOPDIR}\private\corelibs\cdxv\vp60\vp60
LIBDIR =${TOPDIR}\private\corelibs\lib\mapca
## Compile Flags
ALLINCLUDES =-I${CXGENERIC} -I${VP6INCLUDE} -I${CDXVINCLUDE} -I${CORELIBSINCLUDE} -I${PRIVATEINCLUDE} -I${PRIVATEINCLUDE2}
VP6DEFINES =-DPREDICT_2D -DVFW_COMP -DCOMPDLL -DPOSTPROCESS -DCPUISLITTLEENDIAN -DNORMALIZED
ETIDEFINES =-DMAPCA
ALLDEFINES =${VP6DEFINES} ${ETIDEFINES}
DEBUG =-O2
CFLAGS =-msvc -align 8 -ms -etswp -mP3OPT_nonlocal_calls_through_register=true \
-mP2OPT_suppress_library_call_conv_warnings=TRUE -maalign_branch_target \
-magen_interroutine_padding
ALLFLAGS = $(CFLAGS) ${ALLDEFINES} ${ALLINCLUDES} ${DEBUG}
## Files
OBJS = cx\bsp\PackVideo.o \
cx\bsp\PickModes.o \
cx\generic\RawBuffer.o \
cx\bsp\bspTokenize.o \
cx\generic\Transform.o \
cx\bsp\encode.o \
cx\bsp\encodembs.o \
cx\bsp\encodemode.o \
cx\generic\encodemv.o \
cx\bsp\mcomp.o \
cx\generic\misc_common.o \
cx\generic\twopass.o \
cx\bsp\vfwcomp.o \
cx\generic\vfwcomp_if.o \
cx\bsp\bspComp_Globals.o \
cx\bsp\mcompopt.o \
cx\bsp\bsptransform.o \
cx\bsp\CSystemDependant.o
SRCS = $(OBJS:.o=.c)
ARTARGET = ${TARGET}.a
# archive
ARTARGET:${OBJS}
${AR} -cr ${ARTARGET} ${OBJS}
mv ${ARTARGET} ${LIBDIR}
${OBJS} : ${SRCS}
$(CC) $(ALLFLAGS) -c $*.c -o $*.o
clean:
${RM} ${OBJS} ${ARTARGET}
@@ -0,0 +1,21 @@
/****************************************************************************
*
* Module Title : CFrameW.h
*
* Description : Frame writing functions.
*
****************************************************************************/
#ifndef __INC_CFRAMEW_H
#define __INC_CFRAMEW_H
/****************************************************************************
* Header Files
****************************************************************************/
#include "type_aliases.h"
/****************************************************************************
* Functions
****************************************************************************/
extern void WriteFrameHeader ( CP_INSTANCE *cpi );
#endif
@@ -0,0 +1,79 @@
/****************************************************************************
*
* Module Title : SystemDependant.c
*
* Description : Miscellaneous system dependant functions
*
****************************************************************************/
#define STRICT /* Strict type checking. */
/****************************************************************************
* Header Files
****************************************************************************/
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "pbdll.h"
#include "compdll.h"
#include "mcomp.h"
#include "quantize.h"
#include "resource.h" /* Resource IDs. */
/****************************************************************************
* Explicit imports
****************************************************************************/
#if defined(POSTPROCESS)
extern void FDct1d4 (INT16 *InputData, INT16 * OutputData);
extern void IDct4( INT16 *InputData, INT16 *OutputData);
#endif
extern UINT32 ComputeBlockReconError ( CP_INSTANCE *cpi, UINT32 bp);
extern UINT32 GetSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 GetHalfPixelSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,UINT8 * RefPtr2,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 GetIntraErrorC( UINT8* DataPtr, INT32 SourceStride);
extern UINT32 GetInterErr( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride );
extern UINT32 GetSumAbsDiffs( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 GetHalfPixelSumAbsDiffs( UINT8 * SrcData, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern void VP6_quantize_c( QUANTIZER *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
extern UINT32 GetMBFieldVerticalVariance( CP_INSTANCE *cpi);
extern UINT32 FiltBlockBilGetSad_C(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
/****************************************************************************
*
* ROUTINE : CMachineSpecificConfig
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Sets function pointers to vanilla "C" implementations.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CMachineSpecificConfig ( void )
{
GetSAD16 = GetSumAbsDiffs16;
GetSadHalfPixel16 = GetHalfPixelSumAbsDiffs16;
GetSAD = GetSumAbsDiffs;
GetSadHalfPixel = GetHalfPixelSumAbsDiffs;
GetInterError = GetInterErr;
GetIntraError = GetIntraErrorC;
fdct_short = fdct_short_C;
VP6_quantize = VP6_quantize_c;
Sub8 = SUB8;
Sub8_128 = SUB8_128;
Sub8Av2 = SUB8AV2;
GetMBFrameVertVar = GetMBFrameVerticalVariance;
GetMBFieldVertVar = GetMBFieldVerticalVariance;
FiltBlockBilGetSad = FiltBlockBilGetSad_C;
GetBlockReconErr = ComputeBlockReconError;
}
@@ -0,0 +1,371 @@
/****************************************************************************
*
* Module Title : Comp_Globals.c
*
* Description : Global compressor functions & declarations.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h> // For Abs()
#include "compdll.h"
#include "mcomp.h"
/****************************************************************************
* Macros
****************************************************************************/
#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
/****************************************************************************
* Exports
****************************************************************************/
INT32 *XX_LUT;
static INT32 XSquaredTable[511];
// Motion compensation related variables
INT32 *AbsX_LUT = NULL;
static INT32 AbsXTable[511];
UINT32 (*FiltBlockBilGetSad)(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
UINT32 (*GetSAD16)(UINT8 *, INT32, UINT8 *, INT32, UINT32, UINT32);
UINT32 (*GetSadHalfPixel16)(UINT8 *, INT32, UINT8 *, UINT8 *, INT32, UINT32, UINT32);
UINT32 (*GetSAD)(UINT8 *, INT32, UINT8 *, INT32, UINT32, UINT32);
UINT32 (*GetSadHalfPixel)(UINT8 *, INT32, UINT8 *, UINT8 *, INT32, UINT32, UINT32);
UINT32 (*GetInterError)( UINT8 *, INT32, UINT8 *, UINT8 *, INT32 );
UINT32 (*GetIntraError)( UINT8 *, INT32 );
void (*fdct_short) ( INT16 * InputData, INT16 * OutputData );
void (*Sub8)( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconStride);
void (*Sub8_128)( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride );
void (*Sub8Av2)( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr2, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconStride );
/****************************************************************************
* Explicit Imports
****************************************************************************/
extern unsigned int CPUFrequency;
extern void VP6_DeleteTmpBuffers(PB_INSTANCE * pbi);
extern BOOL VP6_AllocateTmpBuffers(PB_INSTANCE * pbi);
extern void VP6_VPInitLibrary(void);
extern void VP6_VPDeInitLibrary(void);
extern void FillValueTokens ( void );
/****************************************************************************
*
* ROUTINE : EDeleteFragmentInfo
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Deletes memory allocated for member data structures.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void EDeleteFragmentInfo ( CP_INSTANCE *cpi )
{
if( cpi->DCT_codes )
duck_free( cpi->DCT_codes );
cpi->DCT_codes = 0;
if( cpi->DCTDataBuffer )
duck_free( cpi->DCTDataBuffer);
cpi->DCTDataBuffer = 0;
if( cpi->quantized_list)
duck_free( cpi->quantized_list);
cpi->quantized_list = 0;
if( cpi->MbBestErr )
duck_free(cpi->MbBestErr);
cpi->MbBestErr = 0;
#if defined FULLFRAMEFDCT
if( cpi->FDCTCoeffs)
duck_free(cpi->FDCTCoeffs);
cpi->FDCTCoeffs = 0;
#endif
}
/****************************************************************************
*
* ROUTINE : EAllocateFragmentInfo
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: TRUE on success, FALSE if allocation failure.
*
* FUNCTION : Allocates memory for encoder data structures.
*
* SPECIAL NOTES : Uses ROUNDUP32 to align pointers to 32-byte boundaries.
*
****************************************************************************/
BOOL EAllocateFragmentInfo ( CP_INSTANCE *cpi )
{
// De-allocate existing memory
EDeleteFragmentInfo(cpi);
// Allocate new memory
cpi->DCT_codes = duck_memalign(32, 64*sizeof(INT16), DMEM_GENERAL);
if(!cpi->DCT_codes) { EDeleteFragmentInfo(cpi); return FALSE; }
cpi->quantized_list = duck_memalign(32, 64*sizeof(Q_LIST_ENTRY), DMEM_GENERAL);
if(!cpi->quantized_list) { EDeleteFragmentInfo(cpi); return FALSE; }
cpi->DCTDataBuffer = duck_memalign(32, 64*sizeof(INT16), DMEM_GENERAL);
if(!cpi->DCTDataBuffer) { EDeleteFragmentInfo(cpi); return FALSE; }
cpi->MbBestErr = (UINT32 *) duck_memalign(32, cpi->pb.MacroBlocks * sizeof(UINT32), DMEM_GENERAL);
if(!cpi->MbBestErr) { EDeleteFrameInfo(cpi); return FALSE; }
#if defined FULLFRAMEFDCT
cpi->FDCTCoeffs= (Q_LIST_ENTRY(*)[64]) duck_memalign(32, sizeof(Q_LIST_ENTRY)*64* cpi->pb.UnitFragments , DMEM_GENERAL);
if(!cpi->FDCTCoeffs) {EDeleteFragmentInfo(cpi); return FALSE;}
#endif
return TRUE;
}
/****************************************************************************
*
* ROUTINE : EDeleteFrameInfo
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Deletes memory allocated for frame buffers.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void EDeleteFrameInfo ( CP_INSTANCE *cpi )
{
if(cpi->yuv0ptr)
duck_free(cpi->yuv0ptr);
cpi->yuv0ptr = 0;
if(cpi->yuv1ptr)
duck_free(cpi->yuv1ptr);
cpi->yuv1ptr = 0;
if( cpi->CoeffTokens )
duck_free(cpi->CoeffTokens);
cpi->CoeffTokens = 0;
if( cpi->OutputBuffer2 )
duck_free(cpi->OutputBuffer2);
cpi->OutputBuffer2 = 0;
}
/****************************************************************************
*
* ROUTINE : EAllocateFrameInfo
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: TRUE on success, FALSE if allocation failure.
*
* FUNCTION : Allocates memory for frame buffers.
*
* SPECIAL NOTES : Uses ROUNDUP32 to align pointers to 32-byte boundaries.
*
****************************************************************************/
BOOL EAllocateFrameInfo ( CP_INSTANCE *cpi )
{
int FrameSize = cpi->pb.ReconYPlaneSize + 2 * cpi->pb.ReconUVPlaneSize;
// De-allocate existing memory
EDeleteFrameInfo ( cpi );
// Allocate frame buffers aligned to 32-byte boundaries
cpi->yuv0ptr = duck_memalign(32, FrameSize*sizeof(YUV_BUFFER_ENTRY), DMEM_GENERAL);
if(!cpi->yuv0ptr) { EDeleteFrameInfo(cpi); return FALSE; }
cpi->yuv1ptr = duck_memalign(32, FrameSize*sizeof(YUV_BUFFER_ENTRY), DMEM_GENERAL);
if(!cpi->yuv1ptr) { EDeleteFrameInfo(cpi); return FALSE; }
cpi->CoeffTokens = duck_memalign(32, FrameSize*sizeof(TOKENEXTRA), DMEM_GENERAL);
if(!cpi->CoeffTokens) { EDeleteFrameInfo(cpi); return FALSE; }
// Allocate the temporary output buffer for packed dct data
cpi->OutputBuffer2 = duck_memalign(32, FrameSize, DMEM_GENERAL);
if(!cpi->OutputBuffer2) { EDeleteFrameInfo(cpi); return FALSE; }
return TRUE;
}
/****************************************************************************
*
* ROUTINE : DeleteCPInstance
*
* INPUTS : None.
*
* OUTPUTS : CP_INSTANCE **cpi : Pointer to pointer to encoder instance.
*
* RETURNS : void
*
* FUNCTION : Deletes memory allocated for encoder instance and sets
* encoder instance pointer to NULL.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void DeleteCPInstance ( CP_INSTANCE **cpi )
{
if ( *cpi != NULL )
{
DeletePreProc ( &(*cpi)->preproc );
VP6_DeleteTmpBuffers ( &(*cpi)->pb );
duck_free ( *cpi );
*cpi = NULL;
}
}
/****************************************************************************
*
* ROUTINE : CreateCPInstance
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : CP_INSTANCE *: Pointer to new encoder instance or NULL.
*
* FUNCTION : Creates and initializes an encoder instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
CP_INSTANCE *CreateCPInstance ( void )
{
UINT32 i;
CP_INSTANCE *cpi;
// Allocate encoder data structure
int cpi_size = sizeof( CP_INSTANCE );
cpi = duck_malloc ( cpi_size, DMEM_GENERAL );
if ( !cpi )
return NULL;
// Initialize
memset ( (unsigned char *)cpi, 0, cpi_size );
// Allocate decoder buffers
if ( !VP6_AllocateTmpBuffers(&cpi->pb) )
{
DeleteCPInstance(&cpi);
return NULL;
}
// Initialise Configuration structure to legal values
cpi->Configuration.BaseQ = 32;
cpi->Configuration.FirstFrameQ = 32;
cpi->Configuration.WorstQuality = 32;
cpi->Configuration.ActiveWorstQuality = 8;
cpi->Configuration.ActiveBestQuality = Q_TABLE_SIZE - 4;
cpi->Configuration.OutputFrameRate = 30;
cpi->Configuration.TargetBandwidth = 100*1024;
cpi->MVChangeFactor = 14;
cpi->FourMvChangeFactor = 8;
cpi->ExhaustiveSearchThresh = 2500;
cpi->MinImprovementForFourMV = 100;
cpi->FourMVThreshold = 10000;
cpi->IntraThresh = 25;
cpi->InterTripOutThresh = 5000;
cpi->BpbCorrectionFactor = 1.0;
cpi->KeyFrameBpbCorrectionFactor = 1.0;
cpi->GoldenFrameEnabled = TRUE;
cpi->InterPrediction = TRUE;
cpi->MotionCompensation = TRUE;
cpi->ThreshMapThreshold = 5;
cpi->QuickCompress = TRUE;
cpi->RdOpt = 0;
cpi->PreProcFilterLevel = 4;
cpi->FixedQ = -1;
cpi->pb.idct = idctc;
cpi->pb.ProcessorFrequency = CPUFrequency;
memset ( cpi->pb.DcProbs, 0, sizeof(cpi->pb.DcProbs) );
memset ( cpi->pb.AcProbs, 0, sizeof(cpi->pb.AcProbs) );
cpi->nExperimentals = 0;
for ( i=0; i<C_SET_EXPERIMENTAL_MAX-C_SET_EXPERIMENTAL_MIN+1; i++ )
cpi->Experimental[i] = 0;
// Access pointers to MV cost array
cpi->EstMvCostPtrX = &cpi->EstMVCost[0][MV_ENTROPY_TOKENS / 2];
cpi->EstMvCostPtrY = &cpi->EstMVCost[1][MV_ENTROPY_TOKENS / 2];
return cpi;
}
/****************************************************************************
*
* ROUTINE : VPEInitLibrary
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Fully initializes the playback library.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VPEInitLibrary ( void )
{
int i;
// Initialise the decompressor
VP6_VPInitLibrary();
CMachineSpecificConfig();
// Prepare Abs difference lookup table
AbsX_LUT = &AbsXTable[255];
for ( i=(-255); i<=255; i++ )
AbsX_LUT[i] = abs(i);
// Prepare table of squared error values
XX_LUT = &XSquaredTable[255];
for ( i=(-255); i<=255; i++ )
XX_LUT[i] = i*i;
// Prepare table of tokens for fast look-up
FillValueTokens();
}
/****************************************************************************
*
* ROUTINE : VPEDeInitLibrary
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-initializes the playback library.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VPEDeInitLibrary ( void )
{
VP6_VPDeInitLibrary();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,130 @@
/****************************************************************************
*
* Module Title : RawBuffer.c
*
* Description : Functions to handle bit-wise writing to raw buffer.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "RawBuffer.h"
#include "codec_common.h"
/****************************************************************************
*
* ROUTINE : WriteLongToBuffer
*
* INPUTS : RAW_BUFFER *buf : Pointer to the buffer instance to be written to.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Writes the 32-bits of buf->DataBlock into the byte
* buffer buf->Buffer in big-endian format.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
INLINE
void WriteLongToBuffer ( RAW_BUFFER *buf )
{
buf->Buffer[buf->pos++] = (buf->DataBlock>>24);
buf->Buffer[buf->pos++] = (buf->DataBlock>>16) & 0x000000FF;
buf->Buffer[buf->pos++] = (buf->DataBlock>> 8) & 0x000000FF;
buf->Buffer[buf->pos++] = buf->DataBlock & 0x000000FF;
}
/****************************************************************************
*
* ROUTINE : InitAddRawBitsToBuffer
*
* INPUTS : RAW_BUFFER *buf : Pointer to the buffer instance to be written to.
* UINT8 *Buffer : Array to be used by RAW_BUFFER to write to.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initializes a Raw Buffer instance given a pointer to an
* array of UINT8s to be used as the storage buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void InitAddRawBitsToBuffer ( RAW_BUFFER *buf, UINT8 *Buffer )
{
buf->Buffer = Buffer;
buf->byte_bit_offset = 32;
buf->DataBlock = 0;
buf->pos = 0;
}
/****************************************************************************
*
* ROUTINE : AddRawBitsToBuffer
*
* INPUTS : RAW_BUFFER *buf : Pointer to the buffer instance to be written to.
* UINT32 data : Bit pattern to be written to the buffer.
* UINT32 bits : Number of significant bits of data to write.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Writes data to the buffer to the specified number of bits
* (UINT32 bits).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void AddRawBitsToBuffer( RAW_BUFFER *buf, UINT32 data, UINT32 bits )
{
// how many bits should we shift by?
buf->byte_bit_offset -= bits;
if ( buf->byte_bit_offset < 0 )
{
// only write the left most bits in this datablock
buf->DataBlock |= (data >> (-buf->byte_bit_offset));
// output block
WriteLongToBuffer ( buf );
buf->DataBlock = 0;
buf->byte_bit_offset += 32;
}
// note we may have bits getting shifted off the left side (like in above case)
buf->DataBlock |= (data << buf->byte_bit_offset);
}
/****************************************************************************
*
* ROUTINE : EndAddRawBitsToBuffer
*
* INPUTS : RAW_BUFFER *buf : Pointer to the buffer instance to be written to.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Finalizes all writes to the buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void EndAddRawBitsToBuffer ( RAW_BUFFER *buf )
{
UINT8 shift = 24;
while ( buf->byte_bit_offset < 32 )
{
buf->Buffer[buf->pos++] = (buf->DataBlock>>shift) & 0xff;
shift -= 8;
buf->byte_bit_offset += 8;
}
buf->byte_bit_offset = 32;
buf->DataBlock = 0;
}
@@ -0,0 +1,454 @@
/****************************************************************************
*
* Module Title : Tokenize.C
*
* Description : Tokenizing fragments for output by pack video
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h> // For abs()
#include "compdll.h"
/****************************************************************************
* Module Statics
****************************************************************************/
static TOKENEXTRA DctValueTokens[DCT_MAX_VALUE*2];
/****************************************************************************
*
* ROUTINE : FillValueTokens
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Fills in the DctValueTokens array used during
* compression for fast look-up of token and eatra-bits
* information.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void FillValueTokens ( void )
{
INT32 i;
for ( i=-2048; i<2047; i++ )
{
UINT32 AbsDataVal = abs ( i );
TOKENEXTRA *TokenExtra = DctValueTokens + 2048 + i;
// Values are tokenised as category value and a number of
// additional bits that define the position within the category.
if ( i == 0 )
{
TokenExtra->Token = 0;
}
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY1] )
{
TokenExtra->Token = AbsDataVal;
TokenExtra->Extra = (i < 0);
}
// Extra Bit 1 determines sign, Bit 0 the value
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY2] )
{
TokenExtra->Token = DCT_VAL_CATEGORY1;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY1]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
// Extra Bit 2 determines sign, Bit 0-1 the value
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY3] )
{
TokenExtra->Token = DCT_VAL_CATEGORY2;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY2]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
// Extra Bit 3 determines sign, Bit 0-2 the value
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY4] )
{
TokenExtra->Token = DCT_VAL_CATEGORY3;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY3]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
// Extra Bit 4 determines sign, Bit 0-3 the value
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY5] )
{
TokenExtra->Token = DCT_VAL_CATEGORY4;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY4]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
// Extra Bit 5 determines sign, Bit 0-4 the value
else if ( AbsDataVal < VP6_DctRangeMinVals[DCT_VAL_CATEGORY6] )
{
TokenExtra->Token = DCT_VAL_CATEGORY5;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY5]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
// Extra Bit 11 determines sign, Bit 0-10 the value
else
{
TokenExtra->Token = DCT_VAL_CATEGORY6;
TokenExtra->Extra = (AbsDataVal - VP6_DctRangeMinVals[DCT_VAL_CATEGORY6]);
TokenExtra->Extra <<=1;
TokenExtra->Extra |= (i < 0);
}
}
}
/****************************************************************************
*
* ROUTINE : TokenizeFrag
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* INT16 *RawData : Array of quantized DCT coefficients.
* UINT32 Plane : Plane block belongs to (Y=0, UV=1)
* BLOCK_CONTEXT *Above : Pointer to an above context.
* BLOCK_CONTEXT *Left : Pointer to a left context.
*
* OUTPUTS : None.
*
* RETURNS : UINT16: Index of the EOB token for the block.
*
* FUNCTION : Takes a set of quantized DCT coefficients for a block
* and produces a set of representative tokens. Each token
* consists of a token identifier and, for most tokens, a
* set of 'extra-bits'.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 TokenizeFrag
(
CP_INSTANCE *cpi,
INT16 *RawData,
UINT32 Plane,
BLOCK_CONTEXT *Above,
BLOCK_CONTEXT *Left
)
{
INT32 i;
UINT32 Token;
INT32 Offset;
INT32 ZeroCount;
INT32 LastNonZeroCoeff=0;
UINT32 token_pos = 0;
UINT32 PlaneX = Plane;
UINT32 PrevTokenIndex;
UINT32 LastTokenNonZero;
for ( i=1; i<64; i++ )
{
// j is coeff number in zig-zag order
int j = cpi->pb.ModifiedScanOrder[i];
if ( RawData[j] )
{
LastNonZeroCoeff = i;
cpi->FrameNzCount[j][1]++;
}
else
cpi->FrameNzCount[j][0]++;
}
// Tokenize the DC value
if ( RawData[0] )
{
if ( cpi->CurrentDcZeroRun[PlaneX] > 0 )
{
// Termination of run of zeros in DC positions
cpi->DcZeroRunStartPtr[PlaneX]->Extra = cpi->CurrentDcZeroRun[PlaneX];
cpi->CurrentDcZeroRun[PlaneX] = 0;
}
Offset = DCT_MAX_VALUE + RawData[0];
Token = DctValueTokens[Offset].Token;
cpi->CoeffTokenPtr->Token = Token;
cpi->CoeffTokenPtr->Extra = DctValueTokens[Offset].Extra;
cpi->FrameDcTokenDist2[Plane][Token]++;
}
else
{
Token = ZERO_TOKEN;
cpi->CoeffTokenPtr->Token = Token;
cpi->CoeffTokenPtr->Extra = 0;
// Check for run of zeros at DC position (Huffman mode)
if ( cpi->CurrentDcZeroRun[PlaneX] == 0 )
{
// New run starts
cpi->DcZeroRunStartPtr[PlaneX] = cpi->CoeffTokenPtr;
cpi->FrameDcTokenDist2[Plane][Token]++;
}
cpi->CurrentDcZeroRun[PlaneX]++;
if ( cpi->CurrentDcZeroRun[PlaneX] >= 74/*11+63*/ )
{
// Maximum run-length is 11+63
cpi->DcZeroRunStartPtr[PlaneX]->Extra = cpi->CurrentDcZeroRun[PlaneX];
cpi->CurrentDcZeroRun[PlaneX] = 0;
}
}
cpi->CoeffTokenPtr->LastTokenL = Left->Token;
cpi->CoeffTokenPtr->LastTokenA = Above->Token;
cpi->FrameDcTokenDist[Plane][Token]++;
PrevTokenIndex = VP6_PrevTokenIndex[Token];
cpi->CoeffTokenPtr++;
token_pos++;
// Update the context
LastTokenNonZero = (Token != ZERO_TOKEN);
Left->Token = LastTokenNonZero;
Above->Token = LastTokenNonZero;
// Tokenize the rest of the block
for ( i=1; i<=LastNonZeroCoeff; i++ )
{
UINT32 Band;
ZeroCount = 0;
while ( !RawData[cpi->pb.ModifiedScanOrder[i]] )
{
i++;
ZeroCount++;
}
// Trap the end of a run of EOBs at AC1
if ( cpi->CurrentAc1EobRun[PlaneX] > 0 )
{
// End of run of EOBs at first AC position
cpi->Ac1EobRunStartPtr[PlaneX]->Extra = cpi->CurrentAc1EobRun[PlaneX];
cpi->CurrentAc1EobRun[PlaneX] = 0;
}
// Code the zero token and zero run length
if ( ZeroCount > 0 )
{
int ZeroBand;
Band = VP6_CoeffToBand[token_pos];
cpi->CoeffTokenPtr->Token = ZERO_TOKEN;
cpi->CoeffTokenPtr->Extra = ZeroCount - 1;
cpi->FrameAcTokenDist [PrevTokenIndex][Plane][Band][ZERO_TOKEN]++;
cpi->FrameAcTokenDist2[PrevTokenIndex][Plane][Band][ZERO_TOKEN]++;
PrevTokenIndex = VP6_PrevTokenIndex[ZERO_TOKEN];
// ZeroBand = 0:1
ZeroBand = (token_pos >= ZRL_BAND2);
cpi->FrameZrlDist[ZeroBand][ZeroCount]++;
cpi->FrameZeroCount[ZeroBand]++;
// Update token_pos
token_pos += ZeroCount;
// Step on to next token
cpi->CoeffTokenPtr++;
}
// Code the non zero value
Offset = DCT_MAX_VALUE + RawData[cpi->pb.ModifiedScanOrder[i]];
cpi->CoeffTokenPtr->Token = DctValueTokens[Offset].Token;
cpi->CoeffTokenPtr->Extra = DctValueTokens[Offset].Extra;
Band = VP6_CoeffToBand[token_pos];
cpi->FrameAcTokenDist [PrevTokenIndex][Plane][Band][cpi->CoeffTokenPtr->Token]++;
cpi->FrameAcTokenDist2[PrevTokenIndex][Plane][Band][cpi->CoeffTokenPtr->Token]++;
PrevTokenIndex = VP6_PrevTokenIndex [cpi->CoeffTokenPtr->Token];
cpi->CoeffTokenPtr++;
token_pos++;
}
// If we have reached the end of the block then code EOB
if ( i < BLOCK_SIZE )
{
UINT32 Band;
cpi->CoeffTokenPtr->Token = DCT_EOB_TOKEN;
cpi->CoeffTokenPtr->Extra = 0;
Band = VP6_CoeffToBand[token_pos];
// if EOB at first AC pos
if ( token_pos == 1 )
{
// The start of an EOB run
if ( cpi->CurrentAc1EobRun[PlaneX] == 0 )
{
cpi->Ac1EobRunStartPtr[PlaneX] = cpi->CoeffTokenPtr;
cpi->FrameAcTokenDist2[PrevTokenIndex][Plane][Band][DCT_EOB_TOKEN]++;
}
cpi->CurrentAc1EobRun[PlaneX]++;
if ( cpi->CurrentAc1EobRun[PlaneX] >= 74 /*11+63*/ )
{
cpi->Ac1EobRunStartPtr[PlaneX]->Extra = cpi->CurrentAc1EobRun[PlaneX];
cpi->CurrentAc1EobRun[PlaneX] = 0;
}
}
else
{
cpi->FrameAcTokenDist2[PrevTokenIndex][Plane][Band][DCT_EOB_TOKEN]++;
}
cpi->FrameAcTokenDist[PrevTokenIndex][Plane][Band][DCT_EOB_TOKEN]++;
PrevTokenIndex = VP6_PrevTokenIndex [DCT_EOB_TOKEN];
cpi->CoeffTokenPtr++;
token_pos++;
}
token_pos--;
// Return the position of the last token.
return cpi->pb.EobOffsetTable[token_pos];
}
/****************************************************************************
*
* Rate Distortion Specific Code...
*
****************************************************************************/
/****************************************************************************
*
* ROUTINE : TokenCost_RD
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT8 Token : Token to be costed.
* int Band : Band that the token belongs in.
* UINT8 Plane : Plane that the token belogs in.
* UINT8 PrecCase : Previous token context type.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Estimated cost in bits of coding this token.
*
* FUNCTION : Produces an estimate of the cost, i.e. number of bits
* required to code, the token using statistics derived
* from the distribution of tokens in the previous frame.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
UINT32 TokenCost_RD ( CP_INSTANCE *cpi, UINT8 Token, int Band, UINT8 Plane, UINT8 PrecCase )
{
if ( Band == -1 )
return cpi->EstDcTokenCosts[Plane][Token] + (ExtraBitLengths_VP6[Token] << 6);
else
return cpi->EstAcTokenCosts[PrecCase][Plane][Band][Token] + (ExtraBitLengths_VP6[Token] << 6);
}
/****************************************************************************
*
* ROUTINE : TokenizeFrag_RD
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* INT16 *RawData : Array of quantized DCT coeffs to be tokenized.
* UINT32 Plane : Plane that the block belongs to.
*
* OUTPUTS : UINT32 *MbCost : Pointer to variable that will hold the
* cost of tokenizing the block.
*
* RETURNS : UINT8: Estimated cost in bits of coding this token.
*
* FUNCTION : Cut down RD version of tokenize function of tokenize block
* that does not update all the context stuff.
*
* SPECIAL NOTES :
*
****************************************************************************/
UINT8 TokenizeFrag_RD
(
CP_INSTANCE *cpi,
INT16 *RawData,
UINT32 Plane,
UINT32 *MbCost
)
{
UINT32 i;
UINT8 Token;
INT32 ZeroCount;
UINT8 TokenPos = 1;
INT32 Band;
INT32 PrevTokenCase ;
// Tokenize the DC value
Token = DctValueTokens[DCT_MAX_VALUE + RawData[0]].Token;
*MbCost += cpi->EstDcTokenCosts[Plane][Token] + (ExtraBitLengths_VP6[Token] << 6);
PrevTokenCase =VP6_PrevTokenIndex[Token];
// Tokenize the rest of the block
for ( i=1; i<BLOCK_SIZE; i++ )
{
// Test for EOB condition
ZeroCount = 0;
while ( !RawData[cpi->pb.ModifiedScanOrder[i]] && (i < BLOCK_SIZE) )
{
i++;
ZeroCount++;
}
// If we have reached the end of the block then code EOB
if ( i == BLOCK_SIZE )
{
Token = DCT_EOB_TOKEN;
Band = VP6_CoeffToBand[TokenPos];
*MbCost += cpi->EstAcTokenCosts[PrevTokenCase][Plane][Band][Token] + (ExtraBitLengths_VP6[Token] << 6);
PrevTokenCase =VP6_PrevTokenIndex[Token];
TokenPos++;
}
else
{
INT32 Offset = DCT_MAX_VALUE + RawData[cpi->pb.ModifiedScanOrder[i]];
if ( ZeroCount > 0 )
{
//0:1
UINT8 ZBand = (TokenPos >= ZRL_BAND2);
Token = ZERO_TOKEN;
Band = VP6_CoeffToBand[TokenPos];
*MbCost += cpi->EstAcTokenCosts[PrevTokenCase][Plane][Band][Token] + (ExtraBitLengths_VP6[Token] << 6);
PrevTokenCase =VP6_PrevTokenIndex[Token];
TokenPos += ZeroCount;
// Get estimated cost of zero run bits (based upon previous frame stats
*MbCost += cpi->EstZrlCosts[ZBand][ZeroCount];
}
Token = DctValueTokens[Offset].Token;
Band = VP6_CoeffToBand[TokenPos];
*MbCost += cpi->EstAcTokenCosts[PrevTokenCase][Plane][Band][Token] + (ExtraBitLengths_VP6[Token] << 6);
PrevTokenCase =VP6_PrevTokenIndex[Token];
TokenPos++;
}
}
TokenPos--;
// Return the position of the last token.
return TokenPos;
}
@@ -0,0 +1,361 @@
/****************************************************************************
*
* Module Title : Transform.c
*
* Description : DCT transform & inverse transform functions.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h> // For Abs()
#include "type_aliases.h"
#include "codec_common.h"
/****************************************************************************
*
* ROUTINE : SUB8
*
* INPUTS : UINT8 *FiltPtr : Pointer to 8x8 source block.
* UINT8 *ReconPtr : Pointer to 8x8 block to be subtracted from FiltPtr.
* UINT8 *old_ptr1 : NOT USED.
* UINT8 *new_ptr1 : NOT USED.
* INT32 SourceStride : Stride of FiltPtr.
* INT32 ReconStride : Stride of ReconPtr.
*
* OUTPUTS : INT16 *DctInputPtr : Pointer to 8x8 array to hold difference.
*
* RETURNS : void
*
* FUNCTION : Does a pixel-by-pixel subtraction of the two 8x8 blocks
* and stores the results in DctInputPtr.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void SUB8
(
UINT8 *FiltPtr,
UINT8 *ReconPtr,
INT16 *DctInputPtr,
UINT8 *old_ptr1, /* NOT USED */
UINT8 *new_ptr1, /* NOT USED */
INT32 SourceStride,
INT32 ReconStride
)
{
int i;
// Loop unrolled to improve speed...
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
{
DctInputPtr[0] = (INT16)((int)(FiltPtr[0]) - ((int)ReconPtr[0]) );
DctInputPtr[1] = (INT16)((int)(FiltPtr[1]) - ((int)ReconPtr[1]) );
DctInputPtr[2] = (INT16)((int)(FiltPtr[2]) - ((int)ReconPtr[2]) );
DctInputPtr[3] = (INT16)((int)(FiltPtr[3]) - ((int)ReconPtr[3]) );
DctInputPtr[4] = (INT16)((int)(FiltPtr[4]) - ((int)ReconPtr[4]) );
DctInputPtr[5] = (INT16)((int)(FiltPtr[5]) - ((int)ReconPtr[5]) );
DctInputPtr[6] = (INT16)((int)(FiltPtr[6]) - ((int)ReconPtr[6]) );
DctInputPtr[7] = (INT16)((int)(FiltPtr[7]) - ((int)ReconPtr[7]) );
// Next row...
FiltPtr += SourceStride;
ReconPtr += ReconStride;
DctInputPtr += BLOCK_HEIGHT_WIDTH;
}
}
/****************************************************************************
*
* ROUTINE : Sub8_128
*
* INPUTS : UINT8 *FiltPtr : Pointer to 8x8 source block.
* UINT8 *old_ptr1 : NOT USED.
* UINT8 *new_ptr1 : NOT USED.
* INT32 SourceStride : Stride of FiltPtr.
*
* OUTPUTS : INT16 *DctInputPtr : Pointer to 8x8 array to hold modified block.
*
* RETURNS : None.
*
* FUNCTION : Subtracts the value 128 from each pixel value in the
* input block FiltPtr.
*
* SPECIAL NOTES : Used when coding a block in INTRA mode to convert the
* pixel range (0,255) to (-128,127). This reduces the
* internal precision required by the DCT transform.
*
****************************************************************************/
void SUB8_128
(
UINT8 *FiltPtr,
INT16 *DctInputPtr,
UINT8 *old_ptr1, /* NOT USED */
UINT8 *new_ptr1, /* NOT USED */
INT32 SourceStride
)
{
int i;
// Loop unrolled to improve speed...
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
{
DctInputPtr[0] = (INT16)((int)(FiltPtr[0]) - 128);
DctInputPtr[1] = (INT16)((int)(FiltPtr[1]) - 128);
DctInputPtr[2] = (INT16)((int)(FiltPtr[2]) - 128);
DctInputPtr[3] = (INT16)((int)(FiltPtr[3]) - 128);
DctInputPtr[4] = (INT16)((int)(FiltPtr[4]) - 128);
DctInputPtr[5] = (INT16)((int)(FiltPtr[5]) - 128);
DctInputPtr[6] = (INT16)((int)(FiltPtr[6]) - 128);
DctInputPtr[7] = (INT16)((int)(FiltPtr[7]) - 128);
// Next row...
FiltPtr += SourceStride;
DctInputPtr += BLOCK_HEIGHT_WIDTH;
}
}
/****************************************************************************
*
* ROUTINE : SUB8AV2
*
* INPUTS : UINT8 *FiltPtr : Pointer to 8x8 source block.
* UINT8 *ReconPtr1 : Pointer to first 8x8 reference block.
* UINT8 *ReconPtr2 : Pointer to second 8x8 reference block.
* UINT8 *old_ptr1 : NOT USED.
* UINT8 *new_ptr1 : NOT USED.
* INT32 SourceStride : Stride of FiltPtr.
* INT32 ReconStride : Stride of ReconPtr1 & ReconPtr2.
*
* OUTPUTS : INT16 *DctInputPtr : Pointer to 8x8 array to hold difference.
*
* RETURNS : void
*
* FUNCTION : Subtracts the average of the two reconstruction blocks
* from the FiltPtr block.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void SUB8AV2
(
UINT8 *FiltPtr,
UINT8 *ReconPtr1,
UINT8 *ReconPtr2,
INT16 *DctInputPtr,
UINT8 *old_ptr1, /* NOT USED */
UINT8 *new_ptr1, /* NOT USED */
INT32 SourceStride,
INT32 ReconStride
)
{
int i;
// Loop unrolled to improve speed...
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
{
DctInputPtr[0] = (INT16)((int)(FiltPtr[0]) - (((int)ReconPtr1[0] + (int)ReconPtr2[0]) / 2) );
DctInputPtr[1] = (INT16)((int)(FiltPtr[1]) - (((int)ReconPtr1[1] + (int)ReconPtr2[1]) / 2) );
DctInputPtr[2] = (INT16)((int)(FiltPtr[2]) - (((int)ReconPtr1[2] + (int)ReconPtr2[2]) / 2) );
DctInputPtr[3] = (INT16)((int)(FiltPtr[3]) - (((int)ReconPtr1[3] + (int)ReconPtr2[3]) / 2) );
DctInputPtr[4] = (INT16)((int)(FiltPtr[4]) - (((int)ReconPtr1[4] + (int)ReconPtr2[4]) / 2) );
DctInputPtr[5] = (INT16)((int)(FiltPtr[5]) - (((int)ReconPtr1[5] + (int)ReconPtr2[5]) / 2) );
DctInputPtr[6] = (INT16)((int)(FiltPtr[6]) - (((int)ReconPtr1[6] + (int)ReconPtr2[6]) / 2) );
DctInputPtr[7] = (INT16)((int)(FiltPtr[7]) - (((int)ReconPtr1[7] + (int)ReconPtr2[7]) / 2) );
// Next row...
FiltPtr += SourceStride;
ReconPtr1 += ReconStride;
ReconPtr2 += ReconStride;
DctInputPtr += BLOCK_HEIGHT_WIDTH;
}
}
/****************************************************************************
*
* ROUTINE : AllZeroDctData
*
* INPUTS : Q_LIST_ENTRY *QuantList : Array of quantized DCT coefficients.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: TRUE if all quantized DCT coeffs are zero, FALSE otherwise.
*
* FUNCTION : Checks for case where all DCT data will be zero.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
BOOL AllZeroDctData ( Q_LIST_ENTRY * QuantList )
{
UINT32 i;
for ( i=0; i<64; i++ )
if ( QuantList[i] != 0 )
return FALSE;
return TRUE;
}
/****************************************************************************
*
* ROUTINE : Sub8Filtered
*
* INPUTS : UINT8 *FiltPtr : Pointer to 8x8 source block.
* UINT8 *ReconPtr : Pointer to 8x8 block to be subtracted from FiltPtr.
* INT32 SourceStride : Stride of FiltPtr.
* INT32 ReconStride : Stride of ReconPtr.
* INT32 *Kernel : Pointer to filter taps to filter source.
*
* OUTPUTS : INT16 *DctInputPtr : Pointer to 8x8 array to hold difference.
*
* RETURNS : void
*
* FUNCTION : Does a pixel-by-pixel subtraction of the two 8x8 blocks
* and stores the results in DctInputPtr. However, at any
* pixel if the difference exceeds 4 then a 3x3 filter is
* applied to the source block before doing the subtraction.
*
* SPECIAL NOTES : The Kernel actually has 10 entries, the first 9 are the
* taps of the 3x3 filter, the last is the filter normalization
* factor.
*
****************************************************************************/
void Sub8Filtered
(
UINT8 *FiltPtr,
UINT8 *ReconPtr,
INT16 *DctInputPtr,
INT32 SourceStride,
INT32 ReconStride,
INT32 *Kernel
)
{
int i,j;
INT32 Tmp;
INT32 Diff;
UINT8 *SrcPtr;
// Loop unrolled to improve speed...
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
{
for ( j=0; j<BLOCK_HEIGHT_WIDTH; j++ )
{
Diff = (INT32)((INT32)FiltPtr[j] - (INT32)ReconPtr[j]);
if ( abs( Diff ) > 4 )
{
// Filter source
// Top row of filter...
SrcPtr = &FiltPtr[j-SourceStride];
Tmp = (UINT32)SrcPtr[-1] * Kernel[0];
Tmp += (UINT32)SrcPtr[0] * Kernel[1];
Tmp += (UINT32)SrcPtr[1] * Kernel[2];
// Middle row of filter...
SrcPtr = &FiltPtr[j];
Tmp += (UINT32)SrcPtr[-1] * Kernel[3];
Tmp += (UINT32)SrcPtr[0] * Kernel[4];
Tmp += (UINT32)SrcPtr[1] * Kernel[5];
// Bottom row of filter...
SrcPtr = &FiltPtr[j+SourceStride];
Tmp += (UINT32)SrcPtr[-1] * Kernel[6];
Tmp += (UINT32)SrcPtr[0] * Kernel[7];
Tmp += (UINT32)SrcPtr[1] * Kernel[8];
// Normalize filter output...
Tmp = Tmp / Kernel[9];
// Subtract...
Tmp = (Tmp - (INT32)ReconPtr[j]);
// Dcide whether to use filtered or unfiltered result...
if ( abs(Tmp)+4 < abs(Diff) )
DctInputPtr[j] = (INT16)Tmp;
else
DctInputPtr[j] = (INT16)Diff;
}
else
DctInputPtr[j] = (INT16)Diff;
}
// Next row...
FiltPtr += SourceStride;
ReconPtr += ReconStride;
DctInputPtr += BLOCK_HEIGHT_WIDTH;
}
}
/****************************************************************************
*
* ROUTINE : Sub8_128Filtered
*
* INPUTS : UINT8 *FiltPtr : Pointer to 8x8 source block.
* INT32 SourceStride : Stride of FiltPtr.
* INT32 *Kernel : Pointer to filter taps to filter source.
*
* OUTPUTS : INT16 *DctInputPtr : Pointer to 8x8 array to hold difference.
*
* RETURNS : void
*
* FUNCTION : Applies a 3x3 filter to the source data and then subtracts
* 128 from each pixel value. The resulting block is stored in
* DctInputPtr.
*
* SPECIAL NOTES : The Kernel actually has 10 entries, the first 9 are the
* taps of the 3x3 filter, the last is the filter normalization
* factor.
*
****************************************************************************/
void Sub8_128Filtered
(
UINT8 *FiltPtr,
INT16 *DctInputPtr,
INT32 SourceStride,
INT32 *Kernel
)
{
int i, j;
INT32 Tmp;
UINT8 *SrcPtr;
// Loop unrolled to improve speed...
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i++ )
{
for ( j=0; j<BLOCK_HEIGHT_WIDTH; j++ )
{
// Filter source
// Top row of filter...
SrcPtr = &FiltPtr[j-SourceStride];
Tmp = (UINT32)SrcPtr[-1] * Kernel[0];
Tmp += (UINT32)SrcPtr[0] * Kernel[1];
Tmp += (UINT32)SrcPtr[1] * Kernel[2];
// Middle row of filter...
SrcPtr = &FiltPtr[j];
Tmp += (UINT32)SrcPtr[-1] * Kernel[3];
Tmp += (UINT32)SrcPtr[0] * Kernel[4];
Tmp += (UINT32)SrcPtr[1] * Kernel[5];
// Bottom row of filter...
SrcPtr = &FiltPtr[j+SourceStride];
Tmp += (UINT32)SrcPtr[-1] * Kernel[6];
Tmp += (UINT32)SrcPtr[0] * Kernel[7];
Tmp += (UINT32)SrcPtr[1] * Kernel[8];
// Normalize filter output...
Tmp = Tmp / Kernel[9];
// Subtract...
DctInputPtr[j] = (INT16)(Tmp - (INT32)128);
}
// Next row...
FiltPtr += SourceStride;
DctInputPtr += BLOCK_HEIGHT_WIDTH;
}
}
@@ -0,0 +1,527 @@
/****************************************************************************
*
* Module Title : Encode.c
*
* Description : Main encode function.
*
****************************************************************************/
/****************************************************************************
* Header Files
****************************************************************************/
#include <stdio.h>
#include "compdll.h"
#include "misc_common.h"
#include "encodemv.h"
#include "encodemode.h"
/****************************************************************************
* Explicit imports
****************************************************************************/
extern void PackCodedVideo ( CP_INSTANCE *cpi );
extern void InitLoopDeringThresholds ( PB_INSTANCE *pbi );
#if defined FULLFRAMEFDCT
extern void BuildFrameMbs ( CP_INSTANCE *cpi );
extern void FDCTFrameMbs ( CP_INSTANCE *cpi );
#endif
extern const UINT32 VP6_QThreshTable[Q_TABLE_SIZE];
extern const UINT32 VP6_ZBinTable[Q_TABLE_SIZE];
extern const UINT32 VP6_RTable[Q_TABLE_SIZE];
/****************************************************************************
*
* ROUTINE : VP6_ShannonCost
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Computed Shannon cost.
*
* FUNCTION : Computes the Shannon cost of coding the frame based
* on the observed distribution of tokens for the frame.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 VP6_ShannonCost ( CP_INSTANCE *cpi )
{
UINT32 Cost = 0;
UINT32 i, j;
UINT32 Sum;
UINT32 Band;
UINT32 Plane;
UINT32 Prob;
// First cost the DC tokens...
for ( Plane=0; Plane<2; Plane++ )
{
Sum = 0;
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
Sum += cpi->FrameDcTokenDist[Plane][i];
}
if ( Sum>0 )
{
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
Prob = (cpi->FrameDcTokenDist[Plane][i] * 255) / Sum;
if ( Prob > 254 )
Prob = 254;
else if ( Prob == 0 )
Prob = 1;
Cost += (VP6_ProbCost[Prob] * cpi->FrameDcTokenDist[Plane][i])/256;
Cost += cpi->FrameDcTokenDist[Plane][i] * ExtraBitLengths_VP6[i];
// Save individual token costs for use in next frames RD code
// Cost in bits x 265.... convert to bits x 64
cpi->EstDcTokenCosts[Plane][i] = VP6_ProbCost[Prob] >> 2;
if ( cpi->EstDcTokenCosts[Plane][i] == 0 )
cpi->EstDcTokenCosts[Plane][i] = 1;
}
}
// Set defaults for predictive cost tables used in RD code
else
{
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
cpi->EstDcTokenCosts[Plane][i] = 4 << 6;
}
}
}
// Then cost the AC tokens...
for ( Plane=0; Plane<2; Plane++ )
{
for ( Band=0; Band<VP6_AC_BANDS; Band++ )
{
for ( j=0; j<PREC_CASES; j++ )
{
Sum = 0;
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
Sum += cpi->FrameAcTokenDist[j][Plane][Band][i];
}
if ( Sum>0 )
{
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
Prob = (cpi->FrameAcTokenDist[j][Plane][Band][i] * 255) / Sum;
if ( Prob > 254 )
Prob = 254;
else if ( Prob == 0 )
Prob = 1;
Cost += (VP6_ProbCost[Prob] * cpi->FrameAcTokenDist[j][Plane][Band][i])/256;
Cost += cpi->FrameAcTokenDist[j][Plane][Band][i] * ExtraBitLengths_VP6[i];
// Save individual token costs for use in next frames RD code
// Cost in bits x 265.... convert to bits x 64
cpi->EstAcTokenCosts[j][Plane][Band][i] = VP6_ProbCost[Prob] >> 2;
if ( cpi->EstAcTokenCosts[j][Plane][Band][i] == 0 )
cpi->EstAcTokenCosts[j][Plane][Band][i] = 1;
}
}
// Set defaults for predictive cost tables used in RD code
else
{
for ( i=0; i<MAX_ENTROPY_TOKENS; i++ )
{
cpi->EstAcTokenCosts[j][Plane][Band][i] = 4 << 6;
}
}
}
}
}
// Finally cost the zero run lengths...
for ( i=0; i<ZRL_BANDS; i++ )
{
Sum = 0;
for ( j=0; j<64; j++ )
{
Sum += cpi->FrameZrlDist[i][j];
}
// Now work out Shannon cost approximations for each run length
if ( Sum>0 )
{
for ( j=0; j<64; j++ )
{
Prob = (cpi->FrameZrlDist[i][j] * 255) / Sum;
if ( Prob > 255 )
Prob = 255;
else if ( Prob == 0 )
Prob = 1;
// Add in to our total cost estimate
Cost += (VP6_ProbCost[Prob] * cpi->FrameZrlDist[i][j])/256;
// Cost in bits x 265.... convert to bits x 64
cpi->EstZrlCosts[i][j] = VP6_ProbCost[Prob] >> 2;
}
}
// Set a default for predictive cost tables used in RD code
else
{
cpi->EstZrlCosts[i][j] = 3 << 6;
}
}
return Cost;
}
/****************************************************************************
*
* ROUTINE : EncodeData
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Always TRUE (This needs fixing!)
*
* SPECIAL NOTES : None.
*
*
* SPECIAL NOTES : Applies rate targetting heuristics.
*
****************************************************************************/
UINT32 EncodeData ( CP_INSTANCE *cpi )
{
unsigned char *tmp;
BOOL RedoY = FALSE;
UINT32 FrameOverShootLimit;
UINT32 FrameUnderShootLimit;
UINT32 ShannonBits;
UINT32 TopIndex;
UINT32 BottomIndex;
INT32 ModeMvCost = cpi->ModeMvCostEstimate/64; // Estimated overhed in bits for modes and MVs
INT32 QuantizePasses = 0;
PB_INSTANCE *pbi = &cpi->pb;
// Set tolerance values for frame overshoot and undershoot.
if ( VP6_GetFrameType(pbi) == BASE_FRAME )
{
if ( cpi->BufferedMode )
{
if ( cpi->BufferLevel < cpi->OptimalBufferLevel )
{
FrameOverShootLimit = cpi->ThisFrameTarget * 10/8;
FrameUnderShootLimit = 0;
}
else
{
FrameOverShootLimit = cpi->ThisFrameTarget * 14/8;
FrameUnderShootLimit = 0;
}
}
// Unbuffered video mode (eg video conferencing)
else
{
FrameOverShootLimit = cpi->ThisFrameTarget * 10/8;
FrameUnderShootLimit = 0;
}
// Limit Q range for the adaptive loop.
BottomIndex = cpi->Configuration.ActiveWorstQuality;
if ( BottomIndex < 20)
BottomIndex = 20;
TopIndex = cpi->Configuration.ActiveBestQuality;
if ( TopIndex > 60 )
TopIndex = 60;
}
else
{
// Normal streamed video mode
if ( cpi->BufferedMode && cpi->pass != 2 )
{
if ( cpi->BufferLevel < cpi->OptimalBufferLevel )
{
// Looser frame size constraints for local file playback
if ( cpi->EndUsage == USAGE_LOCAL_FILE_PLAYBACK )
{
if ( cpi->ThisFrameTarget > cpi->PerFrameBandwidth )
FrameOverShootLimit = cpi->ThisFrameTarget * 2;
else
FrameOverShootLimit = cpi->PerFrameBandwidth * 2;
FrameUnderShootLimit = cpi->ThisFrameTarget * 3/8;
}
else
{
if ( cpi->MaxAllowedDatarate > 125 )
FrameOverShootLimit = (cpi->ThisFrameTarget * cpi->MaxAllowedDatarate)/100;
else
FrameOverShootLimit = cpi->ThisFrameTarget * 125/100;
FrameUnderShootLimit = cpi->ThisFrameTarget * 3/8;
}
}
else
{
// Looser frame size constraints for local file playback
if ( cpi->EndUsage == USAGE_LOCAL_FILE_PLAYBACK)
{
if ( cpi->ThisFrameTarget > cpi->PerFrameBandwidth )
FrameOverShootLimit = cpi->ThisFrameTarget * 2;
else
FrameOverShootLimit = cpi->PerFrameBandwidth * 2;
FrameUnderShootLimit = cpi->ThisFrameTarget * 4/8;
}
else
{
if ( cpi->MaxAllowedDatarate > 150 )
FrameOverShootLimit = (cpi->ThisFrameTarget * cpi->MaxAllowedDatarate)/100;
else
FrameOverShootLimit = cpi->ThisFrameTarget * 150/100;
FrameUnderShootLimit = cpi->ThisFrameTarget * 5/8;
}
}
}
// Unbuffered video mode (eg video conferencing)
// jbb upped this from 10/8 to 14/8 and shut off lower
// limit. This basically eliminated the multiple
// go round issue?
else
{
FrameOverShootLimit = cpi->ThisFrameTarget * 14/8;
FrameUnderShootLimit = cpi->ThisFrameTarget * 0/8;
}
// Limit Q range for the adaptive loop.
BottomIndex = cpi->Configuration.ActiveWorstQuality;
TopIndex = cpi->Configuration.ActiveBestQuality;
if ( TopIndex > 60)
TopIndex = 60;
}
// Q adjustment loop (Only loops around if our rate targeting huristic is badly off).
do
{
#if defined FULLFRAMEFDCT
FDCTFrameMbs ( cpi );
#endif
// Zero down the structures used to count token distributions
memset ( cpi->FrameDcTokenDist, 0, sizeof(cpi->FrameDcTokenDist) );
memset ( cpi->FrameDcTokenDist2, 0, sizeof(cpi->FrameDcTokenDist2) );
memset ( cpi->FrameAcTokenDist, 0, sizeof(cpi->FrameAcTokenDist) );
memset ( cpi->FrameAcTokenDist2, 0, sizeof(cpi->FrameAcTokenDist2) );
memset ( cpi->FrameNzCount, 0, sizeof(cpi->FrameNzCount) );
// Zero down run distribution counts
memset( cpi->FrameZrlDist, 0, sizeof(cpi->FrameZrlDist) );
cpi->FrameZeroCount[0] = 0;
cpi->FrameZeroCount[1] = 0;
// Pack DC tokens and adjust the ones we couldn't predict 2d
pbi->CodedBlockIndex = 0;
// reset our token list
cpi->CoeffTokenPtr = cpi->CoeffTokens;
// Set loop/predictionfilter thresholds based upon Q
if ( pbi->UseLoopFilter == LOOP_FILTER_DERING )
InitLoopDeringThresholds( pbi );
#if defined FULLFRAMEFDCT
BuildFrameMbs ( cpi );
#else
// Encode frame MB-by-MB
EncodeFrameMbs(cpi);
#endif
// Increment the counter on the number of passes through the dct quantize loop
QuantizePasses++;
// Clear MMX state so floating point can work again
#if defined(_MSC_VER)
ClearSysState();
#endif
// If we are in buffered (streaming) mode and have selected fastest speed
// then disallow the re-code loop
if ( (cpi->QuickCompress == 2) && (cpi->BufferedMode) )
break;
// Test for severe over-run or under-run conditions. If necessary adjust Q and try again.
ShannonBits = VP6_ShannonCost(cpi) + ModeMvCost;
// Are we are overshooting and up against the limit of active max Q.
if ( (pbi->quantizer->FrameQIndex == cpi->Configuration.ActiveWorstQuality) &&
(cpi->Configuration.ActiveWorstQuality > cpi->Configuration.WorstQuality) &&
(ShannonBits > FrameOverShootLimit) )
{
INT32 OverSizePercent = ((ShannonBits - FrameOverShootLimit) * 100) / FrameOverShootLimit;
// If so is there any scope for relaxing it
while ( (cpi->Configuration.ActiveWorstQuality > cpi->Configuration.WorstQuality) &&
(OverSizePercent > 0) )
{
cpi->Configuration.ActiveWorstQuality --;
BottomIndex = cpi->Configuration.ActiveWorstQuality;
OverSizePercent -= 6; // Assume 1 qstep = about 65 on frame size.
}
}
// Should we try and recode
if ( ((ShannonBits > FrameOverShootLimit) && (pbi->quantizer->FrameQIndex > BottomIndex)) ||
((ShannonBits < FrameUnderShootLimit) && (pbi->quantizer->FrameQIndex < TopIndex)) )
{
UINT32 LastQIndex = pbi->quantizer->FrameQIndex;
if ( ShannonBits > FrameOverShootLimit )
{
// Truncate TmpBottomIndex
UINT32 TmpBottomIndex = (pbi->quantizer->FrameQIndex + BottomIndex) >> 1;
if ( pbi->quantizer->FrameQIndex > 0 )
TopIndex = pbi->quantizer->FrameQIndex - 1;
else
TopIndex = 0;
// Tweak the appropriate BpbCorrectionFactor.
UpdateBpbCorrectionFactor( cpi, ShannonBits );
if ( VP6_GetFrameType(pbi) == BASE_FRAME )
RegulateQ(cpi, FrameOverShootLimit );
else
RegulateQ(cpi, cpi->ThisFrameTarget );
// Do not allow jumps to be to large and to go out of range.
if ( pbi->quantizer->FrameQIndex < TmpBottomIndex )
ClampAndUpdateQ ( cpi, (UINT32)TmpBottomIndex );
else if ( pbi->quantizer->FrameQIndex > TopIndex )
ClampAndUpdateQ ( cpi, (UINT32)TopIndex );
}
else
{
// Round TmpTopIndex Up
UINT32 TmpTopIndex = (TopIndex + pbi->quantizer->FrameQIndex + 1) >> 1;
if ( pbi->quantizer->FrameQIndex < (Q_TABLE_SIZE-1) )
BottomIndex = pbi->quantizer->FrameQIndex + 1;
else
BottomIndex = (Q_TABLE_SIZE-1);
// Tweak the appropriate BpbCorrectionFactor.
UpdateBpbCorrectionFactor( cpi, ShannonBits );
RegulateQ(cpi, cpi->ThisFrameTarget );
// Clamp Q to upper and lower limits
if ( pbi->quantizer->FrameQIndex < BottomIndex )
ClampAndUpdateQ ( cpi, (UINT32)BottomIndex );
else if ( pbi->quantizer->FrameQIndex > TmpTopIndex )
ClampAndUpdateQ ( cpi, (UINT32)TmpTopIndex );
}
// If we were able to adjust Q index
// given current constraints, then cycle round again.
if ( pbi->quantizer->FrameQIndex != LastQIndex )
{
// Loop round and try again at the modified Q
RedoY = TRUE;
}
else
{
RedoY = FALSE;
}
}
else
RedoY = FALSE;
}
while ( RedoY );
// Optimize the scan order and then repeat dct and tokenize phases
if ( ( (cpi->pb.Configuration.Interlaced) || (cpi->AllowScanOrderUpdates) ) &&
(!cpi->ErrorResilliantMode) &&
(cpi->QuickCompress !=2) )
{
// Work out the optimal scan bands based upon the frame zero counts for this frame
PredictScanOrder( cpi );
// Build the scan order
BuildScanOrder( &(cpi->pb), cpi->NewScanOrderBands );
// Zero down the structures used to count token distributions
memset ( cpi->FrameDcTokenDist, 0, sizeof(cpi->FrameDcTokenDist) );
memset ( cpi->FrameDcTokenDist2, 0, sizeof(cpi->FrameDcTokenDist2) );
memset ( cpi->FrameAcTokenDist, 0, sizeof(cpi->FrameAcTokenDist) );
memset ( cpi->FrameAcTokenDist2, 0, sizeof(cpi->FrameAcTokenDist2) );
memset ( cpi->FrameNzCount, 0, sizeof(cpi->FrameNzCount) );
// Zero run distribution counts
memset( cpi->FrameZrlDist, 0, sizeof(cpi->FrameZrlDist) );
cpi->FrameZeroCount[0] = 0;
cpi->FrameZeroCount[1] = 0;
// Pack DC tokens and adjust the ones we couldn't predict 2d
pbi->CodedBlockIndex = 0;
// reset our token list
cpi->CoeffTokenPtr = cpi->CoeffTokens;
// Set loop/prediction filter thresholds based upon Q
if ( pbi->UseLoopFilter == LOOP_FILTER_DERING )
InitLoopDeringThresholds( pbi );
// Encode frame MB-by-MB
#if defined FULLFRAMEFDCT
BuildFrameMbs ( cpi );
#else
EncodeFrameMbs(cpi);
#endif
// Clear MMX state so floating point can work again
#if defined(_MSC_VER)
ClearSysState();
#endif
}
// Decide whether to drop back to using Huffman entropy coding or not
if ( cpi->pb.VpProfile == SIMPLE_PROFILE )
{
if( ShannonBits > 9000*8 )
pbi->UseHuffman = TRUE;
else
pbi->UseHuffman = FALSE;
}
// Entropy code the tokens generated & output bits to the bitstream
PackCodedVideo(cpi);
// switch pointers so that this frame recon becomes last frame recon
tmp = pbi->LastFrameRecon;
pbi->LastFrameRecon = pbi->ThisFrameRecon;
pbi->ThisFrameRecon = tmp;
// update UMV border
UpdateUMVBorder ( pbi->postproc, pbi->LastFrameRecon );
// Update the golden frame buffer.
if( (pbi->FrameType == BASE_FRAME) || pbi->RefreshGoldenFrame )
memcpy ( pbi->GoldenFrame, pbi->LastFrameRecon, pbi->ReconYPlaneSize + 2* pbi->ReconUVPlaneSize );
#if defined(_MSC_VER)
ClearSysState();
#endif
BuildMVCostEstimates(cpi);
BuildModeCostEstimates(cpi);
// AWG This function returns a UINT32 __NOT__ a BOOL !!
return TRUE;
}
@@ -0,0 +1,454 @@
/****************************************************************************
*
* Module Title : Encodembs.c
*
* Description : Compressor functions for block order transmittal
*
* AUTHOR : Paul Wilkins
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "compdll.h"
#include "misc_common.h"
#include "decodemode.h"
#include "decodemv.h"
#include "quantize.h"
/****************************************************************************
*
* ROUTINE : PredictBlock
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* BLOCK_POSITION bp : Position of block in MB (0-5)
* UINT32 MBrow : MB row (NOT USED).
* UINT32 MBcol : MB column (NOT USED).
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Creates a prediction for an 8x8 block given a coding
* mode and other data stored at the MB level.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void PredictBlock ( CP_INSTANCE *cpi, BLOCK_POSITION bp)
{
MACROBLOCK_INFO *mbi=&cpi->pb.mbi;
INT32 CurrentReconStride = cpi->pb.mbi.blockDxInfo[bp].CurrentReconStride;
INT32 CurrentSourceStride = cpi->pb.mbi.blockDxInfo[bp].CurrentSourceStride;
UINT32 thisRecon = cpi->pb.mbi.blockDxInfo[bp].thisRecon;
UINT32 Source = cpi->pb.mbi.blockDxInfo[bp].Source;
if ( VP6_ModeUsesMC[mbi->Mode] )
{
VP6_PredictFilteredBlock ( &cpi->pb, cpi->DCTDataBuffer, bp );
SubtractBlock ( &cpi->yuv1ptr[Source], cpi->DCTDataBuffer, CurrentSourceStride );
}
else if ( mbi->Mode==CODE_INTER_NO_MV )
{
Sub8 ( &cpi->yuv1ptr[Source], &cpi->pb.LastFrameRecon[thisRecon], cpi->DCTDataBuffer, 0, 0, CurrentSourceStride, CurrentReconStride );
}
else if ( mbi->Mode==CODE_USING_GOLDEN )
{
Sub8 ( &cpi->yuv1ptr[Source], &cpi->pb.GoldenFrame[thisRecon], cpi->DCTDataBuffer, 0, 0, CurrentSourceStride, CurrentReconStride );
}
else if ( mbi->Mode==CODE_INTRA )
{
Sub8_128 ( &cpi->yuv1ptr[Source], cpi->DCTDataBuffer, 0, 0, CurrentSourceStride );
}
}
/****************************************************************************
*
* ROUTINE : PredictDCE
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* BLOCK_POSITION bp : Position of block in MB (0-5)
* Q_LIST_ENTRY *LastDC : Pointer to array of DC values last used (one per prediction frame type)
* BLOCK_CONTEXT *Above : Pointer to above context for block.
* BLOCK_CONTEXT *Left : Pointer to left context for block.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Computes a DC predictor for the block based on two
* supplied contexts, one above and one to the left.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void PredictDCE
(
CP_INSTANCE *cpi,
BLOCK_POSITION bp
)
{
PB_INSTANCE *pbi = &cpi->pb;
UINT8 Frame = VP6_Mode2Frame[pbi->mbi.Mode];
Q_LIST_ENTRY *LastDC = pbi->mbi.blockDxInfo[bp].LastDc;
BLOCK_CONTEXT *Above = pbi->mbi.blockDxInfo[bp].Above;
BLOCK_CONTEXT *Left = pbi->mbi.blockDxInfo[bp].Left;
INT32 Avg;
Avg = LastDC[Frame];
if(Frame == Left->Frame)
{
Avg = Left->Dc;
}
if(Frame == Above->Frame)
{
Avg = Above->Dc;
if(Frame == Left->Frame)
{
#define HIGHBITDUPPED(X) (((signed short) X) >> 15)
Avg += Left->Dc;
Avg += (HIGHBITDUPPED(Avg)&1);
Avg >>= 1;
}
}
//Jim says that y,u,v all use the same quantizer so we probably do not need to have a separate dequant ptr
// make sure the last dc is updated for next time
cpi->DCT_codes[0] -= ((Avg * pbi->mbi.blockDxInfo[bp].dequantPtr[0]));
}
/****************************************************************************
*
* ROUTINE : EncodeMacroBlock
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 MBrow : MB row.
* UINT32 MBcol : MB column.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a single macro-block by coding each of
* it's six constituent blocks in turn.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void EncodeMacroBlock ( CP_INSTANCE *cpi, UINT32 MBrow, UINT32 MBcol )
{
UINT32 bp;
UINT32 fragCoefEOB;
// UINT32 MBPointer;
// UINT32 MBSourcePointer;
//INT32 NextBlock;
//INT32 NextLineInBlock;
UINT32 FragsToCheck[6];
PB_INSTANCE *pbi = &cpi->pb;
UINT32 FragIndex = 2*(MBrow-BORDER_MBS) * pbi->HFragments + 2*(MBcol-BORDER_MBS);
pbi->mbi.Interlaced = pbi->MBInterlaced[MBOffset(MBrow,MBcol)];
//NextBlock = 8;
//NextLineInBlock = 1;
if ( pbi->mbi.Interlaced == 1 )
{
//NextBlock = 1;
//NextLineInBlock = 2;
pbi->mbi.blockDxInfo[0].CurrentReconStride =
pbi->mbi.blockDxInfo[1].CurrentReconStride =
pbi->mbi.blockDxInfo[2].CurrentReconStride =
pbi->mbi.blockDxInfo[3].CurrentReconStride = pbi->Configuration.YStride * 2;
pbi->mbi.blockDxInfo[2].thisRecon -= (pbi->Configuration.YStride * 7);
pbi->mbi.blockDxInfo[3].thisRecon -= (pbi->Configuration.YStride * 7);
pbi->mbi.blockDxInfo[0].CurrentSourceStride =
pbi->mbi.blockDxInfo[1].CurrentSourceStride =
pbi->mbi.blockDxInfo[2].CurrentSourceStride =
pbi->mbi.blockDxInfo[3].CurrentSourceStride = pbi->Configuration.VideoFrameWidth * 2;
pbi->mbi.blockDxInfo[2].Source -= (pbi->Configuration.VideoFrameWidth * 7);
pbi->mbi.blockDxInfo[3].Source -= (pbi->Configuration.VideoFrameWidth * 7);
}
//note: should be able to move FragsToCheck into the blockDxInfo struct
//then in the MB loop, we should be able to inc the values instead of doing these multiplies
//it may not affect the pc performance, but it may help other processors
FragsToCheck[0] = FragIndex;
FragsToCheck[1] = FragIndex+1;
FragsToCheck[2] = FragIndex+cpi->pb.HFragments;
FragsToCheck[3] = FragIndex+cpi->pb.HFragments+1;
FragsToCheck[4] = cpi->pb.YPlaneFragments + (MBrow-BORDER_MBS) * (cpi->pb.HFragments / 2) + MBcol-BORDER_MBS;
FragsToCheck[5] = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments + (MBrow-BORDER_MBS) * ( cpi->pb.HFragments / 2 ) + MBcol-BORDER_MBS;
cpi->pb.mbi.Mode = -1;
for( bp=0 ; bp<6 ; bp++ )
{
cpi->pb.mbi.Mode = cpi->pb.FragInfo[FragsToCheck[bp]].FragCodingMode;
cpi->pb.mbi.Mv[bp].x = cpi->pb.FragInfo[FragsToCheck[bp]].MVectorX;
cpi->pb.mbi.Mv[bp].y = cpi->pb.FragInfo[FragsToCheck[bp]].MVectorY;
}
for( bp=0 ; bp<6 ; bp++ )
{
// Build a block predictor, subtract from source to get prediction error for block
PredictBlock ( cpi, bp );
// Transform the error signal using the forward DCT to get set of transform coefficients
fdct_short ( cpi->DCTDataBuffer, cpi->DCT_codes );
// Predict the DCT DC value from those in surrounding blocks
PredictDCE ( cpi, bp );
// Quantize the resulting DCT coefficients at prevailing Q
VP6_quantize ( cpi->pb.quantizer, cpi->DCT_codes, cpi->pb.mbi.blockDxInfo[bp].coeffsPtr, (UINT8)bp );
// Tokenize the resulting quantized coefficients
fragCoefEOB = (UINT8)TokenizeFrag ( cpi,
cpi->pb.mbi.blockDxInfo[bp].coeffsPtr,
cpi->pb.mbi.blockDxInfo[bp].Plane,
pbi->mbi.blockDxInfo[bp].Above,
pbi->mbi.blockDxInfo[bp].Left );
// Produce reconstructed block so encoder has __exactly__ the same
// data for last frame reconstruction as the decoder
// Re-form the DC value from the prediction
VP6_PredictDC ( &cpi->pb, bp );
// Invert the transform to re-create the prediction error
cpi->pb.idct[fragCoefEOB]( cpi->pb.mbi.blockDxInfo[bp].coeffsPtr,
cpi->pb.mbi.blockDxInfo[bp].dequantPtr,
cpi->pb.ReconDataBuffer[bp] );
// Add prediction error to predictor to re-create block as it appears at decoder
VP6_ReconstructBlock(&cpi->pb, bp);
// DEBUG Code: Store prediction block in Post-processing buffer
//PredictBlockToPostProcessBuffer ( &cpi->pb, bp );
// Update the context info for the next block
cpi->pb.CodedBlockIndex++;
VP6_UpdateContextA ( &cpi->pb, pbi->mbi.blockDxInfo[bp].Above, bp );
VP6_UpdateContext ( &cpi->pb, pbi->mbi.blockDxInfo[bp].Left, bp );
}
if ( pbi->mbi.Interlaced == 1 )
{
/* reset to non interlaced */
pbi->mbi.blockDxInfo[0].CurrentReconStride =
pbi->mbi.blockDxInfo[1].CurrentReconStride =
pbi->mbi.blockDxInfo[2].CurrentReconStride =
pbi->mbi.blockDxInfo[3].CurrentReconStride = pbi->Configuration.YStride;
pbi->mbi.blockDxInfo[2].thisRecon += (pbi->Configuration.YStride * 7);
pbi->mbi.blockDxInfo[3].thisRecon += (pbi->Configuration.YStride * 7);
pbi->mbi.blockDxInfo[0].CurrentSourceStride =
pbi->mbi.blockDxInfo[1].CurrentSourceStride =
pbi->mbi.blockDxInfo[2].CurrentSourceStride =
pbi->mbi.blockDxInfo[3].CurrentSourceStride = pbi->Configuration.VideoFrameWidth;
pbi->mbi.blockDxInfo[2].Source += (pbi->Configuration.VideoFrameWidth * 7);
pbi->mbi.blockDxInfo[3].Source += (pbi->Configuration.VideoFrameWidth * 7);
}
}
/****************************************************************************
*
* ROUTINE : EncodeFrameMbs
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a frame by encoding each of it's constituent
* macro-blocks in turn.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void EncodeFrameMbs ( CP_INSTANCE *cpi )
{
PB_INSTANCE *pbi = &cpi->pb;
unsigned int duration;
unsigned int starttsc;
unsigned int endtsc;
// Record start time
VP6_readTSC ( &starttsc );
// Reset Dc zero & Ac EOB run counters
cpi->CurrentDcZeroRun[0] = 0;
cpi->CurrentDcZeroRun[1] = 0;
cpi->DcZeroRunStartPtr[0] = NULL;
cpi->DcZeroRunStartPtr[1] = NULL;
cpi->CurrentAc1EobRun[0] = 0;
cpi->CurrentAc1EobRun[1] = 0;
cpi->Ac1EobRunStartPtr[0] = NULL;
cpi->Ac1EobRunStartPtr[1] = NULL;
if ( cpi->pb.FrameType == BASE_FRAME )
{
// Initialise probability distributions with baseline default values
memcpy ( cpi->pb.IsMvShortProb, DefaultIsShortProbs, sizeof(cpi->pb.IsMvShortProb) );
memcpy ( cpi->pb.MvShortProbs, DefaultMvShortProbs, sizeof(cpi->pb.MvShortProbs) );
memcpy ( cpi->pb.MvSignProbs, DefaultSignProbs, sizeof(cpi->pb.MvSignProbs) );
memcpy ( cpi->pb.MvSizeProbs, DefaultMvLongProbs, sizeof(cpi->pb.MvSizeProbs) );
memcpy ( cpi->pb.probXmitted, VP6_BaselineXmittedProbs, sizeof(cpi->pb.probXmitted) );
memset ( cpi->pb.MBModeProb, 128, sizeof(cpi->pb.MBModeProb) );
memset ( cpi->pb.BModeProb, 128, sizeof(cpi->pb.BModeProb) );
memset ( cpi->pb.probModeSame, 128, sizeof(cpi->pb.probModeSame) );
memset ( cpi->pb.probMode, 128, sizeof(cpi->pb.probMode) );
memset ( cpi->pb.predictionMode, 1, sizeof(char)*cpi->pb.MacroBlocks );
memset ( cpi->MBModeCostNoNearest, 0, sizeof(cpi->MBModeCostNoNearest) );
memset ( cpi->MBModeCostNoNear, 0, sizeof(cpi->MBModeCostNoNear) );
memset ( cpi->MBModeCostBoth, 0, sizeof(cpi->MBModeCostBoth) );
memset ( cpi->BModeCost, 0, sizeof(cpi->BModeCost) );
}
else
{
cpi->pb.LastMode = CODE_INTER_NO_MV;
}
// since we are on a new frame reset the above contexts
VP6_ResetAboveContext( &cpi->pb );
{
UINT32 MBrow;
UINT32 MBRows = cpi->pb.MBRows;
UINT32 MBCols = cpi->pb.MBCols;
MBCols -= BORDER_MBS;
MBRows -= BORDER_MBS;
// AWG Code Added: Initialize strides for source & recon
pbi->mbi.blockDxInfo[0].CurrentReconStride =
pbi->mbi.blockDxInfo[1].CurrentReconStride =
pbi->mbi.blockDxInfo[2].CurrentReconStride =
pbi->mbi.blockDxInfo[3].CurrentReconStride = pbi->Configuration.YStride;
pbi->mbi.blockDxInfo[0].CurrentSourceStride =
pbi->mbi.blockDxInfo[1].CurrentSourceStride =
pbi->mbi.blockDxInfo[2].CurrentSourceStride =
pbi->mbi.blockDxInfo[3].CurrentSourceStride = pbi->Configuration.VideoFrameWidth;
// AWG End Added Code
// for each row of macroblocks
MBrow=BORDER_MBS;
do
{
MACROBLOCK_INFO *mbi = &cpi->pb.mbi;
UINT32 MBcol;
VP6_ResetLeftContext(&cpi->pb);
// for each macroblock within a row of macroblocks
mbi->blockDxInfo[0].Above = &pbi->fc.AboveY[BORDER_MBS*2];
mbi->blockDxInfo[1].Above = &pbi->fc.AboveY[BORDER_MBS*2+1];
mbi->blockDxInfo[2].Above = &pbi->fc.AboveY[BORDER_MBS*2];
mbi->blockDxInfo[3].Above = &pbi->fc.AboveY[BORDER_MBS*2+1];
mbi->blockDxInfo[4].Above = &pbi->fc.AboveU[BORDER_MBS];
mbi->blockDxInfo[5].Above = &pbi->fc.AboveV[BORDER_MBS];
mbi->blockDxInfo[0].thisRecon = pbi->ReconYDataOffset + ((MBrow * pbi->Configuration.YStride) << 4) + (BORDER_MBS * 16);
mbi->blockDxInfo[1].thisRecon = mbi->blockDxInfo[0].thisRecon + 8;
mbi->blockDxInfo[2].thisRecon = mbi->blockDxInfo[0].thisRecon + (pbi->Configuration.YStride << 3);
mbi->blockDxInfo[3].thisRecon = mbi->blockDxInfo[1].thisRecon + (pbi->Configuration.YStride << 3);
mbi->blockDxInfo[4].thisRecon = pbi->ReconUDataOffset + ((MBrow * pbi->Configuration.UVStride) << 3) + (BORDER_MBS * 8);
mbi->blockDxInfo[5].thisRecon = pbi->ReconVDataOffset + ((MBrow * pbi->Configuration.UVStride) << 3) + (BORDER_MBS * 8);
mbi->blockDxInfo[0].Source = pbi->YDataOffset + ((MBrow * 16) - UMV_BORDER) * pbi->Configuration.VideoFrameWidth;
mbi->blockDxInfo[1].Source = mbi->blockDxInfo[0].Source + 8;
mbi->blockDxInfo[2].Source = mbi->blockDxInfo[0].Source + (pbi->Configuration.VideoFrameWidth << 3);
mbi->blockDxInfo[3].Source = mbi->blockDxInfo[1].Source + (pbi->Configuration.VideoFrameWidth << 3);
mbi->blockDxInfo[4].Source = pbi->UDataOffset + ((MBrow * 8) - (UMV_BORDER>>1)) * (pbi->Configuration.VideoFrameWidth/2);
mbi->blockDxInfo[5].Source = pbi->VDataOffset + ((MBrow * 8) - (UMV_BORDER>>1)) * (pbi->Configuration.VideoFrameWidth/2);
MBcol=BORDER_MBS;
do
{
// Decode the macroblock
EncodeMacroBlock(cpi, MBrow, MBcol);
mbi->blockDxInfo[0].Above += 2;
mbi->blockDxInfo[1].Above += 2;
mbi->blockDxInfo[2].Above += 2;
mbi->blockDxInfo[3].Above += 2;
mbi->blockDxInfo[4].Above += 1;
mbi->blockDxInfo[5].Above += 1;
mbi->blockDxInfo[0].thisRecon += 16;
mbi->blockDxInfo[1].thisRecon += 16;
mbi->blockDxInfo[2].thisRecon += 16;
mbi->blockDxInfo[3].thisRecon += 16;
mbi->blockDxInfo[4].thisRecon += 8;
mbi->blockDxInfo[5].thisRecon += 8;
mbi->blockDxInfo[0].Source += 16;
mbi->blockDxInfo[1].Source += 16;
mbi->blockDxInfo[2].Source += 16;
mbi->blockDxInfo[3].Source += 16;
mbi->blockDxInfo[4].Source += 8;
mbi->blockDxInfo[5].Source += 8;
} while(++MBcol < MBCols);
} while(++MBrow < MBRows);
}
// Terminate current DC run of zeros or AC run of EOB
if ( cpi->CurrentDcZeroRun[0] > 0 )
{
cpi->DcZeroRunStartPtr[0]->Extra = cpi->CurrentDcZeroRun[0];
cpi->CurrentDcZeroRun[0] = 0;
}
if ( cpi->CurrentDcZeroRun[1] > 0 )
{
cpi->DcZeroRunStartPtr[1]->Extra = cpi->CurrentDcZeroRun[1];
cpi->CurrentDcZeroRun[1] = 0;
}
if ( cpi->CurrentAc1EobRun[0] > 0 )
{
cpi->Ac1EobRunStartPtr[0]->Extra = cpi->CurrentAc1EobRun[0];
cpi->CurrentAc1EobRun[0] = 0;
}
if ( cpi->CurrentAc1EobRun[1] > 0 )
{
cpi->Ac1EobRunStartPtr[1]->Extra = cpi->CurrentAc1EobRun[1];
cpi->CurrentAc1EobRun[1] = 0;
}
// Record end time and compute duration
VP6_readTSC ( &endtsc );
duration = (endtsc - starttsc)/cpi->pb.ProcessorFrequency;
if( cpi->avgEncodeTime==0 )
cpi->avgEncodeTime = duration;
else
cpi->avgEncodeTime = ( 7 * cpi->avgEncodeTime + duration ) >> 3;
}
@@ -0,0 +1,764 @@
/****************************************************************************
*
* Module Title : encodemode.c
*
* Description : Functions for encoding modes and motion vectors.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h> // For abs()
#include "compdll.h"
#include "boolhuff.h"
#include "decodemode.h"
#include "encodemv.h"
#include "decodemv.h"
/****************************************************************************
* Explicit Imports
****************************************************************************/
extern void AddBitsToBuffer( BOOL_CODER *bc, UINT32 data, UINT32 bits );
/****************************************************************************
* Module statics.
****************************************************************************/
static const HNODE CodingMode[9] =
{
{ // 0
{ 0, 1 },
{ 0, 2 },
},
{ // 1
{ 0, 3 },
{ 0, 4 },
},
{ // 2
{ 0, 5 },
{ 0, 6 },
},
{ // 3
{ 1, CODE_INTER_NO_MV },
{ 1, CODE_INTER_PLUS_MV },
},
{ // 4
{ 1, CODE_INTER_NEAREST_MV },
{ 1, CODE_INTER_NEAR_MV },
},
{ // 5
{ 1, CODE_INTRA },
{ 1, CODE_INTER_FOURMV },
},
{ // 6
{ 0, 7 },
{ 0, 8 },
},
{ // 7
{ 1, CODE_USING_GOLDEN },
{ 1, CODE_GOLDEN_MV },
},
{ // 8
{ 1, CODE_GOLD_NEAREST_MV},
{ 1, CODE_GOLD_NEAR_MV },
},
};
// NOTE:
// ModeCodeArray contains information required to traverse a binary
// decision tree for coding the coding mode. The form of the tree is
// documented in decodemode.c. Each entry corresponds to a decision
// as to whether to take the 0 or one branch at a particular node.
// An entry whose value is 9 indicates that we have reached a leaf node.
// Each row corresponds to the value of the previously coded mode
// and each column to the succesive node decisions.
static const UINT32 ModeCodeArray[MAX_MODES][7] =
{
0, 0, 0, 9, 9, 9, 9, // CODE_INTER_NO_MV
1, 0, 0, 9, 9, 9, 9, // CODE_INTRA
0, 0, 1, 9, 9, 9, 9, // CODE_INTER_PLUS_MV
0, 1, 0, 9, 9, 9, 9, // CODE_INTER_NEAREST_MV
0, 1, 1, 9, 9, 9, 9, // CODE_INTER_NEAR_MV
1, 1, 0, 0, 9, 9, 9, // CODE_USING_GOLDEN
1, 1, 0, 1, 9, 9, 9, // CODE_GOLDEN_MV
1, 0, 1, 9, 9, 9, 9, // CODE_INTER_FOURMV
1, 1, 1, 0, 9, 9, 9, // CODE_GOLD_NEAREST_MV
1, 1, 1, 1, 9, 9, 9 // CODE_GOLD_NEAR_MV
};
/****************************************************************************
*
* ROUTINE : encodeBlockMode
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* CODING_MODE mode : Mode we are trying to encode.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a block mode into the bitstream using 2 bits.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void encodeBlockMode ( CP_INSTANCE *cpi, CODING_MODE mode )
{
int choice = 0;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MODE_SECTION;
#endif
switch ( mode )
{
case CODE_INTER_NO_MV: choice = 0; break;
case CODE_INTER_PLUS_MV: choice = 1; break;
case CODE_INTER_NEAREST_MV: choice = 2; break;
case CODE_INTER_NEAR_MV: choice = 3; break;
}
AddBitsToBuffer ( &cpi->bc, choice, 2 );
}
/****************************************************************************
*
* ROUTINE : encodeMode
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* CODING_MODE lastmode : Mode of the last coded macroblock.
* CODING_MODE mode : Mode we are trying to encode.
* UINT32 type : MODE_TYPE (all modes available, nonearest
* no near macroblock)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes coding mode for MB into the bitstream using a tree
* traversal algorithm:
* -- First decision is whether mode==lastmode: code a 0 or 1
* using probability from probModeSame.
* -- If mode!=lastmode step down the tree using ModeCodeArray
* to decide whether to code a 0 or 1 decision at each node,
* and probMode to determine the probability of coding a 0
* decision (1 decision probability is then computed as
* (1 minus zero-decision-prob)).
*
* SPECIAL NOTES : Uses VP6_EncodeBool to encode the bits to the bitstream.
*
****************************************************************************/
void encodeMode ( CP_INSTANCE *cpi, CODING_MODE lastmode, CODING_MODE mode, UINT32 type )
{
UINT8 Stat;
UINT8 i = 0;
UINT8 node = 0;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MODE_SECTION;
#endif
if ( mode == lastmode )
{
VP6_EncodeBool ( &cpi->bc, 1, cpi->pb.probModeSame[type][lastmode] );
}
else
{
VP6_EncodeBool( &cpi->bc, 0, cpi->pb.probModeSame[type][lastmode] );
while ( ModeCodeArray[mode][i] != 9 )
{
Stat = cpi->pb.probMode[type][lastmode][node];
VP6_EncodeBool ( &cpi->bc, ModeCodeArray[mode][i], (int)Stat );
if ( ModeCodeArray[mode][i] == 0 )
node = CodingMode[node].left.value;
else
node = CodingMode[node].right.value;
i++;
}
}
}
/****************************************************************************
*
* ROUTINE : encodeModeTest
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* CODING_MODE lastmode : Mode of the last coded macroblock.
* CODING_MODE mode : Mode we are trying to encode.
* UINT32 type : MODE_TYPE (all modes available, nonearest
* no near macroblock)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Exactly the same functionality as encodeMode above,
* _but_ rather than outputting bits to the bitstream,
* BitCounter in cpi->pb in incremented by an estimate
* of the number of bits required.
*
* SPECIAL NOTES : Uses VP6_EncodeBool2 to get an estimate of the number
* of bits that will be generated.
*
****************************************************************************/
void encodeModeTest ( CP_INSTANCE *cpi, CODING_MODE lastmode, CODING_MODE mode, UINT32 type )
{
UINT8 Stat;
UINT8 i = 0;
UINT8 node = 0;
if ( mode==lastmode )
{
VP6_EncodeBool2 ( &cpi->bc, 1, cpi->pb.probModeSame[type][lastmode] );
}
else
{
VP6_EncodeBool2 ( &cpi->bc, 0, cpi->pb.probModeSame[type][lastmode] );
while ( ModeCodeArray[mode][i] != 9 )
{
Stat = cpi->pb.probMode[type][lastmode][node];
VP6_EncodeBool2 ( &cpi->bc, ModeCodeArray[mode][i], (int)Stat );
if ( ModeCodeArray[mode][i] == 0 )
node = CodingMode[node].left.value;
else
node = CodingMode[node].right.value;
i++;
}
}
}
/****************************************************************************
*
* ROUTINE : encodeModeDiff
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* int diff : Probability difference value to encode.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Takes a differential probability value in the range
* -256 to +256 in steps of 4 and encodes it using a fixed
* tree with hard-coded probabilities.
*
* SPECIAL NOTES : The hard coded probabilities for the difference tree
* were calcualated by taking the average number of times a
* branch was taken on some sample material i.e.
* (bond, bike, beautifulmind).
*
****************************************************************************/
void encodeModeDiff ( CP_INSTANCE *cpi, int diff )
{
if ( diff==0 )
{
// 0 difference
VP6_EncodeBool ( &cpi->bc, 0, 205 );
}
else
{
// Non-0
VP6_EncodeBool ( &cpi->bc, 1, 205 );
// transmit sign of difference
VP6_EncodeBool ( &cpi->bc, diff<0, 128 );
// go to abs value
diff = abs(diff);
if ( diff<12 )
{
VP6_EncodeBool ( &cpi->bc, 0, 171 );
VP6_EncodeBool ( &cpi->bc, diff==4, 83 );
}
else
{
VP6_EncodeBool ( &cpi->bc, 1, 171 );
if ( diff<28 )
{
VP6_EncodeBool ( &cpi->bc, 0, 199 );
VP6_EncodeBool ( &cpi->bc, diff==12, 140 );
if ( diff>12 )
{
VP6_EncodeBool ( &cpi->bc, diff==16, 125 );
if ( diff>16 )
VP6_EncodeBool ( &cpi->bc, diff==20, 104 );
}
}
else
{
VP6_EncodeBool ( &cpi->bc, 1, 199 );
AddBitsToBuffer ( &cpi->bc, diff>>2, 7 );
}
}
}
}
/****************************************************************************
*
* ROUTINE : estimateModeDiffCost
*
* INPUTS : int diff : Probability difference value to encode.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Number of bits required to code diff.
*
* FUNCTION : Same as encodeModeDiff above but rather than outputting
* bits to the bitstream it estimates the number of bits
* that will be generated.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int estimateModeDiffCost ( int diff )
{
int cost = 0;
if ( diff==0 )
{
cost += (VP6_ProbCost[205]+128) >> 8;
}
else
{
cost += (VP6_ProbCost[255-205]+128) >> 8;
cost += 64;
// go to abs value
diff = abs(diff);
if ( diff<12 )
{
// < 12
cost += (VP6_ProbCost[171]+128) >> 8;
if ( diff==4 )
cost += (VP6_ProbCost[255-83]+128) >> 8;
else
cost += (VP6_ProbCost[83]+128) >> 8;
}
else
{
// >= 12
cost += (VP6_ProbCost[255-171]+128) >> 8;
if ( diff<28 )
{
// < 28
cost += (VP6_ProbCost[199]+128) >> 8;
if ( diff==12 )
cost += (VP6_ProbCost[255-140]+128) >> 8;
else
{
cost += (VP6_ProbCost[140]+128) >> 8;
if ( diff==16 )
cost += (VP6_ProbCost[255-125]+128) >> 8;
else
{
cost += (VP6_ProbCost[125]+128) >> 8;
if ( diff==20 )
cost += (VP6_ProbCost[255-104]+128) >> 8;
else
cost += (VP6_ProbCost[104]+128) >> 8;
}
}
}
else
{
// >= 28 just send the bits
cost += (VP6_ProbCost[255-199]+128) >> 8;
cost += 7*64;
}
}
}
return cost;
}
/****************************************************************************
*
* ROUTINE : UpdateModeProbs
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Determines which probabilities to transmit and
* use for encoding macroblock modes, and then
* transmits the information necessary to decode the
* probabilities.
*
* a) Pick the lowest cost vector we have available
* b) Compare it to what we used in the last frame
* c) Determine if it makes sense to update the vector
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void UpdateModeProbs ( CP_INSTANCE *cpi )
{
int i, j, k;
int diff;
int costToIdeal;
unsigned int thisCost, bestCost;
unsigned int lowestCost = 0x7fffffff;
unsigned int lastCost = 0x7fffffff;
unsigned int whichVector = 0;
UINT32 total, round;
UINT8 proposedProb[2][10];
PB_INSTANCE *pbi = &cpi->pb;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MODE_SECTION;
#endif
// For each mode type (all modes available, no nearest, no near mode)
for ( j=0; j<MODETYPES; j++ )
{
// sum the totals for each of the modes
cpi->MBModeCount[j][MAX_MODES] = 0;
cpi->CountModeSameAsLast[j][MAX_MODES] = 0;
for ( i=0; i<MAX_MODES; i++ )
{
cpi->MBModeCount[j][MAX_MODES] += cpi->MBModeCount[j][i];
cpi->CountModeSameAsLast[j][MAX_MODES] += cpi->CountModeSameAsLast[j][i];
cpi->CountModeDiffFrLast[j][MAX_MODES] += cpi->CountModeDiffFrLast[j][i];
}
// estimate the cost of using the cheapest vector from our vq codebook
whichVector = 0;
lowestCost = 0x7fffffff;
for ( k=0; k<MODEVECTORS; k++ )
{
thisCost = 0;
for ( i=0; i<MAX_MODES; i++ )
{
thisCost += cpi->CountModeSameAsLast[j][i]*((VP6_ProbCost[VP6_ModeVq[j][k][i*2]] +128)>>8);
thisCost += cpi->CountModeDiffFrLast[j][i]*((VP6_ProbCost[VP6_ModeVq[j][k][i*2+1]]+128)>>8);
}
if ( thisCost<lowestCost )
{
whichVector = k;
lowestCost = thisCost;
}
}
// In the error resilliant mode / VC mode we discount the "last frame values" as
// a candidate vector in order to improve the resilliance to dropped/corrupt frames.
if ( !cpi->ErrorResilliantMode )
{
// estimate the cost of using the vector we have from the last frame
lastCost = 0;
for ( i=0; i<MAX_MODES; i++ )
{
lastCost += cpi->CountModeSameAsLast[j][i]*((VP6_ProbCost[pbi->probXmitted[j][1][i]] + 128)>>8);
lastCost += cpi->CountModeDiffFrLast[j][i]*((VP6_ProbCost[pbi->probXmitted[j][0][i]] + 128)>>8);
}
}
// if the best from our vq book + the cost of transmitting the vector is cheaper
// than our current vector use it. OR... if we are running in error resilliant mode.
if( cpi->ErrorResilliantMode ||
( (lastCost / 64) > (((VP6_ProbCost[255-PROBVECTORXMIT]+128)>>8) + lowestCost) / 64 + 4 ) /* for the vector itself */ )
{
// transmit that we are transmitting a new vector
VP6_EncodeBool ( &cpi->bc,1,PROBVECTORXMIT );
// transmit which vector to use here
AddBitsToBuffer ( &cpi->bc, whichVector, 4 );
// adjust the vector
for ( i=0; i<MAX_MODES; i++ )
{
pbi->probXmitted[j][1][i] = VP6_ModeVq[j][whichVector][i*2];
pbi->probXmitted[j][0][i] = VP6_ModeVq[j][whichVector][i*2+1];
}
}
else
{
lowestCost = lastCost;
// transmit that we are reusing the last vector
VP6_EncodeBool ( &cpi->bc, 0, PROBVECTORXMIT );
}
// calculate the ideal vector and how much it would cost to go to it.
bestCost = 0;
costToIdeal = 0;
total = 1 + cpi->CountModeSameAsLast[j][MAX_MODES]+cpi->CountModeDiffFrLast[j][MAX_MODES];
round = total/2;
for ( i=0; i<10; i++ )
{
// what's the ideal probability
proposedProb[1][i] = (round+256*cpi->CountModeSameAsLast[j][i]) / total;
// calculate the truncated difference between the ideal and where we are now
diff = 4*((proposedProb[1][i] - pbi->probXmitted[j][1][i]) / 4);
costToIdeal += estimateModeDiffCost(diff);
diff += pbi->probXmitted[j][1][i];
proposedProb[1][i] = ( diff<0 ? 0 : (diff>255 ? 255 : diff) );
// update the cost of our ideal choice and of moving to our ideal values
bestCost += cpi->CountModeSameAsLast[j][i]*((VP6_ProbCost[proposedProb[1][i]]+128)>>8);
// what's the ideal probability
proposedProb[0][i] = (round+256*cpi->CountModeDiffFrLast[j][i]) / total;
// calculate the truncated difference between the ideal and where we are now
diff = 4*((proposedProb[0][i] - pbi->probXmitted[j][0][i]) / 4);
costToIdeal += estimateModeDiffCost(diff);
diff += pbi->probXmitted[j][0][i];
proposedProb[0][i] = ( diff<0 ? 0 : (diff>255 ? 255 : diff) );
// update the cost of our ideal choice and of moving to our ideal values
bestCost += cpi->CountModeDiffFrLast[j][i]*((VP6_ProbCost[proposedProb[0][i]]+128)>>8);
}
// if updating our vector to be closer to the ideal is cheaper than going with what we have now
if ( (costToIdeal + bestCost + ((VP6_ProbCost[255-PROBIDEALXMIT]+128)>>8)) / 64 < lowestCost / 64 )
{
// transmit that we are updating the mode probabilities
VP6_EncodeBool ( &cpi->bc, 1, PROBIDEALXMIT );
// encode the differences and adjust the ideal values
for ( i=0; i<10; i++ )
{
diff = proposedProb[1][i]-pbi->probXmitted[j][1][i];
encodeModeDiff(cpi,diff);
diff += pbi->probXmitted[j][1][i];
pbi->probXmitted[j][1][i] = ( diff<0 ? 0 : (diff>255 ? 255 : diff) );
diff = proposedProb[0][i]- pbi->probXmitted[j][0][i];
encodeModeDiff(cpi,diff);
diff += pbi->probXmitted[j][0][i];
pbi->probXmitted[j][0][i] = ( diff<0 ? 0 : (diff>255 ? 255 : diff) );
}
}
else
{
// transmit that we are not updating the mode probabilities
VP6_EncodeBool ( &cpi->bc, 0, PROBIDEALXMIT );
}
}
VP6_BuildModeTree ( &cpi->pb );
}
/****************************************************************************
*
* ROUTINE : encodeModeandMotionVector
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 MBrow : MB row.
* UINT32 MBcol : MB column.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a macroblock's mode and motion vectors to
* the bitstream.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void encodeModeAndMotionVector ( CP_INSTANCE *cpi, UINT32 MBrow, UINT32 MBcol )
{
UINT32 k;
int type, type2;
CODING_MODE mode;
UINT32 FragsToCheck[4];
PB_INSTANCE *pbi = &cpi->pb;
int width = pbi->HFragments;
UINT32 FragIndex = (MBrow-BORDER_MBS)*width*2 + (MBcol-BORDER_MBS)*2;
VP6_FindNearestandNextNearest ( &cpi->pb, MBrow, MBcol, 1, &type );
VP6_FindNearestandNextNearest ( &cpi->pb, MBrow, MBcol, 2, &type2 );
FragsToCheck[0] = FragIndex;
FragsToCheck[1] = FragIndex+1;
FragsToCheck[2] = FragIndex+pbi->HFragments;
FragsToCheck[3] = FragIndex+pbi->HFragments+1;
mode = pbi->predictionMode[MBOffset(MBrow,MBcol)];
encodeMode ( cpi, pbi->LastMode, mode, type );
pbi->LastMode = mode;
// check to see if we need to encode mvs or more sub modes
switch ( mode )
{
case CODE_INTER_PLUS_MV:
encodeMotionVector ( cpi, pbi->FragInfo[FragIndex].MVectorX, pbi->FragInfo[FragIndex].MVectorY, mode );
break;
case CODE_GOLDEN_MV:
encodeMotionVector ( cpi, pbi->FragInfo[FragIndex].MVectorX, pbi->FragInfo[FragIndex].MVectorY, mode);
break;
case CODE_INTER_FOURMV:
// encode sub mode decisions
encodeBlockMode ( cpi, pbi->FragInfo[FragsToCheck[0]].FragCodingMode );
encodeBlockMode ( cpi, pbi->FragInfo[FragsToCheck[1]].FragCodingMode );
encodeBlockMode ( cpi, pbi->FragInfo[FragsToCheck[2]].FragCodingMode );
encodeBlockMode ( cpi, pbi->FragInfo[FragsToCheck[3]].FragCodingMode );
// encode the 4 motion vectors
for ( k=0; k<4; k++ )
if ( pbi->FragInfo[FragsToCheck[k]].FragCodingMode==CODE_INTER_PLUS_MV )
encodeMotionVector ( cpi, pbi->FragInfo[FragsToCheck[k]].MVectorX, pbi->FragInfo[FragsToCheck[k]].MVectorY, CODE_INTER_PLUS_MV );
break;
}
}
/****************************************************************************
*
* ROUTINE : VP6_EstimateCost
*
* INPUTS : BOOL_CODER *bc : Pointer to a BoolCoder (UNUSED).
* HUFF_NODE *hn : Pointer to a Huffman tree.
* int value : Value to be encoded.
* int length : Length in bits of value.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Cost of coding value (in bits).
*
* FUNCTION : Computes the cost of coding value bit-by-bit using
* the Huffman tree specified.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 VP6_EstimateCost ( BOOL_CODER *bc, HUFF_NODE *hn, int value, int length )
{
int i;
int node = 0;
UINT32 total = 0;
for ( i=length-1; i>=0; i-- )
{
int v = (value>>i) & 1;
if ( v )
{
total += (VP6_ProbCost[255-hn[node].freq]+128)>>8;
node = hn[node].rightunion.right.value;
}
else
{
total += (VP6_ProbCost[hn[node].freq]+128)>>8;
node = hn[node].leftunion.left.value;
}
}
return total;
}
/****************************************************************************
*
* ROUTINE : modeCost
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 MBrow : MB row.
* UINT32 MBcol : MB column.
* CODING_MODE mode : Mode to be costed.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Cost of coding mode (in bits*64).
*
* FUNCTION : Computes the cost of coding mode (in bits*64).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 modeCost ( CP_INSTANCE *cpi, UINT32 MBrow, UINT32 MBcol, CODING_MODE mode )
{
int type;
CODING_MODE lastmode;
PB_INSTANCE *pbi = &cpi->pb;
int width = pbi->HFragments;
VP6_FindNearestandNextNearest ( &cpi->pb, MBrow, MBcol, 1, &type );
if ( MBcol==BORDER_MBS && MBrow==BORDER_MBS )
lastmode = CODE_INTER_NO_MV;
else if ( MBcol==BORDER_MBS )
lastmode = pbi->predictionMode[MBOffset(MBrow-1,pbi->MBCols - (BORDER_MBS+1))];
else
lastmode = pbi->predictionMode[MBOffset(MBrow,MBcol-1)];
return cpi->EstModeCost[(lastmode==mode) ? 0 : 1][mode];
}
/****************************************************************************
*
* ROUTINE : blockModeCost
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance (NOT USED).
* UINT32 i : Undefined (NOT USED).
* UINT32 j : Undefined (NOT USED).
* CODING_MODE mode : Mode to be costed (NOT USED).
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Cost of coding mode (in bits*64).
*
* FUNCTION : Computes the cost of coding mode (in bits*64).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 blockModeCost ( CP_INSTANCE *cpi, UINT32 i, UINT32 j, CODING_MODE mode )
{
// All modes within 4 mode mode cost 2 bits (cost specified as bits * 64)
return 128;
}
/****************************************************************************
*
* ROUTINE : BuildModeCostEstimates
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void.
*
* FUNCTION : Compute an estimate of the cost of encoding each mode.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void BuildModeCostEstimates ( CP_INSTANCE *cpi )
{
int i;
for ( i=0; i<MAX_MODES; i++ )
{
cpi->bc.BitCounter = 0;
encodeModeTest ( cpi, i, i, MACROBLOCK );
cpi->EstModeCost[0][i] = (cpi->bc.BitCounter) >> 2;
// Non matching last mode case
cpi->bc.BitCounter = 0;
if ( i==0 )
encodeModeTest ( cpi, 1, i, MACROBLOCK );
else
encodeModeTest ( cpi, 0, i, MACROBLOCK );
cpi->EstModeCost[1][i] = (cpi->bc.BitCounter) >> 2;
}
}
@@ -0,0 +1,24 @@
/****************************************************************************
*
* Module Title : encodemode.h
*
* Description : Functions for encoding modes and Motion Vectors.
*
****************************************************************************/
#ifndef __INC_ENCODEMODE_H
#define __INC_ENCODEMODE_H
#ifndef STRICT
#define STRICT /* Strict type checking */
#endif
/****************************************************************************
* Exports
****************************************************************************/
extern void encodeModeAndMotionVector(CP_INSTANCE* cpi, UINT32 MBrow, UINT32 MBcol);
extern void UpdateModeProbs(CP_INSTANCE *cpi);
extern UINT32 modeCost(CP_INSTANCE *cpi,UINT32 i,UINT32 j,CODING_MODE mode);
extern UINT32 blockModeCost(CP_INSTANCE *cpi,UINT32 i,UINT32 j,CODING_MODE mode);
extern void BuildModeCostEstimates( CP_INSTANCE *cpi );
#endif
@@ -0,0 +1,720 @@
/****************************************************************************
*
* Module Title : encodemv.c
*
* Description : Functions for encoding modes and motion vectors
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "compdll.h"
#include "boolhuff.h"
#include "decodemv.h"
/****************************************************************************
* Macros
****************************************************************************/
// This small correction allows for the fact that an update to an MV probability
// may have benefit in subsequent frames as well as the current one.
#define MV_PROB_UPDATE_CORECTION -1
/****************************************************************************
* Imports
****************************************************************************/
extern void AddBitsToBuffer ( BOOL_CODER *bc, UINT32 data, UINT32 bits );
/****************************************************************************
*
* ROUTINE : encodeMotionVectorComponent
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* int i : Selector as to what set of probs to use.
* INT32 Vector : MV component to be coded.
* INT32 MvOffset : Reference value to code Vector from.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a motion vector component either outputting
* bits to the bitstream _or_ updating BitCounter in
* cpi->bc with the estimated cost.
*
* SPECIAL NOTES : cpi->bc.MeasureCost determines whether bits are
* generated to the bitstream or not.
*
****************************************************************************/
void encodeMotionVectorComponent ( CP_INSTANCE *cpi, int i, INT32 Vector, INT32 MvOffset )
{
UINT8 SignBit;
INT32 TmpVector;
void (*CodeBool)( BOOL_CODER *, int, int );
// Are we outputting bits to the bitstream or just estimating cost?
if ( cpi->bc.MeasureCost )
CodeBool = VP6_EncodeBool2;
else
CodeBool = VP6_EncodeBool;
// Code vector differentially
TmpVector = Vector - MvOffset;
// Convert vector to sign bit and magnitude
if ( TmpVector < 0 )
{
TmpVector = - TmpVector;
SignBit = 1;
}
else
SignBit = 0;
// Is the vector a small vector componet (currently < 2 whole pixels)
if ( TmpVector <= 7 )
{
// Small vector
CodeBool ( &cpi->bc, 0, cpi->pb.IsMvShortProb[i] );
// Code up the magnitude value
switch ( TmpVector )
{
case 0:
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][1] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][2] );
break;
case 1:
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][1] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][2] );
break;
case 2:
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][1] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][3] );
break;
case 3:
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][1] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][3] );
break;
case 4:
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][4] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][5] );
break;
case 5:
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][4] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][5] );
break;
case 6:
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][4] );
CodeBool ( &cpi->bc, 0, cpi->pb.MvShortProbs[i][6] );
break;
case 7:
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][0] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][4] );
CodeBool ( &cpi->bc, 1, cpi->pb.MvShortProbs[i][6] );
break;
}
// Code the sign bit
if ( TmpVector > 0 )
CodeBool ( &cpi->bc, SignBit, cpi->pb.MvSignProbs[i] );
}
else
{
// Indicate that we have a larger vector
CodeBool ( &cpi->bc, 1, cpi->pb.IsMvShortProb[i] );
// Code the magnitude
CodeBool ( &cpi->bc, ((TmpVector & 0x01) ? 1 : 0), cpi->pb.MvSizeProbs[i][0] ); // QPel
CodeBool ( &cpi->bc, ((TmpVector & 0x02) ? 1 : 0), cpi->pb.MvSizeProbs[i][1] ); // HPel
CodeBool ( &cpi->bc, ((TmpVector & 0x04) ? 1 : 0), cpi->pb.MvSizeProbs[i][2] ); // Pel
// At least one of the following must be non zero (or we would have coded a short vector)
// We code from least likely to be set to most likely. The last bit is thus implicit
// if none of the others are set
CodeBool ( &cpi->bc, ((TmpVector & 0x80) ? 1 : 0), cpi->pb.MvSizeProbs[i][7] );
CodeBool ( &cpi->bc, ((TmpVector & 0x40) ? 1 : 0), cpi->pb.MvSizeProbs[i][6] );
CodeBool ( &cpi->bc, ((TmpVector & 0x20) ? 1 : 0), cpi->pb.MvSizeProbs[i][5] );
CodeBool ( &cpi->bc, ((TmpVector & 0x10) ? 1 : 0), cpi->pb.MvSizeProbs[i][4] );
// Only need to code if at least one of the others was set else it is implicit
if ( TmpVector & 0xF0 )
CodeBool ( &cpi->bc, ((TmpVector & 0x08) ? 1 : 0), cpi->pb.MvSizeProbs[i][3] );
// Code the sign bit
CodeBool ( &cpi->bc, SignBit, cpi->pb.MvSignProbs[i] );
}
}
/****************************************************************************
*
* ROUTINE : encodeMotionVector
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* INT32 MVectorX : MV x-component to be coded.
* INT32 MVectorY : MV y-component to be coded.
* CODING_MODE Mode : Coding mode for corresponding MB/Block.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a motion vector to the bitstream.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void encodeMotionVector ( CP_INSTANCE *cpi, INT32 MVectorX, INT32 MVectorY, CODING_MODE Mode )
{
INT32 MvOffsetX = 0;
INT32 MvOffsetY = 0;
PB_INSTANCE *pbi = &cpi->pb;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MV_SECTION;
#endif
// Work out how the MV was coded so that the appropriate origin offset can be applied
if ( Mode == CODE_INTER_PLUS_MV )
{
// Normal Inter MV
if ( pbi->mbi.NearestMvIndex < MAX_NEAREST_ADJ_INDEX )
{
MvOffsetX = pbi->mbi.NearestInterMVect.x;
MvOffsetY = pbi->mbi.NearestInterMVect.y;
}
}
else
{
// Golden Frame MV
if ( pbi->mbi.NearestGMvIndex < MAX_NEAREST_ADJ_INDEX )
{
MvOffsetX = pbi->mbi.NearestGoldMVect.x;
MvOffsetY = pbi->mbi.NearestGoldMVect.y;
}
}
encodeMotionVectorComponent ( cpi, 0, MVectorX, MvOffsetX );
encodeMotionVectorComponent ( cpi, 1, MVectorY, MvOffsetY );
}
/****************************************************************************
*
* ROUTINE : CalculateMvNodeProbabilities
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Build the MV entropy coding tree.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void CalculateMvNodeProbabilities ( CP_INSTANCE *cpi )
{
UINT32 Sum;
UINT32 Sum2;
UINT32 Count;
INT32 AbsVector;
INT32 DistributionOffset;
INT32 NewProb;
INT32 i;
INT32 j;
UINT32 MvShortDist[2][2];
UINT32 MvShortSizeDist[2][8];
UINT32 MvSignDist[2][2];
UINT32 MvSizeDist[2][LONG_MV_BITS][2];
memset( MvShortDist, 0, sizeof(MvShortDist) );
memset( MvShortSizeDist, 0, sizeof(MvShortSizeDist) );
memset( MvSizeDist, 0, sizeof(MvSizeDist) );
memset( MvSignDist, 0, sizeof(MvSignDist) );
// Calculate the distributions for the MV nodes.
cpi->FrameMvCount = 0;
for ( i=0; i<2; i++ )
{
Sum = 0;
for ( j=-(MV_ENTROPY_TOKENS >> 1); j<0; j++ )
{
// -ve vectors
DistributionOffset = (MV_ENTROPY_TOKENS >> 1) + j;
Count = cpi->MvBaselineDist[i][DistributionOffset];
AbsVector = -j;
MvSignDist[i][1] += Count;
if ( AbsVector < 8 )
{
MvShortDist[i][0] += Count; // Short vector
MvShortSizeDist[i][AbsVector] += Count; // Magnitude distribution
}
else
{
MvShortDist[i][1] += Count; // Long vector
MvSizeDist[i][0][(AbsVector & 0x01) ? 1 : 0] += Count; // QPel
MvSizeDist[i][1][(AbsVector & 0x02) ? 1 : 0] += Count; // HPel
MvSizeDist[i][2][(AbsVector & 0x04) ? 1 : 0] += Count; // Bit1
MvSizeDist[i][3][(AbsVector & 0x08) ? 1 : 0] += Count; // Bit2
MvSizeDist[i][4][(AbsVector & 0x10) ? 1 : 0] += Count; // Bit3
MvSizeDist[i][5][(AbsVector & 0x20) ? 1 : 0] += Count; // Bit4
MvSizeDist[i][6][(AbsVector & 0x40) ? 1 : 0] += Count; // Bit5
MvSizeDist[i][7][(AbsVector & 0x80) ? 1 : 0] += Count; // Bit6
}
Sum += Count;
}
// Zero Vector component
Count = cpi->MvBaselineDist[i][(MV_ENTROPY_TOKENS >> 1)];
MvShortDist[i][0] += Count;
MvShortSizeDist[i][0] += Count;
Sum += Count;
for ( j=1; j<(MV_ENTROPY_TOKENS >> 1); j++ )
{
// +ve vectors
DistributionOffset = (MV_ENTROPY_TOKENS >> 1) + j;
Count = cpi->MvBaselineDist[i][DistributionOffset];
AbsVector = j;
MvSignDist[i][0] += Count;
if ( AbsVector < 8 )
{
MvShortDist[i][0] += Count; // Short vector
MvShortSizeDist[i][AbsVector] += Count; // Magnitude distribution
}
else
{
MvShortDist[i][1] += Count; // Long vector
MvSizeDist[i][0][(AbsVector & 0x01) ? 1 : 0] += Count; // QPel
MvSizeDist[i][1][(AbsVector & 0x02) ? 1 : 0] += Count; // HPel
MvSizeDist[i][2][(AbsVector & 0x04) ? 1 : 0] += Count; // Bit1
MvSizeDist[i][3][(AbsVector & 0x08) ? 1 : 0] += Count; // Bit2
MvSizeDist[i][4][(AbsVector & 0x10) ? 1 : 0] += Count; // Bit3
MvSizeDist[i][5][(AbsVector & 0x20) ? 1 : 0] += Count; // Bit4
MvSizeDist[i][6][(AbsVector & 0x40) ? 1 : 0] += Count; // Bit5
MvSizeDist[i][7][(AbsVector & 0x80) ? 1 : 0] += Count; // Bit6
}
Sum += Count;
}
}
cpi->FrameMvCount = Sum; // Note that Sum is reset to 0 for each "i" above
for ( i=0; i<2; i++ ) // X and Y
{
// Convert the distributions to optimal node probabilities
Sum = MvShortDist[i][0] + MvShortDist[i][1];
if ( Sum>0 )
{
Sum2 = MvShortDist[i][0];
NewProb = (Sum2 * 255) / Sum;
NewProb &= ~0x01;
if ( NewProb < 1 )
NewProb = 1;
cpi->NewIsMvShortProb[i] = NewProb;
cpi->NewIsMvShortHits[i][0] = Sum2;
cpi->NewIsMvShortHits[i][1] = Sum - Sum2;
}
// Sign
Sum = ( MvSignDist[i][0] + MvSignDist[i][1] );
if ( Sum>0 )
{
Sum2 = MvSignDist[i][0];
NewProb = (Sum2 * 255) / Sum;
NewProb &= ~0x01;
if ( NewProb < 1 )
NewProb = 1;
cpi->NewMvSignProbs[i] = NewProb;
cpi->NewMvSignHits[i][0] = Sum2;
cpi->NewMvSignHits[i][1] = Sum - Sum2;
}
// Tree nodes for short vectors
for ( j=0; j<7; j++ )
{
// Node specific
switch ( j )
{
case 0:
// Node 0 Low
Sum = MvShortSizeDist[i][0] + MvShortSizeDist[i][1] + MvShortSizeDist[i][2] + MvShortSizeDist[i][3] +
MvShortSizeDist[i][4] + MvShortSizeDist[i][5] + MvShortSizeDist[i][6] + MvShortSizeDist[i][7];
Sum2 = MvShortSizeDist[i][0] + MvShortSizeDist[i][1] + MvShortSizeDist[i][2] + MvShortSizeDist[i][3];
break;
case 1:
// Node 1 LowLow
Sum = Sum2;
Sum2 = MvShortSizeDist[i][0] + MvShortSizeDist[i][1];
break;
case 2:
// Node 2 LowLowLow
Sum = Sum2;
Sum2 = MvShortSizeDist[i][0];
break;
case 3:
// Node 3 LowHighLow
Sum = MvShortSizeDist[i][2] + MvShortSizeDist[i][3];
Sum2 = MvShortSizeDist[i][2];
break;
case 4:
// Node 4 HighLow
Sum = MvShortSizeDist[i][4] + MvShortSizeDist[i][5] + MvShortSizeDist[i][6] + MvShortSizeDist[i][7];
Sum2 = MvShortSizeDist[i][4] + MvShortSizeDist[i][5];
break;
case 5:
// Node 5 HighLowLow
Sum = MvShortSizeDist[i][4] + MvShortSizeDist[i][5];
Sum2 = MvShortSizeDist[i][4];
break;
case 6:
// Node 6 HighLowHigh
Sum = MvShortSizeDist[i][6] + MvShortSizeDist[i][7];
Sum2 = MvShortSizeDist[i][6];
break;
}
if ( Sum )
{
NewProb = (Sum2 * 255)/Sum;
NewProb &= ~0x01;
if ( NewProb < 1 )
NewProb = 1;
cpi->NewMvShortProbs[i][j] = NewProb;
cpi->NewMvShortHits[i][j][0] = Sum2;
cpi->NewMvShortHits[i][j][1] = Sum - Sum2;
}
}
// Long vectors
for ( j=0; j<LONG_MV_BITS; j++ )
{
Sum = MvSizeDist[i][j][0] + MvSizeDist[i][j][1];
Sum2 = MvSizeDist[i][j][0];
if ( Sum )
{
NewProb = (Sum2 * 255)/Sum;
NewProb &= ~0x01;
if ( NewProb < 1 )
NewProb = 1;
cpi->NewMvSizeProbs[i][j] = NewProb;
cpi->NewMvSizeHits[i][j][0] = Sum2;
cpi->NewMvSizeHits[i][j][1] = Sum - Sum2;
}
}
}
}
/****************************************************************************
*
* ROUTINE : BuildandPackMvTree
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Build the MV entropy coding tree.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void BuildandPackMvTree ( CP_INSTANCE *cpi )
{
INT32 i;
INT32 NewProb;
INT32 OldProb;
INT32 NewBits;
INT32 OldBits;
INT32 ProbUpdateCost;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MV_SECTION;
#endif
// calculate the MV node Probabilities
CalculateMvNodeProbabilities ( cpi );
// If appropriate update short, sign, qpel, half pixel and low order bit probabilities.
for ( i=0; i<2; i++ )
{
// Update the Short vector probability.
NewProb = cpi->NewIsMvShortProb[i];
OldProb = cpi->pb.IsMvShortProb[i];
OldBits = ((cpi->NewIsMvShortHits[i][0] * VP6_ProbCost[OldProb])/256) +
((cpi->NewIsMvShortHits[i][1] * VP6_ProbCost[255 - OldProb])/256);
NewBits = ((cpi->NewIsMvShortHits[i][0] * VP6_ProbCost[NewProb])/256) +
((cpi->NewIsMvShortHits[i][1] * VP6_ProbCost[255 - NewProb])/256);
ProbUpdateCost = PROB_UPDATE_BASELINE_COST + MV_PROB_UPDATE_CORECTION;
ProbUpdateCost += (VP6_ProbCost[255 - VP6_MvUpdateProbs[i][0]] + 128) / 256;
ProbUpdateCost -= (VP6_ProbCost[VP6_MvUpdateProbs[i][0]] + 128) / 256;
if ( (OldBits - NewBits) > ProbUpdateCost )
{
cpi->pb.IsMvShortProb[i] = NewProb;
VP6_EncodeBool ( &cpi->bc, 1, VP6_MvUpdateProbs[i][0] );
AddBitsToBuffer ( &cpi->bc, NewProb>>1, PROB_UPDATE_BASELINE_COST );
}
else
{
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][0] );
}
// Sign
NewProb = cpi->NewMvSignProbs[i];
OldProb = cpi->pb.MvSignProbs[i];
OldBits = ((cpi->NewMvSignHits[i][0] * VP6_ProbCost[OldProb])/256) +
((cpi->NewMvSignHits[i][1] * VP6_ProbCost[255 - OldProb])/256);
NewBits = ((cpi->NewMvSignHits[i][0] * VP6_ProbCost[NewProb])/256) +
((cpi->NewMvSignHits[i][1] * VP6_ProbCost[255 - NewProb])/256);
ProbUpdateCost = PROB_UPDATE_BASELINE_COST + MV_PROB_UPDATE_CORECTION;
ProbUpdateCost += (VP6_ProbCost[255 - VP6_MvUpdateProbs[i][1]] + 128) / 256;
ProbUpdateCost -= (VP6_ProbCost[VP6_MvUpdateProbs[i][1]] + 128) / 256;
if ( (OldBits - NewBits) > ProbUpdateCost )
{
cpi->pb.MvSignProbs[i] = NewProb;
VP6_EncodeBool ( &cpi->bc, 1, VP6_MvUpdateProbs[i][1] );
AddBitsToBuffer ( &cpi->bc, NewProb >> 1, PROB_UPDATE_BASELINE_COST );
}
else
{
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][1] );
}
}
// If appropriate update the tree probabilities for short vector
for ( i = 0; i < 2; i++ ) // X then Y
{
INT32 j;
UINT32 MvUpdateProbsOffset = 2; // Offset into VP6_MvUpdateProbs[i][]
// For each node in the tree
for ( j=0; j<7; j++ )
{
NewProb = cpi->NewMvShortProbs[i][j];
OldProb = cpi->pb.MvShortProbs[i][j];
OldBits = ((cpi->NewMvShortHits[i][j][0] * VP6_ProbCost[OldProb])/256) +
((cpi->NewMvShortHits[i][j][1] * VP6_ProbCost[255 - OldProb])/256);
NewBits = ((cpi->NewMvShortHits[i][j][0] * VP6_ProbCost[NewProb])/256) +
((cpi->NewMvShortHits[i][j][1] * VP6_ProbCost[255 - NewProb])/256);
ProbUpdateCost = PROB_UPDATE_BASELINE_COST + MV_PROB_UPDATE_CORECTION;
ProbUpdateCost += (VP6_ProbCost[255 - VP6_MvUpdateProbs[i][MvUpdateProbsOffset]] + 128) / 256;
ProbUpdateCost -= (VP6_ProbCost[VP6_MvUpdateProbs[i][MvUpdateProbsOffset]] + 128) / 256;
if ( (OldBits - NewBits) > ProbUpdateCost )
{
cpi->pb.MvShortProbs[i][j] = NewProb;
VP6_EncodeBool(&cpi->bc, 1, VP6_MvUpdateProbs[i][MvUpdateProbsOffset] );
AddBitsToBuffer( &cpi->bc, NewProb >> 1, PROB_UPDATE_BASELINE_COST );
}
else
{
VP6_EncodeBool(&cpi->bc, 0, VP6_MvUpdateProbs[i][MvUpdateProbsOffset] );
}
// Increment to next offset in VP6_MvUpdateProbs[];
MvUpdateProbsOffset++;
}
}
// If appropriate update the bit probabilities for long vectors
for ( i=0; i<2; i++ ) // X then Y
{
INT32 j;
UINT32 MvUpdateProbsOffset = 2 + 7;
// For each bit
for ( j=0; j<LONG_MV_BITS; j++ )
{
NewProb = cpi->NewMvSizeProbs[i][j];
OldProb = cpi->pb.MvSizeProbs[i][j];
OldBits = ((cpi->NewMvSizeHits[i][j][0] * VP6_ProbCost[OldProb])/256) +
((cpi->NewMvSizeHits[i][j][1] * VP6_ProbCost[255 - OldProb])/256);
NewBits = ((cpi->NewMvSizeHits[i][j][0] * VP6_ProbCost[NewProb])/256) +
((cpi->NewMvSizeHits[i][j][1] * VP6_ProbCost[255 - NewProb])/256);
ProbUpdateCost = PROB_UPDATE_BASELINE_COST + MV_PROB_UPDATE_CORECTION;
ProbUpdateCost += (VP6_ProbCost[255 - VP6_MvUpdateProbs[i][MvUpdateProbsOffset]] + 128) / 256;
ProbUpdateCost -= (VP6_ProbCost[VP6_MvUpdateProbs[i][MvUpdateProbsOffset]] + 128) / 256;
if ( (OldBits - NewBits) > ProbUpdateCost )
{
cpi->pb.MvSizeProbs[i][j] = NewProb;
VP6_EncodeBool(&cpi->bc, 1, VP6_MvUpdateProbs[i][MvUpdateProbsOffset] );
AddBitsToBuffer( &cpi->bc, NewProb >> 1, PROB_UPDATE_BASELINE_COST );
}
else
{
VP6_EncodeBool(&cpi->bc, 0, VP6_MvUpdateProbs[i][MvUpdateProbsOffset] );
}
// Increment to next offset in VP6_MvUpdateProbs[];
MvUpdateProbsOffset++;
}
}
}
/****************************************************************************
*
* ROUTINE : BuildandPackMvTree2
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Build the MV entropy coding tree. This version is
* used when in unbuffered / VC mode to improve tolerance
* to dropped frames.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void BuildandPackMvTree2 ( CP_INSTANCE *cpi )
{
INT32 i;
// Stats to measure section costs
#if defined MEASURE_SECTION_COSTS
ActiveSection = MV_SECTION;
#endif
// calculate the MV node Probabilities
CalculateMvNodeProbabilities ( cpi );
// Send short and sign probabilities
for ( i=0; i<2; i++ )
{
cpi->pb.IsMvShortProb[i] = cpi->NewIsMvShortProb[i];
VP6_EncodeBool ( &cpi->bc, 1, VP6_MvUpdateProbs[i][0] );
AddBitsToBuffer( &cpi->bc, cpi->pb.IsMvShortProb[i] >> 1, PROB_UPDATE_BASELINE_COST );
cpi->pb.MvSignProbs[i] = cpi->NewMvSignProbs[i];
VP6_EncodeBool ( &cpi->bc, 1, VP6_MvUpdateProbs[i][1] );
AddBitsToBuffer( &cpi->bc, cpi->pb.MvSignProbs[i] >> 1, PROB_UPDATE_BASELINE_COST );
}
// Short vector tree nodes
for ( i=0; i<2; i++ )
{
// Node 0 Low
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][2] );
// Node 1 LowLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][3] );
// Node 2 LowLowLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][4] );
// Node 3 LowHighLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][5] );
// Node 4 HighLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][6] );
// Node 5 HighLowLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][7] );
// Node 6 HighHighLow
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][8] );
}
// Long vector Probabilities
for ( i=0; i<2; i++ )
{
// QPel
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][9] );
// HPel
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][10] );
// Bit1
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][11] );
// Bit2
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][12] );
// Bit3
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][13] );
// Bit4
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][14] );
// Bit5
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][15] );
// Bit6
VP6_EncodeBool ( &cpi->bc, 0, VP6_MvUpdateProbs[i][16] );
}
}
/****************************************************************************
*
* ROUTINE : BuildMVCostEstimates
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Calculate a cost in bits of encoding a motion vector.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void BuildMVCostEstimates ( CP_INSTANCE *cpi )
{
int i;
int vect;
cpi->bc.MeasureCost = TRUE;
for ( i=0; i<MV_ENTROPY_TOKENS; i++ )
{
cpi->bc.BitCounter = 0;
vect = i - (MV_ENTROPY_TOKENS/2);
encodeMotionVectorComponent ( cpi, 0, vect, 0 );
// keep all costs at 64 * actual number of bits
cpi->EstMvCostPtrX[vect] = (cpi->bc.BitCounter ) >> 2;
cpi->bc.BitCounter = 0;
encodeMotionVectorComponent ( cpi, 1, vect, 0 );
// keep all costs at 64 * actual number of bits
cpi->EstMvCostPtrY[vect] = (cpi->bc.BitCounter) >> 2;
}
cpi->bc.MeasureCost = FALSE;
}
@@ -0,0 +1,23 @@
/****************************************************************************
*
* Module Title : encodemv.h
*
* Description : functions for decoding modes and motionvectors
*
****************************************************************************/
#ifndef __INC_ENCODEMV_H
#define __INC_ENCODEMV_H
#ifndef STRICT
#define STRICT /* Strict type checking */
#endif
/****************************************************************************
* Exports
****************************************************************************/
extern void BuildandPackMvTree( CP_INSTANCE *cpi );
extern void BuildandPackMvTree2( CP_INSTANCE *cpi );
extern void BuildMVCostEstimates( CP_INSTANCE *cpi );
extern void encodeMotionVector ( CP_INSTANCE *cpi, INT32 MVectorX, INT32 MVectorY, CODING_MODE Mode );
#endif
@@ -0,0 +1,24 @@
/****************************************************************************
*
* Module Title : FullFrameFDCT.c
*
* Description : Compressor functions for block order transmittal
*
* AUTHOR : Paul Wilkins
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "compdll.h"
#include "misc_common.h"
#include "decodemode.h"
#include "decodemv.h"
#include "quantize.h"
extern void PredictBlock ( CP_INSTANCE *cpi, BLOCK_POSITION bp, UINT32 MBrow, UINT32 MBcol );
extern void PredictDCE( CP_INSTANCE *cpi, BLOCK_POSITION bp);
#if defined FULLFRAMEFDCT
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,84 @@
/****************************************************************************
*
* Module Title : MComp.h
*
* Description : Video CODEC: motion compensation module header .
*
****************************************************************************/
#ifndef __INC_MCOMP_H
#define __INC_MCOMP_H
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "type_aliases.h"
#include "codec_common.h"
#include "compdll.h"
/****************************************************************************
* Exports
****************************************************************************/
extern INT32 *AbsX_LUT;
/****************************************************************************
* Functions
****************************************************************************/
extern void InitMotionCompensation ( CP_INSTANCE *cpi);
extern UINT32 GetIntraErrorC ( UINT8 * DataPtr, INT32 SourceStride );
extern UINT32 GetMBIntraError ( CP_INSTANCE *cpi );
extern UINT32 GetMBInterError ( CP_INSTANCE *cpi, UINT8 * SrcPtr, UINT8 * RefPtr, MOTION_VECTOR *MV, UINT32 * );
extern UINT32 GetMBMVInterError ( CP_INSTANCE *cpi, CODING_MODE Mode, UINT8 * RefFramePtr, MOTION_VECTOR *MV, UINT32 *TempErrors );
extern UINT32 GetMBMVExhaustiveSearch ( CP_INSTANCE *cpi, CODING_MODE Mode, UINT8 * RefFramePtr, MOTION_VECTOR *MV, UINT32 * );
extern UINT32 GetBMVExhaustiveSearch ( CP_INSTANCE* cpi, UINT8* RefFramePtr, MOTION_VECTOR* MV, UINT32);
extern UINT32 GetBMVSearch ( CP_INSTANCE* cpi, UINT8* RefFramePtr, MOTION_VECTOR* MV, UINT32 );
extern UINT32 GetMBFrameVerticalVariance ( CP_INSTANCE* cpi );
extern UINT32 GetMBFieldVerticalVariance ( CP_INSTANCE* cpi );
extern UINT32 FindMvViaDiamondSearch
(
CP_INSTANCE *cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT8 **BestBlockPtr,
UINT32 BlockSize
);
extern UINT32 FindMvVia3StepSearch
(
CP_INSTANCE *cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT8 **BestBlockPtr,
UINT32 BlockSize
);
extern void FindBestFractionalPixelStep
(
CP_INSTANCE *cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT32 BlockSize,
UINT32 *MinError,
UINT8 BitShift
);
extern void SkipFractionalPixelStep
(
CP_INSTANCE *cpi,
CODING_MODE Mode,
UINT8 *SrcPtr,
UINT8 *RefPtr,
MOTION_VECTOR *MV,
UINT32 BlockSize,
UINT32 *MinError,
UINT8 BitShift
);
#endif
@@ -0,0 +1,482 @@
/****************************************************************************
*
* Module Title : MiscCommon.c
*
* Description : Miscellaneous common routines
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "compdll.h"
/****************************************************************************
* Macros
****************************************************************************/
#define KF_WORST_Q_INDEX 20
/****************************************************************************
* Module Static
****************************************************************************/
// Provisional data for interpolated positions (x.xx00)
static const LINE_EQ2 InterBpBEquations[Q_TABLE_SIZE] =
{
{ 0.00115, 445.98890}, { 0.00132, 406.83041}, { 0.00148, 400.18762}, { 0.00160, 363.68569},
{ 0.00174, 378.33470}, { 0.00199, 377.42412}, { 0.00237, 300.00652}, { 0.00262, 266.74763},
{ 0.00280, 252.69107}, { 0.00312, 205.72084}, { 0.00351, 183.14721}, { 0.00386, 155.88815},
{ 0.00432, 95.74501}, { 0.00447, 91.53841}, { 0.00469, 69.65309}, { 0.00481, 80.08054},
{ 0.00496, 63.44023}, { 0.00520, 110.00485}, { 0.00542, 108.04172}, { 0.00558, 165.23727},
{ 0.00585, 154.10530}, { 0.00600, 176.84087}, { 0.00621, 169.06892}, { 0.00641, 157.49036},
{ 0.00664, 148.93471}, { 0.00713, 199.24375}, { 0.00752, 210.01239}, { 0.00816, 195.86514},
{ 0.00883, 352.16439}, { 0.00920, 354.57230}, { 0.00958, 393.60319}, { 0.00999, 420.30206},
{ 0.01063, 529.24195}, { 0.01118, 538.52879}, { 0.01170, 651.23813}, { 0.01218, 713.79800},
{ 0.01263, 788.52303}, { 0.01321, 871.46329}, { 0.01393, 1078.68114}, { 0.01459, 1180.46989},
{ 0.01529, 1309.93961}, { 0.01597, 1366.39052}, { 0.01677, 1627.17452}, { 0.01762, 1826.38865},
{ 0.01859, 2010.00287}, { 0.01963, 2388.91757}, { 0.02070, 2683.36530}, { 0.02178, 2875.49060},
{ 0.02260, 3178.16923}, { 0.02418, 3572.88801}, { 0.02531, 4062.37227}, { 0.02709, 4921.59728},
{ 0.02918, 5592.29649}, { 0.03107, 6186.93245}, { 0.03372, 7376.13311}, { 0.03768, 9534.78915},
{ 0.04197, 11906.09757}, { 0.04691, 15241.79652}, { 0.05157, 18904.29545}, { 0.05953, 27091.47553},
{ 0.07025, 41522.27709}, { 0.08343, 67789.86180}, { 0.11547, 124265.97640}, { 0.13380, 210301.81305},
};
static const LINE_EQ2 IntraBpBEquations[Q_TABLE_SIZE] =
{
{ 0.00106, 2288.83435}, { 0.00111, 2381.24321}, { 0.00116, 2484.21594}, { 0.00120, 2536.01662},
{ 0.00127, 2674.68182}, { 0.00136, 2835.12286}, { 0.00146, 2946.60819}, { 0.00154, 3034.48115},
{ 0.00163, 3117.20084}, { 0.00172, 3233.89966}, { 0.00184, 3407.24634}, { 0.00195, 3543.03650},
{ 0.00210, 3699.64900}, { 0.00215, 3793.02049}, { 0.00220, 3854.74475}, { 0.00224, 3915.99566},
{ 0.00227, 3959.82316}, { 0.00233, 4204.84699}, { 0.00237, 4276.08365}, { 0.00242, 4387.12774},
{ 0.00246, 4452.87571}, { 0.00251, 4578.78112}, { 0.00256, 4642.65467}, { 0.00261, 4710.56167},
{ 0.00267, 4780.30368}, { 0.00279, 5030.71570}, { 0.00288, 5170.75293}, { 0.00303, 5374.83851},
{ 0.00315, 5872.91562}, { 0.00324, 6002.40178}, { 0.00331, 6163.13111}, { 0.00341, 6330.88665},
{ 0.00356, 6638.13056}, { 0.00367, 6813.20389}, { 0.00378, 7073.27347}, { 0.00391, 7264.41977},
{ 0.00401, 7464.35187}, { 0.00414, 7686.68885}, { 0.00427, 8222.38307}, { 0.00442, 8469.27069},
{ 0.00459, 8750.44432}, { 0.00472, 8961.97754}, { 0.00492, 9406.63273}, { 0.00513, 9784.70928},
{ 0.00531, 10199.58953}, { 0.00556, 10786.82064}, { 0.00582, 11271.52430}, { 0.00606, 11694.10222},
{ 0.00631, 12147.95242}, { 0.00664, 12808.92178}, { 0.00695, 13528.07213}, { 0.00732, 14860.00245},
{ 0.00779, 15815.03822}, { 0.00822, 16685.69714}, { 0.00884, 18214.89132}, { 0.00972, 20431.29266},
{ 0.01063, 22995.09970}, { 0.01169, 26309.59450}, { 0.01275, 29857.49766}, { 0.01436, 37027.81351},
{ 0.01637, 49621.40625}, { 0.01873, 72068.47846}, { 0.02150, 123873.67566}, { 0.02488, 208511.43171},
};
/****************************************************************************
* Exports
****************************************************************************/
// For FixedQ helps choos appropriate key frame quality.
const UINT8 FixedQKfBoostTable[64] =
{
22, 24, 26, 26, 26, 26, 27, 28,
28, 27, 27, 26, 26, 25, 25, 24,
24, 23, 23, 22, 22, 21, 21, 20,
20, 19, 18, 18, 17, 16, 16, 15,
15, 14, 14, 13, 13, 13, 12, 12,
12, 12, 12, 11, 11, 11, 10, 9,
8, 7, 7, 6, 5, 4, 3, 2,
1, 1, 0, 0, 0, 0, 0, 0
};
const UINT8 GfFixedQKfBoostTable[64] =
{
20, 22, 23, 23, 23, 24, 25, 26,
27, 27, 28, 28, 29, 29, 28, 28,
28, 27, 27, 27, 26, 26, 26, 26,
25, 25, 25, 25, 24, 24, 23, 23,
22, 21, 21, 20, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 6, 5, 5, 4, 4,
4, 3, 3, 2, 1, 0, 0, 0
};
/****************************************************************************
*
* ROUTINE : GetEstimatedBpb
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 TargetQIndex : Q Index to estimate for.
*
* OUTPUTS : None.
*
* RETURNS : double: The current estimate for the number of bits per block
* at the current Q.
*
* FUNCTION : Computes estimate of the number of bits per block
* that will be produced if coded at the specified Q.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
double GetEstimatedBpb ( CP_INSTANCE *cpi, UINT32 TargetQIndex )
{
double BitsPerBlock;
double Complexity = (double)cpi->InterError;
// NOTE 1: Inter and Intra error are the same for key frames.
// NOTE 2: It may prove necessary to clip the complexity value.
// Adjust according to currently active correction factor
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
{
// TEMP: use inter equations * 2 until Key frame values worked out
//BitsPerBlock = ((InterBpBEquations[TargetQIndex].M * Complexity) + InterBpBEquations[TargetQIndex].C)/(double)cpi->pb.UnitFragments;
BitsPerBlock = ((IntraBpBEquations[TargetQIndex].M * Complexity) + IntraBpBEquations[TargetQIndex].C)/(double)cpi->pb.UnitFragments;
BitsPerBlock = BitsPerBlock * cpi->KeyFrameBpbCorrectionFactor;
}
else
{
// Get primary prediction
BitsPerBlock = ((InterBpBEquations[TargetQIndex].M * Complexity) + InterBpBEquations[TargetQIndex].C)/(double)cpi->pb.UnitFragments;
// Apply the correction factor that is based upon recent observations of overshoot and undershoot
// Note that if we are coding a GF update frame we expect overshoot because we are jumping to
// a higher quality from a lower quality (the tables were caluclated using fixed Q). Hence the
// additional correction for this case.
if ( cpi->pb.RefreshGoldenFrame )
BitsPerBlock = BitsPerBlock * (cpi->BpbCorrectionFactor * cpi->GfuBpbCorrectionFactor);
else
BitsPerBlock = BitsPerBlock * cpi->BpbCorrectionFactor;
}
return BitsPerBlock;
}
void UpdateBpbCorrectionFactor2 ( CP_INSTANCE *cpi, UINT32 FrameSize )
{
double BpbCorrectionFactor;
#if defined(_MSC_VER)
// NOTE: This function uses floating point
ClearSysState();
#endif
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
BpbCorrectionFactor = cpi->KeyFrameBpbCorrectionFactor;
else
{
if ( cpi->pb.RefreshGoldenFrame )
BpbCorrectionFactor = cpi->GfuBpbCorrectionFactor;
else
BpbCorrectionFactor = cpi->BpbCorrectionFactor;
}
// Work out a size correction factor.
BpbCorrectionFactor *= (3+(2.0 * FrameSize) / cpi->ThisFrameTarget) /5;
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
cpi->KeyFrameBpbCorrectionFactor = BpbCorrectionFactor;
else
{
if ( cpi->pb.RefreshGoldenFrame )
cpi->GfuBpbCorrectionFactor = BpbCorrectionFactor;
else
cpi->BpbCorrectionFactor = BpbCorrectionFactor;
}
}
/****************************************************************************
*
* ROUTINE : UpdateBpbCorrectionFactor
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 FrameSize : Size of coded frame.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Adjusts the Bits Per Block correction factor used
* for rate prediction.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void UpdateBpbCorrectionFactor ( CP_INSTANCE *cpi, UINT32 FrameSize )
{
INT32 CorrectionFactor=100;
double BpbCorrectionFactor;
#if defined(_MSC_VER)
// NOTE: This function uses floating point
ClearSysState();
#endif
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
BpbCorrectionFactor = cpi->KeyFrameBpbCorrectionFactor;
else
{
if ( cpi->pb.RefreshGoldenFrame )
BpbCorrectionFactor = cpi->GfuBpbCorrectionFactor;
else
BpbCorrectionFactor = cpi->BpbCorrectionFactor;
}
// Work out a size correction factor.
if(cpi->ThisFrameTarget > 0 )
CorrectionFactor = (100 * FrameSize) / cpi->ThisFrameTarget;
if ( (CorrectionFactor > 101) &&
(cpi->pb.quantizer->FrameQIndex > cpi->Configuration.ActiveWorstQuality ) )
{
// We are not already at the worst allowable quality
CorrectionFactor = 100 + ((CorrectionFactor - 100)/4);
if ( CorrectionFactor > 125 ) // Damp the adjustment
BpbCorrectionFactor = (BpbCorrectionFactor * 125)/100;
else
BpbCorrectionFactor = (BpbCorrectionFactor * CorrectionFactor) / 100;
// Keep BpbCorrectionFactor within limits
if ( BpbCorrectionFactor > MAX_BPB_FACTOR )
BpbCorrectionFactor = MAX_BPB_FACTOR;
}
else if ( (CorrectionFactor < 99) &&
(cpi->pb.quantizer->FrameQIndex < cpi->Configuration.ActiveBestQuality ) )
{
// We are not already at the best allowable quality
CorrectionFactor = 100 - ((100 - CorrectionFactor)/4);
if ( CorrectionFactor < 80 ) // Damp the adjustment
BpbCorrectionFactor = (BpbCorrectionFactor * 80)/100;
else
BpbCorrectionFactor = (BpbCorrectionFactor * CorrectionFactor) / 100;
// Keep BpbCorrectionFactor within limits
if ( BpbCorrectionFactor < MIN_BPB_FACTOR )
BpbCorrectionFactor = MIN_BPB_FACTOR;
}
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
cpi->KeyFrameBpbCorrectionFactor = BpbCorrectionFactor;
else
{
if ( cpi->pb.RefreshGoldenFrame )
cpi->GfuBpbCorrectionFactor = BpbCorrectionFactor;
else
cpi->BpbCorrectionFactor = BpbCorrectionFactor;
}
}
/****************************************************************************
*
* ROUTINE : ClampAndUpdateQ
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 QIndex : Current Q Index.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Ensures that the specified Q index is within current
* active range and applies other constraints.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void ClampAndUpdateQ ( CP_INSTANCE *cpi, UINT32 QIndex )
{
// Apply limits to the value of QIndex
// NOTE: Bigger QIndex ==> Higher Quality (Lower Quantizer)!!!!
if ( QIndex > cpi->Configuration.ActiveBestQuality )
QIndex = cpi->Configuration.ActiveBestQuality;
else if ( QIndex < cpi->Configuration.ActiveWorstQuality )
QIndex = cpi->Configuration.ActiveWorstQuality;
// Apply range restrictions for key frames.
if ( VP6_GetFrameType(&cpi->pb) == BASE_FRAME )
{
// Fixed Q Stuff for key frames
if ( cpi->FixedQ >= 0 )
{
UINT8 Q;
// Set an appropriate Key frame Q to match the recent ambient quality
if ( (cpi->LastKeyFrame >= cpi->ForceKeyFrameEvery) )
Q = cpi->FixedQ + (FixedQKfBoostTable[cpi->FixedQ]/2);
else
Q = cpi->FixedQ + FixedQKfBoostTable[cpi->FixedQ];
cpi->pb.quantizer->FrameQIndex = Q;
}
else
{
// Additional QIndex limits for Key frames
if( cpi->pass != 2)
{
if ( QIndex < KF_WORST_Q_INDEX )
QIndex = KF_WORST_Q_INDEX;
else if ( QIndex > 60 )
QIndex = 60;
}
cpi->pb.quantizer->FrameQIndex = QIndex;
}
// We are going to update GF this frame so reset counter till next update due.
if(cpi->pass < 2)
cpi->GfUpdateInterval = DEFAULT_GF_UPDATE_INTERVAL;
else
cpi->GfUpdateInterval = DEFAULT_2PASS_GF_UPDATE_INTERVAL;
cpi->FramesTillGfUpdateDue = cpi->GfUpdateInterval;
if ( cpi->GfUpdateInterval )
cpi->GfuMotionSpeed = GF_UPDATE_MOTION_INTERVAL / cpi->GfUpdateInterval;
else
cpi->GfuMotionSpeed = 0;
cpi->GfuMotionComplexity = GF_DEFAULT_MOTION_CMPLX;
cpi->GfuBoost = 0;
}
else
{
if(cpi->FixedQ >= 0)
{
// We want KFs to count as GF updates
cpi->pb.quantizer->FrameQIndex = cpi->FixedQ;
if(!cpi->DisableGolden)
{
if ( cpi->FramesTillGfUpdateDue == 0 )
{
UINT32 Sum = 0;
UINT32 Sum2 = 0;
UINT32 Sum3 = 0;
UINT32 i;
UINT32 VarianceX = 0;
UINT32 VarianceY = 0;
UINT32 MaxVariance = 0;
// Check the level of MV reuse as a measure of how valuable a GF update is likely to be.
for ( i = 0; i < MAX_MODES; i++ )
Sum += cpi->ModeDist[i];
if ( Sum )
{
Sum2 = Sum - (cpi->ModeDist[CODE_INTRA] + cpi->ModeDist[CODE_INTER_PLUS_MV] + cpi->ModeDist[CODE_INTER_FOURMV]);
Sum3 = Sum2 - cpi->ModeDist[CODE_INTER_NO_MV];
// Convert Sum2 and Sum3 to %
Sum2 = (Sum2 * 100 / Sum);
Sum3 = (Sum3 * 100 / Sum);
}
// Calculate various motion metrics
if ( cpi->FrameMvStats.NumMvs )
{
cpi->GfuMotionSpeed = (cpi->FrameMvStats.SumAbsX > cpi->FrameMvStats.SumAbsY) ? (cpi->FrameMvStats.SumAbsX/cpi->FrameMvStats.NumMvs) : (cpi->FrameMvStats.SumAbsY/cpi->FrameMvStats.NumMvs);
VarianceX = ((cpi->FrameMvStats.NumMvs * cpi->FrameMvStats.SumXSq) - (cpi->FrameMvStats.SumX*cpi->FrameMvStats.SumX)) / (cpi->FrameMvStats.NumMvs * cpi->FrameMvStats.NumMvs);
VarianceY = ((cpi->FrameMvStats.NumMvs * cpi->FrameMvStats.SumYSq) - (cpi->FrameMvStats.SumY*cpi->FrameMvStats.SumY)) / (cpi->FrameMvStats.NumMvs * cpi->FrameMvStats.NumMvs);
MaxVariance = (VarianceX > VarianceY) ? VarianceX : VarianceY;
cpi->GfuMotionComplexity = cpi->GfuMotionSpeed + ((VarianceX)/4) + ((VarianceY)/4);
if ( cpi->GfuMotionComplexity > 31 )
cpi->GfuMotionComplexity = 31;
}
else
{
cpi->GfuMotionSpeed = 0;
cpi->GfuMotionComplexity = 0;
}
// Should we even consider a GF update or is there no point
if ( (Sum2 > GF_MODE_DIST_THRESH1) && (Sum3 > GF_MODE_DIST_THRESH2) &&
(cpi->GfuMotionSpeed <= MAX_GF_UPDATE_MOTION) &&
(MaxVariance <= GF_MAX_VAR_THRESH) )
{
cpi->pb.quantizer->FrameQIndex = cpi->FixedQ + GfFixedQKfBoostTable[cpi->FixedQ];
cpi->pb.RefreshGoldenFrame = TRUE;
}
else
{
cpi->pb.quantizer->FrameQIndex = cpi->FixedQ;
}
}
else
{
cpi->pb.quantizer->FrameQIndex = cpi->FixedQ;
}
}
}
else
{
cpi->pb.quantizer->FrameQIndex = QIndex;
}
}
// If necessary re-initialise the quantiser
VP6_UpdateQC( cpi->pb.quantizer, cpi->pb.Vp3VersionNo );
}
/****************************************************************************
*
* ROUTINE : RegulateQ
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* INT32 TargetBits : Target number of bits for frame.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : This function tries to regulate quanitzer level
* to produce the specified target number of bits.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void RegulateQ ( CP_INSTANCE *cpi, INT32 TargetBits )
{
UINT32 i;
double Predbpb;
UINT32 QIndex = Q_TABLE_SIZE - 1;
double Targetbpb = (double)TargetBits / (double)cpi->pb.UnitFragments;
double LastBitError = 10000.0; // Infeasibly high number to initialize
// Search for the best Q for the target bitrate.
for ( i=0; i<Q_TABLE_SIZE; i++ )
{
Predbpb = GetEstimatedBpb( cpi, i );
if ( Predbpb > Targetbpb )
{
if ( (Predbpb - Targetbpb) <= LastBitError )
QIndex = i;
else
QIndex = i - 1;
break;
}
else
LastBitError = Targetbpb - Predbpb;
}
ClampAndUpdateQ ( cpi, QIndex );
}
/****************************************************************************
*
* ROUTINE : ConfigureQuality
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* UINT32 QualityValue : Quality value.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Sets maximum operating Q value for specified
* quality level.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void ConfigureQuality ( CP_INSTANCE *cpi, UINT32 QualityValue )
{
// Set the worst case quality value.
// Note that the actual quality is determined by lookup into the quantiser table QThreshTable[]
cpi->Configuration.WorstQuality = 63 - QualityValue;
// Set the default Active WorstQuality.
cpi->Configuration.ActiveWorstQuality = cpi->Configuration.WorstQuality;
}
@@ -0,0 +1,97 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by compdll.rc
//
#define IDD_SYNC_SENTINEL 109
#define IDD_STATS_DIALOG 113
#define IDM_SHOW_STATS 115
#define ID_OPTIONS_LIVEVIDEO 116
#define IDM_STOP 117
#define IDM_SHOW_DIFFERENCES 130
#define ID_OPTIONS_SETUPGRABBER 131
#define IDD_DIALOG1 209
#define IDC_CK_ENABLE 1023
#define IDC_ED_HSEARCH 1024
#define IDC_ED_HINSERT 1028
#define IDC_ED_VSEARCH 1029
#define IDC_ED_VINSERT 1030
#define IDC_MFILTER 1039
#define IDC_STATS_FRAME_NO_EDIT 1040
#define IDC_BAR_ENHANCE_EDIT 1041
#define IDC_STATS_LAST_FRAME_EDIT 1041
#define IDC_STATS_AV_EDIT 1042
#define IDC_STATS_PEAK_EDIT 1043
#define IDC_STATS_DROPPED_FRAMES_EDIT 1044
#define IDC_STATS_AVFPS_EDIT 1045
#define IDC_STATS_IFPS_EDIT 1046
#define IDC_STATS_TIME_EDIT 1047
#define IDC_STATS_CURR_EDIT 1048
#define IDC_STATS_CFA_EDIT 1049
#define IDC_STATS_CFAAV_EDIT 1050
#define IDC_EDIT_CAT_A 2000
#define IDC_EDIT_SRC_FR 2001
#define IDC_EDIT_PIX_DIFF_THRESH 2002
#define IDC_EDIT_LOCALS_LOSSY 2003
#define IDC_EDIT_CAT_C 2004
#define IDC_EDIT_CAT_D 2005
#define IDC_EDIT_CAT_B 2006
#define IDC_EDIT_CAT_A_FR 2007
#define IDC_EDIT_CAT_C_FR 2008
#define IDC_EDIT_CAT_D_FR 2009
#define IDC_EDIT_CAT_B_FR 2010
#define IDC_EDIT_NUM_FRAMES 2011
#define IDC_EDIT_NOISE_SUP 2012
#define IDC_EDIT_NOISE_SUP2 2013
#define IDC_PIXEL_LOSSY_CHECK 2014
#define IDC_SCORE_LOSSY 2015
#define IDC_LOCALS_LOSSY 2016
#define IDC_SING_LOSSY 2017
#define IDC_EDIT_SCORE_LOSSY 2018
#define IDC_EDIT_OUT_FRAME_RATE 2019
#define IDC_EDIT_TARGET_DATA_RATE 2020
#define IDC_EDIT_PIX_GREY_THRESH 2021
#define IDC_DCT_THRESH 2023
#define IDC_GREY_DCT_VARIABLE 2024
#define IDC_DCT_THRESH_TOP 2025
#define IDC_CONS_SEMI 2026
#define IDC_CONS_NORM_FRAMES 2027
#define IDC_NUM_CONS_SEMI 2028
#define IDC_NUM_CONS_NORM 2029
#define IDC_NUM_CONS_NORM_MAX 2030
#define IDC_CONS_NORM_FRAMES_MAX 2031
#define IDC_DCT_GREY 2033
#define IDC_GREY 2034
#define IDC_COLOUR 2035
#define IDC_EDIT_MAX_DATA_RATE 2036
#define IDC_CWASH_CHECK 2037
#define IDC_PWASH_CHECK 2038
#define IDC_FF_DCT_EDIT 2039
#define IDM_RUN 40001
#define IDM_COMPRESS 40002
#define IDM_STEP 40003
#define IDM_REPLAY 40004
#define IDM_PARAMS 40005
#define IDM_CAPTURE_RAW 40006
#define IDM_SHOW_ZERO_DIFFERENCES 40007
#define IDM_SHOW_EDGES 40008
#define ID_OPTIONS_DISKSTATS 40008
#define IDM_SHOW_NORMAL 40009
#define IDM_SHOW_SCORE 40010
#define ID_OPTIONS_OUTPUTFILTEREDBITMAPS 40011
#define ID_OPTIONS_DISABLEENCODER 40012
#define RGM_SLOW_FDCT 40013
#define RGM_FAST_IDCT 40014
#define RGM_FAST_FDCT 40015
#define RGM_SLOW_IDCT 40016
#define RGM_DEBLOCK 40017
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40018
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
@@ -0,0 +1,810 @@
/****************************************************************************
*
* Module Title : vfwcomp_if.c
*
* Description : Compressor interface definition.
*
****************************************************************************/
/****************************************************************************
* Header Files
****************************************************************************/
#include <stdio.h>
#include "compdll.h"
#include "twopass.h"
#include <math.h>
/****************************************************************************
* Imports
****************************************************************************/
extern const UINT32 GfuDataRateBoost[64];
extern const UINT32 GfuMotionCorrection[32];
extern const UINT32 GfUsageCorrection[64];
/****************************************************************************
*
* ROUTINE : ZeroStats
*
* INPUTS :
* FIRSTPASS_STATS *stats Stats to empty the accumulator of
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void ZeroStats( FIRSTPASS_STATS *section)
{
section->count = 0;
section->MotionSpeed = 0 ;
section->VarianceX = 0 ;
section->VarianceY = 0 ;
section->PercentGolden = 0;
section->PercentMotionY = 0 ;
section->PercentMotion = 0 ;
section->PercentNewMotion = 0 ;
section->MeanInterError = 0 ;
section->MeanIntraError = 0 ;
section->BitsPerMacroblock = 0 ;
section->SqBitsPerMacroblock = 0 ;
section->PSNR = 0 ;
section->isGolden = 0;
section->isKey = 0;
}
/****************************************************************************
*
* ROUTINE : AccumulateStats
*
* INPUTS : FIRSTPASS_STATS *section stats to accumulate into
* FIRSTPASS_STATS *stats Stats to add to accumulated values
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Accumulates firstpass statistics
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void AccumulateStats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
{
section->count ++;
section->MotionSpeed += frame->MotionSpeed;
section->VarianceX += frame->VarianceX;
section->VarianceY += frame->VarianceY;
section->PercentGolden += frame->PercentGolden;
section->PercentMotionY += frame->PercentMotionY;
section->PercentMotion += frame->PercentMotion;
section->PercentNewMotion += frame->PercentNewMotion;
section->MeanInterError += frame->MeanInterError;
section->MeanIntraError += frame->MeanIntraError;
section->BitsPerMacroblock += frame->BitsPerMacroblock;
section->SqBitsPerMacroblock += frame->SqBitsPerMacroblock;
section->PSNR += frame->PSNR;
section->isGolden += frame->isGolden;
section->isKey += frame->isKey;
}
/****************************************************************************
*
* ROUTINE : AvgStats
*
* INPUTS :
* FIRSTPASS_STATS *stats Stats to convert to averages using count
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void AvgStats ( FIRSTPASS_STATS *section)
{
if(!section->count)
return;
section->MotionSpeed /= section->count;
section->VarianceX /= section->count;
section->VarianceY /= section->count;
section->PercentGolden /= section->count;
section->PercentMotionY /= section->count;
section->PercentMotion /= section->count;
section->PercentNewMotion /= section->count;
section->MeanInterError /= section->count;
section->MeanIntraError /= section->count;
section->BitsPerMacroblock /= section->count;
section->SqBitsPerMacroblock /= section->count;
section->PSNR /= section->count;
}
/****************************************************************************
*
* ROUTINE : OutputStats
*
* INPUTS : FILE *F File to output the stats to
* FIRSTPASS_STATS *stats Stats to fill in
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void OutputStats( FILE *f, FIRSTPASS_STATS *stats)
{
fprintf(f,
"%8d %8d %8d %8d %12.04f %12.04f %12.04f %12.04f %12.04f %12.04f %12.04f %12.04f %12.04f %12.04f \n",
stats->frame,
stats->count,
stats->isKey,
stats->isGolden,
stats->BitsPerMacroblock,
stats->SqBitsPerMacroblock,
stats->MeanInterError,
stats->MeanIntraError,
stats->MotionSpeed,
stats->VarianceX,
stats->VarianceY,
stats->PercentMotion,
stats->PercentNewMotion,
stats->PercentGolden);
}
/****************************************************************************
*
* ROUTINE : InputStats
*
* INPUTS : FILE *F File to read the stats in
* FIRSTPASS_STATS *stats Stats to fill in
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void InputStats( FILE *f, FIRSTPASS_STATS *stats)
{
fscanf(f,
"%d %d %d %d %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg \n",
&stats->frame,
&stats->count,
&stats->isKey,
&stats->isGolden,
&stats->BitsPerMacroblock,
&stats->SqBitsPerMacroblock,
&stats->MeanInterError,
&stats->MeanIntraError,
&stats->MotionSpeed,
&stats->VarianceX,
&stats->VarianceY,
&stats->PercentMotion,
&stats->PercentNewMotion,
&stats->PercentGolden);
}
/****************************************************************************
*
* ROUTINE : Pass2Initialize
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* COMP_CONFIG_VP6 *CompConfig : Encoder configuration.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initialize 1st or 2nd pass of the compressor
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV Pass2Initialize ( CP_INSTANCE *cpi, COMP_CONFIG_VP6 *CompConfig )
{
if(cpi->pass == 2)
{
int actualMBS =(cpi->pb.MBRows - (BORDER_MBS*2)) * (cpi->pb.MBCols - (BORDER_MBS*2));
double fpBitRate; // first pass bitrate
double target; // target bitrate
double NewQ;
double Sigma;
double RoomForVariation;
double tmp;
char dummy[1024];
ClearSysState();
cpi->fs = fopen(CompConfig->FirstPassFile,"r");
strncpy(dummy,CompConfig->FirstPassFile,1024);
strcat(dummy,".sst");
cpi->ss = fopen(dummy,"r");
fgets(dummy,1024,cpi->fs);
fgets(dummy,1024,cpi->ss);
InputStats(cpi->ss,&cpi->fpmss);
tmp = cpi->fpmss.SqBitsPerMacroblock - cpi->fpmss.BitsPerMacroblock*cpi->fpmss.BitsPerMacroblock;
Sigma = sqrt(tmp);
RoomForVariation = (Sigma+2) / 3.5; // 5 q steps above
RoomForVariation = (Sigma+2) / 15; // 5 q steps above
RoomForVariation = 1;
fpBitRate = cpi->fpmss.BitsPerMacroblock * actualMBS * cpi->Configuration.OutputFrameRate;
target = (double) cpi->Configuration.TargetBandwidth;
NewQ = (INT32) FIRSTPASS_Q - ( RoomForVariation + .5 + log(fpBitRate/target) / log(1.04));
if(NewQ < cpi->Configuration.WorstQuality )
NewQ = cpi->Configuration.WorstQuality;
if(NewQ > cpi->Configuration.ActiveBestQuality)
NewQ = cpi->Configuration.ActiveBestQuality;
if(NewQ > 50)
NewQ = 50;
cpi->PassedInWorstQ = cpi->Configuration.WorstQuality;
cpi->Configuration.WorstQuality = (INT32) NewQ;
cpi->CalculatedWorstQ = (INT32) NewQ;
cpi->Configuration.ActiveWorstQuality = cpi->Configuration.WorstQuality;
cpi->TotalBitsLeftInClip = 1.0 * cpi->ActualTargetBitRate * cpi->fpmss.count / cpi->Configuration.OutputFrameRate;
cpi->FramesYetToEncode = cpi->fpmss.count;
//cpi->TotalBitsPerMB = cpi->fpmss.BitsPerMacroblock * cpi->fpmss.count;
cpi->TotalBitsPerMB = cpi->fpmss.MeanInterError * cpi->fpmss.count;
}
else if (cpi->pass == 1)
{
char dummy[1024];
ZeroStats( &cpi->fpmss);
cpi->fs = fopen(CompConfig->FirstPassFile,"w");
fprintf(cpi->fs,
"%8s %8s %8s %8s %12s %12s %12s %12s %12s %12s %12s %12s %12s %12s \n",
"","#","key","golden","bits/mb","sq bits/mb","Inter","Intra","Motion","VarX","VarY",
"%Motion","%NewMotion","%Golden");
strncpy(dummy,CompConfig->FirstPassFile,1024);
strcat(dummy,".sst");
cpi->ss = fopen(dummy,"w");
fprintf(cpi->ss,
"%8s %8s %8s %8s %12s %12s %12s %12s %12s %12s %12s %12s %12s %12s \n",
"","#","key","golden","bits/mb","sq bits/mb","Inter","Intra","Motion","VarX","VarY",
"%Motion","%NewMotion","%Golden");
}
}
/****************************************************************************
*
* ROUTINE : Pass2Control
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS : unsigned int *is_key : Flag whether frame coded
* as intra-frame or not.
*
* RETURNS :
*
* FUNCTION : Determines Section info, and does datarate control
* that is only possible in 2nd pass
*
* SPECIAL NOTES :
*
****************************************************************************/
void CCONV Pass2Control( CP_INSTANCE *cpi)
{
INT32 i;
FIRSTPASS_STATS sectionStats;
FIRSTPASS_STATS thisFrame;
FIRSTPASS_STATS nextFrame;
FIRSTPASS_STATS lastFrame;
double NewBitsPerMB;
double total=0;
double avg = 0;
int actualMBS ;
fpos_t pos1,pos2;
InputStats(cpi->fs,&thisFrame);
fgetpos(cpi->fs,&pos1);
//NewBitsPerMB = cpi->TotalBitsPerMB - thisFrame.BitsPerMacroblock;
NewBitsPerMB = cpi->TotalBitsPerMB - thisFrame.MeanInterError;
// keyframe and section processing !
if( cpi->FramesToKey == 0 )
{
cpi->KFForced = cpi->NextKFForced;
cpi->NextKFForced = 0;
cpi->ThisIsKeyFrame = TRUE;
ZeroStats( &sectionStats);
//AccumulateStats(&sectionStats, &thisFrame);
cpi->FramesToKey = 1;
InputStats(cpi->fs,&nextFrame);
// find the next keyframe
while(!feof(cpi->fs))
{
memcpy(&lastFrame,&thisFrame,sizeof(thisFrame));
memcpy(&thisFrame,&nextFrame,sizeof(thisFrame));
InputStats(cpi->fs,&nextFrame);
// mark a key if first pass marked it a keyframe and its within minimum distance to keyframe numbers or
// the next frame gets a big benefit from it being a keyframe
if( ( thisFrame.isKey
&& ( cpi->FramesToKey > cpi->MinimumDistanceToKeyFrame
&& ( fabs(lastFrame.MeanInterError - thisFrame.MeanInterError) / thisFrame.MeanInterError > .40
|| fabs(lastFrame.MeanIntraError - thisFrame.MeanIntraError) / thisFrame.MeanIntraError > .40
|| thisFrame.MeanIntraError * 5 < thisFrame.MeanInterError * 6
)
|| nextFrame.MeanIntraError > nextFrame.MeanInterError + 2000
)
)
)
{
break;
}
cpi->FramesToKey ++;
// since we don't have a key frame within the next two forcekeyframeevery intervals
// set the next keyframe to be forcekeyframe every
if(cpi->FramesToKey > 2 * cpi->ForceKeyFrameEvery)
{
cpi->FramesToKey = cpi->ForceKeyFrameEvery;
cpi->NextKFForced = 1;
break;
}
}
if(feof(cpi->fs))
cpi->FramesToKey ++;
// distance to keyframe is not 2 times our max distance but it is greater than our max distance
// since we need a keyframe put it in the center between this key frame and the next
if( cpi->FramesToKey > cpi->ForceKeyFrameEvery )
{
cpi->FramesToKey /= 2;
cpi->NextKFForced = 1;
}
fgetpos(cpi->fs,&pos2);
pos2-=pos1;
fseek(cpi->fs,(INT32) -pos2,SEEK_CUR);
// determine how big to make this keyframe based on how well the subsequent frames use inter blocks
total = 1.0;
for(i = 0 ;i < 4 && i < cpi->FramesToKey ; i++)
{
InputStats(cpi->fs,&nextFrame);
total *= ( nextFrame.MeanIntraError - nextFrame.MeanInterError ) / nextFrame.MeanIntraError;
avg += total * ( nextFrame.MeanIntraError - nextFrame.MeanInterError ) ;
// this break out is to insure we handle the situation that is really different from
// our last frame but similar to our next frame doesn't get counted in our metric, which
// is trying to estimate the average amount of data retained from the keyframe.
if(total < .1 || nextFrame.MeanIntraError < 200)
break;
}
cpi->KFBoost = (INT32 ) avg / 180 ;//(16* total);//16 * avg / 6 );
if(cpi->FramesToKey < 4 )//&& cpi->BufferLevel < cpi->OptimalBufferLevel / 2)
cpi->KFBoost = 0;
fgetpos(cpi->fs,&pos2);
pos2-=pos1;
fseek(cpi->fs,(INT32) -pos2,SEEK_CUR);
// read first pass file up until next keyframe and generate avg section stats.
total = 1.0;
for(i = 0 ;i < cpi->FramesToKey-1 ; i++)
{
InputStats(cpi->fs,&thisFrame);
AccumulateStats(&sectionStats, &thisFrame);
}
AvgStats(&sectionStats);
fgetpos(cpi->fs,&pos2);
pos2-=pos1;
fseek(cpi->fs,(INT32) -pos2,SEEK_CUR);
actualMBS = (cpi->pb.MBRows - (BORDER_MBS*2)) * (cpi->pb.MBCols - (BORDER_MBS*2));
if(cpi->TwoPassVBREnabled)
// determine bitrate to shoot for for this section
{
//double SectionBitsPerMB = sectionStats.BitsPerMacroblock * sectionStats.count;
//double Pctg = SectionBitsPerMB / cpi->TotalBitsPerMB ;
double SectionErrorPerMB = sectionStats.MeanInterError * sectionStats.count;
double Pctg = SectionErrorPerMB / cpi->TotalBitsPerMB;
double DesiredSectionSize = cpi->TotalBitsLeftInClip * Pctg;
double DesiredSectionBitRate = cpi->Configuration.OutputFrameRate * DesiredSectionSize / sectionStats.count;
if(sectionStats.count < 2)
DesiredSectionBitRate = cpi->ActualTargetBitRate ;
if(cpi->TwoPassVBRBias)
{
DesiredSectionBitRate = cpi->ActualTargetBitRate * (100 - cpi->TwoPassVBRBias) / 100 + DesiredSectionBitRate * cpi->TwoPassVBRBias / 100 ;
}
if(DesiredSectionBitRate < cpi->ActualTargetBitRate * cpi->TwoPassVBRMinSection / 100 )
DesiredSectionBitRate = cpi->ActualTargetBitRate * cpi->TwoPassVBRMinSection /100 ;
if(DesiredSectionBitRate > (double) cpi->ActualTargetBitRate * cpi->TwoPassVBRMaxSection / 100 )
DesiredSectionBitRate = cpi->ActualTargetBitRate * cpi->TwoPassVBRMaxSection / 100 ;
cpi->Configuration.TargetBandwidth = (INT32) DesiredSectionBitRate;
cpi->InterFrameTarget = (INT32)((cpi->Configuration.TargetBandwidth -
((cpi->KeyFrameDataTarget * cpi->Configuration.OutputFrameRate)/cpi->KeyFrameFrequency)) / cpi->Configuration.OutputFrameRate);
cpi->PerFrameBandwidth = (cpi->Configuration.TargetBandwidth / cpi->Configuration.OutputFrameRate);
if(0)
{
FILE *sectionstats = fopen("section.stt","a");
fprintf(sectionstats,"Frame : %8d Count :%4d sq bits/mb:%8.3f BitsPerMB:%8.3f BitRate: %8d Q:%3d s:%8d buffer:%8d max:%8d \n ",
- 1 + (INT32) cpi->CurrentFrame , sectionStats.count, sectionStats.SqBitsPerMacroblock, sectionStats.BitsPerMacroblock,
cpi->Configuration.TargetBandwidth / 1024, cpi->Configuration.WorstQuality, cpi->SizeStep, cpi->BufferLevel ,cpi->MaxBufferLevel);
fclose(sectionstats);
}
}
else
// determine q to use for this section
{
double SectionErrorPerMB = sectionStats.MeanInterError * sectionStats.count;
double Pctg = SectionErrorPerMB / cpi->TotalBitsPerMB;
double DesiredSectionSize = cpi->TotalBitsLeftInClip * Pctg;
double DesiredSectionBitRate = cpi->Configuration.OutputFrameRate * DesiredSectionSize / sectionStats.count;
double target; // target bitrate
double NewQ;
double RoomForVariation=3;
double FirstPassBitRate = sectionStats.BitsPerMacroblock * actualMBS * cpi->Configuration.OutputFrameRate;
if(sectionStats.count < 2)
DesiredSectionBitRate = cpi->ActualTargetBitRate ;
if(cpi->TwoPassVBRBias)
{
DesiredSectionBitRate = cpi->ActualTargetBitRate * (100 - cpi->TwoPassVBRBias) / 100 + DesiredSectionBitRate * cpi->TwoPassVBRBias / 100 ;
}
if(DesiredSectionBitRate < cpi->ActualTargetBitRate * cpi->TwoPassVBRMinSection / 100 )
DesiredSectionBitRate = cpi->ActualTargetBitRate * cpi->TwoPassVBRMinSection /100 ;
if(DesiredSectionBitRate > (double) cpi->ActualTargetBitRate * cpi->TwoPassVBRMaxSection / 100 )
DesiredSectionBitRate = cpi->ActualTargetBitRate * cpi->TwoPassVBRMaxSection / 100 ;
// Clamp the Section Datarate between what will fill up the buffer and what will empty it to .25 of the optimal
{
double ActualPerFrameBandWidth = cpi->ActualTargetBitRate / cpi->Configuration.OutputFrameRate;
double UnusedSectionEndBufferLevel = cpi->BufferLevel + (((cpi->MaxAllowedDatarate * ActualPerFrameBandWidth) / 100) * sectionStats.count);
double QuarterOptimalBufferLevel = cpi->OptimalBufferLevel / 4.0;
double MaxBitRate = cpi->Configuration.OutputFrameRate * (UnusedSectionEndBufferLevel - QuarterOptimalBufferLevel) / (sectionStats.count + cpi->KFBoost / 16);
double MinBitRate = cpi->Configuration.OutputFrameRate * (UnusedSectionEndBufferLevel - cpi->MaxBufferLevel ) / (sectionStats.count + cpi->KFBoost / 16);
if( MaxBitRate < cpi->ActualTargetBitRate / 3)
MaxBitRate = cpi->ActualTargetBitRate / 3;
if( MinBitRate < cpi->ActualTargetBitRate / 3)
MinBitRate = cpi->ActualTargetBitRate / 3;
if(DesiredSectionBitRate > MaxBitRate)
DesiredSectionBitRate = MaxBitRate;
if(DesiredSectionBitRate < MinBitRate)
DesiredSectionBitRate = MinBitRate;
cpi->Configuration.TargetBandwidth = (INT32) DesiredSectionBitRate;
cpi->InterFrameTarget = (INT32)((cpi->Configuration.TargetBandwidth -
((cpi->KeyFrameDataTarget * cpi->Configuration.OutputFrameRate)/cpi->KeyFrameFrequency)) / cpi->Configuration.OutputFrameRate);
}
target = (double) cpi->Configuration.TargetBandwidth;
// if q is worse than we estimated for the entire clip use it ( this must be a tough section )!!
// otherwise use the one we estimated.
NewQ = (INT32) FIRSTPASS_Q - ( .5 + log(FirstPassBitRate/target) / log(1.040));
if( NewQ < cpi->CalculatedWorstQ )
{
if(NewQ < cpi->PassedInWorstQ)
NewQ = cpi->PassedInWorstQ;
cpi->Configuration.ActiveWorstQuality = (INT32) NewQ;
cpi->Configuration.WorstQuality = (INT32) NewQ;
}
else
{
cpi->Configuration.ActiveWorstQuality = cpi->CalculatedWorstQ;
cpi->Configuration.WorstQuality = cpi->CalculatedWorstQ;
}
if(0)
{
FILE *sectionstats = fopen("section.stt","a");
fprintf(sectionstats,"Frame : %8d Count :%4d sq bits/mb:%8.3f BitsPerMB:%8.3f BitRate: %8d Q:%3d s:%8d buffer:%8d max:%8d mdr %d %d \n ",
- 1 + (INT32) cpi->CurrentFrame , sectionStats.count, sectionStats.SqBitsPerMacroblock, sectionStats.BitsPerMacroblock,
cpi->Configuration.TargetBandwidth / 1024, cpi->Configuration.WorstQuality, cpi->SizeStep,cpi->BufferLevel ,
cpi->MaxBufferLevel , cpi->MaxAllowedDatarate * cpi->ActualTargetBitRate / cpi->Configuration.OutputFrameRate / 100,
cpi->ThisFrameTarget
);
fclose(sectionstats);
}
}
/*
// determine q to use for this section
double target; // target bitrate
double NewQ;
double RoomForVariation=3;
double FirstPassBitRate = sectionStats.BitsPerMacroblock * actualMBS * cpi->Configuration.OutputFrameRate;
double SectionBitsPerMB = sectionStats.BitsPerMacroblock * sectionStats.count;
double Pctg = SectionBitsPerMB / cpi->TotalBitsPerMB ;
double DesiredSectionSize = cpi->TotalBitsLeftInClip* Pctg;
double DesiredSectionBitRate = cpi->Configuration.OutputFrameRate * DesiredSectionSize / sectionStats.count;
if(cpi->TwoPassVBRBias)
{
DesiredSectionBitRate = cpi->ActualTargetBitRate * (100 - cpi->TwoPassVBRBias) / 100 + DesiredSectionBitRate * cpi->TwoPassVBRBias / 100 ;
}
// Clamp the Section Datarate between what will fill up the buffer and what will empty it to .25 of the optimal
{
double ActualPerFrameBandWidth = cpi->ActualTargetBitRate / cpi->Configuration.OutputFrameRate;
double UnusedSectionEndBufferLevel = cpi->BufferLevel + (((cpi->MaxAllowedDatarate * ActualPerFrameBandWidth) / 100) * sectionStats.count);
double QuarterOptimalBufferLevel = cpi->OptimalBufferLevel / 4.0;
double MaxBitRate = cpi->Configuration.OutputFrameRate * (UnusedSectionEndBufferLevel - QuarterOptimalBufferLevel) / (sectionStats.count + cpi->KFBoost / 16);
double MinBitRate = cpi->Configuration.OutputFrameRate * (UnusedSectionEndBufferLevel - cpi->MaxBufferLevel ) / (sectionStats.count + cpi->KFBoost / 16);
if( MaxBitRate < cpi->ActualTargetBitRate / 3)
MaxBitRate = cpi->ActualTargetBitRate / 3;
if( MinBitRate < cpi->ActualTargetBitRate / 3)
MinBitRate = cpi->ActualTargetBitRate / 3;
if(DesiredSectionBitRate > MaxBitRate)
DesiredSectionBitRate = MaxBitRate;
if(DesiredSectionBitRate < MinBitRate)
DesiredSectionBitRate = MinBitRate;
cpi->Configuration.TargetBandwidth = (INT32) DesiredSectionBitRate;
cpi->InterFrameTarget = (INT32)((cpi->Configuration.TargetBandwidth -
((cpi->KeyFrameDataTarget * cpi->Configuration.OutputFrameRate)/cpi->KeyFrameFrequency)) / cpi->Configuration.OutputFrameRate);
//cpi->PerFrameBandwidth = (cpi->Configuration.TargetBandwidth / cpi->Configuration.OutputFrameRate);
}
target = (double) cpi->Configuration.TargetBandwidth;
// if q is worse than we estimated for the entire clip use it ( this must be a tough section )!!
// otherwise use the one we estimated.
NewQ = (INT32) FIRSTPASS_Q - ( RoomForVariation + .5 + log(FirstPassBitRate/target) / log(1.040));
if( NewQ < cpi->CalculatedWorstQ )
{
if(NewQ < cpi->PassedInWorstQ)
NewQ = cpi->PassedInWorstQ;
cpi->Configuration.ActiveWorstQuality = (INT32) NewQ;
cpi->Configuration.WorstQuality = (INT32) NewQ;
}
else
{
cpi->Configuration.ActiveWorstQuality = cpi->CalculatedWorstQ;
cpi->Configuration.WorstQuality = cpi->CalculatedWorstQ;
}
if(0)
{
FILE *sectionstats = fopen("section.stt","a");
fprintf(sectionstats,"Frame : %8d Count :%4d sq bits/mb:%8.3f BitsPerMB:%8.3f BitRate: %8d Q:%3d s:%8d buffer:%8d max:%8d mdr %d %d \n ",
- 1 + (INT32) cpi->CurrentFrame , sectionStats.count, sectionStats.SqBitsPerMacroblock, sectionStats.BitsPerMacroblock,
cpi->Configuration.TargetBandwidth / 1024, cpi->Configuration.WorstQuality, cpi->SizeStep,cpi->BufferLevel ,
cpi->MaxBufferLevel , cpi->MaxAllowedDatarate * cpi->ActualTargetBitRate / cpi->Configuration.OutputFrameRate / 100,
cpi->ThisFrameTarget
);
fclose(sectionstats);
}
}
*/
}
// its not a keyframe check if its time to update our golden frame?
else if (cpi->FramesTillGfUpdateDue == 0 )
{
FIRSTPASS_STATS GfStats;
int count =0;
//double GfuMotionComplexity;
//double MaxVariance;
//int NonZeroMV;
//int NewMotion = 100 - (int) GfStats.PercentMotion;
//int ZeroMotion = (int) (GfStats.PercentMotion - GfStats.PercentNewMotion);
int IntraToInterRatio;
int GfUsage;
ZeroStats( &GfStats);
// ignore the next frame ( it will have this frame as reference no matter what)
InputStats(cpi->fs,&nextFrame);
// check next frames
for(i = 0 ;i < 4 ; i++)
{
InputStats(cpi->fs,&nextFrame);
AccumulateStats(&GfStats, &nextFrame);
if(nextFrame.isGolden)
{
// throwout the next frame after this one
InputStats(cpi->fs,&lastFrame);
}
}
AvgStats(&GfStats);
// + 300 to stop tiny frames from producing huge boosts)
IntraToInterRatio = (int) (100 * GfStats.MeanIntraError / (GfStats.MeanInterError ));
IntraToInterRatio = (int) (IntraToInterRatio * GfStats.PercentNewMotion / 100);
GfUsage = (int) (GfStats.PercentGolden * 8);
cpi->GfuBoost = IntraToInterRatio;
// Correct boost to take account of recent observed level of GF usage
if ( (GfUsage >> 3) < 64)
cpi->GfuBoost = (cpi->GfuBoost * GfUsageCorrection[(GfUsage >> 3)]) / 16;
else
cpi->GfuBoost = (cpi->GfuBoost * GfUsageCorrection[63]) / 16;
cpi->GfuBoost = cpi->GfuBoost* GfuDataRateBoost[cpi->pb.AvgFrameQIndex] / 1000;
// Should we even consider a GF update or is there no point
if ( ( GfStats.PercentNewMotion > GF_MODE_DIST_THRESH2) &&
(GfStats.MotionSpeed <= MAX_GF_UPDATE_MOTION) //&&
//(cpi->GfuBoost > 80 ) &&
//(MaxVariance <= GF_MAX_VAR_THRESH)
)
{
cpi->ThisFrameTarget = (cpi->InterFrameTarget * (100 * cpi->GfUpdateInterval)) /
((100 * cpi->GfUpdateInterval) + cpi->GfuBoost);
cpi->ThisFrameTarget = cpi->ThisFrameTarget + ((cpi->ThisFrameTarget * cpi->GfuBoost) / 100);
if(cpi->FramesToKey > 3)
{
cpi->pb.RefreshGoldenFrame = TRUE;
}
// Select the interval before the next GF update
// To find the interval we find the max of AvX and AvY and work out how many frames
// it will take to move X pels (GF_UPDATE_MOTION_INTERVAL in 1/4 pel) assuming the motion
// level does not change. The value is then capped to the range MIN_GF_UPDATE_INTERVAL to MAX_GF_UPDATE_INTERVAL
if ( cpi->GfuMotionSpeed > 0 )
{
cpi->GfUpdateInterval = GF_UPDATE_MOTION_INTERVAL / cpi->GfuMotionSpeed;
if ( cpi->GfUpdateInterval < MIN_GF_UPDATE_INTERVAL )
cpi->GfUpdateInterval = MIN_GF_UPDATE_INTERVAL;
else if ( cpi->GfUpdateInterval > MAX_GF_UPDATE_INTERVAL )
cpi->GfUpdateInterval = MAX_GF_UPDATE_INTERVAL;
}
else
cpi->GfUpdateInterval = MAX_GF_UPDATE_INTERVAL;
if(0)
{
FILE *gfstats= fopen("gf.stt","a");
fprintf(gfstats,"Frame : %8d boost: %d, speed:%d,baseq:%d, intra2inter: %d, newmotion:%d, GfUsage:%d \n",
- 1 + (INT32) cpi->CurrentFrame ,
cpi->GfuBoost,
cpi->GfuMotionSpeed,
GfuDataRateBoost[cpi->pb.AvgFrameQIndex],
100 * GfStats.MeanIntraError / (GfStats.MeanInterError),
GfStats.PercentNewMotion,
GfUsage
);
fclose(gfstats);
}
}
else
{
}
fgetpos(cpi->fs,&pos2);
pos2-=pos1;
fseek(cpi->fs,(INT32) -pos2,SEEK_CUR);
}
// check if we should boost or lower this frame based on our neighbors.
else
{
}
cpi->FramesYetToEncode --;
cpi->FramesToKey --;
cpi->TotalBitsPerMB = NewBitsPerMB;
}
/****************************************************************************
*
* ROUTINE : Pass1Output
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
*
* OUTPUTS :
*
*
* RETURNS :
*
* FUNCTION : output to external file the 1st pass results
*
* SPECIAL NOTES :
*
****************************************************************************/
void CCONV Pass1Output( CP_INSTANCE *cpi)
{
PB_INSTANCE *pbi = &cpi->pb;
int actualMBS= (cpi->pb.MBRows - (BORDER_MBS*2)) * (cpi->pb.MBCols - (BORDER_MBS*2));
ClearSysState();
cpi->fps.MeanInterError = 1.0 * cpi->InterErrorb / actualMBS;
cpi->fps.MeanIntraError = 1.0 * cpi->IntraError / actualMBS;
cpi->fps.isKey = pbi->FrameType == BASE_FRAME;
cpi->fps.isGolden = pbi->RefreshGoldenFrame;
cpi->fps.PSNR = 60;
cpi->fps.BitsPerMacroblock = 1.0 * cpi->ThisFrameSize / actualMBS;
cpi->fps.SqBitsPerMacroblock = cpi->fps.BitsPerMacroblock*cpi->fps.BitsPerMacroblock;
cpi->fps.QValue = cpi->pb.quantizer->FrameQIndex;
cpi->fps.MeanInterError ;
cpi->fps.MeanIntraError ;
cpi->fps.frame = (UINT32) (cpi->CurrentFrame-1);
AccumulateStats( &cpi->fpmss, &cpi->fps);
OutputStats(cpi->fs,&cpi->fps);
}
@@ -0,0 +1,29 @@
/****************************************************************************
*
* Module Title : twopass.h
*
* Description : Functions for handling twopass dataratecontrol
*
****************************************************************************/
#ifndef __INC_TWOPASS_H
#define __INC_TWOPASS_H
#ifndef STRICT
#define STRICT /* Strict type checking */
#endif
/****************************************************************************
* Module statics
****************************************************************************/
extern void ZeroStats( FIRSTPASS_STATS *section);
extern void AccumulateStats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame);
extern void AvgStats ( FIRSTPASS_STATS *section);
extern void OutputStats( FILE *f, FIRSTPASS_STATS *stats);
extern void InputStats( FILE *f, FIRSTPASS_STATS *stats);
extern void CCONV Pass2Initialize ( CP_INSTANCE *cpi, COMP_CONFIG_VP6 *CompConfig );
extern void CCONV Pass2Control( CP_INSTANCE *cpi);
extern void CCONV Pass1Output( CP_INSTANCE *cpi);
#endif
@@ -0,0 +1,87 @@
/****************************************************************************
*
* Module Title : VFW_COMP_MAIN.c
*
* Description : Main for video codec demo compression dll
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#define INC_WIN_HEADER 1
#include <windows.h>
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Module statics.
*****************************************************************************
*/
unsigned long cProcessesAttached = 0;
HINSTANCE hInstance; /* Application instance handle. */
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Imports
*****************************************************************************
*/
extern void VPEInitLibrary(void);
extern void VPEDeInitLibrary(void);
BOOL WINAPI DllMain(HANDLE hInst, DWORD fdwReason, LPVOID lpReserved)
{
if ( fdwReason == DLL_PROCESS_ATTACH )
{
hInstance = hInst;
if ( cProcessesAttached++ )
{
return(TRUE); // Not the first initialization.
}
else
{
// initialize all the global variables in the dll
VPEInitLibrary();
return TRUE;
}
}
else if ( fdwReason == DLL_PROCESS_DETACH )
{
if (--cProcessesAttached)
{
return TRUE;
}
else
{
VPEDeInitLibrary();
return TRUE;
}
}
else
return FALSE;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
LIBRARY vp31e
EXPORTS
StartEncoder
ChangeCompressorSetting
ChangeEncoderConfig
EncodeFrame
EncodeFrameYuv
StopEncoder
StartDecoder
SetPbParam
GetYUVConfig
DecodeFrame
DecodeFrameToYUV
DrawFrame
StopDecoder
wilkDXrefCreate
wilkDXrefDestroy
wilkDXrefKeyFrame
wilkDXrefInterFrame
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,371 @@
;
; **-MmxEncodeMath.asm
;
; MMX versions of SUB8, SUB8_AV2, SUB8 with fixed subtract of 128
;
;******************************************************************
; Revision History
;
; 1.01 JBB 23-Mar-01 Fixed frame updating for preprocessor
; 1.00 YWX dd-mmm-yy Configuration baseline from Jong Chen's code
;
;******************************************************************
.586
.387
.MODEL flat, SYSCALL, os_dos
.MMX
; macros
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
; local constants go here
OneTwentyEight QWORD 00080008000800080h
@CurSeg ENDS
;
; external variables
;
; external variables go here
; structures
SUB8Params STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
FiltPtr dd ?
ReconPtr dd ?
DctInputPtr dd ?
old_ptr1 dd ?
new_ptr1 dd ?
PixelsPerLine dd ?
ReconPixelsPerLine dd ?
SUB8Params ENDS
SUB8_128Params STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
FiltPtr2 dd ?
DctInputPtr2 dd ?
old_ptr12 dd ?
new_ptr12 dd ?
PixelsPerLine2 dd ?
SUB8_128Params ENDS
SUB8AV2Params STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
FiltPtr dd ?
ReconPtr1 dd ?
ReconPtr2 dd ?
DctInputPtr dd ?
old_ptr1 dd ?
new_ptr1 dd ?
PixelsPerLine dd ?
ReconPixelsPerLine dd ?
SUB8AV2Params ENDS
;
; macro functions
;
SUB8Calc8Bytes MACRO Index:REQ
movq mm0,[eax] ; mm0 = FiltPtr
movq mm1,[ebx] ; mm1 = ReconPtr
movq mm2,mm0 ; dup to prepare for up conversion
movq mm3,mm1 ; dup to prepare for up conversion
; convert from UINT8 to INT16
; movq mm6,[esi]
punpcklbw mm0,mm7 ; mm0 = INT16(FiltPtr)
punpcklbw mm1,mm7 ; mm1 = INT16(ReconPtr)
punpckhbw mm2,mm7 ; mm2 = INT16(FiltPtr)
punpckhbw mm3,mm7 ; mm3 = INT16(ReconPtr)
; start calculation
psubw mm0,mm1 ; mm0 = FiltPtr - ReconPtr
psubw mm2,mm3 ; mm2 = FiltPtr - ReconPtr
; Update the screen canvas in one step
;memcpy( old_ptr1, new_ptr1, BLOCK_HEIGHT_WIDTH );
; movq [edx],mm6
; add edx,edi
; add esi,edi
movq [ecx+Index],mm0 ; write answer out
movq [ecx+Index+8],mm2 ; write answer out
; Increment pointers
add eax,edi
add ebx,ebp
ENDM
;
; **-SUB8_128Calc8Bytes
;
SUB8_128Calc8Bytes MACRO Index:REQ
movq mm0,[eax] ; mm0 = FiltPtr
movq mm2,mm0 ; dup to prepare for up conversion
; convert from UINT8 to INT16
; movq mm6,[esi]
punpcklbw mm0,mm7 ; mm0 = INT16(FiltPtr)
punpckhbw mm2,mm7 ; mm2 = INT16(FiltPtr)
; start calculation
psubw mm0,mm1 ; mm0 = FiltPtr - 128
psubw mm2,mm1 ; mm2 = FiltPtr - 128
; Update the screen canvas in one step
;memcpy( old_ptr1, new_ptr1, BLOCK_HEIGHT_WIDTH );
; movq [edx],mm6
; add edx,edi
; add esi,edi
movq [ecx+Index],mm0 ; write answer out
movq [ecx+Index+8],mm2 ; write answer out
; Increment pointers
add eax,edi
ENDM
;
; **-SUB8AV2Calc8Bytes
;
SUB8AV2Calc8Bytes MACRO Index:REQ
movq mm0,[eax] ; mm0 = FiltPtr
movq mm1,[ebx] ; mm1 = ReconPtr1
movq mm4,[ebp] ; mm4 = ReconPtr2
movq mm2,mm0 ; dup to prepare for up conversion
movq mm3,mm1 ; dup to prepare for up conversion
movq mm5,mm4 ; dup to prepere for up conversion
; convert from UINT8 to INT16
; movq mm6,[esi]
punpcklbw mm0,mm7 ; mm0 = INT16(FiltPtr)
punpcklbw mm1,mm7 ; mm1 = INT16(ReconPtr1)
punpcklbw mm4,mm7 ; mm4 = INT16(ReconPtr2)
punpckhbw mm2,mm7 ; mm2 = INT16(FiltPtr)
punpckhbw mm3,mm7 ; mm3 = INT16(ReconPtr1)
punpckhbw mm5,mm7 ; mm5 = INT16(ReconPtr2)
; average ReconPtr1 and ReconPtr2
paddw mm1,mm4 ; mm1 = ReconPtr1 + ReconPtr2
paddw mm3,mm5 ; mm3 = ReconPtr1 + ReconPtr2
psrlw mm1,1 ; mm1 = (ReconPtr1 + ReconPtr2) / 2
psrlw mm3,1 ; mm3 = (ReconPtr1 + ReconPtr2) / 2
psubw mm0,mm1 ; mm0 = FiltPtr - ((ReconPtr1 + ReconPtr2) / 2)
psubw mm2,mm3 ; mm2 = FiltPtr - ((ReconPtr1 + ReconPtr2) / 2)
; Update the screen canvas in one step
;memcpy( old_ptr1, new_ptr1, BLOCK_HEIGHT_WIDTH );
; movq [edx],mm6
; add edx,edi
; add esi,edi
movq [ecx+Index],mm0 ; write answer out
movq [ecx+Index+8],mm2 ; write answer out
; Increment pointers
add eax,edi
add ebx,(SUB8AV2Params PTR [esp]).ReconPixelsPerLine
add ebp,(SUB8AV2Params PTR [esp]).ReconPixelsPerLine
ENDM
;------------------------------------------------
; local vars
LOCAL_SPACE EQU 0
;
; **-MmxSUB8
;
; Input:
; FiltPtr
; ReconPtr
; DctInputPtr
; old_ptr1
; new_ptr1
;
; Output:
;
;------------------------------------------------
; void MmxSUB8( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
; INT32 PixelsPerLine, INT32 ReconPixelsPerLine )
;
.CODE
NAME MmxSUB8
PUBLIC MmxSUB8_
PUBLIC _MmxSUB8
MmxSUB8_:
_MmxSUB8:
push ecx
push ebx
push edx
push esi
push edi
push ebp
mov eax,(SUB8Params PTR [esp]).FiltPtr
mov ebx,(SUB8Params PTR [esp]).ReconPtr
mov ecx,(SUB8Params PTR [esp]).DctInputPtr
; mov edx,(SUB8Params PTR [esp]).old_ptr1
; mov esi,(SUB8Params PTR [esp]).new_ptr1
mov edi,(SUB8Params PTR [esp]).PixelsPerLine
mov ebp,(SUB8Params PTR [esp]).ReconPixelsPerLine
pxor mm7,mm7 ; clear mm7 for up precision conversion
LoopCtr = 0
WHILE LoopCtr LT 128
SUB8Calc8Bytes <LoopCtr>
LoopCtr = LoopCtr + 16
ENDM
theExit1:
pop ebp
pop edi
pop esi
pop edx
pop ebx
pop ecx
ret
;
; **-MmxSUB8_128
;
; Input:
; FiltPtr
; ReconPtr
; DctInputPtr
; old_ptr1
; new_ptr1
;
; Output:
;
;------------------------------------------------
; void MmxSUB8_128( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
; INT32 PixelsPerLine )
;
.CODE
NAME MmxSUB8_128
PUBLIC MmxSUB8_128_
PUBLIC _MmxSUB8_128
MmxSUB8_128_:
_MmxSUB8_128:
push ecx
push ebx
push edx
push esi
push edi
push ebp
mov eax,(SUB8_128Params PTR [esp]).FiltPtr2
mov ecx,(SUB8_128Params PTR [esp]).DctInputPtr2
; mov edx,(SUB8_128Params PTR [esp]).old_ptr12
; mov esi,(SUB8_128Params PTR [esp]).new_ptr12
mov edi,(SUB8_128Params PTR [esp]).PixelsPerLine2
movq mm1,OneTwentyEight ; load value to subtract with
pxor mm7,mm7 ; clear mm7 for up precision conversion
LoopCtr = 0
WHILE LoopCtr LT 128
SUB8_128Calc8Bytes <LoopCtr>
LoopCtr = LoopCtr + 16
ENDM
theExit3:
pop ebp
pop edi
pop esi
pop edx
pop ebx
pop ecx
ret
;
; **-MmxSUB8AV2
;
; Input:
; FiltPtr
; ReconPtr
; DctInputPtr
; old_ptr1
; new_ptr1
;
; Output:
;
;------------------------------------------------
; void MmxSUB8AV2( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr1, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1,
; INT32 PixelsPerLine, INT32 ReconPixelsPerLine )
;
.CODE
NAME MmxSUB8AV2
PUBLIC MmxSUB8AV2_
PUBLIC _MmxSUB8AV2
MmxSUB8AV2_:
_MmxSUB8AV2:
push ecx
push ebx
push edx
push esi
push edi
push ebp
mov eax,(SUB8AV2Params PTR [esp]).FiltPtr
mov ebx,(SUB8AV2Params PTR [esp]).ReconPtr1
mov ecx,(SUB8AV2Params PTR [esp]).DctInputPtr
; mov edx,(SUB8AV2Params PTR [esp]).old_ptr1
; mov esi,(SUB8AV2Params PTR [esp]).new_ptr1
mov edi,(SUB8AV2Params PTR [esp]).PixelsPerLine
mov ebp,(SUB8AV2Params PTR [esp]).ReconPtr2
pxor mm7,mm7 ; clear mm7 for up precision conversion
LoopCtr = 0
WHILE LoopCtr LT 128
SUB8AV2Calc8Bytes <LoopCtr>
LoopCtr = LoopCtr + 16
ENDM
theExit2:
pop ebp
pop edi
pop esi
pop edx
pop ebx
pop ecx
ret
;************************************************
END
@@ -0,0 +1,255 @@
/****************************************************************************
*
* Module Title : WmtTransform.c
*
* Description : Subtraction functions.
*
***************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <stdio.h>
#include "compdll.h"
/****************************************************************************
* Macros
****************************************************************************/
#ifdef _MSC_VER
#pragma warning(disable:4799)
#pragma warning(disable:4731)
#endif
/****************************************************************************
* Module Statics
****************************************************************************/
_declspec(align(16)) static UINT16 Eight128s[8] = { 128, 128, 128, 128, 128, 128, 128, 128 };
/****************************************************************************
*
* ROUTINE : WmtSUB8
*
* INPUTS : UINT8 *FiltPtr :
* UINT8 *ReconPtr :
* INT16 *DctInputPtr :
* UINT8 *old_ptr1 :
* UINT8 *new_ptr1 :
* INT32 SourceStride :
* INT32 ReconStride :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Subtracts 2 8x8 blocks.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void WmtSUB8
(
UINT8 *FiltPtr,
UINT8 *ReconPtr,
INT16 *DctInputPtr,
UINT8 *old_ptr1,
UINT8 *new_ptr1,
INT32 SourceStride,
INT32 ReconStride
)
{
(void) old_ptr1;
(void) new_ptr1;
_asm
{
mov eax, [FiltPtr]
mov ebx, [ReconPtr]
mov ecx, [DctInputPtr]
mov edi, [SourceStride]
mov esi, [ReconStride]
pxor xmm7, xmm7
lea edx, [ecx+128]
WmtSub8Loop:
movq xmm0, QWORD ptr [eax]
movq xmm1, QWORD ptr [ebx]
punpcklbw xmm0, xmm7
punpcklbw xmm1, xmm7
psubw xmm0, xmm1
lea ecx, [ecx+16]
cmp ecx, edx
lea eax, [eax+edi]
movdqa [ecx-16], xmm0
lea ebx, [ebx+esi]
jc WmtSub8Loop
}
}
/****************************************************************************
*
* ROUTINE : Sub8_128
*
* INPUTS : UINT8 *FiltPtr :
* INT16 *DctInputPtr :
* UINT8 *old_ptr1 :
* UINT8 *new_ptr1 :
* INT32 SourceStride :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Subtracts 128 from each pixel in an 8x8 block.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void WmtSUB8_128
(
UINT8 *FiltPtr,
INT16 *DctInputPtr,
UINT8 *old_ptr1,
UINT8 *new_ptr1,
INT32 SourceStride
)
{
(void) old_ptr1;
(void) new_ptr1;
_asm
{
mov eax, [FiltPtr]
mov edx, [DctInputPtr]
mov ecx, [SourceStride]
lea edi, [edx + 128]
pxor xmm7, xmm7
movdqa xmm1, [Eight128s]
wmtsub8_128loop:
movq xmm0, QWORD PTR [eax]
punpcklbw xmm0, xmm7
psubw xmm0, xmm1;
lea edx, [edx+16]
cmp edx, edi
movdqa [edx-16], xmm0
lea eax, [eax+ecx]
jc wmtsub8_128loop
}
}
/****************************************************************************
*
* ROUTINE : Sub8AV2
*
* INPUTS :
*
*
* OUTPUTS :
*
* RETURNS : None.
*
* FUNCTION : Subtracts 2 8x8 blocks
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
/****************************************************************************
*
* ROUTINE : WmtSUB8AV2
*
* INPUTS : UINT8 *FiltPtr :
* UINT8 *ReconPtr1 :
* UINT8 *ReconPtr2 :
* INT16 *DctInputPtr :
* UINT8 *old_ptr1 :
* UINT8 *new_ptr1 :
* INT32 SourceStride :
* INT32 ReconStride :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Subtracts 2 8x8 blocks.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void WmtSUB8AV2
(
UINT8 *FiltPtr,
UINT8 *ReconPtr1,
UINT8 *ReconPtr2,
INT16 *DctInputPtr,
UINT8 *old_ptr1,
UINT8 *new_ptr1,
INT32 SourceStride,
INT32 ReconStride
)
{
(void) old_ptr1;
(void) new_ptr1;
_asm
{
push ebp
mov esi, [FiltPtr]
mov edi, [DctInputPtr]
mov eax, [ReconPtr1]
mov ebx, [ReconPtr2]
mov ecx, [SourceStride]
mov edx, [ReconStride]
lea ebp, [edi+128]
pxor xmm7, xmm7
WmtSUB8AV2loop:
movq xmm0, QWORD PTR [eax]
movq xmm1, QWORD PTR [ebx]
punpcklbw xmm0, xmm7
punpcklbw xmm1, xmm7
paddw xmm0, xmm1
movq xmm2, QWORD PTR [esi]
psraw xmm0, 1
psubw xmm2, xmm0
lea edi, [edi+16]
cmp edi, ebp
movdqa [edi-16], xmm2
lea eax, [eax+edx]
lea ebx, [ebx+edx]
lea esi, [ecx+esi]
jc WmtSUB8AV2loop
pop ebp
}
}
@@ -0,0 +1,308 @@
; structures
XmmGetErrorParams STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
NewDataPtr dd ?
PixelsPerLine dd ?
ReconPtr1 dd ?
ReconPixelsPerLine dd ?
XSum dd ?
XXSum dd ?
XmmGetErrorParams ENDS
.686P
.387
.MODEL flat, SYSCALL, os_dos
.XMM
; macros
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
.CODE
NAME XmmGetError
PUBLIC XmmGetError_
PUBLIC _XmmGetError
;------------------------------------------------
; local vars
LOCAL_SPACE EQU 0
;------------------------------------------------
; XmmGetError(UINT8* NewDataPtr,
; UINT32 PixelsPerLine,
; UINT8* RefDataPtr1,
; UINT32 RefPixelsPerLine,
; INT32* XSum,
; INT32* XXSum)
XmmGetError_:
_XmmGetError:
push ecx
push ebx
push edx
push esi
mov ecx,(XmmGetErrorParams PTR [esp-8]).PixelsPerLine
mov eax,(XmmGetErrorParams PTR [esp-8]).NewDataPtr
push edi
mov ebx,(XmmGetErrorParams PTR [esp-4]).ReconPtr1
mov edx,(XmmGetErrorParams PTR [esp-4]).ReconPixelsPerLine
push ebp
mov esi,(XmmGetErrorParams PTR [esp]).XSum
mov edi,(XmmGetErrorParams PTR [esp]).XXSum
prefetcht0 [eax+ecx]
prefetcht0 [ebx+edx]
pxor mm5, mm5 ; Blank mmx6
pxor mm6, mm6 ; Blank mmx7
;Row 1
movq mm1, [ebx] ; Copy eight bytes to mm1
movq mm0, [eax] ; Copy eight bytes to mm0
pxor mm7, mm7 ; Blank mmx7
prefetcht0 [eax+ecx*2]
prefetcht0 [ebx+edx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx*2]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 2
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx*2]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 3
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx*2]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 4
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx*2]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 5
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx, edx ; Inc pointer into ref data
add eax, ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx*2]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 6
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx*2]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
prefetcht0 [ebx+edx]
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 7
movq mm0, [eax] ; Copy eight bytes to mm0
prefetcht0 [eax+ecx]
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
add ebx,edx ; Inc pointer into ref data
add eax,ecx ; Inc pointer into the new data
movq mm1, [ebx] ; Copy eight bytes to mm1
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Row 8
movq mm0, [eax] ; Copy eight bytes to mm0
movq mm2, mm0 ; Take copies
movq mm3, mm1 ; Take copies
punpcklbw mm0, mm6 ; unpack to higher precision
punpcklbw mm1, mm6
punpckhbw mm2, mm6 ; unpack to higher precision
punpckhbw mm3, mm6
psubsw mm0, mm1 ; A-B (low order) to MM0
psubsw mm2, mm3 ; A-B (high order) to MM2
paddw mm5, mm0 ; accumulate differences in mm5
paddw mm5, mm2 ; accumulate differences in mm5
pmaddwd mm0, mm0 ; square and accumulate
pmaddwd mm2, mm2 ; square and accumulate
paddd mm7, mm0 ; accumulate in mm7
paddd mm7, mm2 ; accumulate in mm7
; Now accumulate the final results.
movq mm4, mm5 ;
punpcklwd mm5, mm6
punpckhwd mm4, mm6
movq mm0, mm7
paddw mm5, mm4
punpckhdq mm0, mm6
punpckldq mm7, mm6
movq mm4, mm5
paddd mm0, mm7
punpckhdq mm4, mm6
punpckldq mm5, mm6
movd eax, mm0
paddw mm4, mm5
movd ebp, mm4
movsx ebx, bp;
pop ebp
mov DWORD PTR [edi], eax ;XXSum
mov DWORD PTR [esi], ebx; ;XSum
pop edi
emms ; Clear the MMX state.
pop esi
pop edx
pop ebx
pop ecx
ret
;------------------------------------------------------------------------
END
@@ -0,0 +1,153 @@
;------------------------------------------------
XmmGetSAD8Params STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
NewDataPtr dd ?
RefDataPtr dd ?
OffsetN dd ?
OffsetR dd ?
XmmGetSAD8Params ENDS
;------------------------------------------------
.686P
.387
.MODEL flat, SYSCALL, os_dos
.XMM
; macros
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
.CODE
NAME XmmGetSAD8
PUBLIC XmmGetSAD8_
PUBLIC _XmmGetSAD8
;------------------------------------------------
; local vars
LOCAL_SPACE EQU 0
;------------------------------------------------
;INT32 XmmGetSAD8( UINT8 * NewDataPtr, UINT8 * RefDataPtr,
; INT32 OffsetN, INT32 OffsetR)
;
XmmGetSAD8_:
_XmmGetSAD8:
push ecx
push ebx
push edx
push esi
mov ecx,(XmmGetSAD8Params PTR [esp-8]).OffsetN
mov eax,(XmmGetSAD8Params PTR [esp-8]).NewDataPtr ; Load base addresses
push edi
mov ebx,(XmmGetSAD8Params PTR [esp-4]).RefDataPtr
mov edx,(XmmGetSAD8Params PTR [esp-4]).OffsetR
push ebp
;
; ESP = Stack Pointer MM0 = Free
; ESI = Free MM1 = Free
; EDI = Free MM2 = Free
; EBP = Free MM3 = Free
; EBX = RefDataPtr MM4 = Free
; ECX = OffsetN MM5 = Free
; EDX = OffsetR MM6 = Free
; EAX = NewDataPtr MM7 = Free
;
; Row 1
movq mm0, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm0, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 2
movq mm1, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm1, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 3
movq mm2, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm2, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 4
movq mm3, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm3, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 5
movq mm4, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm4, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 6
movq mm5, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm5, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 7
movq mm6, [eax] ; Copy eight bytes to mm0
add eax,ecx ; Inc pointer into the new data
psadbw mm6, [ebx]
add ebx,edx ; Inc pointer into ref data
; Row 8
movq mm7, [eax] ; Copy eight bytes to mm0
psadbw mm7, [ebx]
; start accumulating differences
paddd mm0,mm1
paddd mm2,mm3
pop ebp
paddd mm4,mm5
paddd mm6,mm7
pop edi
paddd mm0,mm2
paddd mm4,mm6
pop esi
paddd mm0,mm4
movd ecx,mm0
theExit:
pop edx
mov eax, ecx ; add in calculated error
pop ebx
pop ecx
ret
;************************************************
END
@@ -0,0 +1,12 @@
;------------------------------------------------
XMMGetSADParams STRUC
dd 6 dup (?) ;6 pushed regs
dd ? ;return address
NewDataPtr dd ?
PixelsPerLine dd ?
RefDataPtr dd ?
RefPixelsPerLine dd ?
ErrorSoFar dd ?
BestSoFar dd ?
XMMGetSADParams ENDS
;------------------------------------------------
@@ -0,0 +1,141 @@
.686P
.387
.MODEL flat, SYSCALL, os_dos
.XMM
; macros
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
.CODE
NAME XmmGetSAD
PUBLIC XMMGetSAD_
PUBLIC _XMMGetSAD
INCLUDE XmmSAD.ash
;------------------------------------------------
; local vars
LOCAL_SPACE EQU 0
;------------------------------------------------
;INT32 XMMGetSAD( UINT8 * NewDataPtr, INT32 PixelsPerLine,
; UINT8 * RefDataPtr, INT32 RefPixelsPerLine,
; INT32 ErrorSoFar, INT32 BestSoFar )
;
XMMGetSAD_:
_XMMGetSAD:
push ecx
push ebx
push edx
push esi
push edi
push ebp
mov ecx, (XMMGetSADParams PTR [esp]).PixelsPerLine
mov eax, (XMMGetSADParams PTR [esp]).NewDataPtr
mov ebx, (XMMGetSADParams PTR [esp]).RefDataPtr
movq mm0, [eax] ; Copy eight bytes to mm0
;
; ESP = Stack Pointer MM0 = Free
; ESI = Free MM1 = Free
; EDI = Free MM2 = Free
; EBP = Free MM3 = Free
; EBX = RefDataPtr MM4 = Free
; ECX = PixelsPerLine MM5 = Free
; EDX = RefPixelsPerLine MM6 = Free
; EAX = NewDataPtr MM7 = Free
; Row 1
mov edx, (XMMGetSADParams PTR [esp]).RefPixelsPerLine
lea esi, [eax+2*ecx]; ; Calculate the source ptr for row4
psadbw mm0, [ebx]
; Row 2
movq mm1, [eax+ecx] ; Copy eight bytes to mm1
lea edi, [ebx+2*edx] ; Calculate the source ptr for row4
psadbw mm1, [ebx+edx]
; Row 3
movq mm2, [eax+2*ecx] ; Copy eight bytes to mm2
add esi, ecx; ; Calculate the source ptr for row4
psadbw mm2, [ebx+2*edx]
add edi, edx; ; Calculate the source ptr for row4
; Row 4
movq mm3, [esi] ; Copy eight bytes to mm3
psadbw mm3, [edi]
; Row 5
movq mm4, [eax+4*ecx] ; Copy eight bytes to mm4
paddd mm0,mm1
psadbw mm4, [ebx+4*edx]
; Row 6
movq mm5, [esi+2*ecx] ; Copy eight bytes to mm5
lea eax, [esi+2*ecx]
psadbw mm5, [edi+2*edx]
lea ebx, [edi+2*edx]
; Row 7
movq mm6, [eax+ecx] ; Copy eight bytes to mm0
psadbw mm6, [ebx+edx]
paddd mm2,mm3
; Row 8
movq mm7, [esi+4*ecx] ; Copy eight bytes to mm0
psadbw mm7, [edi+4*edx]
; start accumulating differences
mov eax, (XMMGetSADParams PTR [esp]).ErrorSoFar
pop ebp
paddd mm4,mm5
paddd mm6,mm7
pop edi
paddd mm0,mm2
paddd mm4,mm6
pop esi
paddd mm0,mm4
movd ecx,mm0
theExit:
pop edx
add eax,ecx ; add in calculated error
pop ebx
pop ecx
ret
;************************************************
END
@@ -0,0 +1,181 @@
/****************************************************************************
*
* Module Title : SystemDependant.c
*
* Description : Miscellaneous system dependant functions.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "compdll.h"
/****************************************************************************
* Macros
****************************************************************************/
#define MMX_ENABLED 1
/****************************************************************************
* Imports
****************************************************************************/
// Functions that should only be used in assembly versions of the code
extern unsigned long VP6_GetProcessorFrequency();
extern void GetProcessorFlags(INT32 *MmxEnabled, INT32 *XmmEnabled, INT32 *WmtEnabled);
extern UINT32 ComputeBlockReconError ( CP_INSTANCE *cpi, UINT32 bp );
extern UINT32 GetSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 GetHalfPixelSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,UINT8 * RefPtr2,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 WmtGetSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 WmtGetHalfPixelSumAbsDiffs16(UINT8 * SrcPtr,INT32 SourceStride,UINT8 * RefPtr,UINT8 * RefPtr2,INT32 ReconStride,UINT32 ErrorSoFar,UINT32 BestSoFar);
extern UINT32 GetIntraErrorC( UINT8* DataPtr, INT32 SourceStride);
extern UINT32 GetInterErr( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride );
extern UINT32 GetSumAbsDiffs( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 GetHalfPixelSumAbsDiffs( UINT8 * SrcData, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 MmxGetSAD( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 MmxGetHalfPixelSAD( UINT8 * SrcData, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 MmxGetInterErr( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride );
extern UINT32 MmxGetIntraError( UINT8* DataPtr, INT32 SourceStride);
extern void MmxSUB8( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconSourceStride );
extern void MmxSUB8_128( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride );
extern void MmxSUB8AV2( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr2, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconSourceStride );
extern UINT32 WmtComputeBlockReconError ( CP_INSTANCE *cpi, UINT32 bp );
extern void WmtSUB8( UINT8 *FiltPtr, UINT8 *ReconPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconSourceStride );
extern void WmtSUB8_128( UINT8 *FiltPtr, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride );
extern void WmtSUB8AV2( UINT8 *FiltPtr, UINT8 *ReconPtr1, UINT8 *ReconPtr2, INT16 *DctInputPtr, UINT8 *old_ptr1, UINT8 *new_ptr1, INT32 SourceStride, INT32 ReconSourceStride );
extern UINT32 XmmGetInterErr( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride );
extern UINT32 XMMGetSAD( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 WmtGetIntraError( UINT8* DataPtr, INT32 SourceStride);
extern UINT32 WmtGetHalfPixelSAD( UINT8 * SrcData, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride, UINT32 ErrorSoFar, UINT32 BestSoFar );
extern UINT32 WmtGetInterErr( UINT8 * NewDataPtr, INT32 SourceStride, UINT8 * RefDataPtr1, UINT8 * RefDataPtr2, INT32 RefStride );
extern void VP6_quantize_c( QUANTIZER *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
extern void VP6_quantize_wmt( QUANTIZER *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
extern void VP6_quantize_mmx( QUANTIZER *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
extern UINT32 GetMBFrameVerticalVariance( CP_INSTANCE *cpi);
extern UINT32 MmxGetMBFrameVertVar( CP_INSTANCE *cpi);
extern UINT32 WmtGetMBFrameVertVar( CP_INSTANCE *cpi);
extern UINT32 GetMBFieldVerticalVariance( CP_INSTANCE *cpi);
extern UINT32 MmxGetMBFieldVertVar( CP_INSTANCE *cpi);
extern UINT32 WmtGetMBFieldVertVar( CP_INSTANCE *cpi);
extern UINT32 FiltBlockBilGetSad_C(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
extern UINT32 FiltBlockBilGetSad_mmx(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
extern UINT32 FiltBlockBilGetSad_wmt(UINT8 *SrcPtr,INT32 SrcStride,UINT8 *ReconPtr1,UINT8 *ReconPtr2,INT32 PixelsPerLine,INT32 ModX, INT32 ModY,UINT32 BestSoFar);
/****************************************************************************
*
* ROUTINE : MachineSpecificConfig
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Checks for machine specifc features such as MMX support
* sets appropriate flags and function pointers.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CMachineSpecificConfig( void )
{
INT32 MmxEnabled;
INT32 XmmEnabled;
INT32 WmtEnabled;
GetProcessorFlags( &MmxEnabled, &XmmEnabled, &WmtEnabled);
GetSAD = GetSumAbsDiffs;
GetSadHalfPixel = GetHalfPixelSumAbsDiffs;
GetInterError = GetInterErr;
if( WmtEnabled )
{
GetSAD16 = WmtGetSumAbsDiffs16;
GetSadHalfPixel16 = WmtGetHalfPixelSumAbsDiffs16;
GetSAD = XMMGetSAD;
GetSadHalfPixel = WmtGetHalfPixelSAD;
GetInterError = WmtGetInterErr;
GetIntraError = WmtGetIntraError;
Sub8 = WmtSUB8;
Sub8_128 = WmtSUB8_128;
Sub8Av2 = WmtSUB8AV2;
VP6_quantize = VP6_quantize_wmt;
GetMBFrameVertVar = WmtGetMBFrameVertVar;
GetMBFieldVertVar = WmtGetMBFieldVertVar;
FiltBlockBilGetSad = FiltBlockBilGetSad_wmt;
GetBlockReconErr = WmtComputeBlockReconError;
}
else if ( XmmEnabled )
{
GetSAD16 = GetSumAbsDiffs16;
GetSadHalfPixel16 = GetHalfPixelSumAbsDiffs16;
GetSAD = XMMGetSAD;
GetSadHalfPixel = MmxGetHalfPixelSAD;
GetInterError = MmxGetInterErr;
GetIntraError = MmxGetIntraError;
Sub8 = MmxSUB8;
Sub8_128 = MmxSUB8_128;
Sub8Av2 = MmxSUB8AV2;
VP6_quantize = VP6_quantize_mmx;
GetMBFrameVertVar = MmxGetMBFrameVertVar;
GetMBFieldVertVar = MmxGetMBFieldVertVar;
FiltBlockBilGetSad = FiltBlockBilGetSad_mmx;
GetBlockReconErr = ComputeBlockReconError;
}
else if ( MmxEnabled )
{
GetSAD16 = GetSumAbsDiffs16;
GetSadHalfPixel16 = GetHalfPixelSumAbsDiffs16;
GetSAD = MmxGetSAD;
GetSadHalfPixel = MmxGetHalfPixelSAD;
GetInterError = MmxGetInterErr;
GetIntraError = MmxGetIntraError;
Sub8 = MmxSUB8;
Sub8_128 = MmxSUB8_128;
Sub8Av2 = MmxSUB8AV2;
VP6_quantize = VP6_quantize_mmx;
GetMBFrameVertVar = MmxGetMBFrameVertVar;
GetMBFieldVertVar = MmxGetMBFieldVertVar;
FiltBlockBilGetSad = FiltBlockBilGetSad_mmx;
GetBlockReconErr = ComputeBlockReconError;
}
else
{
GetSAD16 = GetSumAbsDiffs16;
GetSadHalfPixel16 = GetHalfPixelSumAbsDiffs16;
GetSAD = GetSumAbsDiffs;
GetSadHalfPixel = GetHalfPixelSumAbsDiffs;
GetInterError = GetInterErr;
GetIntraError = GetIntraErrorC;
fdct_short = fdct_short_C;
VP6_quantize = VP6_quantize_c;
Sub8 = SUB8;
Sub8_128 = SUB8_128;
Sub8Av2 = SUB8AV2;
GetMBFrameVertVar = GetMBFrameVerticalVariance;
GetMBFieldVertVar = GetMBFieldVerticalVariance;
FiltBlockBilGetSad = FiltBlockBilGetSad_C;
GetBlockReconErr = ComputeBlockReconError;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,470 @@
/****************************************************************************
*
* Module Title : DFrameR.C
*
* Description : Functions to read from the input bitstream.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Frames
****************************************************************************/
#include "pbdll.h"
#include "postproc_if.h"
/****************************************************************************
*
* ROUTINE : VP6_bitread
*
* INPUTS : BOOL_CODER *br : Pointer to a Bool Decoder instance.
* int bits : Number of bits to be read from input stream.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: The requested bits.
*
* FUNCTION : Decodes the requested number of bits from the encoded data buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 VP6_bitread ( BOOL_CODER *br, int bits )
{
UINT32 z = 0;
int bit;
for ( bit=bits-1; bit>=0; bit-- )
{
z |= (VP6_DecodeBool128(br)<<bit);
}
return z;
}
/****************************************************************************
*
* ROUTINE : VP6_bitread1
*
* INPUTS : BOOL_CODER *br : Pointer to a Bool Decoder instance.
*
* OUTPUTS : None
*
* RETURNS : UINT32: The next decoded bit (0 or 1).
*
* FUNCTION : Decodes the next bit from the encoded data buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
INLINE
UINT32 VP6_bitread1 ( BOOL_CODER *br )
{
return (VP6_DecodeBool128(br));
}
/****************************************************************************
*
* ROUTINE : InitHeaderBuffer
*
* INPUTS : FRAME_HEADER *Header : Pointer to FRAME_HEADER data structure.
* unsigned char *Buffer : Pointer to buffer containing bitstream header.
*
* OUTPUTS : None
*
* RETURNS : void
*
*
* FUNCTION : Initialises extraction of bits from header buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void InitHeaderBuffer ( FRAME_HEADER *Header, unsigned char *Buffer )
{
Header->buffer = Buffer;
Header->value = (Buffer[0]<<24)+(Buffer[1]<<16)+(Buffer[2]<<8)+Buffer[3];
Header->bits_available = 32;
Header->pos = 4;
}
/****************************************************************************
*
* ROUTINE : ReadHeaderBits
*
* INPUTS : FRAME_HEADER *Header : Pointer to FRAME_HEADER data structure.
* UINT32 BitsRequired : Number of bits to extract.
*
* OUTPUTS : None
*
* RETURNS : UINT32: Bits requested
*
* FUNCTION : Extracts requested number of bits from header buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 ReadHeaderBits ( FRAME_HEADER *Header, UINT32 BitsRequired )
{
UINT32 pos = Header->pos;
UINT32 available = Header->bits_available;
UINT32 value = Header->value;
UINT8 *Buffer = &Header->buffer[pos];
UINT32 RetVal = 0;
if ( available < BitsRequired )
{
// Need more bits from input buffer...
RetVal = value >> (32-available);
BitsRequired -= available;
RetVal <<= BitsRequired;
value = (Buffer[0]<<24)+(Buffer[1]<<16)+(Buffer[2]<<8)+(Buffer[3]);
pos += 4;
available = 32;
}
RetVal |= value >> (32-BitsRequired);
// Update data struucture
Header->value = value<<BitsRequired;
Header->bits_available = available-BitsRequired;
Header->pos = pos;
return RetVal;
}
/****************************************************************************
*
* ROUTINE : LoadFrameHeader
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: FALSE in case of error, TRUE otherwise.
*
* FUNCTION : Loads a frame header & carries out some initialization.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
static BOOL LoadFrameHeader ( PB_INSTANCE *pbi )
{
UINT8 DctQMask;
FRAME_HEADER *Header = &pbi->Header;
BOOL RetVal = TRUE;
// Is the frame and inter frame or a key frame
pbi->FrameType = (UINT8)ReadHeaderBits(Header, 1);
// Quality (Q) index
DctQMask = (UINT8)ReadHeaderBits(Header, 6);
// Are we using two BOOL coder data streams/partitions
pbi->MultiStream = (UINT8)ReadHeaderBits(Header, 1);
// If the frame was a base frame then read the frame dimensions and build a bitmap structure.
if ( (pbi->FrameType == BASE_FRAME) )
{
// Read the frame dimensions bytes (0,0 indicates vp31 or later)
pbi->Vp3VersionNo = (UINT8)ReadHeaderBits(Header, 5 );
pbi->VpProfile = (UINT8)ReadHeaderBits(Header, 2 );
if(pbi->Vp3VersionNo > CURRENT_DECODE_VERSION)
{
RetVal = FALSE;
return RetVal;
}
// Initialise version specific quantiser values
VP6_InitQTables( pbi->quantizer, pbi->Vp3VersionNo );
// is this keyframe section of the file interlaced
pbi->Configuration.Interlaced = (UINT8)ReadHeaderBits(Header, 1);
// Start the first bool decoder (modes, mv, probs and some flags)
// The offset depends on whether or not we are using multiple bool code streams
if ( pbi->MultiStream || (pbi->VpProfile == SIMPLE_PROFILE) )
{
VP6_StartDecode(&pbi->br, ((unsigned char*)(Header->buffer + 4)));
// Read the buffer offset for the second bool decoder buffer if it is being used
pbi->Buff2Offset = (UINT32)ReadHeaderBits(Header, 16);
}
else
VP6_StartDecode(&pbi->br, ((unsigned char*)(Header->buffer + 2)));
// SCALING related stuff
SetPPInterlacedMode(pbi->postproc, pbi->Configuration.Interlaced);
if(pbi->Configuration.Interlaced)
{
SetDeInterlaceMode(pbi->postproc, pbi->DeInterlaceMode);
}
{
UINT32 HFragments;
UINT32 VFragments;
UINT32 HOldScaled;
UINT32 VOldScaled;
UINT32 HNewScaled;
UINT32 VNewScaled;
UINT32 OutputHFragments;
UINT32 OutputVFragments;
VFragments = 2 * ((UINT8)VP6_bitread( &pbi->br, 8 ));
HFragments = 2 * ((UINT8)VP6_bitread( &pbi->br, 8 ));
OutputVFragments = 2 * ((UINT8)VP6_bitread( &pbi->br, 8 ));
OutputHFragments = 2 * ((UINT8)VP6_bitread( &pbi->br, 8 ));
if(pbi->Configuration.HRatio == 0)
pbi->Configuration.HRatio = 1;
if(pbi->Configuration.VRatio == 0)
pbi->Configuration.VRatio = 1;
HOldScaled = pbi->Configuration.HScale * pbi->HFragments * 8 / pbi->Configuration.HRatio;
VOldScaled = pbi->Configuration.VScale * pbi->VFragments * 8 / pbi->Configuration.VRatio;
pbi->Configuration.ExpandedFrameWidth = OutputHFragments * 8;
pbi->Configuration.ExpandedFrameHeight = OutputVFragments * 8;
if(VFragments >= OutputVFragments)
{
pbi->Configuration.VScale = 1;
pbi->Configuration.VRatio = 1;
}
else if (5*VFragments >= 4*OutputVFragments)
{
pbi->Configuration.VScale = 5;
pbi->Configuration.VRatio = 4;
}
else if (5*VFragments >= 3*OutputVFragments)
{
pbi->Configuration.VScale = 5;
pbi->Configuration.VRatio = 3;
}
else
{
pbi->Configuration.VScale = 2;
pbi->Configuration.VRatio = 1;
}
if(HFragments >= OutputHFragments)
{
pbi->Configuration.HScale = 1;
pbi->Configuration.HRatio = 1;
}
else if (5*HFragments >= 4*OutputHFragments)
{
pbi->Configuration.HScale = 5;
pbi->Configuration.HRatio = 4;
}
else if (5*HFragments >= 3*OutputHFragments)
{
pbi->Configuration.HScale = 5;
pbi->Configuration.HRatio = 3;
}
else
{
pbi->Configuration.HScale = 2;
pbi->Configuration.HRatio = 1;
}
HNewScaled = pbi->Configuration.HScale * HFragments * 8 / pbi->Configuration.HRatio;
VNewScaled = pbi->Configuration.VScale * VFragments * 8 / pbi->Configuration.VRatio;
pbi->ScaleWidth = HNewScaled;
pbi->ScaleHeight = VNewScaled;
pbi->Configuration.ScalingMode = ((UINT32)VP6_bitread( &pbi->br, 2 ));
// we have a new input size
if( VFragments != pbi->VFragments || HFragments != pbi->HFragments )
{
// Validate the combination of height and width.
pbi->Configuration.VideoFrameWidth = HFragments*8;
pbi->Configuration.VideoFrameHeight = VFragments*8;
VP6_InitFrameDetails(pbi);
}
// we have a new intermediate buffer clean the screen
if( pbi->ScaleBuffer != 0 &&
(HOldScaled != HNewScaled || VOldScaled != VNewScaled) )
{
// turn the screen black!!
memset(pbi->ScaleBuffer, 0x0, (pbi->OutputWidth+32) * (pbi->OutputHeight+32) );
memset(pbi->ScaleBuffer + (pbi->OutputWidth+32) * (pbi->OutputHeight+32),
0x80, (pbi->OutputWidth+32) * (pbi->OutputHeight+32) / 2 );
}
}
// Unless in SIMPLE_PROFILE read the the filter strategy for fractional pels
if ( pbi->VpProfile != SIMPLE_PROFILE )
{
// Find out if selective bicubic filtering should be used for motion prediction.
if ( (BOOL)VP6_DecodeBool(&pbi->br, 128) )
{
pbi->PredictionFilterMode = AUTO_SELECT_PM;
// Read in the variance threshold to be used
pbi->PredictionFilterVarThresh = ((UINT32)VP6_bitread( &pbi->br, 5) << ((pbi->Vp3VersionNo > 7) ? 0 : 5) );
// Read the bicubic vector length limit (0 actually means ignore vector length)
pbi->PredictionFilterMvSizeThresh = (UINT8)VP6_bitread( &pbi->br, 3);
}
else
{
if ( (BOOL)VP6_DecodeBool(&pbi->br, 128) )
pbi->PredictionFilterMode = BICUBIC_ONLY_PM;
else
pbi->PredictionFilterMode = BILINEAR_ONLY_PM;
}
if ( pbi->Vp3VersionNo > 7 )
pbi->PredictionFilterAlpha = VP6_bitread( &pbi->br, 4);
else
pbi->PredictionFilterAlpha = 16; // VP61 backwards compatibility
}
}
// Non key frame sopecific stuff
else
{
// Start the first bool decoder (modes, mv, probs and some flags)
// The offset depends on whether or not we are using multiple bool code streams
if ( pbi->MultiStream || (pbi->VpProfile == SIMPLE_PROFILE) )
{
VP6_StartDecode(&pbi->br, ((unsigned char*)(Header->buffer + 3)));
// Read the buffer offset for the second bool decoder buffer if it is being used
pbi->Buff2Offset = (UINT32)ReadHeaderBits(Header, 16);
}
else
VP6_StartDecode(&pbi->br, ((unsigned char*)(Header->buffer + 1)));
// Find out if the golden frame should be refreshed this frame - use bool decoder
pbi->RefreshGoldenFrame = (BOOL)VP6_DecodeBool(&pbi->br, 128);
if ( pbi->VpProfile != SIMPLE_PROFILE )
{
// Determine if loop filtering is on and if so what type should be used
pbi->UseLoopFilter = VP6_DecodeBool(&pbi->br, 128);
if ( pbi->UseLoopFilter )
{
pbi->UseLoopFilter = (pbi->UseLoopFilter << 1) | VP6_DecodeBool(&pbi->br, 128);
}
if ( pbi->Vp3VersionNo > 7 )
{
// Are the prediction characteristics being updated this frame
if ( VP6_DecodeBool(&pbi->br, 128) )
{
// Find out if selective bicubic filtering should be used for motion prediction.
if ( (BOOL)VP6_DecodeBool(&pbi->br, 128) )
{
pbi->PredictionFilterMode = AUTO_SELECT_PM;
// Read in the variance threshold to be used
pbi->PredictionFilterVarThresh = (UINT32)VP6_bitread( &pbi->br, 5);
// Read the bicubic vector length limit (0 actually means ignore vector length)
pbi->PredictionFilterMvSizeThresh = (UINT8)VP6_bitread( &pbi->br, 3);
}
else
{
if ( (BOOL)VP6_DecodeBool(&pbi->br, 128) )
pbi->PredictionFilterMode = BICUBIC_ONLY_PM;
else
pbi->PredictionFilterMode = BILINEAR_ONLY_PM;
}
pbi->PredictionFilterAlpha = VP6_bitread( &pbi->br, 4 );
}
}
else
pbi->PredictionFilterAlpha = 16; // VP61 backwards compatibility
}
}
// All frames (Key & Inter frames)
if(pbi->Vp3VersionNo < 3 )
RetVal = FALSE;
// Should this frame use huffman for the dct data
pbi->UseHuffman = (BOOL)VP6_DecodeBool(&pbi->br, 128);
// Set this frame quality value from Q Index
pbi->quantizer->FrameQIndex = DctQMask;
VP6_UpdateQ( pbi->quantizer, pbi->Vp3VersionNo );
return RetVal;
}
/****************************************************************************
*
* ROUTINE : VP6_LoadFrame
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None
*
* RETURNS : BOOL: FALSE on error or frame empty, TRUE otherwise.
*
* FUNCTION : Loads the next frame from the encoded data buffer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
BOOL VP6_LoadFrame ( PB_INSTANCE *pbi )
{
BOOL RetVal = TRUE;
// Load the frame header (including the frame size).
if ( !LoadFrameHeader(pbi) )
RetVal = FALSE;
return RetVal;
}
/****************************************************************************
*
* ROUTINE : VP6_SetFrameType
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT8 FrType : Type of the frame.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Sets the current frame type.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_SetFrameType ( PB_INSTANCE *pbi, UINT8 FrType )
{
/* Set the appropriate frame type according to the request */
pbi->FrameType = FrType;
}
/****************************************************************************
*
* ROUTINE : VP6_GetFrameType
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : UINT8: The current frame type.
*
* FUNCTION : Gets the current frame type.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT8 VP6_GetFrameType ( PB_INSTANCE *pbi )
{
return pbi->FrameType;
}
@@ -0,0 +1,160 @@
/****************************************************************************
*
* Module Title : SystemDependant.c
*
* Description : Miscellaneous system dependant functions.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
extern void VP6_BuildQuantIndex_Generic ( QUANTIZER *pbi );
/****************************************************************************
*
* ROUTINE : VP6_SetPbParam
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
* PB_COMMAND_TYPE Command : Command action specifier.
* UINT32 *Parameter : Command dependent value.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Generalised command interface to decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV VP6_SetPbParam( PB_INSTANCE *pbi, PB_COMMAND_TYPE Command, uintptr_t Parameter )
{
#if defined(POSTPROCESS)
switch ( Command )
{
case PBC_SET_CPUFREE:
{
#if defined(_MSC_VER)
double Pixels = pbi->Configuration.VideoFrameWidth * pbi->Configuration.VideoFrameHeight;
double FreeMhz = pbi->ProcessorFrequency * Parameter / 100;
double PixelsPerMhz = 100 * sqrt(1.0*Pixels) / FreeMhz;
#else
double PixelsPerMhz = 100 *10;
#endif
pbi->CPUFree = Parameter;
if( PixelsPerMhz > 150 )
pbi->PostProcessingLevel = 0;
else if( PixelsPerMhz > 100 )
pbi->PostProcessingLevel = 8;
else if( PixelsPerMhz > 90 )
pbi->PostProcessingLevel = 4;
else if( PixelsPerMhz > 80 )
pbi->PostProcessingLevel = 5;
else
pbi->PostProcessingLevel = 6;
break;
}
case PBC_SET_ADDNOISE:
pbi->AddNoiseMode = Parameter;
//SetAddNoiseMode(pbi->postproc, Parameter);
break;
case PBC_SET_REFERENCEFRAME:
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->LastFrameRecon);
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->GoldenFrame);
break;
case PBC_SET_POSTPROC:
if( Parameter == 9 )
VP6_SetPbParam( pbi, PBC_SET_CPUFREE, 70);
else
{
pbi->CPUFree = 0;
pbi->PostProcessingLevel = Parameter;
}
break;
case PBC_SET_DEINTERLACEMODE:
pbi->DeInterlaceMode = Parameter;
break;
case PBC_SET_BLACKCLAMP:
pbi->BlackClamp = Parameter;
break;
case PBC_SET_WHITECLAMP:
pbi->WhiteClamp = Parameter;
break;
default:
break;
}
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_GetProcessorFrequency()
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : unsigned long: clock speed of the host processor.
*
* FUNCTION : Get the Processor's working freqency.
*
* SPECIAL NOTES : Stub function--always returns value 0.
*
****************************************************************************/
unsigned long VP6_GetProcessorFrequency ( void )
{
return 0;
}
/****************************************************************************
*
* ROUTINE : VP6_DMachineSpecificConfig
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Sets up pointers to platform dependant functions.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DMachineSpecificConfig ( void )
{
VP6_BuildQuantIndex = VP6_BuildQuantIndex_Generic;
}
/****************************************************************************
*
* ROUTINE : VP6_IssueWarning
*
* INPUTS : char *WarningMessage : Message to be issued.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Issues a warning message.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_IssueWarning ( char *WarningMessage )
{
(void) WarningMessage;
}
@@ -0,0 +1,478 @@
/****************************************************************************
*
* Module Title : FrameIni.c
*
* Description : Initialization functions.
*
****************************************************************************/
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
#include "duck_mem.h"
#include <intsafe.h> // TODO: make a mac version of this
/****************************************************************************
* Module Static Variables
****************************************************************************/
static const struct
{
INT32 row;
INT32 col;
} NearMacroBlocks[12] =
{
{ -1, 0 },
{ 0, -1 },
{ -1, -1 },
{ -1, 1 },
{ -2, 0 },
{ 0, -2 },
{ -1, -2 },
{ -2, -1 },
{ -2, 1 },
{ -1, 2 },
{ -2, -2 },
{ -2, 2 }
};
/****************************************************************************
*
* ROUTINE : VP6_InitMBI
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initialize MBI structure.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void
VP6_InitMBI(PB_INSTANCE *pbi)
{
pbi->mbi.blockDxInfo[0].ZeroRunProbsBasePtr =
pbi->mbi.blockDxInfo[1].ZeroRunProbsBasePtr =
pbi->mbi.blockDxInfo[2].ZeroRunProbsBasePtr =
pbi->mbi.blockDxInfo[3].ZeroRunProbsBasePtr =
pbi->mbi.blockDxInfo[4].ZeroRunProbsBasePtr =
pbi->mbi.blockDxInfo[5].ZeroRunProbsBasePtr = (UINT8 *)pbi->ZeroRunProbs;
pbi->mbi.blockDxInfo[0].AcProbsBasePtr =
pbi->mbi.blockDxInfo[1].AcProbsBasePtr =
pbi->mbi.blockDxInfo[2].AcProbsBasePtr =
pbi->mbi.blockDxInfo[3].AcProbsBasePtr = pbi->AcProbs + ACProbOffset(0,0,0,0);
pbi->mbi.blockDxInfo[4].AcProbsBasePtr =
pbi->mbi.blockDxInfo[5].AcProbsBasePtr = pbi->AcProbs + ACProbOffset(1,0,0,0);
pbi->mbi.blockDxInfo[0].DcProbsBasePtr =
pbi->mbi.blockDxInfo[1].DcProbsBasePtr =
pbi->mbi.blockDxInfo[2].DcProbsBasePtr =
pbi->mbi.blockDxInfo[3].DcProbsBasePtr = pbi->DcProbs + DCProbOffset(0,0);
pbi->mbi.blockDxInfo[4].DcProbsBasePtr =
pbi->mbi.blockDxInfo[5].DcProbsBasePtr = pbi->DcProbs + DCProbOffset(1,0);
pbi->mbi.blockDxInfo[0].DcNodeContextsBasePtr =
pbi->mbi.blockDxInfo[1].DcNodeContextsBasePtr =
pbi->mbi.blockDxInfo[2].DcNodeContextsBasePtr =
pbi->mbi.blockDxInfo[3].DcNodeContextsBasePtr = pbi->DcNodeContexts + DcNodeOffset(0,0,0);
pbi->mbi.blockDxInfo[4].DcNodeContextsBasePtr =
pbi->mbi.blockDxInfo[5].DcNodeContextsBasePtr = pbi->DcNodeContexts + DcNodeOffset(1,0,0);
pbi->mbi.blockDxInfo[0].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[0]];
pbi->mbi.blockDxInfo[1].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[1]];
pbi->mbi.blockDxInfo[2].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[2]];
pbi->mbi.blockDxInfo[3].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[3]];
pbi->mbi.blockDxInfo[4].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[4]];
pbi->mbi.blockDxInfo[5].dequantPtr = pbi->quantizer->dequant_coeffs[VP6_QTableSelect[5]];
pbi->mbi.blockDxInfo[0].LastDc =
pbi->mbi.blockDxInfo[1].LastDc =
pbi->mbi.blockDxInfo[2].LastDc =
pbi->mbi.blockDxInfo[3].LastDc = pbi->fc.LastDcY;
pbi->mbi.blockDxInfo[4].LastDc = pbi->fc.LastDcU;
pbi->mbi.blockDxInfo[5].LastDc = pbi->fc.LastDcV;
pbi->mbi.blockDxInfo[0].Left = &pbi->fc.LeftY[0];
pbi->mbi.blockDxInfo[1].Left = &pbi->fc.LeftY[0];
pbi->mbi.blockDxInfo[2].Left = &pbi->fc.LeftY[1];
pbi->mbi.blockDxInfo[3].Left = &pbi->fc.LeftY[1];
pbi->mbi.blockDxInfo[4].Left = &pbi->fc.LeftU;
pbi->mbi.blockDxInfo[5].Left = &pbi->fc.LeftV;
pbi->mbi.blockDxInfo[0].MvShift =
pbi->mbi.blockDxInfo[1].MvShift =
pbi->mbi.blockDxInfo[2].MvShift =
pbi->mbi.blockDxInfo[3].MvShift = Y_MVSHIFT;
pbi->mbi.blockDxInfo[4].MvShift =
pbi->mbi.blockDxInfo[5].MvShift = UV_MVSHIFT;
pbi->mbi.blockDxInfo[0].MvModMask =
pbi->mbi.blockDxInfo[1].MvModMask =
pbi->mbi.blockDxInfo[2].MvModMask =
pbi->mbi.blockDxInfo[3].MvModMask = Y_MVMODMASK;
pbi->mbi.blockDxInfo[4].MvModMask =
pbi->mbi.blockDxInfo[5].MvModMask = UV_MVMODMASK;
pbi->mbi.blockDxInfo[0].CurrentReconStride =
pbi->mbi.blockDxInfo[1].CurrentReconStride =
pbi->mbi.blockDxInfo[2].CurrentReconStride =
pbi->mbi.blockDxInfo[3].CurrentReconStride = pbi->Configuration.YStride;
pbi->mbi.blockDxInfo[4].CurrentReconStride =
pbi->mbi.blockDxInfo[5].CurrentReconStride = pbi->Configuration.UVStride;
pbi->mbi.blockDxInfo[0].FrameReconStride =
pbi->mbi.blockDxInfo[1].FrameReconStride =
pbi->mbi.blockDxInfo[2].FrameReconStride =
pbi->mbi.blockDxInfo[3].FrameReconStride = pbi->Configuration.YStride;
pbi->mbi.blockDxInfo[4].FrameReconStride =
pbi->mbi.blockDxInfo[5].FrameReconStride = pbi->Configuration.UVStride;
// Default clear data area down to 0s
memset(pbi->mbi.blockDxInfo[0].coeffsPtr, 0, 6*64*sizeof(Q_LIST_ENTRY));
//______ compressor only ______
pbi->mbi.blockDxInfo[0].FrameSourceStride =
pbi->mbi.blockDxInfo[1].FrameSourceStride =
pbi->mbi.blockDxInfo[2].FrameSourceStride =
pbi->mbi.blockDxInfo[3].FrameSourceStride = pbi->Configuration.VideoFrameWidth;
pbi->mbi.blockDxInfo[4].FrameSourceStride =
pbi->mbi.blockDxInfo[5].FrameSourceStride = pbi->Configuration.VideoFrameWidth/2;
pbi->mbi.blockDxInfo[0].CurrentSourceStride =
pbi->mbi.blockDxInfo[1].CurrentSourceStride =
pbi->mbi.blockDxInfo[2].CurrentSourceStride =
pbi->mbi.blockDxInfo[3].CurrentSourceStride = pbi->Configuration.VideoFrameWidth;
pbi->mbi.blockDxInfo[4].CurrentSourceStride =
pbi->mbi.blockDxInfo[5].CurrentSourceStride = pbi->Configuration.VideoFrameWidth/2;
pbi->mbi.blockDxInfo[0].Plane =
pbi->mbi.blockDxInfo[1].Plane =
pbi->mbi.blockDxInfo[2].Plane =
pbi->mbi.blockDxInfo[3].Plane = 0;
pbi->mbi.blockDxInfo[4].Plane =
pbi->mbi.blockDxInfo[5].Plane = 1;
//______ compressor only ______
}
/****************************************************************************
*
* ROUTINE : VP6_DeleteFragmentInfo
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocates memory associated with decoder data structures.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DeleteFragmentInfo ( PB_INSTANCE *pbi )
{
// Free prior allocs if present
if(pbi->mbi.blockDxInfo[0].coeffsPtr)
duck_free(pbi->mbi.blockDxInfo[0].coeffsPtr);
pbi->mbi.blockDxInfo[0].coeffsPtr = 0;
if( pbi->FragInfo)
duck_free(pbi->FragInfo);
pbi->FragInfo = 0;
if( pbi->fc.AboveY)
duck_free(pbi->fc.AboveY);
pbi->fc.AboveY = 0;
if( pbi->fc.AboveU)
duck_free(pbi->fc.AboveU);
pbi->fc.AboveU = 0;
if( pbi->fc.AboveV)
duck_free(pbi->fc.AboveV);
pbi->fc.AboveV = 0;
if( pbi->MBInterlaced)
duck_free(pbi->MBInterlaced);
pbi->MBInterlaced = 0;
if( pbi->MBMotionVector)
duck_free(pbi->MBMotionVector);
pbi->MBMotionVector = 0;
if( pbi->predictionMode)
duck_free(pbi->predictionMode);
pbi->predictionMode = 0;
#ifdef DMAREADREFERENCE
if(pbi->ReferenceBlocks)
duck_free(pbi->ReferenceBlocks);
pbi->ReferenceBlocks = 0;
#endif
#ifdef DMAWRITERECON
if(pbi->ReconstructedMBs)
duck_free(pbi->ReconstructedMBs);
pbi->ReconstructedMBs = 0;
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_AllocateFragmentInfo
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: TRUE if successful, FALSE on error.
*
* FUNCTION : Initializes the Playback instance passed in.
*
* SPECIAL NOTES : Uses duck_memalign to ensure data structures are aligned
* on 32-byte boundaries to improve cache performance.
*
****************************************************************************/
BOOL VP6_AllocateFragmentInfo ( PB_INSTANCE *pbi )
{
// Clear any existing info
VP6_DeleteFragmentInfo(pbi);
pbi->mbi.blockDxInfo[0].coeffsPtr = (Q_LIST_ENTRY *) duck_memalign(32, sizeof(Q_LIST_ENTRY)*64*6, DMEM_GENERAL);
if(!pbi->mbi.blockDxInfo[0].coeffsPtr) {VP6_DeleteFragmentInfo(pbi); return FALSE;}
pbi->mbi.blockDxInfo[1].coeffsPtr = pbi->mbi.blockDxInfo[0].coeffsPtr + 64;
pbi->mbi.blockDxInfo[2].coeffsPtr = pbi->mbi.blockDxInfo[1].coeffsPtr + 64;
pbi->mbi.blockDxInfo[3].coeffsPtr = pbi->mbi.blockDxInfo[2].coeffsPtr + 64;
pbi->mbi.blockDxInfo[4].coeffsPtr = pbi->mbi.blockDxInfo[3].coeffsPtr + 64;
pbi->mbi.blockDxInfo[5].coeffsPtr = pbi->mbi.blockDxInfo[4].coeffsPtr + 64;
// context allocations
pbi->fc.AboveY = (BLOCK_CONTEXT *) duck_memalign(32, (8+pbi->HFragments) * sizeof(BLOCK_CONTEXT), DMEM_GENERAL);
if(!pbi->fc.AboveY) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
pbi->fc.AboveU = (BLOCK_CONTEXT *) duck_memalign(32, (8+pbi->HFragments / 2) * sizeof(BLOCK_CONTEXT), DMEM_GENERAL);
if(!pbi->fc.AboveU) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
pbi->fc.AboveV = (BLOCK_CONTEXT *) duck_memalign(32, (8+pbi->HFragments / 2) * sizeof(BLOCK_CONTEXT), DMEM_GENERAL);
if(!pbi->fc.AboveV) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
// the encoder is the only thing using this move it to compdll
pbi->MBInterlaced = (char *) duck_memalign(32, pbi->MacroBlocks * sizeof(char), DMEM_GENERAL);
if(!pbi->MBInterlaced) { VP6_DeleteFragmentInfo(pbi); return FALSE; }
pbi->predictionMode = (char *) duck_memalign(32, pbi->MacroBlocks * sizeof(char), DMEM_GENERAL);
if(!pbi->predictionMode) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
pbi->MBMotionVector = (MOTION_VECTOR *) duck_memalign(32, pbi->MacroBlocks * sizeof(MOTION_VECTOR ), DMEM_GENERAL);
if(!pbi->MBMotionVector) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
// the encoder is the only thing using this move it to compdll
pbi->FragInfo = (FRAG_INFO *) duck_memalign(32, pbi->UnitFragments * sizeof(FRAG_INFO), DMEM_GENERAL);
if(!pbi->FragInfo) { VP6_DeleteFragmentInfo(pbi); return FALSE;}
#ifdef DMAREADREFERENCE
pbi->ReferenceBlocks=(UINT8(*)[192])duck_memalign(32, 6*192, DMEM_GENERAL);
if(!pbi->ReferenceBlocks){ VP6_DeleteFragmentInfo(pbi); return FALSE;}
#endif
#ifdef DMAWRITERECON
pbi->ReconstructedMBs = (UINT8*) duck_memalign(32, 768, DMEM_GENERAL);
if(!pbi->ReconstructedMBs){ VP6_DeleteFragmentInfo(pbi); return FALSE;}
#endif
return TRUE;
}
/****************************************************************************
*
* ROUTINE : VP6_DeleteFrameInfo
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocate memory associated with frame level data
* structures.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DeleteFrameInfo ( PB_INSTANCE *pbi )
{
if(pbi->ThisFrameRecon )
duck_free(pbi->ThisFrameRecon );
if(pbi->GoldenFrame)
duck_free(pbi->GoldenFrame);
if(pbi->LastFrameRecon)
duck_free(pbi->LastFrameRecon);
if(pbi->PostProcessBuffer)
duck_free(pbi->PostProcessBuffer);
pbi->ThisFrameRecon = 0;
pbi->GoldenFrame = 0;
pbi->LastFrameRecon = 0;
pbi->PostProcessBuffer = 0;
}
/****************************************************************************
*
* ROUTINE : VP6_AllocateFrameInfo
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
* unsigned int FrameSize : Size of the YUV frame in bytes.
*
* OUTPUTS : None
*
* RETURNS : BOOL: TRUE if successful, FALSE on error.
*
* FUNCTION : Initializes the Playback instance passed in
*
* SPECIAL NOTES : None.
*
****************************************************************************/
BOOL VP6_AllocateFrameInfo ( PB_INSTANCE *pbi, unsigned int FrameSize )
{
// clear any existing info
VP6_DeleteFrameInfo(pbi);
// Allocate frame buffers:
// Added 2 extra lines to framebuffer so that copy12x12 doesn't fail
// when we have a large motion vector in V on the last v block.
// Note : We never use these pixels anyway so this doesn't hurt.
pbi->ThisFrameRecon = (UINT8 *)duck_memalign(32, pbi->Configuration.YStride+FrameSize*sizeof(YUV_BUFFER_ENTRY), DMEM_GENERAL);
if(!pbi->ThisFrameRecon) { VP6_DeleteFrameInfo(pbi); return FALSE;}
pbi->GoldenFrame = (UINT8 *)duck_memalign(32, pbi->Configuration.YStride+FrameSize*sizeof(YUV_BUFFER_ENTRY ), DMEM_GENERAL);
if(!pbi->GoldenFrame) { VP6_DeleteFrameInfo(pbi); return FALSE;}
pbi->LastFrameRecon = (UINT8 *)duck_memalign(32, pbi->Configuration.YStride+FrameSize*sizeof(YUV_BUFFER_ENTRY), DMEM_GENERAL);
if(!pbi->LastFrameRecon) { VP6_DeleteFrameInfo(pbi); return FALSE;}
pbi->PostProcessBuffer = (UINT8 *)duck_memalign(32, pbi->Configuration.YStride+FrameSize*sizeof(YUV_BUFFER_ENTRY), DMEM_GENERAL);
if(!pbi->PostProcessBuffer) { VP6_DeleteFrameInfo(pbi); return FALSE;}
return TRUE;
}
/****************************************************************************
*
* ROUTINE : VP6_InitFrameDetails
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: TRUE on success, FALSE on failure.
*
* FUNCTION : Initialises various details about the frame.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
BOOL VP6_InitFrameDetails ( PB_INSTANCE *pbi )
{
UINT32 i;
int FrameSize;
if ( pbi->CPUFree > 0 )
VP6_SetPbParam( pbi, PBC_SET_CPUFREE, pbi->CPUFree );
/* Set the frame size etc. */
if (UIntMult(pbi->Configuration.VideoFrameWidth, pbi->Configuration.VideoFrameHeight, &pbi->YPlaneSize) == S_OK)
{
pbi->UVPlaneSize = pbi->YPlaneSize / 4;
pbi->HFragments = pbi->Configuration.VideoFrameWidth / pbi->Configuration.HFragPixels;
pbi->VFragments = pbi->Configuration.VideoFrameHeight / pbi->Configuration.VFragPixels;
if (UIntMult(pbi->VFragments, pbi->HFragments, &pbi->YPlaneFragments) == S_OK &&
UIntMult(pbi->YPlaneFragments, 3, &pbi->UnitFragments) == S_OK)
{
pbi->UnitFragments /= 2;
pbi->UVPlaneFragments = pbi->YPlaneFragments / 4;
pbi->Configuration.YStride = (pbi->Configuration.VideoFrameWidth + STRIDE_EXTRA);
pbi->Configuration.UVStride = pbi->Configuration.YStride / 2;
if (UIntMult(pbi->Configuration.YStride, pbi->Configuration.VideoFrameHeight + STRIDE_EXTRA, &pbi->ReconYPlaneSize) == S_OK)
{
pbi->ReconUVPlaneSize = pbi->ReconYPlaneSize / 4;
FrameSize = pbi->ReconYPlaneSize + 2 * pbi->ReconUVPlaneSize;
pbi->YDataOffset = 0;
pbi->UDataOffset = pbi->YPlaneSize;
pbi->VDataOffset = pbi->YPlaneSize + pbi->UVPlaneSize;
pbi->ReconYDataOffset = 0;
pbi->ReconUDataOffset = pbi->ReconYPlaneSize;
pbi->ReconVDataOffset = pbi->ReconYPlaneSize + pbi->ReconUVPlaneSize;
// Image dimensions in Macro-Blocks
pbi->MBRows = (2*BORDER_MBS)+(pbi->Configuration.VideoFrameHeight/16) + ( pbi->Configuration.VideoFrameHeight%16 ? 1 : 0 );
pbi->MBCols = (2*BORDER_MBS)+(pbi->Configuration.VideoFrameWidth/16) + ( pbi->Configuration.VideoFrameWidth%16 ? 1 : 0 );
pbi->MacroBlocks = pbi->MBRows * pbi->MBCols;
for( i=0; i<12; i++ )
pbi->mvNearOffset[i] = MBOffset(NearMacroBlocks[i].row, NearMacroBlocks[i].col);
ChangePostProcConfiguration(pbi->postproc, &pbi->Configuration);
if ( !VP6_AllocateFragmentInfo(pbi) )
return FALSE;
if ( !VP6_AllocateFrameInfo(pbi, FrameSize) )
{
VP6_DeleteFragmentInfo(pbi);
return FALSE;
}
// We have a differently output size than our scaling provides
if ( pbi->ScaleBuffer == 0 && pbi->OutputWidth &&
(pbi->Configuration.VideoFrameWidth != pbi->OutputWidth ||
pbi->Configuration.VideoFrameHeight != pbi->OutputHeight ) )
{
// Add 32 to outputwidth to ensure that we have enough to overscale
// (ie scale to a size that's bigger than our output size). Do this
// now even though we don't use it so we don't have to check border conditions.
pbi->ScaleBuffer = (UINT8 *)
duck_malloc(32 + 3 *
(pbi->OutputWidth + 32) *
(pbi->OutputHeight + 32)*
sizeof(YUV_BUFFER_ENTRY) / 2, DMEM_GENERAL);
}
VP6_InitMBI(pbi);
return TRUE;
}
}
}
return FALSE;
}
/****************************************************************************
*
* ROUTINE : VP6_InitialiseConfiguration
*
* INPUTS : PB_INSTANCE * pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Sets the base size of a coding block (8x8).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_InitialiseConfiguration ( PB_INSTANCE *pbi )
{
pbi->Configuration.HFragPixels = 8;
pbi->Configuration.VFragPixels = 8;
}
@@ -0,0 +1,350 @@
/****************************************************************************
*
* Module Title : Huffman.c
*
* Description : Huffman coding routines.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "huffman.h"
#include "pbdll.h"
/****************************************************************************
* Typedefs
****************************************************************************/
typedef struct _SORT_NODE
{
int next;
int freq;
unsigned char value;
} SORT_NODE;
typedef struct _sortnode
{
int next;
int freq;
tokenorptr value;
} sortnode;
/****************************************************************************
*
* ROUTINE : InsertSorted
*
* INPUTS : sortnode *sn : Array of sort nodes.
* int node : Index of node to be inserted.
* int *startnode : Pointer to _head of linked-list.
*
* OUTPUTS : int *startnode : Pointer to _head of linked-list.
*
* RETURNS : void
*
* FUNCTION : Inserts a node into a sorted linklist.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
static void InsertSorted ( sortnode *sn, int node, int *startnode )
{
int which = *startnode;
int prior = *startnode;
// find the position at which to insert the node
while( which != -1 && sn[node].freq > sn[which].freq )
{
prior = which;
which = sn[which].next;
}
if(which == *startnode)
{
*startnode = node;
sn[node].next = which;
}
else
{
sn[prior].next = node;
sn[node].next = which;
}
}
/****************************************************************************
*
* ROUTINE : VP6_BuildHuffTree
*
* INPUTS : int values : Number of values in the tree.
* unsigned int *counts : Histogram of token frequencies.
*
* OUTPUTS : HUFF_NODE *hn : Array of nodes (containing token frequency)
* from which to create tree.
* unsigned int *counts : Histogram of token frequencies (0 freq clipped to 1).
*
* RETURNS : void
*
* FUNCTION : Creates a Huffman tree data structure from list
* of token frequencies.
*
* SPECIAL NOTES : Maximum of 256 nodes can be handled.
*
****************************************************************************/
void VP6_BuildHuffTree ( HUFF_NODE *hn, unsigned int *counts, int values )
{
int i;
sortnode sn[256];
int sncount=0;
int startnode=0;
// NOTE:
// Create huffman tree in reverse order so that the root will always be 0
int huffptr=values-1;
// Set up sorted linked list of values/pointers into the huffman tree
for ( i=0; i<values; i++ )
{
sn[i].value.selector = 1;
sn[i].value.value = i;
if ( counts[i] == 0 )
counts[i] = 1;
sn[i].freq = counts[i];
sn[i].next = -1;
}
sncount = values;
// Connect above list into a linked list
for ( i=1; i<values; i++ )
InsertSorted ( sn, i, &startnode );
// while there is more than one node in our linked list
while ( sn[startnode].next != -1 )
{
int first = startnode;
int second = sn[startnode].next;
int sumfreq = sn[first].freq + sn[second].freq;
// set-up new merged huffman node
--huffptr;
hn[huffptr].leftunion.left = sn[first].value;
hn[huffptr].rightunion.right = sn[second].value;
hn[huffptr].freq = 256 * sn[first].freq / sumfreq;
// set up new merged sort node pointing to our huffnode
sn[sncount].value.selector = 0;
sn[sncount].value.value = huffptr;
sn[sncount].freq = sumfreq;
sn[sncount].next = -1;
// remove the two nodes we just merged from the linked list
startnode = sn[second].next;
// insert the new sort node into the proper location
InsertSorted(sn, sncount, &startnode);
// account for new nodes
sncount++;
}
return;
}
/****************************************************************************
*
* ROUTINE : VP6_BuildHuffLookupTable
*
* INPUTS : HUFF_NODE *HuffTreeRoot : Pointer to root of Huffman tree.
*
* OUTPUTS : UINT16 *HuffTable : Array (LUT) of Huffman codes.
*
* RETURNS : void
*
* FUNCTION : Traverse Huffman tree to create LUT of Huffman codes.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_BuildHuffLookupTable ( HUFF_NODE *HuffTreeRoot, UINT16 *HuffTable )
{
int i, j;
int bits;
tokenorptr torp;
for ( i=0; i<(1<<HUFF_LUT_LEVELS); i++ )
{
bits = i;
j=0;
torp.value = 0;
torp.selector = 0;
do
{
j++;
if ( (bits>>(HUFF_LUT_LEVELS - j)) & 1 )
torp = HuffTreeRoot[torp.value].rightunion.right;
else
torp = HuffTreeRoot[torp.value].leftunion.left;
}
while ( !(torp.selector) && (j < HUFF_LUT_LEVELS) );
// HuffTable[i] = torp.value<<1 | torp.selector | (j << 12);
((HUFF_TABLE_NODE *)HuffTable)[i].value = torp.value;
((HUFF_TABLE_NODE *)HuffTable)[i].flag = torp.selector;
((HUFF_TABLE_NODE *)HuffTable)[i].length = j;
}
}
/****************************************************************************
*
* ROUTINE : VP6_BuildHuffLookupTable
*
* INPUTS : HUFF_NODE *hn : List of Huffman tree nodes.
* int node : Current position within list of Huffman tree nodes.
* int codevalue : Huffman code as found so far.
* int codelength : Length of Huffman code so far (in bits).
*
* OUTPUTS : unsigned int *codearray : Array to hold Huffman codes.
* unsigned char *lengtharray : Array to hold lengths of Huffman codes.
*
* RETURNS : void
*
* FUNCTION : Recursively traverse Huffman tree to create LUT of Huffman codes.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_CreateCodeArray
(
HUFF_NODE *hn,
int node,
unsigned int *codearray,
unsigned char *lengtharray,
int codevalue,
int codelength
)
{
/* If we are at a leaf then fill in a code array entry */
/* Use recursive calls to scan down the tree */
if( hn[node].leftunion.left.selector )
{
codearray[hn[node].leftunion.left.value] = (codevalue<<1)+0;
lengtharray[hn[node].leftunion.left.value] = codelength+1;
}
else
{
VP6_CreateCodeArray (
hn,
hn[node].leftunion.left.value,
codearray,
lengtharray,
((codevalue << 1) + 0),
(codelength + 1) );
}
if( hn[node].rightunion.right.selector )
{
codearray[hn[node].rightunion.right.value] = (codevalue<<1)+1;
lengtharray[hn[node].rightunion.right.value] = codelength+1;
}
else
{
VP6_CreateCodeArray (
hn,
hn[node].rightunion.right.value,
codearray,
lengtharray,
((codevalue << 1) + 1),
(codelength + 1) );
}
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeValue
*
* INPUTS : BOOL_CODER *bc : Pointer to a Bool Coder instance.
* HUFF_NODE *hn : List of Huffman tree nodes.
*
* OUTPUTS : None.
*
* RETURNS : int: Decoded token value.
*
* FUNCTION : Traverse the Huffman tree by reading node decisions
* from the bitstream until a leaf node is reached. Returns
* the value associated with this leaf node.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int VP6_DecodeValue ( BOOL_CODER *bc, HUFF_NODE *hn )
{
tokenorptr torp;
torp.value = 0;
torp.selector = 0;
// Loop searches down through tree based upon bits read from the bitstream
// until it hits a leaf at which point we have decoded a token.
do
{
if ( VP6_DecodeBool(bc, hn[torp.value].freq) )
torp = hn[torp.value].rightunion.right;
else
torp = hn[torp.value].leftunion.left;
}
while ( !(torp.selector) );
return torp.value;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeValue
*
* INPUTS : BOOL_CODER *bc : Pointer to a Bool Coder instance.
* HUFF_NODE *hn : List of Huffman tree nodes.
* int value : Value to be encoded.
* int length : Length of value to be encoded (in bits).
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Given a Huffman code either output its bits to the encoded
* stream or measure the cost of doing so, depending on the
* flag bc->MeasureCost. Use VP6_EncodeBool2 if only measuring
* approximate number of bits required to encode the Huffman code
* or VP6_EncodeBool if actually producing the coded bits using
* the specified Bool Coder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_EncodeValue
(
BOOL_CODER *bc,
HUFF_NODE *hn,
int value,
int length
)
{
int i;
int node = 0;
for ( i=length-1; i>=0; i-- )
{
int v = (value>>i) & 1;
if ( bc->MeasureCost )
VP6_EncodeBool2 ( bc, (BOOL)v, hn[node].freq );
else
VP6_EncodeBool ( bc, (BOOL)v, hn[node].freq );
if ( v )
node = hn[node].rightunion.right.value;
else
node = hn[node].leftunion.left.value;
}
}
@@ -0,0 +1,195 @@
/****************************************************************************
*
* Module Title : TokenEntropy.c
*
* Description : Entropy configuration routines.
*
****************************************************************************/
#define STRICT /* Strict type checking. */
/****************************************************************************
* Header Files
****************************************************************************/
#include "tokenentropy.h"
#include "pbdll.h"
/****************************************************************************
* Exports
****************************************************************************/
// Costs in bits for different probabilities (expressed in range 0-255)
// Costs are multiplied by 256
const UINT32 VP6_ProbCost[256] =
{
2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129, 1099, 1072, 1046,
1023, 1000, 979, 959, 940, 922, 905, 889, 873, 858, 843, 829, 816, 803, 790, 778,
767, 755, 744, 733, 723, 713, 703, 693, 684, 675, 666, 657, 649, 641, 633, 625,
617, 609, 602, 594, 587, 580, 573, 567, 560, 553, 547, 541, 534, 528, 522, 516,
511, 505, 499, 494, 488, 483, 477, 472, 467, 462, 457, 452, 447, 442, 437, 433,
428, 424, 419, 415, 410, 406, 401, 397, 393, 389, 385, 381, 377, 373, 369, 365,
361, 357, 353, 349, 346, 342, 338, 335, 331, 328, 324, 321, 317, 314, 311, 307,
304, 301, 297, 294, 291, 288, 285, 281, 278, 275, 272, 269, 266, 263, 260, 257,
255, 252, 249, 246, 243, 240, 238, 235, 232, 229, 227, 224, 221, 219, 216, 214,
211, 208, 206, 203, 201, 198, 196, 194, 191, 189, 186, 184, 181, 179, 177, 174,
172, 170, 168, 165, 163, 161, 159, 156, 154, 152, 150, 148, 145, 143, 141, 139,
137, 135, 133, 131, 129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107,
105, 103, 101, 99, 97, 95, 93, 92, 90, 88, 86, 84, 82, 81, 79, 77,
75, 73, 72, 70, 68, 66, 65, 63, 61, 60, 58, 56, 55, 53, 51, 50,
48, 46, 45, 43, 41, 40, 38, 37, 35, 33, 32, 30, 29, 27, 25, 24,
22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 3, 1, 1
};
// Index categories for previous tokens in this block
const UINT8 VP6_PrevTokenIndex[MAX_ENTROPY_TOKENS] = { 0,1,2,2,2,2,2,2,2,2,2,0 };
// For details of tokens and extra bit breakdown see token definitions in huffman.h
const UINT8 ExtraBitLengths_VP6[MAX_ENTROPY_TOKENS] = { 0, 1, 1, 1, 1, 2, 3, 4, 5, 6, 12, 0 };
const UINT32 VP6_DctRangeMinVals[MAX_ENTROPY_TOKENS] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67, 0 };
const UINT8 VP6_DcUpdateProbs[2][MAX_ENTROPY_TOKENS-1] =
{
{ 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 },
{ 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 }
};
const UINT8 ScanBandUpdateProbs[BLOCK_SIZE] =
{
255, 132, 132, 159, 153, 151, 161, 170,
164, 162, 136, 110, 103, 114, 129, 118,
124, 125, 132, 136, 114, 110, 142, 135,
134, 123, 143, 126, 153, 183, 166, 161,
171, 180, 179, 164, 203, 218, 225, 217,
215, 206, 203, 217, 229, 241, 248, 243,
253, 255, 253, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255
};
const UINT8 ZrlUpdateProbs[ZRL_BANDS][ZERO_RUN_PROB_CASES] =
{
{ 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 },
{ 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 },
};
// Zero run probs
const UINT8 ZeroRunProbDefaults[ZRL_BANDS][ZERO_RUN_PROB_CASES] =
{
{ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 },
{ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 },
};
const UINT8 VP6_AcUpdateProbs[PREC_CASES][2][VP6_AC_BANDS][MAX_ENTROPY_TOKENS-1] =
{
{ // preceded by 0
{
{ 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 },
{ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 },
{ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
{ // preceded by 1
{
{ 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 },
{ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 },
{ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 },
{ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 },
{ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
{ // preceded by > 1
{
{ 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 },
{ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 },
{ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 },
{ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
{
{ 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 },
{ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
},
},
};
/****************************************************************************
* Module Statics
****************************************************************************/
// Dc context equations: Dc Token contexts are 00 0!0 and !0!0
static const LINE_EQ VP6_DcNodeEqs[CONTEXT_NODES][DC_TOKEN_CONTEXTS] =
{
{ { 122, 133 },{ 133, 51 },{ 142, -16 } }, // Zero Node
{ { 0, 1 },{ 0, 1 },{ 0, 1 } }, // EOB Node Dummy as no EOBs in DC
{ { 78, 171 },{ 169, 71 },{ 221, -30 } }, // One Node
{ { 139, 117 },{ 214, 44 },{ 246, -3 } }, // Low Val Node
{ { 168, 79 },{ 210, 38 },{ 203, 17 } }, // Two Node (2 vs 3 or 4)
};
/****************************************************************************
*
* ROUTINE : VP6_ConfigureContexts
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Configures the context dependant entropy probabilities.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_ConfigureContexts ( PB_INSTANCE *pbi )
{
UINT32 i;
UINT32 Node;
UINT32 Plane;
INT32 Temp;
// Clear MMX state so floating point can work again
#if defined(_MSC_VER)
ClearSysState();
#endif
// DC Node Probabilities
for ( Plane=0; Plane<2; Plane++ )
{
for ( i=0; i<DC_TOKEN_CONTEXTS; i++ )
{
// Tree Nodes
for ( Node=0; Node<CONTEXT_NODES; Node++ )
{
Temp = ( ( pbi->DcProbs[DCProbOffset(Plane,Node)] * VP6_DcNodeEqs[Node][i].M + 128 ) >> 8)
+ VP6_DcNodeEqs[Node][i].C;
Temp = (Temp > 255)? 255: Temp;
Temp = (Temp < 1)? 1 : Temp;
//pbi->DcNodeContexts[Plane][i][Node] = (UINT8)Temp;
*(pbi->DcNodeContexts + DcNodeOffset(Plane,i,Node)) = (UINT8)Temp;
}
}
}
}
@@ -0,0 +1,687 @@
/****************************************************************************
*
* Module Title : boolhuff.c
*
* Description : Boolean Encoder/Decoder
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "boolhuff.h"
#include "TokenEntropy.h"
#include <stdio.h>
// STATS Variables for measuring section costs
#if defined MEASURE_SECTION_COSTS
UINT32 Sectionbits[10] = {0,0,0,0,0,0,0,0,0,0};
UINT32 ActiveSection = 0;
#endif
#ifdef NOTNORMALIZED
/****************************************************************************
*
* ROUTINE : VP6_StartDecode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean decoder.
* unsigned char *buffer : pointer to buffer of data to be decoded.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initializes the boolean decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StartDecode ( BOOL_CODER *bc, unsigned char *buffer )
{
bc->pos = 0;
bc->value = 0;
bc->range = 0;
bc->buffer = buffer;
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeBool
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean decoder.
* int probability : probability next symbol is a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : Next decoded bit: 0 or 1
*
* FUNCTION : Determines the next value stored in the boolean decoder
* based upon the probability passed in. It uses a simple
* probability model to approximate an arithmetic coder.
*
* SPECIAL NOTES : The accuracy of this decoder gets worse as the range
* approaches 0. This can be avoided with more complex
* normalization functions (as in a standard arithmetic)
* coder. Chosen to avoid this for speed reasons.
*
****************************************************************************/
int VP6_DecodeBool ( BOOL_CODER *bc, int probability )
{
unsigned int split;
// Don't have enough in our range to tell between a 0 and 1 so get
// 3 new bytes.
if( bc->range < 2)
{
unsigned char *spot = bc->buffer+bc->pos;
bc->v[0] = spot[0];
bc->v[1] = spot[1];
bc->v[2] = spot[2];
// range is set to 0x01000001 to avoid having the range * probability
// calculation outrange (this can be handled differently at the cost
// of an extra if).
bc->range = 0x01000000;
bc->pos += 3;
}
// calculate the decision point
// black magic: This code works better than if I calculate probability *
// range and then truncating to 1 (can't explain why)
split = bc->range;
split --; // we always have to maintain
split *= probability;
split >>= 8;
split ++;
if( bc->value < split )
{
bc->range = split;
return 0;
}
else
{
bc->range-=split;
bc->value-=split;
return 1;
}
}
/****************************************************************************
*
* ROUTINE : VP6_StopDecode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean decoder.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs clean-up for boolean decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StopDecode ( BOOL_CODER *bc )
{
return;
}
/****************************************************************************
*
* ROUTINE : VP6_StartEncode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean encoder.
* unsigned char *buffer : pointer to buffer to hold encoded data.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initializes the boolean encoder
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StartEncode ( BOOL_CODER *bc, unsigned char *buffer )
{
bc->pos = 0;
bc->value = 0;
bc->range = 0x01000000;
bc->buffer = buffer;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeBool
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean encoder.
* int x : value to be encoded (0 or 1).
* int probability : probability of getting a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : void.
*
* FUNCTION : Encodes a boolean value (0 or 1) using the specified
* boolean encoder.
*
* SPECIAL NOTES : The accuracy of this encoder gets worse as the range
* approaches 0. This can be avoided with more complex
* normalization functions (as in a standard arithmetic
* coder). Chose to avoid this for speed reasons.
*
****************************************************************************/
void VP6_EncodeBool ( BOOL_CODER *bc, int x, int probability )
{
unsigned int split;
// we don't have enough in our range to tell between a 0 and 1,
// so get 3 new bytes.
if( bc->range < 2 )
{
bc->buffer[bc->pos] = bc->v[0];
bc->buffer[bc->pos+1] = bc->v[1];
bc->buffer[bc->pos+2] = bc->v[2];
bc->pos+=3;
// range is set to 0x01000001 to avoid having the range * probability
// calculation outrange ( this can be handled differently at the cost
// of an extra if).
bc->range = 0x01000000;
bc->value = 0;
}
// calculate the decision point
// black magic: This code works better than if I calculate probability *
// range and then truncating to 1 (can't explain why)
split = bc->range;
split --;
split *= probability;
split >>= 8;
split ++;
if( x )
{
bc->range-=split;
bc->value+=split;
}
else
{
bc->range = split;
}
}
/****************************************************************************
*
* ROUTINE : VP6_StopEncode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean encoder.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs clean-up for boolean encoder
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StopEncode( BOOL_CODER *bc )
{
int i;
for ( i=0; i<3; i++ )
{
bc->buffer[bc->pos + i] = *((unsigned char *) &bc->value + i);
}
bc->pos += 3;
}
#else
/****************************************************************************
*
* ROUTINE : VP6_StartEncode
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
* unsigned char *source : pointer to buffer to hold encoded data.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Perform initialization of the boolean encoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StartEncode ( BOOL_CODER *br, unsigned char *source )
{
br->lowvalue = 0;
br->range = 255;
br->value = 0;
br->count = -24;
br->buffer = source;
br->pos = 0;
}
/****************************************************************************
*
* ROUTINE : VP6_StopEncode
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs clean-up for a boolean encoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StopEncode ( BOOL_CODER *br )
{
if(br->count<-16)
br->lowvalue <<= (24-(br->count&7));
else if(br->count<-8)
br->lowvalue <<= (16-(br->count&7));
else
br->lowvalue <<= (8-(br->count&7));
br->buffer[br->pos++] = (br->lowvalue>>24);
br->buffer[br->pos++] = (br->lowvalue>>16) & 0xff;
br->buffer[br->pos++] = (br->lowvalue>> 8) & 0xff;
br->buffer[br->pos++] = (br->lowvalue ) & 0xff;
br->buffer[br->pos++] = 0;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeBool
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
* int bit : value to be encoded (0 or 1).
* int probability : probability of getting a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes a boolean value (0 or 1) using the
* specified boolean encoder.
*
* SPECIAL NOTES : This encoder uses normalizations, and is fairly accurate,
*
****************************************************************************/
void VP6_EncodeBool ( BOOL_CODER *br, int bit, int probability )
{
unsigned int split;
unsigned int count = br->count;
unsigned int range = br->range;
unsigned int lowvalue = br->lowvalue;
#if defined MEASURE_SECTION_COSTS
if (bit)
Sectionbits[ActiveSection] += VP6_ProbCost[255-probability];
else
Sectionbits[ActiveSection] += VP6_ProbCost[probability];
#endif
split = 1 + (((range-1) * probability) >> 8);
range = split;
if(bit)
{
lowvalue += split;
range = br->range-split;
}
while(range < 0x80)
{
range <<= 1;
if((lowvalue & 0x80000000 ))
{
int x = br->pos-1;
while(x>=0 && br->buffer[x] == 0xff)
{
br->buffer[x] =(unsigned char)0;
x--;
}
br->buffer[x]+=1;
}
lowvalue <<= 1;
if (!++count)
{
count = -8;
br->buffer[br->pos++]=(lowvalue >> 24);
lowvalue &= 0xffffff;
}
}
br->count = count;
br->lowvalue = lowvalue;
br->range = range;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeBoolOne
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
* int bit : value to be encoded (UNUSED).
* int probability : probability of getting a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes the boolean value 1 using the specified boolean encoder.
*
* SPECIAL NOTES : This encoder uses normalizations, and is fairly accurate,
*
****************************************************************************/
void VP6_EncodeBoolOne ( BOOL_CODER *br, int bit, int probability )
{
unsigned int split;
unsigned int count = br->count;
unsigned int range = br->range;
unsigned int lowvalue = br->lowvalue;
#if defined MEASURE_SECTION_COSTS
if (bit)
Sectionbits[ActiveSection] += VP6_ProbCost[255-probability];
else
Sectionbits[ActiveSection] += VP6_ProbCost[probability];
#endif
split = 1 + (((range-1) * probability) >> 8);
lowvalue += split;
range = range-split;
while(range < 0x80)
{
range <<= 1;
if((lowvalue & 0x80000000 ))
{
int x = br->pos-1;
while(x>=0 && br->buffer[x] == 0xff)
{
br->buffer[x] =(unsigned char)0;
x--;
}
br->buffer[x]+=1;
}
lowvalue <<= 1;
if (!++count)
{
count = -8;
br->buffer[br->pos++]=(lowvalue >> 24);
lowvalue &= 0xffffff;
}
}
br->count = count;
br->lowvalue = lowvalue;
br->range = range;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeBoolZero
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
* int bit : value to be encoded (UNUSED).
* int probability : probability of getting a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Encodes the boolean value 0 using the specified boolean encoder.
*
* SPECIAL NOTES : This encoder uses normalizations, and is fairly accurate,
*
****************************************************************************/
void VP6_EncodeBoolZero ( BOOL_CODER *br, int bit, int probability )
{
unsigned int count = br->count;
unsigned int range = br->range;
unsigned int lowvalue = br->lowvalue;
#if defined MEASURE_SECTION_COSTS
if (bit)
Sectionbits[ActiveSection] += VP6_ProbCost[255-probability];
else
Sectionbits[ActiveSection] += VP6_ProbCost[probability];
#endif
range = 1 + (((range-1) * probability) >> 8);
while(range < 0x80)
{
range <<= 1;
if((lowvalue & 0x80000000 ))
{
int x = br->pos-1;
while(x>=0 && br->buffer[x] == 0xff)
{
br->buffer[x] =(unsigned char)0;
x--;
}
br->buffer[x]+=1;
}
lowvalue <<= 1;
if (!++count)
{
count = -8;
br->buffer[br->pos++]=(lowvalue >> 24);
lowvalue &= 0xffffff;
}
}
br->count = count;
br->lowvalue = lowvalue;
br->range = range;
}
/****************************************************************************
*
* ROUTINE : VP6_EncodeBool2
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean encoder.
* int bit : value to be encoded (0 or 1).
* int probability : probability of getting a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Updates br->BitCounter with approximate cost of encoding
* bit.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_EncodeBool2 ( BOOL_CODER *br, int bit, int probability )
{
if (bit)
br->BitCounter += VP6_ProbCost[255-probability];
else
br->BitCounter += VP6_ProbCost[probability];
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeBool
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean decoder.
* int probability : probability that next symbol is a 0 (0-255)
*
* OUTPUTS : None.
*
* RETURNS : Next decoded symbol (0 or 1)
*
* FUNCTION : Decodes the next symbol (0 or 1) using the specified
* boolean decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int VP6_DecodeBool ( BOOL_CODER *br, int probability )
{
unsigned int bit=0;
unsigned int split;
unsigned int bigsplit;
unsigned int count = br->count;
unsigned int range = br->range;
unsigned int value = br->value;
split = 1 + (((range-1) * probability) >> 8);
bigsplit = (split<<24);
range = split;
if(value >= bigsplit)
{
range = br->range-split;
value = value-bigsplit;
bit = 1;
}
if(range>=0x80)
{
br->value = value;
br->range = range;
return bit;
}
else
{
do
{
range +=range;
value +=value;
if (!--count)
{
count = 8;
value |= br->buffer[br->pos];
br->pos++;
}
}
while(range < 0x80 );
}
br->count = count;
br->value = value;
br->range = range;
return bit;
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeBool128
*
* INPUTS : BOOL_CODER *br : pointer to instance of a boolean decoder.
*
* OUTPUTS : None.
*
* RETURNS : int: Next decoded symbol (0 or 1)
*
* FUNCTION : This function determines the next value stored in the
* boolean coder based upon a fixed probability of 0.5
* (128 in normalized units).
*
* SPECIAL NOTES : VP6_DecodeBool128() is a special case of VP6_DecodeBool()
* where the input probability is fixed at 128.
*
****************************************************************************/
int VP6_DecodeBool128 ( BOOL_CODER *br )
{
unsigned int bit;
unsigned int split;
unsigned int bigsplit;
unsigned int count = br->count;
unsigned int range = br->range;
unsigned int value = br->value;
split = ( range + 1) >> 1;
bigsplit = (split<<24);
if(value >= bigsplit)
{
range = (range-split)<<1;
value = (value-bigsplit)<<1;
bit = 1;
}
else
{
range = split<<1;
value = value<<1;
bit = 0;
}
if(!--count)
{
count=8;
value |= br->buffer[br->pos];
br->pos++;
}
br->count = count;
br->value = value;
br->range = range;
return bit;
}
/****************************************************************************
*
* ROUTINE : VP6_StartDecode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean decoder.
* unsigned char *source : pointer to buffer of data to be decoded.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs initialization of the boolean decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StartDecode ( BOOL_CODER *br, unsigned char *source )
{
br->lowvalue = 0;
br->range = 255;
br->count = 8;
br->buffer = source;
br->pos = 0;
br->value = (br->buffer[0]<<24)+(br->buffer[1]<<16)+(br->buffer[2]<<8)+(br->buffer[3]);
br->pos += 4;
}
/****************************************************************************
*
* ROUTINE : VP6_StopDecode
*
* INPUTS : BOOL_CODER *bc : pointer to instance of a boolean decoder (UNUSED).
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs clean-up of the specified boolean decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_StopDecode ( BOOL_CODER *bc )
{
}
#endif
@@ -0,0 +1,225 @@
#include "pbdll.h"
#include "misc_common.h"
#include "xprintf.h"
/****************************************************************************
* Debugging Aid Only
****************************************************************************
*/
#ifdef _MSC_VER
#include <stdio.h>
void vp6_writeframe(PB_INSTANCE *pbi, char * address,int x)
{
// write the frame
FILE *yframe;
char filename[255];
sprintf(filename,"y%04d.raw",x);
yframe=fopen(filename,"wb");
fwrite(address,pbi->ReconYPlaneSize+2*pbi->ReconUVPlaneSize,1,yframe);
fclose(yframe);
}
void vp6_writeframe2(PB_INSTANCE *pbi, char * address,int x)
{
// write the frame
FILE *yframe;
char filename[255];
sprintf(filename,"y%d.raw",x);
yframe=fopen(filename,"wb");
fwrite(address,pbi->YPlaneSize,1,yframe);
fclose(yframe);
}
void vp6_draw(unsigned char *prefix, int frame, char * address,int size)
{
// write the frame
FILE *yframe;
char filename[255];
sprintf(filename,"%s%04d.raw",prefix,frame);
yframe=fopen(filename,"wb");
fwrite(address,size,1,yframe);
fclose(yframe);
}
void vp6_drawb(unsigned char *prefix, int frame, char * address,int pitch,int width,int height)
{
// write the frame
FILE *yframe;
int i;
char filename[255];
sprintf(filename,"%s%04d.raw",prefix,frame);
yframe=fopen(filename,"wb");
for(i=0;i<height;i++)
{
fwrite(address,width,1,yframe);
address+=pitch;
}
fclose(yframe);
}
void vp6_drawc(char *filename, char * address,int pitch,int width,int height)
{
// write the frame
FILE *yframe;
int i;
yframe=fopen(filename,"ab");
for(i=0;i<height;i++)
{
fwrite(address,width,1,yframe);
address+=pitch;
}
fclose(yframe);
}
void vp6_showinfo2(PB_INSTANCE *pbi)
{
vp6_xprintf(pbi,
pbi->Configuration.YStride * UMV_BORDER + UMV_BORDER,
"F:%d G:%d Q:%d S:%d B: %d W:%d H:%d V:%d Decode:%8d, Blit:%8d, PP:%8d, P:%d",
pbi->FrameType,
pbi->RefreshGoldenFrame,
pbi->quantizer->FrameQIndex,
pbi->CurrentFrameSize,
pbi->br.pos,
pbi->HFragments,
pbi->VFragments,
pbi->Vp3VersionNo,
pbi->avgDecodeTime,
pbi->avgBlitTime,
pbi->avgPPTime[8],
pbi->PostProcessingLevel);
}
void vp6_appendframe(PB_INSTANCE *pbi)
{
// write the frame
FILE *yframe;
yframe=fopen("test.raw","ab");
fwrite(pbi->LastFrameRecon,pbi->ReconYPlaneSize+2*pbi->ReconUVPlaneSize,1,yframe);
fclose(yframe);
}
void vp6_showinfo(PB_INSTANCE *pbi)
{
UINT32 MBrow, MBcol;
UINT32 MBRows = pbi->MBRows;
UINT32 MBCols = pbi->MBCols;
// for each row of macroblocks
for ( MBrow=0; MBrow<MBRows; MBrow++ )
{
// for each macroblock within a row of macroblocks
for ( MBcol=0; MBcol<MBCols; MBcol++)
{
vp6_xprintf(pbi,
((MBrow)* 16+5) * pbi->Configuration.YStride + (MBcol)*16+5,
"%d",
pbi->predictionMode[MBOffset(MBrow,MBcol)]);
}
}
}
/****************************************************************************
*
* ROUTINE : PredictBlockToPostProcessBuffer
*
* INPUTS :
*
*
* OUTPUTS :
*
* RETURNS : None.
*
* FUNCTION : Codes a DCT block
*
* Motion vectors and modes asumed to be defined at the MB level.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void VP6_PredictBlockToPostProcessBuffer ( PB_INSTANCE *pbi, BLOCK_POSITION bp )
{
/*
we need a VP6_PredictMacroBlockToPostProcessBuffer
memset(pbi->ReconDataBuffer,0,64*sizeof(short));
// Action depends on decode mode.
if ( pbi->mbi.Mode == CODE_INTER_NO_MV ) // Inter with no motion vector
{
ReconInter( pbi->TmpDataBuffer, (UINT8 *)&pbi->PostProcessBuffer[pbi->mbi.Recon],
(UINT8 *)&pbi->LastFrameRecon[pbi->mbi.Recon],
pbi->ReconDataBuffer, pbi->mbi.CurrentReconStride);
}
else if ( VP6_ModeUsesMC[pbi->mbi.Mode] ) // The mode uses a motion vector.
{
// For the compressor we did this already ( possible optimization).
VP6_PredictFilteredBlock( pbi, pbi->TmpDataBuffer,bp);
ReconBlock(
pbi->TmpDataBuffer,
pbi->ReconDataBuffer,
(UINT8 *)&pbi->PostProcessBuffer[pbi->mbi.Recon],
pbi->mbi.CurrentReconStride );
}
else if ( pbi->mbi.Mode == CODE_USING_GOLDEN ) // Golden frame with motion vector
{
// Reconstruct the pixel data using the golden frame reconstruction and change data
ReconInter( pbi->TmpDataBuffer, (UINT8 *)&pbi->PostProcessBuffer[pbi->mbi.Recon],
(UINT8 *)&pbi->GoldenFrame[ pbi->mbi.Recon ],
pbi->ReconDataBuffer, pbi->mbi.CurrentReconStride );
}
else // Simple Intra coding
{
// Get the pixel index for the first pixel in the fragment.
ReconIntra( pbi->TmpDataBuffer, (UINT8 *)&pbi->PostProcessBuffer[pbi->mbi.Recon], (UINT16 *)pbi->ReconDataBuffer, pbi->mbi.CurrentReconStride );
}
*/
}
void VP6_printmodes(PB_INSTANCE *pbi)
{
static int nFrame = 0; // PB_INSTANCE doesn't provide a frame number, does it?
FILE *f=fopen("modes.txt","a");
unsigned int i,j;
fprintf(f, "Frame %d\n\n", nFrame);
for(i=BORDER_MBS;i<pbi->MBRows-BORDER_MBS;i++)
{
if(pbi->Configuration.Interlaced == 1)
{
for(j=BORDER_MBS;j<pbi->MBCols-BORDER_MBS;j++)
{
fprintf(f,"%d",pbi->MBInterlaced[MBOffset(i,j)]);
}
fprintf(f," ");
}
for(j=BORDER_MBS;j<pbi->MBCols-BORDER_MBS;j++)
{
fprintf(f,"%d",pbi->predictionMode[MBOffset(i,j)]);
}
fprintf(f," ");
for(j=BORDER_MBS;j<pbi->MBCols-BORDER_MBS;j++)
{
fprintf(f,"%3d:%-3d",pbi->MBMotionVector[MBOffset(i,j)].x,pbi->MBMotionVector[MBOffset(i,j)].y);
}
fprintf(f,"\n");
}
fprintf(f,"\n");
fprintf(f,"\n");
fclose(f);
++nFrame;
return;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,656 @@
/****************************************************************************
*
* Module Title : Decodemode.c
*
* Description : Functions for decoding modes and motionvectors
*
****************************************************************************/
//************************************************************************************
// Decoding the Modes:
//
// Decode Mode Tree Looks like this:
//
//
//
//
// zz
//
// 0 Mode Same As Last
//
//
// 1 2
//
// 3 4 5 6
//
// NoMV +MV Nest Near Intra FourMV 7 8
//
// 00Gold GoldMV GNrst GNear
//
//
// 30 probabilitity contexts are set up at each branch (in probMode) corresponding to
//
// 3 for what situation we are in at the mode level (all modes available,
// no nearest mv found, and no near mv found)
//
// 10 one for each possible last mode
//
// Note: if the last mode was near then the probability of getting near at position 4
// above is set to 0 (it would have been coded as same as last). Note also that the
// probablity of getting near when no near mv is available is also always set to 0.
//
// These probs are created from the 20 that can be xmitted in the bitstream (probXmitted)
// For each mode 2 probabilities can be transmitted:
// probability that the mode will appear if the last mode was the same
// probability that the mode will appear if the last mode is not that mode
//
//************************************************************************************
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
#include "decodemode.h"
#include "decodemv.h"
/****************************************************************************
* Implicit Imports
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Exports
****************************************************************************/
//*****************************************************************************
// ModeVQ: This structure holds a table of probability vectors for encoding modes
// To build this table a number of clips were run through and allowed to
// select each of the probabilities that were best for them on each frame. These
// choices were output and a vector quantizer was used to optimize the selection
// of 16 vectors for each MODETYPE (allmodes available, nonearest, and no near)
//*****************************************************************************
const UINT8 VP6_ModeVq[MODETYPES][MODEVECTORS][MAX_MODES*2] =
{
9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4,
48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0,
21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7,
69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0,
11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0,
70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0,
8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0,
141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0,
8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1,
46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0,
28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0,
100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0,
27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0,
80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
16, 20, 0, 0, 2, 8,104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10,
123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2,
26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3,
209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
2, 5, 4, 5, 0,121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1,
175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0,
83, 5, 2, 3, 0,102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0,
233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
34, 16,112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2,
159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1,
75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2,
212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0,
4, 2, 0, 0, 0,172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0,
187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1,
133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0,
251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4,
49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1,
26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6,
103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0,
14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1,
85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0,
31, 28, 0, 0, 3, 14,130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1,
171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3,
51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1,
81, 25, 0, 0, 2, 9,106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0,
14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0,
123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0,
13, 14, 0, 0, 4, 20,175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0
};
// These are the probabilities that we reset to after each keyframe.
// It was created as the average probabilities of the trees.
const UINT8 VP6_BaselineXmittedProbs[4][2][10] =
{
42, 2, 7, 42, 22, 3, 2, 5, 1, 0, 69, 1, 1, 44, 6, 1, 0, 1, 0, 0,
8, 1, 8, 0, 0, 2, 1, 0, 1, 0, 229, 1, 0, 0, 0, 1, 0, 0, 1, 0,
35, 1, 6, 34, 0, 2, 1, 1, 1, 0, 122, 1, 1, 46, 0, 1, 0, 0, 1, 0,
64, 0, 64, 64, 64, 0, 0, 0, 0, 0, 64, 0, 64, 64, 64, 0, 0, 0, 0, 0,
};
/****************************************************************************
*
* ROUTINE : VP6_BuildModeTree
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Fills in probabilities at each branch of the huffman tree
* based upon probXmitted, the frequencies transmitted in the bitstream.
*
****************************************************************************/
void VP6_BuildModeTree ( PB_INSTANCE *pbi )
{
int i,j,k;
// create a huffman tree and code array for each of our modes
// Note: each of the trees is minus the node give by probmodesame
for ( i=0; i<10; i++ )
{
unsigned int Counts[MAX_MODES];
unsigned int total;
// set up the probabilities for each tree
for(k=0;k<MODETYPES;k++)
{
total=0;
for ( j=0; j<10; j++ )
{
if ( i == j )
{
Counts[j]=0;
}
else
{
Counts[j]=100*pbi->probXmitted[k][0][j];
}
total+=Counts[j];
}
pbi->probModeSame[k][i] = 255-
255 * pbi->probXmitted[k][1][i]
/
( 1 +
pbi->probXmitted[k][1][i] +
pbi->probXmitted[k][0][i]
);
// each branch is basically calculated via
// summing all posibilities at that branch.
pbi->probMode[k][i][0]= 1 + 255 *
(
Counts[CODE_INTER_NO_MV]+
Counts[CODE_INTER_PLUS_MV]+
Counts[CODE_INTER_NEAREST_MV]+
Counts[CODE_INTER_NEAR_MV]
) /
( 1 +
total
);
pbi->probMode[k][i][1]= 1 + 255 *
(
Counts[CODE_INTER_NO_MV]+
Counts[CODE_INTER_PLUS_MV]
) /
(
1 +
Counts[CODE_INTER_NO_MV]+
Counts[CODE_INTER_PLUS_MV]+
Counts[CODE_INTER_NEAREST_MV]+
Counts[CODE_INTER_NEAR_MV]
);
pbi->probMode[k][i][2]= 1 + 255 *
(
Counts[CODE_INTRA]+
Counts[CODE_INTER_FOURMV]
) /
(
1 +
Counts[CODE_INTRA]+
Counts[CODE_INTER_FOURMV]+
Counts[CODE_USING_GOLDEN]+
Counts[CODE_GOLDEN_MV]+
Counts[CODE_GOLD_NEAREST_MV]+
Counts[CODE_GOLD_NEAR_MV]
);
pbi->probMode[k][i][3]= 1 + 255 *
(
Counts[CODE_INTER_NO_MV]
) /
(
1 +
Counts[CODE_INTER_NO_MV]+
Counts[CODE_INTER_PLUS_MV]
);
pbi->probMode[k][i][4]= 1 + 255 *
(
Counts[CODE_INTER_NEAREST_MV]
) /
(
1 +
Counts[CODE_INTER_NEAREST_MV]+
Counts[CODE_INTER_NEAR_MV]
) ;
pbi->probMode[k][i][5]= 1 + 255 *
(
Counts[CODE_INTRA]
) /
(
1 +
Counts[CODE_INTRA]+
Counts[CODE_INTER_FOURMV]
);
pbi->probMode[k][i][6]= 1 + 255 *
(
Counts[CODE_USING_GOLDEN]+
Counts[CODE_GOLDEN_MV]
) /
(
1 +
Counts[CODE_USING_GOLDEN]+
Counts[CODE_GOLDEN_MV]+
Counts[CODE_GOLD_NEAREST_MV]+
Counts[CODE_GOLD_NEAR_MV]
);
pbi->probMode[k][i][7]= 1 + 255 *
(
Counts[CODE_USING_GOLDEN]
) /
(
1 +
Counts[CODE_USING_GOLDEN]+
Counts[CODE_GOLDEN_MV]
);
pbi->probMode[k][i][8]= 1 + 255 *
(
Counts[CODE_GOLD_NEAREST_MV]
) /
(
1 +
Counts[CODE_GOLD_NEAREST_MV]+
Counts[CODE_GOLD_NEAR_MV]
);
}
}
}
/****************************************************************************
*
* ROUTINE : VP6_decodeModeDiff
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : a probability difference value decoded from the bitstream.
*
* FUNCTION : this function returns a probability difference value in
* the range -256 to +256 (in steps of 4) transmitted in the
* bitstream using a fixed tree with hardcoded probabilities.
*
* SPECIAL NOTES : The hard coded probabilities for the difference tree
* were calcualated by taking the average number of times a
* branch was taken on some sample material ie
* (bond,bike,beautifulmind)
*
****************************************************************************/
int VP6_decodeModeDiff ( PB_INSTANCE *pbi )
{
int sign;
if ( VP6_DecodeBool(&pbi->br, 205) == 0 )
return 0;
sign = 1 + -2 * VP6_DecodeBool128(&pbi->br);
if( !VP6_DecodeBool(&pbi->br,171) )
{
return sign<<(3-VP6_DecodeBool( &pbi->br,83));
}
else
{
if( !VP6_DecodeBool( &pbi->br,199) )
{
if(VP6_DecodeBool( &pbi->br,140))
return sign * 12;
if(VP6_DecodeBool( &pbi->br,125))
return sign * 16;
if(VP6_DecodeBool( &pbi->br,104))
return sign * 20;
return sign * 24;
}
else
{
int diff = VP6_bitread(&pbi->br,7);
return sign * diff * 4;
}
}
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeModeProbs
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : This function parses the probabilities transmitted in
* the bitstream. The bitstream may either use the
* last frames' baselines, or transmit a pointer to a
* vector of new probabilities. It may then additionally
* contain updates to each of these probabilities.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DecodeModeProbs ( PB_INSTANCE *pbi )
{
int i,j;
// For each mode type (all modes available, no nearest, no near mode)
for ( j=0; j<MODETYPES; j++ )
{
// determine whether we are sending a vector for this mode byte
if ( VP6_DecodeBool( &pbi->br, PROBVECTORXMIT ) )
{
// figure out which vector we have encoded
int whichVector = VP6_bitread(&pbi->br, 4);
// adjust the vector
for ( i=0; i<MAX_MODES; i++ )
{
pbi->probXmitted[j][1][i] = VP6_ModeVq[j][whichVector][i*2];
pbi->probXmitted[j][0][i] = VP6_ModeVq[j][whichVector][i*2+1];
}
}
// decode whether updates to bring it closer to ideal
if ( VP6_DecodeBool( &pbi->br, PROBIDEALXMIT) )
{
for ( i=0; i<10; i++ )
{
int diff;
// determine difference
diff = VP6_decodeModeDiff(pbi);
diff += pbi->probXmitted[j][1][i];
pbi->probXmitted[j][1][i] = ( diff<0 ? 0 : (diff>255?255:diff) );
// determine difference
diff = VP6_decodeModeDiff(pbi);
diff += pbi->probXmitted[j][0][i];
pbi->probXmitted[j][0][i] = ( diff<0 ? 0 : (diff>255?255:diff) );
}
}
}
VP6_BuildModeTree(pbi);
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeBlockMode
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : Decoded coding mode (as a CODING_MODE)
*
* FUNCTION : Decodes a coding mode for a block from 2 bits in the bitstream.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
CODING_MODE VP6_DecodeBlockMode ( PB_INSTANCE *pbi )
{
int choice = VP6_DecodeBool128(&pbi->br)<<1;
choice += VP6_DecodeBool128(&pbi->br);
switch ( choice )
{
case 0: return CODE_INTER_NO_MV; // 0
case 1: return CODE_INTER_PLUS_MV; // 2
case 2: return CODE_INTER_NEAREST_MV; // 3
case 3: return CODE_INTER_NEAR_MV; // 4
}
return (CODING_MODE)0;
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeMode
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* CODING_MODE lastmode : Mode of the last coded macroblock.
* UINT32 type : Mode type (all modes available,
* nonearest macroblock, no near macroblock).
* OUTPUTS : None.
*
* RETURNS : Decoded coding mode (as a CODING_MODE)
*
* FUNCTION : decodes a MBmode from the bitstream using modecodearray
* and probabilities that the value is the same as
* lastmode stored in probModeSame, and the probability
* of mode occuring if lastmode != mode stored in
* probMode.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
CODING_MODE VP6_DecodeMode ( PB_INSTANCE *pbi, CODING_MODE lastmode, UINT32 type )
{
CODING_MODE mode;
if ( VP6_DecodeBool(&pbi->br,pbi->probModeSame[type][lastmode]) )
{
mode = lastmode;
}
else
{ // 0
UINT8 *Stats =pbi->probMode[type][lastmode];
if ( VP6_DecodeBool(&pbi->br,Stats[0]) )
{ // 2
if ( VP6_DecodeBool(&pbi->br,Stats[2]) )
{ //6
if ( VP6_DecodeBool(&pbi->br,Stats[6]) )
{ // 8
mode = CODE_GOLD_NEAREST_MV + VP6_DecodeBool(&pbi->br,Stats[8]);
}
else
{ // 7
mode = CODE_USING_GOLDEN + VP6_DecodeBool(&pbi->br,Stats[7]);
}
}
else
{ //5
mode = CODE_INTRA;
if ( VP6_DecodeBool(&pbi->br,Stats[5]) )
{
mode = CODE_INTER_FOURMV;
}
}
}
else
{ // 1
if ( VP6_DecodeBool(&pbi->br,Stats[1]) )
{ // 4
mode = CODE_INTER_NEAREST_MV + VP6_DecodeBool(&pbi->br,Stats[4]);
}
else
{ // 3
mode = CODE_INTER_NO_MV + 2 * VP6_DecodeBool(&pbi->br,Stats[3]);
}
}
}
return mode;
}
/****************************************************************************
*
* ROUTINE : VP6_decodeModeAndMotionVector
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT32 MBrow : Row number for MB.
* UINT32 MBcol : Col number for MB.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Decodes a macroblock's coding mode and any associated
* motion vectors from the bitstream .
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_decodeModeAndMotionVector ( PB_INSTANCE *pbi, UINT32 MBrow, UINT32 MBcol )
{
int type;
int x, y;
UINT32 k;
CODING_MODE mode; //lastmode;
MOTION_VECTOR mv;
VP6_FindNearestandNextNearest(pbi,MBrow,MBcol,1,&type);
mode = VP6_DecodeMode(pbi,pbi->LastMode,type);
pbi->LastMode = mode;
pbi->predictionMode[MBOffset(MBrow,MBcol)] = mode;
pbi->mbi.Mode = mode;
if ( mode == CODE_INTER_FOURMV )
{
pbi->mbi.BlockMode[0] = VP6_DecodeBlockMode(pbi);
pbi->mbi.BlockMode[1] = VP6_DecodeBlockMode(pbi);
pbi->mbi.BlockMode[2] = VP6_DecodeBlockMode(pbi);
pbi->mbi.BlockMode[3] = VP6_DecodeBlockMode(pbi);
pbi->mbi.BlockMode[4] = CODE_INTER_FOURMV;
pbi->mbi.BlockMode[5] = CODE_INTER_FOURMV;
x=0;
y=0;
for ( k=0; k<4; k++ )
{
if ( pbi->mbi.BlockMode[k] == CODE_INTER_NO_MV )
{
pbi->mbi.Mv[k].x = 0;
pbi->mbi.Mv[k].y = 0;
}
else if( pbi->mbi.BlockMode[k] == CODE_INTER_NEAREST_MV )
{
pbi->mbi.Mv[k].x = pbi->mbi.NearestInterMVect.x;
pbi->mbi.Mv[k].y = pbi->mbi.NearestInterMVect.y;
x+=pbi->mbi.NearestInterMVect.x;
y+=pbi->mbi.NearestInterMVect.y;
}
else if ( pbi->mbi.BlockMode[k] == CODE_INTER_NEAR_MV )
{
pbi->mbi.Mv[k].x = pbi->mbi.NearInterMVect.x;
pbi->mbi.Mv[k].y = pbi->mbi.NearInterMVect.y;
x+=pbi->mbi.NearInterMVect.x;
y+=pbi->mbi.NearInterMVect.y;
}
else if ( pbi->mbi.BlockMode[k] == CODE_INTER_PLUS_MV )
{
VP6_decodeMotionVector(pbi,&mv,CODE_INTER_PLUS_MV);
pbi->mbi.Mv[k].x = mv.x;
pbi->mbi.Mv[k].y = mv.y;
x+=mv.x;
y+=mv.y;
}
}
x = (x+1+(x>=0))>>2;
y = (y+1+(y>=0))>>2;
pbi->MBMotionVector[MBOffset(MBrow,MBcol)].x = pbi->mbi.Mv[3].x;
pbi->MBMotionVector[MBOffset(MBrow,MBcol)].y = pbi->mbi.Mv[3].y;
pbi->mbi.Mv[4].x = x;
pbi->mbi.Mv[4].y = y;
pbi->mbi.Mv[5].x = x;
pbi->mbi.Mv[5].y = y;
}
else
{
switch ( mode )
{
case CODE_INTER_NEAREST_MV:
x = pbi->mbi.NearestInterMVect.x;
y = pbi->mbi.NearestInterMVect.y;
break;
case CODE_INTER_NEAR_MV:
x = pbi->mbi.NearInterMVect.x;
y = pbi->mbi.NearInterMVect.y;
break;
case CODE_GOLD_NEAREST_MV:
VP6_FindNearestandNextNearest(pbi, MBrow, MBcol, 2, &type);
x = pbi->mbi.NearestGoldMVect.x;
y = pbi->mbi.NearestGoldMVect.y;
break;
case CODE_GOLD_NEAR_MV:
VP6_FindNearestandNextNearest(pbi, MBrow, MBcol, 2, &type);
x = pbi->mbi.NearGoldMVect.x;
y = pbi->mbi.NearGoldMVect.y;
break;
case CODE_INTER_PLUS_MV:
VP6_decodeMotionVector(pbi,&mv,CODE_INTER_PLUS_MV);
x = mv.x;
y = mv.y;
break;
case CODE_GOLDEN_MV:
VP6_FindNearestandNextNearest(pbi, MBrow, MBcol, 2, &type);
VP6_decodeMotionVector(pbi,&mv,CODE_GOLDEN_MV);
x = mv.x;
y = mv.y;
break;
default:
x =0;
y =0;
break;
}
pbi->MBMotionVector[MBOffset(MBrow,MBcol)].x = x;
pbi->MBMotionVector[MBOffset(MBrow,MBcol)].y = y;
for ( k=0; k<6 ; k++ )
{
pbi->mbi.Mv[k].x = x;
pbi->mbi.Mv[k].y = y;
pbi->mbi.BlockMode[k] = mode;
}
}
}
@@ -0,0 +1,339 @@
/****************************************************************************
*
* Module Title : Decodemv.c
*
* Description : Functions for decoding modes and motion vectors.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
#include "decodemode.h"
#include "decodemv.h"
/****************************************************************************
* Macros
****************************************************************************/
/****************************************************************************
* Exports
****************************************************************************/
const UINT8 VP6_MvUpdateProbs[2][MV_NODES] =
{
{ 237, 246, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 250, 250, 252 },
{ 231, 243, 245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 251, 251, 254 }
};
const UINT8 DefaultMvShortProbs[2][7] =
{
{ 225, 146, 172, 147, 214, 39, 156 },
{ 204, 170, 119, 235, 140, 230, 228 }
};
const UINT8 DefaultMvLongProbs[2][LONG_MV_BITS] =
{
{ 247, 210, 135, 68, 138, 220, 239, 246 },
{ 244, 184, 201, 44, 173, 221, 239, 253 }
};
const UINT8 DefaultIsShortProbs[2] = { 162, 164 };
const UINT8 DefaultSignProbs[2] = { 128, 128 };
/****************************************************************************
*
* ROUTINE : VP6_ConfigureMvEntropyDecoder
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT8 FrameType : Type of the frame.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Builds the MV entropy decoding tree.
*
* SPECIAL NOTES : None.
*
***************************************************************************/
void VP6_ConfigureMvEntropyDecoder( PB_INSTANCE *pbi, UINT8 FrameType )
{
int i;
// This funciton is not called at all for a BASE_FRAME
// Read any changes to mv probabilities.
for ( i = 0; i < 2; i++ )
{
// Short vector probability
if ( VP6_DecodeBool(&pbi->br, VP6_MvUpdateProbs[i][0]) )
{
pbi->IsMvShortProb[i] = VP6_bitread( &pbi->br, PROB_UPDATE_BASELINE_COST ) << 1;
if ( pbi->IsMvShortProb[i] == 0 )
pbi->IsMvShortProb[i] = 1;
}
// Sign probability
if ( VP6_DecodeBool(&pbi->br, VP6_MvUpdateProbs[i][1]) )
{
pbi->MvSignProbs[i] = VP6_bitread( &pbi->br, PROB_UPDATE_BASELINE_COST ) << 1;
if ( pbi->MvSignProbs[i] == 0 )
pbi->MvSignProbs[i] = 1;
}
}
// Short vector tree node probabilities
for ( i = 0; i < 2; i++ )
{
UINT32 j;
UINT32 MvUpdateProbsOffset = 2; // Offset into MvUpdateProbs[i][]
for ( j = 0; j < 7; j++ )
{
if ( VP6_DecodeBool(&pbi->br, VP6_MvUpdateProbs[i][MvUpdateProbsOffset]) )
{
pbi->MvShortProbs[i][j] = VP6_bitread( &pbi->br, PROB_UPDATE_BASELINE_COST ) << 1;
if ( pbi->MvShortProbs[i][j] == 0 )
pbi->MvShortProbs[i][j] = 1;
}
MvUpdateProbsOffset++;
}
}
// Long vector tree node probabilities
for ( i = 0; i < 2; i++ )
{
UINT32 j;
UINT32 MvUpdateProbsOffset = 2 + 7;
for ( j = 0; j < LONG_MV_BITS; j++ )
{
if ( VP6_DecodeBool(&pbi->br, VP6_MvUpdateProbs[i][MvUpdateProbsOffset]) )
{
pbi->MvSizeProbs[i][j] = VP6_bitread( &pbi->br, PROB_UPDATE_BASELINE_COST ) << 1;
if ( pbi->MvSizeProbs[i][j] == 0 )
pbi->MvSizeProbs[i][j] = 1;
}
MvUpdateProbsOffset++;
}
}
}
/****************************************************************************
*
* ROUTINE : VP6_decodeMotionVector
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* CODING_MODE Mode : MV coding mode.
*
* OUTPUTS : MOTION_VECTOR *mv : Returned motion vector.
*
* RETURNS : void
*
* FUNCTION : Decodes a motion vector from the bitstream.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_decodeMotionVector
(
PB_INSTANCE *pbi,
MOTION_VECTOR *mv,
CODING_MODE Mode
)
{
UINT32 i;
INT32 Vector = 0;
INT32 SignBit = 0;
INT32 MvOffsetX = 0;
INT32 MvOffsetY = 0;
// Work out how the MV was coded so that the appropriate origin offset can be applied
if ( Mode == CODE_INTER_PLUS_MV )
{
// Normal Inter MV
if ( pbi->mbi.NearestMvIndex < MAX_NEAREST_ADJ_INDEX )
{
MvOffsetX = pbi->mbi.NearestInterMVect.x;
MvOffsetY = pbi->mbi.NearestInterMVect.y;
}
}
else
{
// Golden Frame MV
if ( pbi->mbi.NearestGMvIndex < MAX_NEAREST_ADJ_INDEX )
{
MvOffsetX = pbi->mbi.NearestGoldMVect.x;
MvOffsetY = pbi->mbi.NearestGoldMVect.y;
}
}
for ( i = 0; i < 2; i++ )
{
Vector = 0;
// Is the vector a small vector or a large vector
if ( !VP6_DecodeBool(&pbi->br, pbi->IsMvShortProb[i]) )
{
// Small magnitude vector
if ( VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][0] ) )
{
Vector += (1 << 2);
if ( VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][4]) )
{
Vector += (1 << 1);
Vector += VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][6]);
}
else
{
Vector += VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][5]);
}
}
else
{
if ( VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][1]) )
{
Vector += (1 << 1);
Vector += VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][3]);
}
else
{
Vector = VP6_DecodeBool(&pbi->br, pbi->MvShortProbs[i][2]);
}
}
}
else
{
// Large magnitude vector
Vector = VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][0] );
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][1] ) << 1);
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][2] ) << 2);
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][7] ) << 7);
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][6] ) << 6);
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][5] ) << 5);
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][4] ) << 4);
// If none of the higher order bits are set then this bit is implicit
if ( Vector & 0xF0 )
Vector += (VP6_DecodeBool( &pbi->br, pbi->MvSizeProbs[i][3] ) << 3);
else
Vector += 0x08;
}
// Read the sign bit if needed.
if ( Vector != 0 )
{
SignBit = VP6_DecodeBool(&pbi->br, pbi->MvSignProbs[i]);
if ( SignBit )
Vector = -Vector;
}
if ( i )
mv->y = Vector + MvOffsetY;
else
mv->x = Vector + MvOffsetX;
}
}
/****************************************************************************
*
* ROUTINE : VP6_FindNearestandNextNearest
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT32 MBrow : Row of macroblock to check.
* UINT32 MBcol : Col of macroblock to check.
* UINT8 Frame : Frame type which MV should come
* from (Golden or Last).
*
* OUTPUTS : int *type : Type of the vector returned.
*
* RETURNS : void
*
* FUNCTION : Find a Nearest and NextNearest MV in nearby MBs in
* frames having the same type (Golden or Last).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_FindNearestandNextNearest
(
PB_INSTANCE *pbi,
UINT32 MBrow,
UINT32 MBcol,
UINT8 Frame,
int *type
)
{
int i;
UINT32 OffsetMB;
UINT32 BaseMB = MBOffset(MBrow,MBcol);
INT32 Nearest = 0;
INT32 NextNearest = 0;
INT32 nearestIndex;
UINT32 thisMv;
INT32 typet;
typet = NONEAREST_MACROBLOCK;
// BEWARE:
// The use of (unsigned int *) casting here is potentially dangerous
// and will only work if the motion vector structure consists of
// two 16 bit values and is 32 bit aligned.
for ( i=0; i<12 ; i++ )
{
OffsetMB = pbi->mvNearOffset[i] + BaseMB;
if ( VP6_Mode2Frame[pbi->predictionMode[OffsetMB]] != Frame )
continue;
thisMv = *((unsigned int *) &pbi->MBMotionVector[OffsetMB]);
if ( thisMv )
{
*((unsigned int *) &Nearest) = thisMv;
typet = NONEAR_MACROBLOCK;
break;
}
}
nearestIndex = i;
for ( i=i+1; i<12; i++ )
{
OffsetMB = pbi->mvNearOffset[i] + BaseMB;
if ( VP6_Mode2Frame[pbi->predictionMode[OffsetMB]] != Frame )
continue;
thisMv = *((unsigned int *) &pbi->MBMotionVector[OffsetMB]);
if( thisMv == *((unsigned int *) &Nearest) )
continue;
if( thisMv )
{
*((unsigned int *) &NextNearest) = thisMv;
typet = MACROBLOCK;
break;
}
}
// Only update type if normal frame
if ( Frame == 1 )
{
*type = typet;
pbi->mbi.NearestMvIndex = nearestIndex;
*((unsigned int *) &pbi->mbi.NearestInterMVect) = *((unsigned int *) &Nearest);
*((unsigned int *) &pbi->mbi.NearInterMVect) = *((unsigned int *) &NextNearest);
}
else
{
pbi->mbi.NearestGMvIndex = nearestIndex;
*((unsigned int *) &pbi->mbi.NearestGoldMVect) = *((unsigned int *) &Nearest);
*((unsigned int *) &pbi->mbi.NearGoldMVect) = *((unsigned int *) &NextNearest);
}
}
@@ -0,0 +1,330 @@
#include "type_aliases.h"
UINT8 Stats[9][4][4][4]=
{
32 , 56 , 78 ,161 ,
105 ,129 ,182 ,241 ,
78 ,132 ,189 ,212 ,
112 ,169 ,203 ,226 ,
100 ,122 ,178 ,217 ,
200 ,175 ,239 ,247 ,
183 ,153 ,239 ,237 ,
201 ,192 ,242 ,244 ,
75 ,127 ,181 ,205 ,
183 ,178 ,238 ,249 ,
192 ,226 ,243 ,241 ,
190 ,205 ,239 ,244 ,
98 ,150 ,195 ,224 ,
219 ,189 ,243 ,244 ,
177 ,215 ,240 ,248 ,
190 ,207 ,241 ,247 ,
19 , 26 , 14 , 33 ,
113 ,121 , 97 , 87 ,
11 , 14 , 8 , 14 ,
21 , 14 , 14 , 20 ,
100 , 88 ,112 , 73 ,
188 ,169 ,158 ,140 ,
70 , 81 , 46 , 58 ,
100 , 82 , 49 , 55 ,
11 , 20 , 9 , 21 ,
76 , 91 , 68 , 74 ,
6 , 6 , 5 , 11 ,
15 , 18 , 10 , 14 ,
17 , 24 , 16 , 16 ,
87 , 68 , 64 , 61 ,
9 , 8 , 9 , 15 ,
17 , 23 , 10 , 18 ,
186 ,157 ,180 ,162 ,
184 ,208 ,206 ,189 ,
176 ,128 ,203 ,179 ,
184 ,196 ,192 ,176 ,
164 ,149 ,155 ,141 ,
133 ,130 ,156 ,116 ,
145 ,154 ,175 ,144 ,
124 ,150 ,149 ,126 ,
194 ,113 ,173 ,160 ,
191 ,208 ,205 ,164 ,
210 ,179 ,197 ,174 ,
175 ,154 ,190 ,182 ,
144 ,111 ,183 ,165 ,
123 ,118 ,186 ,144 ,
189 ,128 ,168 ,141 ,
99 ,164 ,174 ,145 ,
196 ,160 ,197 ,102 ,
156 ,125 ,173 , 83 ,
219 ,208 ,226 ,137 ,
189 ,148 ,191 ,100 ,
173 ,122 ,146 , 76 ,
111 ,128 ,124 , 81 ,
177 ,176 ,203 ,116 ,
118 ,103 ,145 , 82 ,
223 ,201 ,228 ,129 ,
181 ,137 ,199 , 99 ,
236 ,227 ,236 ,159 ,
200 ,177 ,204 ,121 ,
184 ,157 ,194 ,103 ,
128 ,121 ,135 , 81 ,
204 ,177 ,207 ,121 ,
158 ,127 ,173 , 88 ,
81 , 46 , 70 , 84 ,
135 ,107 , 81 , 73 ,
128 ,128 ,113 , 94 ,
109 ,128 , 84 , 81 ,
122 ,128 , 62 ,111 ,
184 ,171 ,145 ,131 ,
172 ,174 ,151 ,180 ,
160 ,114 ,131 , 91 ,
111 ,128 , 81 , 84 ,
157 ,147 ,127 ,133 ,
113 ,148 ,107 ,135 ,
140 ,140 ,104 ,139 ,
112 ,128 , 92 , 86 ,
146 ,128 ,143 ,137 ,
110 ,128 , 83 ,133 ,
128 ,136 ,144 ,120 ,
108 ,117 ,109 ,108 ,
101 ,107 ,112 ,105 ,
71 , 67 , 49 , 82 ,
66 , 86 , 54 , 68 ,
117 , 93 ,122 ,111 ,
78 ,106 ,152 ,113 ,
49 , 64 , 54 , 96 ,
67 , 62 , 68 , 62 ,
59 , 59 , 43 , 85 ,
70 , 60 , 72 , 72 ,
55 , 65 , 62 , 92 ,
93 , 98 , 92 , 87 ,
54 , 65 , 51 , 64 ,
56 , 31 , 56 , 54 ,
137 ,144 ,147 ,161 ,
110 ,113 ,128 ,134 ,
39 , 46 , 29 , 61 ,
76 , 86 , 98 , 81 ,
47 , 53 , 39 , 63 ,
61 , 69 , 45 , 92 ,
104 , 89 , 76 , 63 ,
97 ,128 , 88 ,108 ,
64 , 56 , 34 , 82 ,
135 , 93 , 82 , 98 ,
43 , 51 , 36 , 56 ,
71 , 64 , 50 , 79 ,
40 , 32 , 33 , 58 ,
73 , 75 , 53 , 85 ,
59 , 64 , 47 , 71 ,
123 , 49 , 61 , 96 ,
70 , 58 , 47 , 78 ,
100 ,105 , 56 ,102 ,
18 ,128 ,128 , 16 ,
175 ,128 ,162 ,128 ,
53 ,128 , 40 ,128 ,
49 ,128 , 41 , 1 ,
122 ,128 ,128 ,128 ,
181 ,189 ,193 ,100 ,
162 ,128 ,166 ,133 ,
110 ,128 , 89 ,128 ,
23 ,128 , 12 ,128 ,
171 ,149 ,182 ,135 ,
36 , 56 , 47 , 16 ,
32 ,128 , 39 , 26 ,
128 ,128 , 37 ,128 ,
106 ,128 ,131 ,134 ,
128 ,128 , 19 , 18 ,
128 ,128 , 12 , 9 ,
128 ,128 ,128 ,128 ,
9 ,128 , 52 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 ,128 ,128 ,
52 , 57 , 68 ,128 ,
13 ,128 , 7 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 ,128 ,128 ,
11 ,128 , 12 , 25 ,
128 ,128 , 1 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 , 45 ,128 ,
128 ,128 ,128 ,128 ,
128 ,128 ,128 ,128 ,
};
UINT32 MBBitCosts[4][4][4][10]=
{
11 , 524 , 351 , 293 , 324 , 523 , 644 , 458 , 815 , 815 , 19 , 394 , 275 , 286 , 286 , 511 , 575 , 351 , 639 , 639 , 32 , 462 , 266 , 200 , 236 , 431 , 571 , 371 , 635 , 635 , 96 , 319 , 131 , 189 , 249 , 322 , 449 , 194 , 513 , 513 ,
48 , 265 , 258 , 246 , 287 , 252 , 360 , 294 , 296 , 482 , 62 , 262 , 178 , 237 , 288 , 233 , 330 , 333 , 394 , 394 , 116 , 261 , 189 , 176 , 236 , 155 , 362 , 322 , 261 , 540 , 227 , 195 , 137 , 235 , 235 , 159 , 310 , 170 , 374 , 374 ,
31 , 485 , 311 , 162 , 267 , 509 , 548 , 433 , 671 , 671 , 62 , 418 , 254 , 110 , 236 , 472 , 536 , 347 , 600 , 600 , 129 , 459 , 258 , 53 , 223 , 439 , 499 , 382 , 746 , 746 , 163 , 379 , 121 , 119 , 197 , 345 , 399 , 199 , 653 , 653 ,
51 , 492 , 237 , 145 , 250 , 404 , 458 , 285 , 573 , 573 , 82 , 408 , 181 , 135 , 244 , 318 , 498 , 225 , 562 , 562 , 140 , 440 , 184 , 74 , 202 , 369 , 391 , 304 , 693 , 693 , 201 , 330 , 114 , 139 , 267 , 336 , 381 , 130 , 618 , 618 ,
38 , 219 , 270 , 303 , 311 , 285 , 392 , 287 , 456 , 456 , 53 , 206 , 209 , 317 , 317 , 264 , 328 , 280 , 392 , 392 , 106 , 161 , 196 , 198 , 238 , 193 , 377 , 292 , 441 , 441 , 198 , 189 , 119 , 210 , 236 , 214 , 369 , 170 , 433 , 433 ,
155 , 115 , 211 , 314 , 302 , 203 , 250 , 298 , 214 , 305 , 101 , 136 , 243 , 279 , 279 , 213 , 285 , 243 , 349 , 349 , 268 , 131 , 206 , 245 , 277 , 148 , 291 , 229 , 210 , 293 , 363 , 107 , 201 , 242 , 335 , 177 , 267 , 150 , 350 , 350 ,
109 , 225 , 200 , 116 , 254 , 313 , 311 , 276 , 430 , 430 , 81 , 233 , 249 , 144 , 261 , 281 , 345 , 239 , 409 , 409 , 283 , 244 , 199 , 64 , 223 , 233 , 376 , 278 , 310 , 560 , 268 , 215 , 122 , 143 , 230 , 262 , 279 , 179 , 374 , 374 ,
144 , 178 , 183 , 161 , 254 , 289 , 294 , 177 , 379 , 379 , 105 , 219 , 198 , 228 , 218 , 245 , 309 , 177 , 373 , 373 , 250 , 212 , 138 , 100 , 240 , 316 , 299 , 214 , 392 , 392 , 291 , 196 , 115 , 156 , 315 , 278 , 382 , 130 , 446 , 446 ,
27 , 503 , 341 , 166 , 290 , 510 , 622 , 472 , 686 , 686 , 61 , 355 , 242 , 115 , 258 , 468 , 532 , 335 , 596 , 596 , 118 , 439 , 262 , 55 , 235 , 472 , 490 , 388 , 824 , 824 , 149 , 333 , 128 , 125 , 206 , 359 , 474 , 194 , 538 , 538 ,
93 , 256 , 234 , 149 , 237 , 233 , 302 , 247 , 392 , 392 , 89 , 272 , 180 , 178 , 254 , 217 , 362 , 243 , 426 , 426 , 283 , 296 , 183 , 86 , 186 , 206 , 336 , 266 , 261 , 517 , 363 , 220 , 120 , 187 , 236 , 196 , 294 , 156 , 278 , 488 ,
147 , 496 , 297 , 47 , 193 , 476 , 516 , 388 , 667 , 667 , 215 , 444 , 231 , 46 , 162 , 454 , 453 , 374 , 643 , 643 , 309 , 477 , 261 , 30 , 166 , 497 , 501 , 407 , 784 , 784 , 275 , 410 , 125 , 96 , 153 , 424 , 419 , 200 , 746 , 746 ,
125 , 448 , 198 , 90 , 162 , 400 , 483 , 299 , 547 , 547 , 157 , 357 , 181 , 104 , 148 , 411 , 418 , 221 , 482 , 482 , 275 , 443 , 185 , 65 , 134 , 448 , 430 , 282 , 773 , 773 , 283 , 366 , 109 , 119 , 181 , 430 , 384 , 152 , 765 , 765 ,
41 , 467 , 241 , 154 , 271 , 494 , 566 , 324 , 630 , 630 , 75 , 318 , 179 , 129 , 284 , 475 , 539 , 245 , 603 , 603 , 140 , 369 , 178 , 72 , 212 , 398 , 417 , 304 , 993 , 993 , 192 , 339 , 100 , 130 , 247 , 373 , 506 , 166 , 570 , 570 ,
165 , 190 , 178 , 147 , 280 , 241 , 259 , 170 , 463 , 463 , 136 , 209 , 164 , 160 , 273 , 229 , 329 , 187 , 393 , 393 , 275 , 237 , 135 , 108 , 234 , 249 , 287 , 220 , 314 , 415 , 384 , 190 , 103 , 178 , 269 , 261 , 365 , 134 , 429 , 429 ,
115 , 472 , 218 , 124 , 114 , 485 , 549 , 278 , 613 , 613 , 176 , 358 , 170 , 132 , 103 , 430 , 494 , 230 , 558 , 558 , 291 , 451 , 185 , 111 , 73 , 464 , 446 , 288 , 827 , 827 , 332 , 342 , 103 , 172 , 131 , 406 , 419 , 152 , 656 , 656 ,
128 , 300 , 165 , 146 , 162 , 403 , 446 , 188 , 510 , 510 , 161 , 361 , 135 , 162 , 158 , 340 , 404 , 164 , 468 , 468 , 275 , 397 , 154 , 110 , 108 , 390 , 500 , 209 , 564 , 564 , 320 , 313 , 106 , 169 , 185 , 362 , 420 , 112 , 747 , 747 ,
};
UINT32 NNMBBitCosts[4][4][4][10]=
{
2 , 572 , 404 , 0 , 0 , 557 , 648 , 594 , 871 , 871 , 4 , 466 , 332 , 0 , 0 , 474 , 757 , 559 , 821 , 821 , 6 , 512 , 293 , 0 , 0 , 461 , 613 , 531 , 677 , 677 , 49 , 338 , 124 , 0 , 0 , 252 , 405 , 285 , 775 , 775 ,
35 , 231 , 289 , 0 , 0 , 213 , 346 , 413 , 283 , 459 , 46 , 176 , 268 , 0 , 0 , 248 , 312 , 268 , 376 , 376 , 65 , 167 , 195 , 0 , 0 , 166 , 342 , 465 , 406 , 406 , 184 , 100 , 131 , 0 , 0 , 162 , 319 , 296 , 383 , 383 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
16 , 297 , 297 , 0 , 0 , 361 , 425 , 297 , 489 , 489 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
33 , 218 , 241 , 0 , 0 , 244 , 362 , 421 , 335 , 483 , 37 , 171 , 268 , 0 , 0 , 259 , 394 , 323 , 458 , 458 , 125 , 156 , 144 , 0 , 0 , 119 , 350 , 357 , 414 , 414 , 215 , 156 , 84 , 0 , 0 , 144 , 361 , 245 , 425 , 425 ,
231 , 110 , 334 , 0 , 0 , 146 , 213 , 334 , 152 , 272 , 111 , 121 , 289 , 0 , 0 , 107 , 394 , 289 , 458 , 458 , 245 , 76 , 302 , 0 , 0 , 115 , 416 , 302 , 239 , 308 , 299 , 78 , 219 , 0 , 0 , 129 , 281 , 219 , 345 , 345 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
14 , 312 , 312 , 0 , 0 , 376 , 440 , 312 , 504 , 504 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 , 64 , 192 , 192 , 0 , 0 , 256 , 320 , 192 , 384 , 384 ,
};
UINT32 NN2MBBitCosts[4][4][4][10]=
{
7 , 556 , 377 , 291 , 0 , 551 , 569 , 523 , 813 , 813 , 12 , 411 , 317 , 243 , 0 , 562 , 626 , 497 , 690 , 690 , 22 , 478 , 280 , 178 , 0 , 490 , 579 , 447 , 643 , 643 , 68 , 325 , 129 , 183 , 0 , 298 , 445 , 275 , 509 , 509 ,
47 , 249 , 250 , 221 , 0 , 272 , 346 , 415 , 231 , 501 , 48 , 198 , 293 , 229 , 0 , 262 , 326 , 293 , 390 , 390 , 90 , 210 , 237 , 193 , 0 , 130 , 349 , 338 , 413 , 413 , 195 , 193 , 134 , 225 , 0 , 139 , 304 , 185 , 368 , 368 ,
32 , 542 , 349 , 128 , 0 , 493 , 583 , 539 , 647 , 647 , 107 , 462 , 363 , 43 , 0 , 526 , 590 , 363 , 654 , 654 , 122 , 520 , 289 , 37 , 0 , 461 , 576 , 508 , 640 , 640 , 113 , 364 , 143 , 87 , 0 , 428 , 492 , 250 , 556 , 556 ,
54 , 431 , 231 , 106 , 0 , 495 , 559 , 364 , 623 , 623 , 81 , 477 , 159 , 103 , 0 , 541 , 605 , 255 , 669 , 669 , 112 , 417 , 195 , 63 , 0 , 481 , 545 , 278 , 609 , 609 , 132 , 372 , 120 , 104 , 0 , 436 , 500 , 186 , 564 , 564 ,
46 , 228 , 230 , 218 , 0 , 247 , 420 , 410 , 318 , 508 , 54 , 161 , 273 , 250 , 0 , 285 , 349 , 273 , 413 , 413 , 121 , 203 , 199 , 180 , 0 , 129 , 294 , 323 , 358 , 358 , 215 , 187 , 107 , 172 , 0 , 163 , 397 , 208 , 461 , 461 ,
129 , 126 , 283 , 341 , 0 , 201 , 238 , 283 , 170 , 329 , 76 , 112 , 316 , 252 , 0 , 255 , 319 , 316 , 383 , 383 , 235 , 125 , 192 , 255 , 0 , 181 , 281 , 232 , 160 , 346 , 275 , 98 , 184 , 214 , 0 , 183 , 264 , 203 , 328 , 328 ,
122 , 208 , 319 , 75 , 0 , 262 , 326 , 319 , 390 , 390 , 60 , 196 , 260 , 196 , 0 , 260 , 324 , 260 , 388 , 388 , 227 , 178 , 253 , 56 , 0 , 285 , 349 , 253 , 413 , 413 , 211 , 168 , 169 , 126 , 0 , 232 , 296 , 169 , 360 , 360 ,
116 , 184 , 204 , 140 , 0 , 248 , 312 , 204 , 376 , 376 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 211 , 373 , 132 , 89 , 0 , 437 , 501 , 132 , 565 , 565 , 283 , 205 , 162 , 86 , 0 , 269 , 333 , 162 , 397 , 397 ,
27 , 531 , 343 , 144 , 0 , 495 , 525 , 498 , 779 , 779 , 67 , 445 , 247 , 80 , 0 , 509 , 573 , 433 , 637 , 637 , 163 , 430 , 236 , 29 , 0 , 449 , 630 , 492 , 694 , 694 , 153 , 393 , 130 , 72 , 0 , 313 , 503 , 291 , 567 , 567 ,
116 , 299 , 257 , 81 , 0 , 247 , 311 , 257 , 375 , 375 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 240 , 246 , 153 , 70 , 0 , 204 , 337 , 318 , 401 , 401 , 140 , 160 , 189 , 166 , 0 , 224 , 288 , 189 , 352 , 352 ,
184 , 500 , 324 , 19 , 0 , 499 , 563 , 525 , 627 , 627 , 198 , 588 , 303 , 17 , 0 , 652 , 716 , 458 , 780 , 780 , 268 , 496 , 315 , 10 , 0 , 535 , 591 , 513 , 655 , 655 , 198 , 375 , 143 , 51 , 0 , 439 , 503 , 267 , 567 , 567 ,
140 , 434 , 254 , 42 , 0 , 498 , 562 , 254 , 626 , 626 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 181 , 489 , 240 , 33 , 0 , 553 , 617 , 240 , 681 , 681 , 165 , 356 , 99 , 98 , 0 , 420 , 484 , 212 , 548 , 548 ,
51 , 427 , 230 , 114 , 0 , 394 , 536 , 368 , 600 , 600 , 93 , 362 , 182 , 82 , 0 , 426 , 490 , 289 , 554 , 554 , 137 , 408 , 183 , 49 , 0 , 472 , 536 , 363 , 600 , 600 , 163 , 302 , 95 , 110 , 0 , 329 , 434 , 226 , 498 , 498 ,
134 , 149 , 221 , 157 , 0 , 213 , 277 , 221 , 341 , 341 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 219 , 207 , 175 , 86 , 0 , 271 , 335 , 175 , 399 , 399 , 227 , 212 , 141 , 118 , 0 , 276 , 340 , 141 , 404 , 404 ,
64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 ,
64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 , 64 , 192 , 256 , 192 , 0 , 256 , 320 , 256 , 384 , 384 ,
};
UINT32 BBitCosts[4][4][4][10]=
{
144 , 0 , 25 , 418 , 418 , 0 , 0 , 0 , 0 , 0 , 121 , 0 , 38 , 308 , 308 , 0 , 0 , 0 , 0 , 0 , 144 , 0 , 32 , 294 , 294 , 0 , 0 , 0 , 0 , 0 , 151 , 0 , 26 , 300 , 387 , 0 , 0 , 0 , 0 , 0 ,
142 , 0 , 34 , 278 , 278 , 0 , 0 , 0 , 0 , 0 , 97 , 0 , 104 , 168 , 168 , 0 , 0 , 0 , 0 , 0 , 129 , 0 , 43 , 253 , 253 , 0 , 0 , 0 , 0 , 0 , 144 , 0 , 34 , 278 , 278 , 0 , 0 , 0 , 0 , 0 ,
186 , 0 , 39 , 162 , 302 , 0 , 0 , 0 , 0 , 0 , 179 , 0 , 47 , 190 , 190 , 0 , 0 , 0 , 0 , 0 , 195 , 0 , 35 , 180 , 272 , 0 , 0 , 0 , 0 , 0 , 195 , 0 , 31 , 196 , 288 , 0 , 0 , 0 , 0 , 0 ,
184 , 0 , 21 , 283 , 375 , 0 , 0 , 0 , 0 , 0 , 195 , 0 , 21 , 268 , 323 , 0 , 0 , 0 , 0 , 0 , 181 , 0 , 29 , 226 , 295 , 0 , 0 , 0 , 0 , 0 , 201 , 0 , 23 , 241 , 303 , 0 , 0 , 0 , 0 , 0 ,
105 , 0 , 57 , 247 , 247 , 0 , 0 , 0 , 0 , 0 , 131 , 0 , 30 , 373 , 373 , 0 , 0 , 0 , 0 , 0 , 94 , 0 , 55 , 284 , 284 , 0 , 0 , 0 , 0 , 0 , 161 , 0 , 26 , 313 , 313 , 0 , 0 , 0 , 0 , 0 ,
121 , 0 , 34 , 368 , 368 , 0 , 0 , 0 , 0 , 0 , 64 , 0 , 128 , 192 , 192 , 0 , 0 , 0 , 0 , 0 , 144 , 0 , 36 , 265 , 265 , 0 , 0 , 0 , 0 , 0 , 179 , 0 , 31 , 245 , 245 , 0 , 0 , 0 , 0 , 0 ,
227 , 0 , 31 , 212 , 212 , 0 , 0 , 0 , 0 , 0 , 179 , 0 , 56 , 171 , 171 , 0 , 0 , 0 , 0 , 0 , 195 , 0 , 33 , 221 , 221 , 0 , 0 , 0 , 0 , 0 , 176 , 0 , 39 , 215 , 215 , 0 , 0 , 0 , 0 , 0 ,
235 , 0 , 18 , 280 , 280 , 0 , 0 , 0 , 0 , 0 , 176 , 0 , 27 , 274 , 274 , 0 , 0 , 0 , 0 , 0 , 186 , 0 , 27 , 235 , 298 , 0 , 0 , 0 , 0 , 0 , 227 , 0 , 21 , 239 , 290 , 0 , 0 , 0 , 0 , 0 ,
192 , 0 , 30 , 206 , 285 , 0 , 0 , 0 , 0 , 0 , 134 , 0 , 52 , 217 , 217 , 0 , 0 , 0 , 0 , 0 , 157 , 0 , 34 , 238 , 282 , 0 , 0 , 0 , 0 , 0 , 181 , 0 , 31 , 225 , 260 , 0 , 0 , 0 , 0 , 0 ,
176 , 0 , 38 , 218 , 218 , 0 , 0 , 0 , 0 , 0 , 134 , 0 , 89 , 153 , 153 , 0 , 0 , 0 , 0 , 0 , 222 , 0 , 48 , 133 , 242 , 0 , 0 , 0 , 0 , 0 , 256 , 0 , 34 , 179 , 214 , 0 , 0 , 0 , 0 , 0 ,
245 , 0 , 39 , 155 , 233 , 0 , 0 , 0 , 0 , 0 , 320 , 0 , 44 , 169 , 157 , 0 , 0 , 0 , 0 , 0 , 250 , 0 , 39 , 166 , 201 , 0 , 0 , 0 , 0 , 0 , 291 , 0 , 39 , 165 , 187 , 0 , 0 , 0 , 0 , 0 ,
186 , 0 , 31 , 204 , 292 , 0 , 0 , 0 , 0 , 0 , 250 , 0 , 29 , 210 , 210 , 0 , 0 , 0 , 0 , 0 , 283 , 0 , 25 , 201 , 226 , 0 , 0 , 0 , 0 , 0 , 275 , 0 , 29 , 196 , 215 , 0 , 0 , 0 , 0 , 0 ,
171 , 0 , 24 , 288 , 331 , 0 , 0 , 0 , 0 , 0 , 151 , 0 , 36 , 249 , 257 , 0 , 0 , 0 , 0 , 0 , 181 , 0 , 31 , 238 , 248 , 0 , 0 , 0 , 0 , 0 , 186 , 0 , 25 , 262 , 284 , 0 , 0 , 0 , 0 , 0 ,
167 , 0 , 35 , 244 , 234 , 0 , 0 , 0 , 0 , 0 , 176 , 0 , 35 , 232 , 232 , 0 , 0 , 0 , 0 , 0 , 192 , 0 , 43 , 169 , 224 , 0 , 0 , 0 , 0 , 0 , 219 , 0 , 27 , 216 , 256 , 0 , 0 , 0 , 0 , 0 ,
219 , 0 , 32 , 170 , 292 , 0 , 0 , 0 , 0 , 0 , 227 , 0 , 42 , 151 , 226 , 0 , 0 , 0 , 0 , 0 , 250 , 0 , 35 , 162 , 230 , 0 , 0 , 0 , 0 , 0 , 262 , 0 , 30 , 184 , 235 , 0 , 0 , 0 , 0 , 0 ,
204 , 0 , 23 , 254 , 290 , 0 , 0 , 0 , 0 , 0 , 201 , 0 , 28 , 222 , 268 , 0 , 0 , 0 , 0 , 0 , 235 , 0 , 28 , 206 , 250 , 0 , 0 , 0 , 0 , 0 , 256 , 0 , 22 , 224 , 256 , 0 , 0 , 0 , 0 , 0 ,
};
@@ -0,0 +1,248 @@
/****************************************************************************
*
* Module Title : PB_Globals.c
*
* Description : Video CODEC Demo: playback dll global declarations
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "pbdll.h"
#include "duck_mem.h"
/****************************************************************************
* Module Statics
****************************************************************************/
static UINT32 VP6_DCQuantScaleP[Q_TABLE_SIZE];
/****************************************************************************
* Imports
****************************************************************************/
extern unsigned long VP6_GetProcessorFrequency();
/****************************************************************************
* Exports
****************************************************************************/
unsigned int CPUFrequency; // Process Frequency
// Truth table to indicate if the given mode uses motion estimation
BOOL VP6_ModeUsesMC[MAX_MODES] = { FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE };
/****************************************************************************
*
* ROUTINE : VP6_DeleteTmpBuffers
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocate buffers used during decoing.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DeleteTmpBuffers ( PB_INSTANCE *pbi )
{
if ( pbi->ReconDataBuffer[0] )
duck_free(pbi->ReconDataBuffer[0]);
if ( pbi->LoopFilteredBlock )
duck_free(pbi->LoopFilteredBlock);
if ( pbi->TmpDataBuffer )
duck_free(pbi->TmpDataBuffer);
if ( pbi->TmpReconBuffer )
duck_free(pbi->TmpReconBuffer);
if ( pbi->ScaleBuffer )
duck_free(pbi->ScaleBuffer);
pbi->ReconDataBuffer[0] = 0;
pbi->LoopFilteredBlock = 0;
pbi->TmpDataBuffer = 0;
pbi->TmpReconBuffer = 0;
pbi->ScaleBuffer = 0;
}
/****************************************************************************
*
* ROUTINE : VP6_AllocateTmpBuffers
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : BOOL: Always TRUE.
*
* FUNCTION : Allocates buffers required during decoding.
*
* SPECIAL NOTES : Uses ROUNDUP32 to ensure that buffers are aligned
* on 32-byte boundaries to improve cache performance.
*
****************************************************************************/
BOOL VP6_AllocateTmpBuffers ( PB_INSTANCE *pbi )
{
// clear any existing info
VP6_DeleteTmpBuffers ( pbi );
pbi->ReconDataBuffer[0] = (INT16 *)duck_memalign(32, 6*64*sizeof(INT16), DMEM_GENERAL);
if ( !pbi->ReconDataBuffer[0] ) { VP6_DeleteTmpBuffers(pbi); return FALSE;};
pbi->ReconDataBuffer[1] = pbi->ReconDataBuffer[0] + 64;
pbi->ReconDataBuffer[2] = pbi->ReconDataBuffer[1] + 64;
pbi->ReconDataBuffer[3] = pbi->ReconDataBuffer[2] + 64;
pbi->ReconDataBuffer[4] = pbi->ReconDataBuffer[3] + 64;
pbi->ReconDataBuffer[5] = pbi->ReconDataBuffer[4] + 64;
pbi->TmpDataBuffer = (INT16 *)duck_memalign(32, 64 * sizeof(INT16), DMEM_GENERAL);
if ( !pbi->TmpDataBuffer ) { VP6_DeleteTmpBuffers(pbi); return FALSE;};
pbi->LoopFilteredBlock = (UINT8 *)duck_memalign(32, 256 * sizeof(UINT8), DMEM_GENERAL);
if ( !pbi->LoopFilteredBlock ) { VP6_DeleteTmpBuffers(pbi); return FALSE;};
pbi->TmpReconBuffer = (INT16 *)duck_memalign(32, 64 * sizeof(INT16), DMEM_GENERAL);
if ( !pbi->TmpReconBuffer ) { VP6_DeleteTmpBuffers(pbi); return FALSE;};
return TRUE;
}
/****************************************************************************
*
* ROUTINE : VP6_DeletePBInstance
*
* INPUTS : PB_INSTANCE **pbi : Pointer to the pointer to the
* decoder instance.
*
* OUTPUTS : PB_INSTANCE **pbi : Pointer to the pointer to the
* decoder instance. Set to 0 on exit.
*
* RETURNS : void
*
* FUNCTION : De-allocates the decoder instance data structure.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DeletePBInstance ( PB_INSTANCE **pbi )
{
if ( *pbi )
{
// Delete any other dynamically allocaed temporary buffers
VP6_DeleteTmpBuffers(*pbi);
VP6_DeleteQuantizer(&(*pbi)->quantizer);
DeletePostProcInstance(&(*pbi)->postproc);
}
// dealoocate and reset pointer to NULL
duck_free ( *pbi );
*pbi = 0;
}
/****************************************************************************
*
* ROUTINE : VP6_CreatePBInstance
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : PB_INSTANCE *: Pointer to allocated decoder instance.
*
* FUNCTION : Allocates space for and initializes decoder instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
PB_INSTANCE *VP6_CreatePBInstance ( void )
{
PB_INSTANCE *pbi = 0;
CONFIG_TYPE ConfigurationInit = { 0,0,0,0,8,8,0,0,0,0,0,0,0,0 };
int pbi_size = sizeof(PB_INSTANCE);
pbi = (PB_INSTANCE *) duck_malloc ( pbi_size, DMEM_GENERAL );
if ( !pbi )
return 0;
// initialize whole structure to 0
memset ( (unsigned char *)pbi, 0, pbi_size );
memcpy ( (void *)&pbi->Configuration, (void *)&ConfigurationInit, sizeof(CONFIG_TYPE) );
if ( !VP6_AllocateTmpBuffers(pbi) )
{
duck_free(pbi);
return 0;
}
pbi->CPUFree = 70;
pbi->idct = idct;
// Initialise Entropy related data structures.
memset( pbi->DcProbs, 0, sizeof(pbi->DcProbs) );
memset( pbi->AcProbs, 0, sizeof(pbi->AcProbs) );
return pbi;
}
/****************************************************************************
*
* ROUTINE : VP6_VPInitLibrary
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Fully initializes the playback library.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_VPInitLibrary(void)
{
int i;
#if !defined(__POWERPC__)
CPUFrequency = VP6_GetProcessorFrequency();
#endif
VP6_DMachineSpecificConfig();
for ( i=0 ; i<Q_TABLE_SIZE; i++ )
{
INT32 dcScale = VP6_DcQuant[i]/2 + 2;
VP6_DCQuantScaleP[i] = dcScale;
}
InitPostProcessing (
VP6_DCQuantScaleP,
VP6_DCQuantScaleP,
VP6_DCQuantScaleP,
CURRENT_DECODE_VERSION );
InitVPUtil();
}
/****************************************************************************
*
* ROUTINE : VP6_VPDeInitLibrary
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-initializes the playback library.
*
* SPECIAL NOTES : Currently nothing to be done.
*
****************************************************************************/
void VP6_VPDeInitLibrary(void)
{
}
@@ -0,0 +1,769 @@
/****************************************************************************
*
* Module Title : Quantise
*
* Description : Quantisation and dequanitsation of an 8x8 dct block. .
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Frames
****************************************************************************/
#include "quantize.h"
#include "duck_mem.h"
#include <stddef.h>
/****************************************************************************
* Module Statics
****************************************************************************/
#define MIN16 ((1<<16)-1)
// Scale factors used to improve precision of DCT/IDCT
#define IDCT_SCALE_FACTOR 2 // Shift left bits to improve IDCT precision
// AC Quantizer Tables
static const UINT32 VP6_QThreshTable[Q_TABLE_SIZE] =
{ 94, 92, 90, 88, 86, 82, 78, 74,
70, 66, 62, 58, 54, 53, 52, 51,
50, 49, 48, 47, 46, 45, 44, 43,
42, 40, 39, 37, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 25,
24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4, 3, 2, 1
};
static const UINT32 VP6_UvQThreshTable[Q_TABLE_SIZE] =
{ 94, 92, 90, 88, 86, 82, 78, 74,
70, 66, 62, 58, 54, 53, 52, 51,
50, 49, 48, 47, 46, 45, 44, 43,
42, 40, 39, 37, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 25,
24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4, 3, 2, 1
};
// AC Zero Bin and Rounding Tables (include fdct normalisation)
static const UINT32 VP6_ZBinTable[Q_TABLE_SIZE] =
{
330,314,298,284,264,246,228,213,
201,190,178,167,156,153,149,146,
144,141,138,135,132,130,127,124,
121,115,110,104, 99, 96, 94, 90,
85, 82, 79, 76, 74, 71, 69, 66,
63, 61, 58, 55, 53, 50, 47, 45,
43, 40, 38, 36, 33, 31, 28, 24,
21, 18, 16, 13, 10, 7, 4, 2
};
static const UINT32 VP6_UvZBinTable[Q_TABLE_SIZE] =
{
330,314,298,284,264,246,228,213,
201,190,178,167,156,153,149,146,
144,141,138,135,132,130,127,124,
121,115,110,104, 99, 96, 94, 90,
85, 82, 79, 76, 74, 71, 69, 66,
63, 61, 58, 55, 53, 50, 47, 45,
43, 40, 38, 36, 33, 31, 28, 24,
21, 18, 16, 13, 10, 7, 4, 2
};
static const UINT32 VP6_RTable[Q_TABLE_SIZE] =
{
48, 56, 64, 70, 78, 82, 86, 88,
91, 92, 94, 94, 99,103,102,100,
99, 97, 95, 93, 91, 89, 87, 85,
83, 79, 77, 73, 71, 69, 67, 65,
64, 62, 60, 58, 56, 54, 52, 50,
48, 46, 44, 42, 40, 38, 36, 34,
32, 30, 28, 26, 24, 22, 20, 18,
16, 14, 12, 10, 8, 6, 4, 2
};
static const UINT32 VP6_UvRTable[Q_TABLE_SIZE] =
{
48, 56, 64, 70, 78, 82, 86, 88,
91, 92, 94, 94, 99,103,102,100,
99, 97, 95, 93, 91, 89, 87, 85,
83, 79, 77, 73, 71, 69, 67, 65,
64, 62, 60, 58, 56, 54, 52, 50,
48, 46, 44, 42, 40, 38, 36, 34,
32, 30, 28, 26, 24, 22, 20, 18,
16, 14, 12, 10, 8, 6, 4, 2
};
// DC Quantizer tables
const Q_LIST_ENTRY VP6_DcQuant[ Q_TABLE_SIZE ] =
{
47, 47, 47, 47, 45, 43, 43, 43,
43, 43, 42, 41, 41, 40, 40, 40,
40, 35, 35, 35, 35, 33, 33, 33,
33, 32, 32, 32, 27, 27, 26, 26,
25, 25, 24, 24, 23, 23, 19, 19,
19, 19, 18, 18, 17, 16, 16, 16,
16, 16, 15, 11, 11, 11, 10, 10,
9, 8, 7, 5, 3, 3, 2, 2
};
static const Q_LIST_ENTRY VP6_UvDcQuant[ Q_TABLE_SIZE ] =
{
47, 47, 47, 47, 45, 43, 43, 43,
43, 43, 42, 41, 41, 40, 40, 40,
40, 35, 35, 35, 35, 33, 33, 33,
33, 32, 32, 32, 27, 27, 26, 26,
25, 25, 24, 24, 23, 23, 19, 19,
19, 19, 18, 18, 17, 16, 16, 16,
16, 16, 15, 11, 11, 11, 10, 10,
9, 8, 7, 5, 3, 3, 2, 2
};
// DC Zero Bin and Rounding Tables (include fdct normalisation)
static const UINT32 VP6_DcZBinTable[Q_TABLE_SIZE] =
{
170,162,152,150,140,130,125,121,
121,118,113,111,110,108,108,106,
105,96, 93, 87, 86, 83, 83, 83,
83, 78, 78, 78, 66, 66, 63, 63,
61, 61, 58, 58, 56, 56, 46, 46,
46, 46, 43, 43, 41, 38, 38, 38,
38, 38, 35, 24, 24, 24, 23, 23,
20, 19, 16, 13, 6, 6, 4, 4
};
static const UINT32 VP6_UvDcZBinTable[Q_TABLE_SIZE] =
{
170,162,152,150,140,130,125,121,
121,118,113,111,110,108,108,106,
105,96, 93, 87, 86, 83, 83, 83,
83, 78, 78, 78, 66, 66, 63, 63,
61, 61, 58, 58, 56, 56, 46, 46,
46, 46, 43, 43, 41, 38, 38, 38,
38, 38, 35, 24, 24, 24, 23, 23,
20, 19, 16, 13, 6, 6, 4, 4
};
static const UINT32 VP6_DcRTable[Q_TABLE_SIZE] =
{
20, 28, 38, 40, 44, 46, 50, 50,
51, 57, 59, 61, 62, 64, 66, 67,
67, 62, 63, 64, 64, 62, 62, 62,
62, 62, 62, 62, 54, 54, 52, 52,
50, 50, 48, 48, 46, 46, 38, 38,
38, 38, 36, 36, 34, 32, 32, 32,
32, 32, 30, 22, 22, 22, 20, 20,
18, 16, 14, 10, 6, 6, 4, 4
};
static const UINT32 VP6_UvDcRTable[Q_TABLE_SIZE] =
{
20, 30, 38, 40, 44, 46, 50, 50,
51, 57, 59, 61, 62, 64, 66, 67,
67, 62, 63, 64, 64, 62, 62, 62,
62, 62, 62, 62, 54, 54, 52, 52,
50, 50, 48, 48, 46, 46, 38, 38,
38, 38, 36, 36, 34, 32, 32, 32,
32, 32, 30, 22, 22, 22, 20, 20,
18, 16, 14, 10, 6, 6, 4, 4
};
// Correction factors for ZBin size.based upon zero run length leading up to the current coef
// The factor is A % of the bin width to be added to the existing zero bin.
static const INT32 VP6_ZlrZbinCorrection[Q_TABLE_SIZE] =
{
-8, 0, 5, 10, 10, 10, 10, 10,
15, 15, 15, 15, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25,
30, 30, 30, 30, 30, 30, 30, 30,
};
/****************************************************************************
*
* Inverse fast DCT index:
*
* This contains the offsets needed to convert zigzag order into x, y order
* for decoding. It is generated from the input zigzag index at at run time.
*
* For maximum speed during both quantisation and dequantisation we maintain
* separate quantisation and zigzag tables for each operation.
*
* qi->quant_index : zigzag index used during quantisation
* dequant_index : zigzag index used during dequantisation
*
* qi->quant_index is the inverse of dequant_index and is calculated during
* initialisation.
*
****************************************************************************/
static const UINT32 dequant_index[64] =
{ 0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
static const UINT32 transIndexC[64] =
{
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63
};
static const UINT32 quant_indexC[64] =
{
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
/****************************************************************************
* Imports
****************************************************************************/
void (*VP6_BuildQuantIndex)( QUANTIZER * qi);
void (*VP6_quantize)( QUANTIZER *qi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list, UINT8 bp );
/****************************************************************************
* Exports
****************************************************************************/
const UINT8 VP6_QTableSelect[6] = { 0,0,0,0,1,1 }; // Controls selection of Q Table,rounding,zero bin etc for Y, U & V blocks
/****************************************************************************
*
* ROUTINE : VP6_InitQTables
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* UINT8 Vp3VersionNo : Decoder version number (NOT USED).
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initialises Q table.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_InitQTables ( QUANTIZER *qi, UINT8 Vp3VersionNo )
{
memcpy ( qi->QThreshTable, VP6_QThreshTable, sizeof(qi->QThreshTable) );
}
/****************************************************************************
*
* ROUTINE : VP6_BuildQuantIndex_Generic
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Builds the quant_index table.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_BuildQuantIndex_Generic ( QUANTIZER *qi )
{
INT32 i,j;
qi->transIndex = (UINT32 *)transIndexC;
// invert the dequant index into the quant index
for ( i=0; i<BLOCK_SIZE; i++ )
{
j = dequant_index[i];
qi->quant_index[j] = i;
}
}
/****************************************************************************
*
* ROUTINE : VP6_init_dequantizer
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* UINT8 Vp3VersionNo : Decoder version number (NOT USED)
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs initialization of the dequantizer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_init_dequantizer ( QUANTIZER *qi, UINT8 Vp3VersionNo )
{
int i, j;
// *************** Y ******************/
// AC: set-up the dequant values and then place in the zig-zag/transposed order.
for ( i=1; i<64; i++ )
{
j = qi->quant_index[i];
qi->dequant_coeffs[0][j] = VP6_QThreshTable[qi->FrameQIndex] << IDCT_SCALE_FACTOR;
}
// DC
qi->dequant_coeffs[0][0] = VP6_DcQuant[qi->FrameQIndex] << IDCT_SCALE_FACTOR;
// *************** UV ******************/
// AC: set-up the dequant values and then place in the zig-zag/transposed order.
for ( i=1; i<64; i++ )
{
j = qi->quant_index[i];
qi->dequant_coeffs[1][j] = VP6_UvQThreshTable[qi->FrameQIndex] << IDCT_SCALE_FACTOR;
}
// DC
qi->dequant_coeffs[1][0] = VP6_UvDcQuant[qi->FrameQIndex] << IDCT_SCALE_FACTOR;
}
/****************************************************************************
*
* ROUTINE : VP6_UpdateQ
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* UINT8 Vp3VersionNo : Decoder version number.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Updates the quantisation tables for a new Q.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_UpdateQ ( QUANTIZER *qi, UINT8 Vp3VersionNo )
{
if ( qi->FrameQIndex == qi->LastFrameQIndex )
return;
// Update the record of last Q index.
qi->LastFrameQIndex = qi->FrameQIndex;
// Invert the dequant index into the quant index --
// the decoder has a different order than the encoder.
VP6_BuildQuantIndex(qi);
// Re-initialise the q tables for forward and reverse transforms.
VP6_init_dequantizer ( qi, Vp3VersionNo );
}
/********************* COMPRESSOR SPECIFIC **********************************/
/****************************************************************************
*
* ROUTINE : VP6_init_quantizer
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* UINT8 Vp3VersionNo : Decoder version number (NOT USED).
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Updates the quantisation tables for a new Q.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
#define SHIFT16 (1<<16)
void VP6_init_quantizer ( QUANTIZER *qi, UINT8 Vp3VersionNo )
{
int i;
double temp_fp_quant_coeffs;
// Notes on setup of quantisers:
// The "* 4" is a normalisation factor for the forward DCT transform.
// ******************* Y *********************
// Calculate DC quant values (Include a *4 for FDCT normalization)
temp_fp_quant_coeffs = (double)( VP6_DcQuant[qi->FrameQIndex] * 4 );
// 1/X (Y)
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
qi->QuantCoeffs[0][0] = (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);
// DC rounding (Y)
qi->QuantRound[0][0] = VP6_DcRTable[qi->FrameQIndex];
// Set DC zero Bin (Y)
qi->ZeroBinSize[0][0] = VP6_DcZBinTable[qi->FrameQIndex];
// AC for Y
for ( i=1; i<64; i++ )
{
// Normalize the quantizer (* 4 for fdct normalisation)
temp_fp_quant_coeffs = (double)(VP6_QThreshTable[qi->FrameQIndex] * 4);
// Convert to 1/x
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
qi->QuantCoeffs[0][i] = (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);
// AC rounding
qi->QuantRound[0][i] = VP6_RTable[qi->FrameQIndex];
// Zero Bins
qi->ZeroBinSize[0][i] = VP6_ZBinTable[qi->FrameQIndex];
}
// ******************* UV *********************
// Calculate DC quant values (Include a *4 for FDCT normalization)
temp_fp_quant_coeffs = (double)( VP6_UvDcQuant[qi->FrameQIndex] * 4 );
// 1/X (UV)
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
qi->QuantCoeffs[1][0] = (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);
// DC rounding (UV)
qi->QuantRound[1][0] = VP6_UvDcRTable[qi->FrameQIndex];
// Set DC zero Bin (UV)
qi->ZeroBinSize[1][0] = VP6_UvDcZBinTable[qi->FrameQIndex];
// AC for UV
for ( i=1; i<64; i++ )
{
// Normalize the quantizer (* 4 for fdct normalisation)
temp_fp_quant_coeffs = (double)(VP6_UvQThreshTable[qi->FrameQIndex] * 4);
// 1/x
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
qi->QuantCoeffs[1][i] = (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);
// AC rounding
qi->QuantRound[1][i] = VP6_UvRTable[qi->FrameQIndex];
// Zero Bins
qi->ZeroBinSize[1][i] = VP6_UvZBinTable[qi->FrameQIndex];
}
for ( i=0; i<8; i++ )
{
qi->round[i] = qi->QuantRound[0][1];
qi->mult[i] = qi->QuantCoeffs[0][1];
qi->zbin[i] = qi->ZeroBinSize[0][1]-1;
}
// Work out the ZRL correction factors for ZBIN
for ( i = 0; i < 64; i++ )
{
qi->ZlrZbinCorrections[0][i] = ((INT32)VP6_QThreshTable[qi->FrameQIndex] * 4 * VP6_ZlrZbinCorrection[i]) / 100;
qi->ZlrZbinCorrections[1][i] = ((INT32)VP6_UvQThreshTable[qi->FrameQIndex] * 4 * VP6_ZlrZbinCorrection[i]) / 100;
}
}
/****************************************************************************
*
* ROUTINE : UpdateQC (compressor's update q)
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* UINT8 Vp3VersionNo : Decoder version number.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Updates the quantisation tables for a new Q
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_UpdateQC ( QUANTIZER *qi, UINT8 Vp3VersionNo )
{
if ( qi->FrameQIndex == qi->LastFrameQIndex )
return;
// Update the record of last Q index.
qi->LastFrameQIndex = qi->FrameQIndex;
// Invert the dequant index into the quant index --
// the decoder has a different order than the encoder.
VP6_BuildQuantIndex_Generic(qi);
// Re-initialise the q tables for forward and reverse transforms.
VP6_init_quantizer ( qi, Vp3VersionNo );
VP6_init_dequantizer ( qi, Vp3VersionNo );
}
/****************************************************************************
*
* ROUTINE : VP6_quantize_c
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
* INT16 *DCT_block : List of 64 DCT coefficients.
* UINT8 bp : Position of block within MB.
*
* OUTPUTS : Q_LIST_ENTRY *quantized_list : List of 64 quantized DCT coefficients.
*
* RETURNS : void
*
* FUNCTION : Quantizes the DCT coefficients wrt the current
* quantization level.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
#define HIGHBITDUPPED(X) (((signed short) X) >> 15)
void VP6_quantize_c( QUANTIZER *qi, INT16 *DCT_block, Q_LIST_ENTRY *quantized_list, UINT8 bp )
{
UINT32 i, j;
INT32 temp;
UINT32 ColourPlane = VP6_QTableSelect[bp];
INT32 * QuantRoundPtr = qi->QuantRound[ColourPlane];
INT32 * QuantCoeffsPtr = qi->QuantCoeffs[ColourPlane];
INT32 * ZBinPtr = qi->ZeroBinSize[ColourPlane];
INT32 * ZrlCorrection = qi->ZlrZbinCorrections[ColourPlane];
INT16 * DCT_blockPtr = DCT_block;
UINT8 Zrl = 0;
// Set the quantized_list to default to 0
memset( quantized_list, 0, 64 * sizeof(Q_LIST_ENTRY) );
// DC quantization
if ( DCT_blockPtr[0] >= ZBinPtr[0] )
{
temp = QuantCoeffsPtr[0] * ( DCT_blockPtr[0] + QuantRoundPtr[0] );
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else if ( DCT_blockPtr[0] <= -ZBinPtr[0] )
{
temp = QuantCoeffsPtr[0] * ( DCT_blockPtr[0] - QuantRoundPtr[0] ) + MIN16;
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else
Zrl++;
// Quantize AC
for( i=1; i<64; i++ )
{
// Zig Zag order...
j = dequant_index[i];
if ( DCT_blockPtr[j] >= (ZBinPtr[j] + ZrlCorrection[Zrl]) )
{
temp = QuantCoeffsPtr[j] * ( DCT_blockPtr[j] + QuantRoundPtr[j] );
quantized_list[i] = (Q_LIST_ENTRY) (temp>>16);
Zrl = 0;
}
else if ( DCT_blockPtr[j] <= -(ZBinPtr[j] + ZrlCorrection[Zrl]) )
{
temp = QuantCoeffsPtr[j] * ( DCT_blockPtr[j] - QuantRoundPtr[j] ) + MIN16;
quantized_list[i] = (Q_LIST_ENTRY) (temp>>16);
Zrl = 0;
}
else
Zrl++;
}
}
/**************************** END COMPRESSOR SPECIFIC **********************************/
/****************************************************************************
*
* ROUTINE : DeleteQuantizerBuffers
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocates buffers associated with the quantizer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
static void DeleteQuantizerBuffers ( QUANTIZER *qi )
{
if ( qi->dequant_coeffsAlloc[0] )
duck_free(qi->dequant_coeffsAlloc[0]);
qi->dequant_coeffsAlloc[0] = 0;
qi->dequant_coeffs[0] = 0;
if ( qi->dequant_coeffsAlloc[1] )
duck_free(qi->dequant_coeffsAlloc[1]);
qi->dequant_coeffsAlloc[1] = 0;
qi->dequant_coeffs[1] = 0;
}
/****************************************************************************
*
* ROUTINE : AllocateQuantizerBuffers
*
* INPUTS : QUANTIZER *qi : Pointer to quantizer instance.
*
* OUTPUTS : None.
*
* RETURNS : INT32: Always TRUE.
*
* FUNCTION : Allocates buffers associated with quantization.
*
* SPECIAL NOTES : Uses ROUNDUP32 to ensure that allocated buffers are
* aligned on 32-byte boundaries to improve cache performance.
*
****************************************************************************/
// TODO: benski> need better checks for other compilers
#if defined(_M_AMD64) || defined(__LP64__)
#define ROUNDUP32(X) ( ( ( (uintptr_t) X ) + 31 )&( 0xFFFFFFFFFFFFFFE0 ) )
#else //#elif //defined(_M_IX86)
#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
#endif
static INT32 AllocateQuantizerBuffers ( QUANTIZER *qi )
{
DeleteQuantizerBuffers(qi);
qi->dequant_coeffsAlloc[0] = (INT16 *)duck_malloc(32+64*sizeof(INT16), DMEM_GENERAL);
if ( !qi->dequant_coeffsAlloc[0] ) { DeleteQuantizerBuffers(qi); return FALSE; };
qi->dequant_coeffs[0] = (INT16 *)ROUNDUP32(qi->dequant_coeffsAlloc[0]);
qi->dequant_coeffsAlloc[1] = (INT16 *)duck_malloc(32+64*sizeof(INT16), DMEM_GENERAL);
if ( !qi->dequant_coeffsAlloc[1] ) { DeleteQuantizerBuffers(qi); return FALSE; };
qi->dequant_coeffs[1] = (INT16 *)ROUNDUP32(qi->dequant_coeffsAlloc[1]);
return TRUE;
}
/****************************************************************************
*
* ROUTINE : VP6_DeleteQuantizer
*
* INPUTS : QUANTIZER **qi : Pointer to pointer to quantizer instance.
*
* OUTPUTS : QUANTIZER **qi : Pointer to pointer to quantizer instance,
* set to NULL on exit.
*
* RETURNS : void.
*
* FUNCTION : De-allocates memory associated with the quantizer.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DeleteQuantizer ( QUANTIZER **qi )
{
if ( *qi )
{
// Delete any other dynamically allocaed temporary buffers
DeleteQuantizerBuffers(*qi);
// De-allocate the quantizer
duck_free(*qi);
*qi=0;
}
}
/****************************************************************************
*
* ROUTINE : VP6_CreateQuantizer
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : Pointer to allocated quantizer instance.
*
* FUNCTION : Allocated memory for and initializes a quantizer instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
QUANTIZER *VP6_CreateQuantizer ( void )
{
QUANTIZER *qi = 0;
int quantizer_size = sizeof(QUANTIZER);
qi = (QUANTIZER *) duck_malloc(quantizer_size, DMEM_GENERAL);
if ( !qi )
return 0;
// initialize whole structure to 0
memset ( (unsigned char *)qi, 0, quantizer_size );
if ( !AllocateQuantizerBuffers(qi) )
VP6_DeleteQuantizer(&qi);
return qi;
}
/****************************************************************************
*
* ROUTINE : GetQuantizedCoeffsMSE_RD
*
* INPUTS : CP_INSTANCE *cpi : Pointer to encoder instance.
* INT16 * DctCodes : Result of Forward DCT
* INT16 * Coeffs, : Quantized Coeffs
* INT16 * DequantMatrix, : Dequantizaton Matrix
*
*
* OUTPUTS : UINT32 *MSE : Mean Square Error
*
* RETURNS : void
*
* FUNCTION : Computer MSE in transform domain.
*
* SPECIAL NOTES : From the arguement that the mse in frequency domain
* is same as the mse in spatial domain, this routine
* calculate the mse in transform domain to saving the
* idct and recon operations for distortion measurement.
*
****************************************************************************/
void GetQuantizedCoeffsMSE_RD
(
INT16 * DctCodes,
INT16 * Coeffs,
INT16 * DequantMatrix,
UINT32 *MSE
)
{
UINT32 Error=0;
INT32 i;
INT32 diff;
for(i=0;i<64;i++)
{
int j = dequant_index[i];
diff = Coeffs[i] * DequantMatrix [i] - DctCodes[j];
Error += diff*diff;
}
*MSE = (Error<<2);
}
@@ -0,0 +1,603 @@
/****************************************************************************
*
* Module Title : recon.c
*
* Description : Frame reconstruction functions.
*
****************************************************************************/
#define STRICT /* Strict type checking. */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h>
#include "pbdll.h"
/****************************************************************************
* Macros
****************************************************************************/
#define TMAX 6
#define TMIN 1
#define Mod8(a) ((a) & 7)
/***************************************************************************
*
* ROUTINE : Var16Point
*
* INPUTS : UINT8 *DataPtr : Pointer to data block.
* INT32 SourceStride : Block stride.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Calculated 16-point variance (no scaling).
*
* FUNCTION : Calculates variance for the 8x8 block *BUT* only samples
* every second pixel in every second row of the block. In
* other words for the 8x8 block only 16 sample points are used.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 Var16Point ( UINT8 *DataPtr, INT32 SourceStride )
{
UINT32 i;
UINT32 XSum=0;
UINT32 XXSum=0;
UINT8 *DiffPtr;
// Loop expanded out for speed.
DiffPtr = DataPtr;
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i+=2 )
{
// Examine alternate pixel locations.
XSum += DiffPtr[0];
XXSum += DiffPtr[0] * DiffPtr[0];
XSum += DiffPtr[2];
XXSum += DiffPtr[2] * DiffPtr[2];
XSum += DiffPtr[4];
XXSum += DiffPtr[4] * DiffPtr[4];
XSum += DiffPtr[6];
XXSum += DiffPtr[6] * DiffPtr[6];
// Step to next row of block.
DiffPtr += (SourceStride << 1);
}
// Compute population variance as mis-match metric.
return (( (XXSum<<4) - XSum*XSum ) ) >> 8;
}
/***************************************************************************
*
* ROUTINE : DiffVar16Point
*
* INPUTS : UINT8 *DataPtr : Pointer to data block.
* INT32 SourceStride : Block stride.
*
* OUTPUTS : None.
*
* RETURNS : UINT32: Calculated 16-point variance (no scaling).
*
* FUNCTION : Calculates a variance for 16 data values.
* Each data value is the absolute difference between a pair of samples
* one line and one column apart
*
* SPECIAL NOTES : None.
*
****************************************************************************/
UINT32 DiffVar16Point ( UINT8 *DataPtr, INT32 SourceStride )
{
UINT32 i;
INT32 X;
UINT32 XSum=0;
UINT32 XXSum=0;
UINT8 *DiffPtr;
UINT8 *DiffPtr2;
// Loop expanded out for speed.
DiffPtr = DataPtr;
DiffPtr2 = DataPtr + SourceStride + 1;
for ( i=0; i<BLOCK_HEIGHT_WIDTH; i+=2 )
{
// Examine alternate pixel locations.
X = abs( DiffPtr[0] - DiffPtr2[0]);
XSum += X;
XXSum += X * X;
X = abs( DiffPtr[2] - DiffPtr2[2]);
XSum += X;
XXSum += X * X;
X = abs( DiffPtr[4] - DiffPtr2[4]);
XSum += X;
XXSum += X * X;
X = abs( DiffPtr[6] - DiffPtr2[6]);
XSum += X;
XXSum += X * X;
// Step to next row of block.
DiffPtr += (SourceStride << 1);
DiffPtr2 += (SourceStride << 1);
}
// Compute population variance as mis-match metric.
return (( (XXSum<<4) - XSum*XSum ) ) >> 8;
}
/****************************************************************************
*
* ROUTINE : InitLoopDeringThresholds
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Initialise thresholds used in the prediction/loop
* deringing filter.
*
* SPECIAL NOTES :
*
*****************************************************************************/
void InitLoopDeringThresholds ( PB_INSTANCE *pbi )
{
UINT32 i;
pbi->DrCutOff = 64;
for ( i=0; i<pbi->DrCutOff; i++ )
pbi->DrThresh[255 - i] = ((TMAX * pbi->DrCutOff) - ((TMAX - TMIN) * i)) / pbi->DrCutOff;
for ( i=pbi->DrCutOff; i<255; i++ )
pbi->DrThresh[255 - i] = TMIN;
}
/****************************************************************************
*
* ROUTINE : LoopDeringBlock
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT8 *SrcPtr : Pointer to block to be deringed.
* UINT32 Stride : Stride for input block data.
* UINT32 Width : Block width.
* UINT32 Height : Block height.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Applies a thresholded dering/smoothing filter to a block
* of data.
*
* SPECIAL NOTES :
*
*****************************************************************************/
void LoopDeringBlock
(
PB_INSTANCE *pbi,
UINT8 *SrcPtr,
UINT32 Stride,
UINT32 Width,
UINT32 Height
)
{
UINT32 i,j;
UINT8 *DataPtr0;
UINT8 *DataPtr1;
UINT8 *DataPtr2;
UINT8 TmpBuffer[16]; // TBD only one value needed... clean up code
INT32 ADiff1;
INT32 ADiff2;
INT32 Sum;
INT32 Thresh;
UINT8 Min = 255;
UINT8 Max = 0;
// Look for the min and max value in the block
DataPtr1 = SrcPtr;
for ( i=0; i<Height; i++ )
{
for ( j=0; j<Width; j++ )
{
if ( *DataPtr1 < Min )
Min = *DataPtr1;
if ( *DataPtr1 > Max )
Max = *DataPtr1;
DataPtr1++;
}
DataPtr1 = (DataPtr1 - Width) + Stride;
}
// Now choose the dering threshold
if ( pbi->DrThresh[255 - Min] > pbi->DrThresh[Max] )
Thresh = pbi->DrThresh[255 - Min];
else
Thresh = pbi->DrThresh[Max];
// Threshold bigger for bigger range
Thresh += ((Max - Min) >> 5);
// Horizontal dering
DataPtr1 = SrcPtr;
for ( i=0; i<Height; i++ )
{
for ( j=0; j<Width; j++ )
{
ADiff1 = abs( (INT32)DataPtr1[j] - (INT32)DataPtr1[j-1] );
ADiff2 = abs( (INT32)DataPtr1[j] - (INT32)DataPtr1[j+1] );
Sum = DataPtr1[j] + DataPtr1[j];
if ( ADiff1 <= Thresh )
Sum += DataPtr1[j-1];
else
Sum += DataPtr1[j];
if ( ADiff2 <= Thresh )
Sum += DataPtr1[j+1];
else
Sum += DataPtr1[j];
Sum = (Sum + 2) >> 2;
TmpBuffer[j] = Sum;
}
// Copy back the filtered line
memcpy ( DataPtr1, TmpBuffer, Width );
// Next line
DataPtr1 += Stride;
}
// Vertical dering
for ( i=0; i<Width; i++ )
{
DataPtr1 = SrcPtr + i;
DataPtr0 = DataPtr1 - Stride;
DataPtr2 = DataPtr1 + Stride;
for ( j=0; j<Height; j++ )
{
ADiff1 = abs( (INT32)*DataPtr1 - (INT32)*DataPtr0 );
ADiff2 = abs( (INT32)*DataPtr1 - (INT32)*DataPtr2 );
Sum = *DataPtr1 + *DataPtr1;
if ( ADiff1 <= Thresh )
Sum += *DataPtr0;
else
Sum += *DataPtr1;
if ( ADiff2 <= Thresh )
Sum += *DataPtr2;
else
Sum += *DataPtr1;
Sum = (Sum + 2) >> 2;
TmpBuffer[j] = Sum;
DataPtr0 += Stride;
DataPtr1 += Stride;
DataPtr2 += Stride;
}
// Copy back the filtered data
DataPtr1 = SrcPtr + i;
for ( j=0; j<Height; j++ )
{
*DataPtr1 = TmpBuffer[j];
DataPtr1 += Stride;
}
}
}
/****************************************************************************
*
* ROUTINE : VP6_PredictFiltered
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* UINT8 *SrcPtr : Pointer to block to be filtered.
* INT32 mx :
* INT32 my :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Build an 8x8 motion prediction block. If the block is
* copied across a block boundary, attempt to eliminate
* the internal border by applying the loop filter internally.
*
* SPECIAL NOTES : None.
*
*****************************************************************************/
void VP6_PredictFiltered
(
PB_INSTANCE *pbi,
UINT8 *SrcPtr,
INT32 mx,
INT32 my,
UINT32 bp
)
{
INT32 mVx, mVy;
INT32 ReconIndex;
MACROBLOCK_INFO *mbi=&pbi->mbi;
UINT8 *TempBuffer = pbi->LoopFilteredBlock;
INT32 BoundaryX, BoundaryY;
// Calculate full pixel motion vector position
if(mx > 0 )
mVx = (mx >> pbi->mbi.blockDxInfo[bp].MvShift);
else
mVx = -((-mx) >> pbi->mbi.blockDxInfo[bp].MvShift);
if(my > 0 )
mVy = (my >> pbi->mbi.blockDxInfo[bp].MvShift);
else
mVy = -((-my) >> pbi->mbi.blockDxInfo[bp].MvShift);
// calculate offset in last frame matching motion vector
ReconIndex = mbi->blockDxInfo[bp].FrameReconStride * mVy + mVx;
// Give our selves a border of 2 extra pixel on all sides (for loop filter and half pixel moves)
ReconIndex -= 2 * mbi->blockDxInfo[bp].CurrentReconStride;
ReconIndex -= 2;
// copy the 12x12 region starting from reconpixel index into our temp buffer.
Copy12x12( SrcPtr + ReconIndex, TempBuffer, mbi->blockDxInfo[bp].CurrentReconStride, 16);
// What sort of loop filtering are we doing
// Dering loop filter is mandated to OFF in the current bitstream#
//if ( pbi->UseLoopFilter == LOOP_FILTER_DERING )
if ( FALSE )
{
// Apply prediction.loop dering filter
LoopDeringBlock( pbi, &TempBuffer[16+1], 16, 10, 10 );
}
else
{
// calculate block border position for x
BoundaryX = (8 - Mod8(mVx))&7;
// calculate block border position for y
BoundaryY = (8 - Mod8(mVy))&7;
// apply the loop filter at the horizontal boundary we selected
if(BoundaryX)
FilteringHoriz_12(
pbi->quantizer->FrameQIndex,
TempBuffer + 2 + BoundaryX,
16);
// apply the loop filter at the vertical boundary we selected
if (BoundaryY)
FilteringVert_12(
pbi->quantizer->FrameQIndex,
TempBuffer + 2 * 16 + BoundaryY * 16,
16);
}
}
/****************************************************************************
*
* ROUTINE : PredictFilteredBlock
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* INT16 *OutputPtr : Pointer to output data.
* BLOCK_POSITION bp : Position of block within MB.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Build an 8x8 motion prediction block. If the block is
* copied across a block boundary, attempt to eliminate
* the internal border by applying the loop filter internally.
*
* SPECIAL NOTES :
*
*****************************************************************************/
void VP6_PredictFilteredBlock
(
PB_INSTANCE *pbi,
INT16 *OutputPtr,
UINT32 bp
)
{
UINT8 *SrcPtr;
UINT8 *TempBuffer;
UINT32 TempPtr1;
UINT32 TempPtr2;
INT32 ModX, ModY;
UINT32 IVar;
UINT32 BicMvSizeLimit;
UINT32 Stride;
UINT32 MvShift = pbi->mbi.blockDxInfo[bp].MvShift; //pbi->mbi.MvShift;
UINT32 MvModMask = pbi->mbi.blockDxInfo[bp].MvModMask; //pbi->mbi.MvModMask;
// Which buffer are we working on?
SrcPtr = pbi->LastFrameRecon;
if ( VP6_Mode2Frame[pbi->mbi.Mode] == 2 )
{
SrcPtr = pbi->GoldenFrame;
}
// No loop filtering in simple profile
if ( pbi->VpProfile == SIMPLE_PROFILE || (pbi->UseLoopFilter == NO_LOOP_FILTER) )
{
INT32 mVx, mVy;
INT32 mx = pbi->mbi.Mv[bp].x;
INT32 my = pbi->mbi.Mv[bp].y;
// Mask off fractional pel bits.
ModX = (mx & MvModMask);
ModY = (my & MvModMask);
// Calculate full pixel motion vector position
mx += (MvModMask&(mx>>31));
my += (MvModMask&(my>>31));
mVx = (mx >> MvShift);
mVy = (my >> MvShift);
// Set up a pointer into the recon buffer
TempBuffer = SrcPtr + pbi->mbi.blockDxInfo[bp].thisRecon + (pbi->mbi.blockDxInfo[bp].FrameReconStride * mVy + mVx);
Stride = pbi->mbi.blockDxInfo[bp].CurrentReconStride;
TempPtr1 = TempPtr2 = 0;
}
else
{
// Loop filter the block
VP6_PredictFiltered( pbi, SrcPtr + pbi->mbi.blockDxInfo[bp].thisRecon, pbi->mbi.Mv[bp].x, pbi->mbi.Mv[bp].y, bp );
TempBuffer = pbi->LoopFilteredBlock;
Stride = 16;
TempPtr1 = 2*16+2; // Offset into the 12x12 loop filtered buffer
TempPtr2 = TempPtr1;
// Mask off fractional pel bits.
ModX = (pbi->mbi.Mv[bp].x & MvModMask);
ModY = (pbi->mbi.Mv[bp].y & MvModMask);
}
// determine if we have a fractional pixel move in the x direction
if ( ModX )
{
TempPtr2 += ( pbi->mbi.Mv[bp].x > 0 )*2 -1;
}
// handle fractional pixel motion in Y
if ( ModY )
{
TempPtr2 += (( pbi->mbi.Mv[bp].y > 0 ) * 2 - 1)*Stride;
}
// put the results back into the real reconstruction buffer
if ( TempPtr1 != TempPtr2 )
{
// The FilterBlock selects a filter based upon a ModX and ModY value that are at 1/8 point
// precision. Because U and V are subsampled the vector is already at the right precision
// for U and V but for Y we have to multiply by 2.
if ( bp < 4 )
{
// Filterblock expects input at 1/8 pel resolution (hence << 1 for Y)
ModX = ModX << 1;
ModY = ModY << 1;
// Select the filtering mode
if ( pbi->VpProfile == SIMPLE_PROFILE )
{
// Simple profile always uses bilinear filtering for speed
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, FALSE, 14 );
}
else if ( pbi->PredictionFilterMode == AUTO_SELECT_PM )
{
// Work out the Mv size limit for selecting bicubic
if ( pbi->PredictionFilterMvSizeThresh > 0 )
BicMvSizeLimit = (1 << (pbi->PredictionFilterMvSizeThresh - 1)) << 2; // Convert to a value in 1/4 pel units
else
BicMvSizeLimit = ((MAX_MV_EXTENT >> 1) + 1) << 2; // Unrestricted
// Only use bicubic on shortish vectors
if ( ( pbi->PredictionFilterMvSizeThresh != 0 ) &&
( ( (UINT32)abs(pbi->mbi.Mv[bp].x) > BicMvSizeLimit ) || ( (UINT32)abs(pbi->mbi.Mv[bp].y) > BicMvSizeLimit ) ) )
{
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, FALSE, pbi->PredictionFilterAlpha);
}
// Should we use a variance test for bicubic as well
else if ( pbi->PredictionFilterVarThresh != 0 )
{
IVar = Var16Point( &TempBuffer[TempPtr1], Stride );
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, (IVar >= pbi->PredictionFilterVarThresh), pbi->PredictionFilterAlpha );
}
else
{
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, TRUE, pbi->PredictionFilterAlpha );
}
}
else
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, (pbi->PredictionFilterMode == BICUBIC_ONLY_PM), pbi->PredictionFilterAlpha );
}
else
{
FilterBlock( &TempBuffer[TempPtr1], &TempBuffer[TempPtr2], (unsigned short *)OutputPtr, Stride, ModX, ModY, FALSE, pbi->PredictionFilterAlpha );
}
}
// No fractional pels
else
UnpackBlock(&TempBuffer[TempPtr1], OutputPtr, Stride );
}
/****************************************************************************
*
* ROUTINE : ReconstructBlock
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* BLOCK_POSITION bp : Position of block within MB.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Reconstructs the coded block depending on coding mode.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_ReconstructBlock ( PB_INSTANCE *pbi, BLOCK_POSITION bp )
{
UINT32 thisRecon = pbi->mbi.blockDxInfo[bp].thisRecon;
// Action depends on decode mode.
if ( pbi->mbi.Mode == CODE_INTER_NO_MV ) // Inter with no motion vector
{
ReconInter( pbi->TmpDataBuffer,
(UINT8 *)&pbi->ThisFrameRecon[thisRecon],
(UINT8 *)&pbi->LastFrameRecon[thisRecon],
(INT16 *)pbi->ReconDataBuffer[bp],
pbi->mbi.blockDxInfo[bp].CurrentReconStride);
}
else if ( VP6_ModeUsesMC[pbi->mbi.Mode] ) // The mode uses a motion vector.
{
// For the compressor we did this already ( possible optimization).
VP6_PredictFilteredBlock( pbi, pbi->TmpDataBuffer,bp);
ReconBlock( pbi->TmpDataBuffer,
(INT16 *)pbi->ReconDataBuffer[bp],
(UINT8 *)&pbi->ThisFrameRecon[thisRecon],
pbi->mbi.blockDxInfo[bp].CurrentReconStride );
}
else if ( pbi->mbi.Mode == CODE_USING_GOLDEN ) // Golden frame with motion vector
{
// Reconstruct the pixel data using the golden frame reconstruction and change data
ReconInter( pbi->TmpDataBuffer,
(UINT8 *)&pbi->ThisFrameRecon[thisRecon],
(UINT8 *)&pbi->GoldenFrame[thisRecon],
(INT16 *)pbi->ReconDataBuffer[bp],
pbi->mbi.blockDxInfo[bp].CurrentReconStride );
}
else // Simple Intra coding
{
// Get the pixel index for the first pixel in the fragment.
ReconIntra( pbi->TmpDataBuffer,
(UINT8 *)&pbi->ThisFrameRecon[thisRecon],
(UINT16 *)pbi->ReconDataBuffer[bp],
pbi->mbi.blockDxInfo[bp].CurrentReconStride );
}
}
@@ -0,0 +1,605 @@
/****************************************************************************
*
* Module Title : vfwpbdll_if.c
*
* Description : Video codec playback dll interface
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h>
#include "pbdll.h"
#include "vp60dversion.h"
/****************************************************************************
* Macros
****************************************************************************/
#ifndef _MSC_VER
#define __try
#define CommentString "\nON2.COM VERSION VP60D " VP60DVERSION "\n"
#pragma comment(exestr,CommentString)
#endif
/****************************************************************************
* Imports
****************************************************************************/
extern unsigned int CPUFrequency;
extern void VP6_DecodeFrameMbs(PB_INSTANCE *pbi);
extern void VP6_InitialiseConfiguration(PB_INSTANCE *pbi);
extern void InitHeaderBuffer ( FRAME_HEADER *Header, unsigned char *Buffer );
extern void SetAddNoiseMode(POSTPROC_INST , int);
#include <stdio.h>
/****************************************************************************
* Module Statics
****************************************************************************/
static const char vp31dVersion[] = VP60DVERSION;
/****************************************************************************
* Exports
****************************************************************************/
#ifdef PBSTATS1
static INT32 TotQ = 0; // TEMP diagnostic variables
static INT32 PBFrameNumber = 0;
#endif
/****************************************************************************
*
* ROUTINE : VP60D_GetVersionNumber
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : const char *: Pointer to decoder version string.
*
* FUNCTION : Returns a pointer to the decoder version string.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
const char * CCONV VP60D_GetVersionNumber ( void )
{
return vp31dVersion;
}
/****************************************************************************
*
* ROUTINE : VP6_StartDecoder
*
* INPUTS : PB_INSTANCE **pbi : Pointer to pointer to decoder instance.
* UINT32 ImageWidth : Width of the image.
* UINT32 ImageHeight : Height of the image.
*
* OUTPUTS : None.
*
* RETURNS : TRUE if succeeds, FALSE otherwise.
*
* FUNCTION : Creates and initializes the decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
BOOL CCONV VP6_StartDecoder( PB_INSTANCE **pbi, UINT32 ImageWidth, UINT32 ImageHeight )
{
__try
{
// set up our structure holding all formerly global information about a playback instance
*pbi = VP6_CreatePBInstance();
// Set Flag to indicate that a key frame is required as the first input
(*pbi)->ScaleWidth = ImageWidth;
(*pbi)->ScaleHeight = ImageHeight;
(*pbi)->OutputWidth = ImageWidth;
(*pbi)->OutputHeight = ImageHeight;
// Validate the combination of height and width.
(*pbi)->Configuration.VideoFrameWidth = ImageWidth;
(*pbi)->Configuration.VideoFrameHeight = ImageHeight;
(*pbi)->postproc = CreatePostProcInstance(&(*pbi)->Configuration);
(*pbi)->quantizer = VP6_CreateQuantizer();
(*pbi)->ProcessorFrequency = CPUFrequency;
// Fills in fragment counts as well
if ( !VP6_InitFrameDetails(*pbi) )
{
VP6_DeletePBInstance(pbi);
return FALSE;
}
// Set last_dct_thresh to an illegal value to make sure the
// Q tables are initialised for the new video sequence.
(*pbi)->quantizer->LastFrameQIndex = 0xFFFFFFFF;
// Set up various configuration parameters.
VP6_InitialiseConfiguration(*pbi);
return TRUE;
}
#if defined(_MSC_VER)
__except( TRUE )
{
VP6_ErrorTrap( *pbi, GEN_EXCEPTIONS );
return FALSE;
}
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_GetPbParam
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
* PB_COMMAND_TYPE Command : Command action specifier.
*
* OUTPUTS : UINT32 *Parameter : Command dependent value requested.
*
* RETURNS : void
*
* FUNCTION : Generalised command interface to decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV VP6_GetPbParam( PB_INSTANCE *pbi, PB_COMMAND_TYPE Command, UINT32 *Parameter )
{
switch ( Command )
{
#if defined(POSTPROCESS)
case PBC_SET_POSTPROC:
*Parameter = pbi->PostProcessingLevel;
#endif
default:
break;
}
}
/****************************************************************************
*
* ROUTINE : VP6_PickPostProcessingLevel
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
*
* OUTPUTS : None.
*
* RETURNS : int: Selected post-processing level.
*
* FUNCTION : Select the post-processing level to be used based
* on how fast we're decoding.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
#define CRITICALWATERMARK (int) (31000 * pbi->CPUFree / 100)
#define DOWNWATERMARK (int) (30000 * pbi->CPUFree / 100)
#define UPWATERMARK (int) (28000 * pbi->CPUFree / 100)
int VP6_PickPostProcessingLevel ( PB_INSTANCE *pbi )
{
int minimumTime = pbi->thisDecodeTime + pbi->avgBlitTime + pbi->avgPPTime[8];
int thisTime = minimumTime + pbi->avgPPTime[pbi->PostProcessingLevel];
int avgTime = pbi->avgDecodeTime + pbi->avgBlitTime;
// estimate the times of all of our unknown postprocessors
if(pbi->avgPPTime[6]==0)
pbi->avgPPTime[6] = avgTime>>1;
if(pbi->avgPPTime[5]==0)
pbi->avgPPTime[5] = avgTime>>1;
if(pbi->avgPPTime[4]==0)
pbi->avgPPTime[4] = (avgTime ) >> 2;
if(pbi->avgPPTime[8]==0)
pbi->avgPPTime[8] = avgTime>>3;
if(pbi->CPUFree == 0 )
return pbi->PostProcessingLevel;
// automatically select a postprocessing level based on the amount
// of time taken to decode blit and postprocess etc
// more than 1/30 of a second no postprocessing at all (its better to show an
// ugly frame than none at all). We use 1/30th of a second because nothing
// tells us the actual framerate
if ( thisTime > (int)(CRITICALWATERMARK) )
{
// this frame's taking too long try to make up time on the subsequent frames
pbi->avgDecodeTime = pbi->thisDecodeTime;
// pick a post processor we can decode in less than 2/3 the time
if(pbi->avgPPTime[6] + minimumTime < CRITICALWATERMARK )
return 6;
if(pbi->avgPPTime[5] + minimumTime < CRITICALWATERMARK )
return 5;
if(pbi->avgPPTime[4] + minimumTime < CRITICALWATERMARK )
return 4;
if(pbi->avgPPTime[8] + minimumTime < CRITICALWATERMARK )
return 8;
return 0;
}
if(thisTime < DOWNWATERMARK && thisTime > UPWATERMARK)
return pbi->PostProcessingLevel;
// pick a post processor we can decode in less than 2/3 the time
if(pbi->avgPPTime[6] + avgTime < UPWATERMARK )
return 6;
if(pbi->avgPPTime[5] + avgTime < UPWATERMARK )
return 5;
if(pbi->avgPPTime[4] + avgTime < UPWATERMARK )
return 4;
if(pbi->avgPPTime[8] + avgTime < UPWATERMARK )
return 8;
return 0;
}
/****************************************************************************
*
* ROUTINE : VP6_GetYUVConfig
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
* YUV_BUFFER_CONFIG *YuvConfig : Pointer to configuration
* data-structure.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Gets details of the reconstruction buffer
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV VP6_GetYUVConfig ( PB_INSTANCE *pbi, YUV_BUFFER_CONFIG *YuvConfig )
{
__try
{
#ifdef _MSC_VER
unsigned int duration;
unsigned int starttsc,endtsc;
VP6_readTSC(&starttsc);
pbi->PostProcessingLevel = VP6_PickPostProcessingLevel(pbi);
#endif
if( pbi->PostProcessingLevel || (pbi->Configuration.Interlaced && pbi->DeInterlaceMode) )
{
#ifdef _MSC_VER
extern void vp6_showinfo2(PB_INSTANCE *pbi);
extern void vp6_showinfo(PB_INSTANCE *pbi);
if ( pbi->PostProcessingLevel > 200 )
{
PostProcess (
pbi->postproc,
pbi->Vp3VersionNo,
pbi->FrameType,
pbi->PostProcessingLevel-200,
pbi->AvgFrameQIndex,
pbi->LastFrameRecon,
pbi->PostProcessBuffer,
(unsigned char *) pbi->FragInfo,
sizeof(FRAG_INFO),
0x0001 );
VP6_readTSC(&endtsc);
vp6_showinfo(pbi);
}
else if ( pbi->PostProcessingLevel > 100 )
{
PostProcess (
pbi->postproc,
pbi->Vp3VersionNo,
pbi->FrameType,
pbi->PostProcessingLevel-100,
pbi->AvgFrameQIndex,
pbi->LastFrameRecon,
pbi->PostProcessBuffer,
(unsigned char *) pbi->FragInfo,
sizeof(FRAG_INFO),
0x0001 );
VP6_readTSC(&endtsc);
vp6_showinfo2(pbi);
}
else
#endif
{
// pbi->AvgFrameQIndex = pbi->quantizer->FrameQIndex;
PostProcess (
pbi->postproc,
pbi->Vp3VersionNo,
pbi->FrameType,
pbi->PostProcessingLevel,
pbi->AvgFrameQIndex,
pbi->LastFrameRecon,
pbi->PostProcessBuffer,
(unsigned char *) pbi->FragInfo,
sizeof(FRAG_INFO),
0x0001 );
#ifdef _MSC_VER
VP6_readTSC(&endtsc);
#endif
}
}
if(pbi->BlackClamp)
ClampLevels( pbi->postproc,pbi->BlackClamp,pbi->WhiteClamp,pbi->PostProcessBuffer, pbi->PostProcessBuffer);
if( pbi->Configuration.VideoFrameWidth < pbi->OutputWidth &&
pbi->Configuration.VideoFrameHeight == pbi->OutputHeight )
{
YuvConfig->YWidth = pbi->OutputWidth+32;
YuvConfig->YHeight = pbi->OutputHeight+32;
YuvConfig->YStride = YuvConfig->YWidth;
YuvConfig->UVWidth = YuvConfig->YWidth / 2;
YuvConfig->UVHeight = YuvConfig->YHeight / 2;
YuvConfig->UVStride = YuvConfig->YStride / 2;
YuvConfig->YBuffer = (char *)pbi->ScaleBuffer;
YuvConfig->UBuffer = (char *)pbi->ScaleBuffer+YuvConfig->YWidth*YuvConfig->YHeight;
YuvConfig->VBuffer = (char *)pbi->ScaleBuffer+YuvConfig->YWidth*YuvConfig->YHeight+YuvConfig->UVWidth*YuvConfig->UVHeight;
if(pbi->PostProcessingLevel)
ScaleOrCenter( pbi->postproc, pbi->PostProcessBuffer, YuvConfig );
else
ScaleOrCenter( pbi->postproc, pbi->LastFrameRecon, YuvConfig );
YuvConfig->YBuffer +=
(YuvConfig->YHeight - pbi->OutputHeight ) / 2 * YuvConfig->YStride
+(YuvConfig->YWidth - pbi->OutputWidth) / 2;
YuvConfig->YWidth = pbi->OutputWidth;
YuvConfig->YHeight = pbi->OutputHeight;
YuvConfig->UBuffer +=
(YuvConfig->UVHeight - pbi->OutputHeight/2 ) / 2 * YuvConfig->UVStride
+(YuvConfig->UVWidth - pbi->OutputWidth/2) / 2;
YuvConfig->VBuffer +=
(YuvConfig->UVHeight - pbi->OutputHeight/2 ) / 2 * YuvConfig->UVStride
+(YuvConfig->UVWidth - pbi->OutputWidth/2) / 2;
YuvConfig->UVWidth = pbi->OutputWidth / 2;
YuvConfig->UVHeight = pbi->OutputHeight / 2;
}
else
{
YuvConfig->YWidth = pbi->Configuration.VideoFrameWidth;
YuvConfig->YHeight = pbi->Configuration.VideoFrameHeight;
YuvConfig->YStride = pbi->Configuration.YStride;
YuvConfig->UVWidth = pbi->Configuration.VideoFrameWidth / 2;
YuvConfig->UVHeight = pbi->Configuration.VideoFrameHeight / 2;
YuvConfig->UVStride = pbi->Configuration.UVStride;
if( pbi->PostProcessingLevel ||(pbi->Configuration.Interlaced && pbi->DeInterlaceMode))
{
YuvConfig->YBuffer = (char *)&pbi->PostProcessBuffer[pbi->ReconYDataOffset+(pbi->Configuration.YStride * UMV_BORDER) + UMV_BORDER];
YuvConfig->UBuffer = (char *)&pbi->PostProcessBuffer[pbi->ReconUDataOffset+ (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2)];
YuvConfig->VBuffer = (char *)&pbi->PostProcessBuffer[pbi->ReconVDataOffset+ (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2)];
}
else
{
YuvConfig->YBuffer = (char *)&pbi->LastFrameRecon[pbi->ReconYDataOffset+ (pbi->Configuration.YStride * UMV_BORDER) + UMV_BORDER];
YuvConfig->UBuffer = (char *)&pbi->LastFrameRecon[pbi->ReconUDataOffset+ (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2)];
YuvConfig->VBuffer = (char *)&pbi->LastFrameRecon[pbi->ReconVDataOffset+ (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2)];
}
}
#if defined(_MSC_VER)
duration = ( endtsc - starttsc )/ pbi->ProcessorFrequency ;
if( pbi->avgPPTime[pbi->PostProcessingLevel%10] == 0)
pbi->avgPPTime[pbi->PostProcessingLevel%10] = duration;
else
pbi->avgPPTime[pbi->PostProcessingLevel%10] = ( 7 * pbi->avgPPTime[pbi->PostProcessingLevel%10] + duration ) >> 3;
#endif
}
#if defined(_MSC_VER)
__except ( TRUE )
{
VP6_ErrorTrap( pbi, GEN_EXCEPTIONS );
}
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_DecodeFrameToYUV
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* char *VideoBufferPtr : Pointer to compressed data buffer.
* unsigned int ByteCount : Size in bytes of compressed data buffer.
* UINT32 ImageWidth : Image width.
* UINT32 ImageHeight : Image height.
*
* OUTPUTS : None
*
* RETURNS : int: 0 for success, negative value for error.
*
* FUNCTION : Decodes a frame into the internal YUV reconstruction buffer.
* Details of this buffer can be obtained by calling GetYUVConfig().
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int CurrentFrame = 0;
int CCONV VP6_DecodeFrameToYUV(PB_INSTANCE *pbi, char *VideoBufferPtr, unsigned int ByteCount)
{
unsigned char *tmp;
__try
{
#ifdef _MSC_VER
unsigned int duration;
unsigned int starttsc,endtsc;
VP6_readTSC(&starttsc);
#endif
pbi->CurrentFrameSize = ByteCount;
// Initialise the bit reader used to read the fixed raw part of the header
InitHeaderBuffer ( &pbi->Header, (unsigned char*)VideoBufferPtr );
// decode the frame header
if ( !VP6_LoadFrame(pbi) )
return -1;
// Start the second boolean decoder
if ( pbi->MultiStream || (pbi->VpProfile == SIMPLE_PROFILE) )
{
pbi->mbi.br = &pbi->br2;
if ( pbi->UseHuffman )
{
// Initialise BITREADER for second bitstream partition
pbi->br3.bitsinremainder = 0;
pbi->br3.remainder = 0;
pbi->br3.position = ((unsigned char*)VideoBufferPtr)+pbi->Buff2Offset;
}
else
VP6_StartDecode(&pbi->br2,((unsigned char*)VideoBufferPtr)+pbi->Buff2Offset);
}
else
{
pbi->mbi.br = &pbi->br;
}
// decode and reconstruct frame
VP6_DecodeFrameMbs(pbi);
// switch pointers so lastframe recon is this frame
tmp = pbi->LastFrameRecon;
pbi->LastFrameRecon = pbi->ThisFrameRecon;
pbi->ThisFrameRecon = tmp;
// update the border
UpdateUMVBorder(pbi->postproc, pbi->LastFrameRecon);
// Update the golden frame buffer
if( (pbi->FrameType == BASE_FRAME) || pbi->RefreshGoldenFrame )
memcpy(pbi->GoldenFrame, pbi->LastFrameRecon, pbi->ReconYPlaneSize + 2* pbi->ReconUVPlaneSize);
#if defined(_MSC_VER)
ClearSysState();
#endif
#ifdef PBSTATS1
// Update PB stats
TotQ += pbi->quantizer->ThisFrameQualityValue;
PBFrameNumber += 1;
#endif
if(pbi->FrameType == BASE_FRAME )
pbi->AvgFrameQIndex = pbi->quantizer->FrameQIndex;
else
pbi->AvgFrameQIndex = (2 + 3 * pbi->AvgFrameQIndex + pbi->quantizer->FrameQIndex) / 4 ;
#ifdef _MSC_VER
VP6_readTSC(&endtsc);
duration = (endtsc-starttsc)/ (pbi->ProcessorFrequency);
pbi->thisDecodeTime = duration;
if( pbi->avgDecodeTime == 0)
pbi->avgDecodeTime = duration;
else
pbi->avgDecodeTime = (7*pbi->avgDecodeTime + duration)>>3;
#endif
#if 0
if (pbi->br.pos>pbi->CurrentFrameSize)
{
FILE *f = fopen("badframes.stt","a");
fprintf(f,"%8d %8d %8d \n", CurrentFrame,pbi->br.pos,pbi->CurrentFrameSize);
fclose(f);
}
#endif
CurrentFrame++;
}
#if defined(_MSC_VER)
__except ( TRUE )
{
VP6_ErrorTrap( pbi, GEN_EXCEPTIONS );
return -2;
}
#endif
return 0;
}
/****************************************************************************
*
* ROUTINE : VP6_StopDecoder
*
* INPUTS : PB_INSTANCE **pbi : Pointer to pointer to decoder instance.
*
* OUTPUTS : PB_INSTANCE **pbi : Pointer to pointer to decoder instance,
* set to NULL on return.
*
* RETURNS : int: TRUE on success, FALSE otherwise.
*
* FUNCTION : Detroys the decoder instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int CCONV VP6_StopDecoder ( PB_INSTANCE **pbi )
{
__try
{
if ( *pbi )
{
// Set flag to say that the decoder is no longer initialised
VP6_DeleteQuantizer(&(*pbi)->quantizer);
DeletePostProcInstance(&(*pbi)->postproc);
VP6_DeleteFragmentInfo(*pbi);
VP6_DeleteFrameInfo(*pbi);
VP6_DeletePBInstance(pbi);
return TRUE;
}
}
#if defined(_MSC_VER)
__except ( TRUE )
{
VP6_ErrorTrap( *pbi, GEN_EXCEPTIONS );
return FALSE;
}
#endif
return TRUE;
}
/****************************************************************************
*
* ROUTINE : VP6_ErrorTrap
*
* INPUTS : PB_INSTANCE *pbi : Pointer to decoder instance.
* int ErrorCode : Error code to report.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Called when a fatal error is detected.
*
* SPECIAL NOTES : Currently does nothing.
*
****************************************************************************/
void VP6_ErrorTrap ( PB_INSTANCE *pbi, int ErrorCode )
{
}
@@ -0,0 +1,454 @@
/****************************************************************************
*
* Module Title : vp5dxv.c
*
* Description : VP50 interface to DXV.
*
* AUTHOR : SJL
*
*****************************************************************************
* Revision History
*
* 1.03 SJL 17/10/02 Up the version to 1.0.0.3, added new dxv interface
* 1.02 YWX 30/09/02 Up the version to 1.0.0.2, added support of scaling
* 1.01 YWX 19/09/02 Fixed bug in blit and up the version to 1.0.0.1
* 1.00 SJL 17/06/02 Base
*
*****************************************************************************
*/
//#include <stdlib.h>
#include "duck_mem.h" /* interface to memory manager */
#include "dxl_plugin.h" /* interface to dxv */
#include "pbdll.h"
const char* VP6LIBVERSION="ON2 VP6 Decode Library for MAC Version 1.0.0.3";
typedef unsigned int FourCC;
#define VP60_FOURCC DXL_MKFOURCC( 'V', 'P', '6', '0')
#define VP61_FOURCC DXL_MKFOURCC( 'V', 'P', '6', '1')
static dxvBitDepth bitDepths[] =
{
DXYV12,DXRGBNULL
};
void vp60_SetParameter(DXL_XIMAGE_HANDLE src,int Command, unsigned int Parameter );
extern void VP6_VPInitLibrary(void);
extern void VP6_VPDeInitLibrary(void);
#include "duck_dxl.h"
#if 0
typedef struct tFrameInfo
{
int KeyFrame;
int Version;
int Quality;
int vp30Flag;
} FrameInfo;
void
vp60_GetInfo(unsigned char * source, FrameInfo * frameInfo)
{
// Is the frame and inter frame or a key frame
frameInfo->KeyFrame = !(source[0] > 0x7f);
frameInfo->Quality = source[0] >> 2;
if(frameInfo->KeyFrame)
frameInfo->Version = ((source[2]>>3) & 0x1f );
else
frameInfo->Version = 0;
frameInfo->vp30Flag = (int)source[1];
}
#endif
// YUV buffer configuration structure
typedef struct
{
int YWidth;
int YHeight;
int YStride;
int UVWidth;
int UVHeight;
int UVStride;
char * YBuffer;
char * UBuffer;
char * VBuffer;
char * uvStart;
int uvDstArea;
int uvUsedArea;
} DXV_YUV_BUFFER_CONFIG;
/* define an algorithm base container */
typedef struct tXImageCODEC
{
FourCC myFourCC;
DXV_YUV_BUFFER_CONFIG FrameBuffer;
PB_INSTANCE *myPBI;
int owned;
} vp60_XIMAGE, *vp60_XIMAGE_HANDLE;
typedef void ((*VP6BLIT_FUNC)(unsigned char *, int, YUV_BUFFER_CONFIG *));
//typedef void ((*vp6_VSCREEN_FUNC)(void));
/****************************************************************************
*
* ROUTINE : vp50_decompress
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION :
*
* SPECIAL NOTES :
*
****************************************************************************/
#include "huffman.h"
static int
vp60_decompress(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE vScreen)
{
int retVal;
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
unsigned char *cAddr;
int cSize;
int w, h;
DXL_GetXImageXYWH(src, NULL, NULL, &w, &h);
// if we have a compressed frame decompress it ( otherwise we'll just redo
// the scaling and postprocessing from the last frame )
cAddr = DXL_GetXImageCDataAddr(src);
cSize = DXL_GetXImageCSize(src);
if(cAddr)
{
if((cSize != 0) && (cAddr[0]>=1 || cAddr[1]>=1 || cAddr[2] >=1))
{
// decode the frame
retVal = VP6_DecodeFrameToYUV(thisAlgorithmBase->myPBI, (char *)cAddr, cSize, w, h);
if(retVal != 0 )
{
if(retVal == -1)
return DXL_VERSION_CONFLICT;
else
return DXL_BAD_DATA;
}
}
}
if (vScreen) /* if there is a vScreen, blit to it */
{
unsigned char * ptrScrn;
short thisPitch, vsHeight;
dxvBlitQuality bq;
dxvBitDepth bd;
VP6BLIT_FUNC blitter;
DXL_GetVScreenAttributes(vScreen, (void **)&ptrScrn, &bq, &bd, &thisPitch, &vsHeight);
if(ptrScrn)
{
int x, y, pSize;
int viewX, viewY;
DXL_GetVScreenView(vScreen, &viewX, &viewY, NULL, NULL);
/* get a frame pointer to the scaled and postprocessed reconstructed buffer */
VP6_GetYUVConfig(thisAlgorithmBase->myPBI, (YUV_BUFFER_CONFIG *) &(thisAlgorithmBase->FrameBuffer));
pSize = VPX_GetSizeOfPixel(bd);
DXL_GetXImageXYWH(src, &x, &y, NULL, NULL);
/* remember to offset if requested */
y += viewY;
x += viewX;
ptrScrn += (x * pSize) + (y * thisPitch);
/* setup ptrs so we can work backwards through Paul's frame buffers */
#if 1
thisAlgorithmBase->FrameBuffer.YBuffer = thisAlgorithmBase->FrameBuffer.YBuffer +
((thisAlgorithmBase->FrameBuffer.YHeight - 1) *
(thisAlgorithmBase->FrameBuffer.YStride));
thisAlgorithmBase->FrameBuffer.UBuffer = thisAlgorithmBase->FrameBuffer.UBuffer +
((thisAlgorithmBase->FrameBuffer.UVHeight - 1) *
(thisAlgorithmBase->FrameBuffer.UVStride));
thisAlgorithmBase->FrameBuffer.VBuffer = thisAlgorithmBase->FrameBuffer.VBuffer +
((thisAlgorithmBase->FrameBuffer.UVHeight - 1) *
(thisAlgorithmBase->FrameBuffer.UVStride));
#endif
if((bd != DXYUY2) && (bd != DXYV12))
{
if(bq == DXBLIT_STRETCH)
{
thisPitch *= 2;
}
}
if(bd == DXYV12 || bd == DXI420)
{
if(thisPitch < 0)
{
thisAlgorithmBase->FrameBuffer.uvStart = (char *) (ptrScrn + abs(thisPitch) + abs(thisPitch) * h/4 + thisPitch/2 );
thisAlgorithmBase->FrameBuffer.uvDstArea = abs((thisPitch * h)/4);
thisAlgorithmBase->FrameBuffer.uvUsedArea = 0;
}
else
{
thisAlgorithmBase->FrameBuffer.uvStart = (char *) (ptrScrn + (thisPitch * h));
thisAlgorithmBase->FrameBuffer.uvDstArea = ((thisPitch * h)/4);
thisAlgorithmBase->FrameBuffer.uvUsedArea = ((thisPitch * thisAlgorithmBase->FrameBuffer.UVHeight)/2);
}
}
blitter = (VP6BLIT_FUNC)VPX_GetBlitter(bq, bd);
if ((void *)blitter != (void *)-1)
{
blitter(ptrScrn, thisPitch, (YUV_BUFFER_CONFIG *)(&thisAlgorithmBase->FrameBuffer));
}
else
{
return DXL_INVALID_BLIT;
}
}
}
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_xImageDestroy
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION : close down a decompressor, releasing the wilk decompressor,
* the xImage (decompressor), and the intermediate vScreen (surface)
*
* SPECIAL NOTES :
*
****************************************************************************/
static int
vp60_xImageDestroy(DXL_XIMAGE_HANDLE src)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
if(thisAlgorithmBase)
{
if ( thisAlgorithmBase->owned )
VP6_StopDecoder ( &(thisAlgorithmBase->myPBI) );
duck_free ( thisAlgorithmBase );
}
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp50_xImageReCreate
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION :
*
* SPECIAL NOTES :
* called during initialization and/or when xImage (decompressor)
* attributes change, note that nImage and src are actually
* synonymous and should be cleared out a bit (to say the least!)
*
*
* !!!!!!
* This function should be prepared to get data that is NOT of the
* type native to the decoder, It should do it's best to verify it
* as valid data and should clean up after itself and return NULL
* if it doesn't recognize the format of the data
*
****************************************************************************/
static void *
vp60_xImageReCreate(DXL_XIMAGE_HANDLE src, unsigned char *data, int type, enum BITDEPTH bitDepth, int w, int h)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
(void) bitDepth;
if (
(type != VP60_FOURCC) &&
(type != VP61_FOURCC) &&
(type != DXL_MKFOURCC( 'V', 'P', '6', '2'))
)
return NULL;
thisAlgorithmBase->myFourCC = type;
/* create new PBI */
if ( !VP6_StartDecoder( &(thisAlgorithmBase->myPBI), w, h ) )
{
vp60_xImageDestroy ( src );
thisAlgorithmBase = NULL;
}
else
{
thisAlgorithmBase->owned = 1;
}
return (DXL_HANDLE)thisAlgorithmBase;
}
/****************************************************************************
*
* ROUTINE : vp50_xImageCreate
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION :
*
* SPECIAL NOTES : in this "glue" case, just calls through to the create function.
*
****************************************************************************/
static DXL_HANDLE
vp60_xImageCreate (DXL_XIMAGE_HANDLE src, unsigned char *data)
{
// return vp60_xImageReCreate(src, data, VP60_FOURCC, (enum BITDEPTH ) 0, 320, 240);
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
/* create a new xImage, specific to this type of decoder,
(see "vp60_XIMAGE" struct above and dxl_main.h) */
thisAlgorithmBase = (vp60_XIMAGE_HANDLE)duck_calloc ( 1, sizeof(vp60_XIMAGE), DMEM_GENERAL );
if (thisAlgorithmBase == NULL)
return NULL;
DXL_RegisterXImageRecreate(src, (RECREATE_FUNC) vp60_xImageReCreate);
DXL_RegisterXImageDestroy(src, (DESTROY_FUNC) vp60_xImageDestroy);
DXL_RegisterXImageDx(src, (DX_FUNC) vp60_decompress);
DXL_RegisterXImageSetParameter(src, (SET_PARAMETER_FUNC) vp60_SetParameter);
thisAlgorithmBase->myFourCC = VP60_FOURCC;
return (DXL_HANDLE)thisAlgorithmBase;
}
/****************************************************************************
*
* ROUTINE : vp50_Init
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int
vp60_Init(void)
{
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, VP60_FOURCC);
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, VP61_FOURCC);
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, DXL_MKFOURCC( 'V', 'P', '6', '2'));
vp3SetBlit();
/* initialize all the global variables */
VP6_VPInitLibrary();
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_Exit
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION : main exit routine, called during DXL_ExitVideo()
* clean up any global information if necessary
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int
vp60_Exit(void)
{
VP6_VPDeInitLibrary();
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE :
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void
vp60_SetParameter(DXL_XIMAGE_HANDLE src, int Command, uinptr_t Parameter)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
VP6_SetPbParam(thisAlgorithmBase->myPBI, (PB_COMMAND_TYPE) Command, Parameter );
}
@@ -0,0 +1,69 @@
## Target to built
TARGET =libvp6d
## TOOLS
CC = ecc
LD = ecc
AR = ar
OBJDUMP = objdump
RM = rm -f
## Directories
TOPDIR =C:\DuckSoft
PRIVATEINCLUDE =${TOPDIR}\private\include
PRIVATEINCLUDE2 =${TOPDIR}\private\include\vp60
CORELIBSINCLUDE =${TOPDIR}\private\corelibs\include
CDXVINCLUDE =${TOPDIR}\private\corelibs\cdxv\include
VP6INCLUDE =${TOPDIR}\private\corelibs\cdxv\vp60\vp60\include
CXGENERIC =${TOPDIR}\private\corelibs\cdxv\vp60\vp60\cx\generic
OBJDIR =${TOPDIR}\ObjectCode\bspvp6e
CURRENTDIR =${TOPDIR}\private\corelibs\cdxv\vp60\vp60
LIBDIR =${TOPDIR}\private\corelibs\lib\mapca
## Compile Flags
ALLINCLUDES =-I${VP6INCLUDE} -I${CDXVINCLUDE} -I${CORELIBSINCLUDE} -I${PRIVATEINCLUDE} -I${PRIVATEINCLUDE2}
VP6DEFINES =-DPREDICT_2D -DVFW_COMP -DCOMPDLL -DPOSTPROCESS -DCPUISLITTLEENDIAN -DNORMALIZED
ETIDEFINES =-DMAPCA
ALLDEFINES =${VP6DEFINES} ${ETIDEFINES}
DEBUG =-O2
CFLAGS =-msvc -align 8 -etswp -mP3OPT_nonlocal_calls_through_register=true \
-mP2OPT_suppress_library_call_conv_warnings=TRUE -maalign_branch_target \
-magen_interroutine_padding
ALLFLAGS = $(CFLAGS) ${ALLDEFINES} ${ALLINCLUDES} ${DEBUG}
## Files
OBJS = bsp\boolhuff.o \
generic\decodembs.o \
generic\decodemode.o \
generic\decodemv.o \
generic\DFrameR.o \
generic\FrameIni.o \
generic\Huffman.o \
generic\pb_globals.o \
generic\quantize.o \
generic\recon.o \
generic\TokenEntropy.o \
bsp\bspQuantize.o \
bsp\DSystemDependant.o \
bsp\duck_mem.o \
generic\vfwpbdll_if.o
SRCS = $(OBJS:.o=.c)
ARTARGET = ${TARGET}.a
# archive
ARTARGET:${OBJS}
${AR} -cr ${ARTARGET} ${OBJS}
mv ${ARTARGET} ${LIBDIR}
${OBJS} : ${SRCS}
$(CC) $(ALLFLAGS) -c $*.c -o $*.o
clean:
${RM} ${OBJS} ${ARTARGET}
@@ -0,0 +1,315 @@
/****************************************************************************
*
* Module Title : OptFunctions.c
*
* Description : MMX or otherwise processor specific
* optimised versions of functions
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.08 JBB 13 Jun 01 VP4 Code Clean Out
* 1.07 JBB 26/01/01 Removed unused function
* 1.06 YWX 23/05/00 Remove the clamping in MmxReconPostProcess()
* 1.05 YWX 15/05/00 Added MmxReconPostProcess()
* 1.04 SJL 03/14/00 Added in Tim's versions of MmxReconInter and MmxReconInterHalfPixel2.
* 1.03 PGW 12/10/99 Changes to reduce uneccessary dependancies.
* 1.02 PGW 30/08/99 Minor changes to MmxReconInterHalfPixel2().
* 1.01 PGW 13/07/99 Changes to keep reconstruction data to 16 bit
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/*
Use Tim's optimized version.
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT // Strict type checking.
#include "codec_common.h"
#include "pbdll.h"
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Imports.
*****************************************************************************
*/
extern INT32 * XX_LUT;
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Exported Functions
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
INT16 Ones[4] = {1,1,1,1};
INT16 OneTwoEight[4] = {128,128,128,128};
UINT8 Eight128s[8] = {128,128,128,128,128,128,128,128};
#pragma warning( disable : 4799 ) // Disable no emms instruction warning!
/****************************************************************************
* Forward References
*****************************************************************************
*/
/****************************************************************************
*
* ROUTINE : ClearSysState()
*
*
* INPUTS : None
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : DoesNothing
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void ClearSysStateC(void)
{
}
/****************************************************************************
*
* ROUTINE : ClearMmx()
*
*
* INPUTS : None
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Clears down the MMX state
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void ClearMmx(void)
{
__asm
{
emms ; Clear the MMX state.
}
}
/****************************************************************************
*
* ROUTINE : MMXReconIntra
*
* INPUTS : INT16 * idct
* Pointer to the output from the idct for this block
*
* UINT32 stride
* Line Length in pixels in recon and reference images
*
*
*
*
* OUTPUTS : UINT8 * dest
* The reconstruction buffer
*
* RETURNS : None
*
* FUNCTION : Reconstructs an intra block - MMX version
*
* SPECIAL NOTES : Tim Murphy's optimized version
*
*
* ERRORS : None.
*
****************************************************************************/
void MMXReconIntra( PB_INSTANCE *pbi, UINT8 * dest, INT16 * idct, INT32 stride )
{
__asm
{
// u pipe
// v pipe
mov eax,[idct] ; Signed 16 bit inputs
mov edx,[dest] ; Signed 8 bit outputs
movq mm0,[Eight128s] ; Set mm0 to 0x8080808080808080
;
mov ebx,[stride] ; Line stride in output buffer
lea ecx,[eax+128] ; Endpoint in input buffer
loop_label: ;
movq mm2,[eax] ; First four input values
;
packsswb mm2,[eax+8] ; pack with next(high) four values
por mm0,mm0 ; stall
pxor mm2,mm0 ; Convert result to unsigned (same as add 128)
lea eax,[eax + 16] ; Step source buffer
cmp eax,ecx ; are we done
;
movq [edx],mm2 ; store results
;
lea edx,[edx+ebx] ; Step output buffer
jc loop_label ; Loop back if we are not done
}
// 6c/8 elts = 9c/8 = 1.125 c/pix
}
/****************************************************************************
*
* ROUTINE : MmxReconInter
*
* INPUTS : UINT8 * RefPtr
* The last frame reference
*
* INT16 * ChangePtr
* Pointer to the change data
*
* UINT32 LineStep
* Line Length in pixels in recon and ref images
*
* OUTPUTS : UINT8 * ReconPtr
* The reconstruction
*
* RETURNS : None
*
* FUNCTION : Reconstructs data from last data and change
*
* SPECIAL NOTES :
*
*
* ERRORS : None.
*
****************************************************************************/
void MmxReconInter( PB_INSTANCE *pbi, UINT8 * ReconPtr, UINT8 * RefPtr, INT16 * ChangePtr, UINT32 LineStep )
{
(void) pbi;
_asm {
push edi
;; mov ebx, [ref]
;; mov ecx, [diff]
;; mov eax, [dest]
;; mov edx, [stride]
mov ebx, [RefPtr]
mov ecx, [ChangePtr]
mov eax, [ReconPtr]
mov edx, [LineStep]
pxor mm0, mm0
lea edi, [ecx + 128]
;
L:
movq mm2, [ebx] ; (+3 misaligned) 8 reference pixels
;
movq mm4, [ecx] ; first 4 changes
movq mm3, mm2
movq mm5, [ecx + 8] ; last 4 changes
punpcklbw mm2, mm0 ; turn first 4 refs into positive 16-bit #s
paddsw mm2, mm4 ; add in first 4 changes
punpckhbw mm3, mm0 ; turn last 4 refs into positive 16-bit #s
paddsw mm3, mm5 ; add in last 4 changes
add ebx, edx ; next row of reference pixels
packuswb mm2, mm3 ; pack result to unsigned 8-bit values
lea ecx, [ecx + 16] ; next row of changes
cmp ecx, edi ; are we done?
;
movq [eax], mm2 ; store result
;
lea eax, [eax+edx] ; next row of output
jc L ; 12c / 8 elts = 18c / 8 pixels = 2.25 c/pix
pop edi
}
}
/****************************************************************************
*
* ROUTINE : CopyBlockUsingMMX
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None.
*
* FUNCTION : Copies a block from source to destination
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void CopyBlockMMX(unsigned char *src, unsigned char *dest, unsigned int srcstride)
{
unsigned char *s = src;
unsigned char *d = dest;
unsigned int stride = srcstride;
// recon copy
_asm
{
mov ecx, [stride]
mov eax, [s]
mov ebx, [d]
lea edx, [ecx + ecx * 2]
movq mm0, [eax]
movq mm1, [eax + ecx]
movq mm2, [eax + ecx*2]
movq mm3, [eax + edx]
lea eax, [eax + ecx*4]
movq [ebx], mm0
movq [ebx + ecx], mm1
movq [ebx + ecx*2], mm2
movq [ebx + edx], mm3
lea ebx, [ebx + ecx * 4]
movq mm0, [eax]
movq mm1, [eax + ecx]
movq mm2, [eax + ecx*2]
movq mm3, [eax + edx]
movq [ebx], mm0
movq [ebx + ecx], mm1
movq [ebx + ecx*2], mm2
movq [ebx + edx], mm3
}
}
@@ -0,0 +1,208 @@
/****************************************************************************
*
* Module Title : WmtOptFunctions.c
*
* Description : willamette processor specific
* optimised versions of functions
*
* AUTHOR : Yaowu Xu
*
* Special Note:
*
*****************************************************************************
* Revision History
*
*
* 1.04 JBB 13 Jun 01 VP4 Code Clean Out
* 1.03 YWX 07-Dec-00 Removed constants and functions that are not in use
* Added push and pop ebx in WmtReconIntra
* 1.02 YWX 30 Aug 00 changed to be compatible with Microsoft compiler
* 1.01 YWX 13 JUL 00 New Willamette Optimized Functions
* 1.00 YWX 14/06/00 Configuration baseline from OptFunctions.c
*
*****************************************************************************
*/
/*
Use Tim's optimized version.
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT // Strict type checking.
#include "codec_common.h"
#include "pbdll.h"
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Imports.
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Exported Functions
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
#if defined(_WIN32_WCE)
#pragma pack(16)
static UINT8 Eight128s[8] = {128,128,128,128,128,128,128,128};
#pragma pack()
#else
_declspec(align(16)) static UINT8 Eight128s[8] = {128,128,128,128,128,128,128,128};
#endif
#pragma warning( disable : 4799 ) // Disable no emms instruction warning!
/****************************************************************************
* Forward References
*****************************************************************************
*/
/****************************************************************************
*
* ROUTINE : WmtReconIntra
*
* INPUTS : INT16 * idct
* Pointer to the output from the idct for this block
*
* UINT32 stride
* Line Length in pixels in recon and reference images
*
*
*
*
* OUTPUTS : UINT8 * dest
* The reconstruction buffer
*
* RETURNS : None
*
* FUNCTION : Reconstructs an intra block - wmt version
*
*
* ERRORS : None.
*
****************************************************************************/
void WmtReconIntra( PB_INSTANCE *pbi, UINT8 * dest, INT16 * idct, INT32 stride )
{
__asm
{
push ebx
mov eax,[idct] ; Signed 16 bit inputs
mov edx,[dest] ; Unsigned 8 bit outputs
movq xmm0,QWORD PTR [Eight128s] ; Set xmm0 to 0x000000000000008080808080808080
pxor xmm3, xmm3 ; set xmm3 to 0
;
mov ebx,[stride] ; Line stride in output buffer
lea ecx,[eax+128] ; Endpoint in input buffer
loop_label:
movdqa xmm2,XMMWORD PTR [eax] ; Read the eight inputs
packsswb xmm2,xmm3 ;
pxor xmm2,xmm0 ; Convert result to unsigned (same as add 128)
lea eax,[eax + 16] ; Step source buffer
cmp eax,ecx ; are we done
movq QWORD PTR [edx],xmm2 ; store results
lea edx,[edx+ebx] ; Step output buffer
jc loop_label ; Loop back if we are not done
pop ebx
}
}
/****************************************************************************
*
* ROUTINE : WmtReconInter
*
* INPUTS : UINT8 * RefPtr
* The last frame reference
*
* INT16 * ChangePtr
* Pointer to the change data
*
* UINT32 LineStep
* Line Length in pixels in recon and ref images
*
* OUTPUTS : UINT8 * ReconPtr
* The reconstruction
*
* RETURNS : None
*
* FUNCTION : Reconstructs data from last data and change
*
* SPECIAL NOTES :
*
*
* ERRORS : None.
*
****************************************************************************/
void WmtReconInter( PB_INSTANCE *pbi, UINT8 * ReconPtr, UINT8 * RefPtr, INT16 * ChangePtr, UINT32 LineStep )
{
(void) pbi;
_asm {
push edi
mov ebx, [RefPtr]
mov ecx, [ChangePtr]
mov eax, [ReconPtr]
mov edx, [LineStep]
pxor xmm0, xmm0
lea edi, [ecx + 128]
L:
movq xmm2, QWORD ptr [ebx] ; (+3 misaligned) 8 reference pixels
movdqa xmm4, XMMWORD ptr [ecx] ; 8 changes
punpcklbw xmm2, xmm0 ;
add ebx, edx ; next row of reference pixels
paddsw xmm2, xmm4 ; add in first 4 changes
lea ecx, [ecx + 16] ; next row of changes
packuswb xmm2, xmm0 ; pack result to unsigned 8-bit values
cmp ecx, edi ; are we done?
movq QWORD PTR [eax], xmm2 ; store result
lea eax, [eax+edx] ; next row of output
jc L ; 12c / 8 elts = 18c / 8 pixels = 2.25 c/pix
pop edi
}
}
@@ -0,0 +1,334 @@
/****************************************************************************
*
* Module Title : SystemDependant.c
*
* Description : Miscellaneous system dependant functions.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <windows.h>
#include "pbdll.h"
#include "math.h"
#include "vp60dversion.h"
#include "quantize.h"
/****************************************************************************
* Macros
****************************************************************************/
#pragma warning(disable:4115)
#define MMX_ENABLED 1
/****************************************************************************
* Imports
****************************************************************************/
extern unsigned int CPUFrequency;
extern void GetProcessorFlags ( INT32 *MmxEnabled, INT32 *XmmEnabled, INT32 *WmtEnabled );
extern void VP6_BuildQuantIndex_Generic ( QUANTIZER *pbi );
extern void VP6_BuildQuantIndex_ForMMX ( QUANTIZER *pbi );
extern void VP6_BuildQuantIndex_ForWMT ( QUANTIZER *pbi );
/****************************************************************************
*
* ROUTINE : VP6_SetPbParam
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
* PB_COMMAND_TYPE Command : Command action specifier.
* UINT32 *Parameter : Command dependent value.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Generalised command interface to decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV VP6_SetPbParam( PB_INSTANCE *pbi, PB_COMMAND_TYPE Command, uintptr_t Parameter )
{
#if defined(POSTPROCESS)
switch ( Command )
{
case PBC_SET_CPUFREE:
{
#if defined(_MSC_VER)
double Pixels = pbi->Configuration.VideoFrameWidth * pbi->Configuration.VideoFrameHeight;
double FreeMhz = pbi->ProcessorFrequency * Parameter / 100;
double PixelsPerMhz = 100 * sqrt(1.0*Pixels) / FreeMhz;
#else
double PixelsPerMhz = 100 *10;
#endif
pbi->CPUFree = Parameter;
if( PixelsPerMhz > 150 )
pbi->PostProcessingLevel = 0;
else if( PixelsPerMhz > 100 )
pbi->PostProcessingLevel = 8;
else if( PixelsPerMhz > 90 )
pbi->PostProcessingLevel = 4;
else if( PixelsPerMhz > 80 )
pbi->PostProcessingLevel = 5;
else
pbi->PostProcessingLevel = 6;
break;
}
case PBC_SET_ADDNOISE:
pbi->AddNoiseMode = Parameter;
//SetAddNoiseMode(pbi->postproc, Parameter);
break;
case PBC_SET_REFERENCEFRAME:
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->LastFrameRecon);
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->GoldenFrame);
break;
case PBC_SET_POSTPROC:
if( Parameter == 9 )
VP6_SetPbParam( pbi, PBC_SET_CPUFREE, 70);
else
{
pbi->CPUFree = 0;
pbi->PostProcessingLevel = Parameter;
}
break;
case PBC_SET_DEINTERLACEMODE:
pbi->DeInterlaceMode = Parameter;
break;
case PBC_SET_BLACKCLAMP:
pbi->BlackClamp = Parameter;
break;
case PBC_SET_WHITECLAMP:
pbi->WhiteClamp = Parameter;
break;
default:
break;
}
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_readTSC
*
* INPUTS : None.
*
* OUTPUTS : unsigned long *tsc : Pointer to returned counter value.
*
* RETURNS : void
*
* FUNCTION : Reads the cpu time stamp counter.
*
* SPECIAL NOTES : Since this function uses RDTSC instruction, which is
* introduced in Pentium processor, this routine is only
* expected to work on Pentium and above.
*
****************************************************************************/
void VP6_readTSC ( unsigned long *tsc )
{
int time;
__asm
{
pushad
cpuid
rdtsc
mov time,eax
popad
}
*tsc = time;
return;
}
/****************************************************************************
*
* ROUTINE : VP6_GetProcessorFrequency
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : unsigned long: The processors' frequency (in MHz).
*
* FUNCTION : Check the Processor's working freqency.
*
* SPECIAL NOTES : This function should only be used here. Limited tests
* have verified it works till 166MHz Pentium with MMX.
*
****************************************************************************/
unsigned long VP6_GetProcessorFrequency()
{
LARGE_INTEGER pf; // Performance Counter Frequency
LARGE_INTEGER startcount, endcount;
unsigned long tsc1, tsc2;
// If the cpu does not support the high resolution counter, return 0
unsigned long time1, time2;
unsigned long cpufreq = 0;
unsigned long Nearest66Mhz, Nearest50Mhz;
unsigned long Delta66, Delta50;
if ( QueryPerformanceFrequency( &pf ) )
{
// read the counter and TSC at start
QueryPerformanceCounter ( &startcount );
VP6_readTSC ( &tsc1 );
// delay for 10 ms to get enough accuracy
time1 = timeGetTime();
time2 = time1;
while ( time2 < time1+5 )
time2 = timeGetTime();
// read the counter and TSC at end
QueryPerformanceCounter ( &endcount );
VP6_readTSC ( &tsc2 );
// calculate the frequency
cpufreq = (unsigned long )( (double)(tsc2-tsc1)
* (double)pf.LowPart
/ (double) (endcount.LowPart - startcount.LowPart)
/ 1000000 );
}
Nearest66Mhz = ((cpufreq * 3 + 100)/200 * 200) / 3;
Delta66 = abs( Nearest66Mhz - cpufreq );
Nearest50Mhz = ((cpufreq + 25)/50 *50);
Delta50 = abs( Nearest50Mhz - cpufreq );
if ( Delta50 < Delta66 )
cpufreq = Nearest50Mhz;
else
{
cpufreq = Nearest66Mhz;
if ( cpufreq == 666 )
cpufreq = 667;
}
return cpufreq;
}
/****************************************************************************
*
* ROUTINE : VP6_DMachineSpecificConfig
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Checks for machine specifc features such as MMX support;
* sets approipriate flags and function pointers.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DMachineSpecificConfig ( void )
{
INT32 MmxEnabled;
INT32 XmmEnabled;
INT32 WmtEnabled;
GetProcessorFlags ( &MmxEnabled, &XmmEnabled, &WmtEnabled );
// If MMX supported use MMX version of functions, else use C versions
if ( WmtEnabled ) // Willamette
VP6_BuildQuantIndex = VP6_BuildQuantIndex_ForWMT;
else if ( MmxEnabled ) // MMX
VP6_BuildQuantIndex = VP6_BuildQuantIndex_ForMMX;
else // No instruction set support
VP6_BuildQuantIndex = VP6_BuildQuantIndex_Generic;
}
/****************************************************************************
*
* ROUTINE : VP6_IssueWarning
*
* INPUTS : char *WarningMessage : Pointer to warning message text.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Issues a warning message.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_IssueWarning ( char *WarningMessage )
{
MessageBox ( NULL, WarningMessage, NULL, MB_ICONEXCLAMATION | MB_TASKMODAL );
}
/****************************************************************************
*
* ROUTINE : VP6_IssueWarning
*
* INPUTS : unsigned int SleepMs : Time (in milli-seconds) to wait.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Pause/Sleep for specified time(in milli-seconds).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_PauseProcess ( unsigned int SleepMs )
{
Sleep ( SleepMs );
}
/****************************************************************************
*
* ROUTINE : VP6_SytemGlobalAlloc
*
* INPUTS : unsigned int Size : Size of block of memory (in bytes).
*
* OUTPUTS : None.
*
* RETURNS : char *: Pointer to allocated block of memory.
*
* FUNCTION : Allocates a block of memory of specified size.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
char *VP6_SytemGlobalAlloc ( unsigned int Size )
{
return GlobalAlloc( GPTR, Size );
}
/****************************************************************************
*
* ROUTINE : VP6_SystemGlobalFree
*
* INPUTS : char *MemPtr : Pointer to block of memory.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocates a block of memory.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_SystemGlobalFree ( char* MemPtr )
{
GlobalFree ( (HGLOBAL)MemPtr );
}
@@ -0,0 +1,381 @@
/****************************************************************************
*
* Module Title : quantindexmmx.c
*
* Description :
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include "codec_common.h"
#include "quantize.h"
#include "math.h"
/****************************************************************************
* Macros
****************************************************************************/
#define MIN16 ((1<<16)-1)
/****************************************************************************
* Module Statics
****************************************************************************/
static UINT32 dequant_index[64] =
{
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
static UINT32 dequant_indexMMX[64] =
{
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
/* Used to unravel the coeffs in the proper order required */
/* by MMX_idct (see mmxidct.cxx) */
static UINT32 transIndexMMX[64] =
{
0, 8, 1, 2, 9, 16, 24, 17,
10, 3, 32, 11, 18, 25, 4, 12,
5, 26, 19, 40, 33, 34, 41, 48,
27, 6, 13, 20, 28, 21, 14, 7,
56, 49, 42, 35, 43, 50, 57, 36,
15, 22, 29, 30, 23, 44, 37, 58,
51, 59, 38, 45, 52, 31, 60, 53,
46, 39, 47, 54, 61, 62, 55, 63
};
static UINT32 transIndexWMT[64] =
{
0, 8, 1, 2, 9, 16, 24, 17,
10, 3, 4, 11, 18, 25, 32, 40,
33, 26, 19, 12, 5, 6, 13, 20,
27, 34, 41, 48, 56, 49, 42, 35,
28, 21, 14, 7, 15, 22, 29, 36,
43, 50, 57, 58, 51, 44, 37, 30,
23, 31, 38, 45, 52, 59, 60, 53,
46, 39, 47, 54, 61, 62, 55, 63
};
/****************************************************************************
*
* ROUTINE : VP6_BuildQuantIndex_ForMMX
*
* INPUTS : QUANTIZER *pbi : Pointer to quantizer instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Builds the quant_index table in a transposed order.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_BuildQuantIndex_ForMMX ( QUANTIZER *pbi )
{
INT32 i, j;
pbi->transIndex = transIndexMMX;
// invert the dequant index into the quant index
for ( i=0; i<BLOCK_SIZE; i++ )
{
j = transIndexMMX[dequant_indexMMX[i]];
pbi->quant_index[j] = i;
}
}
/****************************************************************************
*
* ROUTINE : BuildQuantIndex_ForWMT
*
* INPUTS : QUANTIZER *pbi : Pointer to quantizer instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Builds the quant_index table in a transposed order.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_BuildQuantIndex_ForWMT ( QUANTIZER *pbi )
{
INT32 i, j;
pbi->transIndex = transIndexWMT;
// invert the dequant index into the quant index
for ( i=0; i<BLOCK_SIZE; i++ )
{
j = transIndexWMT[dequant_indexMMX[i]];
pbi->quant_index[j] = i;
}
}
/****************************************************************************
*
* ROUTINE : VP6_quantize_wmt
*
* INPUTS : QUANTIZER *pbi : Pointer to quantizer instance.
* INT16 *DCT_block : Pointer to block of DCT coeffs.
* UINT8 bp : Position of blockin MB.
*
* OUTPUTS : Q_LIST_ENTRY *quantized_list : Pointer to block of quantized DCT coeffs.
*
* RETURNS : void
*
* FUNCTION : Quantizes an 8x8 blockof DCT coefficients.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_quantize_wmt
(
QUANTIZER *qi,
INT16 *DCT_block,
Q_LIST_ENTRY *quantized_list,
UINT8 bp
)
{
UINT32 i, j;
INT32 temp;
INT32 ThisDC;
UINT32 ColourPlane = VP6_QTableSelect[bp];
INT32 *QuantRoundPtr = qi->QuantRound[ColourPlane];
INT32 QuantCoeffsDC = qi->QuantCoeffs[ColourPlane][0];
INT32 *ZBinPtr = qi->ZeroBinSize[ColourPlane];
INT16 *round = &qi->round[0];
INT16 *mult = &qi->mult[0];
INT32 Zrl = 0;
INT32 * ZrlCorrection = qi->ZlrZbinCorrections[ColourPlane];
__declspec(align(16)) unsigned short xyw[64];
// this quantizer stores its results back in the source!!
__asm
{
// setup and collect registers
mov esi, DCT_block
xor ecx, ecx // index ptr
mov edi, round
movdqu xmm2, [edi] // get the round values
mov edi, mult
movdqu xmm3, [edi] // get the quantizer values
lea edi, xyw
mov eax, quantized_list
pxor xmm7, xmm7
// 8 coefficients at a time loop
next8:
movdqa xmm0, [esi+ecx] // get source values
movdqa xmm1, xmm0 // sign bits of the abs values
psraw xmm1, 15 // negative all 1's postive all 0's
// get the absolute value of the input values
pxor xmm0, xmm1 // one's complement of negatives
psubw xmm0, xmm1 // xmm0 = abs coeffs
// calculate & round quantizer
paddw xmm0, xmm2 // Coeff + Quant Round
pmulhuw xmm0, xmm3 // *QuantCoeffs >> 16
// get back the sign bit
pxor xmm0, xmm1 // ones complement of negatives
psubw xmm0, xmm1 // negatives are back as negative
// output the results
movdqa [edi+ecx], xmm0
movdqa [eax+ecx], xmm7
// loop back to the next set
add ecx, 16
cmp ecx, 128
jl next8
}
// DC quantization
ThisDC = DCT_block[0];
if ( ThisDC >= ZBinPtr[0] )
{
temp = QuantCoeffsDC * ( ThisDC + QuantRoundPtr[0] );
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else if ( ThisDC <= -ZBinPtr[0] )
{
temp = QuantCoeffsDC * ( ThisDC - QuantRoundPtr[0] ) + MIN16;
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else
{
Zrl++;
}
// zig-zagify
for ( i=1; i<64; i++ )
{
INT32 x;
INT32 y;
// Zig Zag order
j = dequant_index[i];
x = xyw[j];
y= abs( DCT_block[j]);
if(y<ZBinPtr[j] + ZrlCorrection[Zrl])
{
Zrl ++;
}
else
{
Zrl = 0;
quantized_list[i] = x;
}
}
}
/****************************************************************************
*
* ROUTINE : VP6_quantize_mmx
*
* INPUTS : QUANTIZER *pbi : Pointer to quantizer instance.
* INT16 *DCT_block : Pointer to block of DCT coeffs.
* UINT8 bp : Position of blockin MB.
*
* OUTPUTS : Q_LIST_ENTRY *quantized_list : Pointer to block of quantized DCT coeffs.
*
* RETURNS : void
*
* FUNCTION : Quantizes an 8x8 blockof DCT coefficients.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_quantize_mmx
(
QUANTIZER *qi,
INT16 *DCT_block,
Q_LIST_ENTRY *quantized_list,
UINT8 bp
)
{
UINT32 i, j;
INT32 temp;
INT32 ThisDC;
UINT32 ColourPlane = VP6_QTableSelect[bp];
INT32 *QuantRoundPtr = qi->QuantRound[ColourPlane];
INT32 QuantCoeffsDC = qi->QuantCoeffs[ColourPlane][0];
INT32 *ZBinPtr = qi->ZeroBinSize[ColourPlane];
INT16 *round = &qi->round[0];
INT16 *mult = &qi->mult[0];
INT32 Zrl = 0;
INT32 * ZrlCorrection = qi->ZlrZbinCorrections[ColourPlane];
__declspec(align(16)) unsigned short xyw[64];
// this quantizer stores its results back in the source!!
__asm
{
// setup and collect registers
mov esi, DCT_block
xor ecx, ecx // index ptr
mov edi, round
movq mm2, [edi] // get the round values
mov edi, mult
movq mm3, [edi] // get the quantizer values
lea edi, xyw
mov eax, quantized_list
pxor mm7, mm7
// 8 coefficients at a time loop
next8:
movq mm0, [esi+ecx] // get source values
movq mm1, mm0 // sign bits of the abs values
psraw mm1, 15 // negative all 1's postive all 0's
// get the absolute value of the input values
pxor mm0, mm1 // one's complement of negatives
psubw mm0, mm1 // xmm0 = abs coeffs
// calculate & round quantizer
paddw mm0, mm2 // Coeff + Quant Round
pmulhuw mm0, mm3 // *QuantCoeffs >> 16
// get back the sign bit
pxor mm0, mm1 // ones complement of negatives
psubw mm0, mm1 // negatives are back as negative
// output the results
movq [edi+ecx], mm0
movq [eax+ecx], mm7
// loop back to the next set
add ecx, 8
cmp ecx, 128
jl next8
}
// DC quantization
ThisDC = DCT_block[0];
if ( ThisDC >= ZBinPtr[0] )
{
temp = QuantCoeffsDC * ( ThisDC + QuantRoundPtr[0] );
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else if ( ThisDC <= -ZBinPtr[0] )
{
temp = QuantCoeffsDC * ( ThisDC - QuantRoundPtr[0] ) + MIN16;
quantized_list[0] = (Q_LIST_ENTRY) (temp>>16);
}
else
{
Zrl++;
}
// zig-zagify
for ( i=1; i<64; i++ )
{
INT32 x;
INT32 y;
// Zig Zag order
j = dequant_index[i];
x = xyw[j];
y= abs( DCT_block[j]);
if(y<ZBinPtr[j] + ZrlCorrection[Zrl])
{
Zrl ++;
}
else
{
Zrl = 0;
quantized_list[i] = x;
}
}
}
@@ -0,0 +1,147 @@
/****************************************************************************
*
* Module Title : Timer.C
*
* Description : Video CODEC timer module
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.01 PGW 09/07/99 Added code to support profile timing
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#define INC_WIN_HEADER 1
#include <windows.h>
#include "type_aliases.h"
#include <mmsystem.h>
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Module Static Variables
*****************************************************************************
*/
// Used for calculation of elapsed time
UINT32 LastCPUTime;
/****************************************************************************
*
* ROUTINE : MyInitTimer
*
* INPUTS :
*
* OUTPUTS : None.
*
* RETURNS : None
*
* FUNCTION : Initialises the timer mechanism.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void MyInitTimer( void )
{
}
/****************************************************************************
*
* ROUTINE : MyGetTime
*
* INPUTS :
*
* OUTPUTS : None.
*
* RETURNS : Time in ms since startup.
*
* FUNCTION : Provides a model independant interface for getting times.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
UINT32 MyGetTime( void )
{
/* Use different timing mechanisms for win32 and win16.
* The win16 method is accurate to 1ms whilst the Win32 is not garauteed to better than 16ms
*/
return timeGetTime();
}
/****************************************************************************
*
* ROUTINE : MyGetElapsedCpuTime
*
* INPUTS :
*
* OUTPUTS : None.
*
* RETURNS : CPU cycles since last call
*
* FUNCTION : Calculate the CPU cycles elapsed since the last call
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
UINT32 MyGetElapsedCpuTime( void )
{
UINT32 CurrCPUTime[2]; // Full 64 bit CPU time
UINT32 CurrentCpuTime; // modified 32 bit current time
UINT32 ElapsedTime;
__asm
{
rdtsc ; Get CPU time into EDX:EAX
mov dword ptr [CurrCPUTime], eax ; Save to a global
mov dword ptr [CurrCPUTime+4], edx
}
// Save CurrCPUTime to LastCPUTime
CurrCPUTime[0] = (CurrCPUTime[0] >> 8);
CurrCPUTime[1] = (CurrCPUTime[1] & 0x000000FF) << 24;
CurrentCpuTime = CurrCPUTime[0] | CurrCPUTime[1];
// Check for wrapp around
if ( CurrentCpuTime >= LastCPUTime )
{
ElapsedTime = CurrentCpuTime - LastCPUTime;
}
else
{
ElapsedTime = (LastCPUTime - CurrentCpuTime) + 0xFFFF;
}
LastCPUTime = CurrentCpuTime;
return ElapsedTime;
}
@@ -0,0 +1,420 @@
/****************************************************************************
*
* Module Title : vp60dxv.c
*
* Description : Defines the entry point for the console application.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <math.h> // For Abs()
#include "pbdll.h"
#include "duck_mem.h" /* interface to memory manager */
#include "dxl_plugin.h" /* interface to dxv */
#include "duck_dxl.h"
#include <stddef.h>
/****************************************************************************
* Macros
****************************************************************************/
#ifdef _MSC_VER
#pragma warning(disable:4055)
#endif
#define VP60_FOURCC DXL_MKFOURCC( 'V', 'P', '6', '0')
#define VP61_FOURCC DXL_MKFOURCC( 'V', 'P', '6', '1')
#define VP62_FOURCC DXL_MKFOURCC( 'V', 'P', '6', '2')
extern int VPX_GetSizeOfPixel(dxvBitDepth bd);
extern void *VPX_GetBlitter(dxvBlitQuality bq, dxvBitDepth bd);
/****************************************************************************
* Typedefs
****************************************************************************/
typedef unsigned long FourCC;
typedef struct // YUV buffer configuration structure
{
int YWidth;
int YHeight;
int YStride;
int UVWidth;
int UVHeight;
int UVStride;
char *YBuffer;
char *UBuffer;
char *VBuffer;
char *uvStart;
int uvDstArea;
int uvUsedArea;
} DXV_YUV_BUFFER_CONFIG;
/* define an xImage structure based on the core xImage struct */
typedef struct tXImageCODEC
{
FourCC myFourCC;
DXV_YUV_BUFFER_CONFIG FrameBuffer;
PB_INSTANCE *myPBI;
int owned;
int decompressedOnce;
} vp60_XIMAGE, *vp60_XIMAGE_HANDLE;
typedef void ((*vp6BLIT_FUNC)(unsigned char *, int, YUV_BUFFER_CONFIG *));
//typedef void ((*vp6_VSCREEN_FUNC)(void));
/****************************************************************************
* Modul Statics
****************************************************************************/
/****************************************************************************
* Forward declarationss
****************************************************************************/
void vp60_SetParameter(DXL_XIMAGE_HANDLE src,int Command, uintptr_t Parameter );
/****************************************************************************
* Imports
****************************************************************************/
extern void VP6_VPInitLibrary(void);
extern void VP6_VPDeInitLibrary(void);
extern void VP6_readTSC(unsigned long *tsc);
int vp60_getWH(DXL_XIMAGE_HANDLE src, int *w, int *h)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
*w = thisAlgorithmBase->myPBI->Configuration.VideoFrameWidth;
*h = thisAlgorithmBase->myPBI->Configuration.VideoFrameHeight;
return DXL_OK;
}
#if 0
/****************************************************************************
*
* ROUTINE : vp60_GetInfo
*
* INPUTS : unsigned char *source :
*
* OUTPUTS : FrameInfo *frameInfo :
*
* RETURNS : void
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void vp60_GetInfo ( unsigned char *source, FrameInfo *frameInfo )
{
// Is the frame and inter frame or a key frame
frameInfo->KeyFrame = !(source[0] > 0x7f);
frameInfo->Quality = source[0] >> 2;
if ( frameInfo->KeyFrame )
frameInfo->Version = ((source[2]>>3) & 0x1f );
else
frameInfo->Version = 0;
frameInfo->vp30Flag = (int)source[1];
}
#endif
/****************************************************************************
*
* ROUTINE : vp60_decompress
*
* INPUTS : vp60_XIMAGE_HANDLE src :
* DXL_VSCREEN_HANDLE vScreen :
*
* OUTPUTS : None.
*
* RETURNS : int:
*
* FUNCTION :
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int vp60_decompress ( DXL_XIMAGE_HANDLE src)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
unsigned char *cAddr;
int cSize;
cAddr = DXL_GetXImageCDataAddr(src);
cSize = DXL_GetXImageCSize(src);
// if we have a compressed frame decompress it ( otherwise we'll just redo
// the scaling and postprocessing from the last frame )
if (cAddr)
{
if( cSize != 0 && (cAddr[0]>=1 || cAddr[1]>=1 || cAddr[2] >=1))
{
// decode the frame
int retVal = VP6_DecodeFrameToYUV (
thisAlgorithmBase->myPBI,
(char *)cAddr,
cSize);
if ( retVal != 0 )
{
if ( retVal == -1)
return DXL_VERSION_CONFLICT;
else
return DXL_BAD_DATA;
}
thisAlgorithmBase->decompressedOnce = 1;
}
}
//CT>removed blit for size
VP6_GetYUVConfig(thisAlgorithmBase->myPBI, (YUV_BUFFER_CONFIG *) &thisAlgorithmBase->FrameBuffer);
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_xImageDestroy
*
* INPUTS : vp60_XIMAGE_HANDLE xThis :
*
* OUTPUTS : None.
*
* RETURNS : int:
*
* FUNCTION : Closes decoder and releases resources.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
static int vp60_xImageDestroy ( DXL_XIMAGE_HANDLE src )
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
if(thisAlgorithmBase)
{
if ( thisAlgorithmBase->owned )
VP6_StopDecoder ( &(thisAlgorithmBase->myPBI) );
duck_free ( thisAlgorithmBase );
}
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_xImageReCreate
*
* INPUTS : unsigned char *data :
*
* OUTPUTS : None.
*
* RETURNS : DXL_XIMAGE_HANDLE:
*
* FUNCTION :
*
* SPECIAL NOTES : Called during initialization and/or when xImage
* (decompressor) attributes change, note that nImage and
* src are actually synonymous and should be cleared out
* a bit (to say the least!)
*
* NOTE:
* This function should be prepared to get data that is
* NOT of the type native to the decoder, It should do
* it's best to verify it as valid data and should clean
* up after itself and return NULL if it doesn't recognize
* the format of the data.
*
****************************************************************************/
static DXL_HANDLE vp60_xImageReCreate
(
DXL_XIMAGE_HANDLE src,
unsigned char *data,
int type,
enum BITDEPTH bitDepth,
int w,
int h
)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
(void) bitDepth;
if ( (type != VP60_FOURCC) && (type != VP61_FOURCC) && (type != VP62_FOURCC) )
return NULL;
/* create new PBI */
if ( !VP6_StartDecoder( &(thisAlgorithmBase->myPBI), w, h ) )
{
vp60_xImageDestroy ( src );
thisAlgorithmBase = NULL;
}
else
{
thisAlgorithmBase->owned = 1;
thisAlgorithmBase->decompressedOnce = 0;
}
return (DXL_HANDLE)thisAlgorithmBase;
}
/****************************************************************************
*
* ROUTINE : vp60_xImageCreate
*
* INPUTS : unsigned char *data :
*
* OUTPUTS : None.
*
* RETURNS : DXL_XIMAGE_HANDLE:
*
* FUNCTION :
*
* SPECIAL NOTES : In this "glue" case, just calls through to the
* create function.
*
****************************************************************************/
static DXL_HANDLE vp60_xImageCreate (DXL_XIMAGE_HANDLE src, unsigned char *data)
{
// return vp60_xImageReCreate(src, data, VP60_FOURCC, (enum BITDEPTH ) 0, 320, 240);
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
/* create a new xImage, specific to this type of decoder,
(see "vp60_XIMAGE" struct above and dxl_main.h) */
thisAlgorithmBase = (vp60_XIMAGE_HANDLE)duck_calloc ( 1, sizeof(vp60_XIMAGE), DMEM_GENERAL );
if (thisAlgorithmBase == NULL)
return NULL;
DXL_RegisterXImageRecreate(src, (RECREATE_FUNC) vp60_xImageReCreate);
DXL_RegisterXImageDestroy(src, (DESTROY_FUNC) vp60_xImageDestroy);
DXL_RegisterXImageDx(src, (DX_FUNC) vp60_decompress);
DXL_RegisterXImageSetParameter(src, (SET_PARAMETER_FUNC) vp60_SetParameter);
thisAlgorithmBase->myFourCC = VP60_FOURCC;
thisAlgorithmBase->decompressedOnce = 0;
return (DXL_HANDLE)thisAlgorithmBase;
}
/****************************************************************************
*
* ROUTINE : vp60_Init
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : int
*
* FUNCTION :
*
* SPECIAL NOTES :
*
****************************************************************************/
int vp60_Init ( void )
{
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, VP60_FOURCC);
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, VP61_FOURCC);
DXL_RegisterXImage((CREATE_FUNC) vp60_xImageCreate, VP62_FOURCC);
/* initialize all the global variables */
VP6_VPInitLibrary();
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_Exit
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : int
*
* FUNCTION : Main exit routine, called during DXL_ExitVideo()
* clean up any global information if necessary.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int vp60_Exit(void)
{
VP6_VPDeInitLibrary();
return DXL_OK;
}
/****************************************************************************
*
* ROUTINE : vp60_SetParameter
*
* INPUTS : DXL_XIMAGE_HANDLE src :
* int Command :
* unsigned long Parameter :
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION :
*
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void vp60_SetParameter(DXL_XIMAGE_HANDLE src, int Command, uintptr_t Parameter)
{
vp60_XIMAGE_HANDLE thisAlgorithmBase = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(src);
if ( Command == PBC_SET_PBSTRUCT )
{
if ( thisAlgorithmBase->owned )
VP6_StopDecoder ( &(thisAlgorithmBase->myPBI) );
thisAlgorithmBase->owned = 0;
thisAlgorithmBase->myPBI = (PB_INSTANCE *) Parameter;
}
else
VP6_SetPbParam( thisAlgorithmBase->myPBI, (PB_COMMAND_TYPE)Command, Parameter );
}
//CT:
typedef struct {
unsigned char* baseAddr;
long rowBytes;
} YV12_PLANE;
typedef struct {
YV12_PLANE y;
YV12_PLANE u;
YV12_PLANE v;
} YV12_PLANES;
void GetImageBufs(DXL_XIMAGE_HANDLE x, YV12_PLANES *p)
{
// vp60_XIMAGE_HANDLE xim=(vp60_XIMAGE_HANDLE)x;
vp60_XIMAGE_HANDLE xim = (vp60_XIMAGE_HANDLE)DXL_GetAlgorithmBasePtr(x);
p->y.baseAddr=(unsigned char *)xim->FrameBuffer.YBuffer;
p->u.baseAddr=(unsigned char *)xim->FrameBuffer.UBuffer;
p->v.baseAddr=(unsigned char *)xim->FrameBuffer.VBuffer;
p->y.rowBytes=xim->FrameBuffer.YStride;
p->u.rowBytes=xim->FrameBuffer.UVStride;
p->v.rowBytes=xim->FrameBuffer.UVStride;
}
@@ -0,0 +1,348 @@
/****************************************************************************
*
* Module Title : SystemDependant.c
*
* Description : Miscellaneous system dependant functions.
*
****************************************************************************/
#define STRICT /* Strict type checking */
/****************************************************************************
* Header Files
****************************************************************************/
#include <windows.h>
#include "pbdll.h"
#include "math.h"
#include "vp60dversion.h"
#include "quantize.h"
/****************************************************************************
* Macros
****************************************************************************/
#pragma warning(disable:4115)
#define MMX_ENABLED 1
/****************************************************************************
* Imports
****************************************************************************/
extern unsigned int CPUFrequency;
extern void GetProcessorFlags ( INT32 *MmxEnabled, INT32 *XmmEnabled, INT32 *WmtEnabled );
extern void VP6_BuildQuantIndex_Generic ( QUANTIZER *pbi );
extern void VP6_BuildQuantIndex_ForMMX ( QUANTIZER *pbi );
extern void VP6_BuildQuantIndex_ForWMT ( QUANTIZER *pbi );
/****************************************************************************
*
* ROUTINE : VP6_SetPbParam
*
* INPUTS : PB_INSTANCE **pbi : Pointer to decoder instance.
* PB_COMMAND_TYPE Command : Command action specifier.
* UINT32 *Parameter : Command dependent value.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Generalised command interface to decoder.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void CCONV VP6_SetPbParam( PB_INSTANCE *pbi, PB_COMMAND_TYPE Command, uintptr_t Parameter )
{
#if defined(POSTPROCESS)
switch ( Command )
{
case PBC_SET_CPUFREE:
{
#if defined(_MSC_VER)
double Pixels = pbi->Configuration.VideoFrameWidth * pbi->Configuration.VideoFrameHeight;
double FreeMhz = pbi->ProcessorFrequency * Parameter / 100;
double PixelsPerMhz = 100 * sqrt(1.0*Pixels) / FreeMhz;
#else
double PixelsPerMhz = 100 *10;
#endif
pbi->CPUFree = Parameter;
if( PixelsPerMhz > 150 )
pbi->PostProcessingLevel = 0;
else if( PixelsPerMhz > 100 )
pbi->PostProcessingLevel = 8;
else if( PixelsPerMhz > 90 )
pbi->PostProcessingLevel = 4;
else if( PixelsPerMhz > 80 )
pbi->PostProcessingLevel = 5;
else
pbi->PostProcessingLevel = 6;
break;
}
case PBC_SET_ADDNOISE:
pbi->AddNoiseMode = Parameter;
//SetAddNoiseMode(pbi->postproc, Parameter);
break;
case PBC_SET_REFERENCEFRAME:
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->LastFrameRecon);
CopyFrame( pbi->postproc, (YUV_BUFFER_CONFIG *) Parameter, pbi->GoldenFrame);
break;
case PBC_SET_POSTPROC:
if( Parameter == 9 )
VP6_SetPbParam( pbi, PBC_SET_CPUFREE, 70);
else
{
pbi->CPUFree = 0;
pbi->PostProcessingLevel = Parameter;
}
break;
case PBC_SET_DEINTERLACEMODE:
pbi->DeInterlaceMode = Parameter;
break;
case PBC_SET_BLACKCLAMP:
pbi->BlackClamp = Parameter;
break;
case PBC_SET_WHITECLAMP:
pbi->WhiteClamp = Parameter;
break;
default:
break;
}
#endif
}
/****************************************************************************
*
* ROUTINE : VP6_readTSC
*
* INPUTS : None.
*
* OUTPUTS : unsigned long *tsc : Pointer to returned counter value.
*
* RETURNS : void
*
* FUNCTION : Reads the cpu time stamp counter.
*
* SPECIAL NOTES : Since this function uses RDTSC instruction, which is
* introduced in Pentium processor, this routine is only
* expected to work on Pentium and above.
*
****************************************************************************/
#ifdef _M_AMD64 // For 64-bit apps
unsigned __int64 __rdtsc(void);
#pragma intrinsic(__rdtsc)
#define _RDTSC __rdtsc
#else // For 32-bit apps
#define _RDTSC_STACK(ts) \
__asm rdtsc \
__asm mov DWORD PTR [ts], eax \
__asm mov DWORD PTR [ts+4], edx
__inline unsigned __int64 _inl_rdtsc32() {
unsigned __int64 t;
_RDTSC_STACK(t);
return t;
}
#define _RDTSC _inl_rdtsc32
#endif
void VP6_readTSC(unsigned long *tsc)
{
LARGE_INTEGER t;
t.QuadPart = _RDTSC();
*tsc = t.LowPart;
return;
}
/****************************************************************************
*
* ROUTINE : VP6_GetProcessorFrequency
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : unsigned long: The processors' frequency (in MHz).
*
* FUNCTION : Check the Processor's working freqency.
*
* SPECIAL NOTES : This function should only be used here. Limited tests
* have verified it works till 166MHz Pentium with MMX.
*
****************************************************************************/
unsigned long VP6_GetProcessorFrequency()
{
LARGE_INTEGER pf; // Performance Counter Frequency
LARGE_INTEGER startcount, endcount;
unsigned long tsc1, tsc2;
// If the cpu does not support the high resolution counter, return 0
unsigned long time1, time2;
unsigned long cpufreq = 0;
unsigned long Nearest66Mhz, Nearest50Mhz;
unsigned long Delta66, Delta50;
if ( QueryPerformanceFrequency( &pf ) )
{
// read the counter and TSC at start
QueryPerformanceCounter ( &startcount );
VP6_readTSC ( &tsc1 );
// delay for 10 ms to get enough accuracy
time1 = timeGetTime();
time2 = time1;
while ( time2 < time1+5 )
time2 = timeGetTime();
// read the counter and TSC at end
QueryPerformanceCounter ( &endcount );
VP6_readTSC ( &tsc2 );
// calculate the frequency
cpufreq = (unsigned long )( (double)(tsc2-tsc1)
* (double)pf.LowPart
/ (double) (endcount.LowPart - startcount.LowPart)
/ 1000000 );
}
Nearest66Mhz = ((cpufreq * 3 + 100)/200 * 200) / 3;
Delta66 = abs( Nearest66Mhz - cpufreq );
Nearest50Mhz = ((cpufreq + 25)/50 *50);
Delta50 = abs( Nearest50Mhz - cpufreq );
if ( Delta50 < Delta66 )
cpufreq = Nearest50Mhz;
else
{
cpufreq = Nearest66Mhz;
if ( cpufreq == 666 )
cpufreq = 667;
}
return cpufreq;
}
/****************************************************************************
*
* ROUTINE : VP6_DMachineSpecificConfig
*
* INPUTS : None.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Checks for machine specifc features such as MMX support;
* sets approipriate flags and function pointers.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_DMachineSpecificConfig ( void )
{
#if 0
INT32 MmxEnabled;
INT32 XmmEnabled;
INT32 WmtEnabled;
GetProcessorFlags ( &MmxEnabled, &XmmEnabled, &WmtEnabled );
// If MMX supported use MMX version of functions, else use C versions
if ( WmtEnabled ) // Willamette
VP6_BuildQuantIndex = VP6_BuildQuantIndex_ForWMT;
else if ( MmxEnabled ) // MMX
VP6_BuildQuantIndex = VP6_BuildQuantIndex_ForMMX;
else // No instruction set support
#endif
VP6_BuildQuantIndex = VP6_BuildQuantIndex_Generic;
}
/****************************************************************************
*
* ROUTINE : VP6_IssueWarning
*
* INPUTS : char *WarningMessage : Pointer to warning message text.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Issues a warning message.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_IssueWarning ( char *WarningMessage )
{
MessageBox ( NULL, WarningMessage, NULL, MB_ICONEXCLAMATION | MB_TASKMODAL );
}
/****************************************************************************
*
* ROUTINE : VP6_IssueWarning
*
* INPUTS : unsigned int SleepMs : Time (in milli-seconds) to wait.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Pause/Sleep for specified time(in milli-seconds).
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_PauseProcess ( unsigned int SleepMs )
{
Sleep ( SleepMs );
}
/****************************************************************************
*
* ROUTINE : VP6_SytemGlobalAlloc
*
* INPUTS : unsigned int Size : Size of block of memory (in bytes).
*
* OUTPUTS : None.
*
* RETURNS : char *: Pointer to allocated block of memory.
*
* FUNCTION : Allocates a block of memory of specified size.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
char *VP6_SytemGlobalAlloc ( unsigned int Size )
{
return GlobalAlloc( GPTR, Size );
}
/****************************************************************************
*
* ROUTINE : VP6_SystemGlobalFree
*
* INPUTS : char *MemPtr : Pointer to block of memory.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : De-allocates a block of memory.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void VP6_SystemGlobalFree ( char* MemPtr )
{
GlobalFree ( (HGLOBAL)MemPtr );
}
@@ -0,0 +1,385 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{8666A681-2E07-49A5-B23E-EC28D165C63B}</ProjectGuid>
<RootNamespace>vp6d</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.32505.173</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\obj\vp6d\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\obj\vp6d\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\obj\vp6d\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\obj\vp6d\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\include;..\..\include;..\..\..\..\..\libvp6\corelibs\include;..\..\..\..\..\libvp6\include;..\..\..\..\..\libvp6\include\vp60;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;vp6D_EXPORTS;PREDICT_2D;PBDLL;VFW_PB;USE_DRAWDIB;POSTPROCESS;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4799;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\include;..\include;..\..\include;..\..\..\..\..\libvp6\corelibs\include;..\..\..\..\..\libvp6\include;..\..\..\..\..\libvp6\include\vp60;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;vp6D_EXPORTS;PREDICT_2D;PBDLL;VFW_PB;USE_DRAWDIB;POSTPROCESS;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4799;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\include;..\..\include;..\..\..\..\..\libvp6\corelibs\include;..\..\..\..\..\libvp6\include;..\..\..\..\..\libvp6\include\vp60;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;vp6D_EXPORTS;PREDICT_2D;PBDLL;VFW_PB;USE_DRAWDIB;POSTPROCESS;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4799;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>.\include;..\include;..\..\include;..\..\..\..\..\libvp6\corelibs\include;..\..\..\..\..\libvp6\include;..\..\..\..\..\libvp6\include\vp60;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;vp6D_EXPORTS;PREDICT_2D;PBDLL;VFW_PB;USE_DRAWDIB;POSTPROCESS;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4799;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dx\Generic\boolhuff.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\debug.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\decodembs.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\decodemode.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\decodemv.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="DX\Generic\DFrameR.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="DX\Generic\DSystemDependant.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\FrameIni.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\Huffman.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="DX\Generic\pb_globals.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\quantize.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\recon.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Generic\TokenEntropy.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="DX\Generic\vfwpbdll_if.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Win32\dsystemdependant.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Win32\quantindexmmx.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Win32\vp60dxv.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
<ClCompile Include="dx\Win64\dsystemdependant.c">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename)1.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="xprintf\xprintf.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Full</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Full</Optimization>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Decompress">
<UniqueIdentifier>{95dad006-2a54-48a1-baf0-500b01d2a44e}</UniqueIdentifier>
</Filter>
<Filter Include="Win32">
<UniqueIdentifier>{ca73ff2b-c2ff-4b2d-8dcf-b2fe83464e0f}</UniqueIdentifier>
</Filter>
<Filter Include="Win64">
<UniqueIdentifier>{a92da48f-df62-48b1-9ba1-ffaa42119481}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dx\Generic\boolhuff.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\debug.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\decodembs.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\decodemode.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\decodemv.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="DX\Generic\DFrameR.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="DX\Generic\DSystemDependant.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\FrameIni.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\Huffman.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="DX\Generic\pb_globals.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\quantize.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\recon.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Generic\TokenEntropy.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="DX\Generic\vfwpbdll_if.c">
<Filter>Decompress</Filter>
</ClCompile>
<ClCompile Include="dx\Win32\dsystemdependant.c">
<Filter>Win32</Filter>
</ClCompile>
<ClCompile Include="dx\Win32\quantindexmmx.c">
<Filter>Win32</Filter>
</ClCompile>
<ClCompile Include="dx\Win32\vp60dxv.c">
<Filter>Win32</Filter>
</ClCompile>
<ClCompile Include="xprintf\xprintf.cpp">
<Filter>Win32</Filter>
</ClCompile>
<ClCompile Include="dx\Win64\dsystemdependant.c">
<Filter>Win64</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,257 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
0C02406A0BB7912C00AE885C /* boolhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0240690BB7912C00AE885C /* boolhuff.c */; };
0C02406D0BB7913500AE885C /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02406C0BB7913500AE885C /* debug.c */; };
0C0240840BB7916D00AE885C /* DSystemDependant.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0240760BB7916D00AE885C /* DSystemDependant.c */; };
0C0240850BB7916D00AE885C /* FrameIni.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0240770BB7916D00AE885C /* FrameIni.c */; };
0C0240880BB7916D00AE885C /* modestats.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407A0BB7916D00AE885C /* modestats.c */; };
0C0240890BB7916D00AE885C /* pb_globals.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407B0BB7916D00AE885C /* pb_globals.c */; };
0C02408A0BB7916D00AE885C /* Huffman.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407C0BB7916D00AE885C /* Huffman.c */; };
0C02408B0BB7916D00AE885C /* quantize.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407D0BB7916D00AE885C /* quantize.c */; };
0C02408C0BB7916D00AE885C /* recon.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407E0BB7916D00AE885C /* recon.c */; };
0C02408D0BB7916D00AE885C /* TokenEntropy.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C02407F0BB7916D00AE885C /* TokenEntropy.c */; };
0C0240B30BB791FF00AE885C /* vp60dxv.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C0240B20BB791FF00AE885C /* vp60dxv.c */; };
0C1423C30BB819EB00FDDAB7 /* vfwpbdll_if.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1423C20BB819EB00FDDAB7 /* vfwpbdll_if.c */; };
0C1423D90BB81A1200FDDAB7 /* decodembs.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1423D80BB81A1200FDDAB7 /* decodembs.c */; };
0C1423E00BB81A3000FDDAB7 /* decodemode.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1423DD0BB81A3000FDDAB7 /* decodemode.c */; };
0C1423E10BB81A3000FDDAB7 /* decodemv.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1423DE0BB81A3000FDDAB7 /* decodemv.c */; };
0C1423E20BB81A3000FDDAB7 /* DFrameR.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C1423DF0BB81A3000FDDAB7 /* DFrameR.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0C0240690BB7912C00AE885C /* boolhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = boolhuff.c; path = dx/Generic/boolhuff.c; sourceTree = "<group>"; };
0C02406C0BB7913500AE885C /* debug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = debug.c; path = dx/Generic/debug.c; sourceTree = "<group>"; };
0C0240760BB7916D00AE885C /* DSystemDependant.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = DSystemDependant.c; path = dx/Generic/DSystemDependant.c; sourceTree = "<group>"; };
0C0240770BB7916D00AE885C /* FrameIni.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = FrameIni.c; path = dx/Generic/FrameIni.c; sourceTree = "<group>"; };
0C02407A0BB7916D00AE885C /* modestats.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = modestats.c; path = dx/Generic/modestats.c; sourceTree = "<group>"; };
0C02407B0BB7916D00AE885C /* pb_globals.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pb_globals.c; path = dx/Generic/pb_globals.c; sourceTree = "<group>"; };
0C02407C0BB7916D00AE885C /* Huffman.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = Huffman.c; path = dx/Generic/Huffman.c; sourceTree = "<group>"; };
0C02407D0BB7916D00AE885C /* quantize.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = quantize.c; path = dx/Generic/quantize.c; sourceTree = "<group>"; };
0C02407E0BB7916D00AE885C /* recon.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = recon.c; path = dx/Generic/recon.c; sourceTree = "<group>"; };
0C02407F0BB7916D00AE885C /* TokenEntropy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = TokenEntropy.c; path = dx/Generic/TokenEntropy.c; sourceTree = "<group>"; };
0C0240B20BB791FF00AE885C /* vp60dxv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = vp60dxv.c; path = dx/Win32/vp60dxv.c; sourceTree = "<group>"; };
0C1423C20BB819EB00FDDAB7 /* vfwpbdll_if.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = vfwpbdll_if.c; path = dx/Generic/vfwpbdll_if.c; sourceTree = "<group>"; };
0C1423D80BB81A1200FDDAB7 /* decodembs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decodembs.c; path = dx/Generic/decodembs.c; sourceTree = "<group>"; };
0C1423DD0BB81A3000FDDAB7 /* decodemode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decodemode.c; path = dx/Generic/decodemode.c; sourceTree = "<group>"; };
0C1423DE0BB81A3000FDDAB7 /* decodemv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = decodemv.c; path = dx/Generic/decodemv.c; sourceTree = "<group>"; };
0C1423DF0BB81A3000FDDAB7 /* DFrameR.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = DFrameR.c; path = dx/Generic/DFrameR.c; sourceTree = "<group>"; };
D2AAC046055464E500DB518D /* libvp6d.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvp6d.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D289987405E68DCB004EDB86 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* vp60 */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6A0FF2B0290797F04C91782 /* Documentation */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = vp60;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
0C0240B20BB791FF00AE885C /* vp60dxv.c */,
0C1423C20BB819EB00FDDAB7 /* vfwpbdll_if.c */,
0C1423D80BB81A1200FDDAB7 /* decodembs.c */,
0C1423DD0BB81A3000FDDAB7 /* decodemode.c */,
0C1423DE0BB81A3000FDDAB7 /* decodemv.c */,
0C1423DF0BB81A3000FDDAB7 /* DFrameR.c */,
0C0240690BB7912C00AE885C /* boolhuff.c */,
0C02406C0BB7913500AE885C /* debug.c */,
0C0240760BB7916D00AE885C /* DSystemDependant.c */,
0C0240770BB7916D00AE885C /* FrameIni.c */,
0C02407A0BB7916D00AE885C /* modestats.c */,
0C02407B0BB7916D00AE885C /* pb_globals.c */,
0C02407C0BB7916D00AE885C /* Huffman.c */,
0C02407D0BB7916D00AE885C /* quantize.c */,
0C02407E0BB7916D00AE885C /* recon.c */,
0C02407F0BB7916D00AE885C /* TokenEntropy.c */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
D2AAC046055464E500DB518D /* libvp6d.a */,
);
name = Products;
sourceTree = "<group>";
};
C6A0FF2B0290797F04C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
D2AAC043055464E500DB518D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
D2AAC045055464E500DB518D /* vp60 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "vp60" */;
buildPhases = (
D2AAC043055464E500DB518D /* Headers */,
D2AAC044055464E500DB518D /* Sources */,
D289987405E68DCB004EDB86 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = vp60;
productName = vp60;
productReference = D2AAC046055464E500DB518D /* libvp6d.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "vp6d" */;
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* vp60 */;
projectDirPath = "";
targets = (
D2AAC045055464E500DB518D /* vp60 */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
D2AAC044055464E500DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0C02406A0BB7912C00AE885C /* boolhuff.c in Sources */,
0C02406D0BB7913500AE885C /* debug.c in Sources */,
0C0240840BB7916D00AE885C /* DSystemDependant.c in Sources */,
0C0240850BB7916D00AE885C /* FrameIni.c in Sources */,
0C0240880BB7916D00AE885C /* modestats.c in Sources */,
0C0240890BB7916D00AE885C /* pb_globals.c in Sources */,
0C02408A0BB7916D00AE885C /* Huffman.c in Sources */,
0C02408B0BB7916D00AE885C /* quantize.c in Sources */,
0C02408C0BB7916D00AE885C /* recon.c in Sources */,
0C02408D0BB7916D00AE885C /* TokenEntropy.c in Sources */,
0C0240B30BB791FF00AE885C /* vp60dxv.c in Sources */,
0C1423C30BB819EB00FDDAB7 /* vfwpbdll_if.c in Sources */,
0C1423D90BB81A1200FDDAB7 /* decodembs.c in Sources */,
0C1423E00BB81A3000FDDAB7 /* decodemode.c in Sources */,
0C1423E10BB81A3000FDDAB7 /* decodemv.c in Sources */,
0C1423E20BB81A3000FDDAB7 /* DFrameR.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB91EC08733DB70010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = vp6d;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB91ED08733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = vp6d;
};
name = Release;
};
1DEB91F008733DB70010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = build;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
SYMROOT = ../../../../lib/osx;
USER_HEADER_SEARCH_PATHS = "include ../../include ../../../include ../../../../include ../../../../include/vp60";
};
name = Debug;
};
1DEB91F108733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = build;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
SYMROOT = ../../../../lib/osx;
USER_HEADER_SEARCH_PATHS = "include ../../include ../../../include ../../../../include ../../../../include/vp60";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "vp60" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91EC08733DB70010E9CD /* Debug */,
1DEB91ED08733DB70010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "vp6d" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91F008733DB70010E9CD /* Debug */,
1DEB91F108733DB70010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
@@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vp6e", "vp6e.vcproj", "{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}.Debug.ActiveCfg = Debug|Win32
{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}.Debug.Build.0 = Debug|Win32
{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}.Release.ActiveCfg = Release|Win32
{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
@@ -0,0 +1,626 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vp6e"
ProjectGUID="{9BB38682-B7F7-44E8-BE04-BD9D1F5512CE}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\..\..\Lib\Win32\Debug"
IntermediateDirectory=".\..\..\..\..\ObjectCode\vp6e\debug"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories=".\include,..\include,..\..\include,..\..\..\include,..\..\..\..\include,..\..\..\..\Include\vp60,..\..\..\..\include\vp60"
PreprocessorDefinitions="vp6E_EXPORTS;_DEBUG;WIN32;_WINDOWS;_USRDLL;PREDICT_2D;VFW_COMP;COMPDLL;POSTPROCESS;CPUISLITTLEENDIAN;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\..\..\..\..\ObjectCode\vp6e\debug/vp6e.pch"
AssemblerListingLocation=".\..\..\..\..\ObjectCode\vp6e\debug/"
ObjectFile=".\..\..\..\..\ObjectCode\vp6e\debug/"
ProgramDataBaseFileName=".\..\..\..\..\ObjectCode\vp6e\debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\..\..\Lib\Win32\Debug\s_vp60e.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\..\..\Lib\Win32\Release"
IntermediateDirectory=".\..\..\..\..\ObjectCode\vp6e\Release"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
AdditionalIncludeDirectories=".\include,..\include,..\..\include,..\..\..\include,..\..\..\..\include,..\..\..\..\Include\vp60"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;vp6E_EXPORTS;PREDICT_2D;VFW_COMP;COMPDLL;POSTPROCESS;CPUISLITTLEENDIAN;NORMALIZED;INLINE=__forceinline;FORCEINLINE=__forceinline"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
PrecompiledHeaderFile=".\..\..\..\..\ObjectCode\vp6e\Release/vp6e.pch"
AssemblerListingLocation=".\..\..\..\..\ObjectCode\vp6e\Release/"
ObjectFile=".\..\..\..\..\ObjectCode\vp6e\Release/"
ProgramDataBaseFileName=".\..\..\..\..\ObjectCode\vp6e\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\..\..\Lib\Win32\Release\s_vp60e.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Compress"
Filter="">
<File
RelativePath="CX\Generic\Comp_Globals.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\CSystemDependant.c">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\Encode.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\encodembs.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\encodemode.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\encodemv.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\fullframefdct.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="CX\Generic\mcomp.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="CX\Generic\misc_common.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\PackVideo.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\PickModes.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\RawBuffer.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\Tokenize.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\Transform.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Generic\twopass.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="CX\Generic\vfwcomp.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="CX\Generic\vfwcomp_if.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Win32"
Filter="">
<File
RelativePath="cx\Win32\COptFunctions.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\csystemdependant.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\CWmtFunctions.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\MmxEncodeMath.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.lst /Fo &quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.obj &quot;$(InputPath)&quot;
"
Outputs=".\&quot;$(IntDir)&quot;\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)/$(InputName)&quot;.lst /Fo &quot;$(IntDir)/$(InputName)&quot;.obj &quot;$(InputPath)&quot;"
Outputs="$(IntDir)/$(InputName).obj"/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\WmtTransform.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\XmmGetError.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.lst /Fo &quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.obj &quot;$(InputPath)&quot;
"
Outputs=".\&quot;$(IntDir)&quot;\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)/$(InputName)&quot;.lst /Fo &quot;$(IntDir)/$(InputName)&quot;.obj &quot;$(InputPath)&quot;"
Outputs="$(IntDir)/$(InputName).obj"/>
</FileConfiguration>
</File>
<File
RelativePath="CX\Win32\XmmGetSAD8.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.lst /Fo &quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.obj &quot;$(InputPath)&quot;
"
Outputs=".\&quot;$(IntDir)&quot;\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)/$(InputName)&quot;.lst /Fo &quot;$(IntDir)/$(InputName)&quot;.obj &quot;$(InputPath)&quot;"
Outputs="$(IntDir)/$(InputName).obj"/>
</FileConfiguration>
</File>
<File
RelativePath="cx\Win32\XmmSAD.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.lst /Fo &quot;$(IntDir)&quot;\&quot;$(InputName)&quot;.obj &quot;$(InputPath)&quot;
"
Outputs=".\&quot;$(IntDir)&quot;\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="ml /Zi /Zm /Cx /c /coff /Fl&quot;$(IntDir)/$(InputName)&quot;.lst /Fo &quot;$(IntDir)/$(InputName)&quot;.obj &quot;$(InputPath)&quot;"
Outputs="$(IntDir)/$(InputName).obj"/>
</FileConfiguration>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,139 @@
/****************************************************************************
*
* Module Title : xprintf.cpp
*
* Description : Display a printf style message on the current video frame.
*
****************************************************************************/
/****************************************************************************
* Header Files
****************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#include "xprintf.h"
/****************************************************************************
*
* ROUTINE : xprintf
*
* INPUTS : const PB_INSTANCE *ppbi : Pointer to decoder instance.
* long nPixel : Offset into buffer to write text.
* const char *format : Format string for print.
* ... : Variable length argument list.
*
* OUTPUTS : None.
*
* RETURNS : int: Size (in bytes) of the formatted text.
*
* FUNCTION : Display a printf style message on the current video frame.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int vp6_xprintf ( const PB_INSTANCE *ppbi, long nPixel, const char *format, ... )
{
BOOL bRC;
va_list arglist;
HFONT hfont, hfonto;
int rc = 0;
long nSizeY = ppbi->HFragments * 8;
long nStride = ppbi->Configuration.YStride;
char szFormatted[256] = "";
UINT8 *pDest = &ppbi->PostProcessBuffer[nPixel];
// Format text
va_start ( arglist, format );
_vsnprintf ( szFormatted, sizeof(szFormatted), format, arglist );
va_end ( arglist );
#if defined (_WIN32_WCE)
#else
// Set up temporary bitmap
HDC hdcMemory = NULL;
HBITMAP hbmTemp = NULL;
HBITMAP hbmOrig = NULL;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = 8 * strlen(szFormatted);
rect.bottom = 8;
hdcMemory = CreateCompatibleDC ( NULL );
if ( hdcMemory == NULL )
goto Exit;
hbmTemp = CreateBitmap ( rect.right, rect.bottom, 1, 1, NULL );
if ( hbmTemp == NULL )
goto Exit;
hbmOrig = static_cast<HBITMAP>(SelectObject(hdcMemory, hbmTemp));
if ( !hbmOrig )
goto Exit;
// Write text into bitmap
// font?
hfont = CreateFont ( 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, "" );
if ( hfont == NULL )
goto Exit;
hfonto = static_cast<HFONT>(SelectObject(hdcMemory, hbmTemp));
if ( !hfonto )
goto Exit;
SelectObject ( hdcMemory, hfont );
SetTextColor ( hdcMemory, 1 );
SetBkColor ( hdcMemory, 0 );
SetBkMode ( hdcMemory, TRANSPARENT );
bRC = BitBlt ( hdcMemory, rect.left, rect.top, rect.right, rect.bottom, hdcMemory, rect.left, rect.top, BLACKNESS );
if ( !bRC )
goto Exit;
bRC = ExtTextOut ( hdcMemory, 0, 0, ETO_CLIPPED, &rect, szFormatted, strlen(szFormatted), NULL );
if ( !bRC )
goto Exit;
// Copy bitmap to video frame
long x;
long y;
for ( y=rect.top; y<rect.bottom; ++y )
{
for ( x=rect.left; x<rect.right; ++x )
{
if ( GetPixel( hdcMemory, x, rect.bottom - 1 - y ) )
pDest[x] = 255;
}
pDest += nStride;
}
rc = strlen ( szFormatted );
Exit:
if ( hbmTemp != NULL )
{
if ( hbmOrig != NULL )
{
SelectObject ( hdcMemory, hbmOrig );
}
DeleteObject ( hbmTemp );
}
if ( hfont != NULL )
{
if ( hfonto != NULL )
SelectObject ( hdcMemory, hfonto );
DeleteObject ( hfont );
}
if ( hdcMemory != NULL )
DeleteDC ( hdcMemory );
hdcMemory = 0;
#endif
return rc;
}
@@ -0,0 +1,308 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9E8FD088-3571-4BCD-896D-8DBFEC3042FC}</ProjectGuid>
<RootNamespace>dxv</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>16.0.32002.118</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\obj\dxv\$(PlatformShortName)_$(Configuration)\</IntDir>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\obj\dxv\$(PlatformShortName)_$(Configuration)\</IntDir>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Vcpkg">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Vcpkg">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\include;..\..\..\include;..\..\..\..\libvp6\include;..\..\..\..\libvp6\corelibs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4013;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\include;..\..\..\include;..\..\..\..\libvp6\include;..\..\..\..\libvp6\corelibs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4013;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\..\include;..\..\..\..\libvp6\include;..\..\..\..\libvp6\corelibs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\..\include;..\..\..\..\libvp6\include;..\..\..\..\libvp6\corelibs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="generic\dxlvinfd.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\dxl_attr.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\dxl_main.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\dxl_reg.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\dxv_init.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\vscreen.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="generic\ximage.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="win32\dxAccurateTime.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="win32\icmdxv.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="generic">
<UniqueIdentifier>{12c2bb0c-53fa-442f-812f-1e57762a8b14}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{16f6450f-7013-49fe-a82b-a2a13821ec8c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="generic\dxl_attr.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\dxl_main.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\dxl_reg.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\dxlvinfd.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\dxv_init.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="win32\icmdxv.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\vscreen.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="generic\ximage.c">
<Filter>generic</Filter>
</ClCompile>
<ClCompile Include="win32\dxAccurateTime.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,33 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include "dxl_main.h"
int DXL_SetVScreenBlitQuality(DXL_VSCREEN_HANDLE dst, enum BLITQUALITY blitquality)
{
int oldBQ;
validate(dst);
oldBQ = dst->bq;
dst->bq = blitquality;
return oldBQ;
}
enum BLITQUALITY DXL_GetVScreenBlitQuality(DXL_VSCREEN_HANDLE dst)
{
if (dst) {
return dst->bq;
}
return DXBLIT_SAME;
}
@@ -0,0 +1,69 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include "duck_mem.h"
#include "dxl_main.h"
static DXL_VSCREEN_HANDLE vScreens = NULL;
static int maxScreens;
int preallocVScreens(int lmaxScreens)
{
(void) lmaxScreens; // not used
#if PRE_ALLOCATE
vScreens = (DXL_VSCREEN_HANDLE)duck_calloc(maxScreens = lmaxScreens,sizeof(DXL_VSCREEN),DMEM_GENERAL);
if (vScreens == NULL)
return DXL_ALLOC_FAILED;
#endif
return DXL_OK;
}
void freeVScreens(void)
{
#if PRE_ALLOCATE
int i;
if (vScreens)
{
for(i = 0; i < maxScreens; i++)
DXL_DestroyVScreen(&vScreens[i]);
duck_free(vScreens);
}
#endif
}
DXL_VSCREEN_HANDLE vScreenCreate(void)
{
DXL_VSCREEN_HANDLE nScreen;
#if PRE_ALLOCATE
if (vScreens)
{
int i;
nScreen = vScreens;
for(i=0; i < maxScreens; i++,nScreen++)
if (!nScreen->dkFlags.inUse) break;
if (i < maxScreens)
return nScreen;
}
#endif
nScreen = (DXL_VSCREEN_HANDLE)duck_calloc(1,sizeof(DXL_VSCREEN),DMEM_GENERAL);
if (nScreen)
nScreen->dkFlags.allocated = 1;
return nScreen;
}
@@ -0,0 +1,236 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
/********
DXL_REG.C - functions for registration of "Blit" functions
(C)1996 The Duck Corporation
********/
#include <assert.h>
#include <dxl_main.h>
#include <stdio.h>
#include <string.h>
#include "duck_mem.h"
typedef struct tBlitStruct {
blitFunc setup, blit, exit;
} DXL_BLITTER, DXL_BLITTER_HANDLE;
static int nextBlitter = 1;
/**************/
static DXL_BLITTER blitTable[32][DXL_MAX_IFORMATS];
static signed char blitTranslateTable[MAX_BQUALITIES][MAX_CDEPTHS];
static void nullBlitter(void){}
static DXL_INTERNAL_FORMAT iFormats[] = {
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT,
DXL_NULL_IFORMAT
};
DXL_INTERNAL_FORMAT dxl_GetFOURCCInternalFormat(unsigned long fourcc)
{
int aHandle = dxl_GetAlgHandle(fourcc);
if (aHandle != -1)
return iFormats[aHandle];
return DXL_NULL_IFORMAT;
}
int dxl_RegisterInternalFormat(int xHandle, DXL_INTERNAL_FORMAT xFormat)
{
iFormats[xHandle] = xFormat;
return DXL_OK;
}
DXL_BLIT_FORMAT DXL_ReserveBlitter(void)
{
if (nextBlitter >= 32)
return -1; /*DXL_EXCEEDED_MAX_BLITTERS;*/
return nextBlitter++;
}
DXL_BLIT_FORMAT DXL_OverrideBlitter(enum BLITQUALITY bq,enum BITDEPTH bd)
{
if(blitTranslateTable[bq][bd] == (signed char)-1)
blitTranslateTable[bq][bd] = (char)DXL_ReserveBlitter();
return blitTranslateTable[bq][bd];
}
int DXL_RegisterBlitter(DXL_BLIT_FORMAT dFormat, DXL_INTERNAL_FORMAT sFormat,
blitFunc blit, blitFunc setup, blitFunc exit)
{
if ((dFormat >= nextBlitter) || (sFormat >= DXL_MAX_IFORMATS))
return -1; /*DXL_INVALID_BLIT_FORMAT;*/
blitTable[dFormat][sFormat].setup = setup;
blitTable[dFormat][sFormat].exit = exit;
blitTable[dFormat][sFormat].blit = blit;
return 0; /*DXL_OK;*/
}
DXL_INTERNAL_FORMAT DXL_GetXImageInternalFormat(DXL_XIMAGE_HANDLE xImage,
DXL_VSCREEN_HANDLE vScreen)
{
int ret;
ret = xImage->internalFormat(xImage,vScreen);
if (ret == DXL_NULL_IFORMAT)
{
return (DXL_INTERNAL_FORMAT )
dxl_GetFOURCCInternalFormat(DXL_GetXImageFOURCC(xImage));
}
return (DXL_INTERNAL_FORMAT ) ret;
}
DXL_INTERNAL_FORMAT DXL_GetVScreenInternalFormat(DXL_VSCREEN_HANDLE vScreen)
{
if (vScreen->bd == DXRGB16){
return DXL_LINE16;
}else if (vScreen->bd == DXRGB8||vScreen->bd == DXHALFTONE8){
return DXL_LINE8;
}else
return (DXL_INTERNAL_FORMAT) -1;
}
blitFunc DXL_GetVBlitFunc(DXL_VSCREEN_HANDLE src,DXL_VSCREEN_HANDLE dst)
{
return blitTable[DXL_GetVScreenBlitFormat(dst)]
[DXL_GetVScreenInternalFormat(src)].blit;
}
blitFunc DXL_GetVBlitSetupFunc(DXL_VSCREEN_HANDLE src,DXL_VSCREEN_HANDLE dst)
{
return blitTable[DXL_GetVScreenBlitFormat(dst)]
[DXL_GetVScreenInternalFormat(src)].setup;
}
blitFunc DXL_GetBlitFunc(DXL_XIMAGE_HANDLE xImage,DXL_VSCREEN_HANDLE vScreen)
{
DXL_BLIT_FORMAT i = DXL_GetVScreenBlitFormat(vScreen);
DXL_INTERNAL_FORMAT j = DXL_GetXImageInternalFormat(xImage,vScreen);
if(i == -1)
return (blitFunc)-1;
if(j == DXL_NULL_IFORMAT)
#pragma warning(disable:4054) // typecase from function pointer to data pointer
return (blitFunc)nullBlitter;
#pragma warning(default:4054) // typecase from function pointer to data pointer
else
return blitTable[i][j].blit;
}
void *DXL_GetBlitSetupFunc(DXL_XIMAGE_HANDLE xImage,DXL_VSCREEN_HANDLE vScreen)
{
return blitTable[DXL_GetVScreenBlitFormat(vScreen)]
[DXL_GetXImageInternalFormat(xImage,vScreen)].setup;
}
void *DXL_GetBlitExitFunc(DXL_XIMAGE_HANDLE xImage,DXL_VSCREEN_HANDLE vScreen)
{
return blitTable[DXL_GetVScreenBlitFormat(vScreen)]
[DXL_GetXImageInternalFormat(xImage,vScreen)].exit;
}
DXL_BLIT_FORMAT DXL_GetVScreenBlitFormat(DXL_VSCREEN_HANDLE vScreen)
{ enum BLITQUALITY bq;
if (vScreen->blitFormat != (signed char)-1)
return vScreen->blitFormat;
bq = DXL_GetVScreenBlitQuality(vScreen);
return blitTranslateTable[bq]
[vScreen->bd];
}
void resetBlitters(void)
{
nextBlitter = 0;
duck_memset(blitTable,-1,sizeof(blitTable));
duck_memset(blitTranslateTable,-1,sizeof(blitTranslateTable));
}
int DXL_CheckFCCToVScreenFormat(unsigned long FCC,enum BITDEPTH format, enum BLITQUALITY bq)
{
DXL_XIMAGE_HANDLE src;
DXL_VSCREEN_HANDLE dst;
int ret = DXL_INVALID_BLIT;
src = DXL_CreateXImageOfType(NULL,FCC);
assert(src != NULL);
if (src)
{
dst = DXL_CreateVScreen(
(unsigned char *)0xDEADBEEF, format, 1280,480);
assert(dst != NULL);
if (dst)
{
dst->bq = bq;
ret = DXL_CheckdxImageToVScreen(src, dst);
DXL_DestroyVScreen(dst);
}
DXL_DestroyXImage(src);
}
return ret;
}
int DXL_CheckVScreenXImageBlit(DXL_VSCREEN_HANDLE dst,DXL_XIMAGE_HANDLE src)
{
validate(src);
if (!src->dx)
return -1;
if (!dst) return -1;
if (src->verify != NULL)
return(src->verify(src,dst));
#pragma warning(disable:4054) // typecase from function pointer to data pointer
if((void *)(src->internalFormat) != NULL){
dst->blitter = DXL_GetBlitFunc(src, dst);
if ((dst->blitter != (void *) -1) && (dst->blitter != nullBlitter))
return DXL_OK;
}
#pragma warning(default:4054) // typecase from function pointer to data pointer
return DXL_INVALID_BLIT;
}
int DXL_CheckVScreenBlit(DXL_VSCREEN_HANDLE dst,unsigned long fourcc)
{
return DXL_CheckFCCToVScreenFormat(fourcc,dst->bd, dst->bq);
}
int DXL_CheckdxImageToVScreen(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE dst)
{
return DXL_CheckVScreenXImageBlit( dst, src);
}
@@ -0,0 +1,76 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
/*/////////////////////////////////////////////////////////////////////////
//
// dxlvinfd.c
//
// Purpose: A list of helper functions to the quick time codec code
//
///////////////////////////////////////////////////////////////////////*/
//#include <stdio.h>
//#include <math.h>
//#include <string.h>
#include "dxl_main.h"
struct DisplaySetting {
long dotOne;
long dotTwo;
long dotThree;
long dotFour;
long dotFive;
};
static struct DisplaySetting id_RGB24 ={0x00000000,0x00000000,0xffffffff,0x00000000,0xffffffff};
static struct DisplaySetting id_RGB32 ={0x00000000,0x00000000,0x00000000,0x00000000,0xffffffff};
static struct DisplaySetting id_RGB555={0xffffffff,0x00000000,0xffffffff,0x00000000,0xffffffff};
static struct DisplaySetting id_RGB565={0xffffffff,0x00000000,0x00000000,0x00000000,0xffffffff};
static struct DisplaySetting id_UYVY ={0xff80ff80,0x00800080,0xff80ff80,0x00800080,0x00800080};
static struct DisplaySetting id_YUY2 ={0x80ff80ff,0x80008000,0x80008000,0x80008000,0x80008000};
static struct DisplaySetting id_YVU9 ={0x80008000,0x80008000,0xff80ff80,0xff80ff80,0xff80ff80};
static struct DisplaySetting id_RGB8 ={0x00000000,0xffffffff,0x00000000,0xffffffff,0x00000000};
static struct DisplaySetting id_STRETCH ={0x00000000,0xffffffff,0x00000000,0x00000000,0x00000000};
static struct DisplaySetting id_STRETCH_BRIGHT ={0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000};
static struct DisplaySetting id_STRETCH_SAME ={0xffffffff,0x00000000,0x00000000,0x00000000,0x00000000};
static struct DisplaySetting id_KEY = {0x00000000,0x00000000,0xffffffff,0x00000000,0x00000000};
static struct DisplaySetting id_NOTKEY = {0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};
static struct DisplaySetting id_CLEAR_ME = {0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};
static void OrSettings(struct DisplaySetting *src1,struct DisplaySetting *src2, struct DisplaySetting *dst)
{
if (dst) {
dst->dotOne = src1->dotOne | src2->dotOne;
dst->dotTwo = src1->dotTwo | src2->dotTwo;
dst->dotThree = src1->dotThree | src2->dotThree;
dst->dotFour = src1->dotFour | src2->dotFour;
dst->dotFive = src1->dotFive | src2->dotFive;
}
}
static void SetSettings(struct DisplaySetting *dst,struct DisplaySetting *src)
{
if (dst) {
dst->dotOne = src->dotOne ;
dst->dotTwo = src->dotTwo ;
dst->dotThree = src->dotThree ;
dst->dotFour = src->dotFour ;
dst->dotFive = src->dotFive ;
}
}
@@ -0,0 +1,43 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include "duck_mem.h"
#include "dxl_main.h"
#if defined(DISPLAYDIB)
#if DISPLAYDIB
int globalIsDIB,globalDIBWidth,globalDIBHeight;
#endif
#endif
extern int preallocVScreens(int lmaxScreens);
extern void freeVScreens(void);
int DXL_InitVideo(int lmaxScreens,int lmaxImages)
{
(void)lmaxImages; // Not Used;
/* registerDuckBlitters(); */
resetBlitters();
// DXL_RegisterXImage(NULL,0L,(DXL_INTERNAL_FORMAT ) 0);
preallocVScreens(lmaxScreens);
return DXL_OK;
}
void DXL_ExitVideo(void)
{
freeVScreens();
}
@@ -0,0 +1,175 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include "duck_mem.h"
#include "dxl_main.h"
#include <assert.h>
/***********************************************/
int DXL_GetVScreenSizeOfPixel(DXL_VSCREEN_HANDLE vSc)
{
switch (vSc->bd){
case DXRGB8:
case DXHALFTONE8:
case DXRGB8VESA:
return 1;
case DXRGB16_555:
case DXRGB16_565:
case DXRGB16VESA:
case DXYUY2:
case DXUYVY:
return 2;
case DXRGB24:
return 3;
case DXRGB32:
return 4;
default:
return -1;
}
}
void DXL_DestroyVScreen(DXL_VSCREEN_HANDLE dst)
{
if (dst != NULL){
dst->dkFlags.inUse = 0;
dst->addr = NULL;
if (dst->dkFlags.allocated)
duck_free(dst);
}
}
int DXL_AlterVScreen(DXL_VSCREEN_HANDLE dst, unsigned char *addr,enum BITDEPTH bd, int p,int h)
{
validate(dst);
if (addr != NULL) dst->addr = addr;
if (bd != DXRGBNULL) dst->bd = bd;
if (p != -1) dst->pitch = (short) p;
if (h != -1) dst->height = (short) h;
return DXL_OK;
}
int DXL_AlterVScreenView(DXL_VSCREEN_HANDLE dst,int x,int y,int w,int h)
{
validate(dst);
if (x > -1) dst->viewX = (short)x;// & 0xfffe;
if (y > -1) dst->viewY = (short)y;
if (w > -1) dst->viewW = (short)w;// & 0xfffe;
if (h > -1) dst->viewH = (short)h;
return DXL_OK;
}
DXL_VSCREEN_HANDLE DXL_CreateVScreen(unsigned char *addr, enum BITDEPTH bd, short p,short h)
{
#pragma warning(disable: 4210) // nonstandard extension used : function given file scope
DXL_VSCREEN_HANDLE vScreenCreate(void);
#pragma warning(default: 4210) // nonstandard extension used : function given file scope
DXL_VSCREEN_HANDLE nScreen = vScreenCreate();
if (!nScreen) return NULL;
nScreen->dkFlags.inUse = 1;
nScreen->blitFormat = -1;
DXL_AlterVScreen(nScreen, addr, bd, p, h);
nScreen->bx = nScreen->by = 0;
nScreen->bAddr = NULL;
nScreen->bq = DXBLIT_SAME;
return nScreen;
}
int DXL_GetVScreenView(DXL_VSCREEN_HANDLE dst,int *x,int *y,int *w,int *h)
{
validate(dst);
*x = dst->viewX;
*y = dst->viewY;
*w = dst->viewW;
*h = dst->viewH;
return DXL_OK;
}
int DXL_GetVScreenAttributes(
DXL_VSCREEN_HANDLE vScreen,
void **addr,
dxvBlitQuality *bq,
dxvBitDepth *bd,
short *pitch,
short *height
)
{
if (addr)
{
*addr = (void *) (vScreen->addr);
}
else
{
assert(0);
}
if (bq)
{
*bq = vScreen->bq;
}
else
{
assert(0);
}
if (bd)
{
*bd = vScreen->bd;
}
else
{
assert(0);
}
if (pitch)
{
*pitch = vScreen->pitch;
}
else
{
assert(0);
}
if (height)
{
*height = vScreen->height;
}
else
{
assert(0);
}
return 0;
} /* end get attributes */
@@ -0,0 +1,353 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include "duck_mem.h"
#include "dxl_main.h"
int DXL_SetXImageCSize(DXL_XIMAGE_HANDLE src, int temp)
{
src->fSize = temp;
return temp;
}
void DXL_DestroyXImage(DXL_XIMAGE_HANDLE src)
{
{
#pragma warning(disable:4210) //nonstandard extension used : function given file scope
void DXL_AccurateTime(UINT64* time);
#pragma warning(default:4210) //nonstandard extension used : function given file scope
UINT64 clocksTotal;
double ratio, ratio2;
DXL_AccurateTime(&src->prof.profileEnd);
clocksTotal = (src->prof.profileEnd - src->prof.profileStart);
if (clocksTotal)
{
ratio = src->prof.dxClocks * 1.0 / clocksTotal;
ratio2 = (double)(src->prof.dxClocks / src->prof.frameCount);
}
}
if (src != NULL)
{
if (src->dkFlags.inUse)
{
src->destroy(src);
}
}
}
int DXL_MoveXImage(DXL_XIMAGE_HANDLE src,enum OFFSETXY mode, int x,int y)
{
validate(src);
if (mode != DXL_RELATIVE){
src->x = 0;
src->y = 0;
}
src->x = (short)(src->x + x);
src->y = (short)(src->y + y);
return DXL_OK;
}
int DXL_AlterXImageData(DXL_XIMAGE_HANDLE src, unsigned char *data)
{
validate(src);
src->addr = data;
src->dkFlags.DXed = 0;
if (data == NULL) return DXL_OK;
if (src->seedData)
return src->seedData(src);
else
return 0;
}
int DXL_GetXImageXYWH(DXL_XIMAGE_HANDLE src,int *x,int *y,int *w, int *h)
{
validate(src);
*x = src->x;
*y = src->y;
*w = src->w;
*h = src->h;
return DXL_OK;
}
int DXL_IsXImageKeyFrame(DXL_XIMAGE_HANDLE src)
{
validate(src);
return src->dkFlags.keyFrame;
}
/* typedef DXL_XIMAGE_HANDLE (*createFunc)(unsigned char *data); */
#define NUM_ALG 16
static createFunc creator[NUM_ALG];
static unsigned long fourCC[NUM_ALG];
DXL_XIMAGE_HANDLE DXL_CreateXImage(unsigned char *data)
{
int i;
DXL_XIMAGE_HANDLE nImage = NULL;
for(i = 0; i < NUM_ALG; i++){
if (fourCC[i]){
nImage = creator[i](data);
if ( nImage )
break;
}else
break;
}
if (nImage)
{
nImage->dkFlags.inUse = 1;
nImage->addr = data;
nImage->create = (struct tXImage *(__cdecl *)(void *))creator[i];
}
return nImage;
}
DXL_XIMAGE_HANDLE DXL_CreateXImageOfType(unsigned char *data,unsigned long type)
{
int i;
DXL_XIMAGE_HANDLE nImage = NULL;
for(i = 0; i < NUM_ALG; i++){
if (fourCC[i] == type){
nImage = creator[i](data);
if ( nImage )
break;
}
}
if (nImage)
{
nImage->dkFlags.inUse = 1;
nImage->addr = data;
nImage->prof.profileStart = 0;
nImage->prof.dxClocks = 0;
nImage->prof.frameCount = 0;
}
return nImage;
}
DXL_XIMAGE_HANDLE DXL_CreateXImageFromBMI(
unsigned char *data,
unsigned long fcc,
DK_BITMAPINFOHEADER *srcAndDest /* There will always be two Obiwan */
)
{
int i;
DXL_XIMAGE_HANDLE nImage = NULL;
for(i = 0; i < NUM_ALG; i++){
if (fourCC[i] == fcc){
nImage = creator[i]((unsigned char *) srcAndDest);
if ( nImage )
break;
}
}
if (nImage)
{
nImage->dkFlags.inUse = 1;
nImage->addr = data;
duck_memset(&nImage->prof,0,sizeof(DXL_PROFILEPACK)); /* probably redundent */
}
return nImage;
}
int DXL_RegisterXImage(createFunc myCreator,unsigned long fourcc, DXL_INTERNAL_FORMAT xFormat)
{
int i;
if (!fourcc){
duck_memset(creator,0,sizeof(creator));
duck_memset(fourCC,0,sizeof(fourCC));
return 0;
}
for (i = 0; i < sizeof(fourCC)/sizeof(unsigned long);i++){
if (!fourCC[i]){
creator[i] = myCreator;
fourCC[i] = fourcc;
dxl_RegisterInternalFormat(i, xFormat);
return i;
}
}
return -1;
}
unsigned long *DXL_GetFourCCList(void)
{
/*********
return a list of all supported fourccs
*********/
return fourCC;
}
int dxl_GetAlgHandle(unsigned long fourcc)
{
/*********
search through the fourcc table to find a dx'er's index
*********/
int i;
for (i = 0; i < sizeof(fourCC)/sizeof(unsigned long);i++)
if (fourCC[i] == fourcc) return i;
return -1;
}
unsigned long DXL_GetXImageFOURCC(DXL_XIMAGE_HANDLE src)
{
/*********
find an ximages fourcc (by comparing creator functions)
*********/
int i;
for (i = 0; i < sizeof(fourCC)/sizeof(unsigned long);i++)
if (creator[i] == (createFunc)src->create)
return fourCC[i];
return 0L;
}
unsigned char *DXL_GetDestAddress(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE dst)
{
/*********
get the address within the vscreen to start writing at
*********/
unsigned char *scrnDest = (unsigned char *)0L;
int x,y;
y = dst->viewY + src->y;
x = dst->viewX + src->x;
scrnDest = (unsigned char *) dst->addr;
scrnDest += (x * DXL_GetVScreenSizeOfPixel(dst)) + (y * dst->pitch);
return scrnDest;
}
int DXL_dxImageToVScreen(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE dst)
{
int dxvCode;
validate(src);
if (!src->dx)
return -1;
#pragma warning(disable:4054) // typecase from function pointer to data pointer
if(dst && ((void *)(src->internalFormat) != NULL)) {
/* get your hamdy damdy((c)1997 Duck North) registered blitter setup */
dst->blitSetup = DXL_GetBlitSetupFunc(src,dst);
dst->blitExit = DXL_GetBlitExitFunc(src,dst);
dst->blitter = DXL_GetBlitFunc(src, dst);
if (dst->blitter == (void *) -1)
return DXL_INVALID_BLIT;
}
#pragma warning(default:4054) // typecase from function pointer to data pointer
// if (!src->addr)
// return 1;
#if 1 /* we want to profile ... this should constitute no performance hit to profile */
{
UINT64 timerStart;
UINT64 timerEnd;
void DXL_AccurateTime(UINT64* time);
DXL_AccurateTime(&timerStart);
if (src->prof.profileStart == 0)
src->prof.profileStart = timerStart;
dxvCode = src->dx(src,dst);
DXL_AccurateTime(&timerEnd);
src->prof.dxClocks += (timerEnd - timerStart);
src->prof.frameCount += 1;
}
#else
dxvCode = src->dx(src,dst);
#endif
return dxvCode;
}
long DXL_GetXImageCSize(DXL_XIMAGE_HANDLE src)
{
if (src == NULL) return -1;
if (!src->GetXImageCSize)
return -2;
return(src->GetXImageCSize(src));
}
/***********************************************/
DXL_XIMAGE_HANDLE DXL_AlterXImage(DXL_XIMAGE_HANDLE src,
unsigned char *data,int type,
enum BITDEPTH bitDepth,int width,int height)
{
if (src == NULL)
{
if (type) /* if type specified, try using it as the fourcc */
src = DXL_CreateXImageOfType(data,type);
if (src == NULL) /* if still null, try creating it blind from the data */
src = DXL_CreateXImage(data);
if (src == NULL) /* if still null, give up */
return NULL;
}
if (!src->recreate) /* no way to recreate, assume create is good enough */
return src;
return(src->recreate(src,data,type,bitDepth,width,height));
}
void DXL_SetParameter(DXL_XIMAGE_HANDLE src, int Command, unsigned long Parameter )
{
src->setParameter(src,Command,Parameter);
}
@@ -0,0 +1,40 @@
#include "dxl_main.h"
#include "duck_dxl.h"
/*-------------------------------------------------------------------
File : dxv_util.c
Any extra functions whose lifespan/utility might be "questionable".
Functions that are not part of the "core", but yet are not really
anything but Dxv specific.
-------------------------------------------------------------------*/
/* This function used during the development of ICM wrapper */
/*----------------------------------------------------------*/
char *DXL_DumpRegistry(char *buf);
char *DXL_DumpRegistry(char *buf)
{
int sprintf( char *buffer, const char *format, ...);
unsigned long *g = DXL_GetFourCCList();
int i = 0;
while(g)
{
sprintf(buf,"fourCC[%d] = %c%c%c%c\n",i,
(g[i] & 0xFF000000) >> 24,
(g[i] & 0xFF0000) >> 16,
(g[i] & 0xFF00) >> 8,
(g[i] & 0xFF) >> 0
);
g++;
}
return buf;
}

Some files were not shown because too many files have changed in this diff Show More