Hi,
According to this old post it should be possible to create 2 threads with each thread creating and running an instance of NvEglRenderer:
And I had it working on Jetson 35.1.0 with each thread achieving 60 fps.
But in Jetson 35.2.1 they run at 30 fps each.
Below I copied the smallest working code, which demonstrates the problem.
How to restore the good old functionality?
Thank you
/*
Usage
DISPLAY=:0 ./egl_renderer pos_x offset_x frame_count num_thread
For example, run one thread:
DISPLAY=:0 ./egl_renderer 0 0 100 1
prints
100 frames in 1653 ms fps: 60.485637
Run 2 threads, one thread per display:
DISPLAY=:0 ./egl_renderer 0 2000 100 2
On Jetson 35.2.1 it prints:
pos_x 0 100 frames in 2987 ms fps: 33.475959
pos_x 2000 100 frames in 3324 ms fps: 30.083336
On Jetson 35.1.0 it prints:
pos_x 0 100 frames in 1655 ms fps: 60.416307
pos_x 2000 100 frames in 1651 ms fps: 60.537270
*/
#include “Error.h”
#include “Thread.h”
#include <Argus/Argus.h>
#include <EGLStream/EGLStream.h>
#include <EGLStream/NV/ImageNativeBuffer.h>
#include “NvBufSurface.h”
#include <NvEglRenderer.h>
#include <stdio.h>
#include <stdlib.h>
#include
using namespace Argus;
using namespace EGLStream;
#define FPS 60
#define WIDTH 500
#define HEIGHT 500
int num_frames = 0;
class RendererThread : public ArgusSamples::Thread
{
public:
RendererThread(int pos_x) : m_pos_x(pos_x) {}
bool threadExecute()
{
NvEglRenderer* renderer = NULL;
renderer = NvEglRenderer::createEglRenderer("renderer", WIDTH, HEIGHT, m_pos_x, 0);
renderer->setFPS((float)FPS);
NvBufSurf::NvCommonAllocateParams input_params = {0};
input_params.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params.memtag = NvBufSurfaceTag_NONE;
input_params.width = WIDTH;
input_params.height = HEIGHT;
input_params.layout = NVBUF_LAYOUT_BLOCK_LINEAR;
input_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA;
int dmabuf_fd;
NvBufSurf::NvAllocate(&input_params, 1, &dmabuf_fd);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
long long time_start_ns = ts.tv_sec * 1000*1000*1000LL + ts.tv_nsec;
for(int i = 0; i < num_frames; i++)
{
renderer->render(dmabuf_fd);
}
clock_gettime(CLOCK_MONOTONIC, &ts);
long long time_end_ns = ts.tv_sec * 1000*1000*1000LL + ts.tv_nsec;
printf("pos_x %d %d frames in %d ms fps: %f\n",
m_pos_x,
num_frames, (int)((time_end_ns - time_start_ns)/1E6),
num_frames * 1E9 / (time_end_ns - time_start_ns)
);
requestShutdown();
return true;
}
bool threadInitialize() { return true; }
bool threadShutdown() { return true; }
int m_pos_x;
};
int main(int argc, char * argv)
{
int pos_x = argc > 1? strtol(argv[1], NULL, 10) : 0;
int offset_x = argc > 2? strtol(argv[2], NULL, 10) : 1000;
num_frames = argc > 3? strtol(argv[3], NULL, 10) : 1000;
int num_threads = argc > 4? strtol(argv[4], NULL, 10) : 2;
std::vector<std::unique_ptr<RendererThread>> threads;
for(int i = 0; i < num_threads; i++)
{
threads.push_back(std::make_unique<RendererThread>(pos_x + i*offset_x));
}
for(auto & thread : threads)
{
thread->initialize();
}
for(auto & thread : threads)
{
thread->shutdown();
}
return 0;
}