Hi,
I have a problem starting and stopping the camera device using argus and C++. I want to start/stop it multiple times within the scope of the program.
First of all the code I currently use to start the sensor:
// Create the CameraProvider object
cameraProvider = Argus::UniqueObj<Argus::CameraProvider>(Argus::CameraProvider::create());
iCameraProvider = Argus::interface_cast<Argus::ICameraProvider>(cameraProvider);
if (iCameraProvider == nullptr)
{
LOG_ERROR(m_log, "Failed to create CameraProvider");
}
LOG_INFO(m_log, "Argus Version: " + iCameraProvider->getVersion());
std::vector<Argus::CameraDevice*> cameraDevices;
Argus::Status status = iCameraProvider->getCameraDevices(&cameraDevices);
// Get the selected CameraDevice and SensorMode.
cameraDevice = ArgusSamples::ArgusHelpers::getCameraDevice(cameraProvider.get(), cameraDeviceIndex);
if (cameraDevice == nullptr)
{
LOG_ERROR(m_log, "Selected camera device is not available");
}
sensorMode = ArgusSamples::ArgusHelpers::getSensorMode(cameraDevice, sensorModeIndex);
iSensorMode = Argus::interface_cast<Argus::ISensorMode>(sensorMode);
if (iSensorMode == nullptr)
{
LOG_ERROR(m_log, "Selected sensor mode not available");
}
// Create the capture session using the selected device.
captureSession = Argus::UniqueObj<Argus::CaptureSession>(iCameraProvider->createCaptureSession(cameraDevice));
iCaptureSession = Argus::interface_cast<Argus::ICaptureSession>(captureSession);
if (iCaptureSession == nullptr)
{
LOG_ERROR(m_log, "Failed to create CaptureSession");
throw std::invalid_argument("cannot start capture session");
}
LOG_INFO(m_log, "Creating output stream\n");
streamSettings =
Argus::UniqueObj<Argus::OutputStreamSettings>(iCaptureSession->createOutputStreamSettings(Argus::STREAM_TYPE_EGL));
iEGLStreamSettings = Argus::interface_cast<Argus::IEGLOutputStreamSettings>(streamSettings);
if (iEGLStreamSettings == nullptr)
{
LOG_ERROR(m_log, "Failed to create OutputStreamSettings");
}
iEGLStreamSettings->setPixelFormat(Argus::PIXEL_FMT_YCbCr_420_888);
iEGLStreamSettings->setResolution(iSensorMode->getResolution());
iEGLStreamSettings->setMode(Argus::EGL_STREAM_MODE_MAILBOX);
iEGLStreamSettings->setMetadataEnable(true);
outputStream = Argus::UniqueObj<Argus::OutputStream>(iCaptureSession->createOutputStream(streamSettings.get()));
iEGLOutputStream = Argus::interface_cast<Argus::IEGLOutputStream>(outputStream);
if (iEGLOutputStream == nullptr)
{
LOG_ERROR(m_log, "Failed to create EGLOutputStream");
}
// Initialize and connect CUDA as the EGLStream consumer.
if (!ArgusSamples::initCUDA(&g_cudaContext))
{
LOG_ERROR(m_log, "Cuda could not be initialized");
}
LOG_INFO(m_log, "Connecting CUDA to OutputStream as an EGLStream consumer");
cudaConnection = std::make_shared<CUeglStreamConnection>();
CUresult cuResult = cuEGLStreamConsumerConnect(cudaConnection.get(), iEGLOutputStream->getEGLStream());
if (cuResult != CUDA_SUCCESS)
{
LOG_ERROR(m_log,
"Unable to connect CUDA to EGLStream as a consumer CUresult: "
+ std::string(ArgusSamples::getCudaErrorString(cuResult)));
}
// Create capture request, set sensor mode, and enable output stream.
request = Argus::UniqueObj<Argus::Request>(iCaptureSession->createRequest());
iRequest = Argus::interface_cast<Argus::IRequest>(request);
if (iRequest == nullptr)
{
LOG_ERROR(m_log, "Failed to create Request");
}
iRequest->enableOutputStream(outputStream.get());
autoControlSettings = Argus::interface_cast<Argus::IAutoControlSettings>(iRequest->getAutoControlSettings());
if (autoControlSettings == nullptr)
{
LOG_ERROR(m_log, "Failed to create auto control settings");
}
// Set the sensor mode in the request.
iSourceSettings = Argus::interface_cast<Argus::ISourceSettings>(request);
if (iSourceSettings == nullptr)
{
LOG_ERROR(m_log, "Failed to get source settings request interface");
}
iSourceSettings->setSensorMode(sensorMode);
iSourceSettings->setFrameDurationRange(Argus::Range<std::uint64_t>(static_cast<std::uint64_t>(1e9 / kFramerate)));
status = iSourceSettings->setExposureTimeRange(kExposureTimeRange);
if (status != Argus::STATUS_OK)
{
LOG_WARN(m_log, "Could not set exposure time!");
}
iSourceSettings->setGainRange(kGainRange);
LOG_INFO(m_log, "Starting repeat capture requests.");
status = iCaptureSession->repeat(request.get());
if (status != Argus::STATUS_OK)
{
LOG_ERROR(m_log, "Failed to submit capture request status " + std::to_string(status));
}
Stopping it is done like so:
if (iCaptureSession != nullptr)
{
iCaptureSession->stopRepeat();
Argus::Status status = iCaptureSession->waitForIdle(); // 30s
if (status != Argus::STATUS_OK)
{
LOG_ERROR(m_log, "Failed to wait for idle");
}
LOG_INFO(m_log, "iCaptureSession finished");
}
// Disconnect the Argus producer from the stream.
/// @todo: This is a WAR for a bug in cuEGLStreamConsumerDisconnect (see bug 200239336).
if (iEGLOutputStream != nullptr)
{
LOG_INFO(m_log, "Disconnect iEGLOutputStream");
iEGLOutputStream->disconnect();
}
captureSession.reset();
// Shut down Argus.
cameraProvider.reset();
LOG_INFO(m_log, "close done\n");
However when I then call start again, I get this error:
(Argus) Error EndOfFile: Unexpected error in reading socket (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 277)
(Argus) Error EndOfFile: Receive worker failure, notifying 1 waiting threads (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 350)
(Argus) Error InvalidState: Argus client is exiting with 1 outstanding client threads (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 366)
(Argus) Error EndOfFile: Receiving thread terminated with error (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadWrapper(), line 379)
(Argus) Error EndOfFile: Client thread received an error from socket (in src/rpc/socket/client/ClientSocketManager.cpp, function send(), line 145)
(Argus) Error EndOfFile: (propagating from src/rpc/socket/client/SocketClientDispatch.cpp, function dispatch(), line 91)
(Argus) Error InvalidState: Receive thread is not running cannot send. (in src/rpc/socket/client/ClientSocketManager.cpp, function send(), line 96)
(Argus) Error InvalidState: (propagating from src/rpc/socket/client/SocketClientDispatch.cpp, function dispatch(), line 91)