Microsoft DirectX 9.0 |
The upstream filter delivers media samples to the transform filter by calling the IMemInputPin::Receive method on the transform filter's input pin. To process the data, the transform filter calls the Transform method, which is pure virtual. The CTransformFilter and CTransInPlaceFilter classes use two different versions of this method:
If the Transform method returns S_OK, the filter delivers the sample downstream. To skip a frame, return S_FALSE. If there is a streaming error, return a failure code.
The following example shows how the RLE encoder might implement this method. Your own implementation might differ considerably, depending on what your filter does.
HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
{
// Get pointers to the underlying buffers.
BYTE *pBufferIn, *pBufferOut;
hr = pSource->GetPointer(&pBufferIn);
if (FAILED(hr))
{
return hr;
}
hr = pDest->GetPointer(&pBufferOut);
if (FAILED(hr))
{
return hr;
}
// Process the data.
DWORD cbDest = EncodeFrame(pBufferIn, pBufferOut);
KASSERT((long)cbDest <= pDest->GetSize());
pDest->SetActualDataLength(cbDest);
pDest->SetSyncPoint(TRUE);
return S_OK;
}
This example assumes that EncodeFrame is a private method that implements the RLE encoding. The encoding algorithm itself is not described here; for details, see the topic "Bitmap Compression" in the Platform SDK documentation.
First, the example calls IMediaSample::GetPointer to retrieve the addresses of the underlying buffers. It passes these to the private EncoderFrame method. Then it calls IMediaSample::SetActualDataLength to specify the length of the encoded data. The downstream filter needs this information so that it can manage the buffer properly. Finally, the method calls IMediaSample::SetSyncPoint to set the key frame flag to TRUE. Run-length encoding does not use any delta frames, so every frame is a key frame. For delta frames, set the value to FALSE.
Other issues that you must consider include:
For more information, see Dynamic Format Changes.