1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef WIRELESS_ANDROID_AUTOMOTIVE_CAML_SURROUND_VIEW_CORE_LIB_H_
18 #define WIRELESS_ANDROID_AUTOMOTIVE_CAML_SURROUND_VIEW_CORE_LIB_H_
19 
20 #include <array>
21 #include <cstdint>
22 #include <map>
23 #include <string>
24 #include <vector>
25 
26 namespace android_auto {
27 namespace surround_view {
28 
29 // bounding box (bb)
30 // It is used to describe the car model bounding box in 3D.
31 // It assumes z = 0 and only x, y are used in the struct.
32 // Of course, it is compatible to the 2d version bounding box and may be used
33 // for other bounding box purpose (e.g., 2d bounding box in image).
34 struct BoundingBox {
35     // (x,y) is bounding box's top left corner coordinate.
36     float x;
37     float y;
38 
39     // (width, height) is the size of the bounding box.
40     float width;
41     float height;
42 
BoundingBoxBoundingBox43     BoundingBox() : x(0.0f), y(0.0f), width(0.0f), height(0.0f) {}
44 
BoundingBoxBoundingBox45     BoundingBox(float x_, float y_, float width_, float height_) :
46           x(x_), y(y_), width(width_), height(height_) {}
47 
BoundingBoxBoundingBox48     BoundingBox(const BoundingBox& bb_) :
49           x(bb_.x), y(bb_.y), width(bb_.width), height(bb_.height) {}
50 
51     // Checks if data is valid.
IsValidBoundingBox52     bool IsValid() const { return width >= 0 && height >= 0; }
53 
54     bool operator==(const BoundingBox& rhs) const {
55         return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height;
56     }
57 
58     BoundingBox& operator=(const BoundingBox& rhs) {
59         x = rhs.x;
60         y = rhs.y;
61         width = rhs.width;
62         height = rhs.height;
63         return *this;
64     }
65 };
66 
67 template <typename T>
68 struct Coordinate2dBase {
69     // x coordinate.
70     T x;
71 
72     // y coordinate.
73     T y;
74 
Coordinate2dBaseCoordinate2dBase75     Coordinate2dBase() : x(0), y(0) {}
76 
Coordinate2dBaseCoordinate2dBase77     Coordinate2dBase(T x_, T y_) : x(x_), y(y_) {}
78 
79     bool operator==(const Coordinate2dBase& rhs) const { return x == rhs.x && y == rhs.y; }
80 
81     Coordinate2dBase& operator=(const Coordinate2dBase& rhs) {
82         x = rhs.x;
83         y = rhs.y;
84         return *this;
85     }
86 };
87 
88 // integer type size.
89 typedef Coordinate2dBase<int> Coordinate2dInteger;
90 
91 // float type size.
92 typedef Coordinate2dBase<float> Coordinate2dFloat;
93 
94 struct Coordinate3dFloat {
95     // x coordinate.
96     float x;
97 
98     // y coordinate.
99     float y;
100 
101     // z coordinate.
102     float z;
103 
Coordinate3dFloatCoordinate3dFloat104     Coordinate3dFloat() : x(0), y(0), z(0) {}
105 
Coordinate3dFloatCoordinate3dFloat106     Coordinate3dFloat(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {}
107 
108     bool operator==(const Coordinate3dFloat& rhs) const { return x == rhs.x && y == rhs.y; }
109 
110     Coordinate3dFloat& operator=(const Coordinate3dFloat& rhs) {
111         x = rhs.x;
112         y = rhs.y;
113         return *this;
114     }
115 };
116 
117 //  pixel weight used for illumination assessment
118 struct PixelWeight {
119     // x and y are the coordinates (absolute value) in image space.
120     // pixel coordinate x in horizontal direction.
121     float x;
122 
123     // pixel coordinate y in vertical direction.
124     float y;
125 
126     // pixel weight, range in [0, 1].
127     float weight;
128 
PixelWeightPixelWeight129     PixelWeight() : x(-1), y(-1), weight(0) {}
130 
PixelWeightPixelWeight131     PixelWeight(int x_, int y_, int weight_) : x(x_), y(y_), weight(weight_) {}
132 
133     bool operator==(const PixelWeight& rhs) const {
134         return x == rhs.x && y == rhs.y && weight == rhs.weight;
135     }
136 
137     PixelWeight& operator=(const PixelWeight& rhs) {
138         x = rhs.x;
139         y = rhs.y;
140         weight = rhs.weight;
141         return *this;
142     }
143 };
144 
145 // base size 2d type template.
146 template <typename T>
147 struct Size2dBase {
148     // width of size.
149     T width;
150 
151     // height of size.
152     T height;
153 
Size2dBaseSize2dBase154     Size2dBase() : width(0), height(0) {}
155 
Size2dBaseSize2dBase156     Size2dBase(T width_, T height_) : width(width_), height(height_) {}
157 
IsValidSize2dBase158     bool IsValid() const { return width > 0 && height > 0; }
159 
160     bool operator==(const Size2dBase& rhs) const {
161         return width == rhs.width && height == rhs.height;
162     }
163 
164     Size2dBase& operator=(const Size2dBase& rhs) {
165         width = rhs.width;
166         height = rhs.height;
167         return *this;
168     }
169 };
170 
171 // integer type size.
172 typedef Size2dBase<int> Size2dInteger;
173 
174 // float type size.
175 typedef Size2dBase<float> Size2dFloat;
176 
177 //  surround view 2d parameters
178 struct SurroundView2dParams {
179     // surround view 2d image resolution (width, height).
180     Size2dInteger resolution;
181 
182     // the physical size of surround view 2d area in surround view coordinate.
183     // (surround view coordinate is defined as X rightward, Y forward and
184     // the origin lies on the center of the (symmetric) bowl (ground).
185     // When bowl is not used, surround view coordinate origin lies on the
186     // center of car model bounding box.)
187     // The unit should be consistent with camera extrinsics (translation).
188     Size2dFloat physical_size;
189 
190     // the center of surround view 2d area in surround view coordinate
191     // (consistent with extrinsics coordinate).
192     Coordinate2dFloat physical_center;
193 
194     // Enumeration for list of 2d blending types.
195     enum BlendingType { MULTIBAND = 0, ALPHA };
196 
197     // Blending type for high quality preset.
198     BlendingType high_quality_blending;
199 
200     // Blending type for low quality preset.
201     BlendingType low_quality_blending;
202 
SurroundView2dParamsSurroundView2dParams203     SurroundView2dParams() :
204           resolution{0, 0},
205           physical_size{0.0f, 0.0f},
206           physical_center{0.0f, 0.0f},
207           high_quality_blending(BlendingType::MULTIBAND),
208           low_quality_blending(BlendingType::ALPHA) {}
209 
SurroundView2dParamsSurroundView2dParams210     SurroundView2dParams(Size2dInteger resolution_, Size2dFloat physical_size_,
211                          Coordinate2dFloat physical_center_) :
212           resolution(resolution_),
213           physical_size(physical_size_),
214           physical_center(physical_center_),
215           high_quality_blending(BlendingType::MULTIBAND),
216           low_quality_blending(BlendingType::ALPHA) {}
217 
218     // Checks if data is valid.
IsValidSurroundView2dParams219     bool IsValid() const { return resolution.IsValid() && physical_size.IsValid(); }
220 
221     bool operator==(const SurroundView2dParams& rhs) const {
222         return resolution == rhs.resolution && physical_size == rhs.physical_size &&
223                 physical_center == rhs.physical_center &&
224                 high_quality_blending == rhs.high_quality_blending &&
225                 low_quality_blending == rhs.low_quality_blending;
226     }
227 
228     SurroundView2dParams& operator=(const SurroundView2dParams& rhs) {
229         resolution = rhs.resolution;
230         physical_size = rhs.physical_size;
231         physical_center = rhs.physical_center;
232         high_quality_blending = rhs.high_quality_blending;
233         low_quality_blending = rhs.low_quality_blending;
234         return *this;
235     }
236 };
237 
238 //  surround view 3d parameters
239 struct SurroundView3dParams {
240     // Bowl center is the origin of the surround view coordinate. If surround view
241     // coordinate is different from the global one, a coordinate system
242     // transformation function is required.
243 
244     // planar area radius.
245     // Range in (0, +Inf).
246     float plane_radius;
247 
248     // the number of divisions on the plane area of bowl, in the direction
249     // of the radius.
250     // Range in [1, +Inf).
251     int plane_divisions;
252 
253     // bowl curve curve height.
254     // Range in (0, +Inf).
255     float curve_height;
256 
257     // the number of points on bowl curve curve along radius direction.
258     // Range in [1, +Inf).
259     int curve_divisions;
260 
261     // the number of points along circle (360 degrees)
262     // Range in [1, +Inf).
263     int angular_divisions;
264 
265     // the parabola coefficient of bowl curve curve.
266     // The curve formula is z = a * (x^2 + y^2) for sqrt(x^2 + y^2) >
267     // plane_radius; a is curve_coefficient.
268     // Range in (0, +Inf).
269     float curve_coefficient;
270 
271     // render output image size.
272     Size2dInteger resolution;
273 
274     // Include shadows in high details preset.
275     bool high_details_shadows;
276 
277     // Include reflections in high details preset.
278     bool high_details_reflections;
279 
SurroundView3dParamsSurroundView3dParams280     SurroundView3dParams() :
281           plane_radius(0.0f),
282           plane_divisions(0),
283           curve_height(0.0f),
284           curve_divisions(0),
285           angular_divisions(0),
286           curve_coefficient(0.0f),
287           resolution(0, 0),
288           high_details_shadows(true),
289           high_details_reflections(true) {}
290 
SurroundView3dParamsSurroundView3dParams291     SurroundView3dParams(float plane_radius_, int plane_divisions_, float curve_height_,
292                          int curve_divisions_, int angular_divisions_, float curve_coefficient_,
293                          Size2dInteger resolution_) :
294           plane_radius(plane_radius_),
295           plane_divisions(plane_divisions_),
296           curve_height(curve_height_),
297           curve_divisions(curve_divisions_),
298           angular_divisions(angular_divisions_),
299           curve_coefficient(curve_coefficient_),
300           resolution(resolution_),
301           high_details_shadows(true),
302           high_details_reflections(true) {}
303 
304     // Checks if data is valid.
IsValidSurroundView3dParams305     bool IsValid() const {
306         return plane_radius > 0 && plane_divisions > 0 && curve_height > 0 &&
307                 angular_divisions > 0 && curve_coefficient > 0 && curve_divisions > 0 &&
308                 resolution.IsValid();
309     }
310 
311     bool operator==(const SurroundView3dParams& rhs) const {
312         return plane_radius == rhs.plane_radius && plane_divisions == rhs.plane_divisions &&
313                 curve_height == rhs.curve_height && curve_divisions == rhs.curve_divisions &&
314                 angular_divisions == rhs.angular_divisions &&
315                 curve_coefficient == rhs.curve_coefficient && resolution == rhs.resolution &&
316                 high_details_shadows == rhs.high_details_shadows &&
317                 high_details_reflections == rhs.high_details_reflections;
318     }
319 
320     SurroundView3dParams& operator=(const SurroundView3dParams& rhs) {
321         plane_radius = rhs.plane_radius;
322         plane_divisions = rhs.plane_divisions;
323         curve_height = rhs.curve_height;
324         curve_divisions = rhs.curve_divisions;
325         angular_divisions = rhs.angular_divisions;
326         curve_coefficient = rhs.curve_coefficient;
327         resolution = rhs.resolution;
328         high_details_shadows = rhs.high_details_shadows;
329         high_details_reflections = rhs.high_details_reflections;
330         return *this;
331     }
332 };
333 
334 // surround view camera parameters with native types only.
335 struct SurroundViewCameraParams {
336     // All calibration data |intrinsics|, |rvec| and |tvec|
337     // follow OpenCV format excepting using native arrays, refer:
338     // https://docs.opencv.org/3.4.0/db/d58/group__calib3d__fisheye.html
339     // camera intrinsics. It is the 1d array of camera matrix(3X3) with row first.
340     float intrinsics[9];
341 
342     // lens distortion parameters.
343     float distorion[4];
344 
345     // rotation vector.
346     float rvec[3];
347 
348     // translation vector.
349     float tvec[3];
350 
351     // camera image size (width, height).
352     Size2dInteger size;
353 
354     // fisheye circular fov.
355     float circular_fov;
356 
357     bool operator==(const SurroundViewCameraParams& rhs) const {
358         return (0 == std::memcmp(intrinsics, rhs.intrinsics, 9 * sizeof(float))) &&
359                 (0 == std::memcmp(distorion, rhs.distorion, 4 * sizeof(float))) &&
360                 (0 == std::memcmp(rvec, rhs.rvec, 3 * sizeof(float))) &&
361                 (0 == std::memcmp(tvec, rhs.tvec, 3 * sizeof(float))) && size == rhs.size &&
362                 circular_fov == rhs.circular_fov;
363     }
364 
365     SurroundViewCameraParams& operator=(const SurroundViewCameraParams& rhs) {
366         std::memcpy(intrinsics, rhs.intrinsics, 9 * sizeof(float));
367         std::memcpy(distorion, rhs.distorion, 4 * sizeof(float));
368         std::memcpy(rvec, rhs.rvec, 3 * sizeof(float));
369         std::memcpy(tvec, rhs.tvec, 3 * sizeof(float));
370         size = rhs.size;
371         circular_fov = rhs.circular_fov;
372         return *this;
373     }
374 };
375 
376 // 3D vertex of an overlay object.
377 struct OverlayVertex {
378     // Position in 3d coordinates in world space in order X,Y,Z.
379     float pos[3];
380     // RGBA values, A is used for transparency.
381     uint8_t rgba[4];
382 
383     bool operator==(const OverlayVertex& rhs) const {
384         return (0 == std::memcmp(pos, rhs.pos, 3 * sizeof(float))) &&
385                 (0 == std::memcmp(rgba, rhs.rgba, 4 * sizeof(uint8_t)));
386     }
387 
388     OverlayVertex& operator=(const OverlayVertex& rhs) {
389         std::memcpy(pos, rhs.pos, 3 * sizeof(float));
390         std::memcpy(rgba, rhs.rgba, 4 * sizeof(uint8_t));
391         return *this;
392     }
393 };
394 
395 // Overlay is a list of vertices (may be a single or multiple objects in scene)
396 // coming from a single source or type of sensor.
397 struct Overlay {
398     // Uniqiue Id identifying each overlay.
399     uint16_t id;
400 
401     // List of overlay vertices. 3 consecutive vertices form a triangle.
402     std::vector<OverlayVertex> vertices;
403 
404     // Constructor initializing all member.
OverlayOverlay405     Overlay(uint16_t id_, const std::vector<OverlayVertex>& vertices_) {
406         id = id_;
407         vertices = vertices_;
408     }
409 
410     // Default constructor.
OverlayOverlay411     Overlay() {
412         id = 0;
413         vertices = std::vector<OverlayVertex>();
414     }
415 };
416 
417 // -----------   Structs related to car model  ---------------
418 
419 // 3D Vertex of a car model with normal and optionally texture coordinates.
420 struct CarVertex {
421     // 3d position in (x, y, z).
422     std::array<float, 3> pos;
423 
424     // unit normal at vertex, used for diffuse shading.
425     std::array<float, 3> normal;
426 
427     // texture coordinates, valid in range [0, 1]. (-1, -1) implies no
428     // texture sampling. Note: only a single texture coordinate is currently
429     // supported per vertex. This struct will need to be extended with another
430     // tex_coord if multiple textures are needed per vertex.
431     std::array<float, 2> tex_coord;
432 
433     // Default constructor.
CarVertexCarVertex434     CarVertex() {
435         pos = {0, 0, 0};
436         normal = {1, 0, 0};
437         tex_coord = {-1.0f, -1.0f};
438     }
439 
CarVertexCarVertex440     CarVertex(const std::array<float, 3>& _pos, const std::array<float, 3>& _normal,
441               const std::array<float, 2> _tex_coord) :
442           pos(_pos), normal(_normal), tex_coord(_tex_coord) {}
443 };
444 
445 // Type of texture (color, bump, procedural etc.)
446 // Currently only color is supported.
447 enum CarTextureType : uint32_t {
448     // Texture map is applied to all color parameters: Ka, Kd and Ks.
449     // Data type of texture is RGB with each channel a uint8_t.
450     kKa = 0,
451     kKd,
452     kKs,
453 
454     // Texture for bump maps. Data type is 3 channel float.
455     kBumpMap
456 };
457 
458 // Textures to be used for rendering car model.
459 struct CarTexture {
460     // Type and number of channels are dependant on each car texture type.
461     int width;
462     int height;
463     int channels;
464     int bytes_per_channel;
465     uint8_t* data;
466 
CarTextureCarTexture467     CarTexture() {
468         width = 0;
469         height = 0;
470         channels = 0;
471         bytes_per_channel = 0;
472         data = nullptr;
473     }
474 };
475 
476 // Material parameters for a car part.
477 // Refer to MTL properties: http://paulbourke.net/dataformats/mtl/
478 struct CarMaterial {
479     // Illumination model - 0, 1, 2 currently supported
480     // 0 = Color on and Ambient off
481     // 1 = Color on and Ambient on
482     // 2 = Highlight on
483     // 3 = Reflection on and Ray trace on
484     // 4 - 10 = Reflection/Transparency options not supported,
485     //          Will default to option 3.
486     uint8_t illum;
487 
488     std::array<float, 3> ka;  // Ambient RGB [0, 1]
489     std::array<float, 3> kd;  // Diffuse RGB [0, 1]
490     std::array<float, 3> ks;  // Specular RGB [0, 1]
491 
492     // Dissolve factor [0, 1], 0 = full transparent, 1 = full opaque.
493     float d;
494 
495     // Specular exponent typically range from 0 to 1000.
496     // A high exponent results in a tight, concentrated highlight.
497     float ns;
498 
499     // Set default values of material.
CarMaterialCarMaterial500     CarMaterial() {
501         illum = 0;                // Color on, ambient off
502         ka = {0.0f, 0.0f, 0.0f};  // No ambient.
503         kd = {0.0f, 0.0f, 0.0f};  // No dissolve.
504         ks = {0.0f, 0.0f, 0.0f};  // No specular.
505         d = 1.0f;                 // Fully opaque.
506         ns = 0;                   // No specular exponent.
507     }
508 
509     // Map for texture type to a string id of a texture.
510     std::map<CarTextureType, std::string> textures;
511 };
512 
513 // Type alias for 4x4 homogenous matrix, in row-major order.
514 using Mat4x4 = std::array<float, 16>;
515 
516 // Represents a part of a car model.
517 // Each car part is a object in the car that is individually animated and
518 // has the same illumination properties. A car part may contain sub parts.
519 struct CarPart {
520     // Car part vertices.
521     std::vector<CarVertex> vertices;
522 
523     // Properties/attributes describing car material.
524     CarMaterial material;
525 
526     // Model matrix to transform the car part from object space to its parent's
527     // coordinate space.
528     // The car's vertices are transformed by performing:
529     // parent_model_mat * model_mat * car_part_vertices to transform them to the
530     // global coordinate space.
531     // Model matrix must be a homogenous matrix with orthogonal rotation matrix.
532     Mat4x4 model_mat;
533 
534     // Id of parent part. Parent part's model matrix is used to animate this part.
535     // empty string implies the part has no parent.
536     std::string parent_part_id;
537 
538     // Ids of child parts. If current part is animated all its child parts
539     // are animated as well. Empty vector implies part has not children.
540     std::vector<std::string> child_part_ids;
541 
CarPartCarPart542     CarPart(const std::vector<CarVertex>& car_vertices, const CarMaterial& car_material,
543             const Mat4x4& car_model_mat, std::string car_parent_part_id,
544             const std::vector<std::string>& car_child_part_ids) :
545           vertices(car_vertices),
546           material(car_material),
547           model_mat(car_model_mat),
548           parent_part_id(car_parent_part_id),
549           child_part_ids(car_child_part_ids) {}
550 
551     CarPart& operator=(const CarPart& car_part) {
552         this->vertices = car_part.vertices;
553         this->material = car_part.material;
554         this->model_mat = car_part.model_mat;
555         this->parent_part_id = car_part.parent_part_id;
556         this->child_part_ids = car_part.child_part_ids;
557         return *this;
558     }
559 };
560 
561 struct AnimationParam {
562     // part id
563     std::string part_id;
564 
565     // model matrix.
566     Mat4x4 model_matrix;
567 
568     // bool flag indicating if the model matrix is updated from last
569     // SetAnimations() call.
570     bool is_model_update;
571 
572     // gamma.
573     float gamma;
574 
575     // bool flag indicating if gamma is updated from last
576     // SetAnimations() call.
577     bool is_gamma_update;
578 
579     // texture id.
580     std::string texture_id;
581 
582     // bool flag indicating if texture is updated from last
583     // SetAnimations() call.
584     bool is_texture_update;
585 
586     // Default constructor, no animations are updated.
AnimationParamAnimationParam587     AnimationParam() {
588         is_model_update = false;
589         is_gamma_update = false;
590         is_texture_update = false;
591     }
592 
593     // Constructor with car part name.
AnimationParamAnimationParam594     explicit AnimationParam(const std::string& _part_id) :
595           part_id(_part_id),
596           is_model_update(false),
597           is_gamma_update(false),
598           is_texture_update(false) {}
599 
SetModelMatrixAnimationParam600     void SetModelMatrix(const Mat4x4& model_mat) {
601         is_model_update = true;
602         model_matrix = model_mat;
603     }
604 
SetGammaAnimationParam605     void SetGamma(float gamma_value) {
606         is_gamma_update = true;
607         gamma = gamma_value;
608     }
609 
SetTextureAnimationParam610     void SetTexture(const std::string& tex_id) {
611         is_texture_update = true;
612         texture_id = tex_id;
613     }
614 };
615 
616 enum Format {
617     GRAY = 0,
618     RGB = 1,
619     RGBA = 2,
620 };
621 
622 // collection of surround view static data params.
623 struct SurroundViewStaticDataParams {
624     std::vector<SurroundViewCameraParams> cameras_params;
625 
626     // surround view 2d parameters.
627     SurroundView2dParams surround_view_2d_params;
628 
629     // surround view 3d parameters.
630     SurroundView3dParams surround_view_3d_params;
631 
632     // undistortion focal length scales.
633     std::vector<float> undistortion_focal_length_scales;
634 
635     // car model bounding box for 2d surround view.
636     BoundingBox car_model_bb;
637 
638     // map of texture name to a car texture. Lists all textures to be
639     // used for car model rendering.
640     std::map<std::string, CarTexture> car_textures;
641 
642     // map of car id to a car part. Lists all car parts to be used
643     // for car model rendering.
644     std::map<std::string, CarPart> car_parts;
645 
SurroundViewStaticDataParamsSurroundViewStaticDataParams646     SurroundViewStaticDataParams(const std::vector<SurroundViewCameraParams>& sv_cameras_params,
647                                  const SurroundView2dParams& sv_2d_params,
648                                  const SurroundView3dParams& sv_3d_params,
649                                  const std::vector<float>& scales, const BoundingBox& bb,
650                                  const std::map<std::string, CarTexture>& textures,
651                                  const std::map<std::string, CarPart>& parts) :
652           cameras_params(sv_cameras_params),
653           surround_view_2d_params(sv_2d_params),
654           surround_view_3d_params(sv_3d_params),
655           undistortion_focal_length_scales(scales),
656           car_model_bb(bb),
657           car_textures(textures),
658           car_parts(parts) {}
659 };
660 
661 struct SurroundViewInputBufferPointers {
662     void* gpu_data_pointer;
663     void* cpu_data_pointer;
664     Format format;
665     int width;
666     int height;
SurroundViewInputBufferPointersSurroundViewInputBufferPointers667     SurroundViewInputBufferPointers() :
668           gpu_data_pointer(nullptr), cpu_data_pointer(nullptr), width(0), height(0) {}
SurroundViewInputBufferPointersSurroundViewInputBufferPointers669     SurroundViewInputBufferPointers(void* gpu_data_pointer_, void* cpu_data_pointer_,
670                                     Format format_, int width_, int height_) :
671           gpu_data_pointer(gpu_data_pointer_),
672           cpu_data_pointer(cpu_data_pointer_),
673           format(format_),
674           width(width_),
675           height(height_) {}
676 };
677 
678 struct SurroundViewResultPointer {
679     void* data_pointer;
680     Format format;
681     int width;
682     int height;
683     bool is_data_preallocated;
SurroundViewResultPointerSurroundViewResultPointer684     SurroundViewResultPointer() :
685           data_pointer(nullptr), width(0), height(0), is_data_preallocated(false) {}
686 
687     // Constructor with result data pointer being allocated within core lib.
688     // Use for cases when no already existing buffer is available.
SurroundViewResultPointerSurroundViewResultPointer689     SurroundViewResultPointer(Format format_, int width_, int height_) :
690           format(format_), width(width_), height(height_) {
691         // default formate is gray.
692         const int byte_per_pixel = format_ == RGB ? 3 : format_ == RGBA ? 4 : 1;
693         data_pointer = static_cast<void*>(new char[width * height * byte_per_pixel]);
694         is_data_preallocated = false;
695     }
696 
697     // Constructor with pre-allocated data.
698     // Use for cases when results must be added to an existing allocated buffer.
699     // Example, pre-allocated buffer of a display.
SurroundViewResultPointerSurroundViewResultPointer700     SurroundViewResultPointer(void* data_pointer_, Format format_, int width_, int height_) :
701           data_pointer(data_pointer_),
702           format(format_),
703           width(width_),
704           height(height_),
705           is_data_preallocated(true) {}
706 
~SurroundViewResultPointerSurroundViewResultPointer707     ~SurroundViewResultPointer() {
708         if (data_pointer) {
709             // TODO(b/154365307): Fix freeing up of pre-allocated memory.
710             // if (!is_data_preallocated) {
711             //   delete[] static_cast<char*>(data_pointer);
712             // }
713             data_pointer = nullptr;
714         }
715     }
716 };
717 
718 class SurroundView {
719 public:
720     virtual ~SurroundView() = default;
721 
722     // Sets SurroundView static data.
723     // For details of SurroundViewStaticDataParams, please refer to the
724     // definition.
725     virtual bool SetStaticData(const SurroundViewStaticDataParams& static_data_params) = 0;
726 
727     // Starts 2d pipeline. Returns false if error occurs.
728     virtual bool Start2dPipeline() = 0;
729 
730     // Starts 3d pipeline. Returns false if error occurs.
731     virtual bool Start3dPipeline() = 0;
732 
733     // Stops 2d pipleline. It releases resource owned by the pipeline.
734     // Returns false if error occurs.
735     virtual void Stop2dPipeline() = 0;
736 
737     // Stops 3d pipeline. It releases resource owned by the pipeline.
738     virtual void Stop3dPipeline() = 0;
739 
740     // Updates 2d output resolution on-the-fly. Starts2dPipeline() must be called
741     // before this can be called. For quality assurance, the |resolution| should
742     // not be larger than the original one. This call is not thread safe and there
743     // is no sync between Get2dSurroundView() and this call.
744     virtual bool Update2dOutputResolution(const Size2dInteger& resolution) = 0;
745 
746     // Updates 3d output resolution on-the-fly. Starts3dPipeline() must be called
747     // before this can be called. For quality assurance, the |resolution| should
748     // not be larger than the original one. This call is not thread safe and there
749     // is no sync between Get3dSurroundView() and this call.
750     virtual bool Update3dOutputResolution(const Size2dInteger& resolution) = 0;
751 
752     // Projects camera's pixel location to surround view 2d image location.
753     // |camera_point| is the pixel location in raw camera's space.
754     // |camera_index| is the camera's index.
755     // |surround_view_2d_point| is the surround view 2d image pixel location.
756     virtual bool GetProjectionPointFromRawCameraToSurroundView2d(
757             const Coordinate2dInteger& camera_point, int camera_index,
758             Coordinate2dFloat* surround_view_2d_point) = 0;
759 
760     // Projects camera's pixel location to surround view 3d bowl coordinate.
761     // |camera_point| is the pixel location in raw camera's space.
762     // |camera_index| is the camera's index.
763     // |surround_view_3d_point| is the surround view 3d vertex.
764     virtual bool GetProjectionPointFromRawCameraToSurroundView3d(
765             const Coordinate2dInteger& camera_point, int camera_index,
766             Coordinate3dFloat* surround_view_3d_point) = 0;
767 
768     // Gets 2d surround view image.
769     // It takes input_pointers as input, and output is result_pointer.
770     // Please refer to the definition of SurroundViewInputBufferPointers and
771     // SurroundViewResultPointer.
772     virtual bool Get2dSurroundView(
773             const std::vector<SurroundViewInputBufferPointers>& input_pointers,
774             SurroundViewResultPointer* result_pointer) = 0;
775 
776     // Gets 3d surround view image.
777     // It takes |input_pointers| and |view_matrix| as input, and output is
778     // |result_pointer|. |view_matrix| is 4 x 4 matrix.
779     // Please refer to the definition of
780     // SurroundViewInputBufferPointers and
781     // SurroundViewResultPointer.
782     virtual bool Get3dSurroundView(
783             const std::vector<SurroundViewInputBufferPointers>& input_pointers,
784             const std::array<std::array<float, 4>, 4>& view_matrix,
785             SurroundViewResultPointer* result_pointer) = 0;
786 
787     // Gets 3d surround view image overload.
788     // It takes |input_pointers|, |quaternion| and |translation| as input,
789     // and output is |result_pointer|.
790     // |quaternion| is 4 x 1 array (X, Y, Z, W).
791     // It is required to be unit quaternion as rotation quaternion.
792     // |translation| is 3 X 1 array (x, y, z).
793     // Please refer to the definition of
794     // SurroundViewInputBufferPointers and
795     // SurroundViewResultPointer.
796     virtual bool Get3dSurroundView(
797             const std::vector<SurroundViewInputBufferPointers>& input_pointers,
798             const std::array<float, 4>& quaternion, const std::array<float, 3>& translation,
799             SurroundViewResultPointer* result_pointer) = 0;
800 
801     // Sets 3d overlays.
802     virtual bool Set3dOverlay(const std::vector<Overlay>& overlays) = 0;
803 
804     // Animates a set of car parts.
805     // Only updated car parts are included.
806     // |car_animations| is a vector of AnimationParam specifying updated
807     // car parts with updated animation parameters.
808     virtual bool SetAnimations(const std::vector<AnimationParam>& car_animations) = 0;
809 
810     // for test only.
811     virtual std::vector<SurroundViewInputBufferPointers> ReadImages(const char* filename0,
812                                                                     const char* filename1,
813                                                                     const char* filename2,
814                                                                     const char* filename3) = 0;
815 
816     virtual void WriteImage(const SurroundViewResultPointer result_pointerer,
817                             const char* filename) = 0;
818 };
819 
820 SurroundView* Create();
821 
822 }  // namespace surround_view
823 }  // namespace android_auto
824 
825 #endif  // WIRELESS_ANDROID_AUTOMOTIVE_CAML_SURROUND_VIEW_CORE_LIB_H_
826