Microsoft DirectX 8.1 (C++)

Controlling the Filter Graph in Visual Basic

This section contains the following topics.

Installing the Files

Before using the DirectShow objects in your Visual Basic-based application, you must install Quartz.dll in the Windows\System directory and ensure that the appropriate entries are made in your system's registry database. Currently, the Microsoft® DirectX® Software Development Kit (SDK) Setup program automates this process. To install, start Setup.exe and choose the Runtime option. The dynamic-link library (DLL) will be copied to the correct location, and the registry will be automatically updated.

Registering Quartz.dll with Visual Basic

To verify that the files were installed successfully, open the Visual Basic application and choose the References command from the View menu. (At startup, Visual Basic examines the registry database for registered automation controls and adds their names to the list that appears in this dialog box.) To use the filter graph manager, select the ActiveMovie control type library box.

After Visual Basic registers the type information, you can use the filter graph manager and its associated interfaces in your application.

Preparing to Use the DirectShow Objects

Visual Basic initializes all objects using the FilgraphManager object, which implements the following interfaces.

Each of the interfaces is accessed by a Visual Basic programmable object defined to be of that interface type. You can define the objects as global variables in the general declarations section, as shown in the following example.

Dim g_objVideoWindow As IVideoWindow    
Dim g_objMediaControl As FilgraphManager
Dim g_objMediaPosition As IMediaPosition
Dim g_objBasicAudio  As IBasicAudio     
Dim g_objBasicVideo As IBasicVideo2      

Initialize all the programmable objects using FilgraphManager, as shown in the following example.

    Set g_objMediaControl = New FilgraphManager
    g_objMediaControl.RenderFile (g_strFileName)    ' name of input file
    ...
    Set g_objBasicAudio = g_objMediaControl
    Set g_objVideoWindow = g_objMediaControl
    Set g_objMediaEvent = g_objMediaControl
    Set g_objMediaPosition = g_objMediaControl

Obtain the other interfaces by calling methods that explicitly return the desired interface. The following table summarizes how to obtain these interfaces.

Interface Methods that return the interface pointer
IAMCollection IPinInfo.MediaTypes, IFilterInfo.Pins, FilgraphManager.FilterCollection, FilgraphManager.RegFilterCollection
IFilterInfo First FilgraphManager.FilterCollection, then IAMCollection.Item or IPinInfo.FilterInfo
IMediaTypeInfo IPinInfo.ConnectionMediaType
IPinInfo IFilterInfo.FindPin, IAMCollection.Item
IRegFilterInfo First FilgraphManager.RegFilterCollection, then IAMCollection.Item

For a sample that shows how to manipulate these filter and pin interfaces, see Constructing Filter Graphs Using Visual Basic.

Instantiating the Filter Graph

You can use the filter graph manager to render existing files of the following types.

In addition, you can use the filter graph manager to render an existing filter graph by specifying the file that contains that graph as a parameter to the FilgraphManager.RenderFile method.

Because the filters in a filter graph are dependent on the type of file being rendered, do not instantiate a filter graph until the user selects a file. The filter graph manager is instantiated when the Visual Basic keyword New is used to create the AUTOMATION object. The filter graph object is created when the RenderFile method is called, as shown in the following example.

'Instantiate a filter graph for the requested
'file format.
    
Set g_objMediaControl = New FileGraphManager
g_objMediaControl.RenderFile (g_strFileName)

Rendering Video

The FilgraphManager object supports three methods that an application can call to control the video stream: Run, Pause, and Stop. After the filter graph object is instantiated, your application can call these methods.

The following code example calls these methods in response to the user clicking a button.

Private Sub Toolbar1_ButtonClick(ByVal Button As Button)
' handle buttons on the toolbar

    ' if the objects aren't defined, avoid errors
    If g_objMediaControl Is Nothing Then
        Exit Sub
    End If
    
    If Button.Index = 1 Then 'PLAY
        'Invoke the MediaControl Run() method
        'and play the video through the predefined
        'filter graph.
    
        g_objMediaControl.Run
        g_fVideoRun = True
            
    ElseIf Button.Index = 2 Then  'PAUSE
        'Invoke the MediaControl Pause() method
        'and pause the video that is being
        'displayed through the predefined
        'filter graph.
    
        g_objMediaControl.Pause
        g_fVideoRun = False
    
    ElseIf Button.Index = 3 Then  'STOP
    
        'Invoke the MediaControl Stop() method
        'and stop the video that is being
        'displayed through the predefined
        'filter graph.
    
        g_objMediaControl.Stop
        g_fVideoRun = False
        ' reset to the beginning of the video
        g_objMediaPosition.CurrentPosition = 0
        txtElapsed.Text = "0.0"

Controlling Audio

The IBasicAudio interface supports two properties: the Volume property and the Balance property. The Volume property retrieves or sets the volume. In the sample application, this property is bound to the slider control slVolume. The Balance property retrieves or sets the stereo balance. In the sample application, this property is bound to the slider control slBalance.

Note   The volume is a linear volume scale, so only the far right side of the slider is useful.

The following example adjusts the volume by setting the Volume property.

Private Sub slVolume_Change()
    
    'Set the volume on the slider

    If Not g_objMediaControl Is Nothing Then
    'if g_objMediaControl has been assigned

       g_objBasicAudio.Volume = slVolume.Value

    End If
    
End Sub

Scaling and Translating the Video Output

The IVideoWindow interface supports the methods and properties you can use to alter the size, state, owner, palette, visibility, and so on, for the destination window. If you are not concerned with the location or appearance of the destination window, you can render output in the default window (which appears in the upper-left corner of the desktop) without calling any of these methods or properties.

You can also change the window style by removing the caption, border, and dialog box frame. To do this, set the IVideoWindow.WindowStyle property to 0x06000000. This corresponds to the logical OR operation of the values WS_DLGFRAME (0x04000000) and WS_VSCROLL (0x02000000). For a complete list of window styles and corresponding values, see the Winuser.h file in the Microsoft® Platform SDK.

To move the destination window onto the form, specify a new position by setting the IVideoWindow.Top and IVideoWindow.Left properties of g_objVideoWindow. The Top and Left properties are set to correspond to the upper-left corner of a blank control with a rectangular shape, a placeholder of sorts, that appears on the form. The ScaleMode property for the form was set to 3, which specifies units of pixels. This allows the form properties and DirectShow object properties to be used without conversion. The DirectShow object properties are also expressed in pixels. The default units for a Visual Basic form are twips.

Determine the required size of the rectangle by retrieving the source video width and height. These values correspond to the IBasicVideo2.VideoWidth and IBasicVideo2.VideoHeight properties.

In addition to setting the Top and Left properties, it is necessary to identify the form of the application as the new parent window by passing the window handle of the form, hWnd, to the object's IVideoWindow.Owner property. If the handle is not passed, the destination window will appear relative to the desktop and not the form.

The following example shows these tasks.

    Set g_objVideoWindow = g_objMediaControl
    g_objVideoWindow.WindowStyle = CLng(&H6000000)   ' WS_DLGFRAME | WS_VSCROLL
    g_objVideoWindow.Left = CLng(Shape1.Left)   ' shape is a placeholder on the form
    g_objVideoWindow.Top = CLng(Shape1.Top)
    Shape1.Width = g_objVideoWindow.Width    ' resize the shape given the input video
    Shape1.Height = g_objVideoWindow.Height
    g_objVideoWindow.Owner = frmMain.hWnd    ' set the form as the parent

The following example shows how to initialize the ScaleMode property.

' ...
    frmMain.ScaleMode = 3    ' pixels
' ...

Avoid attempting to scale the destination window by setting the IVideoWindow.Width and IVideoWindow.Height properties for the IVideoWindow object, because performance suffers considerably.

Tracking Status

The IMediaPosition object exposes a number of properties that you can use to retrieve or set the current position, stop point, duration, and rate. The following code examples shows how to do this.

Set g_objMediaPosition = g_objMediaControl
g_dblRunLength = g_objMediaPosition.Duration
txtDuration.Text = CStr(g_dblRunLength)   ' display the duration
g_dblStartPosition = 0.0
txtStart.Text = CDbl(g_dblStartPosition)   ' display the start time
g_dblRate = g_objMediaPosition.Rate
txtRate.Text = CStr(g_dblRate)

Getting and Setting the Start Position

Use the IMediaPosition.CurrentPosition property to let the user adjust the point at which the video begins rendering. The following code example changes the current position in response to the user pressing a key.

 Private Sub txtStart_KeyDown(KeyCode As Integer, Shift As Integer)
' handle user input to change the start position
If KeyCode = vbKeyReturn Then
    If g_objMediaPosition Is Nothing Then
        Exit Sub
    ElseIf CDbl(txtStart.Text) > g_dblRunLength Then
        MsgBox "Specified position invalid: re-enter new position."
    ElseIf CDbl(txtStart.Text) < 0 Then
        MsgBox "Specified position invalid: re-enter new position."
    ElseIf CDbl(txtStart.Text) <> "" Then
        g_dblStartPosition = CDbl(txtStart.Text)
        g_objMediaPosition.CurrentPosition = g_dblStartPosition
    End If
End If
End Sub

Getting and Setting the Rate

Use the IMediaPosition.Rate property to let the user adjust the rate at which the video is rendered. This rate is a ratio with respect to typical playback speed. For example, a rate of 0.5 causes the video to be rendered at one-half its typical speed, and a rate of 2.0 causes the video to be rendered at twice its typical speed.

Unlike the CurrentPosition property, which can be set while the video is being rendered, the Rate property must be set prior to rendering.

Note  The sound track can be disabled for some videos when the rate is less than 1.0.

The following code example changes the rate in response to the user pressing a key.

Private Sub txtRate_KeyDown(KeyCode As Integer, Shift As Integer)
' DirectShow VB sample
' handle user updates to the Rate value
If KeyCode = vbKeyReturn Then
    If g_objMediaPosition Is Nothing Then
        Exit Sub
    ElseIf CDbl(txtRate.Text) < 0# Then
        MsgBox "Negative values invalid: re-enter value between 0 and 2.0"
    ElseIf CStr(txtRate.Text) <> "" Then
        g_dblRate = CDbl(txtRate.Text)
        g_objMediaPosition.Rate = g_dblRate
    End If
End If
End Sub

Cleaning Up

Each time your application uses the Visual Basic Set statement to create an instance of a new DirectShow object, it must include a corresponding Set statement to remove that object (and its corresponding resources) from memory prior to shutdown, as shown in the following code.

Set g_objBasicAudio = Nothing