This guide is about elements which can consume data. After reading this guide, you will know:
A Streaming Sink accepts data from Filter or Streaming Sources and consumes it e.g. by displaying the data or sending it to a device outside the ADTF System. The Streaming Sink therefore acts like a bridge between the data format of ADTF and the data format expected by the external device. If you are looking for a more comprehensive explanation of what Streaming Sinks are follow this link.
For this example we create a Streaming Sink that accepts characters. The CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
project (CharacterStreamingSink)
set (STREAMING_SINK_NAME happy_character_sink)
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/happy_character_sink.h)
file(WRITE happy_character_sink.h)
endif()
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/happy_character_sink.cpp)
file(WRITE happy_character_sink.cpp)
endif()
find_package(ADTF COMPONENTS systemsdk filtersdk REQUIRED)
set (EXAMPLE_SOURCES happy_character_sink.h
happy_character_sink.cpp)
# Adds the happy_character_sink project to the Visual Studio solution, which when build
# creates a shared object called happy_character_sink.adtfplugin
adtf_add_streaming_service(${STREAMING_SINK_NAME} ${EXAMPLE_SOURCES})
adtf_install_plugin(${STREAMING_SINK_NAME} src/examples/bin)
# Generate a plugindescription for our Streaming Sink
adtf_create_plugindescription(
TARGET ${STREAMING_SINK_NAME}
PLUGIN_SUBDIR "src/examples/bin"
VERSION "0.8.15"
LICENSE "ADTF"
SUPPORT_MAIL "support@mycompany.org"
HOMEPAGE_URL "www.mycompany.org"
)
# Generate a documentation for our Streaming Sink
adtf_convert_plugindescription_to_dox(
TARGET ${STREAMING_SINK_NAME}
DIRECTORY ${CMAKE_BINARY_DIR}/src/doxygen/generated
)
cmake-gui.exe
to open the graphical user interface
CMakeLists.txt
file)
build
folder (this is where all the build stuff goes)
Configure
button
Ungrouped Entries
and you will see that the value for the variable ADTF_DIR
is not set.
To fix this click into the "Value" Column and fill in the path to your ADTF directory.
CMAKE
and search for the variable CMAKE_INSTALL_PREFIX
.
By default this variable points to an absolute path with administration privileges which can be a problem.
Set the variable also to your ADTF directory e.g. D:/ADTF/3.4.0
.
Configure
button
Generate
button
Open Project
button to start Visual Studio
happy_character_sink.h
file and add this minimal Streaming Sink declaration:
#pragma once
// Include all necessary headers from the ADTF SDK
#include <adtffiltersdk/adtf_filtersdk.h>
// For simplicity use the necessary namespaces
using namespace adtf::ucom;
using namespace adtf::base;
using namespace adtf::streaming;
using namespace adtf::mediadescription;
// A very simple streaming sink for samples which contain characters.
// Received characters get dumped to the console.
// To implement a Sample Streaming Sink, subclass adtf::filter::cSampleStreamingSink
class cHappyCharacterSink : public adtf::filter::cSampleStreamingSink
{
public:
// This macros provides some meta information about our Sink Implementation
// This will be exposed by the plugin class factory.
ADTF_CLASS_ID_NAME(cHappyCharacterSink,
"happy_character_sender.streaming_sink.adtf_guides.cid",
"Happy Character Sender");
// We setup Pins in the constructor
cHappyCharacterSink();
// This method will be called when a trigger occours via our input Pin.
tResult ProcessInput(ISampleReader* pReader,
const iobject_ptr<const ISample>& pSample) override;
};
happy_character_sink.cpp
file and add this minimal Streaming Sink definition:
#include "happy_character_sink.h"
// The code behind the macro creates a plugin and the main entries to the plugin DLL or shared object.
// The cHappyCharacterSink will be available through the plugins class factory.
ADTF_PLUGIN("Happy Character Sink", cHappyCharacterSink);
// this is our input data
struct tSimple
{
char cValue;
};
cHappyCharacterSink::cHappyCharacterSink()
{
// create a type definition from our existing struct definiton
auto oStructureDefiniton = structure<tSimple>("tSimple")
.Add("cValue", &tSimple::cValue);
// and our Input Pin.
CreateInputPin("charIn", oStructureDefiniton);
SetDescription("charIn", "Incoming characters");
// set basic information about the component itself and purpose
SetDescription("This streaming sink shows how to handle characters as stream.");
}
tResult cHappyCharacterSink::ProcessInput(ISampleReader* /*pReader*/,
const iobject_ptr<const ISample>& pSample)
{
// We use the sample_data template to access the data stored within the sample
// This behaves just like a tSimple pointer.
sample_data<tSimple> oInputData(pSample);
LOG_INFO("Happy Character Sink received: %c", oInputData->cValue);
RETURN_NOERROR;
}
*.adtfplugin
*.plugindescription
files)happy_character_sink.adtfplugin
and happy_character_sink.plugindescription
in the src\examples\bin\debug
folder of your ADTF directory.Fire up the Configuration Editor
Filter Graph Editor
tabComponents
tabHappy Character Source
from the Components
tab into the Filter Graph Editor
Happy Character Sink
from the Components
tab into the Filter Graph Editor
Source
and Sink
Sessions
tabLaunch with ADTF Control
rl running
Congratulations! Now you have an idea of how to consume available data streams in the ADTF System.
Have a look at the Filter in between to learn who are the Filters in between Streaming Sources and Streaming Sinks.