DMABUF FD owned by NvJPEGDecoder is reused by NvBufferCreateEx [Jetpack 4.5]

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, &params);
        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;
}

Hi,
It is only one DMABUF FD used in NvJpegDecoder, so please copy the decoded data to another NvBuffer by calling NvBufferTransform()

I sligtly updated the code for clarity.

We didn’t pass the DMABUF FD used in NvJpegDecoder out, we just use another thread to create some fresh new NvBuffers, their DMABUF FDs conflict.

Hi,
Would like to confirm the release version you are using. So you hit the issue on Jetpack 4.5(r32.5)?

$ jetson_release
 - NVIDIA Jetson Xavier NX (Developer Kit Version)
   * Jetpack 4.5 [L4T 32.5.0]
   * NV Power Mode: MODE_15W_6CORE - Type: 2
   * jetson_stats.service: active
 - Libraries:
   * CUDA: NOT_INSTALLED
   * cuDNN: NOT_INSTALLED
   * TensorRT: NOT_INSTALLED
   * Visionworks: NOT_INSTALLED
   * OpenCV: NOT_INSTALLED compiled CUDA: NO
   * VPI: NOT_INSTALLED
   * Vulkan: 1.2.70

$ apt list --installed | grep nvidia-l4t-multimedia

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

nvidia-l4t-multimedia/stable,now 32.5.0-20210115151051 arm64 [installed,upgradable to: 32.5.2-20210709090156]
nvidia-l4t-multimedia-utils/stable,now 32.5.0-20210115151051 arm64 [installed,upgradable to: 32.5.2-20210709090156]

Hi,
Please try attached libnvjpeg.so. And remember to backup original lib before replacing it.

r32_5_TEST_libnvjpeg.zip (138.2 KB)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.