Published by alax on 25 Oct 2008

Private DMO

Started as Is it possible to use local component in DLL? on microsoft.public.vc.atl newsgroup. The question is to embed a custom DirectX Media Object (DMO) into executable so that it is only available to proprietary application and not to entire system and could be reused in other applications. If in particular this DMO should be available to intelligent connect, e.g. used by embedded Windows Media Player control, the solution requires that private DMO appears fully registered as full featured regular DMO.

A while ago I proposed a solution on getting COM Class/DMO embedded into executable and temporarily exposed as availble without registry registration through CoRegisterClassObject/RegisterClassObject, however in addition to COM class registration, a DMO needs to also be specifically listed as a DMO, through DMORegister API.

In order to expose private DMO to DirectShow subsystem the following steps has to be performed:

  • register COM class object as a COM class (CoRegisterClassObject) to enable its instantiation by its CLSID
  • use DMORegister API to list DMO in global list (warning, seems to be requiring write permission on HKEY_CLASSES_ROOT key)
  • have the filter graph of interest created
  • use DMOUnregister API as early as possible to unlist private DMO from global list
ATLENSURE_SUCCEEDED(__objMap_CPrivateMediaObject.RegisterClassObject(CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE));
DMO_PARTIAL_MEDIATYPE pInputMediaTypes[] = { { MEDIATYPE_Video, CPrivateMediaObject::GetXxxxSubtype() } };
ATLENSURE_SUCCEEDED(DMORegister(L"Private DMO", CLSID_PrivateMediaObject, DMOCATEGORY_VIDEO_DECODER, 0, _countof(pInputMediaTypes), pInputMediaTypes, 0, NULL));
...
ATLVERIFY(SUCCEEDED(DMOUnregister(CLSID_PrivateMediaObject, DMOCATEGORY_VIDEO_DECODER)));

The sample code/project takes an .AVI file which is a XVID video file with a FOURCC compression code changed from XVID to XXXX. The file is unplayable but there is a private DMO which accepts XXXX video and copies data as is into XVID format on its output.

A Visual C++ .NET 2008 source code is available from SVN.

Published by alax on 26 Jul 2008

How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 5: In-Place Processing)

Previously on the topic:

Due to the nature of the brightness and constract correction processing, it would make sense to combine and simplify processing to apply correction “in-place”, that is without copying data from input to output buffer, but instead processing the same buffer before it is passed further downstream.

DMO API offers additional optional IMediaObjectInPlace interface to be implemented on the DMO which the hosting object might prefer to regular IMediaObject.

The interface itself is simple with basically the only Process method to actually handle the processing:

// IMediaObjectInPlace
	STDMETHOD(Process)(ULONG nSize, BYTE* pnData, REFERENCE_TIME nStartTime, DWORD nFlags)
	STDMETHOD(Clone)(IMediaObjectInPlace** ppMediaObject)
	STDMETHOD(GetLatency)(REFERENCE_TIME* pnLatencyTime)

Continue Reading »

Published by alax on 26 Jul 2008

How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 4: Merit)

Previously on the topic:

The implemented so far filter/DMO shown a problem related to its unexpectedly high “importance” in the system with the symptom of “auto-insertion” the filter when it is not necessary. For example, let us render an AVI file through Infinite Tee Pin Filter:

The problem is that DirectShow auto-inserts our Brightness/Contrast filter into the graph while it is obviously not expected, wanted or necessary:

The problem is high filter/DMO merit value and a popular YUY2 video format the filter is advertised to accept on input during DMO registration.

Continue Reading »

Published by alax on 24 Jul 2008

Video Conversion: YUY2 to YV12

See topic on MSDN Forums about coloring issue.

This is a demo of YUY2 to YV12 conversion as suggested copying Y values and averaging U and V.

Original image is on the right.

Code snippet to perform the transformation:

Continue Reading »

Published by alax on 18 Jul 2008

How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 3: Persistence, Automation and Property Pages)

Previously on the topic:

The principal task of video processing is done but there are still things mandatory for the filter to be usable. First of all, a custom interface is required to be able to control the filter from higher level application and to adjust brightness and constract correction values on the run time. Additionally, persistence would not hurt at all to be able to store correction settings along with other graph settings in GraphEdit graph file or anywhere else. Additionally, it would also be convenient to have a property page for the filter to be able to adjust the correction settings through GUI, both on graph composition and while the graph is running.

All the mentioned tasks are interconnected and ATL has an answer in implementation of:

Continue Reading »

Published by alax on 12 Jul 2008

How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 2: Video Processing)

Previously on the topic:

We have the DMO filter project compilable and registered with the system and it is right time to start putting code in that allows connecting the filter to other DirectShow filters, such as video capture or video file source on the input and video renderer on the output.

IMediaObject implementation includes the following groups of functions:

  • object capabilities:
    STDMETHOD(GetStreamCount)(DWORD* pnInputStreamCount, DWORD* pnOutputStreamCount)
    STDMETHOD(GetInputStreamInfo)(DWORD nInputStreamIndex, DWORD* pnFlags)
    STDMETHOD(GetOutputStreamInfo)(DWORD nOutputStreamIndex, DWORD* pnFlags)
    STDMETHOD(GetInputType)(DWORD nInputStreamIndex, DWORD nTypeIndex, DMO_MEDIA_TYPE* pMediaType)
    STDMETHOD(GetOutputType)(DWORD nOutputStreamIndex, DWORD nTypeIndex, DMO_MEDIA_TYPE* pMediaType)
  • current media types:
    STDMETHOD(SetInputType)(DWORD nInputStreamIndex, const DMO_MEDIA_TYPE* pMediaType, DWORD nFlags)
    STDMETHOD(SetOutputType)(DWORD nOutputStreamIndex, const DMO_MEDIA_TYPE* pMediaType, DWORD nFlags)
    STDMETHOD(GetInputCurrentType)(DWORD nInputStreamIndex, DMO_MEDIA_TYPE* pMediaType)
    STDMETHOD(GetOutputCurrentType)(DWORD nOutputStreamIndex, DMO_MEDIA_TYPE* pMediaType)
    STDMETHOD(GetInputSizeInfo)(DWORD nInputStreamIndex, DWORD* pnBufferSize, DWORD* pnMaximalLookAheadBufferSize, DWORD* pnAlignment)
    STDMETHOD(GetOutputSizeInfo)(DWORD nOutputStreamIndex, DWORD* pnBufferSize, DWORD* pnAlignment)
  • streaming:
    STDMETHOD(GetInputMaxLatency)(DWORD nInputStreamIndex, REFERENCE_TIME* pnMaximalLatency)
    STDMETHOD(SetInputMaxLatency)(DWORD nInputStreamIndex, REFERENCE_TIME nMaximalLatency)
    STDMETHOD(Flush)()
    STDMETHOD(Discontinuity)(DWORD nInputStreamIndex)
    STDMETHOD(AllocateStreamingResources)()
  • data processing:
    STDMETHOD(GetInputStatus)(DWORD nInputStreamIndex, DWORD* pnFlags)
    STDMETHOD(Lock)(LONG bLock)
    STDMETHOD(ProcessInput)(DWORD nInputStreamIndex, IMediaBuffer* pMediaBuffer, DWORD nFlags, REFERENCE_TIME nTime, REFERENCE_TIME nLength)
    STDMETHOD(ProcessOutput)(DWORD nFlags, DWORD nOutputBufferCount, DMO_OUTPUT_DATA_BUFFER* pOutputBuffers, DWORD* pnStatus)

Continue Reading »

Published by alax on 05 Jul 2008

How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 1: Starting the Project)

This post is starting a step by step tutorial on writing a simple DirectShow filter using a simplified DirectX Media Objects (DMO) API. From the very scratch, the goal is to make a DirectShow/DMO video processing filter which implements video brightness and contrast correction.

DirectX Media Objects are COM-based components. To implement a COM object we will use Visual Studio .NET 2008 and Active Template Library (ATL).

We are starting creating a no thrills ATL DLL project following by adding a no thrills ATL Simple Object Class:

ATL DLL Project

Continue Reading »