1#include "RaytrixStreamer.h"
23void OnImageCaptured(
const Rx::CRxImage& xImage,
unsigned uCamIdx, Rx::LFR::CImageQueue& camBuffer)
28 Rx::CRxImage xCapturedImage;
29 xCapturedImage.Create(xImage);
34 if (!camBuffer.MoveIn(std::move(xCapturedImage)))
41 catch (Rx::CRxException& ex)
43 printf(
"Exception occured:\n%s\n\n", ex.ToString(
true).ToCString());
44 printf(
"Press any key to end program...\n");
57static void ImageCaptured(
const Rx::CRxImage& xImage,
unsigned uCamIdx,
void* pvContext)
60 OnImageCaptured(xImage, uCamIdx, context->
getCamBuffer(uCamIdx));
96void RaytrixStreamer::findVulkanGPU(
const uint8_t uuid[VK_UUID_SIZE]) {
99 cudaGetDeviceCount(&cudaDeviceCount);
102 for (
int cudaDevice = 0; cudaDevice < cudaDeviceCount; cudaDevice++)
104 cudaDeviceProp deviceProp;
105 cudaGetDeviceProperties(&deviceProp, cudaDevice);
107 std::cout <<
"GPU n: " << cudaDevice << std::endl;
108 const unsigned char* p =
reinterpret_cast<uchar*
>(&deviceProp.uuid);
109 for (
size_t i = 0; i < 16; i++) {
110 printf(
"%02hhx", p[i]);
114 if (!memcmp(&deviceProp.uuid, uuid, VK_UUID_SIZE))
116 vulkanGPU = cudaDevice;
119 std::cout << std::endl;
120 std::cout <<
"Vulkan GPU: " << std::endl;
121 for (
size_t i = 0; i < 16; ++i) {
122 printf(
"%02hhx", uuid[i]);
126 std::cout << std::endl;
129 gpuErrchk(cudaSetDevice(vulkanGPU));
130 std::cout <<
"Available GPUs: " << cudaDeviceCount <<
" Vulkan GPU:" << vulkanGPU << std::endl;
133void RaytrixStreamer::initRxCams() {
135 std::cout <<
"Initializing Rx cams" << std::endl;
138 xCamServer.FindCameras();
141 if (xCamServer.GetCameraCount() == 0)
143 printf(
"No camera found\n");
144 throw HVT_ERROR_NOT_FOUND;
147 printf(
"Number of cameras available: %d\n", xCamServer.GetCameraCount());
149 for (
int i = 0; i < infoJSON.numCams; ++i) {
151 auto& xCam = xCamServer.GetCamera(infoJSON.uIDs[i]);
154 printf(
"Opening camera %i...", infoJSON.uIDs[i]);
159 xCam.AddImageCapturedCallback(ImageCaptured, (
void*)
this);
161 printf(
"______________________________________________\n");
162 printf(
"Camera %d:\n", infoJSON.uIDs[i]);
168 printf(
">> Type: %s\n", xCam.GetDriverName().ToCString());
171 printf(
">> ID : %s\n", xCam.GetInternalSerial().ToCString());
173 printf(
">> Buffersize: %u\n", uBufferSize);
175 printf(
">> Overwrite : %s\n", bOverwrite ?
"Yes" :
"No");
180 camBuffers[i].Initialize(uBufferSize, bOverwrite);
182 if (xCam.IsPropertyAvailable(Rx::ECamProperty::Exposure)) xCam.SetProperty(Rx::ECamProperty::Exposure, infoJSON.exposureCams[i]);
184 Rx::CRxArrayString GUIDs;
185 Rx::LFR::CCalibrationManager::GetCalibrationGUIDs(GUIDs);
187 for (
size_t j = 0; infoJSON.specificCal && j < GUIDs.Length(); ++j) {
188 if (GUIDs.At(j) == infoJSON.GUIDsCalib[i]) {
189 std::cout <<
"Find metric calibration wanted: " << infoJSON.GUIDsCalib[i].ToCString() << std::endl;
194 if (idxInGUIDs >= 0) {
195 Rx::LFR::CCalibrationManager::LoadCalibration(*(camCalibrations[i]), GUIDs.At(idxInGUIDs),
true);
199 if (!Rx::LFR::CCalibrationManager::HasDatabase(xCam))
201 std::cerr <<
"The first camera in your system does not have a database." << std::endl;
202 std::cerr <<
"Either use the installer for your camera settings to install the calibration on your system or create a calibration manualy via RxLive for example." << std::endl;
203 throw HVT_ERROR_NOT_FOUND;
205 Rx::LFR::CCalibrationManager::LoadDefaultCalibration(*(camCalibrations[i]), xCam,
true);
210void RaytrixStreamer::initStreamParameters() {
213 if (synthesisSem == NULL) {
214 std::cerr <<
"Impossible to allocate data for semaphore ..." << std::endl;
215 throw HVT_ERROR_UNKNOWN;
220 using namespace std::chrono_literals;
221 auto framePeriod = std::chrono::nanoseconds(1s) / frameRate;
224 for (
size_t i = 0; i < infoJSON.numCams; ++i)
227 HvtProjectionType ptype;
230 ptype = HvtProjectionType::HVT_PROJECTION_PERSPECTIVE;
236 RS.projectionType = ptype;
237 RS.width_color = infoJSON.width;
238 RS.height_color = infoJSON.height;
239 RS.width_depth = infoJSON.widthDepth;
240 RS.height_depth = infoJSON.heightDepth;
243 RS.colorFrameSize = infoJSON.width * infoJSON.height * 4;
244 RS.colorFrameStride = infoJSON.width * 4;
245 RS.depthFrameSize = infoJSON.widthDepth * infoJSON.heightDepth *
sizeof(float);
246 RS.depthFrameStride = infoJSON.widthDepth *
sizeof(float);
247 RS.colorFormat = HvtImageFormat::HVT_FORMAT_R8G8B8A8_UNORM;
248 RS.depthFormat = HvtImageFormat::HVT_FORMAT_R32_SFLOAT;
249 RS.intrinsics = intrinsics;
250 RS.extrinsics = extrinsics;
251 RS.framePeriod = framePeriod;
252 RS.frameCount = (int)numFrames;
253 readStreams.push_back(RS);
257void RaytrixStreamer::initRxCudaCompute() {
258 std::cout <<
"Initialize RxCUDACompute instances" << std::endl;
259 xCudaComputes =
new Rx::LFR::CCudaCompute[infoJSON.numCams];
261 Rx::LFR::CCuda::EnumerateCudaDevices();
262 Rx::CRxMetaData metaData;
264 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
266 xCudaComputes[i].SetCudaDevice(Rx::LFR::CCuda::GetDevice(vulkanGPU));
268 xCudaComputes[i].ApplyCalibration(*(camCalibrations[i]),
true);
269 if (infoJSON.loadFromRawFile) {
270 seqReaders[i].GetMetaData((Rx::CRxMetaData&)metaData);
271 xCudaComputes[i].GetComputeParams().ImportFromMetaData(metaData);
273 rayImages[i].GetSize((
int&)widthDefault, (
int&)heightDefault);
276 xCudaComputes[i].GetComputeParams().ImportParameterFromFile(infoJSON.filenameComputeParameters);
278 xCamServer.GetCamera(i).GetProperty(Rx::ECamProperty::Width, (
int&)widthDefault);
279 xCamServer.GetCamera(i).GetProperty(Rx::ECamProperty::Height, (
int&)heightDefault);
282 xCudaComputes[i].GetComputeParams().SetValue(Rx::LFR::ECudaComputeParam::PreProc_DataType, (
unsigned) Rx::EDataType::UByte);
284 if (infoJSON.forceRGBResolution) {
285 if (widthDefault / infoJSON.width != heightDefault / infoJSON.height) {
286 std::cout <<
"The focus image divisor should be the same for the rows and the the columns..." << std::endl;
288 imgDivisor = (double)widthDefault / (
double)infoJSON.width;
289 xCudaComputes[i].GetComputeParams().SetValue(Rx::LFR::ECudaComputeParam::Focus_ImageDivisor, imgDivisor);
292 xCudaComputes[i].GetComputeParams().GetValue(Rx::LFR::ECudaComputeParam::Focus_ImageDivisor, (
double&)imgDivisor);
293 infoJSON.width = widthDefault / imgDivisor;
294 infoJSON.height = heightDefault / imgDivisor;
297 if (infoJSON.forceDepthResolution) {
298 if (widthDefault / infoJSON.widthDepth != heightDefault / infoJSON.heightDepth) {
299 std::cout <<
"The depth image divisor should be the same for the rows and the the columns..." << std::endl;
301 imgDivisor = (double)widthDefault / (
double)infoJSON.widthDepth;
302 xCudaComputes[i].GetComputeParams().SetValue(Rx::LFR::ECudaComputeParam::Depth_ImageDivisor, imgDivisor);
305 xCudaComputes[i].GetComputeParams().GetValue(Rx::LFR::ECudaComputeParam::Depth_ImageDivisor, (
double&)imgDivisor);
306 infoJSON.widthDepth = widthDefault / imgDivisor;
307 infoJSON.heightDepth = heightDefault / imgDivisor;
310 catch (Rx::CRxException e) {
311 std::cerr <<
"Failed to initialized cuda compute... Check Raytrix error code: " << e.ToString().ToCString() << std::endl;
312 throw HVT_ERROR_UNKNOWN;
318void RaytrixStreamer::initRxSDK() {
320 printf(
"Authenticate LFR...\n");
322 Rx::LFR::CLightFieldRuntime::Authenticate();
324 catch (Rx::CRxException e) {
325 std::cerr <<
"Impossible to authenticate. Check RaytrixSDK error code: " << e.ToString().ToCString() << std::endl;
326 throw HVT_ERROR_UNKNOWN;
328 if (!Rx::LFR::CLightFieldRuntime::IsFeatureSupported(Rx::ERuntimeFeature::SDK)) {
329 std::cerr <<
"Your license does not allow you to use the SDK properly. Upgrade it or buy another license..." << std::endl;
330 throw HVT_ERROR_INVALID_HANDLE;
332 camCalibrations = (Rx::LFR::CCalibration**)malloc(
sizeof(Rx::LFR::CCalibration*) * infoJSON.numCams);
333 if (camCalibrations == NULL) {
334 std::cerr <<
"Impossible to allocate memory for default calibrations" << std::endl;
335 throw HVT_ERROR_UNKNOWN;
338 if (infoJSON.loadFromRawFile) {
339 rayImages =
new Rx::LFR::CRayImage[infoJSON.numCams];
340 seqReaders =
new Rx::LFR::CSeqFileReader[infoJSON.numCams];
343 camBuffers =
new Rx::LFR::CImageQueue[infoJSON.numCams];
344 capturedImages =
new Rx::CRxImage[infoJSON.numCams];
345 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
346 camCalibrations[i] =
new Rx::LFR::CCalibration();
349 imgFormatRGB =
new Rx::CRxImageFormat[infoJSON.numCams];
350 imgFormatDepth =
new Rx::CRxImageFormat[infoJSON.numCams];
352 pitchInCudaRGB =
new size_t[infoJSON.numCams];
353 pitchInCudaDepth =
new size_t[infoJSON.numCams];
355 referencePlaneToCameraPlane =
new float[infoJSON.numCams];
357 cuImgs =
new Rx::LFR::CudaImage[infoJSON.numCams];
358 cuDepths =
new Rx::LFR::CudaImage[infoJSON.numCams];
361void RaytrixStreamer::initArrayCuda() {
362 std::cout <<
"Init CUDA array" << std::endl;
363 imgRGB = (
unsigned short**)malloc(
sizeof(
unsigned short*) * infoJSON.numCams);
364 imgDepth = (
unsigned short**)malloc(
sizeof(
unsigned short*) * infoJSON.numCams);
365 finalRGB = (
unsigned char**)malloc(
sizeof(
unsigned char*) * infoJSON.numCams);
366 finalDepth = (
float**)malloc(
sizeof(
float*) * infoJSON.numCams);
367 imgFloatDepth = (
float**)malloc(
sizeof(
float*) * infoJSON.numCams);
368 prevFinalDepth = (
float**)malloc(
sizeof(
float*) * infoJSON.numCams);
369 imgUByteRGB = (uchar**)malloc(
sizeof(uchar*) * infoJSON.numCams);
371 if (imgRGB == NULL || imgDepth == NULL || finalRGB == NULL || finalDepth == NULL) {
372 std::cerr <<
"Impossible to allocate data for img vectors..." << std::endl;
373 throw HVT_ERROR_UNKNOWN;
376 gpuErrchk(cudaSetDevice(vulkanGPU));
377 cudaStreams = (cudaStream_t*)malloc(
sizeof(cudaStream_t) * infoJSON.numCams);
378 cudaEvents = (cudaEvent_t*)malloc(
sizeof(cudaEvent_t) * infoJSON.numCams);
380 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
381 gpuErrchk(cudaMalloc(finalRGB + i,
sizeof(uchar) * infoJSON.width * infoJSON.height * 4));
382 gpuErrchk(cudaMalloc(finalDepth + i,
sizeof(
float) * infoJSON.widthDepth * infoJSON.heightDepth));
383 gpuErrchk(cudaMalloc(prevFinalDepth + i,
sizeof(
float) * infoJSON.widthDepth * infoJSON.heightDepth));
385 gpuErrchk(cudaStreamCreate(&(cudaStreams[i])));
386 gpuErrchk(cudaEventCreateWithFlags(&(cudaEvents[i]), cudaEventDisableTiming));
390void RaytrixStreamer::readInfoFromJSON() {
393 errno_t err = _dupenv_s(&jsonPath, &len, ENV_NAME);
395 std::cerr <<
"No " << ENV_NAME <<
"env variable set, cannot load settings" << std::endl;
396 throw HvtResult::HVT_ERROR_NOT_FOUND;
400 std::cout <<
"Start reading JSON file..." << std::endl;
401 std::ifstream jsonRead{ jsonPath, std::ifstream::binary };
402 if (!jsonRead.good()) {
403 std::cout <<
"Impossible to read JSON file, check path... Path given: " << jsonPath << std::endl;
404 throw HVT_ERROR_NOT_FOUND;
406 nlohmann::json jsonContent;
407 jsonRead >> jsonContent;
409 infoJSON.numCams = jsonContent[
"numCams"];
411 infoJSON.forceRGBResolution = jsonContent[
"forceUseOfSpecificRBGResolution"];
412 if (infoJSON.forceRGBResolution) {
414 infoJSON.width = jsonContent[
"width"];
415 infoJSON.height = jsonContent[
"height"];
418 infoJSON.forceDepthResolution = jsonContent[
"forceUseOfSpecificDepthResolution"];
419 if (infoJSON.forceRGBResolution) {
421 infoJSON.widthDepth = jsonContent[
"width_depth"];
422 infoJSON.heightDepth = jsonContent[
"height_depth"];
425 infoJSON.uIDs =
new unsigned int[infoJSON.numCams];
426 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
427 infoJSON.uIDs[i] = jsonContent[
"idCams"][std::to_string(i).c_str()];
430 std::string tmpStdString = jsonContent[
"RxComputeParametersFile"];
431 infoJSON.filenameComputeParameters = Rx::CRxString(tmpStdString.c_str());
433 infoJSON.loadFromRawFile = jsonContent[
"fromRawFile"];
434 if (infoJSON.loadFromRawFile) {
436 infoJSON.filenameRawFiles =
new Rx::CRxString[infoJSON.numCams];
437 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
438 tmpStdString = jsonContent[
"pathRawFile"][std::to_string(i).c_str()];
439 infoJSON.filenameRawFiles[i] = Rx::CRxString(tmpStdString.c_str());
443 infoJSON.specificCal = jsonContent[
"specificCalibration"];
444 if (infoJSON.specificCal) {
446 infoJSON.GUIDsCalib =
new Rx::CRxString[infoJSON.numCams];
447 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
448 tmpStdString = jsonContent[
"GUIDsForCalibration"][std::to_string(i).c_str()];
449 infoJSON.GUIDsCalib[i] = Rx::CRxString(tmpStdString.c_str());
452 if (!infoJSON.loadFromRawFile) {
454 infoJSON.exposureCams =
new float[infoJSON.numCams];
455 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
456 infoJSON.exposureCams[i] = jsonContent[
"exposureCams"][std::to_string(i).c_str()];
460 infoJSON.extrinsicParamsPath = jsonContent[
"ExtrinsicParamsFile"];
461 std::cout <<
"Json path read" << std::endl;
464void RaytrixStreamer::initMutex() {
465 loaderMtxs =
new std::mutex[infoJSON.numCams];
466 loaderCVs =
new std::condition_variable[infoJSON.numCams];
467 canLoadImgs =
new bool[infoJSON.numCams];
468 memset(canLoadImgs,
true, infoJSON.numCams *
sizeof(
bool));
471void RaytrixStreamer::initRxRayFile() {
472 std::cout <<
"Read RayFile: " << std::endl;
474 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
475 std::cout <<
"Seq " << i <<
": " << infoJSON.filenameRawFiles[i].ToCString() << std::endl;
476 seqReaders[i].Open(infoJSON.filenameRawFiles[i]);
477 seqReaders[i].ReadFrame(rayImages[i],
true,
false);
479 Rx::CRxArrayString GUIDs;
480 Rx::LFR::CCalibrationManager::GetCalibrationGUIDs(GUIDs);
482 for (
size_t j = 0; infoJSON.specificCal && j < GUIDs.Length(); ++j) {
483 if (GUIDs.At(j) == infoJSON.GUIDsCalib[i]) {
484 std::cout <<
"Find metric calibration wanted: " << infoJSON.GUIDsCalib[i].ToCString() << std::endl;
489 if (idxInGUIDs >= 0) {
490 camCalibrations[i] =
new Rx::LFR::CCalibration();
491 Rx::LFR::CCalibrationManager::LoadCalibration(*(camCalibrations[i]), GUIDs.At(idxInGUIDs),
true);
494 camCalibrations[i] = (Rx::LFR::CCalibration*)&(rayImages[i].GetCalibration());
498 catch (Rx::CRxException e) {
499 std::cout <<
"Impossible to read Rays file... Check error code: " << e.ToString().ToCString() << std::endl;
500 throw HVT_ERROR_UNKNOWN;
508void RaytrixStreamer::addMsgToPrint(
const char* title,
long long int averageTime,
float frameNumber)
510 if (printMsg == NULL) {
512 printMsg = (
char*)malloc(
sizeof(
char) * SIZE_MSG);
513 if (printMsg == NULL)
517 size_t size = std::strlen(title) + 6 + 6;
518 sprintf(printMsg + whereToAddMsg,
"%s: %f ...", title, (frameNumber) * 1000.f / averageTime);
519 whereToAddMsg += size;
522void RaytrixStreamer::printFPS() {
523 std::cout <<
'\r' << printMsg << std::flush;
526void RaytrixStreamer::resetPrintMsg() {
527 memset(printMsg,
'\0',
sizeof(
char) * SIZE_MSG);
535 const float ZFar = 1.3f;
540 const float ZNear = 0.4f;
545 Rx::LFR::CParameters<Rx::LFR::ECalibrationParam>& paramsCal = camCalibrations[idxCam]->GetParams();
547 paramsCal.GetValue(Rx::LFR::ECalibrationParam::MainLensThick_NominalFocalLengthMM, f);
548 paramsCal.GetValue(Rx::LFR::ECalibrationParam::Sensor_PhysicalPixelSizeMM, sizePixel);
551 intrinsicParams.
focalX = (float)f / (((
float)widthDefault / (
float)infoJSON.widthDepth) * sizePixel);
552 intrinsicParams.
focalY = (float)f / (((
float)heightDefault / (float)infoJSON.heightDepth) * sizePixel);
556 return intrinsicParams;
563 Rx::LFR::CParameters<Rx::LFR::ECalibrationParam>& paramsCal = camCalibrations[idxCam]->GetParams();
564 paramsCal.GetValue(Rx::LFR::ECalibrationParam::IsExtrinsicCalibrated, isExCalib);
565 if (isExCalib != 1) {
566 std::cerr <<
"Camera " << idxCam <<
" is not extrinsincly calibrated... Reconstruction must be wrong." << std::endl;
568 Rx::CRxArrayDouble trans;
569 paramsCal.GetValue(Rx::LFR::ECalibrationParam::Translation_Global_Sensor, trans);
570 double* dataPtr = (
double*)trans.GetPointer();
571 size_t sizeData = trans.Length();
572 bool checkExParams =
true;
574 checkExParams =
false;
576 std::ifstream jsonRead{ infoJSON.extrinsicParamsPath, std::ifstream::binary };
577 if (!jsonRead.good()) {
578 std::cout <<
"Impossible to read JSON extrinsic file, check path... Path given: " << infoJSON.extrinsicParamsPath << std::endl;
579 throw HVT_ERROR_NOT_FOUND;
581 nlohmann::json jsonContent;
582 jsonRead >> jsonContent;
585 pos.x = (float)dataPtr[2] + (
double)jsonContent[
"cameras"][idxCam][
"Position"][0];
586 pos.y = (float)dataPtr[0] + (
double)jsonContent[
"cameras"][idxCam][
"Position"][1];
587 pos.z = (float)dataPtr[1] + (
double)jsonContent[
"cameras"][idxCam][
"Position"][2];
588 referencePlaneToCameraPlane[idxCam] = pos.x;
590 paramsCal.GetValue(Rx::LFR::ECalibrationParam::Rotation_Global_Sensor_Pitch, data);
591 rot.pitch = (float)data + (
double)jsonContent[
"cameras"][idxCam][
"Rotation"][0];
592 paramsCal.GetValue(Rx::LFR::ECalibrationParam::Rotation_Global_Sensor_Roll, data);
593 rot.roll = (float)data + (
double)jsonContent[
"cameras"][idxCam][
"Rotation"][1];
594 paramsCal.GetValue(Rx::LFR::ECalibrationParam::Rotation_Global_Sensor_Yaw, data);
595 rot.yaw = (float)data + (
double)jsonContent[
"cameras"][idxCam][
"Rotation"][2];
601 referencePlaneToCameraPlane[idxCam] = 1.0f;
610 extrinsics.position = pos;
611 extrinsics.rotation = rot;
617 return camBuffers[idxCam];
623void RaytrixStreamer::getRGBDFormats() {
624 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
626 imgFormatRGB[i] = xCudaComputes[i].GetImageFormat(idRGB);
628 catch (Rx::CRxException e) {
629 std::cerr <<
"Impossible to get image format... Check error code: " << e.ToString().ToCString() << std::endl;
630 throw HVT_ERROR_UNKNOWN;
632 if (imgFormatRGB[i].m_iWidth != infoJSON.width || imgFormatRGB[i].m_iHeight != infoJSON.height) {
633 std::cerr <<
"RGB image formats do not correspond..." << std::endl;
634 throw HVT_ERROR_UNKNOWN;
637 imgFormatDepth[i] = xCudaComputes[i].GetImageFormat(idDepth);
639 catch (Rx::CRxException e) {
640 std::cerr <<
"Impossible to get image format... Check error code: " << e.ToString().ToCString() << std::endl;
641 throw HVT_ERROR_UNKNOWN;
643 if (imgFormatDepth[i].m_iWidth != infoJSON.widthDepth || imgFormatDepth[i].m_iHeight != infoJSON.heightDepth) {
644 std::cerr <<
"Depth image formats do not correspond..." << std::endl;
645 throw HVT_ERROR_UNKNOWN;
648 pitchInCudaRGB[i] = cuImgs[i].GetPitch();
649 pitchInCudaDepth[i] = cuDepths[i].GetPitch();
651 std::cout <<
"RGB cam/file " << i <<
" :" << imgFormatRGB[i].ToString().ToCString() << std::endl;
652 std::cout <<
"Depth cam/file " << i <<
" :" << imgFormatDepth[i].ToString().ToCString() << std::endl;
654 isFormatLoaded =
true;
657void RaytrixStreamer::launchAsyncLoader(
bool needToWaitThreadToFinish) {
659 if (infoJSON.loadFromRawFile) {
660 t = std::thread(&RaytrixStreamer::asyncLoaderImageFromSeqFiles,
this);
663 t = std::thread(&RaytrixStreamer::asyncLoaderImage,
this);
665 if (needToWaitThreadToFinish) t.join();
669void RaytrixStreamer::asyncLoaderImageFromOneSeqFile(
size_t idxCam) {
672 if (seqReaders[idxCam].GetFrameCount() == seqReaders[idxCam].GetLastFrameIndex() + 1) {
673 seqReaders[idxCam].SetNextFrameIndex(0);
675 seqReaders[idxCam].ReadFrame(rayImages[idxCam],
false);
677 xCudaComputes[idxCam].UploadRawImage(rayImages[idxCam]);
679 catch (Rx::CRxException e) {
680 std::cerr <<
"Impossible to read or upload ray image to the cuda compute ... Check error code: " << e.ToString().ToCString() << std::endl;
681 throw HVT_ERROR_UNKNOWN;
685void RaytrixStreamer::asyncLoaderImageFromSeqFiles() {
686 bool* tmpSync = &imgsLoaded;
687 std::unique_lock<std::mutex> lckSync(syncMtx);
688 syncCV.wait(lckSync, [tmpSync] {
return !(*tmpSync); });
689 std::thread* threads =
new std::thread[infoJSON.numCams];
690 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
691 threads[i] = std::thread(&RaytrixStreamer::asyncLoaderImageFromOneSeqFile,
this, i);
693 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
703void RaytrixStreamer::asyncLoaderImage() {
704 size_t idxRefCam = 0;
705 bool loadImgSuccess =
false;
707 bool* tmpSync = &imgsLoaded;
708 std::unique_lock<std::mutex> lckSync(syncMtx);
709 syncCV.wait(lckSync, [tmpSync] {
return !(*tmpSync); });
710 while (!loadImgSuccess) {
711 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
712 std::thread(&RaytrixStreamer::asyncLoaderImageOneCam,
this, i).detach();
714 if (infoJSON.numCams == 1) {
715 bool* tmp = canLoadImgs;
716 std::unique_lock<std::mutex> lck(loaderMtxs[0]);
717 loaderCVs[0].wait(lck, [tmp] {
return !(*tmp); });
718 canLoadImgs[0] =
true;
720 loaderCVs[0].notify_all();
724 bool* tmpLoaderRefCam = canLoadImgs + idxRefCam;
725 std::unique_lock<std::mutex> lckLoaderRefCam(loaderMtxs[idxRefCam]);
726 loaderCVs[idxRefCam].wait(lckLoaderRefCam, [tmpLoaderRefCam] {
return !(*tmpLoaderRefCam); });
727 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
728 if (i == idxRefCam)
continue;
730 bool* tmp = canLoadImgs + i;
731 std::unique_lock<std::mutex> lckLoader(loaderMtxs[i]);
732 loaderCVs[i].wait(lckLoader, [tmp] {
return !(*tmp); });
734 loadImgSuccess = (abs(capturedImages[i].GetTimestamp() - capturedImages[idxRefCam].GetTimestamp()) < MAX_TIME_BETWEEN_CAMS);
736 canLoadImgs[i] =
true;
738 loaderCVs[i].notify_all();
740 canLoadImgs[idxRefCam] =
true;
741 lckLoaderRefCam.unlock();
742 loaderCVs[idxRefCam].notify_all();
745 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
746 xCudaComputes[i].UploadRawImage(capturedImages[i]);
749 catch (Rx::CRxException e) {
750 std::cerr <<
"Impossible to upload raw image to the cuda compute ... Check error code: " << e.ToString().ToCString() << std::endl;
751 throw HVT_ERROR_UNKNOWN;
758void RaytrixStreamer::asyncLoaderImageOneCam(
size_t idxCam) {
759 bool* tmp = canLoadImgs + idxCam;
760 std::unique_lock<std::mutex> lck(loaderMtxs[idxCam]);
761 loaderCVs[idxCam].wait(lck, [tmp] {
return *tmp; });
763 bool imgLoadSucess =
false;
764 while (!imgLoadSucess) {
765 if(camCaptureMode == Rx::ECamTriggerMode::Software_SnapShot){
767 auto& cam = xCamServer.GetCamera(idxCam);
771 if (!camBuffers[idxCam].WaitForNotEmpty(MAX_TIME_WAIT_BUFFER))
continue;
774 imgLoadSucess = camBuffers[idxCam].MoveOut(capturedImages[idxCam]);
776 canLoadImgs[idxCam] =
false;
778 loaderCVs[idxCam].notify_all();
781void RaytrixStreamer::acquireRGBD() {
783 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
784 if (!xCudaComputes[i].Compute_TotalFocus(idSpaceRGB)) {
785 std::cerr <<
"Impossible to compute total focus image and depth ... Camera: " << i << std::endl;
786 throw HVT_ERROR_UNKNOWN;
788 if (!xCudaComputes[i].Compute_Depth3D(idSpaceDepth3D[0], idSpaceDepth3D[1])) {
789 std::cerr <<
"Impossible to compute depth ... Camera: " << i << std::endl;
790 throw HVT_ERROR_UNKNOWN;
794 catch (Rx::CRxException e) {
795 std::cerr <<
"Impossible to read or compute... Check error code: " << e.ToString().ToCString() << std::endl;
796 throw HVT_ERROR_UNKNOWN;
798 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
799 cuImgs[i] = xCudaComputes[i].GetCudaImage(idRGB);
800 cuDepths[i] = xCudaComputes[i].GetCudaImage(idDepth);
802 if (!isFormatLoaded) {
805 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
806 switch (imgFormatRGB[i].m_eDataType) {
807 case Rx::EDataType::UByte:
808 imgUByteRGB[i] = (uchar*)cuImgs[i].GetData();
810 case Rx::EDataType::UShort:
811 imgRGB[i] = (
unsigned short*)cuImgs[i].GetData();
814 std::cerr <<
"Not known RGBA format... Check format: " << imgFormatRGB[i].ToString().ToCString() << std::endl;
815 throw HVT_ERROR_UNKNOWN;
818 switch (imgFormatDepth[i].m_eDataType) {
819 case Rx::EDataType::UShort:
820 imgDepth[i] = (
unsigned short*)cuDepths[i].GetData();
822 case Rx::EDataType::Float:
823 imgFloatDepth[i] = (
float*)cuDepths[i].GetData();
826 std::cerr <<
"Not known depth format... Check format: " << imgFormatDepth[i].ToString().ToCString() << std::endl;
827 throw HVT_ERROR_UNKNOWN;
832void RaytrixStreamer::refineRGBD() {
833 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
834 switch (imgFormatRGB[i].m_eDataType) {
835 case Rx::EDataType::UByte:
836 if (pitchInCudaRGB[i] !=
sizeof(uchar) * 4 * infoJSON.width) {
837 removePitch<uchar>(imgUByteRGB[i], finalRGB[i], infoJSON.width, infoJSON.height, pitchInCudaRGB[i] / (
sizeof(uchar) * 4), 4, cudaStreams[i]);
840 gpuErrchk(cudaMemcpyAsync(finalRGB[i], imgUByteRGB[i],
sizeof(uchar) * 4 * infoJSON.width * infoJSON.height, cudaMemcpyDeviceToDevice, cudaStreams[i]));
843 case Rx::EDataType::UShort:
844 uShort2uChar(imgRGB[i], finalRGB[i], infoJSON.width, infoJSON.height, pitchInCudaRGB[i] / (
sizeof(USHORT) * 4), 4, cudaStreams[i]);
847 std::cerr <<
"Not known RGBA format... Check format: " << imgFormatRGB[i].ToString().ToCString() << std::endl;
848 throw HVT_ERROR_UNKNOWN;
851 switch (imgFormatDepth[i].m_eDataType) {
852 case Rx::EDataType::UShort:
854 case Rx::EDataType::Float:
855 scaleAddDataArrayUChannel<float>(imgFloatDepth[i], finalDepth[i], infoJSON.widthDepth, infoJSON.heightDepth, pitchInCudaDepth[i] / (
sizeof(
float) * 4), 4, channelDepth, -1 / 1000.0f, -referencePlaneToCameraPlane[i], cudaStreams[i]);
858 std::cerr <<
"Not known depth format... Check format: " << imgFormatDepth[i].ToString().ToCString() << std::endl;
859 throw HVT_ERROR_UNKNOWN;
861 temporalConsistencyAdjustement<float>(prevFinalDepth[i], finalDepth[i], infoJSON.widthDepth, infoJSON.heightDepth, 5, 0.05, 0.5, cudaStreams[i]);
869void RaytrixStreamer::uploadFrame(
size_t streamId, ReadStream& stream)
871 auto imageIndex = slotStreamingIndex;
873 auto& dstColorSlot = stream.colorSlots.at(imageIndex);
874 auto& dstDepthSlot = stream.depthSlots.at(imageIndex);
877 copyColor(dstColorSlot.cuda_ptr_surf, finalRGB[streamId], stream.width_color, stream.height_color, cudaStreams[streamId]);
878 copyDepth(dstDepthSlot.cuda_ptr_surf, finalDepth[streamId], stream.width_depth, stream.height_depth, cudaStreams[streamId]);
879 gpuErrchk(cudaEventRecord(cudaEvents[streamId], cudaStreams[streamId]));
882void RaytrixStreamer::streamingLoop() {
883 gpuErrchk(cudaSetDevice(vulkanGPU));
884 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
885 if (!infoJSON.loadFromRawFile) {
887 std::cout <<
"Start camera " << i << std::endl;
888 xCamServer.GetCamera(i).Start(camCaptureMode);
892 beginAvgStreaming = std::chrono::steady_clock::now();
893 std::chrono::steady_clock::time_point begin;
895 launchAsyncLoader(
true);
897 std::unique_lock<std::mutex> lck(syncMtx, std::defer_lock);
898 bool* cond = &imgsLoaded;
900 begin = std::chrono::steady_clock::now();
903 syncCV.wait(lck, [cond] {
return *cond; });
915 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
916 uploadFrame(i, readStreams[i]);
918 readStreams[i].streamedFrame = readStreams[i].frameIndex(begin - beginAvgStreaming);
921 swapStreamingToPending();
924 endStreaming = std::chrono::steady_clock::now();
926 if ((
int)numFrames % 100 == 0) {
927 addMsgToPrint(
"Streaming Loop fps", std::chrono::duration_cast<std::chrono::milliseconds>(endStreaming - beginAvgStreaming).count(), numFrames);
932 std::this_thread::yield();
935void RaytrixStreamer::swapStreamingToPending() {
936 std::lock_guard<std::mutex> l(indicesMutex);
937 std::swap(slotPendingIndex, slotStreamingIndex);
938 newDataInPending =
true;
941void RaytrixStreamer::swapPendingToReading() {
942 std::lock_guard<std::mutex> l(indicesMutex);
943 if (newDataInPending)
945 std::swap(slotPendingIndex, slotReadingIndex);
946 newDataInPending =
false;
954template<
typename T>
void RaytrixStreamer::writeInFileWindow(T* dataCorrect, T* dataDebug,
size_t width,
size_t height,
size_t sizeWindow,
int numCam) {
955 if (width / 2 + sizeWindow > width || height / 2 + sizeWindow > height) {
956 std::cerr <<
"Specify a smaller window size..." << std::endl;
957 throw HVT_ERROR_UNKNOWN;
959 if (dataCorrect == NULL || dataDebug == NULL) {
960 std::cerr <<
"Specify allocated array ... " << std::endl;
961 throw HVT_ERROR_UNKNOWN;
964 const char outCorrect[] =
"../RaytrixStreamer/dataCorrect.txt";
965 const char outDebug[] =
"../RaytrixStreamer/dataDebug.txt";
967 fs::path pathCorrect = outCorrect;
968 std::ofstream correctDataStream{ pathCorrect, std::ofstream::out | std::ofstream::trunc };
969 if (!correctDataStream.good()) {
970 std::cerr <<
"Impossible to open data correct file, check path... Path given: " << pathCorrect << std::endl;
971 throw HVT_ERROR_NOT_FOUND;
973 fs::path pathDebug = outDebug;
974 std::ofstream debugDataStream{ pathDebug, std::ofstream::out | std::ofstream::trunc };
975 if (!debugDataStream.good()) {
976 std::cerr <<
"Impossible to open data debug file, check path... Path given: " << pathDebug << std::endl;
977 throw HVT_ERROR_NOT_FOUND;
980 for (
size_t i = 0; i < sizeWindow; ++i) {
981 for (
size_t j = 0; j < sizeWindow; ++j) {
982 correctDataStream << dataCorrect[(width / 2) * ((height / 2) + i) + j] <<
",";
983 debugDataStream << dataDebug[(width / 2) * ((height / 2) + i) + j] <<
",";
985 correctDataStream << std::endl;
986 debugDataStream << std::endl;
989 correctDataStream.close();
990 debugDataStream.close();
993void RaytrixStreamer::debugFloatDepth() {
995 float* imgTmp2 =
new float[infoJSON.widthDepth * infoJSON.heightDepth];
997 gpuErrchk(cudaDeviceSynchronize());
998 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
1000 xCudaComputes[i].Download(Rx::LFR::EImage::DepthMap_View_Virtual, imgTmp);
1001 imgTmp.GetSize(width, height);
1003 catch (Rx::CRxException e) {
1004 std::cerr <<
"Error while debugging depth... Check error code: " << e.ToString().ToCString() << std::endl;
1005 throw HVT_ERROR_UNKNOWN;
1007 std::cout <<
"Downloaded img " << i <<
": Width: " << width <<
" Height: " << height <<
" Nb of bytes: " << imgTmp.GetByteCount() <<
" Format: " << imgTmp.GetFormat().ToString().ToCString() << std::endl;
1008 gpuErrchk(cudaMemcpy(imgTmp2, finalDepth[i], infoJSON.widthDepth * infoJSON.heightDepth *
sizeof(
float), cudaMemcpyDeviceToHost));
1009 std::cout <<
"CUDA img " << i <<
": Width: " << infoJSON.widthDepth <<
" Height : " << infoJSON.heightDepth <<
" Nb of bytes : " << infoJSON.widthDepth * infoJSON.heightDepth *
sizeof(float) <<
" Format: " << imgFormatDepth[i].ToString().ToCString() << std::endl;
1010 gpuErrchk(cudaDeviceSynchronize());
1011 writeInFileWindow<float>((
float*)imgTmp.GetDataPtr(), imgTmp2, infoJSON.widthDepth, infoJSON.heightDepth, 100, i);
1019int RaytrixStreamer::ReadStream::frameIndex(Clock::duration time)
const
1021 return (time / framePeriod);
1024bool RaytrixStreamer::ReadStream::nextFrameReady(Clock::duration time)
const
1026 return streamedFrame != frameIndex(time);
1048 findVulkanGPU(uuid);
1051 if (infoJSON.loadFromRawFile) {
1057 initRxCudaCompute();
1058 initStreamParameters();
1065 std::cout <<
"---- Destroy RaytrixStreamer dll ----" << std::endl;
1066 if (synthesisSem != NULL)
1067 delete synthesisSem;
1068 for (
size_t i = 0; i < infoJSON.numCams; ++i) {
1069 xCamServer.GetCamera(i).Close();
1071 if (infoJSON.loadFromRawFile) {
1072 delete[] seqReaders;
1075 Rx::LFR::CLightFieldRuntime::End();
1079void RaytrixStreamer::enumerateStreamsParameters(uint32_t* streamsCount,
HvtRGBDStreamParameters* parameters)
const
1081 cudaSetDevice(vulkanGPU);
1084 *streamsCount = readStreams.size();
1088 if (*streamsCount != readStreams.size())
1090 throw HvtResult::HVT_ERROR_WRONG_BUFFER_SIZE;
1094 for (
const auto& readStream : readStreams)
1097 SP->
colorResolution = { (uint32_t)readStream.width_color, (uint32_t)readStream.height_color };
1098 SP->
depthResolution = { (uint32_t)readStream.width_depth, (uint32_t)readStream.height_depth };
1101 SP->
colorFormat = (HvtImageFormat)readStream.colorFormat;
1102 SP->
depthFormat = (HvtImageFormat)readStream.depthFormat;
1106 parameters[i] = *SP;
1114 cudaSetDevice(vulkanGPU);
1115 auto isDepth = (bool)exportInfos.
depth;
1116 auto& stream = readStreams.at(exportInfos.
streamIndex);
1119 auto& slots = isDepth ? stream.depthSlots : stream.colorSlots;
1126 throw HvtResult::HVT_ERROR_WRONG_BUFFER_SIZE;
1129 for (
int i = 0; i < numSlots; ++i)
1131 auto mem = exportInfos.
pImages[i];
1134 cudaExternalMemory_t cudaExtMemImageBuffer;
1135 cudaMipmappedArray_t cudaMipmappedImageArray;
1137 cudaExternalMemoryHandleDesc cudaExtMemHandleDesc;
1138 memset(&cudaExtMemHandleDesc, 0,
sizeof(cudaExtMemHandleDesc));
1140 cudaExtMemHandleDesc.type = cudaExternalMemoryHandleTypeOpaqueWin32;
1141 cudaExtMemHandleDesc.handle.win32.handle = (HANDLE)mem.handle;
1142 cudaExtMemHandleDesc.size = mem.size;
1144 gpuErrchk(cudaImportExternalMemory(&cudaExtMemImageBuffer, &cudaExtMemHandleDesc));
1146 cudaExternalMemoryMipmappedArrayDesc externalMemoryMipmappedArrayDesc;
1147 memset(&externalMemoryMipmappedArrayDesc, 0,
sizeof(externalMemoryMipmappedArrayDesc));
1149 cudaExtent extent = isDepth ? make_cudaExtent(stream.width_depth, stream.height_depth, 0) : make_cudaExtent(stream.width_color, stream.height_color, 0);
1150 cudaChannelFormatDesc formatDesc;
1151 formatDesc.x = isDepth ? 32 : 8;
1152 formatDesc.y = isDepth ? 0 : 8;
1153 formatDesc.z = isDepth ? 0 : 8;
1154 formatDesc.w = isDepth ? 0 : 8;
1155 formatDesc.f = isDepth ? cudaChannelFormatKindFloat : cudaChannelFormatKindUnsigned;
1157 externalMemoryMipmappedArrayDesc.offset = 0;
1158 externalMemoryMipmappedArrayDesc.formatDesc = formatDesc;
1159 externalMemoryMipmappedArrayDesc.extent = extent;
1160 externalMemoryMipmappedArrayDesc.flags = 0;
1161 externalMemoryMipmappedArrayDesc.numLevels = mipLevels;
1163 gpuErrchk(cudaExternalMemoryGetMappedMipmappedArray(&cudaMipmappedImageArray, cudaExtMemImageBuffer, &externalMemoryMipmappedArrayDesc));
1165 cudaArray_t cudaMipLevelArray;
1166 cudaResourceDesc resourceDesc;
1168 gpuErrchk(cudaGetMipmappedArrayLevel(&cudaMipLevelArray, cudaMipmappedImageArray, 0));
1171 memset(&resourceDesc, 0,
sizeof(resourceDesc));
1172 resourceDesc.resType = cudaResourceTypeArray;
1173 resourceDesc.res.array.array = cudaMipLevelArray;
1175 cudaSurfaceObject_t surfaceObject;
1176 gpuErrchk(cudaCreateSurfaceObject(&surfaceObject, &resourceDesc));
1180 IS.vk_handle = &mem.handle;
1181 IS.cuda_ptr_surf = surfaceObject;
1185 (isDepth ? stream.importedDepth : stream.importedColor) =
true;
1190 cudaSetDevice(vulkanGPU);
1191 if (exportInfos.semaphore == NULL)
1193 synthesisSem->isValid =
false;
1194 synthesisSem->sem = NULL;
1198 cudaExternalSemaphoreHandleDesc externalSemaphoreHandleDesc = {};
1200 if (exportInfos.type & HvtSemaphoreType::HVT_SEMAPHORE_TYPE_OPAQUE_WIN32_BIT)
1202 externalSemaphoreHandleDesc.type = cudaExternalSemaphoreHandleTypeOpaqueWin32;
1204 else if (exportInfos.type & HvtSemaphoreType::HVT_SEMAPHORE_TYPE_OPAQUE_WIN32_KMT_BIT)
1206 externalSemaphoreHandleDesc.type = cudaExternalSemaphoreHandleTypeOpaqueWin32Kmt;
1208 else if (exportInfos.type & HvtSemaphoreType::HVT_SEMAPHORE_TYPE_SYNC_FD_BIT)
1210 externalSemaphoreHandleDesc.type = cudaExternalSemaphoreHandleTypeOpaqueFd;
1213 externalSemaphoreHandleDesc.handle.win32.handle = (HANDLE)exportInfos.semaphore;
1214 externalSemaphoreHandleDesc.flags = 0;
1216 cudaImportExternalSemaphore(&synthesisSem->sem, &externalSemaphoreHandleDesc);
1217 synthesisSem->isValid =
true;
1221void RaytrixStreamer::destroySemaphore(
Semaphore* sem)
const
1223 cudaSetDevice(vulkanGPU);
1227void RaytrixStreamer::startStreaming()
1231 for (
auto& stream : readStreams)
1233 if (!stream.importedColor || !stream.importedDepth)
1235 throw HvtResult::HVT_ERROR_CALL_ORDER;
1241 std::cout <<
"Starting streaming" << std::endl;
1242 streamingThread = std::thread([&]
1243 { streamingLoop(); });
1248 cudaSetDevice(vulkanGPU);
1251 throw HvtResult::HVT_ERROR_WRONG_BUFFER_SIZE;
1254 swapPendingToReading();
1256 auto imageIndex = slotReadingIndex;
1260 gpuErrchk(cudaEventSynchronize(cudaEvents[i]));
1262 auto& stream = readStreams.at(i);
1265 desc.intrinsics = stream.intrinsics;
1266 desc.imageIndex = imageIndex;
1270void RaytrixStreamer::releaseStreamsFrames(
Semaphore* waitSem)
1272 std::cout <<
"release frames" << std::endl;
1275void RaytrixStreamer::stopStreaming()
1277 cudaSetDevice(vulkanGPU);
1279 if (streamingThread.joinable())
1281 streamingThread.join();
1289template <
typename Closure>
1290HvtResult exceptionFirewall(Closure&& clos)
1296 catch (HvtResult res)
1300 catch (
const std::exception& e)
1302 std::cerr <<
"Catched exception at C boundary : \"" << e.what() <<
"\"" << std::endl;
1303 return HvtResult::HVT_ERROR_UNKNOWN;
1307 return HvtResult::HVT_ERROR_UNKNOWN;
1309 return HvtResult::HVT_SUCESS;
1312template <
typename T>
1313void checkNonNull(T ptr)
1317 throw HvtResult::HVT_ERROR_INVALID_HANDLE;
1332 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtCreateStreamingContext(
const HvtStreamingContextCreateInfo* createInfo, HvtStreamingContext* outStreamingContext)
1335 return exceptionFirewall([&]
1337 checkNonNull(createInfo);
1340 throw HvtResult::HVT_ERROR_HEADER_VERSION;
1344 *outStreamingContext = context->to_handle(); });
1354 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtEnumerateStreamsParameters(HvtStreamingContext streamingContext, uint32_t* pStreamParameterCount,
HvtRGBDStreamParameters* pStreamParameters)
1357 return exceptionFirewall([&]
1359 auto context = RaytrixStreamer::check(streamingContext);
1360 checkNonNull(pStreamParameterCount);
1361 context->enumerateStreamsParameters(pStreamParameterCount, pStreamParameters); });
1370 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtExportStreamImages(HvtStreamingContext streamingContext,
const HvtStreamImagesExportInfo* exportInfos)
1373 return exceptionFirewall([&]
1375 auto context = RaytrixStreamer::check(streamingContext);
1376 checkNonNull(exportInfos);
1377 context->importStreamImages(*exportInfos); });
1387 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtExportSemaphore(HvtStreamingContext streamingContext,
const HvtSemaphoreExportInfo* exportInfo, HvtSemaphore* outSemaphore)
1390 return exceptionFirewall([&]
1392 auto context = RaytrixStreamer::check(streamingContext);
1393 checkNonNull(exportInfo);
1394 context->importSemaphore(*exportInfo); });
1403 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtDestroySemaphore(HvtStreamingContext streamingContext, HvtSemaphore semaphore)
1406 return exceptionFirewall([&]
1408 auto context = RaytrixStreamer::check(streamingContext);
1409 context->destroySemaphore(Semaphore::check(semaphore)); });
1417 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtStartStreaming(HvtStreamingContext streamingContext)
1420 return exceptionFirewall([&]
1422 auto context = RaytrixStreamer::check(streamingContext);
1423 context->startStreaming(); });
1432 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtAcquireStreamsFrames(HvtStreamingContext streamingContext,
const HvtAcquireStreamFramesInfo* infos)
1435 return exceptionFirewall([&]
1437 auto context = RaytrixStreamer::check(streamingContext);
1438 context->acquireStreamsFrames(*infos); });
1450 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtReleaseStreamsFrames(HvtStreamingContext streamingContext, HvtSemaphore waitSemaphore)
1453 return exceptionFirewall([&]
1465 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtStopStreaming(HvtStreamingContext streamingContext)
1468 return exceptionFirewall([&]
1470 auto context = RaytrixStreamer::check(streamingContext);
1471 context->stopStreaming();
1480 HVTAPI_ATTR HvtResult HVTAPI_CALL hvtDestroyStreamingContext(HvtStreamingContext streamingContext)
1483 return exceptionFirewall([&]
1485 auto context = RaytrixStreamer::check(streamingContext);
HvtIntrinsicsPerspective getRxIntrinsicParams(size_t idxCam)
Get the intrinsic parameters of the camera of ID "idxCam". The intrinsic parameters are found through...
~RaytrixStreamer()
Free all the memories that were allocated during the streaming process.
HvtExtrinsics getRxExtrinsicParams(size_t idxCam)
Get the extrinsic parameters of the camera of ID "idxCam". The extrinsic parameters are found through...
float getMinDepth()
Get the minimum depth.
float getMaxDepth()
Get the maximum depth.
Rx::LFR::CImageQueue & getCamBuffer(size_t idxCam)
Get the camera buffer in the list of camera buffers.
RaytrixStreamer(const uint8_t uuid[VK_UUID_SIZE])
Launch all init functions defined in RaytrixStreamer class.
Parameters for query of the current frames infos.
HvtStreamFrameInfo * pStreamFrameInfos
Intrinsics parameters of a perspective projection.
Description of an RGBD stream.
HvtExtent2D depthResolution
HvtImageFormat colorFormat
HvtProjectionType projectionType
HvtImageFormat depthFormat
HvtExtent2D colorResolution
Export info for images of a stream.
HvtStreamImageMemoryInfo * pImages
Parameters for the creation of the Streaming context.
uint8_t graphicsDeviceUUID[VK_UUID_SIZE]
Union of possible intrinsics types data.