Do SIFT and send out the results
Don't yet have the math for calculating poses based on these results.
Change-Id: I6494dbf1d3a7c13db902cf00b7c362a2a956691b
diff --git a/y2020/vision/v4l2_reader.h b/y2020/vision/v4l2_reader.h
index bdf4a8e..3c9d795 100644
--- a/y2020/vision/v4l2_reader.h
+++ b/y2020/vision/v4l2_reader.h
@@ -25,10 +25,10 @@
// Reads the latest image.
//
- // Returns an empty span if no image was available since this object was
- // created. The data referenced in the return value is valid until this method
- // is called again.
- absl::Span<const char> ReadLatestImage();
+ // Returns false if no image was available since the last image was read.
+ // Call LatestImage() to get a reference to the data, which will be valid
+ // until this method is called again.
+ bool ReadLatestImage();
// Sends the latest image.
//
@@ -37,52 +37,58 @@
// ReadLatestImage() will no longer be valid.
void SendLatestImage();
+ const CameraImage &LatestImage() {
+ Buffer *const buffer = &buffers_[saved_buffer_.index];
+ return *flatbuffers::GetTemporaryPointer(*buffer->builder.fbb(),
+ buffer->message_offset);
+ }
+
private:
static constexpr int kNumberBuffers = 16;
struct Buffer {
- void InitializeMessage(size_t max_image_size) {
- builder = aos::Sender<CameraImage>::Builder();
- builder = sender.MakeBuilder();
- // The kernel has an undocumented requirement that the buffer is aligned
- // to 64 bytes. If you give it a nonaligned pointer, it will return EINVAL
- // and only print something in dmesg with the relevant dynamic debug
- // prints turned on.
- builder.fbb()->StartIndeterminateVector(max_image_size, 1, 64,
- &data_pointer);
- CHECK_EQ(reinterpret_cast<uintptr_t>(data_pointer) % 64, 0u)
- << ": Flatbuffers failed to align things as requested";
- }
+ void InitializeMessage(size_t max_image_size);
- void Send(int rows, int cols, size_t image_size) {
- const auto data_offset =
- builder.fbb()->EndIndeterminateVector(image_size, 1);
- auto image_builder = builder.MakeBuilder<CameraImage>();
- image_builder.add_data(data_offset);
- image_builder.add_rows(rows);
- image_builder.add_cols(cols);
- builder.Send(image_builder.Finish());
- data_pointer = nullptr;
+ void PrepareMessage(int rows, int cols, size_t image_size,
+ aos::monotonic_clock::time_point monotonic_eof);
+
+ void Send() {
+ builder.Send(message_offset);
+ message_offset = flatbuffers::Offset<CameraImage>();
}
absl::Span<const char> DataSpan(size_t image_size) {
- return absl::Span<const char>(reinterpret_cast<char *>(data_pointer),
- image_size);
+ return absl::Span<const char>(
+ reinterpret_cast<char *>(CHECK_NOTNULL(data_pointer)), image_size);
}
aos::Sender<CameraImage> sender;
aos::Sender<CameraImage>::Builder builder;
+ flatbuffers::Offset<CameraImage> message_offset;
uint8_t *data_pointer = nullptr;
};
+ struct BufferInfo {
+ int index = -1;
+ aos::monotonic_clock::time_point monotonic_eof =
+ aos::monotonic_clock::min_time;
+
+ explicit operator bool() const { return index != -1; }
+
+ void Clear() {
+ index = -1;
+ monotonic_eof = aos::monotonic_clock::min_time;
+ }
+ };
+
// TODO(Brian): This concept won't exist once we start using variable-size
// H.264 frames.
size_t ImageSize() const { return rows_ * cols_ * 2 /* bytes per pixel */; }
// Attempts to dequeue a buffer (nonblocking). Returns the index of the new
- // buffer, or -1 if there wasn't a frame to dequeue.
- int DequeueBuffer();
+ // buffer, or BufferInfo() if there wasn't a frame to dequeue.
+ BufferInfo DequeueBuffer();
void EnqueueBuffer(int buffer);
@@ -95,7 +101,7 @@
// If this is non-negative, it's the buffer number we're currently holding
// onto.
- int saved_buffer_ = -1;
+ BufferInfo saved_buffer_;
const int rows_ = 480;
const int cols_ = 640;