문제 해결 팁

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

다음 팁은 DirectShow 애플리케이션에서 교착 상태 또는 충돌을 방지하는 데 도움이 됩니다.

전역 개체

전역 C++ 개체는 생성자 메서드에서 DirectShow 개체를 만들거나 소멸자 메서드에서 해제해서는 안 됩니다. 이렇게 하면 다음과 같은 이유로 애플리케이션이 무기한 차단될 수 있습니다.

스레드는 DLL의 진입점 함수 내에서 종료할 수 없습니다. 커널 32는 진입점 함수 중에 전역 프로세스 잠금을 보유하며 잠금은 스레드가 종료되지 않도록 합니다. 일부 DirectShow 개체는 스레드를 소유하므로 DLL 진입점 함수 내에서 해제된 경우 차단할 수 있습니다. 애플리케이션에 전역 C++ 개체가 있는 경우 DLL이 언로드될 때 C 런타임 DLL은 개체의 소멸자를 호출합니다. 소멸자에서 DirectShow 개체를 해제하면 결과적으로 차단할 수 있습니다.

비슷한 이유로 DLL은 진입점 루틴에서 DirectShow 개체를 만들거나 해제해서는 안 됩니다.

인터페이스 해제

애플리케이션이 메시지 루프를 종료하기 전에 메시지를 처리하는 동안 모든 DirectShow 인터페이스 포인터를 해제해야 합니다. 그렇지 않으면 일부 DirectShow 개체가 클린 루틴 중에 메시지를 보내기 때문에 다양한 어설션이 표시될 수 있습니다.

(공동으로 ATL CWindowImpl 클래스를 사용하는 경우 OnFinalMessage 가 인터페이스를 해제할 때까지 기다리지 마세요. 대신 WM_CLOSE 메시지를 처리할 때 해제합니다.)

참조 개수

디버그 버전의 Quartz.dll 언로드할 때 DirectShow 개체에 릴리스되지 않은 참조 수가 있는지 확인합니다. 이 경우 어설션을 throw합니다.

g_cFGObjects == 0 

이 어설션이 실패하면 애플리케이션이 참조 횟수를 유출했음을 의미합니다. 코드를 검토하고 모든 인터페이스 포인터를 해제하는지 확인합니다.

DirectShow에서 디버깅