summaryrefslogtreecommitdiff
path: root/third_party
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2012-04-19 06:36:57 +0000
committerLiong Sauw Ming <ming@teluu.com>2012-04-19 06:36:57 +0000
commit7873aff384696ef64669c51d0b5457d206536a28 (patch)
tree55051a3a80cb6075c5f91e01770ddbc89d3a1ea7 /third_party
parentbe78f596a56580ae6984895355168376d49d9099 (diff)
Re #1276: Integrate BaseClasses with the project and remove unnecessary classes
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4062 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/BaseClasses/amextra.cpp111
-rw-r--r--third_party/BaseClasses/amextra.h56
-rw-r--r--third_party/BaseClasses/baseclasses.sln38
-rw-r--r--third_party/BaseClasses/baseclasses.vcproj574
-rw-r--r--third_party/BaseClasses/cache.h74
-rw-r--r--third_party/BaseClasses/checkbmi.h120
-rw-r--r--third_party/BaseClasses/cprop.cpp383
-rw-r--r--third_party/BaseClasses/cprop.h95
-rw-r--r--third_party/BaseClasses/ddmm.cpp129
-rw-r--r--third_party/BaseClasses/ddmm.h28
-rw-r--r--third_party/BaseClasses/dllentry.cpp367
-rw-r--r--third_party/BaseClasses/dllsetup.cpp693
-rw-r--r--third_party/BaseClasses/dllsetup.h46
-rw-r--r--third_party/BaseClasses/dxmperf.h250
-rw-r--r--third_party/BaseClasses/outputq.cpp801
-rw-r--r--third_party/BaseClasses/outputq.h137
-rw-r--r--third_party/BaseClasses/perflog.cpp347
-rw-r--r--third_party/BaseClasses/perflog.h56
-rw-r--r--third_party/BaseClasses/perfstruct.h194
-rw-r--r--third_party/BaseClasses/pstream.cpp197
-rw-r--r--third_party/BaseClasses/pstream.h114
-rw-r--r--third_party/BaseClasses/pullpin.cpp588
-rw-r--r--third_party/BaseClasses/pullpin.h152
-rw-r--r--third_party/BaseClasses/refclock.cpp402
-rw-r--r--third_party/BaseClasses/schedule.cpp284
-rw-r--r--third_party/BaseClasses/schedule.h128
-rw-r--r--third_party/BaseClasses/seekpt.cpp83
-rw-r--r--third_party/BaseClasses/source.cpp522
-rw-r--r--third_party/BaseClasses/source.h172
-rw-r--r--third_party/BaseClasses/streams.h40
-rw-r--r--third_party/BaseClasses/strmctl.cpp402
-rw-r--r--third_party/BaseClasses/strmctl.h157
-rw-r--r--third_party/BaseClasses/sysclock.cpp74
-rw-r--r--third_party/BaseClasses/sysclock.h39
-rw-r--r--third_party/BaseClasses/transfrm.cpp1016
-rw-r--r--third_party/BaseClasses/transfrm.h304
-rw-r--r--third_party/BaseClasses/transip.cpp974
-rw-r--r--third_party/BaseClasses/transip.h250
-rw-r--r--third_party/BaseClasses/videoctl.cpp746
-rw-r--r--third_party/BaseClasses/videoctl.h168
-rw-r--r--third_party/BaseClasses/vtrans.cpp468
-rw-r--r--third_party/BaseClasses/vtrans.h143
-rw-r--r--third_party/BaseClasses/winctrl.cpp2081
-rw-r--r--third_party/BaseClasses/winctrl.h224
-rw-r--r--third_party/BaseClasses/winutil.cpp2746
-rw-r--r--third_party/BaseClasses/winutil.h419
46 files changed, 115 insertions, 17277 deletions
diff --git a/third_party/BaseClasses/amextra.cpp b/third_party/BaseClasses/amextra.cpp
deleted file mode 100644
index af0de96d..00000000
--- a/third_party/BaseClasses/amextra.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-//------------------------------------------------------------------------------
-// File: AMExtra.cpp
-//
-// Desc: DirectShow base classes - implements CRenderedInputPin class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h> // DirectShow base class definitions
-#include <mmsystem.h> // Needed for definition of timeGetTime
-#include <limits.h> // Standard data type limit definitions
-#include <measure.h> // Used for time critical log functions
-
-#include "amextra.h"
-
-#pragma warning(disable:4355)
-
-// Implements CRenderedInputPin class
-
-CRenderedInputPin::CRenderedInputPin(__in_opt LPCTSTR pObjectName,
- __in CBaseFilter *pFilter,
- __in CCritSec *pLock,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName) :
- CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
- m_bAtEndOfStream(FALSE),
- m_bCompleteNotified(FALSE)
-{
-}
-#ifdef UNICODE
-CRenderedInputPin::CRenderedInputPin(__in_opt LPCSTR pObjectName,
- __in CBaseFilter *pFilter,
- __in CCritSec *pLock,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName) :
- CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
- m_bAtEndOfStream(FALSE),
- m_bCompleteNotified(FALSE)
-{
-}
-#endif
-
-// Flush end of stream condition - caller should do any
-// necessary stream level locking before calling this
-
-STDMETHODIMP CRenderedInputPin::EndOfStream()
-{
- HRESULT hr = CheckStreaming();
-
- // Do EC_COMPLETE handling for rendered pins
- if (S_OK == hr && !m_bAtEndOfStream) {
- m_bAtEndOfStream = TRUE;
- FILTER_STATE fs;
- EXECUTE_ASSERT(SUCCEEDED(m_pFilter->GetState(0, &fs)));
- if (fs == State_Running) {
- DoCompleteHandling();
- }
- }
- return hr;
-}
-
-
-// Called to complete the flush
-
-STDMETHODIMP CRenderedInputPin::EndFlush()
-{
- CAutoLock lck(m_pLock);
-
- // Clean up renderer state
- m_bAtEndOfStream = FALSE;
- m_bCompleteNotified = FALSE;
-
- return CBaseInputPin::EndFlush();
-}
-
-
-// Notify of Run() from filter
-
-HRESULT CRenderedInputPin::Run(REFERENCE_TIME tStart)
-{
- UNREFERENCED_PARAMETER(tStart);
- m_bCompleteNotified = FALSE;
- if (m_bAtEndOfStream) {
- DoCompleteHandling();
- }
- return S_OK;
-}
-
-
-// Clear status on going into paused state
-
-HRESULT CRenderedInputPin::Active()
-{
- m_bAtEndOfStream = FALSE;
- m_bCompleteNotified = FALSE;
- return CBaseInputPin::Active();
-}
-
-
-// Do stuff to deliver end of stream
-
-void CRenderedInputPin::DoCompleteHandling()
-{
- ASSERT(m_bAtEndOfStream);
- if (!m_bCompleteNotified) {
- m_bCompleteNotified = TRUE;
- m_pFilter->NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)m_pFilter);
- }
-}
-
diff --git a/third_party/BaseClasses/amextra.h b/third_party/BaseClasses/amextra.h
deleted file mode 100644
index 5a861bf1..00000000
--- a/third_party/BaseClasses/amextra.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//------------------------------------------------------------------------------
-// File: AMExtra.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __AMEXTRA__
-#define __AMEXTRA__
-
-// Simple rendered input pin
-//
-// NOTE if your filter queues stuff before rendering then it may not be
-// appropriate to use this class
-//
-// In that case queue the end of stream condition until the last sample
-// is actually rendered and flush the condition appropriately
-
-class CRenderedInputPin : public CBaseInputPin
-{
-public:
-
- CRenderedInputPin(__in_opt LPCTSTR pObjectName,
- __in CBaseFilter *pFilter,
- __in CCritSec *pLock,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName);
-#ifdef UNICODE
- CRenderedInputPin(__in_opt LPCSTR pObjectName,
- __in CBaseFilter *pFilter,
- __in CCritSec *pLock,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName);
-#endif
-
- // Override methods to track end of stream state
- STDMETHODIMP EndOfStream();
- STDMETHODIMP EndFlush();
-
- HRESULT Active();
- HRESULT Run(REFERENCE_TIME tStart);
-
-protected:
-
- // Member variables to track state
- BOOL m_bAtEndOfStream; // Set by EndOfStream
- BOOL m_bCompleteNotified; // Set when we notify for EC_COMPLETE
-
-private:
- void DoCompleteHandling();
-};
-
-#endif // __AMEXTRA__
-
diff --git a/third_party/BaseClasses/baseclasses.sln b/third_party/BaseClasses/baseclasses.sln
deleted file mode 100644
index a93b581e..00000000
--- a/third_party/BaseClasses/baseclasses.sln
+++ /dev/null
@@ -1,38 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseClasses", "BaseClasses.vcproj", "{E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug_MBCS|Win32 = Debug_MBCS|Win32
- Debug_MBCS|x64 = Debug_MBCS|x64
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release_MBCS|Win32 = Release_MBCS|Win32
- Release_MBCS|x64 = Release_MBCS|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug_MBCS|Win32.ActiveCfg = Debug_MBCS|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug_MBCS|Win32.Build.0 = Debug_MBCS|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug_MBCS|x64.ActiveCfg = Debug_MBCS|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug_MBCS|x64.Build.0 = Debug_MBCS|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug|Win32.ActiveCfg = Debug|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug|Win32.Build.0 = Debug|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug|x64.ActiveCfg = Debug|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Debug|x64.Build.0 = Debug|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release_MBCS|Win32.ActiveCfg = Release_MBCS|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release_MBCS|Win32.Build.0 = Release_MBCS|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release_MBCS|x64.ActiveCfg = Release_MBCS|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release_MBCS|x64.Build.0 = Release_MBCS|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release|Win32.ActiveCfg = Release|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release|Win32.Build.0 = Release|Win32
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release|x64.ActiveCfg = Release|x64
- {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/third_party/BaseClasses/baseclasses.vcproj b/third_party/BaseClasses/baseclasses.vcproj
index 32373bad..1d310856 100644
--- a/third_party/BaseClasses/baseclasses.vcproj
+++ b/third_party/BaseClasses/baseclasses.vcproj
@@ -4,152 +4,23 @@
Version="8.00"
Name="BaseClasses"
ProjectGUID="{E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}"
- RootNamespace="BaseClasses"
- Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
- <Platform
- Name="x64"
- />
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbasd.lib"
- AdditionalLibraryDirectories=""
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbase.lib"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_MBCS|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
@@ -169,92 +40,40 @@
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbasd.lib"
- AdditionalLibraryDirectories=""
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_MBCS|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".,..\..\..\..\include"
+ PreprocessorDefinitions="NDEBUG,WIN32,_LIB,_WIN32_DCOM,WINVER=0x400"
+ StringPooling="true"
RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="streams.h"
+ PrecompiledHeaderFile=".\Release/baseclasses.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
- DebugInformationFormat="3"
+ SuppressStartupBanner="true"
+ CallingConvention="2"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG,WIN32"
+ Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbase.lib"
+ LinkLibraryDependencies="false"
+ AdditionalOptions="/nodefaultlib "
+ OutputFile="..\lib\strmbas-$(ConfigurationName).lib"
+ SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
@@ -273,10 +92,13 @@
/>
</Configuration>
<Configuration
- Name="Debug|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug Unicode|Win32"
+ OutputDirectory=".\Debug_Unicode"
+ IntermediateDirectory=".\Debug_Unicode"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
>
<Tool
@@ -293,34 +115,42 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
+ AdditionalIncludeDirectories=".,..\..\..\..\include"
+ PreprocessorDefinitions="_DEBUG,_MBCS,_LIB,_WIN32_DCOM,DEBUG,WINVER=0x400,WIN32,UNICODE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
- UsePrecompiledHeader="0"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="streams.h"
+ PrecompiledHeaderFile=".\Debug_Unicode/baseclasses.pch"
+ AssemblerListingLocation=".\Debug_Unicode/"
+ ObjectFile=".\Debug_Unicode/"
+ ProgramDataBaseFileName=".\Debug_Unicode/"
WarningLevel="3"
+ SuppressStartupBanner="true"
DebugInformationFormat="3"
+ CallingConvention="2"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG,WIN32"
+ Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbasd.lib"
- AdditionalLibraryDirectories=""
+ AdditionalOptions="/nodefaultlib "
+ OutputFile="Debug_Unicode\strmbasd.lib"
+ SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
@@ -339,10 +169,13 @@
/>
</Configuration>
<Configuration
- Name="Release|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Release Unicode|Win32"
+ OutputDirectory=".\Release_Unicode"
+ IntermediateDirectory=".\Release_Unicode"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
>
<Tool
@@ -359,31 +192,42 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories=".,..\..\..\..\include"
+ PreprocessorDefinitions="NDEBUG,_MBCS,_LIB,_WIN32_DCOM,WINVER=0x400,WIN32,UNICODE"
+ StringPooling="true"
RuntimeLibrary="2"
- UsePrecompiledHeader="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="streams.h"
+ PrecompiledHeaderFile=".\Release_Unicode/baseclasses.pch"
+ AssemblerListingLocation=".\Release_Unicode/"
+ ObjectFile=".\Release_Unicode/"
+ ProgramDataBaseFileName=".\Release_Unicode/"
WarningLevel="3"
- DebugInformationFormat="3"
+ SuppressStartupBanner="true"
+ CallingConvention="2"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG,WIN32"
+ Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbase.lib"
+ AdditionalOptions="/nodefaultlib "
+ OutputFile="Release_Unicode\STRMBASE.lib"
+ SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
@@ -402,10 +246,13 @@
/>
</Configuration>
<Configuration
- Name="Debug_MBCS|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
@@ -422,97 +269,42 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
+ AdditionalIncludeDirectories=".,..\..\..\..\include"
+ PreprocessorDefinitions="_DEBUG,WIN32,_LIB,_WIN32_DCOM,DEBUG,WINVER=0x400"
BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbasd.lib"
- AdditionalLibraryDirectories=""
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_MBCS|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories="."
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
- RuntimeLibrary="2"
+ RuntimeLibrary="1"
UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="streams.h"
+ PrecompiledHeaderFile=".\Debug/baseclasses.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
+ SuppressStartupBanner="true"
DebugInformationFormat="3"
+ CallingConvention="2"
+ CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG,WIN32"
+ Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
- AdditionalDependencies="strmiids.lib"
- OutputFile="$(OutDir)\strmbase.lib"
+ AdditionalOptions="/nodefaultlib "
+ OutputFile="..\lib\strmbas-$(ConfigurationName).lib"
+ SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
@@ -536,14 +328,9 @@
<Files>
<Filter
Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
- RelativePath=".\amextra.cpp"
- >
- </File>
- <File
RelativePath=".\amfilter.cpp"
>
</File>
@@ -560,98 +347,18 @@
>
</File>
<File
- RelativePath=".\cprop.cpp"
- >
- </File>
- <File
RelativePath=".\ctlutil.cpp"
>
</File>
<File
- RelativePath=".\ddmm.cpp"
- >
- </File>
- <File
- RelativePath=".\dllentry.cpp"
- >
- </File>
- <File
- RelativePath=".\dllsetup.cpp"
- >
- </File>
- <File
RelativePath=".\mtype.cpp"
>
</File>
<File
- RelativePath=".\outputq.cpp"
- >
- </File>
- <File
- RelativePath=".\perflog.cpp"
- >
- </File>
- <File
- RelativePath=".\pstream.cpp"
- >
- </File>
- <File
- RelativePath=".\pullpin.cpp"
- >
- </File>
- <File
- RelativePath=".\refclock.cpp"
- >
- </File>
- <File
RelativePath=".\renbase.cpp"
>
</File>
<File
- RelativePath=".\schedule.cpp"
- >
- </File>
- <File
- RelativePath=".\seekpt.cpp"
- >
- </File>
- <File
- RelativePath=".\source.cpp"
- >
- </File>
- <File
- RelativePath=".\strmctl.cpp"
- >
- </File>
- <File
- RelativePath=".\sysclock.cpp"
- >
- </File>
- <File
- RelativePath=".\transfrm.cpp"
- >
- </File>
- <File
- RelativePath=".\transip.cpp"
- >
- </File>
- <File
- RelativePath=".\videoctl.cpp"
- >
- </File>
- <File
- RelativePath=".\vtrans.cpp"
- >
- </File>
- <File
- RelativePath=".\winctrl.cpp"
- >
- </File>
- <File
- RelativePath=".\winutil.cpp"
- >
- </File>
- <File
RelativePath=".\wxdebug.cpp"
>
</File>
@@ -666,46 +373,21 @@
</Filter>
<Filter
Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ Filter="h;hpp;hxx;hm;inl"
>
<File
- RelativePath=".\amextra.h"
- >
- </File>
- <File
RelativePath=".\amfilter.h"
>
</File>
<File
- RelativePath=".\cache.h"
- >
- </File>
- <File
RelativePath=".\combase.h"
>
</File>
<File
- RelativePath=".\cprop.h"
- >
- </File>
- <File
RelativePath=".\ctlutil.h"
>
</File>
<File
- RelativePath=".\ddmm.h"
- >
- </File>
- <File
- RelativePath=".\dllsetup.h"
- >
- </File>
- <File
- RelativePath=".\dxmperf.h"
- >
- </File>
- <File
RelativePath=".\fourcc.h"
>
</File>
@@ -722,26 +404,6 @@
>
</File>
<File
- RelativePath=".\outputq.h"
- >
- </File>
- <File
- RelativePath=".\perflog.h"
- >
- </File>
- <File
- RelativePath=".\perfstruct.h"
- >
- </File>
- <File
- RelativePath=".\pstream.h"
- >
- </File>
- <File
- RelativePath=".\pullpin.h"
- >
- </File>
- <File
RelativePath=".\refclock.h"
>
</File>
@@ -754,54 +416,14 @@
>
</File>
<File
- RelativePath=".\schedule.h"
- >
- </File>
- <File
RelativePath=".\seekpt.h"
>
</File>
<File
- RelativePath=".\source.h"
- >
- </File>
- <File
RelativePath=".\streams.h"
>
</File>
<File
- RelativePath=".\strmctl.h"
- >
- </File>
- <File
- RelativePath=".\sysclock.h"
- >
- </File>
- <File
- RelativePath=".\transfrm.h"
- >
- </File>
- <File
- RelativePath=".\transip.h"
- >
- </File>
- <File
- RelativePath=".\videoctl.h"
- >
- </File>
- <File
- RelativePath=".\vtrans.h"
- >
- </File>
- <File
- RelativePath=".\winctrl.h"
- >
- </File>
- <File
- RelativePath=".\winutil.h"
- >
- </File>
- <File
RelativePath=".\wxdebug.h"
>
</File>
@@ -814,12 +436,6 @@
>
</File>
</Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
</Files>
<Globals>
</Globals>
diff --git a/third_party/BaseClasses/cache.h b/third_party/BaseClasses/cache.h
deleted file mode 100644
index 0a807c27..00000000
--- a/third_party/BaseClasses/cache.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Cache.h
-//
-// Desc: DirectShow base classes - efines a non-MFC generic cache class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-/* This class implements a simple cache. A cache object is instantiated
- with the number of items it is to hold. An item is a pointer to an
- object derived from CBaseObject (helps reduce memory leaks). The cache
- can then have objects added to it and removed from it. The cache size
- is fixed at construction time and may therefore run out or be flooded.
- If it runs out it returns a NULL pointer, if it fills up it also returns
- a NULL pointer instead of a pointer to the object just inserted */
-
-/* Making these classes inherit from CBaseObject does nothing for their
- functionality but it allows us to check there are no memory leaks */
-
-/* WARNING Be very careful when using this class, what it lets you do is
- store and retrieve objects so that you can minimise object creation
- which in turns improves efficiency. However the object you store is
- exactly the same as the object you get back which means that it short
- circuits the constructor initialisation phase. This means any class
- variables the object has (eg pointers) are highly likely to be invalid.
- Therefore ensure you reinitialise the object before using it again */
-
-
-#ifndef __CACHE__
-#define __CACHE__
-
-
-class CCache : CBaseObject {
-
- /* Make copy constructor and assignment operator inaccessible */
-
- CCache(const CCache &refCache);
- CCache &operator=(const CCache &refCache);
-
-private:
-
- /* These are initialised in the constructor. The first variable points to
- an array of pointers, each of which points to a CBaseObject derived
- object. The m_iCacheSize is the static fixed size for the cache and the
- m_iUsed defines the number of places filled with objects at any time.
- We fill the array of pointers from the start (ie m_ppObjects[0] first)
- and then only add and remove objects from the end position, so in this
- respect the array of object pointers should be treated as a stack */
-
- CBaseObject **m_ppObjects;
- const INT m_iCacheSize;
- INT m_iUsed;
-
-public:
-
- CCache(__in_opt LPCTSTR pName,INT iItems);
- virtual ~CCache();
-
- /* Add an item to the cache */
- CBaseObject *AddToCache(__in CBaseObject *pObject);
-
- /* Remove an item from the cache */
- CBaseObject *RemoveFromCache();
-
- /* Delete all the objects held in the cache */
- void RemoveAll(void);
-
- /* Return the cache size which is set during construction */
- INT GetCacheSize(void) const {return m_iCacheSize;};
-};
-
-#endif /* __CACHE__ */
-
diff --git a/third_party/BaseClasses/checkbmi.h b/third_party/BaseClasses/checkbmi.h
deleted file mode 100644
index 72879679..00000000
--- a/third_party/BaseClasses/checkbmi.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
-
-#ifndef _CHECKBMI_H_
-#define _CHECKBMI_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Helper
-__inline BOOL MultiplyCheckOverflow(DWORD a, DWORD b, __deref_out_range(==, a * b) DWORD *pab) {
- *pab = a * b;
- if ((a == 0) || (((*pab) / a) == b)) {
- return TRUE;
- }
- return FALSE;
-}
-
-
-// Checks if the fields in a BITMAPINFOHEADER won't generate
-// overlows and buffer overruns
-// This is not a complete check and does not guarantee code using this structure will be secure
-// from attack
-// Bugs this is guarding against:
-// 1. Total structure size calculation overflowing
-// 2. biClrUsed > 256 for 8-bit palettized content
-// 3. Total bitmap size in bytes overflowing
-// 4. biSize < size of the base structure leading to accessessing random memory
-// 5. Total structure size exceeding know size of data
-//
-
-__success(return != 0) __inline BOOL ValidateBitmapInfoHeader(
- const BITMAPINFOHEADER *pbmi, // pointer to structure to check
- __out_range(>=, sizeof(BITMAPINFOHEADER)) DWORD cbSize // size of memory block containing structure
-)
-{
- DWORD dwWidthInBytes;
- DWORD dwBpp;
- DWORD dwWidthInBits;
- DWORD dwHeight;
- DWORD dwSizeImage;
- DWORD dwClrUsed;
-
- // Reject bad parameters - do the size check first to avoid reading bad memory
- if (cbSize < sizeof(BITMAPINFOHEADER) ||
- pbmi->biSize < sizeof(BITMAPINFOHEADER) ||
- pbmi->biSize > 4096) {
- return FALSE;
- }
-
- // Reject 0 size
- if (pbmi->biWidth == 0 || pbmi->biHeight == 0) {
- return FALSE;
- }
-
- // Use bpp of 200 for validating against further overflows if not set for compressed format
- dwBpp = 200;
-
- if (pbmi->biBitCount > dwBpp) {
- return FALSE;
- }
-
- // Strictly speaking abs can overflow so cast explicitly to DWORD
- dwHeight = (DWORD)abs(pbmi->biHeight);
-
- if (!MultiplyCheckOverflow(dwBpp, (DWORD)pbmi->biWidth, &dwWidthInBits)) {
- return FALSE;
- }
-
- // Compute correct width in bytes - rounding up to 4 bytes
- dwWidthInBytes = (dwWidthInBits / 8 + 3) & ~3;
-
- if (!MultiplyCheckOverflow(dwWidthInBytes, dwHeight, &dwSizeImage)) {
- return FALSE;
- }
-
- // Fail if total size is 0 - this catches indivual quantities being 0
- // Also don't allow huge values > 1GB which might cause arithmetic
- // errors for users
- if (dwSizeImage > 0x40000000 ||
- pbmi->biSizeImage > 0x40000000) {
- return FALSE;
- }
-
- // Fail if biClrUsed looks bad
- if (pbmi->biClrUsed > 256) {
- return FALSE;
- }
-
- if (pbmi->biClrUsed == 0 && pbmi->biBitCount <= 8 && pbmi->biBitCount > 0) {
- dwClrUsed = (1 << pbmi->biBitCount);
- } else {
- dwClrUsed = pbmi->biClrUsed;
- }
-
- // Check total size
- if (cbSize < pbmi->biSize + dwClrUsed * sizeof(RGBQUAD) +
- (pbmi->biCompression == BI_BITFIELDS ? 3 * sizeof(DWORD) : 0)) {
- return FALSE;
- }
-
- // If it is RGB validate biSizeImage - lots of code assumes the size is correct
- if (pbmi->biCompression == BI_RGB || pbmi->biCompression == BI_BITFIELDS) {
- if (pbmi->biSizeImage != 0) {
- DWORD dwBits = (DWORD)pbmi->biWidth * (DWORD)pbmi->biBitCount;
- DWORD dwWidthInBytes = ((DWORD)((dwBits+31) & (~31)) / 8);
- DWORD dwTotalSize = (DWORD)abs(pbmi->biHeight) * dwWidthInBytes;
- if (dwTotalSize > pbmi->biSizeImage) {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CHECKBMI_H_
diff --git a/third_party/BaseClasses/cprop.cpp b/third_party/BaseClasses/cprop.cpp
deleted file mode 100644
index 7bd76b4e..00000000
--- a/third_party/BaseClasses/cprop.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-//------------------------------------------------------------------------------
-// File: CProp.cpp
-//
-// Desc: DirectShow base classes - implements CBasePropertyPage class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-
-// Constructor for the base property page class. As described in the header
-// file we must be initialised with dialog and title resource identifiers.
-// The class supports IPropertyPage and overrides AddRef and Release calls
-// to keep track of the reference counts. When the last count is released
-// we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces
-// previously obtained by the property page when it had SetObjects called
-
-CBasePropertyPage::CBasePropertyPage(__in_opt LPCTSTR pName, // Debug only name
- __inout_opt LPUNKNOWN pUnk, // COM Delegator
- int DialogId, // Resource ID
- int TitleId) : // To get tital
- CUnknown(pName,pUnk),
- m_DialogId(DialogId),
- m_TitleId(TitleId),
- m_hwnd(NULL),
- m_Dlg(NULL),
- m_pPageSite(NULL),
- m_bObjectSet(FALSE),
- m_bDirty(FALSE)
-{
-}
-
-#ifdef UNICODE
-CBasePropertyPage::CBasePropertyPage(__in_opt LPCSTR pName, // Debug only name
- __inout_opt LPUNKNOWN pUnk, // COM Delegator
- int DialogId, // Resource ID
- int TitleId) : // To get tital
- CUnknown(pName,pUnk),
- m_DialogId(DialogId),
- m_TitleId(TitleId),
- m_hwnd(NULL),
- m_Dlg(NULL),
- m_pPageSite(NULL),
- m_bObjectSet(FALSE),
- m_bDirty(FALSE)
-{
-}
-#endif
-
-// Increment our reference count
-
-STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef()
-{
- LONG lRef = InterlockedIncrement(&m_cRef);
- ASSERT(lRef > 0);
- return max(ULONG(m_cRef),1ul);
-}
-
-
-// Release a reference count and protect against reentrancy
-
-STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease()
-{
- // If the reference count drops to zero delete ourselves
-
- LONG lRef = InterlockedDecrement(&m_cRef);
- if (lRef == 0) {
- m_cRef++;
- SetPageSite(NULL);
- SetObjects(0,NULL);
- delete this;
- return ULONG(0);
- } else {
- // Don't touch m_cRef again here!
- return max(ULONG(lRef),1ul);
- }
-}
-
-
-// Expose our IPropertyPage interface
-
-STDMETHODIMP
-CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv)
-{
- if (riid == IID_IPropertyPage) {
- return GetInterface((IPropertyPage *)this,ppv);
- } else {
- return CUnknown::NonDelegatingQueryInterface(riid,ppv);
- }
-}
-
-
-// Get the page info so that the page site can size itself
-
-STDMETHODIMP CBasePropertyPage::GetPageInfo(__out LPPROPPAGEINFO pPageInfo)
-{
- CheckPointer(pPageInfo,E_POINTER);
- WCHAR wszTitle[STR_MAX_LENGTH];
- WideStringFromResource(wszTitle,m_TitleId);
-
- // Allocate dynamic memory for the property page title
-
- LPOLESTR pszTitle;
- HRESULT hr = AMGetWideString(wszTitle, &pszTitle);
- if (FAILED(hr)) {
- NOTE("No caption memory");
- return hr;
- }
-
- pPageInfo->cb = sizeof(PROPPAGEINFO);
- pPageInfo->pszTitle = pszTitle;
- pPageInfo->pszDocString = NULL;
- pPageInfo->pszHelpFile = NULL;
- pPageInfo->dwHelpContext = 0;
-
- // Set defaults in case GetDialogSize fails
- pPageInfo->size.cx = 340;
- pPageInfo->size.cy = 150;
-
- GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size);
- return NOERROR;
-}
-
-
-// Handles the messages for our property window
-
-INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- CBasePropertyPage *pPropertyPage;
-
- switch (uMsg) {
-
- case WM_INITDIALOG:
-
- _SetWindowLongPtr(hwnd, DWLP_USER, lParam);
-
- // This pointer may be NULL when calculating size
-
- pPropertyPage = (CBasePropertyPage *) lParam;
- if (pPropertyPage == NULL) {
- return (LRESULT) 1;
- }
- pPropertyPage->m_Dlg = hwnd;
- }
-
- // This pointer may be NULL when calculating size
-
- pPropertyPage = _GetWindowLongPtr<CBasePropertyPage*>(hwnd, DWLP_USER);
- if (pPropertyPage == NULL) {
- return (LRESULT) 1;
- }
- return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
-}
-
-
-// Tells us the object that should be informed of the property changes
-
-STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,__in_ecount_opt(cObjects) LPUNKNOWN *ppUnk)
-{
- if (cObjects == 1) {
-
- if ((ppUnk == NULL) || (*ppUnk == NULL)) {
- return E_POINTER;
- }
-
- // Set a flag to say that we have set the Object
- m_bObjectSet = TRUE ;
- return OnConnect(*ppUnk);
-
- } else if (cObjects == 0) {
-
- // Set a flag to say that we have not set the Object for the page
- m_bObjectSet = FALSE ;
- return OnDisconnect();
- }
-
- DbgBreak("No support for more than one object");
- return E_UNEXPECTED;
-}
-
-
-// Create the window we will use to edit properties
-
-STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent,
- LPCRECT pRect,
- BOOL fModal)
-{
- CheckPointer(pRect,E_POINTER);
-
- // Return failure if SetObject has not been called.
- if (m_bObjectSet == FALSE) {
- return E_UNEXPECTED;
- }
-
- if (m_hwnd) {
- return E_UNEXPECTED;
- }
-
- m_hwnd = CreateDialogParam(g_hInst,
- MAKEINTRESOURCE(m_DialogId),
- hwndParent,
- DialogProc,
- (LPARAM) this);
- if (m_hwnd == NULL) {
- return E_OUTOFMEMORY;
- }
-
- OnActivate();
- Move(pRect);
- return Show(SW_SHOWNORMAL);
-}
-
-
-// Set the position of the property page
-
-STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect)
-{
- CheckPointer(pRect,E_POINTER);
-
- if (m_hwnd == NULL) {
- return E_UNEXPECTED;
- }
-
- MoveWindow(m_hwnd, // Property page handle
- pRect->left, // x coordinate
- pRect->top, // y coordinate
- WIDTH(pRect), // Overall window width
- HEIGHT(pRect), // And likewise height
- TRUE); // Should we repaint it
-
- return NOERROR;
-}
-
-
-// Display the property dialog
-
-STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow)
-{
- // Have we been activated yet
-
- if (m_hwnd == NULL) {
- return E_UNEXPECTED;
- }
-
- // Ignore wrong show flags
-
- if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) {
- return E_INVALIDARG;
- }
-
- ShowWindow(m_hwnd,nCmdShow);
- InvalidateRect(m_hwnd,NULL,TRUE);
- return NOERROR;
-}
-
-
-// Destroy the property page dialog
-
-STDMETHODIMP CBasePropertyPage::Deactivate(void)
-{
- if (m_hwnd == NULL) {
- return E_UNEXPECTED;
- }
-
- // Remove WS_EX_CONTROLPARENT before DestroyWindow call
-
- DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
- dwStyle = dwStyle & (~WS_EX_CONTROLPARENT);
-
- // Set m_hwnd to be NULL temporarily so the message handler
- // for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT
- // style back in
- HWND hwnd = m_hwnd;
- m_hwnd = NULL;
- SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle);
- m_hwnd = hwnd;
-
- OnDeactivate();
-
- // Destroy the dialog window
-
- DestroyWindow(m_hwnd);
- m_hwnd = NULL;
- return NOERROR;
-}
-
-
-// Tells the application property page site
-
-STDMETHODIMP CBasePropertyPage::SetPageSite(__in_opt LPPROPERTYPAGESITE pPageSite)
-{
- if (pPageSite) {
-
- if (m_pPageSite) {
- return E_UNEXPECTED;
- }
-
- m_pPageSite = pPageSite;
- m_pPageSite->AddRef();
-
- } else {
-
- if (m_pPageSite == NULL) {
- return E_UNEXPECTED;
- }
-
- m_pPageSite->Release();
- m_pPageSite = NULL;
- }
- return NOERROR;
-}
-
-
-// Apply any changes so far made
-
-STDMETHODIMP CBasePropertyPage::Apply()
-{
- // In ActiveMovie 1.0 we used to check whether we had been activated or
- // not. This is too constrictive. Apply should be allowed as long as
- // SetObject was called to set an object. So we will no longer check to
- // see if we have been activated (ie., m_hWnd != NULL), but instead
- // make sure that m_bObjectSet is TRUE (ie., SetObject has been called).
-
- if (m_bObjectSet == FALSE) {
- return E_UNEXPECTED;
- }
-
- // Must have had a site set
-
- if (m_pPageSite == NULL) {
- return E_UNEXPECTED;
- }
-
- // Has anything changed
-
- if (m_bDirty == FALSE) {
- return NOERROR;
- }
-
- // Commit derived class changes
-
- HRESULT hr = OnApplyChanges();
- if (SUCCEEDED(hr)) {
- m_bDirty = FALSE;
- }
- return hr;
-}
-
-
-// Base class definition for message handling
-
-INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
-{
- // we would like the TAB key to move around the tab stops in our property
- // page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT
- // style behind our back, so we need to switch it back on now behind its
- // back. Otherwise the tab key will be useless in every page.
- //
-
- CBasePropertyPage *pPropertyPage;
- {
- pPropertyPage = _GetWindowLongPtr<CBasePropertyPage*>(hwnd, DWLP_USER);
-
- if (pPropertyPage->m_hwnd == NULL) {
- return 0;
- }
- switch (uMsg) {
- case WM_STYLECHANGING:
- if (wParam == GWL_EXSTYLE) {
- LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam;
- lpss->styleNew |= WS_EX_CONTROLPARENT;
- return 0;
- }
- }
- }
-
- return DefWindowProc(hwnd,uMsg,wParam,lParam);
-}
-
diff --git a/third_party/BaseClasses/cprop.h b/third_party/BaseClasses/cprop.h
deleted file mode 100644
index db449406..00000000
--- a/third_party/BaseClasses/cprop.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//------------------------------------------------------------------------------
-// File: CProp.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __CPROP__
-#define __CPROP__
-
-// Base property page class. Filters typically expose custom properties by
-// implementing special control interfaces, examples are IDirectDrawVideo
-// and IQualProp on renderers. This allows property pages to be built that
-// use the given interface. Applications such as the ActiveMovie OCX query
-// filters for the property pages they support and expose them to the user
-//
-// This class provides all the framework for a property page. A property
-// page is a COM object that supports IPropertyPage. We should be created
-// with a resource ID for the dialog which we will load when required. We
-// should also be given in the constructor a resource ID for a title string
-// we will load from the DLLs STRINGTABLE. The property page titles must be
-// stored in resource files so that they can be easily internationalised
-//
-// We have a number of virtual methods (not PURE) that may be overriden in
-// derived classes to query for interfaces and so on. These functions have
-// simple implementations here that just return NOERROR. Derived classes
-// will almost definately have to override the message handler method called
-// OnReceiveMessage. We have a static dialog procedure that calls the method
-// so that derived classes don't have to fiddle around with the this pointer
-
-class AM_NOVTABLE CBasePropertyPage : public IPropertyPage, public CUnknown
-{
-protected:
-
- LPPROPERTYPAGESITE m_pPageSite; // Details for our property site
- HWND m_hwnd; // Window handle for the page
- HWND m_Dlg; // Actual dialog window handle
- BOOL m_bDirty; // Has anything been changed
- int m_TitleId; // Resource identifier for title
- int m_DialogId; // Dialog resource identifier
-
- static INT_PTR CALLBACK DialogProc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
-
-private:
- BOOL m_bObjectSet ; // SetObject has been called or not.
-public:
-
- CBasePropertyPage(__in_opt LPCTSTR pName, // Debug only name
- __inout_opt LPUNKNOWN pUnk, // COM Delegator
- int DialogId, // Resource ID
- int TitleId); // To get tital
-
-#ifdef UNICODE
- CBasePropertyPage(__in_opt LPCSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- int DialogId,
- int TitleId);
-#endif
- virtual ~CBasePropertyPage() { };
- DECLARE_IUNKNOWN
-
- // Override these virtual methods
-
- virtual HRESULT OnConnect(IUnknown *pUnknown) { return NOERROR; };
- virtual HRESULT OnDisconnect() { return NOERROR; };
- virtual HRESULT OnActivate() { return NOERROR; };
- virtual HRESULT OnDeactivate() { return NOERROR; };
- virtual HRESULT OnApplyChanges() { return NOERROR; };
- virtual INT_PTR OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
-
- // These implement an IPropertyPage interface
-
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
- STDMETHODIMP_(ULONG) NonDelegatingRelease();
- STDMETHODIMP_(ULONG) NonDelegatingAddRef();
- STDMETHODIMP SetPageSite(__in_opt LPPROPERTYPAGESITE pPageSite);
- STDMETHODIMP Activate(HWND hwndParent, LPCRECT prect,BOOL fModal);
- STDMETHODIMP Deactivate(void);
- STDMETHODIMP GetPageInfo(__out LPPROPPAGEINFO pPageInfo);
- STDMETHODIMP SetObjects(ULONG cObjects, __in_ecount_opt(cObjects) LPUNKNOWN *ppUnk);
- STDMETHODIMP Show(UINT nCmdShow);
- STDMETHODIMP Move(LPCRECT prect);
- STDMETHODIMP IsPageDirty(void) { return m_bDirty ? S_OK : S_FALSE; }
- STDMETHODIMP Apply(void);
- STDMETHODIMP Help(LPCWSTR lpszHelpDir) { return E_NOTIMPL; }
- STDMETHODIMP TranslateAccelerator(__inout LPMSG lpMsg) { return E_NOTIMPL; }
-};
-
-#endif // __CPROP__
-
diff --git a/third_party/BaseClasses/ddmm.cpp b/third_party/BaseClasses/ddmm.cpp
deleted file mode 100644
index bfa700cb..00000000
--- a/third_party/BaseClasses/ddmm.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DDMM.cpp
-//
-// Desc: DirectShow base classes - implements routines for using DirectDraw
-// on a multimonitor system.
-//
-// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <ddraw.h>
-#include "ddmm.h"
-
-/*
- * FindDeviceCallback
- */
-typedef struct {
- LPSTR szDevice;
- GUID* lpGUID;
- GUID GUID;
- BOOL fFound;
-} FindDeviceData;
-
-BOOL CALLBACK FindDeviceCallback(__in_opt GUID* lpGUID, __in LPSTR szName, __in LPSTR szDevice, __in LPVOID lParam)
-{
- FindDeviceData *p = (FindDeviceData*)lParam;
-
- if (lstrcmpiA(p->szDevice, szDevice) == 0) {
- if (lpGUID) {
- p->GUID = *lpGUID;
- p->lpGUID = &p->GUID;
- } else {
- p->lpGUID = NULL;
- }
- p->fFound = TRUE;
- return FALSE;
- }
- return TRUE;
-}
-
-
-BOOL CALLBACK FindDeviceCallbackEx(__in_opt GUID* lpGUID, __in LPSTR szName, __in LPSTR szDevice, __in LPVOID lParam, HMONITOR hMonitor)
-{
- FindDeviceData *p = (FindDeviceData*)lParam;
-
- if (lstrcmpiA(p->szDevice, szDevice) == 0) {
- if (lpGUID) {
- p->GUID = *lpGUID;
- p->lpGUID = &p->GUID;
- } else {
- p->lpGUID = NULL;
- }
- p->fFound = TRUE;
- return FALSE;
- }
- return TRUE;
-}
-
-
-/*
- * DirectDrawCreateFromDevice
- *
- * create a DirectDraw object for a particular device
- */
-IDirectDraw * DirectDrawCreateFromDevice(__in_opt LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, PDRAWENUM DirectDrawEnumerateP)
-{
- IDirectDraw* pdd = NULL;
- FindDeviceData find;
-
- if (szDevice == NULL) {
- DirectDrawCreateP(NULL, &pdd, NULL);
- return pdd;
- }
-
- find.szDevice = szDevice;
- find.fFound = FALSE;
- DirectDrawEnumerateP(FindDeviceCallback, (LPVOID)&find);
-
- if (find.fFound)
- {
- //
- // In 4bpp mode the following DDraw call causes a message box to be popped
- // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we
- // make sure it doesn't happen.
- //
- UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
- DirectDrawCreateP(find.lpGUID, &pdd, NULL);
- SetErrorMode(ErrorMode);
- }
-
- return pdd;
-}
-
-
-/*
- * DirectDrawCreateFromDeviceEx
- *
- * create a DirectDraw object for a particular device
- */
-IDirectDraw * DirectDrawCreateFromDeviceEx(__in_opt LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, LPDIRECTDRAWENUMERATEEXA DirectDrawEnumerateExP)
-{
- IDirectDraw* pdd = NULL;
- FindDeviceData find;
-
- if (szDevice == NULL) {
- DirectDrawCreateP(NULL, &pdd, NULL);
- return pdd;
- }
-
- find.szDevice = szDevice;
- find.fFound = FALSE;
- DirectDrawEnumerateExP(FindDeviceCallbackEx, (LPVOID)&find,
- DDENUM_ATTACHEDSECONDARYDEVICES);
-
- if (find.fFound)
- {
- //
- // In 4bpp mode the following DDraw call causes a message box to be popped
- // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we
- // make sure it doesn't happen.
- //
- UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
- DirectDrawCreateP(find.lpGUID, &pdd, NULL);
- SetErrorMode(ErrorMode);
- }
-
- return pdd;
-}
diff --git a/third_party/BaseClasses/ddmm.h b/third_party/BaseClasses/ddmm.h
deleted file mode 100644
index 7b311bc1..00000000
--- a/third_party/BaseClasses/ddmm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DDMM.h
-//
-// Desc: DirectShow base classes - efines routines for using DirectDraw
-// on a multimonitor system.
-//
-// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifdef __cplusplus
-extern "C" { /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-// DDRAW.H might not include these
-#ifndef DDENUM_ATTACHEDSECONDARYDEVICES
-#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L
-#endif
-
-typedef HRESULT (*PDRAWCREATE)(IID *,LPDIRECTDRAW *,LPUNKNOWN);
-typedef HRESULT (*PDRAWENUM)(LPDDENUMCALLBACKA, LPVOID);
-
-IDirectDraw * DirectDrawCreateFromDevice(__in_opt LPSTR, PDRAWCREATE, PDRAWENUM);
-IDirectDraw * DirectDrawCreateFromDeviceEx(__in_opt LPSTR, PDRAWCREATE, LPDIRECTDRAWENUMERATEEXA);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
diff --git a/third_party/BaseClasses/dllentry.cpp b/third_party/BaseClasses/dllentry.cpp
deleted file mode 100644
index 130aad6a..00000000
--- a/third_party/BaseClasses/dllentry.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DlleEntry.cpp
-//
-// Desc: DirectShow base classes - implements classes used to support dll
-// entry points for COM objects.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <initguid.h>
-
-#ifdef DEBUG
-#ifdef UNICODE
-#ifndef _UNICODE
-#define _UNICODE
-#endif // _UNICODE
-#endif // UNICODE
-
-#include <tchar.h>
-#endif // DEBUG
-#include <strsafe.h>
-
-extern CFactoryTemplate g_Templates[];
-extern int g_cTemplates;
-
-HINSTANCE g_hInst;
-DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
-OSVERSIONINFO g_osInfo;
-
-//
-// an instance of this is created by the DLLGetClassObject entrypoint
-// it uses the CFactoryTemplate object it is given to support the
-// IClassFactory interface
-
-class CClassFactory : public IClassFactory, public CBaseObject
-{
-
-private:
- const CFactoryTemplate *const m_pTemplate;
-
- ULONG m_cRef;
-
- static int m_cLocked;
-public:
- CClassFactory(const CFactoryTemplate *);
-
- // IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, __deref_out void ** ppv);
- STDMETHODIMP_(ULONG)AddRef();
- STDMETHODIMP_(ULONG)Release();
-
- // IClassFactory
- STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv);
- STDMETHODIMP LockServer(BOOL fLock);
-
- // allow DLLGetClassObject to know about global server lock status
- static BOOL IsLocked() {
- return (m_cLocked > 0);
- };
-};
-
-// process-wide dll locked state
-int CClassFactory::m_cLocked = 0;
-
-CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
-: CBaseObject(NAME("Class Factory"))
-, m_cRef(0)
-, m_pTemplate(pTemplate)
-{
-}
-
-
-STDMETHODIMP
-CClassFactory::QueryInterface(REFIID riid,__deref_out void **ppv)
-{
- CheckPointer(ppv,E_POINTER)
- ValidateReadWritePtr(ppv,sizeof(PVOID));
- *ppv = NULL;
-
- // any interface on this object is the object pointer.
- if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
- *ppv = (LPVOID) this;
- // AddRef returned interface pointer
- ((LPUNKNOWN) *ppv)->AddRef();
- return NOERROR;
- }
-
- return ResultFromScode(E_NOINTERFACE);
-}
-
-
-STDMETHODIMP_(ULONG)
-CClassFactory::AddRef()
-{
- return ++m_cRef;
-}
-
-STDMETHODIMP_(ULONG)
-CClassFactory::Release()
-{
- LONG lRef = InterlockedDecrement((volatile LONG *)&m_cRef);
- if (lRef == 0) {
- delete this;
- return 0;
- } else {
- return lRef;
- }
-}
-
-STDMETHODIMP
-CClassFactory::CreateInstance(
- LPUNKNOWN pUnkOuter,
- REFIID riid,
- __deref_out void **pv)
-{
- CheckPointer(pv,E_POINTER)
- ValidateReadWritePtr(pv,sizeof(void *));
- *pv = NULL;
-
- /* Enforce the normal OLE rules regarding interfaces and delegation */
-
- if (pUnkOuter != NULL) {
- if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
- *pv = NULL;
- return ResultFromScode(E_NOINTERFACE);
- }
- }
-
- /* Create the new object through the derived class's create function */
-
- HRESULT hr = NOERROR;
- CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
-
- if (pObj == NULL) {
- *pv = NULL;
- if (SUCCEEDED(hr)) {
- hr = E_OUTOFMEMORY;
- }
- return hr;
- }
-
- /* Delete the object if we got a construction error */
-
- if (FAILED(hr)) {
- delete pObj;
- *pv = NULL;
- return hr;
- }
-
- /* Get a reference counted interface on the object */
-
- /* We wrap the non-delegating QI with NDAddRef & NDRelease. */
- /* This protects any outer object from being prematurely */
- /* released by an inner object that may have to be created */
- /* in order to supply the requested interface. */
- pObj->NonDelegatingAddRef();
- hr = pObj->NonDelegatingQueryInterface(riid, pv);
- pObj->NonDelegatingRelease();
- /* Note that if NonDelegatingQueryInterface fails, it will */
- /* not increment the ref count, so the NonDelegatingRelease */
- /* will drop the ref back to zero and the object will "self-*/
- /* destruct". Hence we don't need additional tidy-up code */
- /* to cope with NonDelegatingQueryInterface failing. */
-
- if (SUCCEEDED(hr)) {
- ASSERT(*pv);
- }
-
- return hr;
-}
-
-STDMETHODIMP
-CClassFactory::LockServer(BOOL fLock)
-{
- if (fLock) {
- m_cLocked++;
- } else {
- m_cLocked--;
- }
- return NOERROR;
-}
-
-
-// --- COM entrypoints -----------------------------------------
-
-//called by COM to get the class factory object for a given class
-__control_entrypoint(DllExport) STDAPI
-DllGetClassObject(
- __in REFCLSID rClsID,
- __in REFIID riid,
- __deref_out void **pv)
-{
- *pv = NULL;
- if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
- return E_NOINTERFACE;
- }
-
- // traverse the array of templates looking for one with this
- // class id
- for (int i = 0; i < g_cTemplates; i++) {
- const CFactoryTemplate * pT = &g_Templates[i];
- if (pT->IsClassID(rClsID)) {
-
- // found a template - make a class factory based on this
- // template
-
- *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
- if (*pv == NULL) {
- return E_OUTOFMEMORY;
- }
- ((LPUNKNOWN)*pv)->AddRef();
- return NOERROR;
- }
- }
- return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-//
-// Call any initialization routines
-//
-void
-DllInitClasses(BOOL bLoading)
-{
- int i;
-
- // traverse the array of templates calling the init routine
- // if they have one
- for (i = 0; i < g_cTemplates; i++) {
- const CFactoryTemplate * pT = &g_Templates[i];
- if (pT->m_lpfnInit != NULL) {
- (*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
- }
- }
-
-}
-
-// called by COM to determine if this dll can be unloaded
-// return ok unless there are outstanding objects or a lock requested
-// by IClassFactory::LockServer
-//
-// CClassFactory has a static function that can tell us about the locks,
-// and CCOMObject has a static function that can tell us about the active
-// object count
-STDAPI
-DllCanUnloadNow()
-{
- DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
- CClassFactory::IsLocked(),
- CBaseObject::ObjectsActive()));
-
- if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
- return S_FALSE;
- } else {
- return S_OK;
- }
-}
-
-
-// --- standard WIN32 entrypoints --------------------------------------
-
-
-extern "C" void __cdecl __security_init_cookie(void);
-extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);
-#pragma comment(linker, "/merge:.CRT=.rdata")
-
-extern "C"
-DECLSPEC_NOINLINE
-BOOL
-WINAPI
-DllEntryPoint(
- HINSTANCE hInstance,
- ULONG ulReason,
- __inout_opt LPVOID pv
- )
-{
- if ( ulReason == DLL_PROCESS_ATTACH ) {
- // Must happen before any other code is executed. Thankfully - it's re-entrant
- __security_init_cookie();
- }
- return _DllEntryPoint(hInstance, ulReason, pv);
-}
-
-
-DECLSPEC_NOINLINE
-BOOL
-WINAPI
-_DllEntryPoint(
- HINSTANCE hInstance,
- ULONG ulReason,
- __inout_opt LPVOID pv
- )
-{
-#ifdef DEBUG
- extern bool g_fDbgInDllEntryPoint;
- g_fDbgInDllEntryPoint = true;
-#endif
-
- switch (ulReason)
- {
-
- case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hInstance);
- DbgInitialise(hInstance);
-
- {
- // The platform identifier is used to work out whether
- // full unicode support is available or not. Hence the
- // default will be the lowest common denominator - i.e. N/A
- g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
-
- g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
- if (GetVersionEx(&g_osInfo)) {
- g_amPlatform = g_osInfo.dwPlatformId;
- } else {
- DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
- }
- }
-
- g_hInst = hInstance;
- DllInitClasses(TRUE);
- break;
-
- case DLL_PROCESS_DETACH:
- DllInitClasses(FALSE);
-
-#ifdef DEBUG
- if (CBaseObject::ObjectsActive()) {
- DbgSetModuleLevel(LOG_MEMORY, 2);
- TCHAR szInfo[512];
- extern TCHAR m_ModuleName[]; // Cut down module name
-
- TCHAR FullName[_MAX_PATH]; // Load the full path and module name
- TCHAR *pName; // Searches from the end for a backslash
-
- GetModuleFileName(NULL,FullName,_MAX_PATH);
- pName = _tcsrchr(FullName,'\\');
- if (pName == NULL) {
- pName = FullName;
- } else {
- pName++;
- }
-
- (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s Pid %x Tid %x. "),
- pName, GetCurrentProcessId(), GetCurrentThreadId());
-
- (void)StringCchPrintf(szInfo+lstrlen(szInfo), NUMELMS(szInfo) - lstrlen(szInfo), TEXT("Module %s, %d objects left active!"),
- m_ModuleName, CBaseObject::ObjectsActive());
- DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
-
- // If running remotely wait for the Assert to be acknowledged
- // before dumping out the object register
- DbgDumpObjectRegister();
- }
- DbgTerminate();
-#endif
- break;
- }
-
-#ifdef DEBUG
- g_fDbgInDllEntryPoint = false;
-#endif
- return TRUE;
-}
-
-
diff --git a/third_party/BaseClasses/dllsetup.cpp b/third_party/BaseClasses/dllsetup.cpp
deleted file mode 100644
index ede9c3fd..00000000
--- a/third_party/BaseClasses/dllsetup.cpp
+++ /dev/null
@@ -1,693 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DllSetup.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <strsafe.h>
-
-//---------------------------------------------------------------------------
-// defines
-
-#define MAX_KEY_LEN 260
-
-
-//---------------------------------------------------------------------------
-// externally defined functions/variable
-
-extern int g_cTemplates;
-extern CFactoryTemplate g_Templates[];
-
-//---------------------------------------------------------------------------
-//
-// EliminateSubKey
-//
-// Try to enumerate all keys under this one.
-// if we find anything, delete it completely.
-// Otherwise just delete it.
-//
-// note - this was pinched/duplicated from
-// Filgraph\Mapper.cpp - so should it be in
-// a lib somewhere?
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-EliminateSubKey( HKEY hkey, LPCTSTR strSubKey )
-{
- HKEY hk;
- if (0 == lstrlen(strSubKey) ) {
- // defensive approach
- return E_FAIL;
- }
-
- LONG lreturn = RegOpenKeyEx( hkey
- , strSubKey
- , 0
- , MAXIMUM_ALLOWED
- , &hk );
-
- ASSERT( lreturn == ERROR_SUCCESS
- || lreturn == ERROR_FILE_NOT_FOUND
- || lreturn == ERROR_INVALID_HANDLE );
-
- if( ERROR_SUCCESS == lreturn )
- {
- // Keep on enumerating the first (zero-th)
- // key and deleting that
-
- for( ; ; )
- {
- TCHAR Buffer[MAX_KEY_LEN];
- DWORD dw = MAX_KEY_LEN;
- FILETIME ft;
-
- lreturn = RegEnumKeyEx( hk
- , 0
- , Buffer
- , &dw
- , NULL
- , NULL
- , NULL
- , &ft);
-
- ASSERT( lreturn == ERROR_SUCCESS
- || lreturn == ERROR_NO_MORE_ITEMS );
-
- if( ERROR_SUCCESS == lreturn )
- {
- EliminateSubKey(hk, Buffer);
- }
- else
- {
- break;
- }
- }
-
- RegCloseKey(hk);
- RegDeleteKey(hkey, strSubKey);
- }
-
- return NOERROR;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieSetupRegisterServer()
-//
-// registers specfied file "szFileName" as server for
-// CLSID "clsServer". A description is also required.
-// The ThreadingModel and ServerType are optional, as
-// they default to InprocServer32 (i.e. dll) and Both.
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-AMovieSetupRegisterServer( CLSID clsServer
- , LPCWSTR szDescription
- , LPCWSTR szFileName
- , LPCWSTR szThreadingModel = L"Both"
- , LPCWSTR szServerType = L"InprocServer32" )
-{
- // temp buffer
- //
- TCHAR achTemp[MAX_PATH];
-
- // convert CLSID uuid to string and write
- // out subkey as string - CLSID\{}
- //
- OLECHAR szCLSID[CHARS_IN_GUID];
- HRESULT hr = StringFromGUID2( clsServer
- , szCLSID
- , CHARS_IN_GUID );
- ASSERT( SUCCEEDED(hr) );
-
- // create key
- //
- HKEY hkey;
- (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("CLSID\\%ls"), szCLSID );
- LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT
- , (LPCTSTR)achTemp
- , &hkey );
- if( ERROR_SUCCESS != lreturn )
- {
- return AmHresultFromWin32(lreturn);
- }
-
- // set description string
- //
-
- (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szDescription );
- lreturn = RegSetValue( hkey
- , (LPCTSTR)NULL
- , REG_SZ
- , achTemp
- , sizeof(achTemp) );
- if( ERROR_SUCCESS != lreturn )
- {
- RegCloseKey( hkey );
- return AmHresultFromWin32(lreturn);
- }
-
- // create CLSID\\{"CLSID"}\\"ServerType" key,
- // using key to CLSID\\{"CLSID"} passed back by
- // last call to RegCreateKey().
- //
- HKEY hsubkey;
-
- (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szServerType );
- lreturn = RegCreateKey( hkey
- , achTemp
- , &hsubkey );
- if( ERROR_SUCCESS != lreturn )
- {
- RegCloseKey( hkey );
- return AmHresultFromWin32(lreturn);
- }
-
- // set Server string
- //
- (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szFileName );
- lreturn = RegSetValue( hsubkey
- , (LPCTSTR)NULL
- , REG_SZ
- , (LPCTSTR)achTemp
- , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
- if( ERROR_SUCCESS != lreturn )
- {
- RegCloseKey( hkey );
- RegCloseKey( hsubkey );
- return AmHresultFromWin32(lreturn);
- }
-
- (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szThreadingModel );
- lreturn = RegSetValueEx( hsubkey
- , TEXT("ThreadingModel")
- , 0L
- , REG_SZ
- , (CONST BYTE *)achTemp
- , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
-
- // close hkeys
- //
- RegCloseKey( hkey );
- RegCloseKey( hsubkey );
-
- // and return
- //
- return HRESULT_FROM_WIN32(lreturn);
-
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieSetupUnregisterServer()
-//
-// default ActiveMovie dll setup function
-// - to use must be called from an exported
-// function named DllRegisterServer()
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-AMovieSetupUnregisterServer( CLSID clsServer )
-{
- // convert CLSID uuid to string and write
- // out subkey CLSID\{}
- //
- OLECHAR szCLSID[CHARS_IN_GUID];
- HRESULT hr = StringFromGUID2( clsServer
- , szCLSID
- , CHARS_IN_GUID );
- ASSERT( SUCCEEDED(hr) );
-
- TCHAR achBuffer[MAX_KEY_LEN];
- (void)StringCchPrintf( achBuffer, NUMELMS(achBuffer), TEXT("CLSID\\%ls"), szCLSID );
-
- // delete subkey
- //
-
- hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer );
- ASSERT( SUCCEEDED(hr) );
-
- // return
- //
- return NOERROR;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieSetupRegisterFilter through IFilterMapper2
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
- , IFilterMapper2 * pIFM2
- , BOOL bRegister )
-{
- DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));
-
- // check we've got data
- //
- if( NULL == psetupdata ) return S_FALSE;
-
-
- // unregister filter
- // (as pins are subkeys of filter's CLSID key
- // they do not need to be removed separately).
- //
- DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
- HRESULT hr = pIFM2->UnregisterFilter(
- 0, // default category
- 0, // default instance name
- *psetupdata->clsID );
-
-
- if( bRegister )
- {
- REGFILTER2 rf2;
- rf2.dwVersion = 1;
- rf2.dwMerit = psetupdata->dwMerit;
- rf2.cPins = psetupdata->nPins;
- rf2.rgPins = psetupdata->lpPin;
-
- // register filter
- //
- DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
- hr = pIFM2->RegisterFilter(*psetupdata->clsID
- , psetupdata->strName
- , 0 // moniker
- , 0 // category
- , NULL // instance
- , &rf2);
- }
-
- // handle one acceptable "error" - that
- // of filter not being registered!
- // (couldn't find a suitable #define'd
- // name for the error!)
- //
- if( 0x80070002 == hr)
- return NOERROR;
- else
- return hr;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// RegisterAllServers()
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-RegisterAllServers( LPCWSTR szFileName, BOOL bRegister )
-{
- HRESULT hr = NOERROR;
-
- for( int i = 0; i < g_cTemplates; i++ )
- {
- // get i'th template
- //
- const CFactoryTemplate *pT = &g_Templates[i];
-
- DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"),
- (LPCWSTR)pT->m_Name ));
-
- // register CLSID and InprocServer32
- //
- if( bRegister )
- {
- hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
- , (LPCWSTR)pT->m_Name
- , szFileName );
- }
- else
- {
- hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
- }
-
- // check final error for this pass
- // and break loop if we failed
- //
- if( FAILED(hr) )
- break;
- }
-
- return hr;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieDllRegisterServer2()
-//
-// default ActiveMovie dll setup function
-// - to use must be called from an exported
-// function named DllRegisterServer()
-//
-// this function is table driven using the
-// static members of the CFactoryTemplate
-// class defined in the dll.
-//
-// it registers the Dll as the InprocServer32
-// and then calls the IAMovieSetup.Register
-// method.
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-AMovieDllRegisterServer2( BOOL bRegister )
-{
- HRESULT hr = NOERROR;
-
- DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()")));
-
- // get file name (where g_hInst is the
- // instance handle of the filter dll)
- //
- WCHAR achFileName[MAX_PATH];
-
- // WIN95 doesn't support GetModuleFileNameW
- //
- {
- char achTemp[MAX_PATH];
-
- DbgLog((LOG_TRACE, 2, TEXT("- get module file name")));
-
- // g_hInst handle is set in our dll entry point. Make sure
- // DllEntryPoint in dllentry.cpp is called
- ASSERT(g_hInst != 0);
-
- if( 0 == GetModuleFileNameA( g_hInst
- , achTemp
- , sizeof(achTemp) ) )
- {
- // we've failed!
- DWORD dwerr = GetLastError();
- return AmHresultFromWin32(dwerr);
- }
-
- MultiByteToWideChar( CP_ACP
- , 0L
- , achTemp
- , lstrlenA(achTemp) + 1
- , achFileName
- , NUMELMS(achFileName) );
- }
-
- //
- // first registering, register all OLE servers
- //
- if( bRegister )
- {
- DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
- hr = RegisterAllServers( achFileName, TRUE );
- }
-
- //
- // next, register/unregister all filters
- //
-
- if( SUCCEEDED(hr) )
- {
- // init is ref counted so call just in case
- // we're being called cold.
- //
- DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize")));
- hr = CoInitialize( (LPVOID)NULL );
- ASSERT( SUCCEEDED(hr) );
-
- // get hold of IFilterMapper2
- //
- DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2")));
- IFilterMapper2 *pIFM2 = 0;
- IFilterMapper *pIFM = 0;
- hr = CoCreateInstance( CLSID_FilterMapper2
- , NULL
- , CLSCTX_INPROC_SERVER
- , IID_IFilterMapper2
- , (void **)&pIFM2 );
- if(FAILED(hr))
- {
- DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead")));
-
- hr = CoCreateInstance(
- CLSID_FilterMapper,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IFilterMapper,
- (void **)&pIFM);
- }
- if( SUCCEEDED(hr) )
- {
- // scan through array of CFactoryTemplates
- // registering servers and filters.
- //
- DbgLog((LOG_TRACE, 2, TEXT("- register Filters")));
- for( int i = 0; i < g_cTemplates; i++ )
- {
- // get i'th template
- //
- const CFactoryTemplate *pT = &g_Templates[i];
-
- if( NULL != pT->m_pAMovieSetup_Filter )
- {
- DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name ));
-
- if(pIFM2)
- {
- hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister );
- }
- else
- {
- hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister );
- }
- }
-
- // check final error for this pass
- // and break loop if we failed
- //
- if( FAILED(hr) )
- break;
- }
-
- // release interface
- //
- if(pIFM2)
- pIFM2->Release();
- else
- pIFM->Release();
-
- }
-
- // and clear up
- //
- CoFreeUnusedLibraries();
- CoUninitialize();
- }
-
- //
- // if unregistering, unregister all OLE servers
- //
- if( SUCCEEDED(hr) && !bRegister )
- {
- DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
- hr = RegisterAllServers( achFileName, FALSE );
- }
-
- DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr));
- return hr;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieDllRegisterServer()
-//
-// default ActiveMovie dll setup function
-// - to use must be called from an exported
-// function named DllRegisterServer()
-//
-// this function is table driven using the
-// static members of the CFactoryTemplate
-// class defined in the dll.
-//
-// it registers the Dll as the InprocServer32
-// and then calls the IAMovieSetup.Register
-// method.
-//
-//---------------------------------------------------------------------------
-
-
-STDAPI
-AMovieDllRegisterServer( void )
-{
- HRESULT hr = NOERROR;
-
- // get file name (where g_hInst is the
- // instance handle of the filter dll)
- //
- WCHAR achFileName[MAX_PATH];
-
- {
- // WIN95 doesn't support GetModuleFileNameW
- //
- char achTemp[MAX_PATH];
-
- if( 0 == GetModuleFileNameA( g_hInst
- , achTemp
- , sizeof(achTemp) ) )
- {
- // we've failed!
- DWORD dwerr = GetLastError();
- return AmHresultFromWin32(dwerr);
- }
-
- MultiByteToWideChar( CP_ACP
- , 0L
- , achTemp
- , lstrlenA(achTemp) + 1
- , achFileName
- , NUMELMS(achFileName) );
- }
-
- // scan through array of CFactoryTemplates
- // registering servers and filters.
- //
- for( int i = 0; i < g_cTemplates; i++ )
- {
- // get i'th template
- //
- const CFactoryTemplate *pT = &g_Templates[i];
-
- // register CLSID and InprocServer32
- //
- hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
- , (LPCWSTR)pT->m_Name
- , achFileName );
-
- // instantiate all servers and get hold of
- // IAMovieSetup, if implemented, and call
- // IAMovieSetup.Register() method
- //
- if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) )
- {
- // instantiate object
- //
- PAMOVIESETUP psetup;
- hr = CoCreateInstance( *(pT->m_ClsID)
- , 0
- , CLSCTX_INPROC_SERVER
- , IID_IAMovieSetup
- , reinterpret_cast<void**>(&psetup) );
- if( SUCCEEDED(hr) )
- {
- hr = psetup->Unregister();
- if( SUCCEEDED(hr) )
- hr = psetup->Register();
- psetup->Release();
- }
- else
- {
- if( (E_NOINTERFACE == hr )
- || (VFW_E_NEED_OWNER == hr ) )
- hr = NOERROR;
- }
- }
-
- // check final error for this pass
- // and break loop if we failed
- //
- if( FAILED(hr) )
- break;
-
- } // end-for
-
- return hr;
-}
-
-
-//---------------------------------------------------------------------------
-//
-// AMovieDllUnregisterServer()
-//
-// default ActiveMovie dll uninstall function
-// - to use must be called from an exported
-// function named DllRegisterServer()
-//
-// this function is table driven using the
-// static members of the CFactoryTemplate
-// class defined in the dll.
-//
-// it calls the IAMovieSetup.Unregister
-// method and then unregisters the Dll
-// as the InprocServer32
-//
-//---------------------------------------------------------------------------
-
-STDAPI
-AMovieDllUnregisterServer()
-{
- // initialize return code
- //
- HRESULT hr = NOERROR;
-
- // scan through CFactory template and unregister
- // all OLE servers and filters.
- //
- for( int i = g_cTemplates; i--; )
- {
- // get i'th template
- //
- const CFactoryTemplate *pT = &g_Templates[i];
-
- // check method exists
- //
- if( NULL != pT->m_lpfnNew )
- {
- // instantiate object
- //
- PAMOVIESETUP psetup;
- hr = CoCreateInstance( *(pT->m_ClsID)
- , 0
- , CLSCTX_INPROC_SERVER
- , IID_IAMovieSetup
- , reinterpret_cast<void**>(&psetup) );
- if( SUCCEEDED(hr) )
- {
- hr = psetup->Unregister();
- psetup->Release();
- }
- else
- {
- if( (E_NOINTERFACE == hr )
- || (VFW_E_NEED_OWNER == hr ) )
- hr = NOERROR;
- }
- }
-
- // unregister CLSID and InprocServer32
- //
- if( SUCCEEDED(hr) )
- {
- hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
- }
-
- // check final error for this pass
- // and break loop if we failed
- //
- if( FAILED(hr) )
- break;
- }
-
- return hr;
-}
diff --git a/third_party/BaseClasses/dllsetup.h b/third_party/BaseClasses/dllsetup.h
deleted file mode 100644
index e363b8b6..00000000
--- a/third_party/BaseClasses/dllsetup.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DllSetup.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// To be self registering, OLE servers must
-// export functions named DllRegisterServer
-// and DllUnregisterServer. To allow use of
-// custom and default implementations the
-// defaults are named AMovieDllRegisterServer
-// and AMovieDllUnregisterServer.
-//
-// To the use the default implementation you
-// must provide stub functions.
-//
-// i.e. STDAPI DllRegisterServer()
-// {
-// return AMovieDllRegisterServer();
-// }
-//
-// STDAPI DllUnregisterServer()
-// {
-// return AMovieDllUnregisterServer();
-// }
-//
-//
-// AMovieDllRegisterServer calls IAMovieSetup.Register(), and
-// AMovieDllUnregisterServer calls IAMovieSetup.Unregister().
-
-STDAPI AMovieDllRegisterServer2( BOOL );
-STDAPI AMovieDllRegisterServer();
-STDAPI AMovieDllUnregisterServer();
-
-// helper functions
-STDAPI EliminateSubKey( HKEY, LPCTSTR );
-
-
-STDAPI
-AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
- , IFilterMapper2 * pIFM2
- , BOOL bRegister );
-
diff --git a/third_party/BaseClasses/dxmperf.h b/third_party/BaseClasses/dxmperf.h
deleted file mode 100644
index 54a21203..00000000
--- a/third_party/BaseClasses/dxmperf.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//------------------------------------------------------------------------------
-// File: DXMPerf.h
-//
-// Desc: Macros for DirectShow performance logging.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef _DXMPERF_H_
-#define _DXMPERF_H_
-
-#include <perfstruct.h>
-#include "perflog.h"
-
-#ifdef _IA64_
-extern "C" unsigned __int64 __getReg( int whichReg );
-#pragma intrinsic(__getReg)
-#endif // _IA64_
-
-
-inline ULONGLONG _RDTSC( void ) {
-#ifdef _X86_
- LARGE_INTEGER li;
- __asm {
- _emit 0x0F
- _emit 0x31
- mov li.LowPart,eax
- mov li.HighPart,edx
- }
- return li.QuadPart;
-
-#if 0 // This isn't tested yet
-
-#elif defined (_IA64_)
-
-#define INL_REGID_APITC 3116
- return __getReg( INL_REGID_APITC );
-
-#endif // 0
-
-#else // unsupported platform
- // not implemented on non x86/IA64 platforms
- return 0;
-#endif // _X86_/_IA64_
-}
-
-#define DXMPERF_VIDEOREND 0x00000001
-#define DXMPERF_AUDIOGLITCH 0x00000002
-//#define GETTIME_BIT 0x00000001
-//#define AUDIOREND_BIT 0x00000004
-//#define FRAMEDROP_BIT 0x00000008
-#define AUDIOBREAK_BIT 0x00000010
-#define DXMPERF_AUDIORECV 0x00000020
-#define DXMPERF_AUDIOSLAVE 0x00000040
-#define DXMPERF_AUDIOBREAK 0x00000080
-
-#define PERFLOG_CTOR( name, iface )
-#define PERFLOG_DTOR( name, iface )
-#define PERFLOG_DELIVER( name, source, dest, sample, pmt )
-#define PERFLOG_RECEIVE( name, source, dest, sample, pmt )
-#define PERFLOG_RUN( name, iface, time, oldstate )
-#define PERFLOG_PAUSE( name, iface, oldstate )
-#define PERFLOG_STOP( name, iface, oldstate )
-#define PERFLOG_JOINGRAPH( name, iface, graph )
-#define PERFLOG_GETBUFFER( allocator, sample )
-#define PERFLOG_RELBUFFER( allocator, sample )
-#define PERFLOG_CONNECT( connector, connectee, status, pmt )
-#define PERFLOG_RXCONNECT( connector, connectee, status, pmt )
-#define PERFLOG_DISCONNECT( disconnector, disconnectee, status )
-
-#define PERFLOG_GETTIME( clock, time ) /*{ \
- PERFINFO_WMI_GETTIME perfData; \
- if (NULL != g_pTraceEvent) { \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_GETTIME; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (ULONGLONG) (time); \
- if (g_perfMasks[GETTIME_INDEX] & GETTIME_BIT) \
- (*g_pTraceEvent)( g_traceHandle, (PEVENT_TRACE_HEADER) &perfData ); \
- } \
- }*/
-
-#define PERFLOG_AUDIOREND( clocktime, sampletime, psample, bytetime, cbytes ) /*{ \
- PERFINFO_WMI_AVREND perfData; \
- if (NULL != g_pTraceEvent) { \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIOREND; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (clocktime); \
- perfData.data.sampleTime = (sampletime); \
- if (g_perfMasks[AUDIOREND_INDEX] & AUDIOREND_BIT) \
- (*g_pTraceEvent)( g_traceHandle, (PEVENT_TRACE_HEADER) &perfData ); \
- } \
- }*/
-
-#define PERFLOG_AUDIORECV(StreamTime,SampleStart,SampleStop,Discontinuity,Duration) \
- if (PerflogEnableFlags & DXMPERF_AUDIORECV) { \
- PERFINFO_WMI_AUDIORECV perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIORECV; \
- perfData.data.streamTime = StreamTime; \
- perfData.data.sampleStart = SampleStart; \
- perfData.data.sampleStop = SampleStop; \
- perfData.data.discontinuity = Discontinuity; \
- perfData.data.hwduration = Duration; \
- PerflogTraceEvent((PEVENT_TRACE_HEADER) &perfData); \
- }
-
-#define PERFLOG_AUDIOSLAVE(MasterClock,SlaveClock,ErrorAccum,LastHighErrorSeen,LastLowErrorSeen) \
- if (PerflogEnableFlags & DXMPERF_AUDIOSLAVE) { \
- PERFINFO_WMI_AUDIOSLAVE perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIOSLAVE; \
- perfData.data.masterClock = MasterClock; \
- perfData.data.slaveClock = SlaveClock; \
- perfData.data.errorAccum = ErrorAccum; \
- perfData.data.lastHighErrorSeen = LastHighErrorSeen;\
- perfData.data.lastLowErrorSeen = LastLowErrorSeen; \
- PerflogTraceEvent((PEVENT_TRACE_HEADER) &perfData); \
- }
-
-#define PERFLOG_AUDIOADDBREAK(IterNextWrite,OffsetNextWrite,IterWrite,OffsetWrite) \
- if (PerflogEnableFlags & DXMPERF_AUDIOBREAK) { \
- PERFINFO_WMI_AUDIOADDBREAK perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIOADDBREAK; \
- perfData.data.iterNextWrite = IterNextWrite; \
- perfData.data.offsetNextWrite = OffsetNextWrite; \
- perfData.data.iterWrite = IterWrite; \
- perfData.data.offsetWrite = OffsetWrite; \
- PerflogTraceEvent((PEVENT_TRACE_HEADER) &perfData); \
- }
-
-#define PERFLOG_VIDEOREND( sampletime, clocktime, psample ) \
- if (PerflogEnableFlags & DXMPERF_VIDEOREND) { \
- PERFINFO_WMI_AVREND perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_VIDEOREND; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (clocktime); \
- perfData.data.sampleTime = (sampletime); \
- PerflogTraceEvent ((PEVENT_TRACE_HEADER) &perfData); \
- }
-
-#define PERFLOG_AUDIOGLITCH( instance, glitchtype, currenttime, previoustime ) \
- if (PerflogEnableFlags & DXMPERF_AUDIOGLITCH) { \
- PERFINFO_WMI_AUDIOGLITCH perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_DSOUNDGLITCH; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.glitchType = (glitchtype); \
- perfData.data.sampleTime = (currenttime); \
- perfData.data.previousTime = (previoustime); \
- perfData.data.instanceId = (instance); \
- PerflogTraceEvent ((PEVENT_TRACE_HEADER) &perfData); \
- }
-
-#define PERFLOG_FRAMEDROP( sampletime, clocktime, psample, renderer ) /*{ \
- PERFINFO_WMI_FRAMEDROP perfData; \
- if (NULL != g_pTraceEvent) { \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_FRAMEDROP; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (clocktime); \
- perfData.data.frameTime = (sampletime); \
- if (g_perfMasks[FRAMEDROP_INDEX] & FRAMEDROP_BIT) \
- (*g_pTraceEvent)( g_traceHandle, (PEVENT_TRACE_HEADER) &perfData ); \
- } \
- }*/
-
-/*
-#define PERFLOG_AUDIOBREAK( nextwrite, writepos, msecs ) { \
- PERFINFO_WMI_AUDIOBREAK perfData; \
- if (NULL != g_pTraceEvent) { \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIOBREAK; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (writepos); \
- perfData.data.sampleTime = (nextwrite); \
- perfData.data.sampleDuration = (msecs); \
- if (g_perfMasks[AUDIOBREAK_INDEX] & AUDIOBREAK_BIT) \
- (*g_pTraceEvent)( g_traceHandle, (PEVENT_TRACE_HEADER) &perfData ); \
- } \
- }
-*/
-
-#define PERFLOG_AUDIOBREAK( nextwrite, writepos, msecs ) \
- if (PerflogEnableFlags & AUDIOBREAK_BIT) { \
- PERFINFO_WMI_AUDIOBREAK perfData; \
- memset( &perfData, 0, sizeof( perfData ) ); \
- perfData.header.Size = sizeof( perfData ); \
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID; \
- perfData.header.Guid = GUID_AUDIOBREAK; \
- perfData.data.cycleCounter = _RDTSC(); \
- perfData.data.dshowClock = (writepos); \
- perfData.data.sampleTime = (nextwrite); \
- perfData.data.sampleDuration = (msecs); \
- PerflogTraceEvent ((PEVENT_TRACE_HEADER) &perfData); \
- } \
-
-
-inline
-VOID PERFLOG_STREAMTRACE(
- ULONG Level,
- ULONG Id,
- ULONGLONG DShowClock,
- ULONGLONG Data1,
- ULONGLONG Data2,
- ULONGLONG Data3,
- ULONGLONG Data4
- )
-{
- if (Level <= PerflogModuleLevel)
- {
- PERFINFO_WMI_STREAMTRACE perfData;
- memset( &perfData, 0, sizeof( perfData ) );
- perfData.header.Size = sizeof( perfData );
- perfData.header.Flags = WNODE_FLAG_TRACED_GUID;
- perfData.header.Guid = GUID_STREAMTRACE;
- perfData.data.dshowClock = DShowClock;
- perfData.data.id = Id;
- perfData.data.data[0] = Data1;
- perfData.data.data[1] = Data2;
- perfData.data.data[2] = Data3;
- perfData.data.data[3] = Data4;
- PerflogTraceEvent((PEVENT_TRACE_HEADER) &perfData);
- }
-}
-
-
-#endif // _DXMPERF_H_
diff --git a/third_party/BaseClasses/outputq.cpp b/third_party/BaseClasses/outputq.cpp
deleted file mode 100644
index d3ab6175..00000000
--- a/third_party/BaseClasses/outputq.cpp
+++ /dev/null
@@ -1,801 +0,0 @@
-//------------------------------------------------------------------------------
-// File: OutputQ.cpp
-//
-// Desc: DirectShow base classes - implements COutputQueue class used by an
-// output pin which may sometimes want to queue output samples on a
-// separate thread and sometimes call Receive() directly on the input
-// pin.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-
-
-//
-// COutputQueue Constructor :
-//
-// Determines if a thread is to be created and creates resources
-//
-// pInputPin - the downstream input pin we're queueing samples to
-//
-// phr - changed to a failure code if this function fails
-// (otherwise unchanges)
-//
-// bAuto - Ask pInputPin if it can block in Receive by calling
-// its ReceiveCanBlock method and create a thread if
-// it can block, otherwise not.
-//
-// bQueue - if bAuto == FALSE then we create a thread if and only
-// if bQueue == TRUE
-//
-// lBatchSize - work in batches of lBatchSize
-//
-// bBatchEact - Use exact batch sizes so don't send until the
-// batch is full or SendAnyway() is called
-//
-// lListSize - If we create a thread make the list of samples queued
-// to the thread have this size cache
-//
-// dwPriority - If we create a thread set its priority to this
-//
-COutputQueue::COutputQueue(
- IPin *pInputPin, // Pin to send stuff to
- __inout HRESULT *phr, // 'Return code'
- BOOL bAuto, // Ask pin if queue or not
- BOOL bQueue, // Send through queue
- LONG lBatchSize, // Batch
- BOOL bBatchExact, // Batch exactly to BatchSize
- LONG lListSize,
- DWORD dwPriority,
- bool bFlushingOpt // flushing optimization
- ) : m_lBatchSize(lBatchSize),
- m_bBatchExact(bBatchExact && (lBatchSize > 1)),
- m_hThread(NULL),
- m_hSem(NULL),
- m_List(NULL),
- m_pPin(pInputPin),
- m_ppSamples(NULL),
- m_lWaiting(0),
- m_evFlushComplete(FALSE, phr),
- m_pInputPin(NULL),
- m_bSendAnyway(FALSE),
- m_nBatched(0),
- m_bFlushing(FALSE),
- m_bFlushed(TRUE),
- m_bFlushingOpt(bFlushingOpt),
- m_bTerminate(FALSE),
- m_hEventPop(NULL),
- m_hr(S_OK)
-{
- ASSERT(m_lBatchSize > 0);
-
-
- if (FAILED(*phr)) {
- return;
- }
-
- // Check the input pin is OK and cache its IMemInputPin interface
-
- *phr = pInputPin->QueryInterface(IID_IMemInputPin, (void **)&m_pInputPin);
- if (FAILED(*phr)) {
- return;
- }
-
- // See if we should ask the downstream pin
-
- if (bAuto) {
- HRESULT hr = m_pInputPin->ReceiveCanBlock();
- if (SUCCEEDED(hr)) {
- bQueue = hr == S_OK;
- }
- }
-
- // Create our sample batch
-
- m_ppSamples = new PMEDIASAMPLE[m_lBatchSize];
- if (m_ppSamples == NULL) {
- *phr = E_OUTOFMEMORY;
- return;
- }
-
- // If we're queueing allocate resources
-
- if (bQueue) {
- DbgLog((LOG_TRACE, 2, TEXT("Creating thread for output pin")));
- m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
- if (m_hSem == NULL) {
- DWORD dwError = GetLastError();
- *phr = AmHresultFromWin32(dwError);
- return;
- }
- m_List = new CSampleList(NAME("Sample Queue List"),
- lListSize,
- FALSE // No lock
- );
- if (m_List == NULL) {
- *phr = E_OUTOFMEMORY;
- return;
- }
-
-
- DWORD dwThreadId;
- m_hThread = CreateThread(NULL,
- 0,
- InitialThreadProc,
- (LPVOID)this,
- 0,
- &dwThreadId);
- if (m_hThread == NULL) {
- DWORD dwError = GetLastError();
- *phr = AmHresultFromWin32(dwError);
- return;
- }
- SetThreadPriority(m_hThread, dwPriority);
- } else {
- DbgLog((LOG_TRACE, 2, TEXT("Calling input pin directly - no thread")));
- }
-}
-
-//
-// COutputQueuee Destructor :
-//
-// Free all resources -
-//
-// Thread,
-// Batched samples
-//
-COutputQueue::~COutputQueue()
-{
- DbgLog((LOG_TRACE, 3, TEXT("COutputQueue::~COutputQueue")));
- /* Free our pointer */
- if (m_pInputPin != NULL) {
- m_pInputPin->Release();
- }
- if (m_hThread != NULL) {
- {
- CAutoLock lck(this);
- m_bTerminate = TRUE;
- m_hr = S_FALSE;
- NotifyThread();
- }
- DbgWaitForSingleObject(m_hThread);
- EXECUTE_ASSERT(CloseHandle(m_hThread));
-
- // The thread frees the samples when asked to terminate
-
- ASSERT(m_List->GetCount() == 0);
- delete m_List;
- } else {
- FreeSamples();
- }
- if (m_hSem != NULL) {
- EXECUTE_ASSERT(CloseHandle(m_hSem));
- }
- delete [] m_ppSamples;
-}
-
-//
-// Call the real thread proc as a member function
-//
-DWORD WINAPI COutputQueue::InitialThreadProc(__in LPVOID pv)
-{
- HRESULT hrCoInit = CAMThread::CoInitializeHelper();
-
- COutputQueue *pSampleQueue = (COutputQueue *)pv;
- DWORD dwReturn = pSampleQueue->ThreadProc();
-
- if(hrCoInit == S_OK) {
- CoUninitialize();
- }
-
- return dwReturn;
-}
-
-//
-// Thread sending the samples downstream :
-//
-// When there is nothing to do the thread sets m_lWaiting (while
-// holding the critical section) and then waits for m_hSem to be
-// set (not holding the critical section)
-//
-DWORD COutputQueue::ThreadProc()
-{
- while (TRUE) {
- BOOL bWait = FALSE;
- IMediaSample *pSample;
- LONG lNumberToSend; // Local copy
- NewSegmentPacket* ppacket;
-
- //
- // Get a batch of samples and send it if possible
- // In any case exit the loop if there is a control action
- // requested
- //
- {
- CAutoLock lck(this);
- while (TRUE) {
-
- if (m_bTerminate) {
- FreeSamples();
- return 0;
- }
- if (m_bFlushing) {
- FreeSamples();
- SetEvent(m_evFlushComplete);
- }
-
- // Get a sample off the list
-
- pSample = m_List->RemoveHead();
- // inform derived class we took something off the queue
- if (m_hEventPop) {
- //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
- SetEvent(m_hEventPop);
- }
-
- if (pSample != NULL &&
- !IsSpecialSample(pSample)) {
-
- // If its just a regular sample just add it to the batch
- // and exit the loop if the batch is full
-
- m_ppSamples[m_nBatched++] = pSample;
- if (m_nBatched == m_lBatchSize) {
- break;
- }
- } else {
-
- // If there was nothing in the queue and there's nothing
- // to send (either because there's nothing or the batch
- // isn't full) then prepare to wait
-
- if (pSample == NULL &&
- (m_bBatchExact || m_nBatched == 0)) {
-
- // Tell other thread to set the event when there's
- // something do to
-
- ASSERT(m_lWaiting == 0);
- m_lWaiting++;
- bWait = TRUE;
- } else {
-
- // We break out of the loop on SEND_PACKET unless
- // there's nothing to send
-
- if (pSample == SEND_PACKET && m_nBatched == 0) {
- continue;
- }
-
- if (pSample == NEW_SEGMENT) {
- // now we need the parameters - we are
- // guaranteed that the next packet contains them
- ppacket = (NewSegmentPacket *) m_List->RemoveHead();
- // we took something off the queue
- if (m_hEventPop) {
- //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
- SetEvent(m_hEventPop);
- }
-
- ASSERT(ppacket);
- }
- // EOS_PACKET falls through here and we exit the loop
- // In this way it acts like SEND_PACKET
- }
- break;
- }
- }
- if (!bWait) {
- // We look at m_nBatched from the client side so keep
- // it up to date inside the critical section
- lNumberToSend = m_nBatched; // Local copy
- m_nBatched = 0;
- }
- }
-
- // Wait for some more data
-
- if (bWait) {
- DbgWaitForSingleObject(m_hSem);
- continue;
- }
-
-
-
- // OK - send it if there's anything to send
- // We DON'T check m_bBatchExact here because either we've got
- // a full batch or we dropped through because we got
- // SEND_PACKET or EOS_PACKET - both of which imply we should
- // flush our batch
-
- if (lNumberToSend != 0) {
- long nProcessed;
- if (m_hr == S_OK) {
- ASSERT(!m_bFlushed);
- HRESULT hr = m_pInputPin->ReceiveMultiple(m_ppSamples,
- lNumberToSend,
- &nProcessed);
- /* Don't overwrite a flushing state HRESULT */
- CAutoLock lck(this);
- if (m_hr == S_OK) {
- m_hr = hr;
- }
- ASSERT(!m_bFlushed);
- }
- while (lNumberToSend != 0) {
- m_ppSamples[--lNumberToSend]->Release();
- }
- if (m_hr != S_OK) {
-
- // In any case wait for more data - S_OK just
- // means there wasn't an error
-
- DbgLog((LOG_ERROR, 2, TEXT("ReceiveMultiple returned %8.8X"),
- m_hr));
- }
- }
-
- // Check for end of stream
-
- if (pSample == EOS_PACKET) {
-
- // We don't send even end of stream on if we've previously
- // returned something other than S_OK
- // This is because in that case the pin which returned
- // something other than S_OK should have either sent
- // EndOfStream() or notified the filter graph
-
- if (m_hr == S_OK) {
- DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()")));
- HRESULT hr = m_pPin->EndOfStream();
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()")));
- }
- }
- }
-
- // Data from a new source
-
- if (pSample == RESET_PACKET) {
- m_hr = S_OK;
- SetEvent(m_evFlushComplete);
- }
-
- if (pSample == NEW_SEGMENT) {
- m_pPin->NewSegment(ppacket->tStart, ppacket->tStop, ppacket->dRate);
- delete ppacket;
- }
- }
-}
-
-// Send batched stuff anyway
-void COutputQueue::SendAnyway()
-{
- if (!IsQueued()) {
-
- // m_bSendAnyway is a private parameter checked in ReceiveMultiple
-
- m_bSendAnyway = TRUE;
- LONG nProcessed;
- ReceiveMultiple(NULL, 0, &nProcessed);
- m_bSendAnyway = FALSE;
-
- } else {
- CAutoLock lck(this);
- QueueSample(SEND_PACKET);
- NotifyThread();
- }
-}
-
-void
-COutputQueue::NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- if (!IsQueued()) {
- if (S_OK == m_hr) {
- if (m_bBatchExact) {
- SendAnyway();
- }
- m_pPin->NewSegment(tStart, tStop, dRate);
- }
- } else {
- if (m_hr == S_OK) {
- //
- // we need to queue the new segment to appear in order in the
- // data, but we need to pass parameters to it. Rather than
- // take the hit of wrapping every single sample so we can tell
- // special ones apart, we queue special pointers to indicate
- // special packets, and we guarantee (by holding the
- // critical section) that the packet immediately following a
- // NEW_SEGMENT value is a NewSegmentPacket containing the
- // parameters.
- NewSegmentPacket * ppack = new NewSegmentPacket;
- if (ppack == NULL) {
- return;
- }
- ppack->tStart = tStart;
- ppack->tStop = tStop;
- ppack->dRate = dRate;
-
- CAutoLock lck(this);
- QueueSample(NEW_SEGMENT);
- QueueSample( (IMediaSample*) ppack);
- NotifyThread();
- }
- }
-}
-
-
-//
-// End of Stream is queued to output device
-//
-void COutputQueue::EOS()
-{
- CAutoLock lck(this);
- if (!IsQueued()) {
- if (m_bBatchExact) {
- SendAnyway();
- }
- if (m_hr == S_OK) {
- DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()")));
- m_bFlushed = FALSE;
- HRESULT hr = m_pPin->EndOfStream();
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()")));
- }
- }
- } else {
- if (m_hr == S_OK) {
- m_bFlushed = FALSE;
- QueueSample(EOS_PACKET);
- NotifyThread();
- }
- }
-}
-
-//
-// Flush all the samples in the queue
-//
-void COutputQueue::BeginFlush()
-{
- if (IsQueued()) {
- {
- CAutoLock lck(this);
-
- // block receives -- we assume this is done by the
- // filter in which we are a component
-
- // discard all queued data
-
- m_bFlushing = TRUE;
-
- // Make sure we discard all samples from now on
-
- if (m_hr == S_OK) {
- m_hr = S_FALSE;
- }
-
- // Optimize so we don't keep calling downstream all the time
-
- if (m_bFlushed && m_bFlushingOpt) {
- return;
- }
-
- // Make sure we really wait for the flush to complete
- m_evFlushComplete.Reset();
-
- NotifyThread();
- }
-
- // pass this downstream
-
- m_pPin->BeginFlush();
- } else {
- // pass downstream first to avoid deadlocks
- m_pPin->BeginFlush();
- CAutoLock lck(this);
- // discard all queued data
-
- m_bFlushing = TRUE;
-
- // Make sure we discard all samples from now on
-
- if (m_hr == S_OK) {
- m_hr = S_FALSE;
- }
- }
-
-}
-
-//
-// leave flush mode - pass this downstream
-void COutputQueue::EndFlush()
-{
- {
- CAutoLock lck(this);
- ASSERT(m_bFlushing);
- if (m_bFlushingOpt && m_bFlushed && IsQueued()) {
- m_bFlushing = FALSE;
- m_hr = S_OK;
- return;
- }
- }
-
- // sync with pushing thread -- done in BeginFlush
- // ensure no more data to go downstream -- done in BeginFlush
- //
- // Because we are synching here there is no need to hold the critical
- // section (in fact we'd deadlock if we did!)
-
- if (IsQueued()) {
- m_evFlushComplete.Wait();
- } else {
- FreeSamples();
- }
-
- // Be daring - the caller has guaranteed no samples will arrive
- // before EndFlush() returns
-
- m_bFlushing = FALSE;
- m_bFlushed = TRUE;
-
- // call EndFlush on downstream pins
-
- m_pPin->EndFlush();
-
- m_hr = S_OK;
-}
-
-// COutputQueue::QueueSample
-//
-// private method to Send a sample to the output queue
-// The critical section MUST be held when this is called
-
-void COutputQueue::QueueSample(IMediaSample *pSample)
-{
- if (NULL == m_List->AddTail(pSample)) {
- if (!IsSpecialSample(pSample)) {
- pSample->Release();
- }
- }
-}
-
-//
-// COutputQueue::Receive()
-//
-// Send a single sample by the multiple sample route
-// (NOTE - this could be optimized if necessary)
-//
-// On return the sample will have been Release()'d
-//
-
-HRESULT COutputQueue::Receive(IMediaSample *pSample)
-{
- LONG nProcessed;
- return ReceiveMultiple(&pSample, 1, &nProcessed);
-}
-
-//
-// COutputQueue::ReceiveMultiple()
-//
-// Send a set of samples to the downstream pin
-//
-// ppSamples - array of samples
-// nSamples - how many
-// nSamplesProcessed - How many were processed
-//
-// On return all samples will have been Release()'d
-//
-
-HRESULT COutputQueue::ReceiveMultiple (
- __in_ecount(nSamples) IMediaSample **ppSamples,
- long nSamples,
- __out long *nSamplesProcessed)
-{
- if (nSamples < 0) {
- return E_INVALIDARG;
- }
-
- CAutoLock lck(this);
- // Either call directly or queue up the samples
-
- if (!IsQueued()) {
-
- // If we already had a bad return code then just return
-
- if (S_OK != m_hr) {
-
- // If we've never received anything since the last Flush()
- // and the sticky return code is not S_OK we must be
- // flushing
- // ((!A || B) is equivalent to A implies B)
- ASSERT(!m_bFlushed || m_bFlushing);
-
- // We're supposed to Release() them anyway!
- *nSamplesProcessed = 0;
- for (int i = 0; i < nSamples; i++) {
- DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (direct) : Discarding %d samples code 0x%8.8X"),
- nSamples, m_hr));
- ppSamples[i]->Release();
- }
-
- return m_hr;
- }
- //
- // If we're flushing the sticky return code should be S_FALSE
- //
- ASSERT(!m_bFlushing);
- m_bFlushed = FALSE;
-
- ASSERT(m_nBatched < m_lBatchSize);
- ASSERT(m_nBatched == 0 || m_bBatchExact);
-
- // Loop processing the samples in batches
-
- LONG iLost = 0;
- long iDone = 0;
- for (iDone = 0;
- iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway);
- ) {
-
-//pragma message (REMIND("Implement threshold scheme"))
- ASSERT(m_nBatched < m_lBatchSize);
- if (iDone < nSamples) {
- m_ppSamples[m_nBatched++] = ppSamples[iDone++];
- }
- if (m_nBatched == m_lBatchSize ||
- nSamples == 0 && (m_bSendAnyway || !m_bBatchExact)) {
- LONG nDone;
- DbgLog((LOG_TRACE, 4, TEXT("Batching %d samples"),
- m_nBatched));
-
- if (m_hr == S_OK) {
- m_hr = m_pInputPin->ReceiveMultiple(m_ppSamples,
- m_nBatched,
- &nDone);
- } else {
- nDone = 0;
- }
- iLost += m_nBatched - nDone;
- for (LONG i = 0; i < m_nBatched; i++) {
- m_ppSamples[i]->Release();
- }
- m_nBatched = 0;
- }
- }
- *nSamplesProcessed = iDone - iLost;
- if (*nSamplesProcessed < 0) {
- *nSamplesProcessed = 0;
- }
- return m_hr;
- } else {
- /* We're sending to our thread */
-
- if (m_hr != S_OK) {
- *nSamplesProcessed = 0;
- DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (queued) : Discarding %d samples code 0x%8.8X"),
- nSamples, m_hr));
- for (int i = 0; i < nSamples; i++) {
- ppSamples[i]->Release();
- }
- return m_hr;
- }
- m_bFlushed = FALSE;
- for (long i = 0; i < nSamples; i++) {
- QueueSample(ppSamples[i]);
- }
- *nSamplesProcessed = nSamples;
- if (!m_bBatchExact ||
- m_nBatched + m_List->GetCount() >= m_lBatchSize) {
- NotifyThread();
- }
- return S_OK;
- }
-}
-
-// Get ready for new data - cancels sticky m_hr
-void COutputQueue::Reset()
-{
- if (!IsQueued()) {
- m_hr = S_OK;
- } else {
- {
- CAutoLock lck(this);
- QueueSample(RESET_PACKET);
- NotifyThread();
- }
- m_evFlushComplete.Wait();
- }
-}
-
-// Remove and Release() all queued and Batched samples
-void COutputQueue::FreeSamples()
-{
- CAutoLock lck(this);
- if (IsQueued()) {
- while (TRUE) {
- IMediaSample *pSample = m_List->RemoveHead();
- // inform derived class we took something off the queue
- if (m_hEventPop) {
- //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
- SetEvent(m_hEventPop);
- }
-
- if (pSample == NULL) {
- break;
- }
- if (!IsSpecialSample(pSample)) {
- pSample->Release();
- } else {
- if (pSample == NEW_SEGMENT) {
- // Free NEW_SEGMENT packet
- NewSegmentPacket *ppacket =
- (NewSegmentPacket *) m_List->RemoveHead();
- // inform derived class we took something off the queue
- if (m_hEventPop) {
- //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
- SetEvent(m_hEventPop);
- }
-
- ASSERT(ppacket != NULL);
- delete ppacket;
- }
- }
- }
- }
- for (int i = 0; i < m_nBatched; i++) {
- m_ppSamples[i]->Release();
- }
- m_nBatched = 0;
-}
-
-// Notify the thread if there is something to do
-//
-// The critical section MUST be held when this is called
-void COutputQueue::NotifyThread()
-{
- // Optimize - no need to signal if it's not waiting
- ASSERT(IsQueued());
- if (m_lWaiting) {
- ReleaseSemaphore(m_hSem, m_lWaiting, NULL);
- m_lWaiting = 0;
- }
-}
-
-// See if there's any work to do
-// Returns
-// TRUE if there is nothing on the queue and nothing in the batch
-// and all data has been sent
-// FALSE otherwise
-//
-BOOL COutputQueue::IsIdle()
-{
- CAutoLock lck(this);
-
- // We're idle if
- // there is no thread (!IsQueued()) OR
- // the thread is waiting for more work (m_lWaiting != 0)
- // AND
- // there's nothing in the current batch (m_nBatched == 0)
-
- if (IsQueued() && m_lWaiting == 0 || m_nBatched != 0) {
- return FALSE;
- } else {
-
- // If we're idle it shouldn't be possible for there
- // to be anything on the work queue
-
- ASSERT(!IsQueued() || m_List->GetCount() == 0);
- return TRUE;
- }
-}
-
-
-void COutputQueue::SetPopEvent(HANDLE hEvent)
-{
- m_hEventPop = hEvent;
-}
diff --git a/third_party/BaseClasses/outputq.h b/third_party/BaseClasses/outputq.h
deleted file mode 100644
index db3d4243..00000000
--- a/third_party/BaseClasses/outputq.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//------------------------------------------------------------------------------
-// File: OutputQ.h
-//
-// Desc: DirectShow base classes - defines the COutputQueue class, which
-// makes a queue of samples and sends them to an output pin. The
-// class will optionally send the samples to the pin directly.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-typedef CGenericList<IMediaSample> CSampleList;
-
-class COutputQueue : public CCritSec
-{
-public:
- // Constructor
- COutputQueue(IPin *pInputPin, // Pin to send stuff to
- __inout HRESULT *phr, // 'Return code'
- BOOL bAuto = TRUE, // Ask pin if blocks
- BOOL bQueue = TRUE, // Send through queue (ignored if
- // bAuto set)
- LONG lBatchSize = 1, // Batch
- BOOL bBatchExact = FALSE,// Batch exactly to BatchSize
- LONG lListSize = // Likely number in the list
- DEFAULTCACHE,
- DWORD dwPriority = // Priority of thread to create
- THREAD_PRIORITY_NORMAL,
- bool bFlushingOpt = false // flushing optimization
- );
- ~COutputQueue();
-
- // enter flush state - discard all data
- void BeginFlush(); // Begin flushing samples
-
- // re-enable receives (pass this downstream)
- void EndFlush(); // Complete flush of samples - downstream
- // pin guaranteed not to block at this stage
-
- void EOS(); // Call this on End of stream
-
- void SendAnyway(); // Send batched samples anyway (if bBatchExact set)
-
- void NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate);
-
- HRESULT Receive(IMediaSample *pSample);
-
- // do something with these media samples
- HRESULT ReceiveMultiple (
- __in_ecount(nSamples) IMediaSample **pSamples,
- long nSamples,
- __out long *nSamplesProcessed);
-
- void Reset(); // Reset m_hr ready for more data
-
- // See if its idle or not
- BOOL IsIdle();
-
- // give the class an event to fire after everything removed from the queue
- void SetPopEvent(HANDLE hEvent);
-
-protected:
- static DWORD WINAPI InitialThreadProc(__in LPVOID pv);
- DWORD ThreadProc();
- BOOL IsQueued()
- {
- return m_List != NULL;
- };
-
- // The critical section MUST be held when this is called
- void QueueSample(IMediaSample *pSample);
-
- BOOL IsSpecialSample(IMediaSample *pSample)
- {
- return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16);
- };
-
- // Remove and Release() batched and queued samples
- void FreeSamples();
-
- // Notify the thread there is something to do
- void NotifyThread();
-
-
-protected:
- // Queue 'messages'
- #define SEND_PACKET ((IMediaSample *)(LONG_PTR)(-2)) // Send batch
- #define EOS_PACKET ((IMediaSample *)(LONG_PTR)(-3)) // End of stream
- #define RESET_PACKET ((IMediaSample *)(LONG_PTR)(-4)) // Reset m_hr
- #define NEW_SEGMENT ((IMediaSample *)(LONG_PTR)(-5)) // send NewSegment
-
- // new segment packet is always followed by one of these
- struct NewSegmentPacket {
- REFERENCE_TIME tStart;
- REFERENCE_TIME tStop;
- double dRate;
- };
-
- // Remember input stuff
- IPin * const m_pPin;
- IMemInputPin * m_pInputPin;
- BOOL const m_bBatchExact;
- LONG const m_lBatchSize;
-
- CSampleList * m_List;
- HANDLE m_hSem;
- CAMEvent m_evFlushComplete;
- HANDLE m_hThread;
- __field_ecount_opt(m_lBatchSize) IMediaSample ** m_ppSamples;
- __range(0, m_lBatchSize) LONG m_nBatched;
-
- // Wait optimization
- LONG m_lWaiting;
- // Flush synchronization
- BOOL m_bFlushing;
-
- // flushing optimization. some downstream filters have trouble
- // with the queue's flushing optimization. other rely on it
- BOOL m_bFlushed;
- bool m_bFlushingOpt;
-
- // Terminate now
- BOOL m_bTerminate;
-
- // Send anyway flag for batching
- BOOL m_bSendAnyway;
-
- // Deferred 'return code'
- HRESULT volatile m_hr;
-
- // an event that can be fired after every deliver
- HANDLE m_hEventPop;
-};
-
diff --git a/third_party/BaseClasses/perflog.cpp b/third_party/BaseClasses/perflog.cpp
deleted file mode 100644
index e6425387..00000000
--- a/third_party/BaseClasses/perflog.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-//------------------------------------------------------------------------------
-// File: perflog.cpp
-//
-// Desc: Macros for DirectShow performance logging.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-#pragma warning (disable:4201)
-
-#include <streams.h>
-#include <windows.h>
-#include <tchar.h>
-#include <winperf.h>
-#include <wmistr.h>
-#include <evntrace.h>
-#include <strsafe.h>
-#include "perflog.h"
-
-//
-// Local function prototypes.
-//
-
-ULONG
-WINAPI
-PerflogCallback (
- WMIDPREQUESTCODE RequestCode,
- __in PVOID Context,
- __out ULONG* BufferSize,
- __in PVOID Buffer
- );
-
-//
-// Event tracing function pointers.
-// We have to do this to run on down-level platforms.
-//
-
-#ifdef UNICODE
-
-ULONG
-(__stdcall * _RegisterTraceGuids) (
- __in IN WMIDPREQUEST RequestAddress,
- __in IN PVOID RequestContext,
- IN LPCGUID ControlGuid,
- IN ULONG GuidCount,
- __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
- IN LPCWSTR MofImagePath,
- IN LPCWSTR MofResourceName,
- OUT PTRACEHANDLE RegistrationHandle
- );
-
-#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsW"
-
-#else
-
-ULONG
-(__stdcall * _RegisterTraceGuids) (
- __in IN WMIDPREQUEST RequestAddress,
- __in IN PVOID RequestContext,
- IN LPCGUID ControlGuid,
- IN ULONG GuidCount,
- __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
- IN LPCSTR MofImagePath,
- IN LPCSTR MofResourceName,
- __out OUT PTRACEHANDLE RegistrationHandle
- );
-
-#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsA"
-
-#endif
-
-ULONG
-(__stdcall * _UnregisterTraceGuids) (
- TRACEHANDLE RegistrationHandle
- );
-
-TRACEHANDLE
-(__stdcall * _GetTraceLoggerHandle) (
- __in PVOID Buffer
- );
-
-UCHAR
-(__stdcall * _GetTraceEnableLevel) (
- TRACEHANDLE TraceHandle
- );
-
-ULONG
-(__stdcall * _GetTraceEnableFlags) (
- TRACEHANDLE TraceHandle
- );
-
-ULONG
-(__stdcall * _TraceEvent) (
- TRACEHANDLE TraceHandle,
- __in PEVENT_TRACE_HEADER EventTrace
- );
-
-HINSTANCE _Advapi32;
-
-//
-// Global variables.
-//
-
-BOOL EventTracingAvailable=FALSE;
-ULONG PerflogEnableFlags;
-UCHAR PerflogEnableLevel;
-ULONG PerflogModuleLevel = 0;
-void (*OnStateChanged)(void);
-TRACEHANDLE PerflogTraceHandle=NULL;
-TRACEHANDLE PerflogRegHandle;
-
-// The Win32 wsprintf() function writes a maximum of 1024 characters to it's output buffer.
-// See the documentation for wsprintf()'s lpOut parameter for more information.
-const INT iDEBUGINFO = 1024; // Used to format strings
-
-//
-// This routine initializes performance logging.
-// It should be called from DllMain().
-//
-
-
-VOID
-PerflogReadModuleLevel(
- HINSTANCE hInstance
- )
-{
- LONG lReturn; // Create key return value
- TCHAR szInfo[iDEBUGINFO]; // Constructs key names
- TCHAR szFullName[iDEBUGINFO]; // Load the full path and module name
- HKEY hModuleKey; // Module key handle
- LPTSTR pName; // Searches from the end for a backslash
- DWORD dwKeySize, dwKeyType, dwKeyValue;
-
- DWORD dwSize = GetModuleFileName(
- (hInstance ? hInstance : GetModuleHandle( NULL )),
- szFullName,
- iDEBUGINFO );
-
- if (0 == dwSize || iDEBUGINFO == dwSize) {
- return;
- }
-
- pName = _tcsrchr(szFullName,'\\');
- if (pName == NULL) {
- pName = szFullName;
- } else {
- pName++;
- }
-
- /* Construct the base key name */
- (void)StringCchPrintf(szInfo,NUMELMS(szInfo),TEXT("SOFTWARE\\Debug\\%s"),pName);
-
- /* Open the key for this module */
- lReturn =
- RegOpenKeyEx(
- HKEY_LOCAL_MACHINE, // Handle of an open key
- szInfo, // Address of subkey name
- (DWORD) 0, // Reserved value
- KEY_QUERY_VALUE, // Desired security access
- &hModuleKey ); // Opened handle buffer
-
- if (lReturn != ERROR_SUCCESS) {
- return;
- }
-
- dwKeySize = sizeof(DWORD);
- lReturn = RegQueryValueEx(
- hModuleKey, // Handle to an open key
- TEXT("PERFLOG"),
- NULL, // Reserved field
- &dwKeyType, // Returns the field type
- (LPBYTE) &dwKeyValue, // Returns the field's value
- &dwKeySize ); // Number of bytes transferred
-
- if ((lReturn == ERROR_SUCCESS) && (dwKeyType == REG_DWORD))
- {
- PerflogModuleLevel = dwKeyValue;
- }
-
- RegCloseKey(hModuleKey);
-}
-
-BOOL PerflogInitIfEnabled(
- IN HINSTANCE hInstance,
- __in IN PPERFLOG_LOGGING_PARAMS LogParams
- )
-{
- PerflogReadModuleLevel( hInstance );
- if (PerflogModuleLevel)
- {
- return PerflogInitialize( LogParams );
- }
- else
- {
- return FALSE;
- }
-}
-
-BOOL
-PerflogInitialize (
- __in IN PPERFLOG_LOGGING_PARAMS LogParams
- )
-{
- ULONG status;
-
- //
- // If we're running on a recent-enough platform, this will get
- // pointers to the event tracing routines.
- //
-
- _Advapi32 = GetModuleHandle (_T("ADVAPI32.DLL"));
- if (_Advapi32 == NULL) {
- return FALSE;
- }
-
- *((FARPROC*) &_RegisterTraceGuids) = GetProcAddress (_Advapi32, REGISTERTRACEGUIDS_NAME);
- *((FARPROC*) &_UnregisterTraceGuids) = GetProcAddress (_Advapi32, "UnregisterTraceGuids");
- *((FARPROC*) &_GetTraceLoggerHandle) = GetProcAddress (_Advapi32, "GetTraceLoggerHandle");
- *((FARPROC*) &_GetTraceEnableLevel) = GetProcAddress (_Advapi32, "GetTraceEnableLevel");
- *((FARPROC*) &_GetTraceEnableFlags) = GetProcAddress (_Advapi32, "GetTraceEnableFlags");
- *((FARPROC*) &_TraceEvent) = GetProcAddress (_Advapi32, "TraceEvent");
-
- if (_RegisterTraceGuids == NULL ||
- _UnregisterTraceGuids == NULL ||
- _GetTraceEnableLevel == NULL ||
- _GetTraceEnableFlags == NULL ||
- _TraceEvent == NULL) {
-
- return FALSE;
- }
-
- EventTracingAvailable = TRUE;
-
- OnStateChanged = LogParams->OnStateChanged;
-
- //
- // Register our GUIDs.
- //
-
- status = _RegisterTraceGuids (PerflogCallback,
- LogParams,
- &LogParams->ControlGuid,
- LogParams->NumberOfTraceGuids,
- LogParams->TraceGuids,
- NULL,
- NULL,
- &PerflogRegHandle);
-
- return (status == ERROR_SUCCESS);
-}
-
-//
-// This routine shuts down performance logging.
-//
-
-VOID
-PerflogShutdown (
- VOID
- )
-{
- if (!EventTracingAvailable) {
- return;
- }
-
- _UnregisterTraceGuids (PerflogRegHandle);
- PerflogRegHandle = NULL;
- PerflogTraceHandle = NULL;
-}
-
-//
-// Event tracing callback routine.
-// It's called when controllers call event tracing control functions.
-//
-
-ULONG
-WINAPI
-PerflogCallback (
- WMIDPREQUESTCODE RequestCode,
- __in PVOID Context,
- __out ULONG* BufferSize,
- __in PVOID Buffer
- )
-{
- ULONG status;
-
- UNREFERENCED_PARAMETER (Context);
-
- ASSERT (EventTracingAvailable);
-
- status = ERROR_SUCCESS;
-
- switch (RequestCode) {
-
- case WMI_ENABLE_EVENTS:
- PerflogTraceHandle = _GetTraceLoggerHandle (Buffer);
- PerflogEnableFlags = _GetTraceEnableFlags (PerflogTraceHandle);
- PerflogEnableLevel = _GetTraceEnableLevel (PerflogTraceHandle);
- break;
-
- case WMI_DISABLE_EVENTS:
- PerflogTraceHandle = NULL;
- PerflogEnableFlags = 0;
- PerflogEnableLevel = 0;
- break;
-
- default:
- status = ERROR_INVALID_PARAMETER;
- }
-
- if (OnStateChanged != NULL) {
- OnStateChanged();
- }
-
- *BufferSize = 0;
- return status;
-}
-
-//
-// Logging routine.
-//
-
-VOID
-PerflogTraceEvent (
- __in PEVENT_TRACE_HEADER Event
- )
-{
- if (!EventTracingAvailable) {
- return;
- }
-
- _TraceEvent (PerflogTraceHandle, Event);
-}
-
-VOID
-PerflogTraceEventLevel(
- ULONG Level,
- __in PEVENT_TRACE_HEADER Event
- )
-{
- if ((!EventTracingAvailable) || (Level <= PerflogModuleLevel)) {
- return;
- }
-
- _TraceEvent (PerflogTraceHandle, Event);
-}
-
-
diff --git a/third_party/BaseClasses/perflog.h b/third_party/BaseClasses/perflog.h
deleted file mode 100644
index 503a1304..00000000
--- a/third_party/BaseClasses/perflog.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//------------------------------------------------------------------------------
-// File: perflog.h
-//
-// Desc: Performance logging framework.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-typedef struct _PERFLOG_LOGGING_PARAMS {
- GUID ControlGuid;
- void (*OnStateChanged)(void);
- ULONG NumberOfTraceGuids;
- TRACE_GUID_REGISTRATION TraceGuids[ANYSIZE_ARRAY];
-} PERFLOG_LOGGING_PARAMS, *PPERFLOG_LOGGING_PARAMS;
-
-BOOL
-PerflogInitIfEnabled(
- IN HINSTANCE hInstance,
- __in PPERFLOG_LOGGING_PARAMS LogParams
- );
-
-BOOL
-PerflogInitialize (
- __in PPERFLOG_LOGGING_PARAMS LogParams
- );
-
-VOID
-PerflogShutdown (
- VOID
- );
-
-VOID
-PerflogTraceEvent (
- __in PEVENT_TRACE_HEADER Event
- );
-
-extern ULONG PerflogEnableFlags;
-extern UCHAR PerflogEnableLevel;
-extern ULONG PerflogModuleLevel;
-extern TRACEHANDLE PerflogTraceHandle;
-extern TRACEHANDLE PerflogRegHandle;
-
-#define PerflogTracingEnabled() (PerflogTraceHandle != 0)
-
-#define PerflogEvent( _x_ ) PerflogTraceEventLevel _x_
-
-VOID
-PerflogTraceEventLevel(
- ULONG Level,
- __in PEVENT_TRACE_HEADER Event
- );
-
-VOID
-PerflogTraceEvent (
- __in PEVENT_TRACE_HEADER Event
- );
diff --git a/third_party/BaseClasses/perfstruct.h b/third_party/BaseClasses/perfstruct.h
deleted file mode 100644
index 9c67b738..00000000
--- a/third_party/BaseClasses/perfstruct.h
+++ /dev/null
@@ -1,194 +0,0 @@
-//------------------------------------------------------------------------------
-// File: PerfStruct.h
-//
-// Desc: Structures for DirectShow performance logging.
-//
-// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef _PERFSTRUCT_H_
-#define _PERFSTRUCT_H_
-
-#include <wmistr.h>
-#include <evntrace.h>
-
-// {28CF047A-2437-4b24-B653-B9446A419A69}
-DEFINE_GUID(GUID_DSHOW_CTL,
-0x28cf047a, 0x2437, 0x4b24, 0xb6, 0x53, 0xb9, 0x44, 0x6a, 0x41, 0x9a, 0x69);
-
-// {D0DA7AD6-AE80-4de5-AAFC-C126711E7593}
-DEFINE_GUID(GUID_VIDEOREND,
-0xd0da7ad6, 0xae80, 0x4de5, 0xaa, 0xfc, 0xc1, 0x26, 0x71, 0x1e, 0x75, 0x93);
-
-// {DC70AC3E-93E5-48db-88AB-E42064EC276A}
-DEFINE_GUID(GUID_DSOUNDGLITCH,
-0xdc70ac3e, 0x93e5, 0x48db, 0x88, 0xab, 0xe4, 0x20, 0x64, 0xec, 0x27, 0x6a);
-
-// {3d7e7d93-2fc8-4a07-a719-e0922ff2899}
-DEFINE_GUID(GUID_STREAMTRACE,
-0x3d7e7d93, 0x2fc8, 0x4a07, 0xa7, 0x19, 0xe0, 0x92, 0x2f, 0xf2, 0x89, 0x9e);
-
-// AZFIX: the following GUIDs aren't useful right now.
-
-// {3C33F7F5-EE54-493c-BA25-1656539C05AC}
-DEFINE_GUID(GUID_GETTIME,
-0x3c33f7f5, 0xee54, 0x493c, 0xba, 0x25, 0x16, 0x56, 0x53, 0x9c, 0x5, 0xac);
-
-// {CC44B44D-8169-4952-9E4A-A4E13295E492}
-DEFINE_GUID(GUID_AUDIOREND,
-0xcc44b44d, 0x8169, 0x4952, 0x9e, 0x4a, 0xa4, 0xe1, 0x32, 0x95, 0xe4, 0x92);
-
-// {775D19BF-4D8B-4de6-8DC9-66BAC7B310A2}
-DEFINE_GUID(GUID_FRAMEDROP,
-0x775d19bf, 0x4d8b, 0x4de6, 0x8d, 0xc9, 0x66, 0xba, 0xc7, 0xb3, 0x10, 0xa2);
-
-// {56D29065-EFBE-42dc-8C29-E325DC9C27D5}
-DEFINE_GUID(GUID_AUDIOBREAK,
-0x56d29065, 0xefbe, 0x42dc, 0x8c, 0x29, 0xe3, 0x25, 0xdc, 0x9c, 0x27, 0xd5);
-
-// {E1E6EA87-95A8-497e-BFBA-0295AEBCC707}
-DEFINE_GUID(GUID_AUDIORECV,
-0xe1e6ea87, 0x95a8, 0x497e, 0xbf, 0xba, 0x2, 0x95, 0xae, 0xbc, 0xc7, 0x7);
-
-// {10F7768A-B1E7-4242-AD90-A2D44683D9F0}
-DEFINE_GUID(GUID_AUDIOSLAVE,
-0x10f7768a, 0xb1e7, 0x4242, 0xad, 0x90, 0xa2, 0xd4, 0x46, 0x83, 0xd9, 0xf0);
-
-// {8983803D-691A-49bc-8FF6-962A39C0198F}
-DEFINE_GUID(GUID_AUDIOADDBREAK,
-0x8983803d, 0x691a, 0x49bc, 0x8f, 0xf6, 0x96, 0x2a, 0x39, 0xc0, 0x19, 0x8f);
-
-#define GLITCHTYPE_DSOUNDFIRSTGOOD 0
-#define GLITCHTYPE_DSOUNDFIRSTBAD 1
-
-typedef struct PERFINFO_DSHOW_AUDIOGLITCH {
- ULONGLONG cycleCounter;
- DWORD glitchType;
- LONGLONG sampleTime;
- LONGLONG previousTime;
- ULONG_PTR instanceId;
-} PERFINFO_DSHOW_AUDIOGLITCH, *PPERFINFO_DSHOW_AUDIOGLITCH;
-
-typedef struct PERFINFO_WMI_AUDIOGLITCH {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AUDIOGLITCH data;
-} PERFINFO_WMI_AUDIO_GLITCH, *PPERFINFO_WMI_AUDIOGLITCH;
-
-typedef struct PERFINFO_DSHOW_GETTIME {
- ULONGLONG cycleCounter;
- ULONGLONG dshowClock;
-} PERFINFO_DSHOW_GETTIME, *PPERFINFO_DSHOW_GETTIME;
-
-typedef struct PERFINFO_WMI_GETTIME {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_GETTIME data;
-} PERFINFO_WMI_GETTIME, *PPERFINFO_WMI_GETTIME;
-
-typedef struct PERFINFO_DSHOW_AVREND {
- ULONGLONG cycleCounter;
- ULONGLONG dshowClock;
- ULONGLONG sampleTime;
-} PERFINFO_DSHOW_AVREND, *PPERFINFO_DSHOW_AVREND;
-
-typedef struct PERFINFO_WMI_AVREND {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AVREND data;
-} PERFINFO_WMI_AVREND, *PPERFINFO_WMI_AVREND;
-
-typedef struct PERFINFO_DSHOW_AUDIOBREAK {
- ULONGLONG cycleCounter;
- ULONGLONG dshowClock;
- ULONGLONG sampleTime;
- ULONGLONG sampleDuration;
-} PERFINFO_DSHOW_AUDIOBREAK, *PPERFINFO_DSHOW_AUDIOBREAK;
-
-typedef struct PERFINFO_WMI_AUDIOBREAK {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AUDIOBREAK data;
-} PERFINFO_WMI_AUDIOBREAK, *PPERFINFO_WMI_AUDIOBREAK;
-
-typedef struct PERFINFO_DSHOW_FRAMEDROP {
- ULONGLONG cycleCounter;
- ULONGLONG dshowClock;
- ULONGLONG frameTime;
-} PERFINFO_DSHOW_FRAMEDROP, *PPERFINFO_DSHOW_FRAMEDROP;
-
-typedef struct PERFINFO_WMI_FRAMEDROP {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_FRAMEDROP data;
-} PERFINFO_WMI_FRAMEDROP, *PPERFINFO_WMI_FRAMEDROP;
-
-#define PERFINFO_STREAMTRACE_MPEG2DEMUX_PTS_TRANSLATION 1
-#define PERFINFO_STREAMTRACE_MPEG2DEMUX_SAMPLE_RECEIVED 2
-#define PERFINFO_STREAMTRACE_VMR_BEGIN_ADVISE 3
-#define PERFINFO_STREAMTRACE_VMR_END_ADVISE 4
-#define PERFINFO_STREAMTRACE_VMR_RECEIVE 5
-#define PERFINFO_STREAMTRACE_VMR_BEGIN_DEINTERLACE 6
-#define PERFINFO_STREAMTRACE_VMR_END_DEINTERLACE 7
-#define PERFINFO_STREAMTRACE_VMR_BEGIN_DECODE 8
-#define PERFINFO_STREAMTRACE_VMR_END_DECODE 9
-#define PERFINFO_STREAMTRACE_VMR_DROPPED_FRAME 10
-#define PERFINFO_STREAMTRACE_ENCDEC_DTFILTERINPUT 11
-#define PERFINFO_STREAMTRACE_ENCDEC_DTFILTEROUTPUT 12
-#define PERFINFO_STREAMTRACE_ENCDEC_ETFILTERINPUT 13
-#define PERFINFO_STREAMTRACE_ENCDEC_ETFILTEROUTPUT 14
-#define PERFINFO_STREAMTRACE_ENCDEC_XDSCODECINPUT 15
-#define PERFINFO_STREAMTRACE_SBE_DVRANALYSISINPUT_RECEIVE 16
-#define PERFINFO_STREAMTRACE_SBE_DVRANALYSISINPUT_DELIVER 17
-#define PERFINFO_STREAMTRACE_SBE_DVRINPUTPIN_RECEIVE 18
-#define PERFINFO_STREAMTRACE_SBE_DVROUTPUTPIN_RECEIVE 19
-#define PERFINFO_STREAMTRACE_VMR_RENDER_TIME 20
-
-typedef struct _PERFINFO_DSHOW_STREAMTRACE {
- ULONG id;
- ULONG reserved;
- ULONGLONG dshowClock;
- ULONGLONG data[ 4 ];
-} PERFINFO_DSHOW_STREAMTRACE, *PPERFINFO_DSHOW_STREAMTRACE;
-
-typedef struct _PERFINFO_WMI_STREAMTRACE {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_STREAMTRACE data;
-} PERFINFO_WMI_STREAMTRACE, *PPERFINFO_WMI_STREAMTRACE;
-
-
-typedef struct PERFINFO_DSHOW_AUDIORECV {
- LONGLONG streamTime ;
- LONGLONG sampleStart ;
- LONGLONG sampleStop ;
- LONGLONG hwduration ;
- BOOL discontinuity ;
-} PERFINFO_DSHOW_AUDIORECV, *PPERFINFO_DSHOW_AUDIORECV;
-
-typedef struct PERFINFO_WMI_AUDIORECV {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AUDIORECV data;
-} PERFINFO_WMI_AUDIORECV, *PPERFINFO_WMI_AUDIORECV;
-
-typedef struct PERFINFO_DSHOW_AUDIOSLAVE {
- LONGLONG masterClock ;
- LONGLONG slaveClock ;
- LONGLONG errorAccum ;
- LONGLONG lastHighErrorSeen ;
- LONGLONG lastLowErrorSeen ;
-} PERFINFO_DSHOW_AUDIOSLAVE, *PPERFINFO_DSHOW_AUDIOSLAVE;
-
-typedef struct PERFINFO_WMI_AUDIOSLAVE {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AUDIOSLAVE data;
-} PERFINFO_WMI_AUDIOSLAVE, *PPERFINFO_WMI_AUDIOSLAVE;
-
-typedef struct PERFINFO_DSHOW_AUDIOADDBREAK {
- DWORD iterNextWrite ;
- DWORD offsetNextWrite ;
- DWORD iterWrite ;
- DWORD offsetWrite ;
-} PERFINFO_DSHOW_AUDIOADDBREAK, *PPERFINFO_DSHOW_AUDIOADDBREAK;
-
-typedef struct PERFINFO_WMI_AUDIOADDBREAK {
- EVENT_TRACE_HEADER header;
- PERFINFO_DSHOW_AUDIOADDBREAK data;
-} PERFINFO_WMI_AUDIOADDBREAK, *PPERFINFO_WMI_AUDIOADDBREAK;
-
-#endif // _PREFSTRUCT_H_
diff --git a/third_party/BaseClasses/pstream.cpp b/third_party/BaseClasses/pstream.cpp
deleted file mode 100644
index d20171f5..00000000
--- a/third_party/BaseClasses/pstream.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-//------------------------------------------------------------------------------
-// File: PStream.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <strsafe.h>
-
-#ifdef PERF
-#include <measure.h>
-#endif
-// #include "pstream.h" in streams.h
-
-//
-// Constructor
-//
-CPersistStream::CPersistStream(IUnknown *punk, __inout HRESULT *phr)
- : mPS_fDirty(FALSE)
-{
- mPS_dwFileVersion = GetSoftwareVersion();
-}
-
-
-//
-// Destructor
-//
-CPersistStream::~CPersistStream() {
- // Nothing to do
-}
-
-#if 0
-SAMPLE CODE TO COPY - not active at the moment
-
-//
-// NonDelegatingQueryInterface
-//
-// This object supports IPersist & IPersistStream
-STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
-{
- if (riid == IID_IPersist) {
- return GetInterface((IPersist *) this, ppv); // ???
- }
- else if (riid == IID_IPersistStream) {
- return GetInterface((IPersistStream *) this, ppv);
- }
- else {
- return CUnknown::NonDelegatingQueryInterface(riid, ppv);
- }
-}
-#endif
-
-
-//
-// WriteToStream
-//
-// Writes to the stream (default action is to write nothing)
-HRESULT CPersistStream::WriteToStream(IStream *pStream)
-{
- // You can override this to do things like
- // hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL);
-
- return NOERROR;
-}
-
-
-
-HRESULT CPersistStream::ReadFromStream(IStream * pStream)
-{
- // You can override this to do things like
- // hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL);
-
- return NOERROR;
-}
-
-
-//
-// Load
-//
-// Load all the data from the given stream
-STDMETHODIMP CPersistStream::Load(LPSTREAM pStm)
-{
- HRESULT hr;
- // Load the version number then the data
- mPS_dwFileVersion = ReadInt(pStm, hr);
- if (FAILED(hr)) {
- return hr;
- }
-
- return ReadFromStream(pStm);
-} // Load
-
-
-
-//
-// Save
-//
-// Save the contents of this Stream.
-STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty)
-{
-
- HRESULT hr = WriteInt(pStm, GetSoftwareVersion());
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = WriteToStream(pStm);
- if (FAILED(hr)) {
- return hr;
- }
-
- mPS_fDirty = !fClearDirty;
-
- return hr;
-} // Save
-
-
-// WriteInt
-//
-// Writes an integer to an IStream as 11 UNICODE characters followed by one space.
-// You could use this for shorts or unsigneds or anything (up to 32 bits)
-// where the value isn't actually truncated by squeezing it into 32 bits.
-// Values such as (unsigned) 0x80000000 would come out as -2147483648
-// but would then load as 0x80000000 through ReadInt. Cast as you please.
-
-STDAPI WriteInt(IStream *pIStream, int n)
-{
- WCHAR Buff[13]; // Allows for trailing null that we don't write
- (void)StringCchPrintfW(Buff, NUMELMS(Buff),L"%011d ",n);
- return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL);
-} // WriteInt
-
-
-// ReadInt
-//
-// Reads an integer from an IStream.
-// Read as 4 bytes. You could use this for shorts or unsigneds or anything
-// where the value isn't actually truncated by squeezing it into 32 bits
-// Striped down subset of what sscanf can do (without dragging in the C runtime)
-
-STDAPI_(int) ReadInt(IStream *pIStream, __out HRESULT &hr)
-{
-
- int Sign = 1;
- unsigned int n = 0; // result wil be n*Sign
- WCHAR wch;
-
- hr = pIStream->Read( &wch, sizeof(wch), NULL);
- if (FAILED(hr)) {
- return 0;
- }
-
- if (wch==L'-'){
- Sign = -1;
- hr = pIStream->Read( &wch, sizeof(wch), NULL);
- if (FAILED(hr)) {
- return 0;
- }
- }
-
- for( ; ; ) {
- if (wch>=L'0' && wch<=L'9') {
- n = 10*n+(int)(wch-L'0');
- } else if ( wch == L' '
- || wch == L'\t'
- || wch == L'\r'
- || wch == L'\n'
- || wch == L'\0'
- ) {
- break;
- } else {
- hr = VFW_E_INVALID_FILE_FORMAT;
- return 0;
- }
-
- hr = pIStream->Read( &wch, sizeof(wch), NULL);
- if (FAILED(hr)) {
- return 0;
- }
- }
-
- if (n==0x80000000 && Sign==-1) {
- // This is the negative number that has no positive version!
- return (int)n;
- }
- else return (int)n * Sign;
-} // ReadInt
-
-
-// The microsoft C/C++ compile generates level 4 warnings to the effect that
-// a particular inline function (from some base class) was not needed.
-// This line gets rid of hundreds of such unwanted messages and makes
-// -W4 compilation feasible:
-#pragma warning(disable: 4514)
diff --git a/third_party/BaseClasses/pstream.h b/third_party/BaseClasses/pstream.h
deleted file mode 100644
index 04b6af62..00000000
--- a/third_party/BaseClasses/pstream.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//------------------------------------------------------------------------------
-// File: PStream.h
-//
-// Desc: DirectShow base classes - defines a class for persistent properties
-// of filters.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __PSTREAM__
-#define __PSTREAM__
-
-// Base class for persistent properties of filters
-// (i.e. filter properties in saved graphs)
-
-// The simplest way to use this is:
-// 1. Arrange for your filter to inherit this class
-// 2. Implement in your class WriteToStream and ReadFromStream
-// These will override the "do nothing" functions here.
-// 3. Change your NonDelegatingQueryInterface to handle IPersistStream
-// 4. Implement SizeMax to return the number of bytes of data you save.
-// If you save UNICODE data, don't forget a char is 2 bytes.
-// 5. Whenever your data changes, call SetDirty()
-//
-// At some point you may decide to alter, or extend the format of your data.
-// At that point you will wish that you had a version number in all the old
-// saved graphs, so that you can tell, when you read them, whether they
-// represent the old or new form. To assist you in this, this class
-// writes and reads a version number.
-// When it writes, it calls GetSoftwareVersion() to enquire what version
-// of the software we have at the moment. (In effect this is a version number
-// of the data layout in the file). It writes this as the first thing in the data.
-// If you want to change the version, implement (override) GetSoftwareVersion().
-// It reads this from the file into mPS_dwFileVersion before calling ReadFromStream,
-// so in ReadFromStream you can check mPS_dwFileVersion to see if you are reading
-// an old version file.
-// Normally you should accept files whose version is no newer than the software
-// version that's reading them.
-
-
-// CPersistStream
-//
-// Implements IPersistStream.
-// See 'OLE Programmers Reference (Vol 1):Structured Storage Overview' for
-// more implementation information.
-class CPersistStream : public IPersistStream {
- private:
-
- // Internal state:
-
- protected:
- DWORD mPS_dwFileVersion; // version number of file (being read)
- BOOL mPS_fDirty;
-
- public:
-
- // IPersistStream methods
-
- STDMETHODIMP IsDirty()
- {return (mPS_fDirty ? S_OK : S_FALSE);} // note FALSE means clean
- STDMETHODIMP Load(LPSTREAM pStm);
- STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty);
- STDMETHODIMP GetSizeMax(__out ULARGE_INTEGER * pcbSize)
- // Allow 24 bytes for version.
- { pcbSize->QuadPart = 12*sizeof(WCHAR)+SizeMax(); return NOERROR; }
-
- // implementation
-
- CPersistStream(IUnknown *punk, __inout HRESULT *phr);
- ~CPersistStream();
-
- HRESULT SetDirty(BOOL fDirty)
- { mPS_fDirty = fDirty; return NOERROR;}
-
-
- // override to reveal IPersist & IPersistStream
- // STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
-
- // --- IPersist ---
-
- // You must override this to provide your own class id
- STDMETHODIMP GetClassID(__out CLSID *pClsid) PURE;
-
- // overrideable if you want
- // file version number. Override it if you ever change format
- virtual DWORD GetSoftwareVersion(void) { return 0; }
-
-
- //=========================================================================
- // OVERRIDE THESE to read and write your data
- // OVERRIDE THESE to read and write your data
- // OVERRIDE THESE to read and write your data
-
- virtual int SizeMax() {return 0;}
- virtual HRESULT WriteToStream(IStream *pStream);
- virtual HRESULT ReadFromStream(IStream *pStream);
- //=========================================================================
-
- private:
-
-};
-
-
-// --- Useful helpers ---
-
-
-// Writes an int to an IStream as UNICODE.
-STDAPI WriteInt(IStream *pIStream, int n);
-
-// inverse of WriteInt
-STDAPI_(int) ReadInt(IStream *pIStream, __out HRESULT &hr);
-
-#endif // __PSTREAM__
diff --git a/third_party/BaseClasses/pullpin.cpp b/third_party/BaseClasses/pullpin.cpp
deleted file mode 100644
index a197ba58..00000000
--- a/third_party/BaseClasses/pullpin.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-//------------------------------------------------------------------------------
-// File: PullPin.cpp
-//
-// Desc: DirectShow base classes - implements CPullPin class that pulls data
-// from IAsyncReader.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include "pullpin.h"
-
-#ifdef DXMPERF
-#include "dxmperf.h"
-#endif // DXMPERF
-
-
-CPullPin::CPullPin()
- : m_pReader(NULL),
- m_pAlloc(NULL),
- m_State(TM_Exit)
-{
-#ifdef DXMPERF
- PERFLOG_CTOR( L"CPullPin", this );
-#endif // DXMPERF
-
-}
-
-CPullPin::~CPullPin()
-{
- Disconnect();
-
-#ifdef DXMPERF
- PERFLOG_DTOR( L"CPullPin", this );
-#endif // DXMPERF
-
-}
-
-// returns S_OK if successfully connected to an IAsyncReader interface
-// from this object
-// Optional allocator should be proposed as a preferred allocator if
-// necessary
-HRESULT
-CPullPin::Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync)
-{
- CAutoLock lock(&m_AccessLock);
-
- if (m_pReader) {
- return VFW_E_ALREADY_CONNECTED;
- }
-
- HRESULT hr = pUnk->QueryInterface(IID_IAsyncReader, (void**)&m_pReader);
- if (FAILED(hr)) {
-
-#ifdef DXMPERF
- {
- AM_MEDIA_TYPE * pmt = NULL;
- PERFLOG_CONNECT( this, pUnk, hr, pmt );
- }
-#endif // DXMPERF
-
- return(hr);
- }
-
- hr = DecideAllocator(pAlloc, NULL);
- if (FAILED(hr)) {
- Disconnect();
-
-#ifdef DXMPERF
- {
- AM_MEDIA_TYPE * pmt = NULL;
- PERFLOG_CONNECT( this, pUnk, hr, pmt );
- }
-#endif // DXMPERF
-
- return hr;
- }
-
- LONGLONG llTotal, llAvail;
- hr = m_pReader->Length(&llTotal, &llAvail);
- if (FAILED(hr)) {
- Disconnect();
-
-#ifdef DXMPERF
- {
- AM_MEDIA_TYPE * pmt = NULL;
- PERFLOG_CONNECT( this, pUnk, hr, pmt );
- }
-#endif
-
- return hr;
- }
-
- // convert from file position to reference time
- m_tDuration = llTotal * UNITS;
- m_tStop = m_tDuration;
- m_tStart = 0;
-
- m_bSync = bSync;
-
-#ifdef DXMPERF
- {
- AM_MEDIA_TYPE * pmt = NULL;
- PERFLOG_CONNECT( this, pUnk, S_OK, pmt );
- }
-#endif // DXMPERF
-
-
- return S_OK;
-}
-
-// disconnect any connection made in Connect
-HRESULT
-CPullPin::Disconnect()
-{
- CAutoLock lock(&m_AccessLock);
-
- StopThread();
-
-
-#ifdef DXMPERF
- PERFLOG_DISCONNECT( this, m_pReader, S_OK );
-#endif // DXMPERF
-
-
- if (m_pReader) {
- m_pReader->Release();
- m_pReader = NULL;
- }
-
- if (m_pAlloc) {
- m_pAlloc->Release();
- m_pAlloc = NULL;
- }
-
- return S_OK;
-}
-
-// agree an allocator using RequestAllocator - optional
-// props param specifies your requirements (non-zero fields).
-// returns an error code if fail to match requirements.
-// optional IMemAllocator interface is offered as a preferred allocator
-// but no error occurs if it can't be met.
-HRESULT
-CPullPin::DecideAllocator(
- IMemAllocator * pAlloc,
- __inout_opt ALLOCATOR_PROPERTIES * pProps)
-{
- ALLOCATOR_PROPERTIES *pRequest;
- ALLOCATOR_PROPERTIES Request;
- if (pProps == NULL) {
- Request.cBuffers = 3;
- Request.cbBuffer = 64*1024;
- Request.cbAlign = 0;
- Request.cbPrefix = 0;
- pRequest = &Request;
- } else {
- pRequest = pProps;
- }
- HRESULT hr = m_pReader->RequestAllocator(
- pAlloc,
- pRequest,
- &m_pAlloc);
- return hr;
-}
-
-// start pulling data
-HRESULT
-CPullPin::Active(void)
-{
- ASSERT(!ThreadExists());
- return StartThread();
-}
-
-// stop pulling data
-HRESULT
-CPullPin::Inactive(void)
-{
- StopThread();
-
- return S_OK;
-}
-
-HRESULT
-CPullPin::Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop)
-{
- CAutoLock lock(&m_AccessLock);
-
- ThreadMsg AtStart = m_State;
-
- if (AtStart == TM_Start) {
- BeginFlush();
- PauseThread();
- EndFlush();
- }
-
- m_tStart = tStart;
- m_tStop = tStop;
-
- HRESULT hr = S_OK;
- if (AtStart == TM_Start) {
- hr = StartThread();
- }
-
- return hr;
-}
-
-HRESULT
-CPullPin::Duration(__out REFERENCE_TIME* ptDuration)
-{
- *ptDuration = m_tDuration;
- return S_OK;
-}
-
-
-HRESULT
-CPullPin::StartThread()
-{
- CAutoLock lock(&m_AccessLock);
-
- if (!m_pAlloc || !m_pReader) {
- return E_UNEXPECTED;
- }
-
- HRESULT hr;
- if (!ThreadExists()) {
-
- // commit allocator
- hr = m_pAlloc->Commit();
- if (FAILED(hr)) {
- return hr;
- }
-
- // start thread
- if (!Create()) {
- return E_FAIL;
- }
- }
-
- m_State = TM_Start;
- hr = (HRESULT) CallWorker(m_State);
- return hr;
-}
-
-HRESULT
-CPullPin::PauseThread()
-{
- CAutoLock lock(&m_AccessLock);
-
- if (!ThreadExists()) {
- return E_UNEXPECTED;
- }
-
- // need to flush to ensure the thread is not blocked
- // in WaitForNext
- HRESULT hr = m_pReader->BeginFlush();
- if (FAILED(hr)) {
- return hr;
- }
-
- m_State = TM_Pause;
- hr = CallWorker(TM_Pause);
-
- m_pReader->EndFlush();
- return hr;
-}
-
-HRESULT
-CPullPin::StopThread()
-{
- CAutoLock lock(&m_AccessLock);
-
- if (!ThreadExists()) {
- return S_FALSE;
- }
-
- // need to flush to ensure the thread is not blocked
- // in WaitForNext
- HRESULT hr = m_pReader->BeginFlush();
- if (FAILED(hr)) {
- return hr;
- }
-
- m_State = TM_Exit;
- hr = CallWorker(TM_Exit);
-
- m_pReader->EndFlush();
-
- // wait for thread to completely exit
- Close();
-
- // decommit allocator
- if (m_pAlloc) {
- m_pAlloc->Decommit();
- }
-
- return S_OK;
-}
-
-
-DWORD
-CPullPin::ThreadProc(void)
-{
- while(1) {
- DWORD cmd = GetRequest();
- switch(cmd) {
- case TM_Exit:
- Reply(S_OK);
- return 0;
-
- case TM_Pause:
- // we are paused already
- Reply(S_OK);
- break;
-
- case TM_Start:
- Reply(S_OK);
- Process();
- break;
- }
-
- // at this point, there should be no outstanding requests on the
- // upstream filter.
- // We should force begin/endflush to ensure that this is true.
- // !!!Note that we may currently be inside a BeginFlush/EndFlush pair
- // on another thread, but the premature EndFlush will do no harm now
- // that we are idle.
- m_pReader->BeginFlush();
- CleanupCancelled();
- m_pReader->EndFlush();
- }
-}
-
-HRESULT
-CPullPin::QueueSample(
- __inout REFERENCE_TIME& tCurrent,
- REFERENCE_TIME tAlignStop,
- BOOL bDiscontinuity
- )
-{
- IMediaSample* pSample;
-
- HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
- if (FAILED(hr)) {
- return hr;
- }
-
- LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
- if (tStopThis > tAlignStop) {
- tStopThis = tAlignStop;
- }
- pSample->SetTime(&tCurrent, &tStopThis);
- tCurrent = tStopThis;
-
- pSample->SetDiscontinuity(bDiscontinuity);
-
- hr = m_pReader->Request(
- pSample,
- 0);
- if (FAILED(hr)) {
- pSample->Release();
-
- CleanupCancelled();
- OnError(hr);
- }
- return hr;
-}
-
-HRESULT
-CPullPin::CollectAndDeliver(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop)
-{
- IMediaSample* pSample = NULL; // better be sure pSample is set
- DWORD_PTR dwUnused;
- HRESULT hr = m_pReader->WaitForNext(
- INFINITE,
- &pSample,
- &dwUnused);
- if (FAILED(hr)) {
- if (pSample) {
- pSample->Release();
- }
- } else {
- hr = DeliverSample(pSample, tStart, tStop);
- }
- if (FAILED(hr)) {
- CleanupCancelled();
- OnError(hr);
- }
- return hr;
-
-}
-
-HRESULT
-CPullPin::DeliverSample(
- IMediaSample* pSample,
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop
- )
-{
- // fix up sample if past actual stop (for sector alignment)
- REFERENCE_TIME t1, t2;
- if (S_OK == pSample->GetTime(&t1, &t2)) {
- if (t2 > tStop) {
- t2 = tStop;
- }
-
- // adjust times to be relative to (aligned) start time
- t1 -= tStart;
- t2 -= tStart;
- HRESULT hr = pSample->SetTime(&t1, &t2);
- if (FAILED(hr)) {
- return hr;
- }
- }
-
-#ifdef DXMPERF
- {
- AM_MEDIA_TYPE * pmt = NULL;
- pSample->GetMediaType( &pmt );
- PERFLOG_RECEIVE( L"CPullPin", m_pReader, this, pSample, pmt );
- }
-#endif
-
- HRESULT hr = Receive(pSample);
- pSample->Release();
- return hr;
-}
-
-void
-CPullPin::Process(void)
-{
- // is there anything to do?
- if (m_tStop <= m_tStart) {
- EndOfStream();
- return;
- }
-
- BOOL bDiscontinuity = TRUE;
-
- // if there is more than one sample at the allocator,
- // then try to queue 2 at once in order to overlap.
- // -- get buffer count and required alignment
- ALLOCATOR_PROPERTIES Actual;
- HRESULT hr = m_pAlloc->GetProperties(&Actual);
-
- // align the start position downwards
- REFERENCE_TIME tStart = AlignDown(m_tStart / UNITS, Actual.cbAlign) * UNITS;
- REFERENCE_TIME tCurrent = tStart;
-
- REFERENCE_TIME tStop = m_tStop;
- if (tStop > m_tDuration) {
- tStop = m_tDuration;
- }
-
- // align the stop position - may be past stop, but that
- // doesn't matter
- REFERENCE_TIME tAlignStop = AlignUp(tStop / UNITS, Actual.cbAlign) * UNITS;
-
-
- DWORD dwRequest;
-
- if (!m_bSync) {
-
- // Break out of the loop either if we get to the end or we're asked
- // to do something else
- while (tCurrent < tAlignStop) {
-
- // Break out without calling EndOfStream if we're asked to
- // do something different
- if (CheckRequest(&dwRequest)) {
- return;
- }
-
- // queue a first sample
- if (Actual.cBuffers > 1) {
-
- hr = QueueSample(tCurrent, tAlignStop, TRUE);
- bDiscontinuity = FALSE;
-
- if (FAILED(hr)) {
- return;
- }
- }
-
-
-
- // loop queueing second and waiting for first..
- while (tCurrent < tAlignStop) {
-
- hr = QueueSample(tCurrent, tAlignStop, bDiscontinuity);
- bDiscontinuity = FALSE;
-
- if (FAILED(hr)) {
- return;
- }
-
- hr = CollectAndDeliver(tStart, tStop);
- if (S_OK != hr) {
-
- // stop if error, or if downstream filter said
- // to stop.
- return;
- }
- }
-
- if (Actual.cBuffers > 1) {
- hr = CollectAndDeliver(tStart, tStop);
- if (FAILED(hr)) {
- return;
- }
- }
- }
- } else {
-
- // sync version of above loop
- while (tCurrent < tAlignStop) {
-
- // Break out without calling EndOfStream if we're asked to
- // do something different
- if (CheckRequest(&dwRequest)) {
- return;
- }
-
- IMediaSample* pSample;
-
- hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
- if (FAILED(hr)) {
- OnError(hr);
- return;
- }
-
- LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
- if (tStopThis > tAlignStop) {
- tStopThis = tAlignStop;
- }
- pSample->SetTime(&tCurrent, &tStopThis);
- tCurrent = tStopThis;
-
- if (bDiscontinuity) {
- pSample->SetDiscontinuity(TRUE);
- bDiscontinuity = FALSE;
- }
-
- hr = m_pReader->SyncReadAligned(pSample);
-
- if (FAILED(hr)) {
- pSample->Release();
- OnError(hr);
- return;
- }
-
- hr = DeliverSample(pSample, tStart, tStop);
- if (hr != S_OK) {
- if (FAILED(hr)) {
- OnError(hr);
- }
- return;
- }
- }
- }
-
- EndOfStream();
-}
-
-// after a flush, cancelled i/o will be waiting for collection
-// and release
-void
-CPullPin::CleanupCancelled(void)
-{
- while (1) {
- IMediaSample * pSample;
- DWORD_PTR dwUnused;
-
- HRESULT hr = m_pReader->WaitForNext(
- 0, // no wait
- &pSample,
- &dwUnused);
- if(pSample) {
- pSample->Release();
- } else {
- // no more samples
- return;
- }
- }
-}
diff --git a/third_party/BaseClasses/pullpin.h b/third_party/BaseClasses/pullpin.h
deleted file mode 100644
index 03ad40ec..00000000
--- a/third_party/BaseClasses/pullpin.h
+++ /dev/null
@@ -1,152 +0,0 @@
-//------------------------------------------------------------------------------
-// File: PullPin.h
-//
-// Desc: DirectShow base classes - defines CPullPin class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __PULLPIN_H__
-#define __PULLPIN_H__
-
-//
-// CPullPin
-//
-// object supporting pulling data from an IAsyncReader interface.
-// Given a start/stop position, calls a pure Receive method with each
-// IMediaSample received.
-//
-// This is essentially for use in a MemInputPin when it finds itself
-// connected to an IAsyncReader pin instead of a pushing pin.
-//
-
-class CPullPin : public CAMThread
-{
- IAsyncReader* m_pReader;
- REFERENCE_TIME m_tStart;
- REFERENCE_TIME m_tStop;
- REFERENCE_TIME m_tDuration;
- BOOL m_bSync;
-
- enum ThreadMsg {
- TM_Pause, // stop pulling and wait for next message
- TM_Start, // start pulling
- TM_Exit, // stop and exit
- };
-
- ThreadMsg m_State;
-
- // override pure thread proc from CAMThread
- DWORD ThreadProc(void);
-
- // running pull method (check m_bSync)
- void Process(void);
-
- // clean up any cancelled i/o after a flush
- void CleanupCancelled(void);
-
- // suspend thread from pulling, eg during seek
- HRESULT PauseThread();
-
- // start thread pulling - create thread if necy
- HRESULT StartThread();
-
- // stop and close thread
- HRESULT StopThread();
-
- // called from ProcessAsync to queue and collect requests
- HRESULT QueueSample(
- __inout REFERENCE_TIME& tCurrent,
- REFERENCE_TIME tAlignStop,
- BOOL bDiscontinuity);
-
- HRESULT CollectAndDeliver(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop);
-
- HRESULT DeliverSample(
- IMediaSample* pSample,
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop);
-
-protected:
- IMemAllocator * m_pAlloc;
-
-public:
- CPullPin();
- virtual ~CPullPin();
-
- // returns S_OK if successfully connected to an IAsyncReader interface
- // from this object
- // Optional allocator should be proposed as a preferred allocator if
- // necessary
- // bSync is TRUE if we are to use sync reads instead of the
- // async methods.
- HRESULT Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync);
-
- // disconnect any connection made in Connect
- HRESULT Disconnect();
-
- // agree an allocator using RequestAllocator - optional
- // props param specifies your requirements (non-zero fields).
- // returns an error code if fail to match requirements.
- // optional IMemAllocator interface is offered as a preferred allocator
- // but no error occurs if it can't be met.
- virtual HRESULT DecideAllocator(
- IMemAllocator* pAlloc,
- __inout_opt ALLOCATOR_PROPERTIES * pProps);
-
- // set start and stop position. if active, will start immediately at
- // the new position. Default is 0 to duration
- HRESULT Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop);
-
- // return the total duration
- HRESULT Duration(__out REFERENCE_TIME* ptDuration);
-
- // start pulling data
- HRESULT Active(void);
-
- // stop pulling data
- HRESULT Inactive(void);
-
- // helper functions
- LONGLONG AlignDown(LONGLONG ll, LONG lAlign) {
- // aligning downwards is just truncation
- return ll & ~(lAlign-1);
- };
-
- LONGLONG AlignUp(LONGLONG ll, LONG lAlign) {
- // align up: round up to next boundary
- return (ll + (lAlign -1)) & ~(lAlign -1);
- };
-
- // GetReader returns the (addrefed) IAsyncReader interface
- // for SyncRead etc
- IAsyncReader* GetReader() {
- m_pReader->AddRef();
- return m_pReader;
- };
-
- // -- pure --
-
- // override this to handle data arrival
- // return value other than S_OK will stop data
- virtual HRESULT Receive(IMediaSample*) PURE;
-
- // override this to handle end-of-stream
- virtual HRESULT EndOfStream(void) PURE;
-
- // called on runtime errors that will have caused pulling
- // to stop
- // these errors are all returned from the upstream filter, who
- // will have already reported any errors to the filtergraph.
- virtual void OnError(HRESULT hr) PURE;
-
- // flush this pin and all downstream
- virtual HRESULT BeginFlush() PURE;
- virtual HRESULT EndFlush() PURE;
-
-};
-
-#endif //__PULLPIN_H__
diff --git a/third_party/BaseClasses/refclock.cpp b/third_party/BaseClasses/refclock.cpp
deleted file mode 100644
index 8ae25f44..00000000
--- a/third_party/BaseClasses/refclock.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-//------------------------------------------------------------------------------
-// File: RefClock.cpp
-//
-// Desc: DirectShow base classes - implements the IReferenceClock interface.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <limits.h>
-
-#ifdef DXMPERF
-#include "dxmperf.h"
-#endif // DXMPERF
-
-
-// 'this' used in constructor list
-#pragma warning(disable:4355)
-
-
-STDMETHODIMP CBaseReferenceClock::NonDelegatingQueryInterface(
- REFIID riid,
- __deref_out void ** ppv)
-{
- HRESULT hr;
-
- if (riid == IID_IReferenceClock)
- {
- hr = GetInterface((IReferenceClock *) this, ppv);
- }
- else if (riid == IID_IReferenceClockTimerControl)
- {
- hr = GetInterface((IReferenceClockTimerControl *) this, ppv);
- }
- else
- {
- hr = CUnknown::NonDelegatingQueryInterface(riid, ppv);
- }
- return hr;
-}
-
-CBaseReferenceClock::~CBaseReferenceClock()
-{
-#ifdef DXMPERF
- PERFLOG_DTOR( L"CBaseReferenceClock", (IReferenceClock *) this );
-#endif // DXMPERF
-
- if (m_TimerResolution) timeEndPeriod(m_TimerResolution);
-
- if (m_pSchedule)
- {
- m_pSchedule->DumpLinkedList();
- }
-
- if (m_hThread)
- {
- m_bAbort = TRUE;
- TriggerThread();
- WaitForSingleObject( m_hThread, INFINITE );
- EXECUTE_ASSERT( CloseHandle(m_hThread) );
- m_hThread = 0;
- EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
- delete m_pSchedule;
- }
-}
-
-// A derived class may supply a hThreadEvent if it has its own thread that will take care
-// of calling the schedulers Advise method. (Refere to CBaseReferenceClock::AdviseThread()
-// to see what such a thread has to do.)
-CBaseReferenceClock::CBaseReferenceClock( __in_opt LPCTSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- __inout HRESULT *phr,
- __inout_opt CAMSchedule * pShed )
-: CUnknown( pName, pUnk )
-, m_rtLastGotTime(0)
-, m_TimerResolution(0)
-, m_bAbort( FALSE )
-, m_pSchedule( pShed ? pShed : new CAMSchedule(CreateEvent(NULL, FALSE, FALSE, NULL)) )
-, m_hThread(0)
-{
-
-#ifdef DXMPERF
- PERFLOG_CTOR( pName ? pName : L"CBaseReferenceClock", (IReferenceClock *) this );
-#endif // DXMPERF
-
- ASSERT(m_pSchedule);
- if (!m_pSchedule)
- {
- *phr = E_OUTOFMEMORY;
- }
- else
- {
- // Set up the highest resolution timer we can manage
- TIMECAPS tc;
- m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))
- ? tc.wPeriodMin
- : 1;
-
- timeBeginPeriod(m_TimerResolution);
-
- /* Initialise our system times - the derived clock should set the right values */
- m_dwPrevSystemTime = timeGetTime();
- m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime;
-
- #ifdef PERF
- m_idGetSystemTime = MSR_REGISTER(TEXT("CBaseReferenceClock::GetTime"));
- #endif
-
- if ( !pShed )
- {
- DWORD ThreadID;
- m_hThread = ::CreateThread(NULL, // Security attributes
- (DWORD) 0, // Initial stack size
- AdviseThreadFunction, // Thread start address
- (LPVOID) this, // Thread parameter
- (DWORD) 0, // Creation flags
- &ThreadID); // Thread identifier
-
- if (m_hThread)
- {
- SetThreadPriority( m_hThread, THREAD_PRIORITY_TIME_CRITICAL );
- }
- else
- {
- *phr = E_FAIL;
- EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
- delete m_pSchedule;
- m_pSchedule = NULL;
- }
- }
- }
-}
-
-void CBaseReferenceClock::Restart (IN REFERENCE_TIME rtMinTime)
-{
- Lock();
- m_rtLastGotTime = rtMinTime ;
- Unlock();
-}
-
-STDMETHODIMP CBaseReferenceClock::GetTime(__out REFERENCE_TIME *pTime)
-{
- HRESULT hr;
- if (pTime)
- {
- REFERENCE_TIME rtNow;
- Lock();
- rtNow = GetPrivateTime();
- if (rtNow > m_rtLastGotTime)
- {
- m_rtLastGotTime = rtNow;
- hr = S_OK;
- }
- else
- {
- hr = S_FALSE;
- }
- *pTime = m_rtLastGotTime;
- Unlock();
- MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) );
-
-#ifdef DXMPERF
- PERFLOG_GETTIME( (IReferenceClock *) this, *pTime );
-#endif // DXMPERF
-
- }
- else hr = E_POINTER;
-
- return hr;
-}
-
-/* Ask for an async notification that a time has elapsed */
-
-STDMETHODIMP CBaseReferenceClock::AdviseTime(
- REFERENCE_TIME baseTime, // base reference time
- REFERENCE_TIME streamTime, // stream offset time
- HEVENT hEvent, // advise via this event
- __out DWORD_PTR *pdwAdviseCookie)// where your cookie goes
-{
- CheckPointer(pdwAdviseCookie, E_POINTER);
- *pdwAdviseCookie = 0;
-
- // Check that the event is not already set
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0));
-
- HRESULT hr;
-
- const REFERENCE_TIME lRefTime = baseTime + streamTime;
- if ( lRefTime <= 0 || lRefTime == MAX_TIME )
- {
- hr = E_INVALIDARG;
- }
- else
- {
- *pdwAdviseCookie = m_pSchedule->AddAdvisePacket( lRefTime, 0, HANDLE(hEvent), FALSE );
- hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
- }
- return hr;
-}
-
-
-/* Ask for an asynchronous periodic notification that a time has elapsed */
-
-STDMETHODIMP CBaseReferenceClock::AdvisePeriodic(
- REFERENCE_TIME StartTime, // starting at this time
- REFERENCE_TIME PeriodTime, // time between notifications
- HSEMAPHORE hSemaphore, // advise via a semaphore
- __out DWORD_PTR *pdwAdviseCookie) // where your cookie goes
-{
- CheckPointer(pdwAdviseCookie, E_POINTER);
- *pdwAdviseCookie = 0;
-
- HRESULT hr;
- if (StartTime > 0 && PeriodTime > 0 && StartTime != MAX_TIME )
- {
- *pdwAdviseCookie = m_pSchedule->AddAdvisePacket( StartTime, PeriodTime, HANDLE(hSemaphore), TRUE );
- hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
- }
- else hr = E_INVALIDARG;
-
- return hr;
-}
-
-
-STDMETHODIMP CBaseReferenceClock::Unadvise(DWORD_PTR dwAdviseCookie)
-{
- return m_pSchedule->Unadvise(dwAdviseCookie);
-}
-
-
-REFERENCE_TIME CBaseReferenceClock::GetPrivateTime()
-{
- CAutoLock cObjectLock(this);
-
-
- /* If the clock has wrapped then the current time will be less than
- * the last time we were notified so add on the extra milliseconds
- *
- * The time period is long enough so that the likelihood of
- * successive calls spanning the clock cycle is not considered.
- */
-
- DWORD dwTime = timeGetTime();
- {
- m_rtPrivateTime += Int32x32To64(UNITS / MILLISECONDS, (DWORD)(dwTime - m_dwPrevSystemTime));
- m_dwPrevSystemTime = dwTime;
- }
-
- return m_rtPrivateTime;
-}
-
-
-/* Adjust the current time by the input value. This allows an
- external time source to work out some of the latency of the clock
- system and adjust the "current" time accordingly. The intent is
- that the time returned to the user is synchronised to a clock
- source and allows drift to be catered for.
-
- For example: if the clock source detects a drift it can pass a delta
- to the current time rather than having to set an explicit time.
-*/
-
-STDMETHODIMP CBaseReferenceClock::SetTimeDelta(const REFERENCE_TIME & TimeDelta)
-{
-#ifdef DEBUG
-
- // Just break if passed an improper time delta value
- LONGLONG llDelta = TimeDelta > 0 ? TimeDelta : -TimeDelta;
- if (llDelta > UNITS * 1000) {
- DbgLog((LOG_TRACE, 0, TEXT("Bad Time Delta")));
- //DebugBreak();
- }
-
- // We're going to calculate a "severity" for the time change. Max -1
- // min 8. We'll then use this as the debug logging level for a
- // debug log message.
- const LONG usDelta = LONG(TimeDelta/10); // Delta in micro-secs
-
- DWORD delta = abs(usDelta); // varying delta
- // Severity == 8 - ceil(log<base 8>(abs( micro-secs delta)))
- int Severity = 8;
- while ( delta > 0 )
- {
- delta >>= 3; // div 8
- Severity--;
- }
-
- // Sev == 0 => > 2 second delta!
- DbgLog((LOG_TIMING, Severity < 0 ? 0 : Severity,
- TEXT("Sev %2i: CSystemClock::SetTimeDelta(%8ld us) %lu -> %lu ms."),
- Severity, usDelta, DWORD(ConvertToMilliseconds(m_rtPrivateTime)),
- DWORD(ConvertToMilliseconds(TimeDelta+m_rtPrivateTime)) ));
-
- // Don't want the DbgBreak to fire when running stress on debug-builds.
- #ifdef BREAK_ON_SEVERE_TIME_DELTA
- if (Severity < 0)
- DbgBreakPoint(TEXT("SetTimeDelta > 16 seconds!"),
- TEXT(__FILE__),__LINE__);
- #endif
-
-#endif
-
- CAutoLock cObjectLock(this);
- m_rtPrivateTime += TimeDelta;
- // If time goes forwards, and we have advises, then we need to
- // trigger the thread so that it can re-evaluate its wait time.
- // Since we don't want the cost of the thread switches if the change
- // is really small, only do it if clock goes forward by more than
- // 0.5 millisecond. If the time goes backwards, the thread will
- // wake up "early" (relativly speaking) and will re-evaluate at
- // that time.
- if ( TimeDelta > 5000 && m_pSchedule->GetAdviseCount() > 0 ) TriggerThread();
- return NOERROR;
-}
-
-// Thread stuff
-
-DWORD __stdcall CBaseReferenceClock::AdviseThreadFunction(__in LPVOID p)
-{
- return DWORD(reinterpret_cast<CBaseReferenceClock*>(p)->AdviseThread());
-}
-
-HRESULT CBaseReferenceClock::AdviseThread()
-{
- DWORD dwWait = INFINITE;
-
- // The first thing we do is wait until something interesting happens
- // (meaning a first advise or shutdown). This prevents us calling
- // GetPrivateTime immediately which is goodness as that is a virtual
- // routine and the derived class may not yet be constructed. (This
- // thread is created in the base class constructor.)
-
- while ( !m_bAbort )
- {
- // Wait for an interesting event to happen
- DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait ));
- WaitForSingleObject(m_pSchedule->GetEvent(), dwWait);
- if (m_bAbort) break;
-
- // There are several reasons why we need to work from the internal
- // time, mainly to do with what happens when time goes backwards.
- // Mainly, it stop us looping madly if an event is just about to
- // expire when the clock goes backward (i.e. GetTime stop for a
- // while).
- const REFERENCE_TIME rtNow = GetPrivateTime();
-
- DbgLog((LOG_TIMING, 3,
- TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"),
- ConvertToMilliseconds(rtNow) ));
-
- // We must add in a millisecond, since this is the resolution of our
- // WaitForSingleObject timer. Failure to do so will cause us to loop
- // franticly for (approx) 1 a millisecond.
- m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow );
- LONGLONG llWait = m_rtNextAdvise - rtNow;
-
- ASSERT( llWait > 0 );
-
- llWait = ConvertToMilliseconds(llWait);
- // DON'T replace this with a max!! (The type's of these things is VERY important)
- dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait);
- };
- return NOERROR;
-}
-
-HRESULT CBaseReferenceClock::SetDefaultTimerResolution(
- REFERENCE_TIME timerResolution // in 100ns
- )
-{
- CAutoLock cObjectLock(this);
- if( 0 == timerResolution ) {
- if( m_TimerResolution ) {
- timeEndPeriod( m_TimerResolution );
- m_TimerResolution = 0;
- }
- } else {
- TIMECAPS tc;
- DWORD dwMinResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))
- ? tc.wPeriodMin
- : 1;
- DWORD dwResolution = max( dwMinResolution, DWORD(timerResolution / 10000) );
- if( dwResolution != m_TimerResolution ) {
- timeEndPeriod(m_TimerResolution);
- m_TimerResolution = dwResolution;
- timeBeginPeriod( m_TimerResolution );
- }
- }
- return S_OK;
-}
-
-HRESULT CBaseReferenceClock::GetDefaultTimerResolution(
- __out REFERENCE_TIME* pTimerResolution // in 100ns
- )
-{
- if( !pTimerResolution ) {
- return E_POINTER;
- }
- CAutoLock cObjectLock(this);
- *pTimerResolution = m_TimerResolution * 10000;
- return S_OK;
-}
diff --git a/third_party/BaseClasses/schedule.cpp b/third_party/BaseClasses/schedule.cpp
deleted file mode 100644
index 7d798306..00000000
--- a/third_party/BaseClasses/schedule.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Schedule.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-
-// DbgLog values (all on LOG_TIMING):
-//
-// 2 for schedulting, firing and shunting of events
-// 3 for wait delays and wake-up times of event thread
-// 4 for details of whats on the list when the thread awakes
-
-/* Construct & destructors */
-
-CAMSchedule::CAMSchedule( HANDLE ev )
-: CBaseObject(TEXT("CAMSchedule"))
-, head(&z, 0), z(0, MAX_TIME)
-, m_dwNextCookie(0), m_dwAdviseCount(0)
-, m_pAdviseCache(0), m_dwCacheCount(0)
-, m_ev( ev )
-{
- head.m_dwAdviseCookie = z.m_dwAdviseCookie = 0;
-}
-
-CAMSchedule::~CAMSchedule()
-{
- m_Serialize.Lock();
-
- // Delete cache
- CAdvisePacket * p = m_pAdviseCache;
- while (p)
- {
- CAdvisePacket *const p_next = p->m_next;
- delete p;
- p = p_next;
- }
-
- ASSERT( m_dwAdviseCount == 0 );
- // Better to be safe than sorry
- if ( m_dwAdviseCount > 0 )
- {
- DumpLinkedList();
- while ( !head.m_next->IsZ() )
- {
- head.DeleteNext();
- --m_dwAdviseCount;
- }
- }
-
- // If, in the debug version, we assert twice, it means, not only
- // did we have left over advises, but we have also let m_dwAdviseCount
- // get out of sync. with the number of advises actually on the list.
- ASSERT( m_dwAdviseCount == 0 );
-
- m_Serialize.Unlock();
-}
-
-/* Public methods */
-
-DWORD CAMSchedule::GetAdviseCount()
-{
- // No need to lock, m_dwAdviseCount is 32bits & declared volatile
- return m_dwAdviseCount;
-}
-
-REFERENCE_TIME CAMSchedule::GetNextAdviseTime()
-{
- CAutoLock lck(&m_Serialize); // Need to stop the linked list from changing
- return head.m_next->m_rtEventTime;
-}
-
-DWORD_PTR CAMSchedule::AddAdvisePacket
-( const REFERENCE_TIME & time1
-, const REFERENCE_TIME & time2
-, HANDLE h, BOOL periodic
-)
-{
- // Since we use MAX_TIME as a sentry, we can't afford to
- // schedule a notification at MAX_TIME
- ASSERT( time1 < MAX_TIME );
- DWORD_PTR Result;
- CAdvisePacket * p;
-
- m_Serialize.Lock();
-
- if (m_pAdviseCache)
- {
- p = m_pAdviseCache;
- m_pAdviseCache = p->m_next;
- --m_dwCacheCount;
- }
- else
- {
- p = new CAdvisePacket();
- }
- if (p)
- {
- p->m_rtEventTime = time1; p->m_rtPeriod = time2;
- p->m_hNotify = h; p->m_bPeriodic = periodic;
- Result = AddAdvisePacket( p );
- }
- else Result = 0;
-
- m_Serialize.Unlock();
-
- return Result;
-}
-
-HRESULT CAMSchedule::Unadvise(DWORD_PTR dwAdviseCookie)
-{
- HRESULT hr = S_FALSE;
- CAdvisePacket * p_prev = &head;
- CAdvisePacket * p_n;
- m_Serialize.Lock();
- while ( p_n = p_prev->Next() ) // The Next() method returns NULL when it hits z
- {
- if ( p_n->m_dwAdviseCookie == dwAdviseCookie )
- {
- Delete( p_prev->RemoveNext() );
- --m_dwAdviseCount;
- hr = S_OK;
- // Having found one cookie that matches, there should be no more
- #ifdef DEBUG
- while (p_n = p_prev->Next())
- {
- ASSERT(p_n->m_dwAdviseCookie != dwAdviseCookie);
- p_prev = p_n;
- }
- #endif
- break;
- }
- p_prev = p_n;
- };
- m_Serialize.Unlock();
- return hr;
-}
-
-REFERENCE_TIME CAMSchedule::Advise( const REFERENCE_TIME & rtTime )
-{
- REFERENCE_TIME rtNextTime;
- CAdvisePacket * pAdvise;
-
- DbgLog((LOG_TIMING, 2,
- TEXT("CAMSchedule::Advise( %lu ms )"), ULONG(rtTime / (UNITS / MILLISECONDS))));
-
- CAutoLock lck(&m_Serialize);
-
- #ifdef DEBUG
- if (DbgCheckModuleLevel(LOG_TIMING, 4)) DumpLinkedList();
- #endif
-
- // Note - DON'T cache the difference, it might overflow
- while ( rtTime >= (rtNextTime = (pAdvise=head.m_next)->m_rtEventTime) &&
- !pAdvise->IsZ() )
- {
- ASSERT(pAdvise->m_dwAdviseCookie); // If this is zero, its the head or the tail!!
-
- ASSERT(pAdvise->m_hNotify != INVALID_HANDLE_VALUE);
-
- if (pAdvise->m_bPeriodic == TRUE)
- {
- ReleaseSemaphore(pAdvise->m_hNotify,1,NULL);
- pAdvise->m_rtEventTime += pAdvise->m_rtPeriod;
- ShuntHead();
- }
- else
- {
- ASSERT( pAdvise->m_bPeriodic == FALSE );
- EXECUTE_ASSERT(SetEvent(pAdvise->m_hNotify));
- --m_dwAdviseCount;
- Delete( head.RemoveNext() );
- }
-
- }
-
- DbgLog((LOG_TIMING, 3,
- TEXT("CAMSchedule::Advise() Next time stamp: %lu ms, for advise %lu."),
- DWORD(rtNextTime / (UNITS / MILLISECONDS)), pAdvise->m_dwAdviseCookie ));
-
- return rtNextTime;
-}
-
-/* Private methods */
-
-DWORD_PTR CAMSchedule::AddAdvisePacket( __inout CAdvisePacket * pPacket )
-{
- ASSERT(pPacket->m_rtEventTime >= 0 && pPacket->m_rtEventTime < MAX_TIME);
- ASSERT(CritCheckIn(&m_Serialize));
-
- CAdvisePacket * p_prev = &head;
- CAdvisePacket * p_n;
-
- const DWORD_PTR Result = pPacket->m_dwAdviseCookie = ++m_dwNextCookie;
- // This relies on the fact that z is a sentry with a maximal m_rtEventTime
- for(;;p_prev = p_n)
- {
- p_n = p_prev->m_next;
- if ( p_n->m_rtEventTime >= pPacket->m_rtEventTime ) break;
- }
- p_prev->InsertAfter( pPacket );
- ++m_dwAdviseCount;
-
- DbgLog((LOG_TIMING, 2, TEXT("Added advise %lu, for thread 0x%02X, scheduled at %lu"),
- pPacket->m_dwAdviseCookie, GetCurrentThreadId(), (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));
-
- // If packet added at the head, then clock needs to re-evaluate wait time.
- if ( p_prev == &head ) SetEvent( m_ev );
-
- return Result;
-}
-
-void CAMSchedule::Delete( __inout CAdvisePacket * pPacket )
-{
- if ( m_dwCacheCount >= dwCacheMax ) delete pPacket;
- else
- {
- m_Serialize.Lock();
- pPacket->m_next = m_pAdviseCache;
- m_pAdviseCache = pPacket;
- ++m_dwCacheCount;
- m_Serialize.Unlock();
- }
-}
-
-
-// Takes the head of the list & repositions it
-void CAMSchedule::ShuntHead()
-{
- CAdvisePacket * p_prev = &head;
- CAdvisePacket * p_n;
-
- m_Serialize.Lock();
- CAdvisePacket *const pPacket = head.m_next;
-
- // This will catch both an empty list,
- // and if somehow a MAX_TIME time gets into the list
- // (which would also break this method).
- ASSERT( pPacket->m_rtEventTime < MAX_TIME );
-
- // This relies on the fact that z is a sentry with a maximal m_rtEventTime
- for(;;p_prev = p_n)
- {
- p_n = p_prev->m_next;
- if ( p_n->m_rtEventTime > pPacket->m_rtEventTime ) break;
- }
- // If p_prev == pPacket then we're already in the right place
- if (p_prev != pPacket)
- {
- head.m_next = pPacket->m_next;
- (p_prev->m_next = pPacket)->m_next = p_n;
- }
- #ifdef DEBUG
- DbgLog((LOG_TIMING, 2, TEXT("Periodic advise %lu, shunted to %lu"),
- pPacket->m_dwAdviseCookie, (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));
- #endif
- m_Serialize.Unlock();
-}
-
-
-#ifdef DEBUG
-void CAMSchedule::DumpLinkedList()
-{
- m_Serialize.Lock();
- int i=0;
- DbgLog((LOG_TIMING, 1, TEXT("CAMSchedule::DumpLinkedList() this = 0x%p"), this));
- for ( CAdvisePacket * p = &head
- ; p
- ; p = p->m_next , i++
- )
- {
- DbgLog((LOG_TIMING, 1, TEXT("Advise List # %lu, Cookie %d, RefTime %lu"),
- i,
- p->m_dwAdviseCookie,
- p->m_rtEventTime / (UNITS / MILLISECONDS)
- ));
- }
- m_Serialize.Unlock();
-}
-#endif
diff --git a/third_party/BaseClasses/schedule.h b/third_party/BaseClasses/schedule.h
deleted file mode 100644
index c16700a2..00000000
--- a/third_party/BaseClasses/schedule.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Schedule.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __CAMSchedule__
-#define __CAMSchedule__
-
-class CAMSchedule : private CBaseObject
-{
-public:
- virtual ~CAMSchedule();
- // ev is the event we should fire if the advise time needs re-evaluating
- CAMSchedule( HANDLE ev );
-
- DWORD GetAdviseCount();
- REFERENCE_TIME GetNextAdviseTime();
-
- // We need a method for derived classes to add advise packets, we return the cookie
- DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
- // And a way to cancel
- HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
-
- // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
- // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
- // whoever is using this helper class (typically a clock).
- REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
-
- // Get the event handle which will be set if advise time requires re-evaluation.
- HANDLE GetEvent() const { return m_ev; }
-
-private:
- // We define the nodes that will be used in our singly linked list
- // of advise packets. The list is ordered by time, with the
- // elements that will expire first at the front.
- class CAdvisePacket
- {
- public:
- CAdvisePacket()
- {}
-
- CAdvisePacket * m_next;
- DWORD_PTR m_dwAdviseCookie;
- REFERENCE_TIME m_rtEventTime; // Time at which event should be set
- REFERENCE_TIME m_rtPeriod; // Periodic time
- HANDLE m_hNotify; // Handle to event or semephore
- BOOL m_bPeriodic; // TRUE => Periodic event
-
- CAdvisePacket( __inout_opt CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time)
- {}
-
- void InsertAfter( __inout CAdvisePacket * p )
- {
- p->m_next = m_next;
- m_next = p;
- }
-
- int IsZ() const // That is, is it the node that represents the end of the list
- { return m_next == 0; }
-
- CAdvisePacket * RemoveNext()
- {
- CAdvisePacket *const next = m_next;
- CAdvisePacket *const new_next = next->m_next;
- m_next = new_next;
- return next;
- }
-
- void DeleteNext()
- {
- delete RemoveNext();
- }
-
- CAdvisePacket * Next() const
- {
- CAdvisePacket * result = m_next;
- if (result->IsZ()) result = 0;
- return result;
- }
-
- DWORD_PTR Cookie() const
- { return m_dwAdviseCookie; }
- };
-
- // Structure is:
- // head -> elmt1 -> elmt2 -> z -> null
- // So an empty list is: head -> z -> null
- // Having head & z as links makes insertaion,
- // deletion and shunting much easier.
- CAdvisePacket head, z; // z is both a tail and a sentry
-
- volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
- volatile DWORD m_dwAdviseCount; // Number of elements on list
-
- CCritSec m_Serialize;
-
- // AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
- DWORD_PTR AddAdvisePacket( __inout CAdvisePacket * pPacket );
- // Event that we should set if the packed added above will be the next to fire.
- const HANDLE m_ev;
-
- // A Shunt is where we have changed the first element in the
- // list and want it re-evaluating (i.e. repositioned) in
- // the list.
- void ShuntHead();
-
- // Rather than delete advise packets, we cache them for future use
- CAdvisePacket * m_pAdviseCache;
- DWORD m_dwCacheCount;
- enum { dwCacheMax = 5 }; // Don't bother caching more than five
-
- void Delete( __inout CAdvisePacket * pLink );// This "Delete" will cache the Link
-
-// Attributes and methods for debugging
-public:
-#ifdef DEBUG
- void DumpLinkedList();
-#else
- void DumpLinkedList() {}
-#endif
-
-};
-
-#endif // __CAMSchedule__
diff --git a/third_party/BaseClasses/seekpt.cpp b/third_party/BaseClasses/seekpt.cpp
deleted file mode 100644
index bb13d6f0..00000000
--- a/third_party/BaseClasses/seekpt.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//------------------------------------------------------------------------------
-// File: SeekPT.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include "seekpt.h"
-
-//==================================================================
-// CreateInstance
-// This goes in the factory template table to create new instances
-// If there is already a mapper instance - return that, else make one
-// and save it in a static variable so that forever after we can return that.
-//==================================================================
-
-CUnknown * CSeekingPassThru::CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr)
-{
- return new CSeekingPassThru(NAME("Seeking PassThru"),pUnk, phr);
-}
-
-
-STDMETHODIMP CSeekingPassThru::NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv)
-{
- if (riid == IID_ISeekingPassThru) {
- return GetInterface((ISeekingPassThru *) this, ppv);
- } else {
- if (m_pPosPassThru &&
- (riid == IID_IMediaSeeking ||
- riid == IID_IMediaPosition)) {
- return m_pPosPassThru->NonDelegatingQueryInterface(riid,ppv);
- } else {
- return CUnknown::NonDelegatingQueryInterface(riid, ppv);
- }
- }
-}
-
-
-CSeekingPassThru::CSeekingPassThru( __in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr )
- : CUnknown(pName, pUnk, phr),
- m_pPosPassThru(NULL)
-{
-}
-
-
-CSeekingPassThru::~CSeekingPassThru()
-{
- delete m_pPosPassThru;
-}
-
-STDMETHODIMP CSeekingPassThru::Init(BOOL bRendererSeeking, IPin *pPin)
-{
- HRESULT hr = NOERROR;
- if (m_pPosPassThru) {
- hr = E_FAIL;
- } else {
- m_pPosPassThru =
- bRendererSeeking ?
- new CRendererPosPassThru(
- NAME("Render Seeking COM object"),
- (IUnknown *)this,
- &hr,
- pPin) :
- new CPosPassThru(
- NAME("Render Seeking COM object"),
- (IUnknown *)this,
- &hr,
- pPin);
- if (!m_pPosPassThru) {
- hr = E_OUTOFMEMORY;
- } else {
- if (FAILED(hr)) {
- delete m_pPosPassThru;
- m_pPosPassThru = NULL;
- }
- }
- }
- return hr;
-}
-
diff --git a/third_party/BaseClasses/source.cpp b/third_party/BaseClasses/source.cpp
deleted file mode 100644
index ef7795c4..00000000
--- a/third_party/BaseClasses/source.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Source.cpp
-//
-// Desc: DirectShow base classes - implements CSource, which is a Quartz
-// source filter 'template.'
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// Locking Strategy.
-//
-// Hold the filter critical section (m_pFilter->pStateLock()) to serialise
-// access to functions. Note that, in general, this lock may be held
-// by a function when the worker thread may want to hold it. Therefore
-// if you wish to access shared state from the worker thread you will
-// need to add another critical section object. The execption is during
-// the threads processing loop, when it is safe to get the filter critical
-// section from within FillBuffer().
-
-#include <streams.h>
-
-
-//
-// CSource::Constructor
-//
-// Initialise the pin count for the filter. The user will create the pins in
-// the derived class.
-CSource::CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
-}
-
-CSource::CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
- UNREFERENCED_PARAMETER(phr);
-}
-
-#ifdef UNICODE
-CSource::CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
-}
-
-CSource::CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
- UNREFERENCED_PARAMETER(phr);
-}
-#endif
-
-//
-// CSource::Destructor
-//
-CSource::~CSource()
-{
- /* Free our pins and pin array */
- while (m_iPins != 0) {
- // deleting the pins causes them to be removed from the array...
- delete m_paStreams[m_iPins - 1];
- }
-
- ASSERT(m_paStreams == NULL);
-}
-
-
-//
-// Add a new pin
-//
-HRESULT CSource::AddPin(__in CSourceStream *pStream)
-{
- CAutoLock lock(&m_cStateLock);
-
- /* Allocate space for this pin and the old ones */
- CSourceStream **paStreams = new CSourceStream *[m_iPins + 1];
- if (paStreams == NULL) {
- return E_OUTOFMEMORY;
- }
- if (m_paStreams != NULL) {
- CopyMemory((PVOID)paStreams, (PVOID)m_paStreams,
- m_iPins * sizeof(m_paStreams[0]));
- paStreams[m_iPins] = pStream;
- delete [] m_paStreams;
- }
- m_paStreams = paStreams;
- m_paStreams[m_iPins] = pStream;
- m_iPins++;
- return S_OK;
-}
-
-//
-// Remove a pin - pStream is NOT deleted
-//
-HRESULT CSource::RemovePin(__in CSourceStream *pStream)
-{
- int i;
- for (i = 0; i < m_iPins; i++) {
- if (m_paStreams[i] == pStream) {
- if (m_iPins == 1) {
- delete [] m_paStreams;
- m_paStreams = NULL;
- } else {
- /* no need to reallocate */
- while (++i < m_iPins)
- m_paStreams[i - 1] = m_paStreams[i];
- }
- m_iPins--;
- return S_OK;
- }
- }
- return S_FALSE;
-}
-
-//
-// FindPin
-//
-// Set *ppPin to the IPin* that has the id Id.
-// or to NULL if the Id cannot be matched.
-STDMETHODIMP CSource::FindPin(LPCWSTR Id, __deref_out IPin **ppPin)
-{
- CheckPointer(ppPin,E_POINTER);
- ValidateReadWritePtr(ppPin,sizeof(IPin *));
- // The -1 undoes the +1 in QueryId and ensures that totally invalid
- // strings (for which WstrToInt delivers 0) give a deliver a NULL pin.
- int i = WstrToInt(Id) -1;
- *ppPin = GetPin(i);
- if (*ppPin!=NULL){
- (*ppPin)->AddRef();
- return NOERROR;
- } else {
- return VFW_E_NOT_FOUND;
- }
-}
-
-//
-// FindPinNumber
-//
-// return the number of the pin with this IPin* or -1 if none
-int CSource::FindPinNumber(__in IPin *iPin) {
- int i;
- for (i=0; i<m_iPins; ++i) {
- if ((IPin *)(m_paStreams[i])==iPin) {
- return i;
- }
- }
- return -1;
-}
-
-//
-// GetPinCount
-//
-// Returns the number of pins this filter has
-int CSource::GetPinCount(void) {
-
- CAutoLock lock(&m_cStateLock);
- return m_iPins;
-}
-
-
-//
-// GetPin
-//
-// Return a non-addref'd pointer to pin n
-// needed by CBaseFilter
-CBasePin *CSource::GetPin(int n) {
-
- CAutoLock lock(&m_cStateLock);
-
- // n must be in the range 0..m_iPins-1
- // if m_iPins>n && n>=0 it follows that m_iPins>0
- // which is what used to be checked (i.e. checking that we have a pin)
- if ((n >= 0) && (n < m_iPins)) {
-
- ASSERT(m_paStreams[n]);
- return m_paStreams[n];
- }
- return NULL;
-}
-
-
-//
-
-
-// *
-// * --- CSourceStream ----
-// *
-
-//
-// Set Id to point to a CoTaskMemAlloc'd
-STDMETHODIMP CSourceStream::QueryId(__deref_out LPWSTR *Id) {
- CheckPointer(Id,E_POINTER);
- ValidateReadWritePtr(Id,sizeof(LPWSTR));
-
- // We give the pins id's which are 1,2,...
- // FindPinNumber returns -1 for an invalid pin
- int i = 1+ m_pFilter->FindPinNumber(this);
- if (i<1) return VFW_E_NOT_FOUND;
- *Id = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * 12);
- if (*Id==NULL) {
- return E_OUTOFMEMORY;
- }
- IntToWstr(i, *Id);
- return NOERROR;
-}
-
-
-
-//
-// CSourceStream::Constructor
-//
-// increments the number of pins present on the filter
-CSourceStream::CSourceStream(
- __in_opt LPCTSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *ps,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
- m_pFilter(ps) {
-
- *phr = m_pFilter->AddPin(this);
-}
-
-#ifdef UNICODE
-CSourceStream::CSourceStream(
- __in_opt LPCSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *ps,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
- m_pFilter(ps) {
-
- *phr = m_pFilter->AddPin(this);
-}
-#endif
-//
-// CSourceStream::Destructor
-//
-// Decrements the number of pins on this filter
-CSourceStream::~CSourceStream(void) {
-
- m_pFilter->RemovePin(this);
-}
-
-
-//
-// CheckMediaType
-//
-// Do we support this type? Provides the default support for 1 type.
-HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- CMediaType mt;
- GetMediaType(&mt);
-
- if (mt == *pMediaType) {
- return NOERROR;
- }
-
- return E_FAIL;
-}
-
-
-//
-// GetMediaType/3
-//
-// By default we support only one type
-// iPosition indexes are 0-n
-HRESULT CSourceStream::GetMediaType(int iPosition, __inout CMediaType *pMediaType) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- if (iPosition<0) {
- return E_INVALIDARG;
- }
- if (iPosition>0) {
- return VFW_S_NO_MORE_ITEMS;
- }
- return GetMediaType(pMediaType);
-}
-
-
-//
-// Active
-//
-// The pin is active - start up the worker thread
-HRESULT CSourceStream::Active(void) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- HRESULT hr;
-
- if (m_pFilter->IsActive()) {
- return S_FALSE; // succeeded, but did not allocate resources (they already exist...)
- }
-
- // do nothing if not connected - its ok not to connect to
- // all pins of a source filter
- if (!IsConnected()) {
- return NOERROR;
- }
-
- hr = CBaseOutputPin::Active();
- if (FAILED(hr)) {
- return hr;
- }
-
- ASSERT(!ThreadExists());
-
- // start the thread
- if (!Create()) {
- return E_FAIL;
- }
-
- // Tell thread to initialize. If OnThreadCreate Fails, so does this.
- hr = Init();
- if (FAILED(hr))
- return hr;
-
- return Pause();
-}
-
-
-//
-// Inactive
-//
-// Pin is inactive - shut down the worker thread
-// Waits for the worker to exit before returning.
-HRESULT CSourceStream::Inactive(void) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- HRESULT hr;
-
- // do nothing if not connected - its ok not to connect to
- // all pins of a source filter
- if (!IsConnected()) {
- return NOERROR;
- }
-
- // !!! need to do this before trying to stop the thread, because
- // we may be stuck waiting for our own allocator!!!
-
- hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
- if (FAILED(hr)) {
- return hr;
- }
-
- if (ThreadExists()) {
- hr = Stop();
-
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = Exit();
- if (FAILED(hr)) {
- return hr;
- }
-
- Close(); // Wait for the thread to exit, then tidy up.
- }
-
- // hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
- //if (FAILED(hr)) {
- // return hr;
- //}
-
- return NOERROR;
-}
-
-
-//
-// ThreadProc
-//
-// When this returns the thread exits
-// Return codes > 0 indicate an error occured
-DWORD CSourceStream::ThreadProc(void) {
-
- HRESULT hr; // the return code from calls
- Command com;
-
- do {
- com = GetRequest();
- if (com != CMD_INIT) {
- DbgLog((LOG_ERROR, 1, TEXT("Thread expected init command")));
- Reply((DWORD) E_UNEXPECTED);
- }
- } while (com != CMD_INIT);
-
- DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread initializing")));
-
- hr = OnThreadCreate(); // perform set up tasks
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread.")));
- OnThreadDestroy();
- Reply(hr); // send failed return code from OnThreadCreate
- return 1;
- }
-
- // Initialisation suceeded
- Reply(NOERROR);
-
- Command cmd;
- do {
- cmd = GetRequest();
-
- switch (cmd) {
-
- case CMD_EXIT:
- Reply(NOERROR);
- break;
-
- case CMD_RUN:
- DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???")));
- // !!! fall through???
-
- case CMD_PAUSE:
- Reply(NOERROR);
- DoBufferProcessingLoop();
- break;
-
- case CMD_STOP:
- Reply(NOERROR);
- break;
-
- default:
- DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd));
- Reply((DWORD) E_NOTIMPL);
- break;
- }
- } while (cmd != CMD_EXIT);
-
- hr = OnThreadDestroy(); // tidy up.
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadDestroy failed. Exiting thread.")));
- return 1;
- }
-
- DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread exiting")));
- return 0;
-}
-
-
-//
-// DoBufferProcessingLoop
-//
-// Grabs a buffer and calls the users processing function.
-// Overridable, so that different delivery styles can be catered for.
-HRESULT CSourceStream::DoBufferProcessingLoop(void) {
-
- Command com;
-
- OnThreadStartPlay();
-
- do {
- while (!CheckRequest(&com)) {
-
- IMediaSample *pSample;
-
- HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
- if (FAILED(hr)) {
- Sleep(1);
- continue; // go round again. Perhaps the error will go away
- // or the allocator is decommited & we will be asked to
- // exit soon.
- }
-
- // Virtual function user will override.
- hr = FillBuffer(pSample);
-
- if (hr == S_OK) {
- hr = Deliver(pSample);
- pSample->Release();
-
- // downstream filter returns S_FALSE if it wants us to
- // stop or an error if it's reporting an error.
- if(hr != S_OK)
- {
- DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
- return S_OK;
- }
-
- } else if (hr == S_FALSE) {
- // derived class wants us to stop pushing data
- pSample->Release();
- DeliverEndOfStream();
- return S_OK;
- } else {
- // derived class encountered an error
- pSample->Release();
- DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
- DeliverEndOfStream();
- m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
- return hr;
- }
-
- // all paths release the sample
- }
-
- // For all commands sent to us there must be a Reply call!
-
- if (com == CMD_RUN || com == CMD_PAUSE) {
- Reply(NOERROR);
- } else if (com != CMD_STOP) {
- Reply((DWORD) E_UNEXPECTED);
- DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
- }
- } while (com != CMD_STOP);
-
- return S_FALSE;
-}
-
diff --git a/third_party/BaseClasses/source.h b/third_party/BaseClasses/source.h
deleted file mode 100644
index 528d5bcb..00000000
--- a/third_party/BaseClasses/source.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Source.h
-//
-// Desc: DirectShow base classes - defines classes to simplify creation of
-// ActiveX source filters that support continuous generation of data.
-// No support is provided for IMediaControl or IMediaPosition.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-//
-// Derive your source filter from CSource.
-// During construction either:
-// Create some CSourceStream objects to manage your pins
-// Provide the user with a means of doing so eg, an IPersistFile interface.
-//
-// CSource provides:
-// IBaseFilter interface management
-// IMediaFilter interface management, via CBaseFilter
-// Pin counting for CBaseFilter
-//
-// Derive a class from CSourceStream to manage your output pin types
-// Implement GetMediaType/1 to return the type you support. If you support multiple
-// types then overide GetMediaType/3, CheckMediaType and GetMediaTypeCount.
-// Implement Fillbuffer() to put data into one buffer.
-//
-// CSourceStream provides:
-// IPin management via CBaseOutputPin
-// Worker thread management
-
-#ifndef __CSOURCE__
-#define __CSOURCE__
-
-class CSourceStream; // The class that will handle each pin
-
-
-//
-// CSource
-//
-// Override construction to provide a means of creating
-// CSourceStream derived objects - ie a way of creating pins.
-class CSource : public CBaseFilter {
-public:
-
- CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr);
- CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid);
-#ifdef UNICODE
- CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr);
- CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid);
-#endif
- ~CSource();
-
- int GetPinCount(void);
- CBasePin *GetPin(int n);
-
- // -- Utilities --
-
- CCritSec* pStateLock(void) { return &m_cStateLock; } // provide our critical section
-
- HRESULT AddPin(__in CSourceStream *);
- HRESULT RemovePin(__in CSourceStream *);
-
- STDMETHODIMP FindPin(
- LPCWSTR Id,
- __deref_out IPin ** ppPin
- );
-
- int FindPinNumber(__in IPin *iPin);
-
-protected:
-
- int m_iPins; // The number of pins on this filter. Updated by CSourceStream
- // constructors & destructors.
- CSourceStream **m_paStreams; // the pins on this filter.
-
- CCritSec m_cStateLock; // Lock this to serialize function accesses to the filter state
-
-};
-
-
-//
-// CSourceStream
-//
-// Use this class to manage a stream of data that comes from a
-// pin.
-// Uses a worker thread to put data on the pin.
-class CSourceStream : public CAMThread, public CBaseOutputPin {
-public:
-
- CSourceStream(__in_opt LPCTSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *pms,
- __in_opt LPCWSTR pName);
-#ifdef UNICODE
- CSourceStream(__in_opt LPCSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *pms,
- __in_opt LPCWSTR pName);
-#endif
- virtual ~CSourceStream(void); // virtual destructor ensures derived class destructors are called too.
-
-protected:
-
- CSource *m_pFilter; // The parent of this stream
-
- // *
- // * Data Source
- // *
- // * The following three functions: FillBuffer, OnThreadCreate/Destroy, are
- // * called from within the ThreadProc. They are used in the creation of
- // * the media samples this pin will provide
- // *
-
- // Override this to provide the worker thread a means
- // of processing a buffer
- virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;
-
- // Called as the thread is created/destroyed - use to perform
- // jobs such as start/stop streaming mode
- // If OnThreadCreate returns an error the thread will exit.
- virtual HRESULT OnThreadCreate(void) {return NOERROR;};
- virtual HRESULT OnThreadDestroy(void) {return NOERROR;};
- virtual HRESULT OnThreadStartPlay(void) {return NOERROR;};
-
- // *
- // * Worker Thread
- // *
-
- HRESULT Active(void); // Starts up the worker thread
- HRESULT Inactive(void); // Exits the worker thread.
-
-public:
- // thread commands
- enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT};
- HRESULT Init(void) { return CallWorker(CMD_INIT); }
- HRESULT Exit(void) { return CallWorker(CMD_EXIT); }
- HRESULT Run(void) { return CallWorker(CMD_RUN); }
- HRESULT Pause(void) { return CallWorker(CMD_PAUSE); }
- HRESULT Stop(void) { return CallWorker(CMD_STOP); }
-
-protected:
- Command GetRequest(void) { return (Command) CAMThread::GetRequest(); }
- BOOL CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); }
-
- // override these if you want to add thread commands
- virtual DWORD ThreadProc(void); // the thread function
-
- virtual HRESULT DoBufferProcessingLoop(void); // the loop executed whilst running
-
-
- // *
- // * AM_MEDIA_TYPE support
- // *
-
- // If you support more than one media type then override these 2 functions
- virtual HRESULT CheckMediaType(const CMediaType *pMediaType);
- virtual HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType); // List pos. 0-n
-
- // If you support only one type then override this fn.
- // This will only be called by the default implementations
- // of CheckMediaType and GetMediaType(int, CMediaType*)
- // You must override this fn. or the above 2!
- virtual HRESULT GetMediaType(__inout CMediaType *pMediaType) {return E_UNEXPECTED;}
-
- STDMETHODIMP QueryId(
- __deref_out LPWSTR * Id
- );
-};
-
-#endif // __CSOURCE__
-
diff --git a/third_party/BaseClasses/streams.h b/third_party/BaseClasses/streams.h
index 1926321d..63f33dfe 100644
--- a/third_party/BaseClasses/streams.h
+++ b/third_party/BaseClasses/streams.h
@@ -159,11 +159,11 @@ LONG_PTR _SetWindowLongPtr(HWND hwnd, int nIndex, T p)
//#include <amaudio.h> // ActiveMovie audio interfaces and definitions
#include <wxutil.h> // General helper classes for threads etc
#include <combase.h> // Base COM classes to support IUnknown
-#include <dllsetup.h> // Filter registration support functions
+//#include <dllsetup.h> // Filter registration support functions
#include <measure.h> // Performance measurement
-#include <comlite.h> // Light weight com function prototypes
+//#include <comlite.h> // Light weight com function prototypes
-#include <cache.h> // Simple cache container class
+//#include <cache.h> // Simple cache container class
#include <wxlist.h> // Non MFC generic list class
#include <msgthrd.h> // CMsgThread
#include <mtype.h> // Helper class for managing media types
@@ -172,26 +172,26 @@ LONG_PTR _SetWindowLongPtr(HWND hwnd, int nIndex, T p)
#include <ctlutil.h> // control interface utility classes
#include <evcode.h> // event code definitions
#include <amfilter.h> // Main streams architecture class hierachy
-#include <transfrm.h> // Generic transform filter
-#include <transip.h> // Generic transform-in-place filter
+//#include <transfrm.h> // Generic transform filter
+//#include <transip.h> // Generic transform-in-place filter
#include <uuids.h> // declaration of type GUIDs and well-known clsids
-#include <source.h> // Generic source filter
-#include <outputq.h> // Output pin queueing
+//#include <source.h> // Generic source filter
+//#include <outputq.h> // Output pin queueing
#include <errors.h> // HRESULT status and error definitions
#include <renbase.h> // Base class for writing ActiveX renderers
-#include <winutil.h> // Helps with filters that manage windows
-#include <winctrl.h> // Implements the IVideoWindow interface
-#include <videoctl.h> // Specifically video related classes
-#include <refclock.h> // Base clock class
-#include <sysclock.h> // System clock
-#include <pstream.h> // IPersistStream helper class
-#include <vtrans.h> // Video Transform Filter base class
-#include <amextra.h>
-#include <cprop.h> // Base property page class
-#include <strmctl.h> // IAMStreamControl support
-#include <edevdefs.h> // External device control interface defines
-#include <audevcod.h> // audio filter device error event codes
-
+//#include <winutil.h> // Helps with filters that manage windows
+//#include <winctrl.h> // Implements the IVideoWindow interface
+//#include <videoctl.h> // Specifically video related classes
+const LONGLONG MAX_TIME = 0x7FFFFFFFFFFFFFFF; /* Maximum LONGLONG value */
+//#include <refclock.h> // Base clock class
+//#include <sysclock.h> // System clock
+//#include <pstream.h> // IPersistStream helper class
+//#include <vtrans.h> // Video Transform Filter base class
+//#include <amextra.h>
+//#include <cprop.h> // Base property page class
+//#include <strmctl.h> // IAMStreamControl support
+//#include <edevdefs.h> // External device control interface defines
+//#include <audevcod.h> // audio filter device error event codes
#else
diff --git a/third_party/BaseClasses/strmctl.cpp b/third_party/BaseClasses/strmctl.cpp
deleted file mode 100644
index b7f59521..00000000
--- a/third_party/BaseClasses/strmctl.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-//------------------------------------------------------------------------------
-// File: StrmCtl.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <strmctl.h>
-
-CBaseStreamControl::CBaseStreamControl(__inout HRESULT *phr)
-: m_StreamState(STREAM_FLOWING)
-, m_StreamStateOnStop(STREAM_FLOWING) // means no pending stop
-, m_tStartTime(MAX_TIME)
-, m_tStopTime(MAX_TIME)
-, m_StreamEvent(FALSE, phr)
-, m_dwStartCookie(0)
-, m_dwStopCookie(0)
-, m_pRefClock(NULL)
-, m_FilterState(State_Stopped)
-, m_bIsFlushing(FALSE)
-, m_bStopSendExtra(FALSE)
-{}
-
-CBaseStreamControl::~CBaseStreamControl()
-{
- // Make sure we release the clock.
- SetSyncSource(NULL);
- return;
-}
-
-
-STDMETHODIMP CBaseStreamControl::StopAt(const REFERENCE_TIME * ptStop, BOOL bSendExtra, DWORD dwCookie)
-{
- CAutoLock lck(&m_CritSec);
- m_bStopSendExtra = FALSE; // reset
- m_bStopExtraSent = FALSE;
- if (ptStop)
- {
- if (*ptStop == MAX_TIME)
- {
- DbgLog((LOG_TRACE,2,TEXT("StopAt: Cancel stop")));
- CancelStop();
- // If there's now a command to start in the future, we assume
- // they want to be stopped when the graph is first run
- if (m_FilterState == State_Stopped && m_tStartTime < MAX_TIME) {
- m_StreamState = STREAM_DISCARDING;
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING")));
- }
- return NOERROR;
- }
- DbgLog((LOG_TRACE,2,TEXT("StopAt: %dms extra=%d"),
- (int)(*ptStop/10000), bSendExtra));
- // if the first command is to stop in the future, then we assume they
- // want to be started when the graph is first run
- if (m_FilterState == State_Stopped && m_tStartTime > *ptStop) {
- m_StreamState = STREAM_FLOWING;
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING")));
- }
- m_bStopSendExtra = bSendExtra;
- m_tStopTime = *ptStop;
- m_dwStopCookie = dwCookie;
- m_StreamStateOnStop = STREAM_DISCARDING;
- }
- else
- {
- DbgLog((LOG_TRACE,2,TEXT("StopAt: now")));
- // sending an extra frame when told to stop now would mess people up
- m_bStopSendExtra = FALSE;
- m_tStopTime = MAX_TIME;
- m_dwStopCookie = 0;
- m_StreamState = STREAM_DISCARDING;
- m_StreamStateOnStop = STREAM_FLOWING; // no pending stop
- }
- // we might change our mind what to do with a sample we're blocking
- m_StreamEvent.Set();
- return NOERROR;
-}
-
-STDMETHODIMP CBaseStreamControl::StartAt
-( const REFERENCE_TIME *ptStart, DWORD dwCookie )
-{
- CAutoLock lck(&m_CritSec);
- if (ptStart)
- {
- if (*ptStart == MAX_TIME)
- {
- DbgLog((LOG_TRACE,2,TEXT("StartAt: Cancel start")));
- CancelStart();
- // If there's now a command to stop in the future, we assume
- // they want to be started when the graph is first run
- if (m_FilterState == State_Stopped && m_tStopTime < MAX_TIME) {
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING")));
- m_StreamState = STREAM_FLOWING;
- }
- return NOERROR;
- }
- DbgLog((LOG_TRACE,2,TEXT("StartAt: %dms"), (int)(*ptStart/10000)));
- // if the first command is to start in the future, then we assume they
- // want to be stopped when the graph is first run
- if (m_FilterState == State_Stopped && m_tStopTime >= *ptStart) {
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING")));
- m_StreamState = STREAM_DISCARDING;
- }
- m_tStartTime = *ptStart;
- m_dwStartCookie = dwCookie;
- // if (m_tStopTime == m_tStartTime) CancelStop();
- }
- else
- {
- DbgLog((LOG_TRACE,2,TEXT("StartAt: now")));
- m_tStartTime = MAX_TIME;
- m_dwStartCookie = 0;
- m_StreamState = STREAM_FLOWING;
- }
- // we might change our mind what to do with a sample we're blocking
- m_StreamEvent.Set();
- return NOERROR;
-}
-
-// Retrieve information about current settings
-STDMETHODIMP CBaseStreamControl::GetInfo(__out AM_STREAM_INFO *pInfo)
-{
- if (pInfo == NULL)
- return E_POINTER;
-
- pInfo->tStart = m_tStartTime;
- pInfo->tStop = m_tStopTime;
- pInfo->dwStartCookie = m_dwStartCookie;
- pInfo->dwStopCookie = m_dwStopCookie;
- pInfo->dwFlags = m_bStopSendExtra ? AM_STREAM_INFO_STOP_SEND_EXTRA : 0;
- pInfo->dwFlags |= m_tStartTime == MAX_TIME ? 0 : AM_STREAM_INFO_START_DEFINED;
- pInfo->dwFlags |= m_tStopTime == MAX_TIME ? 0 : AM_STREAM_INFO_STOP_DEFINED;
- switch (m_StreamState) {
- default:
- DbgBreak("Invalid stream state");
- case STREAM_FLOWING:
- break;
- case STREAM_DISCARDING:
- pInfo->dwFlags |= AM_STREAM_INFO_DISCARDING;
- break;
- }
- return S_OK;
-}
-
-
-void CBaseStreamControl::ExecuteStop()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_StreamState = m_StreamStateOnStop;
- if (m_dwStopCookie && m_pSink) {
- DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STOPPED (%d)"),
- m_dwStopCookie));
- m_pSink->Notify(EC_STREAM_CONTROL_STOPPED, (LONG_PTR)this, m_dwStopCookie);
- }
- CancelStop(); // This will do the tidy up
-}
-
-void CBaseStreamControl::ExecuteStart()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_StreamState = STREAM_FLOWING;
- if (m_dwStartCookie) {
- DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STARTED (%d)"),
- m_dwStartCookie));
- m_pSink->Notify(EC_STREAM_CONTROL_STARTED, (LONG_PTR)this, m_dwStartCookie);
- }
- CancelStart(); // This will do the tidy up
-}
-
-void CBaseStreamControl::CancelStop()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_tStopTime = MAX_TIME;
- m_dwStopCookie = 0;
- m_StreamStateOnStop = STREAM_FLOWING;
-}
-
-void CBaseStreamControl::CancelStart()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_tStartTime = MAX_TIME;
- m_dwStartCookie = 0;
-}
-
-
-// This guy will return one of the three StreamControlState's. Here's what the caller
-// should do for each one:
-//
-// STREAM_FLOWING: Proceed as usual (render or pass the sample on)
-// STREAM_DISCARDING: Calculate the time 'til *pSampleStart and wait that long
-// for the event handle (GetStreamEventHandle()). If the
-// wait expires, throw the sample away. If the event
-// fires, call me back, I've changed my mind.
-// I use pSampleStart (not Stop) so that live sources don't
-// block for the duration of their samples, since the clock
-// will always read approximately pSampleStart when called
-
-
-// All through this code, you'll notice the following rules:
-// - When start and stop time are the same, it's as if start was first
-// - An event is considered inside the sample when it's >= sample start time
-// but < sample stop time
-// - if any part of the sample is supposed to be sent, we'll send the whole
-// thing since we don't break it into smaller pieces
-// - If we skip over a start or stop without doing it, we still signal the event
-// and reset ourselves in case somebody's waiting for the event, and to make
-// sure we notice that the event is past and should be forgotten
-// Here are the 19 cases that have to be handled (x=start o=stop <-->=sample):
-//
-// 1. xo<--> start then stop
-// 2. ox<--> stop then start
-// 3. x<o-> start
-// 4. o<x-> stop then start
-// 5. x<-->o start
-// 6. o<-->x stop
-// 7. <x->o start
-// 8. <o->x no change
-// 9. <xo> start
-// 10. <ox> stop then start
-// 11. <-->xo no change
-// 12. <-->ox no change
-// 13. x<--> start
-// 14. <x-> start
-// 15. <-->x no change
-// 16. o<--> stop
-// 17. <o-> no change
-// 18. <-->o no change
-// 19. <--> no change
-
-
-enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckSampleTimes
-( __in const REFERENCE_TIME * pSampleStart, __in const REFERENCE_TIME * pSampleStop )
-{
- CAutoLock lck(&m_CritSec);
-
- ASSERT(!m_bIsFlushing);
- ASSERT(pSampleStart && pSampleStop);
-
- // Don't ask me how I came up with the code below to handle all 19 cases
- // - DannyMi
-
- if (m_tStopTime >= *pSampleStart)
- {
- if (m_tStartTime >= *pSampleStop)
- return m_StreamState; // cases 8 11 12 15 17 18 19
- if (m_tStopTime < m_tStartTime)
- ExecuteStop(); // case 10
- ExecuteStart(); // cases 3 5 7 9 13 14
- return m_StreamState;
- }
-
- if (m_tStartTime >= *pSampleStop)
- {
- ExecuteStop(); // cases 6 16
- return m_StreamState;
- }
-
- if (m_tStartTime <= m_tStopTime)
- {
- ExecuteStart();
- ExecuteStop();
- return m_StreamState; // case 1
- }
- else
- {
- ExecuteStop();
- ExecuteStart();
- return m_StreamState; // cases 2 4
- }
-}
-
-
-enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckStreamState( IMediaSample * pSample )
-{
-
- REFERENCE_TIME rtBufferStart, rtBufferStop;
- const BOOL bNoBufferTimes =
- pSample == NULL ||
- FAILED(pSample->GetTime(&rtBufferStart, &rtBufferStop));
-
- StreamControlState state;
- LONG lWait;
-
- do
- {
- // something has to break out of the blocking
- if (m_bIsFlushing || m_FilterState == State_Stopped)
- return STREAM_DISCARDING;
-
- if (bNoBufferTimes) {
- // Can't do anything until we get a time stamp
- state = m_StreamState;
- break;
- } else {
- state = CheckSampleTimes( &rtBufferStart, &rtBufferStop );
- if (state == STREAM_FLOWING)
- break;
-
- // we aren't supposed to send this, but we've been
- // told to send one more than we were supposed to
- // (and the stop isn't still pending and we're streaming)
- if (m_bStopSendExtra && !m_bStopExtraSent &&
- m_tStopTime == MAX_TIME &&
- m_FilterState != State_Stopped) {
- m_bStopExtraSent = TRUE;
- DbgLog((LOG_TRACE,2,TEXT("%d sending an EXTRA frame"),
- m_dwStopCookie));
- state = STREAM_FLOWING;
- break;
- }
- }
-
- // We're in discarding mode
-
- // If we've no clock, discard as fast as we can
- if (!m_pRefClock) {
- break;
-
- // If we're paused, we can't discard in a timely manner because
- // there's no such thing as stream times. We must block until
- // we run or stop, or we'll end up throwing the whole stream away
- // as quickly as possible
- } else if (m_FilterState == State_Paused) {
- lWait = INFINITE;
-
- } else {
- // wait until it's time for the sample until we say "discard"
- // ("discard in a timely fashion")
- REFERENCE_TIME rtNow;
- EXECUTE_ASSERT(SUCCEEDED(m_pRefClock->GetTime(&rtNow)));
- rtNow -= m_tRunStart; // Into relative ref-time
- lWait = LONG((rtBufferStart - rtNow)/10000); // 100ns -> ms
- if (lWait < 10) break; // Not worth waiting - discard early
- }
-
- } while(WaitForSingleObject(GetStreamEventHandle(), lWait) != WAIT_TIMEOUT);
-
- return state;
-}
-
-
-void CBaseStreamControl::NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart )
-{
- CAutoLock lck(&m_CritSec);
-
- // or we will get confused
- if (m_FilterState == new_state)
- return;
-
- switch (new_state)
- {
- case State_Stopped:
-
- DbgLog((LOG_TRACE,2,TEXT("Filter is STOPPED")));
-
- // execute any pending starts and stops in the right order,
- // to make sure all notifications get sent, and we end up
- // in the right state to begin next time (??? why not?)
-
- if (m_tStartTime != MAX_TIME && m_tStopTime == MAX_TIME) {
- ExecuteStart();
- } else if (m_tStopTime != MAX_TIME && m_tStartTime == MAX_TIME) {
- ExecuteStop();
- } else if (m_tStopTime != MAX_TIME && m_tStartTime != MAX_TIME) {
- if (m_tStartTime <= m_tStopTime) {
- ExecuteStart();
- ExecuteStop();
- } else {
- ExecuteStop();
- ExecuteStart();
- }
- }
- // always start off flowing when the graph starts streaming
- // unless told otherwise
- m_StreamState = STREAM_FLOWING;
- m_FilterState = new_state;
- break;
-
- case State_Running:
-
- DbgLog((LOG_TRACE,2,TEXT("Filter is RUNNING")));
-
- m_tRunStart = tStart;
- // fall-through
-
- default: // case State_Paused:
- m_FilterState = new_state;
- }
- // unblock!
- m_StreamEvent.Set();
-}
-
-
-void CBaseStreamControl::Flushing(BOOL bInProgress)
-{
- CAutoLock lck(&m_CritSec);
- m_bIsFlushing = bInProgress;
- m_StreamEvent.Set();
-}
diff --git a/third_party/BaseClasses/strmctl.h b/third_party/BaseClasses/strmctl.h
deleted file mode 100644
index cb2adf30..00000000
--- a/third_party/BaseClasses/strmctl.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//------------------------------------------------------------------------------
-// File: StrmCtl.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __strmctl_h__
-#define __strmctl_h__
-
-class CBaseStreamControl : public IAMStreamControl
-{
-public:
- // Used by the implementation
- enum StreamControlState
- { STREAM_FLOWING = 0x1000,
- STREAM_DISCARDING
- };
-
-private:
- enum StreamControlState m_StreamState; // Current stream state
- enum StreamControlState m_StreamStateOnStop; // State after next stop
- // (i.e.Blocking or Discarding)
-
- REFERENCE_TIME m_tStartTime; // MAX_TIME implies none
- REFERENCE_TIME m_tStopTime; // MAX_TIME implies none
- DWORD m_dwStartCookie; // Cookie for notification to app
- DWORD m_dwStopCookie; // Cookie for notification to app
- volatile BOOL m_bIsFlushing; // No optimization pls!
- volatile BOOL m_bStopSendExtra; // bSendExtra was set
- volatile BOOL m_bStopExtraSent; // the extra one was sent
-
- CCritSec m_CritSec; // CritSec to guard above attributes
-
- // Event to fire when we can come
- // out of blocking, or to come out of waiting
- // to discard if we change our minds.
- //
- CAMEvent m_StreamEvent;
-
- // All of these methods execute immediately. Helpers for others.
- //
- void ExecuteStop();
- void ExecuteStart();
- void CancelStop();
- void CancelStart();
-
- // Some things we need to be told by our owning filter
- // Your pin must also expose IAMStreamControl when QI'd for it!
- //
- IReferenceClock * m_pRefClock; // Need it to set advises
- // Filter must tell us via
- // SetSyncSource
- IMediaEventSink * m_pSink; // Event sink
- // Filter must tell us after it
- // creates it in JoinFilterGraph()
- FILTER_STATE m_FilterState; // Just need it!
- // Filter must tell us via
- // NotifyFilterState
- REFERENCE_TIME m_tRunStart; // Per the Run call to the filter
-
- // This guy will return one of the three StreamControlState's. Here's what
- // the caller should do for each one:
- //
- // STREAM_FLOWING: Proceed as usual (render or pass the sample on)
- // STREAM_DISCARDING: Calculate the time 'til *pSampleStop and wait
- // that long for the event handle
- // (GetStreamEventHandle()). If the wait
- // expires, throw the sample away. If the event
- // fires, call me back - I've changed my mind.
- //
- enum StreamControlState CheckSampleTimes( __in const REFERENCE_TIME * pSampleStart,
- __in const REFERENCE_TIME * pSampleStop );
-
-public:
- // You don't have to tell us much when we're created, but there are other
- // obligations that must be met. See SetSyncSource & NotifyFilterState
- // below.
- //
- CBaseStreamControl(__inout_opt HRESULT *phr = NULL);
- ~CBaseStreamControl();
-
- // If you want this class to work properly, there are thing you need to
- // (keep) telling it. Filters with pins that use this class
- // should ensure that they pass through to this method any calls they
- // receive on their SetSyncSource.
-
- // We need a clock to see what time it is. This is for the
- // "discard in a timely fashion" logic. If we discard everything as
- // quick as possible, a whole 60 minute file could get discarded in the
- // first 10 seconds, and if somebody wants to turn streaming on at 30
- // minutes into the file, and they make the call more than a few seconds
- // after the graph is run, it may be too late!
- // So we hold every sample until it's time has gone, then we discard it.
- // The filter should call this when it gets a SetSyncSource
- //
- void SetSyncSource( IReferenceClock * pRefClock )
- {
- CAutoLock lck(&m_CritSec);
- if (m_pRefClock) m_pRefClock->Release();
- m_pRefClock = pRefClock;
- if (m_pRefClock) m_pRefClock->AddRef();
- }
-
- // Set event sink for notifications
- // The filter should call this in its JoinFilterGraph after it creates the
- // IMediaEventSink
- //
- void SetFilterGraph( IMediaEventSink *pSink ) {
- m_pSink = pSink;
- }
-
- // Since we schedule in stream time, we need the tStart and must track the
- // state of our owning filter.
- // The app should call this ever state change
- //
- void NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart = 0 );
-
- // Filter should call Flushing(TRUE) in BeginFlush,
- // and Flushing(FALSE) in EndFlush.
- //
- void Flushing( BOOL bInProgress );
-
-
- // The two main methods of IAMStreamControl
-
- // Class adds default values suitable for immediate
- // muting and unmuting of the stream.
-
- STDMETHODIMP StopAt( const REFERENCE_TIME * ptStop = NULL,
- BOOL bSendExtra = FALSE,
- DWORD dwCookie = 0 );
- STDMETHODIMP StartAt( const REFERENCE_TIME * ptStart = NULL,
- DWORD dwCookie = 0 );
- STDMETHODIMP GetInfo( __out AM_STREAM_INFO *pInfo);
-
- // Helper function for pin's receive method. Call this with
- // the sample and we'll tell you what to do with it. We'll do a
- // WaitForSingleObject within this call if one is required. This is
- // a "What should I do with this sample?" kind of call. We'll tell the
- // caller to either flow it or discard it.
- // If pSample is NULL we evaluate based on the current state
- // settings
- enum StreamControlState CheckStreamState( IMediaSample * pSample );
-
-private:
- // These don't require locking, but we are relying on the fact that
- // m_StreamState can be retrieved with integrity, and is a snap shot that
- // may have just been, or may be just about to be, changed.
- HANDLE GetStreamEventHandle() const { return m_StreamEvent; }
- enum StreamControlState GetStreamState() const { return m_StreamState; }
- BOOL IsStreaming() const { return m_StreamState == STREAM_FLOWING; }
-};
-
-#endif
diff --git a/third_party/BaseClasses/sysclock.cpp b/third_party/BaseClasses/sysclock.cpp
deleted file mode 100644
index 0d582917..00000000
--- a/third_party/BaseClasses/sysclock.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//------------------------------------------------------------------------------
-// File: SysClock.cpp
-//
-// Desc: DirectShow base classes - implements a system clock based on
-// IReferenceClock.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <limits.h>
-
-
-#ifdef FILTER_DLL
-
-/* List of class IDs and creator functions for the class factory. This
- provides the link between the OLE entry point in the DLL and an object
- being created. The class factory will call the static CreateInstance
- function when it is asked to create a CLSID_SystemClock object */
-
-CFactoryTemplate g_Templates[1] = {
- {&CLSID_SystemClock, CSystemClock::CreateInstance}
-};
-
-int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
-#endif
-
-/* This goes in the factory template table to create new instances */
-CUnknown * WINAPI CSystemClock::CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr)
-{
- return new CSystemClock(NAME("System reference clock"),pUnk, phr);
-}
-
-
-CSystemClock::CSystemClock(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr) :
- CBaseReferenceClock(pName, pUnk, phr)
-{
-}
-
-STDMETHODIMP CSystemClock::NonDelegatingQueryInterface(
- REFIID riid,
- __deref_out void ** ppv)
-{
- if (riid == IID_IPersist)
- {
- return GetInterface(static_cast<IPersist *>(this), ppv);
- }
- else if (riid == IID_IAMClockAdjust)
- {
- return GetInterface(static_cast<IAMClockAdjust *>(this), ppv);
- }
- else
- {
- return CBaseReferenceClock::NonDelegatingQueryInterface(riid, ppv);
- }
-}
-
-/* Return the clock's clsid */
-STDMETHODIMP
-CSystemClock::GetClassID(__out CLSID *pClsID)
-{
- CheckPointer(pClsID,E_POINTER);
- ValidateReadWritePtr(pClsID,sizeof(CLSID));
- *pClsID = CLSID_SystemClock;
- return NOERROR;
-}
-
-
-STDMETHODIMP
-CSystemClock::SetClockDelta(REFERENCE_TIME rtDelta)
-{
- return SetTimeDelta(rtDelta);
-}
diff --git a/third_party/BaseClasses/sysclock.h b/third_party/BaseClasses/sysclock.h
deleted file mode 100644
index 3976d346..00000000
--- a/third_party/BaseClasses/sysclock.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//------------------------------------------------------------------------------
-// File: SysClock.h
-//
-// Desc: DirectShow base classes - defines a system clock implementation of
-// IReferenceClock.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __SYSTEMCLOCK__
-#define __SYSTEMCLOCK__
-
-//
-// Base clock. Uses timeGetTime ONLY
-// Uses most of the code in the base reference clock.
-// Provides GetTime
-//
-
-class CSystemClock : public CBaseReferenceClock, public IAMClockAdjust, public IPersist
-{
-public:
- // We must be able to create an instance of ourselves
- static CUnknown * WINAPI CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
- CSystemClock(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
-
- DECLARE_IUNKNOWN
-
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
-
- // Yield up our class id so that we can be persisted
- // Implement required Ipersist method
- STDMETHODIMP GetClassID(__out CLSID *pClsID);
-
- // IAMClockAdjust methods
- STDMETHODIMP SetClockDelta(REFERENCE_TIME rtDelta);
-}; //CSystemClock
-
-#endif /* __SYSTEMCLOCK__ */
diff --git a/third_party/BaseClasses/transfrm.cpp b/third_party/BaseClasses/transfrm.cpp
deleted file mode 100644
index 3d170779..00000000
--- a/third_party/BaseClasses/transfrm.cpp
+++ /dev/null
@@ -1,1016 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Transfrm.cpp
-//
-// Desc: DirectShow base classes - implements class for simple transform
-// filters such as video decompressors.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <measure.h>
-
-
-// =================================================================
-// Implements the CTransformFilter class
-// =================================================================
-
-CTransformFilter::CTransformFilter(__in_opt LPCTSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- REFCLSID clsid) :
- CBaseFilter(pName,pUnk,&m_csFilter, clsid),
- m_pInput(NULL),
- m_pOutput(NULL),
- m_bEOSDelivered(FALSE),
- m_bQualityChanged(FALSE),
- m_bSampleSkipped(FALSE)
-{
-#ifdef PERF
- RegisterPerfId();
-#endif // PERF
-}
-
-#ifdef UNICODE
-CTransformFilter::CTransformFilter(__in_opt LPCSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- REFCLSID clsid) :
- CBaseFilter(pName,pUnk,&m_csFilter, clsid),
- m_pInput(NULL),
- m_pOutput(NULL),
- m_bEOSDelivered(FALSE),
- m_bQualityChanged(FALSE),
- m_bSampleSkipped(FALSE)
-{
-#ifdef PERF
- RegisterPerfId();
-#endif // PERF
-}
-#endif
-
-// destructor
-
-CTransformFilter::~CTransformFilter()
-{
- // Delete the pins
-
- delete m_pInput;
- delete m_pOutput;
-}
-
-
-// Transform place holder - should never be called
-HRESULT CTransformFilter::Transform(IMediaSample * pIn, IMediaSample *pOut)
-{
- UNREFERENCED_PARAMETER(pIn);
- UNREFERENCED_PARAMETER(pOut);
- DbgBreak("CTransformFilter::Transform() should never be called");
- return E_UNEXPECTED;
-}
-
-
-// return the number of pins we provide
-
-int CTransformFilter::GetPinCount()
-{
- return 2;
-}
-
-
-// return a non-addrefed CBasePin * for the user to addref if he holds onto it
-// for longer than his pointer to us. We create the pins dynamically when they
-// are asked for rather than in the constructor. This is because we want to
-// give the derived class an oppportunity to return different pin objects
-
-// We return the objects as and when they are needed. If either of these fails
-// then we return NULL, the assumption being that the caller will realise the
-// whole deal is off and destroy us - which in turn will delete everything.
-
-CBasePin *
-CTransformFilter::GetPin(int n)
-{
- HRESULT hr = S_OK;
-
- // Create an input pin if necessary
-
- if (m_pInput == NULL) {
-
- m_pInput = new CTransformInputPin(NAME("Transform input pin"),
- this, // Owner filter
- &hr, // Result code
- L"XForm In"); // Pin name
-
-
- // Can't fail
- ASSERT(SUCCEEDED(hr));
- if (m_pInput == NULL) {
- return NULL;
- }
- m_pOutput = (CTransformOutputPin *)
- new CTransformOutputPin(NAME("Transform output pin"),
- this, // Owner filter
- &hr, // Result code
- L"XForm Out"); // Pin name
-
-
- // Can't fail
- ASSERT(SUCCEEDED(hr));
- if (m_pOutput == NULL) {
- delete m_pInput;
- m_pInput = NULL;
- }
- }
-
- // Return the appropriate pin
-
- if (n == 0) {
- return m_pInput;
- } else
- if (n == 1) {
- return m_pOutput;
- } else {
- return NULL;
- }
-}
-
-
-//
-// FindPin
-//
-// If Id is In or Out then return the IPin* for that pin
-// creating the pin if need be. Otherwise return NULL with an error.
-
-STDMETHODIMP CTransformFilter::FindPin(LPCWSTR Id, __deref_out IPin **ppPin)
-{
- CheckPointer(ppPin,E_POINTER);
- ValidateReadWritePtr(ppPin,sizeof(IPin *));
-
- if (0==lstrcmpW(Id,L"In")) {
- *ppPin = GetPin(0);
- } else if (0==lstrcmpW(Id,L"Out")) {
- *ppPin = GetPin(1);
- } else {
- *ppPin = NULL;
- return VFW_E_NOT_FOUND;
- }
-
- HRESULT hr = NOERROR;
- // AddRef() returned pointer - but GetPin could fail if memory is low.
- if (*ppPin) {
- (*ppPin)->AddRef();
- } else {
- hr = E_OUTOFMEMORY; // probably. There's no pin anyway.
- }
- return hr;
-}
-
-
-// override these two functions if you want to inform something
-// about entry to or exit from streaming state.
-
-HRESULT
-CTransformFilter::StartStreaming()
-{
- return NOERROR;
-}
-
-
-HRESULT
-CTransformFilter::StopStreaming()
-{
- return NOERROR;
-}
-
-
-// override this to grab extra interfaces on connection
-
-HRESULT
-CTransformFilter::CheckConnect(PIN_DIRECTION dir, IPin *pPin)
-{
- UNREFERENCED_PARAMETER(dir);
- UNREFERENCED_PARAMETER(pPin);
- return NOERROR;
-}
-
-
-// place holder to allow derived classes to release any extra interfaces
-
-HRESULT
-CTransformFilter::BreakConnect(PIN_DIRECTION dir)
-{
- UNREFERENCED_PARAMETER(dir);
- return NOERROR;
-}
-
-
-// Let derived classes know about connection completion
-
-HRESULT
-CTransformFilter::CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin)
-{
- UNREFERENCED_PARAMETER(direction);
- UNREFERENCED_PARAMETER(pReceivePin);
- return NOERROR;
-}
-
-
-// override this to know when the media type is really set
-
-HRESULT
-CTransformFilter::SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt)
-{
- UNREFERENCED_PARAMETER(direction);
- UNREFERENCED_PARAMETER(pmt);
- return NOERROR;
-}
-
-
-// Set up our output sample
-HRESULT
-CTransformFilter::InitializeOutputSample(IMediaSample *pSample, __deref_out IMediaSample **ppOutSample)
-{
- IMediaSample *pOutSample;
-
- // default - times are the same
-
- AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
- DWORD dwFlags = m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0;
-
- // This will prevent the image renderer from switching us to DirectDraw
- // when we can't do it without skipping frames because we're not on a
- // keyframe. If it really has to switch us, it still will, but then we
- // will have to wait for the next keyframe
- if (!(pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT)) {
- dwFlags |= AM_GBF_NOTASYNCPOINT;
- }
-
- ASSERT(m_pOutput->m_pAllocator != NULL);
- HRESULT hr = m_pOutput->m_pAllocator->GetBuffer(
- &pOutSample
- , pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID ?
- &pProps->tStart : NULL
- , pProps->dwSampleFlags & AM_SAMPLE_STOPVALID ?
- &pProps->tStop : NULL
- , dwFlags
- );
- *ppOutSample = pOutSample;
- if (FAILED(hr)) {
- return hr;
- }
-
- ASSERT(pOutSample);
- IMediaSample2 *pOutSample2;
- if (SUCCEEDED(pOutSample->QueryInterface(IID_IMediaSample2,
- (void **)&pOutSample2))) {
- /* Modify it */
- AM_SAMPLE2_PROPERTIES OutProps;
- EXECUTE_ASSERT(SUCCEEDED(pOutSample2->GetProperties(
- FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&OutProps)
- ));
- OutProps.dwTypeSpecificFlags = pProps->dwTypeSpecificFlags;
- OutProps.dwSampleFlags =
- (OutProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED) |
- (pProps->dwSampleFlags & ~AM_SAMPLE_TYPECHANGED);
- OutProps.tStart = pProps->tStart;
- OutProps.tStop = pProps->tStop;
- OutProps.cbData = FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId);
- hr = pOutSample2->SetProperties(
- FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId),
- (PBYTE)&OutProps
- );
- if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) {
- m_bSampleSkipped = FALSE;
- }
- pOutSample2->Release();
- } else {
- if (pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) {
- pOutSample->SetTime(&pProps->tStart,
- &pProps->tStop);
- }
- if (pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT) {
- pOutSample->SetSyncPoint(TRUE);
- }
- if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) {
- pOutSample->SetDiscontinuity(TRUE);
- m_bSampleSkipped = FALSE;
- }
- // Copy the media times
-
- LONGLONG MediaStart, MediaEnd;
- if (pSample->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) {
- pOutSample->SetMediaTime(&MediaStart,&MediaEnd);
- }
- }
- return S_OK;
-}
-
-// override this to customize the transform process
-
-HRESULT
-CTransformFilter::Receive(IMediaSample *pSample)
-{
- /* Check for other streams and pass them on */
- AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
- if (pProps->dwStreamId != AM_STREAM_MEDIA) {
- return m_pOutput->m_pInputPin->Receive(pSample);
- }
- HRESULT hr;
- ASSERT(pSample);
- IMediaSample * pOutSample;
-
- // If no output to deliver to then no point sending us data
-
- ASSERT (m_pOutput != NULL) ;
-
- // Set up the output sample
- hr = InitializeOutputSample(pSample, &pOutSample);
-
- if (FAILED(hr)) {
- return hr;
- }
-
- // Start timing the transform (if PERF is defined)
- MSR_START(m_idTransform);
-
- // have the derived class transform the data
-
- hr = Transform(pSample, pOutSample);
-
- // Stop the clock and log it (if PERF is defined)
- MSR_STOP(m_idTransform);
-
- if (FAILED(hr)) {
- DbgLog((LOG_TRACE,1,TEXT("Error from transform")));
- } else {
- // the Transform() function can return S_FALSE to indicate that the
- // sample should not be delivered; we only deliver the sample if it's
- // really S_OK (same as NOERROR, of course.)
- if (hr == NOERROR) {
- hr = m_pOutput->m_pInputPin->Receive(pOutSample);
- m_bSampleSkipped = FALSE; // last thing no longer dropped
- } else {
- // S_FALSE returned from Transform is a PRIVATE agreement
- // We should return NOERROR from Receive() in this cause because returning S_FALSE
- // from Receive() means that this is the end of the stream and no more data should
- // be sent.
- if (S_FALSE == hr) {
-
- // Release the sample before calling notify to avoid
- // deadlocks if the sample holds a lock on the system
- // such as DirectDraw buffers do
- pOutSample->Release();
- m_bSampleSkipped = TRUE;
- if (!m_bQualityChanged) {
- NotifyEvent(EC_QUALITY_CHANGE,0,0);
- m_bQualityChanged = TRUE;
- }
- return NOERROR;
- }
- }
- }
-
- // release the output buffer. If the connected pin still needs it,
- // it will have addrefed it itself.
- pOutSample->Release();
-
- return hr;
-}
-
-
-// Return S_FALSE to mean "pass the note on upstream"
-// Return NOERROR (Same as S_OK)
-// to mean "I've done something about it, don't pass it on"
-HRESULT CTransformFilter::AlterQuality(Quality q)
-{
- UNREFERENCED_PARAMETER(q);
- return S_FALSE;
-}
-
-
-// EndOfStream received. Default behaviour is to deliver straight
-// downstream, since we have no queued data. If you overrode Receive
-// and have queue data, then you need to handle this and deliver EOS after
-// all queued data is sent
-HRESULT
-CTransformFilter::EndOfStream(void)
-{
- HRESULT hr = NOERROR;
- if (m_pOutput != NULL) {
- hr = m_pOutput->DeliverEndOfStream();
- }
-
- return hr;
-}
-
-
-// enter flush state. Receives already blocked
-// must override this if you have queued data or a worker thread
-HRESULT
-CTransformFilter::BeginFlush(void)
-{
- HRESULT hr = NOERROR;
- if (m_pOutput != NULL) {
- // block receives -- done by caller (CBaseInputPin::BeginFlush)
-
- // discard queued data -- we have no queued data
-
- // free anyone blocked on receive - not possible in this filter
-
- // call downstream
- hr = m_pOutput->DeliverBeginFlush();
- }
- return hr;
-}
-
-
-// leave flush state. must override this if you have queued data
-// or a worker thread
-HRESULT
-CTransformFilter::EndFlush(void)
-{
- // sync with pushing thread -- we have no worker thread
-
- // ensure no more data to go downstream -- we have no queued data
-
- // call EndFlush on downstream pins
- ASSERT (m_pOutput != NULL);
- return m_pOutput->DeliverEndFlush();
-
- // caller (the input pin's method) will unblock Receives
-}
-
-
-// override these so that the derived filter can catch them
-
-STDMETHODIMP
-CTransformFilter::Stop()
-{
- CAutoLock lck1(&m_csFilter);
- if (m_State == State_Stopped) {
- return NOERROR;
- }
-
- // Succeed the Stop if we are not completely connected
-
- ASSERT(m_pInput == NULL || m_pOutput != NULL);
- if (m_pInput == NULL || m_pInput->IsConnected() == FALSE ||
- m_pOutput->IsConnected() == FALSE) {
- m_State = State_Stopped;
- m_bEOSDelivered = FALSE;
- return NOERROR;
- }
-
- ASSERT(m_pInput);
- ASSERT(m_pOutput);
-
- // decommit the input pin before locking or we can deadlock
- m_pInput->Inactive();
-
- // synchronize with Receive calls
-
- CAutoLock lck2(&m_csReceive);
- m_pOutput->Inactive();
-
- // allow a class derived from CTransformFilter
- // to know about starting and stopping streaming
-
- HRESULT hr = StopStreaming();
- if (SUCCEEDED(hr)) {
- // complete the state transition
- m_State = State_Stopped;
- m_bEOSDelivered = FALSE;
- }
- return hr;
-}
-
-
-STDMETHODIMP
-CTransformFilter::Pause()
-{
- CAutoLock lck(&m_csFilter);
- HRESULT hr = NOERROR;
-
- if (m_State == State_Paused) {
- // (This space left deliberately blank)
- }
-
- // If we have no input pin or it isn't yet connected then when we are
- // asked to pause we deliver an end of stream to the downstream filter.
- // This makes sure that it doesn't sit there forever waiting for
- // samples which we cannot ever deliver without an input connection.
-
- else if (m_pInput == NULL || m_pInput->IsConnected() == FALSE) {
- if (m_pOutput && m_bEOSDelivered == FALSE) {
- m_pOutput->DeliverEndOfStream();
- m_bEOSDelivered = TRUE;
- }
- m_State = State_Paused;
- }
-
- // We may have an input connection but no output connection
- // However, if we have an input pin we do have an output pin
-
- else if (m_pOutput->IsConnected() == FALSE) {
- m_State = State_Paused;
- }
-
- else {
- if (m_State == State_Stopped) {
- // allow a class derived from CTransformFilter
- // to know about starting and stopping streaming
- CAutoLock lck2(&m_csReceive);
- hr = StartStreaming();
- }
- if (SUCCEEDED(hr)) {
- hr = CBaseFilter::Pause();
- }
- }
-
- m_bSampleSkipped = FALSE;
- m_bQualityChanged = FALSE;
- return hr;
-}
-
-HRESULT
-CTransformFilter::NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- if (m_pOutput != NULL) {
- return m_pOutput->DeliverNewSegment(tStart, tStop, dRate);
- }
- return S_OK;
-}
-
-// Check streaming status
-HRESULT
-CTransformInputPin::CheckStreaming()
-{
- ASSERT(m_pTransformFilter->m_pOutput != NULL);
- if (!m_pTransformFilter->m_pOutput->IsConnected()) {
- return VFW_E_NOT_CONNECTED;
- } else {
- // Shouldn't be able to get any data if we're not connected!
- ASSERT(IsConnected());
-
- // we're flushing
- if (m_bFlushing) {
- return S_FALSE;
- }
- // Don't process stuff in Stopped state
- if (IsStopped()) {
- return VFW_E_WRONG_STATE;
- }
- if (m_bRunTimeError) {
- return VFW_E_RUNTIME_ERROR;
- }
- return S_OK;
- }
-}
-
-
-// =================================================================
-// Implements the CTransformInputPin class
-// =================================================================
-
-
-// constructor
-
-CTransformInputPin::CTransformInputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName)
- : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName)
-{
- DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin")));
- m_pTransformFilter = pTransformFilter;
-}
-
-#ifdef UNICODE
-CTransformInputPin::CTransformInputPin(
- __in_opt LPCSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName)
- : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName)
-{
- DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin")));
- m_pTransformFilter = pTransformFilter;
-}
-#endif
-
-// provides derived filter a chance to grab extra interfaces
-
-HRESULT
-CTransformInputPin::CheckConnect(IPin *pPin)
-{
- HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_INPUT,pPin);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseInputPin::CheckConnect(pPin);
-}
-
-
-// provides derived filter a chance to release it's extra interfaces
-
-HRESULT
-CTransformInputPin::BreakConnect()
-{
- // Can't disconnect unless stopped
- ASSERT(IsStopped());
- m_pTransformFilter->BreakConnect(PINDIR_INPUT);
- return CBaseInputPin::BreakConnect();
-}
-
-
-// Let derived class know when the input pin is connected
-
-HRESULT
-CTransformInputPin::CompleteConnect(IPin *pReceivePin)
-{
- HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseInputPin::CompleteConnect(pReceivePin);
-}
-
-
-// check that we can support a given media type
-
-HRESULT
-CTransformInputPin::CheckMediaType(const CMediaType* pmt)
-{
- // Check the input type
-
- HRESULT hr = m_pTransformFilter->CheckInputType(pmt);
- if (S_OK != hr) {
- return hr;
- }
-
- // if the output pin is still connected, then we have
- // to check the transform not just the input format
-
- if ((m_pTransformFilter->m_pOutput != NULL) &&
- (m_pTransformFilter->m_pOutput->IsConnected())) {
- return m_pTransformFilter->CheckTransform(
- pmt,
- &m_pTransformFilter->m_pOutput->CurrentMediaType());
- } else {
- return hr;
- }
-}
-
-
-// set the media type for this connection
-
-HRESULT
-CTransformInputPin::SetMediaType(const CMediaType* mtIn)
-{
- // Set the base class media type (should always succeed)
- HRESULT hr = CBasePin::SetMediaType(mtIn);
- if (FAILED(hr)) {
- return hr;
- }
-
- // check the transform can be done (should always succeed)
- ASSERT(SUCCEEDED(m_pTransformFilter->CheckInputType(mtIn)));
-
- return m_pTransformFilter->SetMediaType(PINDIR_INPUT,mtIn);
-}
-
-
-// =================================================================
-// Implements IMemInputPin interface
-// =================================================================
-
-
-// provide EndOfStream that passes straight downstream
-// (there is no queued data)
-STDMETHODIMP
-CTransformInputPin::EndOfStream(void)
-{
- CAutoLock lck(&m_pTransformFilter->m_csReceive);
- HRESULT hr = CheckStreaming();
- if (S_OK == hr) {
- hr = m_pTransformFilter->EndOfStream();
- }
- return hr;
-}
-
-
-// enter flushing state. Call default handler to block Receives, then
-// pass to overridable method in filter
-STDMETHODIMP
-CTransformInputPin::BeginFlush(void)
-{
- CAutoLock lck(&m_pTransformFilter->m_csFilter);
- // Are we actually doing anything?
- ASSERT(m_pTransformFilter->m_pOutput != NULL);
- if (!IsConnected() ||
- !m_pTransformFilter->m_pOutput->IsConnected()) {
- return VFW_E_NOT_CONNECTED;
- }
- HRESULT hr = CBaseInputPin::BeginFlush();
- if (FAILED(hr)) {
- return hr;
- }
-
- return m_pTransformFilter->BeginFlush();
-}
-
-
-// leave flushing state.
-// Pass to overridable method in filter, then call base class
-// to unblock receives (finally)
-STDMETHODIMP
-CTransformInputPin::EndFlush(void)
-{
- CAutoLock lck(&m_pTransformFilter->m_csFilter);
- // Are we actually doing anything?
- ASSERT(m_pTransformFilter->m_pOutput != NULL);
- if (!IsConnected() ||
- !m_pTransformFilter->m_pOutput->IsConnected()) {
- return VFW_E_NOT_CONNECTED;
- }
-
- HRESULT hr = m_pTransformFilter->EndFlush();
- if (FAILED(hr)) {
- return hr;
- }
-
- return CBaseInputPin::EndFlush();
-}
-
-
-// here's the next block of data from the stream.
-// AddRef it yourself if you need to hold it beyond the end
-// of this call.
-
-HRESULT
-CTransformInputPin::Receive(IMediaSample * pSample)
-{
- HRESULT hr;
- CAutoLock lck(&m_pTransformFilter->m_csReceive);
- ASSERT(pSample);
-
- // check all is well with the base class
- hr = CBaseInputPin::Receive(pSample);
- if (S_OK == hr) {
- hr = m_pTransformFilter->Receive(pSample);
- }
- return hr;
-}
-
-
-
-
-// override to pass downstream
-STDMETHODIMP
-CTransformInputPin::NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- // Save the values in the pin
- CBasePin::NewSegment(tStart, tStop, dRate);
- return m_pTransformFilter->NewSegment(tStart, tStop, dRate);
-}
-
-
-
-
-// =================================================================
-// Implements the CTransformOutputPin class
-// =================================================================
-
-
-// constructor
-
-CTransformOutputPin::CTransformOutputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName),
- m_pPosition(NULL)
-{
- DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin")));
- m_pTransformFilter = pTransformFilter;
-
-}
-
-#ifdef UNICODE
-CTransformOutputPin::CTransformOutputPin(
- __in_opt LPCSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName),
- m_pPosition(NULL)
-{
- DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin")));
- m_pTransformFilter = pTransformFilter;
-
-}
-#endif
-
-// destructor
-
-CTransformOutputPin::~CTransformOutputPin()
-{
- DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::~CTransformOutputPin")));
-
- if (m_pPosition) m_pPosition->Release();
-}
-
-
-// overriden to expose IMediaPosition and IMediaSeeking control interfaces
-
-STDMETHODIMP
-CTransformOutputPin::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
-{
- CheckPointer(ppv,E_POINTER);
- ValidateReadWritePtr(ppv,sizeof(PVOID));
- *ppv = NULL;
-
- if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {
-
- // we should have an input pin by now
-
- ASSERT(m_pTransformFilter->m_pInput != NULL);
-
- if (m_pPosition == NULL) {
-
- HRESULT hr = CreatePosPassThru(
- GetOwner(),
- FALSE,
- (IPin *)m_pTransformFilter->m_pInput,
- &m_pPosition);
- if (FAILED(hr)) {
- return hr;
- }
- }
- return m_pPosition->QueryInterface(riid, ppv);
- } else {
- return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
- }
-}
-
-
-// provides derived filter a chance to grab extra interfaces
-
-HRESULT
-CTransformOutputPin::CheckConnect(IPin *pPin)
-{
- // we should have an input connection first
-
- ASSERT(m_pTransformFilter->m_pInput != NULL);
- if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) {
- return E_UNEXPECTED;
- }
-
- HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_OUTPUT,pPin);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseOutputPin::CheckConnect(pPin);
-}
-
-
-// provides derived filter a chance to release it's extra interfaces
-
-HRESULT
-CTransformOutputPin::BreakConnect()
-{
- // Can't disconnect unless stopped
- ASSERT(IsStopped());
- m_pTransformFilter->BreakConnect(PINDIR_OUTPUT);
- return CBaseOutputPin::BreakConnect();
-}
-
-
-// Let derived class know when the output pin is connected
-
-HRESULT
-CTransformOutputPin::CompleteConnect(IPin *pReceivePin)
-{
- HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseOutputPin::CompleteConnect(pReceivePin);
-}
-
-
-// check a given transform - must have selected input type first
-
-HRESULT
-CTransformOutputPin::CheckMediaType(const CMediaType* pmtOut)
-{
- // must have selected input first
- ASSERT(m_pTransformFilter->m_pInput != NULL);
- if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) {
- return E_INVALIDARG;
- }
-
- return m_pTransformFilter->CheckTransform(
- &m_pTransformFilter->m_pInput->CurrentMediaType(),
- pmtOut);
-}
-
-
-// called after we have agreed a media type to actually set it in which case
-// we run the CheckTransform function to get the output format type again
-
-HRESULT
-CTransformOutputPin::SetMediaType(const CMediaType* pmtOut)
-{
- HRESULT hr = NOERROR;
- ASSERT(m_pTransformFilter->m_pInput != NULL);
-
- ASSERT(m_pTransformFilter->m_pInput->CurrentMediaType().IsValid());
-
- // Set the base class media type (should always succeed)
- hr = CBasePin::SetMediaType(pmtOut);
- if (FAILED(hr)) {
- return hr;
- }
-
-#ifdef DEBUG
- if (FAILED(m_pTransformFilter->CheckTransform(&m_pTransformFilter->
- m_pInput->CurrentMediaType(),pmtOut))) {
- DbgLog((LOG_ERROR,0,TEXT("*** This filter is accepting an output media type")));
- DbgLog((LOG_ERROR,0,TEXT(" that it can't currently transform to. I hope")));
- DbgLog((LOG_ERROR,0,TEXT(" it's smart enough to reconnect its input.")));
- }
-#endif
-
- return m_pTransformFilter->SetMediaType(PINDIR_OUTPUT,pmtOut);
-}
-
-
-// pass the buffer size decision through to the main transform class
-
-HRESULT
-CTransformOutputPin::DecideBufferSize(
- IMemAllocator * pAllocator,
- __inout ALLOCATOR_PROPERTIES* pProp)
-{
- return m_pTransformFilter->DecideBufferSize(pAllocator, pProp);
-}
-
-
-
-// return a specific media type indexed by iPosition
-
-HRESULT
-CTransformOutputPin::GetMediaType(
- int iPosition,
- __inout CMediaType *pMediaType)
-{
- ASSERT(m_pTransformFilter->m_pInput != NULL);
-
- // We don't have any media types if our input is not connected
-
- if (m_pTransformFilter->m_pInput->IsConnected()) {
- return m_pTransformFilter->GetMediaType(iPosition,pMediaType);
- } else {
- return VFW_S_NO_MORE_ITEMS;
- }
-}
-
-
-// Override this if you can do something constructive to act on the
-// quality message. Consider passing it upstream as well
-
-// Pass the quality mesage on upstream.
-
-STDMETHODIMP
-CTransformOutputPin::Notify(IBaseFilter * pSender, Quality q)
-{
- UNREFERENCED_PARAMETER(pSender);
- ValidateReadPtr(pSender,sizeof(IBaseFilter));
-
- // First see if we want to handle this ourselves
- HRESULT hr = m_pTransformFilter->AlterQuality(q);
- if (hr!=S_FALSE) {
- return hr; // either S_OK or a failure
- }
-
- // S_FALSE means we pass the message on.
- // Find the quality sink for our input pin and send it there
-
- ASSERT(m_pTransformFilter->m_pInput != NULL);
-
- return m_pTransformFilter->m_pInput->PassNotify(q);
-
-} // Notify
-
-
-// the following removes a very large number of level 4 warnings from the microsoft
-// compiler output, which are not useful at all in this case.
-#pragma warning(disable:4514)
diff --git a/third_party/BaseClasses/transfrm.h b/third_party/BaseClasses/transfrm.h
deleted file mode 100644
index 9b276471..00000000
--- a/third_party/BaseClasses/transfrm.h
+++ /dev/null
@@ -1,304 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Transfrm.h
-//
-// Desc: DirectShow base classes - defines classes from which simple
-// transform codecs may be derived.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// It assumes the codec has one input and one output stream, and has no
-// interest in memory management, interface negotiation or anything else.
-//
-// derive your class from this, and supply Transform and the media type/format
-// negotiation functions. Implement that class, compile and link and
-// you're done.
-
-
-#ifndef __TRANSFRM__
-#define __TRANSFRM__
-
-// ======================================================================
-// This is the com object that represents a simple transform filter. It
-// supports IBaseFilter, IMediaFilter and two pins through nested interfaces
-// ======================================================================
-
-class CTransformFilter;
-
-// ==================================================
-// Implements the input pin
-// ==================================================
-
-class CTransformInputPin : public CBaseInputPin
-{
- friend class CTransformFilter;
-
-protected:
- CTransformFilter *m_pTransformFilter;
-
-
-public:
-
- CTransformInputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName);
-#ifdef UNICODE
- CTransformInputPin(
- __in_opt LPCSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName);
-#endif
-
- STDMETHODIMP QueryId(__deref_out LPWSTR * Id)
- {
- return AMGetWideString(L"In", Id);
- }
-
- // Grab and release extra interfaces if required
-
- HRESULT CheckConnect(IPin *pPin);
- HRESULT BreakConnect();
- HRESULT CompleteConnect(IPin *pReceivePin);
-
- // check that we can support this output type
- HRESULT CheckMediaType(const CMediaType* mtIn);
-
- // set the connection media type
- HRESULT SetMediaType(const CMediaType* mt);
-
- // --- IMemInputPin -----
-
- // here's the next block of data from the stream.
- // AddRef it yourself if you need to hold it beyond the end
- // of this call.
- STDMETHODIMP Receive(IMediaSample * pSample);
-
- // provide EndOfStream that passes straight downstream
- // (there is no queued data)
- STDMETHODIMP EndOfStream(void);
-
- // passes it to CTransformFilter::BeginFlush
- STDMETHODIMP BeginFlush(void);
-
- // passes it to CTransformFilter::EndFlush
- STDMETHODIMP EndFlush(void);
-
- STDMETHODIMP NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate);
-
- // Check if it's OK to process samples
- virtual HRESULT CheckStreaming();
-
- // Media type
-public:
- CMediaType& CurrentMediaType() { return m_mt; };
-
-};
-
-// ==================================================
-// Implements the output pin
-// ==================================================
-
-class CTransformOutputPin : public CBaseOutputPin
-{
- friend class CTransformFilter;
-
-protected:
- CTransformFilter *m_pTransformFilter;
-
-public:
-
- // implement IMediaPosition by passing upstream
- IUnknown * m_pPosition;
-
- CTransformOutputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName);
-#ifdef UNICODE
- CTransformOutputPin(
- __in_opt LPCSTR pObjectName,
- __inout CTransformFilter *pTransformFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pName);
-#endif
- ~CTransformOutputPin();
-
- // override to expose IMediaPosition
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
-
- // --- CBaseOutputPin ------------
-
- STDMETHODIMP QueryId(__deref_out LPWSTR * Id)
- {
- return AMGetWideString(L"Out", Id);
- }
-
- // Grab and release extra interfaces if required
-
- HRESULT CheckConnect(IPin *pPin);
- HRESULT BreakConnect();
- HRESULT CompleteConnect(IPin *pReceivePin);
-
- // check that we can support this output type
- HRESULT CheckMediaType(const CMediaType* mtOut);
-
- // set the connection media type
- HRESULT SetMediaType(const CMediaType *pmt);
-
- // called from CBaseOutputPin during connection to ask for
- // the count and size of buffers we need.
- HRESULT DecideBufferSize(
- IMemAllocator * pAlloc,
- __inout ALLOCATOR_PROPERTIES *pProp);
-
- // returns the preferred formats for a pin
- HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType);
-
- // inherited from IQualityControl via CBasePin
- STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
-
- // Media type
-public:
- CMediaType& CurrentMediaType() { return m_mt; };
-};
-
-
-class AM_NOVTABLE CTransformFilter : public CBaseFilter
-{
-
-public:
-
- // map getpin/getpincount for base enum of pins to owner
- // override this to return more specialised pin objects
-
- virtual int GetPinCount();
- virtual CBasePin * GetPin(int n);
- STDMETHODIMP FindPin(LPCWSTR Id, __deref_out IPin **ppPin);
-
- // override state changes to allow derived transform filter
- // to control streaming start/stop
- STDMETHODIMP Stop();
- STDMETHODIMP Pause();
-
-public:
-
- CTransformFilter(__in_opt LPCTSTR , __inout_opt LPUNKNOWN, REFCLSID clsid);
-#ifdef UNICODE
- CTransformFilter(__in_opt LPCSTR , __inout_opt LPUNKNOWN, REFCLSID clsid);
-#endif
- ~CTransformFilter();
-
- // =================================================================
- // ----- override these bits ---------------------------------------
- // =================================================================
-
- // These must be supplied in a derived class
-
- virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut);
-
- // check if you can support mtIn
- virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE;
-
- // check if you can support the transform from this input to this output
- virtual HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut) PURE;
-
- // this goes in the factory template table to create new instances
- // static CCOMObject * CreateInstance(__inout_opt LPUNKNOWN, HRESULT *);
-
- // call the SetProperties function with appropriate arguments
- virtual HRESULT DecideBufferSize(
- IMemAllocator * pAllocator,
- __inout ALLOCATOR_PROPERTIES *pprop) PURE;
-
- // override to suggest OUTPUT pin media types
- virtual HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType) PURE;
-
-
-
- // =================================================================
- // ----- Optional Override Methods -----------------------
- // =================================================================
-
- // you can also override these if you want to know about streaming
- virtual HRESULT StartStreaming();
- virtual HRESULT StopStreaming();
-
- // override if you can do anything constructive with quality notifications
- virtual HRESULT AlterQuality(Quality q);
-
- // override this to know when the media type is actually set
- virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt);
-
- // chance to grab extra interfaces on connection
- virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin);
- virtual HRESULT BreakConnect(PIN_DIRECTION dir);
- virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin);
-
- // chance to customize the transform process
- virtual HRESULT Receive(IMediaSample *pSample);
-
- // Standard setup for output sample
- HRESULT InitializeOutputSample(IMediaSample *pSample, __deref_out IMediaSample **ppOutSample);
-
- // if you override Receive, you may need to override these three too
- virtual HRESULT EndOfStream(void);
- virtual HRESULT BeginFlush(void);
- virtual HRESULT EndFlush(void);
- virtual HRESULT NewSegment(
- REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate);
-
-#ifdef PERF
- // Override to register performance measurement with a less generic string
- // You should do this to avoid confusion with other filters
- virtual void RegisterPerfId()
- {m_idTransform = MSR_REGISTER(TEXT("Transform"));}
-#endif // PERF
-
-
-// implementation details
-
-protected:
-
-#ifdef PERF
- int m_idTransform; // performance measuring id
-#endif
- BOOL m_bEOSDelivered; // have we sent EndOfStream
- BOOL m_bSampleSkipped; // Did we just skip a frame
- BOOL m_bQualityChanged; // Have we degraded?
-
- // critical section protecting filter state.
-
- CCritSec m_csFilter;
-
- // critical section stopping state changes (ie Stop) while we're
- // processing a sample.
- //
- // This critical section is held when processing
- // events that occur on the receive thread - Receive() and EndOfStream().
- //
- // If you want to hold both m_csReceive and m_csFilter then grab
- // m_csFilter FIRST - like CTransformFilter::Stop() does.
-
- CCritSec m_csReceive;
-
- // these hold our input and output pins
-
- friend class CTransformInputPin;
- friend class CTransformOutputPin;
- CTransformInputPin *m_pInput;
- CTransformOutputPin *m_pOutput;
-};
-
-#endif /* __TRANSFRM__ */
-
-
diff --git a/third_party/BaseClasses/transip.cpp b/third_party/BaseClasses/transip.cpp
deleted file mode 100644
index e8e12eb5..00000000
--- a/third_party/BaseClasses/transip.cpp
+++ /dev/null
@@ -1,974 +0,0 @@
-//------------------------------------------------------------------------------
-// File: TransIP.cpp
-//
-// Desc: DirectShow base classes - implements class for simple Transform-
-// In-Place filters such as audio.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// How allocators are decided.
-//
-// An in-place transform tries to do its work in someone else's buffers.
-// It tries to persuade the filters on either side to use the same allocator
-// (and for that matter the same media type). In desperation, if the downstream
-// filter refuses to supply an allocator and the upstream filter offers only
-// a read-only one then it will provide an allocator.
-// if the upstream filter insists on a read-only allocator then the transform
-// filter will (reluctantly) copy the data before transforming it.
-//
-// In order to pass an allocator through it needs to remember the one it got
-// from the first connection to pass it on to the second one.
-//
-// It is good if we can avoid insisting on a particular order of connection
-// (There is a precedent for insisting on the input
-// being connected first. Insisting on the output being connected first is
-// not allowed. That would break RenderFile.)
-//
-// The base pin classes (CBaseOutputPin and CBaseInputPin) both have a
-// m_pAllocator member which is used in places like
-// CBaseOutputPin::GetDeliveryBuffer and CBaseInputPin::Inactive.
-// To avoid lots of extra overriding, we should keep these happy
-// by using these pointers.
-//
-// When each pin is connected, it will set the corresponding m_pAllocator
-// and will have a single ref-count on that allocator.
-//
-// Refcounts are acquired by GetAllocator calls which return AddReffed
-// allocators and are released in one of:
-// CBaseInputPin::Disconnect
-// CBaseOutputPin::BreakConect
-// In each case m_pAllocator is set to NULL after the release, so this
-// is the last chance to ever release it. If there should ever be
-// multiple refcounts associated with the same pointer, this had better
-// be cleared up before that happens. To avoid such problems, we'll
-// stick with one per pointer.
-
-
-
-// RECONNECTING and STATE CHANGES
-//
-// Each pin could be disconnected, connected with a read-only allocator,
-// connected with an upstream read/write allocator, connected with an
-// allocator from downstream or connected with its own allocator.
-// Five states for each pin gives a data space of 25 states.
-//
-// Notation:
-//
-// R/W == read/write
-// R-O == read-only
-//
-// <input pin state> <output pin state> <comments>
-//
-// 00 means an unconnected pin.
-// <- means using a R/W allocator from the upstream filter
-// <= means using a R-O allocator from an upstream filter
-// || means using our own (R/W) allocator.
-// -> means using a R/W allocator from a downstream filter
-// (a R-O allocator from downstream is nonsense, it can't ever work).
-//
-//
-// That makes 25 possible states. Some states are nonsense (two different
-// allocators from the same place). These are just an artifact of the notation.
-// <= <- Nonsense.
-// <- <= Nonsense
-// Some states are illegal (the output pin never accepts a R-O allocator):
-// 00 <= !! Error !!
-// <= <= !! Error !!
-// || <= !! Error !!
-// -> <= !! Error !!
-// Three states appears to be inaccessible:
-// -> || Inaccessible
-// || -> Inaccessible
-// || <- Inaccessible
-// Some states only ever occur as intermediates with a pending reconnect which
-// is guaranteed to finish in another state.
-// -> 00 ?? unstable goes to || 00
-// 00 <- ?? unstable goes to 00 ||
-// -> <- ?? unstable goes to -> ->
-// <- || ?? unstable goes to <- <-
-// <- -> ?? unstable goes to <- <-
-// And that leaves 11 possible resting states:
-// 1 00 00 Nothing connected.
-// 2 <- 00 Input pin connected.
-// 3 <= 00 Input pin connected using R-O allocator.
-// 4 || 00 Needs several state changes to get here.
-// 5 00 || Output pin connected using our allocator
-// 6 00 -> Downstream only connected
-// 7 || || Undesirable but can be forced upon us.
-// 8 <= || Copy forced. <= -> is preferable
-// 9 <= -> OK - forced to copy.
-// 10 <- <- Transform in place (ideal)
-// 11 -> -> Transform in place (ideal)
-//
-// The object of the exercise is to ensure that we finish up in states
-// 10 or 11 whenever possible. State 10 is only possible if the upstream
-// filter has a R/W allocator (the AVI splitter notoriously
-// doesn't) and state 11 is only possible if the downstream filter does
-// offer an allocator.
-//
-// The transition table (entries marked * go via a reconnect)
-//
-// There are 8 possible transitions:
-// A: Connect upstream to filter with R-O allocator that insists on using it.
-// B: Connect upstream to filter with R-O allocator but chooses not to use it.
-// C: Connect upstream to filter with R/W allocator and insists on using it.
-// D: Connect upstream to filter with R/W allocator but chooses not to use it.
-// E: Connect downstream to a filter that offers an allocator
-// F: Connect downstream to a filter that does not offer an allocator
-// G: disconnect upstream
-// H: Disconnect downstream
-//
-// A B C D E F G H
-// ---------------------------------------------------------
-// 00 00 1 | 3 3 2 2 6 5 . . |1 00 00
-// <- 00 2 | . . . . *10/11 10 1 . |2 <- 00
-// <= 00 3 | . . . . *9/11 *7/8 1 . |3 <= 00
-// || 00 4 | . . . . *8 *7 1 . |4 || 00
-// 00 || 5 | 8 7 *10 7 . . . 1 |5 00 ||
-// 00 -> 6 | 9 11 *10 11 . . . 1 |6 00 ->
-// || || 7 | . . . . . . 5 4 |7 || ||
-// <= || 8 | . . . . . . 5 3 |8 <= ||
-// <= -> 9 | . . . . . . 6 3 |9 <= ->
-// <- <- 10| . . . . . . *5/6 2 |10 <- <-
-// -> -> 11| . . . . . . 6 *2/3 |11 -> ->
-// ---------------------------------------------------------
-// A B C D E F G H
-//
-// All these states are accessible without requiring any filter to
-// change its behaviour but not all transitions are accessible, for
-// instance a transition from state 4 to anywhere other than
-// state 8 requires that the upstream filter first offer a R-O allocator
-// and then changes its mind and offer R/W. This is NOT allowable - it
-// leads to things like the output pin getting a R/W allocator from
-// upstream and then the input pin being told it can only have a R-O one.
-// Note that you CAN change (say) the upstream filter for a different one, but
-// only as a disconnect / connect, not as a Reconnect. (Exercise for
-// the reader is to see how you get into state 4).
-//
-// The reconnection stuff goes as follows (some of the cases shown here as
-// "no reconnect" may get one to finalise media type - an old story).
-// If there is a reconnect where it says "no reconnect" here then the
-// reconnection must not change the allocator choice.
-//
-// state 2: <- 00 transition E <- <- case C <- <- (no change)
-// case D -> <- and then to -> ->
-//
-// state 2: <- 00 transition F <- <- (no reconnect)
-//
-// state 3: <= 00 transition E <= -> case A <= -> (no change)
-// case B -> ->
-// transition F <= || case A <= || (no change)
-// case B || ||
-//
-// state 4: || 00 transition E || || case B -> || and then all cases to -> ->
-// F || || case B || || (no change)
-//
-// state 5: 00 || transition A <= || (no reconnect)
-// B || || (no reconnect)
-// C <- || all cases <- <-
-// D || || (unfortunate, but upstream's choice)
-//
-// state 6: 00 -> transition A <= -> (no reconnect)
-// B -> -> (no reconnect)
-// C <- -> all cases <- <-
-// D -> -> (no reconnect)
-//
-// state 10:<- <- transition G 00 <- case E 00 ->
-// case F 00 ||
-//
-// state 11:-> -> transition H -> 00 case A <= 00 (schizo)
-// case B <= 00
-// case C <- 00 (schizo)
-// case D <- 00
-//
-// The Rules:
-// To sort out media types:
-// The input is reconnected
-// if the input pin is connected and the output pin connects
-// The output is reconnected
-// If the output pin is connected
-// and the input pin connects to a different media type
-//
-// To sort out allocators:
-// The input is reconnected
-// if the output disconnects and the input was using a downstream allocator
-// The output pin calls SetAllocator to pass on a new allocator
-// if the output is connected and
-// if the input disconnects and the output was using an upstream allocator
-// if the input acquires an allocator different from the output one
-// and that new allocator is not R-O
-//
-// Data is copied (i.e. call getbuffer and copy the data before transforming it)
-// if the two allocators are different.
-
-
-
-// CHAINS of filters:
-//
-// We sit between two filters (call them A and Z). We should finish up
-// with the same allocator on both of our pins and that should be the
-// same one that A and Z would have agreed on if we hadn't been in the
-// way. Furthermore, it should not matter how many in-place transforms
-// are in the way. Let B, C, D... be in-place transforms ("us").
-// Here's how it goes:
-//
-// 1.
-// A connects to B. They agree on A's allocator.
-// A-a->B
-//
-// 2.
-// B connects to C. Same story. There is no point in a reconnect, but
-// B will request an input reconnect anyway.
-// A-a->B-a->C
-//
-// 3.
-// C connects to Z.
-// C insists on using A's allocator, but compromises by requesting a reconnect.
-// of C's input.
-// A-a->B-?->C-a->Z
-//
-// We now have pending reconnects on both A--->B and B--->C
-//
-// 4.
-// The A--->B link is reconnected.
-// A asks B for an allocator. B sees that it has a downstream connection so
-// asks its downstream input pin i.e. C's input pin for an allocator. C sees
-// that it too has a downstream connection so asks Z for an allocator.
-//
-// Even though Z's input pin is connected, it is being asked for an allocator.
-// It could refuse, in which case the chain is done and will use A's allocator
-// Alternatively, Z may supply one. A chooses either Z's or A's own one.
-// B's input pin gets NotifyAllocator called to tell it the decision and it
-// propagates this downstream by calling ReceiveAllocator on its output pin
-// which calls NotifyAllocator on the next input pin downstream etc.
-// If the choice is Z then it goes:
-// A-z->B-a->C-a->Z
-// A-z->B-z->C-a->Z
-// A-z->B-z->C-z->Z
-//
-// And that's IT!! Any further (essentially spurious) reconnects peter out
-// with no change in the chain.
-
-#include <streams.h>
-#include <measure.h>
-#include <transip.h>
-
-
-// =================================================================
-// Implements the CTransInPlaceFilter class
-// =================================================================
-
-CTransInPlaceFilter::CTransInPlaceFilter
- ( __in_opt LPCTSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- REFCLSID clsid,
- __inout HRESULT *phr,
- bool bModifiesData
- )
- : CTransformFilter(pName, pUnk, clsid),
- m_bModifiesData(bModifiesData)
-{
-#ifdef PERF
- RegisterPerfId();
-#endif // PERF
-
-} // constructor
-
-#ifdef UNICODE
-CTransInPlaceFilter::CTransInPlaceFilter
- ( __in_opt LPCSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- REFCLSID clsid,
- __inout HRESULT *phr,
- bool bModifiesData
- )
- : CTransformFilter(pName, pUnk, clsid),
- m_bModifiesData(bModifiesData)
-{
-#ifdef PERF
- RegisterPerfId();
-#endif // PERF
-
-} // constructor
-#endif
-
-// return a non-addrefed CBasePin * for the user to addref if he holds onto it
-// for longer than his pointer to us. We create the pins dynamically when they
-// are asked for rather than in the constructor. This is because we want to
-// give the derived class an oppportunity to return different pin objects
-
-// As soon as any pin is needed we create both (this is different from the
-// usual transform filter) because enumerators, allocators etc are passed
-// through from one pin to another and it becomes very painful if the other
-// pin isn't there. If we fail to create either pin we ensure we fail both.
-
-CBasePin *
-CTransInPlaceFilter::GetPin(int n)
-{
- HRESULT hr = S_OK;
-
- // Create an input pin if not already done
-
- if (m_pInput == NULL) {
-
- m_pInput = new CTransInPlaceInputPin( NAME("TransInPlace input pin")
- , this // Owner filter
- , &hr // Result code
- , L"Input" // Pin name
- );
-
- // Constructor for CTransInPlaceInputPin can't fail
- ASSERT(SUCCEEDED(hr));
- }
-
- // Create an output pin if not already done
-
- if (m_pInput!=NULL && m_pOutput == NULL) {
-
- m_pOutput = new CTransInPlaceOutputPin( NAME("TransInPlace output pin")
- , this // Owner filter
- , &hr // Result code
- , L"Output" // Pin name
- );
-
- // a failed return code should delete the object
-
- ASSERT(SUCCEEDED(hr));
- if (m_pOutput == NULL) {
- delete m_pInput;
- m_pInput = NULL;
- }
- }
-
- // Return the appropriate pin
-
- ASSERT (n>=0 && n<=1);
- if (n == 0) {
- return m_pInput;
- } else if (n==1) {
- return m_pOutput;
- } else {
- return NULL;
- }
-
-} // GetPin
-
-
-
-// dir is the direction of our pin.
-// pReceivePin is the pin we are connecting to.
-HRESULT CTransInPlaceFilter::CompleteConnect(PIN_DIRECTION dir, IPin *pReceivePin)
-{
- UNREFERENCED_PARAMETER(pReceivePin);
- ASSERT(m_pInput);
- ASSERT(m_pOutput);
-
- // if we are not part of a graph, then don't indirect the pointer
- // this probably prevents use of the filter without a filtergraph
- if (!m_pGraph) {
- return VFW_E_NOT_IN_GRAPH;
- }
-
- // Always reconnect the input to account for buffering changes
- //
- // Because we don't get to suggest a type on ReceiveConnection
- // we need another way of making sure the right type gets used.
- //
- // One way would be to have our EnumMediaTypes return our output
- // connection type first but more deterministic and simple is to
- // call ReconnectEx passing the type we want to reconnect with
- // via the base class ReconeectPin method.
-
- if (dir == PINDIR_OUTPUT) {
- if( m_pInput->IsConnected() ) {
- return ReconnectPin( m_pInput, &m_pOutput->CurrentMediaType() );
- }
- return NOERROR;
- }
-
- ASSERT(dir == PINDIR_INPUT);
-
- // Reconnect output if necessary
-
- if( m_pOutput->IsConnected() ) {
-
- if ( m_pInput->CurrentMediaType()
- != m_pOutput->CurrentMediaType()
- ) {
- return ReconnectPin( m_pOutput, &m_pInput->CurrentMediaType() );
- }
- }
- return NOERROR;
-
-} // ComnpleteConnect
-
-
-//
-// DecideBufferSize
-//
-// Tell the output pin's allocator what size buffers we require.
-// *pAlloc will be the allocator our output pin is using.
-//
-
-HRESULT CTransInPlaceFilter::DecideBufferSize
- ( IMemAllocator *pAlloc
- , __inout ALLOCATOR_PROPERTIES *pProperties
- )
-{
- ALLOCATOR_PROPERTIES Request, Actual;
- HRESULT hr;
-
- // If we are connected upstream, get his views
- if (m_pInput->IsConnected()) {
- // Get the input pin allocator, and get its size and count.
- // we don't care about his alignment and prefix.
-
- hr = InputPin()->PeekAllocator()->GetProperties(&Request);
- if (FAILED(hr)) {
- // Input connected but with a secretive allocator - enough!
- return hr;
- }
- } else {
- // Propose one byte
- // If this isn't enough then when the other pin does get connected
- // we can revise it.
- ZeroMemory(&Request, sizeof(Request));
- Request.cBuffers = 1;
- Request.cbBuffer = 1;
- }
-
-
- DbgLog((LOG_MEMORY,1,TEXT("Setting Allocator Requirements")));
- DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d"),
- Request.cBuffers, Request.cbBuffer));
-
- // Pass the allocator requirements to our output side
- // but do a little sanity checking first or we'll just hit
- // asserts in the allocator.
-
- pProperties->cBuffers = Request.cBuffers;
- pProperties->cbBuffer = Request.cbBuffer;
- pProperties->cbAlign = Request.cbAlign;
- if (pProperties->cBuffers<=0) {pProperties->cBuffers = 1; }
- if (pProperties->cbBuffer<=0) {pProperties->cbBuffer = 1; }
- hr = pAlloc->SetProperties(pProperties, &Actual);
-
- if (FAILED(hr)) {
- return hr;
- }
-
- DbgLog((LOG_MEMORY,1,TEXT("Obtained Allocator Requirements")));
- DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d, Alignment %d"),
- Actual.cBuffers, Actual.cbBuffer, Actual.cbAlign));
-
- // Make sure we got the right alignment and at least the minimum required
-
- if ( (Request.cBuffers > Actual.cBuffers)
- || (Request.cbBuffer > Actual.cbBuffer)
- || (Request.cbAlign > Actual.cbAlign)
- ) {
- return E_FAIL;
- }
- return NOERROR;
-
-} // DecideBufferSize
-
-//
-// Copy
-//
-// return a pointer to an identical copy of pSample
-__out_opt IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource)
-{
- IMediaSample * pDest;
-
- HRESULT hr;
- REFERENCE_TIME tStart, tStop;
- const BOOL bTime = S_OK == pSource->GetTime( &tStart, &tStop);
-
- // this may block for an indeterminate amount of time
- hr = OutputPin()->PeekAllocator()->GetBuffer(
- &pDest
- , bTime ? &tStart : NULL
- , bTime ? &tStop : NULL
- , m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0
- );
-
- if (FAILED(hr)) {
- return NULL;
- }
-
- ASSERT(pDest);
- IMediaSample2 *pSample2;
- if (SUCCEEDED(pDest->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) {
- HRESULT hrProps = pSample2->SetProperties(
- FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer),
- (PBYTE)m_pInput->SampleProps());
- pSample2->Release();
- if (FAILED(hrProps)) {
- pDest->Release();
- return NULL;
- }
- } else {
- if (bTime) {
- pDest->SetTime(&tStart, &tStop);
- }
-
- if (S_OK == pSource->IsSyncPoint()) {
- pDest->SetSyncPoint(TRUE);
- }
- if (S_OK == pSource->IsDiscontinuity() || m_bSampleSkipped) {
- pDest->SetDiscontinuity(TRUE);
- }
- if (S_OK == pSource->IsPreroll()) {
- pDest->SetPreroll(TRUE);
- }
-
- // Copy the media type
- AM_MEDIA_TYPE *pMediaType;
- if (S_OK == pSource->GetMediaType(&pMediaType)) {
- pDest->SetMediaType(pMediaType);
- DeleteMediaType( pMediaType );
- }
-
- }
-
- m_bSampleSkipped = FALSE;
-
- // Copy the sample media times
- REFERENCE_TIME TimeStart, TimeEnd;
- if (pSource->GetMediaTime(&TimeStart,&TimeEnd) == NOERROR) {
- pDest->SetMediaTime(&TimeStart,&TimeEnd);
- }
-
- // Copy the actual data length and the actual data.
- {
- const long lDataLength = pSource->GetActualDataLength();
- if (FAILED(pDest->SetActualDataLength(lDataLength))) {
- pDest->Release();
- return NULL;
- }
-
- // Copy the sample data
- {
- BYTE *pSourceBuffer, *pDestBuffer;
- long lSourceSize = pSource->GetSize();
- long lDestSize = pDest->GetSize();
-
- ASSERT(lDestSize >= lSourceSize && lDestSize >= lDataLength);
-
- if (FAILED(pSource->GetPointer(&pSourceBuffer)) ||
- FAILED(pDest->GetPointer(&pDestBuffer)) ||
- lDestSize < lDataLength ||
- lDataLength < 0) {
- pDest->Release();
- return NULL;
- }
- ASSERT(lDestSize == 0 || pSourceBuffer != NULL && pDestBuffer != NULL);
-
- CopyMemory( (PVOID) pDestBuffer, (PVOID) pSourceBuffer, lDataLength );
- }
- }
-
- return pDest;
-
-} // Copy
-
-
-// override this to customize the transform process
-
-HRESULT
-CTransInPlaceFilter::Receive(IMediaSample *pSample)
-{
- /* Check for other streams and pass them on */
- AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
- if (pProps->dwStreamId != AM_STREAM_MEDIA) {
- return m_pOutput->Deliver(pSample);
- }
- HRESULT hr;
-
- // Start timing the TransInPlace (if PERF is defined)
- MSR_START(m_idTransInPlace);
-
- if (UsingDifferentAllocators()) {
-
- // We have to copy the data.
-
- pSample = Copy(pSample);
-
- if (pSample==NULL) {
- MSR_STOP(m_idTransInPlace);
- return E_UNEXPECTED;
- }
- }
-
- // have the derived class transform the data
- hr = Transform(pSample);
-
- // Stop the clock and log it (if PERF is defined)
- MSR_STOP(m_idTransInPlace);
-
- if (FAILED(hr)) {
- DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace")));
- if (UsingDifferentAllocators()) {
- pSample->Release();
- }
- return hr;
- }
-
- // the Transform() function can return S_FALSE to indicate that the
- // sample should not be delivered; we only deliver the sample if it's
- // really S_OK (same as NOERROR, of course.)
- if (hr == NOERROR) {
- hr = m_pOutput->Deliver(pSample);
- } else {
- // But it would be an error to return this private workaround
- // to the caller ...
- if (S_FALSE == hr) {
- // S_FALSE returned from Transform is a PRIVATE agreement
- // We should return NOERROR from Receive() in this cause because
- // returning S_FALSE from Receive() means that this is the end
- // of the stream and no more data should be sent.
- m_bSampleSkipped = TRUE;
- if (!m_bQualityChanged) {
- NotifyEvent(EC_QUALITY_CHANGE,0,0);
- m_bQualityChanged = TRUE;
- }
- hr = NOERROR;
- }
- }
-
- // release the output buffer. If the connected pin still needs it,
- // it will have addrefed it itself.
- if (UsingDifferentAllocators()) {
- pSample->Release();
- }
-
- return hr;
-
-} // Receive
-
-
-
-// =================================================================
-// Implements the CTransInPlaceInputPin class
-// =================================================================
-
-
-// constructor
-
-CTransInPlaceInputPin::CTransInPlaceInputPin
- ( __in_opt LPCTSTR pObjectName
- , __inout CTransInPlaceFilter *pFilter
- , __inout HRESULT *phr
- , __in_opt LPCWSTR pName
- )
- : CTransformInputPin(pObjectName,
- pFilter,
- phr,
- pName)
- , m_bReadOnly(FALSE)
- , m_pTIPFilter(pFilter)
-{
- DbgLog((LOG_TRACE, 2
- , TEXT("CTransInPlaceInputPin::CTransInPlaceInputPin")));
-
-} // constructor
-
-
-// =================================================================
-// Implements IMemInputPin interface
-// =================================================================
-
-
-// If the downstream filter has one then offer that (even if our own output
-// pin is not using it yet. If the upstream filter chooses it then we will
-// tell our output pin to ReceiveAllocator).
-// Else if our output pin is using an allocator then offer that.
-// ( This could mean offering the upstream filter his own allocator,
-// it could mean offerring our own
-// ) or it could mean offering the one from downstream
-// Else fail to offer any allocator at all.
-
-STDMETHODIMP CTransInPlaceInputPin::GetAllocator(__deref_out IMemAllocator ** ppAllocator)
-{
- CheckPointer(ppAllocator,E_POINTER);
- ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *));
- CAutoLock cObjectLock(m_pLock);
-
- HRESULT hr;
-
- if ( m_pTIPFilter->m_pOutput->IsConnected() ) {
- // Store the allocator we got
- hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
- ->GetAllocator( ppAllocator );
- if (SUCCEEDED(hr)) {
- m_pTIPFilter->OutputPin()->SetAllocator( *ppAllocator );
- }
- }
- else {
- // Help upstream filter (eg TIP filter which is having to do a copy)
- // by providing a temp allocator here - we'll never use
- // this allocator because when our output is connected we'll
- // reconnect this pin
- hr = CTransformInputPin::GetAllocator( ppAllocator );
- }
- return hr;
-
-} // GetAllocator
-
-
-
-/* Get told which allocator the upstream output pin is actually going to use */
-
-
-STDMETHODIMP
-CTransInPlaceInputPin::NotifyAllocator(
- IMemAllocator * pAllocator,
- BOOL bReadOnly)
-{
- HRESULT hr = S_OK;
- CheckPointer(pAllocator,E_POINTER);
- ValidateReadPtr(pAllocator,sizeof(IMemAllocator));
-
- CAutoLock cObjectLock(m_pLock);
-
- m_bReadOnly = bReadOnly;
- // If we modify data then don't accept the allocator if it's
- // the same as the output pin's allocator
-
- // If our output is not connected just accept the allocator
- // We're never going to use this allocator because when our
- // output pin is connected we'll reconnect this pin
- if (!m_pTIPFilter->OutputPin()->IsConnected()) {
- return CTransformInputPin::NotifyAllocator(pAllocator, bReadOnly);
- }
-
- // If the allocator is read-only and we're modifying data
- // and the allocator is the same as the output pin's
- // then reject
- if (bReadOnly && m_pTIPFilter->m_bModifiesData) {
- IMemAllocator *pOutputAllocator =
- m_pTIPFilter->OutputPin()->PeekAllocator();
-
- // Make sure we have an output allocator
- if (pOutputAllocator == NULL) {
- hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()->
- GetAllocator(&pOutputAllocator);
- if(FAILED(hr)) {
- hr = CreateMemoryAllocator(&pOutputAllocator);
- }
- if (SUCCEEDED(hr)) {
- m_pTIPFilter->OutputPin()->SetAllocator(pOutputAllocator);
- pOutputAllocator->Release();
- }
- }
- if (pAllocator == pOutputAllocator) {
- hr = E_FAIL;
- } else if(SUCCEEDED(hr)) {
- // Must copy so set the allocator properties on the output
- ALLOCATOR_PROPERTIES Props, Actual;
- hr = pAllocator->GetProperties(&Props);
- if (SUCCEEDED(hr)) {
- hr = pOutputAllocator->SetProperties(&Props, &Actual);
- }
- if (SUCCEEDED(hr)) {
- if ( (Props.cBuffers > Actual.cBuffers)
- || (Props.cbBuffer > Actual.cbBuffer)
- || (Props.cbAlign > Actual.cbAlign)
- ) {
- hr = E_FAIL;
- }
- }
-
- // Set the allocator on the output pin
- if (SUCCEEDED(hr)) {
- hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
- ->NotifyAllocator( pOutputAllocator, FALSE );
- }
- }
- } else {
- hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
- ->NotifyAllocator( pAllocator, bReadOnly );
- if (SUCCEEDED(hr)) {
- m_pTIPFilter->OutputPin()->SetAllocator( pAllocator );
- }
- }
-
- if (SUCCEEDED(hr)) {
-
- // It's possible that the old and the new are the same thing.
- // AddRef before release ensures that we don't unload it.
- pAllocator->AddRef();
-
- if( m_pAllocator != NULL )
- m_pAllocator->Release();
-
- m_pAllocator = pAllocator; // We have an allocator for the input pin
- }
-
- return hr;
-
-} // NotifyAllocator
-
-
-// EnumMediaTypes
-// - pass through to our downstream filter
-STDMETHODIMP CTransInPlaceInputPin::EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum )
-{
- // Can only pass through if connected
- if( !m_pTIPFilter->m_pOutput->IsConnected() )
- return VFW_E_NOT_CONNECTED;
-
- return m_pTIPFilter->m_pOutput->GetConnected()->EnumMediaTypes( ppEnum );
-
-} // EnumMediaTypes
-
-
-// CheckMediaType
-// - agree to anything if not connected,
-// otherwise pass through to the downstream filter.
-// This assumes that the filter does not change the media type.
-
-HRESULT CTransInPlaceInputPin::CheckMediaType(const CMediaType *pmt )
-{
- HRESULT hr = m_pTIPFilter->CheckInputType(pmt);
- if (hr!=S_OK) return hr;
-
- if( m_pTIPFilter->m_pOutput->IsConnected() )
- return m_pTIPFilter->m_pOutput->GetConnected()->QueryAccept( pmt );
- else
- return S_OK;
-
-} // CheckMediaType
-
-
-// If upstream asks us what our requirements are, we will try to ask downstream
-// if that doesn't work, we'll just take the defaults.
-STDMETHODIMP
-CTransInPlaceInputPin::GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES *pProps)
-{
-
- if( m_pTIPFilter->m_pOutput->IsConnected() )
- return m_pTIPFilter->OutputPin()
- ->ConnectedIMemInputPin()->GetAllocatorRequirements( pProps );
- else
- return E_NOTIMPL;
-
-} // GetAllocatorRequirements
-
-
-// CTransInPlaceInputPin::CompleteConnect() calls CBaseInputPin::CompleteConnect()
-// and then calls CTransInPlaceFilter::CompleteConnect(). It does this because
-// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not
-// want to reconnect a pin if CBaseInputPin::CompleteConnect() fails.
-HRESULT
-CTransInPlaceInputPin::CompleteConnect(IPin *pReceivePin)
-{
- HRESULT hr = CBaseInputPin::CompleteConnect(pReceivePin);
- if (FAILED(hr)) {
- return hr;
- }
-
- return m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin);
-} // CompleteConnect
-
-
-// =================================================================
-// Implements the CTransInPlaceOutputPin class
-// =================================================================
-
-
-// constructor
-
-CTransInPlaceOutputPin::CTransInPlaceOutputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransInPlaceFilter *pFilter,
- __inout HRESULT * phr,
- __in_opt LPCWSTR pPinName)
- : CTransformOutputPin( pObjectName
- , pFilter
- , phr
- , pPinName),
- m_pTIPFilter(pFilter)
-{
- DbgLog(( LOG_TRACE, 2
- , TEXT("CTransInPlaceOutputPin::CTransInPlaceOutputPin")));
-
-} // constructor
-
-
-// EnumMediaTypes
-// - pass through to our upstream filter
-STDMETHODIMP CTransInPlaceOutputPin::EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum )
-{
- // Can only pass through if connected.
- if( ! m_pTIPFilter->m_pInput->IsConnected() )
- return VFW_E_NOT_CONNECTED;
-
- return m_pTIPFilter->m_pInput->GetConnected()->EnumMediaTypes( ppEnum );
-
-} // EnumMediaTypes
-
-
-
-// CheckMediaType
-// - agree to anything if not connected,
-// otherwise pass through to the upstream filter.
-
-HRESULT CTransInPlaceOutputPin::CheckMediaType(const CMediaType *pmt )
-{
- // Don't accept any output pin type changes if we're copying
- // between allocators - it's too late to change the input
- // allocator size.
- if (m_pTIPFilter->UsingDifferentAllocators() && !m_pFilter->IsStopped()) {
- if (*pmt == m_mt) {
- return S_OK;
- } else {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- }
-
- // Assumes the type does not change. That's why we're calling
- // CheckINPUTType here on the OUTPUT pin.
- HRESULT hr = m_pTIPFilter->CheckInputType(pmt);
- if (hr!=S_OK) return hr;
-
- if( m_pTIPFilter->m_pInput->IsConnected() )
- return m_pTIPFilter->m_pInput->GetConnected()->QueryAccept( pmt );
- else
- return S_OK;
-
-} // CheckMediaType
-
-
-/* Save the allocator pointer in the output pin
-*/
-void
-CTransInPlaceOutputPin::SetAllocator(IMemAllocator * pAllocator)
-{
- pAllocator->AddRef();
- if (m_pAllocator) {
- m_pAllocator->Release();
- }
- m_pAllocator = pAllocator;
-} // SetAllocator
-
-
-// CTransInPlaceOutputPin::CompleteConnect() calls CBaseOutputPin::CompleteConnect()
-// and then calls CTransInPlaceFilter::CompleteConnect(). It does this because
-// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not want to
-// reconnect a pin if CBaseOutputPin::CompleteConnect() fails.
-// CBaseOutputPin::CompleteConnect() often fails when our output pin is being connected
-// to the Video Mixing Renderer.
-HRESULT
-CTransInPlaceOutputPin::CompleteConnect(IPin *pReceivePin)
-{
- HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
- if (FAILED(hr)) {
- return hr;
- }
-
- return m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin);
-} // CompleteConnect
diff --git a/third_party/BaseClasses/transip.h b/third_party/BaseClasses/transip.h
deleted file mode 100644
index 3fc335ef..00000000
--- a/third_party/BaseClasses/transip.h
+++ /dev/null
@@ -1,250 +0,0 @@
-//------------------------------------------------------------------------------
-// File: TransIP.h
-//
-// Desc: DirectShow base classes - defines classes from which simple
-// Transform-In-Place filters may be derived.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-//
-// The difference between this and Transfrm.h is that Transfrm copies the data.
-//
-// It assumes the filter has one input and one output stream, and has no
-// interest in memory management, interface negotiation or anything else.
-//
-// Derive your class from this, and supply Transform and the media type/format
-// negotiation functions. Implement that class, compile and link and
-// you're done.
-
-
-#ifndef __TRANSIP__
-#define __TRANSIP__
-
-// ======================================================================
-// This is the com object that represents a simple transform filter. It
-// supports IBaseFilter, IMediaFilter and two pins through nested interfaces
-// ======================================================================
-
-class CTransInPlaceFilter;
-
-// Several of the pin functions call filter functions to do the work,
-// so you can often use the pin classes unaltered, just overriding the
-// functions in CTransInPlaceFilter. If that's not enough and you want
-// to derive your own pin class, override GetPin in the filter to supply
-// your own pin classes to the filter.
-
-// ==================================================
-// Implements the input pin
-// ==================================================
-
-class CTransInPlaceInputPin : public CTransformInputPin
-{
-
-protected:
- CTransInPlaceFilter * const m_pTIPFilter; // our filter
- BOOL m_bReadOnly; // incoming stream is read only
-
-public:
-
- CTransInPlaceInputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransInPlaceFilter *pFilter,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName);
-
- // --- IMemInputPin -----
-
- // Provide an enumerator for media types by getting one from downstream
- STDMETHODIMP EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum );
-
- // Say whether media type is acceptable.
- HRESULT CheckMediaType(const CMediaType* pmt);
-
- // Return our upstream allocator
- STDMETHODIMP GetAllocator(__deref_out IMemAllocator ** ppAllocator);
-
- // get told which allocator the upstream output pin is actually
- // going to use.
- STDMETHODIMP NotifyAllocator(IMemAllocator * pAllocator,
- BOOL bReadOnly);
-
- // Allow the filter to see what allocator we have
- // N.B. This does NOT AddRef
- __out IMemAllocator * PeekAllocator() const
- { return m_pAllocator; }
-
- // Pass this on downstream if it ever gets called.
- STDMETHODIMP GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES *pProps);
-
- HRESULT CompleteConnect(IPin *pReceivePin);
-
- inline const BOOL ReadOnly() { return m_bReadOnly ; }
-
-}; // CTransInPlaceInputPin
-
-// ==================================================
-// Implements the output pin
-// ==================================================
-
-class CTransInPlaceOutputPin : public CTransformOutputPin
-{
-
-protected:
- // m_pFilter points to our CBaseFilter
- CTransInPlaceFilter * const m_pTIPFilter;
-
-public:
-
- CTransInPlaceOutputPin(
- __in_opt LPCTSTR pObjectName,
- __inout CTransInPlaceFilter *pFilter,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pName);
-
-
- // --- CBaseOutputPin ------------
-
- // negotiate the allocator and its buffer size/count
- // Insists on using our own allocator. (Actually the one upstream of us).
- // We don't override this - instead we just agree the default
- // then let the upstream filter decide for itself on reconnect
- // virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc);
-
- // Provide a media type enumerator. Get it from upstream.
- STDMETHODIMP EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum );
-
- // Say whether media type is acceptable.
- HRESULT CheckMediaType(const CMediaType* pmt);
-
- // This just saves the allocator being used on the output pin
- // Also called by input pin's GetAllocator()
- void SetAllocator(IMemAllocator * pAllocator);
-
- __out_opt IMemInputPin * ConnectedIMemInputPin()
- { return m_pInputPin; }
-
- // Allow the filter to see what allocator we have
- // N.B. This does NOT AddRef
- __out IMemAllocator * PeekAllocator() const
- { return m_pAllocator; }
-
- HRESULT CompleteConnect(IPin *pReceivePin);
-
-}; // CTransInPlaceOutputPin
-
-
-class AM_NOVTABLE CTransInPlaceFilter : public CTransformFilter
-{
-
-public:
-
- // map getpin/getpincount for base enum of pins to owner
- // override this to return more specialised pin objects
-
- virtual CBasePin *GetPin(int n);
-
-public:
-
- // Set bModifiesData == false if your derived filter does
- // not modify the data samples (for instance it's just copying
- // them somewhere else or looking at the timestamps).
-
- CTransInPlaceFilter(__in_opt LPCTSTR, __inout_opt LPUNKNOWN, REFCLSID clsid, __inout HRESULT *,
- bool bModifiesData = true);
-#ifdef UNICODE
- CTransInPlaceFilter(__in_opt LPCSTR, __inout_opt LPUNKNOWN, REFCLSID clsid, __inout HRESULT *,
- bool bModifiesData = true);
-#endif
- // The following are defined to avoid undefined pure virtuals.
- // Even if they are never called, they will give linkage warnings/errors
-
- // We override EnumMediaTypes to bypass the transform class enumerator
- // which would otherwise call this.
- HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType)
- { DbgBreak("CTransInPlaceFilter::GetMediaType should never be called");
- return E_UNEXPECTED;
- }
-
- // This is called when we actually have to provide our own allocator.
- HRESULT DecideBufferSize(IMemAllocator*, __inout ALLOCATOR_PROPERTIES *);
-
- // The functions which call this in CTransform are overridden in this
- // class to call CheckInputType with the assumption that the type
- // does not change. In Debug builds some calls will be made and
- // we just ensure that they do not assert.
- HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
- {
- return S_OK;
- };
-
-
- // =================================================================
- // ----- You may want to override this -----------------------------
- // =================================================================
-
- HRESULT CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin);
-
- // chance to customize the transform process
- virtual HRESULT Receive(IMediaSample *pSample);
-
- // =================================================================
- // ----- You MUST override these -----------------------------------
- // =================================================================
-
- virtual HRESULT Transform(IMediaSample *pSample) PURE;
-
- // this goes in the factory template table to create new instances
- // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
-
-
-#ifdef PERF
- // Override to register performance measurement with a less generic string
- // You should do this to avoid confusion with other filters
- virtual void RegisterPerfId()
- {m_idTransInPlace = MSR_REGISTER(TEXT("TransInPlace"));}
-#endif // PERF
-
-
-// implementation details
-
-protected:
-
- __out_opt IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource);
-
-#ifdef PERF
- int m_idTransInPlace; // performance measuring id
-#endif // PERF
- bool m_bModifiesData; // Does this filter change the data?
-
- // these hold our input and output pins
-
- friend class CTransInPlaceInputPin;
- friend class CTransInPlaceOutputPin;
-
- __out CTransInPlaceInputPin *InputPin() const
- {
- return (CTransInPlaceInputPin *)m_pInput;
- };
- __out CTransInPlaceOutputPin *OutputPin() const
- {
- return (CTransInPlaceOutputPin *)m_pOutput;
- };
-
- // Helper to see if the input and output types match
- BOOL TypesMatch()
- {
- return InputPin()->CurrentMediaType() ==
- OutputPin()->CurrentMediaType();
- }
-
- // Are the input and output allocators different?
- BOOL UsingDifferentAllocators() const
- {
- return InputPin()->PeekAllocator() != OutputPin()->PeekAllocator();
- }
-}; // CTransInPlaceFilter
-
-#endif /* __TRANSIP__ */
-
diff --git a/third_party/BaseClasses/videoctl.cpp b/third_party/BaseClasses/videoctl.cpp
deleted file mode 100644
index b12ccbd3..00000000
--- a/third_party/BaseClasses/videoctl.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-//------------------------------------------------------------------------------
-// File: VideoCtl.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include "ddmm.h"
-
-// Load a string from the resource file string table. The buffer must be at
-// least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a
-// buffer in the property page class and use it for all string loading. It
-// cannot be static as multiple property pages may be active simultaneously
-
-LPTSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPTSTR pBuffer, int iResourceID)
-{
- if (LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
- return TEXT("");
- }
- return pBuffer;
-}
-
-#ifdef UNICODE
-LPSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPSTR pBuffer, int iResourceID)
-{
- if (LoadStringA(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
- return "";
- }
- return pBuffer;
-}
-#endif
-
-
-
-// Property pages typically are called through their OLE interfaces. These
-// use UNICODE strings regardless of how the binary is built. So when we
-// load strings from the resource file we sometimes want to convert them
-// to UNICODE. This method is passed the target UNICODE buffer and does a
-// convert after loading the string (if built UNICODE this is not needed)
-// On WinNT we can explicitly call LoadStringW which saves two conversions
-
-#ifndef UNICODE
-
-LPWSTR WINAPI WideStringFromResource(__out_ecount(STR_MAX_LENGTH) LPWSTR pBuffer, int iResourceID)
-{
- *pBuffer = 0;
-
- if (g_amPlatform == VER_PLATFORM_WIN32_NT) {
- LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH);
- } else {
-
- CHAR szBuffer[STR_MAX_LENGTH];
- DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH);
- // if we loaded a string convert it to wide characters, ensuring
- // that we also null terminate the result.
- if (dwStringLength++) {
- MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH);
- }
- }
- return pBuffer;
-}
-
-#endif
-
-
-// Helper function to calculate the size of the dialog
-
-BOOL WINAPI GetDialogSize(int iResourceID,
- DLGPROC pDlgProc,
- LPARAM lParam,
- __out SIZE *pResult)
-{
- RECT rc;
- HWND hwnd;
-
- // Create a temporary property page
-
- hwnd = CreateDialogParam(g_hInst,
- MAKEINTRESOURCE(iResourceID),
- GetDesktopWindow(),
- pDlgProc,
- lParam);
- if (hwnd == NULL) {
- return FALSE;
- }
-
- GetWindowRect(hwnd, &rc);
- pResult->cx = rc.right - rc.left;
- pResult->cy = rc.bottom - rc.top;
-
- DestroyWindow(hwnd);
- return TRUE;
-}
-
-
-// Class that aggregates on the IDirectDraw interface. Although DirectDraw
-// has the ability in its interfaces to be aggregated they're not currently
-// implemented. This makes it difficult for various parts of Quartz that want
-// to aggregate these interfaces. In particular the video renderer passes out
-// media samples that expose IDirectDraw and IDirectDrawSurface. The filter
-// graph manager also exposes IDirectDraw as a plug in distributor. For these
-// objects we provide these aggregation classes that republish the interfaces
-
-STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
-{
- ASSERT(m_pDirectDraw);
-
- // Do we have this interface
-
- if (riid == IID_IDirectDraw) {
- return GetInterface((IDirectDraw *)this,ppv);
- } else {
- return CUnknown::NonDelegatingQueryInterface(riid,ppv);
- }
-}
-
-
-STDMETHODIMP CAggDirectDraw::Compact()
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->Compact();
-}
-
-
-STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags, __deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper, __inout_opt IUnknown *pUnkOuter)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter);
-}
-
-
-STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,
- __in LPPALETTEENTRY lpColorTable,
- __deref_out LPDIRECTDRAWPALETTE *lplpDDPalette,
- __inout_opt IUnknown *pUnkOuter)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter);
-}
-
-
-STDMETHODIMP CAggDirectDraw::CreateSurface(__in LPDDSURFACEDESC lpDDSurfaceDesc,
- __deref_out LPDIRECTDRAWSURFACE *lplpDDSurface,
- __inout_opt IUnknown *pUnkOuter)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter);
-}
-
-
-STDMETHODIMP CAggDirectDraw::DuplicateSurface(__in LPDIRECTDRAWSURFACE lpDDSurface,
- __deref_out LPDIRECTDRAWSURFACE *lplpDupDDSurface)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface);
-}
-
-
-STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,
- __in LPDDSURFACEDESC lplpDDSurfaceDescList,
- __in LPVOID lpContext,
- __in LPDDENUMMODESCALLBACK lpEnumCallback)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback);
-}
-
-
-STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,
- __in LPDDSURFACEDESC lpDDSD,
- __in LPVOID lpContext,
- __in LPDDENUMSURFACESCALLBACK lpEnumCallback)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback);
-}
-
-
-STDMETHODIMP CAggDirectDraw::FlipToGDISurface()
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->FlipToGDISurface();
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetCaps(__out LPDDCAPS lpDDDriverCaps,__out LPDDCAPS lpDDHELCaps)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetDisplayMode(__out LPDDSURFACEDESC lpDDSurfaceDesc)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetFourCCCodes(__inout LPDWORD lpNumCodes,__out_ecount(*lpNumCodes) LPDWORD lpCodes)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetGDISurface(__deref_out LPDIRECTDRAWSURFACE *lplpGDIDDSurface)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(__out LPDWORD lpdwFrequency)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetScanLine(__out LPDWORD lpdwScanLine)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetScanLine(lpdwScanLine);
-}
-
-
-STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(__out LPBOOL lpblsInVB)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB);
-}
-
-
-STDMETHODIMP CAggDirectDraw::Initialize(__in GUID *lpGUID)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->Initialize(lpGUID);
-}
-
-
-STDMETHODIMP CAggDirectDraw::RestoreDisplayMode()
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->RestoreDisplayMode();
-}
-
-
-STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags);
-}
-
-
-STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp);
-}
-
-
-STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent)
-{
- ASSERT(m_pDirectDraw);
- return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent);
-}
-
-
-// Class that aggregates an IDirectDrawSurface interface. Although DirectDraw
-// has the ability in its interfaces to be aggregated they're not currently
-// implemented. This makes it difficult for various parts of Quartz that want
-// to aggregate these interfaces. In particular the video renderer passes out
-// media samples that expose IDirectDraw and IDirectDrawSurface. The filter
-// graph manager also exposes IDirectDraw as a plug in distributor. For these
-// objects we provide these aggregation classes that republish the interfaces
-
-STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
-{
- ASSERT(m_pDirectDrawSurface);
-
- // Do we have this interface
-
- if (riid == IID_IDirectDrawSurface) {
- return GetInterface((IDirectDrawSurface *)this,ppv);
- } else {
- return CUnknown::NonDelegatingQueryInterface(riid,ppv);
- }
-}
-
-
-STDMETHODIMP CAggDrawSurface::AddAttachedSurface(__in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface);
-}
-
-
-STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(__in LPRECT lpRect)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect);
-}
-
-
-STDMETHODIMP CAggDrawSurface::Blt(__in LPRECT lpDestRect,
- __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
- __in LPRECT lpSrcRect,
- DWORD dwFlags,
- __in LPDDBLTFX lpDDBltFx)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx);
-}
-
-
-STDMETHODIMP CAggDrawSurface::BltBatch(__in_ecount(dwCount) LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags);
-}
-
-
-STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,
- __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
- __in LPRECT lpSrcRect,
- DWORD dwTrans)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans);
-}
-
-
-STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,
- __in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface);
-}
-
-
-STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(__in LPVOID lpContext,
- __in LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback);
-}
-
-
-STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,
- __in LPVOID lpContext,
- __in LPDDENUMSURFACESCALLBACK lpfnCallback)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback);
-}
-
-
-STDMETHODIMP CAggDrawSurface::Flip(__in LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetAttachedSurface(__in LPDDSCAPS lpDDSCaps,
- __deref_out LPDIRECTDRAWSURFACE *lplpDDAttachedSurface)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetBltStatus(dwFlags);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetCaps(__out LPDDSCAPS lpDDSCaps)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetCaps(lpDDSCaps);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetClipper(__deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetClipper(lplpDDClipper);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,__out LPDDCOLORKEY lpDDColorKey)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetDC(__out HDC *lphDC)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetDC(lphDC);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetFlipStatus(dwFlags);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetOverlayPosition(__out LPLONG lpdwX,__out LPLONG lpdwY)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetPalette(__deref_out LPDIRECTDRAWPALETTE *lplpDDPalette)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetPalette(lplpDDPalette);
-}
-
-
-STDMETHODIMP CAggDrawSurface::GetPixelFormat(__out LPDDPIXELFORMAT lpDDPixelFormat)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat);
-}
-
-
-// A bit of a warning here: Our media samples in DirectShow aggregate on
-// IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample
-// by QueryInterface). Unfortunately the underlying DirectDraw code cannot
-// be aggregated so we have to use these classes. The snag is that when we
-// call a different surface and pass in this interface as perhaps the source
-// surface the call will fail because DirectDraw dereferences the pointer to
-// get at its private data structures. Therefore we supply this workaround to give
-// access to the real IDirectDraw surface. A filter can call GetSurfaceDesc
-// and we will fill in the lpSurface pointer with the real underlying surface
-
-STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(__out LPDDSURFACEDESC lpDDSurfaceDesc)
-{
- ASSERT(m_pDirectDrawSurface);
-
- // First call down to the underlying DirectDraw
-
- HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Store the real DirectDrawSurface interface
- lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface;
- return hr;
-}
-
-
-STDMETHODIMP CAggDrawSurface::Initialize(__in LPDIRECTDRAW lpDD,__in LPDDSURFACEDESC lpDDSurfaceDesc)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc);
-}
-
-
-STDMETHODIMP CAggDrawSurface::IsLost()
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->IsLost();
-}
-
-
-STDMETHODIMP CAggDrawSurface::Lock(__in LPRECT lpDestRect,
- __inout LPDDSURFACEDESC lpDDSurfaceDesc,
- DWORD dwFlags,
- HANDLE hEvent)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent);
-}
-
-
-STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->ReleaseDC(hDC);
-}
-
-
-STDMETHODIMP CAggDrawSurface::Restore()
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Restore();
-}
-
-
-STDMETHODIMP CAggDrawSurface::SetClipper(__in LPDIRECTDRAWCLIPPER lpDDClipper)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->SetClipper(lpDDClipper);
-}
-
-
-STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,__in LPDDCOLORKEY lpDDColorKey)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey);
-}
-
-
-STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY);
-}
-
-
-STDMETHODIMP CAggDrawSurface::SetPalette(__in LPDIRECTDRAWPALETTE lpDDPalette)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->SetPalette(lpDDPalette);
-}
-
-
-STDMETHODIMP CAggDrawSurface::Unlock(__in LPVOID lpSurfaceData)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->Unlock(lpSurfaceData);
-}
-
-
-STDMETHODIMP CAggDrawSurface::UpdateOverlay(__in LPRECT lpSrcRect,
- __in LPDIRECTDRAWSURFACE lpDDDestSurface,
- __in LPRECT lpDestRect,
- DWORD dwFlags,
- __in LPDDOVERLAYFX lpDDOverlayFX)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX);
-}
-
-
-STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags);
-}
-
-
-STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,__in LPDIRECTDRAWSURFACE lpDDSReference)
-{
- ASSERT(m_pDirectDrawSurface);
- return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference);
-}
-
-
-// DirectShow must work on multiple platforms. In particular, it also runs on
-// Windows NT 3.51 which does not have DirectDraw capabilities. The filters
-// cannot therefore link statically to the DirectDraw library. To make their
-// lives that little bit easier we provide this class that manages loading
-// and unloading the library and creating the initial IDirectDraw interface
-
-CLoadDirectDraw::CLoadDirectDraw() :
- m_pDirectDraw(NULL),
- m_hDirectDraw(NULL)
-{
-}
-
-
-// Destructor forces unload
-
-CLoadDirectDraw::~CLoadDirectDraw()
-{
- ReleaseDirectDraw();
-
- if (m_hDirectDraw) {
- NOTE("Unloading library");
- FreeLibrary(m_hDirectDraw);
- }
-}
-
-
-// We can't be sure that DirectDraw is always available so we can't statically
-// link to the library. Therefore we load the library, get the function entry
-// point addresses and call them to create the driver objects. We return S_OK
-// if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE
-// We initialise a DirectDraw instance by explicitely loading the library and
-// calling GetProcAddress on the DirectDrawCreate entry point that it exports
-
-// On a multi monitor system, we can get the DirectDraw object for any
-// monitor (device) with the optional szDevice parameter
-
-HRESULT CLoadDirectDraw::LoadDirectDraw(__in LPSTR szDevice)
-{
- PDRAWCREATE pDrawCreate;
- PDRAWENUM pDrawEnum;
- LPDIRECTDRAWENUMERATEEXA pDrawEnumEx;
- HRESULT hr = NOERROR;
-
- NOTE("Entering DoLoadDirectDraw");
-
- // Is DirectDraw already loaded
-
- if (m_pDirectDraw) {
- NOTE("Already loaded");
- ASSERT(m_hDirectDraw);
- return NOERROR;
- }
-
- // Make sure the library is available
-
- if(!m_hDirectDraw)
- {
- UINT ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
- m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL"));
- SetErrorMode(ErrorMode);
-
- if (m_hDirectDraw == NULL) {
- DbgLog((LOG_ERROR,1,TEXT("Can't load DDRAW.DLL")));
- NOTE("No library");
- return E_NOINTERFACE;
- }
- }
-
- // Get the DLL address for the creator function
-
- pDrawCreate = (PDRAWCREATE)GetProcAddress(m_hDirectDraw,"DirectDrawCreate");
- // force ANSI, we assume it
- pDrawEnum = (PDRAWENUM)GetProcAddress(m_hDirectDraw,"DirectDrawEnumerateA");
- pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress(m_hDirectDraw,
- "DirectDrawEnumerateExA");
-
- // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff
- if (pDrawCreate == NULL || pDrawEnum == NULL) {
- DbgLog((LOG_ERROR,1,TEXT("Can't get functions: Create=%x Enum=%x"),
- pDrawCreate, pDrawEnum));
- NOTE("No entry point");
- ReleaseDirectDraw();
- return E_NOINTERFACE;
- }
-
- DbgLog((LOG_TRACE,3,TEXT("Creating DDraw for device %s"),
- szDevice ? szDevice : "<NULL>"));
-
- // Create a DirectDraw display provider for this device, using the fancy
- // multimon-aware version, if it exists
- if (pDrawEnumEx)
- m_pDirectDraw = DirectDrawCreateFromDeviceEx(szDevice, pDrawCreate,
- pDrawEnumEx);
- else
- m_pDirectDraw = DirectDrawCreateFromDevice(szDevice, pDrawCreate,
- pDrawEnum);
-
- if (m_pDirectDraw == NULL) {
- DbgLog((LOG_ERROR,1,TEXT("Can't create DDraw")));
- NOTE("No instance");
- ReleaseDirectDraw();
- return E_NOINTERFACE;
- }
- return NOERROR;
-}
-
-
-// Called to release any DirectDraw provider we previously loaded. We may be
-// called at any time especially when something goes horribly wrong and when
-// we need to clean up before returning so we can't guarantee that all state
-// variables are consistent so free only those really allocated allocated
-// This should only be called once all reference counts have been released
-
-void CLoadDirectDraw::ReleaseDirectDraw()
-{
- NOTE("Releasing DirectDraw driver");
-
- // Release any DirectDraw provider interface
-
- if (m_pDirectDraw) {
- NOTE("Releasing instance");
- m_pDirectDraw->Release();
- m_pDirectDraw = NULL;
- }
-
-}
-
-
-// Return NOERROR (S_OK) if DirectDraw has been loaded by this object
-
-HRESULT CLoadDirectDraw::IsDirectDrawLoaded()
-{
- NOTE("Entering IsDirectDrawLoaded");
-
- if (m_pDirectDraw == NULL) {
- NOTE("DirectDraw not loaded");
- return S_FALSE;
- }
- return NOERROR;
-}
-
-
-// Return the IDirectDraw interface we look after
-
-LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw()
-{
- NOTE("Entering GetDirectDraw");
-
- if (m_pDirectDraw == NULL) {
- NOTE("No DirectDraw");
- return NULL;
- }
-
- NOTE("Returning DirectDraw");
- m_pDirectDraw->AddRef();
- return m_pDirectDraw;
-}
-
-
-// Are we running on Direct Draw version 1? We need to find out as
-// we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
-// find out, we simply see if it supports IDirectDraw2. Only version 2 and
-// higher support this.
-
-BOOL CLoadDirectDraw::IsDirectDrawVersion1()
-{
-
- if (m_pDirectDraw == NULL)
- return FALSE;
-
- IDirectDraw2 *p = NULL;
- HRESULT hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&p);
- if (p)
- p->Release();
- if (hr == NOERROR) {
- DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 2 or greater")));
- return FALSE;
- } else {
- DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 1")));
- return TRUE;
- }
-}
diff --git a/third_party/BaseClasses/videoctl.h b/third_party/BaseClasses/videoctl.h
deleted file mode 100644
index 30c37783..00000000
--- a/third_party/BaseClasses/videoctl.h
+++ /dev/null
@@ -1,168 +0,0 @@
-//------------------------------------------------------------------------------
-// File: VideoCtl.h
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __VIDEOCTL__
-#define __VIDEOCTL__
-
-// These help with property page implementations. The first can be used to
-// load any string from a resource file. The buffer to load into is passed
-// as an input parameter. The same buffer is the return value if the string
-// was found otherwise it returns TEXT(""). The GetDialogSize is passed the
-// resource ID of a dialog box and returns the size of it in screen pixels
-
-#define STR_MAX_LENGTH 256
-LPTSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPTSTR pBuffer, int iResourceID);
-
-#ifdef UNICODE
-#define WideStringFromResource StringFromResource
-LPSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPSTR pBuffer, int iResourceID);
-#else
-LPWSTR WINAPI WideStringFromResource(__out_ecount(STR_MAX_LENGTH) LPWSTR pBuffer, int iResourceID);
-#endif
-
-
-BOOL WINAPI GetDialogSize(int iResourceID, // Dialog box resource identifier
- DLGPROC pDlgProc, // Pointer to dialog procedure
- LPARAM lParam, // Any user data wanted in pDlgProc
- __out SIZE *pResult);// Returns the size of dialog box
-
-// Class that aggregates an IDirectDraw interface
-
-class CAggDirectDraw : public IDirectDraw, public CUnknown
-{
-protected:
-
- LPDIRECTDRAW m_pDirectDraw;
-
-public:
-
- DECLARE_IUNKNOWN
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv);
-
- // Constructor and destructor
-
- CAggDirectDraw(__in_opt LPCTSTR pName,__inout_opt LPUNKNOWN pUnk) :
- CUnknown(pName,pUnk),
- m_pDirectDraw(NULL) { };
-
- virtual CAggDirectDraw::~CAggDirectDraw() { };
-
- // Set the object we should be aggregating
- void SetDirectDraw(__inout LPDIRECTDRAW pDirectDraw) {
- m_pDirectDraw = pDirectDraw;
- }
-
- // IDirectDraw methods
-
- STDMETHODIMP Compact();
- STDMETHODIMP CreateClipper(DWORD dwFlags,__deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper,__inout_opt IUnknown *pUnkOuter);
- STDMETHODIMP CreatePalette(DWORD dwFlags,__in LPPALETTEENTRY lpColorTable,__deref_out LPDIRECTDRAWPALETTE *lplpDDPalette,__inout_opt IUnknown *pUnkOuter);
- STDMETHODIMP CreateSurface(__in LPDDSURFACEDESC lpDDSurfaceDesc,__deref_out LPDIRECTDRAWSURFACE *lplpDDSurface,__inout_opt IUnknown *pUnkOuter);
- STDMETHODIMP DuplicateSurface(__in LPDIRECTDRAWSURFACE lpDDSurface,__deref_out LPDIRECTDRAWSURFACE *lplpDupDDSurface);
- STDMETHODIMP EnumDisplayModes(DWORD dwSurfaceDescCount,__in LPDDSURFACEDESC lplpDDSurfaceDescList,__in LPVOID lpContext,__in LPDDENUMMODESCALLBACK lpEnumCallback);
- STDMETHODIMP EnumSurfaces(DWORD dwFlags,__in LPDDSURFACEDESC lpDDSD,__in LPVOID lpContext,__in LPDDENUMSURFACESCALLBACK lpEnumCallback);
- STDMETHODIMP FlipToGDISurface();
- STDMETHODIMP GetCaps(__out LPDDCAPS lpDDDriverCaps,__out LPDDCAPS lpDDHELCaps);
- STDMETHODIMP GetDisplayMode(__out LPDDSURFACEDESC lpDDSurfaceDesc);
- STDMETHODIMP GetFourCCCodes(__inout LPDWORD lpNumCodes,__out_ecount(*lpNumCodes) LPDWORD lpCodes);
- STDMETHODIMP GetGDISurface(__deref_out LPDIRECTDRAWSURFACE *lplpGDIDDSurface);
- STDMETHODIMP GetMonitorFrequency(__out LPDWORD lpdwFrequency);
- STDMETHODIMP GetScanLine(__out LPDWORD lpdwScanLine);
- STDMETHODIMP GetVerticalBlankStatus(__out LPBOOL lpblsInVB);
- STDMETHODIMP Initialize(__in GUID *lpGUID);
- STDMETHODIMP RestoreDisplayMode();
- STDMETHODIMP SetCooperativeLevel(HWND hWnd,DWORD dwFlags);
- STDMETHODIMP SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp);
- STDMETHODIMP WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent);
-};
-
-
-// Class that aggregates an IDirectDrawSurface interface
-
-class CAggDrawSurface : public IDirectDrawSurface, public CUnknown
-{
-protected:
-
- LPDIRECTDRAWSURFACE m_pDirectDrawSurface;
-
-public:
-
- DECLARE_IUNKNOWN
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv);
-
- // Constructor and destructor
-
- CAggDrawSurface(__in_opt LPCTSTR pName,__inout_opt LPUNKNOWN pUnk) :
- CUnknown(pName,pUnk),
- m_pDirectDrawSurface(NULL) { };
-
- virtual ~CAggDrawSurface() { };
-
- // Set the object we should be aggregating
- void SetDirectDrawSurface(__inout LPDIRECTDRAWSURFACE pDirectDrawSurface) {
- m_pDirectDrawSurface = pDirectDrawSurface;
- }
-
- // IDirectDrawSurface methods
-
- STDMETHODIMP AddAttachedSurface(__in LPDIRECTDRAWSURFACE lpDDSAttachedSurface);
- STDMETHODIMP AddOverlayDirtyRect(__in LPRECT lpRect);
- STDMETHODIMP Blt(__in LPRECT lpDestRect,__in LPDIRECTDRAWSURFACE lpDDSrcSurface,__in LPRECT lpSrcRect,DWORD dwFlags,__in LPDDBLTFX lpDDBltFx);
- STDMETHODIMP BltBatch(__in_ecount(dwCount) LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags);
- STDMETHODIMP BltFast(DWORD dwX,DWORD dwY,__in LPDIRECTDRAWSURFACE lpDDSrcSurface,__in LPRECT lpSrcRect,DWORD dwTrans);
- STDMETHODIMP DeleteAttachedSurface(DWORD dwFlags,__in LPDIRECTDRAWSURFACE lpDDSAttachedSurface);
- STDMETHODIMP EnumAttachedSurfaces(__in LPVOID lpContext,__in LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback);
- STDMETHODIMP EnumOverlayZOrders(DWORD dwFlags,__in LPVOID lpContext,__in LPDDENUMSURFACESCALLBACK lpfnCallback);
- STDMETHODIMP Flip(__in LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags);
- STDMETHODIMP GetAttachedSurface(__in LPDDSCAPS lpDDSCaps,__deref_out LPDIRECTDRAWSURFACE *lplpDDAttachedSurface);
- STDMETHODIMP GetBltStatus(DWORD dwFlags);
- STDMETHODIMP GetCaps(__out LPDDSCAPS lpDDSCaps);
- STDMETHODIMP GetClipper(__deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper);
- STDMETHODIMP GetColorKey(DWORD dwFlags,__out LPDDCOLORKEY lpDDColorKey);
- STDMETHODIMP GetDC(__out HDC *lphDC);
- STDMETHODIMP GetFlipStatus(DWORD dwFlags);
- STDMETHODIMP GetOverlayPosition(__out LPLONG lpdwX,__out LPLONG lpdwY);
- STDMETHODIMP GetPalette(__deref_out LPDIRECTDRAWPALETTE *lplpDDPalette);
- STDMETHODIMP GetPixelFormat(__out LPDDPIXELFORMAT lpDDPixelFormat);
- STDMETHODIMP GetSurfaceDesc(__out LPDDSURFACEDESC lpDDSurfaceDesc);
- STDMETHODIMP Initialize(__in LPDIRECTDRAW lpDD,__in LPDDSURFACEDESC lpDDSurfaceDesc);
- STDMETHODIMP IsLost();
- STDMETHODIMP Lock(__in LPRECT lpDestRect,__inout LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent);
- STDMETHODIMP ReleaseDC(HDC hDC);
- STDMETHODIMP Restore();
- STDMETHODIMP SetClipper(__in LPDIRECTDRAWCLIPPER lpDDClipper);
- STDMETHODIMP SetColorKey(DWORD dwFlags,__in LPDDCOLORKEY lpDDColorKey);
- STDMETHODIMP SetOverlayPosition(LONG dwX,LONG dwY);
- STDMETHODIMP SetPalette(__in LPDIRECTDRAWPALETTE lpDDPalette);
- STDMETHODIMP Unlock(__in LPVOID lpSurfaceData);
- STDMETHODIMP UpdateOverlay(__in LPRECT lpSrcRect,__in LPDIRECTDRAWSURFACE lpDDDestSurface,__in LPRECT lpDestRect,DWORD dwFlags,__in LPDDOVERLAYFX lpDDOverlayFX);
- STDMETHODIMP UpdateOverlayDisplay(DWORD dwFlags);
- STDMETHODIMP UpdateOverlayZOrder(DWORD dwFlags,__in LPDIRECTDRAWSURFACE lpDDSReference);
-};
-
-
-class CLoadDirectDraw
-{
- LPDIRECTDRAW m_pDirectDraw; // The DirectDraw driver instance
- HINSTANCE m_hDirectDraw; // Handle to the loaded library
-
-public:
-
- CLoadDirectDraw();
- ~CLoadDirectDraw();
-
- HRESULT LoadDirectDraw(__in LPSTR szDevice);
- void ReleaseDirectDraw();
- HRESULT IsDirectDrawLoaded();
- LPDIRECTDRAW GetDirectDraw();
- BOOL IsDirectDrawVersion1();
-};
-
-#endif // __VIDEOCTL__
-
diff --git a/third_party/BaseClasses/vtrans.cpp b/third_party/BaseClasses/vtrans.cpp
deleted file mode 100644
index cb4fa998..00000000
--- a/third_party/BaseClasses/vtrans.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Vtrans.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <measure.h>
-// #include <vtransfr.h> // now in precomp file streams.h
-
-CVideoTransformFilter::CVideoTransformFilter
- ( __in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, REFCLSID clsid)
- : CTransformFilter(pName, pUnk, clsid)
- , m_itrLate(0)
- , m_nKeyFramePeriod(0) // No QM until we see at least 2 key frames
- , m_nFramesSinceKeyFrame(0)
- , m_bSkipping(FALSE)
- , m_tDecodeStart(0)
- , m_itrAvgDecode(300000) // 30mSec - probably allows skipping
- , m_bQualityChanged(FALSE)
-{
-#ifdef PERF
- RegisterPerfId();
-#endif // PERF
-}
-
-
-CVideoTransformFilter::~CVideoTransformFilter()
-{
- // nothing to do
-}
-
-
-// Reset our quality management state
-
-HRESULT CVideoTransformFilter::StartStreaming()
-{
- m_itrLate = 0;
- m_nKeyFramePeriod = 0; // No QM until we see at least 2 key frames
- m_nFramesSinceKeyFrame = 0;
- m_bSkipping = FALSE;
- m_tDecodeStart = 0;
- m_itrAvgDecode = 300000; // 30mSec - probably allows skipping
- m_bQualityChanged = FALSE;
- m_bSampleSkipped = FALSE;
- return NOERROR;
-}
-
-
-// Overriden to reset quality management information
-
-HRESULT CVideoTransformFilter::EndFlush()
-{
- {
- // Synchronize
- CAutoLock lck(&m_csReceive);
-
- // Reset our stats
- //
- // Note - we don't want to call derived classes here,
- // we only want to reset our internal variables and this
- // is a convenient way to do it
- CVideoTransformFilter::StartStreaming();
- }
- return CTransformFilter::EndFlush();
-}
-
-
-HRESULT CVideoTransformFilter::AbortPlayback(HRESULT hr)
-{
- NotifyEvent(EC_ERRORABORT, hr, 0);
- m_pOutput->DeliverEndOfStream();
- return hr;
-}
-
-
-// Receive()
-//
-// Accept a sample from upstream, decide whether to process it
-// or drop it. If we process it then get a buffer from the
-// allocator of the downstream connection, transform it into the
-// new buffer and deliver it to the downstream filter.
-// If we decide not to process it then we do not get a buffer.
-
-// Remember that although this code will notice format changes coming into
-// the input pin, it will NOT change its output format if that results
-// in the filter needing to make a corresponding output format change. Your
-// derived filter will have to take care of that. (eg. a palette change if
-// the input and output is an 8 bit format). If the input sample is discarded
-// and nothing is sent out for this Receive, please remember to put the format
-// change on the first output sample that you actually do send.
-// If your filter will produce the same output type even when the input type
-// changes, then this base class code will do everything you need.
-
-HRESULT CVideoTransformFilter::Receive(IMediaSample *pSample)
-{
- // If the next filter downstream is the video renderer, then it may
- // be able to operate in DirectDraw mode which saves copying the data
- // and gives higher performance. In that case the buffer which we
- // get from GetDeliveryBuffer will be a DirectDraw buffer, and
- // drawing into this buffer draws directly onto the display surface.
- // This means that any waiting for the correct time to draw occurs
- // during GetDeliveryBuffer, and that once the buffer is given to us
- // the video renderer will count it in its statistics as a frame drawn.
- // This means that any decision to drop the frame must be taken before
- // calling GetDeliveryBuffer.
-
- ASSERT(CritCheckIn(&m_csReceive));
- AM_MEDIA_TYPE *pmtOut, *pmt;
-#ifdef DEBUG
- FOURCCMap fccOut;
-#endif
- HRESULT hr;
- ASSERT(pSample);
- IMediaSample * pOutSample;
-
- // If no output pin to deliver to then no point sending us data
- ASSERT (m_pOutput != NULL) ;
-
- // The source filter may dynamically ask us to start transforming from a
- // different media type than the one we're using now. If we don't, we'll
- // draw garbage. (typically, this is a palette change in the movie,
- // but could be something more sinister like the compression type changing,
- // or even the video size changing)
-
-#define rcS1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcSource
-#define rcT1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcTarget
-
- pSample->GetMediaType(&pmt);
- if (pmt != NULL && pmt->pbFormat != NULL) {
-
- // spew some debug output
- ASSERT(!IsEqualGUID(pmt->majortype, GUID_NULL));
-#ifdef DEBUG
- fccOut.SetFOURCC(&pmt->subtype);
- LONG lCompression = HEADER(pmt->pbFormat)->biCompression;
- LONG lBitCount = HEADER(pmt->pbFormat)->biBitCount;
- LONG lStride = (HEADER(pmt->pbFormat)->biWidth * lBitCount + 7) / 8;
- lStride = (lStride + 3) & ~3;
- DbgLog((LOG_TRACE,3,TEXT("*Changing input type on the fly to")));
- DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"),
- fccOut.GetFOURCC(), lCompression, lBitCount));
- DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"),
- HEADER(pmt->pbFormat)->biHeight,
- rcT1.left, rcT1.top, rcT1.right, rcT1.bottom));
- DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"),
- rcS1.left, rcS1.top, rcS1.right, rcS1.bottom,
- lStride));
-#endif
-
- // now switch to using the new format. I am assuming that the
- // derived filter will do the right thing when its media type is
- // switched and streaming is restarted.
-
- StopStreaming();
- m_pInput->CurrentMediaType() = *pmt;
- DeleteMediaType(pmt);
- // if this fails, playback will stop, so signal an error
- hr = StartStreaming();
- if (FAILED(hr)) {
- return AbortPlayback(hr);
- }
- }
-
- // Now that we have noticed any format changes on the input sample, it's
- // OK to discard it.
-
- if (ShouldSkipFrame(pSample)) {
- MSR_NOTE(m_idSkip);
- m_bSampleSkipped = TRUE;
- return NOERROR;
- }
-
- // Set up the output sample
- hr = InitializeOutputSample(pSample, &pOutSample);
-
- if (FAILED(hr)) {
- return hr;
- }
-
- m_bSampleSkipped = FALSE;
-
- // The renderer may ask us to on-the-fly to start transforming to a
- // different format. If we don't obey it, we'll draw garbage
-
-#define rcS ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcSource
-#define rcT ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcTarget
-
- pOutSample->GetMediaType(&pmtOut);
- if (pmtOut != NULL && pmtOut->pbFormat != NULL) {
-
- // spew some debug output
- ASSERT(!IsEqualGUID(pmtOut->majortype, GUID_NULL));
-#ifdef DEBUG
- fccOut.SetFOURCC(&pmtOut->subtype);
- LONG lCompression = HEADER(pmtOut->pbFormat)->biCompression;
- LONG lBitCount = HEADER(pmtOut->pbFormat)->biBitCount;
- LONG lStride = (HEADER(pmtOut->pbFormat)->biWidth * lBitCount + 7) / 8;
- lStride = (lStride + 3) & ~3;
- DbgLog((LOG_TRACE,3,TEXT("*Changing output type on the fly to")));
- DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"),
- fccOut.GetFOURCC(), lCompression, lBitCount));
- DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"),
- HEADER(pmtOut->pbFormat)->biHeight,
- rcT.left, rcT.top, rcT.right, rcT.bottom));
- DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"),
- rcS.left, rcS.top, rcS.right, rcS.bottom,
- lStride));
-#endif
-
- // now switch to using the new format. I am assuming that the
- // derived filter will do the right thing when its media type is
- // switched and streaming is restarted.
-
- StopStreaming();
- m_pOutput->CurrentMediaType() = *pmtOut;
- DeleteMediaType(pmtOut);
- hr = StartStreaming();
-
- if (SUCCEEDED(hr)) {
- // a new format, means a new empty buffer, so wait for a keyframe
- // before passing anything on to the renderer.
- // !!! a keyframe may never come, so give up after 30 frames
- DbgLog((LOG_TRACE,3,TEXT("Output format change means we must wait for a keyframe")));
- m_nWaitForKey = 30;
-
- // if this fails, playback will stop, so signal an error
- } else {
-
- // Must release the sample before calling AbortPlayback
- // because we might be holding the win16 lock or
- // ddraw lock
- pOutSample->Release();
- AbortPlayback(hr);
- return hr;
- }
- }
-
- // After a discontinuity, we need to wait for the next key frame
- if (pSample->IsDiscontinuity() == S_OK) {
- DbgLog((LOG_TRACE,3,TEXT("Non-key discontinuity - wait for keyframe")));
- m_nWaitForKey = 30;
- }
-
- // Start timing the transform (and log it if PERF is defined)
-
- if (SUCCEEDED(hr)) {
- m_tDecodeStart = timeGetTime();
- MSR_START(m_idTransform);
-
- // have the derived class transform the data
- hr = Transform(pSample, pOutSample);
-
- // Stop the clock (and log it if PERF is defined)
- MSR_STOP(m_idTransform);
- m_tDecodeStart = timeGetTime()-m_tDecodeStart;
- m_itrAvgDecode = m_tDecodeStart*(10000/16) + 15*(m_itrAvgDecode/16);
-
- // Maybe we're waiting for a keyframe still?
- if (m_nWaitForKey)
- m_nWaitForKey--;
- if (m_nWaitForKey && pSample->IsSyncPoint() == S_OK)
- m_nWaitForKey = FALSE;
-
- // if so, then we don't want to pass this on to the renderer
- if (m_nWaitForKey && hr == NOERROR) {
- DbgLog((LOG_TRACE,3,TEXT("still waiting for a keyframe")));
- hr = S_FALSE;
- }
- }
-
- if (FAILED(hr)) {
- DbgLog((LOG_TRACE,1,TEXT("Error from video transform")));
- } else {
- // the Transform() function can return S_FALSE to indicate that the
- // sample should not be delivered; we only deliver the sample if it's
- // really S_OK (same as NOERROR, of course.)
- // Try not to return S_FALSE to a direct draw buffer (it's wasteful)
- // Try to take the decision earlier - before you get it.
-
- if (hr == NOERROR) {
- hr = m_pOutput->Deliver(pOutSample);
- } else {
- // S_FALSE returned from Transform is a PRIVATE agreement
- // We should return NOERROR from Receive() in this case because returning S_FALSE
- // from Receive() means that this is the end of the stream and no more data should
- // be sent.
- if (S_FALSE == hr) {
-
- // We must Release() the sample before doing anything
- // like calling the filter graph because having the
- // sample means we may have the DirectDraw lock
- // (== win16 lock on some versions)
- pOutSample->Release();
- m_bSampleSkipped = TRUE;
- if (!m_bQualityChanged) {
- m_bQualityChanged = TRUE;
- NotifyEvent(EC_QUALITY_CHANGE,0,0);
- }
- return NOERROR;
- }
- }
- }
-
- // release the output buffer. If the connected pin still needs it,
- // it will have addrefed it itself.
- pOutSample->Release();
- ASSERT(CritCheckIn(&m_csReceive));
-
- return hr;
-}
-
-
-
-BOOL CVideoTransformFilter::ShouldSkipFrame( IMediaSample * pIn)
-{
- REFERENCE_TIME trStart, trStopAt;
- HRESULT hr = pIn->GetTime(&trStart, &trStopAt);
-
- // Don't skip frames with no timestamps
- if (hr != S_OK)
- return FALSE;
-
- int itrFrame = (int)(trStopAt - trStart); // frame duration
-
- if(S_OK==pIn->IsSyncPoint()) {
- MSR_INTEGER(m_idFrameType, 1);
- if ( m_nKeyFramePeriod < m_nFramesSinceKeyFrame ) {
- // record the max
- m_nKeyFramePeriod = m_nFramesSinceKeyFrame;
- }
- m_nFramesSinceKeyFrame = 0;
- m_bSkipping = FALSE;
- } else {
- MSR_INTEGER(m_idFrameType, 2);
- if ( m_nFramesSinceKeyFrame>m_nKeyFramePeriod
- && m_nKeyFramePeriod>0
- ) {
- // We haven't seen the key frame yet, but we were clearly being
- // overoptimistic about how frequent they are.
- m_nKeyFramePeriod = m_nFramesSinceKeyFrame;
- }
- }
-
-
- // Whatever we might otherwise decide,
- // if we are taking only a small fraction of the required frame time to decode
- // then any quality problems are actually coming from somewhere else.
- // Could be a net problem at the source for instance. In this case there's
- // no point in us skipping frames here.
- if (m_itrAvgDecode*4>itrFrame) {
-
- // Don't skip unless we are at least a whole frame late.
- // (We would skip B frames if more than 1/2 frame late, but they're safe).
- if ( m_itrLate > itrFrame ) {
-
- // Don't skip unless the anticipated key frame would be no more than
- // 1 frame early. If the renderer has not been waiting (we *guess*
- // it hasn't because we're late) then it will allow frames to be
- // played early by up to a frame.
-
- // Let T = Stream time from now to anticipated next key frame
- // = (frame duration) * (KeyFramePeriod - FramesSinceKeyFrame)
- // So we skip if T - Late < one frame i.e.
- // (duration) * (freq - FramesSince) - Late < duration
- // or (duration) * (freq - FramesSince - 1) < Late
-
- // We don't dare skip until we have seen some key frames and have
- // some idea how often they occur and they are reasonably frequent.
- if (m_nKeyFramePeriod>0) {
- // It would be crazy - but we could have a stream with key frames
- // a very long way apart - and if they are further than about
- // 3.5 minutes apart then we could get arithmetic overflow in
- // reference time units. Therefore we switch to mSec at this point
- int it = (itrFrame/10000)
- * (m_nKeyFramePeriod-m_nFramesSinceKeyFrame - 1);
- MSR_INTEGER(m_idTimeTillKey, it);
-
- // For debug - might want to see the details - dump them as scratch pad
-#ifdef VTRANSPERF
- MSR_INTEGER(0, itrFrame);
- MSR_INTEGER(0, m_nFramesSinceKeyFrame);
- MSR_INTEGER(0, m_nKeyFramePeriod);
-#endif
- if (m_itrLate/10000 > it) {
- m_bSkipping = TRUE;
- // Now we are committed. Once we start skipping, we
- // cannot stop until we hit a key frame.
- } else {
-#ifdef VTRANSPERF
- MSR_INTEGER(0, 777770); // not near enough to next key
-#endif
- }
- } else {
-#ifdef VTRANSPERF
- MSR_INTEGER(0, 777771); // Next key not predictable
-#endif
- }
- } else {
-#ifdef VTRANSPERF
- MSR_INTEGER(0, 777772); // Less than one frame late
- MSR_INTEGER(0, m_itrLate);
- MSR_INTEGER(0, itrFrame);
-#endif
- }
- } else {
-#ifdef VTRANSPERF
- MSR_INTEGER(0, 777773); // Decode time short - not not worth skipping
- MSR_INTEGER(0, m_itrAvgDecode);
- MSR_INTEGER(0, itrFrame);
-#endif
- }
-
- ++m_nFramesSinceKeyFrame;
-
- if (m_bSkipping) {
- // We will count down the lateness as we skip each frame.
- // We re-assess each frame. The key frame might not arrive when expected.
- // We reset m_itrLate if we get a new Quality message, but actually that's
- // not likely because we're not sending frames on to the Renderer. In
- // fact if we DID get another one it would mean that there's a long
- // pipe between us and the renderer and we might need an altogether
- // better strategy to avoid hunting!
- m_itrLate = m_itrLate - itrFrame;
- }
-
- MSR_INTEGER(m_idLate, (int)m_itrLate/10000 ); // Note how late we think we are
- if (m_bSkipping) {
- if (!m_bQualityChanged) {
- m_bQualityChanged = TRUE;
- NotifyEvent(EC_QUALITY_CHANGE,0,0);
- }
- }
- return m_bSkipping;
-}
-
-
-HRESULT CVideoTransformFilter::AlterQuality(Quality q)
-{
- // to reduce the amount of 64 bit arithmetic, m_itrLate is an int.
- // +, -, >, == etc are not too bad, but * and / are painful.
- if (m_itrLate>300000000) {
- // Avoid overflow and silliness - more than 30 secs late is already silly
- m_itrLate = 300000000;
- } else {
- m_itrLate = (int)q.Late;
- }
- // We ignore the other fields
-
- // We're actually not very good at handling this. In non-direct draw mode
- // most of the time can be spent in the renderer which can skip any frame.
- // In that case we'd rather the renderer handled things.
- // Nevertheless we will keep an eye on it and if we really start getting
- // a very long way behind then we will actually skip - but we'll still tell
- // the renderer (or whoever is downstream) that they should handle quality.
-
- return E_FAIL; // Tell the renderer to do his thing.
-
-}
-
-
-
-// This will avoid several hundred useless warnings if compiled -W4 by MS VC++ v4
-#pragma warning(disable:4514)
-
diff --git a/third_party/BaseClasses/vtrans.h b/third_party/BaseClasses/vtrans.h
deleted file mode 100644
index 49b1509b..00000000
--- a/third_party/BaseClasses/vtrans.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//------------------------------------------------------------------------------
-// File: VTrans.h
-//
-// Desc: DirectShow base classes - defines a video transform class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// This class is derived from CTransformFilter, but is specialised to handle
-// the requirements of video quality control by frame dropping.
-// This is a non-in-place transform, (i.e. it copies the data) such as a decoder.
-
-class CVideoTransformFilter : public CTransformFilter
-{
- public:
-
- CVideoTransformFilter(__in_opt LPCTSTR, __inout_opt LPUNKNOWN, REFCLSID clsid);
- ~CVideoTransformFilter();
- HRESULT EndFlush();
-
- // =================================================================
- // ----- override these bits ---------------------------------------
- // =================================================================
- // The following methods are in CTransformFilter which is inherited.
- // They are mentioned here for completeness
- //
- // These MUST be supplied in a derived class
- //
- // NOTE:
- // virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut);
- // virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE;
- // virtual HRESULT CheckTransform
- // (const CMediaType* mtIn, const CMediaType* mtOut) PURE;
- // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
- // virtual HRESULT DecideBufferSize
- // (IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pprop) PURE;
- // virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE;
- //
- // These MAY also be overridden
- //
- // virtual HRESULT StopStreaming();
- // virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt);
- // virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin);
- // virtual HRESULT BreakConnect(PIN_DIRECTION dir);
- // virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin);
- // virtual HRESULT EndOfStream(void);
- // virtual HRESULT BeginFlush(void);
- // virtual HRESULT EndFlush(void);
- // virtual HRESULT NewSegment
- // (REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate);
-#ifdef PERF
-
- // If you override this - ensure that you register all these ids
- // as well as any of your own,
- virtual void RegisterPerfId() {
- m_idSkip = MSR_REGISTER(TEXT("Video Transform Skip frame"));
- m_idFrameType = MSR_REGISTER(TEXT("Video transform frame type"));
- m_idLate = MSR_REGISTER(TEXT("Video Transform Lateness"));
- m_idTimeTillKey = MSR_REGISTER(TEXT("Video Transform Estd. time to next key"));
- CTransformFilter::RegisterPerfId();
- }
-#endif
-
- protected:
-
- // =========== QUALITY MANAGEMENT IMPLEMENTATION ========================
- // Frames are assumed to come in three types:
- // Type 1: an AVI key frame or an MPEG I frame.
- // This frame can be decoded with no history.
- // Dropping this frame means that no further frame can be decoded
- // until the next type 1 frame.
- // Type 1 frames are sync points.
- // Type 2: an AVI non-key frame or an MPEG P frame.
- // This frame cannot be decoded unless the previous type 1 frame was
- // decoded and all type 2 frames since have been decoded.
- // Dropping this frame means that no further frame can be decoded
- // until the next type 1 frame.
- // Type 3: An MPEG B frame.
- // This frame cannot be decoded unless the previous type 1 or 2 frame
- // has been decoded AND the subsequent type 1 or 2 frame has also
- // been decoded. (This requires decoding the frames out of sequence).
- // Dropping this frame affects no other frames. This implementation
- // does not allow for these. All non-sync-point frames are treated
- // as being type 2.
- //
- // The spacing of frames of type 1 in a file is not guaranteed. There MUST
- // be a type 1 frame at (well, near) the start of the file in order to start
- // decoding at all. After that there could be one every half second or so,
- // there could be one at the start of each scene (aka "cut", "shot") or
- // there could be no more at all.
- // If there is only a single type 1 frame then NO FRAMES CAN BE DROPPED
- // without losing all the rest of the movie. There is no way to tell whether
- // this is the case, so we find that we are in the gambling business.
- // To try to improve the odds, we record the greatest interval between type 1s
- // that we have seen and we bet on things being no worse than this in the
- // future.
-
- // You can tell if it's a type 1 frame by calling IsSyncPoint().
- // there is no architected way to test for a type 3, so you should override
- // the quality management here if you have B-frames.
-
- int m_nKeyFramePeriod; // the largest observed interval between type 1 frames
- // 1 means every frame is type 1, 2 means every other.
-
- int m_nFramesSinceKeyFrame; // Used to count frames since the last type 1.
- // becomes the new m_nKeyFramePeriod if greater.
-
- BOOL m_bSkipping; // we are skipping to the next type 1 frame
-
-#ifdef PERF
- int m_idFrameType; // MSR id Frame type. 1=Key, 2="non-key"
- int m_idSkip; // MSR id skipping
- int m_idLate; // MSR id lateness
- int m_idTimeTillKey; // MSR id for guessed time till next key frame.
-#endif
-
- virtual HRESULT StartStreaming();
-
- HRESULT AbortPlayback(HRESULT hr); // if something bad happens
-
- HRESULT Receive(IMediaSample *pSample);
-
- HRESULT AlterQuality(Quality q);
-
- BOOL ShouldSkipFrame(IMediaSample * pIn);
-
- int m_itrLate; // lateness from last Quality message
- // (this overflows at 214 secs late).
- int m_tDecodeStart; // timeGetTime when decode started.
- int m_itrAvgDecode; // Average decode time in reference units.
-
- BOOL m_bNoSkip; // debug - no skipping.
-
- // We send an EC_QUALITY_CHANGE notification to the app if we have to degrade.
- // We send one when we start degrading, not one for every frame, this means
- // we track whether we've sent one yet.
- BOOL m_bQualityChanged;
-
- // When non-zero, don't pass anything to renderer until next keyframe
- // If there are few keys, give up and eventually draw something
- int m_nWaitForKey;
-};
diff --git a/third_party/BaseClasses/winctrl.cpp b/third_party/BaseClasses/winctrl.cpp
deleted file mode 100644
index 4d1f52e3..00000000
--- a/third_party/BaseClasses/winctrl.cpp
+++ /dev/null
@@ -1,2081 +0,0 @@
-//------------------------------------------------------------------------------
-// File: WinCtrl.cpp
-//
-// Desc: DirectShow base classes - implements video control interface class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <intsafe.h>
-#include <checkbmi.h>
-
-// The control interface methods require us to be connected
-
-#define CheckConnected(pin,code) \
-{ \
- if (pin == NULL) { \
- ASSERT(!TEXT("Pin not set")); \
- } else if (pin->IsConnected() == FALSE) { \
- return (code); \
- } \
-}
-
-// This checks to see whether the window has a drain. An application can in
-// most environments set the owner/parent of windows so that they appear in
-// a compound document context (for example). In this case, the application
-// would probably like to be told of any keyboard/mouse messages. Therefore
-// we pass these messages on untranslated, returning TRUE if we're successful
-
-BOOL WINAPI PossiblyEatMessage(HWND hwndDrain, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (hwndDrain != NULL && !InSendMessage())
- {
- switch (uMsg)
- {
- case WM_CHAR:
- case WM_DEADCHAR:
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- case WM_MOUSEACTIVATE:
- case WM_MOUSEMOVE:
- // If we pass this on we don't get any mouse clicks
- //case WM_NCHITTEST:
- case WM_NCLBUTTONDBLCLK:
- case WM_NCLBUTTONDOWN:
- case WM_NCLBUTTONUP:
- case WM_NCMBUTTONDBLCLK:
- case WM_NCMBUTTONDOWN:
- case WM_NCMBUTTONUP:
- case WM_NCMOUSEMOVE:
- case WM_NCRBUTTONDBLCLK:
- case WM_NCRBUTTONDOWN:
- case WM_NCRBUTTONUP:
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_SYSCHAR:
- case WM_SYSDEADCHAR:
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
-
- DbgLog((LOG_TRACE, 2, TEXT("Forwarding %x to drain")));
- PostMessage(hwndDrain, uMsg, wParam, lParam);
-
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
-// This class implements the IVideoWindow control functions (dual interface)
-// we support a large number of properties and methods designed to allow the
-// client (whether it be an automation controller or a C/C++ application) to
-// set and get a number of window related properties such as it's position.
-// We also support some methods that duplicate the properties but provide a
-// more direct and efficient mechanism as many values may be changed in one
-
-CBaseControlWindow::CBaseControlWindow(
- __inout CBaseFilter *pFilter, // Owning filter
- __in CCritSec *pInterfaceLock, // Locking object
- __in_opt LPCTSTR pName, // Object description
- __inout_opt LPUNKNOWN pUnk, // Normal COM ownership
- __inout HRESULT *phr) : // OLE return code
-
- CBaseVideoWindow(pName,pUnk),
- m_pInterfaceLock(pInterfaceLock),
- m_hwndOwner(NULL),
- m_hwndDrain(NULL),
- m_bAutoShow(TRUE),
- m_pFilter(pFilter),
- m_bCursorHidden(FALSE),
- m_pPin(NULL)
-{
- ASSERT(m_pFilter);
- ASSERT(m_pInterfaceLock);
- ASSERT(phr);
- m_BorderColour = VIDEO_COLOUR;
-}
-
-
-// Set the title caption on the base window, we don't do any field checking
-// as we really don't care what title they intend to have. We can always get
-// it back again later with GetWindowText. The only other complication is to
-// do the necessary string conversions between ANSI and OLE Unicode strings
-
-STDMETHODIMP CBaseControlWindow::put_Caption(__in BSTR strCaption)
-{
- CheckPointer((PVOID)strCaption,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-#ifdef UNICODE
- SetWindowText(m_hwnd, strCaption);
-#else
- CHAR Caption[CAPTION];
-
- WideCharToMultiByte(CP_ACP,0,strCaption,-1,Caption,CAPTION,NULL,NULL);
- SetWindowText(m_hwnd, Caption);
-#endif
- return NOERROR;
-}
-
-
-// Get the current base window title caption, once again we do no real field
-// checking. We allocate a string for the window title to be filled in with
-// which ensures the interface doesn't fiddle around with getting memory. A
-// BSTR is a normal C string with the length at position (-1), we use the
-// WriteBSTR helper function to create the caption to try and avoid OLE32
-
-STDMETHODIMP CBaseControlWindow::get_Caption(__out BSTR *pstrCaption)
-{
- CheckPointer(pstrCaption,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- WCHAR WideCaption[CAPTION];
-
-#ifdef UNICODE
- GetWindowText(m_hwnd,WideCaption,CAPTION);
-#else
- // Convert the ASCII caption to a UNICODE string
-
- TCHAR Caption[CAPTION];
- GetWindowText(m_hwnd,Caption,CAPTION);
- MultiByteToWideChar(CP_ACP,0,Caption,-1,WideCaption,CAPTION);
-#endif
- return WriteBSTR(pstrCaption,WideCaption);
-}
-
-
-// Set the window style using GWL_EXSTYLE
-
-STDMETHODIMP CBaseControlWindow::put_WindowStyleEx(long WindowStyleEx)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Should we be taking off WS_EX_TOPMOST
-
- if (GetWindowLong(m_hwnd,GWL_EXSTYLE) & WS_EX_TOPMOST) {
- if ((WindowStyleEx & WS_EX_TOPMOST) == 0) {
- SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) FALSE,(LPARAM) 0);
- }
- }
-
- // Likewise should we be adding WS_EX_TOPMOST
-
- if (WindowStyleEx & WS_EX_TOPMOST) {
- SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) TRUE,(LPARAM) 0);
- WindowStyleEx &= (~WS_EX_TOPMOST);
- if (WindowStyleEx == 0) return NOERROR;
- }
- return DoSetWindowStyle(WindowStyleEx,GWL_EXSTYLE);
-}
-
-
-// Gets the current GWL_EXSTYLE base window style
-
-STDMETHODIMP CBaseControlWindow::get_WindowStyleEx(__out long *pWindowStyleEx)
-{
- CheckPointer(pWindowStyleEx,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- return DoGetWindowStyle(pWindowStyleEx,GWL_EXSTYLE);
-}
-
-
-// Set the window style using GWL_STYLE
-
-STDMETHODIMP CBaseControlWindow::put_WindowStyle(long WindowStyle)
-{
- // These styles cannot be changed dynamically
-
- if ((WindowStyle & WS_DISABLED) ||
- (WindowStyle & WS_ICONIC) ||
- (WindowStyle & WS_MAXIMIZE) ||
- (WindowStyle & WS_MINIMIZE) ||
- (WindowStyle & WS_HSCROLL) ||
- (WindowStyle & WS_VSCROLL)) {
-
- return E_INVALIDARG;
- }
-
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- return DoSetWindowStyle(WindowStyle,GWL_STYLE);
-}
-
-
-// Get the current GWL_STYLE base window style
-
-STDMETHODIMP CBaseControlWindow::get_WindowStyle(__out long *pWindowStyle)
-{
- CheckPointer(pWindowStyle,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- return DoGetWindowStyle(pWindowStyle,GWL_STYLE);
-}
-
-
-// Change the base window style or the extended styles depending on whether
-// WindowLong is GWL_STYLE or GWL_EXSTYLE. We must call SetWindowPos to have
-// the window displayed in it's new style after the change which is a little
-// tricky if the window is not currently visible as we realise it offscreen.
-// In most cases the client will call get_WindowStyle before they call this
-// and then AND and OR in extra bit settings according to the requirements
-
-HRESULT CBaseControlWindow::DoSetWindowStyle(long Style,long WindowLong)
-{
- RECT WindowRect;
-
- // Get the window's visibility before setting the style
- BOOL bVisible = IsWindowVisible(m_hwnd);
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- // Set the new style flags for the window
- SetWindowLong(m_hwnd,WindowLong,Style);
- UINT WindowFlags = SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE;
- WindowFlags |= SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
-
- // Show the window again in the current position
-
- if (bVisible == TRUE) {
-
- SetWindowPos(m_hwnd, // Base window handle
- HWND_TOP, // Just a place holder
- 0,0,0,0, // Leave size and position
- WindowFlags); // Just draw it again
-
- return NOERROR;
- }
-
- // Move the window offscreen so the user doesn't see the changes
-
- MoveWindow((HWND) m_hwnd, // Base window handle
- GetSystemMetrics(SM_CXSCREEN), // Current desktop width
- GetSystemMetrics(SM_CYSCREEN), // Likewise it's height
- WIDTH(&WindowRect), // Use the same width
- HEIGHT(&WindowRect), // Keep height same to
- TRUE); // May as well repaint
-
- // Now show the previously hidden window
-
- SetWindowPos(m_hwnd, // Base window handle
- HWND_TOP, // Just a place holder
- 0,0,0,0, // Leave size and position
- WindowFlags); // Just draw it again
-
- ShowWindow(m_hwnd,SW_HIDE);
-
- if (GetParent(m_hwnd)) {
-
- MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
- }
-
- MoveWindow((HWND) m_hwnd, // Base window handle
- WindowRect.left, // Existing x coordinate
- WindowRect.top, // Existing y coordinate
- WIDTH(&WindowRect), // Use the same width
- HEIGHT(&WindowRect), // Keep height same to
- TRUE); // May as well repaint
-
- return NOERROR;
-}
-
-
-// Get the current base window style (either GWL_STYLE or GWL_EXSTYLE)
-
-HRESULT CBaseControlWindow::DoGetWindowStyle(__out long *pStyle,long WindowLong)
-{
- *pStyle = GetWindowLong(m_hwnd,WindowLong);
- return NOERROR;
-}
-
-
-// Change the visibility of the base window, this takes the same parameters
-// as the ShowWindow Win32 API does, so the client can have the window hidden
-// or shown, minimised to an icon, or maximised to play in full screen mode
-// We pass the request on to the base window to actually make the change
-
-STDMETHODIMP CBaseControlWindow::put_WindowState(long WindowState)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- DoShowWindow(WindowState);
- return NOERROR;
-}
-
-
-// Get the current window state, this function returns a subset of the SW bit
-// settings available in ShowWindow, if the window is visible then SW_SHOW is
-// set, if it is hidden then the SW_HIDDEN is set, if it is either minimised
-// or maximised then the SW_MINIMIZE or SW_MAXIMIZE is set respectively. The
-// other SW bit settings are really set commands not readable output values
-
-STDMETHODIMP CBaseControlWindow::get_WindowState(__out long *pWindowState)
-{
- CheckPointer(pWindowState,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- ASSERT(pWindowState);
- *pWindowState = FALSE;
-
- // Is the window visible, a window is termed visible if it is somewhere on
- // the current desktop even if it is completely obscured by other windows
- // so the flag is a style for each window set with the WS_VISIBLE bit
-
- if (IsWindowVisible(m_hwnd) == TRUE) {
-
- // Is the base window iconic
- if (IsIconic(m_hwnd) == TRUE) {
- *pWindowState |= SW_MINIMIZE;
- }
-
- // Has the window been maximised
- else if (IsZoomed(m_hwnd) == TRUE) {
- *pWindowState |= SW_MAXIMIZE;
- }
-
- // Window is normal
- else {
- *pWindowState |= SW_SHOW;
- }
-
- } else {
- *pWindowState |= SW_HIDE;
- }
- return NOERROR;
-}
-
-
-// This makes sure that any palette we realise in the base window (through a
-// media type or through the overlay interface) is done in the background and
-// is therefore mapped to existing device entries rather than taking it over
-// as it will do when we this window gets the keyboard focus. An application
-// uses this to make sure it doesn't have it's palette removed by the window
-
-STDMETHODIMP CBaseControlWindow::put_BackgroundPalette(long BackgroundPalette)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cWindowLock(&m_WindowLock);
-
- // Check this is a valid automation boolean type
-
- if (BackgroundPalette != OATRUE) {
- if (BackgroundPalette != OAFALSE) {
- return E_INVALIDARG;
- }
- }
-
- // Make sure the window realises any palette it has again
-
- m_bBackground = (BackgroundPalette == OATRUE ? TRUE : FALSE);
- PostMessage(m_hwnd,m_RealizePalette,0,0);
- PaintWindow(FALSE);
-
- return NOERROR;
-}
-
-
-// This returns the current background realisation setting
-
-STDMETHODIMP
-CBaseControlWindow::get_BackgroundPalette(__out long *pBackgroundPalette)
-{
- CheckPointer(pBackgroundPalette,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cWindowLock(&m_WindowLock);
-
- // Get the current background palette setting
-
- *pBackgroundPalette = (m_bBackground == TRUE ? OATRUE : OAFALSE);
- return NOERROR;
-}
-
-
-// Change the visibility of the base window
-
-STDMETHODIMP CBaseControlWindow::put_Visible(long Visible)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Check this is a valid automation boolean type
-
- if (Visible != OATRUE) {
- if (Visible != OAFALSE) {
- return E_INVALIDARG;
- }
- }
-
- // Convert the boolean visibility into SW_SHOW and SW_HIDE
-
- INT Mode = (Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE);
- DoShowWindow(Mode);
- return NOERROR;
-}
-
-
-// Return OATRUE if the window is currently visible otherwise OAFALSE
-
-STDMETHODIMP CBaseControlWindow::get_Visible(__out long *pVisible)
-{
- CheckPointer(pVisible,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // See if the base window has a WS_VISIBLE style - this will return TRUE
- // even if the window is completely obscured by other desktop windows, we
- // return FALSE if the window is not showing because of earlier calls
-
- BOOL Mode = IsWindowVisible(m_hwnd);
- *pVisible = (Mode == TRUE ? OATRUE : OAFALSE);
- return NOERROR;
-}
-
-
-// Change the left position of the base window. This keeps the window width
-// and height properties the same so it effectively shunts the window left or
-// right accordingly - there is the Width property to change that dimension
-
-STDMETHODIMP CBaseControlWindow::put_Left(long Left)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bSuccess;
- RECT WindowRect;
-
- // Get the current window position in a RECT
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- if (GetParent(m_hwnd)) {
-
- MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
- }
-
- // Adjust the coordinates ready for SetWindowPos, the window rectangle we
- // get back from GetWindowRect is in left,top,right and bottom while the
- // coordinates SetWindowPos wants are left,top,width and height values
-
- WindowRect.bottom = WindowRect.bottom - WindowRect.top;
- WindowRect.right = WindowRect.right - WindowRect.left;
- UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
-
- bSuccess = SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- Left, // New left position
- WindowRect.top, // Leave top alone
- WindowRect.right, // The WIDTH (not right)
- WindowRect.bottom, // The HEIGHT (not bottom)
- WindowFlags); // Show window options
-
- if (bSuccess == FALSE) {
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// Return the current base window left position
-
-STDMETHODIMP CBaseControlWindow::get_Left(__out long *pLeft)
-{
- CheckPointer(pLeft,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT WindowRect;
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
- *pLeft = WindowRect.left;
- return NOERROR;
-}
-
-
-// Change the current width of the base window. This property complements the
-// left position property so we must keep the left edge constant and expand or
-// contract to the right, the alternative would be to change the left edge so
-// keeping the right edge constant but this is maybe a little more intuitive
-
-STDMETHODIMP CBaseControlWindow::put_Width(long Width)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bSuccess;
- RECT WindowRect;
-
- // Adjust the coordinates ready for SetWindowPos, the window rectangle we
- // get back from GetWindowRect is in left,top,right and bottom while the
- // coordinates SetWindowPos wants are left,top,width and height values
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- if (GetParent(m_hwnd)) {
-
- MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
- }
-
- WindowRect.bottom = WindowRect.bottom - WindowRect.top;
- UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
-
- // This seems to have a bug in that calling SetWindowPos on a window with
- // just the width changing causes it to ignore the width that you pass in
- // and sets it to a mimimum value of 110 pixels wide (Windows NT 3.51)
-
- bSuccess = SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- WindowRect.left, // Leave left alone
- WindowRect.top, // Leave top alone
- Width, // New WIDTH dimension
- WindowRect.bottom, // The HEIGHT (not bottom)
- WindowFlags); // Show window options
-
- if (bSuccess == FALSE) {
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// Return the current base window width
-
-STDMETHODIMP CBaseControlWindow::get_Width(__out long *pWidth)
-{
- CheckPointer(pWidth,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT WindowRect;
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
- *pWidth = WindowRect.right - WindowRect.left;
- return NOERROR;
-}
-
-
-// This allows the client program to change the top position for the window in
-// the same way that changing the left position does not affect the width of
-// the image so changing the top position does not affect the window height
-
-STDMETHODIMP CBaseControlWindow::put_Top(long Top)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bSuccess;
- RECT WindowRect;
-
- // Get the current window position in a RECT
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- if (GetParent(m_hwnd)) {
-
- MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
- }
-
- // Adjust the coordinates ready for SetWindowPos, the window rectangle we
- // get back from GetWindowRect is in left,top,right and bottom while the
- // coordinates SetWindowPos wants are left,top,width and height values
-
- WindowRect.bottom = WindowRect.bottom - WindowRect.top;
- WindowRect.right = WindowRect.right - WindowRect.left;
- UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
-
- bSuccess = SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- WindowRect.left, // Leave left alone
- Top, // New top position
- WindowRect.right, // The WIDTH (not right)
- WindowRect.bottom, // The HEIGHT (not bottom)
- WindowFlags); // Show window flags
-
- if (bSuccess == FALSE) {
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// Return the current base window top position
-
-STDMETHODIMP CBaseControlWindow::get_Top(long *pTop)
-{
- CheckPointer(pTop,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT WindowRect;
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
- *pTop = WindowRect.top;
- return NOERROR;
-}
-
-
-// Change the height of the window, this complements the top property so when
-// we change this we must keep the top position for the base window, as said
-// before we could keep the bottom and grow upwards although this is perhaps
-// a little more intuitive since we already have a top position property
-
-STDMETHODIMP CBaseControlWindow::put_Height(long Height)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bSuccess;
- RECT WindowRect;
-
- // Adjust the coordinates ready for SetWindowPos, the window rectangle we
- // get back from GetWindowRect is in left,top,right and bottom while the
- // coordinates SetWindowPos wants are left,top,width and height values
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- if (GetParent(m_hwnd)) {
-
- MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2);
- }
-
- WindowRect.right = WindowRect.right - WindowRect.left;
- UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
-
- bSuccess = SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- WindowRect.left, // Leave left alone
- WindowRect.top, // Leave top alone
- WindowRect.right, // The WIDTH (not right)
- Height, // New height dimension
- WindowFlags); // Show window flags
-
- if (bSuccess == FALSE) {
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// Return the current base window height
-
-STDMETHODIMP CBaseControlWindow::get_Height(__out long *pHeight)
-{
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT WindowRect;
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
- *pHeight = WindowRect.bottom - WindowRect.top;
- return NOERROR;
-}
-
-
-// This can be called to change the owning window. Setting the owner is done
-// through this function, however to make the window a true child window the
-// style must also be set to WS_CHILD. After resetting the owner to NULL an
-// application should also set the style to WS_OVERLAPPED | WS_CLIPCHILDREN.
-
-// We cannot lock the object here because the SetParent causes an interthread
-// SendMessage to the owner window. If they are in GetState we will sit here
-// incomplete with the critical section locked therefore blocking out source
-// filter threads from accessing us. Because the source thread can't enter us
-// it can't get buffers or call EndOfStream so the GetState will not complete
-
-STDMETHODIMP CBaseControlWindow::put_Owner(OAHWND Owner)
-{
- // Check we are connected otherwise reject the call
-
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- m_hwndOwner = (HWND) Owner;
- HWND hwndParent = m_hwndOwner;
-
- // Add or remove WS_CHILD as appropriate
-
- LONG Style = GetWindowLong(m_hwnd,GWL_STYLE);
- if (Owner == NULL) {
- Style &= (~WS_CHILD);
- } else {
- Style |= (WS_CHILD);
- }
- SetWindowLong(m_hwnd,GWL_STYLE,Style);
-
- // Don't call this with the filter locked
-
- SetParent(m_hwnd,hwndParent);
-
- PaintWindow(TRUE);
- NOTE1("Changed parent %lx",hwndParent);
-
- return NOERROR;
-}
-
-
-// This complements the put_Owner to get the current owning window property
-// we always return NOERROR although the returned window handle may be NULL
-// to indicate no owning window (the desktop window doesn't qualify as one)
-// If an application sets the owner we call SetParent, however that returns
-// NULL until the WS_CHILD bit is set on, so we store the owner internally
-
-STDMETHODIMP CBaseControlWindow::get_Owner(__out OAHWND *Owner)
-{
- CheckPointer(Owner,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- *Owner = (OAHWND) m_hwndOwner;
- return NOERROR;
-}
-
-
-// And renderer supporting IVideoWindow may have an HWND set who will get any
-// keyboard and mouse messages we receive posted on to them. This is separate
-// from setting an owning window. By separating the two, applications may get
-// messages sent on even when they have set no owner (perhaps it's maximised)
-
-STDMETHODIMP CBaseControlWindow::put_MessageDrain(OAHWND Drain)
-{
- // Check we are connected otherwise reject the call
-
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- m_hwndDrain = (HWND) Drain;
- return NOERROR;
-}
-
-
-// Return the current message drain
-
-STDMETHODIMP CBaseControlWindow::get_MessageDrain(__out OAHWND *Drain)
-{
- CheckPointer(Drain,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- *Drain = (OAHWND) m_hwndDrain;
- return NOERROR;
-}
-
-
-// This is called by the filter graph to inform us of a message we should know
-// is being sent to our owning window. We have this because as a child window
-// we do not get certain messages that are only sent to top level windows. We
-// must see the palette changed/changing/query messages so that we know if we
-// have the foreground palette or not. We pass the message on to our window
-// using SendMessage - this will cause an interthread send message to occur
-
-STDMETHODIMP
-CBaseControlWindow::NotifyOwnerMessage(OAHWND hwnd, // Window handle
- long uMsg, // Message ID
- LONG_PTR wParam, // Parameters
- LONG_PTR lParam) // for message
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Only interested in these Windows messages
-
- switch (uMsg) {
-
- case WM_SYSCOLORCHANGE:
- case WM_PALETTECHANGED:
- case WM_PALETTEISCHANGING:
- case WM_QUERYNEWPALETTE:
- case WM_DEVMODECHANGE:
- case WM_DISPLAYCHANGE:
- case WM_ACTIVATEAPP:
-
- // If we do not have an owner then ignore
-
- if (m_hwndOwner == NULL) {
- return NOERROR;
- }
- SendMessage(m_hwnd,uMsg,(WPARAM)wParam,(LPARAM)lParam);
- break;
-
- // do NOT fwd WM_MOVE. the parameters are the location of the parent
- // window, NOT what the renderer should be looking at. But we need
- // to make sure the overlay is moved with the parent window, so we
- // do this.
- case WM_MOVE:
- PostMessage(m_hwnd,WM_PAINT,0,0);
- break;
- }
- return NOERROR;
-}
-
-
-// Allow an application to have us set the base window in the foreground. We
-// have this because it is difficult for one thread to do do this to a window
-// owned by another thread. We ask the base window class to do the real work
-
-STDMETHODIMP CBaseControlWindow::SetWindowForeground(long Focus)
-{
- // Check this is a valid automation boolean type
-
- if (Focus != OATRUE) {
- if (Focus != OAFALSE) {
- return E_INVALIDARG;
- }
- }
-
- // We shouldn't lock as this sends a message
-
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bFocus = (Focus == OATRUE ? TRUE : FALSE);
- DoSetWindowForeground(bFocus);
-
- return NOERROR;
-}
-
-
-// This allows a client to set the complete window size and position in one
-// atomic operation. The same affect can be had by changing each dimension
-// in turn through their individual properties although some flashing will
-// occur as each of them gets updated (they are better set at design time)
-
-STDMETHODIMP
-CBaseControlWindow::SetWindowPosition(long Left,long Top,long Width,long Height)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- BOOL bSuccess;
-
- // Set the new size and position
- UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE;
-
- ASSERT(IsWindow(m_hwnd));
- bSuccess = SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- Left, // Left position
- Top, // Top position
- Width, // Window width
- Height, // Window height
- WindowFlags); // Show window flags
- ASSERT(bSuccess);
-#ifdef DEBUG
- DbgLog((LOG_TRACE, 1, TEXT("SWP failed error %d"), GetLastError()));
-#endif
- if (bSuccess == FALSE) {
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// This complements the SetWindowPosition to return the current window place
-// in device coordinates. As before the same information can be retrived by
-// calling the property get functions individually but this is atomic and is
-// therefore more suitable to a live environment rather than design time
-
-STDMETHODIMP
-CBaseControlWindow::GetWindowPosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight)
-{
- // Should check the pointers are not NULL
-
- CheckPointer(pLeft,E_POINTER);
- CheckPointer(pTop,E_POINTER);
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT WindowRect;
-
- // Get the current window coordinates
-
- EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect));
-
- // Convert the RECT into left,top,width and height values
-
- *pLeft = WindowRect.left;
- *pTop = WindowRect.top;
- *pWidth = WindowRect.right - WindowRect.left;
- *pHeight = WindowRect.bottom - WindowRect.top;
-
- return NOERROR;
-}
-
-
-// When a window is maximised or iconic calling GetWindowPosition will return
-// the current window position (likewise for the properties). However if the
-// restored size (ie the size we'll return to when normally shown) is needed
-// then this should be used. When in a normal position (neither iconic nor
-// maximised) then this returns the same coordinates as GetWindowPosition
-
-STDMETHODIMP
-CBaseControlWindow::GetRestorePosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight)
-{
- // Should check the pointers are not NULL
-
- CheckPointer(pLeft,E_POINTER);
- CheckPointer(pTop,E_POINTER);
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Use GetWindowPlacement to find the restore position
-
- WINDOWPLACEMENT Place;
- Place.length = sizeof(WINDOWPLACEMENT);
- EXECUTE_ASSERT(GetWindowPlacement(m_hwnd,&Place));
-
- RECT WorkArea;
-
- // We must take into account any task bar present
-
- if (SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,FALSE) == TRUE) {
- if (GetParent(m_hwnd) == NULL) {
- Place.rcNormalPosition.top += WorkArea.top;
- Place.rcNormalPosition.bottom += WorkArea.top;
- Place.rcNormalPosition.left += WorkArea.left;
- Place.rcNormalPosition.right += WorkArea.left;
- }
- }
-
- // Convert the RECT into left,top,width and height values
-
- *pLeft = Place.rcNormalPosition.left;
- *pTop = Place.rcNormalPosition.top;
- *pWidth = Place.rcNormalPosition.right - Place.rcNormalPosition.left;
- *pHeight = Place.rcNormalPosition.bottom - Place.rcNormalPosition.top;
-
- return NOERROR;
-}
-
-
-// Return the current border colour, if we are playing something to a subset
-// of the base window display there is an outside area exposed. The default
-// action is to paint this colour in the Windows background colour (defined
-// as value COLOR_WINDOW) We reset to this default when we're disconnected
-
-STDMETHODIMP CBaseControlWindow::get_BorderColor(__out long *Color)
-{
- CheckPointer(Color,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- *Color = (long) m_BorderColour;
- return NOERROR;
-}
-
-
-// This can be called to set the current border colour
-
-STDMETHODIMP CBaseControlWindow::put_BorderColor(long Color)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Have the window repainted with the new border colour
-
- m_BorderColour = (COLORREF) Color;
- PaintWindow(TRUE);
- return NOERROR;
-}
-
-
-// Delegate fullscreen handling to plug in distributor
-
-STDMETHODIMP CBaseControlWindow::get_FullScreenMode(__out long *FullScreenMode)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CheckPointer(FullScreenMode,E_POINTER);
- return E_NOTIMPL;
-}
-
-
-// Delegate fullscreen handling to plug in distributor
-
-STDMETHODIMP CBaseControlWindow::put_FullScreenMode(long FullScreenMode)
-{
- return E_NOTIMPL;
-}
-
-
-// This sets the auto show property, this property causes the base window to
-// be displayed whenever we change state. This allows an application to have
-// to do nothing to have the window appear but still allow them to change the
-// default behaviour if for example they want to keep it hidden for longer
-
-STDMETHODIMP CBaseControlWindow::put_AutoShow(long AutoShow)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Check this is a valid automation boolean type
-
- if (AutoShow != OATRUE) {
- if (AutoShow != OAFALSE) {
- return E_INVALIDARG;
- }
- }
-
- m_bAutoShow = (AutoShow == OATRUE ? TRUE : FALSE);
- return NOERROR;
-}
-
-
-// This can be called to get the current auto show flag. The flag is updated
-// when we connect and disconnect and through this interface all of which are
-// controlled and serialised by means of the main renderer critical section
-
-STDMETHODIMP CBaseControlWindow::get_AutoShow(__out long *AutoShow)
-{
- CheckPointer(AutoShow,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- *AutoShow = (m_bAutoShow == TRUE ? OATRUE : OAFALSE);
- return NOERROR;
-}
-
-
-// Return the minimum ideal image size for the current video. This may differ
-// to the actual video dimensions because we may be using DirectDraw hardware
-// that has specific stretching requirements. For example the Cirrus Logic
-// cards have a minimum stretch factor depending on the overlay surface size
-
-STDMETHODIMP
-CBaseControlWindow::GetMinIdealImageSize(__out long *pWidth,__out long *pHeight)
-{
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- FILTER_STATE State;
-
- // Must not be stopped for this to work correctly
-
- m_pFilter->GetState(0,&State);
- if (State == State_Stopped) {
- return VFW_E_WRONG_STATE;
- }
-
- RECT DefaultRect = GetDefaultRect();
- *pWidth = WIDTH(&DefaultRect);
- *pHeight = HEIGHT(&DefaultRect);
- return NOERROR;
-}
-
-
-// Return the maximum ideal image size for the current video. This may differ
-// to the actual video dimensions because we may be using DirectDraw hardware
-// that has specific stretching requirements. For example the Cirrus Logic
-// cards have a maximum stretch factor depending on the overlay surface size
-
-STDMETHODIMP
-CBaseControlWindow::GetMaxIdealImageSize(__out long *pWidth,__out long *pHeight)
-{
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- FILTER_STATE State;
-
- // Must not be stopped for this to work correctly
-
- m_pFilter->GetState(0,&State);
- if (State == State_Stopped) {
- return VFW_E_WRONG_STATE;
- }
-
- RECT DefaultRect = GetDefaultRect();
- *pWidth = WIDTH(&DefaultRect);
- *pHeight = HEIGHT(&DefaultRect);
- return NOERROR;
-}
-
-
-// Allow an application to hide the cursor on our window
-
-STDMETHODIMP
-CBaseControlWindow::HideCursor(long HideCursor)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
-
- // Check this is a valid automation boolean type
-
- if (HideCursor != OATRUE) {
- if (HideCursor != OAFALSE) {
- return E_INVALIDARG;
- }
- }
-
- m_bCursorHidden = (HideCursor == OATRUE ? TRUE : FALSE);
- return NOERROR;
-}
-
-
-// Returns whether we have the cursor hidden or not
-
-STDMETHODIMP CBaseControlWindow::IsCursorHidden(__out long *CursorHidden)
-{
- CheckPointer(CursorHidden,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- *CursorHidden = (m_bCursorHidden == TRUE ? OATRUE : OAFALSE);
- return NOERROR;
-}
-
-
-// This class implements the IBasicVideo control functions (dual interface)
-// we support a large number of properties and methods designed to allow the
-// client (whether it be an automation controller or a C/C++ application) to
-// set and get a number of video related properties such as the native video
-// size. We support some methods that duplicate the properties but provide a
-// more direct and efficient mechanism as many values may be changed in one
-
-CBaseControlVideo::CBaseControlVideo(
- __inout CBaseFilter *pFilter, // Owning filter
- __in CCritSec *pInterfaceLock, // Locking object
- __in_opt LPCTSTR pName, // Object description
- __inout_opt LPUNKNOWN pUnk, // Normal COM ownership
- __inout HRESULT *phr) : // OLE return code
-
- CBaseBasicVideo(pName,pUnk),
- m_pFilter(pFilter),
- m_pInterfaceLock(pInterfaceLock),
- m_pPin(NULL)
-{
- ASSERT(m_pFilter);
- ASSERT(m_pInterfaceLock);
- ASSERT(phr);
-}
-
-// Return an approximate average time per frame
-
-STDMETHODIMP CBaseControlVideo::get_AvgTimePerFrame(__out REFTIME *pAvgTimePerFrame)
-{
- CheckPointer(pAvgTimePerFrame,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- COARefTime AvgTime(pVideoInfo->AvgTimePerFrame);
- *pAvgTimePerFrame = (REFTIME) AvgTime;
-
- return NOERROR;
-}
-
-
-// Return an approximate bit rate for the video
-
-STDMETHODIMP CBaseControlVideo::get_BitRate(__out long *pBitRate)
-{
- CheckPointer(pBitRate,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- *pBitRate = pVideoInfo->dwBitRate;
- return NOERROR;
-}
-
-
-// Return an approximate bit error rate
-
-STDMETHODIMP CBaseControlVideo::get_BitErrorRate(__out long *pBitErrorRate)
-{
- CheckPointer(pBitErrorRate,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- *pBitErrorRate = pVideoInfo->dwBitErrorRate;
- return NOERROR;
-}
-
-
-// This returns the current video width
-
-STDMETHODIMP CBaseControlVideo::get_VideoWidth(__out long *pVideoWidth)
-{
- CheckPointer(pVideoWidth,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- *pVideoWidth = pVideoInfo->bmiHeader.biWidth;
- return NOERROR;
-}
-
-
-// This returns the current video height
-
-STDMETHODIMP CBaseControlVideo::get_VideoHeight(__out long *pVideoHeight)
-{
- CheckPointer(pVideoHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- *pVideoHeight = pVideoInfo->bmiHeader.biHeight;
- return NOERROR;
-}
-
-
-// This returns the current palette the video is using as an array allocated
-// by the user. To remain consistent we use PALETTEENTRY fields to return the
-// colours in rather than RGBQUADs that multimedia decided to use. The memory
-// is allocated by the user so we simple copy each in turn. We check that the
-// number of entries requested and the start position offset are both valid
-// If the number of entries evaluates to zero then we return an S_FALSE code
-
-STDMETHODIMP CBaseControlVideo::GetVideoPaletteEntries(long StartIndex,
- long Entries,
- __out long *pRetrieved,
- __out_ecount_part(Entries, *pRetrieved) long *pPalette)
-{
- CheckPointer(pRetrieved,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- CMediaType MediaType;
-
- // Get the video format from the derived class
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo);
-
- // Is the current format palettised
-
- if (PALETTISED(pVideoInfo) == FALSE) {
- *pRetrieved = 0;
- return VFW_E_NO_PALETTE_AVAILABLE;
- }
-
- // Do they just want to know how many are available
-
- if (pPalette == NULL) {
- *pRetrieved = pHeader->biClrUsed;
- return NOERROR;
- }
-
- // Make sure the start position is a valid offset
-
- if (StartIndex >= (LONG) pHeader->biClrUsed || StartIndex < 0) {
- *pRetrieved = 0;
- return E_INVALIDARG;
- }
-
- // Correct the number we can retrieve
-
- LONG Available = (LONG) pHeader->biClrUsed - StartIndex;
- *pRetrieved = max(0,min(Available,Entries));
- if (*pRetrieved == 0) {
- return S_FALSE;
- }
-
- // Copy the palette entries to the output buffer
-
- PALETTEENTRY *pEntries = (PALETTEENTRY *) pPalette;
- RGBQUAD *pColours = COLORS(pVideoInfo) + StartIndex;
-
- for (LONG Count = 0;Count < *pRetrieved;Count++) {
- pEntries[Count].peRed = pColours[Count].rgbRed;
- pEntries[Count].peGreen = pColours[Count].rgbGreen;
- pEntries[Count].peBlue = pColours[Count].rgbBlue;
- pEntries[Count].peFlags = 0;
- }
- return NOERROR;
-}
-
-
-// This returns the current video dimensions as a method rather than a number
-// of individual property get calls. For the same reasons as said before we
-// cannot access the renderer media type directly as the window object thread
-// may be updating it since dynamic format changes may change these values
-
-STDMETHODIMP CBaseControlVideo::GetVideoSize(__out long *pWidth,__out long *pHeight)
-{
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
-
- // Get the video format from the derived class
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- *pWidth = pVideoInfo->bmiHeader.biWidth;
- *pHeight = pVideoInfo->bmiHeader.biHeight;
- return NOERROR;
-}
-
-
-// Set the source video rectangle as left,top,right and bottom coordinates
-// rather than left,top,width and height as per OLE automation interfaces
-// Then pass the rectangle on to the window object to set the source
-
-STDMETHODIMP
-CBaseControlVideo::SetSourcePosition(long Left,long Top,long Width,long Height)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
- SourceRect.left = Left;
- SourceRect.top = Top;
- SourceRect.right = Left + Width;
- SourceRect.bottom = Top + Height;
-
- // Check the source rectangle is valid
-
- HRESULT hr = CheckSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the source rectangle
-
- hr = SetSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the source rectangle in left,top,width and height rather than the
-// left,top,right and bottom values that RECT uses (and which the window
-// object returns through GetSourceRect) which requires a little work
-
-STDMETHODIMP
-CBaseControlVideo::GetSourcePosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight)
-{
- // Should check the pointers are non NULL
-
- CheckPointer(pLeft,E_POINTER);
- CheckPointer(pTop,E_POINTER);
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT SourceRect;
-
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- GetSourceRect(&SourceRect);
-
- *pLeft = SourceRect.left;
- *pTop = SourceRect.top;
- *pWidth = WIDTH(&SourceRect);
- *pHeight = HEIGHT(&SourceRect);
-
- return NOERROR;
-}
-
-
-// Set the video destination as left,top,right and bottom coordinates rather
-// than the left,top,width and height uses as per OLE automation interfaces
-// Then pass the rectangle on to the window object to set the destination
-
-STDMETHODIMP
-CBaseControlVideo::SetDestinationPosition(long Left,long Top,long Width,long Height)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
-
- DestinationRect.left = Left;
- DestinationRect.top = Top;
- DestinationRect.right = Left + Width;
- DestinationRect.bottom = Top + Height;
-
- // Check the target rectangle is valid
-
- HRESULT hr = CheckTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the new target rectangle
-
- hr = SetTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the destination rectangle in left,top,width and height rather than
-// the left,top,right and bottom values that RECT uses (and which the window
-// object returns through GetDestinationRect) which requires a little work
-
-STDMETHODIMP
-CBaseControlVideo::GetDestinationPosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight)
-{
- // Should check the pointers are not NULL
-
- CheckPointer(pLeft,E_POINTER);
- CheckPointer(pTop,E_POINTER);
- CheckPointer(pWidth,E_POINTER);
- CheckPointer(pHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- RECT DestinationRect;
-
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- GetTargetRect(&DestinationRect);
-
- *pLeft = DestinationRect.left;
- *pTop = DestinationRect.top;
- *pWidth = WIDTH(&DestinationRect);
- *pHeight = HEIGHT(&DestinationRect);
-
- return NOERROR;
-}
-
-
-// Set the source left position, the source rectangle we get back from the
-// window object is a true rectangle in left,top,right and bottom positions
-// so all we have to do is to update the left position and pass it back. We
-// must keep the current width constant when we're updating this property
-
-STDMETHODIMP CBaseControlVideo::put_SourceLeft(long SourceLeft)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
- GetSourceRect(&SourceRect);
- SourceRect.right = SourceLeft + WIDTH(&SourceRect);
- SourceRect.left = SourceLeft;
-
- // Check the source rectangle is valid
-
- HRESULT hr = CheckSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the source rectangle
-
- hr = SetSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the current left source video position
-
-STDMETHODIMP CBaseControlVideo::get_SourceLeft(__out long *pSourceLeft)
-{
- CheckPointer(pSourceLeft,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
-
- GetSourceRect(&SourceRect);
- *pSourceLeft = SourceRect.left;
- return NOERROR;
-}
-
-
-// Set the source width, we get the current source rectangle and then update
-// the right position to be the left position (thereby keeping it constant)
-// plus the new source width we are passed in (it expands to the right)
-
-STDMETHODIMP CBaseControlVideo::put_SourceWidth(long SourceWidth)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
- GetSourceRect(&SourceRect);
- SourceRect.right = SourceRect.left + SourceWidth;
-
- // Check the source rectangle is valid
-
- HRESULT hr = CheckSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the source rectangle
-
- hr = SetSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the current source width
-
-STDMETHODIMP CBaseControlVideo::get_SourceWidth(__out long *pSourceWidth)
-{
- CheckPointer(pSourceWidth,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
-
- GetSourceRect(&SourceRect);
- *pSourceWidth = WIDTH(&SourceRect);
- return NOERROR;
-}
-
-
-// Set the source top position - changing this property does not affect the
-// current source height. So changing this shunts the source rectangle up and
-// down appropriately. Changing the height complements this functionality by
-// keeping the top position constant and simply changing the source height
-
-STDMETHODIMP CBaseControlVideo::put_SourceTop(long SourceTop)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
- GetSourceRect(&SourceRect);
- SourceRect.bottom = SourceTop + HEIGHT(&SourceRect);
- SourceRect.top = SourceTop;
-
- // Check the source rectangle is valid
-
- HRESULT hr = CheckSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the source rectangle
-
- hr = SetSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the current top position
-
-STDMETHODIMP CBaseControlVideo::get_SourceTop(__out long *pSourceTop)
-{
- CheckPointer(pSourceTop,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
-
- GetSourceRect(&SourceRect);
- *pSourceTop = SourceRect.top;
- return NOERROR;
-}
-
-
-// Set the source height
-
-STDMETHODIMP CBaseControlVideo::put_SourceHeight(long SourceHeight)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
- GetSourceRect(&SourceRect);
- SourceRect.bottom = SourceRect.top + SourceHeight;
-
- // Check the source rectangle is valid
-
- HRESULT hr = CheckSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the source rectangle
-
- hr = SetSourceRect(&SourceRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the current source height
-
-STDMETHODIMP CBaseControlVideo::get_SourceHeight(__out long *pSourceHeight)
-{
- CheckPointer(pSourceHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT SourceRect;
-
- GetSourceRect(&SourceRect);
- *pSourceHeight = HEIGHT(&SourceRect);
- return NOERROR;
-}
-
-
-// Set the target left position, the target rectangle we get back from the
-// window object is a true rectangle in left,top,right and bottom positions
-// so all we have to do is to update the left position and pass it back. We
-// must keep the current width constant when we're updating this property
-
-STDMETHODIMP CBaseControlVideo::put_DestinationLeft(long DestinationLeft)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
- GetTargetRect(&DestinationRect);
- DestinationRect.right = DestinationLeft + WIDTH(&DestinationRect);
- DestinationRect.left = DestinationLeft;
-
- // Check the target rectangle is valid
-
- HRESULT hr = CheckTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the new target rectangle
-
- hr = SetTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the left position for the destination rectangle
-
-STDMETHODIMP CBaseControlVideo::get_DestinationLeft(__out long *pDestinationLeft)
-{
- CheckPointer(pDestinationLeft,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
-
- GetTargetRect(&DestinationRect);
- *pDestinationLeft = DestinationRect.left;
- return NOERROR;
-}
-
-
-// Set the destination width
-
-STDMETHODIMP CBaseControlVideo::put_DestinationWidth(long DestinationWidth)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
- GetTargetRect(&DestinationRect);
- DestinationRect.right = DestinationRect.left + DestinationWidth;
-
- // Check the target rectangle is valid
-
- HRESULT hr = CheckTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the new target rectangle
-
- hr = SetTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the width for the destination rectangle
-
-STDMETHODIMP CBaseControlVideo::get_DestinationWidth(__out long *pDestinationWidth)
-{
- CheckPointer(pDestinationWidth,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
-
- GetTargetRect(&DestinationRect);
- *pDestinationWidth = WIDTH(&DestinationRect);
- return NOERROR;
-}
-
-
-// Set the target top position - changing this property does not affect the
-// current target height. So changing this shunts the target rectangle up and
-// down appropriately. Changing the height complements this functionality by
-// keeping the top position constant and simply changing the target height
-
-STDMETHODIMP CBaseControlVideo::put_DestinationTop(long DestinationTop)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
- GetTargetRect(&DestinationRect);
- DestinationRect.bottom = DestinationTop + HEIGHT(&DestinationRect);
- DestinationRect.top = DestinationTop;
-
- // Check the target rectangle is valid
-
- HRESULT hr = CheckTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the new target rectangle
-
- hr = SetTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the top position for the destination rectangle
-
-STDMETHODIMP CBaseControlVideo::get_DestinationTop(__out long *pDestinationTop)
-{
- CheckPointer(pDestinationTop,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
-
- GetTargetRect(&DestinationRect);
- *pDestinationTop = DestinationRect.top;
- return NOERROR;
-}
-
-
-// Set the destination height
-
-STDMETHODIMP CBaseControlVideo::put_DestinationHeight(long DestinationHeight)
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
- GetTargetRect(&DestinationRect);
- DestinationRect.bottom = DestinationRect.top + DestinationHeight;
-
- // Check the target rectangle is valid
-
- HRESULT hr = CheckTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now set the new target rectangle
-
- hr = SetTargetRect(&DestinationRect);
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return the height for the destination rectangle
-
-STDMETHODIMP CBaseControlVideo::get_DestinationHeight(__out long *pDestinationHeight)
-{
- CheckPointer(pDestinationHeight,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- RECT DestinationRect;
-
- GetTargetRect(&DestinationRect);
- *pDestinationHeight = HEIGHT(&DestinationRect);
- return NOERROR;
-}
-
-
-// Reset the source rectangle to the full video dimensions
-
-STDMETHODIMP CBaseControlVideo::SetDefaultSourcePosition()
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- HRESULT hr = SetDefaultSourceRect();
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return S_OK if we're using the default source otherwise S_FALSE
-
-STDMETHODIMP CBaseControlVideo::IsUsingDefaultSource()
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- return IsDefaultSourceRect();
-}
-
-
-// Reset the video renderer to use the entire playback area
-
-STDMETHODIMP CBaseControlVideo::SetDefaultDestinationPosition()
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- HRESULT hr = SetDefaultTargetRect();
- if (FAILED(hr)) {
- return hr;
- }
- return OnUpdateRectangles();
-}
-
-
-// Return S_OK if we're using the default target otherwise S_FALSE
-
-STDMETHODIMP CBaseControlVideo::IsUsingDefaultDestination()
-{
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- return IsDefaultTargetRect();
-}
-
-
-// Return a copy of the current image in the video renderer
-
-STDMETHODIMP
-CBaseControlVideo::GetCurrentImage(__inout long *pBufferSize,__out_bcount_part(*pBufferSize, *pBufferSize) long *pVideoImage)
-{
- CheckPointer(pBufferSize,E_POINTER);
- CheckConnected(m_pPin,VFW_E_NOT_CONNECTED);
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- FILTER_STATE State;
-
- // Make sure we are in a paused state
-
- if (pVideoImage != NULL) {
- m_pFilter->GetState(0,&State);
- if (State != State_Paused) {
- return VFW_E_NOT_PAUSED;
- }
- return GetStaticImage(pBufferSize,pVideoImage);
- }
-
- // Just return the memory required
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- RECT SourceRect;
- GetSourceRect(&SourceRect);
- return GetImageSize(pVideoInfo,pBufferSize,&SourceRect);
-}
-
-
-// An application has two ways of using GetCurrentImage, one is to pass a real
-// buffer which should be filled with the current image. The other is to pass
-// a NULL buffer pointer which is interpreted as asking us to return how much
-// memory is required for the image. The constraints for when the latter can
-// be called are much looser. To calculate the memory required we synthesize
-// a VIDEOINFO that takes into account the source rectangle that's being used
-
-HRESULT CBaseControlVideo::GetImageSize(__in VIDEOINFOHEADER *pVideoInfo,
- __out long *pBufferSize,
- __in RECT *pSourceRect)
-{
- NOTE("Entering GetImageSize");
- ASSERT(pSourceRect);
-
- // Check we have the correct input parameters
-
- if (pSourceRect == NULL ||
- pVideoInfo == NULL ||
- pBufferSize == NULL) {
-
- return E_UNEXPECTED;
- }
-
- // Is the data format compatible
-
- if (pVideoInfo->bmiHeader.biCompression != BI_RGB) {
- if (pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) {
- return E_INVALIDARG;
- }
- }
-
- ASSERT(IsRectEmpty(pSourceRect) == FALSE);
-
- BITMAPINFOHEADER bih;
- bih.biWidth = WIDTH(pSourceRect);
- bih.biHeight = HEIGHT(pSourceRect);
- bih.biBitCount = pVideoInfo->bmiHeader.biBitCount;
- LONG Size = DIBSIZE(bih);
- Size += GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER;
- *pBufferSize = Size;
-
- return NOERROR;
-}
-
-
-// Given an IMediaSample containing a linear buffer with an image and a type
-// describing the bitmap make a rendering of the image into the output buffer
-// This may be called by derived classes who render typical video images to
-// handle the IBasicVideo GetCurrentImage method. The pVideoImage pointer may
-// be NULL when passed to GetCurrentImage in which case GetImageSize will be
-// called instead, which will just do the calculation of the memory required
-
-HRESULT CBaseControlVideo::CopyImage(IMediaSample *pMediaSample,
- __in VIDEOINFOHEADER *pVideoInfo,
- __inout long *pBufferSize,
- __out_bcount_part(*pBufferSize, *pBufferSize) BYTE *pVideoImage,
- __in RECT *pSourceRect)
-{
- NOTE("Entering CopyImage");
- ASSERT(pSourceRect);
- BYTE *pCurrentImage;
-
- // Check we have an image to copy
-
- if (pMediaSample == NULL || pSourceRect == NULL ||
- pVideoInfo == NULL || pVideoImage == NULL ||
- pBufferSize == NULL) {
-
- return E_UNEXPECTED;
- }
-
- // Is the data format compatible
-
- if (pVideoInfo->bmiHeader.biCompression != BI_RGB) {
- if (pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) {
- return E_INVALIDARG;
- }
- }
-
- if (*pBufferSize < 0) {
- return E_INVALIDARG;
- }
-
- // Arbitrarily large size to prevent integer overflow problems
- if (pVideoInfo->bmiHeader.biSize > 4096)
- {
- return E_INVALIDARG;
- }
-
- ASSERT(IsRectEmpty(pSourceRect) == FALSE);
-
- BITMAPINFOHEADER bih;
- bih.biWidth = WIDTH(pSourceRect);
- bih.biHeight = HEIGHT(pSourceRect);
- bih.biBitCount = pVideoInfo->bmiHeader.biBitCount;
- DWORD Size = GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER;
- DWORD Total;
- DWORD dwDibSize;
-
- if( !ValidateBitmapInfoHeader( HEADER(pVideoInfo), Size)) {
- return E_INVALIDARG;
- }
-
- // ValidateBitmapInfoHeader checks this but for some reason code scanning
- // tools aren't picking up the annotation
- __analysis_assume(Size >= sizeof(BITMAPINFOHEADER));
-
- if (FAILED(SAFE_DIBSIZE(&bih, &dwDibSize))) {
- return E_INVALIDARG;
- }
-
- if (FAILED(DWordAdd(Size, dwDibSize, &Total))) {
- return E_INVALIDARG;
- }
-
- // Make sure we have a large enough buffer
-
- if ((DWORD)*pBufferSize < Total) {
- return E_OUTOFMEMORY;
- }
-
- // Copy the BITMAPINFO
-
- CopyMemory((PVOID)pVideoImage, (PVOID)&pVideoInfo->bmiHeader, Size);
- ((BITMAPINFOHEADER *)pVideoImage)->biWidth = WIDTH(pSourceRect);
- ((BITMAPINFOHEADER *)pVideoImage)->biHeight = HEIGHT(pSourceRect);
- ((BITMAPINFOHEADER *)pVideoImage)->biSizeImage = DIBSIZE(bih);
- BYTE *pImageData = pVideoImage + Size;
-
- // Get the pointer to it's image data
-
- HRESULT hr = pMediaSample->GetPointer(&pCurrentImage);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Now we are ready to start copying the source scan lines
-
- LONG ScanLine = (pVideoInfo->bmiHeader.biBitCount / 8) * WIDTH(pSourceRect);
- LONG LinesToSkip = pVideoInfo->bmiHeader.biHeight;
- LinesToSkip -= pSourceRect->top + HEIGHT(pSourceRect);
- pCurrentImage += LinesToSkip * DIBWIDTHBYTES(pVideoInfo->bmiHeader);
- pCurrentImage += pSourceRect->left * (pVideoInfo->bmiHeader.biBitCount / 8);
-
- // Even money on this GP faulting sometime...
-
- for (LONG Line = 0;Line < HEIGHT(pSourceRect);Line++) {
- CopyMemory((PVOID)pImageData, (PVOID)pCurrentImage, ScanLine);
- pImageData += DIBWIDTHBYTES(*(BITMAPINFOHEADER *)pVideoImage);
- pCurrentImage += DIBWIDTHBYTES(pVideoInfo->bmiHeader);
- }
- return NOERROR;
-}
-
-
-// Called when we change media types either during connection or dynamically
-// We inform the filter graph and therefore the application that the video
-// size may have changed, we don't bother looking to see if it really has as
-// we leave that to the application - the dimensions are the event parameters
-
-HRESULT CBaseControlVideo::OnVideoSizeChange()
-{
- // Get the video format from the derived class
-
- VIDEOINFOHEADER *pVideoInfo = GetVideoFormat();
- if (pVideoInfo == NULL)
- return E_OUTOFMEMORY;
- WORD Width = (WORD) pVideoInfo->bmiHeader.biWidth;
- WORD Height = (WORD) pVideoInfo->bmiHeader.biHeight;
-
- return m_pFilter->NotifyEvent(EC_VIDEO_SIZE_CHANGED,
- MAKELPARAM(Width,Height),
- MAKEWPARAM(0,0));
-}
-
-
-// Set the video source rectangle. We must check the source rectangle against
-// the actual video dimensions otherwise when we come to draw the pictures we
-// get access violations as GDI tries to touch data outside of the image data
-// Although we store the rectangle in left, top, right and bottom coordinates
-// instead of left, top, width and height as OLE uses we do take into account
-// that the rectangle is used up to, but not including, the right column and
-// bottom row of pixels, see the Win32 documentation on RECT for more details
-
-HRESULT CBaseControlVideo::CheckSourceRect(__in RECT *pSourceRect)
-{
- CheckPointer(pSourceRect,E_POINTER);
- LONG Width,Height;
- GetVideoSize(&Width,&Height);
-
- // Check the coordinates are greater than zero
- // and that the rectangle is valid (left<right, top<bottom)
-
- if ((pSourceRect->left >= pSourceRect->right) ||
- (pSourceRect->left < 0) ||
- (pSourceRect->top >= pSourceRect->bottom) ||
- (pSourceRect->top < 0)) {
-
- return E_INVALIDARG;
- }
-
- // Check the coordinates are less than the extents
-
- if ((pSourceRect->right > Width) ||
- (pSourceRect->bottom > Height)) {
-
- return E_INVALIDARG;
- }
- return NOERROR;
-}
-
-
-// Check the target rectangle has some valid coordinates, which amounts to
-// little more than checking the destination rectangle isn't empty. Derived
-// classes may call this when they have their SetTargetRect method called to
-// check the rectangle validity, we do not update the rectangles passed in
-// Although we store the rectangle in left, top, right and bottom coordinates
-// instead of left, top, width and height as OLE uses we do take into account
-// that the rectangle is used up to, but not including, the right column and
-// bottom row of pixels, see the Win32 documentation on RECT for more details
-
-HRESULT CBaseControlVideo::CheckTargetRect(__in RECT *pTargetRect)
-{
- // Check the pointer is valid
-
- if (pTargetRect == NULL) {
- return E_POINTER;
- }
-
- // These overflow the WIDTH and HEIGHT checks
-
- if (pTargetRect->left > pTargetRect->right ||
- pTargetRect->top > pTargetRect->bottom) {
- return E_INVALIDARG;
- }
-
- // Check the rectangle has valid coordinates
-
- if (WIDTH(pTargetRect) <= 0 || HEIGHT(pTargetRect) <= 0) {
- return E_INVALIDARG;
- }
-
- ASSERT(IsRectEmpty(pTargetRect) == FALSE);
- return NOERROR;
-}
-
diff --git a/third_party/BaseClasses/winctrl.h b/third_party/BaseClasses/winctrl.h
deleted file mode 100644
index 1080a47c..00000000
--- a/third_party/BaseClasses/winctrl.h
+++ /dev/null
@@ -1,224 +0,0 @@
-//------------------------------------------------------------------------------
-// File: WinCtrl.h
-//
-// Desc: DirectShow base classes - defines classes for video control
-// interfaces.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#ifndef __WINCTRL__
-#define __WINCTRL__
-
-#define ABSOL(x) (x < 0 ? -x : x)
-#define NEGAT(x) (x > 0 ? -x : x)
-
-// Helper
-BOOL WINAPI PossiblyEatMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
-class CBaseControlWindow : public CBaseVideoWindow, public CBaseWindow
-{
-protected:
-
- CBaseFilter *m_pFilter; // Pointer to owning media filter
- CBasePin *m_pPin; // Controls media types for connection
- CCritSec *m_pInterfaceLock; // Externally defined critical section
- COLORREF m_BorderColour; // Current window border colour
- BOOL m_bAutoShow; // What happens when the state changes
- HWND m_hwndOwner; // Owner window that we optionally have
- HWND m_hwndDrain; // HWND to post any messages received
- BOOL m_bCursorHidden; // Should we hide the window cursor
-
-public:
-
- // Internal methods for other objects to get information out
-
- HRESULT DoSetWindowStyle(long Style,long WindowLong);
- HRESULT DoGetWindowStyle(__out long *pStyle,long WindowLong);
- BOOL IsAutoShowEnabled() { return m_bAutoShow; };
- COLORREF GetBorderColour() { return m_BorderColour; };
- HWND GetOwnerWindow() { return m_hwndOwner; };
- BOOL IsCursorHidden() { return m_bCursorHidden; };
-
- inline BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- return ::PossiblyEatMessage(m_hwndDrain, uMsg, wParam, lParam);
- }
-
- // Derived classes must call this to set the pin the filter is using
- // We don't have the pin passed in to the constructor (as we do with
- // the CBaseFilter object) because filters typically create the
- // pins dynamically when requested in CBaseFilter::GetPin. This can
- // not be called from our constructor because is is a virtual method
-
- void SetControlWindowPin(CBasePin *pPin) {
- m_pPin = pPin;
- }
-
-public:
-
- CBaseControlWindow(__inout CBaseFilter *pFilter, // Owning media filter
- __in CCritSec *pInterfaceLock, // Locking object
- __in_opt LPCTSTR pName, // Object description
- __inout_opt LPUNKNOWN pUnk, // Normal COM ownership
- __inout HRESULT *phr); // OLE return code
-
- // These are the properties we support
-
- STDMETHODIMP put_Caption(__in BSTR strCaption);
- STDMETHODIMP get_Caption(__out BSTR *pstrCaption);
- STDMETHODIMP put_AutoShow(long AutoShow);
- STDMETHODIMP get_AutoShow(__out long *AutoShow);
- STDMETHODIMP put_WindowStyle(long WindowStyle);
- STDMETHODIMP get_WindowStyle(__out long *pWindowStyle);
- STDMETHODIMP put_WindowStyleEx(long WindowStyleEx);
- STDMETHODIMP get_WindowStyleEx(__out long *pWindowStyleEx);
- STDMETHODIMP put_WindowState(long WindowState);
- STDMETHODIMP get_WindowState(__out long *pWindowState);
- STDMETHODIMP put_BackgroundPalette(long BackgroundPalette);
- STDMETHODIMP get_BackgroundPalette(__out long *pBackgroundPalette);
- STDMETHODIMP put_Visible(long Visible);
- STDMETHODIMP get_Visible(__out long *pVisible);
- STDMETHODIMP put_Left(long Left);
- STDMETHODIMP get_Left(__out long *pLeft);
- STDMETHODIMP put_Width(long Width);
- STDMETHODIMP get_Width(__out long *pWidth);
- STDMETHODIMP put_Top(long Top);
- STDMETHODIMP get_Top(__out long *pTop);
- STDMETHODIMP put_Height(long Height);
- STDMETHODIMP get_Height(__out long *pHeight);
- STDMETHODIMP put_Owner(OAHWND Owner);
- STDMETHODIMP get_Owner(__out OAHWND *Owner);
- STDMETHODIMP put_MessageDrain(OAHWND Drain);
- STDMETHODIMP get_MessageDrain(__out OAHWND *Drain);
- STDMETHODIMP get_BorderColor(__out long *Color);
- STDMETHODIMP put_BorderColor(long Color);
- STDMETHODIMP get_FullScreenMode(__out long *FullScreenMode);
- STDMETHODIMP put_FullScreenMode(long FullScreenMode);
-
- // And these are the methods
-
- STDMETHODIMP SetWindowForeground(long Focus);
- STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd,long uMsg,LONG_PTR wParam,LONG_PTR lParam);
- STDMETHODIMP GetMinIdealImageSize(__out long *pWidth,__out long *pHeight);
- STDMETHODIMP GetMaxIdealImageSize(__out long *pWidth,__out long *pHeight);
- STDMETHODIMP SetWindowPosition(long Left,long Top,long Width,long Height);
- STDMETHODIMP GetWindowPosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight);
- STDMETHODIMP GetRestorePosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight);
- STDMETHODIMP HideCursor(long HideCursor);
- STDMETHODIMP IsCursorHidden(__out long *CursorHidden);
-};
-
-// This class implements the IBasicVideo interface
-
-class CBaseControlVideo : public CBaseBasicVideo
-{
-protected:
-
- CBaseFilter *m_pFilter; // Pointer to owning media filter
- CBasePin *m_pPin; // Controls media types for connection
- CCritSec *m_pInterfaceLock; // Externally defined critical section
-
-public:
-
- // Derived classes must provide these for the implementation
-
- virtual HRESULT IsDefaultTargetRect() PURE;
- virtual HRESULT SetDefaultTargetRect() PURE;
- virtual HRESULT SetTargetRect(RECT *pTargetRect) PURE;
- virtual HRESULT GetTargetRect(RECT *pTargetRect) PURE;
- virtual HRESULT IsDefaultSourceRect() PURE;
- virtual HRESULT SetDefaultSourceRect() PURE;
- virtual HRESULT SetSourceRect(RECT *pSourceRect) PURE;
- virtual HRESULT GetSourceRect(RECT *pSourceRect) PURE;
- virtual HRESULT GetStaticImage(__inout long *pBufferSize,__out_bcount_part(*pBufferSize, *pBufferSize) long *pDIBImage) PURE;
-
- // Derived classes must override this to return a VIDEOINFO representing
- // the video format. We cannot call IPin ConnectionMediaType to get this
- // format because various filters dynamically change the type when using
- // DirectDraw such that the format shows the position of the logical
- // bitmap in a frame buffer surface, so the size might be returned as
- // 1024x768 pixels instead of 320x240 which is the real video dimensions
-
- __out virtual VIDEOINFOHEADER *GetVideoFormat() PURE;
-
- // Helper functions for creating memory renderings of a DIB image
-
- HRESULT GetImageSize(__in VIDEOINFOHEADER *pVideoInfo,
- __out LONG *pBufferSize,
- __in RECT *pSourceRect);
-
- HRESULT CopyImage(IMediaSample *pMediaSample,
- __in VIDEOINFOHEADER *pVideoInfo,
- __inout LONG *pBufferSize,
- __out_bcount_part(*pBufferSize, *pBufferSize) BYTE *pVideoImage,
- __in RECT *pSourceRect);
-
- // Override this if you want notifying when the rectangles change
- virtual HRESULT OnUpdateRectangles() { return NOERROR; };
- virtual HRESULT OnVideoSizeChange();
-
- // Derived classes must call this to set the pin the filter is using
- // We don't have the pin passed in to the constructor (as we do with
- // the CBaseFilter object) because filters typically create the
- // pins dynamically when requested in CBaseFilter::GetPin. This can
- // not be called from our constructor because is is a virtual method
-
- void SetControlVideoPin(__inout CBasePin *pPin) {
- m_pPin = pPin;
- }
-
- // Helper methods for checking rectangles
- virtual HRESULT CheckSourceRect(__in RECT *pSourceRect);
- virtual HRESULT CheckTargetRect(__in RECT *pTargetRect);
-
-public:
-
- CBaseControlVideo(__inout CBaseFilter *pFilter, // Owning media filter
- __in CCritSec *pInterfaceLock, // Serialise interface
- __in_opt LPCTSTR pName, // Object description
- __inout_opt LPUNKNOWN pUnk, // Normal COM ownership
- __inout HRESULT *phr); // OLE return code
-
- // These are the properties we support
-
- STDMETHODIMP get_AvgTimePerFrame(__out REFTIME *pAvgTimePerFrame);
- STDMETHODIMP get_BitRate(__out long *pBitRate);
- STDMETHODIMP get_BitErrorRate(__out long *pBitErrorRate);
- STDMETHODIMP get_VideoWidth(__out long *pVideoWidth);
- STDMETHODIMP get_VideoHeight(__out long *pVideoHeight);
- STDMETHODIMP put_SourceLeft(long SourceLeft);
- STDMETHODIMP get_SourceLeft(__out long *pSourceLeft);
- STDMETHODIMP put_SourceWidth(long SourceWidth);
- STDMETHODIMP get_SourceWidth(__out long *pSourceWidth);
- STDMETHODIMP put_SourceTop(long SourceTop);
- STDMETHODIMP get_SourceTop(__out long *pSourceTop);
- STDMETHODIMP put_SourceHeight(long SourceHeight);
- STDMETHODIMP get_SourceHeight(__out long *pSourceHeight);
- STDMETHODIMP put_DestinationLeft(long DestinationLeft);
- STDMETHODIMP get_DestinationLeft(__out long *pDestinationLeft);
- STDMETHODIMP put_DestinationWidth(long DestinationWidth);
- STDMETHODIMP get_DestinationWidth(__out long *pDestinationWidth);
- STDMETHODIMP put_DestinationTop(long DestinationTop);
- STDMETHODIMP get_DestinationTop(__out long *pDestinationTop);
- STDMETHODIMP put_DestinationHeight(long DestinationHeight);
- STDMETHODIMP get_DestinationHeight(__out long *pDestinationHeight);
-
- // And these are the methods
-
- STDMETHODIMP GetVideoSize(__out long *pWidth,__out long *pHeight);
- STDMETHODIMP SetSourcePosition(long Left,long Top,long Width,long Height);
- STDMETHODIMP GetSourcePosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight);
- STDMETHODIMP GetVideoPaletteEntries(long StartIndex,long Entries,__out long *pRetrieved,__out_ecount_part(Entries, *pRetrieved) long *pPalette);
- STDMETHODIMP SetDefaultSourcePosition();
- STDMETHODIMP IsUsingDefaultSource();
- STDMETHODIMP SetDestinationPosition(long Left,long Top,long Width,long Height);
- STDMETHODIMP GetDestinationPosition(__out long *pLeft,__out long *pTop,__out long *pWidth,__out long *pHeight);
- STDMETHODIMP SetDefaultDestinationPosition();
- STDMETHODIMP IsUsingDefaultDestination();
- STDMETHODIMP GetCurrentImage(__inout long *pBufferSize,__out_bcount_part(*pBufferSize, *pBufferSize) long *pVideoImage);
-};
-
-#endif // __WINCTRL__
-
diff --git a/third_party/BaseClasses/winutil.cpp b/third_party/BaseClasses/winutil.cpp
deleted file mode 100644
index 6653f457..00000000
--- a/third_party/BaseClasses/winutil.cpp
+++ /dev/null
@@ -1,2746 +0,0 @@
-//------------------------------------------------------------------------------
-// File: WinUtil.cpp
-//
-// Desc: DirectShow base classes - implements generic window handler class.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <limits.h>
-#include <dvdmedia.h>
-#include <strsafe.h>
-#include <checkbmi.h>
-
-static UINT MsgDestroy;
-
-// Constructor
-
-CBaseWindow::CBaseWindow(BOOL bDoGetDC, bool bDoPostToDestroy) :
- m_hInstance(g_hInst),
- m_hwnd(NULL),
- m_hdc(NULL),
- m_bActivated(FALSE),
- m_pClassName(NULL),
- m_ClassStyles(0),
- m_WindowStyles(0),
- m_WindowStylesEx(0),
- m_ShowStageMessage(0),
- m_ShowStageTop(0),
- m_MemoryDC(NULL),
- m_hPalette(NULL),
- m_bBackground(FALSE),
-#ifdef DEBUG
- m_bRealizing(FALSE),
-#endif
- m_bNoRealize(FALSE),
- m_bDoPostToDestroy(bDoPostToDestroy)
-{
- m_bDoGetDC = bDoGetDC;
-}
-
-
-// Prepare a window by spinning off a worker thread to do the creation and
-// also poll the message input queue. We leave this to be called by derived
-// classes because they might want to override methods like MessageLoop and
-// InitialiseWindow, if we do this during construction they'll ALWAYS call
-// this base class methods. We make the worker thread create the window so
-// it owns it rather than the filter graph thread which is constructing us
-
-HRESULT CBaseWindow::PrepareWindow()
-{
- if (m_hwnd) return NOERROR;
- ASSERT(m_hwnd == NULL);
- ASSERT(m_hdc == NULL);
-
- // Get the derived object's window and class styles
-
- m_pClassName = GetClassWindowStyles(&m_ClassStyles,
- &m_WindowStyles,
- &m_WindowStylesEx);
- if (m_pClassName == NULL) {
- return E_FAIL;
- }
-
- // Register our special private messages
- m_ShowStageMessage = RegisterWindowMessage(SHOWSTAGE);
-
- // RegisterWindowMessage() returns 0 if an error occurs.
- if (0 == m_ShowStageMessage) {
- return AmGetLastErrorToHResult();
- }
-
- m_ShowStageTop = RegisterWindowMessage(SHOWSTAGETOP);
- if (0 == m_ShowStageTop) {
- return AmGetLastErrorToHResult();
- }
-
- m_RealizePalette = RegisterWindowMessage(REALIZEPALETTE);
- if (0 == m_RealizePalette) {
- return AmGetLastErrorToHResult();
- }
-
- MsgDestroy = RegisterWindowMessage(TEXT("AM_DESTROY"));
- if (0 == MsgDestroy) {
- return AmGetLastErrorToHResult();
- }
-
- return DoCreateWindow();
-}
-
-
-// Destructor just a placeholder so that we know it becomes virtual
-// Derived classes MUST call DoneWithWindow in their destructors so
-// that no messages arrive after the derived class constructor ends
-
-#ifdef DEBUG
-CBaseWindow::~CBaseWindow()
-{
- ASSERT(m_hwnd == NULL);
- ASSERT(m_hdc == NULL);
-}
-#endif
-
-
-// We use the sync worker event to have the window destroyed. All we do is
-// signal the event and wait on the window thread handle. Trying to send it
-// messages causes too many problems, furthermore to be on the safe side we
-// just wait on the thread handle while it returns WAIT_TIMEOUT or there is
-// a sent message to process on this thread. If the constructor failed to
-// create the thread in the first place then the loop will get terminated
-
-HRESULT CBaseWindow::DoneWithWindow()
-{
- if (!IsWindow(m_hwnd) || (GetWindowThreadProcessId(m_hwnd, NULL) != GetCurrentThreadId())) {
-
- if (IsWindow(m_hwnd)) {
-
- // This code should only be executed if the window exists and if the window's
- // messages are processed on a different thread.
- ASSERT(GetWindowThreadProcessId(m_hwnd, NULL) != GetCurrentThreadId());
-
- if (m_bDoPostToDestroy) {
-
- HRESULT hr = S_OK;
- CAMEvent m_evDone(FALSE, &hr);
- if (FAILED(hr)) {
- return hr;
- }
-
- // We must post a message to destroy the window
- // That way we can't be in the middle of processing a
- // message posted to our window when we do go away
- // Sending a message gives less synchronization.
- PostMessage(m_hwnd, MsgDestroy, (WPARAM)(HANDLE)m_evDone, 0);
- WaitDispatchingMessages(m_evDone, INFINITE);
- } else {
- SendMessage(m_hwnd, MsgDestroy, 0, 0);
- }
- }
-
- //
- // This is not a leak, the window manager automatically free's
- // hdc's that were got via GetDC, which is the case here.
- // We set it to NULL so that we don't get any asserts later.
- //
- m_hdc = NULL;
-
- //
- // We need to free this DC though because USER32 does not know
- // anything about it.
- //
- if (m_MemoryDC)
- {
- EXECUTE_ASSERT(DeleteDC(m_MemoryDC));
- m_MemoryDC = NULL;
- }
-
- // Reset the window variables
- m_hwnd = NULL;
-
- return NOERROR;
- }
- const HWND hwnd = m_hwnd;
- if (hwnd == NULL) {
- return NOERROR;
- }
-
- InactivateWindow();
- NOTE("Inactivated");
-
- // Reset the window styles before destruction
-
- SetWindowLong(hwnd,GWL_STYLE,m_WindowStyles);
- ASSERT(GetParent(hwnd) == NULL);
- NOTE1("Reset window styles %d",m_WindowStyles);
-
- // UnintialiseWindow sets m_hwnd to NULL so save a copy
- UninitialiseWindow();
- DbgLog((LOG_TRACE, 2, TEXT("Destroying 0x%8.8X"), hwnd));
- if (!DestroyWindow(hwnd)) {
- DbgLog((LOG_TRACE, 0, TEXT("DestroyWindow %8.8X failed code %d"),
- hwnd, GetLastError()));
- DbgBreak("");
- }
-
- // Reset our state so we can be prepared again
-
- m_pClassName = NULL;
- m_ClassStyles = 0;
- m_WindowStyles = 0;
- m_WindowStylesEx = 0;
- m_ShowStageMessage = 0;
- m_ShowStageTop = 0;
-
- return NOERROR;
-}
-
-
-// Called at the end to put the window in an inactive state. The pending list
-// will always have been cleared by this time so event if the worker thread
-// gets has been signaled and gets in to render something it will find both
-// the state has been changed and that there are no available sample images
-// Since we wait on the window thread to complete we don't lock the object
-
-HRESULT CBaseWindow::InactivateWindow()
-{
- // Has the window been activated
- if (m_bActivated == FALSE) {
- return S_FALSE;
- }
-
- m_bActivated = FALSE;
- ShowWindow(m_hwnd,SW_HIDE);
- return NOERROR;
-}
-
-
-HRESULT CBaseWindow::CompleteConnect()
-{
- m_bActivated = FALSE;
- return NOERROR;
-}
-
-// This displays a normal window. We ask the base window class for default
-// sizes which unless overriden will return DEFWIDTH and DEFHEIGHT. We go
-// through a couple of extra hoops to get the client area the right size
-// as the object specifies which accounts for the AdjustWindowRectEx calls
-// We also DWORD align the left and top coordinates of the window here to
-// maximise the chance of being able to use DCI/DirectDraw primary surface
-
-HRESULT CBaseWindow::ActivateWindow()
-{
- // Has the window been sized and positioned already
-
- if (m_bActivated == TRUE || GetParent(m_hwnd) != NULL) {
-
- SetWindowPos(m_hwnd, // Our window handle
- HWND_TOP, // Put it at the top
- 0, 0, 0, 0, // Leave in current position
- SWP_NOMOVE | // Don't change it's place
- SWP_NOSIZE); // Change Z-order only
-
- m_bActivated = TRUE;
- return S_FALSE;
- }
-
- // Calculate the desired client rectangle
-
- RECT WindowRect, ClientRect = GetDefaultRect();
- GetWindowRect(m_hwnd,&WindowRect);
- AdjustWindowRectEx(&ClientRect,GetWindowLong(m_hwnd,GWL_STYLE),
- FALSE,GetWindowLong(m_hwnd,GWL_EXSTYLE));
-
- // Align left and top edges on DWORD boundaries
-
- UINT WindowFlags = (SWP_NOACTIVATE | SWP_FRAMECHANGED);
- WindowRect.left -= (WindowRect.left & 3);
- WindowRect.top -= (WindowRect.top & 3);
-
- SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- WindowRect.left, // Align left edge
- WindowRect.top, // And also top place
- WIDTH(&ClientRect), // Horizontal size
- HEIGHT(&ClientRect), // Vertical size
- WindowFlags); // Don't show window
-
- m_bActivated = TRUE;
- return NOERROR;
-}
-
-
-// This can be used to DWORD align the window for maximum performance
-
-HRESULT CBaseWindow::PerformanceAlignWindow()
-{
- RECT ClientRect,WindowRect;
- GetWindowRect(m_hwnd,&WindowRect);
- ASSERT(m_bActivated == TRUE);
-
- // Don't do this if we're owned
-
- if (GetParent(m_hwnd)) {
- return NOERROR;
- }
-
- // Align left and top edges on DWORD boundaries
-
- GetClientRect(m_hwnd, &ClientRect);
- MapWindowPoints(m_hwnd, HWND_DESKTOP, (LPPOINT) &ClientRect, 2);
- WindowRect.left -= (ClientRect.left & 3);
- WindowRect.top -= (ClientRect.top & 3);
- UINT WindowFlags = (SWP_NOACTIVATE | SWP_NOSIZE);
-
- SetWindowPos(m_hwnd, // Window handle
- HWND_TOP, // Put it at the top
- WindowRect.left, // Align left edge
- WindowRect.top, // And also top place
- (int) 0,(int) 0, // Ignore these sizes
- WindowFlags); // Don't show window
-
- return NOERROR;
-}
-
-
-// Install a palette into the base window - we may be called by a different
-// thread to the one that owns the window. We have to be careful how we do
-// the palette realisation as we could be a different thread to the window
-// which would cause an inter thread send message. Therefore we realise the
-// palette by sending it a special message but without the window locked
-
-HRESULT CBaseWindow::SetPalette(HPALETTE hPalette)
-{
- // We must own the window lock during the change
- {
- CAutoLock cWindowLock(&m_WindowLock);
- CAutoLock cPaletteLock(&m_PaletteLock);
- ASSERT(hPalette);
- m_hPalette = hPalette;
- }
- return SetPalette();
-}
-
-
-HRESULT CBaseWindow::SetPalette()
-{
- if (!m_bNoRealize) {
- SendMessage(m_hwnd, m_RealizePalette, 0, 0);
- return S_OK;
- } else {
- // Just select the palette
- ASSERT(m_hdc);
- ASSERT(m_MemoryDC);
-
- CAutoLock cPaletteLock(&m_PaletteLock);
- SelectPalette(m_hdc,m_hPalette,m_bBackground);
- SelectPalette(m_MemoryDC,m_hPalette,m_bBackground);
-
- return S_OK;
- }
-}
-
-
-void CBaseWindow::UnsetPalette()
-{
- CAutoLock cWindowLock(&m_WindowLock);
- CAutoLock cPaletteLock(&m_PaletteLock);
-
- // Get a standard VGA colour palette
-
- HPALETTE hPalette = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
- ASSERT(hPalette);
-
- SelectPalette(GetWindowHDC(), hPalette, TRUE);
- SelectPalette(GetMemoryHDC(), hPalette, TRUE);
-
- m_hPalette = NULL;
-}
-
-
-void CBaseWindow::LockPaletteLock()
-{
- m_PaletteLock.Lock();
-}
-
-
-void CBaseWindow::UnlockPaletteLock()
-{
- m_PaletteLock.Unlock();
-}
-
-
-// Realise our palettes in the window and device contexts
-
-HRESULT CBaseWindow::DoRealisePalette(BOOL bForceBackground)
-{
- {
- CAutoLock cPaletteLock(&m_PaletteLock);
-
- if (m_hPalette == NULL) {
- return NOERROR;
- }
-
- // Realize the palette on the window thread
- ASSERT(m_hdc);
- ASSERT(m_MemoryDC);
-
- SelectPalette(m_hdc,m_hPalette,m_bBackground || bForceBackground);
- SelectPalette(m_MemoryDC,m_hPalette,m_bBackground);
- }
-
- // If we grab a critical section here we can deadlock
- // with the window thread because one of the side effects
- // of RealizePalette is to send a WM_PALETTECHANGED message
- // to every window in the system. In our handling
- // of WM_PALETTECHANGED we used to grab this CS too.
- // The really bad case is when our renderer calls DoRealisePalette()
- // while we're in the middle of processing a palette change
- // for another window.
- // So don't hold the critical section while actually realising
- // the palette. In any case USER is meant to manage palette
- // handling - we shouldn't have to serialize everything as well
- ASSERT(CritCheckOut(&m_WindowLock));
- ASSERT(CritCheckOut(&m_PaletteLock));
-
- EXECUTE_ASSERT(RealizePalette(m_hdc) != GDI_ERROR);
- EXECUTE_ASSERT(RealizePalette(m_MemoryDC) != GDI_ERROR);
-
- return (GdiFlush() == FALSE ? S_FALSE : S_OK);
-}
-
-
-// This is the global window procedure
-
-LRESULT CALLBACK WndProc(HWND hwnd, // Window handle
- UINT uMsg, // Message ID
- WPARAM wParam, // First parameter
- LPARAM lParam) // Other parameter
-{
-
- // Get the window long that holds our window object pointer
- // If it is NULL then we are initialising the window in which
- // case the object pointer has been passed in the window creation
- // structure. IF we get any messages before WM_NCCREATE we will
- // pass them to DefWindowProc.
-
- CBaseWindow *pBaseWindow = _GetWindowLongPtr<CBaseWindow*>(hwnd,0);
-
- if (pBaseWindow == NULL) {
-
- // Get the structure pointer from the create struct.
- // We can only do this for WM_NCCREATE which should be one of
- // the first messages we receive. Anything before this will
- // have to be passed to DefWindowProc (i.e. WM_GETMINMAXINFO)
-
- // If the message is WM_NCCREATE we set our pBaseWindow pointer
- // and will then place it in the window structure
-
- // turn off WS_EX_LAYOUTRTL style for quartz windows
- if (uMsg == WM_NCCREATE) {
- SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x400000);
- }
-
- if ((uMsg != WM_NCCREATE)
- || (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams)))
- {
- return(DefWindowProc(hwnd, uMsg, wParam, lParam));
- }
-
- // Set the window LONG to be the object who created us
-#ifdef DEBUG
- SetLastError(0); // because of the way SetWindowLong works
-#endif
-
- LONG_PTR rc = _SetWindowLongPtr(hwnd, (DWORD) 0, pBaseWindow);
-
-
-#ifdef DEBUG
- if (0 == rc) {
- // SetWindowLong MIGHT have failed. (Read the docs which admit
- // that it is awkward to work out if you have had an error.)
- LONG lasterror = GetLastError();
- ASSERT(0 == lasterror);
- // If this is not the case we have not set the pBaseWindow pointer
- // into the window structure and we will blow up.
- }
-#endif
-
- }
- // See if this is the packet of death
- if (uMsg == MsgDestroy && uMsg != 0) {
- pBaseWindow->DoneWithWindow();
- if (pBaseWindow->m_bDoPostToDestroy) {
- EXECUTE_ASSERT(SetEvent((HANDLE)wParam));
- }
- return 0;
- }
- return pBaseWindow->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
-}
-
-
-// When the window size changes we adjust our member variables that
-// contain the dimensions of the client rectangle for our window so
-// that we come to render an image we will know whether to stretch
-
-BOOL CBaseWindow::OnSize(LONG Width, LONG Height)
-{
- m_Width = Width;
- m_Height = Height;
- return TRUE;
-}
-
-
-// This function handles the WM_CLOSE message
-
-BOOL CBaseWindow::OnClose()
-{
- ShowWindow(m_hwnd,SW_HIDE);
- return TRUE;
-}
-
-
-// This is called by the worker window thread when it receives a terminate
-// message from the window object destructor to delete all the resources we
-// allocated during initialisation. By the time the worker thread exits all
-// processing will have been completed as the source filter disconnection
-// flushes the image pending sample, therefore the GdiFlush should succeed
-
-HRESULT CBaseWindow::UninitialiseWindow()
-{
- // Have we already cleaned up
-
- if (m_hwnd == NULL) {
- ASSERT(m_hdc == NULL);
- ASSERT(m_MemoryDC == NULL);
- return NOERROR;
- }
-
- // Release the window resources
-
- EXECUTE_ASSERT(GdiFlush());
-
- if (m_hdc)
- {
- EXECUTE_ASSERT(ReleaseDC(m_hwnd,m_hdc));
- m_hdc = NULL;
- }
-
- if (m_MemoryDC)
- {
- EXECUTE_ASSERT(DeleteDC(m_MemoryDC));
- m_MemoryDC = NULL;
- }
-
- // Reset the window variables
- m_hwnd = NULL;
-
- return NOERROR;
-}
-
-
-// This is called by the worker window thread after it has created the main
-// window and it wants to initialise the rest of the owner objects window
-// variables such as the device contexts. We execute this function with the
-// critical section still locked. Nothing in this function must generate any
-// SendMessage calls to the window because this is executing on the window
-// thread so the message will never be processed and we will deadlock
-
-HRESULT CBaseWindow::InitialiseWindow(HWND hwnd)
-{
- // Initialise the window variables
-
- ASSERT(IsWindow(hwnd));
- m_hwnd = hwnd;
-
- if (m_bDoGetDC)
- {
- EXECUTE_ASSERT(m_hdc = GetDC(hwnd));
- EXECUTE_ASSERT(m_MemoryDC = CreateCompatibleDC(m_hdc));
-
- EXECUTE_ASSERT(SetStretchBltMode(m_hdc,COLORONCOLOR));
- EXECUTE_ASSERT(SetStretchBltMode(m_MemoryDC,COLORONCOLOR));
- }
-
- return NOERROR;
-}
-
-HRESULT CBaseWindow::DoCreateWindow()
-{
- WNDCLASS wndclass; // Used to register classes
- BOOL bRegistered; // Is this class registered
- HWND hwnd; // Handle to our window
-
- bRegistered = GetClassInfo(m_hInstance, // Module instance
- m_pClassName, // Window class
- &wndclass); // Info structure
-
- // if the window is to be used for drawing puposes and we are getting a DC
- // for the entire lifetime of the window then changes the class style to do
- // say so. If we don't set this flag then the DC comes from the cache and is
- // really bad.
- if (m_bDoGetDC)
- {
- m_ClassStyles |= CS_OWNDC;
- }
-
- if (bRegistered == FALSE) {
-
- // Register the renderer window class
-
- wndclass.lpszClassName = m_pClassName;
- wndclass.style = m_ClassStyles;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = sizeof(CBaseWindow *);
- wndclass.hInstance = m_hInstance;
- wndclass.hIcon = NULL;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH) NULL;
- wndclass.lpszMenuName = NULL;
-
- RegisterClass(&wndclass);
- }
-
- // Create the frame window. Pass the pBaseWindow information in the
- // CreateStruct which allows our message handling loop to get hold of
- // the pBaseWindow pointer.
-
- CBaseWindow *pBaseWindow = this; // The owner window object
- hwnd = CreateWindowEx(m_WindowStylesEx, // Extended styles
- m_pClassName, // Registered name
- TEXT("ActiveMovie Window"), // Window title
- m_WindowStyles, // Window styles
- CW_USEDEFAULT, // Start x position
- CW_USEDEFAULT, // Start y position
- DEFWIDTH, // Window width
- DEFHEIGHT, // Window height
- NULL, // Parent handle
- NULL, // Menu handle
- m_hInstance, // Instance handle
- &pBaseWindow); // Creation data
-
- // If we failed signal an error to the object constructor (based on the
- // last Win32 error on this thread) then signal the constructor thread
- // to continue, release the mutex to let others have a go and exit
-
- if (hwnd == NULL) {
- DWORD Error = GetLastError();
- return AmHresultFromWin32(Error);
- }
-
- // Check the window LONG is the object who created us
- ASSERT(GetWindowLongPtr(hwnd, 0) == (LONG_PTR)this);
-
- // Initialise the window and then signal the constructor so that it can
- // continue and then finally unlock the object's critical section. The
- // window class is left registered even after we terminate the thread
- // as we don't know when the last window has been closed. So we allow
- // the operating system to free the class resources as appropriate
-
- InitialiseWindow(hwnd);
-
- DbgLog((LOG_TRACE, 2, TEXT("Created window class (%s) HWND(%8.8X)"),
- m_pClassName, hwnd));
-
- return S_OK;
-}
-
-
-// The base class provides some default handling and calls DefWindowProc
-
-LRESULT CBaseWindow::OnReceiveMessage(HWND hwnd, // Window handle
- UINT uMsg, // Message ID
- WPARAM wParam, // First parameter
- LPARAM lParam) // Other parameter
-{
- ASSERT(IsWindow(hwnd));
-
- if (PossiblyEatMessage(uMsg, wParam, lParam))
- return 0;
-
- // This is sent by the IVideoWindow SetWindowForeground method. If the
- // window is invisible we will show it and make it topmost without the
- // foreground focus. If the window is visible it will also be made the
- // topmost window without the foreground focus. If wParam is TRUE then
- // for both cases the window will be forced into the foreground focus
-
- if (uMsg == m_ShowStageMessage) {
-
- BOOL bVisible = IsWindowVisible(hwnd);
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
- (bVisible ? SWP_NOACTIVATE : 0));
-
- // Should we bring the window to the foreground
- if (wParam == TRUE) {
- SetForegroundWindow(hwnd);
- }
- return (LRESULT) 1;
- }
-
- // When we go fullscreen we have to add the WS_EX_TOPMOST style to the
- // video window so that it comes out above any task bar (this is more
- // relevant to WindowsNT than Windows95). However the SetWindowPos call
- // must be on the same thread as that which created the window. The
- // wParam parameter can be TRUE or FALSE to set and reset the topmost
-
- if (uMsg == m_ShowStageTop) {
- HWND HwndTop = (wParam == TRUE ? HWND_TOPMOST : HWND_NOTOPMOST);
- BOOL bVisible = IsWindowVisible(hwnd);
- SetWindowPos(hwnd, HwndTop, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE |
- (wParam == TRUE ? SWP_SHOWWINDOW : 0) |
- (bVisible ? SWP_NOACTIVATE : 0));
- return (LRESULT) 1;
- }
-
- // New palette stuff
- if (uMsg == m_RealizePalette) {
- ASSERT(m_hwnd == hwnd);
- return OnPaletteChange(m_hwnd,WM_QUERYNEWPALETTE);
- }
-
- switch (uMsg) {
-
- // Repaint the window if the system colours change
-
- case WM_SYSCOLORCHANGE:
-
- InvalidateRect(hwnd,NULL,FALSE);
- return (LRESULT) 1;
-
- // Somebody has changed the palette
- case WM_PALETTECHANGED:
-
- OnPaletteChange((HWND)wParam,uMsg);
- return (LRESULT) 0;
-
- // We are about to receive the keyboard focus so we ask GDI to realise
- // our logical palette again and hopefully it will be fully installed
- // without any mapping having to be done during any picture rendering
-
- case WM_QUERYNEWPALETTE:
- ASSERT(m_hwnd == hwnd);
- return OnPaletteChange(m_hwnd,uMsg);
-
- // do NOT fwd WM_MOVE. the parameters are the location of the parent
- // window, NOT what the renderer should be looking at. But we need
- // to make sure the overlay is moved with the parent window, so we
- // do this.
- case WM_MOVE:
- if (IsWindowVisible(m_hwnd)) {
- PostMessage(m_hwnd,WM_PAINT,0,0);
- }
- break;
-
- // Store the width and height as useful base class members
-
- case WM_SIZE:
-
- OnSize(LOWORD(lParam), HIWORD(lParam));
- return (LRESULT) 0;
-
- // Intercept the WM_CLOSE messages to hide the window
-
- case WM_CLOSE:
-
- OnClose();
- return (LRESULT) 0;
- }
- return DefWindowProc(hwnd,uMsg,wParam,lParam);
-}
-
-
-// This handles the Windows palette change messages - if we do realise our
-// palette then we return TRUE otherwise we return FALSE. If our window is
-// foreground application then we should get first choice of colours in the
-// system palette entries. We get best performance when our logical palette
-// includes the standard VGA colours (at the beginning and end) otherwise
-// GDI may have to map from our palette to the device palette while drawing
-
-LRESULT CBaseWindow::OnPaletteChange(HWND hwnd,UINT Message)
-{
- // First check we are not changing the palette during closedown
-
- if (m_hwnd == NULL || hwnd == NULL) {
- return (LRESULT) 0;
- }
- ASSERT(!m_bRealizing);
-
- // Should we realise our palette again
-
- if ((Message == WM_QUERYNEWPALETTE || hwnd != m_hwnd)) {
- // It seems that even if we're invisible that we can get asked
- // to realize our palette and this can cause really ugly side-effects
- // Seems like there's another bug but this masks it a least for the
- // shutting down case.
- if (!IsWindowVisible(m_hwnd)) {
- DbgLog((LOG_TRACE, 1, TEXT("Realizing when invisible!")));
- return (LRESULT) 0;
- }
-
- // Avoid recursion with multiple graphs in the same app
-#ifdef DEBUG
- m_bRealizing = TRUE;
-#endif
- DoRealisePalette(Message != WM_QUERYNEWPALETTE);
-#ifdef DEBUG
- m_bRealizing = FALSE;
-#endif
-
- // Should we redraw the window with the new palette
- if (Message == WM_PALETTECHANGED) {
- InvalidateRect(m_hwnd,NULL,FALSE);
- }
- }
-
- return (LRESULT) 1;
-}
-
-
-// Determine if the window exists.
-
-bool CBaseWindow::WindowExists()
-{
- return !!IsWindow(m_hwnd);
-}
-
-
-// Return the default window rectangle
-
-RECT CBaseWindow::GetDefaultRect()
-{
- RECT DefaultRect = {0,0,DEFWIDTH,DEFHEIGHT};
- ASSERT(m_hwnd);
- // ASSERT(m_hdc);
- return DefaultRect;
-}
-
-
-// Return the current window width
-
-LONG CBaseWindow::GetWindowWidth()
-{
- ASSERT(m_hwnd);
- // ASSERT(m_hdc);
- return m_Width;
-}
-
-
-// Return the current window height
-
-LONG CBaseWindow::GetWindowHeight()
-{
- ASSERT(m_hwnd);
- // ASSERT(m_hdc);
- return m_Height;
-}
-
-
-// Return the window handle
-
-HWND CBaseWindow::GetWindowHWND()
-{
- ASSERT(m_hwnd);
- // ASSERT(m_hdc);
- return m_hwnd;
-}
-
-
-// Return the window drawing device context
-
-HDC CBaseWindow::GetWindowHDC()
-{
- ASSERT(m_hwnd);
- ASSERT(m_hdc);
- return m_hdc;
-}
-
-
-// Return the offscreen window drawing device context
-
-HDC CBaseWindow::GetMemoryHDC()
-{
- ASSERT(m_hwnd);
- ASSERT(m_MemoryDC);
- return m_MemoryDC;
-}
-
-
-#ifdef DEBUG
-HPALETTE CBaseWindow::GetPalette()
-{
- // The palette lock should always be held when accessing
- // m_hPalette.
- ASSERT(CritCheckIn(&m_PaletteLock));
- return m_hPalette;
-}
-#endif // DEBUG
-
-
-// This is available to clients who want to change the window visiblity. It's
-// little more than an indirection to the Win32 ShowWindow although these is
-// some benefit in going through here as this function may change sometime
-
-HRESULT CBaseWindow::DoShowWindow(LONG ShowCmd)
-{
- ShowWindow(m_hwnd,ShowCmd);
- return NOERROR;
-}
-
-
-// Generate a WM_PAINT message for the video window
-
-void CBaseWindow::PaintWindow(BOOL bErase)
-{
- InvalidateRect(m_hwnd,NULL,bErase);
-}
-
-
-// Allow an application to have us set the video window in the foreground. We
-// have this because it is difficult for one thread to do do this to a window
-// owned by another thread. Rather than expose the message we use to execute
-// the inter thread send message we provide the interface function. All we do
-// is to SendMessage to the video window renderer thread with a WM_SHOWSTAGE
-
-void CBaseWindow::DoSetWindowForeground(BOOL bFocus)
-{
- SendMessage(m_hwnd,m_ShowStageMessage,(WPARAM) bFocus,(LPARAM) 0);
-}
-
-
-// Constructor initialises the owning object pointer. Since we are a worker
-// class for the main window object we have relatively few state variables to
-// look after. We are given device context handles to use later on as well as
-// the source and destination rectangles (but reset them here just in case)
-
-CDrawImage::CDrawImage(__inout CBaseWindow *pBaseWindow) :
- m_pBaseWindow(pBaseWindow),
- m_hdc(NULL),
- m_MemoryDC(NULL),
- m_bStretch(FALSE),
- m_pMediaType(NULL),
- m_bUsingImageAllocator(FALSE)
-{
- ASSERT(pBaseWindow);
- ResetPaletteVersion();
- SetRectEmpty(&m_TargetRect);
- SetRectEmpty(&m_SourceRect);
-
- m_perfidRenderTime = MSR_REGISTER(TEXT("Single Blt time"));
-}
-
-
-// Overlay the image time stamps on the picture. Access to this method is
-// serialised by the caller. We display the sample start and end times on
-// top of the video using TextOut on the device context we are handed. If
-// there isn't enough room in the window for the times we don't show them
-
-void CDrawImage::DisplaySampleTimes(IMediaSample *pSample)
-{
-#ifdef DEBUG
- //
- // Only allow the "annoying" time messages if the users has turned the
- // logging "way up"
- //
- BOOL bAccept = DbgCheckModuleLevel(LOG_TRACE, 5);
- if (bAccept == FALSE) {
- return;
- }
-#endif
-
- TCHAR szTimes[TIMELENGTH]; // Time stamp strings
- ASSERT(pSample); // Quick sanity check
- RECT ClientRect; // Client window size
- SIZE Size; // Size of text output
-
- // Get the time stamps and window size
-
- pSample->GetTime((REFERENCE_TIME*)&m_StartSample, (REFERENCE_TIME*)&m_EndSample);
- HWND hwnd = m_pBaseWindow->GetWindowHWND();
- EXECUTE_ASSERT(GetClientRect(hwnd,&ClientRect));
-
- // Format the sample time stamps
-
- (void)StringCchPrintf(szTimes,NUMELMS(szTimes),TEXT("%08d : %08d"),
- m_StartSample.Millisecs(),
- m_EndSample.Millisecs());
-
- ASSERT(lstrlen(szTimes) < TIMELENGTH);
-
- // Put the times in the middle at the bottom of the window
-
- GetTextExtentPoint32(m_hdc,szTimes,lstrlen(szTimes),&Size);
- INT XPos = ((ClientRect.right - ClientRect.left) - Size.cx) / 2;
- INT YPos = ((ClientRect.bottom - ClientRect.top) - Size.cy) * 4 / 5;
-
- // Check the window is big enough to have sample times displayed
-
- if ((XPos > 0) && (YPos > 0)) {
- TextOut(m_hdc,XPos,YPos,szTimes,lstrlen(szTimes));
- }
-}
-
-
-// This is called when the drawing code sees that the image has a down level
-// palette cookie. We simply call the SetDIBColorTable Windows API with the
-// palette that is found after the BITMAPINFOHEADER - we return no errors
-
-void CDrawImage::UpdateColourTable(HDC hdc,__in BITMAPINFOHEADER *pbmi)
-{
- ASSERT(pbmi->biClrUsed);
- RGBQUAD *pColourTable = (RGBQUAD *)(pbmi+1);
-
- // Set the new palette in the device context
-
- UINT uiReturn = SetDIBColorTable(hdc,(UINT) 0,
- pbmi->biClrUsed,
- pColourTable);
-
- // Should always succeed but check in debug builds
- ASSERT(uiReturn == pbmi->biClrUsed);
-}
-
-
-// No source rectangle scaling is done by the base class
-
-RECT CDrawImage::ScaleSourceRect(const RECT *pSource)
-{
- ASSERT(pSource);
- return *pSource;
-}
-
-
-// This is called when the funky output pin uses our allocator. The samples we
-// allocate are special because the memory is shared between us and GDI thus
-// removing one copy when we ask for the image to be rendered. The source type
-// information is in the main renderer m_mtIn field which is initialised when
-// the media type is agreed in SetMediaType, the media type may be changed on
-// the fly if, for example, the source filter needs to change the palette
-
-void CDrawImage::FastRender(IMediaSample *pMediaSample)
-{
- BITMAPINFOHEADER *pbmi; // Image format data
- DIBDATA *pDibData; // Stores DIB information
- BYTE *pImage; // Pointer to image data
- HBITMAP hOldBitmap; // Store the old bitmap
- CImageSample *pSample; // Pointer to C++ object
-
- ASSERT(m_pMediaType);
-
- // From the untyped source format block get the VIDEOINFO and subsequently
- // the BITMAPINFOHEADER structure. We can cast the IMediaSample interface
- // to a CImageSample object so we can retrieve it's DIBSECTION details
-
- pbmi = HEADER(m_pMediaType->Format());
- pSample = (CImageSample *) pMediaSample;
- pDibData = pSample->GetDIBData();
- hOldBitmap = (HBITMAP) SelectObject(m_MemoryDC,pDibData->hBitmap);
-
- // Get a pointer to the real image data
-
- HRESULT hr = pMediaSample->GetPointer(&pImage);
- if (FAILED(hr)) {
- return;
- }
-
- // Do we need to update the colour table, we increment our palette cookie
- // each time we get a dynamic format change. The sample palette cookie is
- // stored in the DIBDATA structure so we try to keep the fields in sync
- // By the time we get to draw the images the format change will be done
- // so all we do is ask the renderer for what it's palette version is
-
- if (pDibData->PaletteVersion < GetPaletteVersion()) {
- ASSERT(pbmi->biBitCount <= iPALETTE);
- UpdateColourTable(m_MemoryDC,pbmi);
- pDibData->PaletteVersion = GetPaletteVersion();
- }
-
- // This allows derived classes to change the source rectangle that we do
- // the drawing with. For example a renderer may ask a codec to stretch
- // the video from 320x240 to 640x480, in which case the source we see in
- // here will still be 320x240, although the source we want to draw with
- // should be scaled up to 640x480. The base class implementation of this
- // method does nothing but return the same rectangle as we are passed in
-
- RECT SourceRect = ScaleSourceRect(&m_SourceRect);
-
- // Is the window the same size as the video
-
- if (m_bStretch == FALSE) {
-
- // Put the image straight into the window
-
- BitBlt(
- (HDC) m_hdc, // Target device HDC
- m_TargetRect.left, // X sink position
- m_TargetRect.top, // Y sink position
- m_TargetRect.right - m_TargetRect.left, // Destination width
- m_TargetRect.bottom - m_TargetRect.top, // Destination height
- m_MemoryDC, // Source device context
- SourceRect.left, // X source position
- SourceRect.top, // Y source position
- SRCCOPY); // Simple copy
-
- } else {
-
- // Stretch the image when copying to the window
-
- StretchBlt(
- (HDC) m_hdc, // Target device HDC
- m_TargetRect.left, // X sink position
- m_TargetRect.top, // Y sink position
- m_TargetRect.right - m_TargetRect.left, // Destination width
- m_TargetRect.bottom - m_TargetRect.top, // Destination height
- m_MemoryDC, // Source device HDC
- SourceRect.left, // X source position
- SourceRect.top, // Y source position
- SourceRect.right - SourceRect.left, // Source width
- SourceRect.bottom - SourceRect.top, // Source height
- SRCCOPY); // Simple copy
- }
-
- // This displays the sample times over the top of the image. This used to
- // draw the times into the offscreen device context however that actually
- // writes the text into the image data buffer which may not be writable
-
- #ifdef DEBUG
- DisplaySampleTimes(pMediaSample);
- #endif
-
- // Put the old bitmap back into the device context so we don't leak
- SelectObject(m_MemoryDC,hOldBitmap);
-}
-
-
-// This is called when there is a sample ready to be drawn, unfortunately the
-// output pin was being rotten and didn't choose our super excellent shared
-// memory DIB allocator so we have to do this slow render using boring old GDI
-// SetDIBitsToDevice and StretchDIBits. The down side of using these GDI
-// functions is that the image data has to be copied across from our address
-// space into theirs before going to the screen (although in reality the cost
-// is small because all they do is to map the buffer into their address space)
-
-void CDrawImage::SlowRender(IMediaSample *pMediaSample)
-{
- // Get the BITMAPINFOHEADER for the connection
-
- ASSERT(m_pMediaType);
- BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format());
- BYTE *pImage;
-
- // Get the image data buffer
-
- HRESULT hr = pMediaSample->GetPointer(&pImage);
- if (FAILED(hr)) {
- return;
- }
-
- // This allows derived classes to change the source rectangle that we do
- // the drawing with. For example a renderer may ask a codec to stretch
- // the video from 320x240 to 640x480, in which case the source we see in
- // here will still be 320x240, although the source we want to draw with
- // should be scaled up to 640x480. The base class implementation of this
- // method does nothing but return the same rectangle as we are passed in
-
- RECT SourceRect = ScaleSourceRect(&m_SourceRect);
-
- LONG lAdjustedSourceTop = SourceRect.top;
- // if the origin of bitmap is bottom-left, adjust soruce_rect_top
- // to be the bottom-left corner instead of the top-left.
- if (pbmi->biHeight > 0) {
- lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom;
- }
- // Is the window the same size as the video
-
- if (m_bStretch == FALSE) {
-
- // Put the image straight into the window
-
- SetDIBitsToDevice(
- (HDC) m_hdc, // Target device HDC
- m_TargetRect.left, // X sink position
- m_TargetRect.top, // Y sink position
- m_TargetRect.right - m_TargetRect.left, // Destination width
- m_TargetRect.bottom - m_TargetRect.top, // Destination height
- SourceRect.left, // X source position
- lAdjustedSourceTop, // Adjusted Y source position
- (UINT) 0, // Start scan line
- pbmi->biHeight, // Scan lines present
- pImage, // Image data
- (BITMAPINFO *) pbmi, // DIB header
- DIB_RGB_COLORS); // Type of palette
-
- } else {
-
- // Stretch the image when copying to the window
-
- StretchDIBits(
- (HDC) m_hdc, // Target device HDC
- m_TargetRect.left, // X sink position
- m_TargetRect.top, // Y sink position
- m_TargetRect.right - m_TargetRect.left, // Destination width
- m_TargetRect.bottom - m_TargetRect.top, // Destination height
- SourceRect.left, // X source position
- lAdjustedSourceTop, // Adjusted Y source position
- SourceRect.right - SourceRect.left, // Source width
- SourceRect.bottom - SourceRect.top, // Source height
- pImage, // Image data
- (BITMAPINFO *) pbmi, // DIB header
- DIB_RGB_COLORS, // Type of palette
- SRCCOPY); // Simple image copy
- }
-
- // This shows the sample reference times over the top of the image which
- // looks a little flickery. I tried using GdiSetBatchLimit and GdiFlush to
- // control the screen updates but it doesn't quite work as expected and
- // only partially reduces the flicker. I also tried using a memory context
- // and combining the two in that before doing a final BitBlt operation to
- // the screen, unfortunately this has considerable performance penalties
- // and also means that this code is not executed when compiled retail
-
- #ifdef DEBUG
- DisplaySampleTimes(pMediaSample);
- #endif
-}
-
-
-// This is called with an IMediaSample interface on the image to be drawn. We
-// decide on the drawing mechanism based on who's allocator we are using. We
-// may be called when the window wants an image painted by WM_PAINT messages
-// We can't realise the palette here because we have the renderer lock, any
-// call to realise may cause an interthread send message to the window thread
-// which may in turn be waiting to get the renderer lock before servicing it
-
-BOOL CDrawImage::DrawImage(IMediaSample *pMediaSample)
-{
- ASSERT(m_hdc);
- ASSERT(m_MemoryDC);
- NotifyStartDraw();
-
- // If the output pin used our allocator then the samples passed are in
- // fact CVideoSample objects that contain CreateDIBSection data that we
- // use to do faster image rendering, they may optionally also contain a
- // DirectDraw surface pointer in which case we do not do the drawing
-
- if (m_bUsingImageAllocator == FALSE) {
- SlowRender(pMediaSample);
- EXECUTE_ASSERT(GdiFlush());
- NotifyEndDraw();
- return TRUE;
- }
-
- // This is a DIBSECTION buffer
-
- FastRender(pMediaSample);
- EXECUTE_ASSERT(GdiFlush());
- NotifyEndDraw();
- return TRUE;
-}
-
-
-BOOL CDrawImage::DrawVideoImageHere(
- HDC hdc,
- IMediaSample *pMediaSample,
- __in LPRECT lprcSrc,
- __in LPRECT lprcDst
- )
-{
- ASSERT(m_pMediaType);
- BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format());
- BYTE *pImage;
-
- // Get the image data buffer
-
- HRESULT hr = pMediaSample->GetPointer(&pImage);
- if (FAILED(hr)) {
- return FALSE;
- }
-
- RECT SourceRect;
- RECT TargetRect;
-
- if (lprcSrc) {
- SourceRect = *lprcSrc;
- }
- else SourceRect = ScaleSourceRect(&m_SourceRect);
-
- if (lprcDst) {
- TargetRect = *lprcDst;
- }
- else TargetRect = m_TargetRect;
-
- LONG lAdjustedSourceTop = SourceRect.top;
- // if the origin of bitmap is bottom-left, adjust soruce_rect_top
- // to be the bottom-left corner instead of the top-left.
- if (pbmi->biHeight > 0) {
- lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom;
- }
-
-
- // Stretch the image when copying to the DC
-
- BOOL bRet = (0 != StretchDIBits(hdc,
- TargetRect.left,
- TargetRect.top,
- TargetRect.right - TargetRect.left,
- TargetRect.bottom - TargetRect.top,
- SourceRect.left,
- lAdjustedSourceTop,
- SourceRect.right - SourceRect.left,
- SourceRect.bottom - SourceRect.top,
- pImage,
- (BITMAPINFO *)pbmi,
- DIB_RGB_COLORS,
- SRCCOPY));
- return bRet;
-}
-
-
-// This is called by the owning window object after it has created the window
-// and it's drawing contexts. We are constructed with the base window we'll
-// be drawing into so when given the notification we retrive the device HDCs
-// to draw with. We cannot call these in our constructor as they are virtual
-
-void CDrawImage::SetDrawContext()
-{
- m_MemoryDC = m_pBaseWindow->GetMemoryHDC();
- m_hdc = m_pBaseWindow->GetWindowHDC();
-}
-
-
-// This is called to set the target rectangle in the video window, it will be
-// called whenever a WM_SIZE message is retrieved from the message queue. We
-// simply store the rectangle and use it later when we do the drawing calls
-
-void CDrawImage::SetTargetRect(__in RECT *pTargetRect)
-{
- ASSERT(pTargetRect);
- m_TargetRect = *pTargetRect;
- SetStretchMode();
-}
-
-
-// Return the current target rectangle
-
-void CDrawImage::GetTargetRect(__out RECT *pTargetRect)
-{
- ASSERT(pTargetRect);
- *pTargetRect = m_TargetRect;
-}
-
-
-// This is called when we want to change the section of the image to draw. We
-// use this information in the drawing operation calls later on. We must also
-// see if the source and destination rectangles have the same dimensions. If
-// not we must stretch during the drawing rather than a direct pixel copy
-
-void CDrawImage::SetSourceRect(__in RECT *pSourceRect)
-{
- ASSERT(pSourceRect);
- m_SourceRect = *pSourceRect;
- SetStretchMode();
-}
-
-
-// Return the current source rectangle
-
-void CDrawImage::GetSourceRect(__out RECT *pSourceRect)
-{
- ASSERT(pSourceRect);
- *pSourceRect = m_SourceRect;
-}
-
-
-// This is called when either the source or destination rectanges change so we
-// can update the stretch flag. If the rectangles don't match we stretch the
-// video during the drawing otherwise we call the fast pixel copy functions
-// NOTE the source and/or the destination rectangle may be completely empty
-
-void CDrawImage::SetStretchMode()
-{
- // Calculate the overall rectangle dimensions
-
- LONG SourceWidth = m_SourceRect.right - m_SourceRect.left;
- LONG SinkWidth = m_TargetRect.right - m_TargetRect.left;
- LONG SourceHeight = m_SourceRect.bottom - m_SourceRect.top;
- LONG SinkHeight = m_TargetRect.bottom - m_TargetRect.top;
-
- m_bStretch = TRUE;
- if (SourceWidth == SinkWidth) {
- if (SourceHeight == SinkHeight) {
- m_bStretch = FALSE;
- }
- }
-}
-
-
-// Tell us whose allocator we are using. This should be called with TRUE if
-// the filter agrees to use an allocator based around the CImageAllocator
-// SDK base class - whose image buffers are made through CreateDIBSection.
-// Otherwise this should be called with FALSE and we will draw the images
-// using SetDIBitsToDevice and StretchDIBitsToDevice. None of these calls
-// can handle buffers which have non zero strides (like DirectDraw uses)
-
-void CDrawImage::NotifyAllocator(BOOL bUsingImageAllocator)
-{
- m_bUsingImageAllocator = bUsingImageAllocator;
-}
-
-
-// Are we using the image DIBSECTION allocator
-
-BOOL CDrawImage::UsingImageAllocator()
-{
- return m_bUsingImageAllocator;
-}
-
-
-// We need the media type of the connection so that we can get the BITMAPINFO
-// from it. We use that in the calls to draw the image such as StretchDIBits
-// and also when updating the colour table held in shared memory DIBSECTIONs
-
-void CDrawImage::NotifyMediaType(__in CMediaType *pMediaType)
-{
- m_pMediaType = pMediaType;
-}
-
-
-// We store in this object a cookie maintaining the current palette version.
-// Each time a palettised format is changed we increment this value so that
-// when we come to draw the images we look at the colour table value they
-// have and if less than the current we know to update it. This version is
-// only needed and indeed used when working with shared memory DIBSECTIONs
-
-LONG CDrawImage::GetPaletteVersion()
-{
- return m_PaletteVersion;
-}
-
-
-// Resets the current palette version number
-
-void CDrawImage::ResetPaletteVersion()
-{
- m_PaletteVersion = PALETTE_VERSION;
-}
-
-
-// Increment the current palette version
-
-void CDrawImage::IncrementPaletteVersion()
-{
- m_PaletteVersion++;
-}
-
-
-// Constructor must initialise the base allocator. Each sample we create has a
-// palette version cookie on board. When the source filter changes the palette
-// during streaming the window object increments an internal cookie counter it
-// keeps as well. When it comes to render the samples it looks at the cookie
-// values and if they don't match then it knows to update the sample's colour
-// table. However we always create samples with a cookie of PALETTE_VERSION
-// If there have been multiple format changes and we disconnect and reconnect
-// thereby causing the samples to be reallocated we will create them with a
-// cookie much lower than the current version, this isn't a problem since it
-// will be seen by the window object and the versions will then be updated
-
-CImageAllocator::CImageAllocator(__inout CBaseFilter *pFilter,
- __in_opt LPCTSTR pName,
- __inout HRESULT *phr) :
- CBaseAllocator(pName,NULL,phr,TRUE,TRUE),
- m_pFilter(pFilter)
-{
- ASSERT(phr);
- ASSERT(pFilter);
-}
-
-
-// Check our DIB buffers have been released
-
-#ifdef DEBUG
-CImageAllocator::~CImageAllocator()
-{
- ASSERT(m_bCommitted == FALSE);
-}
-#endif
-
-
-// Called from destructor and also from base class to free resources. We work
-// our way through the list of media samples deleting the DIBSECTION created
-// for each. All samples should be back in our list so there is no chance a
-// filter is still using one to write on the display or hold on a pending list
-
-void CImageAllocator::Free()
-{
- ASSERT(m_lAllocated == m_lFree.GetCount());
- EXECUTE_ASSERT(GdiFlush());
- CImageSample *pSample;
- DIBDATA *pDibData;
-
- while (m_lFree.GetCount() != 0) {
- pSample = (CImageSample *) m_lFree.RemoveHead();
- pDibData = pSample->GetDIBData();
- EXECUTE_ASSERT(DeleteObject(pDibData->hBitmap));
- EXECUTE_ASSERT(CloseHandle(pDibData->hMapping));
- delete pSample;
- }
-
- m_lAllocated = 0;
-}
-
-
-// Prepare the allocator by checking all the input parameters
-
-STDMETHODIMP CImageAllocator::CheckSizes(__in ALLOCATOR_PROPERTIES *pRequest)
-{
- // Check we have a valid connection
-
- if (m_pMediaType == NULL) {
- return VFW_E_NOT_CONNECTED;
- }
-
- // NOTE We always create a DIB section with the source format type which
- // may contain a source palette. When we do the BitBlt drawing operation
- // the target display device may contain a different palette (we may not
- // have the focus) in which case GDI will do after the palette mapping
-
- VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *) m_pMediaType->Format();
-
- // When we call CreateDIBSection it implicitly maps only enough memory
- // for the image as defined by thee BITMAPINFOHEADER. If the user asks
- // for an image smaller than this then we reject the call, if they ask
- // for an image larger than this then we return what they can have
-
- if ((DWORD) pRequest->cbBuffer < pVideoInfo->bmiHeader.biSizeImage) {
- return E_INVALIDARG;
- }
-
- // Reject buffer prefixes
-
- if (pRequest->cbPrefix > 0) {
- return E_INVALIDARG;
- }
-
- pRequest->cbBuffer = pVideoInfo->bmiHeader.biSizeImage;
- return NOERROR;
-}
-
-
-// Agree the number of media sample buffers and their sizes. The base class
-// this allocator is derived from allows samples to be aligned only on byte
-// boundaries NOTE the buffers are not allocated until the Commit call
-
-STDMETHODIMP CImageAllocator::SetProperties(
- __in ALLOCATOR_PROPERTIES * pRequest,
- __out ALLOCATOR_PROPERTIES * pActual)
-{
- ALLOCATOR_PROPERTIES Adjusted = *pRequest;
-
- // Check the parameters fit with the current connection
-
- HRESULT hr = CheckSizes(&Adjusted);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseAllocator::SetProperties(&Adjusted, pActual);
-}
-
-
-// Commit the memory by allocating the agreed number of media samples. For
-// each sample we are committed to creating we have a CImageSample object
-// that we use to manage it's resources. This is initialised with a DIBDATA
-// structure that contains amongst other things the GDI DIBSECTION handle
-// We will access the renderer media type during this so we must have locked
-// (to prevent the format changing for example). The class overrides Commit
-// and Decommit to do this locking (base class Commit in turn calls Alloc)
-
-HRESULT CImageAllocator::Alloc(void)
-{
- ASSERT(m_pMediaType);
- CImageSample *pSample;
- DIBDATA DibData;
-
- // Check the base allocator says it's ok to continue
-
- HRESULT hr = CBaseAllocator::Alloc();
- if (FAILED(hr)) {
- return hr;
- }
-
- // We create a new memory mapped object although we don't map it into our
- // address space because GDI does that in CreateDIBSection. It is possible
- // that we run out of resources before creating all the samples in which
- // case the available sample list is left with those already created
-
- ASSERT(m_lAllocated == 0);
- while (m_lAllocated < m_lCount) {
-
- // Create and initialise a shared memory GDI buffer
-
- hr = CreateDIB(m_lSize,DibData);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Create the sample object and pass it the DIBDATA
-
- pSample = CreateImageSample(DibData.pBase,m_lSize);
- if (pSample == NULL) {
- EXECUTE_ASSERT(DeleteObject(DibData.hBitmap));
- EXECUTE_ASSERT(CloseHandle(DibData.hMapping));
- return E_OUTOFMEMORY;
- }
-
- // Add the completed sample to the available list
-
- pSample->SetDIBData(&DibData);
- m_lFree.Add(pSample);
- m_lAllocated++;
- }
- return NOERROR;
-}
-
-
-// We have a virtual method that allocates the samples so that a derived class
-// may override it and allocate more specialised sample objects. So long as it
-// derives its samples from CImageSample then all this code will still work ok
-
-CImageSample *CImageAllocator::CreateImageSample(__in_bcount(Length) LPBYTE pData,LONG Length)
-{
- HRESULT hr = NOERROR;
- CImageSample *pSample;
-
- // Allocate the new sample and check the return codes
-
- pSample = new CImageSample((CBaseAllocator *) this, // Base class
- NAME("Video sample"), // DEBUG name
- (HRESULT *) &hr, // Return code
- (LPBYTE) pData, // DIB address
- (LONG) Length); // Size of DIB
-
- if (pSample == NULL || FAILED(hr)) {
- delete pSample;
- return NULL;
- }
- return pSample;
-}
-
-
-// This function allocates a shared memory block for use by the source filter
-// generating DIBs for us to render. The memory block is created in shared
-// memory so that GDI doesn't have to copy the memory when we do a BitBlt
-
-HRESULT CImageAllocator::CreateDIB(LONG InSize,DIBDATA &DibData)
-{
- BITMAPINFO *pbmi; // Format information for pin
- BYTE *pBase; // Pointer to the actual image
- HANDLE hMapping; // Handle to mapped object
- HBITMAP hBitmap; // DIB section bitmap handle
-
- // Create a file mapping object and map into our address space
-
- hMapping = CreateFileMapping(hMEMORY, // Use system page file
- NULL, // No security attributes
- PAGE_READWRITE, // Full access to memory
- (DWORD) 0, // Less than 4Gb in size
- InSize, // Size of buffer
- NULL); // No name to section
- if (hMapping == NULL) {
- DWORD Error = GetLastError();
- return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error);
- }
-
- // NOTE We always create a DIB section with the source format type which
- // may contain a source palette. When we do the BitBlt drawing operation
- // the target display device may contain a different palette (we may not
- // have the focus) in which case GDI will do after the palette mapping
-
- pbmi = (BITMAPINFO *) HEADER(m_pMediaType->Format());
- if (m_pMediaType == NULL) {
- DbgBreak("Invalid media type");
- }
-
- hBitmap = CreateDIBSection((HDC) NULL, // NO device context
- pbmi, // Format information
- DIB_RGB_COLORS, // Use the palette
- (VOID **) &pBase, // Pointer to image data
- hMapping, // Mapped memory handle
- (DWORD) 0); // Offset into memory
-
- if (hBitmap == NULL || pBase == NULL) {
- EXECUTE_ASSERT(CloseHandle(hMapping));
- DWORD Error = GetLastError();
- return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error);
- }
-
- // Initialise the DIB information structure
-
- DibData.hBitmap = hBitmap;
- DibData.hMapping = hMapping;
- DibData.pBase = pBase;
- DibData.PaletteVersion = PALETTE_VERSION;
- GetObject(hBitmap,sizeof(DIBSECTION),(VOID *)&DibData.DibSection);
-
- return NOERROR;
-}
-
-
-// We use the media type during the DIBSECTION creation
-
-void CImageAllocator::NotifyMediaType(__in CMediaType *pMediaType)
-{
- m_pMediaType = pMediaType;
-}
-
-
-// Overriden to increment the owning object's reference count
-
-STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingAddRef()
-{
- return m_pFilter->AddRef();
-}
-
-
-// Overriden to decrement the owning object's reference count
-
-STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingRelease()
-{
- return m_pFilter->Release();
-}
-
-
-// If you derive a class from CMediaSample that has to transport specialised
-// member variables and entry points then there are three alternate solutions
-// The first is to create a memory buffer larger than actually required by the
-// sample and store your information either at the beginning of it or at the
-// end, the former being moderately safer allowing for misbehaving transform
-// filters. You then adjust the buffer address when you create the base media
-// sample. This has the disadvantage of breaking up the memory allocated to
-// the samples into separate blocks. The second solution is to implement a
-// class derived from CMediaSample and support additional interface(s) that
-// convey your private data. This means defining a custom interface. The final
-// alternative is to create a class that inherits from CMediaSample and adds
-// the private data structures, when you get an IMediaSample in your Receive()
-// call check to see if your allocator is being used, and if it is then cast
-// the IMediaSample into one of your objects. Additional checks can be made
-// to ensure the sample's this pointer is known to be one of your own objects
-
-CImageSample::CImageSample(__inout CBaseAllocator *pAllocator,
- __in_opt LPCTSTR pName,
- __inout HRESULT *phr,
- __in_bcount(length) LPBYTE pBuffer,
- LONG length) :
- CMediaSample(pName,pAllocator,phr,pBuffer,length),
- m_bInit(FALSE)
-{
- ASSERT(pAllocator);
- ASSERT(pBuffer);
-}
-
-
-// Set the shared memory DIB information
-
-void CImageSample::SetDIBData(__in DIBDATA *pDibData)
-{
- ASSERT(pDibData);
- m_DibData = *pDibData;
- m_bInit = TRUE;
-}
-
-
-// Retrieve the shared memory DIB data
-
-__out DIBDATA *CImageSample::GetDIBData()
-{
- ASSERT(m_bInit == TRUE);
- return &m_DibData;
-}
-
-
-// This class handles the creation of a palette. It is fairly specialist and
-// is intended to simplify palette management for video renderer filters. It
-// is for this reason that the constructor requires three other objects with
-// which it interacts, namely a base media filter, a base window and a base
-// drawing object although the base window or the draw object may be NULL to
-// ignore that part of us. We try not to create and install palettes unless
-// absolutely necessary as they typically require WM_PALETTECHANGED messages
-// to be sent to every window thread in the system which is very expensive
-
-CImagePalette::CImagePalette(__inout CBaseFilter *pBaseFilter,
- __inout CBaseWindow *pBaseWindow,
- __inout CDrawImage *pDrawImage) :
- m_pBaseWindow(pBaseWindow),
- m_pFilter(pBaseFilter),
- m_pDrawImage(pDrawImage),
- m_hPalette(NULL)
-{
- ASSERT(m_pFilter);
-}
-
-
-// Destructor
-
-#ifdef DEBUG
-CImagePalette::~CImagePalette()
-{
- ASSERT(m_hPalette == NULL);
-}
-#endif
-
-
-// We allow dynamic format changes of the palette but rather than change the
-// palette every time we call this to work out whether an update is required.
-// If the original type didn't use a palette and the new one does (or vica
-// versa) then we return TRUE. If neither formats use a palette we'll return
-// FALSE. If both formats use a palette we compare their colours and return
-// FALSE if they match. This therefore short circuits palette creation unless
-// absolutely necessary since installing palettes is an expensive operation
-
-BOOL CImagePalette::ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,
- const VIDEOINFOHEADER *pOldInfo)
-{
- // We may not have a current format yet
-
- if (pOldInfo == NULL) {
- return TRUE;
- }
-
- // Do both formats not require a palette
-
- if (ContainsPalette(pNewInfo) == FALSE) {
- if (ContainsPalette(pOldInfo) == FALSE) {
- return FALSE;
- }
- }
-
- // Compare the colours to see if they match
-
- DWORD VideoEntries = pNewInfo->bmiHeader.biClrUsed;
- if (ContainsPalette(pNewInfo) == TRUE)
- if (ContainsPalette(pOldInfo) == TRUE)
- if (pOldInfo->bmiHeader.biClrUsed == VideoEntries)
- if (pOldInfo->bmiHeader.biClrUsed > 0)
- if (memcmp((PVOID) GetBitmapPalette(pNewInfo),
- (PVOID) GetBitmapPalette(pOldInfo),
- VideoEntries * sizeof(RGBQUAD)) == 0) {
-
- return FALSE;
- }
- return TRUE;
-}
-
-
-// This is normally called when the input pin type is set to install a palette
-// We will typically be called from two different places. The first is when we
-// have negotiated a palettised media type after connection, the other is when
-// we receive a new type during processing with an updated palette in which
-// case we must remove and release the resources held by the current palette
-
-// We can be passed an optional device name if we wish to prepare a palette
-// for a specific monitor on a multi monitor system
-
-HRESULT CImagePalette::PreparePalette(const CMediaType *pmtNew,
- const CMediaType *pmtOld,
- __in LPSTR szDevice)
-{
- const VIDEOINFOHEADER *pNewInfo = (VIDEOINFOHEADER *) pmtNew->Format();
- const VIDEOINFOHEADER *pOldInfo = (VIDEOINFOHEADER *) pmtOld->Format();
- ASSERT(pNewInfo);
-
- // This is an performance optimisation, when we get a media type we check
- // to see if the format requires a palette change. If either we need one
- // when previously we didn't or vica versa then this returns TRUE, if we
- // previously needed a palette and we do now it compares their colours
-
- if (ShouldUpdate(pNewInfo,pOldInfo) == FALSE) {
- NOTE("No update needed");
- return S_FALSE;
- }
-
- // We must notify the filter graph that the application may have changed
- // the palette although in practice we don't bother checking to see if it
- // is really different. If it tries to get the palette either the window
- // or renderer lock will ensure it doesn't get in until we are finished
-
- RemovePalette();
- m_pFilter->NotifyEvent(EC_PALETTE_CHANGED,0,0);
-
- // Do we need a palette for the new format
-
- if (ContainsPalette(pNewInfo) == FALSE) {
- NOTE("New has no palette");
- return S_FALSE;
- }
-
- if (m_pBaseWindow) {
- m_pBaseWindow->LockPaletteLock();
- }
-
- // If we're changing the palette on the fly then we increment our palette
- // cookie which is compared against the cookie also stored in all of our
- // DIBSECTION media samples. If they don't match when we come to draw it
- // then we know the sample is out of date and we'll update it's palette
-
- NOTE("Making new colour palette");
- m_hPalette = MakePalette(pNewInfo, szDevice);
- ASSERT(m_hPalette != NULL);
-
- if (m_pBaseWindow) {
- m_pBaseWindow->UnlockPaletteLock();
- }
-
- // The window in which the new palette is to be realised may be a NULL
- // pointer to signal that no window is in use, if so we don't call it
- // Some filters just want to use this object to create/manage palettes
-
- if (m_pBaseWindow) m_pBaseWindow->SetPalette(m_hPalette);
-
- // This is the only time where we need access to the draw object to say
- // to it that a new palette will be arriving on a sample real soon. The
- // constructor may take a NULL pointer in which case we don't call this
-
- if (m_pDrawImage) m_pDrawImage->IncrementPaletteVersion();
- return NOERROR;
-}
-
-
-// Helper function to copy a palette out of any kind of VIDEOINFO (ie it may
-// be YUV or true colour) into a palettised VIDEOINFO. We use this changing
-// palettes on DirectDraw samples as a source filter can attach a palette to
-// any buffer (eg YUV) and hand it back. We make a new palette out of that
-// format and then copy the palette colours into the current connection type
-
-HRESULT CImagePalette::CopyPalette(const CMediaType *pSrc,__out CMediaType *pDest)
-{
- // Reset the destination palette before starting
-
- VIDEOINFOHEADER *pDestInfo = (VIDEOINFOHEADER *) pDest->Format();
- pDestInfo->bmiHeader.biClrUsed = 0;
- pDestInfo->bmiHeader.biClrImportant = 0;
-
- // Does the destination have a palette
-
- if (PALETTISED(pDestInfo) == FALSE) {
- NOTE("No destination palette");
- return S_FALSE;
- }
-
- // Does the source contain a palette
-
- const VIDEOINFOHEADER *pSrcInfo = (VIDEOINFOHEADER *) pSrc->Format();
- if (ContainsPalette(pSrcInfo) == FALSE) {
- NOTE("No source palette");
- return S_FALSE;
- }
-
- // The number of colours may be zero filled
-
- DWORD PaletteEntries = pSrcInfo->bmiHeader.biClrUsed;
- if (PaletteEntries == 0) {
- DWORD Maximum = (1 << pSrcInfo->bmiHeader.biBitCount);
- NOTE1("Setting maximum colours (%d)",Maximum);
- PaletteEntries = Maximum;
- }
-
- // Make sure the destination has enough room for the palette
-
- ASSERT(pSrcInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS);
- ASSERT(pSrcInfo->bmiHeader.biClrImportant <= PaletteEntries);
- ASSERT(COLORS(pDestInfo) == GetBitmapPalette(pDestInfo));
- pDestInfo->bmiHeader.biClrUsed = PaletteEntries;
- pDestInfo->bmiHeader.biClrImportant = pSrcInfo->bmiHeader.biClrImportant;
- ULONG BitmapSize = GetBitmapFormatSize(HEADER(pSrcInfo));
-
- if (pDest->FormatLength() < BitmapSize) {
- NOTE("Reallocating destination");
- pDest->ReallocFormatBuffer(BitmapSize);
- }
-
- // Now copy the palette colours across
-
- CopyMemory((PVOID) COLORS(pDestInfo),
- (PVOID) GetBitmapPalette(pSrcInfo),
- PaletteEntries * sizeof(RGBQUAD));
-
- return NOERROR;
-}
-
-
-// This is normally called when the palette is changed (typically during a
-// dynamic format change) to remove any palette we previously installed. We
-// replace it (if necessary) in the video window with a standard VGA palette
-// that should always be available even if this is a true colour display
-
-HRESULT CImagePalette::RemovePalette()
-{
- if (m_pBaseWindow) {
- m_pBaseWindow->LockPaletteLock();
- }
-
- // Do we have a palette to remove
-
- if (m_hPalette != NULL) {
-
- if (m_pBaseWindow) {
- // Make sure that the window's palette handle matches
- // our palette handle.
- ASSERT(m_hPalette == m_pBaseWindow->GetPalette());
-
- m_pBaseWindow->UnsetPalette();
- }
-
- EXECUTE_ASSERT(DeleteObject(m_hPalette));
- m_hPalette = NULL;
- }
-
- if (m_pBaseWindow) {
- m_pBaseWindow->UnlockPaletteLock();
- }
-
- return NOERROR;
-}
-
-
-// Called to create a palette for the object, the data structure used by GDI
-// to describe a palette is a LOGPALETTE, this includes a variable number of
-// PALETTEENTRY fields which are the colours, we have to convert the RGBQUAD
-// colour fields we are handed in a BITMAPINFO from the media type into these
-// This handles extraction of palettes from true colour and YUV media formats
-
-// We can be passed an optional device name if we wish to prepare a palette
-// for a specific monitor on a multi monitor system
-
-HPALETTE CImagePalette::MakePalette(const VIDEOINFOHEADER *pVideoInfo, __in LPSTR szDevice)
-{
- ASSERT(ContainsPalette(pVideoInfo) == TRUE);
- ASSERT(pVideoInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS);
- BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo);
-
- const RGBQUAD *pColours; // Pointer to the palette
- LOGPALETTE *lp; // Used to create a palette
- HPALETTE hPalette; // Logical palette object
-
- lp = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + SIZE_PALETTE];
- if (lp == NULL) {
- return NULL;
- }
-
- // Unfortunately for some hare brained reason a GDI palette entry (a
- // PALETTEENTRY structure) is different to a palette entry from a DIB
- // format (a RGBQUAD structure) so we have to do the field conversion
- // The VIDEOINFO containing the palette may be a true colour type so
- // we use GetBitmapPalette to skip over any bit fields if they exist
-
- lp->palVersion = PALVERSION;
- lp->palNumEntries = (USHORT) pHeader->biClrUsed;
- if (lp->palNumEntries == 0) lp->palNumEntries = (1 << pHeader->biBitCount);
- pColours = GetBitmapPalette(pVideoInfo);
-
- for (DWORD dwCount = 0;dwCount < lp->palNumEntries;dwCount++) {
- lp->palPalEntry[dwCount].peRed = pColours[dwCount].rgbRed;
- lp->palPalEntry[dwCount].peGreen = pColours[dwCount].rgbGreen;
- lp->palPalEntry[dwCount].peBlue = pColours[dwCount].rgbBlue;
- lp->palPalEntry[dwCount].peFlags = 0;
- }
-
- MakeIdentityPalette(lp->palPalEntry, lp->palNumEntries, szDevice);
-
- // Create a logical palette
-
- hPalette = CreatePalette(lp);
- ASSERT(hPalette != NULL);
- delete[] lp;
- return hPalette;
-}
-
-
-// GDI does a fair job of compressing the palette entries you give it, so for
-// example if you have five entries with an RGB colour (0,0,0) it will remove
-// all but one of them. When you subsequently draw an image it will map from
-// your logical palette to the compressed device palette. This function looks
-// to see if it is trying to be an identity palette and if so sets the flags
-// field in the PALETTEENTRYs so they remain expanded to boost performance
-
-// We can be passed an optional device name if we wish to prepare a palette
-// for a specific monitor on a multi monitor system
-
-HRESULT CImagePalette::MakeIdentityPalette(__inout_ecount_full(iColours) PALETTEENTRY *pEntry,INT iColours, __in LPSTR szDevice)
-{
- PALETTEENTRY SystemEntries[10]; // System palette entries
- BOOL bIdentityPalette = TRUE; // Is an identity palette
- ASSERT(iColours <= iPALETTE_COLORS); // Should have a palette
- const int PalLoCount = 10; // First ten reserved colours
- const int PalHiStart = 246; // Last VGA palette entries
-
- // Does this have the full colour range
-
- if (iColours < 10) {
- return S_FALSE;
- }
-
- // Apparently some displays have odd numbers of system colours
-
- // Get a DC on the right monitor - it's ugly, but this is the way you have
- // to do it
- HDC hdc;
- if (szDevice == NULL || lstrcmpiLocaleIndependentA(szDevice, "DISPLAY") == 0)
- hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
- else
- hdc = CreateDCA(NULL, szDevice, NULL, NULL);
- if (NULL == hdc) {
- return E_OUTOFMEMORY;
- }
- INT Reserved = GetDeviceCaps(hdc,NUMRESERVED);
- if (Reserved != 20) {
- DeleteDC(hdc);
- return S_FALSE;
- }
-
- // Compare our palette against the first ten system entries. The reason I
- // don't do a memory compare between our two arrays of colours is because
- // I am not sure what will be in the flags fields for the system entries
-
- UINT Result = GetSystemPaletteEntries(hdc,0,PalLoCount,SystemEntries);
- for (UINT Count = 0;Count < Result;Count++) {
- if (SystemEntries[Count].peRed != pEntry[Count].peRed ||
- SystemEntries[Count].peGreen != pEntry[Count].peGreen ||
- SystemEntries[Count].peBlue != pEntry[Count].peBlue) {
- bIdentityPalette = FALSE;
- }
- }
-
- // And likewise compare against the last ten entries
-
- Result = GetSystemPaletteEntries(hdc,PalHiStart,PalLoCount,SystemEntries);
- for (UINT Count = 0;Count < Result;Count++) {
- if (INT(Count) + PalHiStart < iColours) {
- if (SystemEntries[Count].peRed != pEntry[PalHiStart + Count].peRed ||
- SystemEntries[Count].peGreen != pEntry[PalHiStart + Count].peGreen ||
- SystemEntries[Count].peBlue != pEntry[PalHiStart + Count].peBlue) {
- bIdentityPalette = FALSE;
- }
- }
- }
-
- // If not an identity palette then return S_FALSE
-
- DeleteDC(hdc);
- if (bIdentityPalette == FALSE) {
- return S_FALSE;
- }
-
- // Set the non VGA entries so that GDI doesn't map them
-
- for (UINT Count = PalLoCount;INT(Count) < min(PalHiStart,iColours);Count++) {
- pEntry[Count].peFlags = PC_NOCOLLAPSE;
- }
- return NOERROR;
-}
-
-
-// Constructor initialises the VIDEOINFO we keep storing the current display
-// format. The format can be changed at any time, to reset the format held
-// by us call the RefreshDisplayType directly (it's a public method). Since
-// more than one thread will typically call us (ie window threads resetting
-// the type and source threads in the type checking methods) we have a lock
-
-CImageDisplay::CImageDisplay()
-{
- RefreshDisplayType(NULL);
-}
-
-
-
-// This initialises the format we hold which contains the display device type
-// We do a conversion on the display device type in here so that when we start
-// type checking input formats we can assume that certain fields have been set
-// correctly, an example is when we make the 16 bit mask fields explicit. This
-// is normally called when we receive WM_DEVMODECHANGED device change messages
-
-// The optional szDeviceName parameter tells us which monitor we are interested
-// in for a multi monitor system
-
-HRESULT CImageDisplay::RefreshDisplayType(__in_opt LPSTR szDeviceName)
-{
- CAutoLock cDisplayLock(this);
-
- // Set the preferred format type
-
- ZeroMemory((PVOID)&m_Display,sizeof(VIDEOINFOHEADER)+sizeof(TRUECOLORINFO));
- m_Display.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- m_Display.bmiHeader.biBitCount = FALSE;
-
- // Get the bit depth of a device compatible bitmap
-
- // get caps of whichever monitor they are interested in (multi monitor)
- HDC hdcDisplay;
- // it's ugly, but this is the way you have to do it
- if (szDeviceName == NULL || lstrcmpiLocaleIndependentA(szDeviceName, "DISPLAY") == 0)
- hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
- else
- hdcDisplay = CreateDCA(NULL, szDeviceName, NULL, NULL);
- if (hdcDisplay == NULL) {
- ASSERT(FALSE);
- DbgLog((LOG_ERROR,1,TEXT("ACK! Can't get a DC for %hs"),
- szDeviceName ? szDeviceName : "<NULL>"));
- return E_FAIL;
- } else {
- DbgLog((LOG_TRACE,3,TEXT("Created a DC for %s"),
- szDeviceName ? szDeviceName : "<NULL>"));
- }
- HBITMAP hbm = CreateCompatibleBitmap(hdcDisplay,1,1);
- if ( hbm )
- {
- GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS);
-
- // This call will get the colour table or the proper bitfields
- GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS);
- DeleteObject(hbm);
- }
- DeleteDC(hdcDisplay);
-
- // Complete the display type initialisation
-
- ASSERT(CheckHeaderValidity(&m_Display));
- UpdateFormat(&m_Display);
- DbgLog((LOG_TRACE,3,TEXT("New DISPLAY bit depth =%d"),
- m_Display.bmiHeader.biBitCount));
- return NOERROR;
-}
-
-
-// We assume throughout this code that any bitfields masks are allowed no
-// more than eight bits to store a colour component. This checks that the
-// bit count assumption is enforced and also makes sure that all the bits
-// set are contiguous. We return a boolean TRUE if the field checks out ok
-
-BOOL CImageDisplay::CheckBitFields(const VIDEOINFO *pInput)
-{
- DWORD *pBitFields = (DWORD *) BITMASKS(pInput);
-
- for (INT iColour = iRED;iColour <= iBLUE;iColour++) {
-
- // First of all work out how many bits are set
-
- DWORD SetBits = CountSetBits(pBitFields[iColour]);
- if (SetBits > iMAXBITS || SetBits == 0) {
- NOTE1("Bit fields for component %d invalid",iColour);
- return FALSE;
- }
-
- // Next work out the number of zero bits prefix
- DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]);
-
- // This is going to see if all the bits set are contiguous (as they
- // should be). We know how much to shift them right by from the
- // count of prefix bits. The number of bits set defines a mask, we
- // invert this (ones complement) and AND it with the shifted bit
- // fields. If the result is NON zero then there are bit(s) sticking
- // out the left hand end which means they are not contiguous
-
- DWORD TestField = pBitFields[iColour] >> PrefixBits;
- DWORD Mask = ULONG_MAX << SetBits;
- if (TestField & Mask) {
- NOTE1("Bit fields for component %d not contiguous",iColour);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-// This counts the number of bits set in the input field
-
-DWORD CImageDisplay::CountSetBits(DWORD Field)
-{
- // This is a relatively well known bit counting algorithm
-
- DWORD Count = 0;
- DWORD init = Field;
-
- // Until the input is exhausted, count the number of bits
-
- while (init) {
- init = init & (init - 1); // Turn off the bottommost bit
- Count++;
- }
- return Count;
-}
-
-
-// This counts the number of zero bits upto the first one set NOTE the input
-// field should have been previously checked to ensure there is at least one
-// set although if we don't find one set we return the impossible value 32
-
-DWORD CImageDisplay::CountPrefixBits(DWORD Field)
-{
- DWORD Mask = 1;
- DWORD Count = 0;
-
- while (TRUE) {
- if (Field & Mask) {
- return Count;
- }
- Count++;
-
- ASSERT(Mask != 0x80000000);
- if (Mask == 0x80000000) {
- return Count;
- }
- Mask <<= 1;
- }
-}
-
-
-// This is called to check the BITMAPINFOHEADER for the input type. There are
-// many implicit dependancies between the fields in a header structure which
-// if we validate now make for easier manipulation in subsequent handling. We
-// also check that the BITMAPINFOHEADER matches it's specification such that
-// fields likes the number of planes is one, that it's structure size is set
-// correctly and that the bitmap dimensions have not been set as negative
-
-BOOL CImageDisplay::CheckHeaderValidity(const VIDEOINFO *pInput)
-{
- // Check the bitmap width and height are not negative.
-
- if (pInput->bmiHeader.biWidth <= 0 ||
- pInput->bmiHeader.biHeight <= 0) {
- NOTE("Invalid bitmap dimensions");
- return FALSE;
- }
-
- // Check the compression is either BI_RGB or BI_BITFIELDS
-
- if (pInput->bmiHeader.biCompression != BI_RGB) {
- if (pInput->bmiHeader.biCompression != BI_BITFIELDS) {
- NOTE("Invalid compression format");
- return FALSE;
- }
- }
-
- // If BI_BITFIELDS compression format check the colour depth
-
- if (pInput->bmiHeader.biCompression == BI_BITFIELDS) {
- if (pInput->bmiHeader.biBitCount != 16) {
- if (pInput->bmiHeader.biBitCount != 32) {
- NOTE("BI_BITFIELDS not 16/32 bit depth");
- return FALSE;
- }
- }
- }
-
- // Check the assumptions about the layout of the bit fields
-
- if (pInput->bmiHeader.biCompression == BI_BITFIELDS) {
- if (CheckBitFields(pInput) == FALSE) {
- NOTE("Bit fields are not valid");
- return FALSE;
- }
- }
-
- // Are the number of planes equal to one
-
- if (pInput->bmiHeader.biPlanes != 1) {
- NOTE("Number of planes not one");
- return FALSE;
- }
-
- // Check the image size is consistent (it can be zero)
-
- if (pInput->bmiHeader.biSizeImage != GetBitmapSize(&pInput->bmiHeader)) {
- if (pInput->bmiHeader.biSizeImage) {
- NOTE("Image size incorrectly set");
- return FALSE;
- }
- }
-
- // Check the size of the structure
-
- if (pInput->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)) {
- NOTE("Size of BITMAPINFOHEADER wrong");
- return FALSE;
- }
- return CheckPaletteHeader(pInput);
-}
-
-
-// This runs a few simple tests against the palette fields in the input to
-// see if it looks vaguely correct. The tests look at the number of palette
-// colours present, the number considered important and the biCompression
-// field which should always be BI_RGB as no other formats are meaningful
-
-BOOL CImageDisplay::CheckPaletteHeader(const VIDEOINFO *pInput)
-{
- // The checks here are for palettised videos only
-
- if (PALETTISED(pInput) == FALSE) {
- if (pInput->bmiHeader.biClrUsed) {
- NOTE("Invalid palette entries");
- return FALSE;
- }
- return TRUE;
- }
-
- // Compression type of BI_BITFIELDS is meaningless for palette video
-
- if (pInput->bmiHeader.biCompression != BI_RGB) {
- NOTE("Palettised video must be BI_RGB");
- return FALSE;
- }
-
- // Check the number of palette colours is correct
-
- if (pInput->bmiHeader.biClrUsed > PALETTE_ENTRIES(pInput)) {
- NOTE("Too many colours in palette");
- return FALSE;
- }
-
- // The number of important colours shouldn't exceed the number used
-
- if (pInput->bmiHeader.biClrImportant > pInput->bmiHeader.biClrUsed) {
- NOTE("Too many important colours");
- return FALSE;
- }
- return TRUE;
-}
-
-
-// Return the format of the video display
-
-const VIDEOINFO *CImageDisplay::GetDisplayFormat()
-{
- return &m_Display;
-}
-
-
-// Return TRUE if the display uses a palette
-
-BOOL CImageDisplay::IsPalettised()
-{
- return PALETTISED(&m_Display);
-}
-
-
-// Return the bit depth of the current display setting
-
-WORD CImageDisplay::GetDisplayDepth()
-{
- return m_Display.bmiHeader.biBitCount;
-}
-
-
-// Initialise the optional fields in a VIDEOINFO. These are mainly to do with
-// the source and destination rectangles and palette information such as the
-// number of colours present. It simplifies our code just a little if we don't
-// have to keep checking for all the different valid permutations in a header
-// every time we want to do anything with it (an example would be creating a
-// palette). We set the base class media type before calling this function so
-// that the media types between the pins match after a connection is made
-
-HRESULT CImageDisplay::UpdateFormat(__inout VIDEOINFO *pVideoInfo)
-{
- ASSERT(pVideoInfo);
-
- BITMAPINFOHEADER *pbmi = HEADER(pVideoInfo);
- SetRectEmpty(&pVideoInfo->rcSource);
- SetRectEmpty(&pVideoInfo->rcTarget);
-
- // Set the number of colours explicitly
-
- if (PALETTISED(pVideoInfo)) {
- if (pVideoInfo->bmiHeader.biClrUsed == 0) {
- pVideoInfo->bmiHeader.biClrUsed = PALETTE_ENTRIES(pVideoInfo);
- }
- }
-
- // The number of important colours shouldn't exceed the number used, on
- // some displays the number of important colours is not initialised when
- // retrieving the display type so we set the colours used correctly
-
- if (pVideoInfo->bmiHeader.biClrImportant > pVideoInfo->bmiHeader.biClrUsed) {
- pVideoInfo->bmiHeader.biClrImportant = PALETTE_ENTRIES(pVideoInfo);
- }
-
- // Change the image size field to be explicit
-
- if (pVideoInfo->bmiHeader.biSizeImage == 0) {
- pVideoInfo->bmiHeader.biSizeImage = GetBitmapSize(&pVideoInfo->bmiHeader);
- }
- return NOERROR;
-}
-
-
-// Lots of video rendering filters want code to check proposed formats are ok
-// This checks the VIDEOINFO we are passed as a media type. If the media type
-// is a valid media type then we return NOERROR otherwise E_INVALIDARG. Note
-// however we only accept formats that can be easily displayed in the display
-// so if we are on a 16 bit device we will not accept 24 bit images. The one
-// complexity is that most displays draw 8 bit palettised images efficiently
-// Also if the input format is less colour bits per pixel then we also accept
-
-HRESULT CImageDisplay::CheckVideoType(const VIDEOINFO *pInput)
-{
- // First of all check the VIDEOINFOHEADER looks correct
-
- if (CheckHeaderValidity(pInput) == FALSE) {
- return E_INVALIDARG;
- }
-
- // Virtually all devices support palettised images efficiently
-
- if (m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount) {
- if (PALETTISED(pInput) == TRUE) {
- ASSERT(PALETTISED(&m_Display) == TRUE);
- NOTE("(Video) Type connection ACCEPTED");
- return NOERROR;
- }
- }
-
-
- // Is the display depth greater than the input format
-
- if (m_Display.bmiHeader.biBitCount > pInput->bmiHeader.biBitCount) {
- NOTE("(Video) Mismatch agreed");
- return NOERROR;
- }
-
- // Is the display depth less than the input format
-
- if (m_Display.bmiHeader.biBitCount < pInput->bmiHeader.biBitCount) {
- NOTE("(Video) Format mismatch");
- return E_INVALIDARG;
- }
-
-
- // Both input and display formats are either BI_RGB or BI_BITFIELDS
-
- ASSERT(m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount);
- ASSERT(PALETTISED(pInput) == FALSE);
- ASSERT(PALETTISED(&m_Display) == FALSE);
-
- // BI_RGB 16 bit representation is implicitly RGB555, and likewise BI_RGB
- // 24 bit representation is RGB888. So we initialise a pointer to the bit
- // fields they really mean and check against the display device format
- // This is only going to be called when both formats are equal bits pixel
-
- const DWORD *pInputMask = GetBitMasks(pInput);
- const DWORD *pDisplayMask = GetBitMasks((VIDEOINFO *)&m_Display);
-
- if (pInputMask[iRED] != pDisplayMask[iRED] ||
- pInputMask[iGREEN] != pDisplayMask[iGREEN] ||
- pInputMask[iBLUE] != pDisplayMask[iBLUE]) {
-
- NOTE("(Video) Bit field mismatch");
- return E_INVALIDARG;
- }
-
- NOTE("(Video) Type connection ACCEPTED");
- return NOERROR;
-}
-
-
-// Return the bit masks for the true colour VIDEOINFO provided
-
-const DWORD *CImageDisplay::GetBitMasks(const VIDEOINFO *pVideoInfo)
-{
- static const DWORD FailMasks[] = {0,0,0};
-
- if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) {
- return BITMASKS(pVideoInfo);
- }
-
- ASSERT(pVideoInfo->bmiHeader.biCompression == BI_RGB);
-
- switch (pVideoInfo->bmiHeader.biBitCount) {
- case 16: return bits555;
- case 24: return bits888;
- case 32: return bits888;
- default: return FailMasks;
- }
-}
-
-
-// Check to see if we can support media type pmtIn as proposed by the output
-// pin - We first check that the major media type is video and also identify
-// the media sub type. Then we thoroughly check the VIDEOINFO type provided
-// As well as the contained VIDEOINFO being correct the major type must be
-// video, the subtype a recognised video format and the type GUID correct
-
-HRESULT CImageDisplay::CheckMediaType(const CMediaType *pmtIn)
-{
- // Does this have a VIDEOINFOHEADER format block
-
- const GUID *pFormatType = pmtIn->FormatType();
- if (*pFormatType != FORMAT_VideoInfo) {
- NOTE("Format GUID not a VIDEOINFOHEADER");
- return E_INVALIDARG;
- }
- ASSERT(pmtIn->Format());
-
- // Check the format looks reasonably ok
-
- ULONG Length = pmtIn->FormatLength();
- if (Length < SIZE_VIDEOHEADER) {
- NOTE("Format smaller than a VIDEOHEADER");
- return E_FAIL;
- }
-
- VIDEOINFO *pInput = (VIDEOINFO *) pmtIn->Format();
-
- // Check the major type is MEDIATYPE_Video
-
- const GUID *pMajorType = pmtIn->Type();
- if (*pMajorType != MEDIATYPE_Video) {
- NOTE("Major type not MEDIATYPE_Video");
- return E_INVALIDARG;
- }
-
- // Check we can identify the media subtype
-
- const GUID *pSubType = pmtIn->Subtype();
- if (GetBitCount(pSubType) == USHRT_MAX) {
- NOTE("Invalid video media subtype");
- return E_INVALIDARG;
- }
- return CheckVideoType(pInput);
-}
-
-
-// Given a video format described by a VIDEOINFO structure we return the mask
-// that is used to obtain the range of acceptable colours for this type, for
-// example, the mask for a 24 bit true colour format is 0xFF in all cases. A
-// 16 bit 5:6:5 display format uses 0xF8, 0xFC and 0xF8, therefore given any
-// RGB triplets we can AND them with these fields to find one that is valid
-
-BOOL CImageDisplay::GetColourMask(__out DWORD *pMaskRed,
- __out DWORD *pMaskGreen,
- __out DWORD *pMaskBlue)
-{
- CAutoLock cDisplayLock(this);
- *pMaskRed = 0xFF;
- *pMaskGreen = 0xFF;
- *pMaskBlue = 0xFF;
-
- // If this format is palettised then it doesn't have bit fields
-
- if (m_Display.bmiHeader.biBitCount < 16) {
- return FALSE;
- }
-
- // If this is a 24 bit true colour display then it can handle all the
- // possible colour component ranges described by a byte. It is never
- // allowed for a 24 bit colour depth image to have BI_BITFIELDS set
-
- if (m_Display.bmiHeader.biBitCount == 24) {
- ASSERT(m_Display.bmiHeader.biCompression == BI_RGB);
- return TRUE;
- }
-
- // Calculate the mask based on the format's bit fields
-
- const DWORD *pBitFields = (DWORD *) GetBitMasks((VIDEOINFO *)&m_Display);
- DWORD *pOutputMask[] = { pMaskRed, pMaskGreen, pMaskBlue };
-
- // We know from earlier testing that there are no more than iMAXBITS
- // bits set in the mask and that they are all contiguous. All that
- // therefore remains is to shift them into the correct position
-
- for (INT iColour = iRED;iColour <= iBLUE;iColour++) {
-
- // This works out how many bits there are and where they live
-
- DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]);
- DWORD SetBits = CountSetBits(pBitFields[iColour]);
-
- // The first shift moves the bit field so that it is right justified
- // in the DWORD, after which we then shift it back left which then
- // puts the leading bit in the bytes most significant bit position
-
- *(pOutputMask[iColour]) = pBitFields[iColour] >> PrefixBits;
- *(pOutputMask[iColour]) <<= (iMAXBITS - SetBits);
- }
- return TRUE;
-}
-
-
-/* Helper to convert to VIDEOINFOHEADER2
-*/
-STDAPI ConvertVideoInfoToVideoInfo2(__inout AM_MEDIA_TYPE *pmt)
-{
- if (pmt->formattype != FORMAT_VideoInfo) {
- return E_INVALIDARG;
- }
- if (NULL == pmt->pbFormat || pmt->cbFormat < sizeof(VIDEOINFOHEADER)) {
- return E_INVALIDARG;
- }
- VIDEOINFO *pVideoInfo = (VIDEOINFO *)pmt->pbFormat;
- DWORD dwNewSize;
- HRESULT hr = DWordAdd(pmt->cbFormat, sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER), &dwNewSize);
- if (FAILED(hr)) {
- return hr;
- }
- PVOID pvNew = CoTaskMemAlloc(dwNewSize);
- if (pvNew == NULL) {
- return E_OUTOFMEMORY;
- }
- CopyMemory(pvNew, pmt->pbFormat, FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader));
- ZeroMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader),
- sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER));
- CopyMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader),
- pmt->pbFormat + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader),
- pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader));
- VIDEOINFOHEADER2 *pVideoInfo2 = (VIDEOINFOHEADER2 *)pvNew;
- pVideoInfo2->dwPictAspectRatioX = (DWORD)pVideoInfo2->bmiHeader.biWidth;
- pVideoInfo2->dwPictAspectRatioY = (DWORD)abs(pVideoInfo2->bmiHeader.biHeight);
- pmt->formattype = FORMAT_VideoInfo2;
- CoTaskMemFree(pmt->pbFormat);
- pmt->pbFormat = (PBYTE)pvNew;
- pmt->cbFormat += sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER);
- return S_OK;
-}
-
-
-// Check a media type containing VIDEOINFOHEADER
-STDAPI CheckVideoInfoType(const AM_MEDIA_TYPE *pmt)
-{
- if (NULL == pmt || NULL == pmt->pbFormat) {
- return E_POINTER;
- }
- if (pmt->majortype != MEDIATYPE_Video ||
- pmt->formattype != FORMAT_VideoInfo ||
- pmt->cbFormat < sizeof(VIDEOINFOHEADER)) {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- const VIDEOINFOHEADER *pHeader = (const VIDEOINFOHEADER *)pmt->pbFormat;
- if (!ValidateBitmapInfoHeader(
- &pHeader->bmiHeader,
- pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader))) {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- return S_OK;
-}
-
-// Check a media type containing VIDEOINFOHEADER2
-STDAPI CheckVideoInfo2Type(const AM_MEDIA_TYPE *pmt)
-{
- if (NULL == pmt || NULL == pmt->pbFormat) {
- return E_POINTER;
- }
- if (pmt->majortype != MEDIATYPE_Video ||
- pmt->formattype != FORMAT_VideoInfo2 ||
- pmt->cbFormat < sizeof(VIDEOINFOHEADER2)) {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- const VIDEOINFOHEADER2 *pHeader = (const VIDEOINFOHEADER2 *)pmt->pbFormat;
- if (!ValidateBitmapInfoHeader(
- &pHeader->bmiHeader,
- pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader))) {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
-
- return S_OK;
-}
diff --git a/third_party/BaseClasses/winutil.h b/third_party/BaseClasses/winutil.h
deleted file mode 100644
index 6bd62354..00000000
--- a/third_party/BaseClasses/winutil.h
+++ /dev/null
@@ -1,419 +0,0 @@
-//------------------------------------------------------------------------------
-// File: WinUtil.h
-//
-// Desc: DirectShow base classes - defines generic handler classes.
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// Make sure that you call PrepareWindow to initialise the window after
-// the object has been constructed. It is a separate method so that
-// derived classes can override useful methods like MessageLoop. Also
-// any derived class must call DoneWithWindow in its destructor. If it
-// doesn't a message may be retrieved and call a derived class member
-// function while a thread is executing the base class destructor code
-
-#ifndef __WINUTIL__
-#define __WINUTIL__
-
-const int DEFWIDTH = 320; // Initial window width
-const int DEFHEIGHT = 240; // Initial window height
-const int CAPTION = 256; // Maximum length of caption
-const int TIMELENGTH = 50; // Maximum length of times
-const int PROFILESTR = 128; // Normal profile string
-const WORD PALVERSION = 0x300; // GDI palette version
-const LONG PALETTE_VERSION = (LONG) 1; // Initial palette version
-const COLORREF VIDEO_COLOUR = 0; // Defaults to black background
-const HANDLE hMEMORY = (HANDLE) (-1); // Says to open as memory file
-
-#define WIDTH(x) ((*(x)).right - (*(x)).left)
-#define HEIGHT(x) ((*(x)).bottom - (*(x)).top)
-#define SHOWSTAGE TEXT("WM_SHOWSTAGE")
-#define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP")
-#define REALIZEPALETTE TEXT("WM_REALIZEPALETTE")
-
-class AM_NOVTABLE CBaseWindow
-{
-protected:
-
- HINSTANCE m_hInstance; // Global module instance handle
- HWND m_hwnd; // Handle for our window
- HDC m_hdc; // Device context for the window
- LONG m_Width; // Client window width
- LONG m_Height; // Client window height
- BOOL m_bActivated; // Has the window been activated
- LPTSTR m_pClassName; // Static string holding class name
- DWORD m_ClassStyles; // Passed in to our constructor
- DWORD m_WindowStyles; // Likewise the initial window styles
- DWORD m_WindowStylesEx; // And the extended window styles
- UINT m_ShowStageMessage; // Have the window shown with focus
- UINT m_ShowStageTop; // Makes the window WS_EX_TOPMOST
- UINT m_RealizePalette; // Makes us realize our new palette
- HDC m_MemoryDC; // Used for fast BitBlt operations
- HPALETTE m_hPalette; // Handle to any palette we may have
- BYTE m_bNoRealize; // Don't realize palette now
- BYTE m_bBackground; // Should we realise in background
- BYTE m_bRealizing; // already realizing the palette
- CCritSec m_WindowLock; // Serialise window object access
- BOOL m_bDoGetDC; // Should this window get a DC
- bool m_bDoPostToDestroy; // Use PostMessage to destroy
- CCritSec m_PaletteLock; // This lock protects m_hPalette.
- // It should be held anytime the
- // program use the value of m_hPalette.
-
- // Maps windows message procedure into C++ methods
- friend LRESULT CALLBACK WndProc(HWND hwnd, // Window handle
- UINT uMsg, // Message ID
- WPARAM wParam, // First parameter
- LPARAM lParam); // Other parameter
-
- virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message);
-
-public:
-
- CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false);
-
-#ifdef DEBUG
- virtual ~CBaseWindow();
-#endif
-
- virtual HRESULT DoneWithWindow();
- virtual HRESULT PrepareWindow();
- virtual HRESULT InactivateWindow();
- virtual HRESULT ActivateWindow();
- virtual BOOL OnSize(LONG Width, LONG Height);
- virtual BOOL OnClose();
- virtual RECT GetDefaultRect();
- virtual HRESULT UninitialiseWindow();
- virtual HRESULT InitialiseWindow(HWND hwnd);
-
- HRESULT CompleteConnect();
- HRESULT DoCreateWindow();
-
- HRESULT PerformanceAlignWindow();
- HRESULT DoShowWindow(LONG ShowCmd);
- void PaintWindow(BOOL bErase);
- void DoSetWindowForeground(BOOL bFocus);
- virtual HRESULT SetPalette(HPALETTE hPalette);
- void SetRealize(BOOL bRealize)
- {
- m_bNoRealize = !bRealize;
- }
-
- // Jump over to the window thread to set the current palette
- HRESULT SetPalette();
- void UnsetPalette(void);
- virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE);
-
- void LockPaletteLock();
- void UnlockPaletteLock();
-
- virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- { return FALSE; };
-
- // Access our window information
-
- bool WindowExists();
- LONG GetWindowWidth();
- LONG GetWindowHeight();
- HWND GetWindowHWND();
- HDC GetMemoryHDC();
- HDC GetWindowHDC();
-
- #ifdef DEBUG
- HPALETTE GetPalette();
- #endif // DEBUG
-
- // This is the window procedure the derived object should override
-
- virtual LRESULT OnReceiveMessage(HWND hwnd, // Window handle
- UINT uMsg, // Message ID
- WPARAM wParam, // First parameter
- LPARAM lParam); // Other parameter
-
- // Must be overriden to return class and window styles
-
- virtual LPTSTR GetClassWindowStyles(
- __out DWORD *pClassStyles, // Class styles
- __out DWORD *pWindowStyles, // Window styles
- __out DWORD *pWindowStylesEx) PURE; // Extended styles
-};
-
-
-// This helper class is entirely subservient to the owning CBaseWindow object
-// All this object does is to split out the actual drawing operation from the
-// main object (because it was becoming too large). We have a number of entry
-// points to set things like the draw device contexts, to implement the actual
-// drawing and to set the destination rectangle in the client window. We have
-// no critical section locking in this class because we are used exclusively
-// by the owning window object which looks after serialising calls into us
-
-// If you want to use this class make sure you call NotifyAllocator once the
-// allocate has been agreed, also call NotifyMediaType with a pointer to a
-// NON stack based CMediaType once that has been set (we keep a pointer to
-// the original rather than taking a copy). When the palette changes call
-// IncrementPaletteVersion (easiest thing to do is to also call this method
-// in the SetMediaType method most filters implement). Finally before you
-// start rendering anything call SetDrawContext so that we can get the HDCs
-// for drawing from the CBaseWindow object we are given during construction
-
-class CDrawImage
-{
-protected:
-
- CBaseWindow *m_pBaseWindow; // Owning video window object
- CRefTime m_StartSample; // Start time for the current sample
- CRefTime m_EndSample; // And likewise it's end sample time
- HDC m_hdc; // Main window device context
- HDC m_MemoryDC; // Offscreen draw device context
- RECT m_TargetRect; // Target destination rectangle
- RECT m_SourceRect; // Source image rectangle
- BOOL m_bStretch; // Do we have to stretch the images
- BOOL m_bUsingImageAllocator; // Are the samples shared DIBSECTIONs
- CMediaType *m_pMediaType; // Pointer to the current format
- int m_perfidRenderTime; // Time taken to render an image
- LONG m_PaletteVersion; // Current palette version cookie
-
- // Draw the video images in the window
-
- void SlowRender(IMediaSample *pMediaSample);
- void FastRender(IMediaSample *pMediaSample);
- void DisplaySampleTimes(IMediaSample *pSample);
- void UpdateColourTable(HDC hdc,__in BITMAPINFOHEADER *pbmi);
- void SetStretchMode();
-
-public:
-
- // Used to control the image drawing
-
- CDrawImage(__inout CBaseWindow *pBaseWindow);
- BOOL DrawImage(IMediaSample *pMediaSample);
- BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample,
- __in LPRECT lprcSrc, __in LPRECT lprcDst);
- void SetDrawContext();
- void SetTargetRect(__in RECT *pTargetRect);
- void SetSourceRect(__in RECT *pSourceRect);
- void GetTargetRect(__out RECT *pTargetRect);
- void GetSourceRect(__out RECT *pSourceRect);
- virtual RECT ScaleSourceRect(const RECT *pSource);
-
- // Handle updating palettes as they change
-
- LONG GetPaletteVersion();
- void ResetPaletteVersion();
- void IncrementPaletteVersion();
-
- // Tell us media types and allocator assignments
-
- void NotifyAllocator(BOOL bUsingImageAllocator);
- void NotifyMediaType(__in CMediaType *pMediaType);
- BOOL UsingImageAllocator();
-
- // Called when we are about to draw an image
-
- void NotifyStartDraw() {
- MSR_START(m_perfidRenderTime);
- };
-
- // Called when we complete an image rendering
-
- void NotifyEndDraw() {
- MSR_STOP(m_perfidRenderTime);
- };
-};
-
-
-// This is the structure used to keep information about each GDI DIB. All the
-// samples we create from our allocator will have a DIBSECTION allocated to
-// them. When we receive the sample we know we can BitBlt straight to an HDC
-
-typedef struct tagDIBDATA {
-
- LONG PaletteVersion; // Current palette version in use
- DIBSECTION DibSection; // Details of DIB section allocated
- HBITMAP hBitmap; // Handle to bitmap for drawing
- HANDLE hMapping; // Handle to shared memory block
- BYTE *pBase; // Pointer to base memory address
-
-} DIBDATA;
-
-
-// This class inherits from CMediaSample and uses all of it's methods but it
-// overrides the constructor to initialise itself with the DIBDATA structure
-// When we come to render an IMediaSample we will know if we are using our own
-// allocator, and if we are, we can cast the IMediaSample to a pointer to one
-// of these are retrieve the DIB section information and hence the HBITMAP
-
-class CImageSample : public CMediaSample
-{
-protected:
-
- DIBDATA m_DibData; // Information about the DIBSECTION
- BOOL m_bInit; // Is the DIB information setup
-
-public:
-
- // Constructor
-
- CImageSample(__inout CBaseAllocator *pAllocator,
- __in_opt LPCTSTR pName,
- __inout HRESULT *phr,
- __in_bcount(length) LPBYTE pBuffer,
- LONG length);
-
- // Maintain the DIB/DirectDraw state
-
- void SetDIBData(__in DIBDATA *pDibData);
- __out DIBDATA *GetDIBData();
-};
-
-
-// This is an allocator based on the abstract CBaseAllocator base class that
-// allocates sample buffers in shared memory. The number and size of these
-// are determined when the output pin calls Prepare on us. The shared memory
-// blocks are used in subsequent calls to GDI CreateDIBSection, once that
-// has been done the output pin can fill the buffers with data which will
-// then be handed to GDI through BitBlt calls and thereby remove one copy
-
-class CImageAllocator : public CBaseAllocator
-{
-protected:
-
- CBaseFilter *m_pFilter; // Delegate reference counts to
- CMediaType *m_pMediaType; // Pointer to the current format
-
- // Used to create and delete samples
-
- HRESULT Alloc();
- void Free();
-
- // Manage the shared DIBSECTION and DCI/DirectDraw buffers
-
- HRESULT CreateDIB(LONG InSize,DIBDATA &DibData);
- STDMETHODIMP CheckSizes(__in ALLOCATOR_PROPERTIES *pRequest);
- virtual CImageSample *CreateImageSample(__in_bcount(Length) LPBYTE pData,LONG Length);
-
-public:
-
- // Constructor and destructor
-
- CImageAllocator(__inout CBaseFilter *pFilter,__in_opt LPCTSTR pName,__inout HRESULT *phr);
-#ifdef DEBUG
- ~CImageAllocator();
-#endif
-
- STDMETHODIMP_(ULONG) NonDelegatingAddRef();
- STDMETHODIMP_(ULONG) NonDelegatingRelease();
- void NotifyMediaType(__in CMediaType *pMediaType);
-
- // Agree the number of buffers to be used and their size
-
- STDMETHODIMP SetProperties(
- __in ALLOCATOR_PROPERTIES *pRequest,
- __out ALLOCATOR_PROPERTIES *pActual);
-};
-
-
-// This class is a fairly specialised helper class for image renderers that
-// have to create and manage palettes. The CBaseWindow class looks after
-// realising palettes once they have been installed. This class can be used
-// to create the palette handles from a media format (which must contain a
-// VIDEOINFO structure in the format block). We try to make the palette an
-// identity palette to maximise performance and also only change palettes
-// if actually required to (we compare palette colours before updating).
-// All the methods are virtual so that they can be overriden if so required
-
-class CImagePalette
-{
-protected:
-
- CBaseWindow *m_pBaseWindow; // Window to realise palette in
- CBaseFilter *m_pFilter; // Media filter to send events
- CDrawImage *m_pDrawImage; // Object who will be drawing
- HPALETTE m_hPalette; // The palette handle we own
-
-public:
-
- CImagePalette(__inout CBaseFilter *pBaseFilter,
- __inout CBaseWindow *pBaseWindow,
- __inout CDrawImage *pDrawImage);
-
-#ifdef DEBUG
- virtual ~CImagePalette();
-#endif
-
- static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, __in LPSTR szDevice);
- HRESULT RemovePalette();
- static HRESULT MakeIdentityPalette(__inout_ecount_full(iColours) PALETTEENTRY *pEntry,INT iColours, __in LPSTR szDevice);
- HRESULT CopyPalette(const CMediaType *pSrc,__out CMediaType *pDest);
- BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo);
- HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,__in LPSTR szDevice);
-
- BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, __in LPRECT lprcSrc, __in LPRECT lprcDst)
- {
- return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst);
- }
-};
-
-
-// Another helper class really for video based renderers. Most such renderers
-// need to know what the display format is to some degree or another. This
-// class initialises itself with the display format. The format can be asked
-// for through GetDisplayFormat and various other accessor functions. If a
-// filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE
-// message then it can call RefreshDisplayType to reset that format). Also
-// many video renderers will want to check formats as they are proposed by
-// source filters. This class provides methods to check formats and only
-// accept those video formats that can be efficiently drawn using GDI calls
-
-class CImageDisplay : public CCritSec
-{
-protected:
-
- // This holds the display format; biSize should not be too big, so we can
- // safely use the VIDEOINFO structure
- VIDEOINFO m_Display;
-
- static DWORD CountSetBits(const DWORD Field);
- static DWORD CountPrefixBits(const DWORD Field);
- static BOOL CheckBitFields(const VIDEOINFO *pInput);
-
-public:
-
- // Constructor and destructor
-
- CImageDisplay();
-
- // Used to manage BITMAPINFOHEADERs and the display format
-
- const VIDEOINFO *GetDisplayFormat();
- HRESULT RefreshDisplayType(__in_opt LPSTR szDeviceName);
- static BOOL CheckHeaderValidity(const VIDEOINFO *pInput);
- static BOOL CheckPaletteHeader(const VIDEOINFO *pInput);
- BOOL IsPalettised();
- WORD GetDisplayDepth();
-
- // Provide simple video format type checking
-
- HRESULT CheckMediaType(const CMediaType *pmtIn);
- HRESULT CheckVideoType(const VIDEOINFO *pInput);
- HRESULT UpdateFormat(__inout VIDEOINFO *pVideoInfo);
- const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo);
-
- BOOL GetColourMask(__out DWORD *pMaskRed,
- __out DWORD *pMaskGreen,
- __out DWORD *pMaskBlue);
-};
-
-// Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2
-STDAPI ConvertVideoInfoToVideoInfo2(__inout AM_MEDIA_TYPE *pmt);
-
-// Check a media type containing VIDEOINFOHEADER
-STDAPI CheckVideoInfoType(const AM_MEDIA_TYPE *pmt);
-
-// Check a media type containing VIDEOINFOHEADER
-STDAPI CheckVideoInfo2Type(const AM_MEDIA_TYPE *pmt);
-
-#endif // __WINUTIL__
-