Mixer Demo
This demo shows how to stream two video sources combined into a single preview sink using the AVT SDK’s mixer feature. It demonstrates camera device selection, overlay configuration from a mixed video output.
Code Example
#include "AvtCore.h"
#include "AvtString.h"
#include "Graph/AvtGraph.h"
#include "Source/AvtVideoSourceProperty.h"
#include "DeviceHelper.h"
#include "MixerHelper.h"
#include "Utility/ToString.h"
#include <iostream>
#include <csignal>
#include <unistd.h>
#include <vector>
using namespace AVTSDK;
using namespace AVTSDK::Utility;
using namespace AVTSDK::Log;
using namespace AVTSDK::Graph;
using namespace AVTSDK::Graph::Mixer;
using namespace AVTSDK::Source;
using namespace std;
bool running = true;
void signalHandler(int signum)
{
running = false;
}
int main()
{
AvtCore::init(AvtLogLevel::LOG_LEVEL_WARNING, AvtLogType::LOG_TYPE_DELAYED);
AvtGraph *graph = nullptr;
vector<int> sourceIDList;
do {
DeviceHelper devHelper;
auto vDevCount = devHelper.getVideoDeviceCount();
if (vDevCount == 0) {
cout << "No Device" << endl;
break;
}
AvtGraphFeature ft;
ft.mVideo.mEnable = true;
auto &vFt = ft.mVideo.mProperty;
#if defined(__QCOM__)
vFt.mGraphicsAPI = AvtGraphicsAPI::GRAPHICS_API_QCOM;
#else
vFt.mGraphicsAPI = AvtGraphicsAPI::GRAPHICS_API_NV;
#endif
AvtVideoSourceProperty firstProp;
firstProp.mLockDevice = true;
if (!devHelper.selectVideoDevice(firstProp)) {
cout << "Failed to select the correct device or device firstProperty" << endl;
break;
}
AvtVideoSourceProperty secondProp;
secondProp.mLockDevice = true;
if (!devHelper.selectVideoDevice(secondProp)) {
cout << "Failed to select the correct device or device secondProperty" << endl;
break;
}
MixerHelper mixerHelper;
vFt.mPreview.mEnable = true;
vFt.mMixer.mEnable = true;
auto &vFtMixerProp = vFt.mMixer.mProperty;
mixerHelper.setMixerProperty(vFtMixerProp);
graph = new AvtGraph(ft);
AvtResult result;
graph->createGraph();
int sourceID;
result = graph->addSource(firstProp, sourceID);
if (result != AvtResult::AVT_RESULT_OK) {
cout << "Failed to add first video source" << endl;
break;
}
sourceIDList.push_back(sourceID);
result = graph->addSource(secondProp, sourceID);
if (result != AvtResult::AVT_RESULT_OK) {
cout << "Failed to add second video source" << endl;
break;
}
sourceIDList.push_back(sourceID);
cout << endl << "start to set overlay for first camera: "
<< firstProp.mDevice.mName.getString() << " ===="<< endl;
sourceID = sourceIDList[0];
result = mixerHelper.setOverlay(graph, sourceID, vFtMixerProp);
if (result != AvtResult::AVT_RESULT_OK) {
cout << "Failed to set overlay for Source_" << sourceID << endl;
break;
}
cout << endl << "==== start to set overlay for secnod camera: "
<< secondProp.mDevice.mName.getString() << " ===="<< endl;
sourceID = sourceIDList[1];
result = mixerHelper.setOverlay(graph, sourceID, vFtMixerProp);
if (result != AvtResult::AVT_RESULT_OK) {
cout << "Failed to set overlay for Source_" << sourceID << endl;
break;
}
result = graph->runGraph();
if (result != AvtResult::AVT_RESULT_OK) {
cout << "Failed to run graph";
break;
}
signal(SIGINT, signalHandler);
// Pause briefly so the set menu shows up clearly after the run graph logs flood in.
sleep (5);
while (running) {
mixerHelper.setOpacityaValue(graph, sourceIDList);
}
} while (false);
if (graph)
delete graph;
AvtCore::uninit();
return 0;
}
Explanation
Helper Classes
DeviceHelper and MixerHelper are helper classes written for the demos and are not part of the library. For details about how to handle devices and mixers, please check the source code of these classes.
-
Initialization
The program begins by initializing the AVT core with a warning-level log configuration.
-
Device Availability Check
It checks whether any video input devices are available. If none are found, the program exits early.
-
Graph and Feature Setup
AvtGraphFeatureis the configuration structure forAvtGraph. It is configured to enable video preview, and the appropriate graphics API (QCOMorNV) is selected based on the platform.The video mixer is also enabled via
vFt.mMixer.mEnable = true, and its properties are configured usingMixerHelper.Mixer mode in
AvtGraphTo add multiple video sources to the graph, you need to enable the video mixer feature before creating the graph, or you may encounter errors when adding more than one video source. If you have no idea what
AvtGraphis, please refer to AVT SDK Multimedia Framework. -
Device and Mixer Selection
The user is prompted twice to select two video input devices via
DeviceHelper::selectVideoDevice(). Then, the mixer resolution and frame rate are determined usingMixerHelper.setMixerProperty(). -
Graph Creation
A new
AvtGraphinstance is created using the configuredAvtGraphFeature. -
Source Node Addition
Both selected video sources are added to the graph using
addSource(). -
Mixer Overlay Setup
The two input video sources are individually mapped into the mixer layout using
MixerHelper::setOverlay(), allowing them to be rendered simultaneously in a single output frame.Note
MixerHelper::setOverlay()is just a helper function to interact with the user and configure theAvtMixerProperty. -
Graph Execution
The graph is executed using
runGraph(), which starts the video processing pipeline. -
Runtime Loop and Termination
A signal handler is registered to listen for
SIGINT(Ctrl+C). During runtime, the opacity values of the mixed sources are updated continuously in a loop usingsetOpacityaValue(). Upon termination, the graph is deleted and the AVT core is uninitialized.