Tag Archives: WTL - Page 2

MediaTools: Tone Source Filter to generate reference audio feed, dual Audio Source Filter and Virtual Audio Capture Device

In order to obtain a reference audio source and especially useful for debugging purposes, including:

  • audio input device unrelated to physical device, to avoid conditions when device is already in use by someone else
  • non-zero audio signal which is independent of certain speaker or broadcasting service, including one that makes capture, transmission or rendering issues easily perceptible by human
  • configurable to provide different audio media types, including through well known DirectShow interfaces, such as IAMStreamConfig
  • configurable to present in system as both regular DirectShow Filter, and as an Audio Capture Source which can be enumerated by applications
  • to be able to check how exactly other applications are accessing and configuring audio capture source

I added a new filter to the Media Tools library, a Tone Source Filter. The filter generates PCM Audio data, either infinite sine waveform, or interrupted signal  of requested parameters:

Tone Source Filter General Property Page

The filter accepts connection on PCM media types with flexible sampling rates in range 8 KHz through 200 KHz, 8-bit audio and 1 channel. Media type is also configurable through or, if not configured this way, the first enumerated media type off the Output pin is also configurable through property page and/or persistent setting accessible via private IDispatch derived interface property.

Tone Source Filter Prefered Format Property Page

Additionally, the filter may configured as a system-wide available audio input device, such as for example available to VLC Media Player or Media Player Classic:

VLC Media Player's Option to use Tone Source Filter based device

In order to configure the filter as such device, the library exports function DoToneSourceFilterDevicePropertySheetModal, which can be called using rundll32 utility (“rundll32 Acquisition.dll,DoToneSourceFilterDevicePropertySheetModal” from command line):

Devices Property Page

A partial Visual C++ .NET 2008 source code is available from SVN, release binary included.

File and Class Summary

Acqusition.dll

Acqusition.dll (download) hosts the following classes:

  • DirectShow Filters
    • Tone Source Filter, to generate reference/debug audio data

Class Overview

Tone Source Filter

The filter generates uninterrupted or interrupted reference sine waveform in form of PCM audio data.

Remarks

The hosting library (DLL) exposes DoToneSourceFilterDevicePropertySheetModal function which provides GUI to configure the filter as one or more audio capture source device, which can be enumerated by System Device Enumerator.

MediaTools: HTTP Stream File Renderer Filter and more

In order to better troubleshoot network cameras and other devices, I added a new DirectShow filter to write HTTP response headers and body into a single file, one file (actually a pairs of files, the second file contains UTF-8 formatted HTTP response headers) per HTTP response.

While troubleshootting JPEG artefact issue with I used the following graph:

HTTP Stream File Renderer Filter in Filter Graph

which started M-JPEG streaming from a camera and had entire stream written into Response-01586228-0001-0001-Headers.txt (Headers) and Response-01586228-0001-0001.dat (Data) files, while parsed JPEG frames were also written into individual files and were available for comparison.

Other changes include:

  • new HTTP Stream File Renderer Filter (details are below)
  • attachable media types on internally used memory allocators, which enable filters to effectively reagree media types in running state
  • workaround for Panasonic BL-C140 camera (may be also helpful for other models), details here

There also seems to be a bug in Intel IPP 6.0 JPEG decoder that leaves bottom right image block incorrectly decoded, only when a sequence of images is decoded and the frame is not the first in the sequence.

A partial Visual C++ .NET 2008 source code is available from SVN, release binary included.

Read more »

The easiest yet user-friendly WTL way to Minimize Application to System Tray Icon

A good old task to easily minimize to system tray icon to not clog the application bar and without too much thinking about it. How To with WTL?

The key points are:

  • manage NOTIFYICONDATA structure (obviously!), where non-zero .cbSize will be an indication of created icon
  • create an icon in WM_SYSCOMMAND/SC_MINIMIZE handler and hide instead default minimization
  • handle icon’s WM_LBUTTONDBLCLK to restore and WM_RBUTTONUP to pop up a menu
  • use default dialog menu to avoid having private one, handle SC_RESTORE and SC_CLOSE system commands to restore and close from system tray icon popup menu

Relevant source code from application main window (dialog) class:

Read more »

MediaTools to deliver video from network/IP cameras and video servers into DirectShow environment

I decided to gather DirectShow code and filters related to processing video from network/IP cameras and video servers into a library (in fact, a few libraries) so that it could be easily used for testing, research and other purposes. As time is going to permit, documentation and sample code will be provided, further development will be carried out.

This initial post publishes two libraries (DLLs) which host DirectShow filters to receive JPEG or M-JPEG video from network using HTTP based protocol, decode video with the help of Intel IPP 6.0 library (UMC version of the JPEG implementation), as well as perform additional helpful features, including writing series of frames into .JPG files and emulating video feed from saved .JPG files, conversion filters to obtain video in 24-bit and 32-bit RGB formats, YUY2 and YV12 formats.

File and Class Summary

Acqusition.dll

Acqusition.dll (download) hosts the following classes:

  • DirectShow Filters
    • HTTP Stream Source Filter, to receive HTTP content and deliver into DirectShow environment through output pin
    • JPEG HTTP Stream Parser Filter, to parse HTTP content (typically received from HTTP Stream Source Filter) of image/jpeg and multipart/x-mixed-replace types and output JPEG frames
    • JPEG Multi File Renderer Filter, to write parsed JPEG frames (typically received from JPEG HTTP Stream Parser Filter) into files
    • JPEG Multi File Source Filter, to read JPEG files (typically written by JPEG Multi File Renderer Filter) and stream video into DirectShow environmentto emulate video feed

Acqusition.dll is dependent only on well known DLLs and does not require presence/redistribution of specific dependency files.

CodingI.dll

CodingI.dll (download) hosts the following classes:

  • DirectShow Filters
    • JPEG Frame Decoder Filter, to parse JPEG data and pass frames downstream with a corresponding mediatype provided with VIDEOINFOHEADER format and correct resolution; in case of resolution changes the filter is capable of dynamically re-agreeing media type with downstream peer
    • JPEG Decoder Filter, to decode JPEG data into 24-bit/32-bit RGB (unfortunately Intel IPP codec has limited capabilities of decoding video into YUV pixel formats)
    • YUY2 Encoder Filter, to convert RGB data into YUY2 pixel format
    • YV12 Encoder Filter, to convert RGB data into YV12 pixel format
  • Shell Extensions
    • JPEG File Resolution Shell Property Page, to provide additional information (such as sampling, color format, resolution) about .JPG and .JPEG files through a shell property page

CodingI.dll is dependent on Intel IPP 6.0 library DLLs and relies on availability of these dependencies in the system. For the CodingI.dll to be operationable, it is required to have a free, trial or registered version of Intel IPP library installed. In particular, the files that are sufficient to be present/redistributed are:

  • libguide40.dll, libiomp5md.dll
  • ippcore-6.0.dll
  • ippi-6.0.dll, ippj-6.0.dll, ipps-6.0.dll, ippcc-6.0.dll, ippvc-6.0.dll
  • ippipx-6.0.dll, ippjpx-6.0.dll, ippspx-6.0.dll, ippccpx-6.0.dll, ippvcpx-6.0.dll

Quick Usage Example

Given a M-JPEG compatible network camera on IP address 98.76.54.32, the graph constructed as shown below is capable to deliver video data and render it through standard Video Mixing Renderer Filter.

Assume the camera is StarDot NetCam SC series, with /jpeg.cgi HTTP request to query for JPEG image and /nph-mjpeg.cgi HTTP request to query for M-JPEG video feed.

To construct the graph in GraphEdit (GraphStudio), first it is required to manually add Alax.Info HTTP Stream Source Filter and provide HTTP URL for the request in the property page:

Then an Alax.Info JPEG HTTP Stream Parser Filter is added and connected downstream to the previously added source filter:

A this point it is possible to automatically render output pin and DirectShow intelligent connect will add the rest of required filters, Alax.Info JPEG Frame Decoder (I), Alax.Info JPEG Decoder (I) and Video Renderer.

However, in order for the graph to run in GraphEdit it is required to manually provide correct video resolution in the properties of JPEG Frame Decoder Filter and once applied reconnect all downstream connections up to video renderer in order to enforce new media type.

Running the graph will start streaming video.

Class Overview

HTTP Stream Source Filter

The filter sends one or series of HTTP requests to receive data from network location and stream received data into DirectShow environment.

Read more »

ProcessSnapshot to take a snapshot of process modules, threads, stacks and performance

While troubleshooting released application on remote production site, it is very useful to grasp a state of the process for further analysis. There are several scenarios in which the following information about process state is helpful:

  • modules (DLLs) loaded into process and their versions
  • threads and their call stacks
  • process and thread performance

An utility ProcessSnapshot takes advantage of Debugging Tools API (dbghelp.dll – note the dialog also displays DLL version in the right bottom corner) and writes this helpful information to text file and it can also take a sequence of the snapshots to compare thread performance and/or stacks and check the difference.

The generated file is in the directory of the utility application and looks like:

Snapshot
  System Time: 10/14/2008 8:46:33 PM
  Local Time: 10/14/2008 11:46:33 PM

Performance
  Creation System Time: 10/14/2008 8:46:28 PM
  Kernel Time: 0.094 s
  User Time: 0.031 s

Modules

  Module: ProcessSnapshot.exe @00400000
    Base Address: 0x00400000
    Base Size: 0x0005b000 (372736)
    Name: ProcessSnapshot.exe
    Path: D:\Projects\Utilities\ProcessSnapshot\Release\ProcessSnapshot.exe
    Product Version: 1.0.0.1
    File Version: 1.0.0.125

  Module: ntdll.dll @7c900000
    Base Address: 0x7c900000
    Base Size: 0x000af000 (716800)
    Name: ntdll.dll
    Path: C:\WINDOWS\system32\ntdll.dll
    Product Version: 5.1.2600.5512
    File Version: 5.1.2600.5512
[...]

Threads

  Thread: 3824
    Base Priority: 8
    Creation System Time: 10/14/2008 8:46:57 PM
    Kernel Time: 0.063 s
    User Time: 0.031 s
    Call Stack
      ntdll!7c90e4f4 KiFastSystemCallRet (+ 0) @7c900000
      USER32!7e4249c4 GetCursorFrameInfo (+ 460) @7e410000
      USER32!7e424a06 DialogBoxIndirectParamAorW (+ 54) @7e410000
      USER32!7e4247ea DialogBoxParamW (+ 63) @7e410000
      ProcessSnapshot!00403f45 ATL::CDialogImpl<CMainDialog,ATL::CWindow>::DoModal (+ 67) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlwin.h, 3478] (+ 28) @00400000
      ProcessSnapshot!00403b6f CProcessSnapshotModule::RunMessageLoop (+ 74) [d:\projects\utilities\processsnapshot\processsnapshot.cpp, 67] (+ 0) @00400000
      ProcessSnapshot!004049b9 ATL::CAtlExeModuleT<CProcessSnapshotModule>::Run (+ 17) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlbase.h, 3552] (+ 0) @00400000
      ProcessSnapshot!004041c3 ATL::CAtlExeModuleT<CProcessSnapshotModule>::WinMain (+ 48) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlbase.h, 3364] (+ 5) @00400000
      ProcessSnapshot!00434477 wWinMain (+ 5) [*d:\projects\utilities\processsnapshot\release\processsnapshot.inj:5, 14] (+ 0) @00400000
      ProcessSnapshot!00415058 __tmainCRTStartup (+ 274) [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c, 263] (+ 27) @00400000
      !00360033

Read more »

Time Zone Information & Monitor Information

I am sharing a couple of utilities to be able to quick check system settings. TimeZoneInformation prints in a human friendly style TIME_ZONE_INFORMATION structure as reported by Windows through GetTimeZoneInformation API.

TIME_ZONE_INFORMATION:
.Bias: -120
.StandardName: FLE Standard Time
.StandardDate: { .wYear 0, .wMonth 10, .wDay 5, .wDayOfWeek 0, .wHour 4, .wMinute 0, .wSecond 0, .wMilliseconds 0 }
.StandardBias: 0
.DaylightName: FLE Daylight Time
.DaylightDate: { .wYear 0, .wMonth 3, .wDay 5, .wDayOfWeek 0, .wHour 3, .wMinute 0, .wSecond 0, .wMilliseconds 0 }
.DaylightBias: -60
[...]

A Visual C++ .NET 2008 source code is available from SVN, release binary included.

And the second utility is MonitorInformation to print multi-monitor related information again as reported by Windows, GetSystemMetrics and EnumDisplayMonitors APIs.

System Metrics:
  SM_XVIRTUALSCREEN: 0
  SM_YVIRTUALSCREEN: 0
  SM_CXVIRTUALSCREEN: 1680
  SM_CYVIRTUALSCREEN: 1050
  SM_CMONITORS: 1
  SM_SAMEDISPLAYFORMAT: 1

Monitor 0 at (0, 0) - (1680, 1050):
  Coordinates (rcMonitor): (0, 0) - (1680, 1050)
  Work Area (rcWork): (0, 0) - (1680, 1026)
  Flags (dwFlags): 0x1
  Device Name (szDevice): \\.\DISPLAY1

A Visual C++ .NET 2008 source code is available from SVN, release binary included.

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)

Read more »