summaryrefslogtreecommitdiff
path: root/src/plugins/directshow/player/directshowiosource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/directshow/player/directshowiosource.cpp')
-rw-r--r--src/plugins/directshow/player/directshowiosource.cpp169
1 files changed, 39 insertions, 130 deletions
diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp
index 6dee14fb0..bb4d0f00d 100644
--- a/src/plugins/directshow/player/directshowiosource.cpp
+++ b/src/plugins/directshow/player/directshowiosource.cpp
@@ -46,13 +46,6 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qurl.h>
-static const GUID directshow_subtypes[] =
-{
- MEDIASUBTYPE_Avi,
- MEDIASUBTYPE_WAVE,
- MEDIASUBTYPE_NULL
-};
-
DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop)
: m_ref(1)
, m_state(State_Stopped)
@@ -63,30 +56,21 @@ DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop)
, m_allocator(0)
, m_peerPin(0)
, m_pinId(QLatin1String("Data"))
+ , m_queriedForAsyncReader(false)
{
- 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);
- }
+ // This filter has only one possible output type, that is, a stream of data
+ // with no particular subtype. The graph builder will try every demux/decode filters
+ // to find one able to decode the stream.
+ //
+ // The filter works in pull mode, the downstream filter is responsible for requesting
+ // samples from this one.
+
+ m_outputType.majortype = MEDIATYPE_Stream;
+ m_outputType.subtype = MEDIASUBTYPE_NULL; // Wildcard
+ m_outputType.bFixedSizeSamples = TRUE;
+ m_outputType.lSampleSize = 1;
- setMediaTypes(mediaTypes);
+ setMediaTypes(QVector<AM_MEDIA_TYPE>() << m_outputType);
}
DirectShowIOSource::~DirectShowIOSource()
@@ -136,6 +120,7 @@ HRESULT DirectShowIOSource::QueryInterface(REFIID riid, void **ppvObject)
} else if (riid == IID_IPin) {
*ppvObject = static_cast<IPin *>(this);
} else if (riid == IID_IAsyncReader) {
+ m_queriedForAsyncReader = true;
*ppvObject = static_cast<IAsyncReader *>(m_reader);
} else {
*ppvObject = 0;
@@ -330,116 +315,40 @@ ULONG DirectShowIOSource::GetMiscFlags()
// IPin
HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
- QMutexLocker locker(&m_mutex);
- if (!pReceivePin) {
+ if (!pReceivePin)
return E_POINTER;
- } else if (m_state != State_Stopped) {
- return VFW_E_NOT_STOPPED;
- } else if (m_peerPin) {
- return VFW_E_ALREADY_CONNECTED;
- } else {
- HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
-
- m_peerPin = pReceivePin;
- m_peerPin->AddRef();
- if (!pmt) {
- IEnumMediaTypes *mediaTypes = 0;
- if (pReceivePin->EnumMediaTypes(&mediaTypes) == S_OK) {
- for (AM_MEDIA_TYPE *type = 0;
- mediaTypes->Next(1, &type, 0) == S_OK;
- DirectShowMediaType::deleteType(type)) {
- switch (tryConnect(pReceivePin, type)) {
- case S_OK:
- DirectShowMediaType::freeData(type);
- mediaTypes->Release();
- return S_OK;
- case VFW_E_NO_TRANSPORT:
- hr = VFW_E_NO_TRANSPORT;
- break;
- default:
- break;
- }
- }
- mediaTypes->Release();
- }
- 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];
-
- switch (tryConnect(pReceivePin, &type)) {
- case S_OK:
- return S_OK;
- case VFW_E_NO_TRANSPORT:
- hr = VFW_E_NO_TRANSPORT;
- break;
- default:
- break;
- }
- }
- } else if (pmt->majortype == MEDIATYPE_Stream && (hr = tryConnect(pReceivePin, pmt))) {
- return S_OK;
- }
-
- m_peerPin->Release();
- m_peerPin = 0;
+ QMutexLocker locker(&m_mutex);
- m_mediaType.clear();
+ if (m_state != State_Stopped)
+ return VFW_E_NOT_STOPPED;
- return hr;
- }
-}
+ if (m_peerPin)
+ return VFW_E_ALREADY_CONNECTED;
-HRESULT DirectShowIOSource::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type)
-{
- m_mediaType = *type;
+ // If we get a type from the graph manager, check that we support that
+ if (pmt && (pmt->majortype != MEDIATYPE_Stream || pmt->subtype != MEDIASUBTYPE_NULL))
+ return VFW_E_TYPE_NOT_ACCEPTED;
- HRESULT hr = pin->ReceiveConnection(this, type);
+ // 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);
- if (!SUCCEEDED(hr)) {
+ if (SUCCEEDED(hr) && m_queriedForAsyncReader) {
+ m_peerPin = pReceivePin;
+ m_peerPin->AddRef();
+ } else {
+ pReceivePin->Disconnect();
if (m_allocator) {
m_allocator->Release();
m_allocator = 0;
}
- } else if (!m_allocator) {
- hr = VFW_E_NO_TRANSPORT;
-
- if (IMemInputPin *memPin = com_cast<IMemInputPin>(pin, IID_IMemInputPin)) {
- if ((m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator))) {
- ALLOCATOR_PROPERTIES properties;
- if (memPin->GetAllocatorRequirements(&properties) == S_OK
- || m_allocator->GetProperties(&properties) == S_OK) {
- if (properties.cbAlign == 0)
- properties.cbAlign = 1;
-
- ALLOCATOR_PROPERTIES actualProperties;
- if (SUCCEEDED(hr = m_allocator->SetProperties(&properties, &actualProperties)))
- hr = memPin->NotifyAllocator(m_allocator, TRUE);
- }
- if (!SUCCEEDED(hr)) {
- m_allocator->Release();
- m_allocator = 0;
- }
- }
- memPin->Release();
- }
- if (!SUCCEEDED(hr))
- pin->Disconnect();
+ if (!m_queriedForAsyncReader)
+ hr = VFW_E_NO_TRANSPORT;
}
+
return hr;
}
@@ -453,6 +362,8 @@ HRESULT DirectShowIOSource::ReceiveConnection(IPin *pConnector, const AM_MEDIA_T
HRESULT DirectShowIOSource::Disconnect()
{
+ QMutexLocker locker(&m_mutex);
+
if (!m_peerPin) {
return S_FALSE;
} else if (m_state != State_Stopped) {
@@ -471,8 +382,6 @@ HRESULT DirectShowIOSource::Disconnect()
m_peerPin->Release();
m_peerPin = 0;
- m_mediaType.clear();
-
return S_OK;
}
}
@@ -510,7 +419,7 @@ HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
return VFW_E_NOT_CONNECTED;
} else {
- DirectShowMediaType::copy(pmt, m_mediaType);
+ DirectShowMediaType::copy(pmt, m_outputType);
return S_OK;
}