1
/* This file is part of the KDE project.
3
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5
This library is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published by
7
the Free Software Foundation, either version 2.1 or 3 of the License.
9
This library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public License
15
along with this library. If not, see <http://www.gnu.org/licenses/>.
18
#include <QtCore/QFile>
20
#include "qasyncreader.h"
21
#include "qbasefilter.h"
29
QAsyncReader::QAsyncReader(QBaseFilter *parent, const QVector<AM_MEDIA_TYPE> &mediaTypes) : QPin(parent, PINDIR_OUTPUT, mediaTypes)
33
QAsyncReader::~QAsyncReader()
37
STDMETHODIMP QAsyncReader::QueryInterface(REFIID iid, void **out)
43
if (iid == IID_IAsyncReader) {
45
*out = static_cast<IAsyncReader*>(this);
49
return QPin::QueryInterface(iid, out);
52
STDMETHODIMP_(ULONG) QAsyncReader::AddRef()
54
return QPin::AddRef();
57
STDMETHODIMP_(ULONG) QAsyncReader::Release()
59
return QPin::Release();
63
STDMETHODIMP QAsyncReader::RequestAllocator(IMemAllocator *preferred, ALLOCATOR_PROPERTIES *prop,IMemAllocator **actual)
65
ALLOCATOR_PROPERTIES prop2;
67
if (prop->cbAlign == 0) {
68
prop->cbAlign = 1; //align on 1 char
71
if (preferred && preferred->SetProperties(prop, &prop2) == S_OK) {
77
//we should try to create one memory allocator ourselves here
81
STDMETHODIMP QAsyncReader::Request(IMediaSample *sample,DWORD_PTR user)
83
QMutexLocker mutexLocker(&m_mutexWait);
84
QWriteLocker locker(&m_lock);
86
return VFW_E_WRONG_STATE;
89
m_requestQueue.enqueue(AsyncRequest(sample, user));
90
m_requestWait.wakeOne();
94
STDMETHODIMP QAsyncReader::WaitForNext(DWORD timeout, IMediaSample **sample, DWORD_PTR *user)
96
QMutexLocker locker(&m_mutexWait);
97
if (!sample ||!user) {
104
AsyncRequest r = getNextRequest();
107
//there is no request in the queue
109
return VFW_E_WRONG_STATE;
111
//First we need to lock the mutex
112
if (m_requestWait.wait(&m_mutexWait, timeout) == false) {
113
return VFW_E_TIMEOUT;
116
return VFW_E_WRONG_STATE;
119
r = getNextRequest();
123
//at this point we're sure to have a request to proceed
131
return SyncReadAligned(r.sample);
134
STDMETHODIMP QAsyncReader::BeginFlush()
136
QMutexLocker mutexLocker(&m_mutexWait);
137
QWriteLocker locker(&m_lock);
139
m_requestWait.wakeOne();
143
STDMETHODIMP QAsyncReader::EndFlush()
145
QWriteLocker locker(&m_lock);
150
STDMETHODIMP QAsyncReader::SyncReadAligned(IMediaSample *sample)
156
REFERENCE_TIME start = 0,
158
HRESULT hr = sample->GetTime(&start, &stop);
163
LONGLONG startPos = start / 10000000;
164
LONG length = static_cast<LONG>((stop - start) / 10000000);
167
hr = sample->GetPointer(&buffer);
173
read(startPos, length, buffer, &actual);
175
return sample->SetActualDataLength(actual);
178
STDMETHODIMP QAsyncReader::SyncRead(LONGLONG pos, LONG length, BYTE *buffer)
180
return read(pos, length, buffer, 0);
185
QAsyncReader::AsyncRequest QAsyncReader::getNextRequest()
187
QWriteLocker locker(&m_lock);
189
if (!m_requestQueue.isEmpty()) {
190
ret = m_requestQueue.dequeue();