summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Stromme <christian.stromme@theqtcompany.com>2016-08-12 14:24:49 +0200
committerChristian Stromme <christian.stromme@qt.io>2016-08-23 13:27:01 +0000
commit4025a05c64100b13615f856ac0b403b3623a5cf4 (patch)
treec1d8c5d986bdfac49d2c363755603e72acb36ca6
parent0ce67605de8e71f0607b36e2ef28801c3fc5c655 (diff)
DirectShow: Restore negotiation of sample type in the io filter
This functionality was removed in d44a327da4a956f62cc0d51, but is still needed, as we need to negotiate the media type with the input pin; even if we limit the scope to streaming types. Task-number: QTBUG-55264 Change-Id: I7cc02c5ea17cca9912c29c40813314b04b91bd18 Reviewed-by: Yoann Lopes <yoann.lopes@qt.io>
-rw-r--r--src/plugins/directshow/player/directshowiosource.cpp82
-rw-r--r--src/plugins/directshow/player/directshowiosource.h2
-rw-r--r--src/plugins/directshow/player/directshowmediatypelist.h4
3 files changed, 77 insertions, 11 deletions
diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp
index 6fa3c7b9..1b74415e 100644
--- a/src/plugins/directshow/player/directshowiosource.cpp
+++ b/src/plugins/directshow/player/directshowiosource.cpp
@@ -40,6 +40,22 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qurl.h>
+static const GUID directshow_subtypes[] =
+{
+ MEDIASUBTYPE_NULL,
+ MEDIASUBTYPE_Avi,
+ MEDIASUBTYPE_Asf,
+ MEDIASUBTYPE_MPEG1Video,
+ MEDIASUBTYPE_QTMovie,
+ MEDIASUBTYPE_WAVE,
+ MEDIASUBTYPE_AIFF,
+ MEDIASUBTYPE_AU,
+ MEDIASUBTYPE_DssVideo,
+ MEDIASUBTYPE_MPEG1Audio,
+ MEDIASUBTYPE_MPEG1System,
+ MEDIASUBTYPE_MPEG1VideoCD
+};
+
DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop)
: m_ref(1)
, m_state(State_Stopped)
@@ -58,13 +74,29 @@ DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop)
//
// The filter works in pull mode, the downstream filter is responsible for requesting
// samples from this one.
+ //
+ QVector<AM_MEDIA_TYPE> mediaTypes;
+ AM_MEDIA_TYPE type =
+ {
+ MEDIATYPE_Stream, // majortype
+ MEDIASUBTYPE_NULL, // subtype
+ TRUE, // bFixedSizeSamples
+ FALSE, // bTemporalCompression
+ 1, // lSampleSize
+ GUID_NULL, // formattype
+ 0, // pUnk
+ 0, // cbFormat
+ 0, // pbFormat
+ };
+
+ static const int count = sizeof(directshow_subtypes) / sizeof(GUID);
+
+ for (int i = 0; i < count; ++i) {
+ type.subtype = directshow_subtypes[i];
+ mediaTypes.append(type);
+ }
- m_outputType.majortype = MEDIATYPE_Stream;
- m_outputType.subtype = MEDIASUBTYPE_NULL; // Wildcard
- m_outputType.bFixedSizeSamples = TRUE;
- m_outputType.lSampleSize = 1;
-
- setMediaTypes(QVector<AM_MEDIA_TYPE>() << m_outputType);
+ setMediaTypes(mediaTypes);
}
DirectShowIOSource::~DirectShowIOSource()
@@ -321,14 +353,44 @@ HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
return VFW_E_ALREADY_CONNECTED;
// If we get a type from the graph manager, check that we support that
- if (pmt && (pmt->majortype != MEDIATYPE_Stream || pmt->subtype != MEDIASUBTYPE_NULL))
+ if (pmt && pmt->majortype != MEDIATYPE_Stream)
return VFW_E_TYPE_NOT_ACCEPTED;
// This filter only works in pull mode, the downstream filter must query for the
// AsyncReader interface during ReceiveConnection().
// If it doesn't, we can't connect to it.
m_queriedForAsyncReader = false;
- HRESULT hr = pReceivePin->ReceiveConnection(this, pmt ? pmt : &m_outputType);
+ HRESULT hr = 0;
+ // Negotiation of media type
+ // - Complete'ish type (Stream with subtype specified).
+ if (pmt && pmt->subtype != MEDIASUBTYPE_NULL /* aka. GUID_NULL */) {
+ hr = pReceivePin->ReceiveConnection(this, pmt);
+ // Update the media type for the current connection.
+ if (SUCCEEDED(hr))
+ m_connectionMediaType = *pmt;
+ } else if (pmt && pmt->subtype == MEDIATYPE_NULL) { // - Partial type (Stream, but no subtype specified).
+ m_connectionMediaType = *pmt;
+ // Check if the receiving pin accepts any of the streaming subtypes.
+ QVector<AM_MEDIA_TYPE>::const_iterator cit = m_mediaTypes.constBegin();
+ while (cit != m_mediaTypes.constEnd()) {
+ m_connectionMediaType.subtype = cit->subtype;
+ hr = pReceivePin->ReceiveConnection(this, &m_connectionMediaType);
+ if (SUCCEEDED(hr))
+ break;
+ ++cit;
+ }
+ } else { // - No media type specified.
+ // Check if the receiving pin accepts any of the streaming types.
+ QVector<AM_MEDIA_TYPE>::const_iterator cit = m_mediaTypes.constBegin();
+ while (cit != m_mediaTypes.constEnd()) {
+ hr = pReceivePin->ReceiveConnection(this, cit);
+ if (SUCCEEDED(hr)) {
+ m_connectionMediaType = *cit;
+ break;
+ }
+ ++cit;
+ }
+ }
if (SUCCEEDED(hr) && m_queriedForAsyncReader) {
m_peerPin = pReceivePin;
@@ -341,6 +403,8 @@ HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
}
if (!m_queriedForAsyncReader)
hr = VFW_E_NO_TRANSPORT;
+
+ m_connectionMediaType.clear();
}
return hr;
@@ -413,7 +477,7 @@ HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
return VFW_E_NOT_CONNECTED;
} else {
- DirectShowMediaType::copy(pmt, m_outputType);
+ DirectShowMediaType::copy(pmt, m_connectionMediaType);
return S_OK;
}
diff --git a/src/plugins/directshow/player/directshowiosource.h b/src/plugins/directshow/player/directshowiosource.h
index f5e8ec6d..60300ba1 100644
--- a/src/plugins/directshow/player/directshowiosource.h
+++ b/src/plugins/directshow/player/directshowiosource.h
@@ -119,7 +119,7 @@ private:
IReferenceClock *m_clock;
IMemAllocator *m_allocator;
IPin *m_peerPin;
- DirectShowMediaType m_outputType;
+ DirectShowMediaType m_connectionMediaType;
QString m_filterName;
const QString m_pinId;
bool m_queriedForAsyncReader;
diff --git a/src/plugins/directshow/player/directshowmediatypelist.h b/src/plugins/directshow/player/directshowmediatypelist.h
index 86033453..8dc6e17e 100644
--- a/src/plugins/directshow/player/directshowmediatypelist.h
+++ b/src/plugins/directshow/player/directshowmediatypelist.h
@@ -54,9 +54,11 @@ public:
virtual HRESULT skipMediaType(int token, int *index, ULONG count);
virtual HRESULT cloneMediaType(int token, int index, IEnumMediaTypes **enumeration);
+protected:
+ QVector<AM_MEDIA_TYPE> m_mediaTypes;
+
private:
int m_mediaTypeToken;
- QVector<AM_MEDIA_TYPE> m_mediaTypes;
};
#endif