Enumerating Media Foundation Transforms (MFTs)

Matthew van Eerde already made a similar wrapper over MFTEnumEx in How to enumerate Media Foundation transforms on your system, and this one extends it with enumeration of attributes, also listing them in human friendly way.
This sort of code should perhaps have been in Media Foundation SDK Samples, however we have what we have.

Media Foundation Transforms (MFTs) – they are registered and accessed through the registry, being available for enumeration with and without qualifying criteria. Some of the transforms are dual, DMO/MFT, some are MFT only which make their useful functionality not available directly for DirectShow pipeline. Luckily, the interface is similar to those of DMOs and making it reasonably possible to wrap one into another. Comparison of MFTs and DMOs shows how the two form factors compare one to the other.

Enumeration tool/utility shows availability of registered MFTs in the system. In Windows 7. For example, the output in Windows 7 workstation in provided below.

The output is a good cheat sheet for seeing support of media types in Windows components.

Download links:

Continue reading →

Using Vista Video Resizer DSP in DirectShow, via DMO Wrapper Filter

Windows Vista introduced helpful video and audio Digital Signal Processors (DSPs) in DMO form-factor, which however do not work smoothly with DMO Wrapper Filter and thus cannot be directly used in DirectShow.

There perhaps was no intent in first place to extend DirectShow functionality with these new components, and no effort was put into providing this mode of operation, however as long as the new classes are DMOs, it is still possible to tune them up to work in DirectShow pipeline.

This sample code/application provides a code snippet on how Video Resizer DSP can be used in DirectShow. There were earlier some discussions on MSDN Forums and this complements the guidelines with code.

The idea is the following:

  • CoCreateInstance the DSP as DMO and add it to DMO Wrapper Filter
  • Use IWMResizerProps::SetFullCropRegion to initialize the DSP
  • Connect input pin
  • Set output type via IMediaObject::SetOutputType
  • IGraphBuilder::ConnectDirect output pin

The sample application takes a video file (note that for the brevity of the sample, not all files will be supported, there is an assumption that files are decoded into VIDEOINFOHEADER media type, and we limit color spaces to 32-bit RGB only to avoid problems on the way in this tiny sample).

The application takes file path (I recommend .WMV) creates DirectShow pipeline, adds Sample Grabber filter to force color space to be 32-bit RGB, adds resizer and sets it up to double video height, but not width, and plays the video.

The application’s filter graph looks like this:

And the video window is stretched twice in height:

A binary [Win32] and Visual C++ .NET 2010 source code [Trac, Subversion] are available from SVN; the important part goes here.

Latest RTSP news from Beward BD4370D and nessyMediaServer

A feed coming from Beward BD4370D Megapixel IP camera:

DESCRIBE rtsp://ipaddress/h264 RTSP/1.0
CSeq: 2
User-Agent: Alax.Info RTSP Streamer Module/1.0.0.774
Accept: application/sdp

RTSP/1.0 200 OK
CSeq: 2
Date: Tue, Jun 29 2010 01:50:09 GMT
Content-Base: rtsp://ipaddress/h264/
Content-Type: application/sdp
Content-Length: 645

v=0
o=- 1277694477005767 1 IN IP4 0.0.0.0
s=Session streamed by "nessyMediaServer"
i=h264
t=0 0
a=tool:LIVE555 Streaming Media v2010.04.09_dyna_modi_2010.05.05
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:Session streamed by "nessyMediaServer"
a=x-qt-text-inf:h264
m=video 0 RTP/AVP 99
c=IN IP4 0.0.0.0
a=rtpmap:99 H264/90000
a=fmtp:99 packetization-mode=28;profile-level-id=4D0029; sprop-parameter-sets=Z00AKZpigPAET5eAtQEBAUAAAPoAADqYOhgAIAAAAwCAAG7y40MABAAAAwAQAA3eXCgA,aO48gA==
a=control:track1
a=cliprect:0,0,1920,1080
a=framerate:30.000000
m=audio 7878 RTP/AVP 0
a=rtpmap:0 PCMU/8000/1
a=control:track2

SETUP rtsp://ipaddress/h264/track1 RTSP/1.0
CSeq: 3
User-Agent: Alax.Info RTSP Streamer Module/1.0.0.774
Transport: RTP/AVP;unicast;client_port=10000-10001

RTSP/1.0 200 OK
CSeq: 3
Cdate
Date: Tue, Jun 29 2010 01:50:10 GMT
Transport: RTP/AVP;unicast;destination=1.2.3.4;source=5.6.7.8;client_port=10000-10001;server_port=6970-6971
Session: 55

Cdate??? You gonna be kidding me… Anyone had a chance to have a look into RTSP RFC?

Memory Allocators with Blackmagic DeckLink video capture hardware

With all respect to Blackmagic Design products, there are bugs so painfully hard to identify. Capture board driver has specific requirements as for buffers allocated for captured video frames. The parameters of memory allocator in used are going in ALLOCATOR_PROPERTIES structure.

typedef struct _AllocatorProperties {
  long cBuffers; // 30
  long cbBuffer;
  long cbAlign; // 16
  long cbPrefix;
} ALLOCATOR_PROPERTIES;

The board is going to use 30 buffers (for a second of video specific capture with NTSC video) and the buffers have to have specific alignment. This is reasonable and goes well if the capture filter, backed in turn by WDM driver, runs with all defaults set and driver’s defaults apply.

As a part of buffer negotiation however, the capture filter queries its peer if there are other suggestions as for buffer allocation. There might be some, why not? Most of the filters don’t have any preferences and thus do fine, because default implementation on the input pin is E_NOTIMPL:

// what requirements do we have of the allocator - override if you want
// to support other people's allocators but need a specific alignment
// or prefix.
STDMETHODIMP
CBaseInputPin::GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES*pProps)
{
    UNREFERENCED_PARAMETER(pProps);
    return E_NOTIMPL;
}

The problem is that that if there are any, esp. those for different alignment, the capture filter accepts them, prefers them to the ones he would use otherwise. Then when streaming starts he finds itself checking the properties of the allocator and as the check fails, the filter does not do any streaming without indicating any runtime error.

That’s it – you hit Start button and there is nothing but blackness, without any single video frame streamed through. And the reason is just downstream peer saying “well, I’d say two buffers on the allocator would be good for me – but since I am not responsible for final choice you can do whatever you think is okay”.

As the capture filter is responsible to choose the allocator and set it up, and alignment is so important for it, then why wouldn’t it negotiate and apply the values that would work? If it was unable to end with with negotiating anything meaningful, why would not it indicate a streaming error? It should have definitely done that.

Endangered species – Debugging Tools for Windows

A standalone redistributable installation before, Debugging Tools for Windows was finally absorbed into Windows SDK. MSDN quote from Download and Install Debugging Tools for Windows:

Install Debugging Tools for Windows as a Standalone Component

If you do not want an entire kit (WDK or SDK), you can install the Debugging Tools as a standalone component from the Windows SDK.

TO INTSTALL JUST DEBUGGING TOOLS: In the SDK installation wizard, select Debugging Tools, and clear other components that you don’t want. Note that .NET Framework 4.0 also will be installed.

  • Install Debugging Tools for Windows as a Standalone Component

Install Debugging Tools for Windows without Installing .NET Framework

If you do NOT want to install the .NET Framework, there are additional steps needed.

Start the install process on a different computer where it is okay to install the .NET Framework. The installer requires .NET Framework 4.0 or higher, and will install .NET if it is not already installed.

Install the Debugging Tools as a standalone component from the Windows SDK. In the installation wizard, select Debugging Tools, and clear other components that you don’t want.

After installation is complete, go to the program files directory and look for (%Program Files%)\Windows Kits\8.0\Debuggers\Redist.
Copy and run the applicable MSIs on the computer that cannot have .NET.

Also, Windows SDK for Windows 8 Consumer Preview is not available as ISO download. So you have to use web downloader, install the gear, and having gone through this, the .MSI of interest are finally there.

You gotta be kidding me, though still thanks for not removing those completely.

Enumerating Binary Resource Languages

The small application is a goos sample and useful tool in the same time. It enumerates PE binary resources and counts languages used. Why? Normally you want single language of resources, however Visual Studio IDE does not show you languages in a convenient way and it is so easy to make a language mess which does not bite you immediately but might bring you troubles later. Apart from this there was a suspicion that language mess might cause runtime bugs on UpdateResource API.

The application gets you a summary of languages used and returns with exit code (checkable using e.g. errorlevel) indicating number of languages.

Output is TSV: LANGID, Language Name, Resource Count:

C:\>ListResourceLanguages.exe C:\Windows\syswow64\shell32.dll
1049    Russian 545
1033    English 3318

Download links:

Resource Tools: Custom Resource Types

This update for Resource Tools adds an option to access custom resource types, such as FILE, TYPELIB, REGISTRY etc. It lets enumerate the resource, and load/save them. The COM interafce adds new Items property; the code snippet below accesses type library of image2.dll and saves it into external tyle library file image2.tlb:

image = new ActiveXObject("AlaxInfo.ResourceTools.Image");
image.Initialize("C:\\Windows\\syswow64\\imapi2.dll");
image.Items("TYPELIB").Item(1).SaveToFile(null, "imapi2.tlb");

Additionally, image.EndUpdate(false) call makes the object close all references to the underlying file so that it can be available for other operations (e.g. overwrite), and the COM object might be further re-initialized and reused.

Download links: