On a Jetson AGX Thor, I am trying to pass the fd returned from NvJPEGDecoder (jetson_multimedia_api/samples/common/classes/NvJpegDecoder.cpp) or from NvBufSurf::NvAllocate to another process.
To do that, I combine the steps in 06_jpeg_decode example with 13_argus_multi_camera transport example, where I send the file descriptor over socket with SCM_RIGHTS + the NvBufSurfaceMapParams. However, on the sender side (which runs the NvJPEGDecoder), when I try to run NvBufSurfaceGetMapParams, it prints “NvBufSurfaceCudaMemGetMapParams: Invalid argument extendedMapParams” and fails (return -1). It fails with both the fd returned from NvJPEGDecoder::decodeToFd, and the dmabuf_fd after NvTransform (created with NvBufSurf::NvAllocate).
Could you help me?
My code structure is something like:
#include "NvJpegDecoder.h"
#include "NvBufSurface.h"
#include <chrono>
#include <fstream>
#include <thread>
#include <iostream>
int main() {
std::ifstream file("test.jpg", std::ios::binary | std::ios::ate);
if (!file.is_open()) {
return 1;
}
std::streamsize filesize = file.tellg();
if (filesize <= 0) {
return 1;
}
file.seekg(0, std::ios::beg);
std::vector<unsigned char> jpeg_data(filesize);
if (!file.read(reinterpret_cast<char*>(jpeg_data.data()), filesize)) {
return 1;
}
const auto jpeg_size = filesize;
auto* decoder = NvJPEGDecoder::createJPEGDecoder("jpeg_dec");
decoder->setMemType(NVBUF_MEM_CUDA_DEVICE);
decoder->setUseExternalBuffer(true);
int tmp_fd;
uint32_t pixfmt, width, height;
decoder->decodeToFd(tmp_fd, jpeg_data.data(), jpeg_size, pixfmt, width, height);
NvBufSurface *nvbuf_surf = 0;
if (NvBufSurfaceFromFd(tmp_fd, (void **)(&nvbuf_surf)) == -1) {
return -1;
}
NvBufSurf::NvCommonAllocateParams params = {0};
params.memType = NVBUF_MEM_CUDA_PINNED;
params.width = width;
params.height = height;
params.layout = NVBUF_LAYOUT_PITCH;
params.colorFormat = NVBUF_COLOR_FORMAT_NV12_ER; // Convert to NV12_ER
params.memtag = NvBufSurfaceTag_VIDEO_CONVERT;
int dst_dma_fd;
if (NvBufSurf::NvAllocate(¶ms, 1, &dst_dma_fd) == -1) {
return -1;
}
NvBufSurf::NvCommonTransformParams transform_params = {0};
transform_params.src_top = 0;
transform_params.src_left = 0;
transform_params.src_width = width;
transform_params.src_height = height;
transform_params.dst_top = 0;
transform_params.dst_left = 0;
transform_params.dst_width = width;
transform_params.dst_height = height;
transform_params.flag = NVBUFSURF_TRANSFORM_FILTER;
transform_params.flip = NvBufSurfTransform_None;
transform_params.filter = NvBufSurfTransformInter_Nearest;
if (NvBufSurf::NvTransform(&transform_params, tmp_fd, dst_dma_fd) == -1){
NvBufSurf::NvDestroy(dst_dma_fd);
return -1;
}
if (NvBufSurfaceFromFd(dst_dma_fd, (void**)(&nvbuf_surf)) == -1) {
return -1;
}
NvBufSurfaceMapParams buf_par = {0};
if (NvBufSurfaceGetMapParams(nvbuf_surf, 0, &buf_par) == -1) { /// This fails always, with both tmp_fd and dst_dma_fd
return -1;
}
// Send dst_dma_fd over socket with SCM_RIGHTS + buf_par, and load with NvBufSurfaceImport
return 0;
}