@@ -400,13 +400,19 @@ std::vector<std::string> ProviderDirectShow::findDeviceNames() {
400400
401401 enumerateDevices ([&](IMoniker* moniker, std::string_view name) {
402402 // Try to bind device, check if available
403- IBaseFilter* filter = nullptr ;
404- HRESULT hr = moniker->BindToObject (0 , 0 , IID_IBaseFilter, (void **)&filter);
405- if (SUCCEEDED (hr) && filter) {
406- m_allDeviceNames.emplace_back (name.data (), name.size ());
407- filter->Release ();
408- } else {
409- CCAP_LOG_I (" ccap: \" %s\" is not a valid video capture device, removed\n " , name.data ());
403+ // Use SEH to catch crashes from buggy drivers (e.g., unplugged devices like Oculus Quest 3)
404+ __try {
405+ IBaseFilter* filter = nullptr ;
406+ HRESULT hr = moniker->BindToObject (0 , 0 , IID_IBaseFilter, (void **)&filter);
407+ if (SUCCEEDED (hr) && filter) {
408+ m_allDeviceNames.emplace_back (name.data (), name.size ());
409+ filter->Release ();
410+ } else {
411+ CCAP_LOG_I (" ccap: \" %s\" is not a valid video capture device, removed\n " , name.data ());
412+ }
413+ } __except (EXCEPTION_EXECUTE_HANDLER ) {
414+ // Catch crashes from buggy camera drivers (e.g., when camera is physically unplugged)
415+ CCAP_LOG_W (" ccap: \" %s\" caused an exception during device binding, skipping\n " , name.data ());
410416 }
411417 // Unavailable devices are not added to the list
412418 return false ; // Continue enumeration
@@ -660,19 +666,29 @@ bool ProviderDirectShow::open(std::string_view deviceName) {
660666
661667 enumerateDevices ([&](IMoniker* moniker, std::string_view name) {
662668 if (deviceName.empty () || deviceName == name) {
663- auto hr = moniker->BindToObject (0 , 0 , IID_IBaseFilter, (void **)&m_deviceFilter);
664- if (SUCCEEDED (hr)) {
665- CCAP_LOG_V (" ccap: Using video capture device: %s\n " , name.data ());
666- m_deviceName = name;
667- found = true ;
668- return true ; // stop enumeration when returning true
669- } else {
669+ // Use SEH to catch crashes from buggy drivers (e.g., unplugged devices like Oculus Quest 3)
670+ __try {
671+ auto hr = moniker->BindToObject (0 , 0 , IID_IBaseFilter, (void **)&m_deviceFilter);
672+ if (SUCCEEDED (hr)) {
673+ CCAP_LOG_V (" ccap: Using video capture device: %s\n " , name.data ());
674+ m_deviceName = name;
675+ found = true ;
676+ return true ; // stop enumeration when returning true
677+ } else {
678+ if (!deviceName.empty ()) {
679+ reportError (ErrorCode::InvalidDevice, " \" " + std::string (deviceName) + " \" is not a valid video capture device, bind failed" );
680+ return true ; // stop enumeration when returning true
681+ }
682+
683+ CCAP_LOG_I (" ccap: bind \" %s\" failed(result=%x), try next device...\n " , name.data (), hr);
684+ }
685+ } __except (EXCEPTION_EXECUTE_HANDLER ) {
686+ // Catch crashes from buggy camera drivers (e.g., when camera is physically unplugged)
687+ CCAP_LOG_W (" ccap: \" %s\" caused an exception during device binding, skipping\n " , name.data ());
670688 if (!deviceName.empty ()) {
671- reportError (ErrorCode::InvalidDevice, " \" " + std::string (deviceName) + " \" is not a valid video capture device, bind failed " );
689+ reportError (ErrorCode::InvalidDevice, " \" " + std::string (deviceName) + " \" caused an exception during binding " );
672690 return true ; // stop enumeration when returning true
673691 }
674-
675- CCAP_LOG_I (" ccap: bind \" %s\" failed(result=%x), try next device...\n " , name.data (), hr);
676692 }
677693 }
678694 // continue enumerating when returning false
0 commit comments