2016-09-23 19 views
2

DirectShow.NET을 사용하여 웹캠 컨트롤을 만들고 있습니다. 카메라의 비디오를 WPF 창으로 렌더링하려고합니다. 현재 일어나고있는 것은 IVMRWindowlessControl9이 창없는 모드로 들어가는 것 같지 않고 적절한 방법을 호출하고 있음에도 불구하고 내가 지정한 창에 종속되어 있지 않다는 것입니다.IVMRWindowlessControl9가 상위 WPF 창으로 렌더링되지 않습니다.

왜 이러한 메소드가 호출되지 않습니까? 내가하지 않는 다른 것이 있습니까? 여기

IGraphBuilder graphBuilder = (IGraphBuilder) new FilterGraph(); 
ICaptureGraphBuilder2 captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();    
IMediaControl mediaControl = (IMediaControl) this.graphBuilder; 
IBaseFilter renderFilter = (IBaseFilter) new VideoMixingRenderer9(); 

hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder); 
DsError.ThrowExceptionForHR(hr); 

IBaseFilter sourceFilter = FindCaptureDevice(); 

hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");       
DsError.ThrowExceptionForHR(hr); 

SetCaptureResolution(); 

IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)renderFilter; 

hr = filterConfig.SetNumberOfStreams(1); 
DsError.ThrowExceptionForHR(hr); 

hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless); 
DsError.ThrowExceptionForHR(hr); 

windowlessControl = (IVMRWindowlessControl9)renderFilter; 

hr = this.graphBuilder.AddFilter(renderFilter, "Video Capture"); 
DsError.ThrowExceptionForHR(hr); 

Window window = Window.GetWindow(this); 
var wih = new WindowInteropHelper(window); 
IntPtr hWnd = wih.Handle; 
hr = windowlessControl.SetVideoClippingWindow(hWnd); 
DsError.ThrowExceptionForHR(hr); 

hr = windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox); 
DsError.ThrowExceptionForHR(hr); 

hr = this.captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, sourceFilter, null, null); 
DsError.ThrowExceptionForHR(hr); 

Marshal.ReleaseComObject(sourceFilter); 

hr = this.mediaControl.Run(); 
DsError.ThrowExceptionForHR(hr); 

은 (쉽게를 볼 수 있도록 내가 배경 녹색을 만든 ) 무슨 일이 일어나고 있는지의 이미지입니다 : WPF & IVMRWindowlessControl9

아래

는 관련 코드의 조각이다 다음은 필터 그래프의 다이어그램입니다. enter image description here

잠재적 인 질문에 답하려면 (이 문제가 있었으므로 p reviously), yes, hWnd이 설정 중이며/값이 있습니다. 따라서 windowlessControl에 창에 대한 포인터가 있습니다.

+0

'SetNumberOfStreams'가 너무 빠르거나,'SetRenderingMode'가 [go go]해야합니다 (https://msdn.microsoft.com/en-us/library/windows/desktop/dd407299). ActiveMovie Window는 비디오 렌더러가 설정되지 않았 음을 나타냅니다. 효과적인 필터 그래프는 예상했던 것과 다를 수도 있습니다. [DirectShow 필터 그래프 이해하기] (http://alax.info/blog/1678)를 참조하십시오. 특히, 효과적인 그래프에는 두 개의 렌더러가있을 수 있습니다. –

+0

@RomanR. http://imgur.com/a/wjjm5 - 다음은 애플리케이션 실행 중에 캡처 한 필터 그래프 이미지에 대한 링크입니다. 이게 정상적으로 보이나요? –

답변

1

필터 그래프를 실행할 때 생성되는 "ActiveMovie Window"팝업은 다른 UI의 일부로 구성되지 않고 파이프 라인에 삽입되어 기본 모드로 실행되는 비디오 렌더러 필터의 증상입니다. 하위 창 등으로 포함됩니다. .

귀하의 그래프 나고는 무슨 일이 일어나고 있는지에 빛을 반전 :

삽입 한 비디오 렌더러 필터를 설정 한 다음 API를 추가하여 입력에 연결된 다른 하나가 . 처음에는 UI에 임베드되지만 유휴 상태로 유지되고 다른 하나는 비디오를 팝업으로 렌더링합니다.

문제를 제공하는 코드 라인은 다음과 같습니다

hr = this.captureGraphBuilder.RenderStream(PinCategory.Capture, 
    MediaType.Video, sourceFilter, null, null); 

문제는, 비디오 렌더러를 삽입하고 집어 연결할 수를 예상하여 그래프를 구축 사람들 quite typical 특히 그것이 때때로 작품 및 그러한 코드 스 니펫은 온라인에서 찾을 수 있습니다.

MSDN 말한다 다음 pSink 매개 변수가 NULL

경우, 메소드는 디폴트의 렌더링을 사용하려고합니다. 비디오의 경우 Video Renderer을 사용하고 오디오의 경우 DirectSound 렌더러를 사용합니다.

호출이 다른 인스턴스를 추가 했으므로 기존 인스턴스가 연결될 것으로 예상했습니다. RenderStream은 강력한 호출이고 연결된 것을 얻기 위해 마법을 걸러내는 반면, 잘못된 방법으로 뭔가를 끝내기 쉽습니다.

이미 비디오 렌더러를 사용하고 있다면이 호출에서 싱크 인수로 사용할 수 있습니다. 또는 RenderStream을 피하고 점차적으로 필터를 추가하여 모든 것이 기대치에 부합하는지 확인해야합니다.

... 방법은 필터 그래프에 이미 렌더러를 사용하려고 시도합니다 : 아니면, 또 다른 옵션은 AM_RENDEREX_RENDERTOEXISTINGRENDERERS 플래그 대신 IFilterGraph2::RenderEx 전화입니다. 새로운 렌더러를 그래프에 추가하지 않습니다. (필요한 경우 중간 변환 필터가 추가됩니다.) 메서드가 성공하려면 그래프에 적절한 렌더러가 있어야하며 연결되지 않은 입력 핀이 있어야합니다.

+0

렌더 필터를 sink 매개 변수로 사용했습니다. 그것은 의도 한 그래프를 만든 것으로 보이지만 비디오를 창에 표시하지 않습니다. 더 이상 'ActiveMovie 창'이 없지만 웹캠 비디오가 창에 나타나지 않습니다. '시간 = this.captureGraphBuilder.RenderStream (PinCategory.Capture, MediaType.Video, sourceFilter, 널 (null), renderFilter)이 윈도우가 어떻게 생겼는지의 이미지입니다' : 이 내가 렌더링 필터를 추가하는 방법입니다 : http://imgur.com/a/ljMPS. 다음은 새로운 캡처 그래프 이미지입니다 (http://imgur.com/a/FiLOU). –

+1

['IVMRWindowlessControl9 :: SetVideoPosition'] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd390550)을 사용하여 렌더러를 배치합니까? 나는 위의 코드에서 이것을 보지 못했다. 또한 질문을 업데이트 할 수 있습니다 (특히 이미지를 삽입 할 때) –

+0

우수. 웬일인지, 나는'IVMRWindowlessControl9'에 SetVideoPosition()이 필요하다고 생각하지 않았습니다. 하지만 그 트릭을했다. 결국, 필자의 필터 그래프가 잘못 설정되어 비디오 위치를 설정해야했습니다. –