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

Side by Side 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: fix style checker errors 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h"
6
7 #include "base/bind_helpers.h"
8 #include "base/threading/platform_thread.h"
9 #include "media/capture/video/chromeos/camera_device_delegate.h"
10 #include "media/capture/video/chromeos/camera_hal_delegate.h"
11 #include "ui/display/display.h"
12 #include "ui/display/display_observer.h"
13 #include "ui/display/screen.h"
14
15 namespace media {
16
17 VideoCaptureDeviceArcChromeOS::VideoCaptureDeviceArcChromeOS(
18 scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_screen_observer,
19 const VideoCaptureDeviceDescriptor& device_descriptor,
20 scoped_refptr<CameraHalDelegate> camera_hal_delegate)
21 : device_descriptor_(device_descriptor),
22 camera_hal_delegate_(std::move(camera_hal_delegate)),
23 capture_task_runner_(base::ThreadTaskRunnerHandle::Get()),
24 camera_device_ipc_thread_(std::string("CameraDeviceIpcThread") +
25 device_descriptor.device_id),
26 screen_observer_delegate_(new ScreenObserverDelegate(
27 this,
28 std::move(task_runner_for_screen_observer))),
29 lens_facing_(device_descriptor.facing),
30 camera_orientation_(0),
31 // External cameras have lens_facing as MEDIA_VIDEO_FACING_NONE.
32 // We don't want to rotate the frame even if the device rotates.
33 rotates_with_device_(lens_facing_ !=
34 VideoFacingMode::MEDIA_VIDEO_FACING_NONE),
35 rotation_(0) {}
36
37 VideoCaptureDeviceArcChromeOS::~VideoCaptureDeviceArcChromeOS() {
38 DCHECK(capture_task_runner_->BelongsToCurrentThread());
39 DCHECK(!camera_device_ipc_thread_.IsRunning());
40 screen_observer_delegate_->RemoveObserver();
41 }
42
43 // VideoCaptureDevice implementation.
44 void VideoCaptureDeviceArcChromeOS::AllocateAndStart(
45 const VideoCaptureParams& params,
46 std::unique_ptr<Client> client) {
47 DCHECK(capture_task_runner_->BelongsToCurrentThread());
48 DCHECK(!camera_device_delegate_);
49
50 if (!camera_device_ipc_thread_.Start()) {
51 std::string error_msg = "Failed to start device thread";
52 LOG(ERROR) << error_msg;
53 client->OnError(FROM_HERE, error_msg);
54 return;
55 }
56 camera_device_delegate_ =
57 new CameraDeviceDelegate(device_descriptor_, camera_hal_delegate_,
58 camera_device_ipc_thread_.task_runner());
59 camera_device_ipc_thread_.task_runner()->PostTask(
60 FROM_HERE,
61 base::Bind(&CameraDeviceDelegate::AllocateAndStart,
62 camera_device_delegate_, params, base::Passed(&client)));
63 camera_device_ipc_thread_.task_runner()->PostTask(
64 FROM_HERE, base::Bind(&CameraDeviceDelegate::SetRotation,
65 camera_device_delegate_, rotation_));
66 }
67
68 void VideoCaptureDeviceArcChromeOS::StopAndDeAllocate() {
69 DCHECK(capture_task_runner_->BelongsToCurrentThread());
70
71 if (!camera_device_delegate_) {
72 return;
73 }
74 camera_device_ipc_thread_.task_runner()->PostTask(
75 FROM_HERE, base::Bind(&CameraDeviceDelegate::StopAndDeAllocate,
76 camera_device_delegate_));
77 // Wait until all other references to |camera_device_delegate_| are dropped to
78 // make sure all the IPC calls are done. This is best-effort as the camera
79 // HAL may never return, say, due to a deadlock, in which case the loop simply
80 // times out and we destroy everything.
81 const int kWaitTimeoutSecs = 3;
82 base::TimeTicks wait_until =
83 base::TimeTicks() + base::TimeDelta::FromSeconds(kWaitTimeoutSecs);
84 while (!camera_device_delegate_->HasOneRef()) {
85 if (base::TimeTicks() >= wait_until) {
86 LOG(ERROR) << "Timed out waiting capture device to stop";
87 break;
88 }
89 base::PlatformThread::YieldCurrentThread();
90 }
91 camera_device_ipc_thread_.Stop();
92 camera_device_delegate_ = nullptr;
93 }
94
95 void VideoCaptureDeviceArcChromeOS::TakePhoto(TakePhotoCallback callback) {
96 DCHECK(capture_task_runner_->BelongsToCurrentThread());
97 DCHECK(camera_device_delegate_);
98 camera_device_ipc_thread_.task_runner()->PostTask(
99 FROM_HERE, base::Bind(&CameraDeviceDelegate::TakePhoto,
100 camera_device_delegate_, base::Passed(&callback)));
101 }
102
103 void VideoCaptureDeviceArcChromeOS::GetPhotoState(
104 GetPhotoStateCallback callback) {
105 DCHECK(capture_task_runner_->BelongsToCurrentThread());
106 camera_device_ipc_thread_.task_runner()->PostTask(
107 FROM_HERE, base::Bind(&CameraDeviceDelegate::GetPhotoState,
108 camera_device_delegate_, base::Passed(&callback)));
109 }
110
111 void VideoCaptureDeviceArcChromeOS::SetPhotoOptions(
112 mojom::PhotoSettingsPtr settings,
113 SetPhotoOptionsCallback callback) {
114 DCHECK(capture_task_runner_->BelongsToCurrentThread());
115 camera_device_ipc_thread_.task_runner()->PostTask(
116 FROM_HERE, base::Bind(&CameraDeviceDelegate::SetPhotoOptions,
117 camera_device_delegate_, base::Passed(&settings),
118 base::Passed(&callback)));
119 }
120
121 void VideoCaptureDeviceArcChromeOS::SetDisplayRotation(
122 const display::Display& display) {
123 DCHECK(capture_task_runner_->BelongsToCurrentThread());
124 if (display.IsInternal())
125 SetRotation(display.rotation() * 90);
126 }
127
128 void VideoCaptureDeviceArcChromeOS::SetRotation(int rotation) {
129 DCHECK(capture_task_runner_->BelongsToCurrentThread());
130 if (!rotates_with_device_) {
131 rotation = 0;
132 } else if (lens_facing_ == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
133 // Original frame when |rotation| = 0
134 // -----------------------
135 // | * |
136 // | * * |
137 // | * * |
138 // | ******* |
139 // | * * |
140 // | * * |
141 // -----------------------
142 //
143 // |rotation| = 90, this is what back camera sees
144 // -----------------------
145 // | ******** |
146 // | * **** |
147 // | * *** |
148 // | * *** |
149 // | * **** |
150 // | ******** |
151 // -----------------------
152 //
153 // |rotation| = 90, this is what front camera sees
154 // -----------------------
155 // | ******** |
156 // | **** * |
157 // | *** * |
158 // | *** * |
159 // | **** * |
160 // | ******** |
161 // -----------------------
162 //
163 // Therefore, for back camera, we need to rotate (360 - |rotation|).
164 rotation = (360 - rotation) % 360;
165 }
166 // Take into account camera orientation w.r.t. the display. External cameras
167 // would have camera_orientation_ as 0.
168 rotation_ = (rotation + camera_orientation_) % 360;
169 if (camera_device_ipc_thread_.IsRunning()) {
170 camera_device_ipc_thread_.task_runner()->PostTask(
171 FROM_HERE, base::Bind(&CameraDeviceDelegate::SetRotation,
172 camera_device_delegate_, rotation_));
173 }
174 }
175
176 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698