[Argus] Getting metadata without image / display

Hello! I am looking to build a fairly simple application which gathers the brightness of the environment from raw camera bayer data. This data must be unprocessed, to avoid “brightness” being affected by gain. To do so, I need a CaptureMetadata object, but not the image itself. There WILL be a display attached, and it is imperative that it is not interfered with. I ran across this thread, but it never received an answer, appears to be outdated, and I do not have the same limitations. Events would be fine, and I am able to use the BufferOutputStream. However, events don’t seem to be called until the capture is consumed (or at least, I assume that’s why eventProvider’s waitForEvents times out or hangs, depending on whether or not I add a timeout), and this thread appears to imply that one cannot use the BufferOutputStream without a display configured and image output to it.

First you need to confirm the sensor have output embedded data and driver have proper configure for it.
Then you can get the sensor embedded data via Argus API. Have below for reference.

https://docs.nvidia.com/jetson/l4t-multimedia/classArgus_1_1Ext_1_1ISensorPrivateMetadata.html

I don’t think I’m looking for the sensor’s private metadata- just the CaptureMetadata container should work fine (unless I’m misunderstanding the BayerHistogram). However, none of the methods to get that without an EGLStream seem to be working.

I’ve tried with a BufferOutputStream:

#include <iostream>
#include <vector>
#include <Argus/Argus.h>

int main() {
	Argus::UniqueObj<Argus::CameraProvider> cameraProvider(Argus::CameraProvider::create());
	Argus::ICameraProvider* iCameraProvider = Argus::interface_cast<Argus::ICameraProvider>(cameraProvider);
	
	std::vector<Argus::CameraDevice*> cameraDevices;
	iCameraProvider->getCameraDevices(&cameraDevices);
	
	Argus::UniqueObj<Argus::CaptureSession> captureSession(iCameraProvider->createCaptureSession(cameraDevices[0]));
	Argus::ICaptureSession* iCaptureSession = Argus::interface_cast<Argus::ICaptureSession>(captureSession);
	
	Argus::UniqueObj<Argus::OutputStreamSettings> streamSettings(iCaptureSession->createOutputStreamSettings(Argus::STREAM_TYPE_BUFFER));
	Argus::IBufferOutputStreamSettings* iStreamSettings = Argus::interface_cast<Argus::IBufferOutputStreamSettings>(streamSettings);
	iStreamSettings->setBufferType(Argus::BUFFER_TYPE_EGL_IMAGE);
	iStreamSettings->setMetadataEnable(true);
	Argus::UniqueObj<Argus::OutputStream> outputStream(iCaptureSession->createOutputStream(streamSettings.get()));
	Argus::IBufferOutputStream* iBufferOutputStream = Argus::interface_cast<Argus::IBufferOutputStream>(outputStream);
	Argus::UniqueObj<Argus::Buffer> buffer;
	
	Argus::UniqueObj<Argus::Request> request(iCaptureSession->createRequest(Argus::CAPTURE_INTENT_MANUAL));
	Argus::IRequest* iRequest = Argus::interface_cast<Argus::IRequest>(request);
	iRequest->enableOutputStream(outputStream.get());

	iCaptureSession->capture(request.get());
	
	buffer.reset(iBufferOutputStream->acquireBuffer(10000000000));
	Argus::IBuffer* iBuffer = Argus::interface_cast<Argus::IBuffer>(buffer);
	const Argus::CaptureMetadata* metadata = iBuffer->getMetadata();
	const Argus::ICaptureMetadata* iMetadata = Argus::interface_cast<const Argus::ICaptureMetadata>(metadata);
	std::cout << iMetadata->getSensorTimestamp() << std::endl;
	
	cameraProvider.reset();
	return 0;
}

and with Events:

#include <iostream>
#include <vector>
#include <Argus/Argus.h>

int main() {
	Argus::UniqueObj<Argus::CameraProvider> cameraProvider(Argus::CameraProvider::create());
	Argus::ICameraProvider* iCameraProvider = Argus::interface_cast<Argus::ICameraProvider>(cameraProvider);
	
	std::vector<Argus::CameraDevice*> cameraDevices;
	iCameraProvider->getCameraDevices(&cameraDevices);
	
	Argus::UniqueObj<Argus::CaptureSession> captureSession(iCameraProvider->createCaptureSession(cameraDevices[0]));
	Argus::ICaptureSession* iCaptureSession = Argus::interface_cast<Argus::ICaptureSession>(captureSession);
	
	Argus::UniqueObj<Argus::Request> request(iCaptureSession->createRequest(Argus::CAPTURE_INTENT_MANUAL));
	
	Argus::IEventProvider* iEventProvider = Argus::interface_cast<Argus::IEventProvider>(captureSession);
	std::vector<Argus::EventType> eventTypes;
	eventTypes.push_back(Argus::EVENT_TYPE_CAPTURE_COMPLETE);
	Argus::UniqueObj<Argus::EventQueue> queue(iEventProvider->createEventQueue(eventTypes));
	Argus::IEventQueue *iQueue = Argus::interface_cast<Argus::IEventQueue>(queue);

	iCaptureSession->capture(request.get());
	
	iEventProvider->waitForEvents(queue.get(), 10000000000);
	const Argus::Event* event = iQueue->getNextEvent();
	const Argus::IEventCaptureComplete* iEvent = Argus::interface_cast<const Argus::IEventCaptureComplete>(event);
	const Argus::CaptureMetadata* metadata = iEvent->getMetadata();
	const Argus::ICaptureMetadata* iMetadata = Argus::interface_cast<const Argus::ICaptureMetadata>(metadata);
	std::cout << iMetadata->getSensorTimestamp() << std::endl;
	
	cameraProvider.reset();
	return 0;
}

and both hit the 10 second timeout.