www.pudn.com > avi_file_source.rar > AVI_FileSource.cpp
//------------------------------------------------------------------------------ // File: AsyncFlt.cpp // // Desc: DirectShow sample code - implementation of CAsyncFilter. // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ #include "stdafx.h" #include#include "asyncio.h" #include "asyncrdr.h" #include "AVI_FileSource.h" // // Setup data for filter registration // const AMOVIESETUP_MEDIATYPE sudOpPinTypes[] = { { &MEDIATYPE_Stream, // clsMajorType &MEDIASUBTYPE_Avi // clsMinorType }, { &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 , 2 // nTypes , &sudOpPinTypes[0] }; // lpTypes const AMOVIESETUP_FILTER sudAsync = { &CLSID_AVI_File_Source // clsID , L"AVI_File_Source" // strName , MERIT_UNLIKELY // dwMerit , 1 // nPins , &sudOpPin }; // lpPin // // Object creation template // CFactoryTemplate g_Templates[1] = { { L"AVI_File_Source" , &CLSID_AVI_File_Source , 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); } /**************CAsyncFilter class implementation**********************/ CAsyncFilter::CAsyncFilter(LPUNKNOWN pUnk, HRESULT *phr) : CAsyncReader(NAME("Mem Reader"), pUnk, &m_Stream, phr), m_pFileName(NULL), m_pbData(NULL) { RETAILMSG(1,(TEXT("AVI_File_Source_Filter: constructor\n"))); } CAsyncFilter::~CAsyncFilter() { delete [] m_pbData; delete [] m_pFileName; } STDMETHODIMP CAsyncFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv) { if (riid == IID_IFileSourceFilter) { return GetInterface((IFileSourceFilter *)this, ppv); } else { return CAsyncReader::NonDelegatingQueryInterface(riid, ppv); } } /* IFileSourceFilter methods */ // Load a (new) file STDMETHODIMP CAsyncFilter::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}; lstrcpy(lpszFileName, lpwszFileName); #endif CAutoLock lck(&m_csFilter); /* Check the file type */ CMediaType cmt; /****Anil on 01-02-2007 - check the filename extension and set the mediaType accordingly****/ /* Find the extension */ LPTSTR lpType; int len = lstrlen(lpszFileName); if(len >= 4 && lpszFileName[len - 4] == TEXT('.')) { lpType = lpszFileName + len - 3; /* Set subtype based on file extension */ if(lstrcmpi(lpType, TEXT("avi")) == 0) { cmt.SetType(&MEDIATYPE_Stream); cmt.SetSubtype(&MEDIASUBTYPE_Avi); RETAILMSG(1,(TEXT("AVI_File_Source_Filter: Configuring SUBTYPE to AVI\n"))); } else { cmt.SetType(&MEDIATYPE_Stream); cmt.SetSubtype(&MEDIASUBTYPE_NULL); } } else { 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,lpszFileName); 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 CAsyncFilter::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; } BOOL CAsyncFilter::ReadTheFile(LPCTSTR lpszFileName) { // 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); #if 0 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 m_pbData = pbMem; #endif m_llSize = (LONGLONG)uliSize.QuadPart; // Close the file CloseHandle(hFile); return TRUE; } /*****************CMemStream class implementation*********************/ CMemStream::CMemStream() { this->m_llPosition = 0; this->m_FileHandle = 0; } CMemStream::~CMemStream() { if(this->m_FileHandle) { CloseHandle(this->m_FileHandle); } } /* Initialization */ HRESULT CMemStream::Init(LPBYTE pbData, LONGLONG llLength, LPCTSTR lpszFileName, DWORD dwKBPerSec) { m_pbData = pbData; m_llLength = llLength; m_dwKBPerSec = dwKBPerSec; m_dwTimeStart = timeGetTime(); /*****Anil on 10-02-2007****/ m_FileHandle = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (m_FileHandle == INVALID_HANDLE_VALUE) { DbgLog((LOG_TRACE, 2, TEXT("Could not open %s\n"), lpszFileName)); return S_FALSE; } return S_OK; } HRESULT CMemStream::SetPointer(LONGLONG llPos) { if (llPos < 0 || llPos > m_llLength) { return S_FALSE; } else { m_llPosition = llPos; return S_OK; } } HRESULT CMemStream::Read(PBYTE pbBuffer, DWORD dwBytesToRead, BOOL bAlign, LPDWORD pdwBytesRead) { CAutoLock lck(&m_csLock); DWORD dwReadLength; DWORD dwBytesRead; /* 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); } /****Anil on 10-02-2007 - Lets not do the buffering ....perform I/O for every Read call****/ #if 0 CopyMemory((PVOID)pbBuffer, (PVOID)(m_pbData + m_llPosition), dwReadLength); #endif DWORD retVal; retVal = (DWORD) SetFilePointer(m_FileHandle, (LONG)m_llPosition, NULL, FILE_BEGIN); if(retVal == 0xFFFFFFFF) { if(GetLastError() != NO_ERROR) { RETAILMSG(1,(TEXT("CMemStream::Read-> SetFilePointer Failed"))); return FALSE; } } // Read the data from the file if (!ReadFile(m_FileHandle, (LPVOID) pbBuffer, dwReadLength, &dwBytesRead, NULL) || (dwBytesRead != dwReadLength)) { RETAILMSG(1,(TEXT("CMemStream::Read-> ReadFile Failed"))); CloseHandle(m_FileHandle); return FALSE; } m_llPosition += dwReadLength; *pdwBytesRead = dwReadLength; return S_OK; } LONGLONG CMemStream::Size(LONGLONG *pSizeAvailable) { LONGLONG llCurrentAvailable = static_cast (UInt32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec)); *pSizeAvailable = min(m_llLength, llCurrentAvailable); return m_llLength; } DWORD CMemStream::Alignment() { return 1; } void CMemStream::Lock() { m_csLock.Lock(); } void CMemStream::Unlock() { m_csLock.Unlock(); }