# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  VB6 - DirectShow WebCam Minimal Code

## dilettante

There are a number of possible APIs in Windows for previewing and capturing from webcams.  One of the most popular for its broad support on Windows versions and its relative ease of use when requirements are simple is the AviCap/Video for Windows API.

But a downside of VfW is that the driver model Windows uses to support video capture devices changed after the end of 16-bit Windows (Win3.1, etc.).  This means several things, but most commonly frustrating is that instead of mapping multiple webcams as device 1, 2, ... 9 they work through a compatibility layer thats maps _one of them_ as device 1.

This can make selecting the webcam to use difficult to impractical.  And using more than one webcam at a time doesn't seem possible.

The usual answer has been: "Use DirectShow instead of VfW."


*DirectShow vs. VB6*

One problem with using DirectShow is that Microsoft seemed to have lost enthusiasm after providing only a partial implementation.  The parts of DirectShow (also called ActiveMovie) we did get a VB6-friendly API for are implemented in the Quartz.dll which should be part of Windows in any recent version (and perhaps even back to most "late" Windows 95 versions like 95B or OSR2.x).

You can still do a lot of things using just what we have, but the finer points of using DirectShow in VB6 require a 3rd party DLL to wrap a few more DirectShow C++ interfaces.


*This "Minimal Approach" to VB6, DirectShow, and WebCams*

What I have done here is to try to stretch things as far as I could manage.

Here is what you _can_ do:

Choose among your webcams and display a live preview image."Snap" and display a still image from the webcam feed.

Here is what you _can't_ do:

Get a "friendly" list of just the usable webcams.Control the capture resolution/dimensions or other capture settings or even raise the built-in dialogs to let the user do so.


*The Demo*

What I wanted to accomplish was to see how far I could get with the two tasks we _can_ perform without using any 3rd party libraries.


Form1

This is the main UI Form, which uses Form2 as a dialog when requested via its menu ("Add new camera...").

There is a lot more code there than I'd like that does nothing except manage the menu.  As you add cameras they are added to the menu.  There is also code there to load and save "settings" which include the index of the selected camera and list of added cameras by name.

Basically a lot of UI-management code which I hope doesn't obscure the DirectShow-related logic itself.

The other ugly hunk of code in there is the BuildGraph() function, which is a small interpreter of a sort that processes a "filter script" and a "connection script" to add the necessary filters and connect them to create a webcam preview graph for DirectShow.


Form2

Since I can't find any way to find just the list of usuable webcams, the user has to pick them out from among the full list of available "filters" (as they are called)!  Not practical at all for a real application, but it works for a test/demo program.

That's what Form2 in the demo Project is for, a dialog from which to pick new cameras.

Note that your camera might appear there once, twice, or even three or more times depending on how many "filters" of different kinds it supports.  Just pick any of them, the demo program will just use the name and sort it out later.


Module1

This contains some GDI and OLE API calls to convert the captured frame from a "packed DIB" into a StdPicture object that can be used with PaintPicture, etc.  This raw StdPicture is created using a "memory DC" so there are some limits on how you can use it, i.e. simply assigning it to a PictureBox.Picture has some issues.

But in this demo we need to scale it anyway since we can't control the actual capture dimensions.

You could rework this passing in the hDC of a Form, PictureBox etc. I suppose.


*Running the DSMini1 Project*

The attached ZIP archive contains the entire Project.

All you should need to do is unzip the archive, then open the Project in VB6.  If you have a webcam connected, you can just go ahead and run it within the IDE.

From there you will have to "Add" your webcam by browsing the filter list.

After a valid add, the live preview starts immediately at the left.

Clicking on the Snap button should take a snapshot and display it in the PictureBox at the right.

If you have another webcam connectd you shuld be able to add that one too.  Once you have two or more added you can choose among them via Form1's menu.

Settings are persisted in Settings.txt, so a subsequent run should save you the trouble of picking cameras again.


*Remarks*

I don't know what webcams this will work with, but I know it works with two very different ones I've tried so far.

----------


## dilettante

To show that you can use these techniques to run multiple webcams, I give you DSMini2.

The menus are rearranged, the settings file contents are slightly different, and the snapshot function has been pulled out, but now if you have multiple webcams you can preview two at once.  Pretty much all of the other comments about running DSMini1 apply to DSMini2.


One thing not mentioned about DSMini1 is that it scales the views to fit the camera's aspect ratio.  The same applies in DSMini2, but it might be more noticeable if your webcams have different aspect ratio settings: one view will be "shorter" than the other one.

----------


## dilettante

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).

----------


## dilettante

Hmm, DSMini3 has a small flaw.

When you select a camera to preview that has a different aspect ratio from the default one it expects, it fails to adjust the "snapshot" PictureBox.  The result is some stretching or squishing of the snapshot.

Not a big deal but something to consider.  If you need to deal with it I'm sure you can on your own.  Not worth reposting an update I suppose.  DSMini1 was handling this issue properly though.

----------


## ColinE66

I don't have a webcam attached to my PC but, nonetheless, I lifted some of your code into a VB6 project of my own as I was interested in your GetCurrentImage implementation. It does indeed work very well but is, however, a lot (noticably!) slower than using the SampleGrabber approach.

Is this because of your over-generosity of the buffer size or is it just intrinsically slower?

----------


## ravemaster

yes I have checked it but i only give me black picturebox, no image at all, only black.  that is why I wonder why that ocx is having no problem except that it has no save to file or to db capability.

attach is the screenshot of the result

----------


## dilettante

> I don't have a webcam attached to my PC but, nonetheless, I lifted some of your code into a VB6 project of my own as I was interested in your GetCurrentImage implementation. It does indeed work very well but is, however, a lot (noticably!) slower than using the SampleGrabber approach.
> 
> Is this because of your over-generosity of the buffer size or is it just intrinsically slower?


SampleGrabber works without pausing the filter graph, but GetCurrentImage requires that.  However I don't know of any way to use SampleGrabber in a VB6 program without additional helper DLLs, so GetCurrentImage is useful in "first steps" examples of working DirectShow programs.

----------


## dilettante

> yes I have checked it but i only give me black picturebox, no image at all, only black.


Could be lots of things.  Might be that your webcam has default settings leading to a black picture.  Or it might be that the filter graph I am building doesn't work with your camera.  This is where you would need to experiement since there may not be a universal solution.

Start by working with the graphedt.exe utility from the DirectShow (now part of the Windows) SDK.

What camera do you have?




> that is why I wonder why that ocx is having no problem except that it has no save to file or to db capability.


Ocx?  What ocx?

Save to file or DB?  This is a code sample.  If you want a full blown program for some purpose you can add more code or hire a programmer.  This is CodeBank, not UtilityBank.  :Stick Out Tongue: 

Plus at this point saving the image isn't too useful.  First you need control over the capture format or risk getting nothing but tiny low-res images.  This kind of control also requires a 3rd party helper DLL.

----------


## dilettante

Ok, here is a more elaborate example DSElaborate5, based on DSMini1 & DSMini3 (one camera, with snapshot capture).


*Background Info*

I have not found a way to get these features without a helper DLL that can wrap a few more DirectShow interfaces in "Automation" (ActiveX) form.

I decided to use what _appears to be_ the widely used FSFWrap.dll from Geraint Davies Consulting Ltd. (GDCL).  I says _appears to_ be widely used, because oddly enough some heavy searching of the Web didn't turn up a single useful example of the use of this library.  All I found was an example from GDCL that doesn't seems to work with cam-capture, and somebody's attempt to convert that same VB6 example to VB.Net 2XXX (not sure which VB.Net, don't care).

My conclusion:

This was never that popular, or it used to be and a lot of posted examples have disappeared since 2005 or so, or it is quite popular but most users are too lazy or greedy to share by posting helpful information and working code...

... or I'm just not that great at searching.  :Cool: 


*This New Example*

In order to run this example yourself you will have to obtain and install this library.  I'm attaching the instructions along with a .DEP file that the author failed to provide for the library.  I can't provide the DLL, because (a.) we aren't supposed to attach binaries and (b.) it isn't mine to hand out.

So here are the new features:

Camera selection dialog is now built selectively, i.e. it should list your cameras and only your cameras.Capture (pin) properties can be viewed and altered when a camera is started.Camera (filter) properties can be viewed and altered once a camera has been started, and these changes are "live."
I can't find a way to make the pin properties pages work properly except as part of building the filter graph and starting it.  Perhaps somebody else has an alternative that allows changes to these while the graph is running.


Since I now have a way to configure the pin properties (mainly the capture dimensions) I have added an unrelated feature:

Both Snap and Snap+Save (to JPEG file) buttons are present.
And "Snap to Byte array" could be added.  The code is there, you just need Edanmo's olelib.tlb for that.  See the new GPP2J.cls module's header comments for details.


I hope you find this new version interesting, if not useful.



mod comment - Link to FSFWrap removed as it's closed source.  Its easy enough to google for though.

----------


## dilettante

> SampleGrabber works without pausing the filter graph, but GetCurrentImage requires that.  However I don't know of any way to use SampleGrabber in a VB6 program without additional helper DLLs, so GetCurrentImage is useful in "first steps" examples of working DirectShow programs.


Ok, so that's what the docs say.

But I found somebody skipping the pause yet doing GetCurrentImage() calls... so I tried it and things are working just fine!

----------


## dilettante

Ok, one more time...

This version is the same as 5b above, but with a change to the filter graph and method by which the graph is connected.  All told just a few lines difference.

It _might_ address the "black picture" problem though.


*ffdshow*

It is also worth noting that if you have ffdshow installed, a dialog from it may appear when testing in the IDE and again for the compiled EXE.  It seems to maintain a "blacklist" or something though, so you can choose "don't show this again for this program" and you won't be bothered again.

Of course you'll get that both for VB6.EXE (runs in the IDE) and the compiled program, separately.  And you can always opt to be reminded each time instead if this matters to you.

----------


## ColinE66

I actually use capstill.dll in my program (link in sig) and I do recall seeing some code at his site for working with webcams but, if memory serves, it accompanied his fsfwrap.dll - you might want to take a look at that.

EDIT; sorry for confusion if you happened to read the pre-edit version of my post; capstill.dll is the one that facilitates the SampleGrabber, not fsfwrap.dll. Within one of the demo projects (can't remember if it was capstill or fsfwrap) I recall seeing some code related to webcams.

----------


## dilettante

I still have to get around to looking at the Sample Grabber.  I see that it is a deprecated filter with Merit set to MERIT_DO_NOT_USE, but what isn't deprecated by Microsoft these days?


The point of this thread was to try to demystify the use of DirectShow webcam capture in VB6.  I'm not sure that this can be done once you start requiring extra helper DLLs.

My examples 3 and 4 above are refinements of 1 and 2 and don't introduce anything complex.  They also get results as good or better than what most people are doing with the older VfW API anyway.

What 1 through 4 lack is the ability to set the most minimal capture params, such as the capture image size.  While my several stabs at example 5 address this, it is indirect (i.e. via the properties dialogs).


So all I really care about beyond this is setting those within the program itself, in code instead of through dialogs.  Well, that and trying to figure out where the "black picture" problem comes from for some cameras or users and fixing that if possible.

----------


## ColinE66

OK. I was just trying to help as earlier you said this:




> I decided to use what _appears to be_ the widely used FSFWrap.dll from Geraint Davies Consulting Ltd. (GDCL).  I says _appears to_ be widely used, because oddly enough some heavy searching of the Web didn't turn up a single useful example of the use of this library.  All I found was an example from GDCL that doesn't seems to work with cam-capture, and somebody's attempt to convert that same VB6 example to VB.Net 2XXX (not sure which VB.Net, don't care).
> 
> My conclusion:
> 
> This was never that popular, or it used to be and a lot of posted examples have disappeared since 2005 or so, or it is quite popular but most users are too lazy or greedy to share by posting helpful information and working code...
> 
> ... or I'm just not that great at searching.

----------


## dilettante

Thanks, I missed your link.  I normally have signatures turned off since so many are huge blobs of images and other distractions.

----------


## dilettante

I tried 5b with a laptop having a camera identifying itself as _Chicony USB 2.0 Camera_ and it works there too.

One quirk I did see was that if I changed the capture dimensions from those it defaults to (which are never the dimensions marked "(default)" in the properties dialog???)... the image can come up very dark.

But with this dark image, if I then choose the  Configure camera properties... dialog and once that pops up I click on the Default button there... the camera seems to automatically adjust the exposure to something usable.

I'm not saying this is the root of the "black picture" issue, but it did seem odd.

----------


## sambra22

hi 
first thank you a lot for the app it helped me a lot 
i added it to my project 
i still new to programming i have 5 month now 
my only problem is  :
is there a way to filter the list items to show only the camera drivers because there is a lot drivers shown 
thanks for help

----------


## dilettante

To limit the list of filters to _capture_ filters (cameras) you need to use a 3rd party helper library.  That is because the necessary interfaces to do this in VB6 were not provided by Microsoft.

See post #9 and later for examples of this, using the popular helper library FSFWrap (free).  Those are the "Elaborate" examples: 5a, 5b, and 5c.

----------


## sambra22

hi Mr delettante :
thank you a lot for the help
i did it it works great thanks a  lot  so much

----------


## sambra22

hi  delettante 
i need an advice from you if possible
how i can learn how to use any library file 
for example i want to learn how to use twain32.dll or FSFwrap.dll 
or any other dll file what is the best way thanks

----------


## dilettante

You need to get the DLL's documentation.

For FSFWrap there isn't much that I can find except what its author posted years ago.  So to use it you have the few hints there, his sample programs there, what you can work out using the Object Browser in the VB6 IDE, and what you can guess based on the C++ interfaces documented in the MSDN Library.

As far as I can tell not many people ever did much with FSFWrap, or if they did they never wrote much about it that I could find on the Web.

Documentation can be as hard to create (or harder) than writing the code itself.  So many free libraries don't have much.

The TWAIN API is very old (though still popular).  But because it is old it can be very hard to find any Microsoft documentation for it now, plus it is "owned" by http://www.twain.org/ so you might try there.

----------


## sambra22

hi
so to learn how to use any library i have to get its documentation  because its always seems for me that the codes is hard to learn and understand 
thank you for your advice 
thanks a lot

----------


## ladoo

xxxxxxxxxxxxxxxxxxxxxxxxxxx

----------


## dilettante

What you have posted is an example of using AviCap in the most simplistic fashion possible.

_I see you have edited this out of post #23 now._

This is extremely common and there are quite a few CodeBank examples already posted.  Your program also makes use of the clipboard in way that programs _never should_ when at all possible.  There are far better AviCap examples here in the CodeBank that _do not_ destroy the user's clipboard data.

And your attachment has nothing to do with using DirectShow from VB, which is what this thread is all about.


The reason to try to use DirectShow instead of AviCap is that it offers your program much more control over capture formats and camera settings, allows selection among multiple cameras, capture from more than one camera at a time, and offers other potential advantages.

That's why this thread is here: to help people start programming using DirectShow instead of the old AviCap API.

----------


## ladoo

:Big Grin: system is overheating...............................................cool down

----------


## SpaceDonkey

Hello,

First, thanks for this thread.

I tried 5C but no luck, I keep getting 'BlueGraph error' , tried with several webcams. (Win8 x64 btw)

----------


## Mike Scott

downloaded the DSMini4.zip and find it works great with a USB cam, but not with a video to USB adapter.
In this event, the EasyCap adapter.   It sees the cam as 'SMI grabber device'  (which works as I can see the pic in other apps), but when I try preview I get-
----------------------------------
Selected camera for preview 0 failed, may not be connected
SMI grabber device
BuildGraph error 1
----------------------------------

Any suggestions?

----------


## dilettante

> I tried 5C but no luck, I keep getting 'BlueGraph error' , tried with several webcams. (Win8 x64 btw)





> downloaded the DSMini4.zip and find it works great with a USB cam, but not with a video to USB adapter.  In this event, the EasyCap adapter.
> 
> Any suggestions?


I don't have a Win8 test system set up but I would expect it to work there with no problems.

However these programs are only able to handle some generic cases so finding webcams that won't work is very likely.  These sample programs are probably best treated as _examples_ of how you can use DirectShow in VB6 programs.

DirectShow covers a large set of multimedia operations through "building blocks" and your programs need to "assemble" several blocks together to "spell a word" (to stretch an alphabet-block analogy).  These programs are making assumptions about the "block" at the beginning and the "block" at the end and try to assemble the necessary "blocks" to span the gap between them.

It is a little more complicated even than that makes it sound.  Every "block" can have zero to many inputs and zero to many outputs, and your program needs to string the blocks together by joining the right outputs to the right inputs.

Your capture device (camera) may not have the particular output "pin" as they're called that my programs here expect.  Or it might have the right output pin, but it may require another intermediate filter block to transform its output data stream.


To handle things truly generically (to write a "universal" program) you'll probably need to understand the process better than I do, you'll need more complicated code, and it may not even be possible in VB6 since only a few items are made available in a form easily used in VB6.  The FSFShow wrapper helps, but may not make enough of DirectShow available to do the entire job.


If you have the Windows SDK you'll find that the old DirectShow SDK has been merged into it.  This gives you a tool to play with called graphedt.exe ("GraphEdit"):


This might give you something to experiment with so you can improve what I have tried to do in these sample programs.

Of course translating from there to a VB6 program can be tricky, and it will require that you study the DirectShow documentation in some detail.  But perhaps my sample programs and the FSFWrap author's samples will help get you there.

----------


## Mike Scott

> I don't have a Win8 test system set up but I would expect it to work there with no problems.
> 
> However these programs are only able to handle some generic cases so finding webcams that won't work is very likely.  These sample programs are probably best treated as _examples_ of how you can use DirectShow in VB6 programs.
> 
> DirectShow covers a large set of multimedia operations through "building blocks" and your programs need to "assemble" several blocks together to "spell a word" (to stretch an alphabet-block analogy).  These programs are making assumptions about the "block" at the beginning and the "block" at the end and try to assemble the necessary "blocks" to span the gap between them.
> 
> It is a little more complicated even than that makes it sound.  Every "block" can have zero to many inputs and zero to many outputs, and your program needs to string the blocks together by joining the right outputs to the right inputs.
> 
> Your capture device (camera) may not have the particular output "pin" as they're called that my programs here expect.  Or it might have the right output pin, but it may require another intermediate filter block to transform its output data stream.
> ...


Unfortunately, the SDK kit looks like it's for Win8 only. I'm on XP  :-(

----------


## dilettante

> Unfortunately, the SDK kit looks like it's for Win8 only. I'm on XP  :-(


When you snooze you lose I guess.  XP is dead and cold now with Vista on the chopping block next.

There should still be a Windows 7 SDK for a few months.

And you can still order old SDK CDs for a shipping fee from SDKs.


But as far as I know even the Win8 SDK download should install fine on an XP system.  Just note that a lot of old stuff is gone and some of the new stuff won't run on XP.


Also note that your old MSDN Library CDs that VB6 uses for it online Help contain most of the C++ and VB6 DirectShow documentation that exists.  The October 2001 issue is best, but any from shortly before then should be Ok too.

----------


## redp

> However these programs are only able to handle some generic cases so finding webcams that won't work is very likely. These sample programs are probably best treated as examples of how you can use DirectShow in VB6 programs.
> 
> DirectShow covers a large set of multimedia operations through "building blocks" and your programs need to "assemble" several blocks together to "spell a word" (to stretch an alphabet-block analogy). These programs are making assumptions about the "block" at the beginning and the "block" at the end and try to assemble the necessary "blocks" to span the gap between them.


hello Dilletante!

*This is Red from the Philippines.*

I've tried your webcam demo number 2*(DSMini2)* and it worked for me.

However, when i tried doing some video saving stuff, it caused me several sleepless nights because 
i can't seem to get it working. in fact, i don't know how to start. I Googled sample codes BUT it gave me
lots of C/C++/C# codes instead of VB6. The closest VB6 code that i tested are your sample codes posted here.

Some say that VB6 can't do deep webcam programming, instead they recommend C/C++/C#..
BUT i don't believe it. I've seen how you code and i know that you do webcam recording. You have done 
capturing "pins" in your codes "but the saving to file" part is not included..

I know there are others out there that use classic VB6 BUT don't have webcam video recording in their programs.
Since you are an expert in this field, please share us a sample code on how to record the "capture pin" while the 
"preview pin" is displaying the video. Another minimal code will do.

see attached images:

----------


## dilettante

Sorry Red,

I'm no expert, I was only playing with it a bit to see how far I could get without using helper libraries.  Then I looked around and found one simple helper library and played with that a little.

It looks like you have dug a little deeper.  Maybe you can get AVI writing working and post sample code for us to look at here.

----------


## ColinE66

There's a File Writer filter that comes with windows that can be added to the graph. I've never used it myself but have a Google....

----------


## redp

*Big thanks to your reply Dilettante..* 
sorry, mispelled your name from my previous post  :Smilie: 

i'll dig some AVI stuff then post the codes here when i'm done.
Again, the codes you posted are very helpful to non-experts like me (i consider you as an expert).

BTW, i tried FFMPEG to record webcam's video.
It did work but you need to "STOP" the graph from VB6 ==>  fgmVidCap(0).STOP

From what i saw, there should ONLY BE 1 INSTANCE of an "OPEN webcam"
before it pushes with the recording. 
Meaning, if you want to use FFMPEG to record a webcam's video, STEP 1 is to "close that particular webcam".
STEP 2 is the the FFMPEG execution.

Here's how i did the recording:
*ffmpeg -t 00:00:30 -f dshow -i video="USB Video Device" -r 30 -s 480x320 -y sample_1.AVI*


-t 00:00:30                            time to record is 30 seconds
-f dshow                                it uses DirectShow? i'm not sure
-i video="USB Video Device"       video input comes from my cheap USB Webcam
-r 30                                     rate is 30 frames per second
-s 480x320                             video size
-y sample_1.AVI                      output name, -y means overwrite if file exists


Dilettante, i need to continue previewing my webcam WHILE the FFMPEG code is executed.
Any suggestion?

Thank you.

----------


## redp

*Thanks for your reply ColinE66!*

 :Smilie:   yes, sure i will Google what you said.
Hope i can find it.

----------


## dilettante

> Dilettante, i need to continue previewing my webcam WHILE the FFMPEG code is executed.
> Any suggestion?


There may be DirectShow filters that can split the data into two paths (sort of a "Y adapter").

----------


## redp

Yes Dilettante, i agree with you... That "data(video) splitter" exists somewhere. Many have done it using C/C++/.Net..

For now, I still want to do it with classic VB6.. Gut feel tells me that it can be done.

Anyway, when i'm done with this splitter thing, i will come back here and thank you again  :Smilie: 

- Red

----------


## Schmidt

There's two default-splitters in the DirectShow-Filterlist:
- one is the "Smart Tee"
- and the other one is the "Infinite Pin Tee Filter"

the Smart-Tee is suitable in Video-scenarios, whenever a given capture-device does not already offer two separate  Capture- and Preview-Pins.
Internally the splitting is ensured - but with a preference of the stream which goes out on the Capture-Pin - that ensures a better behaviour with regards to dropped frames -
and that capture-pin is usually, where Video-encoders and another standard-filter, the "Avi Writer Filter" usually make one "downstream-path", whereas the Preview-Pin
leads into the usual "Video Renderer"-Filter as the other endpoint.

The "Infinite Pin Tee Filter" does not prefer one splitted stream over the other - it tries to provide the same stream-samples across all branches - it is the more generic one.

Below is a ScreenShot of my updated NewGraphBuilder-example, showing the "Smart-Tee in action" 
The NewGraphBuilder-App (with the additional help of three typelibs) is now covering nearly all the functionality 
of the original Builder-example which came with the FSFWrap.dll-Helper-lib.

I've also cleaned up the code of the original Builder-Example, which is now reduced to about half the lines it formerly had.

The used Typelibs are:
- ActiveMovie Control Typelib      (that's the usual one, which is always useful in VB6/DirectShow-contexts)
- MS Video Control 1.0 Typelib    (this was offering such nice interfaces as IBaseFilter, IGraphBuilder etc. - so no need to define them in ones own typelib)
- Edanmo's OleInterfaces and functions  (for more generic OLE-interactions per IIDs - but also has IPersistStream- and other interfaces, allowing for *.grf loading/saving)

In the Zip-Archive I've included Eduardo Morcillos olelib.tlb (later on there's no need to include it into your setups) - and the other two are system-standard-libs.

----------


## redp

> Below is a ScreenShot of my updated NewGraphBuilder-example, showing the "Smart-Tee in action" 
> The NewGraphBuilder-App (with the additional help of three typelibs) is now covering nearly all the functionality 
> of the original Builder-example which came with the FSFWrap.dll-Helper-lib.


*Schmidt, glad to hear from another expert(you are truly a master in this regard)..*

I will try the attached code then come back.
And to _Dilettante/ColinE66_, finally _Schmidt's code_ is the answer to the "splitter" problem..

Though I haven't tested it, i'm thanking you Schmidt for this contribution in behalf of those users who prefer classic VB6.
This is a huge help from non-experts like us.

----------


## Schmidt

No need for "praise in bold letters" (makes not only me feeling a bit uncomfortable I'd guess) ... 

Your: "I will try the attached code then come back" - is already enough. :-)

As for playing around with the Builder-App ...
Anything you are able to "click together" (Graph-wise, with your Mouse), you should be
able to accomplish (finally, in your own Application) also per direct code.

If you were able to construct a certain, well-working graph (and know all the filter-members
who make up this graph) - then try to achieve the construction in as few "Click-steps" as possible.

Especially the [Connect Downstream...] button (with its CurrentPin.Render-call behind it)
can be a big help in attempts on "cutting down the amount of actions until a certain graph is running".

Also "inverse graph-construction" would be possible this way - e.g. when you use the 
[Connect Downstream...]-Button to automatically construct larger parts up to their endpoints - 
and then if the result is not satisfying, but only in a few "last parts" -> just step-backwards, 
removing Filters on the graph - and then construct only what you deleted anew (with better
suiting filters, to reach your endpoints).

There's still a lot one could do with regards to "easing graph-construction even more for VB-Classic" - 
but that would require (if done correctly) a special wrapping of all the important classes who take part
in such DirectShow-scenarios:
cGraph
cFilter
cPin

'more comfortable Source-classes
cVideoInput
cAudioInput
cFileInput

'comfortable to use Classes "in-between"
cSplitter
cMuxer
cEncoder
cDecoder
cSampleGrabber

'more comfortable to use EndPoint-Classes
cVideoEndpoint
cAudioEndpoint
cFileEndpoint


That's not all that much - but each of those Objects could (and should) offer nice Properties, nice 
VB-friendly Enumerators (wrapped in VB-Collections) - and much better Find- and "Plug-together"-
comfort-functions ... best done in a way, so that all the used Typelibs and Interfaces remain 
hidden (in case those new Classes are wrapped in a ActiveX-Dll-Project) - so that the end-user
of this DShow-wrapper-Dll would need only to check-in this single reference into his DirectShow
related projects (the references to quartz.dll, msvidctl.dll and olelib.tlb could remain hidden in the Dll-Project).

But maybe we should discuss this not in this thread, but start a new Thread for that here in the
code-bank. I'd be willing to do some ground-work and post Implementations for some of the 
BaseClasses as: cGraph, cFilter, cPin and e.g. cVideoEndpoint and maybe also cSampleGrabber - 
it would be up to the community, to fill in the blanks (the remaining comfort-classes +  functionality 
within those classes). 
Especially when dilettante would join in, such an encapsulation could evolve nicely I'd think.

Olaf

----------


## ColinE66

I'd be happy to contribute to such an effort and have more experience than most with regard to graph-building in VB6. In particular, I am very interested in a robust SampleGrabber. Geraint Davies capstill.dll is fine up to a point, but will only accept 24bit RGB inputs and some upstream filters are not always willing to provide this! An overlay filter would be great too as would (getting greedy now!) a filter that one could use to adjust RGB, HSL on-the-fly.

----------


## Schmidt

Ahh, Colin ... since we know each other for so long now - and due to your Vee-Hive-background, I counted you in automatically already... sorry. :-)

Olaf

----------


## ColinE66

That's fine. I've been looking forward to the day that vbRichClient tackles DirectShow but didn't like to ask! ;-)

----------


## dilettante

I might be able to help a little, but right now I have a contract that is eating up a lot of my time.  I'll look for the new thread and try to contribute where I can.

I haven't followed how vbRichClient has progressed but I'm not sure a single gigantic DLL with a mixed bag of things in it meets everyone's needs.  Perhaps I haven't given the idea enough thought but I prefer things to be more granular.

I have a hard time "selling" the idea of projects dependent on large 3rd party libraries.  My clients have been bitten badly before by such things.

----------


## Schmidt

> I might be able to help a little, but right now I have a contract that is eating up a lot of my time.  I'll look for the new thread and try to contribute where I can.


Ok - just in case... this new DirectShow-wrapper-stuff will not have a RichClient-dependency... ;-)




> I haven't followed how vbRichClient has progressed but I'm not sure a single gigantic DLL with a mixed bag of things in it meets everyone's needs.  Perhaps I haven't given the idea enough thought but I prefer things to be more granular.


As for "giving the idea enough thought" - please do ... 
- when you write "single gigantic DLL with a mixed bag of things" - then think: "VB-Runtime-alternative"
(-> msvbvm60.dll is pretty much the same "mixed bag", containing beside the "compiler-runtime-functions" also 
- a Form- and a UserControl-engine with dynamic-add/remove, 
- a GDI-based drawing-engine supported on different "Canvases", 
- a set of Controls, a Collection and a few other classes I've perhaps forgot).

The RichClient-development aims at replacing the msvbvm60.dll in the long-run completely.
Because of that it is based on platform-independent libs already (in its two most "weighty" parts; the DB-engine and the Rendering- and Control-engine).

As for Deployment-size (in modern LZMA-format, 7zip-archived):
VBRuntime: msvbvm60.7z = 519KByte
RichClient: RC5BaseDlls.7z = 1634KByte - so roughly 1MB more "to ship or to download" (which is still OK these days for the "bunch of additional class-functionality")




> I have a hard time "selling" the idea of projects dependent on large 3rd party libraries.  My clients have been bitten badly before by such things.


You mean "large 3rd party libs" as in e.g.: ... 'ADO' for example? ;-)

Just joking - but I think you see where I'm getting at ...
I mean, there *were* some problems with ADO-typelibs, caused by "the vendor" ... 
and wellknown fixes for that in the meantime too - sure - but then... same thing recently with the CommonCtls...

Not sure what could go wrong in case of a RichClient-dependency in this regard ... what you (or your customers) should fear?
MS would need to break COM completely - to prevent the instantiation of COM-classes from the RichClient - but in this case no VBClassic-App would work anymore.
I'm the last person who has an interest in "breaking VBClassic-Apps" - and a bit of trust with regards to:
"Stuff from Schmidt" should be there in the VBClassic-community I hope (maybe not yet in this forum here, but I'm working to change that <g>)...

But before getting more Off-Topic - maybe we should continue per Mail?

It's just - there's a lot of still enthusiastic and young developers here in the Forum (to my surprise, being a late-comer to the party here).
Young guns, who have loads more "coding-power-per-day" compared to us middle-aged or "already somewhat older" devs who have to "make good with experience".

I'd like when more experienced VBClassic-devs would join the efforts to come up with a new IDE and a new Compiler 
(sharing in the help-efforts of "channelizing and directing the enthusiasm of the younger devs" a bit).

So, yeah - I'd like when you could throw your weight into the idea as well - and as for "daily work" - 
I'm moving slowly with all that too (as my spare-time allows) - but every year there's more groundwork done.
As said, a mail would be nice - maybe I'm able to convince you finally... :-)

Olaf

----------


## dilettante

> - when you write "single gigantic DLL with a mixed bag of things" - then think: "VB-Runtime-alternative"...
> 
> The RichClient-development aims at replacing the msvbvm60.dll in the long-run completely.


Yeah, I thought this might be the direction.




> You mean "large 3rd party libs" as in e.g.: ... 'ADO' for example? ;-)


Well Microsoft did indeed recently cause some ADO grief (Win7 SP1 comes to mind) but I was thinking of large sets of 3rd party controls you can't get anymore.




> I'm the last person who has an interest in "breaking VBClassic-Apps" - and a bit of trust with regards to:
> "Stuff from Schmidt" should be there in the VBClassic-community I hope (maybe not yet in this forum here, but I'm working to change that <g>)...


Er, don't point at those UseNet groups if you want credibility.  A veritiable _Mos Eisley Space Port_ of the worst VB6 programmers in the universe in recent years.




> But before getting more Off-Topic - maybe we should continue per Mail?


Thanks for the invitation, perhaps once I get more settled.  I'm doing a lot of travel these days chasing contract work, and mostly come in here instead of vegetating watching television while sitting in motel rooms.

I'm not sure how else you might move forward though. VB Classic (A True VB 7.0) has been started though your goals may differ and I'm not sure how the rules work for threads in that forum.

But I will give it more thought.

----------


## Schmidt

As for "not pointing at those Usenet-groups if you want credibility"...

You're probably right with your "Mos Eisley Space Port"-analogy (the UseNet as a whole goes this route... sadly, I might add).
But that this automatically would imply an: "only the worst programmers imaginable post there" - I'd doubt.
I mean, 'Nobody' could reach your conclusion here, if not from occasional UseNet-lurking: ;-)




> If that Schmidt guy takes an interest he might have more detail to contribute.  He dives deeper into COM and VB issues than most of us need to.


Sorry to dig that up, but a bit of "self-defense" is in order I think...? :-)




> I'm not sure how else you might move forward though. VB Classic (A True VB 7.0) has been started though your goals may differ and I'm not sure how the rules work for threads in that forum.


Just posted a reply in the thread you linked to - maybe we can continue the discussion (about "RichClient and stuff") there - because I've always seen (and developed) it in this larger context.


Olaf

----------


## dilettante

Nothing to defend against.

You can find anything anywhere.  My only point was that the VB newsgroups are dominated by people who don't ever seem to get very good at programming, almost as if nobody else will have them.  I wasn't implying that anyone who ever posted there is hopeless though.  There is just a bit of a reputation there.

----------


## redp

It's Expert-to-Expert talking here  :Smilie: 
Count me in as one of your followers.

About my problem from this thread (Saving webcam video to AVI.. Capturing while Recording),
I'm resting my case. Olaf Schmidt's sample code is the answer though i can't figure what to do.
I can't figure how to "assemble/extract" that part where the codes remaining in the program(Dilettante's DSMini2) 
are those that solve my problem..

I don't want to bother any of you guys since you have a more important things to take care of.
It's going to be too much if i still ask you to do it for me.
I'll continue playing with Olaf's code until i solve my problem.

BTW, Dilettante's sample code is very important.
It was an eye-opener for me to see other experts work like Olaf and ColinE66.

Lastly, to Olaf: i didn't use bold letters anymore but praises, yes. You all deserve it.
Thank You A Lot.

Red

----------


## dilettante

Using the MS Video Control 1.0 Typelib is an eye-opener for me too.  I've never done much with DirectShow and that little was a long time ago, so I was just trying to see what results I could get.  My failure to mention it merely means I was completely ignorant of this second typelib, and wish I'd done more research in the first place.

I hope when I'm back home from my current "road show" I can take time to play with this a little bit again.

This was sort of a "Beginner's Introduction to DirectShow" code example thread.  Maybe now we need an "Intermediate DirectShow" thread?

----------


## redp

When will your current "road show" finish Dilettante? Will it take long?

if there will be an "Intermediate DirectShow" thread started by you, i'm thanking you in advance.
i doubt if Schmidt and ColinE66 will still see "that thread" because they're now busy contemplating
with a "new version" of VB6 Classic with other heavy experts. Are you joining Dilettante?

Well, back to the intermediate thread, i'm looking forward to seeing it in action  :Smilie:

----------


## Schmidt

I'd like when I could open it with what I currently have with regards to the outlined Class-Structures from one of my posts above ...
@Colin - the cSampleGrabber is already working - but what is still missing is a cMediaType-implementation, to be able to comfortably 
read-out and apply those settings on cPins who support this (to force certain resolutions and color-spaces)...

Can't tell when this will finally be finished...(maybe this week, maybe in two) - am currently a bit in a Round-Robin-Mode
(with short-outbursts here into the forum <g>).

But if dilettante or Colin already have something new, worthwhile enough to make a (somewhat enhanced) demo from - 
no need to wait for me - I'll join you then.

Olaf

----------


## ColinE66

Most of my exposure to DirectShow has come about through my use of Geraint Davies' DLL's (fsfwrap, ovtool, and capstill). I am by no means an expert with the underlying DirectShow frame-work, although I am familiar with some of it in an 'if only VB6 had access to that' kind of way; I mean, it's all there just waiting for somebody (Olaf!) to expose it! Having said that, I am happy to contribute to an intermediate VB6 tutorial if dilettante expands upon what he has in mind for it to cover. I'm fine with graph-building, pin and filter enumerations etc. and can certainly contribute something in that respect.

@Olaf, is there anything that is currently 'usable' (notwithstanding the absence of cMediaType) that I can play around with, please? Oh, and is a cOverlay class planned?

----------


## dilettante

> When will your current "road show" finish Dilettante? Will it take long?


I have to finish out this week here, then get to another customer's site and spend 3 days there.  Then back home to work on things from there... then back to those sites, and so on.

I'm tied up quite a bit for a while, great news since it means a little money coming in.  But for a while I won't be doing anything with VB6 except poking around to read questions here and make short replies in my spare time.




> if there will be an "Intermediate DirectShow" thread started by you, i'm thanking you in advance.
> i doubt if Schmidt and ColinE66 will still see "that thread" because they're now busy contemplating
> with a "new version" of VB6 Classic with other heavy experts. Are you joining Dilettante?


Right now most of my time is taken up with Android projects.  I don't do any Windows programming anymore except for recreation unless I get a specific contract to do some Windows programming.

Right now I don't plan on writing more about DirectShow.  I don't have enough experience with it to do a good job anyway.

I'll keep an eye on the "future VB" thread but I can't contribute right now.

----------


## redp

So you're moving back and forth Dilettante.. That really takes time and effort. Why not use the power of "networking" in order for you not to go to your project site physically?

I just paused before typing this to pray that you, Olaf and ColinE66 will get huge projects in the near future and with huge amounts of course.. You all deserve to "get profits" because of your share/contributions on programming not to mention VB forums and the like..

And since you need to focus doing your projects, maybe this is the end of this thread.

Your fellow expert's replies from this thread will be read by other beginners in the future.. and will remember the names like Dilettante, Olaf Schmidt and ColinE66..

----------


## tilki

Hi everyone
Sorry for my poor english.
I am using windows 7. I try to show webcam on my vb6 form. I am using DSMini4.zip. It is working on my labtop without any problem. My labtop has embeded webcam. It works also I plug other webcam it work too. But when I plug same webcam to other desktop computer the program give a message "builtgraph error". How can I solve this problem. Thank You

----------


## dilettante

Building the filter graph is the biggest problem faced when using this approach.

The code posted above tries to stich one together at runtime but it isn't perfect.  Success can vary quite a bit from machine to machine, because not every machine has the same set of filters installed.

For all I know... it may be impossible to write a generic program to do this successfully on every PC even when using exactly the same webcam.

----------


## tilki

Thank you for your reply.
Are there any solution for using any other machines same program? Can I set filters or something else to run other machines?

----------


## dilettante

Often the filters can be installed as part of installing video codec packages.  There are some filter packages like DirectShow FilterPack 5.1 but i have not used them, and I couldn't say whether they contain the necessary filters.

----------


## tilki

Thank you for your information. When I try it, give my experience to you.

----------


## Jonney

> Hi everyone
> Sorry for my poor english.
> I am using windows 7. I try to show webcam on my vb6 form. I am using DSMini4.zip. It is working on my labtop without any problem. My labtop has embeded webcam. It works also I plug other webcam it work too. But when I plug same webcam to other desktop computer the program give a message "builtgraph error". How can I solve this problem. Thank You


Download and install K-Lite Codec pack will solve your problem.

----------


## blueconscious4

Hi, This is excellent. Is there a way to capture physical button press of a camera to capture?




> There are a number of possible APIs in Windows for previewing and capturing from webcams.  One of the most popular for its broad support on Windows versions and its relative ease of use when requirements are simple is the AviCap/Video for Windows API.
> 
> But a downside of VfW is that the driver model Windows uses to support video capture devices changed after the end of 16-bit Windows (Win3.1, etc.).  This means several things, but most commonly frustrating is that instead of mapping multiple webcams as device 1, 2, ... 9 they work through a compatibility layer thats maps _one of them_ as device 1.
> 
> This can make selecting the webcam to use difficult to impractical.  And using more than one webcam at a time doesn't seem possible.
> 
> The usual answer has been: "Use DirectShow instead of VfW."
> 
> 
> ...

----------


## blueconscious4

Hi Is there a way to extend this to capture image based on physical button press of a camera?

----------


## dilettante

This has nothing to do with still cameras, so you'd want to look at WIA 2.0 or something else.  Even then I don't believe there is any communication between a still camera and the PC when the "shutter release" button is pressed.

----------


## blueconscious4

Hi, my camera was  a medical imaging camera. It is not a shutter release camera. Software it came with also uses DirectShow and was able to capture it when camera button is pressed. Any chance we could do similar to their software?

----------


## Ben321

3rd party DLL to wrap the extra functions in? Has anybody done that yet?

----------


## doudou

> There are a number of possible APIs in Windows for previewing and capturing from webcams.  One of the most popular for its broad support on Windows versions and its relative ease of use when requirements are simple is the AviCap/Video for Windows API.
> 
> But a downside of VfW is that the driver model Windows uses to support video capture devices changed after the end of 16-bit Windows (Win3.1, etc.).  This means several things, but most commonly frustrating is that instead of mapping multiple webcams as device 1, 2, ... 9 they work through a compatibility layer thats maps _one of them_ as device 1.
> 
> This can make selecting the webcam to use difficult to impractical.  And using more than one webcam at a time doesn't seem possible.
> 
> The usual answer has been: "Use DirectShow instead of VfW."
> 
> 
> ...


Hi Dilettante,

Thanks so much for this, this is the only good DirectShow - VB6 I was able to find. I would like to implement some of your code into Excel using VBA. I have an Excel input form, and I would like users to be able to take a snapshot from webcam video steam, (the snapshot will be stored in an embedded Active X image control). I am having a little trouble extracting the DirectShow part of the code to implement it. I am hoping you can provide some guidance on that. Thanks in advance.

----------


## dilettante

Hello -

I'm not a VBA guy, but from what I could tell trying to bang around a bit in Excel and then trying a few web searches for ideas I can see a few issues that might get in your way.

For one thing you don't have UserControls in most VBA hosts (e.g. Excel) so you'd have to "unwrap" my UserControl code to work directly within a UserForm.  However UserForms don't give you access to their hWnd (at least in old Excel 2003 that I have) so you're stuck right there because the video preview window will need it set as its Owner window.

So from where I'm sitting you'd have to extract parts of my code to make an OCX in VB6 that could be used by Excel as a video preview control.

Somebody with more experience trying to squeeze more from Excel might have a better option, but that's all I can think of right now.  But the good news (?) is that almost everything but the DSPreview.ctl is more or less plain old VB code that should be doable in VBA UserForms, Classes, etc.

----------


## doudou

> Hello -
> 
> I'm not a VBA guy, but from what I could tell trying to bang around a bit in Excel and then trying a few web searches for ideas I can see a few issues that might get in your way.
> 
> For one thing you don't have UserControls in most VBA hosts (e.g. Excel) so you'd have to "unwrap" my UserControl code to work directly within a UserForm.  However UserForms don't give you access to their hWnd (at least in old Excel 2003 that I have) so you're stuck right there because the video preview window will need it set as its Owner window.
> 
> So from where I'm sitting you'd have to extract parts of my code to make an OCX in VB6 that could be used by Excel as a video preview control.
> 
> Somebody with more experience trying to squeeze more from Excel might have a better option, but that's all I can think of right now.  But the good news (?) is that almost everything but the DSPreview.ctl is more or less plain old VB code that should be doable in VBA UserForms, Classes, etc.


Thanks for your response, you can extend the capability of a VBA userform using Windows API. Please see the following link. http://www.cpearson.com/excel/formcontrol.aspx 

The thing I am struggling with is not fully understanding the implementation of the code, I am thinking it is mostly due to "obscuring" but UI stuff like you have mentioned.

----------


## dilettante

> Thanks for your response, you can extend the capability of a VBA userform using Windows API. Please see the following link. http://www.cpearson.com/excel/formcontrol.aspx


Yeah, I've seen that Pearson hack but I don't care for it at all.  Window spelunking is an act of desperation at best, and it can easily return the hWnd of the _wrong window_.  It's a "by guess and by golly" approach and hardly a real fix.

But sometimes beggars can't be choosers.  I don't have a better suggestion.


Well it has been a while since I last visited this topic in any seriousness.  I decided to try starting more or less from scratch and see how much I could strip it down.

Along the way I think I figured out how to eliminate the problematic manual Filter Graph construction.  This approach should be easier and require less camera-by-camera configuration.  At least it seems to adapt nicely to the two very different USB webcams I have here with me at the moment.

It still needs FSFWrap, so see Visual Basic Questions for the download.  It also makes use of my DSDib2Pic.bas module that I think could be a lot cleaner but right now I don't have time to investigate a cleanup of that.

There are also a few gyrations here that (1.) resize things to fit the video capture dimensions, and (2.) allow the capture properties (including size) to be changed from their defaults.  However this demo doesn't try to persist any settings at all, so each run you must choose a camera, even if you only have one connected at the time.

I also noted that one of the webcams I have right here sometimes comes up under a specific name, and other times comes up as "USB Video Device" - a generic name.  This seems to change when I disconnect and later reconnect the webcam to a USB port.  Weird, but something to watch out for if you need to persist settings.


Hopefully this will be a little more helpful.

----------


## dilettante

As a caution: this new program above could be problematic if you have a webcam that defaults to a large picture size.  The program tries to put the preview window and a "snapshot" Image control side-by-side at the capture size and size the Form to fit and center it within the default monitor.

So it is possible for it to size the Form such that you can't get to the control widgets in the caption bar's corners since they can end up off-screen.

You could modify the program to do some scaling to keep things in reasonable proportion.

----------


## doudou

> Yeah, I've seen that Pearson hack but I don't care for it at all.  Window spelunking is an act of desperation at best, and it can easily return the hWnd of the _wrong window_.  It's a "by guess and by golly" approach and hardly a real fix.
> 
> But sometimes beggars can't be choosers.  I don't have a better suggestion.
> 
> 
> Well it has been a while since I last visited this topic in any seriousness.  I decided to try starting more or less from scratch and see how much I could strip it down.
> 
> Along the way I think I figured out how to eliminate the problematic manual Filter Graph construction.  This approach should be easier and require less camera-by-camera configuration.  At least it seems to adapt nicely to the two very different USB webcams I have here with me at the moment.
> 
> ...


This is great, thanks a lot.

----------


## dilettante

Pretty much as expected, the old DIB-to-StdPicture logic had some issues.  I was never happy with it and upon re-examination I even found some glaring GDI handle leaks and such.

Here is one more run at the whole thing again.  Basically it changes nothing from the last example I posted just above except:

The Form is now a fixed-size Form of about 970 pixels width.  This should help when testing a webcam supporting hi-res video dimensions.The webcam preview window is fixed in width at about 640 pixels.  Really part of the fixed-Form stuff.The "snapped" picture view is a PictureBox scaled to 50% of the preview to save on Form size.  Really part of the fixed-Form stuff.The DIB-to-StdPicture logic has been rewritten to be a little cleaner and take care of some flaws in its GDI handling and to return error information.

Almost nothing in the DirectShow logic has been altered, so this version really is quite similar to the previous except for the fixed Form size stuff and the improved DIB to StdPicture code.

----------


## dilettante

Here's my last version of this (I think).

Cleaned up DIB fetch thanks to a trick to request required size.  When porting to VBA be cautious with this.Optimized StdPicture creation using SetDIBits instead of MoveMemory.Pause/Run on snap to optimize snap-shotting - almost no "blink" now except when Aero is active.Added save to disk as JPEG.

----------


## tmighty

----

----------


## DEXWERX

bummer, it's too bad the source for FSWrapper wasn't available. It shouldn't be too hard to come up with a VB Compatible typelib, to implement the needed classes in VB.

----------


## Schmidt

> bummer, it's too bad the source for FSWrapper wasn't available. It shouldn't be too hard to come up with a VB Compatible typelib, to implement the needed classes in VB.


Did you see the Demo I've posted in #38?
It replaces already most of the functionality of the FSWrapper with other typelibs (which come preinstalled on the system).

Olaf

----------


## DEXWERX

> Did you see the Demo I've posted in #38?
> It replaces already most of the functionality of the FSWrapper with other typelibs (which come preinstalled on the system).
> 
> Olaf


That's perfect, Olaf. Thanks.

----------


## Ben321

Have you found a solution to this complete lack of VB6 support in quartz.dll, that would allow a VB6 programmer full access to the entirety of the DirectShow framework? I think you can access it all with VC++. Has anybody yet bothered to create a VB6 friendly wrapper (preferably an ActiveX DLL file, or at least an STDCALL DLL File) in VC++, that gives VB6 users the full power of DirectShow? If so, where can I download this DLL file?

----------


## fafalone

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:


```
#include <dshow.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
  CoInitialize(NULL);

  // 1. フィルタグラフ作成
  IGraphBuilder *pGraph = NULL;
  CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
      IID_IGraphBuilder, (void **)&pGraph);

  // 2. システムデバイス列挙子を作成
  ICreateDevEnum *pDevEnum = NULL;
  CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
      IID_ICreateDevEnum, (void **)&pDevEnum);

  IEnumMoniker *pClassEnum = NULL;
  pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);

  ULONG cFetched;
  IMoniker *pMoniker = NULL;
  IBaseFilter *pSrc = NULL;
  if (pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK){
    // 最初のモニカをフィルタオブジェクトにバインドする
    pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void **)&pSrc);
    pMoniker->Release();
  }
  pClassEnum->Release();
  pDevEnum->Release();

  pGraph->AddFilter(pSrc, L"Video Capture");

  // 3. キャプチャビルダの作成
  ICaptureGraphBuilder2 *pBuilder = NULL;
  CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
      IID_ICaptureGraphBuilder2, (void **)&pBuilder);
  pBuilder->SetFiltergraph(pGraph);
  
  // 4. ファイルライタフィルタの設定
  IBaseFilter *pMux = NULL;
  IFileSinkFilter *pSink = NULL;

  // ファイルへ
  pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\dvcap_tmp.avi", &pMux, &pSink);
  pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc, NULL, pMux);
  REFERENCE_TIME rtStart = 50000000, rtStop = 80000000;
  pBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc, &rtStart, &rtStop,
      0, 0 );
  // ディスプレイへ
  pBuilder->RenderStream( &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pSrc, NULL, NULL );


  // 5. キャプチャ開始
  IMediaControl *pMediaControl;
  pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
  pMediaControl->Run();

  MessageBox(NULL, "Click to stop.", "DirectShow", MB_OK);
  
  // 6. 終了
  pSrc->Release();
  pMux->Release();
  pSink->Release();
  pMediaControl->Release();
  pEvent->Release();
  pBuilder->Release();
  pGraph->Release();
  CoUninitialize();

  cout << "end\n";
  return 0;
}
```

----------


## Ben321

> 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:
> 
> ...


TLB or DLL should work. Not really sure what the difference is though. Aren't they both PE type files (just as EXE is as well)?

----------


## fafalone

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.

----------


## dilettante

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."

----------


## Ben321

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.

----------


## dilettante

Great project idea.  Let us know when it is ready.  :Wink: 

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.

----------


## Ben321

> Great project idea.  Let us know when it is ready. 
> 
> 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.

----------


## fafalone

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.

----------


## Ben321

> 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.

----------


## fafalone

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.

----------


## Darkbob

I tried the first example but it doesn't run properly under Windows 10.  Anybody get any kind of video capture working under VB6 with Windows 10?

----------


## dilettante

I just tested that program on Windows 10, and as expected it runs just fine.

----------


## dilettante

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.

----------


## tandean

Hi, Can anyone help me for this problem?
i copy the form to my project.but i can not to compile because this problem


=================================================
SOLVED PROBLEM.
just active the quartz.dll in reference..
thank you dilettante for ur code..  :Big Grin:

----------


## jpbro

Hi dilettante,

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:



```
                   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
```

----------


## dilettante

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  :Wink: ).

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.

----------


## jpbro

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.

----------


## dilettante

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.

----------


## Fiftys

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?

Christian

----------


## dilettante

> 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.

----------


## Fiftys

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.

----------


## Fiftys

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!

Christian

----------


## dilettante

That path appears to be:

HKEY_CURRENT_USER\Software\Microsoft\Direct3D\Shims\EnableOverlays

These are appcompat shims, and I'm not sure what your program did that might trigger Windows to apply them.  I did find this:

Overlay mixer seems to be broken in Windows 8

I'll have to do more checking, but I haven't had problems like this recently on post-Win7 OSs myself.

At least you have a "cure" for the issue.

----------


## dilettante

As I have tried working with this over time I think the only thing I really learned is that "minimal code yields minimal results."

When you try to refine it to handle lots of different webcams with lots of flexibility... you end up needing more and more code.

----------


## FunkyDexter

Deleted several posts that were in incorrect thread

----------


## Hondo6566

Hi,
when I test it I have borders on left, top and bottom.
When I save the picture the borders are stil on the pictures.
How can I fix this?

Andreas

----------


## Hondo6566

Btw:
I have test it with a videocam at a Pinnacle Dazzle.
With a WebCam there is no border.

----------


## Hondo6566

Hi,
capturing to a single picture works fine now, but how can I capture an save as Video MP4 or so?

Thanks Andreas

----------


## dilettante

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.

Try asking your question in the Q&A forum.

----------


## Hondo6566

Hi,
I send  DSWC 1.3.zip to a friend for testing, and he told me he gets only black/white video picture.
What is the Problem?

Andreas

----------


## dilettante

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.

----------


## mnsman

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.

----------


## dilettante

Once you have a bitmap image then you just snip out the portion you want as a new bitmap or array of pixel values.  Do a BitBlt, GetDIBits, etc.

But from there analyzing them is another topic altogether.  Machine vision isn't a trivial matter.

----------


## mnsman

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.

----------


## dilettante

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.

Maybe something here might help:

Read pixel, twips or other scalemod coordinates in picturebox.?

----------


## mnsman

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.

----------


## mpoore

> Here's my last version of this (I think).


This is really close to what I need, but I am having trouble with two things.

1. I'd like to be able to set the resolution programmatically.
2. I'd like to be able to rotate the preview.

Can you provide any help on the above? I can't seem to figure it out.

----------


## dilettante

I haven't found a way to set the resolution.  There probably is one, but it doesn't seem to be exposed via any of the typelibs I have tried.

Rotating might be possible by adding another filter to the FilterChain.

----------


## mpoore

> Rotating might be possible by adding another filter to the FilterChain.


If found a sourceforge project that includes a rotate filter. https://sourceforge.net/projects/videoprocessing/

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":



```
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
```

I am stumped on what to do.

----------


## lostpacket

Thanks for this great example!

----------


## waqaraq

> 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

----------


## dilettante

I'm not sure what to suggest.

That's about a 6 year old Project I haven't looked at in a while.  However when I ran it just now on Windows 10 it is working fine for me.

So I doubt it has anything to do with Windows 10.  More likely there is something else going on, like some issue with your webcam(s).

You probably need different FILTERLIST and CONNECTIONLIST values.  That sort of thing can take some effort to work out and you'd probably need to use the graphedt.exe tool from the Windows SDK.

I have some later code that tries to take another approach instead of using hard-coded lists but I don't think I ever got it refined to the point where it made sense to post it.

----------


## waqaraq

Thanks for your reply. Actually, I've a working code for target tracking. But works on the basis of copying data to clipboard and then pasting it into a picture. That works fine for target tracking for a single camera. But in my latest project, I'm trying to do depth estimation using two cameras and that's when I found that my code won't work for two cameras simultaneously. I wonder if you could modify your code a bit to make an ocx with two images from two cameras as output, the image processing and tracking plus depth estimation, I'll be able to do that at my own. 

P.S: You seem to be a vivid vb developer. Can you please advise me on a problem which I face on Windows 10. In XP, while developing active x controls, I used to get the preview window in IE but it doesn't work anymore in Windows10. It just gives an option to enable content and then nothing happens.

----------


## dilettante

I suggest you ask this in a new thread in the VB6 and Earlier forum.

I haven't played with IE-hosted controls in a very long time, but others may have.

----------


## waqaraq

> This can make selecting the webcam to use difficult to impractical.  And using more than one webcam at a time doesn't seem possible.


I understand that it is a pretty old thread. But, I am posting it here for the help of anyone who might want to have two webcams simultaneously in their VB6 code without directshow. So, here is an MWE (Minimal Working Example) with attached files as code. Just make sure to choose the cam which is not being shown by default in the dialog which appears or it will start showing the same cam in both windows.

MWE 2 cams.zip

----------


## gerocire

Hola chicos vereis se que este poss es ya antiguo pero quiero utilizar la cam y pasa lo siguiente ,en windows 8.1 a 64 bit pongo algunos codigos de cam y resulta que sucede lo siguiente ,, solo me funcionan una vez y luego me tiran a la configuracion de la camara ya dejando de funcionar sin embargo en windows 7 32 bit si funciona ... alguna solucion  .. y otra pregunta hay algun codigo o modulo para cam que no de problemas para windows 8.1 64 bit muchas gracias ....

----------

