Microsoft Developer Web Service Day

MSDN Forums bug today earlier was nothing. Here is a new one with Microsoft Connect. A StackOverflow poster found a bug and created a feedback item with MS Connect:

MS Connect before Sign In

Available to anonymous, however invisible to authenticated user after sign in:

MS Connect after Sign In

The content that you requested cannot be found or you do not have permission to view it.

It should be a permission thing, I suppose.

MediaTools: Fix for Motion JPEG video

A small fix for M-JPEG video streams retrieved by HTTP Stream Source Filter:

  • Username and password contained in URL are honored for Basic HTTP authentication
  • Correctly parsed HTTP response headers with quotes, e.g.:
    Content-Type: multipart/x-mixed-replace; boundary=myboundary

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

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.

Continue reading →

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.

Continue reading →

WinHTTP escaping problem

WinHttpCrackUrl and WinHttpCreateUrl API functions are breaking URL string into components and recompose back to string. There was a mess with passwords and security issues since when putting password into URL is no more acceptable. Experienced users might remember the times when URL could embed password, e.g. ftp://john:mysecretpassword@host.com/path. Password is lo longer accepted by major applications in a typed in string and no more allowed by updated RFC 3986 “Uniform Resource Identifier (URI): Generic Syntax”:

3.2.1.  User Information

   The userinfo subcomponent may consist of a user name and, optionally,
   scheme-specific information about how to gain authorization to access
   the resource.  The user information, if present, is followed by a
   commercial at-sign ("@") that delimits it from the host.

      userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )

   Use of the format "user:password" in the userinfo field is
   deprecated.  Applications should not render as clear text any data
   after the first colon (":") character found within a userinfo
   subcomponent unless the data after the colon is the empty string
   (indicating no password).

What if we don’t have URLs typed in? But it still convenient to keep password as a part of URL? Luckily there is such thing as compatibility, so we can rely on WinHTTP subsystem to process passwords for us. The problem however is escapement. The most tricky is that it is not a bug, it is documented but is unintuitive. The cracking part would unescape all components if ICU_DECODE flag is provided. The composing part however will only escape (ICU_ESCAPE) the part to the right from port number (whether it is specified or expected to be)!

For example (see source code below):

g_ppszUrls[3] http://user:pa%40ss@site.com/path?name=value%20%2F%3A%40
.lpszScheme http
.nScheme 1
.lpszHostName site.com
.nPort 80
.lpszUserName user
.lpszPassword pa@ss
.lpszUrlPath /path
.lpszExtraInfo ?name=value /:@
pszUrl http://user:pa@ss@site.com/path?name=value /:@
pszUrl (ICU_ESCAPE) http://user:pa@ss@site.com/path?name=value%20/:@

Continue reading →