View Full Version : Direct access to Firewire Driver Interface?

January 23, 2009, 22:11:42
I'm trying to incorporate an Imaging Source Firewire camera (DFK 21BF04-Z2) in my existing C# CLR /C++ COM application. I'm getting video, but it's black and white. I'd like to set the parameters on the driver directly to switch it to color output. But, because I need to use my legacy video renderer, I believe that I cannot use the control itself. I was hoping to access the COM object directly when I insert the DShow video capture filter into the graph. I have done this before using C# interop, where I wrap the COM interface, but I can do this directly in C++/COM as well. I'd really appreciate any help.


Stefan Geissler
January 26, 2009, 08:13:53

You are right, you must set the video format using some more or less complicated DirectShow code.

Here is some C++ code, that sets a "BY8" video format. The same should be useable for setting "UYVY" too:

HRESULT findMediaType( IAMStreamConfig* pConfig, GUID subtypeToFind, AM_MEDIA_TYPE** pMediaType )

if( pConfig != 0 ) // does have a IAMStreamConfig interface
// this is needed, cause we want the interface to expose all media types it supports
// and not only the last one set.
pConfig->SetFormat( 0 );

int caps, confstr_size;

hr = pConfig->GetNumberOfCapabilities( &caps, &confstr_size );
if( FAILED( hr ) ) return hr;

std::auto_ptr<BYTE> pByte( new BYTE[confstr_size] );

for( int i = 0; i < caps; ++i )
hr = pConfig->GetStreamCaps( i, &pMT, pByte.get() );

if( pMT->subtype == subtypeToFind )
*pMediaType = pMT;
return S_OK;

::DeleteMediaType( pMT );
pMT = 0; // just to be on the safe side

return E_FAIL;

// Set the "BY8" video format.
IPin* pOutPin = 0;
if( SUCCEEDED( findPin( filtertoquery, pOutPin, PINDIR_OUTPUT, 0 ) ) && pOutPin != 0 )
IAMStreamConfig* pStrmConfig = 0;
pOutPin->QueryInterface( &pStrmConfig );

AM_MEDIA_TYPE* pmt = 0;

hr = findMediaType( pStrmConfig, subTypeToSet, &pmt );
if( SUCCEEDED( hr ) )
pStrmConfig->SetFormat( pmt );
::DeleteMediaType( pmt );

"filtertoquery" is the video capture filter.

Please understand, that I can not provide DirectShow programming support.

May be http://www.codeproject.com is a helpful source for your problem.

January 26, 2009, 15:05:07
Thanks - I had forgotten that your driver supports IAMStreamConfig!! Your example was excellent.

To get this to work in DirectShowNet/C#, I had to do the following:

Insert a definition for BY8 into the Uuids.cs file:
/// <summary> MEDIASUBTYPE_BY8 </summary>
public static readonly Guid BY8 = new Guid(0x20385942, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

Use the following code, stripped down from the example given:

IPin capture_pin = DsFindPin.ByDirection((IBaseFilter)sourceFilter, PinDirection.Output, 0);

if (capture_pin != null)
IAMStreamConfig stream_config = (IAMStreamConfig)capture_pin;
if (stream_config != null)
int num_caps = 0;
int size = 0;
int hr1 = stream_config.GetNumberOfCapabilities(out num_caps, out size);

IntPtr scc = Marshal.AllocCoTaskMem(num_caps * size);
for (int i = 0; i < num_caps; i++)
AMMediaType mt;

hr1 = stream_config.GetStreamCaps(i, out mt, scc);

if (mt.subType == MediaSubType.BY8)
hr1 = stream_config.SetFormat(mt);