| 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 WebString toString(media::mojom::blink::MeteringMode value) { |
| 62 switch (value) { |
| 63 case media::mojom::blink::MeteringMode::NONE: |
| 64 return WebString::fromUTF8("none"); |
| 65 case media::mojom::blink::MeteringMode::MANUAL: |
| 66 return WebString::fromUTF8("manual"); |
| 67 case media::mojom::blink::MeteringMode::SINGLE_SHOT: |
| 68 return WebString::fromUTF8("single-shot"); |
| 69 case media::mojom::blink::MeteringMode::CONTINUOUS: |
| 70 return WebString::fromUTF8("continuous"); |
| 71 default: |
| 72 NOTREACHED() << "Unknown MeteringMode"; |
| 73 } |
| 74 return WebString(); |
| 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. | |
| 292 MediaSettingsRange* iso = MediaSettingsRange::create( | |
| 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(); | 320 PhotoCapabilities* caps = PhotoCapabilities::create(); |
| 327 caps->setIso(iso); | 321 // TODO(mcasas): Remove the explicit MediaSettingsRange::create() when |
| 328 caps->setImageHeight(height); | 322 // mojo::StructTraits supports garbage-collected mappings, |
| 329 caps->setImageWidth(width); | 323 // https://crbug.com/700180. |
| 330 caps->setZoom(zoom); | 324 caps->setIso(MediaSettingsRange::create(std::move(capabilities->iso))); |
| 325 caps->setImageHeight( |
| 326 MediaSettingsRange::create(std::move(capabilities->height))); |
| 327 caps->setImageWidth( |
| 328 MediaSettingsRange::create(std::move(capabilities->width))); |
| 329 caps->setZoom(MediaSettingsRange::create(std::move(capabilities->zoom))); |
| 330 caps->setExposureCompensation(MediaSettingsRange::create( |
| 331 std::move(capabilities->exposure_compensation))); |
| 332 caps->setColorTemperature( |
| 333 MediaSettingsRange::create(std::move(capabilities->color_temperature))); |
| 334 caps->setBrightness( |
| 335 MediaSettingsRange::create(std::move(capabilities->brightness))); |
| 336 caps->setContrast( |
| 337 MediaSettingsRange::create(std::move(capabilities->contrast))); |
| 338 caps->setSaturation( |
| 339 MediaSettingsRange::create(std::move(capabilities->saturation))); |
| 340 caps->setSharpness( |
| 341 MediaSettingsRange::create(std::move(capabilities->sharpness))); |
| 342 |
| 331 caps->setFocusMode(capabilities->focus_mode); | 343 caps->setFocusMode(capabilities->focus_mode); |
| 332 caps->setExposureMode(capabilities->exposure_mode); | 344 caps->setExposureMode(capabilities->exposure_mode); |
| 333 caps->setExposureCompensation(exposureCompensation); | |
| 334 caps->setWhiteBalanceMode(capabilities->white_balance_mode); | 345 caps->setWhiteBalanceMode(capabilities->white_balance_mode); |
| 335 caps->setFillLightMode(capabilities->fill_light_mode); | 346 caps->setFillLightMode(capabilities->fill_light_mode); |
| 347 |
| 336 caps->setRedEyeReduction(capabilities->red_eye_reduction); | 348 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); | 349 resolver->resolve(caps); |
| 343 } | 350 } |
| 344 m_serviceRequests.erase(resolver); | 351 m_serviceRequests.erase(resolver); |
| 345 } | 352 } |
| 346 | 353 |
| 347 void ImageCapture::onSetOptions(ScriptPromiseResolver* resolver, bool result) { | 354 void ImageCapture::onSetOptions(ScriptPromiseResolver* resolver, bool result) { |
| 348 if (!m_serviceRequests.contains(resolver)) | 355 if (!m_serviceRequests.contains(resolver)) |
| 349 return; | 356 return; |
| 350 | 357 |
| 351 if (result) | 358 if (result) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 362 | 369 |
| 363 // TODO(mcasas): Should be using a mojo::StructTraits. | 370 // TODO(mcasas): Should be using a mojo::StructTraits. |
| 364 if (blob->data.isEmpty()) | 371 if (blob->data.isEmpty()) |
| 365 resolver->reject(DOMException::create(UnknownError, "platform error")); | 372 resolver->reject(DOMException::create(UnknownError, "platform error")); |
| 366 else | 373 else |
| 367 resolver->resolve( | 374 resolver->resolve( |
| 368 Blob::create(blob->data.data(), blob->data.size(), blob->mime_type)); | 375 Blob::create(blob->data.data(), blob->data.size(), blob->mime_type)); |
| 369 m_serviceRequests.erase(resolver); | 376 m_serviceRequests.erase(resolver); |
| 370 } | 377 } |
| 371 | 378 |
| 379 void ImageCapture::onCapabilitiesBootstrap( |
| 380 media::mojom::blink::PhotoCapabilitiesPtr capabilities) { |
| 381 DVLOG(1) << __func__; |
| 382 if (capabilities.is_null()) |
| 383 return; |
| 384 |
| 385 // TODO(mcasas): adapt the mojo interface to return a list of supported Modes |
| 386 // when moving these out of PhotoCapabilities, https://crbug.com/700607. |
| 387 m_capabilities.setWhiteBalanceMode( |
| 388 WTF::Vector<WTF::String>({toString(capabilities->white_balance_mode)})); |
| 389 m_capabilities.setExposureMode( |
| 390 WTF::Vector<WTF::String>({toString(capabilities->exposure_mode)})); |
| 391 m_capabilities.setFocusMode( |
| 392 WTF::Vector<WTF::String>({toString(capabilities->focus_mode)})); |
| 393 |
| 394 // TODO(mcasas): Remove the explicit MediaSettingsRange::create() when |
| 395 // mojo::StructTraits supports garbage-collected mappings, |
| 396 // https://crbug.com/700180. |
| 397 if (capabilities->exposure_compensation->max != |
| 398 capabilities->exposure_compensation->min) { |
| 399 m_capabilities.setExposureCompensation(MediaSettingsRange::create( |
| 400 std::move(capabilities->exposure_compensation))); |
| 401 } |
| 402 if (capabilities->color_temperature->max != |
| 403 capabilities->color_temperature->min) { |
| 404 m_capabilities.setColorTemperature( |
| 405 MediaSettingsRange::create(std::move(capabilities->color_temperature))); |
| 406 } |
| 407 if (capabilities->iso->max != capabilities->iso->min) { |
| 408 m_capabilities.setIso( |
| 409 MediaSettingsRange::create(std::move(capabilities->iso))); |
| 410 } |
| 411 |
| 412 if (capabilities->brightness->max != capabilities->brightness->min) { |
| 413 m_capabilities.setBrightness( |
| 414 MediaSettingsRange::create(std::move(capabilities->brightness))); |
| 415 } |
| 416 if (capabilities->contrast->max != capabilities->contrast->min) { |
| 417 m_capabilities.setContrast( |
| 418 MediaSettingsRange::create(std::move(capabilities->contrast))); |
| 419 } |
| 420 if (capabilities->saturation->max != capabilities->saturation->min) { |
| 421 m_capabilities.setSaturation( |
| 422 MediaSettingsRange::create(std::move(capabilities->saturation))); |
| 423 } |
| 424 if (capabilities->sharpness->max != capabilities->sharpness->min) { |
| 425 m_capabilities.setSharpness( |
| 426 MediaSettingsRange::create(std::move(capabilities->sharpness))); |
| 427 } |
| 428 |
| 429 if (capabilities->zoom->max != capabilities->zoom->min) { |
| 430 m_capabilities.setZoom( |
| 431 MediaSettingsRange::create(std::move(capabilities->zoom))); |
| 432 } |
| 433 |
| 434 // TODO(mcasas): do |torch| when the mojom interface is updated, |
| 435 // https://crbug.com/700607. |
| 436 } |
| 437 |
| 372 void ImageCapture::onServiceConnectionError() { | 438 void ImageCapture::onServiceConnectionError() { |
| 373 m_service.reset(); | 439 m_service.reset(); |
| 374 for (ScriptPromiseResolver* resolver : m_serviceRequests) | 440 for (ScriptPromiseResolver* resolver : m_serviceRequests) |
| 375 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | 441 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
| 376 m_serviceRequests.clear(); | 442 m_serviceRequests.clear(); |
| 377 } | 443 } |
| 378 | 444 |
| 379 DEFINE_TRACE(ImageCapture) { | 445 DEFINE_TRACE(ImageCapture) { |
| 380 visitor->trace(m_streamTrack); | 446 visitor->trace(m_streamTrack); |
| 447 visitor->trace(m_capabilities); |
| 381 visitor->trace(m_serviceRequests); | 448 visitor->trace(m_serviceRequests); |
| 382 EventTargetWithInlineData::trace(visitor); | 449 EventTargetWithInlineData::trace(visitor); |
| 383 ContextLifecycleObserver::trace(visitor); | 450 ContextLifecycleObserver::trace(visitor); |
| 384 } | 451 } |
| 385 | 452 |
| 386 } // namespace blink | 453 } // namespace blink |
| OLD | NEW |