MediaTools: Two samples to capture M-JPEG video into JPEG files and to play JPEG files back

I added two new simple samples for the MediaTools DirectShow filters to demonstrate how to capture M-JPEG video feed, esp. from an IP camera, and write the video frames into sequence of JPEG files. The other sample takes a directory on the input and plays the images back as video. If you are working on certain transformation filter, it is an easy way to make a reference feed and use it for debugging purposes.

The filters behind that empower the sample are described in another post.

RenderHttpMjpegVideoIntoFiles01 sample takes an URL on the input to generate image/jpeg JPEG or multipart/x-mixed-replace M-JPEG stream. For example, it might be http://demo1.stardotcams.com/nph-mjpeg.cgi feed from a demo StarDot Technologies IP camera.

The application will create a new directory to write files into, and will save each new video frame received into new JPEG file.

Z:\MediaTools\Samples\RenderHttpMjpegVideoIntoFiles01\Release>RenderHttpMjpegVideoIntoFiles01.exe http://demo1.stardotcams.com/nph-mjpeg.cgi
URL: http://demo1.stardotcams.com/nph-mjpeg.cgi
Writing to directory: Z:\MediaTools\Samples\RenderHttpMjpegVideoIntoFiles01\Release\2010-05-12 22-07-37
Event: nCode EC_CLOCK_CHANGED 0xD, nParameter1 0x00000000, nParameter2 0x00000000
Event: nCode EC_PAUSED 0xE, nResult 0x00000000, nParameter2 0x00000000
[...]
^C

The application will generate the files and convert media sample time stamps into file time.

RenderHttpMjpegVideoIntoFiles01 Sample Output

The DirectShow graph that implements the operation is the following:

RenderHttpMjpegVideoIntoFiles01 Filter Graph

The other sample RenderJpegFiles01 takes a directory path to look for JPEG files, e.g. generated by previous sample, and pushes them into DirectShow graph as a video feed. File times will be converted [back] to media sample times.

Continue reading →

ProcessSnapshot: Create process minidump for port-mortem debugging

ProcessSnapshot is a utility to take a snapshot of process call stacks, and the snapshot taken is written into a human friendly text file.

ProcessSnapshot is taking process minidump files

Additionally to this, the utility has been given a capability to create process minidump files, on user request. The minidump files can be used with debugger to analyze the context of the process using feature rich debug environment, esp. Microsoft Visual Studio. To create a minidump for a process, check a corresponding box and press “Take a Dump” button. A file named “<process-image-name> – <date> <time>.dmp” will be created in the directory of the utility executable.

See also:

A binary [Win32, x64] and partial Visual C++ .NET 2008 source code are available from SVN.

Windows Virtual PC files and locations

Microsoft Windows Virtual PC implements virtual machines and the application holds the entire machine state and virtual hard disk information in files. In a few large files in fact, so a question to move and/or backup the files is a question of periodic interest.

So what are the files it is using? First of all, the primary file a user clicks on to start virtual machine is a .VMCX file and it is located in “C:\Users\$(UserName)\Virtual Machines” directory. It is a shortcut to internal files and is holding very basic information about the machine, its state and location of other files.


<?xml version="1.0" encoding="UTF-16"?>
<!-- Microsoft Virtual Machine Description and Registration Settings -->
<vm_description>
    <ram_size type="string">512 MB</ram_size>
    <vmstate type="string">Hibernated</vmstate>
    <primary_disk1 type="string">C:\Users\Roman\AppData\Local\Microsoft\Windows Virtual PC\Virtual Machines\Windows XP Mode.vhd</primary_disk1>
    <secondary_disk1 type="string" />
    <notes type="string">Windows XP Professional in "XP Mode"
Username XPMUser, Password XPM User</notes>
    <vmc_path type="string">C:\Users\Roman\AppData\Local\Microsoft\Windows Virtual PC\Virtual Machines\Windows XP Mode.vmc</vmc_path>
</vm_description>

This directory has a special hidden desktop.ini file in it, which instruct the shell to treat the directory and the files in a special way, as Virtual PC files. This is also how Windows is providing user a link “Create virtual machine”.

The .VMCX file is editable (its format is based on XML) and it holds references to .VHD virtual disk files and .VMC virtual machine configuration files. However, .VMCX file is nothing but a shortcut only, and Windows Virtual PC will re-created those files once underlying .VMC file is double-clicked to be started, so there is no need to edit .VMCX files.

.VMC file is a virtual machine configuration file and it holds the settings a user provides for the virtual machine through settings dialog. The file is also using XML formatting, and is editable. While the file is small itself, its location is used as a base location for .VSV file, where software stores runtime state of virtual machine. The .VSV file size is stipulated by amount of RAM granted to the virtual machine, so the file may be pretty large itself and it might be desired to be moved to another location also. To achieve this, the small .VMC file needs to be moved to location of interest. A .VMC file can be double-clicked itself to start the virtual machine.

Windows Virtual PC Settings Dialog

.VHD are the large files as they store data from virtual hard disks, so moving them may make sense. Additionally to the files themselves, if “Create Undo Disks” option is enabled, software will manage additional .VUD file with the name of format “VirtualPCUndo_$(VirtualMachineName)_$(Token).vud” file with changes that has not yet been applied. If moved, the .VUD files have to be thought of as a part of .VHD files.

By default a .VMC file holds both absolute and relative path refrences to .VHD and .VUD files, with relative reference as a priority. So if .VMC and .VHD (optionally with .VUD) files are moved together, no special path update/edit required. Software will be able to locate moved disk file automatically as soon as virtual machine is started. Still it is possible to edit the files manually and have files located in different directories. Also if disk file location is modified via GUI, software offers/attempts to strip undo disk .VUD file and cancel unapplied changes. If configuration file is edited manually, it is possible to keep undo disks without canceling the changes.

When moving files to a different location, make sure to check directory security so that Windows Virtual PC has sufficient privileges accessing files in the new location, or otherwise it would show ambiguous error messages “Could not register the virtual machine”.

See Also: Windows Virtual PC Tips on microsoft.com

DirectShow Spy: IAMFilterData interface

This quick update for DirectShow Filter Graph Spy adds tracing for (deprecated) IAMFilterData interface, and also fixes problem with Media Player Classic – Home Cinema, when the player crashes in External Filters windows.

Partial Visual C++ .NET 2008 source code is available from SVN, release binary included (Win32, x64); installation instructions are in another post.

DirectShow Spy: Filter Mapper Spy

DirectShow Filter Graph Spy was updated to add new functionality: spying over another DirectShow object – Filter Mapper. Filter Mapper object is used for filter registration purposes and also internally by DirectShow’s Intelligent Connect. IFilterMapper2 interface traces provide detailed description on steps DirectShow takes in order to connect and/or render filter pins. For example when trying to render MEDIATYPE_Audio pin, Filter Mapper suggested “RDP DShow Redirection Filter” and, then, “Default DirectSound Device”:

FilterMapperSpy.h(186): CFilterMapperSpy::EnumMatchingFilters: nFlags 0x0, bExactMatch 0, nMinimalMerit 0x00200001, bInputNeeded 1, nInputTypeCount 1, pInputPinCategory NULL, bRender 1, bOutputNeeded 0, nOutputTypeCount 0, pOutputPinCategory NULL
FilterMapperSpy.h(191): CFilterMapperSpy::EnumMatchingFilters: nInputTypeIndex 0, MajorType {73647561-0000-0010-8000-00AA00389B71}, Subtype {00000000-0000-0000-0000-000000000000}
FilterMapperSpy.h(212): CFilterMapperSpy::EnumMatchingFilters: pMoniker @device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{AB9D6472-752F-43F6-B29E-61207BDA8E06}
FilterMapperSpy.h(220): CFilterMapperSpy::EnumMatchingFilters: sFriendlyName "RDP DShow Redirection Filter", sDescription "", sDevicePath ""
FilterMapperSpy.h(212): CFilterMapperSpy::EnumMatchingFilters: pMoniker @device:cm:{E0F158E1-CB04-11D0-BD4E-00A0C911CE86}\Default DirectSound Device
FilterMapperSpy.h(220): CFilterMapperSpy::EnumMatchingFilters: sFriendlyName "Default DirectSound Device", sDescription "", sDevicePath ""

Important is that DirectShow’s internals are using the mapper through COM instantiation and this provides a safe method to override default behavior process wide in order to, for example, extend Intelligent Connect functionality onto custom, unregistered globally, private filters.

Also, the binary is renamed from FilterGraphSpy.dll to DirectShowSpy.dll.

Partial Visual C++ .NET 2008 source code is available from SVN, release binary included (Win32, x64); installation instructions are in another post.

DirectShow Filter Graph Spy: 64-bit version and hook API

Today’s update for DirectShow Filter Graph Spy introduces 64-bit version (mind the beta state) and a mini-API for an external module to be involved into graph building process.

Filter Graph Spy is offering three new interfaces that provide extensibility of the spy:

  • IFilterGraphAddRemoveHook
  • IFilterGraphConnectHook
  • IFilterGraphStateControlHook

The interfaces are contained in the type library and can be imported using #import directive. An implementation of one or more of these interfaces will receive hook style calls corresponding to respective Filter Graph Manager calls, system wide including in context of other applications.

A COM object may be registered as a hook object with Spy and NoThreadSpy COM classes under predefined registry keys:

Registering a DirectShow Filter Graph Spy Hook

Spy will instantiate the registered hook objects and forward them the calls it receive, before passing them to system Filter Graph Manager object. A hook object has an option to override default processing, including, for example, inserting its own filter in between. For example, IFilterGraph::Reconnect call is implemented the following way:

STDMETHOD(Reconnect)(IPin* pPin) throw()
{
    _Z4(atlTraceCOM, 4, _T("...\n"));
    HOOK_PROLOG(CFilterGraphConnectHookHost)
        OnReconnect(pT, pPin, &bDefault);
    HOOK_EPILOG()
    return m_pInnerFilterGraph2->Reconnect(pPin);
}

Before passing the call to original Reconnect method, spy is iterating through associated hooks, passing them IFilterGraphConnectHook::OnReconnect call. Setting bDefault parameter to FALSE will prevent spy from passing the call to original method.

Included BdaHooks project shows a sample implementation of the hooking COM classes (note .rgs registration).

Filter Graph Spy is compatible with all current Windows operating systems, 32-bit and 64-bit (x64), in particular including:

  • Windows 7
  • Windows Server 2008
  • Windows Vista
  • Windows Server 2003
  • Windows XP
  • Windows 2000

NOTE: DirectShow Filter Graph Spy is NOT suitable for production environment, it is NOT licensed to be redistributed to be a part of production state software item.

Partial Visual C++ .NET 2008 source code is available from SVN, release binary included (Win32, x64); installation instructions are in another post.

regsvr32 32-bit vs. 64-bit

Regsvr32 tool is the one to register DLL hosted COM servers with the system, this is what many have learned without even knowing anything about COM.

On 64-bit operating systems DLLs are 32-bit and 64-bit images, and an important thing about them is that there is no way to mix them in a single process. That is, 32-bit DLLs are for 32-bit processes, running inside WOW64 subsystem, 64-bit DLLs are for native processes.

So how comes that running regsvr32 from command line we can register both 32-bit and 64-bit DLLs. Does the system automatically identify image type of the DLL? Yes, the screenshot below illustrates registration of 64-bit DLL from command line “regsvr32 FilterGraphSpy.dll“.

regsvr32 FilterGraphSpy.dll (64-bit)

Process Explorer: regsvr32 Processes

Command line interpreter starts a 32-bit version of regsvr32 tool, which is located in SysWOW64 directory. It detects that provided image is 64-bit and spawns a 64-bit twin from system32 directory, forwarding the registration task to it. The latter loads 64-bit DLL, being native 64-bit process itself, and does the thing.

As simple as that.