diff options
Diffstat (limited to 'src/plugins/wmf/mftvideo.cpp')
-rw-r--r-- | src/plugins/wmf/mftvideo.cpp | 142 |
1 files changed, 82 insertions, 60 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; } |