10#include <wmcodecdsp.h>
11#include <mftransform.h>
16QUuid qIID_IMFTransform(0xbf94c121, 0x5b05, 0x4e6f, 0x80,0x00, 0xba,0x59,0x89,0x61,0x41,0x4d);
24 HRESULT hr = CoInitializeEx(
nullptr, COINIT_APARTMENTTHREADED);
25 if (hr == RPC_E_CHANGED_MODE)
26 qWarning() <<
"Failed attempt to change apartment concurrency model";
31 m_resampler->AddInputStreams(1, &m_inputStreamID);
57 ComPtr<IMFSample> sample;
62 ComPtr<IMFMediaBuffer>
buffer;
70 hr =
buffer->Lock(&
data, &maxLen, ¤tLen);
80 hr =
buffer->SetCurrentLength(
in.size());
84 hr = sample->AddBuffer(
buffer.Get());
88 return m_resampler->ProcessInput(m_inputStreamID, sample.Get(), 0);
93 ComPtr<IMFSample> sample;
94 ComPtr<IMFMediaBuffer>
buffer;
96 if (m_resamplerNeedsSampleBuffer) {
101 auto expectedOutputSize =
outputBufferSize(m_totalInputBytes) - m_totalOutputBytes;
106 hr = sample->AddBuffer(
buffer.Get());
113 MFT_OUTPUT_DATA_BUFFER outputDataBuffer;
114 outputDataBuffer.dwStreamID = 0;
116 outputDataBuffer.pEvents =
nullptr;
117 outputDataBuffer.dwStatus = 0;
118 outputDataBuffer.pSample = m_resamplerNeedsSampleBuffer ? sample.Get() :
nullptr;
120 hr = m_resampler->ProcessOutput(0, 1, &outputDataBuffer, &status);
122 ComPtr<IMFMediaBuffer> outputBuffer;
123 outputDataBuffer.pSample->ConvertToContiguousBuffer(outputBuffer.GetAddressOf());
125 BYTE *
data =
nullptr;
126 hr = outputBuffer->Lock(&
data,
nullptr, &
len);
129 outputBuffer->Unlock();
131 }
while (SUCCEEDED(hr));
133 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
141 m_totalInputBytes +=
in.size();
143 if (m_inputFormat == m_outputFormat) {
144 m_totalOutputBytes +=
in.size();
145 return {
in.data(),
in.size()};
153 hr = processOutput(
out);
156 qCWarning(qLcAudioResampler) <<
"Resampling failed" << hr;
158 m_totalOutputBytes +=
out.size();
167 DWORD totalLength = 0;
168 HRESULT hr = sample->GetTotalLength(&totalLength);
172 m_totalInputBytes += totalLength;
176 if (m_inputFormat == m_outputFormat) {
177 ComPtr<IMFMediaBuffer> outputBuffer;
178 sample->ConvertToContiguousBuffer(outputBuffer.GetAddressOf());
180 BYTE *
data =
nullptr;
181 hr = outputBuffer->Lock(&
data,
nullptr, &
len);
184 outputBuffer->Unlock();
189 hr = m_resampler->ProcessInput(m_inputStreamID, sample, 0);
191 hr = processOutput(
out);
194 qCWarning(qLcAudioResampler) <<
"Resampling failed" << hr;
197 m_totalOutputBytes +=
out.size();
204 qCDebug(qLcAudioResampler) <<
"Setup audio resampler" << fin <<
"->" << fout;
206 m_totalInputBytes = 0;
207 m_totalOutputBytes = 0;
210 qCDebug(qLcAudioResampler) <<
"Pass through mode";
212 m_outputFormat = fout;
216 if (!m_resampler || !m_wmf)
222 HRESULT hr = m_resampler->SetInputType(m_inputStreamID, min.Get(), 0);
224 qCWarning(qLcAudioResampler) <<
"Failed to set input type" << hr;
228 hr = m_resampler->SetOutputType(0, mout.Get(), 0);
230 qCWarning(qLcAudioResampler) <<
"Failed to set output type" << hr;
234 MFT_OUTPUT_STREAM_INFO streamInfo;
235 hr = m_resampler->GetOutputStreamInfo(0, &streamInfo);
237 qCWarning(qLcAudioResampler) <<
"Could not obtain stream info" << hr;
241 m_resamplerNeedsSampleBuffer = (streamInfo.dwFlags
242 & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)) == 0;
245 m_outputFormat = fout;
quint64 outputBufferSize(quint64 inputBufferSize) const
bool setup(const QAudioFormat &in, const QAudioFormat &out)
QByteArray resample(const QByteArrayView &in)
quint64 inputBufferSize(quint64 outputBufferSize) const
Combined button and popup list for selecting options.
ComPtr< IMFMediaType > formatToMediaType(QWindowsMediaFoundation &, const QAudioFormat &format)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
unsigned long long quint64
QUuid qCLSID_CResamplerMediaObject("f447b69e-1884-4a7e-8055-346f74d6edb3")
QT_BEGIN_NAMESPACE QUuid qIID_IMFTransform(0xbf94c121, 0x5b05, 0x4e6f, 0x80, 0x00, 0xba, 0x59, 0x89, 0x61, 0x41, 0x4d)
QTextStream out(stdout)
[7]