65 m_bTransformation =
true;
77 m_oAttributes.emplace_back(strName);
81 ddl::DDStructure GetDefinition()
83 auto oPointCloudDescription = ddl::DDStructure(
"point_cloud_sample_header");
85 if (m_bTransformation)
87 static const auto oTransformationDescription =
88 ddl::DDStructureGenerator<tSensorTransformation>(
"sensor_transformation")
89 .addElement(
"x", &tSensorTransformation::x)
90 .addElement(
"y", &tSensorTransformation::y)
91 .addElement(
"z", &tSensorTransformation::z)
92 .addElement(
"roll", &tSensorTransformation::roll)
93 .addElement(
"pitch", &tSensorTransformation::pitch)
94 .addElement(
"yaw", &tSensorTransformation::yaw);
96 oPointCloudDescription.addElement(stream_meta_type_pointcloud_properties::Transformation,
97 oTransformationDescription);
101 if (!m_oAttributes.empty())
103 static const auto oDataTypeEnum = ddl::DDEnumGenerator<tAttribute::tDataType>(
104 "data_type", {{
"dt_boolean", tAttribute::tDataType::dt_boolean},
105 {
"dt_uint_8", tAttribute::tDataType::dt_uint8},
106 {
"dt_int_8", tAttribute::tDataType::dt_int8},
107 {
"dt_uint_16", tAttribute::tDataType::dt_uint16},
108 {
"dt_int_16", tAttribute::tDataType::dt_int16},
109 {
"dt_float16", tAttribute::tDataType::dt_float16},
110 {
"dt_uint_32", tAttribute::tDataType::dt_uint32},
111 {
"dt_int_32", tAttribute::tDataType::dt_int32},
112 {
"dt_float32", tAttribute::tDataType::dt_float32},
113 {
"dt_uint_64", tAttribute::tDataType::dt_uint64},
114 {
"dt_int_64", tAttribute::tDataType::dt_int64},
115 {
"dt_float64", tAttribute::tDataType::dt_float64},
116 {
"dt_computed_from_index", tAttribute::tDataType::dt_computed_from_index}});
118 static const auto oEndianEnum = ddl::DDEnumGenerator<tAttribute::tInMemory::eEndianess>(
119 "endianess", {{
"endian_big", tAttribute::tInMemory::eEndianess::endian_big},
120 {
"endian_little", tAttribute::tInMemory::eEndianess::endian_little}});
122 static const auto oInMemoryDescription =
123 ddl::DDStructureGenerator<tAttribute::tInMemory>(
"in_memory")
124 .addElement(
"endianess", &tAttribute::tInMemory::endianess, oEndianEnum)
125 .addElement(
"offset", &tAttribute::tInMemory::offset)
126 .addElement(
"stride", &tAttribute::tInMemory::stride);
128 static const auto oComputedFromIndexDescription =
129 ddl::DDStructureGenerator<tAttribute::tComputedFromIndex>(
"computed_from_index")
130 .addElement(
"stride_to_increment", &tAttribute::tComputedFromIndex::stride_to_increment)
131 .addElement(
"stride_to_reset", &tAttribute::tComputedFromIndex::stride_to_reset)
132 .addElement(
"increment", &tAttribute::tComputedFromIndex::increment)
133 .addElement(
"offset", &tAttribute::tComputedFromIndex::offset);
135 static const auto oAttributeDescription =
136 ddl::DDStructureGenerator<tAttribute>(
"attribute")
137 .addElement(
"type", &tAttribute::type, oDataTypeEnum)
138 .addElement(
"in_memory", &tAttribute::sInMemory, oInMemoryDescription)
139 .addElement(
"computed", &tAttribute::sComputed, oComputedFromIndexDescription);
141 auto oAttributesDescription = ddl::DDStructure(stream_meta_type_pointcloud_properties::Attributes);
142 for (
const auto& oUserAttr : m_oAttributes)
144 oAttributesDescription.addElement(oUserAttr, oAttributeDescription);
147 oPointCloudDescription.addElement(stream_meta_type_pointcloud_properties::Attributes,
148 oAttributesDescription);
153 oPointCloudDescription.addElement<
size_t>(stream_meta_type_pointcloud_properties::Count);
156 return oPointCloudDescription;
160 bool m_bTransformation =
false;
161 std::vector<std::string> m_oAttributes;
162 bool m_bSize =
false;
175 const auto [strName, strDDL, eRepresentation] =
176 adtf::mediadescription::get_media_description_from_stream_type(*pType.Get());
177 SetDynamicSampleHeader(ddl::DDStructure(strName, strDDL), eRepresentation);
183 adtf::ucom::object_ptr<const adtf::base::IProperties> pProperties;
184 THROW_IF_FAILED(pType->GetConfig(pProperties));
187 if (pProperties->Exists(stream_meta_type_pointcloud_properties::Transformation))
190 oTransformation.x = adtf::base::get_property_by_path<float>(
191 *pProperties, stream_meta_type_pointcloud_properties::TransformationX);
192 oTransformation.y = adtf::base::get_property_by_path<float>(
193 *pProperties, stream_meta_type_pointcloud_properties::TransformationY);
194 oTransformation.z = adtf::base::get_property_by_path<float>(
195 *pProperties, stream_meta_type_pointcloud_properties::TransformationZ);
196 oTransformation.roll = adtf::base::get_property_by_path<float>(
197 *pProperties, stream_meta_type_pointcloud_properties::TransformationRoll);
198 oTransformation.pitch = adtf::base::get_property_by_path<float>(
199 *pProperties, stream_meta_type_pointcloud_properties::TransformationPitch);
200 oTransformation.yaw = adtf::base::get_property_by_path<float>(
201 *pProperties, stream_meta_type_pointcloud_properties::TransformationYaw);
203 m_oTransformation = oTransformation;
209 std::map<std::string, std::pair<std::string, tAttribute>, std::less<>> oFoundAttributes;
210 adtf::base::visit_sub_properties(
211 *pProperties, stream_meta_type_pointcloud_properties::Attributes,
212 [&](
const adtf::base::IProperty& oProperty)
214 std::string strOrder;
215 THROW_IF_FAILED(oProperty.GetName(adtf_string_intf(strOrder)));
217 adtf::ucom::object_ptr<const adtf::base::IProperties> pSubProperties;
218 THROW_IF_FAILED(oProperty.GetProperties(pSubProperties));
220 const auto strAttributeName = adtf::base::get_property_by_path<std::string>(
221 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeName);
225 const auto strDataType = adtf::base::get_property_by_path<std::string>(
226 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeDataType);
228 static const std::unordered_map<std::string, tAttribute::tDataType> oDataTypeNames{
229 {
"bool", tAttribute::tDataType::dt_boolean},
230 {
"uint8", tAttribute::tDataType::dt_uint8},
231 {
"int8", tAttribute::tDataType::dt_int8},
232 {
"uint16", tAttribute::tDataType::dt_uint16},
233 {
"int16", tAttribute::tDataType::dt_int16},
234 {
"float16", tAttribute::tDataType::dt_float16},
235 {
"uint32", tAttribute::tDataType::dt_uint32},
236 {
"int32", tAttribute::tDataType::dt_int32},
237 {
"float32", tAttribute::tDataType::dt_float32},
238 {
"uint64", tAttribute::tDataType::dt_uint64},
239 {
"int64", tAttribute::tDataType::dt_int64},
240 {
"float64", tAttribute::tDataType::dt_float64},
241 {
"computed", tAttribute::tDataType::dt_computed_from_index}};
243 const auto it = oDataTypeNames.find(strDataType);
244 if (it == oDataTypeNames.end())
246 THROW_ERROR_DESC(ERR_INVALID_TYPE,
"Invalid datatype.");
248 oAttribute.type = it->second;
250 if (oAttribute.type == tAttribute::tDataType::dt_computed_from_index)
252 oAttribute.sComputed.stride_to_increment = adtf::base::get_property_by_path<uint64_t>(
254 stream_meta_type_pointcloud_properties::AttributeComputedStrideToIncrement);
255 oAttribute.sComputed.stride_to_reset = adtf::base::get_property_by_path<uint64_t>(
257 stream_meta_type_pointcloud_properties::AttributeComputedStrideToReset);
258 oAttribute.sComputed.increment = adtf::base::get_property_by_path<double>(
259 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeComputedIncrement);
260 oAttribute.sComputed.offset = adtf::base::get_property_by_path<double>(
261 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeComputedOffset);
265 static const std::unordered_map<std::string, tAttribute::tInMemory::eEndianess>
266 oEndianessNames{{
"be", tAttribute::tInMemory::eEndianess::endian_big},
267 {
"le", tAttribute::tInMemory::eEndianess::endian_little}};
269 oAttribute.sInMemory.endianess =
270 oEndianessNames.at(adtf::base::get_property_by_path<std::string>(
272 stream_meta_type_pointcloud_properties::AttributeInMemoryEndianess));
273 oAttribute.sInMemory.offset = adtf::base::get_property_by_path<uint64_t>(
274 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeInMemoryOffset);
275 oAttribute.sInMemory.stride = adtf::base::get_property_by_path<uint64_t>(
276 *pSubProperties, stream_meta_type_pointcloud_properties::AttributeInMemoryStride);
279 oFoundAttributes.emplace(strOrder, std::make_pair(strAttributeName, oAttribute));
282 for (
const auto& oOrderedAttributePair : oFoundAttributes)
284 m_oStaticAttributes.add(oOrderedAttributePair.second.first, oOrderedAttributePair.second.second);
289 if (pProperties->Exists(stream_meta_type_pointcloud_properties::Count))
291 m_oCount = adtf::base::get_property_by_path<size_t>(
292 *pProperties, stream_meta_type_pointcloud_properties::Count);
295 CheckCompatibility();
312 CheckCompatibility();
315 adtf::ucom::object_ptr<adtf::base::IProperties> pPropertiesType;
316 THROW_IF_FAILED(pType->GetConfig(pPropertiesType));
321 if (m_oTransformation)
323 THROW_IF_FAILED(CreateAndSetProperty(
324 *pPropertiesType, stream_meta_type_pointcloud_properties::TransformationX, m_oTransformation->x));
325 THROW_IF_FAILED(CreateAndSetProperty(
326 *pPropertiesType, stream_meta_type_pointcloud_properties::TransformationY, m_oTransformation->y));
327 THROW_IF_FAILED(CreateAndSetProperty(
328 *pPropertiesType, stream_meta_type_pointcloud_properties::TransformationZ, m_oTransformation->z));
329 THROW_IF_FAILED(CreateAndSetProperty(*pPropertiesType,
330 stream_meta_type_pointcloud_properties::TransformationRoll,
331 m_oTransformation->roll));
332 THROW_IF_FAILED(CreateAndSetProperty(*pPropertiesType,
333 stream_meta_type_pointcloud_properties::TransformationPitch,
334 m_oTransformation->pitch));
335 THROW_IF_FAILED(CreateAndSetProperty(*pPropertiesType,
336 stream_meta_type_pointcloud_properties::TransformationYaw,
337 m_oTransformation->yaw));
342 for (
const auto& oStaticAttrTuple : m_oStaticAttributes)
344 const auto& strAttributeName = std::get<std::string>(oStaticAttrTuple);
345 const auto& oAttribute = std::get<tAttribute>(oStaticAttrTuple);
347 const auto strPropertyPath = std::string(stream_meta_type_pointcloud_properties::Attributes) +
"/" +
348 std::to_string(nIndex) +
"/";
349 THROW_IF_FAILED(adtf::base::create_property_tree(*pPropertiesType, strPropertyPath.c_str()));
351 THROW_IF_FAILED(CreateAndSetProperty(
352 *pPropertiesType, strPropertyPath + stream_meta_type_pointcloud_properties::AttributeName,
355 static const std::unordered_map<tAttribute::tDataType, std::string> oDataTypeStrings{
356 {tAttribute::tDataType::dt_boolean,
"bool"}, {tAttribute::tDataType::dt_uint8,
"uint8"},
357 {tAttribute::tDataType::dt_int8,
"int8"}, {tAttribute::tDataType::dt_uint16,
"uint16"},
358 {tAttribute::tDataType::dt_int16,
"int16"}, {tAttribute::tDataType::dt_float16,
"float16"},
359 {tAttribute::tDataType::dt_uint32,
"uint32"}, {tAttribute::tDataType::dt_int32,
"int32"},
360 {tAttribute::tDataType::dt_float32,
"float32"}, {tAttribute::tDataType::dt_uint64,
"uint64"},
361 {tAttribute::tDataType::dt_int64,
"int64"}, {tAttribute::tDataType::dt_float64,
"float64"},
362 {tAttribute::tDataType::dt_computed_from_index,
"computed"}};
363 THROW_IF_FAILED(CreateAndSetProperty(
364 *pPropertiesType, strPropertyPath + stream_meta_type_pointcloud_properties::AttributeDataType,
365 oDataTypeStrings.at(oAttribute.type)));
367 if (oAttribute.type == tAttribute::tDataType::dt_computed_from_index)
369 THROW_IF_FAILED(CreateAndSetProperty(
371 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeComputedStrideToIncrement,
372 oAttribute.sComputed.stride_to_increment));
373 THROW_IF_FAILED(CreateAndSetProperty(
375 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeComputedStrideToReset,
376 oAttribute.sComputed.stride_to_reset));
377 THROW_IF_FAILED(CreateAndSetProperty(
379 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeComputedIncrement,
380 oAttribute.sComputed.increment));
381 THROW_IF_FAILED(CreateAndSetProperty(
383 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeComputedOffset,
384 oAttribute.sComputed.offset));
388 static const std::map<tAttribute::tInMemory::eEndianess, std::string> oEndianessStrings = {
389 {tAttribute::tInMemory::eEndianess::endian_big,
"be"},
390 {tAttribute::tInMemory::eEndianess::endian_little,
"le"}};
392 THROW_IF_FAILED(CreateAndSetProperty(
394 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeInMemoryEndianess,
395 oEndianessStrings.at(oAttribute.sInMemory.endianess)));
396 THROW_IF_FAILED(CreateAndSetProperty(
398 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeInMemoryOffset,
399 oAttribute.sInMemory.offset));
400 THROW_IF_FAILED(CreateAndSetProperty(
402 strPropertyPath + stream_meta_type_pointcloud_properties::AttributeInMemoryStride,
403 oAttribute.sInMemory.stride));
411 THROW_IF_FAILED(CreateAndSetProperty(*pPropertiesType,
412 stream_meta_type_pointcloud_properties::Count, *m_oCount));
417 assert(m_oDynamicSampleHeader);
418 THROW_IF_FAILED(adtf::mediadescription::set_media_description_properties(
419 *pPropertiesType, *m_oDynamicSampleHeader, m_eRepresentation));
431 if (m_oTransformationAccess)
433 THROW_ERROR_DESC(ERR_ACCESS_DENIED,
"Sensor transformation is already defined.");
436 m_oTransformation = oTransformation;
448 THROW_ERROR_DESC(ERR_INVALID_ARG,
"Can't add static attribute to dynamic layout.");
450 if (m_oStaticAttributes.exists(strName))
452 THROW_ERROR_DESC(ERR_INVALID_ARG,
"Static attribute '%s' already exists.", strName.c_str());
455 m_oStaticAttributes.add(strName, oAttribute);
466 THROW_ERROR_DESC(ERR_INVALID_ARG,
467 "Can't add static count to type with dynamic layout which also contains a count element.");
473 void SetDynamicSampleHeader(ddl::DDStructure oHeader, ddl::DataRepresentation eRepresentation)
475 m_oTransformationAccess = std::nullopt;
476 m_oDynamicAttributes.clear();
477 m_oCountAccess = std::nullopt;
479 ddl::codec::CodecFactory oCodecFactory(oHeader);
483 const auto oTransformationElement =
484 oCodecFactory.getElement(stream_meta_type_pointcloud_properties::Transformation);
485 m_oTransformationAccess.emplace(oTransformationElement, eRepresentation);
487 catch (
const std::runtime_error&)
491 const auto oAttributesElement = [&]() -> std::optional<ddl::codec::CodecFactory::Element>
495 return oCodecFactory.getElement(stream_meta_type_pointcloud_properties::Attributes);
497 catch (
const std::runtime_error&)
503 if (oAttributesElement)
505 for (
const auto& oAttribute : oAttributesElement->getChildElements())
507 m_oDynamicAttributes.add(oAttribute.getName(), tAttributeAccess(oAttribute, eRepresentation));
513 const auto oCountElement = oCodecFactory.getElement(stream_meta_type_pointcloud_properties::Count);
514 m_oCountAccess.emplace(oCountElement, eRepresentation);
516 catch (
const std::runtime_error&)
520 m_nHeaderSize = oCodecFactory.getStaticBufferSize(eRepresentation);
521 m_oDynamicSampleHeader = std::move(oHeader);
522 m_eRepresentation = eRepresentation;
530 return m_nHeaderSize;
538 static size_t GetPayloadSize(
size_t nPointCount,
const tAttributes& oAttributes)
noexcept
541 for (
const auto& oTuple : oAttributes)
543 const auto& oAttribute = std::get<tAttribute>(oTuple);
544 nMax = std::max(nMax, oAttribute.sInMemory.offset + nPointCount * oAttribute.sInMemory.stride +
557 return m_oStaticAttributes;
565 std::vector<std::string> oResult;
566 for (
const auto& oAttributeTuple : m_oDynamicAttributes)
568 oResult.emplace_back(std::get<std::string>(oAttributeTuple));
581 for (
const auto& oAttributeTuple : m_oStaticAttributes)
583 oResult.emplace_back(std::get<std::string>(oAttributeTuple));
595 if (m_oTransformationAccess)
597 THROW_ERROR_DESC(ERR_NOT_SUPPORTED,
"Can't predict sensor transformation for an external source.");
600 return m_oTransformation;
611 THROW_ERROR_DESC(ERR_NOT_SUPPORTED,
"Can't predict amount of points in pointcloud for an external source.");
622 return m_oDynamicSampleHeader.has_value();
626 struct tPointCloudAccess
628 tPointCloudAccess() =
delete;
629 tPointCloudAccess(
const tPointCloudAccess&) =
delete;
640 m_oHeader(detail::tConstBuffer(pData, m_oLayout.
GetHeaderSize())),
641 m_oData(detail::tConstBuffer(static_cast<const std::byte*>(pData) + m_oLayout.
GetHeaderSize(),
644 Construct(nDataSize);
656 m_oHeader(detail::tBuffer(pData, m_oLayout.
GetHeaderSize())),
657 m_oData(detail::tBuffer(static_cast<std::byte*>(pData) + m_oLayout.
GetHeaderSize(),
660 Construct(nDataSize);
671 m_oHeader(detail::tConstBuffer(oData.GetPtr(), m_oLayout.
GetHeaderSize())),
672 m_oData(detail::tConstBuffer(static_cast<const std::byte*>(oData.GetPtr()) + m_oLayout.
GetHeaderSize(),
675 Construct(oData.GetSize());
686 m_oHeader(detail::tBuffer(oData.GetPtr(), m_oLayout.
GetHeaderSize())),
687 m_oData(detail::tBuffer(static_cast<std::byte*>(oData.GetPtr()) + m_oLayout.
GetHeaderSize(),
690 Construct(oData.GetSize());
698 const void* GetData()
const
700 return std::visit([
this](
auto&& oData) ->
const void* {
return oData.pData; }, m_oData);
703 void* GetMutableData()
706 [
this](
auto&& oData) ->
void*
708 if constexpr (std::is_same_v<
decltype(oData.pData),
const void*
const>)
710 THROW_ERROR_DESC(ERR_INVALID_ARG,
711 "Can't obtain a mutable buffer reference from non-const buffer.");
721 size_t GetBufferSize()
const
723 return std::visit([
this](
auto&& oData) ->
size_t {
return oData.nSize; }, m_oData);
728 if (m_oResolvedAttributes)
730 return *m_oResolvedAttributes;
740 return m_oResolvedSensorTransformation;
746 std::optional<size_t>
GetCount()
const
748 if (m_oResolvedCount)
750 return m_oResolvedCount;
756 template <
typename Callable,
typename Signature = adtf::ucom::nitro::detail::signature_t<Callable>>
757 void IteratePoints(Callable&& fnCallback)
const
759 IteratePointsImplementation(std::function<Signature>(fnCallback), make_tuple_sequence<adtf::ucom::nitro::detail::function_traits<std::remove_reference_t<Callable>>::argument_count,
size_t>());
762 template <
typename Callable,
typename ...Indices,
typename Signature = adtf::ucom::nitro::detail::signature_t<Callable>>
763 void IteratePoints(Callable&& fnCallback, Indices... indices)
const
765 static_assert(adtf::ucom::nitro::detail::function_traits<std::remove_reference_t<Callable>>::argument_count ==
sizeof...(Indices));
766 IteratePointsImplementation(std::function<Signature>(fnCallback), std::forward_as_tuple(indices...));
770 template<
typename T, T ...I>
771 static auto make_tuple_sequence_helper(std::integer_sequence<T, I...>)
773 return std::make_tuple(I...);
776 template<std::
size_t I,
typename T>
777 static auto make_tuple_sequence()
779 return make_tuple_sequence_helper(std::make_integer_sequence<T, I>());
782 template <
typename ...Indices, std::size_t... Is>
783 auto GetAttributesByIndex(
const std::tuple<Indices...>& indices,
784 std::index_sequence<Is...>)
const
786 return std::forward_as_tuple(
static_cast<const tAttribute&
>(
GetAttributes().at(std::get<Is>(indices)))...);
789 template <
typename ...Indices>
790 auto GetAttributesByIndex(
const std::tuple<Indices...>& indices)
const
792 return GetAttributesByIndex(indices, std::index_sequence_for<Indices...>{});
795 template <
typename ...Attributes,
typename ...Indices>
796 void IteratePointsImplementation(
const std::function<
void(Attributes...)>& fnCallback,
const std::tuple<Indices...>& indices)
const
798 const auto oAttributes = GetAttributesByIndex(indices);
799 for (
size_t nIndex = 0; nIndex <
GetCount(); ++nIndex)
801 CallWithAttribute<
sizeof...(Attributes)>(fnCallback, oAttributes, nIndex);
805 template <
size_t nAttributeIndex,
typename ...CallbackAttributes,
typename AttributeReferences,
typename ...Attributes>
806 void CallWithAttribute(
const std::function<
void(CallbackAttributes...)>& fnCallback,
807 [[maybe_unused]]
const AttributeReferences& oAttributes,
808 [[maybe_unused]]
size_t nIndex,
809 Attributes&&... args)
const
811 if constexpr (nAttributeIndex == 0)
813 fnCallback(detail::to_type<CallbackAttributes>(std::forward<Attributes>(args))...);
817 CallWithAttribute<nAttributeIndex - 1>(fnCallback,
820 get_attribute_value(std::get<nAttributeIndex - 1>(oAttributes), detail::tConstBuffer(GetData(), GetBufferSize()), nIndex), std::forward<Attributes>(args)...);
824 void Construct(
const size_t nDataSize)
830 THROW_ERROR_DESC(ERR_INVALID_ARG,
"Static layout must not define a header.");
837 size_t nPointSizeBytes = 0;
838 for (
const auto& oAttributeTuple : m_oLayout.m_oStaticAttributes)
840 const auto& oAttribute = std::get<tAttribute>(oAttributeTuple);
841 nPointSizeBytes += oAttribute.Size(oAttribute.type);
844 if (nPointSizeBytes != 0)
846 m_oResolvedCount = nDataSize / nPointSizeBytes;
854 THROW_ERROR_DESC(ERR_INVALID_ARG,
"Can't target dynamic layout without a header.");
858 THROW_ERROR_DESC(ERR_INVALID_ARG,
"Passed buffer can't even hold valid header.");
865 template<
typename T,
typename Access>
866 T Resolve(
const Access& oHeaderAccess)
const
869 [&oHeaderAccess](
auto&& oHeader) -> T
871 if constexpr (!std::is_same_v<std::monostate, std::decay_t<
decltype(oHeader)>>)
873 return oHeaderAccess.getMember(oHeader.pData, oHeader.nSize);
883 tAttributes ResolveAttributes()
const
886 for (
const auto& oAttribute : m_oLayout.m_oDynamicAttributes)
888 oResult.add(std::get<0>(oAttribute), Resolve<tAttribute>(std::get<1>(oAttribute)));
895 if (m_oLayout.m_oTransformationAccess)
897 m_oResolvedSensorTransformation = Resolve<tSensorTransformation>(*m_oLayout.m_oTransformationAccess);
899 m_oResolvedAttributes = ResolveAttributes();
901 if (m_oLayout.m_oCountAccess)
903 m_oResolvedCount = Resolve<size_t>(*m_oLayout.m_oCountAccess);
907 if (!m_oResolvedCount && m_oResolvedAttributes)
910 size_t nPointSizeBytes = 0;
911 for (
const auto& oAttributeTuple : *m_oResolvedAttributes)
913 const auto& oAttribute = std::get<tAttribute>(oAttributeTuple);
914 nPointSizeBytes += oAttribute.Size(oAttribute.type);
917 if (nPointSizeBytes != 0)
919 m_oResolvedCount = GetBufferSize() / nPointSizeBytes;
927 const std::variant<std::monostate, detail::tBuffer, detail::tConstBuffer> m_oHeader;
928 std::optional<tAttributes> m_oResolvedAttributes;
930 std::optional<tSensorTransformation> m_oResolvedSensorTransformation;
931 std::optional<size_t> m_oResolvedCount;
933 const std::variant<detail::tBuffer, detail::tConstBuffer> m_oData;
937 struct tSensorTransformationAccess
939 tSensorTransformationAccess() =
delete;
940 tSensorTransformationAccess(
const ddl::codec::CodecFactory::Element& oElement,
941 ddl::DataRepresentation eRepresentation)
943 m_oX = adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"x").getIndex(), eRepresentation)
945 m_oY = adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"y").getIndex(), eRepresentation)
947 m_oZ = adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"z").getIndex(), eRepresentation)
950 adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"roll").getIndex(), eRepresentation)
953 adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"pitch").getIndex(), eRepresentation)
956 adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"yaw").getIndex(), eRepresentation)
960 tSensorTransformation getMember(
const void* pHeader,
const size_t nHeaderSize)
const
962 tSensorTransformation oResult{ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oX),
963 ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oY),
964 ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oZ),
965 ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oRoll),
966 ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oPitch),
967 ddl::codec::LeafValueGetter<float>::getValue(pHeader, nHeaderSize, m_oYaw)};
973 ddl::codec::LeafLayout m_oX;
974 ddl::codec::LeafLayout m_oY;
975 ddl::codec::LeafLayout m_oZ;
976 ddl::codec::LeafLayout m_oRoll;
977 ddl::codec::LeafLayout m_oPitch;
978 ddl::codec::LeafLayout m_oYaw;
981 struct tAttributeAccess
983 tAttributeAccess() =
delete;
985 tAttributeAccess(
const ddl::codec::CodecFactory::Element& oElement, ddl::DataRepresentation eRepresentation)
988 adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"type").getIndex(), eRepresentation)
990 m_oEndianess = adtf::mediadescription::tLeafCodecIndex(
991 oElement.getChildElement(
"in_memory.endianess").getIndex(), eRepresentation)
993 m_oOffsetMemory = adtf::mediadescription::tLeafCodecIndex(
994 oElement.getChildElement(
"in_memory.offset").getIndex(), eRepresentation)
996 m_oStride = adtf::mediadescription::tLeafCodecIndex(oElement.getChildElement(
"in_memory.stride").getIndex(),
999 m_oStrideToInc = adtf::mediadescription::tLeafCodecIndex(
1000 oElement.getChildElement(
"computed.stride_to_increment").getIndex(), eRepresentation)
1002 m_oStrideToReset = adtf::mediadescription::tLeafCodecIndex(
1003 oElement.getChildElement(
"computed.stride_to_reset").getIndex(), eRepresentation)
1005 m_oIncrement = adtf::mediadescription::tLeafCodecIndex(
1006 oElement.getChildElement(
"computed.increment").getIndex(), eRepresentation)
1008 m_oOffsetComputed = adtf::mediadescription::tLeafCodecIndex(
1009 oElement.getChildElement(
"computed.offset").getIndex(), eRepresentation)
1013 tAttribute getMember(
const void* pHeader,
const size_t nHeaderSize)
const
1016 oResult.type = ddl::codec::LeafValueGetter<tAttribute::tDataType>::getValue(pHeader, nHeaderSize, m_oType);
1017 if (oResult.type != tAttribute::tDataType::dt_computed_from_index)
1019 oResult.sInMemory.endianess = ddl::codec::LeafValueGetter<tAttribute::tInMemory::eEndianess>::getValue(
1020 pHeader, nHeaderSize, m_oEndianess);
1021 oResult.sInMemory.offset =
1022 ddl::codec::LeafValueGetter<size_t>::getValue(pHeader, nHeaderSize, m_oOffsetMemory);
1023 oResult.sInMemory.stride =
1024 ddl::codec::LeafValueGetter<size_t>::getValue(pHeader, nHeaderSize, m_oStride);
1028 oResult.sComputed.stride_to_increment =
1029 ddl::codec::LeafValueGetter<size_t>::getValue(pHeader, nHeaderSize, m_oStrideToInc);
1030 oResult.sComputed.stride_to_reset =
1031 ddl::codec::LeafValueGetter<size_t>::getValue(pHeader, nHeaderSize, m_oStrideToReset);
1032 oResult.sComputed.increment =
1033 ddl::codec::LeafValueGetter<double>::getValue(pHeader, nHeaderSize, m_oIncrement);
1034 oResult.sComputed.offset =
1035 ddl::codec::LeafValueGetter<double>::getValue(pHeader, nHeaderSize, m_oOffsetComputed);
1042 ddl::codec::LeafLayout m_oType;
1044 ddl::codec::LeafLayout m_oEndianess;
1045 ddl::codec::LeafLayout m_oOffsetMemory;
1046 ddl::codec::LeafLayout m_oStride;
1048 ddl::codec::LeafLayout m_oStrideToInc;
1049 ddl::codec::LeafLayout m_oStrideToReset;
1050 ddl::codec::LeafLayout m_oIncrement;
1051 ddl::codec::LeafLayout m_oOffsetComputed;
1056 tCountAccess() =
delete;
1058 tCountAccess(
const ddl::codec::CodecFactory::Element& oElement, ddl::DataRepresentation eRepresentation)
1060 m_oCount = adtf::mediadescription::tLeafCodecIndex(oElement.getIndex(), eRepresentation).getLayout();
1063 size_t getMember(
const void* pHeader,
const size_t nHeaderSize)
const
1065 return ddl::codec::LeafValueGetter<size_t>::getValue(pHeader, nHeaderSize, m_oCount);
1069 ddl::codec::LeafLayout m_oCount;
1072 void CheckCompatibility()
const
1074 using namespace std::literals;
1076 if (!m_oStaticAttributes.empty() && !m_oDynamicAttributes.empty())
1078 THROW_ERROR_DESC(ERR_NOT_SUPPORTED,
"The defines both static and dynamic attributes, which is not allowed.");
1081 static const std::array<std::string, 6> oReservedAttributes{
"x"s,
"y"s,
"z"s,
"distance"s,
"yaw"s,
"pitch"s};
1082 size_t nMandatoryCount = 0;
1083 for (
const auto& strAttribute : oReservedAttributes)
1085 if (m_oStaticAttributes.exists(strAttribute))
1089 else if (m_oDynamicAttributes.exists(strAttribute))
1095 if (nMandatoryCount < 3)
1097 THROW_ERROR_DESC(ERR_INVALID_TYPE,
"The StreamType is missing mandatory attributes.");
1101 template<
typename T>
1103 CreateAndSetProperty(adtf::base::IProperties& oProperties,
const std::string& strPath,
const T& oValue)
1105 RETURN_IF_FAILED(adtf::base::create_property_tree(oProperties, strPath.c_str()));
1106 RETURN_IF_FAILED(adtf::base::set_property_by_path(oProperties, strPath.c_str(), oValue));
1111 std::optional<tCountAccess> m_oCountAccess;
1112 std::optional<tSensorTransformationAccess> m_oTransformationAccess;
1113 indexed_vector<tAttributeAccess> m_oDynamicAttributes;
1115 tAttributes m_oStaticAttributes;
1116 std::optional<tSensorTransformation> m_oTransformation;
1117 std::optional<size_t> m_oCount;
1118 size_t m_nHeaderSize = 0;
1119 std::optional<ddl::DDStructure> m_oDynamicSampleHeader;
1120 ddl::DataRepresentation m_eRepresentation;