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

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

Powered by Google App Engine
This is Rietveld 408576698