2

I have an issue trying to control camera parameters. Here is the function to set brightness parameter (I am extending the code from Windows Media Foundation recording audio) :

HRESULT deviceInput::SetupCamera(UINT32 deviceID) {
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
IMFActivate* device = this->getDevice(deviceID);
if (device == NULL)
    return E_FAIL;
IMFMediaSource* pCameraSource = NULL;
HRESULT hr = (m_devices[deviceID])->ActivateObject(IID_PPV_ARGS(&pCameraSource));
if (FAILED(hr)) {
    wcout << "Could not activate object" << endl;
    return hr;
}
IAMVideoProcAmp* spVideo = NULL;
hr = CoCreateInstance(__uuidof(IMFMediaSource) , NULL, CLSCTX_INPROC_SERVER, __uuidof(IAMVideoProcAmp),
                      reinterpret_cast<void**>(&spVideo));  
hr = pCameraSource->QueryInterface(IID_PPV_ARGS(&spVideo));
if(FAILED(hr)) {
    wcout << "Could not get interface" << endl;
    return hr;
}
if(spVideo) {
    wcout << "Getting brightness" << endl;
    long Min, Max, step, def, control;
    Sleep(100); // if I remove this - will get "Element not found error"
    hr = spVideo->GetRange(VideoProcAmp_Brightness, &Min, &Max, &step, &def, &control);
    if (SUCCEEDED(hr))
        wcout << "Brightness. Min = " << Min <<", max = " << Max << endl;
    else {
        _com_error err(hr);
        LPCTSTR errMsg = err.ErrorMessage();
        wcout << "Failed: " << errMsg << endl;
    }
}
CoUninitialize();
return hr;
}

It seems I need to insert a pause before calling GetRange() method, otherwise I am getting "Element not found" error. QueryInterface works correctly, since I am checking HRESULT value, and spVideo gets populated regardless of the delay. Does anyone know how to get this to work without inserting arbitrary delays?

Community
  • 1
  • 1
Ilya
  • 93
  • 8
  • I suppose you need to start video capture from this source and change parameters on active device. This should ensure the backstage stuff is properly initialized. – Roman R. Jul 04 '16 at 18:55

1 Answers1

1

you described well known problem. The fact is that after execution of activating system needs time for initializing driver for camera. It needs time. If you really want to remove Sleep function then you should call camera properties via DeviceIoControl On MSDN USB Video Class Properties you find the next text "Call KsSynchronousDeviceControl or DeviceIoControl to make property requests from a user-mode component. DeviceIoControl is documented in the Microsoft Windows SDK documentation." By the way, for using of DeviceIoControl it DOES NOT NEED activate MediaSource. DeviceIoControl function needs only symbolicLink of camera. However, writing code for direct working with driver can be very difficult (I wrote it in one C++ class).

Evgeny Pereguda
  • 553
  • 1
  • 4
  • 9
  • Evgeny, thanks for the answer. So there is no way to check if the driver is ready from within MediaFoundation class (some kind of blocking call maybe?). – Ilya Jul 05 '16 at 04:50
  • No. There is no way for working with camera properties via `MediaFoundation`. Only via `IAMVideoProcAmp` DirectShow or `DeviceIoControl`. Camera is a hardware device - it means that for working with it you need use the same code as for working with any device on Windows (for example hard disk) - `DeviceIoControl`. – Evgeny Pereguda Jul 05 '16 at 05:28