2016-07-04 33 views
2

Ich habe ein Problem bei der Kontrolle der Kameraparameter. Hier ist die Funktion Helligkeitsparameter einstellen (ich Verlängerung der Code von Windows Media Foundation recording audio):IAMVideoProcAmp GetRange funktioniert nur nach Verzögerung (C++)?

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; 
} 

Es scheint, ich brauche eine Pause einzulegen, bevor GetRange() -Methode, sonst erhalte ich „Element nicht gefunden“ Fehler . QueryInterface funktioniert korrekt, da ich den HRESULT-Wert überprüfe und spVideo unabhängig von der Verzögerung gefüllt wird. Weiß jemand, wie man das bewerkstelligen kann, ohne willkürliche Verzögerungen einzuführen?

+0

Ich nehme an, Sie müssen die Videoaufnahme von dieser Quelle starten und die Parameter auf dem aktiven Gerät ändern. Dies sollte sicherstellen, dass das Backstage-Zeug richtig initialisiert ist. –

Antwort

1

haben Sie wohlbekanntes Problem beschrieben. Tatsache ist, dass nach der Ausführung des Aktivierungssystems Zeit benötigt wird, um den Treiber für die Kamera zu initialisieren. Es braucht Zeit. Wenn Sie die Funktion Sleep wirklich entfernen möchten, sollten Sie die Kameraeigenschaften über DeviceIoControl aufrufen. Auf MSDN USB Video Class Properties finden Sie den nächsten Text "KsSynchronousDeviceControl oder DeviceIoControl aufrufen, um Eigenschaftsanforderungen aus einer Benutzermoduskomponente zu erstellen. DeviceIoControl ist in der Microsoft Windows SDK-Dokumentation dokumentiert . " By the way, für die Verwendung von DeviceIoControl es braucht nicht aktivieren MediaSource. DeviceIoControl Funktion benötigt nur SymbolicLink der Kamera. Das Schreiben von Code für das direkte Arbeiten mit dem Treiber kann jedoch sehr schwierig sein (ich habe es in einer C++ Klasse geschrieben).

+0

Evgeny, danke für die Antwort. Es gibt also keine Möglichkeit zu überprüfen, ob der Treiber in der MediaFoundation-Klasse bereit ist (vielleicht eine Art Blockier-Call?). – Ilya

+0

Nein. Es gibt keine Möglichkeit, mit Kameraeigenschaften über 'MediaFoundation' zu arbeiten. Nur über 'IAMVideoProcAmp' DirectShow oder' DeviceIoControl'. Die Kamera ist ein Hardwaregerät - das bedeutet, dass Sie für die Arbeit mit demselben Gerät den gleichen Code verwenden müssen wie für die Arbeit mit jedem Gerät unter Windows (z. B. Festplatte) - 'DeviceIoControl'. –