// queue an aligned read request. call WaitForNext to get
// completion.
STDMETHODIMP CAsyncOutputPin::Request(
IMediaSample* pSample,
DWORD 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);
}
//
// 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);
}