The Microsoft DirectShow application programming interface (API) is a media-streaming architecture for Microsoft Windows. Using DirectShow, your applications can perform high-quality video and audio playback or capture.
The following example shows how to enumerate filters.
' ########################################################################################
' DirectShow example.
' Enumerating filters.
' ########################################################################################
' CSED_PBCC - Use the PBCC compiler
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "dshow.inc"
#INCLUDE ONCE "ole2utils.inc" ' For IUnknown_Release
' ========================================================================================
' The Filter Graph Manager supports the IFilterGraph.EnumFilters method, which enumerates
' all the filters in the filter graph. It returns a pointer to the IEnumFilters interface.
' The IEnumFilters.Next method retrieves IBaseFilter interface pointers.
' ========================================================================================
FUNCTION EnumFilters (BYVAL pGraph AS IGraphBuilder) AS LONG
LOCAL hr AS LONG ' HRESULT
LOCAL pEnum AS IEnumFilters ' IEnumFilters interface
LOCAL pFilter AS IBaseFilter ' IBaseFilter interface
LOCAL cFetched AS DWORD ' Number of filters fetched
LOCAL FilterInfo AS FILTER_INFO ' FILTER_INFO structure
hr = pGraph.EnumFilters(pEnum)
IF hr <> %S_OK THEN
FUNCTION = hr
EXIT FUNCTION
END IF
DO
hr = pEnum.Next(1, pFilter, cFetched)
IF hr <> %S_OK OR cFetched = 0 THEN EXIT DO
RESET FilterInfo
hr = pFilter.QueryFilterInfo(FilterInfo)
IF hr <> %S_OK THEN
STDOUT "Could not get the filter info"
ELSE
STDOUT FilterInfo.achName
' The FILTER_INFO structure holds a pointer to the Filter Graph
' Manager, with a reference count that must be released.
IF FilterInfo.pGraph <> %NULL THEN IUnknown_Release FilterInfo.pGraph
END IF
' Release the filter
pFilter = NOTHING
LOOP
' Release the collection
pEnum = NOTHING
FUNCTION = %S_OK
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pGraph AS IGraphBuilder
LOCAL wszFile AS WSTRINGZ * %MAX_PATH
pGraph = NEWCOM CLSID $CLSID_FilterGraph
wszFile = EXE.Path$ & "useglue.wmv"
pGraph.RenderFile(wszFile)
EnumFilters(pGraph)
pGraph = NOTHING
WAITKEY$
END FUNCTION
' ========================================================================================
The following example demonstrates how to write a simple video player.
' ========================================================================================
' DirectShow example.
' Allows to select a video clip and plays it.
' Based on an example by Vladimir Shulakov posted in the PowerBASIC forums:
' http://www.powerbasic.com/support/pbforums/showthread.php?t=23966
' ========================================================================================
' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "commdlg.inc"
#INCLUDE ONCE "dshow.inc"
' Menu identifiers
%ID_FILE_OPENCLIP = 40001
%ID_FILE_EXIT = 40002
' Custom message
%WM_GRAPHNOTIFY = %WM_USER + 13
GLOBAL bIsPlaying AS LONG
' Interface pointers
GLOBAL pIGraphBuilder AS IGraphBuilder
GLOBAL pIMediaControl AS IMediaControl
GLOBAL pIMediaEventEx AS IMediaEventEx
GLOBAL pIVideoWindow AS IVideoWindow
' ========================================================================================
' Play the movie inside the window.
' ========================================================================================
SUB PlayMovieInWindow (BYVAL hwnd AS DWORD, BYREF wszFileName AS WSTRINGZ)
LOCAL hr AS LONG
' If there is a clip loaded, stop it
IF ISOBJECT(pIMediaControl) THEN
pIMediaControl.Stop
pIMediaControl = NOTHING
pIVideoWindow = NOTHING
pIMediaEventEx = NOTHING
pIGraphBuilder = NOTHING
END IF
' Create an instance of the IGraphBuilder object
pIGraphBuilder = NEWCOM CLSID $CLSID_FilterGraph
IF hr <> %S_OK OR ISNOTHING(pIGraphBuilder) THEN EXIT SUB
' Retrieve interafce pointers
pIMediaControl = pIGraphBuilder
IF ISNOTHING(pIMediaControl) THEN EXIT SUB
pIMediaEventEx = pIGraphBuilder
IF ISNOTHING(pIMediaEventEx) THEN EXIT SUB
pIVideoWindow = pIGraphBuilder
IF ISNOTHING(pIVideoWindow) THEN EXIT SUB
' Render the file
hr = pIGraphBuilder.RenderFile(wszFileName)
IF hr <> %S_OK THEN EXIT SUB
' Set the window owner and style
pIVideoWindow.Visible = %OAFALSE
pIVideoWindow.Owner = hwnd
pIVideoWindow.WindowStyle = %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
' Have the graph signal event via window callbacks for performance
pIMediaEventEx.SetNotifyWindow(hwnd, %WM_GRAPHNOTIFY, 0)
' Set the window position
LOCAL rc AS RECT
GetClientRect hwnd, rc
pIVideoWindow.SetWindowPosition(rc.Left, rc.Top, rc.Right, rc.Bottom)
' Make the window visible
pIVideoWindow.Visible = %OATRUE
' Run the graph
pIMediaControl.Run
bIsPlaying = %TRUE
END SUB
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI aware
' SetProcessDPIAware
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
pWindow.CreateWindow(%NULL, "DirectShow Demo", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Set the client size
pWindow.SetClientSize 500, 320
' // Center the window
pWindow.CenterWindow
LOCAL hMenu AS DWORD
LOCAL hMenuFile AS DWORD
hMenu = CreateMenu
hMenuFile = CreatePopUpMenu
AppendMenu hMenu, %MF_POPUP OR %MF_ENABLED, hMenuFile, "&File"
AppendMenu hMenuFile, %MF_ENABLED, %ID_FILE_OPENCLIP, "&Open clip..."
AppendMenu hMenuFile, %MF_ENABLED, %ID_FILE_EXIT, "E&xit"
SetMenu pWindow.hwnd, hMenu
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL rc AS RECT
LOCAL strFilter AS WSTRING
LOCAL strDefExt AS WSTRING
LOCAL strFileName AS WSTRING
SELECT CASE wMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL, %ID_FILE_EXIT
IF HI(WORD, wParam) = %BN_CLICKED AND bIsPlaying = 0 THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
FUNCTION = 0
EXIT FUNCTION
END IF
CASE %ID_FILE_OPENCLIP
IF HI(WORD, wParam) = %BN_CLICKED THEN
strFilter = CHR$("Video Files (*.MPG;*MPEG;*.AVI;*.MOV;*.QT;*.WMV)", 0, "*.MPG;*.MPEG;*.AVI;*.MOV;*.QT;*.WMV", 0)
DISPLAY OPENFILE hwnd, 0, 0, "", "", strFilter, "", "", %OFN_EXPLORER OR %OFN_FILEMUSTEXIST TO strFileName
IF LEN(strFileName) THEN PlayMovieInWindow(hwnd, BYCOPY strFileName)
END IF
END SELECT
CASE %WM_GRAPHNOTIFY
LOCAL lEventCode AS LONG
LOCAL lParam1 AS LONG
LOCAL lParam2 AS LONG
IF ISOBJECT(pIMediaEventEx) THEN
DO
pIMediaEventEx.GetEvent(lEventCode, lParam1, lParam2, 0)
IF OBJRESULT <> %S_OK THEN EXIT DO
pIMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2)
IF lEventCode = %EC_COMPLETE THEN
IF ISOBJECT(pIVideoWindow) THEN
pIVideoWindow.Visible = %OAFALSE
pIVideoWindow.Owner = %NULL
pIVideoWindow = NOTHING
END IF
pIMediaControl = NOTHING
pIMediaEventEx = NOTHING
pIGraphBuilder = NOTHING
bIsPlaying = %FALSE
EXIT DO
END IF
LOOP
END IF
CASE %WM_SIZE
GetClientRect hwnd, rc
IF ISOBJECT(pIVideoWindow) THEN
pIVideoWindow.SetWindowPosition(rc.Left, rc.Top, rc.Right, rc.Bottom)
RedrawWindow hwnd, rc, 0, %RDW_INVALIDATE OR %RDW_UPDATENOW
END IF
CASE %WM_ERASEBKGND
IF bIsPlaying = %FALSE THEN
hDC = wParam
GetClientRect hwnd, rc
FillRect hDC, rc, GetStockObject(%BLACK_BRUSH)
FUNCTION = %TRUE
EXIT FUNCTION
END IF
CASE %WM_SYSCOMMAND
' Capture this message and send a WM_CLOSE message
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_DESTROY
IF ISOBJECT(pIMediaControl) THEN
pIMediaControl.Stop
pIMediaControl = NOTHING
END IF
IF ISOBJECT(pIVideoWindow) THEN
pIVideoWindow.Visible = %OAFALSE
pIVideoWindow.Owner = %NULL
pIVideoWindow = NOTHING
END IF
pIMediaEventEx = NOTHING
pIGraphBuilder = NOTHING
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hwnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================