00001
00002
00003
00004 #include "types.h"
00005 #include "image.h"
00006 #include "device.h"
00007
00008 #include <cstring>
00009 #include <algorithm>
00010 #include <array>
00011 #include <deque>
00012 #include <algorithm>
00013 #include <iomanip>
00014
00015 #define unknown "UNKNOWN"
00016
00017 namespace rsimpl
00018 {
00019 const char * get_string(rs_stream value)
00020 {
00021 #define CASE(X) case RS_STREAM_##X: return #X;
00022 switch(value)
00023 {
00024 CASE(DEPTH)
00025 CASE(COLOR)
00026 CASE(INFRARED)
00027 CASE(INFRARED2)
00028 CASE(POINTS)
00029 CASE(RECTIFIED_COLOR)
00030 CASE(COLOR_ALIGNED_TO_DEPTH)
00031 CASE(DEPTH_ALIGNED_TO_COLOR)
00032 CASE(DEPTH_ALIGNED_TO_RECTIFIED_COLOR)
00033 CASE(INFRARED2_ALIGNED_TO_DEPTH)
00034 CASE(DEPTH_ALIGNED_TO_INFRARED2)
00035 CASE(FISHEYE)
00036 default: assert(!is_valid(value)); return unknown;
00037 }
00038 #undef CASE
00039 }
00040
00041 const char * get_string(rs_format value)
00042 {
00043 #define CASE(X) case RS_FORMAT_##X: return #X;
00044 switch(value)
00045 {
00046 CASE(ANY)
00047 CASE(Z16)
00048 CASE(DISPARITY16)
00049 CASE(XYZ32F)
00050 CASE(YUYV)
00051 CASE(RGB8)
00052 CASE(BGR8)
00053 CASE(RGBA8)
00054 CASE(BGRA8)
00055 CASE(Y8)
00056 CASE(Y16)
00057 CASE(RAW10)
00058 CASE(RAW16)
00059 CASE(RAW8)
00060 default: assert(!is_valid(value)); return unknown;
00061 }
00062 #undef CASE
00063 }
00064
00065 const char * get_string(rs_preset value)
00066 {
00067 #define CASE(X) case RS_PRESET_##X: return #X;
00068 switch(value)
00069 {
00070 CASE(BEST_QUALITY)
00071 CASE(LARGEST_IMAGE)
00072 CASE(HIGHEST_FRAMERATE)
00073 default: assert(!is_valid(value)); return unknown;
00074 }
00075 #undef CASE
00076 }
00077
00078 const char * get_string(rs_distortion value)
00079 {
00080 #define CASE(X) case RS_DISTORTION_##X: return #X;
00081 switch(value)
00082 {
00083 CASE(NONE)
00084 CASE(MODIFIED_BROWN_CONRADY)
00085 CASE(INVERSE_BROWN_CONRADY)
00086 CASE(FTHETA)
00087 default: assert(!is_valid(value)); return unknown;
00088 }
00089 #undef CASE
00090 }
00091
00092 const char * get_string(rs_option value)
00093 {
00094 #define CASE(X) case RS_OPTION_##X: return #X;
00095 switch(value)
00096 {
00097 CASE(COLOR_BACKLIGHT_COMPENSATION)
00098 CASE(COLOR_BRIGHTNESS)
00099 CASE(COLOR_CONTRAST)
00100 CASE(COLOR_EXPOSURE)
00101 CASE(COLOR_GAIN)
00102 CASE(COLOR_GAMMA)
00103 CASE(COLOR_HUE)
00104 CASE(COLOR_SATURATION)
00105 CASE(COLOR_SHARPNESS)
00106 CASE(COLOR_WHITE_BALANCE)
00107 CASE(COLOR_ENABLE_AUTO_EXPOSURE)
00108 CASE(COLOR_ENABLE_AUTO_WHITE_BALANCE)
00109 CASE(F200_LASER_POWER)
00110 CASE(F200_ACCURACY)
00111 CASE(F200_MOTION_RANGE)
00112 CASE(F200_FILTER_OPTION)
00113 CASE(F200_CONFIDENCE_THRESHOLD)
00114 CASE(F200_DYNAMIC_FPS)
00115 CASE(SR300_AUTO_RANGE_ENABLE_MOTION_VERSUS_RANGE)
00116 CASE(SR300_AUTO_RANGE_ENABLE_LASER)
00117 CASE(SR300_AUTO_RANGE_MIN_MOTION_VERSUS_RANGE)
00118 CASE(SR300_AUTO_RANGE_MAX_MOTION_VERSUS_RANGE)
00119 CASE(SR300_AUTO_RANGE_START_MOTION_VERSUS_RANGE)
00120 CASE(SR300_AUTO_RANGE_MIN_LASER)
00121 CASE(SR300_AUTO_RANGE_MAX_LASER)
00122 CASE(SR300_AUTO_RANGE_START_LASER)
00123 CASE(SR300_AUTO_RANGE_UPPER_THRESHOLD)
00124 CASE(SR300_AUTO_RANGE_LOWER_THRESHOLD)
00125 CASE(R200_LR_AUTO_EXPOSURE_ENABLED)
00126 CASE(R200_LR_GAIN)
00127 CASE(R200_LR_EXPOSURE)
00128 CASE(R200_EMITTER_ENABLED)
00129 CASE(R200_DEPTH_UNITS)
00130 CASE(R200_DEPTH_CLAMP_MIN)
00131 CASE(R200_DEPTH_CLAMP_MAX)
00132 CASE(R200_DISPARITY_MULTIPLIER)
00133 CASE(R200_DISPARITY_SHIFT)
00134 CASE(R200_AUTO_EXPOSURE_MEAN_INTENSITY_SET_POINT)
00135 CASE(R200_AUTO_EXPOSURE_BRIGHT_RATIO_SET_POINT)
00136 CASE(R200_AUTO_EXPOSURE_KP_GAIN)
00137 CASE(R200_AUTO_EXPOSURE_KP_EXPOSURE)
00138 CASE(R200_AUTO_EXPOSURE_KP_DARK_THRESHOLD)
00139 CASE(R200_AUTO_EXPOSURE_TOP_EDGE)
00140 CASE(R200_AUTO_EXPOSURE_BOTTOM_EDGE)
00141 CASE(R200_AUTO_EXPOSURE_LEFT_EDGE)
00142 CASE(R200_AUTO_EXPOSURE_RIGHT_EDGE)
00143 CASE(R200_DEPTH_CONTROL_ESTIMATE_MEDIAN_DECREMENT)
00144 CASE(R200_DEPTH_CONTROL_ESTIMATE_MEDIAN_INCREMENT)
00145 CASE(R200_DEPTH_CONTROL_MEDIAN_THRESHOLD)
00146 CASE(R200_DEPTH_CONTROL_SCORE_MINIMUM_THRESHOLD)
00147 CASE(R200_DEPTH_CONTROL_SCORE_MAXIMUM_THRESHOLD)
00148 CASE(R200_DEPTH_CONTROL_TEXTURE_COUNT_THRESHOLD)
00149 CASE(R200_DEPTH_CONTROL_TEXTURE_DIFFERENCE_THRESHOLD)
00150 CASE(R200_DEPTH_CONTROL_SECOND_PEAK_THRESHOLD)
00151 CASE(R200_DEPTH_CONTROL_NEIGHBOR_THRESHOLD)
00152 CASE(R200_DEPTH_CONTROL_LR_THRESHOLD)
00153 CASE(FISHEYE_EXPOSURE)
00154 CASE(FISHEYE_GAIN)
00155 CASE(FISHEYE_STROBE)
00156 CASE(FISHEYE_EXTERNAL_TRIGGER)
00157 CASE(FRAMES_QUEUE_SIZE)
00158 CASE(TOTAL_FRAME_DROPS)
00159 CASE(FISHEYE_ENABLE_AUTO_EXPOSURE)
00160 CASE(FISHEYE_AUTO_EXPOSURE_MODE)
00161 CASE(FISHEYE_AUTO_EXPOSURE_ANTIFLICKER_RATE)
00162 CASE(FISHEYE_AUTO_EXPOSURE_PIXEL_SAMPLE_RATE)
00163 CASE(FISHEYE_AUTO_EXPOSURE_SKIP_FRAMES)
00164 CASE(HARDWARE_LOGGER_ENABLED)
00165 default: assert(!is_valid(value)); return unknown;
00166 }
00167 #undef CASE
00168 }
00169
00170 const char * get_string(rs_source value)
00171 {
00172 #define CASE(X) case RS_SOURCE_##X: return #X;
00173 switch(value)
00174 {
00175 CASE(VIDEO)
00176 CASE(MOTION_TRACKING)
00177 CASE(ALL)
00178 default: assert(!is_valid(value)); return unknown;
00179 }
00180 #undef CASE
00181 }
00182
00183 const char * get_string(rs_capabilities value)
00184 {
00185 #define CASE(X) case RS_CAPABILITIES_##X: return #X;
00186 switch(value)
00187 {
00188 CASE(DEPTH)
00189 CASE(COLOR)
00190 CASE(INFRARED)
00191 CASE(INFRARED2)
00192 CASE(FISH_EYE)
00193 CASE(MOTION_EVENTS)
00194 CASE(MOTION_MODULE_FW_UPDATE)
00195 CASE(ADAPTER_BOARD)
00196 CASE(ENUMERATION)
00197 default: assert(!is_valid(value)); return unknown;
00198 }
00199 #undef CASE
00200 }
00201
00202 const char * get_string(rs_event_source value)
00203 {
00204 #define CASE(X) case RS_EVENT_##X: return #X;
00205 switch(value)
00206 {
00207 CASE(IMU_ACCEL)
00208 CASE(IMU_GYRO)
00209 CASE(IMU_DEPTH_CAM)
00210 CASE(IMU_MOTION_CAM)
00211 CASE(G0_SYNC)
00212 CASE(G1_SYNC)
00213 CASE(G2_SYNC)
00214 default: assert(!is_valid(value)); return unknown;
00215 }
00216 #undef CASE
00217 }
00218
00219 const char * get_string(rs_blob_type value)
00220 {
00221 #define CASE(X) case RS_BLOB_TYPE_##X: return #X;
00222 switch(value)
00223 {
00224 CASE(MOTION_MODULE_FIRMWARE_UPDATE)
00225 default: assert(!is_valid(value)); return unknown;
00226 }
00227 #undef CASE
00228 }
00229
00230 const char * get_string(rs_camera_info value)
00231 {
00232 #define CASE(X) case RS_CAMERA_INFO_##X: return #X;
00233 switch(value)
00234 {
00235 CASE(DEVICE_NAME)
00236 CASE(DEVICE_SERIAL_NUMBER)
00237 CASE(CAMERA_FIRMWARE_VERSION)
00238 CASE(ADAPTER_BOARD_FIRMWARE_VERSION)
00239 CASE(MOTION_MODULE_FIRMWARE_VERSION)
00240 CASE(IMAGER_MODEL_NUMBER)
00241 CASE(CAMERA_TYPE)
00242 CASE(OEM_ID)
00243 CASE(MODULE_VERSION)
00244 CASE(BUILD_DATE)
00245 CASE(CALIBRATION_DATE)
00246 CASE(PROGRAM_DATE)
00247 CASE(FOCUS_ALIGNMENT_DATE)
00248 CASE(FOCUS_VALUE)
00249 CASE(CONTENT_VERSION)
00250 CASE(ISP_FW_VERSION)
00251 CASE(LENS_TYPE)
00252 CASE(LENS_COATING__TYPE)
00253 CASE(NOMINAL_BASELINE)
00254 CASE(3RD_LENS_TYPE)
00255 CASE(3RD_LENS_COATING_TYPE)
00256 CASE(3RD_NOMINAL_BASELINE)
00257 CASE(EMITTER_TYPE)
00258 default: assert(!is_valid(value)); return unknown;
00259 }
00260 #undef CASE
00261 }
00262
00263 const char * get_string(rs_frame_metadata value)
00264 {
00265 #define CASE(X) case RS_FRAME_METADATA_##X: return #X;
00266 switch (value)
00267 {
00268 CASE(ACTUAL_EXPOSURE)
00269 CASE(ACTUAL_FPS)
00270 default: assert(!is_valid(value)); return unknown;
00271 }
00272 #undef CASE
00273 }
00274
00275 const char * get_string(rs_timestamp_domain value)
00276 {
00277 #define CASE(X) case RS_TIMESTAMP_DOMAIN_##X: return #X;
00278 switch (value)
00279 {
00280 CASE(CAMERA)
00281 CASE(MICROCONTROLLER)
00282 default: assert(!is_valid(value)); return unknown;
00283 }
00284 #undef CASE
00285 }
00286
00287 size_t subdevice_mode_selection::get_image_size(rs_stream stream) const
00288 {
00289 return rsimpl::get_image_size(get_width(), get_height(), get_format(stream));
00290 }
00291
00292 void subdevice_mode_selection::set_output_buffer_format(const rs_output_buffer_format in_output_format)
00293 {
00294 output_format = in_output_format;
00295 }
00296
00297 void subdevice_mode_selection::unpack(byte * const dest[], const byte * source) const
00298 {
00299 const int MAX_OUTPUTS = 2;
00300 const auto & outputs = get_outputs();
00301 assert(outputs.size() <= MAX_OUTPUTS);
00302
00303
00304 const byte * in = source;
00305 size_t in_stride = mode.pf.get_image_size(mode.native_dims.x, 1);
00306 if(pad_crop < 0) in += in_stride * -pad_crop + mode.pf.get_image_size(-pad_crop, 1);
00307
00308
00309 byte * out[MAX_OUTPUTS];
00310 size_t out_stride[MAX_OUTPUTS] = { 0 };
00311 for(size_t i=0; i<outputs.size(); ++i)
00312 {
00313 out[i] = dest[i];
00314 out_stride[i] = rsimpl::get_image_size(get_width(), 1, outputs[i].second);
00315 if(pad_crop > 0) out[i] += out_stride[i] * pad_crop + rsimpl::get_image_size(pad_crop, 1, outputs[i].second);
00316 }
00317
00318
00319 const int unpack_width = get_unpacked_width(), unpack_height = get_unpacked_height();
00320 if(mode.native_dims.x == get_width())
00321 {
00322
00323 mode.pf.unpackers[unpacker_index].unpack(out, in, unpack_width * unpack_height);
00324 }
00325 else
00326 {
00327
00328
00329 assert(mode.pf.plane_count == 1);
00330 for(int i=0; i<unpack_height; ++i)
00331 {
00332 mode.pf.unpackers[unpacker_index].unpack(out, in, unpack_width);
00333 for(size_t i=0; i<outputs.size(); ++i) out[i] += out_stride[i];
00334 in += in_stride;
00335 }
00336 }
00337 }
00338
00339 int subdevice_mode_selection::get_unpacked_width() const
00340 {
00341 return std::min(mode.native_intrinsics.width, get_width());
00342 }
00343
00344 int subdevice_mode_selection::get_unpacked_height() const
00345 {
00346 return std::min(mode.native_intrinsics.height, get_height());
00347 }
00348
00350
00352
00353 bool stream_request::contradict(stream_request req) const
00354 {
00355 if (((format != RS_FORMAT_ANY && format != req.format) ||
00356 (width != 0 && width != req.width) ||
00357 (height != 0 && height != req.height) ||
00358 (fps != 0 && fps != req.fps) ||
00359 (output_format != req.output_format)))
00360 return true;
00361 return false;
00362 }
00363
00364 bool stream_request::is_filled() const
00365 {
00366 return width != 0 && height != 0 && format != RS_FORMAT_ANY && fps != 0;
00367 }
00368
00369 static_device_info::static_device_info() : num_libuvc_transfer_buffers(1), nominal_depth_scale(0.001f)
00370 {
00371 for(auto & s : stream_subdevices) s = -1;
00372 for(auto & s : data_subdevices) s = -1;
00373 for(auto & s : presets) for(auto & p : s) p = stream_request();
00374 for(auto & p : stream_poses)
00375 {
00376 p = {{{1,0,0},{0,1,0},{0,0,1}}, {0,0,0}};
00377 }
00378 }
00379
00380
00381
00382 struct search_request_params
00383 {
00384 stream_request requests[RS_STREAM_NATIVE_COUNT];
00385 int stream;
00386 search_request_params(stream_request in_requests[RS_STREAM_NATIVE_COUNT], int i)
00387 : stream(i)
00388 {
00389 for (auto i = 0; i<RS_STREAM_NATIVE_COUNT; i++)
00390 {
00391 requests[i] = in_requests[i];
00392 }
00393 }
00394 };
00395
00396 bool device_config::all_requests_filled(const stream_request(&requests)[RS_STREAM_NATIVE_COUNT]) const
00397 {
00398 for (auto i = 0; i<RS_STREAM_NATIVE_COUNT; i++)
00399 {
00400 if (requests[i].enabled &&
00401 (requests[i].height == 0 ||
00402 requests[i].width == 0 ||
00403 requests[i].format == RS_FORMAT_ANY ||
00404 requests[i].fps == 0))
00405 return false;
00406 }
00407 return true;
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 bool device_config::find_good_requests_combination( stream_request(&requests)[RS_STREAM_NATIVE_COUNT], std::vector<stream_request> stream_requests[RS_STREAM_NATIVE_COUNT]) const
00421 {
00422 std::deque<search_request_params> calls;
00423
00424
00425
00426 search_request_params p = { requests, 0 };
00427 calls.push_back(p);
00428
00429 while (!calls.empty())
00430 {
00431
00432 p = calls.front();
00433 calls.pop_front();
00434
00435
00436 if (all_requests_filled(p.requests) && validate_requests(p.requests))
00437 {
00438 for (auto i = 0; i < RS_STREAM_NATIVE_COUNT; i++)
00439 {
00440 requests[i] = p.requests[i];
00441 }
00442 return true;
00443 }
00444
00445
00446 if (!requests[p.stream].enabled || requests[p.stream].is_filled())
00447 {
00448
00449 search_request_params new_p = { p.requests, p.stream + 1 };
00450 calls.push_back(new_p);
00451 continue;
00452 }
00453
00454
00455 for (size_t i = 0; i < stream_requests[p.stream].size(); i++)
00456 {
00457
00458
00459 if (!requests[p.stream].contradict(stream_requests[p.stream][i]))
00460 {
00461
00462 p.requests[p.stream] = stream_requests[p.stream][i];
00463
00464
00465
00466 if (validate_requests(p.requests))
00467 {
00468
00469 search_request_params new_p = { p.requests, p.stream + 1 };
00470 calls.push_back(new_p);
00471 }
00472 }
00473 }
00474
00475 }
00476
00477 return false;
00478 }
00479
00480 bool device_config::fill_requests(stream_request(&requests)[RS_STREAM_NATIVE_COUNT]) const
00481 {
00482
00483 if(all_requests_filled(requests))
00484 {
00485 return true;
00486 }
00487
00488
00489
00490 std::vector<stream_request> stream_requests[RS_STREAM_NATIVE_COUNT];
00491
00492 get_all_possible_requestes(stream_requests);
00493
00494
00495 return find_good_requests_combination(requests, stream_requests);
00496 }
00497
00498 void device_config::get_all_possible_requestes(std::vector<stream_request>(&stream_requests)[RS_STREAM_NATIVE_COUNT]) const
00499 {
00500 for (size_t i = 0; i < info.subdevice_modes.size(); i++)
00501 {
00502 stream_request request;
00503 auto mode = info.subdevice_modes[i];
00504
00505 for (auto pad_crop : mode.pad_crop_options)
00506 {
00507 for (auto & unpacker : mode.pf.unpackers)
00508 {
00509 auto selection = subdevice_mode_selection(mode, pad_crop, int(&unpacker - mode.pf.unpackers.data()));
00510
00511 request.enabled = true;
00512 request.fps = selection.get_framerate();
00513 request.height = selection.get_height();
00514 request.width = selection.get_width();
00515 auto outputs = selection.get_outputs();
00516
00517 for (auto output : outputs)
00518 {
00519 request.format = output.second;
00520 for (auto output_format = static_cast<int>(RS_OUTPUT_BUFFER_FORMAT_CONTINUOUS); output_format < static_cast<int>(RS_OUTPUT_BUFFER_FORMAT_COUNT); output_format++)
00521 {
00522 request.output_format = static_cast<rs_output_buffer_format>(output_format);
00523 stream_requests[output.first].push_back(request);
00524 }
00525 }
00526 }
00527 }
00528 }
00529 }
00530
00531 subdevice_mode_selection device_config::select_mode(const stream_request(&requests)[RS_STREAM_NATIVE_COUNT], int subdevice_index) const
00532 {
00533
00534 auto any_stream_requested = false;
00535 std::array<bool, RS_STREAM_NATIVE_COUNT> stream_requested = {};
00536 for(int j = 0; j < RS_STREAM_NATIVE_COUNT; ++j)
00537 {
00538 if(requests[j].enabled && info.stream_subdevices[j] == subdevice_index)
00539 {
00540 stream_requested[j] = true;
00541 any_stream_requested = true;
00542 }
00543 }
00544
00545
00546 if(!any_stream_requested) return subdevice_mode_selection();
00547
00548
00549 for(auto & subdevice_mode : info.subdevice_modes)
00550 {
00551
00552 if(subdevice_mode.subdevice != subdevice_index) continue;
00553
00554
00555 for(auto pad_crop : subdevice_mode.pad_crop_options)
00556 {
00557 for(auto & unpacker : subdevice_mode.pf.unpackers)
00558 {
00559 auto selection = subdevice_mode_selection(subdevice_mode, pad_crop, (int)(&unpacker - subdevice_mode.pf.unpackers.data()));
00560
00561
00562 auto stream_unsatisfied = stream_requested;
00563 for(auto & output : unpacker.outputs)
00564 {
00565 const auto & req = requests[output.first];
00566
00567 selection.set_output_buffer_format(req.output_format);
00568 if(req.enabled && (req.width == selection.get_width() )
00569 && (req.height == selection.get_height())
00570 && (req.format == selection.get_format(output.first))
00571 && (req.fps == subdevice_mode.fps))
00572 {
00573 stream_unsatisfied[output.first] = false;
00574 }
00575 }
00576
00577
00578 if(std::any_of(begin(stream_unsatisfied), end(stream_unsatisfied), [](bool b) { return b; })) continue;
00579 return selection;
00580 }
00581 }
00582 }
00583
00584
00585 std::ostringstream ss;
00586 ss << "uvc subdevice " << subdevice_index << " cannot provide";
00587 bool first = true;
00588 for(int j = 0; j < RS_STREAM_NATIVE_COUNT; ++j)
00589 {
00590 if(!stream_requested[j]) continue;
00591 ss << (first ? " " : " and ");
00592 ss << requests[j].width << 'x' << requests[j].height << ':' << get_string(requests[j].format);
00593 ss << '@' << requests[j].fps << "Hz " << get_string((rs_stream)j);
00594 first = false;
00595 }
00596 throw std::runtime_error(ss.str());
00597 }
00598
00599 std::vector<subdevice_mode_selection> device_config::select_modes(const stream_request (&reqs)[RS_STREAM_NATIVE_COUNT]) const
00600 {
00601
00602 stream_request requests[RS_STREAM_NATIVE_COUNT];
00603 for (int i = 0; i<RS_STREAM_NATIVE_COUNT; ++i) requests[i] = reqs[i];
00604
00605
00606 validate_requests(requests, true);
00607
00608
00609 fill_requests(requests);
00610
00611
00612 int num_subdevices = 0;
00613 for(auto & mode : info.subdevice_modes) num_subdevices = std::max(num_subdevices, mode.subdevice+1);
00614 std::vector<subdevice_mode_selection> selected_modes;
00615 for(int i = 0; i < num_subdevices; ++i)
00616 {
00617 auto selection = select_mode(requests, i);
00618 if(selection.mode.pf.fourcc) selected_modes.push_back(selection);
00619 }
00620 return selected_modes;
00621 }
00622
00623 bool device_config::validate_requests(stream_request(&requests)[RS_STREAM_NATIVE_COUNT], bool throw_exception) const
00624 {
00625
00626
00627 for (auto & rule : info.interstream_rules)
00628 {
00629 auto & a = requests[rule.a], &b = requests[rule.b]; auto f = rule.field;
00630 if (a.enabled && b.enabled)
00631 {
00632 bool compat = true;
00633 std::stringstream error_message;
00634
00635 if (rule.same_format)
00636 {
00637 if ((a.format != RS_FORMAT_ANY) && (b.format != RS_FORMAT_ANY) && (a.format != b.format))
00638 {
00639 if (throw_exception) error_message << rule.a << " format (" << rs_format_to_string(a.format) << ") must be equal to " << rule.b << " format (" << rs_format_to_string(b.format) << ")!";
00640 compat = false;
00641 }
00642 }
00643 else if((a.*f != 0) && (b.*f != 0))
00644 {
00645 if ((rule.bigger == RS_STREAM_COUNT) && (!rule.divides && !rule.divides2))
00646 {
00647
00648 if ((a.*f + rule.delta != b.*f) && (a.*f + rule.delta2 != b.*f))
00649 {
00650 if (throw_exception) error_message << " " << rule.b << " value " << b.*f << " must be equal to either " << (a.*f + rule.delta) << " or " << (a.*f + rule.delta2) << "!";
00651 compat = false;
00652 }
00653 }
00654 else
00655 {
00656 if (((rule.bigger == rule.a) && (a.*f < b.*f)) || ((rule.bigger == rule.b) && (b.*f < a.*f)))
00657 {
00658 if (throw_exception) error_message << " " << rule.a << " value " << a.*f << " must be " << ((rule.bigger == rule.a) ? "bigger" : "smaller") << " then " << rule.b << " value " << b.*f << "!";
00659 compat = false;
00660 }
00661 if ((rule.divides && (a.*f % b.*f)) || (rule.divides2 && (b.*f % a.*f)))
00662 {
00663 if (throw_exception) error_message << " " << rule.a << " value " << a.*f << " must " << (rule.divides ? "be divided by" : "divide") << rule.b << " value " << b.*f << "!";
00664 compat = false;
00665 }
00666 }
00667 }
00668 if (!compat)
00669 {
00670 if (throw_exception)
00671 throw std::runtime_error(to_string() << "requested settings for " << rule.a << " and " << rule.b << " are incompatible!" << error_message.str());
00672 return false;
00673 }
00674 }
00675 }
00676 return true;
00677 }
00678
00679 std::string firmware_version::to_string() const
00680 {
00681 if (is_any) return "any";
00682
00683 std::stringstream s;
00684 s << std::setfill('0') << std::setw(2) << m_major << "."
00685 << std::setfill('0') << std::setw(2) << m_minor << "."
00686 << std::setfill('0') << std::setw(2) << m_patch << "."
00687 << std::setfill('0') << std::setw(2) << m_build;
00688 return s.str();
00689 }
00690
00691 std::vector<std::string> firmware_version::split(const std::string& str)
00692 {
00693 std::vector<std::string> result;
00694 auto e = str.end();
00695 auto i = str.begin();
00696 while (i != e){
00697 i = find_if_not(i, e, [](char c) { return c == '.'; });
00698 if (i == e) break;
00699 auto j = find(i, e, '.');
00700 result.emplace_back(i, j);
00701 i = j;
00702 }
00703 return result;
00704 }
00705
00706 int firmware_version::parse_part(const std::string& name, int part)
00707 {
00708 return atoi(split(name)[part].c_str());
00709 }
00710
00711 calibration_validator::calibration_validator(std::function<bool(rs_stream, rs_stream)> extrinsic_validator, std::function<bool(rs_stream)> intrinsic_validator)
00712 : extrinsic_validator(extrinsic_validator), intrinsic_validator(intrinsic_validator)
00713 {
00714 }
00715
00716 calibration_validator::calibration_validator()
00717 : extrinsic_validator([](rs_stream, rs_stream) { return true; }), intrinsic_validator([](rs_stream) { return true; })
00718 {
00719 }
00720
00721 bool calibration_validator::validate_extrinsics(rs_stream from_stream, rs_stream to_stream) const
00722 {
00723 return extrinsic_validator(from_stream, to_stream);
00724 }
00725 bool calibration_validator::validate_intrinsics(rs_stream stream) const
00726 {
00727 return intrinsic_validator(stream);
00728 }
00729
00730 }