Das Aufnahmegerät trennt die Verbindung zum benutzerdefinierten CTransInPlaceFilter, wenn eine Verbindung zum Renderer iC++

Programme in C++. Entwicklerforum
Anonymous
 Das Aufnahmegerät trennt die Verbindung zum benutzerdefinierten CTransInPlaceFilter, wenn eine Verbindung zum Renderer i

Post by Anonymous »

Ich habe einen benutzerdefinierten DirectShow CTransInPlace-Filter namens SampleGrabber2 erstellt, der den SampleGrabber-Filter und zugehörige Schnittstellen mit Unterstützung für VIDEOINFOHEADER2 replizieren soll. Ich habe die Pins derzeit so eingerichtet, dass der Pin alle VIH1-Medientypen ablehnt, wenn VIH2 vorhanden, aber nicht bereitgestellt ist. Wenn keine VIH2-Medientypen vorhanden sind, wird der erste bereitgestellte VIH1-Typ verwendet. Dies funktioniert wie erwartet in GraphEdit, sobald die Verbindung hergestellt ist, aber wenn ich versuche, eine Verbindung herzustellen, tritt ein interessantes Verhalten auf.
Ich habe 4 DirectShow-Filter im Diagramm:
  • Aufnahmefilter für eine Webcam, die nur VIH1 ausgibt
  • Aufnahmefilter für ein Capture Board (CB), das sowohl VIH1 als auch VIH2 ausgibt
  • SampleGrabber2
  • VMR9
Ich habe CB zunächst ohne Fehler mit SampleGrabber2 verbunden. Diese Verbindung priorisiert VIH2 korrekt. Dann verbinde ich den Ausgang von SampleGrabber2 mit einem VMR9-Filter. Diese Aktion trennt CB von SampleGrabber2, während die Verbindung zwischen VMR9 und SampleGrabber2 intakt bleibt. Nach der erzwungenen Trennung kann ich CB wieder mit SampleGrabber2 verbinden und das Diagramm wie gewohnt ausführen. Das Verbinden der Webcam mit SampleGrabber2 und dann SampleGrabber2 mit VMR9 führt nicht zu diesen Verbindungsabbrüchen.
Hier ist der relevante Medientyp-Aushandlungscode. Wie kann ich eine nahtlose Aushandlung durchführen und diese Verbindungsabbrüche verhindern? Ich gehe davon aus, dass dies etwas mit der Allokatorverhandlung zu tun hat, aber bisher hatte ich kein Glück, das Problem zu beheben.

Code: Select all

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 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;
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post