ADTF  3.18.2
Source Code for Demo Sample Data Reference Generator Plugin
Location
./src/examples/src/adtf/streaming_services/sources/sample_data_reference/
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:
Remarks
  • Use this method only if you REALLY know what you are doing!
Header
#pragma once
using namespace adtf::base;
using namespace adtf::ucom;
using namespace adtf::streaming;
using namespace adtf::filter;
using namespace adtf::system;
//*************************************************************************************************
class cDemoSampleDataReferenceSource: public adtf::filter::cSampleStreamingSource
{
public:
ADTF_CLASS_ID_NAME(cDemoSampleDataReferenceSource,
"demo_sample_data_reference_generator.streaming_source.adtf.cid",
"Demo Sample Data Reference Generator");
private:
property_variable<uint32_t> m_nWidth = 640;
property_variable<uint32_t> m_nHeight = 480;
property_variable<int64_t> m_nFrameDelay = 1000000;
object_ptr<adtf::services::IReferenceClock> m_pClock;
std::vector<uint8_t> m_oBuffer;
ISampleWriter* m_pOutputWriter;
weak_object_ptr<ISample> m_pLastSentSample;
public:
cDemoSampleDataReferenceSource();
tResult Init() override;
tResult StartStreaming() override;
tResult StopStreaming() override;
private:
object_ptr<IStreamType> GetStreamTypeFromProperties();
void TimerFunc();
};
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
#define REQUIRE_INTERFACE(_interface)
Macro usable with ADTF_CLASS_DEPENDENCIES() to require mandatory interfaces.
#define ADTF_CLASS_DEPENDENCIES(...)
Add interface ids (string literals,.
#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
Base class for ADTF sample streaming sources.
This class is used to provide a fallback kernel thread/timer for a runner of a streaming service.
Kernel interface for thread, timer and signal handling.
Definition: kernel_intf.h:388
The IReferenceClock interface provides the reference time source for the filter graph.
Namespace for the ADTF Base SDK.
Namespace for the ADTF Filter SDK.
Namespace for the ADTF Streaming SDK.
Namespace for the ADTF System SDK.
Namespace for the ADTF uCOM3 SDK.
Copyright © Audi Electronics Venture GmbH.
Implementation
#include "demo_sample_data_reference_source.h"
// Avoid Warning C4244 in std::generate(m_oBuffer.begin(), m_oBuffer.end(), std::rand)
namespace {
unsigned char generator()
{
return static_cast<unsigned char>(std::rand());
}
}
ADTF_PLUGIN("Demo Sample Data Reference Plugin",
cDemoSampleDataReferenceSource);
cDemoSampleDataReferenceSource::cDemoSampleDataReferenceSource()
{
m_nWidth.SetDescription("Specified width for Sample dimension.");
RegisterPropertyVariable("width", m_nWidth);
m_nHeight.SetDescription("Specified height for Sample dimension.");
RegisterPropertyVariable("height", m_nHeight);
m_nFrameDelay.SetDescription("Update interval in microseconds for Sample creation. This is only used when no Timer Runner is connected to the 'generate_frames' runner.");
RegisterPropertyVariable("frame_delay", m_nFrameDelay);
m_pOutputWriter = CreateOutputPin("output", GetStreamTypeFromProperties());
SetDescription("output", "Provides the generated referenced samples");
// For session compatibility reasons we use this fallback helper for the case where no active runner is connected to the runner.
// In your own implementations use a simple CreateRunner(...) instead!
m_oTimer = adtf::filter::cRunnerFallback(this, "generate_frames", cTimerTriggerHint(*m_nFrameDelay),[this]{ TimerFunc(); });
SetDescription("generate_frames",
"Connect a Timer Runner that will trigger the frame generation. In this case the property `frame_delay` has no effect."
"If this is not connected, the source will create a timer on its own.");
// sets a short description for the component
SetDescription("Use this Streaming Source to to generate samples that reference external data.");
// set help link to jump to documentation from ADTF Configuration Editor
SetHelpLink("$(ADTF_DIR)/doc/adtf_html/page_demo_sample_data_reference.html");
}
tResult cDemoSampleDataReferenceSource::Init()
{
RETURN_IF_FAILED(cSampleStreamingSource::Init());
m_oBuffer.resize(m_nWidth * m_nHeight);
m_pOutputWriter->ChangeType(GetStreamTypeFromProperties());
}
object_ptr<IStreamType> cDemoSampleDataReferenceSource::GetStreamTypeFromProperties()
{
tStreamImageFormat sFormat;
sFormat.m_strFormatName = ADTF_IMAGE_FORMAT(GREYSCALE_8);
sFormat.m_ui32Width = m_nWidth;
sFormat.m_ui32Height = m_nHeight;
sFormat.m_szMaxByteSize = m_nWidth * m_nHeight;
sFormat.m_ui8DataEndianess = PLATFORM_BYTEORDER;
object_ptr<IStreamType> pType = make_object_ptr<cStreamType>(stream_meta_type_image());
set_stream_type_image_format(*pType, sFormat);
return pType;
}
tResult cDemoSampleDataReferenceSource::StartStreaming()
{
RETURN_IF_FAILED(cSampleStreamingSource::StartStreaming());
RETURN_IF_FAILED(m_oTimer.Activate(m_nFrameDelay));
}
tResult cDemoSampleDataReferenceSource::StopStreaming()
{
m_oTimer.Deactivate();
return cSampleStreamingSource::StopStreaming();
}
void cDemoSampleDataReferenceSource::TimerFunc()
{
auto tmNow = m_pClock->GetStreamTimeNs();
// first we make sure that the previous sample has been released by checking the weak pointer.
object_ptr<ISample> pLockedLastSample(m_pLastSentSample);
if (pLockedLastSample)
{
// someone still has a reference to the last sample we sent, so we cannot change the buffer,
// we'll try again later.
// keep in mind that the video display keeps the sample until it receives a new one. So you
// cannot use it to display the images from this source.
LOG_WARNING("The last sample is still referenced, cannot update buffer!");
return;
}
// modify image buffer
std::generate(m_oBuffer.begin(), m_oBuffer.end(), generator);
// transmit a new reference to the buffer
// we cannot use alloc_sample in this case, and thus make no use of cached samples in the sample
// pool
auto pNewSample = make_object_ptr<cReferenceSample>();
pNewSample->SetTime(tmNow);
{
object_ptr_locked<ISampleBuffer> pSampleBuffer;
auto oResult = pNewSample->WriteLock(pSampleBuffer, 0);
if (IS_FAILED(oResult))
{
m_pOutputWriter->SetStreamError(oResult);
return;
}
// the reference sample buffer within cReferenceSample stores only the pointer and the size
// and does not copy the data
oResult = pSampleBuffer->Write(adtf_memory_buffer<uint8_t>(m_oBuffer.data(),
m_oBuffer.size()));
if (IS_FAILED(oResult))
{
m_pOutputWriter->SetStreamError(oResult);
return;
}
}
m_pLastSentSample = pNewSample;
m_pOutputWriter->Write(ucom_object_ptr_cast<ISample>(pNewSample));
m_pOutputWriter->ManualTrigger(tmNow);
}
#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
#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.
virtual tResult GetObject(iobject_ptr< IObject > &pObject, const char *strNameOID) const =0
Get registered object from object registry.
#define PLATFORM_BYTEORDER
defines a link to __get_platform_byteorder.
Definition: constants.h:124
tResult set_stream_type_image_format(IStreamType &oType, const tStreamImageFormat &oFormat)
Helper function to set the properties of a IStreamType for a stream_meta_type_image.
adtf::ucom::IRuntime * _runtime
Global Runtime Pointer to reference to the current runtime.
#define ADTF_IMAGE_FORMAT(_FORMAT_)
Helper Macro to get the FormatName of the predefined Format within stream_image_format.