Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: media/video/capture/win/video_capture_device_factory_win.cc

Issue 558503003: Windows video capture: Remove duplicated code from GetDeviceSupportedFormats* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/video/capture/win/video_capture_device_factory_win.h" 5 #include "media/video/capture/win/video_capture_device_factory_win.h"
6 6
7 #include <mfapi.h> 7 #include <mfapi.h>
8 #include <mferror.h> 8 #include <mferror.h>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 183 }
184 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " 184 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: "
185 << logging::SystemErrorCodeToString(hr); 185 << logging::SystemErrorCodeToString(hr);
186 devices[i]->Release(); 186 devices[i]->Release();
187 } 187 }
188 } 188 }
189 189
190 static void GetDeviceSupportedFormatsDirectShow(const Name& device, 190 static void GetDeviceSupportedFormatsDirectShow(const Name& device,
191 VideoCaptureFormats* formats) { 191 VideoCaptureFormats* formats) {
192 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); 192 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name();
193 ScopedComPtr<ICreateDevEnum> dev_enum;
194 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
195 CLSCTX_INPROC);
196 if (FAILED(hr))
197 return;
198 193
199 ScopedComPtr<IEnumMoniker> enum_moniker;
200 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
201 enum_moniker.Receive(), 0);
202 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera
203 // exists. Therefore the FAILED macro can't be used.
204 if (hr != S_OK)
205 return;
206
207 // Walk the capture devices. No need to check for device presence again since
208 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old
209 // VFW devices are already skipped previously in GetDeviceNames() enumeration.
210 base::win::ScopedComPtr<IBaseFilter> capture_filter; 194 base::win::ScopedComPtr<IBaseFilter> capture_filter;
211 hr = VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), 195 base::win::ScopedComPtr<IPin> output_capture_pin;
212 capture_filter.Receive()); 196 CapabilityList capabilities;
213 if (!capture_filter) { 197 if (!VideoCaptureDeviceWin::GetDeviceSupportedFormats(
214 DLOG(ERROR) << "Failed to create capture filter: " 198 device, &capture_filter, &output_capture_pin, &capabilities)) {
215 << logging::SystemErrorCodeToString(hr);
216 return; 199 return;
217 } 200 }
218 201
219 base::win::ScopedComPtr<IPin> output_capture_pin( 202 capabilities.CapabilitiesToVideoCaptureFormats(formats);
220 VideoCaptureDeviceWin::GetPin(capture_filter,
221 PINDIR_OUTPUT,
222 PIN_CATEGORY_CAPTURE));
223 if (!output_capture_pin) {
224 DLOG(ERROR) << "Failed to get capture output pin";
225 return;
226 }
227
228 ScopedComPtr<IAMStreamConfig> stream_config;
229 hr = output_capture_pin.QueryInterface(stream_config.Receive());
230 if (FAILED(hr)) {
231 DLOG(ERROR) << "Failed to get IAMStreamConfig interface from "
232 "capture device: " << logging::SystemErrorCodeToString(hr);
233 return;
234 }
235
236 int count = 0, size = 0;
237 hr = stream_config->GetNumberOfCapabilities(&count, &size);
238 if (FAILED(hr)) {
239 DLOG(ERROR) << "GetNumberOfCapabilities failed: "
240 << logging::SystemErrorCodeToString(hr);
241 return;
242 }
243
244 scoped_ptr<BYTE[]> caps(new BYTE[size]);
245 for (int i = 0; i < count; ++i) {
246 VideoCaptureDeviceWin::ScopedMediaType media_type;
247 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get());
248 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED()
249 // macros here since they'll trigger incorrectly.
250 if (hr != S_OK) {
251 DLOG(ERROR) << "GetStreamCaps failed: "
252 << logging::SystemErrorCodeToString(hr);
253 return;
254 }
255
256 if (media_type->majortype == MEDIATYPE_Video &&
257 media_type->formattype == FORMAT_VideoInfo) {
258 VideoCaptureFormat format;
259 format.pixel_format =
260 VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat(
261 media_type->subtype);
262 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN)
263 continue;
264 VIDEOINFOHEADER* h =
265 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
266 format.frame_size.SetSize(h->bmiHeader.biWidth,
267 h->bmiHeader.biHeight);
268 // Trust the frame rate from the VIDEOINFOHEADER.
269 format.frame_rate = (h->AvgTimePerFrame > 0) ?
270 kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) :
271 0.0f;
272 formats->push_back(format);
273 DVLOG(1) << device.name() << " " << format.ToString();
274 }
275 }
276 } 203 }
277 204
278 static void GetDeviceSupportedFormatsMediaFoundation( 205 static void GetDeviceSupportedFormatsMediaFoundation(
279 const Name& device, 206 const Name& device,
280 VideoCaptureFormats* formats) { 207 VideoCaptureFormats* formats) {
281 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name(); 208 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name();
282 ScopedComPtr<IMFMediaSource> source; 209 ScopedComPtr<IMFMediaSource> source;
283 if (!CreateVideoCaptureDeviceMediaFoundation(device.id().c_str(), 210 if (!CreateVideoCaptureDeviceMediaFoundation(device.id().c_str(),
284 source.Receive())) { 211 source.Receive())) {
285 return; 212 return;
286 } 213 }
287 214
288 base::win::ScopedComPtr<IMFSourceReader> reader; 215 base::win::ScopedComPtr<IMFSourceReader> reader;
289 HRESULT hr = 216 HRESULT hr =
290 MFCreateSourceReaderFromMediaSource(source, NULL, reader.Receive()); 217 MFCreateSourceReaderFromMediaSource(source, NULL, reader.Receive());
291 if (FAILED(hr)) { 218 if (FAILED(hr)) {
292 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " 219 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: "
293 << logging::SystemErrorCodeToString(hr); 220 << logging::SystemErrorCodeToString(hr);
294 return; 221 return;
295 } 222 }
296 223
297 DWORD stream_index = 0; 224 CapabilityList capabilities;
298 ScopedComPtr<IMFMediaType> type; 225 hr = VideoCaptureDeviceMFWin::FillCapabilities(reader, &capabilities);
299 while (SUCCEEDED(reader->GetNativeMediaType( 226 if (FAILED(hr)) {
300 kFirstVideoStream, stream_index, type.Receive()))) { 227 DLOG(ERROR) << "FillCapabilities failed: "
301 UINT32 width, height; 228 << logging::SystemErrorCodeToString(hr);
302 hr = MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &width, &height); 229 return;
303 if (FAILED(hr)) { 230 }
304 DLOG(ERROR) << "MFGetAttributeSize failed: "
305 << logging::SystemErrorCodeToString(hr);
306 return;
307 }
308 VideoCaptureFormat capture_format;
309 capture_format.frame_size.SetSize(width, height);
310 231
311 UINT32 numerator, denominator; 232 capabilities.CapabilitiesToVideoCaptureFormats(formats);
312 hr = MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, &denominator);
313 if (FAILED(hr)) {
314 DLOG(ERROR) << "MFGetAttributeSize failed: "
315 << logging::SystemErrorCodeToString(hr);
316 return;
317 }
318 capture_format.frame_rate = denominator
319 ? static_cast<float>(numerator) / denominator : 0.0f;
320
321 GUID type_guid;
322 hr = type->GetGUID(MF_MT_SUBTYPE, &type_guid);
323 if (FAILED(hr)) {
324 DLOG(ERROR) << "GetGUID failed: "
325 << logging::SystemErrorCodeToString(hr);
326 return;
327 }
328 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid,
329 &capture_format.pixel_format);
330 type.Release();
331 formats->push_back(capture_format);
332 ++stream_index;
333
334 DVLOG(1) << device.name() << " " << capture_format.ToString();
335 }
336 } 233 }
337 234
338 // Returns true iff the current platform supports the Media Foundation API 235 // Returns true iff the current platform supports the Media Foundation API
339 // and that the DLLs are available. On Vista this API is an optional download 236 // and that the DLLs are available. On Vista this API is an optional download
340 // but the API is advertised as a part of Windows 7 and onwards. However, 237 // but the API is advertised as a part of Windows 7 and onwards. However,
341 // we've seen that the required DLLs are not available in some Win7 238 // we've seen that the required DLLs are not available in some Win7
342 // distributions such as Windows 7 N and Windows 7 KN. 239 // distributions such as Windows 7 N and Windows 7 KN.
343 // static 240 // static
344 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { 241 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() {
345 // Even though the DLLs might be available on Vista, we get crashes 242 // Even though the DLLs might be available on Vista, we get crashes
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 315 }
419 } 316 }
420 } 317 }
421 } 318 }
422 } 319 }
423 320
424 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( 321 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats(
425 const Name& device, 322 const Name& device,
426 VideoCaptureFormats* formats) { 323 VideoCaptureFormats* formats) {
427 DCHECK(thread_checker_.CalledOnValidThread()); 324 DCHECK(thread_checker_.CalledOnValidThread());
325 formats->clear();
tommi (sloooow) - chröme 2014/10/22 16:23:13 if formats needs to be empty on entry, I prefer to
428 if (use_media_foundation_) 326 if (use_media_foundation_)
429 GetDeviceSupportedFormatsMediaFoundation(device, formats); 327 GetDeviceSupportedFormatsMediaFoundation(device, formats);
430 else 328 else
431 GetDeviceSupportedFormatsDirectShow(device, formats); 329 GetDeviceSupportedFormatsDirectShow(device, formats);
330 for (VideoCaptureFormats::iterator it = formats->begin();
tommi (sloooow) - chröme 2014/10/22 16:23:13 nit: empty line before this one
331 it != formats->end(); ++it) {
332 DVLOG(1) << device.name() << " " << it->ToString();
333 }
432 } 334 }
433 335
434 } // namespace media 336 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698