WMPlayer 10/11 can't play .asf file with my DMO

Discussion in 'Windows Media Player' started by mickeychio, Dec 30, 2006.

  1. mickeychio

    mickeychio Guest

    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
     
    mickeychio, Dec 30, 2006
    #1
    1. Advertisements

  2. You meant to post this in the newsgroup
    microsoft.public.windowsmedia.sdk

    Cheers - Neil

     
    Neil Smith [MVP Digital Media], Dec 30, 2006
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.