Issue with Suspending and Reenabling IMX490 Process on Jetson AGX Orin

Hardware setup:

  • Jetson Orin AGX 64GB Devkit
  • LI-JXAV-MIPI-ADPT-4CAM
  • LI-GMSL2-IPX-DESER
  • LI-IMX490-GMSL2-120H
  • JetPack 5.1 (2.1)

I am running a process which grabs frames from my camera (IMX490). This code is adapted from 09_argus_camera_jpeg sample attached below. I am suspending the process using SIGSTOP. Before suspending the process, I run stop repeating and wait for captured frames to be processed. To start capturing again, I use SIGCONT and create a new ConsumerThread and start repeating.

This works fine if I start and stop quickly, but if I wait a couple minutes before re-enabling the process, I often get Argus::STATUS_DISCONNECTED followed by Argus::STATUS_CANCELLED. The error logs are below. I have tried boosting my clocks as described here. Is there a proper way to have the cameras go to sleep when they are not in use? Why do the cameras enter a cancelled state after longer periods of time? Why do not see Argus::STATUS_TIMEOUTas the error status if the error logs read timeout?

SCF: Error Timeout:  (propagating from src/services/capture/CaptureServiceEvent.cpp, function wait(), line 59)
Error: Camera HwEvents wait, this may indicate a hardware timeout occured,abort current/incoming cc
PowerServiceCore:handleRequests: timePassed = 70475
launchCC abort cc 2385 session 0
SCF: Error Timeout:  (propagating from src/api/Session.cpp, function capture(), line 823)
(Argus) Error Timeout:  (propagating from src/api/ScfCaptureThread.cpp, function run(), line 110)
(Argus) Error InvalidState: MetadataResult callback for unknown capture. (in src/api/CaptureSessionImpl.cpp, function metadataResult(), line 1238)

Here is a bit of the thread exeute function ported from the example below:

bool ConsumerThread::threadExecute() {
  Argus::IEGLOutputStream* iEglOutputStream =
      Argus::interface_cast<Argus::IEGLOutputStream>(m_stream);
  EGLStream::IFrameConsumer* iFrameConsumer =
      Argus::interface_cast<EGLStream::IFrameConsumer>(m_consumer);
  Argus::IEventQueue* iQueue = Argus::interface_cast<Argus::IEventQueue>(m_queue);

  // Wait until the producer has connected to the stream.
  if (iEglOutputStream->waitUntilConnected() != Argus::STATUS_OK) {
    return false;
  }

  while (m_running_) {
    Argus::Status argusStatus;
    m_eventProvider->waitForEvents(m_queue.get(), kWaitForEventTimeout);
    if (iQueue->getSize() == 0) {
      continue;
    }

    const Argus::Event* event = iQueue->getNextEvent();
    const Argus::IEvent* iEvent = Argus::interface_cast<const Argus::IEvent>(event);
    if (!iEvent) {
      break;
    }

    if (iEvent->getEventType() == Argus::EVENT_TYPE_ERROR) {
      const Argus::IEventError* iEventError =
          Argus::interface_cast<const Argus::IEventError>(event);
      argusStatus = iEventError->getStatus();
      printErrorStatus(argusStatus);
      errorStatus = true;
      break;
    }

    // Acquire a frame.
    frame = Argus::UniqueObj<EGLStream::Frame>(
        iFrameConsumer->acquireFrame(kAcquireFrameTimeout, &argusStatus));
    uint64_t captureTimestampNanoseconds = context_->clock->now().time_since_epoch().count();
    if (argusStatus != Argus::STATUS_OK) {
      printErrorStatus(argusStatus);
      errorStatus = true;
      break;
    }
    EGLStream::IFrame* iFrame = Argus::interface_cast<EGLStream::IFrame>(frame);
    if (!iFrame) {
      break;
    }
    // Process image 
    ...

}

StopCapturing() is called before the process is suspended

void StopCapturing() {
  // Stop the repeating request and wait for idle.
  iCaptureSession_->stopRepeat();
  iCaptureSession_->waitForIdle();

  // Destroy the output stream to end the consumer thread.
  captureStream_.reset();

  // Wait for the consumer thread to complete.
  PROPAGATE_ERROR(consumerThread_->shutdown());
  delete consumerThread_;
}

Thanks in advance!

hello ppomalapally,

let’s have issue narrow down, please try you could reproduce the same by using simple gst pipeline.
for example,
$ gst-launch-1.0 -e nvarguscamerasrc num-buffers=1 ! "video/x-raw(memory:NVMM), width=(int)1280, height=(int)720" ! nvvidconv ! jpegenc ! filesink location=capture0.jpeg

Do you mean run this and close it multiple times? Should I test with SIGSTOP or SIGCONT?

hello ppomalapally,

yes, please try with above gst pipeline for testing.
it shall enable camera sensor to capture single frame, saving it as capture0.jpeg, and sending EOS to shutdown the camera sensor.

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