From 60f56a3cb63c5d5667b9f66ea30ae327b123d2a7 Mon Sep 17 00:00:00 2001 From: oioitff Date: Thu, 30 May 2013 19:22:09 +0800 Subject: [PATCH] Remove the filter project. --- filter/asyncStreamflt/asyncflt.cpp | 149 ---- filter/asyncStreamflt/asyncflt.def | 13 - filter/asyncStreamflt/asyncflt.h | 305 -------- filter/asyncStreamflt/asyncflt.rc | 53 -- filter/asyncStreamflt/asyncflt.sln | 21 - filter/asyncStreamflt/asyncflt.vcxproj | 305 -------- .../asyncStreamflt/asyncflt.vcxproj.filters | 52 -- filter/asyncStreamflt/asyncio.cpp | 708 ------------------ filter/asyncStreamflt/asyncio.h | 273 ------- filter/asyncStreamflt/asyncrdr.cpp | 436 ----------- filter/asyncStreamflt/asyncrdr.h | 228 ------ filter/include/StreamSourceflt.h | 26 - filter/lib/AsyncStreamflt.ax | Bin 49152 -> 0 bytes 13 files changed, 2569 deletions(-) delete mode 100644 filter/asyncStreamflt/asyncflt.cpp delete mode 100644 filter/asyncStreamflt/asyncflt.def delete mode 100644 filter/asyncStreamflt/asyncflt.h delete mode 100644 filter/asyncStreamflt/asyncflt.rc delete mode 100644 filter/asyncStreamflt/asyncflt.sln delete mode 100644 filter/asyncStreamflt/asyncflt.vcxproj delete mode 100644 filter/asyncStreamflt/asyncflt.vcxproj.filters delete mode 100644 filter/asyncStreamflt/asyncio.cpp delete mode 100644 filter/asyncStreamflt/asyncio.h delete mode 100644 filter/asyncStreamflt/asyncrdr.cpp delete mode 100644 filter/asyncStreamflt/asyncrdr.h delete mode 100644 filter/include/StreamSourceflt.h delete mode 100644 filter/lib/AsyncStreamflt.ax diff --git a/filter/asyncStreamflt/asyncflt.cpp b/filter/asyncStreamflt/asyncflt.cpp deleted file mode 100644 index 433052e166..0000000000 --- a/filter/asyncStreamflt/asyncflt.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// A simple stream source filter based on the sample code -// It requires DirectShow BasicClass for compiling - -#include - -#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; -} - diff --git a/filter/asyncStreamflt/asyncflt.def b/filter/asyncStreamflt/asyncflt.def deleted file mode 100644 index b3ada7e395..0000000000 --- a/filter/asyncStreamflt/asyncflt.def +++ /dev/null @@ -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 - diff --git a/filter/asyncStreamflt/asyncflt.h b/filter/asyncStreamflt/asyncflt.h deleted file mode 100644 index d4deefdd4d..0000000000 --- a/filter/asyncStreamflt/asyncflt.h +++ /dev/null @@ -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 (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; -}; diff --git a/filter/asyncStreamflt/asyncflt.rc b/filter/asyncStreamflt/asyncflt.rc deleted file mode 100644 index 02ab017ddf..0000000000 --- a/filter/asyncStreamflt/asyncflt.rc +++ /dev/null @@ -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 - -///////////////////////////////////////////////////////////////////////////// -// -// 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 \ No newline at end of file diff --git a/filter/asyncStreamflt/asyncflt.sln b/filter/asyncStreamflt/asyncflt.sln deleted file mode 100644 index 323946fa5b..0000000000 --- a/filter/asyncStreamflt/asyncflt.sln +++ /dev/null @@ -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 diff --git a/filter/asyncStreamflt/asyncflt.vcxproj b/filter/asyncStreamflt/asyncflt.vcxproj deleted file mode 100644 index 40a56890b7..0000000000 --- a/filter/asyncStreamflt/asyncflt.vcxproj +++ /dev/null @@ -1,305 +0,0 @@ - - - - - Debug Unicode - Win32 - - - Debug - Win32 - - - Release Unicode - Win32 - - - Release - Win32 - - - - async - - - - - - DynamicLibrary - false - - - DynamicLibrary - false - Unicode - - - DynamicLibrary - false - Unicode - - - DynamicLibrary - false - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\lib - .\Release\ - true - false - .\Debug_Unicode\ - .\Debug_Unicode\ - true - true - ..\lib - .\Release_Unicode\ - true - false - .\Debug\ - .\Debug\ - true - true - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(IncludePath) - $(LibraryPath) - $(IncludePath) - $(LibraryPath) - $(IncludePath) - $(LibraryPath) - $(IncludePath) - $(LibraryPath) - AsyncStreamflt.ax - AsyncStreamflt_u.ax - - - - OnlyExplicitInline - ..\include;%(AdditionalIncludeDirectories) - NDEBUG;_WINDOWS;_USRDLL;ASYNC_EXPORTS;INC_OLE2;STRICT;_WIN32_WINNT=0x0403;WIN32;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - streams.h - .\Release/asyncflt.pch - .\Release/ - .\Release/ - .\Release/ - Level4 - true - StdCall - Default - - - /MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions) - strmbase.lib;quartz.lib;winmm.lib;msvcrt.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - ..\lib\AsyncStreamflt.ax - true - %(AdditionalLibraryDirectories) - false - .\asyncflt.def - .\Release/asyncflt.pdb - - - true - .\Release/asyncflt.lib - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/asyncflt.tlb - - - NDEBUG;WIN32;%(PreprocessorDefinitions) - 0x0409 - ..\..\..\BaseClasses;%(AdditionalIncludeDirectories) - - - - - Disabled - ..\include;%(AdditionalIncludeDirectories) - INC_OLE2;STRICT;_WIN32_WINNT=0x0403;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;DBG=1;DEBUG;_DEBUG;WIN32;UNICODE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - streams.h - .\Debug_Unicode/asyncflt.pch - .\Debug_Unicode/ - .\Debug_Unicode/ - .\Debug_Unicode/ - Level4 - true - ProgramDatabase - StdCall - Default - - - /MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions) - strmbasd.lib;quartz.lib;winmm.lib;msvcrtd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - Debug_Unicode/asyncflt.ax - true - %(AdditionalLibraryDirectories) - false - .\asyncflt.def - true - .\Debug_Unicode/asyncflt.lib - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug_Unicode/asyncflt.tlb - - - _DEBUG;WIN32;%(PreprocessorDefinitions) - 0x0409 - ..\..\..\BaseClasses;%(AdditionalIncludeDirectories) - - - - - OnlyExplicitInline - ..\include;%(AdditionalIncludeDirectories) - NDEBUG;_WINDOWS;_MBCS;_USRDLL;ASYNC_EXPORTS;INC_OLE2;STRICT;_WIN32_WINNT=0x0403;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;WIN32;UNICODE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - streams.h - .\Release_Unicode/asyncflt.pch - .\Release_Unicode/ - .\Release_Unicode/ - .\Release_Unicode/ - Level4 - true - StdCall - Default - - - /MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions) - strmbase.lib;quartz.lib;winmm.lib;msvcrt.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - Release_Unicode/asyncflt.ax - true - %(AdditionalLibraryDirectories) - false - .\asyncflt.def - .\Release_Unicode/asyncflt.pdb - - - true - .\Release_Unicode/asyncflt.lib - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release_Unicode/asyncflt.tlb - - - NDEBUG;WIN32;%(PreprocessorDefinitions) - 0x0409 - ..\..\..\BaseClasses;%(AdditionalIncludeDirectories) - - - - - Disabled - ..\include;%(AdditionalIncludeDirectories) - INC_OLE2;STRICT;_WIN32_WINNT=0x0403;WIN32;_WIN32;_MT;_DLL;_X86_=1;WINVER=0x0403;DBG=1;DEBUG;_DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - streams.h - .\Debug/asyncflt.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level4 - true - ProgramDatabase - StdCall - Default - - - /MACHINE:I386 /IGNORE:4089 /IGNORE:4098 %(AdditionalOptions) - strmbasd.lib;quartz.lib;winmm.lib;msvcrtd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - Debug/asyncflt.ax - true - %(AdditionalLibraryDirectories) - false - .\asyncflt.def - true - .\Debug/asyncflt.lib - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/asyncflt.tlb - - - _DEBUG;WIN32;%(PreprocessorDefinitions) - 0x0409 - ..\..\..\BaseClasses;%(AdditionalIncludeDirectories) - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/filter/asyncStreamflt/asyncflt.vcxproj.filters b/filter/asyncStreamflt/asyncflt.vcxproj.filters deleted file mode 100644 index 9cfe53cf50..0000000000 --- a/filter/asyncStreamflt/asyncflt.vcxproj.filters +++ /dev/null @@ -1,52 +0,0 @@ - - - - - {2cb60d77-18ca-45ad-a4f3-0d736ca63aac} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {1aece6a2-e345-4279-81ae-993564c5b48a} - h;hpp;hxx;hm;inl - - - {56fe04f5-c6f6-43c9-95e2-a95245afadd0} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/filter/asyncStreamflt/asyncio.cpp b/filter/asyncStreamflt/asyncio.cpp deleted file mode 100644 index 1532796d4a..0000000000 --- a/filter/asyncStreamflt/asyncio.cpp +++ /dev/null @@ -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 -#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(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; -} - - diff --git a/filter/asyncStreamflt/asyncio.h b/filter/asyncStreamflt/asyncio.h deleted file mode 100644 index a7b69d0682..0000000000 --- a/filter/asyncStreamflt/asyncio.h +++ /dev/null @@ -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 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__ diff --git a/filter/asyncStreamflt/asyncrdr.cpp b/filter/asyncStreamflt/asyncrdr.cpp deleted file mode 100644 index a9061512d6..0000000000 --- a/filter/asyncStreamflt/asyncrdr.cpp +++ /dev/null @@ -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 -#include "asyncio.h" -#include "asyncrdr.h" - -#include - -#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; - } -} - - - diff --git a/filter/asyncStreamflt/asyncrdr.h b/filter/asyncStreamflt/asyncrdr.h deleted file mode 100644 index 11f57c3cd6..0000000000 --- a/filter/asyncStreamflt/asyncrdr.h +++ /dev/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__ diff --git a/filter/include/StreamSourceflt.h b/filter/include/StreamSourceflt.h deleted file mode 100644 index 326d3735be..0000000000 --- a/filter/include/StreamSourceflt.h +++ /dev/null @@ -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__ \ No newline at end of file diff --git a/filter/lib/AsyncStreamflt.ax b/filter/lib/AsyncStreamflt.ax deleted file mode 100644 index 744e7237b167cf6dae6b900ff9efea749164bbed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49152 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