Add information to the data passed about 3D to account for 2D only games
Some checks are pending
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) Waiting to run
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) Waiting to run
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) Waiting to run
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) Waiting to run
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) Waiting to run
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) Waiting to run
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) Waiting to run
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) Waiting to run
CD / Create Pi Mono Setup (push) Blocked by required conditions
CD / Publishing (push) Blocked by required conditions

This commit is contained in:
Lorenzooone
2025-03-26 00:43:29 +01:00
parent cf5b97e1a3
commit 72110aba94
14 changed files with 94 additions and 60 deletions

View File

@@ -13,5 +13,6 @@ bool connect_ftd3(bool print_failed, CaptureData* capture_data, CaptureDevice* d
void ftd3_capture_main_loop(CaptureData* capture_data);
void ftd3_capture_cleanup(CaptureData* capture_data);
uint64_t ftd3_get_video_in_size(CaptureData* capture_data);
uint64_t ftd3_get_video_in_size(CaptureData* capture_data, bool override_3d);
#endif

View File

@@ -9,7 +9,7 @@ uint64_t ftd3_get_capture_size(bool is_3d_enabled);
uint64_t ftd3_get_capture_size(CaptureData* capture_data);
std::string ftd3_get_serial(std::string serial_string, int &curr_serial_extra_id);
void ftd3_insert_device(std::vector<CaptureDevice> &devices_list, std::string serial_string, int &curr_serial_extra_id, uint32_t usb_speed, bool is_driver);
void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point<std::chrono::high_resolution_clock> &base_time);
void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point<std::chrono::high_resolution_clock> &base_time, bool is_3d);
bool ftd3_capture_3d_setup(CaptureData* capture_data, bool first_pass, bool& stored_3d_status);
#endif

View File

@@ -15,6 +15,7 @@ bool connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* de
void usb_capture_main_loop(CaptureData* capture_data);
void usb_capture_cleanup(CaptureData* capture_data);
uint64_t usb_get_video_in_size(CaptureData* capture_data);
uint64_t usb_get_video_in_size(CaptureData* capture_data, bool override_3d);
void usb_ds_3ds_init();
void usb_ds_3ds_close();

View File

@@ -231,6 +231,7 @@ struct CaptureDataSingleBuffer {
CaptureReceived capture_buf;
double time_in_buf;
uint32_t inner_index;
bool is_3d;
};
class CaptureDataBuffers {
@@ -238,10 +239,10 @@ public:
CaptureDataBuffers();
CaptureDataSingleBuffer* GetReaderBuffer(CaptureReaderType reader_type);
void ReleaseReaderBuffer(CaptureReaderType reader_type);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index, bool is_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index, bool is_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index, bool is_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d = false);
CaptureDataSingleBuffer* GetWriterBuffer(int index = 0);
void ReleaseWriterBuffer(int index = 0, bool update_last_curr_in = true);
private:

View File

@@ -4,6 +4,6 @@
#include "capture_structs.hpp"
#include "display_structs.hpp"
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d);
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status);
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d, bool is_data_3d);
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d);
#endif

View File

@@ -21,8 +21,8 @@ bool connect(bool print_failed, CaptureData* capture_data, FrontendData* fronten
void captureCall(CaptureData* capture_data);
void capture_error_print(bool print_failed, CaptureData* capture_data, std::string error_string);
void capture_error_print(bool print_failed, CaptureData* capture_data, std::string graphical_string, std::string detailed_string);
uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read);
uint64_t get_video_in_size(CaptureData* capture_data);
uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read, bool is_3d);
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d);
std::string get_name_of_device(CaptureStatus* capture_status, bool use_long = false);
int get_usb_speed_of_device(CaptureStatus* capture_status);
bool get_device_can_do_3d(CaptureStatus* capture_status);

View File

@@ -95,7 +95,7 @@ void CaptureDataBuffers::ReleaseWriterBuffer(int index, bool update_last_curr_in
access_mutex.unlock();
}
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index) {
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, size_t offset, int index, bool is_3d) {
if(offset >= read)
return;
if(!is_writer_index_valid(index))
@@ -116,17 +116,18 @@ void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, d
target->read = read - offset;
target->time_in_buf = time_in_buf;
target->capture_type = capture_type;
target->is_3d = is_3d;
this->ReleaseWriterBuffer(index);
}
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, capture_type, 0, index);
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index, bool is_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, capture_type, 0, index, is_3d);
}
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, offset, index);
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index, bool is_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, offset, index, is_3d);
}
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, 0, index);
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, 0, index, is_3d);
}

View File

@@ -19,6 +19,7 @@
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) {
@@ -38,7 +39,8 @@ static bool fast_capture_call_init_async_transfers(FTD3XXReceivedDataBuffer* rec
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;
FT_STATUS ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap);
received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status;
FT_STATUS ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, 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;
@@ -90,7 +92,8 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(inner_curr_in);
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer[inner_curr_in].read_buffer, &received_buffer[inner_curr_in].overlap);
received_buffer[inner_curr_in].is_3d = could_use_3d && stored_3d_status;
ftStatus = FT_ASYNC_CALL(handle, fifo_channel, buffer, 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;
@@ -104,7 +107,7 @@ static void fast_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture
return;
}
data_output_update(inner_curr_in, received_buffer[inner_curr_in].read_buffer, capture_data, clock_start);
data_output_update(inner_curr_in, received_buffer[inner_curr_in].read_buffer, capture_data, clock_start, received_buffer[inner_curr_in].is_3d);
}
}
@@ -126,17 +129,18 @@ static bool safe_capture_call(FTD3XXReceivedDataBuffer* received_buffer, Capture
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, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, NULL);
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(received_buffer->is_3d), &received_buffer->read_buffer, NULL);
#else
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, ftd3_get_capture_size(could_use_3d && stored_3d_status), &received_buffer->read_buffer, 1000);
FT_STATUS ftStatus = FT_ReadPipeEx(handle, fifo_channel, buffer, 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);
data_output_update(0, received_buffer->read_buffer, capture_data, clock_start, received_buffer->is_3d);
}
return false;

View File

@@ -27,6 +27,7 @@ struct FTD3LibusbCaptureReceivedData {
int internal_index;
CaptureData* capture_data;
uint32_t* last_index;
bool is_3d;
std::chrono::time_point<std::chrono::high_resolution_clock> *clock_start;
SharedConsumerMutex *is_buffer_free_shared_mutex;
int* status;
@@ -72,7 +73,7 @@ static void reset_ftd3_libusb_status(FTD3LibusbCaptureReceivedData* ftd3_libusb_
error_ftd3_libusb_status(ftd3_libusb_capture_recv_data, 0);
}
static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, uint32_t index, int pipe) {
static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, uint32_t index, int pipe, bool is_3d) {
if(ftd3_libusb_capture_recv_data == NULL)
return;
if((*ftd3_libusb_capture_recv_data->status) < 0)
@@ -81,7 +82,8 @@ static void ftd3_libusb_read_frame_request(CaptureData* capture_data, FTD3Libusb
ftd3_libusb_capture_recv_data->cb_data.function = ftd3_libusb_read_frame_cb;
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(ftd3_libusb_capture_recv_data->internal_index);
uint8_t* buffer = (uint8_t*)&data_buf->capture_buf;
ftd3_libusb_async_in_start((ftd3_device_device_handlers*)capture_data->handle, pipe, MAX_TIME_WAIT * 1000, buffer, ftd3_get_capture_size(capture_data), &ftd3_libusb_capture_recv_data->cb_data);
ftd3_libusb_capture_recv_data->is_3d = is_3d;
ftd3_libusb_async_in_start((ftd3_device_device_handlers*)capture_data->handle, pipe, MAX_TIME_WAIT * 1000, buffer, ftd3_get_capture_size(is_3d), &ftd3_libusb_capture_recv_data->cb_data);
}
static void end_ftd3_libusb_read_frame_cb(FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data, bool early_release) {
@@ -109,7 +111,7 @@ static void ftd3_libusb_read_frame_cb(void* user_data, int transfer_length, int
if(*ftd3_libusb_capture_recv_data->pause_output)
return end_ftd3_libusb_read_frame_cb(ftd3_libusb_capture_recv_data, true);
data_output_update(ftd3_libusb_capture_recv_data->internal_index, transfer_length, ftd3_libusb_capture_recv_data->capture_data, *ftd3_libusb_capture_recv_data->clock_start);
data_output_update(ftd3_libusb_capture_recv_data->internal_index, transfer_length, ftd3_libusb_capture_recv_data->capture_data, *ftd3_libusb_capture_recv_data->clock_start, ftd3_libusb_capture_recv_data->is_3d);
end_ftd3_libusb_read_frame_cb(ftd3_libusb_capture_recv_data, false);
}
@@ -204,7 +206,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa
return;
for(int i = 0; i < FTD3_CONCURRENT_BUFFERS; i++)
ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe);
ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe, could_use_3d && stored_3d_status);
while(capture_data->status.connected && capture_data->status.running) {
if(could_use_3d && (stored_3d_status != capture_data->status.requested_3d)) {
@@ -221,7 +223,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa
*ftd3_libusb_capture_recv_data->pause_output = false;
for(int i = 0; i < FTD3_CONCURRENT_BUFFERS; i++)
ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe);
ftd3_libusb_read_frame_request(capture_data, ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data), index++, pipe, could_use_3d && stored_3d_status);
*ftd3_libusb_capture_recv_data[0].clock_start = std::chrono::high_resolution_clock::now();
}
@@ -230,7 +232,7 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa
return;
}
FTD3LibusbCaptureReceivedData* free_buffer = ftd3_libusb_get_free_buffer(ftd3_libusb_capture_recv_data);
ftd3_libusb_read_frame_request(capture_data, free_buffer, index++, pipe);
ftd3_libusb_read_frame_request(capture_data, free_buffer, index++, pipe, could_use_3d && stored_3d_status);
}
}

View File

@@ -35,23 +35,18 @@ void list_devices_ftd3(std::vector<CaptureDevice> &devices_list, std::vector<no_
ftd3_list_devices_compat(devices_list, no_access_list, valid_3dscapture_descriptions);
}
void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point<std::chrono::high_resolution_clock> &base_time) {
const auto curr_time = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> diff = curr_time - base_time;
base_time = curr_time;
capture_data->data_buffers.WriteToBuffer(NULL, read_data, diff.count(), &capture_data->status.device, inner_index);
if(capture_data->status.cooldown_curr_in)
capture_data->status.cooldown_curr_in = capture_data->status.cooldown_curr_in - 1;
// Signal that there is data available
capture_data->status.video_wait.unlock();
capture_data->status.audio_wait.unlock();
static uint64_t ftd3_get_video_in_size(bool is_3d_enabled) {
if(!is_3d_enabled)
return sizeof(RGB83DSVideoInputData);
return sizeof(RGB83DSVideoInputData_3D);
}
uint64_t ftd3_get_video_in_size(CaptureData* capture_data) {
if(!get_3d_enabled(&capture_data->status))
return sizeof(RGB83DSVideoInputData);
return sizeof(RGB83DSVideoInputData_3D);
return ftd3_get_video_in_size(get_3d_enabled(&capture_data->status));
}
uint64_t ftd3_get_video_in_size(CaptureData* capture_data, bool override_3d) {
return ftd3_get_video_in_size(override_3d);
}
uint64_t ftd3_get_capture_size(bool is_3d_enabled) {
@@ -64,6 +59,21 @@ uint64_t ftd3_get_capture_size(CaptureData* capture_data) {
return ftd3_get_capture_size(get_3d_enabled(&capture_data->status));
}
void data_output_update(int inner_index, size_t read_data, CaptureData* capture_data, std::chrono::time_point<std::chrono::high_resolution_clock> &base_time, bool is_3d) {
if(is_3d && (read_data < ftd3_get_video_in_size(is_3d)) && (read_data >= ftd3_get_video_in_size(false)))
is_3d = false;
const auto curr_time = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> diff = curr_time - base_time;
base_time = curr_time;
capture_data->data_buffers.WriteToBuffer(NULL, read_data, diff.count(), &capture_data->status.device, inner_index, is_3d);
if(capture_data->status.cooldown_curr_in)
capture_data->status.cooldown_curr_in = capture_data->status.cooldown_curr_in - 1;
// Signal that there is data available
capture_data->status.video_wait.unlock();
capture_data->status.audio_wait.unlock();
}
static void preemptive_close_connection(CaptureData* capture_data) {
ftd3_device_device_handlers* handlers = (ftd3_device_device_handlers*)capture_data->handle;
ftd3_abort_pipe_compat(handlers, BULK_IN);

View File

@@ -395,6 +395,10 @@ uint64_t usb_get_video_in_size(CaptureData* capture_data) {
return _usb_get_video_in_size(get_usb_device_desc(capture_data), get_3d_enabled(&capture_data->status));
}
uint64_t usb_get_video_in_size(CaptureData* capture_data, bool override_3d) {
return _usb_get_video_in_size(get_usb_device_desc(capture_data), override_3d);
}
void usb_capture_main_loop(CaptureData* capture_data) {
if(!usb_is_initialized())
return;

View File

@@ -419,10 +419,10 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
CaptureDataSingleBuffer* data_buffer = capture_data->data_buffers.GetReaderBuffer(CAPTURE_READER_AUDIO);
if(data_buffer != NULL) {
loaded_samples = audio.samples.size();
if((data_buffer->read > get_video_in_size(capture_data)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer->read);
if((data_buffer->read > get_video_in_size(capture_data, data_buffer->is_3d)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer->read, data_buffer->is_3d);
double out_time = data_buffer->time_in_buf;
bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, endianness, data_buffer, &capture_data->status);
bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, endianness, data_buffer, &capture_data->status, data_buffer->is_3d);
if(!conversion_success)
audio_data->signal_conversion_error();
audio.samples.emplace(out_buf[audio_buf_counter], n_samples, out_time);
@@ -602,11 +602,11 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data,
CaptureDataSingleBuffer* data_buffer = capture_data->data_buffers.GetReaderBuffer(CAPTURE_READER_VIDEO);
if(data_buffer != NULL) {
last_frame_time = data_buffer->time_in_buf;
if(data_buffer->read >= get_video_in_size(capture_data)) {
if(data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d)) {
if(capture_data->status.cooldown_curr_in || (!capture_data->status.connected))
blank_out = true;
else {
bool conversion_success = convertVideoToOutput(out_buf, endianness, data_buffer, &capture_data->status, frontend_data.display_data.interleaved_3d);
bool conversion_success = convertVideoToOutput(out_buf, endianness, data_buffer, &capture_data->status, frontend_data.display_data.interleaved_3d, data_buffer->is_3d);
if(!conversion_success)
UpdateOutText(out_text_data, "", "Video conversion failed...", TEXT_KIND_NORMAL);
}

View File

@@ -59,7 +59,7 @@ static inline void convertVideoToOutputChunk_3D(RGB83DSVideoInputData_3D *p_in,
memcpy(&p_out->screen_data[start_out], &p_in->screen_data[start_in], iters * 3);
}
static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, bool interleaved_3d) {
static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, bool interleaved_3d, bool requested_3d) {
if(!enabled_3d) {
convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_NO_BOTTOM_SIZE_3DS, 0, BOT_SIZE_3DS);
@@ -67,6 +67,15 @@ static void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_
convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_WIDTH_3DS, (((i * 2) + 0) * IN_VIDEO_WIDTH_3DS) + IN_VIDEO_NO_BOTTOM_SIZE_3DS, i * IN_VIDEO_WIDTH_3DS);
convertVideoToOutputChunk(&p_in->ftd3_received.video_in, p_out, IN_VIDEO_WIDTH_3DS, (((i * 2) + 1) * IN_VIDEO_WIDTH_3DS) + IN_VIDEO_NO_BOTTOM_SIZE_3DS, BOT_SIZE_3DS + IN_VIDEO_NO_BOTTOM_SIZE_3DS + (i * IN_VIDEO_WIDTH_3DS));
}
if(requested_3d && interleaved_3d) {
for(int i = TOP_WIDTH_3DS - 1; i >= 0; i--) {
memcpy(&p_out->screen_data[BOT_SIZE_3DS + (((2 * i) + 1) * HEIGHT_3DS)], &p_out->screen_data[BOT_SIZE_3DS + (i * HEIGHT_3DS)], HEIGHT_3DS * 3);
memcpy(&p_out->screen_data[BOT_SIZE_3DS + ((2 * i) * HEIGHT_3DS)], &p_out->screen_data[BOT_SIZE_3DS + (i * HEIGHT_3DS)], HEIGHT_3DS * 3);
}
}
else if(requested_3d) {
memcpy(&p_out->screen_data[BOT_SIZE_3DS + TOP_SIZE_3DS], &p_out->screen_data[BOT_SIZE_3DS], TOP_SIZE_3DS * 3);
}
}
else {
size_t last_line_index = ((IN_VIDEO_SIZE_3DS_3D - IN_VIDEO_NO_BOTTOM_SIZE_3DS_3D) / (IN_VIDEO_WIDTH_3DS_3D * 3)) - 1;
@@ -206,7 +215,7 @@ static void usb_3DSconvertVideoToOutput(USB3DSCaptureReceived *p_in, VideoOutput
memcpy(p_out->screen_data, p_in->video_in.screen_data, IN_VIDEO_HEIGHT_3DS * IN_VIDEO_WIDTH_3DS * 3);
}
static void usb_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, CaptureDevice* capture_device, bool enabled_3d, const bool is_big_endian, bool interleaved_3d) {
static void usb_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, CaptureDevice* capture_device, bool enabled_3d, const bool is_big_endian, bool interleaved_3d, bool requested_3d) {
if(capture_device->is_3ds) {
if(!enabled_3d)
usb_3DSconvertVideoToOutput(&p_in->usb_received_3ds, p_out);
@@ -288,13 +297,14 @@ static void usb_is_device_convertVideoToOutput(CaptureReceived *p_in, VideoOutpu
}
}
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d) {
bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool interleaved_3d, bool is_data_3d) {
CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset);
bool converted = false;
CaptureDevice* chosen_device = &status->device;
bool is_3d_requested = get_3d_enabled(status);
#ifdef USE_FTD3
if(chosen_device->cc_type == CAPTURE_CONN_FTD3) {
ftd3_convertVideoToOutput(p_in, p_out, get_3d_enabled(status), interleaved_3d);
ftd3_convertVideoToOutput(p_in, p_out, is_data_3d, interleaved_3d, is_3d_requested);
converted = true;
}
#endif
@@ -306,7 +316,7 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt
#endif
#ifdef USE_DS_3DS_USB
if(chosen_device->cc_type == CAPTURE_CONN_USB) {
usb_convertVideoToOutput(p_in, p_out, chosen_device, get_3d_enabled(status), is_big_endian, interleaved_3d);
usb_convertVideoToOutput(p_in, p_out, chosen_device, is_data_3d, is_big_endian, interleaved_3d, is_3d_requested);
converted = true;
}
#endif
@@ -325,14 +335,14 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt
return converted;
}
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status) {
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status, bool is_data_3d) {
if(!status->device.has_audio)
return true;
CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset);
uint8_t* base_ptr = NULL;
#ifdef USE_FTD3
if(status->device.cc_type == CAPTURE_CONN_FTD3) {
if(!get_3d_enabled(status))
if(!is_data_3d)
base_ptr = (uint8_t*)p_in->ftd3_received.audio_data;
else
base_ptr = (uint8_t*)p_in->ftd3_received_3d.audio_data;
@@ -344,7 +354,7 @@ bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, const bool i
#endif
#ifdef USE_DS_3DS_USB
if(status->device.cc_type == CAPTURE_CONN_USB) {
if(!get_3d_enabled(status))
if(!is_data_3d)
base_ptr = (uint8_t*)p_in->usb_received_3ds.audio_data;
else
base_ptr = (uint8_t*)p_in->usb_received_3ds_3d.audio_data;

View File

@@ -222,10 +222,10 @@ void captureCall(CaptureData* capture_data) {
}
}
uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read) {
uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read, bool is_3d) {
if(!capture_data->status.device.has_audio)
return 0;
uint64_t n_samples = (read - get_video_in_size(capture_data)) / 2;
uint64_t n_samples = (read - get_video_in_size(capture_data, is_3d)) / 2;
if(n_samples > capture_data->status.device.max_samples_in)
n_samples = capture_data->status.device.max_samples_in;
// Avoid entering a glitched state due to a partial packet or something
@@ -234,14 +234,14 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, uint64_t read) {
return n_samples;
}
uint64_t get_video_in_size(CaptureData* capture_data) {
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d) {
#ifdef USE_CYNI_USB
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_NISETRO)
return cyni_device_get_video_in_size(capture_data);
#endif
#ifdef USE_FTD3
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3)
return ftd3_get_video_in_size(capture_data);
return ftd3_get_video_in_size(capture_data, is_3d);
#endif
#ifdef USE_FTD2
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD2)
@@ -249,7 +249,7 @@ uint64_t get_video_in_size(CaptureData* capture_data) {
#endif
#ifdef USE_DS_3DS_USB
if(capture_data->status.device.cc_type == CAPTURE_CONN_USB)
return usb_get_video_in_size(capture_data);
return usb_get_video_in_size(capture_data, is_3d);
#endif
#ifdef USE_IS_DEVICES_USB
if(capture_data->status.device.cc_type == CAPTURE_CONN_IS_NITRO)