ADTF  3.18.2
Source Code for Demo Legacy Virtual Clock Input Plugin
Location
./src/examples/src/adtf/streaming_services/adtf2_legacy/legacy_virtual_clock/
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
Header
#include <a_utils_platform_inc.h>
#include <adtf3.h>
#include <adtf2_support.h>
#include "demo_legacy_virtual_clock.h"
ADTF_PLUGIN("Demo Legacy Virtual Clock Plugin",
cDemoLegacyVirtualClock);
cDemoLegacyVirtualClock::cDemoLegacyVirtualClock()
{
SetPropertyInt("width", 300);
SetPropertyInt("height", 300);
SetPropertyInt("frame_delay", 100000);
// sets a short description for the component
set_description(*this, "Use this legacy Streaming Source to generate video data configured by 'width', 'height' and 'frame_delay properties.");
}
cDemoLegacyVirtualClock::~cDemoLegacyVirtualClock()
{
}
tResult cDemoLegacyVirtualClock::Init(tInitStage eStage)
{
RETURN_IF_FAILED(cLegacyStreamingSource::Init(eStage));
if (eStage == tInitStage::StageFirst)
{
m_nWidth = GetPropertyInt("width");
m_nHeight = GetPropertyInt("height");
object_ptr<IStreamType> pType = make_object_ptr<cStreamType>(stream_meta_type_image());
set_property(*pType, stream_meta_type_image::FormatName, ADTF_IMAGE_FORMAT(GREYSCALE_8));
set_property(*pType, stream_meta_type_image::PixelWidth, m_nWidth);
set_property(*pType, stream_meta_type_image::PixelHeight, m_nHeight);
set_property(*pType, stream_meta_type_image::MaxByteSize, m_nWidth * m_nHeight);
RETURN_IF_FAILED(m_oOutputPin.Create("output", pType));
RETURN_IF_FAILED(RegisterPin(m_oOutputPin));
}
}
tResult cDemoLegacyVirtualClock::Start()
{
RETURN_IF_FAILED(cLegacyStreamingSource::Start());
m_oTimer = kernel_timer(OIGetInstanceName() + "::frame_timer", GetPropertyInt("frame_delay"), 0,
&cDemoLegacyVirtualClock::TimerFunc,
this);
if (!m_oTimer.Stoppable())
{
RETURN_ERROR_DESC(ERR_UNEXPECTED, "Unable to create kernel timer");
}
}
tResult cDemoLegacyVirtualClock::Stop()
{
m_oTimer.Stop();
return cLegacyStreamingSource::Stop();
}
tResult cDemoLegacyVirtualClock::Shutdown(tInitStage eStage)
{
return cLegacyStreamingSource::Shutdown(eStage);
}
void cDemoLegacyVirtualClock::TimerFunc()
{
tResult nResult = TransmitNewFrame();
if (IS_FAILED(nResult))
{
m_oOutputPin.SetStreamError(nResult);
}
}
tResult cDemoLegacyVirtualClock::TransmitNewFrame()
{
object_ptr<ISample> pSample;
RETURN_IF_FAILED(alloc_sample(pSample, _clock->GetStreamTimeNs()));
{
object_ptr_locked<ISampleBuffer> pBuffer;
RETURN_IF_FAILED(pSample->WriteLock(pBuffer, m_nWidth * m_nHeight));
DrawClock(pBuffer->GetPtr());
}
return m_oOutputPin.Transmit(object_ptr<const ISample>(pSample));
}
void cDemoLegacyVirtualClock::DrawClock(void* pvBuffer)
{
// generate black image
adtf_util::cMemoryBlock::MemZero(pvBuffer, m_nWidth * m_nHeight);
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int Radius = (x2 < y2) ? x2 : y2;
DrawCircle(pvBuffer, 2);
DrawLine(pvBuffer, 1, 0, Radius, Radius/5, Radius);
DrawLine(pvBuffer, 1, 2*Radius - Radius/5, Radius, Radius*2, Radius);
DrawLine(pvBuffer, 1, Radius , 0, Radius, Radius/5);
DrawLine(pvBuffer, 1, Radius , 2*Radius, Radius, 2*Radius - Radius/5);
DrawTimeLines(pvBuffer, _clock->GetStreamTime());
}
void cDemoLegacyVirtualClock::DrawTimeLine(void* pvBuffer,
int nLineWidth,
int nClockTime,
int nPrecision)
{
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int nRadius = (x2 < y2) ? x2 : y2;
if (nPrecision == 0) return;
int nRest = nClockTime % nPrecision;
double alpha = double( 360.0 / nPrecision) * double(nRest);
int x = int(sin((alpha / 180.0) * 3.145) * double(nRadius));
int y = int(cos((alpha / 180.0) * 3.145) * double(nRadius));
if (nRest >= 0 && nRest <= nPrecision/2)
{
if (x < 0)
{
x = nRadius - x;
}
else
{
x = nRadius + x;
}
}
else
{
if (x < 0)
{
x = nRadius + x;
}
else
{
x = nRadius - x;
}
}
if (nRest >= nPrecision/4 && nRest <= (nPrecision*3)/4)
{
if (y < 0)
{
y = nRadius - y;
}
else
{
y = nRadius + y;
}
}
else
{
if (y < 0)
{
y = nRadius + y;
}
else
{
y = nRadius - y;
}
}
DrawLine(pvBuffer, nLineWidth, nRadius, nRadius, x, y);
}
void cDemoLegacyVirtualClock::DrawTimeLines(void* pvBuffer, tTimeStamp nTime)
{
int nSeconds = int(nTime / tTimeStamp(1000000));
int nMinutes = nSeconds * 2000 / 60;
DrawTimeLine(pvBuffer, 1, nSeconds, 60);
DrawTimeLine(pvBuffer, 2, nMinutes, 2000 * 60);
}
void cDemoLegacyVirtualClock::DrawCircle(void* pvBuffer, int nLineWidth)
{
//simple algorithm from bresenham
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int Radius = (x2 < y2) ? x2 : y2;
Radius = Radius - nLineWidth;
int x = 0;
int y = Radius;
int S = 0;
int xBreakPixel = int(double(3.1) * double(Radius) / double(4.0));
while (x < xBreakPixel )
{
DrawPixel(pvBuffer, nLineWidth, x + Radius, Radius - y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - x, Radius - y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius + y, Radius - x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - y, Radius - x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius + y, Radius + x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - y, Radius + x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, x + Radius, Radius + y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - x, Radius + y, 0xFF);
int qRadius = Radius * Radius;
int qx = (x + 1) * (x + 1);
S = qx + (y * y) - qRadius;
S += (qx + ((y - 1) * (y - 1)) - qRadius);
x++;
if (S > 0)
{
y--;
}
}
}
void cDemoLegacyVirtualClock::DrawPixel(void* pvBuffer, int nLineWidth,
int xWidth , int yHeight , int nValue)
{
uint8_t* pImage = (uint8_t*)pvBuffer;
if (xWidth >= 0 && xWidth < m_nWidth
&& yHeight >= 0 && yHeight < m_nHeight)
{
int nPixelNo = (yHeight * m_nWidth) + xWidth;
if (nPixelNo > 0 && nPixelNo < m_nWidth * m_nHeight / 2)
{
pImage[nPixelNo] = (uint8_t)nValue;
if (nLineWidth > 1)
{
for (int nIdx = 1; nIdx <= nLineWidth/2; nIdx++)
{
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth+nIdx, yHeight, nValue);
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth, yHeight+nIdx, nValue);
}
for (int nIdx = nLineWidth; nIdx > 1; nIdx--)
{
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth+nIdx, yHeight, nValue);
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth, yHeight+nIdx, nValue);
}
}
}
}
}
void cDemoLegacyVirtualClock::DrawLine(void* pvBuffer,
int nLineWidth,
int x0Width,
int y0Height,
int x1Width,
int y1Height)
{
int x0 = x0Width;
int y0 = y0Height;
int x1 = x1Width;
int y1 = y1Height;
int deltax = abs(x1 - x0);
int deltay = abs(y1 - y0);
bool bSwapped = false;
if (deltay > deltax)
{
bSwapped = true;
x0 = y0Height;
x1 = y1Height;
y0 = x0Width;
y1 = x1Width;
}
if (x0 > x1)
{
int nSwap = 0;
nSwap = x1;
x1 = x0;
x0 = nSwap;
nSwap = y1;
y1 = y0;
y0 = nSwap;
}
deltax = x1 - x0;
deltay = abs(y1 - y0);
int delta = -deltax / 2;
int x = x0;
int y = y0;
for (; x <= x1; x++)
{
if (bSwapped)
{
DrawPixel(pvBuffer, nLineWidth, y, x, 0xFF);
}
else
{
DrawPixel(pvBuffer, nLineWidth, x, y, 0xFF);
}
delta = delta + deltay;
if (delta > 0)
{
if (y0 < y1)
{
y++;
}
else
{
y--;
}
delta = delta - deltax;
}
}
}
Copyright © Audi Electronics Venture GmbH.
#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_ERROR_DESC(_code,...)
Same as RETURN_ERROR(_error) using a printf like parameter list for detailed error description.
#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.
tResult set_property(IConfiguration &oConfiguration, const char *strNameOfValue, VALUETYPE oValue)
Set the property.
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.
void set_description(base::ant::IConfiguration &oConfig, const char *strDescription)
Sets description information.
#define ADTF_IMAGE_FORMAT(_FORMAT_)
Helper Macro to get the FormatName of the predefined Format within stream_image_format.
Implementation
#include <a_utils_platform_inc.h>
#include <adtf3.h>
#include <adtf2_support.h>
#include "demo_legacy_virtual_clock.h"
ADTF_PLUGIN("Demo Legacy Virtual Clock Plugin",
cDemoLegacyVirtualClock);
cDemoLegacyVirtualClock::cDemoLegacyVirtualClock()
{
SetPropertyInt("width", 300);
SetPropertyInt("height", 300);
SetPropertyInt("frame_delay", 100000);
// sets a short description for the component
set_description(*this, "Use this legacy Streaming Source to generate video data configured by 'width', 'height' and 'frame_delay properties.");
}
cDemoLegacyVirtualClock::~cDemoLegacyVirtualClock()
{
}
tResult cDemoLegacyVirtualClock::Init(tInitStage eStage)
{
RETURN_IF_FAILED(cLegacyStreamingSource::Init(eStage));
if (eStage == tInitStage::StageFirst)
{
m_nWidth = GetPropertyInt("width");
m_nHeight = GetPropertyInt("height");
object_ptr<IStreamType> pType = make_object_ptr<cStreamType>(stream_meta_type_image());
set_property(*pType, stream_meta_type_image::FormatName, ADTF_IMAGE_FORMAT(GREYSCALE_8));
set_property(*pType, stream_meta_type_image::PixelWidth, m_nWidth);
set_property(*pType, stream_meta_type_image::PixelHeight, m_nHeight);
set_property(*pType, stream_meta_type_image::MaxByteSize, m_nWidth * m_nHeight);
RETURN_IF_FAILED(m_oOutputPin.Create("output", pType));
RETURN_IF_FAILED(RegisterPin(m_oOutputPin));
}
}
tResult cDemoLegacyVirtualClock::Start()
{
RETURN_IF_FAILED(cLegacyStreamingSource::Start());
m_oTimer = kernel_timer(OIGetInstanceName() + "::frame_timer", GetPropertyInt("frame_delay"), 0,
&cDemoLegacyVirtualClock::TimerFunc,
this);
if (!m_oTimer.Stoppable())
{
RETURN_ERROR_DESC(ERR_UNEXPECTED, "Unable to create kernel timer");
}
}
tResult cDemoLegacyVirtualClock::Stop()
{
m_oTimer.Stop();
return cLegacyStreamingSource::Stop();
}
tResult cDemoLegacyVirtualClock::Shutdown(tInitStage eStage)
{
return cLegacyStreamingSource::Shutdown(eStage);
}
void cDemoLegacyVirtualClock::TimerFunc()
{
tResult nResult = TransmitNewFrame();
if (IS_FAILED(nResult))
{
m_oOutputPin.SetStreamError(nResult);
}
}
tResult cDemoLegacyVirtualClock::TransmitNewFrame()
{
object_ptr<ISample> pSample;
RETURN_IF_FAILED(alloc_sample(pSample, _clock->GetStreamTimeNs()));
{
object_ptr_locked<ISampleBuffer> pBuffer;
RETURN_IF_FAILED(pSample->WriteLock(pBuffer, m_nWidth * m_nHeight));
DrawClock(pBuffer->GetPtr());
}
return m_oOutputPin.Transmit(object_ptr<const ISample>(pSample));
}
void cDemoLegacyVirtualClock::DrawClock(void* pvBuffer)
{
// generate black image
adtf_util::cMemoryBlock::MemZero(pvBuffer, m_nWidth * m_nHeight);
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int Radius = (x2 < y2) ? x2 : y2;
DrawCircle(pvBuffer, 2);
DrawLine(pvBuffer, 1, 0, Radius, Radius/5, Radius);
DrawLine(pvBuffer, 1, 2*Radius - Radius/5, Radius, Radius*2, Radius);
DrawLine(pvBuffer, 1, Radius , 0, Radius, Radius/5);
DrawLine(pvBuffer, 1, Radius , 2*Radius, Radius, 2*Radius - Radius/5);
DrawTimeLines(pvBuffer, _clock->GetStreamTime());
}
void cDemoLegacyVirtualClock::DrawTimeLine(void* pvBuffer,
int nLineWidth,
int nClockTime,
int nPrecision)
{
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int nRadius = (x2 < y2) ? x2 : y2;
if (nPrecision == 0) return;
int nRest = nClockTime % nPrecision;
double alpha = double( 360.0 / nPrecision) * double(nRest);
int x = int(sin((alpha / 180.0) * 3.145) * double(nRadius));
int y = int(cos((alpha / 180.0) * 3.145) * double(nRadius));
if (nRest >= 0 && nRest <= nPrecision/2)
{
if (x < 0)
{
x = nRadius - x;
}
else
{
x = nRadius + x;
}
}
else
{
if (x < 0)
{
x = nRadius + x;
}
else
{
x = nRadius - x;
}
}
if (nRest >= nPrecision/4 && nRest <= (nPrecision*3)/4)
{
if (y < 0)
{
y = nRadius - y;
}
else
{
y = nRadius + y;
}
}
else
{
if (y < 0)
{
y = nRadius + y;
}
else
{
y = nRadius - y;
}
}
DrawLine(pvBuffer, nLineWidth, nRadius, nRadius, x, y);
}
void cDemoLegacyVirtualClock::DrawTimeLines(void* pvBuffer, tTimeStamp nTime)
{
int nSeconds = int(nTime / tTimeStamp(1000000));
int nMinutes = nSeconds * 2000 / 60;
DrawTimeLine(pvBuffer, 1, nSeconds, 60);
DrawTimeLine(pvBuffer, 2, nMinutes, 2000 * 60);
}
void cDemoLegacyVirtualClock::DrawCircle(void* pvBuffer, int nLineWidth)
{
//simple algorithm from bresenham
int x2 = m_nWidth / 2;
int y2 = m_nHeight / 2;
int Radius = (x2 < y2) ? x2 : y2;
Radius = Radius - nLineWidth;
int x = 0;
int y = Radius;
int S = 0;
int xBreakPixel = int(double(3.1) * double(Radius) / double(4.0));
while (x < xBreakPixel )
{
DrawPixel(pvBuffer, nLineWidth, x + Radius, Radius - y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - x, Radius - y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius + y, Radius - x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - y, Radius - x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius + y, Radius + x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - y, Radius + x, 0xFF);
DrawPixel(pvBuffer, nLineWidth, x + Radius, Radius + y, 0xFF);
DrawPixel(pvBuffer, nLineWidth, Radius - x, Radius + y, 0xFF);
int qRadius = Radius * Radius;
int qx = (x + 1) * (x + 1);
S = qx + (y * y) - qRadius;
S += (qx + ((y - 1) * (y - 1)) - qRadius);
x++;
if (S > 0)
{
y--;
}
}
}
void cDemoLegacyVirtualClock::DrawPixel(void* pvBuffer, int nLineWidth,
int xWidth , int yHeight , int nValue)
{
uint8_t* pImage = (uint8_t*)pvBuffer;
if (xWidth >= 0 && xWidth < m_nWidth
&& yHeight >= 0 && yHeight < m_nHeight)
{
int nPixelNo = (yHeight * m_nWidth) + xWidth;
if (nPixelNo > 0 && nPixelNo < m_nWidth * m_nHeight / 2)
{
pImage[nPixelNo] = (uint8_t)nValue;
if (nLineWidth > 1)
{
for (int nIdx = 1; nIdx <= nLineWidth/2; nIdx++)
{
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth+nIdx, yHeight, nValue);
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth, yHeight+nIdx, nValue);
}
for (int nIdx = nLineWidth; nIdx > 1; nIdx--)
{
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth+nIdx, yHeight, nValue);
DrawPixel(pvBuffer, nLineWidth/2-1, xWidth, yHeight+nIdx, nValue);
}
}
}
}
}
void cDemoLegacyVirtualClock::DrawLine(void* pvBuffer,
int nLineWidth,
int x0Width,
int y0Height,
int x1Width,
int y1Height)
{
int x0 = x0Width;
int y0 = y0Height;
int x1 = x1Width;
int y1 = y1Height;
int deltax = abs(x1 - x0);
int deltay = abs(y1 - y0);
bool bSwapped = false;
if (deltay > deltax)
{
bSwapped = true;
x0 = y0Height;
x1 = y1Height;
y0 = x0Width;
y1 = x1Width;
}
if (x0 > x1)
{
int nSwap = 0;
nSwap = x1;
x1 = x0;
x0 = nSwap;
nSwap = y1;
y1 = y0;
y0 = nSwap;
}
deltax = x1 - x0;
deltay = abs(y1 - y0);
int delta = -deltax / 2;
int x = x0;
int y = y0;
for (; x <= x1; x++)
{
if (bSwapped)
{
DrawPixel(pvBuffer, nLineWidth, y, x, 0xFF);
}
else
{
DrawPixel(pvBuffer, nLineWidth, x, y, 0xFF);
}
delta = delta + deltay;
if (delta > 0)
{
if (y0 < y1)
{
y++;
}
else
{
y--;
}
delta = delta - deltax;
}
}
}