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
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...
"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
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...
Warm Regards,
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...
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...
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
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...
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.
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