Tag Archives: Source

GPS Location/Coordinate Converter: Fractional Seconds, More Shortcuts

This adds a small update to the recently published GPS Location/Coordinate Converter utility:

  • Seconds in Degrees, Minutes & Seconds notation are shown and are accepted as floating point numbers
  • More shortcuts to popular online map services (note that only Google Maps and Yandex Maps are still accepted as input via clipboard):
    • Bing Maps
    • Yahoo Maps
    • Open Street Map
    • WikiMapia

The latter makes the tool an easy to use converted between the services for a GPS POI.

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

Sample: Simultaneous Audio Playback via Waveform Audio (waveOut) API

The minimalistic sample demonstrates support of [deprecated] Waveform Audio API for multiple playback streams.

Depending on command line parameters, the application starts threads to open audio hardware using separate waveOutOpen call and stream one or more generated sine waves:

  • 1,000 Hz sine wave as 22,050 Hz, Mono, 16-bit PCM (command line parameter “a”)
  • 5,000 Hz sine wave as 32,000 Hz, Mono, 16-bit PCM (command line parameter “b”)
  • 15,000 Hz sine wave as 44,100 Hz, Mono, 16-bit PCM (command line parameter “c”)
Check(waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormatEx, NULL, NULL, CALLBACK_NULL));
ATLASSERT(hWaveOut);
WAVEHDR* pWaveHeader;
HGLOBAL hWaveHeader = (WAVEHDR*) GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof *pWaveHeader + WaveFormatEx.nAvgBytesPerSec * 10);
pWaveHeader = (WAVEHDR*) GlobalLock(hWaveHeader);
ATLENSURE_THROW(pWaveHeader, E_OUTOFMEMORY);
pWaveHeader->lpData = (LPSTR) (BYTE*) (pWaveHeader + 1);
pWaveHeader->dwBufferLength = WaveFormatEx.nAvgBytesPerSec * 10;
//pWaveHeader->dwUser = 
pWaveHeader->dwFlags = 0;
pWaveHeader->dwLoops = 0;
#pragma region Generate Actual Data
{
    SHORT* pnData = (SHORT*) pWaveHeader->lpData;
    SIZE_T nDataCount = pWaveHeader->dwBufferLength / sizeof *pnData;
    for(SIZE_T nIndex = 0; nIndex < nDataCount; nIndex++)
    pnData[nIndex] = (SHORT) (32000 * sin(1.0 * nIndex / WaveFormatEx.nSamplesPerSec * nFrequency * 2 * M_PI));
}
#pragma endregion 
Check(waveOutPrepareHeader(hWaveOut, pWaveHeader, sizeof *pWaveHeader));
Check(waveOutWrite(hWaveOut, pWaveHeader, sizeof *pWaveHeader));
GlobalUnlock(hWaveHeader);

The operating system is supposed to mix the waves, which can be easily perceived taking place. It is possible to run the application with multiple waveforms within a process, e.g. “abc” command line parameter, and/or start multiple instances of the application.

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

A tricky EVR bug was caught up: input pin may falsely report disconnected state

Crime

An application which builds a DirectShow graph unexpectedly started failing with VFW_E_NOT_CONNECTED (0×80040209) error code.

Scene

The problem takes place during DirectShow graph building, yet in stopped state. Specific call which appeared to be giving out the error in first place appears to be EVR input pin’s IPin::ConnectionMediaType, and the problem is also specific to Enhanced video Renderer (Windows 7, but not necessarily only this version).

Investigation

The problem does not appear to be persistent. On the contrary, it is taking place for just a few milliseconds after pin connection. After the problem is gone, it does not seem to ever come up again unless the filter graph is built again from the beginning.

EVR pin connection is always reporting success, so the following error code stating VFW_E_NOT_CONNECTED “The operation cannot be performed because the pins are not connected.” goes against documented behavior, and is thus a bug.

Depending on time between pin connection and media type polling, the call can reach EVR:

  • before it starts showing the problem – stage A
  • at the time the call fails – stage B
  • after the failure time interval, when the call is successful from then on – stage C

Thus, the problem is limited to specific use cases:

  • the application should care about media type on EVR input
  • unexpected failure takes place when the call reaches in stage B
  • also found: the clipping window for the EVR has to belong to a non-primary monitor

If an application keep polling for media type in a loop, the result may be about the following:

UINT nStageA = 0, nStageB = 0, nStageC = 0;
// [...]
for(; ; )
{
    AM_MEDIA_TYPE MediaType;
    ZeroMemory(&MediaType, sizeof MediaType);
    const HRESULT nConnectionMediaTypeResult = pInputPin->ConnectionMediaType(&MediaType);
    if(SUCCEEDED(nConnectionMediaTypeResult))
    {
        if(nStageB)
        {
            nStageC++;
            break;
        } else
            nStageA++;
    } else
    {
        ATLASSERT(nConnectionMediaTypeResult == VFW_E_NOT_CONNECTED);
        nStageB++;
    }
    CoTaskMemFree(MediaType.pbFormat);
}
// [...]
CString sMessage;
sMessage.Format(_T("Bingo!\r\n\r\n") _T("nStageA %d, nStageB %d - 0x%08x, nStageC %d\n"), nStageA, nStageB, nResult, nStageC);
AtlMessageBox(m_hWnd, (LPCTSTR) sMessage, _T("Result"), MB_ICONERROR);

Workaround

An obvious straightforward workaround is to follow EVR connection with a wait for Stage B to pass, or timeout – whichever takes place first.

Also, vote for the bug on Microsoft Connect.

More Details

Video renderer filter are notorious for re-agreeing media type and being fretful as for memory allocators and media types (for a good reason though!). So it makes sense to suggest that the problem takes place when the filter is doing something related, such as it starts background activity immediately after connection in order to discover upstream peer capabilities.

In order to possibly get details on this, it is possible to raise an exception as soon as Stage B is detected and take a look at thread states using a debugger. Indeed, on of the background threads is engaged in EVR reconnection activity:

Yes it does the reconnection, but nevertheless it is expected to do the things undercover and transparently, it still allows a failure on the outer API.

     evr.dll!GetSourceRectFromMediaType() + 0x37 bytes    
     evr.dll!CEVRInputPin::CheckMediaType() + 0x81 bytes    
     evr.dll!CBasePin::ReceiveConnection() + 0x61 bytes    
     evr.dll!CEVRInputPin::ReceiveConnection() + 0x1fc2d bytes    
     quartz.dll!CBasePin::AttemptConnection() - 0x21 bytes    
     quartz.dll!CBasePin::TryMediaTypes() + 0x60 bytes    
     quartz.dll!CBasePin::AgreeMediaType() + 0x54 bytes    
     quartz.dll!CBasePin::Connect() + 0x46 bytes    
     quartz.dll!CFilterGraph::ConnectDirectInternal() + 0x83 bytes    
     quartz.dll!CFilterGraph::ConnectRecursively() + 0x2c bytes    
     quartz.dll!CFilterGraph::ConnectInternal() + 0xde bytes    
     quartz.dll!CFilterGraph::Connect() + 0x17 bytes    
     quartz.dll!CFGControl::WorkerDisplayChanged() + 0xf1 bytes    
     quartz.dll!CFGControl::CGraphWindow::OnReceiveMessage() + 0x2e2a bytes    
>    quartz.dll!WndProc() + 0x3e bytes    
     user32.dll!_InternalCallWinProc@20() + 0x23 bytes    
     user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 bytes    
     user32.dll!_DispatchMessageWorker@8() + 0xed bytes    
     user32.dll!_DispatchMessageW@4() + 0xf bytes    
     quartz.dll!ObjectThread() + 0x65 bytes

A test Visual C++ .NET 2010 application is available from SVN. The code requires a media file, and refers to 352×288 I420.avi, which is included into ZIP file attached to MS Connect Feedback.

IP Video Source: Pure JPEG URLs and Software Version

This does not update the software with new features, but there are a few simple things worth mentioning explicitly.

The first is that virtual DirectShow camera device can be set up with both M-JPEG and JPEG URLs. That is, IP cameras which do not implement M-JPEG, or implement it in a buggy way (there is a *huge* deal of such out there) can still be set up to send video as individual video frames/images as long as they implement JPEG snapshots. This is taking place often at a lower frame rate, but still works.

The driver will automatically detect type of URL (by response from the device) and will choose best access method for the given URL.

Second is that if you are looking for IP Video Source software version, such as to check against available updates, it is here on the UI (right click the caption):

IP Video Source: 64-bit version, resolution flexibility, Adobe FMLE

The IP Video Source update provides several improvements to the driver:

  • copy/paste feature to backup, restore, or synchronize installed devices between 32-bit and 64-bit versions
  • 64-bit version and .MSI
  • dynamic video resizing (via Video Resizer DSP)
  • Adobe FMLE compatibility

Updates in greater detail follow.

Device Copy/Paste Feature

The video device management window is providing Copy and Paste buttons, which let user transfer device information, including name and settings, through clipboard for various purposes:

  • save data in order to be able to restore devices later
  • restore devices from saved list, or re-create from a list saved on another machine
  • duplicate a device
  • synchronize devices between 32-bit and 64-bit versions

The device data is a text, one line per device, lines in comma-separated values (CSV) format.

Read more »

DirectShow Video Source Filter for JPEG and M-JPEG IP Cameras

This implements a DirectShow driver/wrapper over a HTTP based JPEG/M-JPEG streamed video, widely available with IP cameras. Once installed, it provides a Start Menu shortcut to manage video capture devices, where a user can add/remove devices. The devices are automatically registered with DriectShow and are available to applications.

The compatibility list includes:

  • Windows SDK AmCap Sample (reference)
  • VideoLan VLC
  • Skype (see below)
  • Google Talk Video Chat
  • Luxriot (as rather an example as Luxriot has its own generic JPEG/M-JPEG device driver, however this still demonstrates compatibility and interoperability of applications)
  • GraphEdit, GraphStudio and similar tools

Read more »

Utility Clearance: Enumerate VCM Codecs

EnumerateVcmCodecs uses ICOpen API to enuerate available codecs and prints out information obtained from enumeration. 32-bit and 64-bit versions respectively enumerate codecs available for the platform (lists may vary because the codecs are actually provided by different DLLs, built for respective platform).

szName
  fccType: 0x63646976 (vidc), fccHandler 0x64697663 (cvid)
  dwFlags 0
  dwVersion 0x0, dwVersionICM 0x104
  szDescription ""
  szDriver "iccvid.dll"
szName
  fccType: 0x63646976 (vidc), fccHandler 0x30323469 (i420)
  dwFlags 0
  dwVersion 0x0, dwVersionICM 0x104
  szDescription ""
  szDriver "msh263.drv"
...

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

See also: