5#include <QtCore/qcoreapplication.h>
14 , m_ownStream(ownStream)
15 , m_currentReadResult(0)
20 this->moveToThread(stream->thread());
25 if (m_currentReadResult)
26 m_currentReadResult->Release();
28 m_stream->deleteLater();
32STDMETHODIMP MFStream::QueryInterface(REFIID riid, LPVOID *ppvObject)
36 if (riid == IID_IMFByteStream) {
37 *ppvObject =
static_cast<IMFByteStream*>(
this);
38 }
else if (riid == IID_IUnknown) {
39 *ppvObject =
static_cast<IUnknown*>(
this);
50 return InterlockedIncrement(&m_cRef);
55 LONG cRef = InterlockedDecrement(&m_cRef);
64STDMETHODIMP MFStream::GetCapabilities(DWORD *pdwCapabilities)
68 *pdwCapabilities = MFBYTESTREAM_IS_READABLE;
69 if (!m_stream->isSequential())
70 *pdwCapabilities |= MFBYTESTREAM_IS_SEEKABLE;
74STDMETHODIMP MFStream::GetLength(QWORD *pqwLength)
78 QMutexLocker locker(&m_mutex);
79 *pqwLength = QWORD(m_stream->size());
83STDMETHODIMP MFStream::SetLength(QWORD)
88STDMETHODIMP MFStream::GetCurrentPosition(QWORD *pqwPosition)
92 QMutexLocker locker(&m_mutex);
93 *pqwPosition = m_stream->pos();
97STDMETHODIMP MFStream::SetCurrentPosition(QWORD qwPosition)
99 QMutexLocker locker(&m_mutex);
103 if (m_currentReadResult)
106 bool seekOK = m_stream->seek(qint64(qwPosition));
113STDMETHODIMP MFStream::IsEndOfStream(BOOL *pfEndOfStream)
117 QMutexLocker locker(&m_mutex);
118 *pfEndOfStream = m_stream->atEnd() ? TRUE : FALSE;
122STDMETHODIMP MFStream::Read(BYTE *pb, ULONG cb, ULONG *pcbRead)
124 QMutexLocker locker(&m_mutex);
125 qint64 read = m_stream->read((
char*)(pb), qint64(cb));
127 *pcbRead = ULONG(read);
131STDMETHODIMP MFStream::BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback,
134 if (!pCallback || !pb)
137 Q_ASSERT(m_currentReadResult == NULL);
139 AsyncReadState *state =
new (std::nothrow) AsyncReadState(pb, cb);
141 return E_OUTOFMEMORY;
143 HRESULT hr = MFCreateAsyncResult(state, pCallback, punkState, &m_currentReadResult);
148 QCoreApplication::postEvent(
this,
new QEvent(QEvent::User));
152STDMETHODIMP MFStream::EndRead(IMFAsyncResult* pResult, ULONG *pcbRead)
157 pResult->GetObject(&pUnk);
158 AsyncReadState *state =
static_cast<AsyncReadState*>(pUnk);
159 *pcbRead = state->bytesRead();
162 m_currentReadResult->Release();
163 m_currentReadResult = NULL;
168STDMETHODIMP MFStream::Write(
const BYTE *, ULONG, ULONG *)
173STDMETHODIMP MFStream::BeginWrite(
const BYTE *, ULONG ,
180STDMETHODIMP MFStream::EndWrite(IMFAsyncResult *,
186STDMETHODIMP MFStream::Seek(
187 MFBYTESTREAM_SEEK_ORIGIN SeekOrigin,
188 LONGLONG llSeekOffset,
190 QWORD *pqwCurrentPosition)
192 QMutexLocker locker(&m_mutex);
193 if (m_currentReadResult)
196 qint64 pos = qint64(llSeekOffset);
197 switch (SeekOrigin) {
201 pos += m_stream->pos();
204 bool seekOK = m_stream->seek(pos);
205 if (pqwCurrentPosition)
206 *pqwCurrentPosition = pos;
213STDMETHODIMP MFStream::Flush()
218STDMETHODIMP MFStream::Close()
220 QMutexLocker locker(&m_mutex);
226void MFStream::doRead()
231 bool readDone =
true;
232 IUnknown *pUnk = NULL;
233 HRESULT hr = m_currentReadResult->GetObject(&pUnk);
236 AsyncReadState *state =
static_cast<AsyncReadState*>(pUnk);
238 Read(state->pb(), state->cb() - state->bytesRead(), &cbRead);
241 state->setBytesRead(cbRead + state->bytesRead());
242 if (state->cb() > state->bytesRead() && !m_stream->atEnd()) {
249 m_currentReadResult->SetStatus(hr);
250 MFInvokeCallback(m_currentReadResult);
254void MFStream::customEvent(QEvent *event)
256 if (event->type() != QEvent::User) {
257 QObject::customEvent(event);
266MFStream::AsyncReadState::AsyncReadState(BYTE *pb, ULONG cb)
275STDMETHODIMP MFStream::AsyncReadState::QueryInterface(REFIID riid, LPVOID *ppvObject)
280 if (riid == IID_IUnknown) {
281 *ppvObject =
static_cast<IUnknown*>(
this);
284 return E_NOINTERFACE;
292 return InterlockedIncrement(&m_cRef);
297 LONG cRef = InterlockedDecrement(&m_cRef);
304BYTE* MFStream::AsyncReadState::pb()
const
309ULONG MFStream::AsyncReadState::cb()
const
314ULONG MFStream::AsyncReadState::bytesRead()
const
319void MFStream::AsyncReadState::setBytesRead(ULONG cbRead)
326#include "moc_mfstream_p.cpp"
\inmodule QtCore \reentrant