The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

xrt: Make stereo_camera_calibration refcounted

This allows the data to be safely shared and passed around, even allowing us
to tag frames with the data and passed around that way instead.

Since it now can be passed around more safely make the prober call the save
function instead of the calibration code. This then forms a basis for further
work where we can hook this up into a more proper configuration file.

+167 -60
+1
src/xrt/auxiliary/CMakeLists.txt
··· 34 34 endif() 35 35 36 36 set(TRACKING_SOURCE_FILES 37 + tracking/t_data_utils.c 37 38 tracking/t_imu_fusion.hpp 38 39 tracking/t_imu.cpp 39 40 tracking/t_imu.h
+1
src/xrt/auxiliary/meson.build
··· 111 111 ) 112 112 113 113 tracking_srcs = [ 114 + 'tracking/t_data_utils.c', 114 115 'tracking/t_imu.h', 115 116 'tracking/t_imu_fusion.hpp', 116 117 'tracking/t_imu.cpp',
+6 -5
src/xrt/auxiliary/tracking/t_calibration.cpp
··· 535 535 536 536 cv::Size image_size(cols, rows); 537 537 cv::Size new_image_size(cols, rows); 538 - t_stereo_camera_calibration &data = 539 - *U_TYPED_CALLOC(t_stereo_camera_calibration); 540 - StereoCameraCalibrationWrapper wrapped(data); 541 538 539 + StereoCameraCalibrationWrapper wrapped = {}; 542 540 wrapped.view[0].image_size_pixels.w = image_size.width; 543 541 wrapped.view[0].image_size_pixels.h = image_size.height; 544 542 wrapped.view[1].image_size_pixels = wrapped.view[0].image_size_pixels; ··· 591 589 P("CALIBRATION DONE RP ERROR %f", rp_error); 592 590 593 591 // Preview undistortion/rectification. 594 - StereoRectificationMaps maps(data); 592 + StereoRectificationMaps maps(wrapped.base); 595 593 c.state.view[0].map1 = maps.view[0].rectify.remap_x; 596 594 c.state.view[0].map2 = maps.view[0].rectify.remap_y; 597 595 c.state.view[0].maps_valid = true; ··· 633 631 // Validate that nothing has been re-allocated. 634 632 assert(wrapped.isDataStorageValid()); 635 633 636 - t_file_save_raw_data_hack(&data); 634 + if (c.status != NULL) { 635 + t_stereo_camera_calibration_reference(&c.status->stereo_data, 636 + wrapped.base); 637 + } 637 638 } 638 639 639 640 static void
+42 -20
src/xrt/auxiliary/tracking/t_calibration_opencv.hpp
··· 22 22 23 23 24 24 /*! 25 - * Save raw calibration data to file, hack until prober has storage for such 26 - * things. 27 - */ 28 - extern "C" bool 29 - t_file_save_raw_data_hack(struct t_stereo_camera_calibration *data); 30 - 31 - /*! 32 25 * @brief Essential calibration data wrapped for C++. 33 26 * 34 27 * Just like the cv::Mat that it holds, this object does not own all the memory ··· 80 73 */ 81 74 struct StereoCameraCalibrationWrapper 82 75 { 83 - t_stereo_camera_calibration &base; 76 + t_stereo_camera_calibration *base; 84 77 CameraCalibrationWrapper view[2]; 85 78 cv::Mat_<double> camera_translation_mat; 86 79 cv::Mat_<double> camera_rotation_mat; 87 80 cv::Mat_<double> camera_essential_mat; 88 81 cv::Mat_<double> camera_fundamental_mat; 89 82 90 - StereoCameraCalibrationWrapper(t_stereo_camera_calibration &stereo) 91 - : base(stereo), view{CameraCalibrationWrapper{stereo.view[0]}, 92 - CameraCalibrationWrapper{stereo.view[1]}}, 93 - camera_translation_mat(3, 1, &stereo.camera_translation[0]), 94 - camera_rotation_mat(3, 3, &stereo.camera_rotation[0][0]), 95 - camera_essential_mat(3, 3, &stereo.camera_essential[0][0]), 96 - camera_fundamental_mat(3, 3, &stereo.camera_fundamental[0][0]) 83 + 84 + static t_stereo_camera_calibration * 85 + allocData() 97 86 { 87 + t_stereo_camera_calibration *data_ptr = NULL; 88 + t_stereo_camera_calibration_alloc(&data_ptr); 89 + return data_ptr; 90 + } 91 + 92 + StereoCameraCalibrationWrapper(t_stereo_camera_calibration *stereo) 93 + : base(stereo), view{CameraCalibrationWrapper{stereo->view[0]}, 94 + CameraCalibrationWrapper{stereo->view[1]}}, 95 + camera_translation_mat(3, 1, &stereo->camera_translation[0]), 96 + camera_rotation_mat(3, 3, &stereo->camera_rotation[0][0]), 97 + camera_essential_mat(3, 3, &stereo->camera_essential[0][0]), 98 + camera_fundamental_mat(3, 3, &stereo->camera_fundamental[0][0]) 99 + { 100 + // Correct reference counting. 101 + t_stereo_camera_calibration *temp = NULL; 102 + t_stereo_camera_calibration_reference(&temp, stereo); 103 + 98 104 assert(isDataStorageValid()); 99 105 } 100 106 107 + StereoCameraCalibrationWrapper() 108 + : StereoCameraCalibrationWrapper(allocData()) 109 + { 110 + 111 + // The function allocData returns with a ref count of one, 112 + // the constructor increments the refcount with one, 113 + // so to correct it we need to decrement the ref count with one. 114 + t_stereo_camera_calibration *tmp = base; 115 + t_stereo_camera_calibration_reference(&tmp, NULL); 116 + } 117 + 118 + ~StereoCameraCalibrationWrapper() 119 + { 120 + t_stereo_camera_calibration_reference(&base, NULL); 121 + } 122 + 101 123 bool 102 124 isDataStorageValid() const noexcept 103 125 { 104 126 return camera_translation_mat.size() == cv::Size(1, 3) && 105 127 (double *)camera_translation_mat.data == 106 - &base.camera_translation[0] && 128 + &base->camera_translation[0] && 107 129 108 130 camera_rotation_mat.size() == cv::Size(3, 3) && 109 131 (double *)camera_rotation_mat.data == 110 - &base.camera_rotation[0][0] && 132 + &base->camera_rotation[0][0] && 111 133 112 134 camera_essential_mat.size() == cv::Size(3, 3) && 113 135 (double *)camera_essential_mat.data == 114 - &base.camera_essential[0][0] && 136 + &base->camera_essential[0][0] && 115 137 116 138 camera_fundamental_mat.size() == cv::Size(3, 3) && 117 139 (double *)camera_fundamental_mat.data == 118 - &base.camera_fundamental[0][0] && 140 + &base->camera_fundamental[0][0] && 119 141 120 142 view[0].isDataStorageValid() && 121 143 view[1].isDataStorageValid(); ··· 179 201 * @brief Constructor - produces rectification data for a stereo camera 180 202 * based on calibration data. 181 203 */ 182 - StereoRectificationMaps(t_stereo_camera_calibration &data); 204 + StereoRectificationMaps(t_stereo_camera_calibration *data); 183 205 };
+28
src/xrt/auxiliary/tracking/t_data_utils.c
··· 1 + // Copyright 2019-2020, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Small data helpers for calibration. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @ingroup aux_tracking 8 + */ 9 + 10 + #include "tracking/t_tracking.h" 11 + #include "util/u_misc.h" 12 + 13 + #include <stdio.h> 14 + 15 + 16 + void 17 + t_stereo_camera_calibration_alloc(struct t_stereo_camera_calibration **out_c) 18 + { 19 + struct t_stereo_camera_calibration *c = 20 + U_TYPED_CALLOC(struct t_stereo_camera_calibration); 21 + t_stereo_camera_calibration_reference(out_c, c); 22 + } 23 + 24 + void 25 + t_stereo_camera_calibration_destroy(struct t_stereo_camera_calibration *c) 26 + { 27 + free(c); 28 + }
+19 -30
src/xrt/auxiliary/tracking/t_file.cpp
··· 31 31 32 32 /* 33 33 * 34 - * Free functions. 35 - * 36 - */ 37 - 38 - extern "C" void 39 - t_stereo_camera_calibration_free(struct t_stereo_camera_calibration **data_ptr) 40 - { 41 - free(*data_ptr); 42 - *data_ptr = NULL; 43 - } 44 - 45 - 46 - /* 47 - * 48 34 * Refine and create functions. 49 35 * 50 36 */ ··· 91 77 } 92 78 93 79 StereoRectificationMaps::StereoRectificationMaps( 94 - t_stereo_camera_calibration &data) 80 + t_stereo_camera_calibration *data) 95 81 { 96 - assert(data.view[0].image_size_pixels.w == 97 - data.view[1].image_size_pixels.w); 98 - assert(data.view[0].image_size_pixels.h == 99 - data.view[1].image_size_pixels.h); 82 + assert(data != NULL); 83 + assert(data->view[0].image_size_pixels.w == 84 + data->view[1].image_size_pixels.w); 85 + assert(data->view[0].image_size_pixels.h == 86 + data->view[1].image_size_pixels.h); 100 87 101 - assert(data.view[0].use_fisheye == data.view[1].use_fisheye); 88 + assert(data->view[0].use_fisheye == data->view[1].use_fisheye); 102 89 103 - cv::Size image_size(data.view[0].image_size_pixels.w, 104 - data.view[0].image_size_pixels.h); 90 + cv::Size image_size(data->view[0].image_size_pixels.w, 91 + data->view[0].image_size_pixels.h); 105 92 StereoCameraCalibrationWrapper wrapped(data); 106 93 107 94 /* ··· 109 96 * 110 97 * Here cv::noArray() means zero distortion. 111 98 */ 112 - if (data.view[0].use_fisheye) { 99 + if (data->view[0].use_fisheye) { 113 100 #if 0 114 101 //! @todo for some reason this looks weird? 115 102 // Alpha of 1.0 kinda works, not really. ··· 188 175 } 189 176 190 177 view[0].rectify = calibration_get_undistort_map( 191 - data.view[0], view[0].rotation_mat, view[0].projection_mat); 178 + data->view[0], view[0].rotation_mat, view[0].projection_mat); 192 179 view[1].rectify = calibration_get_undistort_map( 193 - data.view[1], view[1].rotation_mat, view[1].projection_mat); 180 + data->view[1], view[1].rotation_mat, view[1].projection_mat); 194 181 } 195 182 196 183 /* ··· 203 190 t_stereo_camera_calibration_load_v1( 204 191 FILE *calib_file, struct t_stereo_camera_calibration **out_data) 205 192 { 206 - t_stereo_camera_calibration &raw = 207 - *U_TYPED_CALLOC(t_stereo_camera_calibration); 208 - StereoCameraCalibrationWrapper wrapped(raw); 193 + t_stereo_camera_calibration *data_ptr = NULL; 194 + t_stereo_camera_calibration_alloc(&data_ptr); 195 + StereoCameraCalibrationWrapper wrapped(data_ptr); 209 196 210 197 // Dummy matrix 211 198 cv::Mat dummy; ··· 266 253 267 254 268 255 assert(wrapped.isDataStorageValid()); 269 - *out_data = &raw; 256 + 257 + t_stereo_camera_calibration_reference(out_data, data_ptr); 258 + t_stereo_camera_calibration_reference(&data_ptr, NULL); 270 259 271 260 return true; 272 261 } ··· 281 270 extern "C" bool 282 271 t_file_save_raw_data(FILE *calib_file, struct t_stereo_camera_calibration *data) 283 272 { 284 - StereoCameraCalibrationWrapper wrapped(*data); 273 + StereoCameraCalibrationWrapper wrapped(data); 285 274 // Dummy matrix 286 275 cv::Mat dummy; 287 276
+1 -2
src/xrt/auxiliary/tracking/t_tracker_psmv.cpp
··· 563 563 break; 564 564 } 565 565 566 - StereoCameraCalibrationWrapper wrapped(*data); 567 - StereoRectificationMaps rectify(*data); 566 + StereoRectificationMaps rectify(data); 568 567 t.view[0].populate_from_calib(data->view[0], rectify.view[0].rectify); 569 568 t.view[1].populate_from_calib(data->view[1], rectify.view[1].rectify); 570 569 t.disparity_to_depth = rectify.disparity_to_depth_mat;
+53 -2
src/xrt/auxiliary/tracking/t_tracking.h
··· 12 12 #pragma once 13 13 14 14 #include "xrt/xrt_frame.h" 15 + #include "util/u_misc.h" 15 16 16 17 #include <stdio.h> 17 18 ··· 103 104 //! Is the camera fisheye? 104 105 bool use_fisheye; 105 106 }; 107 + 106 108 /*! 107 109 * Stereo camera calibration data to be given to trackers. 108 110 */ 109 111 struct t_stereo_camera_calibration 110 112 { 113 + //! Ref counting 114 + struct xrt_reference reference; 115 + 111 116 //! Calibration of individual views/sensor 112 117 struct t_camera_calibration view[2]; 113 118 ··· 125 130 double camera_fundamental[3][3]; 126 131 }; 127 132 133 + /*! 134 + * Allocates a new stereo calibration data, unreferences the old @p calib. 135 + */ 136 + void 137 + t_stereo_camera_calibration_alloc(struct t_stereo_camera_calibration **calib); 128 138 129 139 /*! 130 - * Free stereo calibration data. 140 + * Only to be called by @ref t_stereo_camera_calibration_reference. 131 141 */ 132 142 void 133 - t_stereo_camera_calibration_free(struct t_stereo_camera_calibration **data_ptr); 143 + t_stereo_camera_calibration_destroy(struct t_stereo_camera_calibration *c); 144 + 145 + /*! 146 + * Update the reference counts on a stereo calibration data(s). 147 + * 148 + * @param dst Pointer to a object reference, if the object reference is 149 + * non-null will decrement it's counter. The reference that 150 + * @p dst points to will be set to @p src. 151 + * @param[in] src Object to be have it's refcount increased @p dst is set to 152 + * this. 153 + */ 154 + static inline void 155 + t_stereo_camera_calibration_reference(struct t_stereo_camera_calibration **dst, 156 + struct t_stereo_camera_calibration *src) 157 + { 158 + struct t_stereo_camera_calibration *old_dst = *dst; 159 + 160 + if (old_dst == src) { 161 + return; 162 + } 163 + 164 + if (src) { 165 + xrt_reference_inc(&src->reference); 166 + } 167 + 168 + *dst = src; 169 + 170 + if (old_dst) { 171 + if (xrt_reference_dec(&old_dst->reference)) { 172 + t_stereo_camera_calibration_destroy(old_dst); 173 + } 174 + } 175 + } 134 176 135 177 /*! 136 178 * Load stereo calibration data from a given file. ··· 145 187 bool 146 188 t_stereo_camera_calibration_load_v1_hack( 147 189 struct t_stereo_camera_calibration **out_data); 190 + 191 + /*! 192 + * Save raw calibration data to file, hack until prober has storage for such 193 + * things. 194 + */ 195 + bool 196 + t_file_save_raw_data_hack(struct t_stereo_camera_calibration *data); 148 197 149 198 150 199 /* ··· 321 370 int cooldown; 322 371 //! Number of non-moving frames before capture. 323 372 int waits_remaining; 373 + //! Stereo calibration data that was produced. 374 + struct t_stereo_camera_calibration *stereo_data; 324 375 }; 325 376 326 377 struct t_calibration_params
+15
src/xrt/state_trackers/gui/gui_scene_calibrate.c
··· 58 58 */ 59 59 60 60 static void 61 + save_calibration(struct calibration_scene *cs) 62 + { 63 + if (cs->status.stereo_data == NULL) { 64 + return; 65 + } 66 + 67 + // Save the data. 68 + t_file_save_raw_data_hack(cs->status.stereo_data); 69 + 70 + // Free data, no longer needed. 71 + t_stereo_camera_calibration_reference(&cs->status.stereo_data, NULL); 72 + } 73 + 74 + static void 61 75 draw_texture(struct gui_ogl_texture *tex, bool header) 62 76 { 63 77 if (tex == NULL) { ··· 95 109 96 110 igText( 97 111 "Calibration complete - showing preview of undistortion."); 112 + save_calibration(cs); 98 113 return; 99 114 } 100 115
+1 -1
src/xrt/state_trackers/prober/p_tracking.c
··· 286 286 * 287 287 * Does null checking and sets to null. 288 288 */ 289 - t_stereo_camera_calibration_free(&fact->data); 289 + t_stereo_camera_calibration_reference(&fact->data, NULL); 290 290 #endif 291 291 292 292 free(fact);