• <xmp id="om0om">
  • <table id="om0om"><noscript id="om0om"></noscript></table>
  • Compute Graph Framework SDK Reference  5.8
    All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
    ChannelPacketImpl.hpp
    Go to the documentation of this file.
    1
    2// This code contains NVIDIA Confidential Information and is disclosed
    3// under the Mutual Non-Disclosure Agreement.
    4//
    5// Notice
    6// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
    7// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
    8// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
    9// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
    10//
    11// NVIDIA Corporation assumes no responsibility for the consequences of use of such
    12// information or for any infringement of patents or other rights of third parties that may
    13// result from its use. No license is granted by implication or otherwise under any patent
    14// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
    15// expressly authorized by NVIDIA. Details are subject to change without notice.
    16// This code supersedes and replaces all information previously supplied.
    17// NVIDIA Corporation products are not authorized for use as critical
    18// components in life support devices or systems without express written approval of
    19// NVIDIA Corporation.
    20//
    21// Copyright (c) 2018-2022 NVIDIA Corporation. All rights reserved.
    22//
    23// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
    24// rights in and to this software and related documentation and any modifications thereto.
    25// Any use, reproduction, disclosure or distribution of this software and related
    26// documentation without an express license agreement from NVIDIA Corporation is
    27// strictly prohibited.
    28//
    30
    31#ifndef DW_FRAMEWORK_CHANNEL_DW_PACKET_IMPL_HPP_
    32#define DW_FRAMEWORK_CHANNEL_DW_PACKET_IMPL_HPP_
    33
    35#include <dw/roadcast/base_types/RoadCastBaseTypes.h>
    38
    39namespace dw
    40{
    41namespace framework
    42{
    43
    45
    47{
    48public:
    49 ImageHandlePacket(const GenericData& specimen, dwContextHandle_t ctx)
    50 {
    51 auto* props = specimen.getData<dwImageProperties>();
    52 if (props)
    53 {
    54 m_prop = *props;
    55 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandle, m_prop, ctx));
    57 }
    58 else
    59 {
    60 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    61 }
    62 }
    63
    65 {
    67 }
    68
    70 {
    71 dwImage_destroy(m_imageHandle);
    72 }
    73
    74protected:
    75 dwImageHandle_t m_imageHandle = DW_NULL_HANDLE;
    76 dwImageHandle_t m_dispatchImage = DW_NULL_HANDLE;
    77 dwImageProperties m_prop{};
    78};
    79
    80template <>
    81class ChannelPacket<dwImageHandle_t> : public ImageHandlePacket, public ChannelSocketPacketBase
    82{
    83public:
    84 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    85 : ImageHandlePacket(specimen, ctx)
    86 , m_ctx(ctx)
    87 {
    88 if (m_prop.type != DW_IMAGE_CPU)
    89 {
    90 // Allocate streamer to CPU
    91 m_prop.meta = {};
    92 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerToCPU, &m_prop, DW_IMAGE_CPU, ctx));
    93 }
    94
    95 // Allocate streamer from CPU back to original type
    96 dwImageProperties cpuProp = m_prop;
    97 cpuProp.type = DW_IMAGE_CPU;
    98
    99 if (m_prop.type != DW_IMAGE_CPU)
    100 {
    101 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerFromCPU, &cpuProp, m_prop.type, ctx));
    102 }
    103
    104 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandleCPU, cpuProp, ctx));
    105 FRWK_CHECK_DW_ERROR(dwImage_getDataLayout(&m_elementSize, &m_planeCount, m_planeChannelCount, m_planeSize, &cpuProp));
    106
    107 // Compute buffer size needed for transfer
    108 size_t bufferSize = sizeof(dwImageCPU);
    109 for (size_t i = 0; i < m_planeCount; i++)
    110 {
    111 size_t planeRowBytes = m_elementSize * m_planeSize[i].x * m_planeChannelCount[i];
    112 bufferSize += planeRowBytes * m_planeSize[i].y;
    113 }
    114
    115 initBuffer(bufferSize);
    116 }
    117
    118 ~ChannelPacket() override
    119 {
    120 if (m_prop.type != DW_IMAGE_CPU)
    121 {
    122 dwImage_destroy(m_imageHandleCPU);
    123 dwImageStreamer_release(m_streamerToCPU);
    124 dwImageStreamer_release(m_streamerFromCPU);
    125 }
    126 }
    127
    128 // Image serialization static functions to allow re-use in dwBlindnessDetectionOutput serialization.
    129 static size_t serializeImage(dwImageCPU* cpuImage, unsigned char* buffer_start, size_t bufferSize,
    130 size_t planeCount, size_t elementSize, uint32_t planeChannelCount[],
    131 dwVector2ui planeSize[])
    132 {
    133
    134 memcpy(buffer_start, cpuImage, sizeof(dwImageCPU));
    135
    136 size_t bufferOffset = sizeof(dwImageCPU);
    137 for (size_t i = 0; i < planeCount; i++)
    138 {
    139 size_t planeOffset = 0U;
    140 size_t pitch = cpuImage->pitch[i];
    141 size_t planeRowBytes = elementSize * planeSize[i].x * planeChannelCount[i];
    142 for (size_t j = 0; j < planeSize[i].y; j++)
    143 {
    144 if (bufferOffset + planeRowBytes > bufferSize)
    145 {
    146 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwImageHandle_t>: serialize: send packet size, buffer size mismatch.");
    147 }
    148 memcpy(buffer_start + bufferOffset, cpuImage->data[i] + planeOffset, planeRowBytes);
    149 planeOffset += pitch;
    150 bufferOffset += planeRowBytes;
    151 }
    152 }
    153 return bufferOffset;
    154 }
    155
    156 static void deserializeImage(dwImageHandle_t copyToImage, unsigned char* buffer_start, size_t bufferSize,
    157 size_t planeCount, size_t elementSize, uint32_t planeChannelCount[],
    158 dwVector2ui planeSize[])
    159 {
    160
    161 // Ensure metadata is a match
    162 dwImageCPU* cpuImage = nullptr;
    163 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, copyToImage));
    164
    165 size_t bufferOffset = sizeof(dwImageCPU);
    166 for (size_t i = 0; i < planeCount; i++)
    167 {
    168 size_t planeOffset = 0U;
    169 size_t pitch = cpuImage->pitch[i];
    170 size_t planeRowBytes = elementSize * planeSize[i].x * planeChannelCount[i];
    171 for (size_t j = 0; j < planeSize[i].y; j++)
    172 {
    173 if (bufferOffset + planeRowBytes > bufferSize)
    174 {
    175 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwImageHandle_t>: deserialize: recieve packet size, buffer size mismatch.");
    176 }
    177 memcpy(cpuImage->data[i] + planeOffset, buffer_start + bufferOffset, planeRowBytes);
    178 planeOffset += pitch;
    179 bufferOffset += planeRowBytes;
    180 }
    181 }
    182 }
    183
    184 // Serializes the frame before transmission
    185 void serializeImpl() final
    186 {
    187 dwImageCPU* cpuImage = nullptr;
    188 dwImageHandle_t recvImage = nullptr;
    189 dwImageHandle_t* returnedImage = nullptr;
    190
    191 if (m_prop.type != DW_IMAGE_CPU)
    192 {
    193 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_dispatchImage, m_streamerToCPU));
    194 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImage, 0, m_streamerToCPU));
    195
    196 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, recvImage));
    197 }
    198 else
    199 {
    200 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, m_dispatchImage));
    201 }
    202
    203 serializeImage(cpuImage, m_buffer.get(), m_bufferSize, m_planeCount, m_elementSize, m_planeChannelCount, m_planeSize);
    204
    205 if (m_prop.type != DW_IMAGE_CPU)
    206 {
    207 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImage, m_streamerToCPU));
    208 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerToCPU));
    209 }
    210 }
    211
    212 // Deserializes the frame after transmission
    213 void deserialize(size_t) final
    214 {
    215 dwImageHandle_t copyToImage = m_dispatchImage;
    216 if (m_prop.type != DW_IMAGE_CPU)
    217 {
    218 copyToImage = m_imageHandleCPU;
    219 }
    220
    221 // This needs to happen here to ensure that fields can be updated later.
    222 dwImageCPU recvImage{};
    223 memcpy(&recvImage, m_buffer.get(), sizeof(dwImageCPU));
    224
    225 deserializeImage(copyToImage, m_buffer.get(), m_bufferSize, m_planeCount, m_elementSize, m_planeChannelCount, m_planeSize);
    226
    227 if (m_prop.type != DW_IMAGE_CPU)
    228 {
    229 dwImageHandle_t recvImageHandle = nullptr;
    230 dwImageHandle_t* returnedImage = nullptr;
    231
    232 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_imageHandleCPU, m_streamerFromCPU));
    233 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImageHandle, 0, m_streamerFromCPU));
    234
    235 dwImage_copyConvert(m_dispatchImage, recvImageHandle, m_ctx);
    236 dwImage_setMetaData(&recvImage.prop.meta, m_dispatchImage);
    237 dwImage_setTimestamp(recvImage.timestamp_us, m_dispatchImage);
    238
    239 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImageHandle, m_streamerFromCPU));
    240 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerFromCPU));
    241 }
    242 }
    243
    244private:
    245 dwImageHandle_t m_imageHandleCPU = DW_NULL_HANDLE;
    246
    247 size_t m_elementSize = 0;
    248 size_t m_planeCount = 0;
    249 uint32_t m_planeChannelCount[DW_MAX_IMAGE_PLANES]{};
    250 dwVector2ui m_planeSize[DW_MAX_IMAGE_PLANES]{};
    251
    252 dwImageStreamerHandle_t m_streamerToCPU = DW_NULL_HANDLE;
    253 dwImageStreamerHandle_t m_streamerFromCPU = DW_NULL_HANDLE;
    254
    255 dwContextHandle_t m_ctx = DW_NULL_HANDLE;
    256};
    257
    260{
    261public:
    262 LatencyPacket(const GenericData& specimen)
    263 {
    264 auto* props = specimen.getData<dwLatency>();
    265 if (props)
    266 {
    267 m_data.size = props->size;
    268 m_data.senderTime = props->senderTime;
    269 m_allocation = std::make_unique<uint8_t[]>(props->size);
    270 m_data.data = m_allocation.get();
    272 }
    273 else
    274 {
    275 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    276 }
    277 }
    278
    280 {
    281 return GenericData(&m_data);
    282 }
    283
    284protected:
    285 std::unique_ptr<uint8_t[]> m_allocation{};
    288};
    289
    290// dwLatency packet for channel socket which is used for measurement of latency/data rate across tegras.
    291template <>
    293{
    294public:
    295 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
    296 : LatencyPacket(specimen)
    297 {
    298 m_objectSize = sizeof(uint8_t);
    299 m_maxCount = m_data.size;
    300
    301 m_headerSize = sizeof(dwLatency);
    302
    303 // packet has fixed size for simplicity
    304 // variable length packet is currently not supported
    305 initBuffer(m_headerSize + m_maxCount * m_objectSize);
    306 }
    307
    308 // Serializes the frame before transmission
    309 void serializeImpl() final
    310 {
    311 //copy packet data into buffer
    312 memcpy(m_buffer.get(), &m_data, m_headerSize);
    313
    314 // deep copy objects data
    315 memcpy(m_buffer.get() + m_headerSize, m_data.data, m_data.size * m_objectSize);
    316 }
    317
    318 // Deserializes the frame after transmission
    319 void deserialize(size_t) final
    320 {
    321 //retrieve dwLatency from buffer
    322 memcpy(&m_data, m_buffer.get(), m_headerSize);
    323
    324 //retrieve object data
    325 // points objects to the correct location in byte buffer
    326 m_data.data = m_buffer.get() + m_headerSize;
    327 }
    328
    329private:
    330 size_t m_headerSize;
    331 size_t m_objectSize;
    332 size_t m_maxCount;
    333};
    334
    337{
    338public:
    339 PyramidImagePacket(const GenericData& specimen, dwContextHandle_t ctx)
    340 {
    341 auto* props = specimen.getData<dwPyramidImageProperties>();
    342 if (props)
    343 {
    344 m_props = *props;
    345 FRWK_CHECK_DW_ERROR(dwPyramid_createFromProperties(&m_pyramidImage, &m_props, ctx));
    347 }
    348 else
    349 {
    350 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    351 }
    352 }
    353
    355 {
    357 }
    358
    360 {
    361 dwPyramid_destroy(m_pyramidImage);
    362 }
    363
    364protected:
    365 dwPyramidImage m_pyramidImage{};
    366 dwPyramidImage m_dispatchPyramid{};
    367 dwPyramidImageProperties m_props{};
    368};
    369
    370template <>
    371class ChannelPacket<dwPyramidImage> : public PyramidImagePacket, public ChannelSocketPacketBase
    372{
    373public:
    374 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    375 : PyramidImagePacket(specimen, ctx)
    376 , m_ctx(ctx)
    377 {
    378 size_t bufferSize = sizeof(dwImageCPU) * m_props.levelCount;
    379
    380 for (uint32_t level = 0; level < m_props.levelCount; ++level)
    381 {
    382 dwImageProperties& prop = m_props.levelProps[level];
    383
    384 dwImageProperties cpuProp = prop;
    385 cpuProp.type = DW_IMAGE_CPU;
    386
    387 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandleCPU[level], cpuProp, ctx));
    388 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerToCPU[level], &prop, DW_IMAGE_CPU, ctx));
    389 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerFromCPU[level], &cpuProp, prop.type, ctx));
    390
    391 size_t elementSize = 0;
    392 uint32_t planeChannelCount[DW_MAX_IMAGE_PLANES]{};
    393 dwVector2ui planeSize[DW_MAX_IMAGE_PLANES]{};
    394
    395 FRWK_CHECK_DW_ERROR(dwImage_getDataLayout(&elementSize, &m_planeCount[level], planeChannelCount, planeSize, &cpuProp));
    396
    397 // Compute buffer size needed for transfer
    398 for (size_t i = 0; i < m_planeCount[level]; i++)
    399 {
    400 bufferSize += (elementSize * planeSize[i].x * planeChannelCount[i]) * planeSize[i].y;
    401 }
    402 }
    403
    404 m_pyramidImage.levelCount = m_props.levelCount;
    405 initBuffer(bufferSize);
    406 }
    407
    408 ~ChannelPacket() override
    409 {
    410 for (uint32_t level = 0; level < m_pyramidImage.levelCount; ++level)
    411 {
    412 dwImage_destroy(m_imageHandleCPU[level]);
    413 dwImageStreamer_release(m_streamerToCPU[level]);
    414 dwImageStreamer_release(m_streamerFromCPU[level]);
    415 }
    416 }
    417
    418 // Serializes the frame before transmission
    419 void serializeImpl() override
    420 {
    421 size_t written = 0;
    422
    423 for (uint32_t i = 0; i < m_pyramidImage.levelCount; i++)
    424 {
    425 dwImageHandle_t recvImage = nullptr;
    426 dwImageHandle_t* returnedImage = nullptr;
    427
    428 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_pyramidImage.levelImages[i], m_streamerToCPU[i]));
    429 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImage, 0, m_streamerToCPU[i]));
    430
    431 dwImageCPU* cpuImage = nullptr;
    432 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, recvImage));
    433
    434 memcpy(m_buffer.get() + written, cpuImage, sizeof(dwImageCPU));
    435 written += sizeof(dwImageCPU);
    436
    437 for (size_t j = 0; j < m_planeCount[i]; j++)
    438 {
    439 size_t planeSize = cpuImage->pitch[j] * cpuImage->prop.height;
    440 memcpy(m_buffer.get() + written, cpuImage->data[j], planeSize);
    441 written += planeSize;
    442 }
    443
    444 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImage, m_streamerToCPU[i]));
    445 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerToCPU[i]));
    446 }
    447 }
    448
    449 // Deserializes the frame before transmission
    450 void deserialize(size_t) override
    451 {
    452 size_t read = 0;
    453
    454 for (uint32_t i = 0; i < m_pyramidImage.levelCount; i++)
    455 {
    456 dwImageCPU recvImage{};
    457 memcpy(&recvImage, m_buffer.get() + read, sizeof(dwImageCPU));
    458 read += sizeof(dwImageCPU);
    459
    460 dwImageCPU* cpuImage = nullptr;
    461 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, m_imageHandleCPU[i]));
    462
    463 for (size_t j = 0; j < m_planeCount[i]; j++)
    464 {
    465 size_t planeSize = cpuImage->pitch[j] * cpuImage->prop.height;
    466 memcpy(cpuImage->data[j], m_buffer.get() + read, planeSize);
    467 read += planeSize;
    468 }
    469
    470 dwImageHandle_t recvImageHandle = nullptr;
    471 dwImageHandle_t* returnedImage = nullptr;
    472
    473 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_imageHandleCPU[i], m_streamerFromCPU[i]));
    474 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImageHandle, 0, m_streamerFromCPU[i]));
    475
    476 dwImage_copyConvert(m_pyramidImage.levelImages[i], recvImageHandle, m_ctx);
    477 dwImage_setMetaData(&recvImage.prop.meta, m_pyramidImage.levelImages[i]);
    478 dwImage_setTimestamp(recvImage.timestamp_us, m_pyramidImage.levelImages[i]);
    479
    480 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImageHandle, m_streamerFromCPU[i]));
    481 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerFromCPU[i]));
    482 }
    483 }
    484
    485private:
    486 size_t m_planeCount[DW_PYRAMID_LEVEL_MAX_COUNT]{0};
    487 dwImageStreamerHandle_t m_streamerToCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
    488 dwImageStreamerHandle_t m_streamerFromCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
    489 dwImageHandle_t m_imageHandleCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
    490 dwContextHandle_t m_ctx = DW_NULL_HANDLE;
    491};
    492
    495{
    496public:
    498 {
    499 auto* props = specimen.getData<dwFeatureNccScores>();
    500 if (props)
    501 {
    502 m_ncc.size = props->size;
    505 }
    506 else
    507 {
    508 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    509 }
    510 }
    511
    513 {
    514 cudaFree(m_ncc.d_nccScores);
    515 }
    516
    518 {
    519 return GenericData(&m_dispatchNcc);
    520 }
    521
    522protected:
    525};
    526
    527template <>
    529{
    530public:
    531 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
    532 : FeatureNccScoresPacket(specimen)
    533 {
    534 initBuffer(m_ncc.size);
    535 }
    536
    537 // Serializes the frame before transmission
    538 void serializeImpl() override
    539 {
    540#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    541 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get(), m_ncc.d_nccScores, m_ncc.size, cudaMemcpyDeviceToHost));
    542#endif
    543 }
    544
    545 // Deserializes the frame before transmission
    546 void deserialize(size_t) override
    547 {
    548#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    549 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_ncc.d_nccScores, m_buffer.get(), m_bufferSize, cudaMemcpyHostToDevice));
    550#endif
    551 }
    552};
    553
    555{
    556public:
    557 FeatureArrayPacket(const GenericData& specimen, dwContextHandle_t ctx)
    558 {
    559 auto* props = specimen.getData<dwFeatureArray>();
    560 if (props)
    561 {
    562 dwStatus ret = dwFeatureArray_create(&m_featureArray,
    563 props->maxFeatures,
    564 props->memoryType,
    565 ctx);
    566 if (ret != DW_SUCCESS)
    567 {
    568 throw Exception(DW_BAD_ALLOC, "FeatureArrayPacket: cannot allocate packet");
    569 }
    571 }
    572 else
    573 {
    574 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    575 }
    576 }
    577
    579 {
    580 dwFeatureArray_destroy(m_featureArrayOrig);
    581 }
    582
    584 {
    586 }
    587
    588protected:
    589 dwFeatureArray m_featureArray{};
    590 dwFeatureArray m_featureArrayOrig{};
    591};
    592
    594template <>
    595class ChannelPacket<dwFeatureArray> : public FeatureArrayPacket, public ChannelSocketPacketBase
    596{
    597public:
    598 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    599 : FeatureArrayPacket(specimen, ctx)
    600 {
    601 m_propIndex[0] = sizeof(dwFeatureArray);
    602 m_propIndex[1] = m_propIndex[0] + sizeof(dwFeature2DStatus) * m_featureArray.maxFeatures; // statuses
    603 m_propIndex[2] = m_propIndex[1] + sizeof(uint32_t) * m_featureArray.maxFeatures; // ages
    604 m_propIndex[3] = m_propIndex[2] + sizeof(float32_t) * m_featureArray.maxFeatures; // scales
    605 m_propIndex[4] = m_propIndex[3] + sizeof(uint32_t) * m_featureArray.maxFeatures; // ids
    606 m_propIndex[5] = m_propIndex[4] + sizeof(uint32_t) * m_featureArray.maxFeatures; // newToOldMap
    607 m_propIndex[6] = m_propIndex[5] + sizeof(dwVector2f) * m_featureArray.maxFeatures; // locations
    608 m_propIndex[7] = m_propIndex[6] + sizeof(uint32_t); // featureCount
    609 m_propIndex[8] = m_propIndex[7] + sizeof(uint32_t); // validTrackedCount
    610
    611 initBuffer(m_propIndex[8]);
    612 }
    613
    614 // Serializes the frame before transmission
    615 void serializeImpl() override
    616 {
    617 static_assert(sizeof(dwFeatureArray) == 80, "dwFeatureArray size has changed, update serialization");
    618
    619 memcpy(m_buffer.get(), &m_featureArray, m_propIndex[0]);
    620
    621 if (m_featureArray.memoryType == DW_MEMORY_TYPE_CUDA)
    622 {
    623#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    624 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[0], m_featureArray.statuses, m_propIndex[1] - m_propIndex[0], cudaMemcpyDeviceToHost));
    625 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[1], m_featureArray.ages, m_propIndex[2] - m_propIndex[1], cudaMemcpyDeviceToHost));
    626 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[2], m_featureArray.scales, m_propIndex[3] - m_propIndex[2], cudaMemcpyDeviceToHost));
    627 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[3], m_featureArray.ids, m_propIndex[4] - m_propIndex[3], cudaMemcpyDeviceToHost));
    628 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[4], m_featureArray.newToOldMap, m_propIndex[5] - m_propIndex[4], cudaMemcpyDeviceToHost));
    629 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[5], m_featureArray.locations, m_propIndex[6] - m_propIndex[5], cudaMemcpyDeviceToHost));
    630 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[6], m_featureArray.featureCount, m_propIndex[7] - m_propIndex[6], cudaMemcpyDeviceToHost));
    631 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_buffer.get() + m_propIndex[7], m_featureArray.validTrackedCount, m_propIndex[8] - m_propIndex[7], cudaMemcpyDeviceToHost));
    632#endif
    633 }
    634 else if (m_featureArray.memoryType == DW_MEMORY_TYPE_CPU ||
    635 m_featureArray.memoryType == DW_MEMORY_TYPE_PINNED)
    636 {
    637 memcpy(m_buffer.get() + m_propIndex[0], m_featureArray.statuses, m_propIndex[1] - m_propIndex[0]);
    638 memcpy(m_buffer.get() + m_propIndex[1], m_featureArray.ages, m_propIndex[2] - m_propIndex[1]);
    639 memcpy(m_buffer.get() + m_propIndex[2], m_featureArray.scales, m_propIndex[3] - m_propIndex[2]);
    640 memcpy(m_buffer.get() + m_propIndex[3], m_featureArray.ids, m_propIndex[4] - m_propIndex[3]);
    641 memcpy(m_buffer.get() + m_propIndex[4], m_featureArray.newToOldMap, m_propIndex[5] - m_propIndex[4]);
    642 memcpy(m_buffer.get() + m_propIndex[5], m_featureArray.locations, m_propIndex[6] - m_propIndex[5]);
    643 memcpy(m_buffer.get() + m_propIndex[6], m_featureArray.featureCount, m_propIndex[7] - m_propIndex[6]);
    644 memcpy(m_buffer.get() + m_propIndex[7], m_featureArray.validTrackedCount, m_propIndex[8] - m_propIndex[7]);
    645 }
    646 }
    647
    648 // Deserializes the frame before transmission
    649 void deserialize(size_t) override
    650 {
    651 static_assert(sizeof(dwFeatureArray) == 80, "dwFeatureArray size has changed, update deserialization");
    652
    653 auto array = reinterpret_cast<dwFeatureArray*>(m_buffer.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    654 if (m_featureArray.maxFeatures != array->maxFeatures)
    655 {
    656 throw Exception(DW_INVALID_ARGUMENT, "ChannelPacket<dwFeatureArray>: deserialize: maxFeatures does not match");
    657 }
    658
    659 if (m_featureArray.memoryType == DW_MEMORY_TYPE_CUDA)
    660 {
    661#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    662 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.statuses, m_buffer.get() + m_propIndex[0], m_propIndex[1] - m_propIndex[0], cudaMemcpyHostToDevice));
    663 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.ages, m_buffer.get() + m_propIndex[1], m_propIndex[2] - m_propIndex[1], cudaMemcpyHostToDevice));
    664 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.scales, m_buffer.get() + m_propIndex[2], m_propIndex[3] - m_propIndex[2], cudaMemcpyHostToDevice));
    665 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.ids, m_buffer.get() + m_propIndex[3], m_propIndex[4] - m_propIndex[3], cudaMemcpyHostToDevice));
    666 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.newToOldMap, m_buffer.get() + m_propIndex[4], m_propIndex[5] - m_propIndex[4], cudaMemcpyHostToDevice));
    667 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.locations, m_buffer.get() + m_propIndex[5], m_propIndex[6] - m_propIndex[5], cudaMemcpyHostToDevice));
    668 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.featureCount, m_buffer.get() + m_propIndex[6], m_propIndex[7] - m_propIndex[6], cudaMemcpyHostToDevice));
    669 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureArray.validTrackedCount, m_buffer.get() + m_propIndex[7], m_propIndex[8] - m_propIndex[7], cudaMemcpyHostToDevice));
    670#endif
    671 }
    672 else if (m_featureArray.memoryType == DW_MEMORY_TYPE_CPU ||
    673 m_featureArray.memoryType == DW_MEMORY_TYPE_PINNED)
    674 {
    675 memcpy(m_featureArray.statuses, m_buffer.get() + m_propIndex[0], m_propIndex[1] - m_propIndex[0]);
    676 memcpy(m_featureArray.ages, m_buffer.get() + m_propIndex[1], m_propIndex[2] - m_propIndex[1]);
    677 memcpy(m_featureArray.scales, m_buffer.get() + m_propIndex[2], m_propIndex[3] - m_propIndex[2]);
    678 memcpy(m_featureArray.ids, m_buffer.get() + m_propIndex[3], m_propIndex[4] - m_propIndex[3]);
    679 memcpy(m_featureArray.newToOldMap, m_buffer.get() + m_propIndex[4], m_propIndex[5] - m_propIndex[4]);
    680 memcpy(m_featureArray.locations, m_buffer.get() + m_propIndex[5], m_propIndex[6] - m_propIndex[5]);
    681 memcpy(m_featureArray.featureCount, m_buffer.get() + m_propIndex[6], m_propIndex[7] - m_propIndex[6]);
    682 memcpy(m_featureArray.validTrackedCount, m_buffer.get() + m_propIndex[7], m_propIndex[8] - m_propIndex[7]);
    683 }
    684
    685 m_featureArray.timeIdx = array->timeIdx;
    686 }
    687
    688private:
    689 size_t m_propIndex[9] = {};
    690};
    691
    694{
    695public:
    696 FeatureHistoryArrayPacket(const GenericData& specimen, dwContextHandle_t ctx)
    697 {
    698 auto* props = specimen.getData<dwFeatureHistoryArray>();
    699 if (props)
    700 {
    701 dwStatus ret = dwFeatureHistoryArray_create(&m_featureHistoryArray,
    702 props->maxFeatures,
    703 props->maxHistory,
    704 props->memoryType,
    705 ctx);
    706 if (ret != DW_SUCCESS)
    707 {
    708 throw Exception(DW_BAD_ALLOC, "FeatureHistoryArrayPacket: cannot allocate packet");
    709 }
    711 }
    712 else
    713 {
    714 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    715 }
    716 }
    717
    719 {
    720 dwFeatureHistoryArray_destroy(m_featureHistoryArrayOrig);
    721 }
    722
    724 {
    726 }
    727
    728protected:
    729 dwFeatureHistoryArray m_featureHistoryArray{};
    730 dwFeatureHistoryArray m_featureHistoryArrayOrig{};
    731};
    732
    733template <>
    734class ChannelPacket<dwFeatureHistoryArray> : public FeatureHistoryArrayPacket, public ChannelSocketPacketBase
    735{
    736public:
    737 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    738 : FeatureHistoryArrayPacket(specimen, ctx)
    739 {
    740 initBuffer(sizeof(dwFeatureHistoryArray) + m_featureHistoryArray.bytes);
    741 }
    742
    743 // Serializes the frame before transmission
    744 void serializeImpl() override
    745 {
    746 static_assert(sizeof(dwFeatureHistoryArray) == 104, "dwFeatureHistoryArray size has changed, update serialization");
    747
    748 uint8_t* ptr = m_buffer.get() + sizeof(dwFeatureHistoryArray);
    749 memcpy(m_buffer.get(), &m_featureHistoryArray, sizeof(dwFeatureHistoryArray));
    750
    751 if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CUDA)
    752 {
    753#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    754 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(ptr, m_featureHistoryArray.data, m_featureHistoryArray.bytes, cudaMemcpyDeviceToHost));
    755#endif
    756 }
    757 else if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CPU ||
    758 m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_PINNED)
    759 {
    760 memcpy(ptr, m_featureHistoryArray.data, m_featureHistoryArray.bytes);
    761 }
    762 }
    763
    764 // Deserializes the frame before transmission
    765 void deserialize(size_t) override
    766 {
    767 static_assert(sizeof(dwFeatureHistoryArray) == 104, "dwFeatureHistoryArray size has changed, update deserialization");
    768
    769 auto array = reinterpret_cast<dwFeatureHistoryArray*>(m_buffer.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    770 if (m_featureHistoryArray.maxFeatures != array->maxFeatures || m_featureHistoryArray.maxHistory != array->maxHistory)
    771 {
    772 throw Exception(DW_INVALID_ARGUMENT, "ChannelPacket<dwFeatureHistoryArray>: deserialize: maxFeatures or maxHistory does not match");
    773 }
    774
    775 uint8_t* ptr = m_buffer.get() + sizeof(dwFeatureHistoryArray);
    776 if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CUDA)
    777 {
    778#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    779 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_featureHistoryArray.data, ptr, m_featureHistoryArray.bytes, cudaMemcpyHostToDevice));
    780#endif
    781 }
    782 else if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CPU ||
    783 m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_PINNED)
    784 {
    785 memcpy(m_featureHistoryArray.data, ptr, m_featureHistoryArray.bytes);
    786 }
    787
    788 m_featureHistoryArray.currentTimeIdx = array->currentTimeIdx;
    789 }
    790};
    791
    793// dwSensorRawData packet for channel socket
    794template <>
    796{
    797public:
    798 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    799 : ChannelPacket(*specimen.getData<dwSensorNodeRawData>(), ctx)
    800 {
    801 auto* frame = getFrame();
    802 m_frame = GenericData(frame);
    803 }
    804
    805 ChannelPacket(dwSensorNodeRawData& ref, dwContextHandle_t)
    806 : ChannelPacketBase(ref.size)
    807 , m_data(ref)
    808 {
    809 }
    810
    812 {
    813 return &m_data;
    814 }
    815
    816 void setBufferSize(size_t bufferSize)
    817 {
    818 m_bufferSize = bufferSize;
    819 }
    820
    821 // Serializes the frame before transmission
    822 void serializeImpl() final
    823 {
    824 //copy packet data into buffer
    825 memcpy(m_buffer.get(), &m_data, m_bufferSize);
    826 }
    827
    828 // Deserializes the frame after transmission
    829 void deserialize(size_t) final
    830 {
    831 //retrieve packet data from buffer
    832 memcpy(&m_data, m_buffer.get(), m_bufferSize);
    833 }
    834
    835private:
    836 dwSensorNodeRawData m_data{};
    837};
    838
    840// dwRadarScan packet for channel socket
    841template <>
    842class ChannelPacket<dwRadarScan> : public ChannelPacketBase
    843{
    844public:
    845 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    846 : ChannelPacket(*specimen.getData<dwRadarScan>(), ctx)
    847 {
    848 auto* frame = getFrame();
    849 m_frame = GenericData(frame);
    850 }
    851
    852 ChannelPacket(dwRadarScan& ref, dwContextHandle_t)
    853 : m_data(ref)
    854 {
    855 size_t bufferSize = std::max(static_cast<size_t>(DW_RADARSCAN_MINIMUM_PAYLOAD_SIZE),
    856 (std::max(sizeof(dwRadarStatus), std::max(sizeof(dwRadarTrack), sizeof(dwRadarDetection))))) *
    857 ref.numReturns;
    858 m_scanData.reset(new uint8_t[bufferSize]);
    859 m_data.data = m_scanData.get();
    860
    861 bufferSize += (sizeof(dwRadarDetectionMisc) + sizeof(dwRadarDetectionStdDev) + sizeof(dwRadarDetectionQuality) +
    862 sizeof(dwRadarDetectionProbability) + sizeof(dwRadarDetectionFFTPatch)) *
    863 ref.numReturns;
    864 bufferSize += sizeof(dwRadarScan);
    865
    866 m_scanDetectionMisc = std::make_unique<uint8_t[]>(sizeof(dwRadarDetectionMisc) * ref.numReturns);
    867 m_scanDetectionStdDev = std::make_unique<uint8_t[]>(sizeof(dwRadarDetectionStdDev) * ref.numReturns);
    868 m_scanDetectionQuality = std::make_unique<uint8_t[]>(sizeof(dwRadarDetectionQuality) * ref.numReturns);
    869 m_scanDetectionProbability = std::make_unique<uint8_t[]>(sizeof(dwRadarDetectionProbability) * ref.numReturns);
    870 m_scanDetectionFFTPatch = std::make_unique<uint8_t[]>(sizeof(dwRadarDetectionFFTPatch) * ref.numReturns);
    871
    872 m_data.detectionMisc = reinterpret_cast<const dwRadarDetectionMisc*>(m_scanDetectionMisc.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    873 m_data.detectionStdDev = reinterpret_cast<const dwRadarDetectionStdDev*>(m_scanDetectionStdDev.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    874 m_data.detectionQuality = reinterpret_cast<const dwRadarDetectionQuality*>(m_scanDetectionQuality.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    875 m_data.detectionProbability = reinterpret_cast<const dwRadarDetectionProbability*>(m_scanDetectionProbability.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    876 m_data.detectionFFTPatch = reinterpret_cast<const dwRadarDetectionFFTPatch*>(m_scanDetectionFFTPatch.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    877
    878 initBuffer(bufferSize);
    879 }
    880
    881 dwRadarScan* getFrame()
    882 {
    883 return &m_data;
    884 }
    885
    886 void setBufferSize(size_t bufferSize)
    887 {
    888 m_bufferSize = bufferSize;
    889 }
    890
    891 // Serializes the frame before transmission
    892 size_t serialize() final
    893 {
    894 size_t bufferSize = getRadarDataSize(m_data);
    895 size_t offset = 0;
    896
    897 memcpy(m_buffer.get(), &m_data, sizeof(dwRadarScan));
    898 offset += sizeof(dwRadarScan);
    899 memcpy(m_buffer.get() + offset, m_data.data, bufferSize);
    900 offset += bufferSize;
    901 memcpy(m_buffer.get() + offset, m_data.detectionMisc, sizeof(dwRadarDetectionMisc) * m_data.numReturns);
    902 offset += sizeof(dwRadarDetectionMisc) * m_data.numReturns;
    903 memcpy(m_buffer.get() + offset, m_data.detectionStdDev, sizeof(dwRadarDetectionStdDev) * m_data.numReturns);
    904 offset += sizeof(dwRadarDetectionStdDev) * m_data.numReturns;
    905 memcpy(m_buffer.get() + offset, m_data.detectionQuality, sizeof(dwRadarDetectionQuality) * m_data.numReturns);
    906 offset += sizeof(dwRadarDetectionQuality) * m_data.numReturns;
    907 memcpy(m_buffer.get() + offset, m_data.detectionProbability, sizeof(dwRadarDetectionProbability) * m_data.numReturns);
    908 offset += sizeof(dwRadarDetectionProbability) * m_data.numReturns;
    909 memcpy(m_buffer.get() + offset, m_data.detectionFFTPatch, sizeof(dwRadarDetectionFFTPatch) * m_data.numReturns);
    910 offset += sizeof(dwRadarDetectionFFTPatch) * m_data.numReturns;
    911
    912 return offset;
    913 }
    914
    915 // Deserializes the frame after transmission
    916 void deserialize(size_t) final
    917 {
    918 size_t offset = 0;
    919 // retrieve packet data from buffer
    920 memcpy(&m_data, m_buffer.get(), sizeof(dwRadarScan));
    921 offset += sizeof(dwRadarScan);
    922 m_data.data = m_buffer.get() + offset;
    923 offset += getRadarDataSize(m_data);
    924 m_data.detectionMisc = reinterpret_cast<const dwRadarDetectionMisc*>(m_buffer.get() + offset); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    925 offset += sizeof(dwRadarDetectionMisc) * m_data.numReturns;
    926 m_data.detectionStdDev = reinterpret_cast<const dwRadarDetectionStdDev*>(m_buffer.get() + offset); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    927 offset += sizeof(dwRadarDetectionStdDev) * m_data.numReturns;
    928 m_data.detectionQuality = reinterpret_cast<const dwRadarDetectionQuality*>(m_buffer.get() + offset); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    929 offset += sizeof(dwRadarDetectionQuality) * m_data.numReturns;
    930 m_data.detectionProbability = reinterpret_cast<const dwRadarDetectionProbability*>(m_buffer.get() + offset); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    931 offset += sizeof(dwRadarDetectionProbability) * m_data.numReturns;
    932 m_data.detectionFFTPatch = reinterpret_cast<const dwRadarDetectionFFTPatch*>(m_buffer.get() + offset); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    933 offset += sizeof(dwRadarDetectionFFTPatch) * m_data.numReturns;
    934 }
    935
    936private:
    937 size_t getRadarDataSize(const dwRadarScan& radarScan)
    938 {
    939 size_t bufferSize = 0;
    940 switch (radarScan.scanType.returnType)
    941 {
    942 case DW_RADAR_RETURN_TYPE_DETECTION:
    943 bufferSize = sizeof(dwRadarDetection) * radarScan.numReturns;
    944 break;
    945 case DW_RADAR_RETURN_TYPE_TRACK:
    946 bufferSize = std::max(sizeof(dwRadarTrack), static_cast<size_t>(DW_RADARSCAN_MINIMUM_PAYLOAD_SIZE)) * radarScan.numReturns;
    947 break;
    948 case DW_RADAR_RETURN_TYPE_STATUS:
    949 bufferSize = sizeof(dwRadarStatus) * radarScan.numReturns;
    950 break;
    951 case DW_RADAR_RETURN_TYPE_COUNT:
    952 default:
    953 throw Exception(DW_INVALID_ARGUMENT, "[ChannelPacketImpl]: Invalid radarScan return type");
    954 }
    955 return bufferSize;
    956 }
    957
    958 dwRadarScan m_data{};
    959 std::unique_ptr<uint8_t[]> m_scanData;
    960 std::unique_ptr<uint8_t[]> m_scanDetectionMisc;
    961 std::unique_ptr<uint8_t[]> m_scanDetectionStdDev;
    962 std::unique_ptr<uint8_t[]> m_scanDetectionQuality;
    963 std::unique_ptr<uint8_t[]> m_scanDetectionProbability;
    964 std::unique_ptr<uint8_t[]> m_scanDetectionFFTPatch;
    965};
    966
    968// dwLidarDecodedPacket packet for channel socket
    969template <>
    970class ChannelPacket<dwLidarDecodedPacket> : public ChannelPacketBase
    971{
    972public:
    973 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    974 : ChannelPacket(*specimen.getData<dwLidarDecodedPacket>(), ctx)
    975 {
    976 auto* frame = getFrame();
    977 m_frame = GenericData(frame);
    978 }
    979
    980 ChannelPacket(dwLidarDecodedPacket& ref, dwContextHandle_t)
    981 : m_data(ref)
    982 {
    983 size_t bufferSize = sizeof(dwLidarDecodedPacket) + sizeof(dwLidarPointRTHI) * ref.maxPoints + sizeof(dwLidarPointXYZI) * ref.maxPoints;
    984
    985 m_pointsRTHI = std::make_unique<uint8_t[]>(sizeof(dwLidarPointRTHI) * ref.maxPoints);
    986 m_pointsXYZI = std::make_unique<uint8_t[]>(sizeof(dwLidarPointXYZI) * ref.maxPoints);
    987
    988 m_data.pointsRTHI = reinterpret_cast<const dwLidarPointRTHI*>(m_pointsRTHI.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    989 m_data.pointsXYZI = reinterpret_cast<const dwLidarPointXYZI*>(m_pointsXYZI.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    990
    991 initBuffer(bufferSize);
    992 }
    993
    994 dwLidarDecodedPacket* getFrame()
    995 {
    996 return &m_data;
    997 }
    998
    999 void setBufferSize(size_t bufferSize)
    1000 {
    1001 m_bufferSize = bufferSize;
    1002 }
    1003
    1004 // Serializes the frame before transmission
    1005 void serializeImpl() final
    1006 {
    1007 //copy packet data into buffer
    1008 size_t header = sizeof(dwLidarDecodedPacket);
    1009 memcpy(m_buffer.get(), &m_data, header);
    1010 memcpy(m_buffer.get() + header, m_data.pointsRTHI, sizeof(dwLidarPointRTHI) * m_data.nPoints);
    1011 header += sizeof(dwLidarPointRTHI) * m_data.nPoints;
    1012 memcpy(m_buffer.get() + header, m_data.pointsXYZI, sizeof(dwLidarPointXYZI) * m_data.nPoints);
    1013 }
    1014
    1015 // Deserializes the frame after transmission
    1016 void deserialize(size_t) final
    1017 {
    1018 //retrieve packet data from buffer
    1019 memcpy(&m_data, m_buffer.get(), sizeof(dwLidarDecodedPacket));
    1020 m_data.pointsRTHI = reinterpret_cast<const dwLidarPointRTHI*>(m_buffer.get() + // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    1021 sizeof(dwLidarDecodedPacket));
    1022 m_data.pointsXYZI = reinterpret_cast<const dwLidarPointXYZI*>(m_buffer.get() + sizeof(dwLidarDecodedPacket) + // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    1023 sizeof(dwLidarPointRTHI) * m_data.nPoints);
    1024 }
    1025
    1026private:
    1027 dwLidarDecodedPacket m_data{};
    1028 std::unique_ptr<uint8_t[]> m_pointsRTHI;
    1029 std::unique_ptr<uint8_t[]> m_pointsXYZI;
    1030};
    1031
    1034{
    1035public:
    1036 EgomotionStateHandlePacket(const GenericData& specimen, dwContextHandle_t ctx)
    1037 {
    1038 auto* props = specimen.getData<dwEgomotionStateParams>();
    1039 if (props)
    1040 {
    1041 dwEgomotionState_createEmpty(&m_egomotionState, *props, ctx);
    1043 }
    1044 else
    1045 {
    1046 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    1047 }
    1048 }
    1049
    1051 {
    1052 dwEgomotionState_release(m_egomotionState);
    1053 }
    1054
    1056 {
    1058 }
    1059
    1060protected:
    1061 dwEgomotionStateHandle_t m_egomotionState = DW_NULL_HANDLE;
    1062 dwEgomotionStateHandle_t m_dispatchEgomotionState = DW_NULL_HANDLE;
    1063};
    1064
    1065template <>
    1066class ChannelPacket<dwEgomotionStateHandle_t> : public EgomotionStateHandlePacket, public ChannelSocketPacketBase
    1067{
    1068public:
    1069 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    1070 : EgomotionStateHandlePacket(specimen, ctx)
    1071 {
    1072 dwEgomotionState_getMaxNumBytes(&m_numBytes, m_egomotionState);
    1073 m_bufferSize = m_numBytes + sizeof(m_numBytes);
    1074 initBuffer(m_bufferSize);
    1075 }
    1076
    1077 ChannelPacket(dwEgomotionStateParams& params, dwContextHandle_t ctx)
    1078 : ChannelPacket(GenericData(&params), ctx)
    1079 {
    1080 }
    1081
    1082 dwEgomotionStateHandle_t* getFrame()
    1083 {
    1084 return &m_dispatchEgomotionState;
    1085 }
    1086
    1088 {
    1089 size_t numBytes = 0;
    1090 memcpy(&numBytes, m_buffer.get(), sizeof(numBytes));
    1091 return numBytes;
    1092 }
    1093
    1094 void serializeImpl() final
    1095 {
    1096 // Serialize state at producer side
    1097 dwEgomotionState_serialize(&m_numBytes,
    1098 m_buffer.get() + sizeof(m_numBytes),
    1099 m_bufferSize - sizeof(m_numBytes),
    1100 m_dispatchEgomotionState);
    1101 memcpy(m_buffer.get(), &m_numBytes, sizeof(m_numBytes));
    1102 }
    1103
    1104 void deserialize(size_t) final
    1105 {
    1106 memcpy(&m_numBytes, m_buffer.get(), sizeof(m_numBytes));
    1107 if (m_numBytes > m_bufferSize - sizeof(m_numBytes))
    1108 {
    1109 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwEgomotionStateHandle_t>: deserialize: recv packet size mismatch available buffer size.");
    1110 }
    1111 // Deserialize state at consumer side
    1112 dwEgomotionState_deserialize(m_buffer.get() + sizeof(m_numBytes),
    1113 m_numBytes,
    1114 m_dispatchEgomotionState);
    1115 }
    1116
    1117private:
    1118 size_t m_numBytes = 0;
    1119};
    1120
    1123{
    1124public:
    1126 {
    1127 auto* props = specimen.getData<dwPointCloud>();
    1128 if (props != nullptr)
    1129 {
    1130 m_data = *props;
    1131 m_data.points = nullptr;
    1132 dwStatus ret = dwPointCloud_createBuffer(&m_data);
    1133 if (ret != DW_SUCCESS)
    1134 {
    1135 throw Exception(DW_BAD_ALLOC, "PointCloudPacket: cannot allocate packet");
    1136 }
    1137
    1138 m_dataOri = m_data;
    1139 }
    1140 else
    1141 {
    1142 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
    1143 }
    1144 }
    1145
    1147 {
    1148 dwPointCloud_destroyBuffer(&m_dataOri);
    1149 }
    1150
    1152 {
    1153 return GenericData(&m_data);
    1154 }
    1155
    1156protected:
    1157 dwPointCloud m_data{};
    1158 dwPointCloud m_dataOri{};
    1159};
    1160
    1161// PointCloud packet for channel socket
    1162template <>
    1163class ChannelPacket<dwPointCloud> : public PointCloudPacket, public ChannelSocketPacketBase
    1164{
    1165public:
    1166 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
    1167 : PointCloudPacket(specimen)
    1168 {
    1169 if (m_data.numAuxChannels > 0)
    1170 {
    1171 throw Exception(DW_NOT_IMPLEMENTED, "ChannelPacket<dwPointCloud>: time to add support for aux data: DRIV-8273");
    1172 }
    1173
    1174 m_objectSize = getFormatSize(m_data.format);
    1175 m_maxCount = m_data.capacity;
    1176 m_headerSize = sizeof(dwPointCloud);
    1177
    1178 initBuffer(m_headerSize + m_maxCount * m_objectSize);
    1179 }
    1180
    1181 // Serializes the frame before transmission
    1182 void serializeImpl() final
    1183 {
    1184 uint8_t* ptr = m_buffer.get() + m_headerSize;
    1185 memcpy(m_buffer.get(), &m_data, m_headerSize);
    1186 if (m_data.type == DW_MEMORY_TYPE_CUDA)
    1187 {
    1188#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    1189 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(ptr, m_data.points, m_data.size * m_objectSize, cudaMemcpyDeviceToHost));
    1190#endif
    1191 }
    1192 else if (m_data.type == DW_MEMORY_TYPE_CPU ||
    1193 m_data.type == DW_MEMORY_TYPE_PINNED)
    1194 {
    1195 memcpy(ptr, m_data.points, m_data.size * m_objectSize);
    1196 }
    1197 }
    1198
    1199 void deserialize(size_t) final
    1200 {
    1201 uint8_t* ptr = m_buffer.get() + m_headerSize;
    1202 memcpy(&m_data, m_buffer.get(), m_headerSize);
    1203
    1204 if (m_data.type == DW_MEMORY_TYPE_CUDA)
    1205 {
    1206 m_data.points = m_dataOri.points;
    1207#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8357
    1208 FRWK_CHECK_CUDA_ERROR(cudaMemcpy(m_data.points, ptr, m_data.size * m_objectSize, cudaMemcpyHostToDevice));
    1209#endif
    1210 }
    1211 else if (m_data.type == DW_MEMORY_TYPE_CPU ||
    1212 m_data.type == DW_MEMORY_TYPE_PINNED)
    1213 {
    1214 m_data.points = static_cast<void*>(m_buffer.get() + m_headerSize);
    1215 }
    1216 }
    1217
    1218 static size_t getFormatSize(dwPointCloudFormat format)
    1219 {
    1220 uint32_t formatSize = 0;
    1221 switch (format)
    1222 {
    1223 case DW_POINTCLOUD_FORMAT_XYZI:
    1224 formatSize = sizeof(dwLidarPointXYZI);
    1225 break;
    1226 case DW_POINTCLOUD_FORMAT_RTHI:
    1227 formatSize = sizeof(dwLidarPointRTHI);
    1228 break;
    1229 default:
    1230 throw std::runtime_error("ChannelPacket<dwPointCloud>: unknown dwPointCloudFormat");
    1231 }
    1232 return formatSize;
    1233 }
    1234
    1235private:
    1236 size_t m_headerSize{};
    1237 size_t m_objectSize{};
    1238 size_t m_maxCount{};
    1239};
    1240
    1242// dwLidarPacketsArray for channel socket
    1243template <>
    1245{
    1246public:
    1247 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    1248 : ChannelPacket(*specimen.getData<dwLidarPacketsArray>(), ctx)
    1249 {
    1250 auto* frame = getFrame();
    1251 m_frame = GenericData(frame);
    1252 }
    1253
    1254 ChannelPacket(dwLidarPacketsArray& ref, dwContextHandle_t)
    1255 : m_data(ref)
    1256 {
    1257 m_headerSize = sizeof(dwLidarPacketsArray);
    1258 size_t lidarDecodedPacketsSize = m_data.maxPacketsPerSpin * sizeof(dwLidarDecodedPacket);
    1259 size_t pointsXYZISize = m_data.maxPacketsPerSpin * m_data.maxPointsPerPacket * sizeof(dwLidarPointXYZI);
    1260 size_t pointsRTHISize = m_data.maxPacketsPerSpin * m_data.maxPointsPerPacket * sizeof(dwLidarPointRTHI);
    1261
    1262 initBuffer(m_headerSize + lidarDecodedPacketsSize + pointsXYZISize + pointsRTHISize);
    1263
    1264 m_lidarPacketsPtr = reinterpret_cast<dwLidarDecodedPacket*>(m_buffer.get() + m_headerSize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    1265 m_pointsXYZIPtr = reinterpret_cast<dwLidarPointXYZI*>(m_buffer.get() + m_headerSize + lidarDecodedPacketsSize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    1266 m_pointsRTHIPtr = reinterpret_cast<dwLidarPointRTHI*>(m_buffer.get() + m_headerSize + lidarDecodedPacketsSize + pointsXYZISize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
    1267
    1268 m_data.packets = m_lidarPacketsPtr;
    1269 m_data.pointsXYZIArray = m_pointsXYZIPtr;
    1270 m_data.pointsRTHIArray = m_pointsRTHIPtr;
    1271 }
    1272
    1274 {
    1275 return &m_data;
    1276 }
    1277
    1278 // Serializes the frame before transmission
    1279 void serializeImpl() final
    1280 {
    1281 size_t lidarDecodedPacketsSize = m_data.packetSize * sizeof(dwLidarDecodedPacket);
    1282 size_t pointsXYZISize = m_data.packetSize * m_data.maxPointsPerPacket * sizeof(dwLidarPointXYZI);
    1283 size_t pointsRTHISize = m_data.packetSize * m_data.maxPointsPerPacket * sizeof(dwLidarPointRTHI);
    1284
    1285 memcpy(m_buffer.get(), &m_data, m_headerSize);
    1286
    1287 if (m_data.packets != m_lidarPacketsPtr)
    1288 {
    1289 memcpy(m_lidarPacketsPtr, m_data.packets, lidarDecodedPacketsSize);
    1290 }
    1291 if (m_data.pointsXYZIArray != m_pointsXYZIPtr)
    1292 {
    1293 memcpy(m_pointsXYZIPtr, m_data.pointsXYZIArray, pointsXYZISize);
    1294 }
    1295 if (m_data.pointsRTHIArray != m_pointsRTHIPtr)
    1296 {
    1297 memcpy(m_pointsRTHIPtr, m_data.pointsRTHIArray, pointsRTHISize);
    1298 }
    1299 }
    1300
    1301 void deserialize(size_t) final
    1302 {
    1303 memcpy(&m_data, m_buffer.get(), m_headerSize);
    1304 m_data.packets = m_lidarPacketsPtr;
    1305 m_data.pointsXYZIArray = m_pointsXYZIPtr;
    1306 m_data.pointsRTHIArray = m_pointsRTHIPtr;
    1307 for (size_t packetsIndex = 0; packetsIndex < m_data.packetSize; ++packetsIndex)
    1308 {
    1309 m_data.packets[packetsIndex].pointsXYZI = &(m_data.pointsXYZIArray[packetsIndex * m_data.maxPointsPerPacket]);
    1310 m_data.packets[packetsIndex].pointsRTHI = &(m_data.pointsRTHIArray[packetsIndex * m_data.maxPointsPerPacket]);
    1311 }
    1312 }
    1313
    1314private:
    1315 dwLidarPacketsArray m_data{};
    1316
    1317 size_t m_headerSize{};
    1318
    1319 dwLidarDecodedPacket* m_lidarPacketsPtr{};
    1320 dwLidarPointXYZI* m_pointsXYZIPtr{};
    1321 dwLidarPointRTHI* m_pointsRTHIPtr{};
    1322};
    1323
    1325template <>
    1327{
    1328public:
    1329 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
    1330 : ChannelPacket(*specimen.getData<dwTraceNodeData>(), ctx)
    1331 {
    1332 auto* frame = getFrame();
    1333 m_frame = GenericData(frame);
    1334 }
    1335
    1336 ChannelPacket(dwTraceNodeData& ref, dwContextHandle_t)
    1337 : m_data(ref), m_headerSize(sizeof(dwTraceNodeData)), m_maxDataSize(ref.maxDataSize)
    1338 {
    1339 initBuffer(m_headerSize + m_maxDataSize);
    1340 m_TraceData = m_buffer.get() + m_headerSize;
    1341 m_data.data = m_TraceData;
    1342 }
    1343
    1344 ~ChannelPacket() override = default;
    1345
    1347 {
    1348 return &m_data;
    1349 }
    1350
    1351 // Serializes the frame before transmission
    1352 void serializeImpl() final
    1353 {
    1354 // safety check. avoid error count caused memcpy failure
    1355 if (m_data.dataSize > m_maxDataSize)
    1356 {
    1357 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwTraceNodeData>: serializeImpl: send packet size mismatch buffer size.");
    1358 }
    1359 memcpy(m_buffer.get(), &m_data, m_headerSize);
    1360 if (m_data.data != m_TraceData && m_data.dataSize <= m_maxDataSize)
    1361 {
    1362 memcpy(m_TraceData, m_data.data, m_data.dataSize * sizeof(uint8_t)); //deep copy. only copy valid value
    1363 }
    1364 }
    1365
    1366 // Deserializes the frame before transmission
    1367 void deserialize(size_t) final
    1368 {
    1369 memcpy(&m_data, m_buffer.get(), m_headerSize);
    1370 // safety check. avoid error count caused read failure
    1371 if (m_data.dataSize > m_maxDataSize)
    1372 {
    1373 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwTraceNodeData>: deserialize: recv packet size mismatch buffer size.");
    1374 }
    1375 m_data.data = m_buffer.get() + m_headerSize;
    1376 }
    1377
    1378private:
    1379 dwTraceNodeData m_data{};
    1380 size_t m_headerSize{};
    1381 size_t m_maxDataSize{};
    1382 uint8_t* m_TraceData;
    1383};
    1384
    1385// dwCodecPacket
    1388{
    1389public:
    1390 CodecPacket(const GenericData& specimen)
    1391 {
    1392 auto* size = specimen.getData<size_t>();
    1393 if (size != nullptr)
    1394 {
    1395 m_dataBuffer = std::make_unique<uint8_t[]>(*size);
    1396 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
    1397 }
    1398 else
    1399 {
    1400 throw Exception(DW_INVALID_ARGUMENT, "Invalid codec packet buffer size.");
    1401 }
    1402 m_maxDataSize = *size;
    1403 }
    1404
    1406 {
    1407 return GenericData(&m_packet);
    1408 }
    1409
    1410protected:
    1411 dwCodecPacket m_packet{};
    1412 std::unique_ptr<uint8_t[]> m_dataBuffer{};
    1414};
    1415
    1416template <>
    1417class ChannelPacket<dwCodecPacket> : public ChannelSocketPacketBase, public CodecPacket
    1418{
    1419public:
    1420 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
    1421 : CodecPacket(specimen)
    1422 {
    1423 m_headerSize = sizeof(dwCodecPacket);
    1424 initBuffer(m_headerSize + m_maxDataSize);
    1425 }
    1426
    1427 // Serializes the packet before transmission
    1428 void serializeImpl() final
    1429 {
    1430 // safety check. avoid error count caused memcpy failure
    1431 if (m_packet.dataSizeBytes > m_maxDataSize)
    1432 {
    1433 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwCodecPacket>: serializeImpl: send packet size mismatch buffer size.");
    1434 }
    1435 memcpy(m_buffer.get(), &m_packet, m_headerSize);
    1436 // deep copy
    1437 memcpy(m_buffer.get() + m_headerSize, m_packet.data, m_packet.dataSizeBytes);
    1438 }
    1439
    1440 // Deserializes the frame before transmission
    1441 void deserialize(size_t) final
    1442 {
    1443 memcpy(&m_packet, m_buffer.get(), m_headerSize);
    1444 // safety check. avoid error count caused read failure
    1445 if (m_packet.dataSizeBytes > m_maxDataSize)
    1446 {
    1447 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwCodecPacket>: deserialize: recv packet size mismatch buffer size.");
    1448 }
    1449 // deep copy
    1450 memcpy(m_dataBuffer.get(), m_buffer.get() + m_headerSize, m_packet.dataSizeBytes);
    1451 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
    1452 }
    1453
    1454private:
    1455 size_t m_headerSize;
    1456};
    1457
    1458// SensorServiceNodeRawData
    1461{
    1462public:
    1464 {
    1465 auto* size = specimen.getData<size_t>();
    1466 if (size != nullptr)
    1467 {
    1468 m_dataBuffer = std::make_unique<uint8_t[]>(*size);
    1469 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
    1470 }
    1471 else
    1472 {
    1473 throw Exception(DW_INVALID_ARGUMENT, "Invalid maximum buffer size.");
    1474 }
    1475 m_maxDataSize = *size;
    1476 }
    1477
    1479 {
    1480 return GenericData(&m_packet);
    1481 }
    1482
    1483protected:
    1485 std::unique_ptr<uint8_t[]> m_dataBuffer{};
    1487};
    1488
    1489template <>
    1491{
    1492public:
    1493 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
    1495 {
    1496 m_headerSize = sizeof(SensorServiceNodeRawData);
    1497 initBuffer(m_headerSize + m_maxDataSize);
    1498 }
    1499
    1500 // Serializes the packet before transmission
    1501 void serializeImpl() final
    1502 {
    1503 // safety check. avoid error count caused memcpy failure
    1504 if (m_packet.size > m_maxDataSize)
    1505 {
    1506 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<SensorServiceNodeRawData>: serializeImpl: send packet size mismatch buffer size.");
    1507 }
    1508 memcpy(m_buffer.get(), &m_packet, m_headerSize);
    1509 // deep copy
    1510 memcpy(m_buffer.get() + m_headerSize, m_packet.data, m_packet.size);
    1511 }
    1512
    1513 // Deserializes the frame before transmission
    1514 void deserialize(size_t) final
    1515 {
    1516 memcpy(&m_packet, m_buffer.get(), m_headerSize);
    1517 // safety check. avoid error count caused read failure
    1518 if (m_packet.size > m_maxDataSize)
    1519 {
    1520 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<SensorServiceNodeRawData>: deserialize: recv packet size mismatch buffer size.");
    1521 }
    1522 // deep copy
    1523 memcpy(m_dataBuffer.get(), m_buffer.get() + m_headerSize, m_packet.size);
    1524 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
    1525 }
    1526
    1527private:
    1528 size_t m_headerSize;
    1529};
    1530
    1531} // namespace framework
    1532} // namespace dw
    1533
    1534#endif // DW_FRAMEWORK_CHANNEL_DW_PACKET_IMPL_HPP_
    #define FRWK_CHECK_CUDA_ERROR(x)
    Definition: Exception.hpp:340
    #define FRWK_CHECK_DW_ERROR(x)
    Definition: Exception.hpp:263
    ChannelPacket(const GenericData &specimen, dwContextHandle_t)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t)
    ChannelPacket(dwEgomotionStateParams &params, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t)
    static size_t serializeImage(dwImageCPU *cpuImage, unsigned char *buffer_start, size_t bufferSize, size_t planeCount, size_t elementSize, uint32_t planeChannelCount[], dwVector2ui planeSize[])
    static void deserializeImage(dwImageHandle_t copyToImage, unsigned char *buffer_start, size_t bufferSize, size_t planeCount, size_t elementSize, uint32_t planeChannelCount[], dwVector2ui planeSize[])
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(dwLidarDecodedPacket &ref, dwContextHandle_t)
    ChannelPacket(dwLidarPacketsArray &ref, dwContextHandle_t)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t)
    static size_t getFormatSize(dwPointCloudFormat format)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(dwRadarScan &ref, dwContextHandle_t)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(dwSensorNodeRawData &ref, dwContextHandle_t)
    ChannelPacket(const GenericData &specimen, dwContextHandle_t ctx)
    ChannelPacket(dwTraceNodeData &ref, dwContextHandle_t)
    CodecPacket(const GenericData &specimen)
    GenericData getGenericData() final
    std::unique_ptr< uint8_t[]> m_dataBuffer
    EgomotionStateHandlePacket(const GenericData &specimen, dwContextHandle_t ctx)
    FeatureArrayPacket(const GenericData &specimen, dwContextHandle_t ctx)
    FeatureHistoryArrayPacket(const GenericData &specimen, dwContextHandle_t ctx)
    FeatureNccScoresPacket(const GenericData &specimen)
    ImageHandlePacket(const GenericData &specimen, dwContextHandle_t ctx)
    GenericData getGenericData() override
    std::unique_ptr< uint8_t[]> m_allocation
    LatencyPacket(const GenericData &specimen)
    GenericData getGenericData() override
    PointCloudPacket(const GenericData &specimen)
    PyramidImagePacket(const GenericData &specimen, dwContextHandle_t ctx)
    SensorServiceNodeRawDataPacket(const GenericData &specimen)
    dwTraceNodeData { size_t maxDataSize dwTraceNodeData
    dwLidarPacketsArray { dwLidarDecodedPacket *packets dwLidarPacketsArray
    Definition: Exception.hpp:47
    人人超碰97caoporen国产