ADTF  3.18.2
The ADTF Codecs and SampleCodecs

The ADTF Codecs and CodecFactory

With ADTF 3.14 a new SampleCodec and Codec was introduced. With ADTF 3.15 it has been moved to to the open source DDL Library within the dev_essential.

SampleCodec and Codec

The new osborn::cSampleCodecFactory can create the cSampleCodec, cSampleDecoder, cStaticSampleCodec and the cStaticSampleDecoder that must be accessed with the help of a CodecIndex.

The Codec Index and the Element Iterator

The codec index will provide a fast index based vector to find the right element in the child elements and retrieve the access information for reading and writing their values. This codec index identifies exactly one element within the structure. To retrieve the index use the GetElements method of the Codecs.

Preparing
struct creation:
struct tMySubStruct
{
uint16_t value1[2];
uint32_t value2;
uint8_t value3;
};
struct tMyStruct
{
uint16_t value = 1;
tMySubStruct sub_array[2] = {{{2, 3}, 4, 5}, {{6, 7}, 8, 9}};
uint32_t array[3] = {10, 11, 12};
};
DDL creation:
using namespace adtf::mediadescription;
oMySubStruct.addElement("value1", &tMySubStruct::value1);
oMySubStruct.addElement("value2", &tMySubStruct::value2);
oMySubStruct.addElement("value3", &tMySubStruct::value3);
oMyStruct.addElement("value", &tMyStruct::value);
oMyStruct.addElement("sub_array", &tMyStruct::sub_array, oMySubStruct);
oMyStruct.addElement("array", &tMyStruct::array);
Creating a valid Structure Data Definition by a existing type and its member types.
Definition: ddstructure.h:644
Namespace for the ADTF Media Description SDK.
Sample creation:
using namespace adtf::streaming;
tMyStruct sMyStruct;
RETURN_IF_FAILED(pSample->Set(0, &sMyStruct, sizeof(sMyStruct)));
#define RETURN_IF_FAILED(s)
Return if expression is failed, which requires the calling function's return type to be tResult.
Object pointer implementation used for reference counting on objects of type IObject.
Definition: object_ptr.h:163
tResult alloc_sample(ucom::ant::iobject_ptr< ucom::ant::IObject > &pSampleObject, const char *strSampleCID)
Helper Function to get a Sample Instance through the adtf::ucom::ant::IRuntime.
Namespace for the ADTF Streaming SDK.
Usage of decoder only on first level
using namespace adtf::mediadescription;
cSampleCodecFactory oFactory(oMyStruct);
RETURN_IF_FAILED(oFactory.IsValid());
auto oDecoder = oFactory.MakeStaticDecoderFor(pSample);
//iterate the elements at the first level
for (auto oElement : oDecoder.GetElements())
{
auto oCodecIndex = oElement.getIndex(); //this codec
auto oFullName = oElement.getFullName();
auto strArray = oElement.isArray() ? "is array" : "is no array";
auto strArraySize = std::to_string(oElement.getArraySize());
auto bHasChildren = oElement.hasChildren();
auto strHasChildren = bHasChildren ? "has children" : "has no children";
std::string strValue;
if (!bHasChildren)
{
strValue = oElement.getValue<std::string>();
}
else
{
//if we call getStringValue on a structure it throws an error!
strValue = "<this is a structure>";
}
std::cout << "CodecIndex: " << toString(oCodecIndex) << " - " << oFullName << " - " << strArray
<< " - "
<< " ArraySize " << strArraySize << " - " << strHasChildren << std::endl;
std::cout << " Value: " << strValue << std::endl
<< std::endl;
}
cString to_string(const tResult &i_oResult, eResultFormatFlags i_eFormatFlags=eResultFormatFlags::RFF_DisableNone, const tChar *i_strFormat=nullptr)
Copy all information of an assigned result object to a (formatted) string.
std::string toString(const Result &result, ResultFormatFlags formatting_flags=DisableNone, const char *format=nullptr)
Copy all information of an assigned result object to a (formatted) string.

Following output:
CodecIndex: {{0, 0}} - value - is no array - ArraySize 1 - has no children
Value: 1
CodecIndex: {{1, 0}} - sub_array[0] - is array - ArraySize 2 - has children
Value: <this is a structure>
CodecIndex: {{2, 0}} - array[0] - is array - ArraySize 3 - has no children
Value: 10
Usage of sample factory at each level to prepare codec usage
//iterate the elements at each level use the helper template
for_each_element(oFactory.GetElements(),
[](auto& oElement)
{
auto oCodecIndex = oElement.getIndex(); //this codec
auto oFullName = oElement.getFullName();
auto strArray = oElement.isArray() ? "is array" : "is no array";
auto strArraySize = std::to_string(oElement.getArraySize());
auto bHasChildren = oElement.hasChildren();
auto strHasChildren = bHasChildren ? "has children" : "has no children";
std::string strType;
if (!bHasChildren)
{
strType = std::to_string(static_cast<int8_t>(oElement.getType()));
}
else
{
strType = "<this is a structure>";
}
std::cout << "CodecIndex: " << toString(oCodecIndex) << " - " << oFullName << " - " << strArray
<< " - "
<< " ArraySize " << strArraySize << " - " << strHasChildren << std::endl;
std::cout << " Type: " << strType << std::endl
<< std::endl;
//this function does not go into array level! ... only array positions 0 are retrieved!
});
void for_each_element(ElementsType &oElements, const element_callback< ElementsType > &fnCallback)
Iterates elements without array elements (also structures).

Following output:
CodecIndex: {{0, 0}} - value - is no array - ArraySize 1 - has no children
Type: 5
CodecIndex: {{1, 0}} - sub_array[0] - is array - ArraySize 2 - has children
Type: <this is a structure>
CodecIndex: {{1, 0}, {0, 0}} - sub_array[0].value1[0] - is array - ArraySize 2 - has no children
Type: 5
CodecIndex: {{1, 0}, {1, 0}} - sub_array[0].value2 - is no array - ArraySize 1 - has no children
Type: 7
CodecIndex: {{1, 0}, {2, 0}} - sub_array[0].value3 - is no array - ArraySize 1 - has no children
Type: 3
CodecIndex: {{2, 0}} - array[0] - is array - ArraySize 3 - has no children
Type: 7
Usage of decoder at each leaf level
//iterate the elements at each level use the helper template
for_each_leaf_element(oDecoder.GetElements(),
[](auto& oElement) {
auto oCodecIndex = oElement.getIndex(); //this codec
auto oFullName = oElement.getFullName();
auto strArray = oElement.isArray() ? "is array" : "is no array";
auto strArraySize = std::to_string(oElement.getArraySize());
auto bHasChildren = oElement.hasChildren();
auto strHasChildren = bHasChildren ? "has children" : "has no children";
std::string strValue;
if (!bHasChildren)
{
strValue = oElement.getStringValue();
//for a direct type conversion use following: (gcc needs that syntax)
//strValue = oElement.template getValue<std::string>();
}
else
{
//the for_each_leaf_element only go thru POD types, the structures are resolved for you
//this else path will never be reached!
strValue = "<this is a structure>";
}
std::cout << "CodecIndex: " << toString(oCodecIndex) << " - " << oFullName << " - " << strArray
<< " - "
<< " ArraySize " << strArraySize << " - " << strHasChildren << std::endl;
std::cout << " Value: " << strValue << std::endl
<< std::endl;
});
void for_each_leaf_element(ElementsType &oElements, const element_callback< ElementsType > &fnCallback)
Iterates ALL leaf elements within ALL array elements.

Following output:
CodecIndex: {{0, 0}} - value - is no array - ArraySize 1 - has no children
Value: 1
CodecIndex: {{1, 0}, {0, 0}} - sub_array[0].value1[0] - is array - ArraySize 2 - has no children
Value: 2
CodecIndex: {{1, 0}, {0, 1}} - sub_array[0].value1[1] - is array - ArraySize 2 - has no children
Value: 3
CodecIndex: {{1, 0}, {1, 0}} - sub_array[0].value2 - is no array - ArraySize 1 - has no children
Value: 4
CodecIndex: {{1, 0}, {2, 0}} - sub_array[0].value3 - is no array - ArraySize 1 - has no children
Value: 5
CodecIndex: {{1, 1}, {0, 0}} - sub_array[1].value1[0] - is array - ArraySize 2 - has no children
Value: 6
CodecIndex: {{1, 1}, {0, 1}} - sub_array[1].value1[1] - is array - ArraySize 2 - has no children
Value: 7
CodecIndex: {{1, 1}, {1, 0}} - sub_array[1].value2 - is no array - ArraySize 1 - has no children
Value: 8
CodecIndex: {{1, 1}, {2, 0}} - sub_array[1].value3 - is no array - ArraySize 1 - has no children
Value: 9
CodecIndex: {{2, 0}} - array[0] - is array - ArraySize 3 - has no children
Value: 10
CodecIndex: {{2, 1}} - array[1] - is array - ArraySize 3 - has no children
Value: 11
CodecIndex: {{2, 2}} - array[2] - is array - ArraySize 3 - has no children
Value: 12

The Codec Leaf Index

Since the DDL Codecs where introduced the access to the elements where indexed based in a flat structure. Each leaf element was identified via a leaf counter index. At one side this was a big advantage for fast access, but on the other side it leaded to a long initialization time while the structure has huge arrays. The legacy API for this leaf index can be found at cCodecFactoryLegacy, cCodecLegacy and cDecoderLegacy.

This API is used to support also the "old" adtf_ddl::access_element API. This support will be removed in further releases, so please see Porting ADTF DDL to Open Source DDL Library chapter for a guide thru the porting process.

To map a leaf index to its corresponding codec index use the legacy Resolve method.

The Codecs and the Codec APIs

You will now have 5 different CodecFactory implementations and 4 different APIs. To give you an overview, have a look at following table:

The CodecFactory and its Decoders/Codecs The Codec Index and the Element Iterator The Codec Leaf Index adtf_ddl::access_element API
(old adtf_ddl pkg)
ddl::access_element API
(comes with dev_essential 1.1.0)
osborn::cSampleCodecFactory yes legacy legacy no
ddl::codec::CodecFactory (new codec API within dev_essential) yes legacy no no
ddl::codec::CodecFactory (current dev_essential) no yes no yes
flash::cSampleCodecFactory (old) no yes yes no
old adtf_ddl::cCodecFactory (old) no yes yes

no

We recommend to port your code to the newest osborn::cSampleCodecFactory / ddl::codec::CodecFactory and only use the The Codec Index and the Element Iterator API. All other will be removed in further releases!

Porting ADTF DDL to Open Source DDL Library

Since ADTF 3.14 we changed the dependencies of the of the mainpage_mediadescription_pkg from the ADTF DDL SDK (Legacy Package) to the DDL Library. This prevent any further forked development within ADTF of the DDL Library. Additionally, you will now have different codec implementations: see The Codecs and the Codec APIs for details.

Unfortunatelly, your code needs to be adapted to work with this new featured classes:

Port your code to the new Open Source DDL Library

The deprecated warnings will guide you through the porting process. Following things are to do:

You will automatically use the new cSampleCodecFactory
If you are using the adtf_ddl::cCodecFactory directly, you have to use change to the classes.
//old code
auto oDecoder = oSampleCodecFactory.MakeDecoderFor(...);
//new code (no change necessary)
auto oDecoder = oSampleCodecFactory.MakeDecoderFor(...);
Factory class for ddl codecs for samples.
Definition: sample_codec.h:946
cSampleDecoder MakeDecoderFor(const adtf::streaming::ISample &oSample, ddl::tDataRepresentation eDataRepresentation) const
Creates a decoder for the given sample.
In the new cSampleDecoder and cStaticSampleDecoder is no cVariant anymore
The most important change for you is! There is NO adtf_util::cVariant used!
//old code
auto oVariant = oDecoder.GetElementValue("my_value");
//... to figure out the type
auto nType = oVariant.GetType();
tUInt64 nValue = oVariant.GetInt64();
//new code (use the templated direct type to convert)
auto oElement = oDecoder.GetElement("my_value")
auto nType = oElement.getType();
tUInt64 nValue = oElement.getValue<tUInt64>();
uint64_t tUInt64
type definition for unsigned integer values (64bit) (platform and compiler independent type).
Change Codec and cCodec
If you are using the adtf_ddl::cCodecFactory directly, you have to use change the classes.
//old code
auto oDecoder = oCodecFactory.MakeDecoderFor(...);
//new code
ddl::CodecFactory oCodecFactory;
auto oDecoder = oCodecFactory.makeDecoderFor(...);
//new code
auto oDecoder = oCodecFactory.makeDecoderFor(...);
//old code
//new code
ddl::Codec oCodec;
//new code
//old code
//new code
ddl::Decoder oDecoder;
//new code
cDecoder MakeDecoderFor(const void *pData, size_t nDataSize, tDataRepresentation eRep=tDataRepresentation::Deserialized) const
Creates a decoder for the given data.
Factory class for ddl codecs.
Decoder makeDecoderFor(const void *data, size_t data_size, DataRepresentation rep=deserialized) const
Creates a decoder for the given data.
Decoder for dynamic structures defined by a DataDefinition definition.
Definition: codec_legacy.h:129
Decoder for dynamic structures defined by a DataDefinition definition.
Definition: codec_legacy.h:46
Decoder makeDecoderFor(const void *data, size_t data_size, DataRepresentation rep=deserialized) const
Creates a decoder for the given data.
Legacy support for access_element API
//old code
//this will work, but is deprecated
//new code uses the Codec Iterator!
auto oElement = oDecoder.GetElement("my_element").getIndex();
tResult GetElement(size_t nIndex, const tStructElement *&pElement) const
Access information about an element.
tResult find_index(const T &oDecoder, const A_UTILS_NS::cString &strElementName, size_t &nIndex)
Find the index of an element by name.
Legacy StructElement instead of tStructElement
//old code
oDecoder.GetElement(nIdx, pElement);
std::string oElementName = oElement.strName;
//new code for legacy, but deprecated
oDecoder.GetElement(nIdx, pElement);
std::string oElementName = oElement.name;
//new code for using Codec Iterator
auto oElement = oDecoder.GetElement("my_element");
//iterate all element with the Element Iterator
for_each_leaf_element(oDecoder.GetElements(),
[](const auto& oElement){
std::cout << oElement.getFullName() << std::endl;
});

You may also fully switch off legacy API with the following:

In code
//define the NO_ADTF_MEDIA_DESCRIPTION_LEGACY macro before including adtf_mediadescription
#define NO_ADTF_MEDIA_DESCRIPTION_LEGACY
#include <adtf_mediadescription.h>
In cmake
# set NO_ADTF_MEDIA_DESCRIPTION_LEGACY als target compile definition
target_compile_defintions(my_filter PRIVATE NO_ADTF_MEDIA_DESCRIPTION_LEGACY)

Keep your code in legacy mode

Change the usage of namespace
Instead of using the adtf::mediadescription namespace use the adtf::mediadescription::adtf_ddl_legacy namespace.
//oldcode
#include <adtf_mediadescription.h>
using namspace adtf::media_description;
//oldcode
#include <adtf_mediadescription.h>
using namspace adtf::media_description::adtf_ddl_legacy;

Keep your code in legacy mode

Use new DDL Library with only a small effort
You may use the new DDL Library and the new adtf::mediadescription classes very fast, if you change only the usage of tStructElement:
//oldcode
#include <adtf_mediadescription.h>
using namspace adtf::media_description;
//oldcode
#include <adtf_mediadescription.h>
using namspace adtf::media_description_adtf_ddl_legacy;
Use StructElement instead of tStructElement
//old code
oDecoder.GetElement(nIdx, pElement);
//new code
oDecoder.GetElement(nIdx, pElement);
//old code
auto oElement = oDecoder.GetElement(nIdx);
auto oElementName = oElement.strName;
//new code
auto oElement = oDecoder.GetElement(nIdx);
auto oElementName = oElement.name;

Switch off deprecated warnings if you do not port:

In code
//define the ADTF3_NO_DEPRECATED_WARNINGS macro before including adtf_mediadescription
#define ADTF3_NO_DEPRECATED_WARNINGS
#include <adtf_mediadescription.h>
In cmake
# set ADTF3_NO_DEPRECATED_WARNINGS als target compile definition
target_compile_defintions(my_filter PRIVATE ADTF3_NO_DEPRECATED_WARNINGS)