VCDProperties

VCD Properties provide a generic, hardware independent and extend-able way to control the settings of a video capture device.

Introduction

DirectShow defines two sub sets of properties for video capture devices: VideoProcAmp and CameraControl. There is only one scalar data type ( long ) defined to represent a property value. Although this concept is an abstraction that allows you to write device independent code, there are two problems:

Basic concepts

The basic idea behind VCD properties is a structured organization. In order to understand this, we will have to consider the elements of which a property consists. First of all, a property has a name like "exposure". In addition, it contains elements such as the value and an automation state. Therefore, we may say that a property is an object that contains a name and a set of elements. This object is called IVCDPropertyItem. The elements are called IVCDPropertyElement and contain a set of interfaces that allow the element to be manipulated. The interfaces provide different access methods to the property. The interface IVCDRangeProperty, for example, provides access to the property that is equivalent to the property access of DirectShow. The IVCDAbsoluteValueProperty allows access to the property in terms of a physical dimension with high accuracy. After this consideration, the structure of VCD property is clear: The property item contains property elements, which contain one or more interfaces. In order to be able to manipulate a property, you have to retrieve the appropriate item, element and interface. Please open the application "VCD Property Inspector" from the IC Imaging Control start menu in order to get an idea how the VCD properties are organized for your device.

Finding Property objects

First of all, we need a way to specify a property item, element or interface in order to be able to find it. There are GUIDs (Global Unique IDentifiers) for every property item, element and interface defined. They are listed under constants. These GUIDs should be used in the VCD property find methods. All property items that are supported by the currently active video capture device are contained in the IVCDPropertyItems collection. This collection provides methods for retrieving a property item, element or interface. They are called IVCDPropertyItems::findItem, IVCDPropertyItems::findElement and IVCDPropertyItems::findInterface. The object to be retrieved has to specified by a single GUID for findItem and a combination of GUIDs for the other two. In the following, we will call the GUID or combination of GUIDs that specify a property object, a GUID path.

Finding Interfaces

As described earlier, an interface is the object that actually allows data to be read from and to be written a property. As described in the previous section, we will use the GUID path for the desired interface as a parameter to IVCDPropertyItems::findInterface to retrieve the interface. Before we do this, we will have to decide which interface we want to use. In case of an auto item (IVCDPropertyElement, GUID: VCDElement_Auto) we will try to retrieve a switch interface (IVCDSwitchProperty, GUID: IID_IVCDSwitchProperty) because a switch is the expected functionality of the auto item. In case of the value item - the actual value of the property - we have to search for the best interface. The best or most advanced interface is the absolute value interface (refer to IVCDAbsoluteValueProperty for details).

As described at the beginning, the absolute values interface provides high accuracy and a meaning of the value it represents. The following code retrieves the absolute value interface for the value element of the exposure property item:

// Get supported property items.
tIVCDPropertyItemsPtr pItems = m_Grabber.getAvailableVCDProperties();
// Retrieve the absolute value interface for exposure.
tIVCDAbsoluteValuePropertyPtr pAbsVal = 0;
if( pItems->findInterfacePtr( VCDID_Exposure, VCDElement_Value, pAbsVal ) != 0 )
{
    // Interface successfully retrieved.
}
else
{
    // There is no absolute value interface for the value element
    // of the exposure property item.
}

If the absolute values interface does not exist for this property, we try to retrieve the map strings interface (IVCDMapStringsProperty, GUID: IID_IVCDMapStringsProperty). It is not as accurate as the absolute values interface, but it provides a meaning for the value. The following code retrieves the map strings interface for the value element of the exposure property item:

// Get supported property items.
tIVCDPropertyItemsPtr pItems = m_Grabber.getAvailableVCDProperties();
// Retrieve the map strings interface for exposure.
tIVCDMapStringsPropertyPtr pMapStrings = 0;
if( pItems->findInterfacePtr( VCDID_Exposure, VCDElement_Value, pMapStrings ) != 0 )
{
    // Interface successfully retrieved.
}
else
{
    // There is no map strings interface for the value element
    // of the exposure property item.
}

If the map strings interface does not exist for this property, we try to retrieve the range interface (IVCDRangeProperty, GUID: IID_IVCDRangeProperty). This interface does not provide a meaning for the value but it may provide more values than the map strings interface. The following code retrieves the range interface for the value element of the exposure property item:

// Get supported property items.
tIVCDPropertyItemsPtr pItems = m_Grabber.getAvailableVCDProperties();
// Retrieve the range interface for exposure.
tIVCDRangePropertyPtr pRange = 0;
if( pItems->findInterfacePtr( VCDID_Exposure, VCDElement_Value, pRange ) != 0 )
{
    // Interface successfully retrieved.
}
else
{
    // There is no range interface for the value element
    // of the exposure property item.
}

Using Interfaces

In the previous section, we learned how to get an interface. Now we will discuss how use them in order to get information about the property and manipulate the value. All interfaces provide the following properties:

The absolute values and the range interface provide properties to get information about the minimum, maximum value that can be assigned to the actual value. The absolute values interface provides additional information about the physical dimension of the value. The map strings interface provides a collection of strings which build the set of possible values the may be assigned to the actual value.

If the absolute values interface could be retrieved the code for accessing the interface looks as follows:

// AbsValItf is a valid absolute value interface for exposure.
if( pAbsVal->getAvailable() )
{
    // Set the current value to the average.
    pAbsVal->setValue( ( pAbsVal->getRangeMin() + pAbsVal->getRangeMax() ) / 2 );
}

If the map strings interface could be retrieved the code for accessing the interface looks as follows:

// pMapStrings is a valid map strings interface for exposure.
if( pMapStrings->getAvailable() )
{
    // Set the current value to the average.
    pMapStrings->setValue( ( pMapStrings->getRangeMin() + pMapStrings->getRangeMax() ) / 2 );
}

If only the range interface could be retrieved the code for accessing the interface looks as follows:

// pRange is a valid range interface for exposure.
if( pRange->getAvailable() )
{
    // Set the current value to the average.
    pRange->setValue( ( pRange->getRangeMin() + pRange->getRangeMax() ) / 2 );
}

Serialization of property values

The IVCDPropertyItems collection provides a method called IVCDPropertyItems::save that serialize the current state of all VCD properties of the currently selected device into a string. The property values are stored in XML format. Therefore, it is easy to store the string in the registry or a file for later restore operations. Please note that the XML representation is not documented and will change without notice. The method for restoring all property values is called IVCDPropertyItems::load.

<< Technical Articles