Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WebCam Problems

33 views
Skip to first unread message

BeeJ

unread,
Mar 22, 2013, 5:43:23 PM3/22/13
to
I am having problems getting image data from an internal laptop webcam.
It may be that the drivers just do not support but maybe someone here
has further insights.

I am using the VFW framecallback to get the image data then convert it
to a JPEG file. I need JPEG files.

The callback method looks like:

Public Sub FrameCallBack(ByVal pData As Long, ByVal DataLen As Long)

pData contains a pointer to the data and DataLen shows the length.
DataLen always shows the expected data length but the image created
with StretchDIBits is blank. See code below.

Now I know this code all works because if I plug in a USB webcam
everything works just fine and I get the image in the picCam() box and
convert it and save it as JPEG. So I suspect the laptop internal
webcam driver.

Also, if I call VFW to directly output a bitmap for the internal
laptop webcam it works properly (as does the USB webcam).

So two questions arise.

1) any suggestions to help fix this other than try to update drivers
(done) or to convert the bitmap method to JPEG ? (I can do that but it
is too slow).

2) is there a way to programmatically detect that the image is not
there? Images can be anything up to 1080p equivalent. If I can do
this then I can warn to not use JPEG or automatically switch to just
saving bitmaps and eating up hoards of disk space.


' <snip>
FrameCallbackRemove ' shut off callback

' this is the expected Width and Height of the Frame
lWd = CapWd
lHt = CapHt

With picCam(ePicCam)
.ScaleMode = vbPixels
.Width = lWd ' NOT * Screen.TwipsPerPixelX
.Height = lHt ' NOT * Screen.TwipsPerPixelY
.ScaleWidth = lWd
.ScaleHeight = lHt

Set .Picture = Nothing ' or LoadPicture("")
.AutoRedraw = True

'Debug.Print "DataLen " & DataLen
'Debug.Print "Width=" & m_tBI.biWidth
'Debug.Print "Height=" & m_tBI.biHeight
'Debug.Print "XPelsPerMeter=" & m_tBI.biXPelsPerMeter
'Debug.Print "SizeImage=" & m_tBI.biSizeImage

StretchDIBits .hdc, 0, 0, lWd, lHt, 0, 0, lWd, lHt, ByVal pData,
m_tBI, DIB_RGB_COLORS, vbSrcCopy

.Picture = .Image

End With


Deanna Earley

unread,
Mar 25, 2013, 8:12:18 AM3/25/13
to
On 22/03/2013 21:43, BeeJ wrote:
> I am having problems getting image data from an internal laptop webcam.
> It may be that the drivers just do not support but maybe someone here
> has further insights.
>
> I am using the VFW framecallback to get the image data then convert it
> to a JPEG file. I need JPEG files.
>
> The callback method looks like:
>
> Public Sub FrameCallBack(ByVal pData As Long, ByVal DataLen As Long)
>
> pData contains a pointer to the data and DataLen shows the length.
> DataLen always shows the expected data length but the image created with
> StretchDIBits is blank. See code below.

Seeing as that's not the signature of the real callback that VfW calls,
can you show the code that translates it from:
Public Function capVideoStreamCallback (ByVal lWnd As Long, ByVal lpVHdr
As Long) As Long

Your code below also makes use of the BitmapInfo structure (m_tBI) but
again, omits any creation of it.

It's possible that your problem is stemming from the video
format/bitdepth, or something as silly as the contrast/brightness being
set to 0 (some drivers use this as a default)

> 2) is there a way to programmatically detect that the image is not
> there? Images can be anything up to 1080p equivalent. If I can do
> this then I can warn to not use JPEG or automatically switch to just
> saving bitmaps and eating up hoards of disk space.

It depends on the code I've asked for above.
After checking the header is valid, you can tell if the image data is
all black by looking for non 0 colour values.

I would also recommend moving to WDM for anything more advanced, as VfW
is even more "legacy" than VB6 :) but it's pretty much impossible to use
from native VB6.

--
Deanna Earley (dee.e...@icode.co.uk)
iCatcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

BeeJ

unread,
Mar 25, 2013, 11:54:11 AM3/25/13
to
Deanna Earley formulated the question :
1) if the failed image process generates a file that opens as it is an
image file in any Windows image viewer as sell as loads without error
into a VB picture box but has no visible image what more does the
header tell us? The non-image that is seen is a pastel pink.
Windows Explorer Properties Summary says
Width 640, Height 480, Horz DPI 96, Vert DPI 96, Bit Depth 24, Frame
Count 1.

2) I searched all over for WDM samples and tutorials and documentation.
Found very little. Do you have any sources, links etc?

3) (m_tBI) is unfilled. perhaps a placeholder for the call use. But
remember, this same routine is called when a USB webcam is used and
produces a correct image. So maybe there are some defaults properly
set in the drivers in one case and not the other. I have not yet tried
to examine it after the call. It seems that StretchDIBits is happy
with pixel width, height and the data provided and nothing else. This
is for all webcam resolutions tried from 160x120 to 1920x1080 (USB
webcam only).

Here is the macro <snip 1> for framecallback. I left in all my notes.
<snip 2> is the call to VFW to generate the bitmap; basically tells the
driver to create/capture a full frame and save to the given filename.

<snip 1>
Private Function capVideoFrameCallback(ByVal m_hWndC As Long, tVH As
VIDEOHDR) As Long

' this is where the callback occurs
' the pointers to the data are passed to where the frame is
processed

Dim obj As Object

'<TASK> @@@ capVideoFrameCallback mdlFrameCallback

' FLAGS
' VHDR_DONE Set by the device driver to indicate it is
finished with the data buffer and it is returning the buffer to the
application.
' VHDR_PREPARED Set by the system to indicate the data
buffer has been prepared with videoStreamPrepareHeader.
' VHDR_INQUEUE Set by the system to indicate the data
buffer is queued for playback.
' VHDR_KEYFRAME Set by the device driver to indicate a key
frame.

' Debug.Print "FLAGS = " & tVH.dwFlags
'
' Debug.Print "TIME = " & tVH.dwTimeCaptured ' Milliseconds from
start of stream
' Debug.Print "USER = " & tVH.dwUser ' User-defined data
'
' Debug.Print "BFRLEN = " & tVH.dwBufferLength

Set obj = GetCaptureClassByKey(m_hWndC)
If Not obj Is Nothing Then
fWebCam.FrameCallBack tVH.lpData, tVH.dwBytesUsed

End If
capVideoFrameCallback = 1

End Function 'capVideoFrameCallback

<snip 2>
' save the file
Call SendMessage(g_hCap, WM_CAP_FILE_SAVEDIB, 0&, ByVal
CStr(sDPName))


BeeJ

unread,
Mar 25, 2013, 2:42:07 PM3/25/13
to
Deanna Earley used his keyboard to write :
> On 22/03/2013 21:43, BeeJ wrote:
> I am having problems getting image data from an internal laptop webcam.
> It may be that the drivers just do not support but maybe someone here
> has further insights.
>
>
> It's possible that your problem is stemming from the video format/bitdepth,
> or something as silly as the contrast/brightness being set to 0 (some drivers
> use this as a default)
>
Interesting question but I have failed to investigate fully.

1) Internal webcam: the macro BMP direct looks fine. only the frame
callback looks bad. also the live image looks fine.
Camera Dialog Device Settings / Camera Controls all parameters look
reasonable (nothing pegged)
Internal webcam shows "Select a Video Device" as VC0331 USB2.0 Digital
Camera.

2) USB cam: sometimes resets it brightness and contrast so I get a
black image everywhere: live, framecallback and macro BMP. Don't know
why it does that.

BTW, how in VB6 do I programmatically get the Video Device name as
shown in the Capture Source Select a Video Device: combobox?


BeeJ

unread,
Mar 25, 2013, 6:00:15 PM3/25/13
to
Here is a little back further up the call stack

Private Sub tmrMotionCallbackLaunch_Timer()

' this starts the Motion surveillance

On Error Resume Next
Dim bSuccess As Boolean

tmrMotionCallbackLaunch.Enabled = False

bSuccess = FrameCallbackSet(Me)

End Sub 'tmrMotionCallbackLaunch_Timer

Public Function FrameCallbackSet(ByVal obj As Object) As Boolean

' Set the Method where the Frame Callback goes to deliver a WebCam
Picture Frame
'
' Note: this frame is delivered here before it is presened for view
' so the image can be modified.

On Error Resume Next
Dim hWnd As Long

hWnd = CapHandle

If SendMessage(hWnd, WM_CAP_SET_CALLBACK_FRAME, 0, AddressOf
capVideoFrameCallback) Then

m_colCaptureClasses.Add ObjPtr(obj), CStr(hWnd)
If Err Then
Err.Clear

End If
g_bFrameWait = True
FrameCallbackSet = True

End If

End Function 'FrameCallbackSet


0 new messages