summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2020-09-22 13:04:44 +0200
committerVal Doroshchuk <valentyn.doroshchuk@qt.io>2020-09-24 11:30:48 +0200
commitbf82ab669c53c4b9abb724e197252a788323095e (patch)
tree88de9b04c52327bc650662756eecf43d4e6f84b0
parentce6440c999c34a2b80fa25121e893eccf68203a5 (diff)
downloadqtmultimedia-bf82ab669c53c4b9abb724e197252a788323095e.tar.gz
DirectShow: Use also pin category when negotiating
The pin should be negotiated once and use PIN_CATEGORY_CAPTURE. The same logic is implemented in chromium. Pick-to: 5.15 Change-Id: I89ac13c1a7e982c1011b2a872e853ee5bc2036b2 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp66
-rw-r--r--src/plugins/directshow/camera/dscamerasession.h2
-rw-r--r--src/plugins/directshow/common/directshowutils.cpp29
-rw-r--r--src/plugins/directshow/common/directshowutils.h2
4 files changed, 57 insertions, 42 deletions
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index e7467bf0b..7ceefe2c5 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -428,6 +428,7 @@ bool DSCameraSession::unload()
SAFE_RELEASE(m_nullRendererFilter);
SAFE_RELEASE(m_filterGraph);
SAFE_RELEASE(m_graphBuilder);
+ SAFE_RELEASE(m_outputPin);
setStatus(QCamera::UnloadedStatus);
@@ -781,6 +782,9 @@ bool DSCameraSession::createFilterGraph()
goto failed;
}
+ if (!DirectShowUtils::getPin(m_sourceFilter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE, &m_outputPin, &hr))
+ qWarning() << "Failed to get the pin for the video control:" << hr;
+
// Sample grabber filter
if (!m_previewSampleGrabber) {
m_previewSampleGrabber = new DirectShowSampleGrabber(this);
@@ -1055,24 +1059,18 @@ void DSCameraSession::updateSourceCapabilities()
reinterpret_cast<void**>(&pVideoControl));
if (FAILED(hr)) {
qWarning() << "Failed to get the video control";
- } else {
- IPin *pPin = nullptr;
- if (!DirectShowUtils::getPin(m_sourceFilter, PINDIR_OUTPUT, &pPin, &hr)) {
- qWarning() << "Failed to get the pin for the video control";
- } else {
- long supportedModes;
- hr = pVideoControl->GetCaps(pPin, &supportedModes);
- if (FAILED(hr)) {
- qWarning() << "Failed to get the supported modes of the video control";
- } else if (supportedModes & VideoControlFlag_FlipHorizontal) {
- long mode;
- hr = pVideoControl->GetMode(pPin, &mode);
- if (FAILED(hr))
- qWarning() << "Failed to get the mode of the video control";
- else if (supportedModes & VideoControlFlag_FlipHorizontal)
- m_needsHorizontalMirroring = (mode & VideoControlFlag_FlipHorizontal);
- }
- pPin->Release();
+ } else if (m_outputPin) {
+ long supportedModes;
+ hr = pVideoControl->GetCaps(m_outputPin, &supportedModes);
+ if (FAILED(hr)) {
+ qWarning() << "Failed to get the supported modes of the video control";
+ } else if (supportedModes & VideoControlFlag_FlipHorizontal) {
+ long mode;
+ hr = pVideoControl->GetMode(m_outputPin, &mode);
+ if (FAILED(hr))
+ qWarning() << "Failed to get the mode of the video control";
+ else if (supportedModes & VideoControlFlag_FlipHorizontal)
+ m_needsHorizontalMirroring = (mode & VideoControlFlag_FlipHorizontal);
}
pVideoControl->Release();
}
@@ -1107,28 +1105,22 @@ void DSCameraSession::updateSourceCapabilities()
QList<QCamera::FrameRateRange> frameRateRanges;
- if (pVideoControl) {
- IPin *pPin = nullptr;
- if (!DirectShowUtils::getPin(m_sourceFilter, PINDIR_OUTPUT, &pPin, &hr)) {
- qWarning() << "Failed to get the pin for the video control";
- } else {
- long listSize = 0;
- LONGLONG *frameRates = nullptr;
- SIZE size = { resolution.width(), resolution.height() };
- hr = pVideoControl->GetFrameRateList(pPin, iIndex, size, &listSize, &frameRates);
- if (hr == S_OK && listSize > 0 && frameRates) {
- for (long i = 0; i < listSize; ++i) {
- qreal fr = qreal(10000000) / frameRates[i];
- frameRateRanges.append(QCamera::FrameRateRange(fr, fr));
- }
-
- // Make sure higher frame rates come first
- std::sort(frameRateRanges.begin(), frameRateRanges.end(), qt_frameRateRangeGreaterThan);
+ if (pVideoControl && m_outputPin) {
+ long listSize = 0;
+ LONGLONG *frameRates = nullptr;
+ SIZE size = { resolution.width(), resolution.height() };
+ hr = pVideoControl->GetFrameRateList(m_outputPin, iIndex, size, &listSize, &frameRates);
+ if (hr == S_OK && listSize > 0 && frameRates) {
+ for (long i = 0; i < listSize; ++i) {
+ qreal fr = qreal(10000000) / frameRates[i];
+ frameRateRanges.append(QCamera::FrameRateRange(fr, fr));
}
- CoTaskMemFree(frameRates);
- pPin->Release();
+ // Make sure higher frame rates come first
+ std::sort(frameRateRanges.begin(), frameRateRanges.end(), qt_frameRateRangeGreaterThan);
}
+
+ CoTaskMemFree(frameRates);
}
if (frameRateRanges.isEmpty()) {
diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h
index 5e7d026c2..9f88163b9 100644
--- a/src/plugins/directshow/camera/dscamerasession.h
+++ b/src/plugins/directshow/camera/dscamerasession.h
@@ -231,6 +231,8 @@ private:
QMap<QCameraImageProcessingControl::ProcessingParameter, QVariant> m_pendingImageProcessingParametrs;
+ IPin *m_outputPin = nullptr;
+
friend class SampleGrabberCallbackPrivate;
};
diff --git a/src/plugins/directshow/common/directshowutils.cpp b/src/plugins/directshow/common/directshowutils.cpp
index 1457837ce..9222ad779 100644
--- a/src/plugins/directshow/common/directshowutils.cpp
+++ b/src/plugins/directshow/common/directshowutils.cpp
@@ -93,6 +93,25 @@ bool DirectShowUtils::hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESUL
return (pinDir == direction);
}
+bool pinMatchesCategory(IPin* pPin, REFGUID category)
+{
+ bool found = false;
+ IKsPropertySet *pKs = nullptr;
+ DirectShowUtils::ScopedSafeRelease<IKsPropertySet> ks_property { &pKs };
+ HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs));
+
+ if (SUCCEEDED(hr)) {
+ GUID pin_category;
+ DWORD return_value;
+ hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
+ &pin_category, sizeof(pin_category), &return_value);
+ if (SUCCEEDED(hr) && (return_value == sizeof(pin_category)))
+ found = (pin_category == category);
+ }
+
+ return found;
+}
+
/**
* @brief DirectShowUtils::getPin
* @param filter
@@ -101,7 +120,7 @@ bool DirectShowUtils::hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESUL
* @param hrOut
* @return
*/
-bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut)
+bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, REFGUID category, IPin **pin, HRESULT *hrOut)
{
IEnumPins *enumPins = nullptr;
const ScopedSafeRelease<IEnumPins> releaseEnumPins { &enumPins };
@@ -122,9 +141,11 @@ bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IP
PIN_DIRECTION currentPinDir;
*hrOut = nextPin->QueryDirection(&currentPinDir);
if (currentPinDir == pinDirection) {
- *pin = nextPin;
- (*pin)->AddRef();
- return true;
+ if (category == GUID_NULL || pinMatchesCategory(nextPin, category)) {
+ *pin = nextPin;
+ (*pin)->AddRef();
+ return true;
+ }
}
}
diff --git a/src/plugins/directshow/common/directshowutils.h b/src/plugins/directshow/common/directshowutils.h
index 5f2cfaa23..ec761abe6 100644
--- a/src/plugins/directshow/common/directshowutils.h
+++ b/src/plugins/directshow/common/directshowutils.h
@@ -68,7 +68,7 @@ struct ScopedSafeRelease
}
};
-bool getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut);
+bool getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, REFGUID category, IPin **pin, HRESULT *hrOut);
bool isPinConnected(IPin *pin, HRESULT *hrOut = nullptr);
bool hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut = nullptr);
bool matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut = nullptr);