Hi,
I am writing a decoder-DMO to decode Motion JPEG stream contained in asf files. The DMO passed DMOTest application and work fine in DirectShow GraphEdit tool with my testing .asf files. But when I play the files with WMPlayer 10 and 11, both failed. WMPlayer 10 reported an error message "The object can only be created as an aggregated object" and WMPlayer 11 reported error code "C00B11D1" (when pressed Web Help).
I use Visual Studio 2005’s ATL template to create the DMO and inherit IMediaObjectImpl. I have tested if WMPlayer ever created the DMO with Visual Studio’s Debug->Attach Process and concluded that the DMO’s constructor and destructor were called. Could anyone give me some little hint to the problem?
The following are the header of the DMO and module code:
//*************** MJPEG decoder Header ******************************
// MjpegDecoder.h : Declaration of the CMjpegDecoder
#pragma once
#include "resource.h" // main symbols
#include "MjpegDMO.h"
#define FIX_LOCK_NAME
#include <dmo.h>
#include <Dmoimpl.h>
#include <queue>
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
// CMjpegDecoder
class ATL_NO_VTABLE CMjpegDecoder :
public IMediaObjectImpl<CMjpegDecoder, 1, 1>,
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMjpegDecoder, &CLSID_MjpegDecoder>,
public IDispatchImpl<IMjpegDecoder, &IID_IMjpegDecoder, &LIBID_MjpegDMOLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CMjpegDecoder()
{
m_pUnkMarshaler = NULL;
m_bDiscontinued = false;
}
DECLARE_REGISTRY_RESOURCEID(IDR_MJPEGDECODER)
BEGIN_COM_MAP(CMjpegDecoder)
COM_INTERFACE_ENTRY(IMediaObject)
COM_INTERFACE_ENTRY(IMjpegDecoder)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_GET_CONTROLLING_UNKNOWN()
HRESULT FinalConstruct()
{
return CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
}
void FinalRelease()
{
FreeStreamingResources();
m_pUnkMarshaler.Release();
}
CComPtr<IUnknown> m_pUnkMarshaler;
private:
struct MediaSample {
IMediaBuffer *pBuffer;
DWORD dwFlags;
REFERENCE_TIME rtTimestamp;
REFERENCE_TIME rtTimelength;
};
std::queue<MediaSample> m_queInputSamples;
bool m_bDiscontinued;
public:
STDMETHODIMP InternalAllocateStreamingResources();
STDMETHODIMP InternalDiscontinuity(ULONG ulStreamIndex);
STDMETHODIMP InternalFlush();
STDMETHODIMP InternalFreeStreamingResources();
STDMETHODIMP InternalGetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME *prtLatency);
STDMETHODIMP InternalGetInputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pcbMaxLookahead, ULONG *pulAlignment);
STDMETHODIMP InternalGetInputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags);
STDMETHODIMP InternalGetInputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt);
STDMETHODIMP InternalGetOutputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pulAlignment);
STDMETHODIMP InternalGetOutputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags);
STDMETHODIMP InternalGetOutputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt);
STDMETHODIMP InternalProcessInput(
DWORD ulStreamIndex,
IMediaBuffer *pBuffer, // [in], must not be NULL
DWORD dwFlags, // [in] - discontinuity, timestamp, etc.
REFERENCE_TIME rtTimestamp, // [in], valid if flag set
REFERENCE_TIME rtTimelength // [in], valid if flag set
);
STDMETHODIMP InternalProcessOutput(
DWORD dwFlags,
DWORD ulOutputBufferCount,
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
DWORD *pdwStatus);
STDMETHODIMP InternalSetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME rtLatency);
STDMETHODIMP InternalAcceptingInput(DWORD dwInputStreamIndex);
STDMETHODIMP InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt);
STDMETHODIMP InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt);
};
OBJECT_ENTRY_AUTO(__uuidof(MjpegDecoder), CMjpegDecoder)
/*************** DMO Module *****************************************
// MjpegDMO.cpp : Implementation of DLL Exports.
#include "stdafx.h"
#include "resource.h"
#include "MjpegDMO.h"
#define FIX_LOCK_NAME
#include <dmo.h>
#include "uuids.h"
#include "MJpegDecoder.h"
class CMjpegDMOModule : public CAtlDllModuleT< CMjpegDMOModule >
{
public :
DECLARE_LIBID(LIBID_MjpegDMOLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_NOVOSUNMJPEGDMO, "{C8B6B082-6DB5-4EDE-871F-228BF5AD877F}")
};
CMjpegDMOModule _AtlModule;
#ifdef _MANAGED
#pragma managed(push, off)
#endif
// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
hInstance;
return _AtlModule.DllMain(dwReason, lpReserved);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
return _AtlModule.DllCanUnloadNow();
}
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
DMO_PARTIAL_MEDIATYPE mtIn, aryMtOut[2];
mtIn.type = MEDIATYPE_Video;
mtIn.subtype = MEDIASUBTYPE_MJPG;
aryMtOut[0].type = MEDIATYPE_Video;
aryMtOut[0].subtype = MEDIASUBTYPE_YUY2;
aryMtOut[1].type = MEDIATYPE_Video;
aryMtOut[1].subtype = MEDIASUBTYPE_RGB32;
HRESULT hr = DMORegister(
L" Mjpeg Decoder", // Friendly name
CLSID_MjpegDecoder, // CLSID
DMOCATEGORY_VIDEO_DECODER, // Category
0, // Flags
1, // Number of input types
&mtIn, // Array of input types
2, // Number of output types
aryMtOut); // Array of output types
if (FAILED(hr)) return hr;
hr = _AtlModule.DllRegisterServer();
return hr;
}
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
DMOUnregister(CLSID_MjpegDecoder, DMOCATEGORY_VIDEO_DECODER);
HRESULT hr = _AtlModule.DllUnregisterServer();
return hr;
}
EggHeadCafe.com - .NET Developer Portal of Choice
http://www.eggheadcafe.com
Neil Smith [MVP Digital Media] - 30 Dec 2006 16:41 GMT
You meant to post this in the newsgroup
microsoft.public.windowsmedia.sdk
Cheers - Neil
>Hi,
>
[quoted text clipped - 191 lines]
>EggHeadCafe.com - .NET Developer Portal of Choice
>http://www.eggheadcafe.com
------------------------------------------------
Digital Media MVP : 2004-2006
http://mvp.support.microsoft.com/mvpfaqs