dshowsrcwrapper: fix DirectShow caps negotiation and set capture pin caps
authorJerome Laheurte <jlaheurte@quividi.com>
Fri, 22 Apr 2016 12:51:31 +0000 (14:51 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 23 Apr 2016 14:21:44 +0000 (15:21 +0100)
Some cameras (IDS) have broken DirectShow drivers which incorrectly fill some
fields in the VIDEOINFOHEADER structure; comparison between suggested and
supported media types in CBaseRenderer should ignore deprecated and/or not
essential fields; additionaly explicitely setting the mediatype for the capture
pin before trying to connect it works around another IDS driver bug, and
should have been already done anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=765428

sys/dshowsrcwrapper/gstdshowfakesink.cpp
sys/dshowsrcwrapper/gstdshowvideosrc.cpp

index c524c7c..3c5fca8 100644 (file)
@@ -46,12 +46,19 @@ STDMETHODIMP
 
 HRESULT CDshowFakeSink::CheckMediaType (const CMediaType * pmt)
 {
-  if (pmt != NULL) {
-    if (*pmt == m_MediaType)
-      return S_OK;
-  }
+  if (!IsEqualGUID(pmt->majortype, m_MediaType.majortype) ||
+      !IsEqualGUID(pmt->subtype, m_MediaType.subtype) ||
+      !IsEqualGUID(pmt->formattype, m_MediaType.formattype) ||
+      (pmt->cbFormat != m_MediaType.cbFormat))
+    return S_FALSE;
+
+  VIDEOINFOHEADER *info1 = (VIDEOINFOHEADER*)pmt->pbFormat;
+  VIDEOINFOHEADER *info2 = (VIDEOINFOHEADER*)m_MediaType.pbFormat;
 
-  return S_FALSE;
+  if (memcmp(&info1->bmiHeader, &info2->bmiHeader, sizeof(BITMAPINFOHEADER)))
+    return S_FALSE;
+
+  return S_OK;
 }
 
 HRESULT CDshowFakeSink::DoRenderSample (IMediaSample * pMediaSample)
index e4ade97..9b478db 100644 (file)
@@ -682,6 +682,12 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
           src->filter_graph->Disconnect (input_pin);
         }
 
+        hres = src->pVSC->SetFormat(pin_mediatype->mediatype);
+        if (FAILED (hres)) {
+          GST_ERROR ("Failed to set capture pin format (error=0x%x)", hres);
+          goto error;
+        }
+
         hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin,
             input_pin, pin_mediatype->mediatype);
         input_pin->Release ();