Compute Graph Framework SDK Reference  5.8
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