Unable to create a NvMediaIJPE object for JPEG compression after Drive Software 10.0 upgrade

Hello,

We were using a modified version of https://gitlab.com/autowarefoundation/autoware.ai/drivers/tree/master/autoware_driveworks_gmsl_interface to run GMSL Cameras on ROS.

Now with the new Drive OS upgrade, we have refreshed the dependencies and fixed library names. Now the program compiles and we are able to:

Initialize a dwContextHandle_t
Initialize a dwSALHandle_t

but after when we do:

NvMediaDevice *device;
    device = NvMediaDeviceCreate();
    if (!device) {
      std::cerr << "WOW: NvMediaDeviceCreate failed." << std::endl;
      exit(1);
    }

    const uint32_t max_jpeg_size = 3 * 1290 * 1208;

    NvMediaIJPE *jpegEncoder = NvMediaIJPECreate(device,
                                                 NvMediaSurfaceType_Image_YUV_420,
                                                 (uint8_t) 1,
                                                 max_jpeg_size);
    if (!jpegEncoder) {
      std::cerr << "WOW: NvMediaIJPECreate failed." << std::endl;
      exit(1);
    }

It prints:
[NvMediaIJPECreate:54] 1015 NvMediaSurfacetype is deprecated.
WOW: NvMediaIJPECreate failed.

So after checking the documentation ( https://docs.nvidia.com/drive/drive_os_5.1.6.1L/nvvib_docs/DRIVE_OS_Linux_SDK_Development_Guide/baggage/group__surface__handling__api.html#ga334e1b66e894fdedccc4f6c280e65e90
) and the header file descriptions, I applied the following to fix it:

NvMediaDevice *device;
    device = NvMediaDeviceCreate();
    if (!device) {
      std::cerr << "WOW: NvMediaDeviceCreate failed." << std::endl;
      exit(1);
    }
    NvMediaSurfFormatAttr attrs[7];
    attrs[0].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_SURF_TYPE;
    attrs[0].value = NVM_SURF_ATTR_SURF_TYPE_YUV;
    attrs[1].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_LAYOUT;
    attrs[1].value = NVM_SURF_ATTR_LAYOUT_BL;
    attrs[2].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_DATA_TYPE;
    attrs[2].value = NVM_SURF_ATTR_DATA_TYPE_INT;
    attrs[3].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_MEMORY;
    attrs[3].value = NVM_SURF_ATTR_MEMORY_PLANAR;
    attrs[4].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_SUB_SAMPLING_TYPE;
    attrs[4].value = NVM_SURF_ATTR_SUB_SAMPLING_TYPE_422;
    attrs[5].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_BITS_PER_COMPONENT;
    attrs[5].value = NVM_SURF_ATTR_BITS_PER_COMPONENT_8;
    attrs[6].type = NvMediaSurfFormatAttrType::NVM_SURF_ATTR_COMPONENT_ORDER;
    attrs[6].value = NVM_SURF_ATTR_COMPONENT_ORDER_YUV;

    NvMediaSurfaceType surface_type = NvMediaSurfaceFormatGetType(attrs, 7);

    std::cout << "surface_type: " << surface_type << std::endl;

    const uint32_t max_jpeg_size = 3 * 1290 * 1208;

    NvMediaIJPE *jpegEncoder = NvMediaIJPECreate(device,
                                                 NvMediaSurfaceType_Image_YUV_420,
                                                 (uint8_t) 1,
                                                 max_jpeg_size);
    if (!jpegEncoder) {
      std::cerr << "WOW: NvMediaIJPECreate failed." << std::endl;
      exit(1);
    }

It prints:
surface_type: 99999
[NvMediaIJPECreate:54] 99999 NvMediaSurfacetype is deprecated.
WOW: NvMediaIJPECreate failed.

So the previous code used to work on Drive 8.0 and what am I missing to replicate the same behaviour using the new SDK?

Thanks

I haven’t figured out what’s the problem in your code snippet. But could you refer to our samples about how to invoke NvMediaSurfaceFormatGetType() first? e.g. ipp_component.c. Thanks!

~/nvidia/nvidia_sdk/DRIVE_Software_10.0_Linux_OS_E3550/DRIVEOS/drive-t186ref-linux/targetfs_a/home/nvidia/drive-t186ref-linux/samples

Thanks a lot, now it has passed that stage!

NvMediaSurfFormatAttr attrs[7];
NVM_SURF_FMT_SET_ATTR_YUV(attrs, YUV, 422, PLANAR, UINT, 8, PL);
NvMediaSurfaceType surface_type = NvMediaSurfaceFormatGetType(attrs, 7);

Using this surface type, it is able to create the NvMediaIJPE encoder.

I had to go through ~/nvidia/nvidia_sdk/DRIVE_Software_10.0_Linux_OS_E3550/DRIVEOS/drive-t186ref-linux/targetfs_a/home/nvidia/drive-t186ref-linux/samples/nvmedia/ipp_raw/cmdline.c file though to find a surface type similar to before.

In the end the uint that represents the surface type changed to 42 from 1015

Good to hear you solve your problem!

If anyone needs a working ROS sekonix camera driver for drive agx with Drive 10.0 here you can access it:

2 Likes