We use a thread to decode several jpeg files (different size) using NvJPEGDecoder, which owns a fixed DMABUF FD;
we use another thread to create NvBuffer using API NvBufferCreateEx, the fixed FD owned by NvJPEGDecoder may be reused and returned by NvBufferCreateEx.
test code:
#include "nvbuf_utils.h"
#include "NvJpegDecoder.h"
#include <cstdlib>
#include <stdexcept>
#include <iostream>
#include <thread>
#include <vector>
#include <deque>
#include <memory>
#include <sstream>
#include <fstream>
#include <string>
void create() {
std::deque<int> fds;
for (int i = 0; i < 200; ++i) {
NvBufferColorFormat format = std::rand() > RAND_MAX / 2 ? NvBufferColorFormat_ARGB32 : NvBufferColorFormat_YUV420;
int width = (512 + (std::rand() % 512)) & ~3;
int height = (512 + (std::rand() % 512)) & ~3;
NvBufferCreateParams create_params;
create_params.width = width;
create_params.height = height;
create_params.payloadType = NvBufferPayload_SurfArray;
create_params.layout = NvBufferLayout_Pitch;
create_params.colorFormat = format;
create_params.nvbuf_tag = NvBufferTag_VIDEO_CONVERT;
int fd = -1;
int ret = NvBufferCreateEx(&fd, &create_params);
if (ret) {
throw std::runtime_error("create nvbuffer failed");
}
std::cout << "created fd: " << fd << ", format: " << (int) format << ", size: " << width << " x " << height << std::endl;
NvBufferParams params;
ret = NvBufferGetParams(fd, ¶ms);
if (ret) {
throw std::runtime_error("get nvbuffer params failed");
}
if (params.pixel_format != format || params.width[0] != width || params.height[0] != height) {
std::cout << "output: " << (int) params.pixel_format << " @ " << params.width[0] << " x " << params.height[0]
<< ", expected: " << (int) format << " @ " << width << " x " << height << std::endl;
throw std::logic_error("abort");
}
fds.push_back(fd);
if (fds.size() > 10) {
fd = fds.front();
fds.pop_front();
NvBufferDestroy(fd);
std::cout << "destroyed fd " << fd << std::endl;
}
}
for (int fd : fds) {
NvBufferDestroy(fd);
}
}
void decode() {
NvJPEGDecoder *decoder = NvJPEGDecoder::createJPEGDecoder("dec");
std::vector<const char *> filenames = {
// "123.jpg",
"1623911071908545.jpg",
"1623911071970477.jpg",
"1623911072064753.jpg",
"1623911072116309.jpg",
"1623911072191377.jpg",
"1623911072218551.jpg",
"1623911072266272.jpg",
"1623911072308098.jpg",
"1623911072371586.jpg",
"1623911072410162.jpg",
"1623911072476422.jpg",
"1623911072511168.jpg",
"1623911072572386.jpg",
"1623911072609480.jpg",
"1623911072661801.jpg",
"1623911072705869.jpg",
"1623911072751829.jpg",
"1623911072809667.jpg",
"1623911072862215.jpg",
"1623911072896757.jpg",
"1623911072950181.jpg",
"1623911073024013.jpg",
"1623911073046086.jpg",
"1623911073107782.jpg",
"1623911073179597.jpg",
"1623911073201786.jpg",
"1623911073231199.jpg",
"1623911073264730.jpg",
"1623911073338655.jpg",
"1623911073363981.jpg",
"1623911073407842.jpg",
"1623911073457783.jpg",
"1623911073525101.jpg",
"1623911073570111.jpg",
"1623911073628556.jpg",
"1623911073673217.jpg",
"1623911073698922.jpg",
"1623911073747305.jpg",
"1623911073798333.jpg",
"1623911073868908.jpg",
"1623911073894701.jpg",
"1623911073929884.jpg",
"1623911073974545.jpg",
"1623911074022663.jpg",
"1623911074066042.jpg",
"1623911074137229.jpg",
"1623911074176162.jpg",
"1623911074242473.jpg",
"1623911074278442.jpg",
"1623911074316018.jpg",
"1623911074346135.jpg",
"1623911074389461.jpg",
"1623911074445527.jpg",
"1623911074482912.jpg",
"1623911074508853.jpg",
"1623911074541684.jpg",
"1623911074610351.jpg",
"1623911074638008.jpg",
"1623911074667713.jpg",
"1623911074708107.jpg",
"1623911074773143.jpg",
"1623911074812889.jpg",
"1623911074833586.jpg",
"1623911074892406.jpg",
"1623911074978969.jpg",
"1623911075001825.jpg",
"1623911075050630.jpg",
"1623911075116945.jpg",
"1623911075181685.jpg",
"1623911075209656.jpg",
"1623911075240599.jpg",
"1623911075297791.jpg",
"1623911075331839.jpg",
"1623911075364448.jpg",
"1623911075422990.jpg",
"1623911075464952.jpg",
"1623911075507541.jpg",
"1623911075568608.jpg",
"1623911075616312.jpg",
"1623911075671952.jpg",
"1623911075697054.jpg",
"1623911075732421.jpg",
"1623911075781591.jpg",
"1623911075825405.jpg",
"1623911075876738.jpg",
"1623911075914959.jpg",
"1623911075957005.jpg",
"1623911075986963.jpg",
"1623911076039948.jpg",
"1623911076078918.jpg",
"1623911076126389.jpg",
"1623911076156394.jpg",
"1623911076227565.jpg",
"1623911076253073.jpg",
"1623911076283560.jpg",
"1623911076348497.jpg",
"1623911076426362.jpg",
"1623911076521932.jpg",
"1623911076577364.jpg",
"1623911076647235.jpg",
"1623911076664111.jpg",
"1623911076713712.jpg",
"1623911076769035.jpg",
"1623911076804200.jpg",
"1623911076848952.jpg",
"1623911076884188.jpg",
"1623911076933266.jpg",
"1623911076966360.jpg",
"1623911077004031.jpg",
"1623911077054912.jpg",
"1623911077119537.jpg",
"1623911077168487.jpg",
"1623911077205210.jpg",
"1623911077231655.jpg",
"1623911077373581.jpg",
"1623911077412348.jpg",
"1623911077476890.jpg",
"1623911077540180.jpg",
"1623911077580971.jpg",
"1623911077620309.jpg",
"1623911077673005.jpg",
"1623911077695699.jpg",
"1623911077761360.jpg",
"1623911077815780.jpg",
"1623911077839010.jpg",
"1623911077881518.jpg",
"1623911077938957.jpg",
"1623911077964473.jpg",
"1623911078000220.jpg",
};
for (const char *filename : filenames) {
std::ifstream jpeg_file("data/" + std::string(filename));
std::stringstream buffer;
buffer << jpeg_file.rdbuf();
auto jpeg_data = std::make_shared<std::string>(buffer.str());
int fd = -1;
unsigned char *in_buf = (unsigned char *) jpeg_data->data();
unsigned long in_buf_size = jpeg_data->size();
uint32_t pixfmt = 0;
uint32_t width = 0;
uint32_t height = 0;
decoder->decodeToFd(fd, in_buf, in_buf_size, pixfmt, width, height);
std::cout << "decoded fd: " << fd << std::endl;
}
delete decoder;
}
int main(int argc, char *argv[]) {
std::thread thread1(create);
std::thread thread2(decode);
thread1.join();
thread2.join();
return 0;
}