Compute Graph Framework SDK Reference  5.10
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 DWFRAMEWORK_DWNODES_COMMON_CHANNELPACKETIMPL_HPP_
32#define DWFRAMEWORK_DWNODES_COMMON_CHANNELPACKETIMPL_HPP_
33
34#include <dw/egomotion/EgomotionState.h>
35#include <dw/image/Image.h>
36#include <dw/imageprocessing/features/FeatureList.h>
37#include <dw/imageprocessing/pyramid/Pyramid.h>
38#include <dw/interop/streamer/ImageStreamer.h>
39#include <dw/pointcloudprocessing/pointcloud/PointCloud.h>
40#include <dw/roadcast/base_types/RoadCastBaseTypes.h>
41#include <dw/sensors/Codec.h>
42#include <dw/sensors/lidar/Lidar.h>
43#include <dwcgf/Exception.hpp>
50
51namespace dw
52{
53namespace framework
54{
55
57
59{
60public:
61 ImageHandlePacket(const GenericData& specimen, dwContextHandle_t ctx)
62 {
63 auto* props = specimen.getData<dwImageProperties>();
64 if (props)
65 {
66 m_prop = *props;
67 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandle, m_prop, ctx));
69 }
70 else
71 {
72 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
73 }
74 }
75
77 {
79 }
80
82 {
83 dwImage_destroy(m_imageHandle);
84 }
85
86protected:
87 dwImageHandle_t m_imageHandle = DW_NULL_HANDLE;
88 dwImageHandle_t m_dispatchImage = DW_NULL_HANDLE;
89 dwImageProperties m_prop{};
90};
91
92template <>
93class ChannelPacket<dwImageHandle_t> : public ImageHandlePacket, public ChannelSocketPacketBase
94{
95public:
96 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
97 : ImageHandlePacket(specimen, ctx)
98 , m_ctx(ctx)
99 {
100 if (m_prop.type != DW_IMAGE_CPU)
101 {
102 // Allocate streamer to CPU
103 m_prop.meta = {};
104 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerToCPU, &m_prop, DW_IMAGE_CPU, ctx));
105 }
106
107 // Allocate streamer from CPU back to original type
108 dwImageProperties cpuProp = m_prop;
109 cpuProp.type = DW_IMAGE_CPU;
110
111 if (m_prop.type != DW_IMAGE_CPU)
112 {
113 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerFromCPU, &cpuProp, m_prop.type, ctx));
114 }
115
116 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandleCPU, cpuProp, ctx));
117 FRWK_CHECK_DW_ERROR(dwImage_getDataLayout(&m_elementSize, &m_planeCount, m_planeChannelCount, m_planeSize, &cpuProp));
118
119 // Compute buffer size needed for transfer
120 size_t bufferSize = sizeof(dwImageCPU);
121 for (size_t i = 0; i < m_planeCount; i++)
122 {
123 size_t planeRowBytes = m_elementSize * m_planeSize[i].x * m_planeChannelCount[i];
124 bufferSize += planeRowBytes * m_planeSize[i].y;
125 }
126
127 initBuffer(bufferSize);
128 }
129
130 ~ChannelPacket() override
131 {
132 if (m_prop.type != DW_IMAGE_CPU)
133 {
134 dwImage_destroy(m_imageHandleCPU);
135 dwImageStreamer_release(m_streamerToCPU);
136 dwImageStreamer_release(m_streamerFromCPU);
137 }
138 }
139
140 // Image serialization static functions to allow re-use in dwBlindnessDetectionOutput serialization.
141 static size_t serializeImage(dwImageCPU* cpuImage, unsigned char* buffer_start, size_t bufferSize,
142 size_t planeCount, size_t elementSize, uint32_t planeChannelCount[],
143 dwVector2ui planeSize[])
144 {
145
146 memcpy(buffer_start, cpuImage, sizeof(dwImageCPU));
147
148 size_t bufferOffset = sizeof(dwImageCPU);
149 for (size_t i = 0; i < planeCount; i++)
150 {
151 size_t planeOffset = 0U;
152 size_t pitch = cpuImage->pitch[i];
153 size_t planeRowBytes = elementSize * planeSize[i].x * planeChannelCount[i];
154 for (size_t j = 0; j < planeSize[i].y; j++)
155 {
156 if (bufferOffset + planeRowBytes > bufferSize)
157 {
158 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwImageHandle_t>: serialize: send packet size, buffer size mismatch.");
159 }
160 memcpy(buffer_start + bufferOffset, cpuImage->data[i] + planeOffset, planeRowBytes);
161 planeOffset += pitch;
162 bufferOffset += planeRowBytes;
163 }
164 }
165 return bufferOffset;
166 }
167
168 static void deserializeImage(dwImageHandle_t copyToImage, unsigned char* buffer_start, size_t bufferSize,
169 size_t planeCount, size_t elementSize, uint32_t planeChannelCount[],
170 dwVector2ui planeSize[])
171 {
172
173 // Ensure metadata is a match
174 dwImageCPU* cpuImage = nullptr;
175 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, copyToImage));
176
177 size_t bufferOffset = sizeof(dwImageCPU);
178 for (size_t i = 0; i < planeCount; i++)
179 {
180 size_t planeOffset = 0U;
181 size_t pitch = cpuImage->pitch[i];
182 size_t planeRowBytes = elementSize * planeSize[i].x * planeChannelCount[i];
183 for (size_t j = 0; j < planeSize[i].y; j++)
184 {
185 if (bufferOffset + planeRowBytes > bufferSize)
186 {
187 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwImageHandle_t>: deserialize: recieve packet size, buffer size mismatch.");
188 }
189 memcpy(cpuImage->data[i] + planeOffset, buffer_start + bufferOffset, planeRowBytes);
190 planeOffset += pitch;
191 bufferOffset += planeRowBytes;
192 }
193 }
194 }
195
196 // Serializes the frame before transmission
197 void serializeImpl() final
198 {
199 dwImageCPU* cpuImage = nullptr;
200 dwImageHandle_t recvImage = nullptr;
201 dwImageHandle_t* returnedImage = nullptr;
202
203 if (m_prop.type != DW_IMAGE_CPU)
204 {
205 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_dispatchImage, m_streamerToCPU));
206 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImage, 0, m_streamerToCPU));
207
208 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, recvImage));
209 }
210 else
211 {
212 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, m_dispatchImage));
213 }
214
215 serializeImage(cpuImage, m_buffer.get(), m_bufferSize, m_planeCount, m_elementSize, m_planeChannelCount, m_planeSize);
216
217 if (m_prop.type != DW_IMAGE_CPU)
218 {
219 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImage, m_streamerToCPU));
220 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerToCPU));
221 }
222 }
223
224 // Deserializes the frame after transmission
225 void deserialize(size_t) final
226 {
227 dwImageHandle_t copyToImage = m_dispatchImage;
228 if (m_prop.type != DW_IMAGE_CPU)
229 {
230 copyToImage = m_imageHandleCPU;
231 }
232
233 // This needs to happen here to ensure that fields can be updated later.
234 dwImageCPU recvImage{};
235 memcpy(&recvImage, m_buffer.get(), sizeof(dwImageCPU));
236
237 deserializeImage(copyToImage, m_buffer.get(), m_bufferSize, m_planeCount, m_elementSize, m_planeChannelCount, m_planeSize);
238
239 if (m_prop.type != DW_IMAGE_CPU)
240 {
241 dwImageHandle_t recvImageHandle = nullptr;
242 dwImageHandle_t* returnedImage = nullptr;
243
244 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_imageHandleCPU, m_streamerFromCPU));
245 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImageHandle, 0, m_streamerFromCPU));
246
247 dwImage_copyConvert(m_dispatchImage, recvImageHandle, m_ctx);
248 dwImage_setMetaData(&recvImage.prop.meta, m_dispatchImage);
249 dwImage_setTimestamp(recvImage.timestamp_us, m_dispatchImage);
250
251 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImageHandle, m_streamerFromCPU));
252 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerFromCPU));
253 }
254 }
255
256private:
257 dwImageHandle_t m_imageHandleCPU = DW_NULL_HANDLE;
258
259 size_t m_elementSize = 0;
260 size_t m_planeCount = 0;
261 uint32_t m_planeChannelCount[DW_MAX_IMAGE_PLANES]{};
262 dwVector2ui m_planeSize[DW_MAX_IMAGE_PLANES]{};
263
264 dwImageStreamerHandle_t m_streamerToCPU = DW_NULL_HANDLE;
265 dwImageStreamerHandle_t m_streamerFromCPU = DW_NULL_HANDLE;
266
267 dwContextHandle_t m_ctx = DW_NULL_HANDLE;
268};
269
272{
273public:
274 LatencyPacket(const GenericData& specimen)
275 {
276 auto* props = specimen.getData<dwLatency>();
277 if (props)
278 {
279 m_data.size = props->size;
280 m_data.senderTime = props->senderTime;
281 m_allocation = std::make_unique<uint8_t[]>(props->size);
282 m_data.data = m_allocation.get();
284 }
285 else
286 {
287 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
288 }
289 }
290
292 {
293 return GenericData(&m_data);
294 }
295
296protected:
297 std::unique_ptr<uint8_t[]> m_allocation{};
300};
301
302// dwLatency packet for channel socket which is used for measurement of latency/data rate across tegras.
303template <>
305{
306public:
307 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
308 : LatencyPacket(specimen)
309 {
310 m_objectSize = sizeof(uint8_t);
311 m_maxCount = m_data.size;
312
313 m_headerSize = sizeof(dwLatency);
314
315 // packet has fixed size for simplicity
316 // variable length packet is currently not supported
317 initBuffer(m_headerSize + m_maxCount * m_objectSize);
318 }
319
320 // Serializes the frame before transmission
321 void serializeImpl() final
322 {
323 //copy packet data into buffer
324 memcpy(m_buffer.get(), &m_data, m_headerSize);
325
326 // deep copy objects data
327 memcpy(m_buffer.get() + m_headerSize, m_data.data, m_data.size * m_objectSize);
328 }
329
330 // Deserializes the frame after transmission
331 void deserialize(size_t) final
332 {
333 //retrieve dwLatency from buffer
334 memcpy(&m_data, m_buffer.get(), m_headerSize);
335
336 //retrieve object data
337 // points objects to the correct location in byte buffer
338 m_data.data = m_buffer.get() + m_headerSize;
339 }
340
341private:
342 size_t m_headerSize;
343 size_t m_objectSize;
344 size_t m_maxCount;
345};
346
349{
350public:
351 PyramidImagePacket(const GenericData& specimen, dwContextHandle_t ctx)
352 {
353 auto* props = specimen.getData<dwPyramidImageProperties>();
354 if (props)
355 {
356 m_props = *props;
357 FRWK_CHECK_DW_ERROR(dwPyramid_createFromProperties(&m_pyramidImage, &m_props, ctx));
359 }
360 else
361 {
362 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
363 }
364 }
365
367 {
369 }
370
372 {
373 dwPyramid_destroy(m_pyramidImage);
374 }
375
376protected:
377 dwPyramidImage m_pyramidImage{};
378 dwPyramidImage m_dispatchPyramid{};
379 dwPyramidImageProperties m_props{};
380};
381
382template <>
383class ChannelPacket<dwPyramidImage> : public PyramidImagePacket, public ChannelSocketPacketBase
384{
385public:
386 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
387 : PyramidImagePacket(specimen, ctx)
388 , m_ctx(ctx)
389 {
390 size_t bufferSize = sizeof(dwImageCPU) * m_props.levelCount;
391
392 for (uint32_t level = 0; level < m_props.levelCount; ++level)
393 {
394 dwImageProperties& prop = m_props.levelProps[level];
395
396 dwImageProperties cpuProp = prop;
397 cpuProp.type = DW_IMAGE_CPU;
398
399 FRWK_CHECK_DW_ERROR(dwImage_create(&m_imageHandleCPU[level], cpuProp, ctx));
400 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerToCPU[level], &prop, DW_IMAGE_CPU, ctx));
401 FRWK_CHECK_DW_ERROR(dwImageStreamer_initialize(&m_streamerFromCPU[level], &cpuProp, prop.type, ctx));
402
403 size_t elementSize = 0;
404 uint32_t planeChannelCount[DW_MAX_IMAGE_PLANES]{};
405 dwVector2ui planeSize[DW_MAX_IMAGE_PLANES]{};
406
407 FRWK_CHECK_DW_ERROR(dwImage_getDataLayout(&elementSize, &m_planeCount[level], planeChannelCount, planeSize, &cpuProp));
408
409 // Compute buffer size needed for transfer
410 for (size_t i = 0; i < m_planeCount[level]; i++)
411 {
412 bufferSize += (elementSize * planeSize[i].x * planeChannelCount[i]) * planeSize[i].y;
413 }
414 }
415
416 m_pyramidImage.levelCount = m_props.levelCount;
417 initBuffer(bufferSize);
418 }
419
420 ~ChannelPacket() override
421 {
422 for (uint32_t level = 0; level < m_pyramidImage.levelCount; ++level)
423 {
424 dwImage_destroy(m_imageHandleCPU[level]);
425 dwImageStreamer_release(m_streamerToCPU[level]);
426 dwImageStreamer_release(m_streamerFromCPU[level]);
427 }
428 }
429
430 // Serializes the frame before transmission
431 void serializeImpl() override
432 {
433 size_t written = 0;
434
435 for (uint32_t i = 0; i < m_pyramidImage.levelCount; i++)
436 {
437 dwImageHandle_t recvImage = nullptr;
438 dwImageHandle_t* returnedImage = nullptr;
439
440 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_pyramidImage.levelImages[i], m_streamerToCPU[i]));
441 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImage, 0, m_streamerToCPU[i]));
442
443 dwImageCPU* cpuImage = nullptr;
444 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, recvImage));
445
446 memcpy(m_buffer.get() + written, cpuImage, sizeof(dwImageCPU));
447 written += sizeof(dwImageCPU);
448
449 for (size_t j = 0; j < m_planeCount[i]; j++)
450 {
451 size_t planeSize = cpuImage->pitch[j] * cpuImage->prop.height;
452 memcpy(m_buffer.get() + written, cpuImage->data[j], planeSize);
453 written += planeSize;
454 }
455
456 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImage, m_streamerToCPU[i]));
457 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerToCPU[i]));
458 }
459 }
460
461 // Deserializes the frame before transmission
462 void deserialize(size_t) override
463 {
464 size_t read = 0;
465
466 for (uint32_t i = 0; i < m_pyramidImage.levelCount; i++)
467 {
468 dwImageCPU recvImage{};
469 memcpy(&recvImage, m_buffer.get() + read, sizeof(dwImageCPU));
470 read += sizeof(dwImageCPU);
471
472 dwImageCPU* cpuImage = nullptr;
473 FRWK_CHECK_DW_ERROR(dwImage_getCPU(&cpuImage, m_imageHandleCPU[i]));
474
475 for (size_t j = 0; j < m_planeCount[i]; j++)
476 {
477 size_t planeSize = cpuImage->pitch[j] * cpuImage->prop.height;
478 memcpy(cpuImage->data[j], m_buffer.get() + read, planeSize);
479 read += planeSize;
480 }
481
482 dwImageHandle_t recvImageHandle = nullptr;
483 dwImageHandle_t* returnedImage = nullptr;
484
485 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerSend(m_imageHandleCPU[i], m_streamerFromCPU[i]));
486 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReceive(&recvImageHandle, 0, m_streamerFromCPU[i]));
487
488 dwImage_copyConvert(m_pyramidImage.levelImages[i], recvImageHandle, m_ctx);
489 dwImage_setMetaData(&recvImage.prop.meta, m_pyramidImage.levelImages[i]);
490 dwImage_setTimestamp(recvImage.timestamp_us, m_pyramidImage.levelImages[i]);
491
492 FRWK_CHECK_DW_ERROR(dwImageStreamer_consumerReturn(&recvImageHandle, m_streamerFromCPU[i]));
493 FRWK_CHECK_DW_ERROR(dwImageStreamer_producerReturn(returnedImage, 0, m_streamerFromCPU[i]));
494 }
495 }
496
497private:
498 size_t m_planeCount[DW_PYRAMID_LEVEL_MAX_COUNT]{0};
499 dwImageStreamerHandle_t m_streamerToCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
500 dwImageStreamerHandle_t m_streamerFromCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
501 dwImageHandle_t m_imageHandleCPU[DW_PYRAMID_LEVEL_MAX_COUNT]{};
502 dwContextHandle_t m_ctx = DW_NULL_HANDLE;
503};
504
507{
508public:
510 {
511 auto* props = specimen.getData<dwFeatureNccScores>();
512 if (props)
513 {
514 m_ncc.size = props->size;
517 }
518 else
519 {
520 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
521 }
522 }
523
525 {
526 cudaFree(m_ncc.d_nccScores);
527 }
528
530 {
531 return GenericData(&m_dispatchNcc);
532 }
533
534protected:
537};
538
539template <>
541{
542public:
543 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
544 : FeatureNccScoresPacket(specimen)
545 {
546 initBuffer(m_ncc.size);
547 }
548
549 // Serializes the frame before transmission
550 void serializeImpl() override
551 {
552 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get(), m_ncc.d_nccScores, m_ncc.size, cudaMemcpyDeviceToHost, cudaStream_t(0)));
553 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
554 }
555
556 // Deserializes the frame before transmission
557 void deserialize(size_t) override
558 {
559 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_ncc.d_nccScores, m_buffer.get(), m_bufferSize, cudaMemcpyHostToDevice, cudaStream_t(0)));
560 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
561 }
562};
563
565{
566public:
567 FeatureArrayPacket(const GenericData& specimen, dwContextHandle_t ctx)
568 {
569 auto* props = specimen.getData<dwFeatureArray>();
570 if (props)
571 {
572 dwStatus ret = dwFeatureArray_create(&m_featureArray,
573 props->maxFeatures,
574 props->memoryType,
575 ctx);
576 if (ret != DW_SUCCESS)
577 {
578 throw Exception(DW_BAD_ALLOC, "FeatureArrayPacket: cannot allocate packet");
579 }
581 }
582 else
583 {
584 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
585 }
586 }
587
589 {
590 dwFeatureArray_destroy(m_featureArrayOrig);
591 }
592
594 {
596 }
597
598protected:
599 dwFeatureArray m_featureArray{};
600 dwFeatureArray m_featureArrayOrig{};
601};
602
604template <>
605class ChannelPacket<dwFeatureArray> : public FeatureArrayPacket, public ChannelSocketPacketBase
606{
607public:
608 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
609 : FeatureArrayPacket(specimen, ctx)
610 {
611 m_propIndex[0] = sizeof(dwFeatureArray);
612 m_propIndex[1] = m_propIndex[0] + sizeof(dwFeature2DStatus) * m_featureArray.maxFeatures; // statuses
613 m_propIndex[2] = m_propIndex[1] + sizeof(uint32_t) * m_featureArray.maxFeatures; // ages
614 m_propIndex[3] = m_propIndex[2] + sizeof(float32_t) * m_featureArray.maxFeatures; // scales
615 m_propIndex[4] = m_propIndex[3] + sizeof(uint32_t) * m_featureArray.maxFeatures; // ids
616 m_propIndex[5] = m_propIndex[4] + sizeof(uint32_t) * m_featureArray.maxFeatures; // newToOldMap
617 m_propIndex[6] = m_propIndex[5] + sizeof(dwVector2f) * m_featureArray.maxFeatures; // locations
618 m_propIndex[7] = m_propIndex[6] + sizeof(uint32_t); // featureCount
619 m_propIndex[8] = m_propIndex[7] + sizeof(uint32_t); // validTrackedCount
620
621 initBuffer(m_propIndex[8]);
622 }
623
624 // Serializes the frame before transmission
625 void serializeImpl() override
626 {
627 static_assert(sizeof(dwFeatureArray) == 80, "dwFeatureArray size has changed, update serialization");
628
629 memcpy(m_buffer.get(), &m_featureArray, m_propIndex[0]);
630
631 if (m_featureArray.memoryType == DW_MEMORY_TYPE_CUDA)
632 {
633 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[0], m_featureArray.statuses, m_propIndex[1] - m_propIndex[0], cudaMemcpyDeviceToHost, m_stream));
634 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[1], m_featureArray.ages, m_propIndex[2] - m_propIndex[1], cudaMemcpyDeviceToHost, m_stream));
635 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[2], m_featureArray.scales, m_propIndex[3] - m_propIndex[2], cudaMemcpyDeviceToHost, m_stream));
636 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[3], m_featureArray.ids, m_propIndex[4] - m_propIndex[3], cudaMemcpyDeviceToHost, m_stream));
637 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[4], m_featureArray.newToOldMap, m_propIndex[5] - m_propIndex[4], cudaMemcpyDeviceToHost, m_stream));
638 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[5], m_featureArray.locations, m_propIndex[6] - m_propIndex[5], cudaMemcpyDeviceToHost, m_stream));
639 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[6], m_featureArray.featureCount, m_propIndex[7] - m_propIndex[6], cudaMemcpyDeviceToHost, m_stream));
640 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_buffer.get() + m_propIndex[7], m_featureArray.validTrackedCount, m_propIndex[8] - m_propIndex[7], cudaMemcpyDeviceToHost, m_stream));
641 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(m_stream));
642 }
643 else if (m_featureArray.memoryType == DW_MEMORY_TYPE_CPU ||
644 m_featureArray.memoryType == DW_MEMORY_TYPE_PINNED)
645 {
646 memcpy(m_buffer.get() + m_propIndex[0], m_featureArray.statuses, m_propIndex[1] - m_propIndex[0]);
647 memcpy(m_buffer.get() + m_propIndex[1], m_featureArray.ages, m_propIndex[2] - m_propIndex[1]);
648 memcpy(m_buffer.get() + m_propIndex[2], m_featureArray.scales, m_propIndex[3] - m_propIndex[2]);
649 memcpy(m_buffer.get() + m_propIndex[3], m_featureArray.ids, m_propIndex[4] - m_propIndex[3]);
650 memcpy(m_buffer.get() + m_propIndex[4], m_featureArray.newToOldMap, m_propIndex[5] - m_propIndex[4]);
651 memcpy(m_buffer.get() + m_propIndex[5], m_featureArray.locations, m_propIndex[6] - m_propIndex[5]);
652 memcpy(m_buffer.get() + m_propIndex[6], m_featureArray.featureCount, m_propIndex[7] - m_propIndex[6]);
653 memcpy(m_buffer.get() + m_propIndex[7], m_featureArray.validTrackedCount, m_propIndex[8] - m_propIndex[7]);
654 }
655 }
656
657 // Deserializes the frame before transmission
658 void deserialize(size_t) override
659 {
660 static_assert(sizeof(dwFeatureArray) == 80, "dwFeatureArray size has changed, update deserialization");
661
662 auto array = reinterpret_cast<dwFeatureArray*>(m_buffer.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
663 if (m_featureArray.maxFeatures != array->maxFeatures)
664 {
665 throw Exception(DW_INVALID_ARGUMENT, "ChannelPacket<dwFeatureArray>: deserialize: maxFeatures does not match");
666 }
667
668 if (m_featureArray.memoryType == DW_MEMORY_TYPE_CUDA)
669 {
670 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.statuses, m_buffer.get() + m_propIndex[0], m_propIndex[1] - m_propIndex[0], cudaMemcpyHostToDevice, m_stream));
671 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.ages, m_buffer.get() + m_propIndex[1], m_propIndex[2] - m_propIndex[1], cudaMemcpyHostToDevice, m_stream));
672 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.scales, m_buffer.get() + m_propIndex[2], m_propIndex[3] - m_propIndex[2], cudaMemcpyHostToDevice, m_stream));
673 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.ids, m_buffer.get() + m_propIndex[3], m_propIndex[4] - m_propIndex[3], cudaMemcpyHostToDevice, m_stream));
674 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.newToOldMap, m_buffer.get() + m_propIndex[4], m_propIndex[5] - m_propIndex[4], cudaMemcpyHostToDevice, m_stream));
675 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.locations, m_buffer.get() + m_propIndex[5], m_propIndex[6] - m_propIndex[5], cudaMemcpyHostToDevice, m_stream));
676 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.featureCount, m_buffer.get() + m_propIndex[6], m_propIndex[7] - m_propIndex[6], cudaMemcpyHostToDevice, m_stream));
677 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureArray.validTrackedCount, m_buffer.get() + m_propIndex[7], m_propIndex[8] - m_propIndex[7], cudaMemcpyHostToDevice, m_stream));
678 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(m_stream));
679 }
680 else if (m_featureArray.memoryType == DW_MEMORY_TYPE_CPU ||
681 m_featureArray.memoryType == DW_MEMORY_TYPE_PINNED)
682 {
683 memcpy(m_featureArray.statuses, m_buffer.get() + m_propIndex[0], m_propIndex[1] - m_propIndex[0]);
684 memcpy(m_featureArray.ages, m_buffer.get() + m_propIndex[1], m_propIndex[2] - m_propIndex[1]);
685 memcpy(m_featureArray.scales, m_buffer.get() + m_propIndex[2], m_propIndex[3] - m_propIndex[2]);
686 memcpy(m_featureArray.ids, m_buffer.get() + m_propIndex[3], m_propIndex[4] - m_propIndex[3]);
687 memcpy(m_featureArray.newToOldMap, m_buffer.get() + m_propIndex[4], m_propIndex[5] - m_propIndex[4]);
688 memcpy(m_featureArray.locations, m_buffer.get() + m_propIndex[5], m_propIndex[6] - m_propIndex[5]);
689 memcpy(m_featureArray.featureCount, m_buffer.get() + m_propIndex[6], m_propIndex[7] - m_propIndex[6]);
690 memcpy(m_featureArray.validTrackedCount, m_buffer.get() + m_propIndex[7], m_propIndex[8] - m_propIndex[7]);
691 }
692
693 m_featureArray.timeIdx = array->timeIdx;
694 }
695
696private:
697 size_t m_propIndex[9] = {};
698 cudaStream_t m_stream = cudaStream_t{nullptr};
699};
700
703{
704public:
705 FeatureHistoryArrayPacket(const GenericData& specimen, dwContextHandle_t ctx)
706 {
707 auto* props = specimen.getData<dwFeatureHistoryArray>();
708 if (props)
709 {
710 dwStatus ret = dwFeatureHistoryArray_create(&m_featureHistoryArray,
711 props->maxFeatures,
712 props->maxHistory,
713 props->memoryType,
714 ctx);
715 if (ret != DW_SUCCESS)
716 {
717 throw Exception(DW_BAD_ALLOC, "FeatureHistoryArrayPacket: cannot allocate packet");
718 }
720 }
721 else
722 {
723 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
724 }
725 }
726
728 {
729 dwFeatureHistoryArray_destroy(m_featureHistoryArrayOrig);
730 }
731
733 {
735 }
736
737protected:
738 dwFeatureHistoryArray m_featureHistoryArray{};
739 dwFeatureHistoryArray m_featureHistoryArrayOrig{};
740};
741
742template <>
743class ChannelPacket<dwFeatureHistoryArray> : public FeatureHistoryArrayPacket, public ChannelSocketPacketBase
744{
745public:
746 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
747 : FeatureHistoryArrayPacket(specimen, ctx)
748 {
749 initBuffer(sizeof(dwFeatureHistoryArray) + m_featureHistoryArray.bytes);
750 }
751
752 // Serializes the frame before transmission
753 void serializeImpl() override
754 {
755 static_assert(sizeof(dwFeatureHistoryArray) == 104, "dwFeatureHistoryArray size has changed, update serialization");
756
757 uint8_t* ptr = m_buffer.get() + sizeof(dwFeatureHistoryArray);
758 memcpy(m_buffer.get(), &m_featureHistoryArray, sizeof(dwFeatureHistoryArray));
759
760 if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CUDA)
761 {
762 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(ptr, m_featureHistoryArray.data, m_featureHistoryArray.bytes, cudaMemcpyDeviceToHost, cudaStream_t(0)));
763 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
764 }
765 else if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CPU ||
766 m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_PINNED)
767 {
768 memcpy(ptr, m_featureHistoryArray.data, m_featureHistoryArray.bytes);
769 }
770 }
771
772 // Deserializes the frame before transmission
773 void deserialize(size_t) override
774 {
775 static_assert(sizeof(dwFeatureHistoryArray) == 104, "dwFeatureHistoryArray size has changed, update deserialization");
776
777 auto array = reinterpret_cast<dwFeatureHistoryArray*>(m_buffer.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
778 if (m_featureHistoryArray.maxFeatures != array->maxFeatures || m_featureHistoryArray.maxHistory != array->maxHistory)
779 {
780 throw Exception(DW_INVALID_ARGUMENT, "ChannelPacket<dwFeatureHistoryArray>: deserialize: maxFeatures or maxHistory does not match");
781 }
782
783 uint8_t* ptr = m_buffer.get() + sizeof(dwFeatureHistoryArray);
784 if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CUDA)
785 {
786 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_featureHistoryArray.data, ptr, m_featureHistoryArray.bytes, cudaMemcpyHostToDevice, cudaStream_t(0)));
787 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
788 }
789 else if (m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_CPU ||
790 m_featureHistoryArray.memoryType == DW_MEMORY_TYPE_PINNED)
791 {
792 memcpy(m_featureHistoryArray.data, ptr, m_featureHistoryArray.bytes);
793 }
794
795 m_featureHistoryArray.currentTimeIdx = array->currentTimeIdx;
796 }
797};
798
800// dwSensorRawData packet for channel socket
801template <>
803{
804public:
805 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
806 : ChannelPacket(*specimen.getData<dwSensorNodeRawData>(), ctx)
807 {
808 auto* frame = getFrame();
809 m_frame = GenericData(frame);
810 }
811
812 ChannelPacket(dwSensorNodeRawData& ref, dwContextHandle_t)
813 : ChannelPacketBase(ref.size)
814 , m_data(ref)
815 {
816 }
817
819 {
820 return &m_data;
821 }
822
823 void setBufferSize(size_t bufferSize)
824 {
825 m_bufferSize = bufferSize;
826 }
827
828 // Serializes the frame before transmission
829 void serializeImpl() final
830 {
831 //copy packet data into buffer
832 memcpy(m_buffer.get(), &m_data, m_bufferSize);
833 }
834
835 // Deserializes the frame after transmission
836 void deserialize(size_t) final
837 {
838 //retrieve packet data from buffer
839 memcpy(&m_data, m_buffer.get(), m_bufferSize);
840 }
841
842private:
843 dwSensorNodeRawData m_data{};
844};
845
847// dwLidarDecodedPacket packet for channel socket
848template <>
849class ChannelPacket<dwLidarDecodedPacket> : public ChannelPacketBase
850{
851public:
852 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
853 : ChannelPacket(*specimen.getData<dwLidarDecodedPacket>(), ctx)
854 {
855 auto* frame = getFrame();
856 m_frame = GenericData(frame);
857 }
858
859 ChannelPacket(dwLidarDecodedPacket& ref, dwContextHandle_t)
860 : m_data(ref)
861 {
862 size_t bufferSize = sizeof(dwLidarDecodedPacket) + sizeof(dwLidarPointRTHI) * ref.maxPoints + sizeof(dwLidarPointXYZI) * ref.maxPoints;
863
864 m_pointsRTHI = std::make_unique<uint8_t[]>(sizeof(dwLidarPointRTHI) * ref.maxPoints);
865 m_pointsXYZI = std::make_unique<uint8_t[]>(sizeof(dwLidarPointXYZI) * ref.maxPoints);
866
867 m_data.pointsRTHI = reinterpret_cast<const dwLidarPointRTHI*>(m_pointsRTHI.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
868 m_data.pointsXYZI = reinterpret_cast<const dwLidarPointXYZI*>(m_pointsXYZI.get()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
869
870 initBuffer(bufferSize);
871 }
872
873 dwLidarDecodedPacket* getFrame()
874 {
875 return &m_data;
876 }
877
878 void setBufferSize(size_t bufferSize)
879 {
880 m_bufferSize = bufferSize;
881 }
882
883 // Serializes the frame before transmission
884 void serializeImpl() final
885 {
886 //copy packet data into buffer
887 size_t header = sizeof(dwLidarDecodedPacket);
888 memcpy(m_buffer.get(), &m_data, header);
889 memcpy(m_buffer.get() + header, m_data.pointsRTHI, sizeof(dwLidarPointRTHI) * m_data.nPoints);
890 header += sizeof(dwLidarPointRTHI) * m_data.nPoints;
891 memcpy(m_buffer.get() + header, m_data.pointsXYZI, sizeof(dwLidarPointXYZI) * m_data.nPoints);
892 }
893
894 // Deserializes the frame after transmission
895 void deserialize(size_t) final
896 {
897 //retrieve packet data from buffer
898 memcpy(&m_data, m_buffer.get(), sizeof(dwLidarDecodedPacket));
899 m_data.pointsRTHI = reinterpret_cast<const dwLidarPointRTHI*>(m_buffer.get() + // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
900 sizeof(dwLidarDecodedPacket));
901 m_data.pointsXYZI = reinterpret_cast<const dwLidarPointXYZI*>(m_buffer.get() + sizeof(dwLidarDecodedPacket) + // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
902 sizeof(dwLidarPointRTHI) * m_data.nPoints);
903 }
904
905private:
906 dwLidarDecodedPacket m_data{};
907 std::unique_ptr<uint8_t[]> m_pointsRTHI;
908 std::unique_ptr<uint8_t[]> m_pointsXYZI;
909};
910
913{
914public:
915 EgomotionStateHandlePacket(const GenericData& specimen, dwContextHandle_t ctx)
916 {
917 auto* props = specimen.getData<dwEgomotionStateParams>();
918 if (props)
919 {
920 dwEgomotionState_createEmpty(&m_egomotionState, *props, ctx);
922 }
923 else
924 {
925 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
926 }
927 }
928
930 {
931 dwEgomotionState_release(m_egomotionState);
932 }
933
935 {
937 }
938
939protected:
940 dwEgomotionStateHandle_t m_egomotionState = DW_NULL_HANDLE;
941 dwEgomotionStateHandle_t m_dispatchEgomotionState = DW_NULL_HANDLE;
942};
943
944template <>
945class ChannelPacket<dwEgomotionStateHandle_t> : public EgomotionStateHandlePacket, public ChannelSocketPacketBase
946{
947public:
948 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
949 : EgomotionStateHandlePacket(specimen, ctx)
950 {
951 dwEgomotionState_getMaxNumBytes(&m_numBytes, m_egomotionState);
952 m_bufferSize = m_numBytes + sizeof(m_numBytes);
953 initBuffer(m_bufferSize);
954 }
955
956 ChannelPacket(dwEgomotionStateParams& params, dwContextHandle_t ctx)
957 : ChannelPacket(GenericData(&params), ctx)
958 {
959 }
960
961 dwEgomotionStateHandle_t* getFrame()
962 {
963 return &m_dispatchEgomotionState;
964 }
965
966 size_t getNumBytes()
967 {
968 size_t numBytes = 0;
969 memcpy(&numBytes, m_buffer.get(), sizeof(numBytes));
970 return numBytes;
971 }
972
973 void serializeImpl() final
974 {
975 // Serialize state at producer side
976 dwEgomotionState_serialize(&m_numBytes,
977 m_buffer.get() + sizeof(m_numBytes),
978 m_bufferSize - sizeof(m_numBytes),
979 m_dispatchEgomotionState);
980 memcpy(m_buffer.get(), &m_numBytes, sizeof(m_numBytes));
981 }
982
983 void deserialize(size_t) final
984 {
985 memcpy(&m_numBytes, m_buffer.get(), sizeof(m_numBytes));
986 if (m_numBytes > m_bufferSize - sizeof(m_numBytes))
987 {
988 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwEgomotionStateHandle_t>: deserialize: recv packet size mismatch available buffer size.");
989 }
990 // Deserialize state at consumer side
991 dwEgomotionState_deserialize(m_buffer.get() + sizeof(m_numBytes),
992 m_numBytes,
993 m_dispatchEgomotionState);
994 }
995
996private:
997 size_t m_numBytes = 0;
998};
999
1002{
1003public:
1005 {
1006 auto* props = specimen.getData<dwPointCloud>();
1007 if (props != nullptr)
1008 {
1009 m_data = *props;
1010 m_data.points = nullptr;
1011 dwStatus ret = dwPointCloud_createBuffer(&m_data);
1012 if (ret != DW_SUCCESS)
1013 {
1014 throw Exception(DW_BAD_ALLOC, "PointCloudChannelPacket: cannot allocate packet");
1015 }
1016
1017 m_dataOri = m_data;
1018 }
1019 else
1020 {
1021 throw Exception(DW_INVALID_ARGUMENT, "Invalid reference data provided.");
1022 }
1023 }
1024
1026 {
1027 dwPointCloud_destroyBuffer(&m_dataOri);
1028 }
1029
1031 {
1032 return GenericData(&m_data);
1033 }
1034
1035protected:
1036 dwPointCloud m_data{};
1037 dwPointCloud m_dataOri{};
1038};
1039
1040// PointCloud packet for channel socket
1041template <>
1043{
1044public:
1045 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
1046 : PointCloudChannelPacket(specimen)
1047 {
1048 if (m_data.numAuxChannels > 0)
1049 {
1050 throw Exception(DW_NOT_IMPLEMENTED, "ChannelPacket<dwPointCloud>: time to add support for aux data: DRIV-8273");
1051 }
1052
1053 m_objectSize = getFormatSize(m_data.format);
1054 m_maxCount = m_data.capacity;
1055 m_headerSize = sizeof(dwPointCloud);
1056
1057 initBuffer(m_headerSize + m_maxCount * m_objectSize);
1058 }
1059
1060 // Serializes the frame before transmission
1061 void serializeImpl() final
1062 {
1063 uint8_t* ptr = m_buffer.get() + m_headerSize;
1064 memcpy(m_buffer.get(), &m_data, m_headerSize);
1065 if (m_data.type == DW_MEMORY_TYPE_CUDA)
1066 {
1067 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(ptr, m_data.points, m_data.size * m_objectSize, cudaMemcpyDeviceToHost, cudaStream_t(0)));
1068 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
1069 }
1070 else if (m_data.type == DW_MEMORY_TYPE_CPU ||
1071 m_data.type == DW_MEMORY_TYPE_PINNED)
1072 {
1073 memcpy(ptr, m_data.points, m_data.size * m_objectSize);
1074 }
1075 }
1076
1077 void deserialize(size_t) final
1078 {
1079 uint8_t* ptr = m_buffer.get() + m_headerSize;
1080 memcpy(&m_data, m_buffer.get(), m_headerSize);
1081
1082 if (m_data.type == DW_MEMORY_TYPE_CUDA)
1083 {
1084 m_data.points = m_dataOri.points;
1085 FRWK_CHECK_CUDA_ERROR(cudaMemcpyAsync(m_data.points, ptr, m_data.size * m_objectSize, cudaMemcpyHostToDevice, cudaStream_t(0)));
1086 FRWK_CHECK_CUDA_ERROR(cudaStreamSynchronize(0));
1087 }
1088 else if (m_data.type == DW_MEMORY_TYPE_CPU ||
1089 m_data.type == DW_MEMORY_TYPE_PINNED)
1090 {
1091 m_data.points = static_cast<void*>(m_buffer.get() + m_headerSize);
1092 }
1093 }
1094
1095 static size_t getFormatSize(dwPointCloudFormat format)
1096 {
1097 uint32_t formatSize = 0;
1098 switch (format)
1099 {
1100 case DW_POINTCLOUD_FORMAT_XYZI:
1101 formatSize = sizeof(dwLidarPointXYZI);
1102 break;
1103 case DW_POINTCLOUD_FORMAT_RTHI:
1104 formatSize = sizeof(dwLidarPointRTHI);
1105 break;
1106 default:
1107 throw std::runtime_error("ChannelPacket<dwPointCloud>: unknown dwPointCloudFormat");
1108 }
1109 return formatSize;
1110 }
1111
1112private:
1113 size_t m_headerSize{};
1114 size_t m_objectSize{};
1115 size_t m_maxCount{};
1116};
1117
1119// dwLidarPacketsArray for channel socket
1120template <>
1122{
1123public:
1124 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
1125 : ChannelPacket(*specimen.getData<dwLidarPacketsArray>(), ctx)
1126 {
1127 auto* frame = getFrame();
1128 m_frame = GenericData(frame);
1129 }
1130
1131 ChannelPacket(dwLidarPacketsArray& ref, dwContextHandle_t)
1132 : m_data(ref)
1133 {
1134 m_headerSize = sizeof(dwLidarPacketsArray);
1135 size_t lidarDecodedPacketsSize = m_data.maxPacketsPerSpin * sizeof(dwLidarDecodedPacket);
1136 size_t pointsXYZISize = m_data.maxPacketsPerSpin * m_data.maxPointsPerPacket * sizeof(dwLidarPointXYZI);
1137 size_t pointsRTHISize = m_data.maxPacketsPerSpin * m_data.maxPointsPerPacket * sizeof(dwLidarPointRTHI);
1138
1139 initBuffer(m_headerSize + lidarDecodedPacketsSize + pointsXYZISize + pointsRTHISize);
1140
1141 m_lidarPacketsPtr = reinterpret_cast<dwLidarDecodedPacket*>(m_buffer.get() + m_headerSize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1142 m_pointsXYZIPtr = reinterpret_cast<dwLidarPointXYZI*>(m_buffer.get() + m_headerSize + lidarDecodedPacketsSize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1143 m_pointsRTHIPtr = reinterpret_cast<dwLidarPointRTHI*>(m_buffer.get() + m_headerSize + lidarDecodedPacketsSize + pointsXYZISize); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1144
1145 m_data.packets = m_lidarPacketsPtr;
1146 m_data.pointsXYZIArray = m_pointsXYZIPtr;
1147 m_data.pointsRTHIArray = m_pointsRTHIPtr;
1148 }
1149
1151 {
1152 return &m_data;
1153 }
1154
1155 // Serializes the frame before transmission
1156 void serializeImpl() final
1157 {
1158 size_t lidarDecodedPacketsSize = m_data.packetSize * sizeof(dwLidarDecodedPacket);
1159 size_t pointsXYZISize = m_data.packetSize * m_data.maxPointsPerPacket * sizeof(dwLidarPointXYZI);
1160 size_t pointsRTHISize = m_data.packetSize * m_data.maxPointsPerPacket * sizeof(dwLidarPointRTHI);
1161
1162 memcpy(m_buffer.get(), &m_data, m_headerSize);
1163
1164 if (m_data.packets != m_lidarPacketsPtr)
1165 {
1166 memcpy(m_lidarPacketsPtr, m_data.packets, lidarDecodedPacketsSize);
1167 }
1168 if (m_data.pointsXYZIArray != m_pointsXYZIPtr)
1169 {
1170 memcpy(m_pointsXYZIPtr, m_data.pointsXYZIArray, pointsXYZISize);
1171 }
1172 if (m_data.pointsRTHIArray != m_pointsRTHIPtr)
1173 {
1174 memcpy(m_pointsRTHIPtr, m_data.pointsRTHIArray, pointsRTHISize);
1175 }
1176 }
1177
1178 void deserialize(size_t) final
1179 {
1180 memcpy(&m_data, m_buffer.get(), m_headerSize);
1181 m_data.packets = m_lidarPacketsPtr;
1182 m_data.pointsXYZIArray = m_pointsXYZIPtr;
1183 m_data.pointsRTHIArray = m_pointsRTHIPtr;
1184 for (size_t packetsIndex = 0; packetsIndex < m_data.packetSize; ++packetsIndex)
1185 {
1186 m_data.packets[packetsIndex].pointsXYZI = &(m_data.pointsXYZIArray[packetsIndex * m_data.maxPointsPerPacket]);
1187 m_data.packets[packetsIndex].pointsRTHI = &(m_data.pointsRTHIArray[packetsIndex * m_data.maxPointsPerPacket]);
1188 }
1189 }
1190
1191private:
1192 dwLidarPacketsArray m_data{};
1193
1194 size_t m_headerSize{};
1195
1196 dwLidarDecodedPacket* m_lidarPacketsPtr{};
1197 dwLidarPointXYZI* m_pointsXYZIPtr{};
1198 dwLidarPointRTHI* m_pointsRTHIPtr{};
1199};
1200
1202template <>
1204{
1205public:
1206 ChannelPacket(const GenericData& specimen, dwContextHandle_t ctx)
1207 : ChannelPacket(*specimen.getData<dwTraceNodeData>(), ctx)
1208 {
1209 auto* frame = getFrame();
1210 m_frame = GenericData(frame);
1211 }
1212
1213 ChannelPacket(dwTraceNodeData& ref, dwContextHandle_t)
1214 : m_data(ref), m_headerSize(sizeof(dwTraceNodeData)), m_maxDataSize(ref.maxDataSize)
1215 {
1216 initBuffer(m_headerSize + m_maxDataSize);
1217 m_TraceData = m_buffer.get() + m_headerSize;
1218 m_data.data = m_TraceData;
1219 }
1220
1221 ~ChannelPacket() override = default;
1222
1224 {
1225 return &m_data;
1226 }
1227
1228 // Serializes the frame before transmission
1229 void serializeImpl() final
1230 {
1231 // safety check. avoid error count caused memcpy failure
1232 if (m_data.dataSize > m_maxDataSize)
1233 {
1234 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwTraceNodeData>: serializeImpl: send packet size mismatch buffer size.");
1235 }
1236 memcpy(m_buffer.get(), &m_data, m_headerSize);
1237 if (m_data.data != m_TraceData && m_data.dataSize <= m_maxDataSize)
1238 {
1239 memcpy(m_TraceData, m_data.data, m_data.dataSize * sizeof(uint8_t)); //deep copy. only copy valid value
1240 }
1241 }
1242
1243 // Deserializes the frame before transmission
1244 void deserialize(size_t) final
1245 {
1246 memcpy(&m_data, m_buffer.get(), m_headerSize);
1247 // safety check. avoid error count caused read failure
1248 if (m_data.dataSize > m_maxDataSize)
1249 {
1250 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwTraceNodeData>: deserialize: recv packet size mismatch buffer size.");
1251 }
1252 m_data.data = m_buffer.get() + m_headerSize;
1253 }
1254
1255private:
1256 dwTraceNodeData m_data{};
1257 size_t m_headerSize{};
1258 size_t m_maxDataSize{};
1259 uint8_t* m_TraceData;
1260};
1261
1262// dwCodecPacket
1265{
1266public:
1267 CodecPacket(const GenericData& specimen)
1268 {
1269 auto* size = specimen.getData<size_t>();
1270 if (size != nullptr)
1271 {
1272 m_dataBuffer = std::make_unique<uint8_t[]>(*size);
1273 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
1274 }
1275 else
1276 {
1277 throw Exception(DW_INVALID_ARGUMENT, "Invalid codec packet buffer size.");
1278 }
1279 m_maxDataSize = *size;
1280 }
1281
1283 {
1284 return GenericData(&m_packet);
1285 }
1286
1287protected:
1288 dwCodecPacket m_packet{};
1289 std::unique_ptr<uint8_t[]> m_dataBuffer{};
1291};
1292
1293template <>
1294class ChannelPacket<dwCodecPacket> : public ChannelSocketPacketBase, public CodecPacket
1295{
1296public:
1297 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
1298 : CodecPacket(specimen)
1299 {
1300 m_headerSize = sizeof(dwCodecPacket);
1301 initBuffer(m_headerSize + m_maxDataSize);
1302 }
1303
1304 // Serializes the packet before transmission
1305 void serializeImpl() final
1306 {
1307 // safety check. avoid error count caused memcpy failure
1308 if (m_packet.dataSizeBytes > m_maxDataSize)
1309 {
1310 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwCodecPacket>: serializeImpl: send packet size mismatch buffer size.");
1311 }
1312 memcpy(m_buffer.get(), &m_packet, m_headerSize);
1313 // deep copy
1314 memcpy(m_buffer.get() + m_headerSize, m_packet.data, m_packet.dataSizeBytes);
1315 }
1316
1317 // Deserializes the frame before transmission
1318 void deserialize(size_t) final
1319 {
1320 memcpy(&m_packet, m_buffer.get(), m_headerSize);
1321 // safety check. avoid error count caused read failure
1322 if (m_packet.dataSizeBytes > m_maxDataSize)
1323 {
1324 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<dwCodecPacket>: deserialize: recv packet size mismatch buffer size.");
1325 }
1326 // deep copy
1327 memcpy(m_dataBuffer.get(), m_buffer.get() + m_headerSize, m_packet.dataSizeBytes);
1328 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
1329 }
1330
1331private:
1332 size_t m_headerSize;
1333};
1334
1335// SensorServiceNodeRawData
1338{
1339public:
1341 {
1342 auto* size = specimen.getData<size_t>();
1343 if (size != nullptr)
1344 {
1345 m_dataBuffer = std::make_unique<uint8_t[]>(*size);
1346 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
1347 }
1348 else
1349 {
1350 throw Exception(DW_INVALID_ARGUMENT, "Invalid maximum buffer size.");
1351 }
1352 m_maxDataSize = *size;
1353 }
1354
1356 {
1357 return GenericData(&m_packet);
1358 }
1359
1360protected:
1362 std::unique_ptr<uint8_t[]> m_dataBuffer{};
1364};
1365
1366template <>
1368{
1369public:
1370 ChannelPacket(const GenericData& specimen, dwContextHandle_t)
1372 {
1373 m_headerSize = sizeof(SensorServiceNodeRawData);
1374 initBuffer(m_headerSize + m_maxDataSize);
1375 }
1376
1377 // Serializes the packet before transmission
1378 void serializeImpl() final
1379 {
1380 // safety check. avoid error count caused memcpy failure
1381 if (m_packet.size > m_maxDataSize)
1382 {
1383 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<SensorServiceNodeRawData>: serializeImpl: send packet size mismatch buffer size.");
1384 }
1385 memcpy(m_buffer.get(), &m_packet, m_headerSize);
1386 // deep copy
1387 memcpy(m_buffer.get() + m_headerSize, m_packet.data, m_packet.size);
1388 }
1389
1390 // Deserializes the frame before transmission
1391 void deserialize(size_t) final
1392 {
1393 memcpy(&m_packet, m_buffer.get(), m_headerSize);
1394 // safety check. avoid error count caused read failure
1395 if (m_packet.size > m_maxDataSize)
1396 {
1397 throw Exception(DW_OUT_OF_BOUNDS, "ChannelPacket<SensorServiceNodeRawData>: deserialize: recv packet size mismatch buffer size.");
1398 }
1399 // deep copy
1400 memcpy(m_dataBuffer.get(), m_buffer.get() + m_headerSize, m_packet.size);
1401 m_packet.data = static_cast<uint8_t*>(m_dataBuffer.get());
1402 }
1403
1404private:
1405 size_t m_headerSize;
1406};
1407
1408} // namespace framework
1409} // namespace dw
1410
1411#endif // DWFRAMEWORK_DWNODES_COMMON_CHANNELPACKETIMPL_HPP_
#define FRWK_CHECK_CUDA_ERROR(x)
Definition: Exception.hpp:126
#define FRWK_CHECK_DW_ERROR(x)
Definition: Exception.hpp:47
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(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
PointCloudChannelPacket(const GenericData &specimen)
PyramidImagePacket(const GenericData &specimen, dwContextHandle_t ctx)
SensorServiceNodeRawDataPacket(const GenericData &specimen)
Definition: Buffer.hpp:40