Alternative way to program instead of using ISpeci

2019-07-29 18:30发布

问题:

To start off I'm terrible at this directshow stuff. I have almost no clue as to how it works. And I'm trying to access this "value" from a camera that's called Area of Interest x and y, at least that's what it was called in the Camera program that came with the camera. Basically it moves the the camera's view left to right or top to bottom (The camera does not physically move). Problem is I can't find how to do that in Directshow.

But, luckily, I came across a program with a source code that had access to this value using directshow. So, after looking through the code I found it and the code looked like this..

case IDC_DEVICE_SETUP:
{
    if(gcap.pVCap == NULL)
        break;

    ISpecifyPropertyPages *pSpec;
    CAUUID cauuid;
    hr = gcap.pVCap->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);
    if(hr == S_OK)
    {
         hr = pSpec->GetPages(&cauuid);
         hr = OleCreatePropertyFrame(ghwndApp, 30, 30, NULL, 1,
                        (IUnknown **)&gcap.pVCap, cauuid.cElems,
                        (GUID *)cauuid.pElems, 0, 0, NULL);
         CoTaskMemFree(cauuid.pElems);
         pSpec->Release();
    }
    break;
}

Problem is that this its a button and when you click on it, it creates a window with some of the properties of the camera setting that I don't need access to. Basically, there is a two problems. First, I don't need to want to create a window, I just want to access the value programmatically and second, I only want to access the specific part of the values from this property page. Is there a way to do that?

回答1:

The IAMCameraControl interface seems to come nearest to what you want, but it's not exactly what you want. I can't remember that there is a standard DirectShow interface that does what you want.

The property page you see for the IBaseFilter is implemented by the driver for the filter. The driver is free to do whatever he wants with all knowledge about internal interfaces. There is no need to exhibit these interfaces to external users. If you are lucky then the camera vendor's property page is using a COM interface that the vendor is willing to document so that you can use it.

So I would ask the camera vendor if they provide an official COM interface that you could use. If they don't, you could try to reverse engineer what they do (not so easy) and hope that they don't change the interface with the next software release.

Regarding the general question given in the comments:

COM is a programming interface that defines how to create objects, how to define the interface (e.g. methods) of these objects and how to call methods on the objects.

DirectShow is based on COM. DirectShow defines several COM interfaces like IFilterGraph as a container for all devices and filters that you use. Another COM interface defined by DirectShow is IBaseFilter which is the base interface for all filters (devices, transformation filters) that you could use.

The individual COM objects are sometimes implemented by DirectShow, but device specific objects like the IBaseFilter for your capturing device are implemented by some DLL delivered by the hardware vendor.

In your case gcap.pVCap is the IBaseFilter interface for the capture device. In COM objects can implement multiple interfaces. In your code pVCap is queried (QueryInterface) if it supports the interface ISpecifyPropertyPages. If this is the case, then the OlePropertyFrame is created which displays the property page which is implemented by the camera object. Complete control goes to the camera object which is implementing the ISpecifyPropertyPages interface. When the camera object displays the property page it can directly access it's own properties. But it can also make the properties available externally by exporting another interface like IMyCameraSpecificInterface.