Remove the filter project.

This commit is contained in:
oioitff committed 2013-05-30 19:22:09 +08:00
1 parent 852a07d347
commit 60f56a3cb6
13 files changed
-2569

No files matched your search

-149
View File
@@ -1,149 +0,0 @@
// A simple stream source filter based on the sample code
// It requires DirectShow BasicClass for compiling
#include <streams.h>
#include "asyncio.h"
#include "asyncrdr.h"
#pragma warning(disable:4710) // 'function' not inlined (optimization)
#include "asyncflt.h"
//
// Setup data for filter registration
//
const AMOVIESETUP_MEDIATYPE sudOpPinTypes =
{ &MEDIATYPE_Stream // clsMajorType
, &MEDIASUBTYPE_NULL }; // clsMinorType
const AMOVIESETUP_PIN sudOpPin =
{ L"Output" // strName
, FALSE // bRendered
, TRUE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"Input" // strConnectsToPin
, 1 // nTypes
, &sudOpPinTypes }; // lpTypes
const AMOVIESETUP_FILTER sudAsync =
{ &CLSID_AsyncStreamSource // clsID
, L"Stream/File Source (Async.)" // strName
, MERIT_UNLIKELY // dwMerit
, 1 // nPins
, &sudOpPin }; // lpPin
//
// Object creation template
//
CFactoryTemplate g_Templates[1] = {
{ L"Stream/File Source (Async.)"
, &CLSID_AsyncStreamSource
, CAsyncFilter::CreateInstance
, NULL
, &sudAsync }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
////////////////////////////////////////////////////////////////////////
//
// Exported entry points for registration and unregistration
// (in this case they only call through to default implementations).
//
////////////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
//
// DllEntryPoint
//
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
//* Create a new instance of this class
CUnknown * WINAPI CAsyncFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{
ASSERT(phr);
// DLLEntry does the right thing with the return code and
// the returned value on failure
return new CAsyncFilter(pUnk, phr);
}
BOOL CAsyncFilter::ReadTheFile(LPCTSTR lpszFileName)
{
DWORD dwBytesRead;
// Open the requested file
HANDLE hFile = CreateFile(lpszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DbgLog((LOG_TRACE, 2, TEXT("Could not open %s\n"), lpszFileName));
return FALSE;
}
// Determine the file size
ULARGE_INTEGER uliSize;
uliSize.LowPart = GetFileSize(hFile, &uliSize.HighPart);
PBYTE pbMem = new BYTE[uliSize.LowPart];
if (pbMem == NULL)
{
CloseHandle(hFile);
return FALSE;
}
// Read the data from the file
if (!ReadFile(hFile,
(LPVOID) pbMem,
uliSize.LowPart,
&dwBytesRead,
NULL) ||
(dwBytesRead != uliSize.LowPart))
{
DbgLog((LOG_TRACE, 1, TEXT("Could not read file\n")));
delete [] pbMem;
CloseHandle(hFile);
return FALSE;
}
// Save a pointer to the data that was read from the file
if (m_pbData)
delete [] m_pbData;
m_pbData = pbMem;
m_llSize = (LONGLONG)uliSize.QuadPart;
// Close the file
CloseHandle(hFile);
return TRUE;
}
-13
View File
@@ -1,13 +0,0 @@
;===========================================================================
; Copyright (c) 1992-2002 Microsoft Corporation. All Rights Reserved.
;===========================================================================
LIBRARY AsyncStreamflt.ax
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
-305
View File
@@ -1,305 +0,0 @@
// A simple stream source filter based on the sample code
#include "StreamSourceflt.h"
// NOTE: This filter does NOT support AVI format
//
// Define an internal filter that wraps the base CBaseReader stuff
//
class CMemStream : public CAsyncStream
{
public:
CMemStream() :
m_llPosition(0)
{
}
/* Initialization */
void Init(LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE)
{
m_pbData = pbData;
m_llLength = llLength;
m_dwKBPerSec = dwKBPerSec;
m_dwTimeStart = timeGetTime();
m_llreadSize = llLength;
m_bisReadPassEnd = FALSE;
}
HRESULT SetPointer(LONGLONG llPos)
{
if (llPos < 0 || llPos > m_llLength) {
return S_FALSE;
} else {
m_llPosition = llPos;
return S_OK;
}
}
HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
CAutoLock lck(&m_csLock);
DWORD dwReadLength;
/* Wait until the bytes are here! */
DWORD dwTime = timeGetTime();
if (m_llPosition + dwBytesToRead > m_llLength) {
dwReadLength = (DWORD)(m_llLength - m_llPosition);
} else {
dwReadLength = dwBytesToRead;
}
DWORD dwTimeToArrive =
((DWORD)m_llPosition + dwReadLength) / m_dwKBPerSec;
if (dwTime - m_dwTimeStart < dwTimeToArrive) {
Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
}
CopyMemory((PVOID)pbBuffer, (PVOID)(m_pbData + m_llPosition),
dwReadLength);
m_llPosition += dwReadLength;
*pdwBytesRead = dwReadLength;
if (m_llPosition >= m_llreadSize)
m_bisReadPassEnd = TRUE;
else
m_bisReadPassEnd = FALSE;
return S_OK;
}
LONGLONG Size(LONGLONG *pSizeAvailable)
{
LONGLONG llCurrentAvailable =
static_cast <LONGLONG> (UInt32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec));
*pSizeAvailable = min(m_llLength, llCurrentAvailable);
return m_llLength;
}
DWORD Alignment()
{
return 1;
}
void Lock()
{
m_csLock.Lock();
}
void Unlock()
{
m_csLock.Unlock();
}
private:
CCritSec m_csLock;
PBYTE m_pbData;
LONGLONG m_llLength;
LONGLONG m_llPosition;
DWORD m_dwKBPerSec;
DWORD m_dwTimeStart;
public:
LONGLONG m_llreadSize;
BOOL m_bisReadPassEnd;
};
class CAsyncFilter : public CAsyncReader, public IStreamSourceFilter
{
public:
CAsyncFilter(LPUNKNOWN pUnk, HRESULT *phr) :
CAsyncReader(NAME("Mem Reader"), pUnk, &m_Stream, phr),
m_pFileName(NULL),
m_pbData(NULL)
{
}
~CAsyncFilter()
{
delete [] m_pbData;
delete [] m_pFileName;
}
static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IStreamSourceFilter) {
return GetInterface((IStreamSourceFilter *)this, ppv);
} else if (riid == IID_IFileSourceFilter) {
return GetInterface((IFileSourceFilter *)this, ppv);
} else {
return CAsyncReader::NonDelegatingQueryInterface(riid, ppv);
}
}
/* IFileSourceFilter methods */
// Load a (new) file
STDMETHODIMP Load(LPCOLESTR lpwszFileName, const AM_MEDIA_TYPE *pmt)
{
CheckPointer(lpwszFileName, E_POINTER);
// lstrlenW is one of the few Unicode functions that works on win95
int cch = lstrlenW(lpwszFileName) + 1;
#ifndef UNICODE
TCHAR *lpszFileName=0;
lpszFileName = new char[cch * 2];
if (!lpszFileName) {
return E_OUTOFMEMORY;
}
WideCharToMultiByte(GetACP(), 0, lpwszFileName, -1,
lpszFileName, cch, NULL, NULL);
#else
TCHAR lpszFileName[MAX_PATH]={0};
(void)StringCchCopy(lpszFileName, NUMELMS(lpszFileName), lpwszFileName);
#endif
CAutoLock lck(&m_csFilter);
/* Check the file type */
CMediaType cmt;
if (NULL == pmt) {
cmt.SetType(&MEDIATYPE_Stream);
cmt.SetSubtype(&MEDIASUBTYPE_NULL);
} else {
cmt = *pmt;
}
if (!ReadTheFile(lpszFileName)) {
#ifndef UNICODE
delete [] lpszFileName;
#endif
return E_FAIL;
}
m_Stream.Init(m_pbData, m_llSize);
if (m_pFileName)
delete [] m_pFileName;
m_pFileName = new WCHAR[cch];
if (m_pFileName!=NULL)
CopyMemory(m_pFileName, lpwszFileName, cch*sizeof(WCHAR));
// this is not a simple assignment... pointers and format
// block (if any) are intelligently copied
m_mt = cmt;
/* Work out file type */
cmt.bTemporalCompression = TRUE; //???
cmt.lSampleSize = 1;
return S_OK;
}
// Modeled on IPersistFile::Load
// Caller needs to CoTaskMemFree or equivalent.
STDMETHODIMP GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt)
{
CheckPointer(ppszFileName, E_POINTER);
*ppszFileName = NULL;
if (m_pFileName!=NULL) {
DWORD n = sizeof(WCHAR)*(1+lstrlenW(m_pFileName));
*ppszFileName = (LPOLESTR) CoTaskMemAlloc( n );
if (*ppszFileName!=NULL) {
CopyMemory(*ppszFileName, m_pFileName, n);
}
}
if (pmt!=NULL) {
CopyMediaType(pmt, &m_mt);
}
return NOERROR;
}
STDMETHODIMP LoadStream(void *stream, LONGLONG readSize, LONGLONG streamSize, AM_MEDIA_TYPE *pmt )
{
CAutoLock lck(&m_csFilter);
/* Check the file type */
CMediaType cmt;
if (NULL == pmt) {
cmt.SetType(&MEDIATYPE_Stream);
cmt.SetSubtype(&MEDIASUBTYPE_NULL);
} else {
cmt = *pmt;
}
if (m_pFileName)
delete [] m_pFileName;
m_pFileName = NULL;
PBYTE pbMem = new BYTE[streamSize];
if (pbMem == NULL)
return E_FAIL;
CopyMemory(pbMem, stream, readSize);
if (m_pbData)
delete [] m_pbData;
m_pbData = pbMem;
m_llSize = streamSize;
m_Stream.Init(m_pbData, m_llSize);
m_Stream.m_llreadSize = readSize;
// this is not a simple assignment... pointers and format
// block (if any) are intelligently copied
m_mt = cmt;
/* Work out file type */
cmt.bTemporalCompression = TRUE; //???
cmt.lSampleSize = 1;
return S_OK;
}
STDMETHODIMP AddStreamData(LONGLONG offset, void *stream, LONGLONG addSize)
{
if (m_pbData == NULL)
return E_FAIL;
if (addSize > m_llSize - offset)
addSize = m_llSize - offset;
CopyMemory(m_pbData + offset, stream, addSize);
if (offset + addSize > m_Stream.m_llreadSize)
m_Stream.m_llreadSize = offset + addSize;
return S_OK;
}
STDMETHODIMP GetStreamInfo(LONGLONG *readSize, LONGLONG *streamSize)
{
if (readSize)
*readSize = m_Stream.m_llreadSize;
if (streamSize)
*streamSize = m_llSize;
return S_OK;
}
STDMETHODIMP SetReadSize(LONGLONG readSize)
{
m_Stream.m_llreadSize = readSize;
return S_OK;
}
BOOL STDMETHODCALLTYPE IsReadPassEnd()
{
return m_Stream.m_bisReadPassEnd;
}
private:
BOOL CAsyncFilter::ReadTheFile(LPCTSTR lpszFileName);
private:
LPWSTR m_pFileName;
LONGLONG m_llSize;
PBYTE m_pbData;
CMemStream m_Stream;
};
-53
View File
@@ -1,53 +0,0 @@
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) Microsoft Corporation. All Rights Reserved.
//
//--------------------------------------------------------------------------;
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 9,0,0,0
PRODUCTVERSION 9,0,0,0
FILEFLAGSMASK 0x30003fL
#ifdef _DEBUG
FILEFLAGS 0xbL
#else
FILEFLAGS 0xaL
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "ActiveMovie", "Filter dll"
VALUE "Comment", "Async Stream/File Source Filter"
VALUE "CompanyName", "NULL"
VALUE "FileDescription", "Stream/File Source (Async.)"
VALUE "FileVersion", "9.00"
VALUE "InternalName", "AsyncStreamflt.ax"
VALUE "LegalCopyright", "NULL"
VALUE "OLESelfRegister", "AM20"
VALUE "OriginalFilename", "AsyncStreamflt.ax"
VALUE "ProductName", "Async Stream/File Source Filter"
VALUE "ProductVersion", "9.00"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
-21
View File
@@ -1,21 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "async", "asyncflt.vcxproj", "{0413A576-4B1B-7294-5FA3-3F839282D877}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug Unicode|Win32 = Debug Unicode|Win32
Debug|Win32 = Debug|Win32
Release Unicode|Win32 = Release Unicode|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0413A576-4B1B-7294-5FA3-3F839282D877}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
{0413A576-4B1B-7294-5FA3-3F839282D877}.Debug|Win32.ActiveCfg = Debug|Win32
{0413A576-4B1B-7294-5FA3-3F839282D877}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
{0413A576-4B1B-7294-5FA3-3F839282D877}.Release|Win32.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-305
View File
@@ -1,305 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug Unicode|Win32">
<Configuration>Debug Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release Unicode|Win32">
<Configuration>Release Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>async</ProjectName>
<SccProjectName />
<SccLocalPath />
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\lib</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.\Debug_Unicode\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.\Debug_Unicode\</IntDir>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</IgnoreImportLibrary>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">..\lib</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">.\Release_Unicode\</IntDir>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</IgnoreImportLibrary>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(LibraryPath)</LibraryPath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath)</LibraryPath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(LibraryPath)</LibraryPath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath)</LibraryPath>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AsyncStreamflt.ax</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">AsyncStreamflt_u.ax</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;ASYNC_EXPORTS;INC_OLE2;STRICT;_WIN32_WINNT=0x0403;WIN32;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderFile>streams.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>.\Release/asyncflt.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>strmbase.lib;quartz.lib;winmm.lib;msvcrt.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\lib\AsyncStreamflt.ax</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\asyncflt.def</ModuleDefinitionFile>
<ProgramDatabaseFile>.\Release/asyncflt.pdb</ProgramDatabaseFile>
<OptimizeReferences>
</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>.\Release/asyncflt.lib</ImportLibrary>
</Link>
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/asyncflt.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\..\BaseClasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>INC_OLE2;STRICT;_WIN32_WINNT=0x0403;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;DBG=1;DEBUG;_DEBUG;WIN32;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderFile>streams.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>.\Debug_Unicode/asyncflt.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug_Unicode/</AssemblerListingLocation>
<ObjectFileName>.\Debug_Unicode/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug_Unicode/</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>strmbasd.lib;quartz.lib;winmm.lib;msvcrtd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>Debug_Unicode/asyncflt.ax</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\asyncflt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ImportLibrary>.\Debug_Unicode/asyncflt.lib</ImportLibrary>
</Link>
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug_Unicode/asyncflt.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\..\BaseClasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_MBCS;_USRDLL;ASYNC_EXPORTS;INC_OLE2;STRICT;_WIN32_WINNT=0x0403;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;WIN32;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderFile>streams.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>.\Release_Unicode/asyncflt.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release_Unicode/</AssemblerListingLocation>
<ObjectFileName>.\Release_Unicode/</ObjectFileName>
<ProgramDataBaseFileName>.\Release_Unicode/</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>strmbase.lib;quartz.lib;winmm.lib;msvcrt.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>Release_Unicode/asyncflt.ax</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\asyncflt.def</ModuleDefinitionFile>
<ProgramDatabaseFile>.\Release_Unicode/asyncflt.pdb</ProgramDatabaseFile>
<OptimizeReferences>
</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>.\Release_Unicode/asyncflt.lib</ImportLibrary>
</Link>
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release_Unicode/asyncflt.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\..\BaseClasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>INC_OLE2;STRICT;_WIN32_WINNT=0x0403;WIN32;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;DBG=1;DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderFile>streams.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>.\Debug/asyncflt.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>StdCall</CallingConvention>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>strmbasd.lib;quartz.lib;winmm.lib;msvcrtd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>Debug/asyncflt.ax</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>.\asyncflt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ImportLibrary>.\Debug/asyncflt.lib</ImportLibrary>
</Link>
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/asyncflt.tlb</TypeLibraryName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>..\..\..\BaseClasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="asyncflt.cpp" />
<ClCompile Include="asyncio.cpp" />
<ClCompile Include="asyncrdr.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="asyncflt.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="asyncflt.h" />
<ClInclude Include="asyncio.h" />
<ClInclude Include="asyncrdr.h" />
<ClInclude Include="StreamSourceflt.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="asyncflt.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{2cb60d77-18ca-45ad-a4f3-0d736ca63aac}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{1aece6a2-e345-4279-81ae-993564c5b48a}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{56fe04f5-c6f6-43c9-95e2-a95245afadd0}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="asyncflt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="asyncio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="asyncrdr.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="asyncflt.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="asyncflt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="asyncio.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="asyncrdr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="StreamSourceflt.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="asyncflt.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
-708
View File
@@ -1,708 +0,0 @@
//------------------------------------------------------------------------------
// File: AsyncIo.cpp
//
// Desc: DirectShow sample code - base library with I/O functionality.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "asyncio.h"
// --- CAsyncRequest ---
// implementation of CAsyncRequest representing a single
// outstanding request. All the i/o for this object is done
// in the Complete method.
// init the params for this request.
// Read is not issued until the complete call
HRESULT
CAsyncRequest::Request(
CAsyncIo *pIo,
CAsyncStream *pStream,
LONGLONG llPos,
LONG lLength,
BOOL bAligned,
BYTE* pBuffer,
LPVOID pContext, // filter's context
DWORD_PTR dwUser) // downstream filter's context
{
m_pIo = pIo;
m_pStream = pStream;
m_llPos = llPos;
m_lLength = lLength;
m_bAligned = bAligned;
m_pBuffer = pBuffer;
m_pContext = pContext;
m_dwUser = dwUser;
m_hr = VFW_E_TIMEOUT; // not done yet
return S_OK;
}
// issue the i/o if not overlapped, and block until i/o complete.
// returns error code of file i/o
//
//
HRESULT
CAsyncRequest::Complete()
{
m_pStream->Lock();
m_hr = m_pStream->SetPointer(m_llPos);
if(S_OK == m_hr)
{
DWORD dwActual;
m_hr = m_pStream->Read(m_pBuffer, m_lLength, m_bAligned, &dwActual);
if(m_hr == OLE_S_FIRST)
{
if(m_pContext)
{
IMediaSample *pSample = reinterpret_cast<IMediaSample *>(m_pContext);
pSample->SetDiscontinuity(TRUE);
m_hr = S_OK;
}
}
if(FAILED(m_hr))
{
}
else if(dwActual != (DWORD)m_lLength)
{
// tell caller size changed - probably because of EOF
m_lLength = (LONG) dwActual;
m_hr = S_FALSE;
}
else
{
m_hr = S_OK;
}
}
m_pStream->Unlock();
return m_hr;
}
// --- CAsyncIo ---
// note - all events created manual reset
CAsyncIo::CAsyncIo(CAsyncStream *pStream)
: m_hThread(NULL),
m_evWork(TRUE),
m_evDone(TRUE),
m_evStop(TRUE),
m_listWork(NAME("Work list")),
m_listDone(NAME("Done list")),
m_bFlushing(FALSE),
m_cItemsOut(0),
m_bWaiting(FALSE),
m_pStream(pStream)
{
}
CAsyncIo::~CAsyncIo()
{
// move everything to the done list
BeginFlush();
// shutdown worker thread
CloseThread();
// empty the done list
POSITION pos = m_listDone.GetHeadPosition();
while(pos)
{
CAsyncRequest* pRequest = m_listDone.GetNext(pos);
delete pRequest;
}
m_listDone.RemoveAll();
}
// ready for async activity - call this before calling Request.
//
// start the worker thread if we need to
//
// !!! use overlapped i/o if possible
HRESULT
CAsyncIo::AsyncActive(void)
{
return StartThread();
}
// call this when no more async activity will happen before
// the next AsyncActive call
//
// stop the worker thread if active
HRESULT
CAsyncIo::AsyncInactive(void)
{
return CloseThread();
}
// add a request to the queue.
HRESULT
CAsyncIo::Request(
LONGLONG llPos,
LONG lLength,
BOOL bAligned,
BYTE * pBuffer,
LPVOID pContext,
DWORD_PTR dwUser)
{
if(bAligned)
{
if(!IsAligned(llPos) ||
!IsAligned(lLength) ||
!IsAligned((LONG_PTR) pBuffer))
{
return VFW_E_BADALIGN;
}
}
CAsyncRequest* pRequest = new CAsyncRequest;
if (!pRequest)
return E_OUTOFMEMORY;
HRESULT hr = pRequest->Request(this,
m_pStream,
llPos,
lLength,
bAligned,
pBuffer,
pContext,
dwUser);
if(SUCCEEDED(hr))
{
// might fail if flushing
hr = PutWorkItem(pRequest);
}
if(FAILED(hr))
{
delete pRequest;
}
return hr;
}
// wait for the next request to complete
HRESULT
CAsyncIo::WaitForNext(
DWORD dwTimeout,
LPVOID * ppContext,
DWORD_PTR * pdwUser,
LONG * pcbActual)
{
CheckPointer(ppContext,E_POINTER);
CheckPointer(pdwUser,E_POINTER);
CheckPointer(pcbActual,E_POINTER);
// some errors find a sample, others don't. Ensure that
// *ppContext is NULL if no sample found
*ppContext = NULL;
// wait until the event is set, but since we are not
// holding the critsec when waiting, we may need to re-wait
for(;;)
{
if(!m_evDone.Wait(dwTimeout))
{
// timeout occurred
return VFW_E_TIMEOUT;
}
// get next event from list
CAsyncRequest* pRequest = GetDoneItem();
if(pRequest)
{
// found a completed request
// check if ok
HRESULT hr = pRequest->GetHResult();
if(hr == S_FALSE)
{
// this means the actual length was less than
// requested - may be ok if he aligned the end of file
if((pRequest->GetActualLength() +
pRequest->GetStart()) == Size())
{
hr = S_OK;
}
else
{
// it was an actual read error
hr = E_FAIL;
}
}
// return actual bytes read
*pcbActual = pRequest->GetActualLength();
// return his context
*ppContext = pRequest->GetContext();
*pdwUser = pRequest->GetUser();
delete pRequest;
return hr;
}
else
{
// Hold the critical section while checking the list state
CAutoLock lck(&m_csLists);
if(m_bFlushing && !m_bWaiting)
{
// can't block as we are between BeginFlush and EndFlush
// but note that if m_bWaiting is set, then there are some
// items not yet complete that we should block for.
return VFW_E_WRONG_STATE;
}
}
// done item was grabbed between completion and
// us locking m_csLists.
}
}
// perform a synchronous read request on this thread.
// Need to hold m_csFile while doing this (done in request object)
HRESULT
CAsyncIo::SyncReadAligned(
LONGLONG llPos,
LONG lLength,
BYTE * pBuffer,
LONG * pcbActual,
PVOID pvContext)
{
CheckPointer(pcbActual,E_POINTER);
if(!IsAligned(llPos) ||
!IsAligned(lLength) ||
!IsAligned((LONG_PTR) pBuffer))
{
return VFW_E_BADALIGN;
}
CAsyncRequest request;
HRESULT hr = request.Request(this,
m_pStream,
llPos,
lLength,
TRUE,
pBuffer,
pvContext,
0);
if(FAILED(hr))
return hr;
hr = request.Complete();
// return actual data length
*pcbActual = request.GetActualLength();
return hr;
}
HRESULT
CAsyncIo::Length(LONGLONG *pllTotal, LONGLONG *pllAvailable)
{
CheckPointer(pllTotal,E_POINTER);
*pllTotal = m_pStream->Size(pllAvailable);
return S_OK;
}
// cancel all items on the worklist onto the done list
// and refuse further requests or further WaitForNext calls
// until the end flush
//
// WaitForNext must return with NULL only if there are no successful requests.
// So Flush does the following:
// 1. set m_bFlushing ensures no more requests succeed
// 2. move all items from work list to the done list.
// 3. If there are any outstanding requests, then we need to release the
// critsec to allow them to complete. The m_bWaiting as well as ensuring
// that we are signalled when they are all done is also used to indicate
// to WaitForNext that it should continue to block.
// 4. Once all outstanding requests are complete, we force m_evDone set and
// m_bFlushing set and m_bWaiting false. This ensures that WaitForNext will
// not block when the done list is empty.
HRESULT
CAsyncIo::BeginFlush()
{
// hold the lock while emptying the work list
{
CAutoLock lock(&m_csLists);
// prevent further requests being queued.
// Also WaitForNext will refuse to block if this is set
// unless m_bWaiting is also set which it will be when we release
// the critsec if there are any outstanding).
m_bFlushing = TRUE;
CAsyncRequest * preq;
while((preq = GetWorkItem()) != 0)
{
preq->Cancel();
PutDoneItem(preq);
}
// now wait for any outstanding requests to complete
if(m_cItemsOut > 0)
{
// can be only one person waiting
ASSERT(!m_bWaiting);
// this tells the completion routine that we need to be
// signalled via m_evAllDone when all outstanding items are
// done. It also tells WaitForNext to continue blocking.
m_bWaiting = TRUE;
}
else
{
// all done
// force m_evDone set so that even if list is empty,
// WaitForNext will not block
// don't do this until we are sure that all
// requests are on the done list.
m_evDone.Set();
return S_OK;
}
}
ASSERT(m_bWaiting);
// wait without holding critsec
for(;;)
{
m_evAllDone.Wait();
{
// hold critsec to check
CAutoLock lock(&m_csLists);
if(m_cItemsOut == 0)
{
// now we are sure that all outstanding requests are on
// the done list and no more will be accepted
m_bWaiting = FALSE;
// force m_evDone set so that even if list is empty,
// WaitForNext will not block
// don't do this until we are sure that all
// requests are on the done list.
m_evDone.Set();
return S_OK;
}
}
}
}
// end a flushing state
HRESULT
CAsyncIo::EndFlush()
{
CAutoLock lock(&m_csLists);
m_bFlushing = FALSE;
ASSERT(!m_bWaiting);
// m_evDone might have been set by BeginFlush - ensure it is
// set IFF m_listDone is non-empty
if(m_listDone.GetCount() > 0)
{
m_evDone.Set();
}
else
{
m_evDone.Reset();
}
return S_OK;
}
// start the thread
HRESULT
CAsyncIo::StartThread(void)
{
if(m_hThread)
{
return S_OK;
}
// clear the stop event before starting
m_evStop.Reset();
DWORD dwThreadID;
m_hThread = CreateThread(NULL,
0,
InitialThreadProc,
this,
0,
&dwThreadID);
if(!m_hThread)
{
DWORD dwErr = GetLastError();
return HRESULT_FROM_WIN32(dwErr);
}
return S_OK;
}
// stop the thread and close the handle
HRESULT
CAsyncIo::CloseThread(void)
{
// signal the thread-exit object
m_evStop.Set();
if(m_hThread)
{
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
m_hThread = NULL;
}
return S_OK;
}
// manage the list of requests. hold m_csLists and ensure
// that the (manual reset) event hevList is set when things on
// the list but reset when the list is empty.
// returns null if list empty
CAsyncRequest*
CAsyncIo::GetWorkItem()
{
CAutoLock lck(&m_csLists);
CAsyncRequest * preq = m_listWork.RemoveHead();
// force event set correctly
if(m_listWork.GetCount() == 0)
{
m_evWork.Reset();
}
return preq;
}
// get an item from the done list
CAsyncRequest*
CAsyncIo::GetDoneItem()
{
CAutoLock lock(&m_csLists);
CAsyncRequest * preq = m_listDone.RemoveHead();
// force event set correctly if list now empty
// or we're in the final stages of flushing
// Note that during flushing the way it's supposed to work is that
// everything is shoved on the Done list then the application is
// supposed to pull until it gets nothing more
//
// Thus we should not set m_evDone unconditionally until everything
// has moved to the done list which means we must wait until
// cItemsOut is 0 (which is guaranteed by m_bWaiting being TRUE).
if(m_listDone.GetCount() == 0 &&
(!m_bFlushing || m_bWaiting))
{
m_evDone.Reset();
}
return preq;
}
// put an item on the work list - fail if bFlushing
HRESULT
CAsyncIo::PutWorkItem(CAsyncRequest* pRequest)
{
CAutoLock lock(&m_csLists);
HRESULT hr;
if(m_bFlushing)
{
hr = VFW_E_WRONG_STATE;
}
else if(m_listWork.AddTail(pRequest))
{
// event should now be in a set state - force this
m_evWork.Set();
// start the thread now if not already started
hr = StartThread();
}
else
{
hr = E_OUTOFMEMORY;
}
return(hr);
}
// put an item on the done list - ok to do this when
// flushing
HRESULT
CAsyncIo::PutDoneItem(CAsyncRequest* pRequest)
{
ASSERT(CritCheckIn(&m_csLists));
if(m_listDone.AddTail(pRequest))
{
// event should now be in a set state - force this
m_evDone.Set();
return S_OK;
}
else
{
return E_OUTOFMEMORY;
}
}
// called on thread to process any active requests
void
CAsyncIo::ProcessRequests(void)
{
// lock to get the item and increment the outstanding count
CAsyncRequest * preq = NULL;
for(;;)
{
{
CAutoLock lock(&m_csLists);
preq = GetWorkItem();
if(preq == NULL)
{
// done
return;
}
// one more item not on the done or work list
m_cItemsOut++;
// release critsec
}
preq->Complete();
// regain critsec to replace on done list
{
CAutoLock l(&m_csLists);
PutDoneItem(preq);
if(--m_cItemsOut == 0)
{
if(m_bWaiting)
m_evAllDone.Set();
}
}
}
}
// the thread proc - assumes that DWORD thread param is the
// this pointer
DWORD
CAsyncIo::ThreadProc(void)
{
HANDLE ahev[] = {m_evStop, m_evWork};
for(;;)
{
DWORD dw = WaitForMultipleObjects(2,
ahev,
FALSE,
INFINITE);
if(dw == WAIT_OBJECT_0+1)
{
// requests need processing
ProcessRequests();
}
else
{
// any error or stop event - we should exit
return 0;
}
}
}
// perform a synchronous read request on this thread.
// may not be aligned - so we will have to buffer.
HRESULT
CAsyncIo::SyncRead(
LONGLONG llPos,
LONG lLength,
BYTE * pBuffer)
{
if(IsAligned(llPos) &&
IsAligned(lLength) &&
IsAligned((LONG_PTR) pBuffer))
{
LONG cbUnused;
return SyncReadAligned(llPos, lLength, pBuffer, &cbUnused, NULL);
}
// not aligned with requirements - use buffered file handle.
//!!! might want to fix this to buffer the data ourselves?
CAsyncRequest request;
HRESULT hr = request.Request(this,
m_pStream,
llPos,
lLength,
FALSE,
pBuffer,
NULL,
0);
if(FAILED(hr))
{
return hr;
}
return request.Complete();
}
// Return the alignment
HRESULT
CAsyncIo::Alignment(LONG *pAlignment)
{
CheckPointer(pAlignment,E_POINTER);
*pAlignment = Alignment();
return S_OK;
}
-273
View File
@@ -1,273 +0,0 @@
//------------------------------------------------------------------------------
// File: AsyncIo.h
//
// Desc: DirectShow sample code - base library for I/O functionality.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __ASYNCIO_H__
#define __ASYNCIO_H__
//
// definition of CAsyncFile object that performs file access. It provides
// asynchronous, unbuffered, aligned reads from a file, using a worker thread
// on win95 and potentially overlapped i/o if available.
// !!! Need to use real overlapped i/o if available
// currently only uses worker thread, not overlapped i/o
class CAsyncIo;
class CAsyncStream;
//
// Model the stream we read from based on a file-like interface
//
class CAsyncStream
{
public:
virtual ~CAsyncStream() {};
virtual HRESULT SetPointer(LONGLONG llPos) = 0;
virtual HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead) = 0;
virtual LONGLONG Size(LONGLONG *pSizeAvailable = NULL) = 0;
virtual DWORD Alignment() = 0;
virtual void Lock() = 0;
virtual void Unlock() = 0;
//virtual void SetStopHandle(HANDLE hevStop) {}
};
// represents a single request and performs the i/o. Can be called on either
// worker thread or app thread, but must hold pcsFile across file accesses.
// (ie across SetFilePointer/ReadFile pairs)
class CAsyncRequest
{
CAsyncIo *m_pIo;
CAsyncStream *m_pStream;
LONGLONG m_llPos;
BOOL m_bAligned;
LONG m_lLength;
BYTE* m_pBuffer;
LPVOID m_pContext;
DWORD_PTR m_dwUser;
HRESULT m_hr;
public:
// init the params for this request. Issue the i/o
// if overlapped i/o is possible.
HRESULT Request(
CAsyncIo *pIo,
CAsyncStream *pStream,
LONGLONG llPos,
LONG lLength,
BOOL bAligned,
BYTE* pBuffer,
LPVOID pContext, // filter's context
DWORD_PTR dwUser); // downstream filter's context
// issue the i/o if not overlapped, and block until i/o complete.
// returns error code of file i/o
HRESULT Complete();
// cancels the i/o. blocks until i/o is no longer pending
HRESULT Cancel()
{
return S_OK;
};
// accessor functions
LPVOID GetContext()
{
return m_pContext;
};
DWORD_PTR GetUser()
{
return m_dwUser;
};
HRESULT GetHResult() {
return m_hr;
};
// we set m_lLength to the actual length
LONG GetActualLength() {
return m_lLength;
};
LONGLONG GetStart() {
return m_llPos;
};
};
typedef CGenericList<CAsyncRequest> CRequestList;
// this class needs a worker thread, but the ones defined in classes\base
// are not suitable (they assume you have one message sent or posted per
// request, whereas here for efficiency we want just to set an event when
// there is work on the queue).
//
// we create CAsyncRequest objects and queue them on m_listWork. The worker
// thread pulls them off, completes them and puts them on m_listDone.
// The events m_evWork and m_evDone are set when the corresponding lists are
// not empty.
//
// Synchronous requests are done on the caller thread. These should be
// synchronised by the caller, but to make sure we hold m_csFile across
// the SetFilePointer/ReadFile code.
//
// Flush by calling BeginFlush. This rejects all further requests (by
// setting m_bFlushing within m_csLists), cancels all requests and moves them
// to the done list, and sets m_evDone to ensure that no WaitForNext operations
// will block. Call EndFlush to cancel this state.
//
// we support unaligned calls to SyncRead. This is done by opening the file
// twice if we are using unbuffered i/o (m_dwAlign > 1).
// !!!fix this to buffer on top of existing file handle?
class CAsyncIo
{
CCritSec m_csReader;
CAsyncStream *m_pStream;
CCritSec m_csLists; // locks access to the list and events
BOOL m_bFlushing; // true if between BeginFlush/EndFlush
CRequestList m_listWork;
CRequestList m_listDone;
CAMEvent m_evWork; // set when list is not empty
CAMEvent m_evDone;
// for correct flush behaviour: all protected by m_csLists
LONG m_cItemsOut; // nr of items not on listDone or listWork
BOOL m_bWaiting; // TRUE if someone waiting for m_evAllDone
CAMEvent m_evAllDone; // signal when m_cItemsOut goes to 0 if m_cWaiting
CAMEvent m_evStop; // set when thread should exit
HANDLE m_hThread;
LONGLONG Size() {
ASSERT(m_pStream != NULL);
return m_pStream->Size();
};
// start the thread
HRESULT StartThread(void);
// stop the thread and close the handle
HRESULT CloseThread(void);
// manage the list of requests. hold m_csLists and ensure
// that the (manual reset) event hevList is set when things on
// the list but reset when the list is empty.
// returns null if list empty
CAsyncRequest* GetWorkItem();
// get an item from the done list
CAsyncRequest* GetDoneItem();
// put an item on the work list
HRESULT PutWorkItem(CAsyncRequest* pRequest);
// put an item on the done list
HRESULT PutDoneItem(CAsyncRequest* pRequest);
// called on thread to process any active requests
void ProcessRequests(void);
// initial static thread proc calls ThreadProc with DWORD
// param as this
static DWORD WINAPI InitialThreadProc(LPVOID pv) {
CAsyncIo * pThis = (CAsyncIo*) pv;
return pThis->ThreadProc();
};
DWORD ThreadProc(void);
public:
CAsyncIo(CAsyncStream *pStream);
~CAsyncIo();
// open the file
HRESULT Open(LPCTSTR pName);
// ready for async activity - call this before
// calling Request
HRESULT AsyncActive(void);
// call this when no more async activity will happen before
// the next AsyncActive call
HRESULT AsyncInactive(void);
// queue a requested read. must be aligned.
HRESULT Request(
LONGLONG llPos,
LONG lLength,
BOOL bAligned,
BYTE* pBuffer,
LPVOID pContext,
DWORD_PTR dwUser);
// wait for the next read to complete
HRESULT WaitForNext(
DWORD dwTimeout,
LPVOID *ppContext,
DWORD_PTR * pdwUser,
LONG * pcbActual);
// perform a read of an already aligned buffer
HRESULT SyncReadAligned(
LONGLONG llPos,
LONG lLength,
BYTE* pBuffer,
LONG* pcbActual,
PVOID pvContext);
// perform a synchronous read. will be buffered
// if not aligned.
HRESULT SyncRead(
LONGLONG llPos,
LONG lLength,
BYTE* pBuffer);
// return length
HRESULT Length(LONGLONG *pllTotal, LONGLONG* pllAvailable);
// all Reader positions, read lengths and memory locations must
// be aligned to this.
HRESULT Alignment(LONG* pl);
HRESULT BeginFlush();
HRESULT EndFlush();
LONG Alignment()
{
return m_pStream->Alignment();
};
BOOL IsAligned(LONG l) {
if ((l & (Alignment() -1)) == 0) {
return TRUE;
} else {
return FALSE;
}
};
BOOL IsAligned(LONGLONG ll) {
return IsAligned( (LONG) (ll & 0xffffffff));
};
// Accessor
HANDLE StopEvent() const { return m_evDone; }
};
#endif // __ASYNCIO_H__
-436
View File
@@ -1,436 +0,0 @@
//------------------------------------------------------------------------------
// File: AsyncRdr.cpp
//
// Desc: DirectShow sample code - base library with I/O functionality.
// This file implements I/O source filter methods and output pin
// methods for CAsyncReader and CAsyncOutputPin.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "asyncio.h"
#include "asyncrdr.h"
#include <initguid.h>
#include "asyncflt.h"
// --- CAsyncOutputPin implementation ---
CAsyncOutputPin::CAsyncOutputPin(
HRESULT * phr,
CAsyncReader *pReader,
CAsyncIo *pIo,
CCritSec * pLock)
: CBasePin(
NAME("Async output pin"),
pReader,
pLock,
phr,
L"Output",
PINDIR_OUTPUT),
m_pReader(pReader),
m_pIo(pIo)
{
}
CAsyncOutputPin::~CAsyncOutputPin()
{
}
STDMETHODIMP CAsyncOutputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
CheckPointer(ppv,E_POINTER);
if(riid == IID_IAsyncReader)
{
m_bQueriedForAsyncReader = TRUE;
return GetInterface((IAsyncReader*) this, ppv);
}
else
{
return CBasePin::NonDelegatingQueryInterface(riid, ppv);
}
}
HRESULT CAsyncOutputPin::GetMediaType(int iPosition, CMediaType *pMediaType)
{
if(iPosition < 0)
{
return E_INVALIDARG;
}
if(iPosition > 0)
{
return VFW_S_NO_MORE_ITEMS;
}
CheckPointer(pMediaType,E_POINTER);
CheckPointer(m_pReader,E_UNEXPECTED);
*pMediaType = *m_pReader->LoadType();
return S_OK;
}
HRESULT CAsyncOutputPin::CheckMediaType(const CMediaType* pType)
{
CAutoLock lck(m_pLock);
/* We treat MEDIASUBTYPE_NULL subtype as a wild card */
if((m_pReader->LoadType()->majortype == pType->majortype) &&
(m_pReader->LoadType()->subtype == MEDIASUBTYPE_NULL ||
m_pReader->LoadType()->subtype == pType->subtype))
{
return S_OK;
}
return S_FALSE;
}
HRESULT CAsyncOutputPin::InitAllocator(IMemAllocator **ppAlloc)
{
CheckPointer(ppAlloc,E_POINTER);
HRESULT hr = NOERROR;
CMemAllocator *pMemObject = NULL;
*ppAlloc = NULL;
/* Create a default memory allocator */
pMemObject = new CMemAllocator(NAME("Base memory allocator"), NULL, &hr);
if(pMemObject == NULL)
{
return E_OUTOFMEMORY;
}
if(FAILED(hr))
{
delete pMemObject;
return hr;
}
/* Get a reference counted IID_IMemAllocator interface */
hr = pMemObject->QueryInterface(IID_IMemAllocator,(void **)ppAlloc);
if(FAILED(hr))
{
delete pMemObject;
return E_NOINTERFACE;
}
ASSERT(*ppAlloc != NULL);
return NOERROR;
}
// we need to return an addrefed allocator, even if it is the preferred
// one, since he doesn't know whether it is the preferred one or not.
STDMETHODIMP
CAsyncOutputPin::RequestAllocator(
IMemAllocator* pPreferred,
ALLOCATOR_PROPERTIES* pProps,
IMemAllocator ** ppActual)
{
CheckPointer(pPreferred,E_POINTER);
CheckPointer(pProps,E_POINTER);
CheckPointer(ppActual,E_POINTER);
ASSERT(m_pIo);
// we care about alignment but nothing else
if(!pProps->cbAlign || !m_pIo->IsAligned(pProps->cbAlign))
{
m_pIo->Alignment(&pProps->cbAlign);
}
ALLOCATOR_PROPERTIES Actual;
HRESULT hr;
if(pPreferred)
{
hr = pPreferred->SetProperties(pProps, &Actual);
if(SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
{
pPreferred->AddRef();
*ppActual = pPreferred;
return S_OK;
}
}
// create our own allocator
IMemAllocator* pAlloc;
hr = InitAllocator(&pAlloc);
if(FAILED(hr))
{
return hr;
}
//...and see if we can make it suitable
hr = pAlloc->SetProperties(pProps, &Actual);
if(SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
{
// we need to release our refcount on pAlloc, and addref
// it to pass a refcount to the caller - this is a net nothing.
*ppActual = pAlloc;
return S_OK;
}
// failed to find a suitable allocator
pAlloc->Release();
// if we failed because of the IsAligned test, the error code will
// not be failure
if(SUCCEEDED(hr))
{
hr = VFW_E_BADALIGN;
}
return hr;
}
// queue an aligned read request. call WaitForNext to get
// completion.
STDMETHODIMP CAsyncOutputPin::Request(
IMediaSample* pSample,
DWORD_PTR dwUser) // user context
{
CheckPointer(pSample,E_POINTER);
REFERENCE_TIME tStart, tStop;
HRESULT hr = pSample->GetTime(&tStart, &tStop);
if(FAILED(hr))
{
return hr;
}
LONGLONG llPos = tStart / UNITS;
LONG lLength = (LONG) ((tStop - tStart) / UNITS);
LONGLONG llTotal=0, llAvailable=0;
hr = m_pIo->Length(&llTotal, &llAvailable);
if(llPos + lLength > llTotal)
{
// the end needs to be aligned, but may have been aligned
// on a coarser alignment.
LONG lAlign;
m_pIo->Alignment(&lAlign);
llTotal = (llTotal + lAlign -1) & ~(lAlign-1);
if(llPos + lLength > llTotal)
{
lLength = (LONG) (llTotal - llPos);
// must be reducing this!
ASSERT((llTotal * UNITS) <= tStop);
tStop = llTotal * UNITS;
pSample->SetTime(&tStart, &tStop);
}
}
BYTE* pBuffer;
hr = pSample->GetPointer(&pBuffer);
if(FAILED(hr))
{
return hr;
}
return m_pIo->Request(llPos,
lLength,
TRUE,
pBuffer,
(LPVOID)pSample,
dwUser);
}
// sync-aligned request. just like a request/waitfornext pair.
STDMETHODIMP
CAsyncOutputPin::SyncReadAligned(
IMediaSample* pSample)
{
CheckPointer(pSample,E_POINTER);
REFERENCE_TIME tStart, tStop;
HRESULT hr = pSample->GetTime(&tStart, &tStop);
if(FAILED(hr))
{
return hr;
}
LONGLONG llPos = tStart / UNITS;
LONG lLength = (LONG) ((tStop - tStart) / UNITS);
LONGLONG llTotal;
LONGLONG llAvailable;
hr = m_pIo->Length(&llTotal, &llAvailable);
if(llPos + lLength > llTotal)
{
// the end needs to be aligned, but may have been aligned
// on a coarser alignment.
LONG lAlign;
m_pIo->Alignment(&lAlign);
llTotal = (llTotal + lAlign -1) & ~(lAlign-1);
if(llPos + lLength > llTotal)
{
lLength = (LONG) (llTotal - llPos);
// must be reducing this!
ASSERT((llTotal * UNITS) <= tStop);
tStop = llTotal * UNITS;
pSample->SetTime(&tStart, &tStop);
}
}
BYTE* pBuffer;
hr = pSample->GetPointer(&pBuffer);
if(FAILED(hr))
{
return hr;
}
LONG cbActual;
hr = m_pIo->SyncReadAligned(llPos,
lLength,
pBuffer,
&cbActual,
pSample);
pSample->SetActualDataLength(cbActual);
return hr;
}
//
// collect the next ready sample
STDMETHODIMP
CAsyncOutputPin::WaitForNext(
DWORD dwTimeout,
IMediaSample** ppSample, // completed sample
DWORD_PTR * pdwUser) // user context
{
CheckPointer(ppSample,E_POINTER);
LONG cbActual;
IMediaSample* pSample=0;
HRESULT hr = m_pIo->WaitForNext(dwTimeout,
(LPVOID*) &pSample,
pdwUser,
&cbActual);
if(SUCCEEDED(hr))
{
pSample->SetActualDataLength(cbActual);
}
*ppSample = pSample;
return hr;
}
//
// synchronous read that need not be aligned.
STDMETHODIMP
CAsyncOutputPin::SyncRead(
LONGLONG llPosition, // absolute Io position
LONG lLength, // nr bytes required
BYTE* pBuffer) // write data here
{
return m_pIo->SyncRead(llPosition, lLength, pBuffer);
}
// return the length of the file, and the length currently
// available locally. We only support locally accessible files,
// so they are always the same
STDMETHODIMP
CAsyncOutputPin::Length(
LONGLONG* pTotal,
LONGLONG* pAvailable)
{
return m_pIo->Length(pTotal, pAvailable);
}
STDMETHODIMP
CAsyncOutputPin::BeginFlush(void)
{
return m_pIo->BeginFlush();
}
STDMETHODIMP
CAsyncOutputPin::EndFlush(void)
{
return m_pIo->EndFlush();
}
STDMETHODIMP
CAsyncOutputPin::Connect(
IPin * pReceivePin,
const AM_MEDIA_TYPE *pmt // optional media type
)
{
return m_pReader->Connect(pReceivePin, pmt);
}
// --- CAsyncReader implementation ---
#pragma warning(disable:4355)
CAsyncReader::CAsyncReader(
TCHAR *pName,
LPUNKNOWN pUnk,
CAsyncStream *pStream,
HRESULT *phr)
: CBaseFilter(
pName,
pUnk,
&m_csFilter,
CLSID_AsyncStreamSource,
NULL
),
m_OutputPin(
phr,
this,
&m_Io,
&m_csFilter),
m_Io(pStream)
{
}
CAsyncReader::~CAsyncReader()
{
}
int CAsyncReader::GetPinCount()
{
return 1;
}
CBasePin * CAsyncReader::GetPin(int n)
{
if((GetPinCount() > 0) && (n == 0))
{
return &m_OutputPin;
}
else
{
return NULL;
}
}
-228
View File
@@ -1,228 +0,0 @@
//------------------------------------------------------------------------------
// File: AsyncRdr.h
//
// Desc: DirectShow sample code - base library for I/O functionality.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __ASYNCRDR_H__
#define __ASYNCRDR_H__
//
// AsyncRdr
//
// Defines an IO source filter.
//
// This filter (CAsyncReader) supports IBaseFilter and IFileSourceFilter interfaces from the
// filter object itself. It has a single output pin (CAsyncOutputPin)
// which supports IPin and IAsyncReader.
//
// This filter is essentially a wrapper for the CAsyncFile class that does
// all the work.
//
// the filter class (defined below)
class CAsyncReader;
// the output pin class
class CAsyncOutputPin
: public IAsyncReader,
public CBasePin
{
protected:
CAsyncReader* m_pReader;
CAsyncIo * m_pIo;
// This is set every time we're asked to return an IAsyncReader
// interface
// This allows us to know if the downstream pin can use
// this transport, otherwise we can hook up to thinks like the
// dump filter and nothing happens
BOOL m_bQueriedForAsyncReader;
HRESULT InitAllocator(IMemAllocator **ppAlloc);
public:
// constructor and destructor
CAsyncOutputPin(
HRESULT * phr,
CAsyncReader *pReader,
CAsyncIo *pIo,
CCritSec * pLock);
~CAsyncOutputPin();
// --- CUnknown ---
// need to expose IAsyncReader
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
// --- IPin methods ---
STDMETHODIMP Connect(
IPin * pReceivePin,
const AM_MEDIA_TYPE *pmt // optional media type
);
// --- CBasePin methods ---
// return the types we prefer - this will return the known
// file type
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
// can we support this type?
HRESULT CheckMediaType(const CMediaType* pType);
// Clear the flag so we see if IAsyncReader is queried for
HRESULT CheckConnect(IPin *pPin)
{
m_bQueriedForAsyncReader = FALSE;
return CBasePin::CheckConnect(pPin);
}
// See if it was asked for
HRESULT CompleteConnect(IPin *pReceivePin)
{
if (m_bQueriedForAsyncReader) {
return CBasePin::CompleteConnect(pReceivePin);
} else {
#ifdef VFW_E_NO_TRANSPORT
return VFW_E_NO_TRANSPORT;
#else
return E_FAIL;
#endif
}
}
// Remove our connection status
HRESULT BreakConnect()
{
m_bQueriedForAsyncReader = FALSE;
return CBasePin::BreakConnect();
}
// --- IAsyncReader methods ---
// pass in your preferred allocator and your preferred properties.
// method returns the actual allocator to be used. Call GetProperties
// on returned allocator to learn alignment and prefix etc chosen.
// this allocator will be not be committed and decommitted by
// the async reader, only by the consumer.
STDMETHODIMP RequestAllocator(
IMemAllocator* pPreferred,
ALLOCATOR_PROPERTIES* pProps,
IMemAllocator ** ppActual);
// queue a request for data.
// media sample start and stop times contain the requested absolute
// byte position (start inclusive, stop exclusive).
// may fail if sample not obtained from agreed allocator.
// may fail if start/stop position does not match agreed alignment.
// samples allocated from source pin's allocator may fail
// GetPointer until after returning from WaitForNext.
STDMETHODIMP Request(
IMediaSample* pSample,
DWORD_PTR dwUser); // user context
// block until the next sample is completed or the timeout occurs.
// timeout (millisecs) may be 0 or INFINITE. Samples may not
// be delivered in order. If there is a read error of any sort, a
// notification will already have been sent by the source filter,
// and STDMETHODIMP will be an error.
STDMETHODIMP WaitForNext(
DWORD dwTimeout,
IMediaSample** ppSample, // completed sample
DWORD_PTR * pdwUser); // user context
// sync read of data. Sample passed in must have been acquired from
// the agreed allocator. Start and stop position must be aligned.
// equivalent to a Request/WaitForNext pair, but may avoid the
// need for a thread on the source filter.
STDMETHODIMP SyncReadAligned(
IMediaSample* pSample);
// sync read. works in stopped state as well as run state.
// need not be aligned. Will fail if read is beyond actual total
// length.
STDMETHODIMP SyncRead(
LONGLONG llPosition, // absolute file position
LONG lLength, // nr bytes required
BYTE* pBuffer); // write data here
// return total length of stream, and currently available length.
// reads for beyond the available length but within the total length will
// normally succeed but may block for a long period.
STDMETHODIMP Length(
LONGLONG* pTotal,
LONGLONG* pAvailable);
// cause all outstanding reads to return, possibly with a failure code
// (VFW_E_TIMEOUT) indicating they were cancelled.
// these are defined on IAsyncReader and IPin
STDMETHODIMP BeginFlush(void);
STDMETHODIMP EndFlush(void);
};
//
// The filter object itself. Supports IBaseFilter through
// CBaseFilter and also IFileSourceFilter directly in this object
class CAsyncReader : public CBaseFilter
{
protected:
// filter-wide lock
CCritSec m_csFilter;
// all i/o done here
CAsyncIo m_Io;
// our output pin
CAsyncOutputPin m_OutputPin;
// Type we think our data is
CMediaType m_mt;
public:
// construction / destruction
CAsyncReader(
TCHAR *pName,
LPUNKNOWN pUnk,
CAsyncStream *pStream,
HRESULT *phr);
~CAsyncReader();
// --- CBaseFilter methods ---
int GetPinCount();
CBasePin *GetPin(int n);
// --- Access our media type
const CMediaType *LoadType() const
{
return &m_mt;
}
virtual HRESULT Connect(
IPin * pReceivePin,
const AM_MEDIA_TYPE *pmt // optional media type
)
{
return m_OutputPin.CBasePin::Connect(pReceivePin, pmt);
}
};
#endif //__ASYNCRDR_H__
-26
View File
@@ -1,26 +0,0 @@
// This is a header file for the stream/file source filter
#ifndef __ASYNC_STREAMSOURCE_H__
#define __ASYNC_STREAMSOURCE_H__
// {2AE44C10-B451-4B01-9BBE-A5FBEF68C9D4}
DEFINE_GUID(CLSID_AsyncStreamSource,
0x2ae44c10, 0xb451, 0x4b01, 0x9b, 0xbe, 0xa5, 0xfb, 0xef, 0x68, 0xc9, 0xd4);
// {268424D1-B6E9-4B28-8751-B7774F5ECF77}
DEFINE_GUID(IID_IStreamSourceFilter,
0x268424d1, 0xb6e9, 0x4b28, 0x87, 0x51, 0xb7, 0x77, 0x4f, 0x5e, 0xcf, 0x77);
// We define the interface the app can use to program us
MIDL_INTERFACE("268424D1-B6E9-4B28-8751-B7774F5ECF77")
IStreamSourceFilter : public IFileSourceFilter
{
public:
virtual STDMETHODIMP LoadStream(void *stream, LONGLONG readSize, LONGLONG streamSize, AM_MEDIA_TYPE *pmt ) = 0;
virtual STDMETHODIMP AddStreamData(LONGLONG offset, void *stream, LONGLONG addSize) = 0;
virtual STDMETHODIMP GetStreamInfo(LONGLONG *readSize, LONGLONG *streamSize) = 0;
virtual STDMETHODIMP SetReadSize(LONGLONG readSize) = 0;
virtual BOOL STDMETHODCALLTYPE IsReadPassEnd() = 0;
};
#endif // __ASYNC_STREAMSOURCE_H__
Binary file not shown.