X264 and TensorRT sudden reboot (MJPG encoder not affected, but not fast enough) on Jetson Orin Nano

Hi there,

Our startup needs to be able to record video while also performing inference on each frame using TensorRT. Our use case needs the frame rate to be as high as possible, and at least above 10FPS.

I am facing and issue where when I try to run a python script which records video while also performing inference on that video using a custom small TensorRT engine, my Jetson Orin Nano reboots almost instantly (it will usually run for a few frames before sudden rebooting) when I use the X264 software encoder in my pipeline, which, as far as I’m aware, I need to use in order to get a relatively high FPS.

Notably, when I run the same script using MJPG encoding, it works fine, however it only runs at about 5FPS which is too slow for our task.

Here is a simplified version of our script:

import cv2
import os
import numpy as np

import data.augmentation as augmentations
from tensorrt_inference import TensorRTInference
from utils.fps import FPS

if os.name == 'nt':
    ENGINE_PATH: str = "models/windows_built_engine.trt"
else:
    ENGINE_PATH: str = "/home/fov/Desktop/FOVCamerasWebApp/jetson/models/jetson_orin_dynamic_output.trt"


print("Creating capture and encoder pipelines...")

  cap = cv2.VideoCapture(
      'nvarguscamerasrc !  '
      'video/x-raw(memory:NVMM) , width=1920, height=1080, format=NV12, framerate=30/1 ! '
      'nvvidconv flip-method=2 ! '
      'video/x-raw, width=1920, height=1080, format=BGRx ! '
      'videoconvert ! '
      'video/x-raw, format=BGR ! '
      'appsink'
  )

  # Note: this one works, but only runs at about 5FPS which is too slow
  # out = cv2.VideoWriter("test.avi", cv2.VideoWriter_fourcc(*'MJPG'), 30, (1920, 1080))

  # Note: this can run at 20FPS, but causes a sudden reboot when ran with the tensorrt model
  out = cv2.VideoWriter(
      'appsrc is-live=true do-timestamp=true format=3 ! '
      'video/x-raw, format=(string)BGR ! '
      'videoconvert ! '
      'video/x-raw, format=(string)NV12 ! '
      'x264enc bitrate=4000 speed-preset=ultrafast tune=zerolatency ! '
      'video/x-h264, profile=baseline ! '
      'h264parse ! '
      'qtmux ! '
      'filesink location=output.mp4',
      0, 30.0, (1920, 1080), True
  )

print("Loading TensorRT model...")
tensorrt_model = TensorRTInference(ENGINE_PATH)

inputs, outputs, bindings, stream = tensorrt_model.allocate_buffers()

fps = FPS()

while cap.isOpened():
    fps.start()
    ret_val, img = cap.read()

    if not ret_val:
        print("Failed to get the frame from the camera.")
        break

    if os.name == 'nt':
        img = cv2.resize(img, (1920, 1080))

    img_tensor = augmentations.numpy2tensor(img)
    out.write(img)
    del img

    # Run inference
    np.copyto(inputs[0].host, img_tensor.ravel())

    tensorrt_model.do_inference(inputs, outputs, bindings, stream)

    fps.stop()
    print(f"FPS: {fps.fps()}")

    # Get the output
    res = [output.host for output in outputs]
    print(res)

cap.release()
out.release()

Here is the device info

I would attach syslogs, but they don’t show anything useful from what I can tell. The crash and reboot occur instantly, so there’s not much to show.

I will note that the TensorRT engine I’m using is pretty tiny (the underlying convolutional neural network is only about 100k parameters), its file size is 678kb.

I do need to process and save FHD video.

I should also note that I also attempted to use the camera and video recording functionality from the jetson-inference library. It successfully enables me to record video at a high frame rate (approx 17FPS) and also perform inference using the TensorRT model, however after it runs for a bit over a minute or so, it will suddenly crash and reboot. I need to be able to record videos at least 30 minutes long.

Hi,
It may be hitting thermal condition and trigger throttling. Please run sudo tegrastats to check the system status. And you may consider use JPEG encoder.

Or may consider use Orin NX for having H265 hardware encoder.

Hi @DaneLLL

A temperature issue I would think is unlikely as it reboots suddenly? sudo tegrastats doesn’t show anything out of the ordinary in the lead up to it (GPU around 50C).

Saving frames as individual jpeg images rather than as a video does work fast enough for now via a simple cv2.imwrite(...)! However for future use cases we will need higher frame rates that I’ve only been able to achieve using the x264 encoder and this doesn’t seem like the most satisfying solution.

We unfortunately can’t do any upgrades, we have already invested in 10 Jetson Orin Nanos and most of them are already deployed remotely.

Do any other suggestions or debugging tips come to mind?

Thanks
Tim

Hi,
Please check if you can upgrade to 6.0GA(r36.3) and try it on Orin Nano developer kit. If the issue is still present, please share a method so that we can set up and try. It looks like in the condition watchdog timer is triggered to reboot the system. We would need to replicate the condition and check. By default we have a fan attaching to the module, and would expect it can cool down the system in most conditions.

Hi,

Unfortunately we are not able to upgrade the JetPack version to 6.0 as we already have cameras deployed (in a different country) and are not able to reflash them without being there physically.

The above script with these engine weights (google drive link) should replicate the issue. I’m also using an IMX477 CSI camera sensor.

I should also note that even saving the videos as individual frames using the JPEG encoder does actually result in the Nvidia Jetson Orin Developer Kits rebooting when its ran for more than an hour, however this only occurs on some of our devices (3 out of 6 rebooted after being ran for more than an hour, and less than 3 hours). Can confirm that the devices did not run out of memory.

I can also confirm that the fan is working on the local Nvidia Jetson Orin Nano developer kit that I have locally, and that the temperature stays within reasonable bounds (55-ish C)

Please let me know if there’s anything else I can provide to help, or if there’s any reliable method for me to test this by myself,
Thanks
Tim

Hi,
Please share full steps of deploying jetson_orin_dynamic_output.trt on Orin Nano developer kit. We will set up and try.

If you cannot upgrade to 6.0GA, we would suggest at least upgrade to 5.1.3.

That’s great thanks!

Libraries

Here are the versions of the relevant libraries:

cuda-python==12.3.0
Pillow==7.0.0  
tensorrt==8.5.2.2 
numpy==1.17.4   

OpenCV doesn’t show up with pip list so I assume it just came with Jetpack, here’s the version, but it shouldn’t matter too much I think:

>>> import cv2
>>> print(cv2.__version__)
4.5.4

I installed tensorrt as follows:

sudo apt-get install libopenblas-base libopenmpi-dev libomp-dev -y
sudo apt-get install tensorrt nvidia-tensorrt nvidia-tensorrt-dev python3-libnvinfer-dev -y

Code:

Here is my tensorrt_inference.py class which we will later import to our actual inference script:

import ctypes
import numpy as np
import tensorrt as trt

from cuda import cuda, cudart
from typing import Union, Optional


TRT_LOGGER = trt.Logger(trt.Logger.WARNING)


def check_cuda_err(err):
    if isinstance(err, cuda.CUresult):
        if err != cuda.CUresult.CUDA_SUCCESS:
            raise RuntimeError("Cuda Error: {}".format(err))
    if isinstance(err, cudart.cudaError_t):
        if err != cudart.cudaError_t.cudaSuccess:
            raise RuntimeError("Cuda Runtime Error: {}".format(err))
    else:
        raise RuntimeError("Unknown error type: {}".format(err))


def cuda_call(call):
    err, res = call[0], call[1:]
    check_cuda_err(err)
    if len(res) == 1:
        res = res[0]
    return res


class TensorRTInference:
    def __init__(self, engine_path: str):
        self.engine = self.load_engine(engine_path)
        self.context = self.engine.create_execution_context()
        print("TensorRT engine loaded successfully")

    @staticmethod
    def load_engine(engine_path) -> trt.ICudaEngine:
        """Load a TensorRT engine from file."""
        with open(engine_path, 'rb') as f, trt.Runtime(TRT_LOGGER) as runtime:
            return runtime.deserialize_cuda_engine(f.read())

    def allocate_buffers(self):
        inputs = []
        outputs = []
        bindings = []
        stream = cuda_call(cudart.cudaStreamCreate())
        tensor_names = [self.engine.get_tensor_name(i) for i in range(self.engine.num_io_tensors)]
        for binding in tensor_names:
            # get_tensor_profile_shape returns (min_shape, optimal_shape, max_shape)
            # Pick out the max shape to allocate enough memory for the binding.
            if binding == "boxes":
                shape = (5, 4)
            elif binding == "labels":
                shape = (5,)
            elif binding == "scores":
                shape = (5,)
            else:
                shape = self.engine.get_tensor_shape(binding)
            shape_valid = np.all([s >= 0 for s in shape])
            if not shape_valid:
                raise ValueError(f"Binding {binding} has dynamic shape, " + \
                                 "but no profile was specified.")
            size = trt.volume(shape)
            trt_type = self.engine.get_tensor_dtype(binding)

            # Allocate host and device buffers
            if trt.nptype(trt_type):
                dtype = np.dtype(trt.nptype(trt_type))
                bindingMemory = HostDeviceMem(size, dtype)
            else:  # no numpy support: create a byte array instead (BF16, FP8, INT4)
                size = int(size * trt_type.itemsize)
                bindingMemory = HostDeviceMem(size)

            # Append the device buffer to device bindings.
            bindings.append(int(bindingMemory.device))

            # Append to the appropriate list.
            if self.engine.get_tensor_mode(binding) == trt.TensorIOMode.INPUT:
                inputs.append(bindingMemory)
            else:
                outputs.append(bindingMemory)
        return inputs, outputs, bindings, stream

    def do_inference(self, inputs, outputs, bindings, stream):
        def execute_async_func():
            self.context.execute_async_v3(stream_handle=stream)
        # Setup context tensor address.
        num_io = self.engine.num_io_tensors
        for i in range(num_io):
            self.context.set_tensor_address(self.engine.get_tensor_name(i), bindings[i])
        return self._do_inference_base(inputs, outputs, stream, execute_async_func)

    def _do_inference_base(self, inputs, outputs, stream, execute_async_func):
        # Transfer input data to the GPU.
        kind = cudart.cudaMemcpyKind.cudaMemcpyHostToDevice
        [cuda_call(cudart.cudaMemcpyAsync(inp.device, inp.host, inp.nbytes, kind, stream)) for inp in inputs]
        # Run inference.
        execute_async_func()
        # Transfer predictions back from the GPU.
        kind = cudart.cudaMemcpyKind.cudaMemcpyDeviceToHost
        [cuda_call(cudart.cudaMemcpyAsync(out.host, out.device, out.nbytes, kind, stream)) for out in outputs]
        # Synchronize the stream
        cuda_call(cudart.cudaStreamSynchronize(stream))
        # Return only the host outputs.
        return [out.host for out in outputs]


class HostDeviceMem:
    """Pair of host and device memory, where the host memory is wrapped in a numpy array"""
    def __init__(self, size: int, dtype: Optional[np.dtype] = None):
        dtype = dtype or np.dtype(np.uint8)
        nbytes = size * dtype.itemsize
        host_mem = cuda_call(cudart.cudaMallocHost(nbytes))
        pointer_type = ctypes.POINTER(np.ctypeslib.as_ctypes_type(dtype))

        self._host = np.ctypeslib.as_array(ctypes.cast(host_mem, pointer_type), (size,))
        self._device = cuda_call(cudart.cudaMalloc(nbytes))
        self._nbytes = nbytes

    @property
    def host(self) -> np.ndarray:
        return self._host

    @host.setter
    def host(self, data: Union[np.ndarray, bytes]):
        if isinstance(data, np.ndarray):
            if data.size > self.host.size:
                raise ValueError(
                    f"Tried to fit an array of size {data.size} into host memory of size {self.host.size}"
                )
            np.copyto(self.host[:data.size], data.flat, casting='safe')
        else:
            assert self.host.dtype == np.uint8
            self.host[:self.nbytes] = np.frombuffer(data, dtype=np.uint8)

    @property
    def device(self) -> int:
        return self._device

    @property
    def nbytes(self) -> int:
        return self._nbytes

    def __str__(self):
        return f"Host:\n{self.host}\nDevice:\n{self.device}\nSize:\n{self.nbytes}\n"

    def __repr__(self):
        return self.__str__()

    def free(self):
        cuda_call(cudart.cudaFree(self.device))
        cuda_call(cudart.cudaFreeHost(self.host.ctypes.data))

Here is the data conversion file that I use to prepare the image data for our tensorrt engine/ neural network, augmentations.py:

from PIL import Image
import numpy as np
import cv2

NORMALIZATION_MEAN = np.array([0.485, 0.456, 0.406])
NORMALIZATION_STD = np.array([0.229, 0.224, 0.225])

def image2tensor(image):
    # Assume image is a PIL Image
    # Convert PIL Image to a numpy array
    np_image = np.array(image).astype(np.float32) / 255.0  # Scale to [0, 1]
    np_image = np_image[:, :, ::-1]  # Convert to BGR if needed
    # Normalize
    np_image = (np_image - NORMALIZATION_MEAN) / NORMALIZATION_STD
    # Move axis to match the (C, H, W) format
    np_image = np_image.transpose(2, 0, 1)
    return np_image

def numpy2tensor(image):
    # Assume image is a numpy array in BGR format
    np_image = image.astype(np.float32) / 255.0  # Scale to [0, 1]
    # Convert to RGB
    np_image = np_image[:, :, ::-1]
    # Normalize
    np_image = (np_image - NORMALIZATION_MEAN) / NORMALIZATION_STD
    # Move axis to match the (C, H, W) format
    np_image = np_image.transpose(2, 0, 1)
    return np_image

And here is the simpler version of an inference script that results in a crash:

import cv2
import os
import numpy as np

import data.augmentation as augmentations
from tensorrt_inference import TensorRTInference


ENGINE_PATH: str = "models/jetson_orin_dynamic_output.trt"


print("Creating capture and encoder pipelines...")

  cap = cv2.VideoCapture(
      'nvarguscamerasrc !  '
      'video/x-raw(memory:NVMM) , width=1920, height=1080, format=NV12, framerate=30/1 ! '
      'nvvidconv flip-method=2 ! '
      'video/x-raw, width=1920, height=1080, format=BGRx ! '
      'videoconvert ! '
      'video/x-raw, format=BGR ! '
      'appsink'
  )

  # Note: this one works, but only runs at about 5FPS which is too slow
  # out = cv2.VideoWriter("test.avi", cv2.VideoWriter_fourcc(*'MJPG'), 30, (1920, 1080))

  # Note: this can run at 20FPS, but causes a sudden reboot when ran with the tensorrt model
  out = cv2.VideoWriter(
      'appsrc is-live=true do-timestamp=true format=3 ! '
      'video/x-raw, format=(string)BGR ! '
      'videoconvert ! '
      'video/x-raw, format=(string)NV12 ! '
      'x264enc bitrate=4000 speed-preset=ultrafast tune=zerolatency ! '
      'video/x-h264, profile=baseline ! '
      'h264parse ! '
      'qtmux ! '
      'filesink location=output.mp4',
      0, 30.0, (1920, 1080), True
  )

print("Loading TensorRT model...")
tensorrt_model = TensorRTInference(ENGINE_PATH)

inputs, outputs, bindings, stream = tensorrt_model.allocate_buffers()

while cap.isOpened():
    fps.start()
    ret_val, img = cap.read()

    if not ret_val:
        print("Failed to get the frame from the camera.")
        break

    if os.name == 'nt':
        img = cv2.resize(img, (1920, 1080))

    img_tensor = augmentations.numpy2tensor(img)
    out.write(img)
    del img

    # Run inference
    np.copyto(inputs[0].host, img_tensor.ravel())

    tensorrt_model.do_inference(inputs, outputs, bindings, stream)

    # Get the output
    res = [output.host for output in outputs]
    print(res)

cap.release()
out.release()

I believe that should be everything needed to recreate. Thanks!

Here is further cv2 build information:

>>> import cv2
>>> print(cv2.getBuildInformation())

General configuration for OpenCV 4.5.4 =====================================
  Version control:               4.5.4-8-g3e4c170df4

  Platform:
    Timestamp:                   2022-01-18T10:01:01Z
    Host:                        Linux 5.10.65-tegra aarch64
    CMake:                       3.16.3
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/make
    Configuration:               Release

  CPU/HW features:
    Baseline:                    NEON FP16

  C/C++:
    Built as dynamic libs?:      YES
    C++ standard:                11
    C++ Compiler:                /usr/bin/c++  (ver 9.3.0)
    C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
    C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
    C Compiler:                  /usr/bin/cc
    C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections    -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
    Linker flags (Release):      -Wl,--gc-sections -Wl,--as-needed  
    Linker flags (Debug):        -Wl,--gc-sections -Wl,--as-needed  
    ccache:                      NO
    Precompiled headers:         NO
    Extra dependencies:          dl m pthread rt
    3rdparty dependencies:

  OpenCV modules:
    To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo python2 python3 stitching ts video videoio
    Disabled:                    world
    Disabled by dependency:      -
    Unavailable:                 java
    Applications:                tests perf_tests examples apps
    Documentation:               NO
    Non-free algorithms:         NO

  GUI:                           GTK2
    GTK+:                        YES (ver 2.24.32)
      GThread :                  YES (ver 2.64.6)
      GtkGlExt:                  NO

  Media I/O: 
    ZLib:                        /usr/lib/aarch64-linux-gnu/libz.so (ver 1.2.11)
    JPEG:                        /usr/lib/aarch64-linux-gnu/libjpeg.so (ver 80)
    WEBP:                        build (ver encoder: 0x020f)
    PNG:                         /usr/lib/aarch64-linux-gnu/libpng.so (ver 1.6.37)
    TIFF:                        /usr/lib/aarch64-linux-gnu/libtiff.so (ver 42 / 4.1.0)
    JPEG 2000:                   build (ver 2.4.0)
    HDR:                         YES
    SUNRASTER:                   YES
    PXM:                         YES
    PFM:                         YES

  Video I/O:
    FFMPEG:                      YES
      avcodec:                   YES (58.54.100)
      avformat:                  YES (58.29.100)
      avutil:                    YES (56.31.100)
      swscale:                   YES (5.5.100)
      avresample:                YES (4.0.0)
    GStreamer:                   YES (1.16.2)
    v4l/v4l2:                    YES (linux/videodev2.h)

  Parallel framework:            TBB (ver 2020.1 interface 11101)

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Lapack:                      NO
    Eigen:                       YES (ver 3.3.7)
    Custom HAL:                  YES (carotene (ver 0.0.1))
    Protobuf:                    build (3.5.1)

  Python 2:
    Interpreter:                 /usr/bin/python2.7 (ver 2.7.18)
    Libraries:                   /usr/lib/aarch64-linux-gnu/libpython2.7.so (ver 2.7.18)
    numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.16.5)
    install path:                lib/python2.7/dist-packages/cv2/python-2.7

  Python 3:
    Interpreter:                 /usr/bin/python3 (ver 3.8.10)
    Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.8.so (ver 3.8.10)
    numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver 1.17.4)
    install path:                lib/python3.8/dist-packages/cv2/python-3.8

  Python (for build):            /usr/bin/python2.7

  Java:                          
    ant:                         NO
    JNI:                         NO
    Java wrappers:               NO
    Java tests:                  NO

  Install to:                    /usr
-----------------------------------------------------------------

Unfortunately its too late (and I’m too tired) (3am here!) to explore this fully but it looks like we can actually upgrade JetPack without having to reflash the SD card physically [1], is that correct?

We are using tailscale and AWS IOT Secure Tunnelling to connect to our devices? Will upgrading Jetpack affect those? My previous impression was that you have to physically reflash the SD Cards to upgrade jetpack. Our devices our in a different country and its infeasible for us to reach them physically, so we are very dependent on those connections.

[1]: JetPack SDK | NVIDIA Developer

@DaneLLL I will link to my other posted topic which details one of the errors resulting from a sudden reboot of running this script: GPU not detected on Nvidia Jetson Orin Nano after sudden reboot (I need to run TensorRT engine inference) - Jetson & Embedded Systems / Jetson Orin Nano - NVIDIA Developer Forums

This topic here that we are in is about sudden rebooting preventing me from recording video and performing inference with a TensorRT engine.

However that other topic was about a specific error that occurred on one of our cameras after one of the sudden reboots. It’s quite a worrying error that says that the GPU is not available. It’s an extra issue on top of the sudden rebooting that I need to try and solve - that camera is not usable without the GPU of course unfortunately.

If we can solve it here too though, that’d be great!

Hi @DaneLLL,

Wondering if there’s any update?

Especially regarding “No GPU found” issue? This is quite a critical issue for us which needs to be fixed by itself so will reopen an issue if not - will help future people with the same issue find it directly through the title too when search for the same issue.

Thanks
Tim

Hi,
We have not replicated the issue yet. From your experience, how long does it take to observe the issue?

It should be practically instantly when used with the x264 encoder script above.

When saving images using a jog encoder it can take 5 to 60 mins

Hi,
It looks like we also need jetson_orin_dynamic_output.trt. Could you zip one package with all files and share the full steps? So that we can simply execute the steps one-by-one to replicate the issue.

I already attached it above in the Google drive link @DaneLLL . Look at May 22 message

Hi is there any update?

@DaveYYY I got an email that you were confused about how to import files in Python which looks like you might have deleted. If you’re still confused, let me know; in this specific example above, I should have written import augmentations, but I trust that you guys are able to fill in the gaps for trivial issues like that.

I can’t edit the post to correct the above import typo, but it should be very clear what to fix for anyone else looking.

How frequently did you hit the issue?
We ran the code for more than 30 minutes without crashing, but the output trensor is all zero.
Is that expected?
We cannot measure FPS because apparrently you didn’t include that part of the code, but it worked well otherwise.

1 Like

Hi @DaveYYY ,

Thanks for running the experiment!

I’ll be back in the office tomorrow morning Irish time and will re-run the script on my two local cameras to confirm, however the issue was hit on all at all eight of our cameras, where it would usually happen instantly with this specific script if I recall correctly (with different encoders, it could take up to 60 mins).

Can I ask what version of Jetpack are you running on the Jetson Orin Nano that you are testing on?

And yes, the tensorrt output would be 0. The model is trained to footballs!

Thanks
Tim

I tried on Orin Nano with JetPack 5.1.3 + an IMX 219 camera, instead of your 5.1.1 + IMX 477.
If you are using DevKit, upgrading from 5.1.1 to 5.1.3 via APT should be easy, if it is really the JetPack version that makes a difference.

Sorry would you excuse my ignorance and tell me how I can upgrade to 5.1.3 via apt from 5.1.1?

I thought that you had to manually take out and flash the SD card, but sounds like there’s a much easier way?