New Sample Grabber

Category: Direct Show

Date: 02-16-2022

Return to Index


 
'Compilable Example:  (Jose Includes)
#Compile Exe
#Dim All
 
#Debug Error On
#Debug Display On
 
%Unicode = 1
#Include "Win32API.inc"
#Include Once "dshow.inc"
#Include "qedit.inc"
 
%WM_GraphNotify = %WM_User + 13
%IDC_Button = 500
 
Global hDlg, wRes, hRes  As Dword
Global pBuffer As String Ptr, pBufferSize As Long
 
Global pGraph          As IGraphBuilder           'Filter Graph Manager
Global pBuild          As ICaptureGraphBuilder2   'Capture Graph Builder
Global pSysDevEnum     As ICreateDevEnum          'enumeration object
Global pEnumCat        As IEnumMoniker
Global pMoniker        As IMoniker                'contains information about other objects
Global pceltFetched    As Dword
Global pCap            As IBaseFilter             'Video capture filter
Global pControl        As IMediaControl
Global pWindow         As IVideoWindow            'Display Window
Global pConfig         As IAMStreamConfig   'video output format
 
Global pGrabber        As ISampleGrabber
Global pSample         As IMediaSample
Global pEvents         As IMediaEventEX
 
Function PBMain() As Long
   Dialog Default Font "Tahoma", 12, 1
   Dialog New Pixels, 0, "DirectShow SampleGrabber Test",300,300,640+150,480, %WS_OverlappedWindow Or %WS_ClipSiblings Or %WS_ClipChildren To hDlg
   Control Add Button, hDlg, %IDC_Button, "Sample Grabber", 5,20,130,25
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Local w,h As Long
   Select Case Cb.Msg
      Case %WM_InitDialog
         pGraph      = NewCom ClsId $CLSID_FilterGraph                              'filter graph
         pBuild      = NewCom ClsId $CLSID_CaptureGraphBuilder2                     'capture graph builder
         pSysDevEnum = NewCom ClsId $CLSID_SystemDeviceEnum                         'enumeration object
         DisplayFirstCamera
 
       Case %WM_Command
          Select Case Cb.Ctl
             Case %IDC_Button
                FrameGrabber
                ? Str$(wRes) + Str$(hRes) + Str$(pBufferSize)
          End Select
 
      Case %WM_Destroy
         pGraph = Nothing
         pBuild = Nothing
         pSysDevEnum = Nothing
 
      Case %WM_Size
         Dialog Get Client hDlg To w,h
         pWindow.SetWindowPosition(150,0,w-150,h)
 
   End Select
End Function
 
Sub DisplayFirstCamera
   If pSysDevEnum.CreateClassEnumerator($CLSID_VideoInputDeviceCategory, pEnumCat, 0) <> %S_Ok Then Exit Sub
   pEnumCat.next(1, pMoniker, pceltFetched)                               'cycle through monikders
   pMoniker.BindToObject(NothingNothing, $IID_IBaseFilter, pCap)       'create device filter for the chosen device
   pGraph.AddFilter(pCap,"First Camera")                                 'add chosen device filter to the filter graph
   pBuild.SetFilterGraph(pGraph)                                         'initialize pBuild
   pBuild.RenderStream $Pin_Category_Preview, $MediaType_Video, pCap, NothingNothing   'render the live source
   pWindow = pGraph
   pWindow.Owner = hDlg
   pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren Or %WS_ClipSiblings  'video window settings
   pControl = pGraph
   pControl.Run
End Sub
 
Sub FrameGrabber()
   'https://docs.microsoft.com/en-us/windows/win32/directshow/using-the-sample-grabber
   Local pmt As AM_Media_Type
   Local pVIH As VideoInfoHeader
 
 
   'create samplegrabber filter
   pGrabber    = NewCom ClsId $CLSID_SampleGrabber
   pGraph.AddFilter(pGrabber,"Sample Grabber")
 
   'set media type SampleGrabber will receive
   pmt.MajorType  = $MediaType_Video
   pmt.SubType    = $MediaSubType_RGB24
   pmt.FormatType = $Format_VideoInfo  '$GUID_Null
   pmt.pbFormat   = %Null
   pmt.cbFormat   = 0
   pGrabber.SetMediaType(pmt)
   pGrabber.GetConnectedMediaType(pmt)
 
   'get frame bytes
   pGrabber.SetBufferSamples %True                         'activates buffering
   pGrabber.SetOneShot %True                               'half after first sample
   pGrabber.GetCurrentBuffer pBufferSize, %Null            'call twice. 1st to get needed buffer size. not use during run time
   pGrabber.GetCurrentBuffer pBufferSize, pBuffer          'call twice. 2nd to retrieve pointer to image into pBuffer
 
   'get frame size
   pVIH = pbFormat 'pmt.FormatType
   wRes = pVIH.bmiHeader.biWidth
   hRes = pVIH.bmiHeader.biHeight
   Dialog Set Text hDlg, Str$(wRes) + Str$(hRes)
 
   pGrabber = Nothing
End Sub


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm