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

Side by Side Diff: media/capture/video/linux/camera_characteristics.cc

Issue 2508803002: Rotate frames correctly for back camera (Closed)
Patch Set: calculate rotation in video_capture_device_linux Created 4 years, 1 month 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 (c) 2016 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 "camera_characteristics.h"
6
7 #include <base/files/file_util.h>
8 #include <base/logging.h>
9
10 namespace media {
11
12 // /etc/camera/camera_characteristics.conf contains camera information which
13 // driver cannot provide.
14 static const char kCameraCharacteristicsConfigFile[] =
15 "/etc/camera/camera_characteristics.conf";
16 static const char kLensFacing[] = "lens_facing";
17 static const char kSensorOrientation[] = "sensor_orientation";
18 static const char kUsbVidPid[] = "usb_vid_pid";
19 static const char kFramesToSkipAfterStreamon[] =
20 "frames_to_skip_after_streamon";
21 static const char kHorizontalViewAngle_16_9[] = "horizontal_view_angle_16_9";
22 static const char kHorizontalViewAngle_4_3[] = "horizontal_view_angle_4_3";
23 static const char kLensInfoAvailableFocalLengths[] =
24 "lens_info_available_focal_lengths";
25 static const char kLensInfoMinimumFocusDistance[] =
26 "lens_info_minimum_focus_distance";
27 static const char kLensInfoOptimalFocusDistance[] =
28 "lens_info_optimal_focus_distance";
29 static const char kVerticalViewAngle_16_9[] = "vertical_view_angle_16_9";
30 static const char kVerticalViewAngle_4_3[] = "vertical_view_angle_4_3";
31
32 /* HAL v3 parameters */
33 static const char kLensInfoAvailableApertures[] =
34 "lens_info_available_apertures";
35 static const char kSensorInfoPhysicalSize[] = "sensor_info_physical_size";
36 static const char kSensorInfoPixelArraySize[] = "sensor_info_pixel_array_size";
37
38 static const struct DeviceInfo kDefaultCharacteristics = {
39 "", // device_path
40 "", // usb_vid
41 "", // usb_pid
42 0, // lens_facing
43 0, // sensor_orientation
44 0, // frames_to_skip_after_streamon
45 66.5, // horizontal_view_angle_16_9
46 0.0, // horizontal_view_angle_4_3
47 {1.6}, // lens_info_available_focal_lengths
48 0.3, // lens_info_minimum_focus_distance
49 0.5, // lens_info_optimal_focus_distance
50 42.5, // vertical_view_angle_16_9
51 0.0 // vertical_view_angle_4_3
52 };
53
54 CameraCharacteristics::CameraCharacteristics() {}
55
56 CameraCharacteristics::~CameraCharacteristics() {}
57
58 const DeviceInfos CameraCharacteristics::GetCharacteristicsFromFile(
59 const std::vector<std::string>& devices) {
60 const base::FilePath path(kCameraCharacteristicsConfigFile);
61 FILE* file = base::OpenFile(path, "r");
62 if (!file) {
63 LOG(ERROR) << __func__ << ": Can't open file "
64 << kCameraCharacteristicsConfigFile
65 << ". Use default characteristics instead";
66 for (const auto& device : devices) {
67 device_infos_.push_back(kDefaultCharacteristics);
68 size_t pos = device.find(":");
69 if (pos != std::string::npos) {
70 device_infos_.back().usb_vid = device.substr(0, pos - 1);
71 device_infos_.back().usb_pid = device.substr(pos + 1);
72 } else {
73 LOG(ERROR) << __func__ << ": Invalid device: " << device;
kcwu 2016/11/17 10:31:18 If parse failed, you will push_back a default valu
74 }
75 }
76 return device_infos_;
77 }
78
79 char buffer[256], key[256], value[256];
80 uint32_t camera_id;
81 uint32_t module_id = -1;
82 std::string vid, pid;
83 while (fgets(buffer, sizeof(buffer), file)) {
84 // Skip comments and empty lines.
85 if (buffer[0] == '#' || buffer[0] == '\n') {
86 continue;
87 }
88
89 if (sscanf(buffer, "%[^=]=%s", key, value) != 2) {
90 LOG(ERROR) << __func__ << ": Illegal format: " << buffer;
91 continue;
92 }
93 std::vector<char*> sub_keys;
94 char* sub_key = strtok(key, ".");
kcwu 2016/11/17 10:31:19 Don't use strtok() because it keep internal state
95 while (sub_key) {
96 sub_keys.push_back(sub_key);
97 sub_key = strtok(NULL, ".");
98 }
99
100 if (sscanf(sub_keys[0], "camera%u", &camera_id) != 1) {
101 LOG(ERROR) << __func__ << ": Illegal format: " << sub_keys[0];
102 continue;
103 }
104 if (camera_id > device_infos_.size()) {
105 // Camera id should be ascending by one.
106 LOG(ERROR) << __func__ << ": Invalid camera id: " << camera_id;
107 continue;
108 } else if (camera_id == device_infos_.size()) {
109 device_infos_.push_back(kDefaultCharacteristics);
110 }
kcwu 2016/11/17 10:31:18 what if camera_id < device_infos_.size() ? I'd pr
111
112 uint32_t tmp_module_id;
113 if (sscanf(sub_keys[1], "module%u", &tmp_module_id) != 1) {
114 AddPerCameraCharacteristic(camera_id, sub_keys[1], value);
115 } else {
116 if (tmp_module_id != module_id) {
117 vid.clear();
118 pid.clear();
119 module_id = tmp_module_id;
120 }
121 if (strcmp(sub_keys[2], kUsbVidPid) == 0) {
122 char tmp_vid[256], tmp_pid[256];
123 if (sscanf(value, "%[0-9a-z]:%[0-9a-z]", tmp_vid, tmp_pid) != 2) {
124 LOG(ERROR) << __func__ << ": Invalid format: " << sub_keys[2];
125 continue;
126 }
127 vid = tmp_vid;
128 pid = tmp_pid;
129 for (const auto& device : devices) {
130 if (device.compare(value) == 0) {
131 device_infos_[camera_id].usb_vid = vid;
132 device_infos_[camera_id].usb_pid = pid;
133 break;
134 }
135 }
136
137 VLOG(1) << __func__ << ": Camera" << camera_id << " " << kUsbVidPid
138 << ": " << value;
139 } else if (!vid.empty() && !pid.empty()) {
140 // Some characteristics are module-specific, so only matched ones are
141 // selected.
142 if (device_infos_[camera_id].usb_vid != vid ||
143 device_infos_[camera_id].usb_pid != pid) {
144 VLOG(1) << __func__ << ": Mismatched module: "
145 << "vid: " << vid << " pid: " << pid;
146 continue;
147 }
148 AddPerModuleCharacteristic(camera_id, sub_keys[2], value);
149 } else {
150 // Characteristic usb_vid_pid should come before other module-specific
151 // characteristics.
152 LOG(ERROR) << __func__ << ": Illegal format."
153 << " usb_vid_pid should come before: " << buffer;
154 }
155 }
156 }
157 base::CloseFile(file);
158 return device_infos_;
159 }
160
161 int CameraCharacteristics::GetCameraFacing(const std::string& model_id) {
162 std::vector<std::string> model_ids;
163 model_ids.push_back(model_id);
164 DeviceInfos device_infos = GetCharacteristicsFromFile(model_ids);
165 for (auto device_info : device_infos) {
166 char vid_pid[16];
167 sprintf(vid_pid, "%s:%s", device_info.usb_vid.c_str(),
kcwu 2016/11/17 10:31:19 I am wondering will this buffer overflow?
168 device_info.usb_pid.c_str());
169 if (strcmp(model_id.c_str(), vid_pid) == 0) {
170 return device_info.lens_facing;
171 }
172 }
173 return DeviceInfo::LENS_FACING_UNKNOWN;
174 }
175
176 void CameraCharacteristics::AddPerCameraCharacteristic(
177 uint32_t camera_id,
178 const char* characteristic,
179 const char* value) {
180 if (strcmp(characteristic, kLensFacing) == 0) {
181 VLOG(1) << __func__ << ": " << characteristic << ": " << value;
182 device_infos_[camera_id].lens_facing = strtol(value, NULL, 10);
183 } else if (strcmp(characteristic, kSensorOrientation) == 0) {
184 VLOG(1) << __func__ << ": " << characteristic << ": " << value;
185 device_infos_[camera_id].sensor_orientation = strtol(value, NULL, 10);
186 } else {
187 LOG(ERROR) << __func__ << ": Unknown characteristic: " << characteristic
188 << " value: " << value;
189 }
190 }
191
192 void CameraCharacteristics::AddPerModuleCharacteristic(
193 uint32_t camera_id,
194 const char* characteristic,
195 const char* value) {
196 if (strcmp(characteristic, kFramesToSkipAfterStreamon) == 0) {
197 VLOG(1) << __func__ << ": " << characteristic << ": " << value;
198 device_infos_[camera_id].frames_to_skip_after_streamon =
199 strtol(value, NULL, 10);
200 } else if (strcmp(characteristic, kHorizontalViewAngle_16_9) == 0) {
201 AddFloatValue(value, kHorizontalViewAngle_16_9,
202 &device_infos_[camera_id].horizontal_view_angle_16_9);
203 } else if (strcmp(characteristic, kHorizontalViewAngle_4_3) == 0) {
204 AddFloatValue(value, kHorizontalViewAngle_4_3,
205 &device_infos_[camera_id].horizontal_view_angle_4_3);
206 } else if (strcmp(characteristic, kLensInfoAvailableFocalLengths) == 0) {
207 device_infos_[camera_id].lens_info_available_focal_lengths.clear();
208 char tmp_value[256];
209 strcpy(tmp_value, value);
210 char* focal_length = strtok(tmp_value, ",");
211 while (focal_length) {
212 float tmp_focal_length = strtof(focal_length, NULL);
213 if (tmp_focal_length != 0.0) {
214 VLOG(1) << __func__ << ": " << characteristic << ": "
215 << tmp_focal_length;
216 device_infos_[camera_id].lens_info_available_focal_lengths.push_back(
217 tmp_focal_length);
218 } else {
219 LOG(ERROR) << __func__ << ": Invalid " << characteristic << ": "
220 << value;
221 device_infos_[camera_id].lens_info_available_focal_lengths.clear();
222 device_infos_[camera_id].lens_info_available_focal_lengths.push_back(
223 kDefaultCharacteristics.lens_info_available_focal_lengths[0]);
224 break;
225 }
226 focal_length = strtok(NULL, ",");
227 }
228 } else if (strcmp(characteristic, kLensInfoMinimumFocusDistance) == 0) {
229 AddFloatValue(value, kLensInfoMinimumFocusDistance,
230 &device_infos_[camera_id].lens_info_minimum_focus_distance);
231 } else if (strcmp(characteristic, kLensInfoOptimalFocusDistance) == 0) {
232 AddFloatValue(value, kLensInfoOptimalFocusDistance,
233 &device_infos_[camera_id].lens_info_optimal_focus_distance);
234 } else if (strcmp(characteristic, kVerticalViewAngle_16_9) == 0) {
235 AddFloatValue(value, kVerticalViewAngle_16_9,
236 &device_infos_[camera_id].vertical_view_angle_16_9);
237 } else if (strcmp(characteristic, kVerticalViewAngle_4_3) == 0) {
238 AddFloatValue(value, kVerticalViewAngle_4_3,
239 &device_infos_[camera_id].vertical_view_angle_4_3);
240 } else if (strcmp(characteristic, kLensInfoAvailableApertures) == 0) {
241 /* Do nothing. This is for hal v3 */
242 } else if (strcmp(characteristic, kSensorInfoPhysicalSize) == 0) {
243 /* Do nothing. This is for hal v3 */
244 } else if (strcmp(characteristic, kSensorInfoPixelArraySize) == 0) {
245 /* Do nothing. This is for hal v3 */
246 } else {
247 LOG(ERROR) << __func__ << ": Unknown characteristic: " << characteristic
248 << " value: " << value;
249 }
250 }
251
252 void CameraCharacteristics::AddFloatValue(const char* value,
253 const char* characteristic_name,
254 float* characteristic) {
255 float tmp_value = strtof(value, NULL);
256 if (tmp_value != 0.0) {
kcwu 2016/11/17 10:31:19 compare float value using "!=" ?
257 VLOG(1) << __func__ << ": " << characteristic_name << ": " << value;
258 *characteristic = tmp_value;
259 } else {
260 LOG(ERROR) << __func__ << ": Invalid " << characteristic_name << ": "
kcwu 2016/11/17 10:31:18 I didn't check the detail. But reject 0 for this g
261 << value;
262 }
263 }
264
265 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698