00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "stdafx.h"
00013 #include "asyncio.h"
00014 #include "asyncrdr.h"
00015
00016
00017
00018 CAsyncOutputPin::CAsyncOutputPin(
00019 HRESULT * phr,
00020 CAsyncReader *pReader,
00021 CAsyncIo *pIo,
00022 CCritSec * pLock)
00023 : CBasePin(
00024 NAME("Async output pin"),
00025 pReader,
00026 pLock,
00027 phr,
00028 L"Output",
00029 PINDIR_OUTPUT),
00030 m_pReader(pReader),
00031 m_pIo(pIo)
00032 {
00033 }
00034
00035 CAsyncOutputPin::~CAsyncOutputPin()
00036 {
00037 }
00038
00039 STDMETHODIMP
00040 CAsyncOutputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00041 {
00042 CheckPointer(ppv,E_POINTER);
00043
00044 if (riid == IID_IAsyncReader) {
00045 m_bQueriedForAsyncReader = TRUE;
00046 return GetInterface((IAsyncReader*) this, ppv);
00047 } else {
00048 return CBasePin::NonDelegatingQueryInterface(riid, ppv);
00049 }
00050 }
00051
00052 HRESULT
00053 CAsyncOutputPin::GetMediaType(int iPosition, CMediaType *pMediaType)
00054 {
00055 if (iPosition < 0) {
00056 return E_INVALIDARG;
00057 }
00058 if (iPosition > 0) {
00059 return VFW_S_NO_MORE_ITEMS;
00060 }
00061
00062 *pMediaType = *m_pReader->LoadType();
00063 return S_OK;
00064 }
00065
00066 HRESULT
00067 CAsyncOutputPin::CheckMediaType(const CMediaType* pType)
00068 {
00069 CAutoLock lck(m_pLock);
00070
00071
00072 if ((m_pReader->LoadType()->majortype == pType->majortype) &&
00073 (m_pReader->LoadType()->subtype == MEDIASUBTYPE_NULL ||
00074 m_pReader->LoadType()->subtype == pType->subtype)) {
00075 return S_OK;
00076 }
00077 return S_FALSE;
00078 }
00079
00080 HRESULT
00081 CAsyncOutputPin::InitAllocator(IMemAllocator **ppAlloc)
00082 {
00083 HRESULT hr = NOERROR;
00084 *ppAlloc = NULL;
00085 CMemAllocator *pMemObject = NULL;
00086
00087
00088 pMemObject = new CMemAllocator(NAME("Base memory allocator"),NULL, &hr);
00089 if (pMemObject == NULL) {
00090 return E_OUTOFMEMORY;
00091 }
00092
00093 if (FAILED(hr)) {
00094 delete pMemObject;
00095 return hr;
00096 }
00097
00098
00099 hr = pMemObject->QueryInterface(IID_IMemAllocator,(void **)ppAlloc);
00100 if (FAILED(hr)) {
00101 delete pMemObject;
00102 return E_NOINTERFACE;
00103 }
00104
00105 ASSERT(*ppAlloc != NULL);
00106 return NOERROR;
00107 }
00108
00109
00110
00111 STDMETHODIMP
00112 CAsyncOutputPin::RequestAllocator(
00113 IMemAllocator* pPreferred,
00114 ALLOCATOR_PROPERTIES* pProps,
00115 IMemAllocator ** ppActual)
00116 {
00117
00118 if (!pProps->cbAlign || !m_pIo->IsAligned(pProps->cbAlign)) {
00119 m_pIo->Alignment(&pProps->cbAlign);
00120 }
00121
00122 ALLOCATOR_PROPERTIES Actual;
00123 HRESULT hr;
00124
00125 if (pPreferred) {
00126 hr = pPreferred->SetProperties(pProps, &Actual);
00127 if (SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign)) {
00128 pPreferred->AddRef();
00129 *ppActual = pPreferred;
00130 return S_OK;
00131 }
00132 }
00133
00134
00135 IMemAllocator* pAlloc;
00136 hr = InitAllocator(&pAlloc);
00137 if (FAILED(hr)) {
00138 return hr;
00139 }
00140
00141
00142 hr = pAlloc->SetProperties(pProps, &Actual);
00143 if (SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign)) {
00144
00145
00146 *ppActual = pAlloc;
00147 return S_OK;
00148 }
00149
00150
00151 pAlloc->Release();
00152
00153
00154
00155 if (SUCCEEDED(hr)) {
00156 hr = VFW_E_BADALIGN;
00157 }
00158 return hr;
00159 }
00160
00161
00162
00163
00164 STDMETHODIMP
00165 CAsyncOutputPin::Request(
00166 IMediaSample* pSample,
00167 DWORD dwUser)
00168 {
00169 REFERENCE_TIME tStart, tStop;
00170 HRESULT hr = pSample->GetTime(&tStart, &tStop);
00171 if (FAILED(hr)) {
00172 return hr;
00173 }
00174
00175 LONGLONG llPos = tStart / UNITS;
00176 LONG lLength = (LONG) ((tStop - tStart) / UNITS);
00177 LONGLONG llTotal;
00178 LONGLONG llAvailable;
00179
00180 hr = m_pIo->Length(&llTotal, &llAvailable);
00181 if (llPos + lLength > llTotal) {
00182
00183
00184
00185 LONG lAlign;
00186 m_pIo->Alignment(&lAlign);
00187 llTotal = (llTotal + lAlign -1) & ~(lAlign-1);
00188
00189 if (llPos + lLength > llTotal) {
00190 lLength = (LONG) (llTotal - llPos);
00191
00192
00193 ASSERT((llTotal * UNITS) <= tStop);
00194 tStop = llTotal * UNITS;
00195 pSample->SetTime(&tStart, &tStop);
00196 }
00197 }
00198
00199
00200 BYTE* pBuffer;
00201 hr = pSample->GetPointer(&pBuffer);
00202 if (FAILED(hr)) {
00203 return hr;
00204 }
00205
00206 return m_pIo->Request(
00207 llPos,
00208 lLength,
00209 TRUE,
00210 pBuffer,
00211 (LPVOID)pSample,
00212 dwUser);
00213 }
00214
00215
00216 STDMETHODIMP
00217 CAsyncOutputPin::SyncReadAligned(
00218 IMediaSample* pSample)
00219 {
00220 REFERENCE_TIME tStart, tStop;
00221 HRESULT hr = pSample->GetTime(&tStart, &tStop);
00222 if (FAILED(hr)) {
00223 return hr;
00224 }
00225
00226 LONGLONG llPos = tStart / UNITS;
00227 LONG lLength = (LONG) ((tStop - tStart) / UNITS);
00228 LONGLONG llTotal;
00229 LONGLONG llAvailable;
00230
00231 hr = m_pIo->Length(&llTotal, &llAvailable);
00232 if (llPos + lLength > llTotal) {
00233
00234
00235
00236 LONG lAlign;
00237 m_pIo->Alignment(&lAlign);
00238 llTotal = (llTotal + lAlign -1) & ~(lAlign-1);
00239
00240 if (llPos + lLength > llTotal) {
00241 lLength = (LONG) (llTotal - llPos);
00242
00243
00244 ASSERT((llTotal * UNITS) <= tStop);
00245 tStop = llTotal * UNITS;
00246 pSample->SetTime(&tStart, &tStop);
00247 }
00248 }
00249
00250
00251 BYTE* pBuffer;
00252 hr = pSample->GetPointer(&pBuffer);
00253 if (FAILED(hr)) {
00254 return hr;
00255 }
00256
00257 LONG cbActual;
00258 hr = m_pIo->SyncReadAligned(
00259 llPos,
00260 lLength,
00261 pBuffer,
00262 &cbActual,
00263 pSample
00264 );
00265
00266 pSample->SetActualDataLength(cbActual);
00267 return hr;
00268 }
00269
00270
00271
00272
00273 STDMETHODIMP
00274 CAsyncOutputPin::WaitForNext(
00275 DWORD dwTimeout,
00276 IMediaSample** ppSample,
00277 DWORD * pdwUser)
00278 {
00279 LONG cbActual;
00280 IMediaSample* pSample;
00281
00282 HRESULT hr = m_pIo->WaitForNext(
00283 dwTimeout,
00284 (LPVOID*) &pSample,
00285 pdwUser,
00286 &cbActual
00287 );
00288
00289 if (SUCCEEDED(hr)) {
00290 pSample->SetActualDataLength(cbActual);
00291 }
00292
00293 *ppSample = pSample;
00294 return hr;
00295 }
00296
00297
00298
00299
00300 STDMETHODIMP
00301 CAsyncOutputPin::SyncRead(
00302 LONGLONG llPosition,
00303 LONG lLength,
00304 BYTE* pBuffer)
00305 {
00306 return m_pIo->SyncRead(llPosition, lLength, pBuffer);
00307 }
00308
00309
00310
00311
00312 STDMETHODIMP
00313 CAsyncOutputPin::Length(
00314 LONGLONG* pTotal,
00315 LONGLONG* pAvailable)
00316 {
00317 HRESULT hr = m_pIo->Length(pTotal, pAvailable);
00318 return hr;
00319 }
00320
00321 STDMETHODIMP
00322 CAsyncOutputPin::BeginFlush(void)
00323 {
00324 return m_pIo->BeginFlush();
00325 }
00326
00327 STDMETHODIMP
00328 CAsyncOutputPin::EndFlush(void)
00329 {
00330 return m_pIo->EndFlush();
00331 }
00332
00333
00334 STDMETHODIMP
00335 CAsyncOutputPin::Connect(
00336 IPin * pReceivePin,
00337 const AM_MEDIA_TYPE *pmt
00338 )
00339 {
00340 return m_pReader->Connect(pReceivePin, pmt);
00341 }
00342
00343
00344
00345
00346 #pragma warning(disable:4355)
00347
00348 CAsyncReader::CAsyncReader(
00349 TCHAR *pName,
00350 LPUNKNOWN pUnk,
00351 CAsyncStream *pStream,
00352 HRESULT *phr,
00353 const CLSID& clsid)
00354 : CBaseFilter(
00355 pName,
00356 pUnk,
00357 &m_csFilter,
00358 clsid,
00359 NULL
00360 ),
00361 m_OutputPin(
00362 phr,
00363 this,
00364 &m_Io,
00365 &m_csFilter),
00366 m_Io(pStream)
00367 {
00368 }
00369
00370 CAsyncReader::~CAsyncReader()
00371 {
00372 }
00373
00374 STDMETHODIMP CAsyncReader::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00375 {
00376 CheckPointer(ppv, E_POINTER);
00377
00378 return
00379 (riid == __uuidof(IAMFilterMiscFlags)) ? GetInterface((IAMFilterMiscFlags*)this, ppv) :
00380 __super::NonDelegatingQueryInterface(riid, ppv);
00381 }
00382
00383
00384
00385 ULONG CAsyncReader::GetMiscFlags()
00386 {
00387 return AM_FILTER_MISC_FLAGS_IS_SOURCE;
00388 }
00389
00390
00391 int
00392 CAsyncReader::GetPinCount()
00393 {
00394 return 1;
00395 }
00396
00397 CBasePin *
00398 CAsyncReader::GetPin(int n)
00399 {
00400 if ((GetPinCount() > 0) && (n == 0)) {
00401 return &m_OutputPin;
00402 } else {
00403 return NULL;
00404 }
00405 }
00406
00407