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

Unified Diff: media/capture/video/chromeos/video_capture_device_arc_chromeos.cc

Issue 2837273004: media: add video capture device for ARC++ camera HAL v3 (Closed)
Patch Set: RELAND: media: add video capture device for ARC++ camera HAL v3 Created 3 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: media/capture/video/chromeos/video_capture_device_arc_chromeos.cc
diff --git a/media/capture/video/chromeos/video_capture_device_arc_chromeos.cc b/media/capture/video/chromeos/video_capture_device_arc_chromeos.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f23d025f93cdf35523a350a93124a4564ff389f5
--- /dev/null
+++ b/media/capture/video/chromeos/video_capture_device_arc_chromeos.cc
@@ -0,0 +1,186 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/platform_thread.h"
+#include "media/capture/video/chromeos/camera_device_delegate.h"
+#include "media/capture/video/chromeos/camera_hal_delegate.h"
+#include "ui/display/display.h"
+#include "ui/display/display_observer.h"
+#include "ui/display/screen.h"
+
+namespace media {
+
+VideoCaptureDeviceArcChromeOS::VideoCaptureDeviceArcChromeOS(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_screen_observer,
+ const VideoCaptureDeviceDescriptor& device_descriptor,
+ scoped_refptr<CameraHalDelegate> camera_hal_delegate)
+ : device_descriptor_(device_descriptor),
+ camera_hal_delegate_(std::move(camera_hal_delegate)),
+ capture_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ camera_device_ipc_thread_(std::string("CameraDeviceIpcThread") +
+ device_descriptor.device_id),
+ screen_observer_delegate_(new ScreenObserverDelegate(
+ this,
+ std::move(task_runner_for_screen_observer))),
+ lens_facing_(device_descriptor.facing),
+ camera_orientation_(0),
+ // External cameras have lens_facing as MEDIA_VIDEO_FACING_NONE.
+ // We don't want to rotate the frame even if the device rotates.
+ rotates_with_device_(lens_facing_ !=
+ VideoFacingMode::MEDIA_VIDEO_FACING_NONE),
+ rotation_(0) {}
+
+VideoCaptureDeviceArcChromeOS::~VideoCaptureDeviceArcChromeOS() {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ DCHECK(!camera_device_ipc_thread_.IsRunning());
+ screen_observer_delegate_->RemoveObserver();
+}
+
+// VideoCaptureDevice implementation.
+void VideoCaptureDeviceArcChromeOS::AllocateAndStart(
+ const VideoCaptureParams& params,
+ std::unique_ptr<Client> client) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ DCHECK(!camera_device_delegate_);
+
+ if (!camera_device_ipc_thread_.Start()) {
+ std::string error_msg = "Failed to start device thread";
+ LOG(ERROR) << error_msg;
+ client->OnError(FROM_HERE, error_msg);
+ return;
+ }
+ camera_device_delegate_ = base::MakeUnique<CameraDeviceDelegate>(
+ device_descriptor_, camera_hal_delegate_,
+ camera_device_ipc_thread_.task_runner());
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::AllocateAndStart,
+ camera_device_delegate_->GetWeakPtr(), params,
+ base::Passed(&client)));
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::SetRotation,
+ camera_device_delegate_->GetWeakPtr(), rotation_));
+}
+
+void VideoCaptureDeviceArcChromeOS::StopAndDeAllocate() {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+ if (!camera_device_delegate_) {
+ return;
+ }
+
+ // We do our best to allow the camera HAL cleanly shut down the device. In
+ // general we don't trust the camera HAL so if the device does not close in
+ // time we simply terminate the Mojo channel by resetting
+ // |camera_device_delegate_|.
+ base::WaitableEvent device_closed(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::StopAndDeAllocate,
+ camera_device_delegate_->GetWeakPtr(),
+ base::Bind(
+ [](base::WaitableEvent* device_closed) {
+ device_closed->Signal();
+ },
+ base::Unretained(&device_closed))));
+ base::TimeDelta kWaitTimeoutSecs = base::TimeDelta::FromSeconds(3);
+ device_closed.TimedWait(kWaitTimeoutSecs);
+
+ camera_device_ipc_thread_.Stop();
+ camera_device_delegate_.reset();
+}
+
+void VideoCaptureDeviceArcChromeOS::TakePhoto(TakePhotoCallback callback) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ DCHECK(camera_device_delegate_);
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::TakePhoto,
+ camera_device_delegate_->GetWeakPtr(),
+ base::Passed(&callback)));
+}
+
+void VideoCaptureDeviceArcChromeOS::GetPhotoState(
+ GetPhotoStateCallback callback) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::GetPhotoState,
+ camera_device_delegate_->GetWeakPtr(),
+ base::Passed(&callback)));
+}
+
+void VideoCaptureDeviceArcChromeOS::SetPhotoOptions(
+ mojom::PhotoSettingsPtr settings,
+ SetPhotoOptionsCallback callback) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CameraDeviceDelegate::SetPhotoOptions,
+ camera_device_delegate_->GetWeakPtr(),
+ base::Passed(&settings), base::Passed(&callback)));
+}
+
+void VideoCaptureDeviceArcChromeOS::SetDisplayRotation(
+ const display::Display& display) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ if (display.IsInternal())
+ SetRotation(display.rotation() * 90);
+}
+
+void VideoCaptureDeviceArcChromeOS::SetRotation(int rotation) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+ if (!rotates_with_device_) {
+ rotation = 0;
+ } else if (lens_facing_ == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
+ // Original frame when |rotation| = 0
+ // -----------------------
+ // | * |
+ // | * * |
+ // | * * |
+ // | ******* |
+ // | * * |
+ // | * * |
+ // -----------------------
+ //
+ // |rotation| = 90, this is what back camera sees
+ // -----------------------
+ // | ******** |
+ // | * **** |
+ // | * *** |
+ // | * *** |
+ // | * **** |
+ // | ******** |
+ // -----------------------
+ //
+ // |rotation| = 90, this is what front camera sees
+ // -----------------------
+ // | ******** |
+ // | **** * |
+ // | *** * |
+ // | *** * |
+ // | **** * |
+ // | ******** |
+ // -----------------------
+ //
+ // Therefore, for back camera, we need to rotate (360 - |rotation|).
+ rotation = (360 - rotation) % 360;
+ }
+ // Take into account camera orientation w.r.t. the display. External cameras
+ // would have camera_orientation_ as 0.
+ rotation_ = (rotation + camera_orientation_) % 360;
+ if (camera_device_ipc_thread_.IsRunning()) {
+ camera_device_ipc_thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&CameraDeviceDelegate::SetRotation,
+ camera_device_delegate_->GetWeakPtr(), rotation_));
+ }
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698