Hello,
I am trying to write a simple h264 encoder with jetson multimedia api. In the “frontend” sample, there is a convenience class VideoEncoder, that seems simple to use. However, I don’t quite understand how to use the encodeFromFd function. In the sample it is managed with custom Argus frames, but the implementation is not available. So far I’ve been trying to encode cv::Mat camera frames like so:
static void callback(int dmabuf_fd, void* arg)
{
std::cout << "buf done" << std::endl;
}
int main() {
VideoEncoder encoder("myenc", "out.h264", 1920, 1080, V4L2_PIX_FMT_H264);
encoder.setBufferDoneCallback(callback, nullptr);
encoder.initialize();
cv::VideoCapture cap("/dev/video0");
if (!cap.isOpened()) {
std::cerr << "Error: Could not open the camera." << std::endl;
return -1;
}
cv::Mat image;
while (true) {
cap >> image;
if (image.empty()) {
std::cerr << "Error: Captured empty frame." << std::endl;
continue;
}
NvBufSurf::NvCommonAllocateParams input_params = { 0 };
input_params.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params.width = 1920;
input_params.height = 1080;
input_params.layout = NVBUF_LAYOUT_BLOCK_LINEAR;
input_params.colorFormat = NVBUF_COLOR_FORMAT_NV12;
input_params.memtag = NvBufSurfaceTag_NONE;
int bufn = 0;
if (NvBufSurf::NvAllocate(&input_params, 1, &bufn) < 0)
{
std::cout << "Failed to create nvbuffer!" << std::endl;
return -1;
}
NvBufSurface* nvbuf_surface = nullptr;
if (NvBufSurfaceFromFd(bufn, (void**)&nvbuf_surface) != 0) {
std::cerr << "Error: Failed to map dmabuf_fd to NvBufSurface" << std::endl;
return -1;
}
memcpy(nvbuf_surface->surfaceList[0].dataPtr, image.data, image.total() * image.elemSize());
if (encoder.encodeFromFd(bufn)) {
std::cout << "success_" << std::endl;
}
}
cap.release();
cv::destroyAllWindows();
return 0;
}
The first frame is encoded fine, but then I get segfaults when trying to allocate another buffer. Buffer done callback is also never reached. Is the issue the incorrect image format or buffer handling? Thanks guys, I’m really struggling