diff options
-rw-r--r-- | src/plugins/wmf/mftvideo.cpp | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/src/plugins/wmf/mftvideo.cpp b/src/plugins/wmf/mftvideo.cpp index 8e7ce0693..7d6b3b905 100644 --- a/src/plugins/wmf/mftvideo.cpp +++ b/src/plugins/wmf/mftvideo.cpp @@ -521,18 +521,67 @@ STDMETHODIMP MFTransform::ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, if (!m_sample) return MF_E_TRANSFORM_NEED_MORE_INPUT; - if (pOutputSamples[0].pSample) - pOutputSamples[0].pSample->Release(); + IMFMediaBuffer *input = NULL; + IMFMediaBuffer *output = NULL; + + DWORD sampleLength = 0; + m_sample->GetTotalLength(&sampleLength); + + // If the sample length is null, it means we're getting DXVA buffers. + // In that case just pass on the sample we got as input. + // Otherwise we need to copy the input buffer into the buffer the sink + // is giving us. + if (pOutputSamples[0].pSample && sampleLength > 0) { + + if (FAILED(m_sample->ConvertToContiguousBuffer(&input))) + goto done; + + if (FAILED(pOutputSamples[0].pSample->ConvertToContiguousBuffer(&output))) + goto done; + + DWORD inputLength = 0; + DWORD outputLength = 0; + input->GetMaxLength(&inputLength); + output->GetMaxLength(&outputLength); + + if (outputLength < inputLength) { + pOutputSamples[0].pSample->RemoveAllBuffers(); + output->Release(); + output = NULL; + if (SUCCEEDED(MFCreateMemoryBuffer(inputLength, &output))) + pOutputSamples[0].pSample->AddBuffer(output); + } + + if (output) + m_sample->CopyToBuffer(output); - pOutputSamples[0].pSample = m_sample; - pOutputSamples[0].pSample->AddRef(); + LONGLONG hnsDuration = 0; + LONGLONG hnsTime = 0; + if (SUCCEEDED(m_sample->GetSampleDuration(&hnsDuration))) + pOutputSamples[0].pSample->SetSampleDuration(hnsDuration); + if (SUCCEEDED(m_sample->GetSampleTime(&hnsTime))) + pOutputSamples[0].pSample->SetSampleTime(hnsTime); + + } else { + if (pOutputSamples[0].pSample) + pOutputSamples[0].pSample->Release(); + pOutputSamples[0].pSample = m_sample; + pOutputSamples[0].pSample->AddRef(); + } + +done: pOutputSamples[0].dwStatus = 0; *pdwStatus = 0; m_sample->Release(); m_sample = 0; + if (input) + input->Release(); + if (output) + output->Release(); + return S_OK; } |