Hmm looks like it's high time to go and make a TLB with all the DirectShow interfaces like I just did for Core Audio. Saw this example then saw how easy ICaptureGraphBuilder2 makes capturing**...
The quartz.dll this project uses seems to have extremely few of the interfaces... is there a more thorough one before I go off on another massive interface conversion expedition?
Is there a particular reason a DLL is being used? Do the interfaces require some sort of background code that a TLB wouldn't support?
-----
* I was looking at this code... if I made such a TLB in a VB friendly form like usual, it looks like an easy direct translation:
A TLB isn't executable code no. Although I went over this when trying to figure out whether a compiled TLB broke the rules against posting binaries and never got a clear answer as to whether one might be able to craft an exploit based on newer TLBs supporting "cpp_quote" with C++ code in it. Never seen anything more than cpp_quote in newer IDL sources though.
I don't think a TLB would be considered a "binary" for purposes of exclusion in an upload here. They have no executable code, being basically a form of predigested source code (metadata) to be consumed by compilers and related tools.
A simple DirectShow TLB would probably not be enough. Many of the low-level DirectShow entrypoints and data structures are not easily consumed by VB and need to be wrapped with a little code to handle the "impedance mismatch."
I'm looking for a simple way to access pixel data from a webcam. I wonder if anybody has made an easy way of accessing a webcam via DirectShow, as a specific purpose build Webcam Directshow DLL file. It's too much trouble to try to figure out how to build up a graph from scratch. I'd like a way to just easilly add a webcam into my program, and have each frame be an event that is fired, that I can then use to access the raw pixel data from the webcam. And I also need to be able to spawn the driver-defined dialog box for controlling the webcam, as well as the default system dialog box for setting things like the output codec/format of the webcam, image dimensions, and frame rate.
I would like it to be a simple to use DLL file, that hides from the programmer all the complexities of graph building.
Seriously though, I haven't found anything like that available off the shelf anywhere. That probably means nobody has ever been motivated enough to create it because as you can see from the rest of this thread there is a ton of work involved. You can look other places and you'll find the same sort of "bits and pieces of the puzzle" here and there but no slick and complete "picture"... er, "ready to hang."
When I started the effort that began this thread I was hoping there wouldn't be too much to it. Surely people were just making this harder than it needed to be? I was wrong.
Seriously though, I haven't found anything like that available off the shelf anywhere. That probably means nobody has ever been motivated enough to create it because as you can see from the rest of this thread there is a ton of work involved. You can look other places and you'll find the same sort of "bits and pieces of the puzzle" here and there but no slick and complete "picture"... er, "ready to hang."
When I started the effort that began this thread I was hoping there wouldn't be too much to it. Surely people were just making this harder than it needed to be? I was wrong.
With VC++, it's theoretically possible to access ALL of the DirectShow framework. Maybe (if you have any VC++ experience) you could take just as much as is required to get a webcam running, and spawn any dialog boxes that might be needed to control the webcam (both driver-provided dialogs for the camera, as well as built-in Windows ones that let you set the format and dimensions of the image), and get the raw pixel bytes from it as a byte array, and then compile a DLL file with those features, so I can use it in my VB6 program.
Are you talking about something different than the C++ code I posted above? That outputs the webcam stream to a file, and there's nothing that would seem to preclude doing it in VB6.
Are you talking about something different than the C++ code I posted above? That outputs the webcam stream to a file, and there's nothing that would seem to preclude doing it in VB6.
The disadvantage is that you have to figure out just which filter corresponds to your camera. There's TONS of filters in the DirectShow framework.
I was looking for a dedicated ActiveX DLL file, or ActiveX control (OCX file), that I could add to my project, and that would encapsulate ALL of the functionality needed for WEBCAM OPERATION (ignoring all the rest of the DirectShow framework), and present me, the programmer, with a single interface for webcam operation, hiding all of the hard-to-do internal "stuff" within the DLL or OCX file.
Well the example above that I'm planning on porting selects the first video input device it finds... there shouldn't be multiple listings for that if all you have is a webcam, and nothing else like a video capture card.
Here is another more streamlined example using FSFWrap.dll along with Quartz.dll for simple webcam video capture. Plenty of room for improvement and features.
It starts and enumerates the Camera filters it can find, adds them to a menu.
User picks a camera from the menu.
Camera capture filter graph is built and preview window displayed, picking up a previously-saved camera config if found.
Snap menu to take a JPEG snapshot becomes visible.
"Camera-name" menu becomes visible with Camera and Capture Config options, Save and Load Config options.
This really duplicates what previous sample programs above do. However it strips away some redundancy and adds a few comments that might be useful to figure out how to repurpose parts of the code in your own programs.
If I stay interested I might go further and try to pick up frame events and implement audio capture. It seems like a simple one-on-one audio/visual chat program could be built without a huge amount of trouble. I may be underestimating the effort required though.
Edit:
Replaced attachment. Had a ridiculous bug in managing the enabled state of menu items, blocking "save" operations. Sorry for the confusion.
Last edited by dilettante; Jun 20th, 2016 at 09:12 PM.
Reason: replaced attachment
I think there's a small bug in your 1.3 demo. If you have never saved a config file, then mnuCameraSave will always be disabled (so you can never save a config file). If you get rid of the Else condition in mnuCamerasCamera_Click then it will be enabled and you can subsequently save settings:
Code:
With New FSFWRAPLib.StreamConfig
.Pin = VidCapPinInfo
If .SupportsConfig = OATRUE Then
mnuCameraSave.Enabled = True
If Exists(App.Path & "\" & mnuCamera.Caption & ".cfg") Then
mnuCameraLoad.Enabled = True
.Restore App.Path & "\" & mnuCamera.Caption & ".cfg"
' Get rid of the following 2 lines to ensure Save config menu option is enabled even if we have never saved the configuration before
' Else
' mnuCameraSave.Enabled = False
End If
Else
mnuCameraSave.Enabled = False
mnuCameraLoad.Enabled = False
End If
End With
I ran into that myself and I believe I fixed it then re-posted on Jun 20th (couple days back). You are right, there was leftover crud from an earlier version and I failed to test thoroughly (clearly my eyes weren't good enough to see it sticking out at me - got to get new glasses ).
I started digging deeper for another project and quickly realized we're about at our limits though. Even FSFWrap.dll only helps just so much and for some things additional typelibs and/or C++ DLLs are required.
Everything we need is all there, but Microsoft never bothered to expose it for use in VB6 and similar langauges. Of course we're used to that by now and this late in the day it probably isn't worth trying to extend what Geraint Davies did for us so long ago.
Ahh sorry, must have grabbed an older version of 1.3 and just got around to looking at it now.
Thanks again for your work on this - it's quite useful as-is even if we're missing out on some stuff that would be available with additional typelibs/dlls.
I'm just glad there wasn't a second place in there with a similar glaring bug... not that there won't be others found, perhaps just a bit less silly.
Too bad we lost out.
It was easier with WIA instead of working with DirectShow. But too many script kiddies ended up using it to pirate videos and Microsoft noticed hardly anyone had started using WIA for webcam capture and such, so most of the support for media files and video cameras was stripped out.
Last edited by dilettante; Jun 23rd, 2016 at 12:37 PM.
Hello, i'm very impressed reading the code samples. My tests with Quartz and FSWrapper worked very well until today. Now my code is freezing in the IDE (WIN 10 latest build) at the end of SetupVideoWindow...
When i compile an executable version, everything works. The same code on another device (Surface pro 4 with rear / front camera runs perfect in the IDE. But the 10 Euro-Cam on my main developer machine won't work in the IDE anymore. Any Ideas?
Now my code is freezing in the IDE (WIN 10 latest build) at the end of SetupVideoWindow...
When i compile an executable version, everything works. The same code on another device (Surface pro 4 with rear / front camera runs perfect in the IDE. But the 10 Euro-Cam on my main developer machine won't work in the IDE anymore. Any Ideas?
I don't really know. What version(s) of my example programs above are doing that?
I have reworked the code a lot for other projects recently, and maybe something there would make a difference. I hope to get it cleaned up so I can post it soon.
My mod starts with your example DS Webcam Snap 3, but since the freezing problem occured, all of your samples are freezing on this machine with this simple usb-cam. I think, it's a problem between the IDE an the cam-driver. When i build a graph with GraphEdit, just with these filters "USB2.0 PC CAMERA" - "AVI Decompressor" - "Video Renderer" the cam works fine. When i compile your samples, the cam worked again as expected. Maybe it's a dependece between the VB6.exe and DirectShow? This cheap cam worked for a week without any probs with the VB6-IDE. Today i will start my tests with an new (maybe better) USB-Cam.
I've found the reaseon, because one of my compiled sample is freezing too. I've searched the registry looking for the name of the sample and i got these entrys:
After deleting those keys everything runs fine, including the VB6-IDE!
In theory you could use this to snap frames rapidly then use something else to stitch those into an MP4 movie. However the frame rate wouldn't be too high and the encoding process would be a lot more work than what we're talking about above.
You probably would want to take some other direction. This just supports camera preview and snapshots.
There might be lots of reasons. As we've found this is a very difficult thing to get to work correctly with every combination of cameras and computers.
There is probably a FilterGraph flaw. That's where you might have to use the Graph Edit developer's tool to experiment. See post #28 above.
Thank you dilettante for open sourcing your code. I have quite a dilemma at the moment and I'm hoping that you or someone else qualified can help.
As a bit of background, I have a legacy program in vb6 that was written by a programmer who is no longer supporting it. As a tech I've managed to make minor changes over the years but now I'm faced with a hardware change that requires either a total rewrite of the original program at great expense or a modification to the existing. Because the new hardware is not as accurate as the original custom hardware I'm trying to use a webcam to course correct (compensate) for the inaccuracy. There are two motors which control xy positioning and there lies the problem. We have many machines doing this and the first one became irreparable. We anticipate this will become an issue in the future with the remaining machines.
I am not a programmer but as I said I have managed to make minor adjustments over the years and I've had experience with programming access 2000 vba. I've made several attempts at capturing the webcam to a picturebox in order to determine the course corrections necessary. It works but my code is too slow. First off I don't need to analyze the entire 640x480 picture and the picture really doesn't need to be displayed at all. At most I only need to analyze a block of 10x10 pixels at a time. As the machine operates the block of pixels will change. How do I either put the select block of pixels from the webcam into memory for analysis OR directly analyze the pixels with getpixel from the dsPreview.ctl? All help will be appreciated. Thanks in advance.
Thanks for the reply dilettante. The analysis and compensation isn't a problem with my current method. It works but the whole process is too slow. I used your code to 1) capture to picturebox1 and then I copied picturebox1 to hidden picturebox2 at the outset. 2) Moved the stepper motors one step. 3) Captured another pic to picturebox1 and compared to hidden picturebox2. 4) Compensated by stepping appropriate motor as needed. 5) Copy picturebox1 to picturebox2. Repeat steps 2-5.
I have yet to figure out how to use bitblt with your code. In fact I don't even know where to start. That is the direction I thought I needed to go. After more thought I don't think I need picturebox2 with my current method. I'm trying to avoid pictureboxes altogether. Any further guidance will be appreciated.
Well once you have a captured image within a PictureBox you should be able to use its .hDC and its .Image.Handle for blitting or fetching the pixel bits.
Looks like the OP for that the link you provided was looking for a moore neighbour tracing algorithm. I wrote one, it works well and it saves the motor steps to an access db for later use. Precisely what he needed for a CNC I presume. I'm not able to look at the code you provided him at the moment due to illness. Within the next day or so with any luck. Thanks dilettante.
The name of the rotate filter is "CSIR VPP Rotate Filter"
My understanding is that the pins from two filters should be connected, but I am struggling with the code to make that happen.
Here is the code from "Webcam Snap":
Code:
Private Sub mnuCamerasCamera_Click(Index As Integer)
Dim Filter As FSFWRAPLib.IFilterClass
Dim Pins As QuartzTypeLib.IAMCollection
Dim RFI As QuartzTypeLib.IRegFilterInfo
Dim FI As QuartzTypeLib.IFilterInfo
mnuCameras.Enabled = False
Set FGM = New QuartzTypeLib.FilgraphManager
Set Filter = Filters.Item(Index)
mnuCamera.Caption = Filter.Name
mnuCamera.Visible = True
Set Filters = Nothing
Set CaptureFilter = Filter.Create(FGM)
Set Pins = CaptureFilter.Pins
For Each CapturePin In Pins
With CapturePin
If .Direction = DIRECTIONOUT Then
If .Name = "Capture" Then
For Each RFI In FGM.RegFilterCollection
If RFI.Name = "AVI Decompressor" Then
RFI.Filter FI 'Adds this filter to FGM. We won't use this FI though,
'we just have to pass an argument to this call.
Exit For
End If
Next
.Render 'Auto-create filter graph, should pick up AVI Decompressor.
SetupVideoWindow
Exit Sub
End If
End If
End With
Next
lblStatus.Caption = " Couldn't find capture pin!"
End Sub
A little refinement. Mainly small bug fixes in Form menu handling, a tweak to the logic for creating a StdPicture snapshot, etc.
Big change: Replaced a bunch of inline DirectShow related code in Form1.frm by a new DSPreview.ctl UserControl.
DSMini3 is the improved version of the single cam/snapshot demo (DSMini1).
DSMini4 is the improved version of the dual-cam demo (DSMini2).
When I try to run it on my Windows10 machine for evaluating the code, it gives me the error as shown in the screenshot below. Specifically, I am running DSMini4