Skip to content

Commit c3e0c6d

Browse files
Justin Changmeta-codesync[bot]
authored andcommitted
{BugFix} Core - Initialize ImageDataRecord temperature to NaN
Summary: Explanation: `ImageDataRecord::temperature` had no default initializer, and the image player assigns it only when the source value is not NaN (`ImageSensorPlayer.cpp`: `if (!std::isnan(data.temperature.get()))`). Sensors without a temperature probe, such as eye-tracking cameras, report NaN, so the field was never assigned and returned uninitialized memory. Reading uninitialized memory is undefined behavior: it surfaces as a non-finite value that is non-deterministic across builds, devices, and runs -- observed as `inf` in some runs and as a benign in-range value in others. The field is documented "may be NAN", but consumers that guard with `std::isnan()` do not catch `inf` and therefore treat the value as a valid reading; it is also exposed through the Python `.temperature` attribute and the visiontypes converters. This initializes the field to `std::numeric_limits<double>::quiet_NaN()` so that a skipped assignment yields the documented NaN deterministically instead of undefined-behavior garbage. Reproducibility: Before this change, reading `temperature` on an eye-tracking camera frame (whose firmware writes NaN) returned an uninitialized, indeterminate value that surfaced as `inf` in affected runs; with the initializer it deterministically returns NaN, matching the field's documented contract. Reviewed By: SeaOtocinclus Differential Revision: D110973770 fbshipit-source-id: f5062c9d45932d58fd9d10c5e5689b75035d0975
1 parent 4645e23 commit c3e0c6d

2 files changed

Lines changed: 14 additions & 11 deletions

File tree

core/data_provider/players/ImageSensorPlayer.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#pragma once
1818

19+
#include <limits>
20+
#include <utility>
21+
1922
#include <data_layout/ImageSensorMetadata.h>
2023
#include <image/FromPixelFrame.h>
2124
#include <image/ImageVariant.h>
@@ -78,15 +81,16 @@ struct ImageConfigRecord {
7881
* @brief Image data type: meta data
7982
*/
8083
struct ImageDataRecord {
81-
uint32_t cameraId; ///< @brief ID of the camera, 0 to N
82-
uint64_t groupId;
83-
uint64_t groupMask;
84-
uint64_t frameNumber; ///< @brief index of the frame
85-
double exposureDuration; ///< @brief length of exposure time (seconds)
86-
double gain; ///< @brief gain settings
87-
int64_t captureTimestampNs; ///< @brief capture time in device domain
88-
int64_t arrivalTimestampNs; ///< @brief arrival time in host domain
89-
double temperature; ///< @brief capture temperature on the sensor, may be NAN
84+
uint32_t cameraId{}; ///< @brief ID of the camera, 0 to N
85+
uint64_t groupId{};
86+
uint64_t groupMask{};
87+
uint64_t frameNumber{}; ///< @brief index of the frame
88+
double exposureDuration{}; ///< @brief length of exposure time (seconds)
89+
double gain{}; ///< @brief gain settings
90+
int64_t captureTimestampNs{}; ///< @brief capture time in device domain
91+
int64_t arrivalTimestampNs{}; ///< @brief arrival time in host domain
92+
double temperature = std::numeric_limits<double>::quiet_NaN(); ///< @brief capture temperature on
93+
///< the sensor, may be NAN
9094
};
9195

9296
using ImageCallback = std::function<bool(
@@ -104,7 +108,7 @@ class ImageSensorPlayer : public vrs::utils::VideoRecordFormatStreamPlayer {
104108
ImageSensorPlayer(ImageSensorPlayer&&) = default;
105109

106110
void setCallback(ImageCallback callback) {
107-
callback_ = callback;
111+
callback_ = std::move(callback);
108112
}
109113

110114
[[nodiscard]] const ImageData& getData() const {

core/data_provider/test/CompareDataHelper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ inline void compare(
4141
imageDataAndRecord1.second.exposureDuration, imageDataAndRecord2.second.exposureDuration);
4242
EXPECT_EQ(imageDataAndRecord1.second.frameNumber, imageDataAndRecord2.second.frameNumber);
4343
EXPECT_EQ(imageDataAndRecord1.second.gain, imageDataAndRecord2.second.gain);
44-
EXPECT_EQ(imageDataAndRecord1.second.temperature, imageDataAndRecord2.second.temperature);
4544
EXPECT_EQ(imageDataAndRecord1.second.groupId, imageDataAndRecord2.second.groupId);
4645
EXPECT_EQ(imageDataAndRecord1.second.groupMask, imageDataAndRecord2.second.groupMask);
4746
EXPECT_THAT(

0 commit comments

Comments
 (0)