Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Building Custom DirectShow Filters

130 views
Skip to first unread message

Shankar

unread,
Sep 29, 2004, 9:27:02 AM9/29/04
to
Hi Everyone,
I'm new to DirectShow filter development. I need to develop a custom
DirectShow Transform Filter in Windows CE .NET 4.2. As a starup i wanted to
compile the sample filter (called EZRGB24) that was given with the Win CE
installation and connect it to the Filter Graph to understand the connection
process. From the MSDN doc i understood that Transform filters needs to be
implemented as DLL. But when i compiled the existing Filter i got only .lib
file. I tried changing the "Sources" file to generate a DLL, this gives me
linker errors ( i have linked the strmbase.lib, strmiids.lib) as suggested in
the MSDN documentation. The following are the error messages,

e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllCanUnloadNow
e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllGetClassObject
e:\wince420\platform\smdk2410\lib\armv4i\retail\ezrgb24.lib() : error
LNK1120: 2 unresolved externals
e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllCanUnloadNow
e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllGetClassObject
e:\wince420\platform\smdk2410\lib\armv4i\retail\ezrgb24.lib() : error
LNK1120: 2 unresolved externals
e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllCanUnloadNow
e:\wince420\platform\smdk2410\apps\ezrgb24\ezrgb24.def() : error LNK2001:
unresolved external symbol DllGetClassObject
e:\wince420\platform\smdk2410\lib\armv4i\retail\ezrgb24.lib() : error
LNK1120: 2 unresolved externals
e:\wince420\platform\smdk2410\apps\ezrgb24\link() : error LNK1181: cannot
open input file 'e:\wince420\platform\SMDK2410\lib\ARMV4I\retail\ezrgb24.exp'

Can some one please help me in answering the following,
1. Even though the MSDN documentation says that the filters needs to
implemented as DLL, why do the example filter compilation gives a .lib file.
Is there any specific reason for the same ?
2. The procedure to build a sample filter and get a dll
3. The procedure to add it to the filter graph.

I posted this question in the multimedia group and got the feedback that the
problem looks more like using COM in Windows CE.

Thanks in Advance,

Shankar



Louis Clausen [MS]

unread,
Sep 30, 2004, 4:57:34 PM9/30/04
to
You can generate the DLL for the EZRGB24 sample filter by following these
steps:
1. Build the ezrgb24.lib file by calling Build in the sample's original
source directory.
2. Generate the DLL by calling "sysgen -p directx ezrgb24"
(This performs the linking step for ezrgb24, which is a module in the
DirectX project)

This will generate the ezrgb24.dll file.

To add this filter to a FilterGraph, you first need to register it (on the
desktop you would call regsvr32 ezrgb24.dll, but on CE you might need to
load the DLL yourself [with LoadLibrary], get the address of
DllRegisterServer() from the DLL [with GetProcAddress], and call
DllRegisterServer).

After the filter is registered, you will be able to create an instance of
the filter with CoCreateInstance (you will need to link against ezrgb24.lib
or include ezuids.h in your test application to get the CLSID_EZrgb24 CLSID
for use in CoCreateInstance [the interface UID will be IID_IBaseFilter]).

You can then add the filter to a filter graph with IGraphBuilder::AddFilter,
and connect the necessary pins using IBaseFilter::EnumPins and
IGraphBuilder::Connect. You can take a look at the sample player application
DDXCLMV (under public\directx\sdk\samples\dshow\Players\ddxclmv) to see an
example of pin enumeration and connection management.

--
Louis Clausen
Software Design Engineer in Test
Windows CE Multimedia

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.

"Shankar" <Sha...@discussions.microsoft.com> wrote in message
news:B3F5B5FD-968F-4215...@microsoft.com...

Shankar

unread,
Oct 1, 2004, 10:49:03 AM10/1/04
to
Thank you for that valuable information and very descriptive mail. It helped
me a lot in proceeding further. Now i'm able to load the library but i'm
unable to register the filter.
I have come up to a stage where i'm calling the DllRegisterServer function
of the ezrgb24.dll from an application. But this function call returns me an
error code for which i'm unable to find the meaning. I get 0x800700c1 as
error number. The DllRegisterServer function of ezrgb24, calls
AMovieDllregisterServer2 function. But from the MSDN documentation section
"Registering DirectShow filters" i found that

"Filter categories introduced with AMovieDLLRegisterServer2 are not
currently supported on Windows CE".

So, i changed the function call to AMovieDllregisterServer and tested, but
the result was same. Can you please help me in solving this problem ?

Regards,
Shankar

Louis Clausen [MS]

unread,
Oct 1, 2004, 8:17:27 PM10/1/04
to
It seems the call to DllRegisterServer with the EZRGB24.dll is not producing
the right registry entries.

To get the EZRGB24.dll properly registered, add the following into your
device's registry (the Remote Registry Editor under Tools [I think that's
where it is] will let you do this by hand, or you can add this to your
platform.reg file and remake your runtime image. Note, everything between
the [] brackets (including the brackets) should be on one line. Also, you
can do this for other objects, too, by changing the GUID and the Dll
location appropriately.

[HKEY_CLASSES_ROOT\CLSID\{8B498501-1218-11CF-ADC4-00A0D100041B}\InprocServer32]
@="\\Release\\ezrgb24.dll"
"ThreadingModel"="Both"

--
Louis Clausen
Software Design Engineer in Test
Windows CE Multimedia

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.

"Shankar" <Sha...@discussions.microsoft.com> wrote in message

news:B0811779-2F8D-4CF4...@microsoft.com...

Shankar

unread,
Oct 4, 2004, 8:31:02 AM10/4/04
to
Thank you for the continuous help. I tried adding the registry entry
suggested below, in my platform.reg file. I rebuilt the image and tested, but
the result was same. Even after adding the registry entry, I'm still getting
the same error number when the DllRegisterServer function is called. I also
played around by adding/removing the components from the image but with no
success. Please suggest, is there any thing else that i can doubt ?

Warm Regards,

Louis Clausen [MS]

unread,
Oct 4, 2004, 1:44:56 PM10/4/04
to
After editing that registry setting, you no longer should be calling
DllRegisterServer.

The only thing DllRegisterServer does is add that registry setting, so once
you've added it to your platform.reg file, you won't need to call
DllRegisterServer at all.

--
Louis Clausen
Software Design Engineer in Test
Windows CE Multimedia

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.

"Shankar" <Sha...@discussions.microsoft.com> wrote in message

news:43708249-324B-4698...@microsoft.com...

Shankar

unread,
Oct 5, 2004, 10:29:14 AM10/5/04
to
Thank you very much. I was able to proceed further. I have added the filter
into the filter graph programatically. I was also able to connect the input
pin of the ezrgb24 filter to the output pin of the video decoder for a .wmv
file. I'm in the process of connecting the output pin of ezrgb24 filter to
the Video renderer. When i try to do this i get an error number 0x80040217 -
VFW_E_CANNOT_CONNECT which means "No combination of intermediate filters
could be found to make the connection." When i was going through the
description of ezrgb24 filter (ezrgb24.cpp source file) i found that even
when we add ezrgb24 filter using GRAPHEDT in a PC environment, GRAPHEDT may
put a colour space convertor in between this filter and the video renderer.
I'm not very sure, but i'm doubting that my platform may not have such a
converter. If you can throw me some ideas on why this could happen, it would
be great. Thank you again for you continuous help.

Louis Clausen [MS]

unread,
Oct 6, 2004, 6:03:41 PM10/6/04
to
It looks like the Video renderer is not accepting the output format that the
EZRGB24 filter supports. The video renderer accepts video formats depending
on what the underlying display driver supports.

Some questions you can answer to help get to the bottom of this:
1. What video driver are you using currently?
2. What is the pixel format of the video driver/display?
3. Does the video driver support DDraw?
4. If the video driver supports DDraw, does it support Overlays?

In the meantime, you can try modifying the EZRGB24 sample to support
different input types by modifying the CheckInputType function (but be sure
to make a backup copy for your use later on).

--
Louis Clausen
Software Design Engineer in Test
Windows CE Multimedia

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.

"Shankar" <Sha...@discussions.microsoft.com> wrote in message

news:6A59F0DD-3B1E-4BB4...@microsoft.com...

Shankar

unread,
Oct 11, 2004, 10:13:02 AM10/11/04
to
I'm using the SMDK board from Samsung for my experiments. I tried to answer
the 4 questions, the following are those,

1. What is the pixel format of the video driver/display? Ans:-rgb565
2. Does the video driver support DDraw? Ans:-No
3. If the video driver supports DDraw, does it support Overlays? Ans:-No

I could'nt get the answer for the first question. I tried few experiments by
changing the ezrgb24 filter code. I tried changing the Media sub type
property of the ezrgb24 filter's input as well as output pin from
MEDIASUBTYPE_NULL to MEDIASUBTYPE_RGB565 but the result is same. Can the
connection fail because of any other reason, like different buffer
requirements ?

Now, i have a more general doubt. How to decide what should be the property
of a transform filter's output pin, so that it gets connected with the
existing video renderer without any problems. Actually, i'm kind of running
out of ideas here. Please help.

Louis Clausen [MS]

unread,
Oct 11, 2004, 4:36:26 PM10/11/04
to
To change the media type that the EZrgb24 filter presents on its output pin,
you'll need to modify GetMediaType. This is the method that any filter
downstream (such as the video renderer) will call to determine pin type. In
this case, I would recommend setting a breakpoint in GetMediaType to
determine what media type is being returned. My guess is that it is
returning RGB24. You can try changing this to RGB565 (change the
MEDIASUBTYPE of the CMediaType object being returned, also change the
bmiHeader in the VideoInfoHeader that is stored in the CMediaType's Format
(the method just below, CanPerformEZrgb24, gets the Format and looks at the
bmiHeader, so you can use it as an example)).

--
Louis Clausen
Software Design Engineer in Test
Windows CE Multimedia

This posting is provided "AS IS" with no warranties, and confers no rights.
You assume all risk for your use.

"Shankar" <Sha...@discussions.microsoft.com> wrote in message

news:BEEAF684-2278-4F3B...@microsoft.com...

Shankar

unread,
Oct 12, 2004, 10:07:07 AM10/12/04
to
I tried modifying the GetMediaType function. Your guess was correct. In that
function the Media sub type was returned as rgb24. The following is what I
tried,
I first read the properties of the output pin that was connected to the
Video Renderer before disconnecting the graph to insert ezrgb24. I found that
the media sub type was MEDIASUBTYPE_RGB565. I also found that
bmiHeader.biBitCount was 16 and bmiHeader.biCompression was 3 (BI_BITFIELDS).
But the ezrgb24 filter was having 24 and 0 in these fields respectively. So i
changed these fields also as required. But the result was same. The following
is my GetMediaType function,

if (m_pInput->IsConnected() == FALSE) {
RETAILMSG (1, (TEXT("returns E_UNEXPECTED\n"))); // sb - added
return E_UNEXPECTED;
}

// This should never happen

if (iPosition < 0) {
RETAILMSG (1, (TEXT("returns E_INVALIDARG\n"))); // sb - added
return E_INVALIDARG;
}

// Do we have more items to offer

if (iPosition > 0) {
RETAILMSG (1, (TEXT("returns E_VFW_S_NO_MORE_ITEMS\n")));
return VFW_S_NO_MORE_ITEMS;
}

*pMediaType = m_pInput->CurrentMediaType();

// sb - added
if (IsEqualGUID(*pMediaType->Subtype(), MEDIASUBTYPE_RGB24))
RETAILMSG (1, (TEXT("MEDIASUBTYPE_RGB24 is the subtype returned\n")));

pMediaType->SetSubtype(&MEDIASUBTYPE_RGB565);

if (IsEqualGUID(*pMediaType->Subtype(), MEDIASUBTYPE_RGB565))
RETAILMSG (1, (TEXT("MEDIASUBTYPE_RGB565 is the subtype
returned\n")));

VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pMediaType->Format();
pvi->bmiHeader.biBitCount = 16;
pvi->bmiHeader.biCompression = BI_BITFIELDS;
RETAILMSG (1, (TEXT("biBitCount is %d\n"),pvi->bmiHeader.biBitCount));
RETAILMSG (1, (TEXT("biCompression is %d\n"),pvi->bmiHeader.biCompression));
RETAILMSG (1, (TEXT("returns NOERROR\n"))); // sb - added
return NOERROR;

Also i'm not sure why do we operate on m_pInputPin in this function. Since
we are connecting ezrgb24 filter's output pin to the Video renderers input
pin, Are we not suppose to work on m_pOutputPin ? As the existing code was
operating on input pin i left it as it is and added only the required code.

Am i suppose to look at some other fields of AM_MEDIA_TYPE, VIDEOINFOHEADER
or BITMAPINFOHEADER structures. Please help me.

V Reddy@discussions.microsoft.com Krishna V Reddy

unread,
Feb 14, 2005, 3:45:02 AM2/14/05
to
Hi Louis

Based upon ezrgb24 example, i have written a transform filter(name is Tnsfm)
I have done following steps to build .
1. Added the entries for Tnsfm in
"D:\WINCE420\PUBLIC\DIRECTX\CESYSGEN\makefile".
2. compiled the source with build -cf from cmd window and then using
'sysgen -p directx Tnsfm" cmd in cmd window. as a result i have got
Tnsfm.dll. which i have copied to PlatformRelease directory.
3. I have added the following entry in Directx.reg (located at
"D:\WINCE420\PUBLIC\DIRECTX\OAK\FILES")
[HKEY_CLASSES_ROOT\CLSID\{6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}]
@="Transform Filter"

[HKEY_CLASSES_ROOT\CLSID\{6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}]
@="Transform Filter"
"Merit"=dword:00800000

[HKEY_CLASSES_ROOT\CLSID\{6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}\InprocServer32]
@="Trnsfm.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}\Pins\Input]
"Direction"=dword:00000000

[HKEY_CLASSES_ROOT\CLSID\{6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}\Pins\Output]
"Direction"=dword:00000001


4. I have recompiled the BSP project and loaded the WinCE image onto target.
5. I have copied Tnsfm.dll to windows directory of Target.
6. I have executed Graphedt on target

But i am not able to find the filter "Transform Filter" in insert filters
dialog.

I have other custom filters ( Parser Filters, Source Filters, which were
extended from CBaseFilters) shown in the insert filters dialog.
Is there any specific way of registration of for Transform filters. I have
stuck here, as i wanted to build audio decoder. Please help me.

Thanks in Adance
Krishna.


-------*Trnsfm.cpp--------------------------------


#include <windows.h>
#include <streams.h>
#include <initguid.h>
#include "Trnsfm.h"

// {6AC7C19E-8CA0-4e3d-9A9F-2881DE29E0A0}
DEFINE_GUID(CLSID_Transform,
0x6ac7c19e, 0x8ca0, 0x4e3d, 0x9a, 0x9f, 0x28, 0x81, 0xde, 0x29, 0xe0, 0xa0);
// Setup information

const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_Video, // Major type
&MEDIASUBTYPE_NULL // Minor type
};

const AMOVIESETUP_PIN sudpPins[] =
{
{ L"Input", // Pins string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
},
{ L"Output", // Pins string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
}
};

const AMOVIESETUP_FILTER sudEZrgb24 =
{
&CLSID_Transform, // Filter CLSID
L"Transform Filter", // String name
MERIT_PREFERRED, // Filter merit
2, // Number of pins
sudpPins // Pin information
};


// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance

CFactoryTemplate g_Templates[] = {
{ L"Transform Filter"
, &CLSID_Transform
, CTransform::CreateInstance
, NULL
, &sudEZrgb24 }

};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);


//
// DllRegisterServer
//
// Handles sample registry and unregistry
//
STDAPI DllRegisterServer()
{
//return AMovieDllRegisterServer2( TRUE );
return AMovieDllRegisterServer();

} // DllRegisterServer


//
// DllUnregisterServer
//
STDAPI DllUnregisterServer()
{
//return AMovieDllRegisterServer2( FALSE );
return AMovieDllUnregisterServer();

} // DllUnregisterServer

//
// DllEntryPoint
///

extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}


//
// Constructor
//
CTransform::CTransform(TCHAR *tszName,
LPUNKNOWN punk,
HRESULT *phr) :
CTransformFilter(tszName, punk, CLSID_Transform)
{


} // (Constructor)


//
// CreateInstance
//
// Provide the way for COM to create a EZrgb24 object
//
CUnknown *CTransform::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
{
CTransform *pNewObject = new CTransform(NAME("Transform Filter"), punk,
phr);
if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}
return pNewObject;

} // CreateInstance


//
STDMETHODIMP CTransform::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);

if (riid == IID_ISpecifyPropertyPages)
{
return GetInterface((ISpecifyPropertyPages *) this, ppv);

} else {
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}

} // NonDelegatingQueryInterface


//
// Transform
//
// Copy the input sample into the output sample - then transform the output
// sample 'in place'. If we have all keyframes, then we shouldn't do a copy
// If we have cinepak or indeo and are decompressing frame N it needs frame
// decompressed frame N-1 available to calculate it, unless we are at a
// keyframe. So with keyframed codecs, you can't get away with applying the
// transform to change the frames in place, because you'll corrupt the next
// frames decompression. The runtime MPEG decoder does not have keyframes in
// the same way so it can be done in place. We know if a sample is key frame
// as we transform because the sync point property will be set on the sample
//
HRESULT CTransform::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
// Copy the properties across

RETAILMSG(1, (TEXT("CTransform::Transform\n")));

HRESULT hr = Copy(pIn, pOut);
if (FAILED(hr)) {
return hr;
}

// Check to see if it is time to do the sample

CRefTime tStart, tStop ;
pIn->GetTime((REFERENCE_TIME *) &tStart, (REFERENCE_TIME *) &tStop);
return Transform(pOut);

} // Transform


//
// Copy
//
// Make destination an identical copy of source
//
HRESULT CTransform::Copy(IMediaSample *pSource, IMediaSample *pDest) const
{
// Copy the sample data

BYTE *pSourceBuffer, *pDestBuffer;
long lSourceSize = pSource->GetActualDataLength();
long lDestSize = pDest->GetSize();

ASSERT(lDestSize >= lSourceSize);

pSource->GetPointer(&pSourceBuffer);
pDest->GetPointer(&pDestBuffer);

CopyMemory( (PVOID) pDestBuffer,(PVOID) pSourceBuffer,lSourceSize);

// Copy the sample times

REFERENCE_TIME TimeStart, TimeEnd;
if (NOERROR == pSource->GetTime(&TimeStart, &TimeEnd)) {
pDest->SetTime(&TimeStart, &TimeEnd);
}

LONGLONG MediaStart, MediaEnd;
if (pSource->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) {
pDest->SetMediaTime(&MediaStart,&MediaEnd);
}

// Copy the Sync point property

HRESULT hr = pSource->IsSyncPoint();
if (hr == S_OK) {
pDest->SetSyncPoint(TRUE);
}
else if (hr == S_FALSE) {
pDest->SetSyncPoint(FALSE);
}
else { // an unexpected error has occured...
return E_UNEXPECTED;
}

// Copy the media type

AM_MEDIA_TYPE *pMediaType;
pSource->GetMediaType(&pMediaType);
pDest->SetMediaType(pMediaType);
DeleteMediaType(pMediaType);

// Copy the preroll property

hr = pSource->IsPreroll();
if (hr == S_OK) {
pDest->SetPreroll(TRUE);
}
else if (hr == S_FALSE) {
pDest->SetPreroll(FALSE);
}
else { // an unexpected error has occured...
return E_UNEXPECTED;
}

// Copy the discontinuity property

hr = pSource->IsDiscontinuity();
if (hr == S_OK) {
pDest->SetDiscontinuity(TRUE);
}
else if (hr == S_FALSE) {
pDest->SetDiscontinuity(FALSE);
}
else { // an unexpected error has occured...
return E_UNEXPECTED;
}

// Copy the actual data length

long lDataLength = pSource->GetActualDataLength();
pDest->SetActualDataLength(lDataLength);

return NOERROR;

} // Copy


//
// Transform (in place)
//
// 'In place' apply the image effect to this sample
//
HRESULT CTransform::Transform(IMediaSample *pMediaSample)
{
return NOERROR;

} // Transform (in place)


// Check the input type is OK - return an error otherwise

HRESULT CTransform::CheckInputType(const CMediaType *mtIn)
{
// check this is a VIDEOINFOHEADER type
RETAILMSG(1, (TEXT("CTransform::CheckInputType...")));

if (*mtIn->FormatType() != FORMAT_VideoInfo) {
RETAILMSG(1, (TEXT("FAILED\n")));
return E_INVALIDARG;
}

// Can we transform this type

return NOERROR;
}


//
// Checktransform
//
// Check a transform can be done between these formats
//
HRESULT CTransform::CheckTransform(const CMediaType *mtIn, const CMediaType
*mtOut)
{

return NOERROR;

} // CheckTransform


//
// DecideBufferSize
//
// Tell the output pin's allocator what size buffers we
// require. Can only do this when the input is connected
//
HRESULT CTransform::DecideBufferSize(IMemAllocator
*pAlloc,ALLOCATOR_PROPERTIES *pProperties)
{
// Is the input pin connected

if (m_pInput->IsConnected() == FALSE) {

return E_UNEXPECTED;
}

ASSERT(pAlloc);
ASSERT(pProperties);
HRESULT hr = NOERROR;

pProperties->cBuffers = 1;
pProperties->cbBuffer = m_pInput->CurrentMediaType().GetSampleSize();
ASSERT(pProperties->cbBuffer);

// Ask the allocator to reserve us some sample memory, NOTE the function
// can succeed (that is return NOERROR) but still not have allocated the
// memory that we requested, so we must check we got whatever we wanted

ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProperties,&Actual);
if (FAILED(hr)) {
return hr;
}

ASSERT( Actual.cBuffers == 1 );

if (pProperties->cBuffers > Actual.cBuffers ||
pProperties->cbBuffer > Actual.cbBuffer) {
return E_FAIL;
}
return NOERROR;

} // DecideBufferSize


//
// GetMediaType
//
// I support one type, namely the type of the input pin
// This type is only available if my input is connected
//
HRESULT CTransform::GetMediaType(int iPosition, CMediaType *pMediaType)
{
// Is the input pin connected

if (m_pInput->IsConnected() == FALSE) {

return E_UNEXPECTED;
}

// This should never happen

if (iPosition < 0) {
return E_INVALIDARG;
}

// Do we have more items to offer

if (iPosition > 0) {
return VFW_S_NO_MORE_ITEMS;
}

*pMediaType = m_pInput->CurrentMediaType();
return NOERROR;

} // GetMediaType


//
// GetClassID
//
// This is the only method of IPersist
//
STDMETHODIMP CTransform::GetClassID(CLSID *pClsid)
{
return CBaseFilter::GetClassID(pClsid);
} // GetClassID


//
// GetPages
//
// Returns the clsid's of the property pages we support
//
STDMETHODIMP CTransform::GetPages(CAUUID *pPages)
{
pPages->cElems = 0;
pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
if (pPages->pElems == NULL) {
return E_OUTOFMEMORY;
}
return NOERROR;

} // GetPages


------------------------------Trnsfm.h----------------------------

class CTransform : public CTransformFilter,
public ISpecifyPropertyPages

{

public:

DECLARE_IUNKNOWN;
static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);

// Reveals IEZrgb24 and ISpecifyPropertyPages
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);

// Overrriden from CTransformFilter base class

HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);
HRESULT CheckInputType(const CMediaType *mtIn);
HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut);
HRESULT DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES
*pProperties);
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);

// ISpecifyPropertyPages interface
STDMETHODIMP GetPages(CAUUID *pPages);

// CPersistStream override
STDMETHODIMP GetClassID(CLSID *pClsid);

private:

// Constructor
CTransform(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);

// Look after doing the special effect
HRESULT Copy(IMediaSample *pSource, IMediaSample *pDest) const;
HRESULT Transform(IMediaSample *pMediaSample);

CCritSec m_EZrgb24Lock; // Private play critical section

}; // EZrgb24

-------------------------Sources-------------------------

TARGETNAME=trnsfm
TARGETTYPE=LIBRARY
TARGETDEFNAME=$(TARGETNAME)
COPYRES=1
WINCETARGETFILE0=$(_RELEASELIBDIR)\$(TARGETDEFNAME).def
WINCETARGETFILES=$(_RELEASELIBDIR)\$(TARGETNAME).res

SOURCES=\
trnsfm.cpp

#xref VIGUID {68785eef-eb45-439c-8771-b769ca7bc37a}
#xref VSGUID {692639ce-16fe-4913-87bd-2e25e89c6206}

--------------------Trnsfm.def--------------------------

LIBRARY trnsfm.dll
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE


0 new messages