0

I've created a custom DirectShow CTransInPlace filter meant to replicate the SampleGrabber filter and related interfaces with support for VIDEOINFOHEADER2 called SampleGrabber2. I currently have the pins set up such that if VIH2 is present but not provided, the pin will deny any VIH1 media types. If there are no VIH2 media types, it will take the first provided VIH1 type. This works as expected in GraphEdit once connected, but when I try to connect there is some interesting behavior.

I have 4 DirectShow filters in the graph:

  • Capture filter for a webcam that only outputs VIH1
  • Capture filter for a capture board (CB) that outputs both VIH1 and VIH2
  • SampleGrabber2
  • VMR9

I first connect CB to SampleGrabber2 with no errors. This connection correctly prioritizes VIH2. Then I connect SampleGrabber2's output to a VMR9 filter. This action disconnects CB from SampleGrabber2 while leaving the connection between VMR9 and SampleGrabber2 intact. After the forceful disconnection, I can reconnect CB to SampleGrabber2 and run the graph as normal. Connecting the webcam to SampleGrabber2 then SampleGrabber2 to VMR9 does not produce these disconnections.

Here is the relevant media type negotiation code, how can I make a seamless negotiation and prevent these disconnects? I'm assuming this has something to do with the allocator negotiation but so far I've had no luck trying to remedy that.

HRESULT CSG2InPin::CheckMediaType(const CMediaType* pmt)
{
 if (!pmt) return E_POINTER;
 
 if (IsConnected()) {
 const CMediaType& cur = CurrentMediaType();
 return (*pmt == cur) ? S_OK : VFW_E_TYPE_NOT_ACCEPTED;
 }
 // One-time probe: does the peer enumerate a VIH2 we would accept?
 if (!m_peerHasVIH2Checked && m_spPeer) {
 m_peerHasVIH2Checked = true;
 CComPtr<IEnumMediaTypes> spEnum;
 if (SUCCEEDED(m_spPeer->EnumMediaTypes(&spEnum)) && spEnum) {
 AM_MEDIA_TYPE* pTry = nullptr;
 while (spEnum->Next(1, &pTry, nullptr) == S_OK) {
 CMediaType mt(*pTry);
 if (mt.majortype == MEDIATYPE_Video &&
 mt.formattype == FORMAT_VideoInfo2 &&
 SUCCEEDED(m_pTransformFilter->CheckInputType(&mt))) {
 m_peerHasVIH2 = true;
 break;
 }
 }
 }
 }
 // If the peer can do VIH2 and we’re currently being offered VIH1, decline it
 // so the search advances to VIH2.
 if (pmt->majortype == MEDIATYPE_Video &&
 pmt->formattype == FORMAT_VideoInfo &&
 m_peerHasVIH2) {
 return VFW_E_TYPE_NOT_ACCEPTED; // "Prefer VIH2 if available"
 }
 // Otherwise, defer to the filter’s policy
 return m_pTransformFilter->CheckInputType(pmt);
}
...
HRESULT CSampleGrabber2::CheckInputType(const CMediaType* mtIn)
{
 if ((mtIn->majortype != MEDIATYPE_Video) ||
 (mtIn->formattype != FORMAT_VideoInfo) && 
 (mtIn->formattype != FORMAT_VideoInfo2))
 {
 return VFW_E_TYPE_NOT_ACCEPTED;
 }
 
 currentFormat = (mtIn->formattype == FORMAT_VideoInfo2) ? VIH2 : VIH;
 return S_OK;
}
asked Nov 4 at 23:19

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.