Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "modules/imagecapture/ImageCapture.h" | 5 #include "modules/imagecapture/ImageCapture.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
| 8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 9 #include "core/dom/DOMException.h" | 9 #include "core/dom/DOMException.h" |
| 10 #include "core/dom/ExceptionCode.h" | 10 #include "core/dom/ExceptionCode.h" |
| 11 #include "core/fileapi/Blob.h" | 11 #include "core/fileapi/Blob.h" |
| 12 #include "core/frame/ImageBitmap.h" | 12 #include "core/frame/ImageBitmap.h" |
| 13 #include "modules/EventTargetModules.h" | 13 #include "modules/EventTargetModules.h" |
| 14 #include "modules/imagecapture/MediaSettingsRange.h" | 14 #include "modules/imagecapture/MediaSettingsRange.h" |
| 15 #include "modules/imagecapture/PhotoCapabilities.h" | 15 #include "modules/imagecapture/PhotoCapabilities.h" |
| 16 #include "modules/imagecapture/PhotoSettings.h" | 16 #include "modules/imagecapture/PhotoSettings.h" |
| 17 #include "modules/mediastream/MediaStreamTrack.h" | 17 #include "modules/mediastream/MediaStreamTrack.h" |
| 18 #include "modules/mediastream/MediaTrackCapabilities.h" | |
| 19 #include "platform/WaitableEvent.h" | |
| 18 #include "platform/mojo/MojoHelper.h" | 20 #include "platform/mojo/MojoHelper.h" |
| 19 #include "public/platform/InterfaceProvider.h" | 21 #include "public/platform/InterfaceProvider.h" |
| 20 #include "public/platform/Platform.h" | 22 #include "public/platform/Platform.h" |
| 21 #include "public/platform/WebImageCaptureFrameGrabber.h" | 23 #include "public/platform/WebImageCaptureFrameGrabber.h" |
| 22 #include "public/platform/WebMediaStreamTrack.h" | 24 #include "public/platform/WebMediaStreamTrack.h" |
| 23 #include "wtf/PtrUtil.h" | 25 #include "wtf/PtrUtil.h" |
| 24 | 26 |
| 25 namespace blink { | 27 namespace blink { |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 49 return media::mojom::blink::FillLightMode::OFF; | 51 return media::mojom::blink::FillLightMode::OFF; |
| 50 if (blinkMode == "auto") | 52 if (blinkMode == "auto") |
| 51 return media::mojom::blink::FillLightMode::AUTO; | 53 return media::mojom::blink::FillLightMode::AUTO; |
| 52 if (blinkMode == "flash") | 54 if (blinkMode == "flash") |
| 53 return media::mojom::blink::FillLightMode::FLASH; | 55 return media::mojom::blink::FillLightMode::FLASH; |
| 54 if (blinkMode == "torch") | 56 if (blinkMode == "torch") |
| 55 return media::mojom::blink::FillLightMode::TORCH; | 57 return media::mojom::blink::FillLightMode::TORCH; |
| 56 return media::mojom::blink::FillLightMode::NONE; | 58 return media::mojom::blink::FillLightMode::NONE; |
| 57 } | 59 } |
| 58 | 60 |
| 61 std::string toString(media::mojom::blink::MeteringMode value) { | |
|
Reilly Grant (use Gerrit)
2017/03/14 21:38:57
Return String so you don't need to do a conversion
mcasas
2017/03/14 22:28:01
haraken@ recommended that too, done.
| |
| 62 switch (value) { | |
| 63 case media::mojom::blink::MeteringMode::NONE: | |
| 64 return "none"; | |
| 65 case media::mojom::blink::MeteringMode::MANUAL: | |
| 66 return "manual"; | |
| 67 case media::mojom::blink::MeteringMode::SINGLE_SHOT: | |
| 68 return "single-shot"; | |
| 69 case media::mojom::blink::MeteringMode::CONTINUOUS: | |
| 70 return "continuous"; | |
| 71 default: | |
| 72 NOTREACHED() << "Unknown MeteringMode"; | |
| 73 } | |
| 74 return ""; | |
| 75 } | |
| 76 | |
| 59 } // anonymous namespace | 77 } // anonymous namespace |
| 60 | 78 |
| 61 ImageCapture* ImageCapture::create(ExecutionContext* context, | 79 ImageCapture* ImageCapture::create(ExecutionContext* context, |
| 62 MediaStreamTrack* track, | 80 MediaStreamTrack* track, |
| 63 ExceptionState& exceptionState) { | 81 ExceptionState& exceptionState) { |
| 64 if (track->kind() != "video") { | 82 if (track->kind() != "video") { |
| 65 exceptionState.throwDOMException( | 83 exceptionState.throwDOMException( |
| 66 NotSupportedError, | 84 NotSupportedError, |
| 67 "Cannot create an ImageCapturer from a non-video Track."); | 85 "Cannot create an ImageCapturer from a non-video Track."); |
| 68 return nullptr; | 86 return nullptr; |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 } | 278 } |
| 261 | 279 |
| 262 // The platform does not know about MediaStreamTrack, so we wrap it up. | 280 // The platform does not know about MediaStreamTrack, so we wrap it up. |
| 263 WebMediaStreamTrack track(m_streamTrack->component()); | 281 WebMediaStreamTrack track(m_streamTrack->component()); |
| 264 m_frameGrabber->grabFrame( | 282 m_frameGrabber->grabFrame( |
| 265 &track, new CallbackPromiseAdapter<ImageBitmap, void>(resolver)); | 283 &track, new CallbackPromiseAdapter<ImageBitmap, void>(resolver)); |
| 266 | 284 |
| 267 return promise; | 285 return promise; |
| 268 } | 286 } |
| 269 | 287 |
| 288 MediaTrackCapabilities& ImageCapture::getMediaTrackCapabilities() { | |
| 289 return m_capabilities; | |
| 290 } | |
| 291 | |
| 270 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) | 292 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) |
| 271 : ContextLifecycleObserver(context), m_streamTrack(track) { | 293 : ContextLifecycleObserver(context), m_streamTrack(track) { |
| 272 DCHECK(m_streamTrack); | 294 DCHECK(m_streamTrack); |
| 273 DCHECK(!m_service.is_bound()); | 295 DCHECK(!m_service.is_bound()); |
| 274 | 296 |
| 275 Platform::current()->interfaceProvider()->getInterface( | 297 Platform::current()->interfaceProvider()->getInterface( |
| 276 mojo::MakeRequest(&m_service)); | 298 mojo::MakeRequest(&m_service)); |
| 277 | 299 |
| 278 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( | 300 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
| 279 &ImageCapture::onServiceConnectionError, wrapWeakPersistent(this)))); | 301 &ImageCapture::onServiceConnectionError, wrapWeakPersistent(this)))); |
| 302 | |
| 303 // Launch a retrieval of the current capabilities, which arrive asynchronously | |
| 304 // to avoid blocking the main UI thread. | |
| 305 m_service->GetCapabilities( | |
| 306 m_streamTrack->component()->source()->id(), | |
| 307 convertToBaseCallback(WTF::bind(&ImageCapture::onCapabilitiesBootstrap, | |
| 308 wrapPersistent(this)))); | |
| 280 } | 309 } |
| 281 | 310 |
| 282 void ImageCapture::onCapabilities( | 311 void ImageCapture::onCapabilities( |
| 283 ScriptPromiseResolver* resolver, | 312 ScriptPromiseResolver* resolver, |
| 284 media::mojom::blink::PhotoCapabilitiesPtr capabilities) { | 313 media::mojom::blink::PhotoCapabilitiesPtr capabilities) { |
| 285 DVLOG(1) << __func__; | 314 DVLOG(1) << __func__; |
| 286 if (!m_serviceRequests.contains(resolver)) | 315 if (!m_serviceRequests.contains(resolver)) |
| 287 return; | 316 return; |
| 288 if (capabilities.is_null()) { | 317 if (capabilities.is_null()) { |
| 289 resolver->reject(DOMException::create(UnknownError, "platform error")); | 318 resolver->reject(DOMException::create(UnknownError, "platform error")); |
| 290 } else { | 319 } else { |
| 291 // TODO(mcasas): Should be using a mojo::StructTraits. | 320 // TODO(mcasas): Should be using a mojo::StructTraits, but they have issues |
| 292 MediaSettingsRange* iso = MediaSettingsRange::create( | 321 // handling garbage-collected mappings. |
| 293 capabilities->iso->max, capabilities->iso->min, | |
| 294 capabilities->iso->current, capabilities->iso->step); | |
| 295 MediaSettingsRange* height = MediaSettingsRange::create( | |
| 296 capabilities->height->max, capabilities->height->min, | |
| 297 capabilities->height->current, capabilities->height->step); | |
| 298 MediaSettingsRange* width = MediaSettingsRange::create( | |
| 299 capabilities->width->max, capabilities->width->min, | |
| 300 capabilities->width->current, capabilities->width->step); | |
| 301 MediaSettingsRange* zoom = MediaSettingsRange::create( | |
| 302 capabilities->zoom->max, capabilities->zoom->min, | |
| 303 capabilities->zoom->current, capabilities->zoom->step); | |
| 304 MediaSettingsRange* exposureCompensation = | |
| 305 MediaSettingsRange::create(capabilities->exposure_compensation->max, | |
| 306 capabilities->exposure_compensation->min, | |
| 307 capabilities->exposure_compensation->current, | |
| 308 capabilities->exposure_compensation->step); | |
| 309 MediaSettingsRange* colorTemperature = | |
| 310 MediaSettingsRange::create(capabilities->color_temperature->max, | |
| 311 capabilities->color_temperature->min, | |
| 312 capabilities->color_temperature->current, | |
| 313 capabilities->color_temperature->step); | |
| 314 MediaSettingsRange* brightness = MediaSettingsRange::create( | |
| 315 capabilities->brightness->max, capabilities->brightness->min, | |
| 316 capabilities->brightness->current, capabilities->brightness->step); | |
| 317 MediaSettingsRange* contrast = MediaSettingsRange::create( | |
| 318 capabilities->contrast->max, capabilities->contrast->min, | |
| 319 capabilities->contrast->current, capabilities->contrast->step); | |
| 320 MediaSettingsRange* saturation = MediaSettingsRange::create( | |
| 321 capabilities->saturation->max, capabilities->saturation->min, | |
| 322 capabilities->saturation->current, capabilities->saturation->step); | |
| 323 MediaSettingsRange* sharpness = MediaSettingsRange::create( | |
| 324 capabilities->sharpness->max, capabilities->sharpness->min, | |
| 325 capabilities->sharpness->current, capabilities->sharpness->step); | |
| 326 PhotoCapabilities* caps = PhotoCapabilities::create(); | 322 PhotoCapabilities* caps = PhotoCapabilities::create(); |
| 327 caps->setIso(iso); | 323 caps->setIso(MediaSettingsRange::create(std::move(capabilities->iso))); |
|
haraken
2017/03/14 19:56:37
Why do we need to create a new MediaSettingsRange
mcasas
2017/03/14 22:28:01
Indeed; but StructTraits<> can't map a MediaSettin
haraken
2017/03/15 08:43:08
Maybe would it be an option to define a struct and
| |
| 328 caps->setImageHeight(height); | 324 caps->setImageHeight( |
| 329 caps->setImageWidth(width); | 325 MediaSettingsRange::create(std::move(capabilities->height))); |
| 330 caps->setZoom(zoom); | 326 caps->setImageWidth( |
| 327 MediaSettingsRange::create(std::move(capabilities->width))); | |
| 328 caps->setZoom(MediaSettingsRange::create(std::move(capabilities->zoom))); | |
| 329 caps->setExposureCompensation(MediaSettingsRange::create( | |
| 330 std::move(capabilities->exposure_compensation))); | |
| 331 caps->setColorTemperature( | |
| 332 MediaSettingsRange::create(std::move(capabilities->color_temperature))); | |
| 333 caps->setBrightness( | |
| 334 MediaSettingsRange::create(std::move(capabilities->brightness))); | |
| 335 caps->setContrast( | |
| 336 MediaSettingsRange::create(std::move(capabilities->contrast))); | |
| 337 caps->setSaturation( | |
| 338 MediaSettingsRange::create(std::move(capabilities->saturation))); | |
| 339 caps->setSharpness( | |
| 340 MediaSettingsRange::create(std::move(capabilities->sharpness))); | |
| 341 | |
| 331 caps->setFocusMode(capabilities->focus_mode); | 342 caps->setFocusMode(capabilities->focus_mode); |
| 332 caps->setExposureMode(capabilities->exposure_mode); | 343 caps->setExposureMode(capabilities->exposure_mode); |
| 333 caps->setExposureCompensation(exposureCompensation); | |
| 334 caps->setWhiteBalanceMode(capabilities->white_balance_mode); | 344 caps->setWhiteBalanceMode(capabilities->white_balance_mode); |
| 335 caps->setFillLightMode(capabilities->fill_light_mode); | 345 caps->setFillLightMode(capabilities->fill_light_mode); |
| 346 | |
| 336 caps->setRedEyeReduction(capabilities->red_eye_reduction); | 347 caps->setRedEyeReduction(capabilities->red_eye_reduction); |
| 337 caps->setColorTemperature(colorTemperature); | |
| 338 caps->setBrightness(brightness); | |
| 339 caps->setContrast(contrast); | |
| 340 caps->setSaturation(saturation); | |
| 341 caps->setSharpness(sharpness); | |
| 342 resolver->resolve(caps); | 348 resolver->resolve(caps); |
| 343 } | 349 } |
| 344 m_serviceRequests.erase(resolver); | 350 m_serviceRequests.erase(resolver); |
| 345 } | 351 } |
| 346 | 352 |
| 347 void ImageCapture::onSetOptions(ScriptPromiseResolver* resolver, bool result) { | 353 void ImageCapture::onSetOptions(ScriptPromiseResolver* resolver, bool result) { |
| 348 if (!m_serviceRequests.contains(resolver)) | 354 if (!m_serviceRequests.contains(resolver)) |
| 349 return; | 355 return; |
| 350 | 356 |
| 351 if (result) | 357 if (result) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 362 | 368 |
| 363 // TODO(mcasas): Should be using a mojo::StructTraits. | 369 // TODO(mcasas): Should be using a mojo::StructTraits. |
| 364 if (blob->data.isEmpty()) | 370 if (blob->data.isEmpty()) |
| 365 resolver->reject(DOMException::create(UnknownError, "platform error")); | 371 resolver->reject(DOMException::create(UnknownError, "platform error")); |
| 366 else | 372 else |
| 367 resolver->resolve( | 373 resolver->resolve( |
| 368 Blob::create(blob->data.data(), blob->data.size(), blob->mime_type)); | 374 Blob::create(blob->data.data(), blob->data.size(), blob->mime_type)); |
| 369 m_serviceRequests.erase(resolver); | 375 m_serviceRequests.erase(resolver); |
| 370 } | 376 } |
| 371 | 377 |
| 378 void ImageCapture::onCapabilitiesBootstrap( | |
| 379 media::mojom::blink::PhotoCapabilitiesPtr capabilities) { | |
| 380 DVLOG(1) << __func__; | |
| 381 if (capabilities.is_null()) | |
| 382 return; | |
| 383 | |
| 384 // TODO(mcasas): adapt the mojo interface to return a list of supported Modes | |
| 385 // when moving these out of PhotoCapabilities, https://crbug.com/700607. | |
| 386 m_capabilities.setWhiteBalanceMode(WTF::Vector<WTF::String>( | |
|
haraken
2017/03/14 19:56:37
Why does the mode need to be a vector? It has only
mcasas
2017/03/14 22:28:01
MediaTrackCapabilities.idl specifies these members
| |
| 387 {WebString::fromASCII(toString(capabilities->white_balance_mode))})); | |
|
haraken
2017/03/14 19:56:37
Can we simply return WebString from toString()?
mcasas
2017/03/14 22:28:01
Done.
| |
| 388 m_capabilities.setExposureMode(WTF::Vector<WTF::String>( | |
| 389 {WebString::fromASCII(toString(capabilities->exposure_mode))})); | |
| 390 m_capabilities.setFocusMode(WTF::Vector<WTF::String>( | |
| 391 {WebString::fromASCII(toString(capabilities->focus_mode))})); | |
| 392 | |
| 393 if (capabilities->exposure_compensation->max != | |
| 394 capabilities->exposure_compensation->min) { | |
| 395 m_capabilities.setExposureCompensation(MediaSettingsRange::create( | |
| 396 std::move(capabilities->exposure_compensation))); | |
| 397 } | |
| 398 if (capabilities->color_temperature->max != | |
| 399 capabilities->color_temperature->min) { | |
| 400 m_capabilities.setColorTemperature( | |
| 401 MediaSettingsRange::create(std::move(capabilities->color_temperature))); | |
| 402 } | |
| 403 if (capabilities->iso->max != capabilities->iso->min) { | |
| 404 m_capabilities.setIso( | |
| 405 MediaSettingsRange::create(std::move(capabilities->iso))); | |
| 406 } | |
| 407 | |
| 408 if (capabilities->brightness->max != capabilities->brightness->min) { | |
| 409 m_capabilities.setBrightness( | |
| 410 MediaSettingsRange::create(std::move(capabilities->brightness))); | |
| 411 } | |
| 412 if (capabilities->contrast->max != capabilities->contrast->min) { | |
| 413 m_capabilities.setContrast( | |
| 414 MediaSettingsRange::create(std::move(capabilities->contrast))); | |
| 415 } | |
| 416 if (capabilities->saturation->max != capabilities->saturation->min) { | |
| 417 m_capabilities.setSaturation( | |
| 418 MediaSettingsRange::create(std::move(capabilities->saturation))); | |
| 419 } | |
| 420 if (capabilities->sharpness->max != capabilities->sharpness->min) { | |
| 421 m_capabilities.setSharpness( | |
| 422 MediaSettingsRange::create(std::move(capabilities->sharpness))); | |
| 423 } | |
| 424 | |
| 425 if (capabilities->zoom->max != capabilities->zoom->min) { | |
| 426 m_capabilities.setZoom( | |
| 427 MediaSettingsRange::create(std::move(capabilities->zoom))); | |
| 428 } | |
| 429 | |
| 430 // TODO(mcasas): do |torch| when the mojom interface is updated, | |
| 431 // https://crbug.com/700607. | |
| 432 } | |
| 433 | |
| 372 void ImageCapture::onServiceConnectionError() { | 434 void ImageCapture::onServiceConnectionError() { |
| 373 m_service.reset(); | 435 m_service.reset(); |
| 374 for (ScriptPromiseResolver* resolver : m_serviceRequests) | 436 for (ScriptPromiseResolver* resolver : m_serviceRequests) |
| 375 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | 437 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
| 376 m_serviceRequests.clear(); | 438 m_serviceRequests.clear(); |
| 377 } | 439 } |
| 378 | 440 |
| 379 DEFINE_TRACE(ImageCapture) { | 441 DEFINE_TRACE(ImageCapture) { |
| 380 visitor->trace(m_streamTrack); | 442 visitor->trace(m_streamTrack); |
| 443 visitor->trace(m_capabilities); | |
| 381 visitor->trace(m_serviceRequests); | 444 visitor->trace(m_serviceRequests); |
| 382 EventTargetWithInlineData::trace(visitor); | 445 EventTargetWithInlineData::trace(visitor); |
| 383 ContextLifecycleObserver::trace(visitor); | 446 ContextLifecycleObserver::trace(visitor); |
| 384 } | 447 } |
| 385 | 448 |
| 386 } // namespace blink | 449 } // namespace blink |
| OLD | NEW |