미리 보기 핀 구현(선택 사항)
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine 및 오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]
이 항목에서는 DirectShow 캡처 필터에서 미리 보기 핀을 구현하는 방법을 설명합니다.
필터에 미리 보기 핀이 있는 경우 미리 보기 핀은 캡처 핀에서 전달된 데이터의 복사본을 보내야 합니다. 이렇게 할 때 미리 보기 핀에서만 데이터를 보내면 캡처 핀이 프레임을 삭제하지 않습니다. 캡처 핀은 항상 미리 보기 핀보다 우선 순위가 있습니다.
캡처 핀과 미리 보기 핀은 동일한 형식의 데이터를 보내야 합니다. 따라서 동일한 미디어 형식을 사용하여 연결해야 합니다. 캡처 핀이 먼저 연결되면 미리 보기 핀은 동일한 미디어 형식을 제공하고 다른 형식을 거부해야 합니다. 미리 보기 핀이 먼저 연결되고 캡처 핀이 다른 미디어 유형과 연결되는 경우 미리 보기 핀은 새 미디어 형식을 사용하여 다시 연결해야 합니다. 미리 보기 핀의 필터 다운스트림에서 새 형식을 거부하는 경우 캡처 핀도 형식을 거부해야 합니다. IPin::QueryAccept 메서드를 사용하여 미리 보기 핀에서 필터 다운스트림을 쿼리하고 IFilterGraph::Reconnect 메서드를 사용하여 핀을 다시 연결합니다. 이러한 규칙은 필터 그래프 관리자가 캡처 핀을 다시 연결하는 경우에도 적용됩니다.
다음 예제에서는 이 프로세스의 개요를 보여줍니다.
// Override CBasePin::CheckMediaType.
CCapturePin::CheckMediaType(CMediaType *pmt)
{
if (m_pMyPreviewPin->IsConnected())
{
// The preview pin is already connected, so query the pin it is
// connected to. If the other pin rejects it, so do we.
hr = m_pMyPreviewPin->GetConnected()->QueryAccept(pmt);
if (hr != S_OK)
{
// The preview pin cannot reconnect with this media type.
return E_INVALIDARG;
}
// The preview pin will reconnect when SetMediaType is called.
}
// Decide whether the capture pin accepts the format.
BOOL fAcceptThisType = ... // (Not shown.)
return (fAcceptThisType? S_OK : E_FAIL);
}
// Override CBasePin::SetMediaType.
CCapturePin::SetMediaType(CMediaType *pmt);
{
if (m_pMyPreviewPin->IsConnected())
{
// The preview pin is already connected, so it must reconnect.
if (m_pMyPreviewPin->GetConnected()->QueryAccept(pmt) == S_OK)
{
// The downstream pin will accept the new type, so it's safe
// to reconnect.
m_pFilter->m_pGraph->Reconnect(m_pMyPreviewPin);
}
else
{
return VFW_E_INVALIDMEDIATYPE;
}
}
// Now do anything that the capture pin needs to set the type.
hr = MyInternalSetMediaType(pmt);
// And finally, call the base-class method.
return CBasePin::SetMediaType(pmt);
}
CPreviewPin::CheckMediaType(CMediaType *pmt)
{
if (m_pMyCapturePin->IsConnected())
{
// The preview pin must connect with the same type.
CMediaType cmt = m_pMyCapturePin->m_mt;
return (*pmt == cmt ? S_OK : VFW_E_INVALIDMEDIATYPE);
}
// Decide whether the preview pin accepts the format. You can use your
// knowledge of which types the capture pin will accept. Regardless,
// when the capture pin connects, the preview pin will reconnect.
return (fAcceptThisType? S_OK : E_FAIL);
}
관련 항목