ADTF  3.18.2
Source Code for Substream Dumper Plugin
Location
./src/examples/src/adtf/filters/standard_filters/substream_dumper_filter/
Namespace for entire ADTF SDK.
Build Environment
To see how to set up the build environment have a look at ADTF CMake Environment
this implementation shows:
Implementation
#include <unordered_map>
using namespace adtf::ucom;
using namespace adtf::base;
using namespace adtf::streaming;
using namespace adtf::mediadescription;
using namespace adtf::filter;
using namespace ddl;
class cDemoSubStreamDumper: public cFilter
{
public:
ADTF_CLASS_ID_NAME(cDemoSubStreamDumper,
"demo_substream_dumper.filter.adtf.cid",
"Substream Dumper");
public:
cDemoSubStreamDumper()
{
// sets a short description for the component
SetDescription("Use this filter to dump data of all samples of all available substreams.");
// set help link to jump to documentation from ADTF Configuration Editor
SetHelpLink("$(ADTF_DIR)/doc/adtf_html/page_demo_substream_dumper.html");
m_pReader = CreateInputPin("input", stream_meta_type_substreams());
SetDescription("input", "Incoming data of substreams for printing.");
// Every filter that uses a substream input is required to request transmission of the substreams that it is interested in.
// It will not receive any data otherwise! Non-interactive requests need to be performed within the following callback!
m_pReader->SetSynchronousTypeUpdateCallback([&](const iobject_ptr<const IStreamType>& pStreamType) -> tResult
{
// this callback is called synchronously whenever the source changes the type and once when the connection is established.
// Never use this callback to setup data structures to decode and/or access sample data, request handling is completely
// independent of the data transmission. Use the AcceptType method instead.
// first we clear all ongoing requests
m_oRequests.clear();
// and then request samples from all substreams
stream_meta_type_substreams::ListSubStreams(*pStreamType.Get(), [&](const char* /*strName*/, uint32_t nSubStreamId)
{
object_ptr<IStreamingRequest> pRequest;
THROW_IF_FAILED(m_pReader->RequestSamples(pRequest, nSubStreamId));
// we store the request object for as long as we want those samples.
m_oRequests.push_back(pRequest);
});
});
}
tResult AcceptType(ISampleReader* pReader, const iobject_ptr<const IStreamType>& pStreamType) override
{
// let the base class do basic compatibility checks (i.e. if the stream meta type matches)
RETURN_IF_FAILED(cFilter::AcceptType(pReader, pStreamType));
// iterate over all available substreams.
stream_meta_type_substreams::ListSubStreams(*pStreamType.Get(), [&](const char* strName, uint32_t nSubStreamId)
{
// first we try to generate a codec factory for the substream.
auto pSubStreamType = stream_meta_type_substreams::GetSubStreamType(*pStreamType.Get(), strName);
cSampleCodecFactory oCodecFactory(pSubStreamType);
if (IS_OK(oCodecFactory.IsValid()))
{
m_oCodecFactories[nSubStreamId] = {oCodecFactory, strName};
}
});
}
tResult ProcessInput(ISampleReader* /*pReader*/, const iobject_ptr<const ISample>& pSample) override
{
// check the substreamid of the sample.
auto itCodecFactory = m_oCodecFactories.find(get_sample_substream_id(pSample));
if (itCodecFactory != m_oCodecFactories.end())
{
// and dump it with the matching decoder.
auto oDecoder = itCodecFactory->second.oCodecFactory.MakeDecoderFor(pSample);
LOG_INFO("Sample from %s:", itCodecFactory->second.strName.c_str());
DumpSample(oDecoder);
}
}
private:
void DumpSample(const adtf::mediadescription::cSampleDecoder& oDecoder)
{
LOG_INFO("%s = %s",
oElement.getFullName().c_str(),
oElement.getStringValue().c_str());
});
}
// we need to store the concrete class and not ISampleReader to access RequestSamples()
cPinReader* m_pReader = nullptr;
std::vector<object_ptr<IStreamingRequest>> m_oRequests;
struct tCodecFactoryAndName
{
cSampleCodecFactory oCodecFactory;
std::string strName;
};
std::unordered_map<uint32_t, tCodecFactoryAndName> m_oCodecFactories;
};
// this creates the plugin entry methods and class factories
ADTF_PLUGIN("Substream Dumper Plugin", cDemoSubStreamDumper);
#define ADTF_PLUGIN(__plugin_identifier,...)
The ADTF Plugin Macro will add the code of a adtf::ucom::ant::IPlugin implementation.
Definition: adtf_plugin.h:22
Copyright © Audi Electronics Venture GmbH.
#define RETURN_IF_FAILED(s)
Return if expression is failed, which requires the calling function's return type to be tResult.
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
#define ADTF_CLASS_ID_NAME(_class, _strcid, _strclabel)
Common macro to enable correct treatment of class identifier AND Class Name by IClassInfo.
Definition: class_id.h:33
const tElements & GetElements() const
Retrieves the elements of the decoder to get element information and the values.
Decoder for samples with static and/or dynamic data.
Definition: sample_codec.h:605
Namespace for the ADTF Base SDK.
adtf::streaming::ant::cDynamicSampleReader cPinReader
use cSampleReader as cPinReader
Namespace for the ADTF Filter SDK.
void for_each_leaf_element(ElementsType &oElements, const element_callback< ElementsType > &fnCallback)
Iterates ALL leaf elements within ALL array elements.
Namespace for the ADTF Media Description SDK.
uint32_t get_sample_substream_id(const ant::ISample &oSample)
Namespace for the ADTF Streaming SDK.
Namespace for the ADTF uCOM3 SDK.