Help with webcam or video stream

Just starting out? Need help? Post your questions and find answers here.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Here are some constants for capture that you'll need (sorry I forgot last time around). :oops: #WM_CAP_GRAB_FRAME_NOSTOP is included below. That should take care of compiler error. Depending on your app, You may or may not need to use some of these.

Code: Select all

#WM_CAP_START = #WM_USER
#WM_CAP_UNICODE_START = #WM_USER +100
#WM_CAP_PAL_SAVEA = #WM_CAP_START + 81
#WM_CAP_PAL_SAVEW = #WM_CAP_UNICODE_START + 81
#WM_CAP_UNICODE_END = #WM_CAP_PAL_SAVEW
#WM_CAP_ABORT = #WM_CAP_START + 69
#WM_CAP_DLG_VIDEOCOMPRESSION = #WM_CAP_START + 46
#WM_CAP_DLG_VIDEODISPLAY = #WM_CAP_START + 43
#WM_CAP_DLG_VIDEOFORMAT = #WM_CAP_START + 41
#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14
#WM_CAP_DRIVER_GET_NAMEA = #WM_CAP_START + 12
#WM_CAP_DRIVER_GET_NAMEW = #WM_CAP_UNICODE_START + 12
#WM_CAP_DRIVER_GET_VERSIONA = #WM_CAP_START + 13
#WM_CAP_DRIVER_GET_VERSIONW = #WM_CAP_UNICODE_START + 13
#WM_CAP_EDIT_COPY = #WM_CAP_START + 30
#WM_CAP_END = #WM_CAP_UNICODE_END
#WM_CAP_FILE_ALLOCATE = #WM_CAP_START + 22
#WM_CAP_FILE_GET_CAPTURE_FILEA = #WM_CAP_START + 21
#WM_CAP_FILE_GET_CAPTURE_FILEW = #WM_CAP_UNICODE_START + 21
#WM_CAP_FILE_SAVEASA = #WM_CAP_START + 23
#WM_CAP_FILE_SAVEASW = #WM_CAP_UNICODE_START + 23
#WM_CAP_FILE_SAVEDIBA = #WM_CAP_START + 25
#WM_CAP_FILE_SAVEDIBW = #WM_CAP_UNICODE_START + 25
#WM_CAP_FILE_SET_CAPTURE_FILEA = #WM_CAP_START + 20
#WM_CAP_FILE_SET_CAPTURE_FILEW = #WM_CAP_UNICODE_START + 20
#WM_CAP_FILE_SET_INFOCHUNK = #WM_CAP_START + 24
#WM_CAP_GET_AUDIOFORMAT = #WM_CAP_START + 36
#WM_CAP_GET_CAPSTREAMPTR = #WM_CAP_START + 1
#WM_CAP_GET_MCI_DEVICEA = #WM_CAP_START + 67
#WM_CAP_GET_MCI_DEVICEW = #WM_CAP_UNICODE_START + 67
#WM_CAP_GET_SEQUENCE_SETUP = #WM_CAP_START + 65
#WM_CAP_GET_STATUS = #WM_CAP_START + 54
#WM_CAP_GET_USER_DATA = #WM_CAP_START + 8
#WM_CAP_GET_VIDEOFORMAT = #WM_CAP_START + 44
#WM_CAP_GRAB_FRAME = #WM_CAP_START + 60
#WM_CAP_GRAB_FRAME_NOSTOP = #WM_CAP_START + 61
#WM_CAP_PAL_AUTOCREATE = #WM_CAP_START + 83
#WM_CAP_PAL_MANUALCREATE = #WM_CAP_START + 84
#WM_CAP_PAL_OPENA = #WM_CAP_START + 80
#WM_CAP_PAL_OPENW = #WM_CAP_UNICODE_START + 80
#WM_CAP_PAL_PASTE = #WM_CAP_START + 82
#WM_CAP_SEQUENCE = #WM_CAP_START + 62
#WM_CAP_SEQUENCE_NOFILE = #WM_CAP_START + 63
#WM_CAP_SET_AUDIOFORMAT = #WM_CAP_START + 35
#WM_CAP_SET_CALLBACK_CAPCONTROL = #WM_CAP_START + 85
#WM_CAP_SET_CALLBACK_ERRORA = #WM_CAP_START + 2
#WM_CAP_SET_CALLBACK_ERRORW = #WM_CAP_UNICODE_START + 2
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_SET_CALLBACK_STATUSA = #WM_CAP_START + 3
#WM_CAP_SET_CALLBACK_STATUSW = #WM_CAP_UNICODE_START + 3
#WM_CAP_SET_CALLBACK_VIDEOSTREAM = #WM_CAP_START + 6
#WM_CAP_SET_CALLBACK_WAVESTREAM = #WM_CAP_START + 7
#WM_CAP_SET_CALLBACK_YIELD = #WM_CAP_START + 4
#WM_CAP_SET_MCI_DEVICEA = #WM_CAP_START + 66
#WM_CAP_SET_MCI_DEVICEW = #WM_CAP_UNICODE_START + 66
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
#WM_CAP_SET_SCROLL = #WM_CAP_START + 55
#WM_CAP_SET_SEQUENCE_SETUP = #WM_CAP_START + 64
#WM_CAP_SET_USER_DATA = #WM_CAP_START + 9
#WM_CAP_SET_VIDEOFORMAT = #WM_CAP_START + 45
#WM_CAP_SINGLE_FRAME = #WM_CAP_START + 72
#WM_CAP_SINGLE_FRAME_CLOSE = #WM_CAP_START + 71
#WM_CAP_SINGLE_FRAME_OPEN = #WM_CAP_START + 70
#WM_CAP_STOP = #WM_CAP_START + 68

#AVSTREAMMASTER_AUDIO = 0
#AVSTREAMMASTER_NONE = 1
For more on #WM_CAP_GRAB_FRAME_NOSTOP, see here Not necessary, so use it only if it applies to your situation.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

ok i can save pic of webcam when window is opened but can't save pic without that window.

i want remove this line :

Code: Select all

If OpenWindow(0, 0, 0, 340, 300, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Video capture") 
but source not work.

How can i do this ?

Remember i want without any window save pic of webcam.

Thanks :wink:

Best regards.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Here's a quick example of taking snapshots with a minimized window using ShowWindow_(WindowID(0),#SW_SHOWMINIMIZED). You can also use HideWindow(0) to hide the entire window. Tested on WinXP with PB 3.91 beta2. This example is set to take a snapshot every 10 seconds with the program ending after 30 seconds.

To see the snapshots as they happen, Explore to c:\ and view as thumbnails and look at c:\snapshot.bmp

Code: Select all

#WM_CAP_START = #WM_USER 
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10 
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11 
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14 
#WM_CAP_EDIT_COPY = #WM_CAP_START + 30 
#WM_CAP_FILE_SAVEDIBA = #WM_CAP_START + 25 
#WM_CAP_GRAB_FRAME = #WM_CAP_START + 60 
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50 
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52 
#WM_CAP_STOP = #WM_CAP_START + 68 

Global hWndC

Procedure snapshot()
  SendMessage_(hWndC, #WM_CAP_GRAB_FRAME, 0, 0) 
  SendMessage_(hWndC, #WM_CAP_FILE_SAVEDIBA, 0, "c:\snapshot.bmp") 
EndProcedure

If OpenWindow(0, 0, 0, 340, 260, #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget, "Video capture") 
  
  ; to hide the window use HideWindow(0, 1) 
  ;HideWindow(0, 1) 
  
  ; to run minimized in taskbar use  ShowWindow_(WindowID(0),#SW_SHOWMINIMIZED) 
  ShowWindow_(WindowID(0),#SW_SHOWMINIMIZED) 
  
  If OpenLibrary(0, "C:\WINDOWS\system32\avicap32.dll") 
    *capAddress = IsFunction(0, "capCreateCaptureWindowA") 
    hWndC = CallFunctionFast(*capAddress, "My Capture Window", #WS_CHILD, 10, 10, 320, 240, WindowID(0),1) 
    SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0) 
    SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #False, 0) 
    SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 15, 0) 
    ; for saving in other formats 
    ;CreateImage(0, 320, 240); 
  EndIf 
EndIf 

; get initial snapshot
snapshot()

; get starting point for time count 
startCount = GetTickCount_() 

; frequency of snapshot in milliseconds (I'll use 10 seconds here) 
snapFrequency = 10000 

; run progarm for 30 seconds 
endCount = startCount + 30000 

Repeat 
  Event = WaitWindowEvent() 
  
  currentTick = GetTickCount_() 
  
  If currentTick > endCount ; end program 
    ; take final snapshot before closing
    snapshot()
    quit = #True 
  ElseIf currentTick > startCount + snapFrequency ; take snapshot 
    startCount = currentTick 
    snapshot()
  EndIf 
  
  If Event = #PB_EventCloseWindow 
    quit = #True 
  EndIf 
  
Until quit = #True 

SendMessage_(hWndC, #WM_CAP_STOP, 0, 0) 
SendMessage_(hWndC, #WM_CAP_DRIVER_DISCONNECT, 0, 0) 
DestroyWindow_(hWndC) 
CloseLibrary(0) 

End
Remember, this is a plain and simple app. You'll need to add your own error handling routines as well as system checks. :wink:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

Very thanks Sparkie :D

It's now work fine........

Your code is first small code for work with webcam in purebasic.

You are big helper :wink:
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

Sparkie are you know how can we detect webcam status for busy or not busy !?

I want add an code before connect to webcam device for check webcam are use by other apps or not and then connect to device.

How must do it ? :wink:
PWS32
User
User
Posts: 85
Joined: Sat May 10, 2003 1:02 pm
Location: Germany

Post by PWS32 »

Hi Sparkie,

have you a idea to implement this Funktions ?

WM_CAP_DLG_VIDEODISPLAY
The WM_CAP_DLG_VIDEODISPLAY message displays a dialog box in which the user can set or adjust the video output. This dialog box might contain controls that affect the hue, contrast, and brightness of the displayed image, as well as key color alignment. You can send this message explicitly or by using the capDlgVideoDisplay macro.

WM_CAP_SET_VIDEOFORMAT
The WM_CAP_SET_VIDEOFORMAT message sets the format of captured video data. You can send this message explicitly or by using the capSetVideoFormat macro.

The WM_CAP_DLG_VIDEOFORMAT
message displays a dialog box in which the user can select the video format. The Video Format dialog box might be used to select image dimensions, bit depth, and hardware compression options. You can send this message explicitly or by using the capDlgVideoFormat macro.

WM_CAP_DLG_VIDEOSOURCE
The WM_CAP_DLG_VIDEOSOURCE message displays a dialog box in which the user can control the video source. The Video Source dialog box might contain controls that select input sources; alter the hue, contrast, brightness of the image; and modify the video quality before digitizing the images into the frame buffer. You can send this message explicitly or by using the capDlgVideoSource macro.


Best regards,
Peter
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Glad you're finding this information useful. I'm learning with you as we go along here, so please don't mistake me for an expert in this area. :)

@Wolf
I want add an code before connect to webcam device for check webcam are use by other apps or not and then connect to device.

How must do it ? ;)
Try something like this:

Code: Select all

If SendMessage_(handle_to_your_capture_preview_window, #WM_CAP_DRIVER_CONNECT, 0, 0)
 ; connection is free to use so continue on
Else
  MessageRequester("Error", "Capture device in use", #MB_ICONERROR)
  ; connection in use so do something else
EndIf
@PWS32
You should first check the capabilities of your capture driver with a WM_CAP_DRIVER_GET_CAPS message. I do not use this at this time as I already know the capabilities on my system. I will however be adding it to my project later this weekend (time permitting) and will share it with you at that time. You can bypass all that and just try the following messages. If they work, then assume your driver has the capabilites to display the dialogs. :D

SendMessage_(handle_to_your_capture_preview_window, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
SendMessage_(handle_to_your_capture_preview_window, #WM_CAP_DLG_VIDEOFORMAT, 0, 0)
SendMessage_(handle_to_your_capture_preview_window, #WM_CAP_DLG_VIDEODISPLAY, 0, 0)

As for #WM_CAP_SET_VIDEOFORMAT, this requires a little more work as we now have to work with some structures (BITMAPINFO, BITMAPINFOHEADER, RGBQUAD)

I will be adding this to my project this weekend (again, time permitting) and will post more at that time. You can also take a look at here at msdn for more info. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
chio
User
User
Posts: 30
Joined: Thu Jun 24, 2004 1:55 pm
Location: New York City
Contact:

Ok so far

Post by chio »

Ok guys this is what I have so far, is done differently than some of yours and is based on code from a bunch of different sources. See what you guys think and recommend.

This will capture, allow you to choose capture and sources, and do motion. I have only worked on the Start Capture not the movie savings from the bottom.

My only problem is that when capture starts I can't stop it unless I quit the app.

Recommendations???

Code: Select all

Global cap.l,I1.l,I2.l,I3.l,sb.l,window1X,window1Y,window2X,window2Y,videoW,videoH,windowW,windowH
Global Frame.l
Frame  = 1

window1X = 0
window1Y = 380
window2X = 170
window2Y = 380

windowW = 640
windowH = 480
videoW = 160
videoH = 120

Procedure Callback(WindowID, Message, wParam, lParam) 
Result = #PB_ProcessPureBasicEvents 
Select Message
  Case #WM_PAINT
  InvalidateRect_(WindowID(),0,1)
  Case #WM_SIZE
  InvalidateRect_(WindowID(),0,1)
;  UpdateStatusBar(100)
  Case #WM_MOVE
  InvalidateRect_(WindowID(),0,1)
EndSelect
ProcedureReturn Result 
EndProcedure 

Procedure StatusCallback(Hwnd.l,nId.l,lpsz.s)
SendMessage_(cap,1032,0,0)
StatusBarText(100,0,lpsz) 
Result = 1
ProcedureReturn result
EndProcedure

Procedure ErrorCallback(Hwnd.l,nId.l,lpsz.s)
SendMessage_(cap,1032,0,0)
StatusBarText(100,0,lpsz) 
Result = 1
ProcedureReturn result
EndProcedure

Procedure FrameCallback(Hwnd.l,0)
StatusBarText(100,0,"Frame : "+ Str(Frame)) 
Result = 1
Frame = Frame +1
ProcedureReturn result
EndProcedure

Procedure markIt(x.l,y.l)
  StartDrawing(WindowOutput())
        FrontColor(255,0, 255) 
        Plot(x,y)   
  StopDrawing()
EndProcedure


#Image = 114
#Image2 = 115 



Procedure FX()

          CapCatchBMP("test2.bmp")
          Im3 = LoadImage_(im3,"test2.bmp",0,160,120,$2030)
     ;     SendMessage_(I1,#STM_SETIMAGE,#IMAGE_BITMAP,Im3)
          Delay(1)

          CapCatchBMP("test3.bmp")
          Im4 = LoadImage_(im4,"test3.bmp",0,160,120,$2030)
      ;    SendMessage_(I2,#STM_SETIMAGE,#IMAGE_BITMAP,Im4)
          

  
          myIma = LoadImage(71,"test2.bmp")
          ImageGadget(#Image,window1X,window1Y, videoW, videoH,UseImage(71)) 
          myImb = LoadImage(72,"test3.bmp")
          ImageGadget(#Image2,window2X,window2Y, videoW, videoH,UseImage(72)) 


nn = 0
nn2 = 0 
MyImage = CreateImage(70, ImageWidth(), ImageHeight()) 
WindowEvent() 
UseImage(70) 
StartDrawing(ImageOutput()) 
 hDC = GetDC_(GadgetID(#Image)) 
 hDC2 = GetDC_(GadgetID(#Image2))

  For i = 0 To ImageHeight() 
    For ii = 0 To ImageWidth() 
    Color =GetPixel_(hDC,ii,i) 
    Color2 =GetPixel_(hDC2,ii,i)
    Temp = (Red(Color) + Green(Color) + Blue(Color))/3 
    Temp2 = (Red(Color2) + Green(Color2) + Blue(Color2))/3 
    NewColor = RGB(Temp,Temp,Temp) 
    colCh = Temp - Temp2
    colCh2 = Temp2 - Temp
    UseImage(70) 

    thrsh = 25

    If colCh >= thrsh Or colCh2 >= thrsh
     myColor = RGB(255,1,255)
     Plot(ii,i,myColor)
     nn=0 
     Else
     Plot(ii,i,Color) 
     EndIf
    UseImage(71) 
    Next ii 
  Next i 

  UseImage(70) 
  StopDrawing() 
  ;SetGadgetState(#Image,ImageID()) 
  SendMessage_(I3,#STM_SETIMAGE,#IMAGE_BITMAP,MyImage)
  ;SaveImage(0,"Black&White.bmp",#PB_ImagePlugin_BMP) 
  FreeImage(70)
  FreeImage(71)
  FreeImage(72)

EndProcedure 


Hwnd.l = OpenWindow(0,10,10,930,530, #PB_Window_SizeGadget|#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered, "PureBasic Window")
If hwnd
cap = CreateCapwindow(WindowID(),0,0,400,300,1000)
Buffer$ = Space(1)
If CreateGadgetList(WindowID())
t1.l = TextGadget(10, 1, 310, 100, 24,"Select Driver : ¥")  
cb.l = ComboBoxGadget(0, 0,330,300,120) 
b1.l = ButtonGadget(1, 420, 10, 100,24,"Start Capture")
t2.l = TextGadget(10, 1, 358, 100, 20,"Snapshot-Preview :")  
;I1 = CreateWindowEx_($0,"static","",$5400100E,window1X,window1Y,160,120,hwnd,2,GetModuleHandle_(0),0) 
;I2 = CreateWindowEx_($0,"static","",$5400100E,window2X,window2Y,160,120,hwnd,2,GetModuleHandle_(0),0) 
I3 = CreateWindowEx_($0,"static","",$5400100E,600,window2Y-100,160,120,hwnd,2,GetModuleHandle_(0),0) 
b2.l = ButtonGadget(3, 420, 60, 100,24,"Source")
b3.l = ButtonGadget(4, 420, 90, 100,24,"Format")
b4.l = ButtonGadget(5, 420, 120, 100,24,"Display")
b5.l = ButtonGadget(6, 420, 150, 100,24,"Compression")
b6.l = ButtonGadget(7, 420, 220, 100,24,"Aufnahme")
b7.l = ButtonGadget(8, 420, 250, 100,24,"Setup")
b8.l = ButtonGadget(9, 420, 320, 100,24,"Preview-Modus")
b9.l = ButtonGadget(10, 420, 350, 100,24,"Overlay-Modus")
b10.l = ButtonGadget(11, 420, 380, 100,24,"Waveformat lesen")
b11.l = ButtonGadget(12, 420, 410, 100,24,"Waveformat setzen")
sb   = CreateStatusBar(100, hwnd) 
b12.l = ButtonGadget(13, 420, 190, 100,24,"Abspielen")



          LoadImage(71,"test2.bmp")
          ImageGadget(#Image,window1X,window1Y, videoW, videoH,UseImage(71)) 
          LoadImage(72,"test3.bmp")
          ImageGadget(#Image2,window2X,window2Y, videoW, videoH,UseImage(72)) 



r = CapGetDrivers(Buffer$)
For x = 1 To r
AddGadgetItem(0,-1,Trim(StringField(Buffer$,x,",")))
Next x
EndIf

SetGadgetState(0,0) 
ActivateGadget(0)

SetWindowCallback(@Callback())

Repeat
    EventID.l = WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
        CapConnect(0)
        mciSendString_("close all",0,0,0)
        ;CapFree()
      Quit = 1
    EndIf
    If EventID = #PB_EventGadget
;    Debug EventID
      Select EventGadgetID()
        Case 0
          SetCursor_(LoadCursor_(0,#IDC_WAIT))
          CapConnect(GetGadgetState(0))
          CapSetOverlay()
          CapSetStatusCallback(@StatusCallback())
          CapSetErrorCallback(@ErrorCallback())
          SetCursor_(LoadCursor_(0,#IDC_ARROW))
  
        Case 1
        
        If gg=0
         SetGadgetText(1,"Stop")
          Repeat
          EventID.l = WaitWindowEvent()
        ;  Debug gg
          FX()
          Until gg=1
          gg=1
          ;CreateThread(@FX(), 23)

        ElseIf gg=1
          SetGadgetText(1,"Start")
         ; Debug gg
          gg=0
       
       
      EndIf  
          
          
        Case 3
          CapSourceDlg()
        Case 4
          CapFormatDlg()
        Case 5
          CapDisplayDlg()
        Case 6
          CapCompressDlg()
        Case 7
          mciSendString_("close all",0,0,0)
          CapStartCatchAVI("test.avi")
        Case 8
          CapSetSetup(0,1,0,1,1,30)
        Case 9
          CapSetPreview(3,1)
          CapSetFrameCallback(@FrameCallback())
        Case 10
          CapSetOverlay()
          CapSetFrameCallback(0)
          Frame = 0
        Case 11
          Channels = CapGetWaveFormat(1)
          Bits = CapGetWaveFormat(2)
          Samples = CapGetWaveFormat(3)
          MessageRequester("",Str(Channels)+","+Str(Bits)+","+Str(Samples),0)
        Case 12
          CapSetWaveFormat(2,16,44100)
        Case 13
          If g = 0
          SetGadgetText(13,"STOP")
          A$ = "Open test.avi type AVIVideo alias MPEGFile parent " + Str(hwnd) + " STYLE " + Str(#WS_CHILD)
          mciSendString_( A$,0,0,0 )
          mciSendString_("Put  MPEGFile Window At 180 380 160 120",0,0,0 )
          mciSendString_("Play MPEGFile repeat",0,0,0 )
          g = 1
          Else
          SetGadgetText(13,"Abspielen")
          mciSendString_("close all",0,0,0)
          g = 0
          EndIf
      EndSelect
    EndIf 
  Until Quit = 1 
EndIf
End
chio
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

@Sparkie

When run this line in your code :

Code: Select all

SendMessage_(handle_to_your_capture_preview_window, #WM_CAP_DRIVER_CONNECT, 0, 0)
It's execute #WM_CAP_DRIVER_CONNECT an then if your webcam device is in use opened one window for select "source webcam device" and if we use "IF" at first in this line #WM_CAP_DRIVER_CONNECT execute too and opened that window again.

I think must use one code for check status of webcam for its in use or not .

Somthing like this:

Code: Select all

#WM_CAP_Get_DRIVER_Status 

Best regards.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@Wolf
I'll take a closer look this weekend and see what I can do about that. Right now I'm using a callback to handle this but it's a little shaky ;)

@chio
Running your code here produces Error line 65: CapCatchBMP() is not a function, an array, or linked list.
My only problem is that when capture starts I can't stop it unless I quit the app
You should be able to stop capture by pressing escape or clicking a mouse key.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
chio
User
User
Posts: 30
Joined: Thu Jun 24, 2004 1:55 pm
Location: New York City
Contact:

Instal avicap

Post by chio »

Oh sorry you need to install the AVICAP library which can be downloaded from http://www.purearea.net/pb/english/index.htm in UserLibs its pretty helpfull.
chio
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@Wolf
Until I figure out a better way, here's how I am handling a capture device already in use by another program. It's not pretty, but it works for me. :)

I catch the handle to the dialog window (Video Source) that isn't a child of my WindowID().

Code: Select all

Procedure myWindowCallback(hwnd, msg, wparam, lparam)
  Shared dlgClosed
  result = #PB_ProcessPureBasicEvents
  
; handle video source dialog (here we close it by sending Escape key)
; kind of messy right now but it seems to work
  
  If hwnd = WindowID(your_window_id#) And msg = #WM_KILLFOCUS And driverConnected = #False
    hDlg = FindWindowEx_(0, 0, "#32770", "Video Source") ; get the handle to the dialog
  EndIf
  
  If hDlg <> 0 And driverConnected = #False
    If dlgClosed = #False
      dlgClosed = #True ; this ensures we send Escape key one time only
      keybd_event_(#VK_ESCAPE, 0, 0, 0)
      keybd_event_(#VK_ESCAPE, 0, #KEYEVENTF_KEYUP, 0)
    EndIf
  EndIf
  
  ProcedureReturn result
EndProcedure
Make sure you have a SetWindowCallback(@myWindowCallback()) in your app.

You'll also need an error callback for the capture device.

Code: Select all

#WM_CAP_SET_CALLBACK_ERRORA = #WM_CAP_START + 2 ; define your callback constant
#IDS_CAP_DRIVER_ERROR = 418  ; Driver specific error message

Procedure MyCapErrorCallback(hwnd.l, nID.l, lpsz.l)
  If nID = #IDS_CAP_DRIVER_ERROR
    MessageRequester("Error", "Error connecting to capture device." + Chr(10)+Chr(13) + "Application will now close", #MB_ICONERROR)
    CloseWindow(your_window_id#)
  Else
    MessageRequester("Error", "Unspecified capture device error (" + Str(nID) + ")", #MB_ICONERROR)
  EndIf
EndProcedure
Then you set the error callback with...

Code: Select all

SendMessage_(handle_to_your_capture_window, #WM_CAP_SET_CALLBACK_ERRORA, 0, @MyCapErrorCallback())  


@chio I installed the AVICAP lib and the example captest.pb ran fine. I realize your project is not complete as of yet, but I'm sorry to say once I started the capture, your code didn't do much for me other than flicker and refuse to let me close the app (as you had warned us ;) ) The 3 ImageGadgets seemed to be oversized as well. Maybe you should ask the AVICAP author for an opinion as I'm not sure what the problem is at this time. :(
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post by PolyVector »

This webcam code always confuses me...
Is there any way to grab an image from a webcam directly to memory, without passing through a window or a file?
If that's possible, you could make the output part of a texture on a 3d character... :D :D :D
*gets lots of stupid ideas*
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@PolyVector AKAIK, in order to grab frames, you'll need a minimum of a capture window with a parent window. From there you can use #WM_CAP_EDIT_COPY which places a frame snapshot to the clipboard, or #WM_CAP_GRAB_FRAME (or #WM_CAP_GRAB_FRAME_NOSTOP), which places a frame snapshot into the frame buffer.

I've used the #WM_CAP_EDIT_COPY along with GetClipboardData() to CreateImage() and it works fine. I have not yet tried working with the frame buffer. It doesn't appear to be too difficult. If I understand the process correctly, you will need a frame callback (#WM_CAP_SET_CALLBACK_FRAME) to access the frame buffer.

I know zip, zilch, nada about Textures, so I have no idea if this does you any good. :?

I'm only a week or two into this whole capture thing, so there may well be other possibilities available to you. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post by PolyVector »

I'll look into it when I have less projects piling up on me... :D
Post Reply