• Welcome to Jose's Read Only Forum 2023.
 

DirectShow Examples

Started by José Roca, September 03, 2011, 02:24:51 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
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
' ========================================================================================


José Roca

 
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
' ========================================================================================