diff options
author | Christian Stromme <christian.stromme@theqtcompany.com> | 2016-08-12 14:24:49 +0200 |
---|---|---|
committer | Christian Stromme <christian.stromme@qt.io> | 2016-08-23 13:27:01 +0000 |
commit | 4025a05c64100b13615f856ac0b403b3623a5cf4 (patch) | |
tree | c1d8c5d986bdfac49d2c363755603e72acb36ca6 /src/plugins/directshow/player | |
parent | 0ce67605de8e71f0607b36e2ef28801c3fc5c655 (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>
Diffstat (limited to 'src/plugins/directshow/player')
-rw-r--r-- | src/plugins/directshow/player/directshowiosource.cpp | 82 | ||||
-rw-r--r-- | src/plugins/directshow/player/directshowiosource.h | 2 | ||||
-rw-r--r-- | src/plugins/directshow/player/directshowmediatypelist.h | 4 |
3 files changed, 77 insertions, 11 deletions
diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp index 6fa3c7b9a..1b74415e4 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 f5e8ec6d1..60300ba18 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 860334532..8dc6e17e4 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 |