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:
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
RETURN_IF_FAILED(oFactory.IsValid());
auto oDecoder = oFactory.MakeStaticDecoderFor(pSample);
for (auto oElement : oDecoder.GetElements())
{
auto oCodecIndex = oElement.getIndex();
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
{
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
[](auto& oElement)
{
auto oCodecIndex = oElement.getIndex();
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;
});
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
[](auto& oElement) {
auto oCodecIndex = oElement.getIndex();
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();
}
else
{
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:
- 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.
In the new cSampleDecoder and cStaticSampleDecoder is no cVariant anymore.
auto oVariant = oDecoder.GetElementValue("my_value");
auto nType = oVariant.GetType();
tUInt64 nValue = oVariant.GetInt64();
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.
adtf_ddl::cCodecFactory oCodecFactory;
auto oDecoder = oCodecFactory.MakeDecoderFor(...);
adtf_ddl::cCodec oCodec;
adtf_ddl::cDecoder oDecoder;
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
Legacy support for access_element API
adtf_ddl::access_element::find_index(oDecoder, ...);
auto oElement = oDecoder.GetElement("my_element").getIndex();
Legacy StructElement instead of tStructElement
adtf_ddl::tStructElement* pElement;
oDecoder.GetElement(nIdx, pElement);
std::string oElementName = oElement.strName;
oDecoder.GetElement(nIdx, pElement);
std::string oElementName = oElement.name;
auto oElement = oDecoder.GetElement("my_element");
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 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.
#include <adtf_mediadescription.h>
using namspace adtf::media_description;
#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:
#include <adtf_mediadescription.h>
using namspace adtf::media_description;
#include <adtf_mediadescription.h>
using namspace adtf::media_description_adtf_ddl_legacy;
Use StructElement instead of tStructElement
adtf_ddl::tStructElement* pElement;
oDecoder.GetElement(nIdx, pElement);
oDecoder.GetElement(nIdx, pElement);
auto oElement = oDecoder.GetElement(nIdx);
auto oElementName = oElement.strName;
auto oElement = oDecoder.GetElement(nIdx);
auto oElementName = oElement.name;
Switch off deprecated warnings if you do not port:
#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)