summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-11-07 15:53:18 +0100
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-12-04 11:41:42 +0000
commita6164acd2f35daca98e6b79b97b8fb55d1d4359a (patch)
treebaf5fe98b89e28e0b947615b9aecb35822ed1932 /src
parent43f3d14a99431da5e0ebd29f6c1f27526a6e2d48 (diff)
WMF: fix type negotiation in video probe transform.
- report supported types (same as the video sink) - handle type changes coming from upstream Change-Id: I922fc4869ecac3999e055c39adf1b847127a0012 Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/wmf/mftvideo.cpp142
-rw-r--r--src/plugins/wmf/mftvideo.h4
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp19
3 files changed, 87 insertions, 78 deletions
diff --git a/src/plugins/wmf/mftvideo.cpp b/src/plugins/wmf/mftvideo.cpp
index b141d49a2..5f32f1f61 100644
--- a/src/plugins/wmf/mftvideo.cpp
+++ b/src/plugins/wmf/mftvideo.cpp
@@ -52,6 +52,7 @@ MFTransform::MFTransform():
m_inputType(0),
m_outputType(0),
m_sample(0),
+ m_videoSinkTypeHandler(0),
m_bytesPerLine(0)
{
}
@@ -64,8 +65,8 @@ MFTransform::~MFTransform()
if (m_outputType)
m_outputType->Release();
- for (int i = 0; i < m_mediaTypes.size(); ++i)
- m_mediaTypes[i]->Release();
+ if (m_videoSinkTypeHandler)
+ m_videoSinkTypeHandler->Release();
}
void MFTransform::addProbe(MFVideoProbeControl *probe)
@@ -84,12 +85,18 @@ void MFTransform::removeProbe(MFVideoProbeControl *probe)
m_videoProbes.removeOne(probe);
}
-void MFTransform::addSupportedMediaType(IMFMediaType *type)
+void MFTransform::setVideoSink(IUnknown *videoSink)
{
- if (!type)
- return;
- QMutexLocker locker(&m_mutex);
- m_mediaTypes.append(type);
+ // This transform supports the same input types as the video sink.
+ // Store its type handler interface in order to report the correct supported types.
+
+ if (m_videoSinkTypeHandler) {
+ m_videoSinkTypeHandler->Release();
+ m_videoSinkTypeHandler = NULL;
+ }
+
+ if (videoSink)
+ videoSink->QueryInterface(IID_PPV_ARGS(&m_videoSinkTypeHandler));
}
STDMETHODIMP MFTransform::QueryInterface(REFIID riid, void** ppv)
@@ -228,20 +235,42 @@ STDMETHODIMP MFTransform::AddInputStreams(DWORD cStreams, DWORD *adwStreamIDs)
STDMETHODIMP MFTransform::GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
{
- // This MFT does not have a list of preferred input types
- Q_UNUSED(dwInputStreamID);
- Q_UNUSED(dwTypeIndex);
- Q_UNUSED(ppType);
- return E_NOTIMPL;
+ // We support the same input types as the video sink
+ if (!m_videoSinkTypeHandler)
+ return E_NOTIMPL;
+
+ if (dwInputStreamID > 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (!ppType)
+ return E_POINTER;
+
+ return m_videoSinkTypeHandler->GetMediaTypeByIndex(dwTypeIndex, ppType);
}
-STDMETHODIMP MFTransform::GetOutputAvailableType(DWORD dwOutputStreamID,DWORD dwTypeIndex, IMFMediaType **ppType)
+STDMETHODIMP MFTransform::GetOutputAvailableType(DWORD dwOutputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
{
- // This MFT does not have a list of preferred output types
- Q_UNUSED(dwOutputStreamID);
- Q_UNUSED(dwTypeIndex);
- Q_UNUSED(ppType);
- return E_NOTIMPL;
+ // Since we don't modify the samples, the output type must be the same as the input type.
+ // Report our input type as the only available output type.
+
+ if (dwOutputStreamID > 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (!ppType)
+ return E_POINTER;
+
+ // Input type must be set first
+ if (!m_inputType)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ if (dwTypeIndex > 0)
+ return MF_E_NO_MORE_TYPES;
+
+ // Return a copy to make sure our type is not modified
+ if (FAILED(MFCreateMediaType(ppType)))
+ return E_OUTOFMEMORY;
+
+ return m_inputType->CopyAllItems(*ppType);
}
STDMETHODIMP MFTransform::SetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags)
@@ -257,17 +286,14 @@ STDMETHODIMP MFTransform::SetInputType(DWORD dwInputStreamID, IMFMediaType *pTyp
if (!isMediaTypeSupported(pType))
return MF_E_INVALIDMEDIATYPE;
- DWORD flags = 0;
- if (pType && !m_inputType && m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK)
- return MF_E_INVALIDMEDIATYPE;
-
if (dwFlags == MFT_SET_TYPE_TEST_ONLY)
return pType ? S_OK : E_POINTER;
if (m_inputType) {
m_inputType->Release();
// Input type has changed, discard output type (if it's set) so it's reset later on
- if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) {
+ DWORD flags = 0;
+ if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) {
m_outputType->Release();
m_outputType = 0;
}
@@ -286,29 +312,27 @@ STDMETHODIMP MFTransform::SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pT
if (dwOutputStreamID > 0)
return MF_E_INVALIDSTREAMNUMBER;
+ if (dwFlags == MFT_SET_TYPE_TEST_ONLY && !pType)
+ return E_POINTER;
+
QMutexLocker locker(&m_mutex);
+ // Input type must be set first
+ if (!m_inputType)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
if (m_sample)
return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
- if (!isMediaTypeSupported(pType))
- return MF_E_INVALIDMEDIATYPE;
-
DWORD flags = 0;
- if (pType && !m_outputType && m_inputType && m_inputType->IsEqual(pType, &flags) != S_OK)
+ if (pType && m_inputType->IsEqual(pType, &flags) != S_OK)
return MF_E_INVALIDMEDIATYPE;
if (dwFlags == MFT_SET_TYPE_TEST_ONLY)
return pType ? S_OK : E_POINTER;
- if (m_outputType) {
+ if (m_outputType)
m_outputType->Release();
- // Output type has changed, discard input type (if it's set) so it's reset later on
- if (m_inputType && m_inputType->IsEqual(pType, &flags) != S_OK) {
- m_inputType->Release();
- m_inputType = 0;
- }
- }
m_outputType = pType;
@@ -333,10 +357,11 @@ STDMETHODIMP MFTransform::GetInputCurrentType(DWORD dwInputStreamID, IMFMediaTyp
if (!m_inputType)
return MF_E_TRANSFORM_TYPE_NOT_SET;
- *ppType = m_inputType;
- (*ppType)->AddRef();
+ // Return a copy to make sure our type is not modified
+ if (FAILED(MFCreateMediaType(ppType)))
+ return E_OUTOFMEMORY;
- return S_OK;
+ return m_inputType->CopyAllItems(*ppType);
}
STDMETHODIMP MFTransform::GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType)
@@ -349,19 +374,14 @@ STDMETHODIMP MFTransform::GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaT
QMutexLocker locker(&m_mutex);
- if (!m_outputType) {
- if (m_inputType) {
- *ppType = m_inputType;
- (*ppType)->AddRef();
- return S_OK;
- }
+ if (!m_outputType)
return MF_E_TRANSFORM_TYPE_NOT_SET;
- }
- *ppType = m_outputType;
- (*ppType)->AddRef();
+ // Return a copy to make sure our type is not modified
+ if (FAILED(MFCreateMediaType(ppType)))
+ return E_OUTOFMEMORY;
- return S_OK;
+ return m_outputType->CopyAllItems(*ppType);
}
STDMETHODIMP MFTransform::GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags)
@@ -374,7 +394,7 @@ STDMETHODIMP MFTransform::GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags)
QMutexLocker locker(&m_mutex);
- if (!m_inputType)
+ if (!m_inputType || !m_outputType)
return MF_E_TRANSFORM_TYPE_NOT_SET;
if (m_sample)
@@ -392,7 +412,7 @@ STDMETHODIMP MFTransform::GetOutputStatus(DWORD *pdwFlags)
QMutexLocker locker(&m_mutex);
- if (!m_outputType)
+ if (!m_inputType || !m_outputType)
return MF_E_TRANSFORM_TYPE_NOT_SET;
if (m_sample)
@@ -464,7 +484,7 @@ STDMETHODIMP MFTransform::ProcessInput(DWORD dwInputStreamID, IMFSample *pSample
QMutexLocker locker(&m_mutex);
- if (!m_inputType || !m_outputType)
+ if (!m_inputType)
return MF_E_TRANSFORM_TYPE_NOT_SET;
if (m_sample)
@@ -510,6 +530,14 @@ STDMETHODIMP MFTransform::ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount,
QMutexLocker locker(&m_mutex);
+ if (!m_inputType)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ if (!m_outputType) {
+ pOutputSamples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
+ return MF_E_TRANSFORM_STREAM_CHANGE;
+ }
+
if (!m_sample)
return MF_E_TRANSFORM_NEED_MORE_INPUT;
@@ -728,16 +756,10 @@ QByteArray MFTransform::dataFromBuffer(IMFMediaBuffer *buffer, int height, int *
bool MFTransform::isMediaTypeSupported(IMFMediaType *type)
{
- // if the list is empty, it supports all formats
- if (!type || m_mediaTypes.isEmpty())
+ // If we don't have the video sink's type handler,
+ // assume it supports anything...
+ if (!m_videoSinkTypeHandler || !type)
return true;
- for (int i = 0; i < m_mediaTypes.size(); ++i) {
- DWORD flags = 0;
- m_mediaTypes.at(i)->IsEqual(type, &flags);
- if (flags & MF_MEDIATYPE_EQUAL_FORMAT_TYPES)
- return true;
- }
-
- return false;
+ return m_videoSinkTypeHandler->IsMediaTypeSupported(type, NULL) == S_OK;
}
diff --git a/src/plugins/wmf/mftvideo.h b/src/plugins/wmf/mftvideo.h
index 1a188c4db..c37c8f700 100644
--- a/src/plugins/wmf/mftvideo.h
+++ b/src/plugins/wmf/mftvideo.h
@@ -53,7 +53,7 @@ public:
void addProbe(MFVideoProbeControl* probe);
void removeProbe(MFVideoProbeControl* probe);
- void addSupportedMediaType(IMFMediaType *type);
+ void setVideoSink(IUnknown *videoSink);
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
@@ -99,7 +99,7 @@ private:
IMFSample *m_sample;
QMutex m_mutex;
- QList<IMFMediaType*> m_mediaTypes;
+ IMFMediaTypeHandler *m_videoSinkTypeHandler;
QList<MFVideoProbeControl*> m_videoProbes;
QMutex m_videoProbeMutex;
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index e4c498b76..9fb1762ef 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -692,7 +692,6 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
IUnknown *element = 0;
IMFTopologyNode *node = 0;
IUnknown *outputObject = 0;
- IMFMediaTypeHandler *videoSink = 0;
IMFTopologyNode *inputNode = 0;
IMFTopologyNode *mftNode = 0;
bool mftAdded = false;
@@ -711,22 +710,10 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
if (id != outputNodeId)
break;
- // Use output supported media types for the MFT
if (FAILED(node->GetObject(&outputObject)))
break;
- if (FAILED(outputObject->QueryInterface(IID_IMFMediaTypeHandler, (void**)&videoSink)))
- break;
-
- DWORD mtCount;
- if (FAILED(videoSink->GetMediaTypeCount(&mtCount)))
- break;
-
- for (DWORD i = 0; i < mtCount; ++i) {
- IMFMediaType *type = 0;
- if (SUCCEEDED(videoSink->GetMediaTypeByIndex(i, &type)))
- m_videoProbeMFT->addSupportedMediaType(type);
- }
+ m_videoProbeMFT->setVideoSink(outputObject);
// Insert MFT between the output node and the node connected to it.
DWORD outputIndex = 0;
@@ -760,13 +747,13 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
node->Release();
if (element)
element->Release();
- if (videoSink)
- videoSink->Release();
if (outputObject)
outputObject->Release();
if (mftAdded)
break;
+ else
+ m_videoProbeMFT->setVideoSink(NULL);
}
} while (false);