// Copyright (c) farm-ng, inc.
//
// Licensed under the Amiga Development Kit License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://github.com/farm-ng/amiga-dev-kit/blob/main/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

message Vec2I64 {
  int64 x = 1;
  int64 y = 2;
}

message Vec2F32 {
  float x = 1;
  float y = 2;
}

message Vec2F64 {
  double x = 1;
  double y = 2;
}

message Vec3I64 {
  int64 x = 1;
  int64 y = 2;
  int64 z = 3;
}

message Vec3F32 {
  float x = 1;
  float y = 2;
  float z = 3;
}

message Vec3F64 {
  double x = 1;
  double y = 2;
  double z = 3;
}

message Mat2F32 {
  Vec2F32 col_0 = 1;
  Vec2F32 col_1 = 2;
}

message Mat2F64 {
  Vec2F64 col_0 = 1;
  Vec2F64 col_1 = 2;
}

message Mat3F32 {
  Vec3F32 col_0 = 1;
  Vec3F32 col_1 = 2;
  Vec3F32 col_2 = 3;
}

message Mat3F64 {
  Vec3F64 col_0 = 1;
  Vec3F64 col_1 = 2;
  Vec3F64 col_2 = 3;
}

message VecXF32 {
   repeated float data = 1;
}

message VecXF64 {
   repeated double data = 1;
}

message MatXF32 {
   int32 rows =1;
   int32 cols =2;
   repeated float data = 3;
}

message MatXF64 {
   int32 rows =1;
   int32 cols =2;
   repeated float data = 3;
}

message CameraSettings {
  bool auto_exposure = 1;
  uint32 exposure_time = 2;
  uint32 iso_value = 3;
  uint32 lens_pos = 4;
}

// The encoding format for the video stream
// https://docs.luxonis.com/projects/api/en/latest/references/python/#depthai.VideoEncoderProperties.Profile
enum EncoderProfile {
  H264_BASELINE = 0;
  H264_HIGH = 1;
  H264_MAIN = 2;
  H265_MAIN = 3;
  MJPEG = 4;
}

// The rate control mode for the video stream
// https://docs.luxonis.com/projects/api/en/latest/references/python/#depthai.VideoEncoderProperties.RateControlMode
enum RateControlMode {
  CBR = 0;  // Constant Bit Rate
  VBR = 1;  // Variable Bit Rate
}

// The options for the video encoder
message EncoderOptions {
  // The profile to use for encoding.
  EncoderProfile profile = 1;

  // The rate control mode to use.
  RateControlMode rate_control_mode = 2;

  // The preferred bitrate for constant bitrate (CBR) mode, in kilobits per second (kbps).
  uint32 cbr_preferred_bitrate_kbps = 3;

  // The quality setting for variable bitrate (VBR) mode or MJPEG encoding.
  // For VBR mode, this represents the desired quality level.
  // For MJPEG encoding, this represents the JPEG quality level.
  uint32 vbr_or_mjpeg_quality = 4;

  // The number of frames between keyframes.
  uint32 frames_per_keyframe = 5;
}

enum PixelFormat {
  UNKNOWN = 0;
  YUV420 = 1;
  RAW8 = 2;
  Encoded = 3;
}

message Resolution {
  uint32 width = 1;
  uint32 height = 2;
}


message OakImageMeta {
  int64 category = 1;          // DepthAI catetory
  int64 instance_num = 2;      // DepthAI instance number
  int64 sequence_num = 3;      // for synchronization between left, right and stereo
  double timestamp = 4;        // seconds, capture time (begin of exposure) synchronized with host monotonic
  double timestamp_device = 5; // seconds, capture time (begin of exposure) in the device monotonic clock
  double timestamp_recv = 7;   // seconds, host receive time in host monotonic clock
  CameraSettings settings = 6;
  EncoderOptions encoder_options = 8;
  Resolution resolution = 9;
  PixelFormat pixel_format = 10;
}

message OakFrame {
  OakImageMeta meta = 1;
  bytes image_data = 2; // decode/encode with cv2.imencode/cv2.imdecode
}

message OakGyro {
  Vec3F32 gyro = 1;
  int32 sequence_num = 2;
  string accuracy = 3;
  double timestamp = 4;        // See OakImageMeta
  double timestamp_device = 5; // See OakImageMeta
  double timestamp_recv = 6;   // See OakImageMeta
}

message OakAccelero {
  Vec3F32 accelero = 1;
  int32 sequence_num = 2;
  string accuracy = 3;
  double timestamp = 4;        // See OakImageMeta
  double timestamp_device = 5; // See OakImageMeta
  double timestamp_recv = 6;   // See OakImageMeta
}

message OakImuPacket {
  OakGyro gyro_packet = 1;
  OakAccelero accelero_packet = 2;
}

message OakImuPackets {
  repeated OakImuPacket packets = 1;
}

// Message for a single tracked feature
message OakTrackedFeaturePacket {
  Vec2F32 xy = 1;
  int32 id = 2;
  int32 age = 3;
  float harrisScore = 4;
  float trackingError = 5;
}

// Message for sending tracked features from the device to the host
// Reference: https://docs.luxonis.com/projects/api/en/latest/components/nodes/feature_tracker/
message OakTrackedFeaturePackets {
  repeated OakTrackedFeaturePacket packets = 1;
  int64 sequence_num = 2;
  double timestamp = 3;        // See OakImageMeta
  double timestamp_device = 4; // See OakImageMeta
  double timestamp_recv = 5;   // See OakImageMeta
}

message OakDeviceInfo {
  string name = 1;
  string mxid = 2;
  string ip = 3;
}

message OakSyncFrame {
  OakFrame left = 1;
  OakFrame right = 2;
  OakFrame rgb = 3;
  OakFrame disparity = 4;
  OakNNData nn = 5;
  OakImuPackets imu_packets = 6;
  int64 sequence_num = 7;
  OakDeviceInfo device_info = 8;
}

message OakNNData {
  OakImageMeta meta = 1;
  uint32 num_channels = 2;
  uint32 height = 3;
  uint32 width = 4;
  bytes data = 5;
}

message Pair {
  string key = 1;
  string value = 2;
}

message Metadata {
  repeated Pair pairs = 1;
}

message OakDataSample {
  OakSyncFrame frame = 1;
  Metadata metadata = 2;
}

message RotationMatrix {
  repeated double rotation_matrix = 1;
}

message Extrinsics {
  repeated double rotation_matrix = 1;
  Vec3F32 spec_translation = 2;
  int32 to_camera_socket = 3;
  Vec3F32 translation = 4;
}

message CameraData {
  uint32 camera_number = 1;
  int32 camera_type = 2;
  repeated double distortion_coeff = 3;
  Extrinsics extrinsics = 4;
  uint32 height = 5;
  repeated double intrinsic_matrix = 6;
  uint32 lens_position = 7;
  double spec_hfov_deg = 8;
  uint32 width = 9;
}

message StereoRectificationData {
  uint32 left_camera_socket = 1;
  repeated double rectified_rotation_left = 2;
  repeated double rectified_rotation_right = 3;
  uint32 right_camera_socket = 4;
}

message OakCalibration {
  string batch_name = 1;
  int32 batch_time = 2;
  string board_conf = 3;
  string board_custom = 4;
  string board_name = 5;
  int32 board_options = 6;
  string board_rev = 7;
  repeated CameraData camera_data = 8;
  string hardware_conf = 9;
  Extrinsics imu_extrinsics = 10;
  repeated string miscellaneous_data = 11;
  string product_name = 12;
  StereoRectificationData stereo_rectification_data = 13;
  uint32 version = 14;
}
