Archive for the 'Source' Category

Published by Roman on 13 May 2010

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 »

Published by Roman on 24 Dec 2009

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.

Published by Roman on 09 Oct 2009

How to use windowless Video Mixing Renderer Filter to show video fullscreen

The question is being asked from time to time. Everyone knows what is full screen video. Video renderers implement full screen capability since long ago through their IVideoWindow::put_FullScreenMode property, and even Filter Graph Manager exposes its own IVideoWindow interface to forward calls to filter’s implementation of IVideoWindow interface.

However, for Video Mixing Renderers, version 7 and 9, the preferred and recommended mode is windowless, where no IVideoWindow interface is available.

Note The IVMRWindowlessControl or IVMRWindowlessControl9 interface is now preferred over IVideoWindow. For more information, see Using Windowless Mode.

So in order to implement full screen mode it takes the application to attach Video Mixing Renderer filter to a private frameless window, to its entire client area and expand the window to entire monitor area.

The sample project FullScreenWindowlessVmrSample01 is illustrating this technique.

FullScreenWindowlessVmrSample01 Main Dialog

Continue Reading »

Published by Roman on 21 Sep 2009

How to overlay a bitmap on top of video with Video Mixing Renderer (VMR-9)

A 100-lines code snippet which illustrates how a bitmap is overlaid over displayed video with Video Mixing Renderer 9 Filter using IVMRMixerBitmap9 interface. A video clip is played (default is Windows clock.avi, but you can replace it with your longer one to see overlay is really in a loop).

http://code.assembla.com/…/VmrMixerBitmapSample01/…

VMR9AlphaBitmap AlphaBitmap;
ZeroMemory(&AlphaBitmap, sizeof AlphaBitmap);
AlphaBitmap.dwFlags = VMR9AlphaBitmap_hDC;
AlphaBitmap.hdc = Dc;
AlphaBitmap.rSrc = CRect(0, 0, 32, 32);
AlphaBitmap.rDest.left = (FLOAT) 0.75;
AlphaBitmap.rDest.top = (FLOAT) 0.75;
AlphaBitmap.rDest.right = (FLOAT) 0.95;
AlphaBitmap.rDest.bottom = (FLOAT) 0.95;
AlphaBitmap.fAlpha = 0.75;
const HRESULT nSetAlphaBitmapResult = pVmrMixerBitmap->SetAlphaBitmap(&AlphaBitmap);
ATLENSURE_SUCCEEDED(nSetAlphaBitmapResult);

With a low FPS clip like clock.avi it is clear that the overlaid image is only updated with the next “main” video frame.

IVMRMixerBitmap9 Usage Sample

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

Published by Roman on 08 Aug 2009

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.

Published by Roman on 22 Jun 2009

RegSetKeySecurity, CRegKey::SetKeySecurity and CSecurityDesc

One thing is worth special mentioning in connection with previous post on DirectShow Filter Graph Spy on Microsoft Vista system: ATL’s CSecurityDesc class caused to waste some time.

CRegKey Key;
ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.Open(HKEY_CLASSES_ROOT, pszKeyName, READ_CONTROL | WRITE_OWNER)));
CSecurityDesc AdministratorsOwnerSecurityDescriptor;
AdministratorsOwnerSecurityDescriptor.SetOwner(Sids::Admins());
ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.SetKeySecurity(OWNER_SECURITY_INFORMATION, &AdministratorsOwnerSecurityDescriptor)));

The code compiles fine, but on runtime it gives error 87 (ERROR_INVALID_PARAMETER, E_INVALIDARG) in the last line, returned from RegSetKeySecurity API call. My first guess was that ATL’s CSecurityDesc class for some reason prepared wrong descriptor which resulted in rejecting it as an argument. From the first glance it looks (not sure) that this class deals, to some extent, with structures itself rather than using API functions, so it could be that it results in something looking differently from expected by API calls.

Still the problem is in class itself and its cast from CSecurityDesc& to required SECURITY_DESCRIPTOR* type. The class only implements operator to automatically cast to const SECURITY_DESCRIPTOR* type, so the following line would not be passed by compiler:

Key.SetKeySecurity(OWNER_SECURITY_INFORMATION, AdministratorsOwnerSecurityDescriptor)

However &AdministratorsOwnerSecurityDescriptor is another level of indirection and hence SECURITY_DESCRIPTOR** type, which is passed by compiler, but results in indeed invalid argument.

So in order to correctly convert CSecurityDesc& to SECURITY_DESCRIPTOR* it can be done this way:

CRegKey Key;
ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.Open(HKEY_CLASSES_ROOT, pszKeyName, READ_CONTROL | WRITE_OWNER)));
CSecurityDesc AdministratorsOwnerSecurityDescriptor;
AdministratorsOwnerSecurityDescriptor.SetOwner(Sids::Admins());
ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.SetKeySecurity(OWNER_SECURITY_INFORMATION, const_cast<SECURITY_DESCRIPTOR*>((const SECURITY_DESCRIPTOR*) AdministratorsOwnerSecurityDescriptor))));

Published by Roman on 01 Apr 2009

YV12, Extended Video Renderer Strides, Private DMO and more

Recently it was the time to sort out an issue with a video DMO, which outputs YV12 video and in the same time is capable of supporting extended video strides in order to efficiently make a direct connection to Video Mixing Renderer Filters.

From past experience, I already knew that some bugs are definitely involved but their effect was yet unexplored. For a testbed application, I took good old FrameRateSample02 application, which generates multiple video feeds and routes it to video renderers:

FrameRateSample02 Application with New Choices

With new source video choices the application is capable of constructing filter graphs that use a private DMO (that is hosted inside the executable) wrapped with DMO Wrapper Filter, with a graph topology shown below:

Filter Graph with a Private DMO

Continue Reading »

Next »