source: trunk/src/3rdparty/phonon/ds9/qasyncreader.cpp

Last change on this file was 561, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 5.2 KB
Line 
1/* This file is part of the KDE project.
2
3Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5This library is free software: you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation, either version 2.1 or 3 of the License.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public License
15along with this library. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "qasyncreader.h"
19#include "qbasefilter.h"
20
21QT_BEGIN_NAMESPACE
22
23namespace Phonon
24{
25 namespace DS9
26 {
27 QAsyncReader::QAsyncReader(QBaseFilter *parent, const QVector<AM_MEDIA_TYPE> &mediaTypes) : QPin(parent, PINDIR_OUTPUT, mediaTypes)
28 {
29 }
30
31 QAsyncReader::~QAsyncReader()
32 {
33 }
34
35 STDMETHODIMP QAsyncReader::QueryInterface(REFIID iid, void **out)
36 {
37 if (!out) {
38 return E_POINTER;
39 }
40
41 if (iid == IID_IAsyncReader) {
42 AddRef();
43 *out = static_cast<IAsyncReader*>(this);
44 return S_OK;
45 }
46
47 return QPin::QueryInterface(iid, out);
48 }
49
50 STDMETHODIMP_(ULONG) QAsyncReader::AddRef()
51 {
52 return QPin::AddRef();
53 }
54
55 STDMETHODIMP_(ULONG) QAsyncReader::Release()
56 {
57 return QPin::Release();
58 }
59
60
61 STDMETHODIMP QAsyncReader::RequestAllocator(IMemAllocator *preferred, ALLOCATOR_PROPERTIES *prop,IMemAllocator **actual)
62 {
63 ALLOCATOR_PROPERTIES prop2;
64
65 if (prop->cbAlign == 0) {
66 prop->cbAlign = 1; //align on 1 char
67 }
68
69 if (preferred && preferred->SetProperties(prop, &prop2) == S_OK) {
70 preferred->AddRef();
71 *actual = preferred;
72 return S_OK;
73 }
74
75 //we should try to create one memory allocator ourselves here
76 return E_FAIL;
77 }
78
79 STDMETHODIMP QAsyncReader::Request(IMediaSample *sample,DWORD_PTR user)
80 {
81 QMutexLocker locker(&m_mutex);
82 if (m_flushing) {
83 return VFW_E_WRONG_STATE;
84 }
85
86 m_requestQueue.enqueue(AsyncRequest(sample, user));
87 m_requestWait.wakeOne();
88 return S_OK;
89 }
90
91 STDMETHODIMP QAsyncReader::WaitForNext(DWORD timeout, IMediaSample **sample, DWORD_PTR *user)
92 {
93 QMutexLocker locker(&m_mutex);
94 if (!sample ||!user) {
95 return E_POINTER;
96 }
97
98 //msdn says to return immediately if we're flushing but that doesn't seem to be true
99 //since it triggers a dead-lock somewhere inside directshow (see task 258830)
100
101 *sample = 0;
102 *user = 0;
103
104 if (m_requestQueue.isEmpty()) {
105 if (m_requestWait.wait(&m_mutex, timeout) == false) {
106 return VFW_E_TIMEOUT;
107 }
108 if (m_requestQueue.isEmpty()) {
109 return VFW_E_WRONG_STATE;
110 }
111 }
112
113 AsyncRequest r = m_requestQueue.dequeue();
114
115 //at this point we're sure to have a request to proceed
116 if (r.sample == 0) {
117 return E_FAIL;
118 }
119
120 *sample = r.sample;
121 *user = r.user;
122 return syncReadAlignedUnlocked(r.sample);
123 }
124
125 STDMETHODIMP QAsyncReader::BeginFlush()
126 {
127 QMutexLocker locker(&m_mutex);
128 m_flushing = true;
129 m_requestWait.wakeOne();
130 return S_OK;
131 }
132
133 STDMETHODIMP QAsyncReader::EndFlush()
134 {
135 QMutexLocker locker(&m_mutex);
136 m_flushing = false;
137 return S_OK;
138 }
139
140 STDMETHODIMP QAsyncReader::SyncReadAligned(IMediaSample *sample)
141 {
142 QMutexLocker locker(&m_mutex);
143 return syncReadAlignedUnlocked(sample);
144 }
145
146 STDMETHODIMP QAsyncReader::SyncRead(LONGLONG pos, LONG length, BYTE *buffer)
147 {
148 QMutexLocker locker(&m_mutex);
149 return read(pos, length, buffer, 0);
150 }
151
152
153 STDMETHODIMP QAsyncReader::syncReadAlignedUnlocked(IMediaSample *sample)
154 {
155 Q_ASSERT(!m_mutex.tryLock());
156
157 if (!sample) {
158 return E_POINTER;
159 }
160
161 REFERENCE_TIME start = 0,
162 stop = 0;
163 HRESULT hr = sample->GetTime(&start, &stop);
164 if(FAILED(hr)) {
165 return hr;
166 }
167
168 LONGLONG startPos = start / 10000000;
169 LONG length = static_cast<LONG>((stop - start) / 10000000);
170
171 BYTE *buffer;
172 hr = sample->GetPointer(&buffer);
173 if(FAILED(hr)) {
174 return hr;
175 }
176
177 LONG actual = 0;
178 read(startPos, length, buffer, &actual);
179
180 return sample->SetActualDataLength(actual);
181 }
182
183 }
184}
185
186QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.