none
Programmatically identifying the proper usb webcam

    คำถาม

  • I'm developing a C# DotNet application where I need access a usb camera. I'm using the DirectShow implementation of AForge for this (http://www.aforgenet.com). My application should automatically detect/select the proper webcam device in the following setup:

    • I don't know vendor/id etc. of the webcam in advance.
    • I do know that it is connected to an external usb hub (I don't know anything about the hub itself)

    I do know vender/id etc. of another usb device connected to that same usb hub

    So, what I must be able to do is:

    1. find the webcam that is connected to the same hub as the well-known device.
    2. determine the monniker string for that webcam, which is needed by the aforge library for opening and accessing the webcam device.

    I'm looking for a way to perform steps 1+2 in managed code. I've looked around for quite a while but I didn't find a solution.
    Is there anyone who can explain to me how I can accomplish this?

    Many thanks in advance,

    Merijn

    29 กุมภาพันธ์ 2555 14:03

คำตอบ

ตอบทั้งหมด

  • MdeJ wrote:
    >
    >I'm developing a C# DotNet application where I need access a usb camera.
    >...
    >I do know vender/id etc. of another usb device connected to that same usb hub
    >
    >So, what I must be able to do is:
    >1. find the webcam that is connected to the same hub as the well-known device.
    >2. determine the monniker string for that webcam, which is needed by the
    >aforge library for opening and accessing the webcam device.
    >
    >I'm looking for a way to perform steps 1+2 in managed code. I've looked
    >around for quite a while but I didn't find a solution.
    >Is there anyone who can explain to me how I can accomplish this?
     
    What you are describing is very complicated.  Further, it's only going to
    work in limited circumstances, in a computer with a very specific hardware
    configuration.
     
    The best plan is to use the system device enumerator
    (CLSID_SystemDeviceEnum) to enumerate  the list of all web cams.  If
    there's only one, you win.  If there is more than one, you should present a
    list to the user and have them pick one by "friendly name".  The enumerator
    gives you the moniker for the camera.  The cameras will be enumerated in
    the same order as long as they don't move slots, so once you get a device
    ordinal, you can grab that one from then on.
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.
     

    Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.
    1 มีนาคม 2555 5:18
  • Tim,

    Thanks a lot for your reply.

    We are in the situation that we can assume a very specific hardware configuration, i.e., a webcam connected to a usb hub to which also a dedicated device is attached for which we know name, vender and such. So, the challenge is to identify the webcam that is attached to that same hub. This can't be too difficult, can it?

    I'm able to use CLSID_SystemDeviceEnum to get all webcams and their moniker strings. However, now I need to find out for a given camera, where it is located in the tree of connected usb devices. I'm also able to construct this usb tree. However, I don't know how, given a usb device, find the corresponding moniker string, or the other way around, given a moniker string, determine the corresponding usb device. That is where I'm stuck.

    Any further suggetsions would be very welcome.

    Kind regards,

    Merijn

    3 มีนาคม 2555 10:06
  • MdeJ wrote:
    >
    >We are in the situation that we can assume a very specific hardware
    >configuration, i.e., a webcam connected to a usb hub to which also a
    >dedicated device is attached for which we know name, vender and such. So,
    >the challenge is to identify the webcam that is attached to that same hub.
    >This can't be too difficult, can it?
     
    Yes, it can.  The operating system and the Device Manager are all designed
    to abstract all of that information.  You shouldn't NEED to know the exact
    topology.  Your driver should work on a given device whereever it is
    located in the topology.  As a result, the topology is not easy to get.
     
    >I'm able to use CLSID_SystemDeviceEnum to get all webcams and their
    >moniker strings. However, now I need to find out for a given camera,
    >where it is located in the tree of connected usb devices. I'm also
    >able to construct this usb tree.
     
    How did you do that?  Are you using the "usbview" method of talking
    directly to the hubs?  If so, you're 99% of the way there.  You will go to
    hell for doing so, but you can reverse engineer the format of the moniker
    and the hardware ID enough to find pieces of one in the other, and you can
    ask the hub for the hardware IDs of all of the devices on its ports.  From
    that, you should be able to figure out how to line them up.
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.
     

    Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.
    3 มีนาคม 2555 18:51
  •  

    Learn how to enumerate devices using the Setup API:

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff550855(v=vs.85).aspx

    Learn what a DevNode (aka ‘DevInst) is and what device trees are:

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff554721(v=vs.85).aspx

    Learn what CM_Get_Parent() does.

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff538610(v=vs.85).aspx

    Once you know all that then do this in your program:

    Get the DevNode for your USB hub.

    Begin enumerating video capture devices (WebCams).

    For each video capture device find its DevNode.

    Call CM_Get_Parent() recursively until the parent DevNode matches the USB hub’s DevNode, or until CM_Get_Parent() fails.

    If you find a match then you will know that the video capture device under scrutiny lives somewhere under your hub.

    Here’s some related code that might put you on the fast track:

    DirectKS Sample Application

    http://www.microsoft.com/download/en/details.aspx?id=18989

    UsbViewer in C#

    http://sourceforge.net/projects/usbviewerincsha/

    Good luck.


    • แก้ไขโดย David Miller already exists 4 มีนาคม 2555 15:30
    • ทำเครื่องหมายเป็นคำตอบโดย MdeJ 20 มีนาคม 2555 22:03
    4 มีนาคม 2555 15:28
  • I don't know how, given a usb device, find the corresponding moniker string, or the other way around, given a moniker string, determine the corresponding usb device. That is where I'm stuck.

    Any further suggetsions would be very welcome.

    Kind regards,

    Merijn

     

    I explained that here:

    http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/b9b7bc7a-f1c6-4f58-87c9-8e468d094f46



    4 มีนาคม 2555 15:38
  • Tim, David,

    Thanks a lot for your help. It took a while but I succeeded in what I wanted. This is what I did:

    1. I create a device tree using a combination of SetupDiGetClassDevs, SetupDiEnumDeviceInfo, and CM_Get_Parent.
    2. In this device tree I identify my "known" device from its manufacturer name that I obtain by calling SetupDiGetDeviceRegistryProperty.
    3. The usbhub is simply the parent of the device identified at step 2.
    4. I identify webcams in the device tree by calling SetupDiEnumDeviceInterfaces and specifying KSCATEGORY_CAPTURE as interface class guid.
    5. I can now easily identify the webcam that is connected to the hub from step 3.
    6. I obtain the moniker string for the webcam device by calling SetupDiGetDeviceInterfaceDetail and prefixing the resulting devicepath with "@device:pnp:".
    7. Finally, I can use this moniker string with the aforge library to connect to the webcam.

    I've implemented everything in a C# library from which I make calls to Cfgmgr32.dll and setupapi.dll.

    Merijn

    20 มีนาคม 2555 22:03
  •  

    Cool.

    Glad I could help.

    Thanks for replying.

    I was becoming embittered.  :lol:

    21 มีนาคม 2555 14:29