ADTF
Loading...
Searching...
No Matches
ADTF Codecs and SampleCodecs

Codec and CodecFactory

The SampleCodec is part of the Open Source DDL Library within the Dev Essential package.

SampleCodec and Codec

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

Codec Index and 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 adtf::mediadescription::cSampleCodec::GetElements method of the Codecs.

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);

Sample creation:

oData->value = 1;
const auto pSample = oData.Release();

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;
}

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!
});

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;
});

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

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 adtf::mediadescription::osborn::adtf_ddl_access::cCodecFactoryLegacy, adtf::mediadescription::osborn::adtf_ddl_access::cCodecLegacy and adtf::mediadescription::osborn::adtf_ddl_access::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 for migration.

To map a leaf index to its corresponding codec index use the legacy adtf::mediadescription::osborn::adtf_ddl_access::cCodecFactoryLegacy::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:

CodecFactory and its Decoders/Codecs Codec Index and Element Iterator Codec Leaf Index adtf_ddl::access_element API (old adtf) ddl::access_element API (new ddl library)
adtf::mediadescription::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
adtf::mediadescription::flash::cSampleCodecFactory (old) no yes yes no
adtf::mediadescription::osborn::adtf_ddl_access::cCodecFactoryLegacy (old) no yes yes no
Note
We recommend to port your code to the newest adtf::mediadescription::cSampleCodecFactory / ddl::codec::CodecFactory and only use the Codec Index and Element Iterator.
All other will be removed in further releases!

Porting ADTF DDL to Open Source DDL Library

If you have created DDL based code before ADTF 3.14, your code needs to be adapted.
The deprecated warnings will guide you through the porting process.

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(...);
cSampleDecoder MakeDecoderFor(const adtf::streaming::ISample &oSample, ddl::tDataRepresentation eDataRepresentation) const

In the new cSampleDecoder and cStaticSampleDecoder is no cVariant anymore.

//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>();

If you are using the adtf_ddl::cCodecFactory directly, you have to use change the classes.

//old code
adtf_ddl::cCodecFactory oCodecFactory;
auto oDecoder = oCodecFactory.MakeDecoderFor(...);
//new code
ddl::CodecFactory oCodecFactory;
auto oDecoder = oCodecFactory.makeDecoderFor(...);
//new code
auto oDecoder = oCodecFactory.makeDecoderFor(...);
//old code
adtf_ddl::cCodec oCodec;
//new code
ddl::Codec oCodec;
//new code
//old code
adtf_ddl::cDecoder oDecoder;
//new code
ddl::Decoder oDecoder;
//new code
Definition codec_factory_legacy.h:36
Decoder makeDecoderFor(const void *data, size_t data_size, DataRepresentation rep=deserialized) const
Definition codec_factory_legacy.h:116
Definition codec_legacy.h:129
Definition codec_legacy.h:46
Definition codec_factory.h:31
Decoder makeDecoderFor(const void *data, size_t data_size, DataRepresentation rep=deserialized) const
Definition codec.h:164
Definition codec.h:30

Legacy support for access_element API

//old code
//this will work, but is deprecated
adtf_ddl::access_element::find_index(oDecoder, ...);
//new code uses the Codec Iterator!
auto oElement = oDecoder.GetElement("my_element").getIndex();

Legacy StructElement instead of tStructElement

//old code
adtf_ddl::tStructElement* pElement;
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;
});
Definition struct_element.h:32

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

//define the NO_ADTF_MEDIA_DESCRIPTION_LEGACY macro before including adtf_mediadescription
#define NO_ADTF_MEDIA_DESCRIPTION_LEGACY
#include <adtf_mediadescription.h>
# 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

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;

Migrate with 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
adtf_ddl::tStructElement* pElement;
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:

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