|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qevrvideooverlay.h" |
|
43 |
|
44 #include <d3d9.h> |
|
45 #include <wmp.h> |
|
46 |
|
47 QEvrVideoOverlay::QEvrVideoOverlay(HINSTANCE evrHwnd) |
|
48 : m_ref(1) |
|
49 , m_evrHwnd(evrHwnd) |
|
50 , ptrMFCreateVideoPresenter(0) |
|
51 , m_presenter(0) |
|
52 , m_displayControl(0) |
|
53 , m_aspectRatioMode(Qt::KeepAspectRatio) |
|
54 , m_winId(0) |
|
55 , m_fullScreen(0) |
|
56 { |
|
57 ptrMFCreateVideoPresenter = reinterpret_cast<PtrMFCreateVideoPresenter>( |
|
58 GetProcAddress(m_evrHwnd, "MFCreateVideoPresenter")); |
|
59 } |
|
60 |
|
61 QEvrVideoOverlay::~QEvrVideoOverlay() |
|
62 { |
|
63 FreeLibrary(m_evrHwnd); |
|
64 } |
|
65 |
|
66 WId QEvrVideoOverlay::winId() const |
|
67 { |
|
68 return m_winId; |
|
69 } |
|
70 |
|
71 void QEvrVideoOverlay::setWinId(WId id) |
|
72 { |
|
73 m_winId = id; |
|
74 |
|
75 if (m_displayControl) { |
|
76 m_displayControl->SetVideoWindow(id); |
|
77 m_displayControl->SetAspectRatioMode(m_aspectRatioMode == Qt::KeepAspectRatio |
|
78 ? MFVideoARMode_PreservePicture |
|
79 : MFVideoARMode_None); |
|
80 |
|
81 setDisplayRect(m_displayRect); |
|
82 } |
|
83 } |
|
84 |
|
85 QRect QEvrVideoOverlay::displayRect() const |
|
86 { |
|
87 return m_displayRect; |
|
88 } |
|
89 |
|
90 void QEvrVideoOverlay::setDisplayRect(const QRect &rect) |
|
91 { |
|
92 if (m_displayControl) { |
|
93 RECT displayRect = { rect.left(), rect.top(), rect.right(), rect.bottom() }; |
|
94 |
|
95 if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) { |
|
96 SIZE size; |
|
97 m_displayControl->GetNativeVideoSize(&size, 0); |
|
98 |
|
99 QSize clippedSize = rect.size(); |
|
100 clippedSize.scale(size.cx, size.cy, Qt::KeepAspectRatio); |
|
101 |
|
102 long x = (size.cx - clippedSize.width()) / 2; |
|
103 long y = (size.cy - clippedSize.height()) / 2; |
|
104 |
|
105 MFVideoNormalizedRect sourceRect = |
|
106 { |
|
107 float(x) / size.cx, |
|
108 float(y) / size.cy, |
|
109 float(x + clippedSize.width()) / size.cx, |
|
110 float(y + clippedSize.height()) / size.cy |
|
111 }; |
|
112 m_displayControl->SetVideoPosition(&sourceRect, &displayRect); |
|
113 } else { |
|
114 m_displayControl->SetVideoPosition(0, &displayRect); |
|
115 } |
|
116 } |
|
117 |
|
118 m_displayRect = rect; |
|
119 } |
|
120 |
|
121 bool QEvrVideoOverlay::isFullScreen() const |
|
122 { |
|
123 return m_fullScreen; |
|
124 } |
|
125 |
|
126 void QEvrVideoOverlay::setFullScreen(bool fullScreen) |
|
127 { |
|
128 emit fullScreenChanged(m_fullScreen = fullScreen); |
|
129 } |
|
130 |
|
131 QSize QEvrVideoOverlay::nativeSize() const |
|
132 { |
|
133 SIZE size; |
|
134 |
|
135 if (m_displayControl && m_displayControl->GetNativeVideoSize(&size, 0) == S_OK) { |
|
136 return QSize(size.cx, size.cy); |
|
137 } else { |
|
138 return QSize(); |
|
139 } |
|
140 } |
|
141 |
|
142 Qt::AspectRatioMode QEvrVideoOverlay::aspectRatioMode() const |
|
143 { |
|
144 return m_aspectRatioMode; |
|
145 } |
|
146 |
|
147 void QEvrVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode) |
|
148 { |
|
149 m_aspectRatioMode = mode; |
|
150 |
|
151 if (m_displayControl) { |
|
152 m_displayControl->SetAspectRatioMode(mode == Qt::KeepAspectRatio |
|
153 ? MFVideoARMode_PreservePicture |
|
154 : MFVideoARMode_None); |
|
155 setDisplayRect(m_displayRect); |
|
156 } |
|
157 } |
|
158 |
|
159 void QEvrVideoOverlay::repaint() |
|
160 { |
|
161 if (m_displayControl) |
|
162 m_displayControl->RepaintVideo(); |
|
163 } |
|
164 |
|
165 int QEvrVideoOverlay::brightness() const |
|
166 { |
|
167 return 0; |
|
168 } |
|
169 |
|
170 void QEvrVideoOverlay::setBrightness(int) |
|
171 { |
|
172 } |
|
173 |
|
174 int QEvrVideoOverlay::contrast() const |
|
175 { |
|
176 return 0; |
|
177 } |
|
178 |
|
179 void QEvrVideoOverlay::setContrast(int) |
|
180 { |
|
181 } |
|
182 |
|
183 int QEvrVideoOverlay::hue() const |
|
184 { |
|
185 return 0; |
|
186 } |
|
187 |
|
188 void QEvrVideoOverlay::setHue(int) |
|
189 { |
|
190 } |
|
191 |
|
192 int QEvrVideoOverlay::saturation() const |
|
193 { |
|
194 return 0; |
|
195 } |
|
196 |
|
197 void QEvrVideoOverlay::setSaturation(int) |
|
198 { |
|
199 } |
|
200 |
|
201 void QEvrVideoOverlay::setDisplayControl(IMFVideoDisplayControl *control) |
|
202 { |
|
203 if (m_displayControl) |
|
204 m_displayControl->Release(); |
|
205 |
|
206 m_displayControl = control; |
|
207 |
|
208 if (m_displayControl) { |
|
209 m_displayControl->AddRef(); |
|
210 m_displayControl->SetVideoWindow(m_winId); |
|
211 m_displayControl->SetAspectRatioMode(m_aspectRatioMode == Qt::KeepAspectRatio |
|
212 ? MFVideoARMode_PreservePicture |
|
213 : MFVideoARMode_None); |
|
214 |
|
215 setDisplayRect(m_displayRect); |
|
216 } |
|
217 } |
|
218 |
|
219 void QEvrVideoOverlay::openStateChanged(long state) |
|
220 { |
|
221 if (state == wmposMediaOpen) { |
|
222 setDisplayRect(m_displayRect); |
|
223 |
|
224 emit nativeSizeChanged(); |
|
225 } |
|
226 }; |
|
227 |
|
228 // IUnknown |
|
229 HRESULT QEvrVideoOverlay::QueryInterface(REFIID riid, void **object) |
|
230 { |
|
231 if (!object) { |
|
232 return E_POINTER; |
|
233 } else if (riid == __uuidof(IUnknown) |
|
234 || riid == __uuidof(IMFAttributes) |
|
235 || riid == __uuidof(IMFActivate)) { |
|
236 *object = static_cast<IMFActivate *>(this); |
|
237 } else { |
|
238 return E_NOINTERFACE; |
|
239 } |
|
240 |
|
241 AddRef(); |
|
242 |
|
243 return S_OK; |
|
244 } |
|
245 |
|
246 ULONG QEvrVideoOverlay::AddRef() |
|
247 { |
|
248 return InterlockedIncrement(&m_ref); |
|
249 } |
|
250 |
|
251 ULONG QEvrVideoOverlay::Release() |
|
252 { |
|
253 ULONG ref = InterlockedDecrement(&m_ref); |
|
254 |
|
255 Q_ASSERT(ref != 0); |
|
256 |
|
257 return ref; |
|
258 } |
|
259 |
|
260 // IMFActivate |
|
261 HRESULT QEvrVideoOverlay::ActivateObject(REFIID riid, void **ppv) |
|
262 { |
|
263 if (riid != __uuidof(IMFVideoPresenter)) { |
|
264 return E_NOINTERFACE; |
|
265 } else if (!ptrMFCreateVideoPresenter) { |
|
266 return E_NOINTERFACE; |
|
267 } else if (m_presenter) { |
|
268 *ppv = m_presenter; |
|
269 |
|
270 return S_OK; |
|
271 } else { |
|
272 IMFVideoDisplayControl *displayControl = 0; |
|
273 |
|
274 IMFGetService *service; |
|
275 HRESULT hr; |
|
276 if ((hr = (*ptrMFCreateVideoPresenter)( |
|
277 0, |
|
278 __uuidof(IDirect3DDevice9), |
|
279 __uuidof(IMFVideoPresenter), |
|
280 reinterpret_cast<void **>(&m_presenter))) != S_OK) { |
|
281 qWarning("failed to create video presenter"); |
|
282 } else if ((hr = m_presenter->QueryInterface( |
|
283 __uuidof(IMFGetService), reinterpret_cast<void **>(&service))) != S_OK) { |
|
284 qWarning("failed to query IMFGetService interface"); |
|
285 } else { |
|
286 if ((hr = service->GetService( |
|
287 MR_VIDEO_RENDER_SERVICE, |
|
288 __uuidof(IMFVideoDisplayControl), |
|
289 reinterpret_cast<void **>(&displayControl))) != S_OK) { |
|
290 qWarning("failed to get IMFVideoDisplayControl service"); |
|
291 } |
|
292 service->Release(); |
|
293 } |
|
294 |
|
295 setDisplayControl(displayControl); |
|
296 |
|
297 if (m_presenter && hr != S_OK) { |
|
298 m_presenter->Release(); |
|
299 m_presenter = 0; |
|
300 } |
|
301 |
|
302 *ppv = m_presenter; |
|
303 |
|
304 return hr; |
|
305 } |
|
306 } |
|
307 |
|
308 HRESULT QEvrVideoOverlay::ShutdownObject() |
|
309 { |
|
310 setDisplayControl(0); |
|
311 |
|
312 if (m_presenter) { |
|
313 m_presenter->Release(); |
|
314 m_presenter = 0; |
|
315 } |
|
316 return S_OK; |
|
317 } |
|
318 |
|
319 HRESULT QEvrVideoOverlay::DetachObject() |
|
320 { |
|
321 if (m_presenter) { |
|
322 m_presenter->Release(); |
|
323 m_presenter = 0; |
|
324 } |
|
325 |
|
326 return S_OK; |
|
327 } |