UDP message sent off wrong network interface

This is a funny one and I wonder what is exactly causing such misbehavior. An UDP broadcasting socket is being bound to IP address 192.168.0.2:

__E(m_Socket.Create(SOCK_DGRAM, IPPROTO_UDP) != INVALID_SOCKET);
static const DWORD g_nBroadcastValue = 1;
__E(m_Socket.SetOption(SOL_SOCKET, SO_BROADCAST, &g_nBroadcastValue, sizeof g_nBroadcastValue));
ZeroMemory(&m_LocalAddress, sizeof m_LocalAddress);
m_LocalAddress.sin_family = AF_INET;
m_LocalAddress.sin_port = htons(nPort); // 7365
m_LocalAddress.sin_addr.S_un.S_addr = htonl(nLocalIpAddress); // 192.168.0.2
_Z4(atlTraceGeneral, 4, _T("m_Socket %d, m_LocalAddress.sin_addr %hs\n"), m_Socket, inet_ntoa(m_LocalAddress.sin_addr));
__E(bind(m_Socket, (SOCKADDR*) &m_LocalAddress, sizeof m_LocalAddress) != SOCKET_ERROR)

Then off this socket a broadcast message is sent using sendto:

SOCKADDR_IN RemoteAddress;
ZeroMemory(&RemoteAddress, sizeof RemoteAddress);
RemoteAddress.sin_family = AF_INET;
RemoteAddress.sin_port = htons(7364);
RemoteAddress.sin_addr.S_un.S_addr = INADDR_BROADCAST;
_Z4(atlTraceGeneral, 4, _T("BroadcastSocketData.m_Socket %d\n"), BroadcastSocketData.m_Socket);
__E(sendto(BroadcastSocketData.m_Socket, NULL, 0, 0, (const SOCKADDR*) &RemoteAddress, sizeof RemoteAddress) != SOCKET_ERROR)

The problem however is that WireShark shows the message going off the wrong network interface, with IP address 192.168.56.1, while 192.68.0.2 is an IP address on a different network adapter:

C:\>ipconfig /all

Ethernet adapter Home Area Connection:

        Connection-specific DNS Suffix  . :
        Description . . . . . . . . . . . : Intel(R) 82566DC-2 Gigabit Network Connection
        Dhcp Enabled. . . . . . . . . . . : No
        IP Address. . . . . . . . . . . . : 192.168.0.2
        Subnet Mask . . . . . . . . . . . : 255.255.0.0
        Default Gateway . . . . . . . . . : 192.168.0.1
        DNS Servers . . . . . . . . . . . : 192.168.0.1
                                            4.2.2.4

Ethernet adapter VirtualBox Host-Only Network:

        Connection-specific DNS Suffix  . :
        Description . . . . . . . . . . . : VirtualBox Host-Only Ethernet Adapter
        Dhcp Enabled. . . . . . . . . . . : No
        IP Address. . . . . . . . . . . . : 192.168.56.1
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        IP Address. . . . . . . . . . . . : fe80::a00:27ff:fe00:5ce8%7
        Default Gateway . . . . . . . . . :
        DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
                                            fec0:0:0:ffff::2%1
                                            fec0:0:0:ffff::3%1

The problem appears to be in collision of networks: 192.168.0.0/16 and 192.168.56.0/24. It seems that nevertheless the socket is bound to proper NIC, where the message is expected to be sent through, Windows Sockets takes a random matching  adapter for the transmission.

A correction of the IP address from 192.168.56.1 to 192.169.56.1. immediately fixes the problem. There however has been no problems with other applications, the collision did not bring any other issues.

Some more information on the topic: Windows XP Professional, 32-bit, Service Pack 3.

See also on MSDN Forums: http://social.msdn.microsoft.com/Forums/…/

Audio Oscillogram DirectShow Filter

Unlike video, audio is difficult to troubleshoot in a way that once an issue has been noticed it was dynamic and already in past and it may be difficult to repeat, explain, forward as a screenshot etc. So it needs a visualization in order to check certain specific of the media stream.

Here we go with a Audio Oscillogram Filter, a filter which may be inserted into audio part of the graph, it insists on PCM audio (multichannel is OK, 8 or 16 bits per sample), so decoders might be required upstream and will be automatically inserted.

Once the filter is running, it shows a tool window with a visualization of the waveform coming through. Additionally, it shows a discontinuity sample (that is, a sample with AM_SAMPLE_DATADISCONTINUITY flag)  with a thick read vertical line, and a mismatch (gap or override) in neighboring sample start and stop times with a thin red line.

Alax.Info Audio Oscillogram Filter

Additionally to this, a window provides an option to pop up downstream audio renderer property sheet in order to check/debug rendering statistics, such as buffer fullness and break count (programmatically available via IAMAudioRendererStats interface). Unfortunately Microsoft does not provide a well done proxy/stub pair for this interface and the property page and there is no way to access this property page connecting to graph remotely. Using this filter the property sheet is shown directly from the hosting process and works correctly.

Audio Renderer Properties

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

File and Class Summary

Utility.dll

Utility.dll (download) hosts the following classes:

  • DirectShow Filters
    • Audio Oscillogram Filter, to visualize/debug audio data

Class Overview

Audio Oscillogram Filter

The filter visualizes PCM audio data going through in a form of oscillogram.

Remarks

The filter will create a tool window with audio visualization when put into paused/running state. The filter graph should be controlled (IMediaControl) from a GUI aware apartment so that window messages could reach internal filter’s window.

Windows Media Codec List

Windows Media Codec List utility uses IWMCodecInfo interface (see also IWMCodecInfo2, IWMCodecInfo3) lists installed Windows Media Codecs and their formats and presents the findings in a convenient way. The utility gives a quick idea what a programmer would obtain through IWMCodecInfo2/IWMCodecInfo3 interfaces and what well known format structures (WM_MEDIA_TYPE, AM_MEDIA_TYPE, WAVEFORMATEX, VIDEOINFOHEADER) correspond to particular format.

For a description of Windows Media video and audio codecs, check article Encoding Audio and Video with Windows Media Codecs.

Windows Media Codec List Screenshot

Copy button copies discovered information into clipboard in comma-separated values (CSV) format (e.g. suitable fo rMicrosoft Excel). Submit button posts the same information to this website for… possibly further aggregation.

Some quick facts immediately visualized by the utility:

  • for a video codec there is exactly one generic codec format listed
  • video codec FOUCCs are: WM Video – WMV1, WMV2, WMV3; WM Video Screen – MSS1, MSS2; WM Video Image – WMVP, WVP2; WM Video Advanced Profile – WVC1
  • for audio codecs there are complete codec formats enumerated, with names/descriptions suitable for GUI
  • audio codecs enumerate different formats in response to enumeration settings (e.g. request for VBR formats)
  • WM Audio Lossless only lists formats for single pass VBR mode
  • audio format tags (wFormatTag) are: WM Audio including Professional and Lossless – 0x0161, 0x0162, 0x0163; WM Audio Voice – 0x000A; ACELP.net – 0x0130

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

Continue reading →

Asus Eee PC, Tray Utility, Default Resolution

Among things beyond of any understanding are those presented by Asustek/Asus engineers. While hardware is more or less OK, software is often confusing. Asus Eee PC 1000HE, out of which I own one, comes with Asus Eee PC Tray Utility 5.1.1.4008.

Asus Eee PC Tray Utility 5.1.1.4008

A helper application to provide quick access to certain hardware control functions, it is OK. No, you don’t have an option to close it and even if you kill it from task manager, another Asus utility will immediately relaunch it. It is a kind monther care from Asus who are just sure that they know the right way.

The laptop las an LCD of 1024×600 pixel reoslution, and, as it usually happens, most accurate, sharp and best looking image is on the display when screen resolution is also set to 1024×600. That is, one virtual screen resolution pixel that matches exactly one physical pixel on the LCD matrix. Do I  need to be so much detailed on the obvious things, because everyone knows this as it seems? Everyone but Asus engineers who for some reasons sell laptops that automatically switch to default resolution 800×600. Even if you change resolution to desired one, the laptop will switch it back  sometimes when you logon, when you reboot, when you use fast switch user capability… Could it be more stupid than that? Perhaps it could, but this way it is already rather annoying.

After less than two months, the hotkey which switches LCD resolution sunk down while it was only used for one thing: to bring back resolution of 1024×600, which beyound of any doubt had to be default resolution without any justification to fall back to a different one for no reason. The key is definitely not going to last for too long.

Asus Eee PC 1000HE Resolution Hotkey

Out of curiosity, I started the utility on my desktop, where it immediately blinded me by turning off both of my Asus monitors and left me no other way to press reset button to reboot the box.

I thought that there might be an update for the utility on Asus Support website because this kind of thing had to be fixed with apologies and sincere promises to never happen again. I was reluctant to use Asus Update utility because it is more refined masterpiece of stupidity. However on the website, there is no utility in downloads at all. It could be a part of another downloadable package, but there was also no obvious indication that would give a hint what update is required.

So that only solution left was to anatomize the crapware and think of a workaround to at least for some time extend the life of the hotkey. The utility below, PostAsTrayCommand, will look for Asus tray icon utility to be running and will post a requested command (this way it can also be used to switch on or off wireless LAN, or the camera) to the utility.

To switch resolution to 1024×600, a command of 32797 has to be posted. The screenshot below gives an idea of other values, which might be useful:

AsTray Utility Tray Icon Menu Commands

To post a command, it needs to be started from command line “PostAsTrayCommand.exe 32797” and it makes sense to add it to Startup group to be automatically launched on logon.

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

Another third party DirectShow filter that may break your very own application

One of the DirectShow’s most important features is Intelligent Connect, which allows Filter Graph Manager to build graphs out of independent filters trying to connect them together including options to fall back to originally non-preferred alternatives and so on.

It is however important that filters are properly registered with the Filter Mapper. For the developers to do so, there are special guidelines for registering filters. Unfortunately it is not always the case that developers carefully take them into consideration, and so we have compatibility issues. In particular a faulty filter may break an application it is not intended to be used in in first place. Some examples were already mentioned: Ahead Nero NeResize Filter, FFDShow Video Decoder Filter, PICVideo MJPEG Decompressor Filter.

As we are moving on, the brilliant collection is expanding. New entry on the list:

MainConcept Color Space Converter Filter

Friendly Name: MainConcept Color Space Converter
File Name: mccsc.ax
File Version: 1.0.103.60203 (note that other versions might be hopefully free from this problem)
Merit: 0x00600000 (MERIT_NORMAL)

Symptoms: registers itself under higher merit and takes over standard Color Space Converter Filter. As such, might be used in various applications including those, where it is not supposed to appear. Does not fully implement functionality of the filter being replaced and can crash breaking expected operation of third party application.

MediaTools: How to manually configure filters to render M-JPEG video stream from an IP camera

Media Tools DirectShow Filters can be used to acquire, parse and decoder M-JPEG encoded video stream from an IP camera or a video server, however for a quick start it is necessary to properly register filters on system and create a DirectShow graph.

To register the filters, it is necessary to download DLLs from repository. While Acquisition.dll does not require special prerequisites installed, CodingI.dll is using Intel Integrated Performance Primitives (IPP) version 6.0.0 internally and requires its [at least] redistributables installed before DLLs are being registered using regsvr32.

Intel went further with new releases of IPP, which are incompatible with the version used to build CodingI.dll, so it is version 6.0.0 (in downloads on Intel website: version 6.0 build 0) has to be installed. Note that Intel DLLs from C:\Program Files\Intel\IPP\6.0.0.044\ia32\bin (version 6.0.0.062 is known to be also compatible) need to be on system search path, or copied to C:\Windows\system32 directory.

Once Intel IPP is prepared, it is required to register CodingI.dll using regsvr32. This registers filters and they are available in GraphEdit and for applications. It is important that on the way of constructing graph which renders video using standard video renderers it is required to specify correct resolution for video, or otherwise graph might fail to start with a message “The graph could not change state”, caused by video renderer failure to dynamically change to different (effective) resolution.

To create rendering graph, add Alax.Info HTTP Stream Source Filter from the filter list and provide camera URL in properties, e.g. http://cam15001.miemasu.net/nphMotionJPEG?Kind=1

Adding Alax.Info HTTP Stream Source Filter

Continue reading →

XviD video encoder and window messages from a worker thread

While encoding video, Xvid Video Encoder provides an optional status window displaying information on encoding progress.

Xvid Encoder Status Window

Since streaming typically takes place in a worker thread, with possibly no windows at all, and no message pump, the window is to be created on GUI thread and the encoder needs to synchronize progress updates with the window.

Such synchronization is a typical point where a deadlock can occur. Carelessly a window message may be sent in a blocking way so that worker thread is waiting while the message is processed on the window thread. If this sending happens at the moment of GUI thread trying to stop worker thread, a deadlock takes place. This problem often comes up when message sending takes place indirectly, e.g. being wrapped by an API call, such as SetWindowText, or as it can be seen below IsDlgButtonChecked.

In order to avoid deadlocks one should never SendMessage from a worker thread. Instead there should be a PostMessage with possibly a wait function which waits for either synchronization event (set by window) or worker thread termination request:

{
  CLock Lock(m_CriticalSection);
  m_sText = sText;
  m_SynchronizationEvent.Reset();
}
PostMessage(...);
HANDLE phObjects[] = { ThreadTerminationEvent, m_SynchronizationEvent };
const DWORD nWaitResult =  WaitForMultipleObjects(..., phObjects, ...);
if(nWaitResult == WAIT_OBJECT_0 + 1 ) // m_SynchronizationEvent
{
  CLock Lock(m_CriticalSection);
  // ...
}

Back to Xvid encoder: trying to abort encoding process, the application deadlocks. Thread checking shows worker thread state:

Xvid Video Encoder Deadlocked Thread Call Stack

That is, a described deadlock in action.

While it is already made this way letting deadlock occur, is there any workaround to avoid locking? Yes, there is. Stopping encoding, GUI thread should keep pumping messages while waiting for worker thread termination. Before closing worker thread handle, one needs to signal the thread to terminate and wait using thread handle with MsgWaitForMultipleObjects, so that messages possibly sent while terminating the thread are dispatched to target windows.