cc3dsfs/source/CaptureDeviceSpecific/3DSCapture_FTD3/3dscapture_ftd3_driver_acquisition.cpp
Lorenzooone 8e87c7afd1
Some checks failed
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux32 flags:32 name:Linux GCC 32 os:ubuntu-latest]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux64 flags:64 name:Linux GCC x64 os:ubuntu-latest]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm32 flags:arm32 name:Linux GCC ARM 32 os:ubuntu-latest]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm64 flags:arm64 name:Linux GCC ARM 64 os:ubuntu-latest]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:macos name:macOS Apple Silicon os:macos-14]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win32 flags:-A Win32 name:Windows VS2022 Win32 os:windows-2022]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win64 flags:-A x64 name:Windows VS2022 x64 os:windows-2022]) (push) Has been cancelled
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:winarm64 flags:-A ARM64 name:Windows VS2022 ARM os:windows-2022]) (push) Has been cancelled
CD / Create Pi Mono Setup (push) Has been cancelled
CD / Publishing (push) Has been cancelled
Add Wall to compilation flags
2025-04-08 04:20:02 +02:00

186 lines
7.6 KiB
C++

#include "3dscapture_ftd3_driver_acquisition.hpp"
#include "3dscapture_ftd3_driver_comms.hpp"
#include "3dscapture_ftd3_compatibility.hpp"
#include "3dscapture_ftd3_shared_general.hpp"
#include "devicecapture.hpp"
#include "devicecapture.hpp"
//#include "ftd3xx_symbols_renames.h"
#ifdef _WIN32
#define FTD3XX_STATIC
#define FT_ASYNC_CALL FT_ReadPipeEx
#else
#define FT_ASYNC_CALL FT_ReadPipeAsync
#endif
#include <ftd3xx.h>
#include <chrono>
struct FTD3XXReceivedDataBuffer {
OVERLAPPED overlap;
ULONG read_buffer;
bool is_3d;
};
static bool wait_all_fast_capture_call_async_transfers(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data) {
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
for(int inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS; ++inner_curr_in) {
FT_STATUS ftStatus = FT_GetOverlappedResult(handle, &received_buffer[inner_curr_in].overlap, &received_buffer[inner_curr_in].read_buffer, true);
if(FT_FAILED(ftStatus)) {
capture_error_print(true, capture_data, "Disconnected: USB error");
return false;
}
}
return true;
}
static bool fast_capture_call_init_async_transfers(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel, int &inner_curr_in, bool could_use_3d, bool stored_3d_status) {
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
for(inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS - 1; ++inner_curr_in) {
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(inner_curr_in);
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status;
FT_STATUS ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, (ULONG)ftd3_get_capture_size(received_buffer[inner_curr_in].is_3d), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap);
if(ftStatus != FT_IO_PENDING) {
capture_error_print(true, capture_data, "Disconnected: Read failed");
return false;
}
}
inner_curr_in = FTD3_CONCURRENT_BUFFERS - 1;
return true;
}
static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel) {
int inner_curr_in = 0;
FT_STATUS ftStatus;
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
bool stored_3d_status = true;
bool result_3d_setup = ftd3_capture_3d_setup(capture_data, true, stored_3d_status, true);
if(!result_3d_setup)
return;
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
for (inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS; ++inner_curr_in) {
ftStatus = FT_InitializeOverlapped(handle, &received_buffer[inner_curr_in].overlap);
if(ftStatus) {
capture_error_print(true, capture_data, "Disconnected: Initialize failed");
return;
}
}
if(!fast_capture_call_init_async_transfers(received_buffer, capture_data, fifo_channel, inner_curr_in, could_use_3d, stored_3d_status))
return;
auto clock_start = std::chrono::high_resolution_clock::now();
while (capture_data->status.connected && capture_data->status.running) {
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
if(!wait_all_fast_capture_call_async_transfers(received_buffer, capture_data))
return;
result_3d_setup = ftd3_capture_3d_setup(capture_data, false, stored_3d_status, true);
if(!result_3d_setup)
return;
if(!fast_capture_call_init_async_transfers(received_buffer, capture_data, fifo_channel, inner_curr_in, could_use_3d, stored_3d_status))
return;
clock_start = std::chrono::high_resolution_clock::now();
}
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(inner_curr_in);
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status;
ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, (ULONG)ftd3_get_capture_size(received_buffer[inner_curr_in].is_3d), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap);
if(ftStatus != FT_IO_PENDING) {
capture_error_print(true, capture_data, "Disconnected: Read failed");
return;
}
inner_curr_in = (inner_curr_in + 1) % FTD3_CONCURRENT_BUFFERS;
ftStatus = FT_GetOverlappedResult(handle, &received_buffer[inner_curr_in].overlap, &received_buffer[inner_curr_in].read_buffer, true);
if(FT_FAILED(ftStatus)) {
capture_error_print(true, capture_data, "Disconnected: USB error");
return;
}
data_output_update(inner_curr_in, received_buffer[inner_curr_in].read_buffer, capture_data, clock_start, received_buffer[inner_curr_in].is_3d);
}
}
static bool safe_capture_call(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data, int fifo_channel) {
auto clock_start = std::chrono::high_resolution_clock::now();
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
bool could_use_3d = get_3d_enabled(&capture_data->status, true);
bool stored_3d_status = true;
bool result_3d_setup = ftd3_capture_3d_setup(capture_data, true, stored_3d_status, true);
if(!result_3d_setup)
return true;
while(capture_data->status.connected && capture_data->status.running) {
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
result_3d_setup = ftd3_capture_3d_setup(capture_data, false, stored_3d_status, true);
if(!result_3d_setup)
return true;
}
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(0);
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
received_buffer->is_3d = could_use_3d && stored_3d_status;
#ifdef _WIN32
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, (ULONG)ftd3_get_capture_size(received_buffer->is_3d), &received_buffer->read_buffer, NULL);
#else
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, (ULONG)ftd3_get_capture_size(received_buffer->is_3d), &received_buffer->read_buffer, 1000);
#endif
if(FT_FAILED(ftStatus)) {
capture_error_print(true, capture_data, "Disconnected: Read failed");
return true;
}
data_output_update(0, received_buffer->read_buffer, capture_data, clock_start, received_buffer->is_3d);
}
return false;
}
static FTD3XXReceivedDataBuffer* init_received_buffer() {
if(ftd3_driver_get_is_bad())
return new FTD3XXReceivedDataBuffer;
return new FTD3XXReceivedDataBuffer[FTD3_CONCURRENT_BUFFERS];
}
static void close_received_buffer(FTD3XXReceivedDataBuffer* received_buffer, CaptureData* capture_data) {
if(ftd3_driver_get_is_bad()) {
capture_data->data_buffers.ReleaseWriterBuffer(0, false);
delete received_buffer;
return;
}
void* handle = ((ftd3_device_device_handlers*)capture_data->handle)->driver_handle;
for(int inner_curr_in = 0; inner_curr_in < FTD3_CONCURRENT_BUFFERS; ++inner_curr_in) {
FT_STATUS ftStatus = FT_GetOverlappedResult(handle, &received_buffer[inner_curr_in].overlap, &received_buffer[inner_curr_in].read_buffer, true);
if(FT_ReleaseOverlapped(handle, &received_buffer[inner_curr_in].overlap)) {
capture_error_print(true, capture_data, "Disconnected: Release failed");
}
capture_data->data_buffers.ReleaseWriterBuffer(inner_curr_in, false);
}
delete []received_buffer;
}
void ftd3_driver_capture_main_loop(CaptureData* capture_data, int pipe) {
FTD3XXReceivedDataBuffer* received_buffer = init_received_buffer();
int fifo_channel = pipe;
#ifndef _WIN32
fifo_channel = 0;
#endif
if(!ftd3_driver_get_is_bad())
fast_capture_call(received_buffer, capture_data, fifo_channel);
else
safe_capture_call(received_buffer, capture_data, fifo_channel);
close_received_buffer(received_buffer, capture_data);
}