The program uses ESCAPI to read a webcam and display the webcam's image in a small window. It also draws a video waveform monitor.
The problem I'm having is that the program makes my computer labor and causes the cooling fan to race. CPU consumption is about 18%. I have tried isolating various portions of the code to no avail. I have the debugger turned off.
Am I doing something wrong? Is there any way to write this program to be easier on Windows and the computer hardware? Or am I asking too much?
I'm aiming for a frame rate of 30 fps.
Any help is greatly appreciated. If this is asking too much, thanks anyway.
Thank you.
Code: Select all
;WORKS WITH ESCAPI
;LAST MODIFIED 12/17/2023
InitKeyboard()
InitSprite()
Global Dim gammaTable.a(257)
Global Dim gainTable.a(257)
;PRESETS
Global gain.f = 0.86
Global gamma.f = 1
Global pedestal = 16
Procedure makeGammaLUT(gamma.f)
For cnt = 0 To 255
;gammaTable.a(cnt) = Pow(cnt,gamma) * (255/Pow(255,gamma))
gammaTable.a(cnt) = cnt ; UNITY GAMMA
Next
EndProcedure
Procedure makeGainLUT(gain)
For cnt = 0 To 255
If cnt * gain > 255: gainTable(cnt) = 255
ElseIf cnt * gain < 1: gainTable(cnt) = 0
Else: gainTable(cnt) = cnt * gain
EndIf
Next
EndProcedure
makeGammaLUT(gamma)
makeGainLUT(gain)
result = ExamineDesktops(): Global V_RES = DesktopHeight(0): Global H_RES = DesktopWidth(0)
;SCRNH = V_RES: SCRNW = H_RES
Global fullScreen = #False
;Global recordingNow
;Global clip = #False ;#True
;Global whiteClip = 235 ;100 IRE
;Global whiteClip = 239 ;102 IRE
;Global whiteClip = 246 ;105 IRE
;Global whiteClip = 254 ;108 IRE
Global Process = #True
If Process = #False: clip = #False: EndIf
std$ = "SDR"
;"HLG" OR "SDR" OR "HDR"
Enumeration
#GAINGAD = 1;GAIN GADGET
#GAMMA;GAMMA GADGET
#PEDESTAL;PEDESTAL GADGET
#GAINTEXT
#PEDTEXT
#GAMMATEXT
EndEnumeration
#KR = 0.2126:#KG = 0.7152:#KB = 0.0722 ;REC.709
IncludeFile "escapi.pbi"
Global HEIGHT = (V_RES / 2)-40
Global WIDTH = HEIGHT * 16 / 9
;Global WIDTH = (H_RES / 4)-40
Global WIDTHM1 = H_RES - 1
Global HEIGHTM1 = V_RES - 1
Procedure Graticule_720(std$)
StartDrawing(ImageOutput(3))
DrawingMode(#PB_2DDrawing_Default)
;BLACK
lum = 16
LineXY(68,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff);BLACK
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-16, "0%", $ffffff)
;lum = 246 ;105 IRE
;LineXY(68,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff);BLACK
;LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
If std$ = "HLG" Or std$ = "HDR"
lum = 397 / 4 ;HLG
LineXY(36,(255 - lum) + 52, WIDTH-45,(255 - lum) + 52,$00ffff)
DrawText(600,(255 - lum) + 42,"38", $ffffff)
;DrawText(2,(255 - lum) + 44,"397", $ffffff)
DrawText(6,(255 - lum) + 42, "18%", $ffffff)
ElseIf std$ = "SDR"
;lum = 254; 109 IRE
;LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
lum = 104; 40 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "40%", $ffffff)
lum = 82; 30 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "30%", $ffffff)
lum = 38; 10 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "10%", $ffffff)
lum = 169; 70 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "70%", $ffffff)
lum = 213; 90 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "90%", $ffffff)
lum = 60; 20 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15 , "20%", $ffffff)
lum = 147 ;60 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15, "60%", $ffffff)
lum = 191; 80 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15, "80%", $ffffff)
lum = 126; 50 IRE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9,$00ffff)
DrawText(10,(640 - lum*2)-15, "50%", $ffffff)
EndIf
;HLG 90% REFLECTANCE
If std$ = "HLG" Or std$ = "HDR"
;lum = 235
;LineXY(36,(640 - lum*2), WIDTH-45,(640 - lum*2),$00ffff)
;DrawText(600,(510 - lum) + 84, "100", $ffffff)
;DrawText(6,(510 - lum) + 84,"90%", $ffffff)
ElseIf std$ = "SDR"
lum = 235 ;90% REFLECTANCE
LineXY(36,(640 - lum*2)-9, WIDTH-45,(640 - lum*2)-9, $00ffff)
DrawText(10,(640 - lum*2)-15, "100%", $ffffff)
EndIf
;DrawText(6, 90, "REFL.", $ffffff)
;DrawText(600, 90, "IRE", $ffffff)
StopDrawing()
EndProcedure
Procedure Graticule_1080(std$)
DrawingMode(#PB_2DDrawing_Default)
;BLACK
lum = 16
LineXY(68,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff);BLACK
LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
DrawText(6,(440 - lum*2)-45, "0", $ffffff)
;DrawText(6,(640 - lum*2)-45, " 0%", $ffffff)
;GAMMA
If std$ = "HLG" Or std$ = "HDR"
lum = 397 / 4 ;HLG
LineXY(36,(255 - lum) + 52, WIDTH-45,(255 - lum) + 52,$00ffff)
DrawText(600,(255 - lum) + 42,"38", $ffffff)
;DrawText(2,(255 - lum) + 44,"397", $ffffff)
DrawText(6,(255 - lum) + 42, "18%", $ffffff)
ElseIf std$ = "SDR"
lum = 104
LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
DrawText(600,(640 - lum*2)-45 , "40", $ffffff)
DrawText(6,(640 - lum*2)-45, "18%", $ffffff)
lum = 82
LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
DrawText(600,(640 - lum*2)-45, "30", $ffffff)
lum = 126
LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45,$00ffff)
DrawText(600,(640 - lum*2)-45, "50", $ffffff)
EndIf
;WHITE
;HLG 90% REFLECTANCE
If std$ = "HLG" Or std$ = "HDR"
;lum = 235
;LineXY(36,(640 - lum*2), WIDTH-45,(640 - lum*2),$00ffff)
;DrawText(500,(510 - lum) + 84, "100", $ffffff)
;DrawText(6,(510 - lum) + 84,"90%", $ffffff)
ElseIf std$ = "SDR"
lum = 235 ;90% REFLECTANCE
LineXY(36,(640 - lum*2)-45, WIDTH-45,(640 - lum*2)-45, $00ffff)
DrawText(600,(640 - lum*2)-45, "100", $ffffff)
DrawText(6,(640 - lum*2)-45, "90%", $ffffff)
EndIf
DrawText(6, 90, "REFL.", $ffffff)
DrawText(600, 90, "IRE", $ffffff)
EndProcedure
LoadFont(1,"arial",13,#PB_Font_Bold);FOR SCOPE GRATICULE
LoadFont(2,"arial",21);FOR GADGETS
device = 0
count = setupESCAPI()
If count = 0
MessageRequester("Error", "Unable to initialize ESCAPI. Use 32-bit version")
End
EndIf
;name$ = Space(255)
getCaptureDeviceName(device, @name$, 255)
bufSize = H_RES * V_RES * 4
scp.SimpleCapParams
scp\mWidth = H_RES
scp\mHeight = V_RES
scp\mTargetBuf = AllocateMemory(bufSize)
If initCapture(device, @scp) = #False
MessageRequester("Error", "Unable to initialize webcam.")
End
EndIf
If H_RES = 1280
image1 = CreateImage(1, (H_RES-290)/2, V_RES - 66, 24) ;SCOPE
image3 = CreateImage(3, (H_RES-290)/2, V_RES - 66, 24):Graticule_720(std$) ;GRATICULE
ElseIf H_RES > 1280
image1 = CreateImage(1, (H_RES-145)/2, V_RES - 66, 24) ;SCOPE
image3 = CreateImage(3, (H_RES-145)/2, V_RES - 66, 24):Graticule_720(std$) ;GRATICULE
EndIf
image2 = CreateImage(2,H_RES,V_RES, 24);CAMERA
OpenWindow(2,0,0,H_RES, V_RES,"Camera", #PB_Window_BorderLess) ;FULL-SCREEN WINDOW
AddKeyboardShortcut(2,#PB_Shortcut_F11,#PB_Shortcut_F11) ;F11 FOR FULL SCREEN
AddKeyboardShortcut(2,#PB_Shortcut_F2,#PB_Shortcut_F2) ;F2 SHRINK CAMERA WINDOW
AddKeyboardShortcut(2,#PB_Shortcut_Space,#PB_Shortcut_Space) ;SPACE BAR TO STOP/START RECORDING
AddKeyboardShortcut(2, #PB_Shortcut_Control|#PB_Shortcut_Q, 113);CTL Q TO QUIT
AddKeyboardShortcut(2, #PB_Shortcut_Escape,27);ESC TO QUIT
OpenWindowedScreen(WindowID(2),0,0,WindowWidth(2),WindowHeight(2),0,0,0,#PB_Screen_WaitSynchronization)
HideWindow(2,#True)
;MAIN WINDOW
;If V_RES = 720
OpenWindow(1,72,0, WIDTH*2, V_RES - 66,"Waveform", #PB_Window_SystemMenu)
AddKeyboardShortcut(1,#PB_Shortcut_F11,#PB_Shortcut_F11) ;F11 FOR FULL SCREEN
AddKeyboardShortcut(1,#PB_Shortcut_Space,#PB_Shortcut_Space) ;SPACE BAR TO STOP/START RECORDING
AddKeyboardShortcut(1, #PB_Shortcut_Control|#PB_Shortcut_Q, 113);CTL Q TO QUIT
AddKeyboardShortcut(1, #PB_Shortcut_Escape,27);ESC TO QUIT
;OpenWindowedScreen(WindowID(1),0,0,H_RES,V_RES,0,0,0,#PB_Screen_WaitSynchronization)
;EndIf
;If V_RES = 720
SpinGadget(#GAINGAD, WIDTH * 1.5, 15,200,48,0,100)
SpinGadget(#GAMMA,WIDTH * 1.5, 65,200,48,0,100)
SpinGadget(#PEDESTAL,WIDTH * 1.5, 115,200,48,0,100)
SetGadgetFont(#GAINGAD,FontID(2))
SetGadgetFont(#PEDESTAL,FontID(2))
SetGadgetFont(#GAMMA,FontID(2))
CheckBoxGadget(201,860,180,200,50,"WHITE CLIP")
CheckBoxGadget(202,860,220,200,50,"PROCESS")
SetGadgetFont(201,FontID(2))
SetGadgetFont(202,FontID(2))
SetGadgetText(#GAINGAD,StrD(gain,2))
SetGadgetText(#GAMMA,StrD(gamma,2))
SetGadgetText(#PEDESTAL,StrD(pedestal,2))
TextGadget(#GAINTEXT,WIDTH * 1.1,20,200,48,"GAIN")
TextGadget(#PEDTEXT,WIDTH * 1.1,70,200,48,"GAMMA")
TextGadget(#GAMMATEXT,WIDTH * 1.1,120,200,48,"PEDESTAL")
TextGadget(11,WIDTH * 1.1,180,600,48,"WHITE: 100%")
TextGadget(12,WIDTH * 1.1,220,600,48,"18% GRAY: 40%")
TextGadget(13,WIDTH * 1.1,260,600,48,"BLACK: 0%")
SetGadgetFont(#GAINTEXT,FontID(2))
SetGadgetFont(#PEDTEXT,FontID(2))
SetGadgetFont(#GAMMATEXT,FontID(2))
SetGadgetFont(11,FontID(2))
SetGadgetFont(12,FontID(2))
SetGadgetFont(13,FontID(2))
;setCaptureProperty(DEVICE,#CAPTURE_ZOOM,0,#VideoProcAmp_Flags_Manual)
;setCaptureProperty(DEVICE,#CAPTURE_BRIGHTNESS,0.5,#VideoProcAmp_Flags_Manual); INITIALIZE TO UNITY
Quit = #False
Repeat ;MAIN LOOP
doCapture(device)
;While isCaptureDone(device) = #False: Delay(1): Wend
While isCaptureDone(device) = #False: Wend
event = WindowEvent()
If event = #PB_Event_CloseWindow
Quit = #True
Break
ElseIf event = #PB_Event_Gadget
If EventGadget() = #GAINGAD
If EventType() = #PB_EventType_Up:gain + 0.01
ElseIf EventType() = #PB_EventType_Down:gain - 0.01
EndIf
SetGadgetText(#GAINGAD,StrD(gain,2))
makeGainLUT(gain)
ElseIf EventGadget() = #GAMMA
If EventType() = #PB_EventType_Up: gamma - 0.01
ElseIf EventType() = #PB_EventType_Down: gamma + 0.01
EndIf
;If gamma <= 0.5
SetGadgetText(#GAMMA,StrD(gamma,2))
factor.f = 255/Pow(255,gamma)
makeGammaLUT(gamma)
;EndIf
ElseIf EventGadget() = #PEDESTAL
If EventType() = #PB_EventType_Up:pedestal + 1
ElseIf EventType() = #PB_EventType_Down:pedestal - 1
EndIf
SetGadgetText(#PEDESTAL,StrD(pedestal,2))
EndIf
ElseIf event = #PB_Event_Menu
menuItem = EventMenu()
; If menuitem = #PB_Shortcut_F2
; If WindowHeight(2) = V_RES
; ResizeWindow(2,0,0,H_RES,V_RES-66)
; Else: ResizeWindow(2,0,0,H_RES,V_RES);:SetActiveWindow(2)
; EndIf
; EndIf
If menuitem = #PB_Shortcut_F11
If fullScreen <> #False
fullScreen = #False:ShowCursor_(#True)
HideWindow(2,#True)
SetActiveWindow(1)
Else
fullScreen = #True:ShowCursor_(#False)
HideWindow(2,#False)
SetActiveWindow(2)
EndIf
ElseIf menuitem = #PB_Shortcut_Space
Debug "space bar"
EndIf
EndIf
;SCOPE
If fullScreen = #False
StartDrawing(ImageOutput(1))
DrawImage(ImageID(3),0,0);DRAW GRATICULE
;ElseIf V_RES = 1080: Graticule_1080(std$)
;EndIf
*readBufr = scp\mTargetBuf
;DRAW SCOPE
For y = 0 To HEIGHTM1
For x = 0 To WIDTHM1
r = (PeekA(*readBufr+2))
g = (PeekA(*readBufr+1))
b = (PeekA(*readBufr))
If Process <> #False
rf = r * gain
If clip = #True
If rf > whiteClip:rf=whiteClip
ElseIf rf < 16:rf=16:EndIf;clip
EndIf
gf = g * gain
If clip = #True
If gf > whiteClip:gf=whiteClip
ElseIf gf < 16:gf=16:EndIf;clip
EndIf
bf = b * gain
If clip = #True
If bf > whiteClip:bf=whiteClip
ElseIf bf < 16:bf=16:EndIf;clip
EndIf
r=gammaTable(rf) + PEDESTAL
If clip = #True
If r > whiteClip:r=whiteClip ;clip at 105 IRE
ElseIf r < 16:r=16:EndIf;clip
EndIf
g=gammaTable(gf) + PEDESTAL
If clip = #True
If g > whiteClip:g=whiteClip ;clip at 105 IRE
ElseIf g < 16:g=16:EndIf;clip
EndIf
b=gammaTable(bf) + PEDESTAL
If clip = #True
If b > whiteClip:b=whiteClip ;clip at 105 IRE
ElseIf b < 16:b=16:EndIf;clip
EndIf
EndIf
;DRAW SCOPE
lum.f = (r*#KR) + (g*#KG) + (b*#KB)
;lum = 254;CALIBRATE
Plot(x/3+50, (640 - lum*2)-9, $00cc00)
*readBufr + 4
Next
Next
StopDrawing()
;DRAW CAMERA
*readBufr = scp\mTargetBuf
;DRAW CAMERA
StartDrawing(ImageOutput(2))
For y = 0 To V_RES - 1: For x = 0 To H_RES - 1
r = (PeekA(*readBufr+2))
g = (PeekA(*readBufr+1))
b = (PeekA(*readBufr))
If process <> #False
rf = r * gain
If clip = #True
If rf > whiteClip:rf=whiteClip
ElseIf rf < 16:rf=16:EndIf;clip
EndIf
gf = g * gain
If clip = #True
If gf > whiteClip:gf=whiteClip
ElseIf gf < 16:gf=16:EndIf;clip
EndIf
bf = b * gain
If clip = #True
If bf > whiteClip:bf=whiteClip
ElseIf bf < 16:bf=16:EndIf;clip
EndIf
r=gammaTable(rf) + PEDESTAL
If clip = #True
If r > whiteClip:r=whiteClip ;clip at 105 IRE
ElseIf r < 16:r=16:EndIf;clip
EndIf
g=gammaTable(gf) + PEDESTAL
If clip = #True
If g > whiteClip:g=whiteClip ;clip at 105 IRE
ElseIf g < 16:g=16:EndIf;clip
EndIf
b=gammaTable(bf) + PEDESTAL
If clip = #True
If b > whiteClip:b=whiteClip ;clip at 105 IRE
ElseIf b < 16:b=16:EndIf;clip
EndIf
EndIf
Plot(x, y, RGB(r,g,b));MONITOR IS SLIGHTLY UNDERSCANNED
*readBufr + 4
Next
Next
StopDrawing()
Else ;FULLSCREEN = TRUE
*readBufr = scp\mTargetBuf
StartDrawing(ImageOutput(2))
For y = 0 To V_RES - 1: For x = 0 To H_RES - 1
r = (PeekA(*readBufr+2))
g = (PeekA(*readBufr+1))
b = (PeekA(*readBufr))
If process <> #False
rf = r * gain
If clip = #True
If rf > whiteClip:rf=whiteClip
ElseIf rf < 16:rf=16:EndIf;clip
EndIf
gf = g * gain
If clip = #True
If gf > whiteClip:gf=whiteClip
ElseIf gf < 16:gf=16:EndIf;clip
EndIf
bf = b * gain
If clip = #True
If bf > whiteClip:bf=whiteClip
ElseIf bf < 16:bf=16:EndIf;clip
EndIf
r=gammaTable(rf) + PEDESTAL
If clip = #True
If r > whiteClip:r=whiteClip ;clip at 105 IRE
ElseIf r < 16:r=16:EndIf;clip
EndIf
g=gammaTable(gf) + PEDESTAL
If clip = #True
If g > whiteClip:g=whiteClip ;clip at 105 IRE
ElseIf g < 16:g=16:EndIf;clip
EndIf
b=gammaTable(bf) + PEDESTAL
If clip = #True
If b > whiteClip:b=whiteClip ;clip at 105 IRE
ElseIf b < 16:b=16:EndIf;clip
EndIf
EndIf
Plot(x, y, RGB(r,g,b));MONITOR IS SLIGHTLY UNDERSCANNED
*readBufr + 4
Next
Next
StopDrawing()
EndIf
If fullScreen = #False
StartDrawing(WindowOutput(1))
DrawImage(ImageID(1),0,0);DRAW SCOPE TO SCREEN
If H_RES = 1280
DrawImage(ImageID(2),496,294,640,360)
ElseIf H_RES > 1280
DrawImage(ImageID(2),WindowWidth(1)/2,WindowHeight(1)/2,640,360)
EndIf;DRAW CAMERA TO SCREEN
StopDrawing()
Else ;FULL SCREEN
StartDrawing(WindowOutput(2))
DrawImage(ImageID(2),0,0)
StopDrawing()
EndIf
StopDrawing()
Until quit <> #False
Delay(500)
;StopDrawing()
deinitCapture(device)
FreeImage(1):FreeImage(2):FreeImage(3)
FreeMemory(scp\mTargetBuf)
CloseWindow(1)
End