mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-14 18:19:36 +01:00
Remove the filter project.
This commit is contained in:
1 parent
852a07d347
commit
60f56a3cb6
13 files changed
-2569
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -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.
Reference in new issue
Block a user