1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "goog_sensor_sync"
18
19 #include "goog_sensor_sync.h"
20
21 #include <inttypes.h>
22 #include <stdint.h>
23 #include <string.h>
24
25 #include <algorithm>
26 #include <cmath>
27 #include <deque>
28
29 #include "utils/Errors.h"
30 #include "utils/Log.h"
31 #include "utils/RefBase.h"
32 #include "utils/String16.h"
33
34 namespace android {
35 namespace camera_sensor_listener {
36
37 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
38 using ::android::frameworks::sensorservice::V1_0::Result;
39 using ::android::hardware::sensors::V1_0::SensorInfo;
40
GoogSensorSync(uint8_t cam_id,size_t event_queue_size)41 GoogSensorSync::GoogSensorSync(uint8_t cam_id, size_t event_queue_size)
42 : GoogSensorWrapper(event_queue_size), cam_id_(cam_id) {
43 ALOGI("%s %d Sensor sync camera ID: %d", __func__, __LINE__,
44 static_cast<int>(cam_id_));
45 }
46
~GoogSensorSync()47 GoogSensorSync::~GoogSensorSync() {
48 Disable();
49 if (sync_cnt_ != 0) {
50 ALOGI("%s %d Total failure/sync for camera %d: %d/%d", __func__, __LINE__,
51 static_cast<int>(cam_id_), sync_failure_cnt_, sync_cnt_);
52 }
53 if (match_cnt_ != 0) {
54 ALOGI("%s %d Total failure/match for camera %d: %d/%d", __func__, __LINE__,
55 static_cast<int>(cam_id_), match_failure_cnt_, match_cnt_);
56 }
57 }
58
Create(uint8_t cam_id,size_t event_queue_size)59 sp<GoogSensorSync> GoogSensorSync::Create(uint8_t cam_id,
60 size_t event_queue_size) {
61 sp<GoogSensorSync> sensor_sync_ptr =
62 new GoogSensorSync(cam_id, event_queue_size);
63 if (sensor_sync_ptr == nullptr) {
64 ALOGE("%s %d failed to create GoogSensorSync.", __func__, __LINE__);
65 } else {
66 status_t result = sensor_sync_ptr->Enable();
67 if (result != 0) {
68 ALOGE("%s %d failed to enable GoogSensorSync.", __func__, __LINE__);
69 } else {
70 ALOGI("%s %d successfully enabled GoogSensorSync.", __func__, __LINE__);
71 }
72 }
73 return sensor_sync_ptr;
74 }
75
ExtractFrameIdAndBoottimeTimestamp(const ExtendedSensorEvent & event,int64_t * frame_id,int64_t * timestamp_boottime) const76 void GoogSensorSync::ExtractFrameIdAndBoottimeTimestamp(
77 const ExtendedSensorEvent& event, int64_t* frame_id,
78 int64_t* timestamp_boottime) const {
79 // Cast away const-ness.
80 float* data = const_cast<float*>(&event.sensor_event.u.data[0]);
81 // Reinterpret_cast to uint64_t pointer, since sensor hal concatenates
82 // two 32-bit floating point to pass 1 64-bit uint64_t data.
83 uint64_t* vsync_data = reinterpret_cast<uint64_t*>(data);
84 // Static_cast from uint64_t to int64_t to align with vsync timestamp format.
85 *frame_id = static_cast<int64_t>(vsync_data[1]);
86 *timestamp_boottime = static_cast<int64_t>(vsync_data[2]);
87 }
88
ExtractAocEventCounter(const ExtendedSensorEvent & event)89 uint64_t GoogSensorSync::ExtractAocEventCounter(const ExtendedSensorEvent& event) {
90 // AoC sensor Event is one uint64_t data. It can be accessed with stepCount
91 // from the data union.
92 return event.sensor_event.u.stepCount;
93 }
94
GetLatestNSamples(int num_sample,std::vector<int64_t> * latest_n_vsync_timestamps,std::vector<int64_t> * latest_n_frame_ids,std::vector<int64_t> * latest_n_boottime_timestamps,std::vector<int64_t> * latest_n_arrival_timestamps) const95 void GoogSensorSync::GetLatestNSamples(
96 int num_sample, std::vector<int64_t>* latest_n_vsync_timestamps,
97 std::vector<int64_t>* latest_n_frame_ids,
98 std::vector<int64_t>* latest_n_boottime_timestamps,
99 std::vector<int64_t>* latest_n_arrival_timestamps) const {
100 if (latest_n_vsync_timestamps == nullptr || latest_n_frame_ids == nullptr ||
101 latest_n_boottime_timestamps == nullptr ||
102 latest_n_arrival_timestamps == nullptr) {
103 return;
104 }
105 latest_n_vsync_timestamps->clear();
106 latest_n_frame_ids->clear();
107 latest_n_boottime_timestamps->clear();
108 latest_n_arrival_timestamps->clear();
109
110 if (num_sample < 0) {
111 return;
112 }
113 std::lock_guard<std::mutex> el(event_buffer_lock_);
114 int start_index =
115 std::max(0, static_cast<int>(event_buffer_.size()) - num_sample);
116 auto event = event_buffer_.begin();
117 std::advance(event, start_index);
118 for (; event != event_buffer_.end(); ++event) {
119 latest_n_vsync_timestamps->push_back(event->sensor_event.timestamp);
120 latest_n_arrival_timestamps->push_back(event->event_arrival_time_ns);
121 int64_t frame_id, boottime_timestamp;
122 ExtractFrameIdAndBoottimeTimestamp(*event, &frame_id, &boottime_timestamp);
123 latest_n_frame_ids->push_back(frame_id);
124 latest_n_boottime_timestamps->push_back(boottime_timestamp);
125 }
126 }
127
GetSensorHandle()128 int32_t GoogSensorSync::GetSensorHandle() {
129 sp<ISensorManager> manager = ISensorManager::getService();
130 if (manager == nullptr) {
131 ALOGE("%s %d Cannot get ISensorManager", __func__, __LINE__);
132 return -1;
133 }
134 SensorInfo info;
135 bool find = false;
136 static constexpr size_t kMaxVsyncNameSize = 16;
137 char sensor_for_camera[kMaxVsyncNameSize];
138 snprintf(sensor_for_camera, sizeof(sensor_for_camera), "camera v-sync %d",
139 cam_id_);
140
141 manager->getSensorList(
142 [&info, &find, &sensor_for_camera](const auto& list, auto result) {
143 if (result != Result::OK) {
144 return;
145 }
146 for (const SensorInfo& item : list) {
147 if (item.typeAsString == "com.google.sensor.camera_vsync") {
148 ALOGV("%s %d Enumerating sensor %s %s %zu %zu", __func__, __LINE__,
149 item.name.c_str(), sensor_for_camera,
150 strlen(item.name.c_str()), strlen(sensor_for_camera));
151 if (!strncasecmp(item.name.c_str(), sensor_for_camera,
152 strlen(sensor_for_camera))) {
153 info = item;
154 find = true;
155 break;
156 }
157 }
158 }
159 });
160
161 if (find) {
162 ALOGI("%s %d handle for %d is found. Sensor name %s", __func__, __LINE__,
163 static_cast<int>(cam_id_), info.name.c_str());
164 } else {
165 ALOGE("%s %d handle for %d is not found!", __func__, __LINE__,
166 static_cast<int>(cam_id_));
167 }
168 return find ? info.sensorHandle : -1;
169 }
170
SyncTimestamp(int64_t timestamp)171 int64_t GoogSensorSync::SyncTimestamp(int64_t timestamp) {
172 status_t ret;
173
174 if (!IsEnabled()) {
175 ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
176 return timestamp;
177 }
178
179 std::lock_guard<std::mutex> el(event_buffer_lock_);
180 int64_t min_delta = kMaxTimeDriftNs;
181 int64_t nearest_sync = timestamp;
182 for (auto event : event_buffer_) {
183 if (llabs(event.sensor_event.timestamp - timestamp) < min_delta) {
184 min_delta = llabs(event.sensor_event.timestamp - timestamp);
185 nearest_sync = event.sensor_event.timestamp;
186 }
187 }
188
189 sync_cnt_++;
190 if (min_delta == kMaxTimeDriftNs) {
191 struct timespec res;
192 clock_gettime(CLOCK_BOOTTIME, &res);
193 int64_t curr_time = (int64_t)res.tv_sec * 1000000000LL + res.tv_nsec;
194
195 ALOGV("%s %d Cannot sync timestamp for input timestamp %" PRId64
196 "at CPU time %" PRId64,
197 __func__, __LINE__, timestamp, curr_time);
198 sync_failure_cnt_++;
199 if (sync_failure_cnt_ >= kFailureThreshold) {
200 ALOGW("%s %d Camera %d: out of %d camera timestamps, %d failed to sync",
201 __func__, __LINE__, static_cast<int>(cam_id_), sync_cnt_,
202 sync_failure_cnt_);
203 sync_cnt_ = 0;
204 sync_failure_cnt_ = 0;
205 }
206 }
207
208 return nearest_sync;
209 }
210
FindNearestEvent(int64_t timestamp)211 std::optional<ExtendedSensorEvent> GoogSensorSync::FindNearestEvent(
212 int64_t timestamp) {
213 if (!IsEnabled()) {
214 ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
215 return std::nullopt;
216 }
217 std::lock_guard<std::mutex> el(event_buffer_lock_);
218 int64_t min_delta = kMaxTimeDriftNs;
219 std::optional<ExtendedSensorEvent> nearest_event;
220 for (auto event : event_buffer_) {
221 int64_t delta = llabs(event.sensor_event.timestamp - timestamp);
222 if (delta < min_delta) {
223 min_delta = delta;
224 nearest_event = event;
225 }
226 }
227 return nearest_event;
228 }
229
MatchTimestamp(int64_t timestamp,int64_t frame_id)230 int64_t GoogSensorSync::MatchTimestamp(int64_t timestamp, int64_t frame_id) {
231 if (!IsEnabled()) {
232 ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
233 return timestamp;
234 }
235
236 std::lock_guard<std::mutex> el(event_buffer_lock_);
237 for (auto event : event_buffer_) {
238 int64_t event_frame_id, event_timestamp;
239 ExtractFrameIdAndBoottimeTimestamp(event, &event_frame_id, &event_timestamp);
240 if (frame_id == event_frame_id && timestamp == event_timestamp) {
241 match_cnt_++;
242 return event.sensor_event.timestamp;
243 }
244 }
245 match_cnt_++;
246 match_failure_cnt_++;
247 if (match_failure_cnt_ >= kFailureThreshold) {
248 ALOGW("%s %d Camera %d: out of %d camera timestamps, %d failed to match",
249 __func__, __LINE__, static_cast<int>(cam_id_), match_cnt_,
250 match_failure_cnt_);
251 match_cnt_ = 0;
252 match_failure_cnt_ = 0;
253 }
254 return timestamp;
255 }
256
257 } // namespace camera_sensor_listener
258 } // namespace android
259