Fix graphical issues with Optimize CCs

This commit is contained in:
Lorenzooone 2025-11-17 03:37:32 +01:00
parent 79116a27fd
commit efac5ce6b9
8 changed files with 312 additions and 91 deletions

View File

@ -16,8 +16,8 @@
void list_devices_cyop_device(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list, bool* devices_allowed_scan);
bool cyop_device_connect_usb(bool print_failed, CaptureData* capture_data, CaptureDevice* device);
uint64_t cyop_device_get_video_in_size(CaptureStatus* status, bool is_3d, InputVideoDataType video_data_type);
uint64_t cyop_device_get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type);
uint64_t cyop_device_get_video_in_size(CaptureStatus* status, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type);
uint64_t cyop_device_get_video_in_size(CaptureData* capture_data, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type);
void cyop_device_acquisition_main_loop(CaptureData* capture_data);
void usb_cyop_device_acquisition_cleanup(CaptureData* capture_data);
bool is_device_optimize_3ds(CaptureDevice* device);

View File

@ -91,7 +91,7 @@ struct PACKED USB3DSOptimizeColumnInfo {
uint16_t column_index : 10;
uint16_t unk : 4;
uint16_t buffer_num : 1;
uint16_t has_extra_header_data : 1;
uint16_t has_extra_header_data_2d_only : 1;
};
struct PACKED USB3DSOptimizeHeaderData {
@ -242,6 +242,10 @@ struct ALIGNED(16) PACKED USB8883DSOptimizeCaptureReceived_3D {
USB8883DSOptimizeInputColumnData3D bottom_only_column;
};
struct ALIGNED(16) PACKED USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen {
USB8883DSOptimizeInputColumnData3D columns_data[TOP_WIDTH_3DS + 1];
};
struct ALIGNED(16) PACKED USB5653DSOptimizeCaptureReceivedExtraHeader {
USB5653DSOptimizeInputColumnData columns_data[TOP_WIDTH_3DS + 1];
};
@ -272,6 +276,7 @@ union CaptureReceived {
USB5653DSOptimizeCaptureReceived_3D cypress_optimize_received_565_3d;
USB8883DSOptimizeCaptureReceived cypress_optimize_received_888;
USB8883DSOptimizeCaptureReceived_3D cypress_optimize_received_888_3d;
USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen cypress_optimize_received_888_3d_2d;
USB5653DSOptimizeCaptureReceivedExtraHeader cypress_optimize_received_565_extra_header;
USB8883DSOptimizeCaptureReceivedExtraHeader cypress_optimize_received_888_extra_header;
};
@ -347,6 +352,7 @@ struct CaptureDataSingleBuffer {
double time_in_buf;
uint32_t inner_index;
bool is_3d;
bool should_be_3d;
InputVideoDataType buffer_video_data_type;
};
@ -355,10 +361,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, 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);
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, bool should_be_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, CaptureScreensType capture_type, int index, bool is_3d = false, bool should_be_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, size_t offset, int index, bool is_3d = false, bool should_be_3d = false);
void WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d = false, bool should_be_3d = false);
CaptureDataSingleBuffer* GetWriterBuffer(int index = 0);
void ReleaseWriterBuffer(int index = 0, bool update_last_curr_in = true);
private:

View File

@ -26,7 +26,7 @@ void capture_error_print(bool print_failed, CaptureData* capture_data, std::stri
void capture_warning_print(CaptureData* capture_data, std::string warning_string);
void capture_warning_print(CaptureData* capture_data, std::string graphical_string, std::string detailed_string);
uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer* data_buffer);
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type);
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type);
std::string get_device_id_string(CaptureStatus* capture_status);
std::string get_device_serial_key_string(CaptureStatus* capture_status);
std::string get_name_of_device(CaptureStatus* capture_status, bool use_long = false, bool want_real_serial = false);

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, bool is_3d) {
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, bool should_be_3d) {
if(offset >= read)
return;
if(!is_writer_index_valid(index))
@ -117,18 +117,19 @@ void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, d
target->time_in_buf = time_in_buf;
target->capture_type = capture_type;
target->is_3d = is_3d;
target->should_be_3d = should_be_3d;
target->buffer_video_data_type = device->video_data_type;
this->ReleaseWriterBuffer(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, CaptureScreensType capture_type, int index, bool is_3d, bool should_be_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, capture_type, 0, index, is_3d, should_be_3d);
}
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, size_t offset, int index, bool is_3d, bool should_be_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, offset, index, is_3d, should_be_3d);
}
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);
void CaptureDataBuffers::WriteToBuffer(CaptureReceived* buffer, uint64_t read, double time_in_buf, CaptureDevice* device, int index, bool is_3d, bool should_be_3d) {
return this->WriteToBuffer(buffer, read, time_in_buf, device, CAPTURE_SCREENS_BOTH, 0, index, is_3d, should_be_3d);
}

View File

@ -212,11 +212,14 @@ bool cyop_device_connect_usb(bool print_failed, CaptureData* capture_data, Captu
return true;
}
uint64_t cyop_device_get_video_in_size(bool is_3d, InputVideoDataType video_data_type) {
uint64_t cyop_device_get_video_in_size(bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
bool is_rgb888 = video_data_type == OPTIMIZE_RGB888_FORMAT;
if(is_rgb888) {
if(is_3d)
return sizeof(USB8883DSOptimizeCaptureReceived_3D);
if(should_be_3d) {
if(is_3d)
return sizeof(USB8883DSOptimizeCaptureReceived_3D);
return sizeof(USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen);
}
return sizeof(USB8883DSOptimizeCaptureReceived);
}
if(is_3d)
@ -224,11 +227,14 @@ uint64_t cyop_device_get_video_in_size(bool is_3d, InputVideoDataType video_data
return sizeof(USB5653DSOptimizeCaptureReceived);
}
uint64_t cyop_device_get_video_in_size_extra_header(bool is_3d, InputVideoDataType video_data_type) {
uint64_t cyop_device_get_video_in_size_extra_header(bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
bool is_rgb888 = video_data_type == OPTIMIZE_RGB888_FORMAT;
if(is_rgb888) {
if(is_3d)
return sizeof(USB8883DSOptimizeCaptureReceived_3D);
if(should_be_3d) {
if(is_3d)
return sizeof(USB8883DSOptimizeCaptureReceived_3D);
return sizeof(USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen);
}
return sizeof(USB8883DSOptimizeCaptureReceivedExtraHeader);
}
if(is_3d)
@ -237,13 +243,13 @@ uint64_t cyop_device_get_video_in_size_extra_header(bool is_3d, InputVideoDataTy
}
uint64_t cyop_device_get_video_in_size(CaptureStatus* status, bool is_3d, InputVideoDataType video_data_type) {
return cyop_device_get_video_in_size(is_3d, video_data_type);
uint64_t cyop_device_get_video_in_size(CaptureStatus* status, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
return cyop_device_get_video_in_size(is_3d, should_be_3d, video_data_type);
}
uint64_t cyop_device_get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type) {
return cyop_device_get_video_in_size(&capture_data->status, is_3d, video_data_type);
uint64_t cyop_device_get_video_in_size(CaptureData* capture_data, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
return cyop_device_get_video_in_size(&capture_data->status, is_3d, should_be_3d, video_data_type);
}
bool is_device_optimize_3ds(CaptureDevice* device) {
@ -293,7 +299,7 @@ static int cypress_device_read_frame_request(CaptureData* capture_data, CypressO
const cyop_device_usb_device* usb_device_info = (const cyop_device_usb_device*)capture_data->status.device.descriptor;
cypress_device_capture_recv_data->index = index;
cypress_device_capture_recv_data->cb_data.function = cypress_device_read_frame_cb;
//size_t read_size = cyop_device_get_video_in_size(is_3d, video_data_type);
//size_t read_size = cyop_device_get_video_in_size(is_3d, is_3d, video_data_type);
size_t read_size = SINGLE_RING_BUFFER_SLICE_SIZE;
int new_buffer_slice_index = ((*cypress_device_capture_recv_data->last_ring_buffer_slice_allocated) + 1) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
uint8_t* buffer = &cypress_device_capture_recv_data->ring_slice_buffer_arr[new_buffer_slice_index * SINGLE_RING_BUFFER_SLICE_SIZE];
@ -343,7 +349,7 @@ static void end_cypress_device_read_frame_cb(CypressOptimize3DSDeviceCaptureRece
static USB3DSOptimizeColumnInfo convert_to_column_info(uint16_t value) {
// The macos compiler requires this... :/
USB3DSOptimizeColumnInfo column_info;
column_info.has_extra_header_data = (value >> 15) & 1;
column_info.has_extra_header_data_2d_only = (value >> 15) & 1;
column_info.buffer_num = (value >> 14) & 1;
column_info.unk = (value >> 10) & 0xF;
column_info.column_index = value & 0x3FF;
@ -351,13 +357,98 @@ static USB3DSOptimizeColumnInfo convert_to_column_info(uint16_t value) {
}
static bool get_expect_extra_header_in_buffer(uint16_t value) {
return convert_to_column_info(value).has_extra_header_data;
return convert_to_column_info(value).has_extra_header_data_2d_only;
}
static bool get_is_data_2d_only(uint16_t value) {
return convert_to_column_info(value).has_extra_header_data_2d_only;
}
static bool get_is_pos_column_synch_in_buffer(uint8_t* buffer, size_t pos_to_check, uint16_t column_index) {
if(read_le16(buffer + pos_to_check) != SYNCH_VALUE_OPTIMIZE)
return false;
return convert_to_column_info(read_le16(buffer + pos_to_check + 2)).column_index == column_index;
}
static bool get_is_pos_column_synch_in_buffer(USB3DSOptimizeHeaderSoundData* in_ptr, uint16_t column_index) {
return get_is_pos_column_synch_in_buffer((uint8_t*)&in_ptr->header_info, 0, column_index);
}
static bool get_is_pos_first_synch_in_buffer(uint8_t* buffer, size_t pos_to_check) {
if(read_le16(buffer + pos_to_check) != SYNCH_VALUE_OPTIMIZE)
return get_is_pos_column_synch_in_buffer(buffer, pos_to_check, 0);
}
static bool get_is_buffer_rgb565_fully_synced(CaptureReceived* buffer) {
USB5653DSOptimizeCaptureReceived* real_buffer = &buffer->cypress_optimize_received_565;
USB5653DSOptimizeCaptureReceivedExtraHeader* real_buffer_special = &buffer->cypress_optimize_received_565_extra_header;
bool is_special = get_expect_extra_header_in_buffer(read_le16((uint8_t*)&real_buffer->columns_data[0].header_sound.header_info.column_info));
for(int i = 0; i < TOP_WIDTH_3DS; i++)
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].header_sound, i))
return false;
if(is_special && (!get_is_pos_column_synch_in_buffer(&real_buffer_special->columns_data[TOP_WIDTH_3DS].header_sound, TOP_WIDTH_3DS)))
return false;
return convert_to_column_info(read_le16(buffer + pos_to_check + 2)).column_index == 0;
return true;
}
static bool get_is_buffer_rgb565_3d_fully_synced(CaptureReceived* buffer) {
USB5653DSOptimizeCaptureReceived_3D* real_buffer = &buffer->cypress_optimize_received_565_3d;
for(int i = 0; i < TOP_WIDTH_3DS; i++) {
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].top_r_screen_column.header_sound, i * 2))
return false;
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].bot_top_l_screens_column.header_sound, (i * 2) + 1))
return false;
}
if(!get_is_pos_column_synch_in_buffer(&real_buffer->bottom_only_column.header_sound, TOP_WIDTH_3DS * 2))
return false;
return true;
}
static bool get_is_buffer_rgb888_fully_synced(CaptureReceived* buffer) {
USB8883DSOptimizeCaptureReceived* real_buffer = &buffer->cypress_optimize_received_888;
USB8883DSOptimizeCaptureReceivedExtraHeader* real_buffer_special = &buffer->cypress_optimize_received_888_extra_header;
bool is_special = get_expect_extra_header_in_buffer(read_le16((uint8_t*)&real_buffer->columns_data[0].header_sound.header_info.column_info));
for(int i = 0; i < TOP_WIDTH_3DS; i++)
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].header_sound, i))
return false;
if(is_special && (!get_is_pos_column_synch_in_buffer(&real_buffer_special->columns_data[TOP_WIDTH_3DS].header_sound, TOP_WIDTH_3DS)))
return false;
return true;
}
static bool get_is_buffer_rgb888_3d_fully_synced(CaptureReceived* buffer) {
USB8883DSOptimizeCaptureReceived_3D* real_buffer = &buffer->cypress_optimize_received_888_3d;
for(int i = 0; i < TOP_WIDTH_3DS; i++) {
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i][0].header_sound, i * 2))
return false;
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i][1].header_sound, (i * 2) + 1))
return false;
}
if(!get_is_pos_column_synch_in_buffer(&real_buffer->bottom_only_column.header_sound, TOP_WIDTH_3DS * 2))
return false;
return true;
}
static bool get_is_buffer_rgb888_3d_2d_fully_synced(CaptureReceived* buffer) {
USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen* real_buffer = &buffer->cypress_optimize_received_888_3d_2d;
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++) {
if(!get_is_pos_column_synch_in_buffer(&real_buffer->columns_data[i].header_sound, i))
return false;
}
return true;
}
static bool get_is_buffer_fully_synched(CaptureReceived* buffer, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
bool is_rgb888 = video_data_type == OPTIMIZE_RGB888_FORMAT;
if(!is_rgb888) {
if(!is_3d)
return get_is_buffer_rgb565_fully_synced(buffer);
return get_is_buffer_rgb565_3d_fully_synced(buffer);
}
if(is_3d)
return get_is_buffer_rgb888_3d_fully_synced(buffer);
if(should_be_3d)
return get_is_buffer_rgb888_3d_2d_fully_synced(buffer);
return get_is_buffer_rgb888_fully_synced(buffer);
}
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer) {
@ -395,14 +486,18 @@ static void copy_slice_data_to_buffer(uint8_t* dst, uint8_t *src, size_t start_s
}
}
static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_arr, size_t start_slice_index, size_t start_slice_pos, int internal_index, std::chrono::time_point<std::chrono::high_resolution_clock>* clock_start, size_t read_size, bool is_3d) {
static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_arr, size_t start_slice_index, size_t start_slice_pos, int internal_index, std::chrono::time_point<std::chrono::high_resolution_clock>* clock_start, size_t read_size, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
// Output to the other threads...
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(internal_index);
copy_slice_data_to_buffer((uint8_t*)&data_buf->capture_buf, buffer_arr, start_slice_index, start_slice_pos, read_size);
if(!get_is_buffer_fully_synched(&data_buf->capture_buf, is_3d, should_be_3d, video_data_type)) {
capture_data->data_buffers.ReleaseWriterBuffer(internal_index, false);
return;
}
const auto curr_time = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double> diff = curr_time - (*clock_start);
*clock_start = curr_time;
capture_data->data_buffers.WriteToBuffer(NULL, read_size, diff.count(), &capture_data->status.device, internal_index, is_3d);
capture_data->data_buffers.WriteToBuffer(NULL, read_size, diff.count(), &capture_data->status.device, internal_index, is_3d, should_be_3d);
if (capture_data->status.cooldown_curr_in)
capture_data->status.cooldown_curr_in = capture_data->status.cooldown_curr_in - 1;
capture_data->status.video_wait.unlock();
@ -453,7 +548,10 @@ static void cypress_device_read_frame_synchronized(CypressOptimize3DSDeviceCaptu
volatile int read_slice_index = *cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index;
volatile size_t read_slice_pos = *cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos;
int num_consecutive_ready_buffers = get_num_consecutive_ready_ring_buffer_slices(cypress_device_capture_recv_data, read_slice_index);
size_t video_in_size = (size_t)cyop_device_get_video_in_size(*cypress_device_capture_recv_data->stored_is_3d, *cypress_device_capture_recv_data->stored_video_data_type);
bool should_be_3d_data = *cypress_device_capture_recv_data->stored_is_3d;
bool is_3d_data = should_be_3d_data;
InputVideoDataType video_data_type = *cypress_device_capture_recv_data->stored_video_data_type;
size_t video_in_size = (size_t)cyop_device_get_video_in_size(is_3d_data, should_be_3d_data, video_data_type);
size_t curr_consecutive_available_bytes = (num_consecutive_ready_buffers * SINGLE_RING_BUFFER_SLICE_SIZE) - read_slice_pos;
if(curr_consecutive_available_bytes >= sizeof(USB3DSOptimizeHeaderData)) {
uint8_t tmp_buffer[sizeof(USB3DSOptimizeHeaderData)];
@ -464,12 +562,16 @@ static void cypress_device_read_frame_synchronized(CypressOptimize3DSDeviceCaptu
}
else {
if(get_expect_extra_header_in_buffer(read_le16(tmp_buffer, 1)))
video_in_size = (size_t)cyop_device_get_video_in_size_extra_header(*cypress_device_capture_recv_data->stored_is_3d, *cypress_device_capture_recv_data->stored_video_data_type);
video_in_size = (size_t)cyop_device_get_video_in_size_extra_header(is_3d_data, should_be_3d_data, video_data_type);
if(get_is_data_2d_only(read_le16(tmp_buffer, 1))) {
is_3d_data = false;
video_in_size = (size_t)cyop_device_get_video_in_size_extra_header(is_3d_data, should_be_3d_data, video_data_type);
}
}
}
if(curr_consecutive_available_bytes >= video_in_size) {
// Enough data. Time to do output...
cypress_output_to_thread(cypress_device_capture_recv_data->capture_data, cypress_device_capture_recv_data->ring_slice_buffer_arr, read_slice_index, read_slice_pos, 0, cypress_device_capture_recv_data->clock_start, video_in_size, *cypress_device_capture_recv_data->stored_is_3d);
cypress_output_to_thread(cypress_device_capture_recv_data->capture_data, cypress_device_capture_recv_data->ring_slice_buffer_arr, read_slice_index, read_slice_pos, 0, cypress_device_capture_recv_data->clock_start, video_in_size, is_3d_data, should_be_3d_data, video_data_type);
// Keep the ring buffer going.
size_t raw_new_pos = read_slice_pos + video_in_size;
int new_slice_index = (int)(read_slice_index + (raw_new_pos / SINGLE_RING_BUFFER_SLICE_SIZE));
@ -705,7 +807,7 @@ static int restart_captures_cc_reads(CaptureData* capture_data, CypressOptimize3
}
if(set_max_again)
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), (size_t)cyop_device_get_video_in_size_extra_header(stored_is_3d, stored_video_data_type));
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), (size_t)cyop_device_get_video_in_size_extra_header(stored_is_3d, stored_is_3d, stored_video_data_type));
index = 0;
reset_buffer_processing_data(cypress_device_capture_recv_data);
@ -761,7 +863,7 @@ static bool cyop_device_acquisition_loop(CaptureData* capture_data, CypressOptim
capture_error_print(true, capture_data, "Capture Start: Failed");
return false;
}
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), (size_t)cyop_device_get_video_in_size_extra_header(stored_is_3d, stored_video_data_type));
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), (size_t)cyop_device_get_video_in_size_extra_header(stored_is_3d, stored_is_3d, stored_video_data_type));
if(!schedule_all_reads(capture_data, cypress_device_capture_recv_data, index, stored_video_data_type, stored_is_3d, "Initial Reads: Failed"))
return false;

View File

@ -457,7 +457,7 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data, volatile
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, data_buffer->is_3d, data_buffer->buffer_video_data_type)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
if((data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->should_be_3d, data_buffer->buffer_video_data_type)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY) && capture_data->status.connected) {
uint64_t n_samples = get_audio_n_samples(capture_data, data_buffer);
double out_time = data_buffer->time_in_buf;
bool conversion_success = convertAudioToOutput(out_buf[audio_buf_counter], n_samples, last_buffer_index, endianness, data_buffer, &capture_data->status);
@ -645,7 +645,7 @@ 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, data_buffer->is_3d, data_buffer->buffer_video_data_type)) {
if(data_buffer->read >= get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->should_be_3d, data_buffer->buffer_video_data_type)) {
if(capture_data->status.cooldown_curr_in || (!capture_data->status.connected))
blank_out = true;
else {

View File

@ -293,30 +293,44 @@ static inline bool usb_OptimizeHasExtraHeaderSoundData(USB3DSOptimizeHeaderSound
// The macos compiler requires this... :/
uint16_t base_data = read_le16((uint8_t*)&header_sound_data->header_info.column_info);
USB3DSOptimizeColumnInfo column_info;
column_info.has_extra_header_data = (base_data >> 15) & 1;
return column_info.has_extra_header_data;
column_info.has_extra_header_data_2d_only = (base_data >> 15) & 1;
return column_info.has_extra_header_data_2d_only;
}
static inline uint16_t usb_OptimizeGetDataBufferNumber(USB3DSOptimizeHeaderSoundData* header_sound_data) {
// The macos compiler requires this... :/
uint16_t base_data = read_le16((uint8_t*)&header_sound_data->header_info.column_info);
USB3DSOptimizeColumnInfo column_info;
column_info.buffer_num = (base_data >> 14) & 1;
return column_info.buffer_num;
}
static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptLE(USB5653DSOptimizeCaptureReceived *p_in, VideoOutputData *p_out, uint16_t column) {
//de-interleave pixels
const int pixels_size = sizeof(VideoPixelRGB16);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
const size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
const size_t column_last_bot_pos = TOP_WIDTH_3DS;
const size_t ptr_out_size = sizeof(deinterleaved_rgb565_pixels);
size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
size_t target_bot_column_pre_last = BOT_WIDTH_3DS - 2;
bool is_special_header = usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound);
deinterleaved_rgb565_pixels* out_ptr_bottom = (deinterleaved_rgb565_pixels*)p_out->rgb16_video_output_data.screen_data;
deinterleaved_rgb565_pixels* out_ptr_top = out_ptr_bottom + ((BOT_SIZE_3DS * pixels_size) / ptr_out_size);
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
if(column < column_last_bot_pos)
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
in_ptr = (interleaved_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceivedExtraHeader*)p_in)->columns_data[column].pixel);
if(is_special_header) {
column_start_bot_pos -= 1;
column_pre_last_bot_pos -= 2;
target_bot_column_pre_last = BOT_WIDTH_3DS - 1;
if(column == column_last_bot_pos)
return;
}
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
const uint32_t num_iters = HEIGHT_3DS;
if(column == column_last_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
else if(column == column_pre_last_bot_pos) {
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 2);
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, target_bot_column_pre_last);
}
else if(column < column_start_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
@ -329,23 +343,29 @@ static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptLE(USB5653
static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptBE(USB5653DSOptimizeCaptureReceived *p_in, VideoOutputData *p_out, uint16_t column) {
//de-interleave pixels
const int pixels_size = sizeof(VideoPixelRGB16);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
const size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
const size_t column_last_bot_pos = TOP_WIDTH_3DS;
const size_t ptr_out_size = sizeof(deinterleaved_rgb565_pixels);
size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
size_t target_bot_column_pre_last = BOT_WIDTH_3DS - 2;
bool is_special_header = usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound);
deinterleaved_rgb565_pixels* out_ptr_bottom = (deinterleaved_rgb565_pixels*)p_out->rgb16_video_output_data.screen_data;
deinterleaved_rgb565_pixels* out_ptr_top = out_ptr_bottom + ((BOT_SIZE_3DS * pixels_size) / ptr_out_size);
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
if(column < column_last_bot_pos)
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
in_ptr = (interleaved_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceivedExtraHeader*)p_in)->columns_data[column].pixel);
if(is_special_header) {
column_start_bot_pos -= 1;
column_pre_last_bot_pos -= 2;
target_bot_column_pre_last = BOT_WIDTH_3DS - 1;
if(column == column_last_bot_pos)
return;
}
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
const uint32_t num_iters = HEIGHT_3DS;
if(column == column_last_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
else if(column == column_pre_last_bot_pos) {
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 2);
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, target_bot_column_pre_last);
}
else if(column < column_start_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
@ -358,19 +378,24 @@ static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptBE(USB5653
static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptLE(USB5653DSOptimizeCaptureReceived_3D *p_in, VideoOutputData *p_out, uint16_t column, bool interleaved_3d) {
//de-interleave pixels
const int pixels_size = sizeof(VideoPixelRGB16);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
const size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
const size_t column_last_bot_pos = TOP_WIDTH_3DS;
const size_t ptr_out_size = sizeof(deinterleaved_rgb565_pixels);
size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
size_t target_bot_column_pre_last = BOT_WIDTH_3DS - 2;
bool is_special_header = usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].bot_top_l_screens_column.header_sound);
deinterleaved_rgb565_pixels* out_ptr_bottom = (deinterleaved_rgb565_pixels*)p_out->rgb16_video_output_data.screen_data;
deinterleaved_rgb565_pixels* out_ptr_top_l = out_ptr_bottom + ((BOT_SIZE_3DS * pixels_size) / ptr_out_size);
deinterleaved_rgb565_pixels* out_ptr_top_r = out_ptr_bottom + (((TOP_SIZE_3DS + BOT_SIZE_3DS) * pixels_size) / ptr_out_size);
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column.pixel;
if(column < column_last_bot_pos)
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].bot_top_l_screens_column.pixel;
//else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound)) {
//in_ptr = (interleaved_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceived_3DExtraHeader*)p_in)->columns_data[column].pixel);
//}
if(is_special_header) {
column_start_bot_pos -= 1;
column_pre_last_bot_pos -= 2;
target_bot_column_pre_last = BOT_WIDTH_3DS - 1;
if(column == column_last_bot_pos)
return;
}
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].bot_top_l_screens_column.pixel;
int multiplier_top = 1;
if(interleaved_3d) {
multiplier_top = 2;
@ -383,7 +408,7 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptLE(USB56
memcpy_data_u16le_origin((uint16_t*)(out_ptr_top_r + ((column * HEIGHT_3DS * multiplier_top * pixels_size) / ptr_out_size)), (uint8_t*)p_in->columns_data[column].top_r_screen_column.pixel, HEIGHT_3DS, false);
if(column == column_pre_last_bot_pos) {
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoTop(out_ptr_top_l, in_ptr, num_iters, 0, column, multiplier_top);
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 2);
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, target_bot_column_pre_last);
}
else if(column < column_start_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoTop(out_ptr_top_l, in_ptr, num_iters, 0, column, multiplier_top);
@ -397,19 +422,24 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptLE(USB56
static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptBE(USB5653DSOptimizeCaptureReceived_3D *p_in, VideoOutputData *p_out, uint16_t column, bool interleaved_3d) {
//de-interleave pixels
const int pixels_size = sizeof(VideoPixelRGB16);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
const size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
const size_t column_last_bot_pos = TOP_WIDTH_3DS;
const size_t ptr_out_size = sizeof(deinterleaved_rgb565_pixels);
size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
size_t target_bot_column_pre_last = BOT_WIDTH_3DS - 2;
bool is_special_header = usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].bot_top_l_screens_column.header_sound);
deinterleaved_rgb565_pixels* out_ptr_bottom = (deinterleaved_rgb565_pixels*)p_out->rgb16_video_output_data.screen_data;
deinterleaved_rgb565_pixels* out_ptr_top_l = out_ptr_bottom + ((BOT_SIZE_3DS * pixels_size) / ptr_out_size);
deinterleaved_rgb565_pixels* out_ptr_top_r = out_ptr_bottom + (((TOP_SIZE_3DS + BOT_SIZE_3DS) * pixels_size) / ptr_out_size);
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column.pixel;
if(column < column_last_bot_pos)
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].bot_top_l_screens_column.pixel;
//else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound)) {
//in_ptr = (interleaved_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceived_3DExtraHeader*)p_in)->columns_data[column].pixel);
//}
if(is_special_header) {
column_start_bot_pos -= 1;
column_pre_last_bot_pos -= 2;
target_bot_column_pre_last = BOT_WIDTH_3DS - 1;
if(column == column_last_bot_pos)
return;
}
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].bot_top_l_screens_column.pixel;
int multiplier_top = 1;
if(interleaved_3d) {
multiplier_top = 2;
@ -422,7 +452,7 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptBE(USB56
memcpy_data_u16le_origin((uint16_t*)(out_ptr_top_r + ((column * HEIGHT_3DS * multiplier_top * pixels_size) / ptr_out_size)), (uint8_t*)p_in->columns_data[column].top_r_screen_column.pixel, HEIGHT_3DS, true);
if(column == column_pre_last_bot_pos) {
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoTop(out_ptr_top_l, in_ptr, num_iters, 0, column, multiplier_top);
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 2);
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, target_bot_column_pre_last);
}
else if(column < column_start_bot_pos)
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoTop(out_ptr_top_l, in_ptr, num_iters, 0, column, multiplier_top);
@ -436,23 +466,29 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptBE(USB56
static inline void usb_3DS888OptimizeconvertVideoToOutputLineDirectOpt(USB8883DSOptimizeCaptureReceived *p_in, VideoOutputData *p_out, uint16_t column) {
//de-interleave pixels
const int pixels_size = sizeof(VideoPixelRGB);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
const size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
const size_t column_last_bot_pos = TOP_WIDTH_3DS;
const size_t ptr_out_size = sizeof(deinterleaved_rgb888_u16_pixels);
size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
size_t column_pre_last_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2);
size_t target_bot_column_pre_last = BOT_WIDTH_3DS - 2;
bool is_special_header = usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound);
deinterleaved_rgb888_u16_pixels* out_ptr_bottom = (deinterleaved_rgb888_u16_pixels*)p_out->rgb_video_output_data.screen_data;
deinterleaved_rgb888_u16_pixels* out_ptr_top = out_ptr_bottom + ((BOT_SIZE_3DS * pixels_size) / ptr_out_size);
interleaved_rgb888_u16_pixels* in_ptr = (interleaved_rgb888_u16_pixels*)p_in->bottom_only_column;
if(column < column_last_bot_pos)
in_ptr = (interleaved_rgb888_u16_pixels*)p_in->columns_data[column].pixel;
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
in_ptr = (interleaved_rgb888_u16_pixels*)(((USB8883DSOptimizeCaptureReceivedExtraHeader*)p_in)->columns_data[column].pixel);
if(is_special_header) {
column_start_bot_pos -= 1;
column_pre_last_bot_pos -= 2;
target_bot_column_pre_last = BOT_WIDTH_3DS - 1;
if(column == column_last_bot_pos)
return;
}
in_ptr = (interleaved_rgb888_u16_pixels*)p_in->columns_data[column].pixel;
const uint32_t num_iters = HEIGHT_3DS;
if(column == column_last_bot_pos)
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
else if(column == column_pre_last_bot_pos) {
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 2);
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, target_bot_column_pre_last);
}
else if(column < column_start_bot_pos)
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoTop(out_ptr_top, in_ptr, num_iters, 0, column);
@ -462,6 +498,37 @@ static inline void usb_3DS888OptimizeconvertVideoToOutputLineDirectOpt(USB8883DS
}
}
static inline void usb_3DS888Optimizeconvert3DForced2DVideoToOutputLineDirectOpt(USB8883DSOptimizeCaptureReceived_3D_Forced2DSingleScreen *p_in, VideoOutputData *p_out, uint16_t column, bool &do_expand) {
const int pixels_size = sizeof(VideoPixelRGB);
bool is_for_bottom = true;
uint8_t* out_ptr = (uint8_t*)p_out->rgb_video_output_data.screen_data;
if(usb_OptimizeGetDataBufferNumber(&p_in->columns_data[column].header_sound) == 1) {
out_ptr = out_ptr + (BOT_SIZE_3DS * pixels_size);
is_for_bottom = false;
}
size_t column_start = 0;
size_t column_end = TOP_WIDTH_3DS;
size_t special_column_index = 0xFFFF;
size_t special_column_target = 0xFFFF;
if(is_for_bottom) {
column_start = TOP_WIDTH_3DS - BOT_WIDTH_3DS + 1;
column_end = TOP_WIDTH_3DS;
special_column_index = TOP_WIDTH_3DS - BOT_WIDTH_3DS;
special_column_target = BOT_WIDTH_3DS - 1;
do_expand = false;
}
if(column == special_column_index) {
memcpy(out_ptr + (special_column_target * HEIGHT_3DS * pixels_size), (uint8_t*)p_in->columns_data[special_column_index].pixel, HEIGHT_3DS * pixels_size);
return;
}
if(column < column_start)
return;
if(column >= column_end)
return;
memcpy(out_ptr + ((column - column_start) * HEIGHT_3DS * pixels_size), (uint8_t*)p_in->columns_data[column].pixel, HEIGHT_3DS * pixels_size);
}
static inline void usb_3DS888Optimizeconvert3DVideoToOutputLineDirectOpt(USB8883DSOptimizeCaptureReceived_3D *p_in, VideoOutputData *p_out, uint16_t column, bool interleaved_3d, bool is_bottom_data) {
const int pixels_size = sizeof(VideoPixelRGB);
const size_t column_start_bot_pos = (SCREEN_WIDTH_FIRST_PIXEL_BOTTOM_3DS * 2) + 2;
@ -478,7 +545,6 @@ static inline void usb_3DS888Optimizeconvert3DVideoToOutputLineDirectOpt(USB8883
if((!is_bottom_data) && (column >= TOP_WIDTH_3DS))
return;
uint8_t* src_ptr = (uint8_t*)p_in->bottom_only_column.pixel;
uint8_t* dst_ptr_first = out_ptr_bottom;
uint8_t* dst_ptr_second = out_ptr_bottom;
if(is_bottom_data) {
@ -603,7 +669,7 @@ static void usb_cypress_nisetro_ds_convertVideoToOutput(CaptureReceived *p_in, V
}
}
static void usb_3ds_optimize_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, const bool is_big_endian, bool interleaved_3d, bool requested_3d, bool is_rgb888) {
static void usb_3ds_optimize_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d, bool should_be_3d, const bool is_big_endian, bool interleaved_3d, bool requested_3d, bool is_rgb888) {
if(!is_rgb888) {
if(!enabled_3d) {
if(!is_big_endian)
@ -625,9 +691,17 @@ static void usb_3ds_optimize_convertVideoToOutput(CaptureReceived *p_in, VideoOu
}
else {
if(!enabled_3d) {
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++)
usb_3DS888OptimizeconvertVideoToOutputLineDirectOpt(&p_in->cypress_optimize_received_888, p_out, i);
expand_2d_to_3d_convertVideoToOutput((uint8_t*)p_out->rgb_video_output_data.screen_data, sizeof(VideoPixelRGB), interleaved_3d, requested_3d);
bool do_expand = true;
if(should_be_3d) {
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++)
usb_3DS888Optimizeconvert3DForced2DVideoToOutputLineDirectOpt(&p_in->cypress_optimize_received_888_3d_2d, p_out, i, do_expand);
}
else {
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++)
usb_3DS888OptimizeconvertVideoToOutputLineDirectOpt(&p_in->cypress_optimize_received_888, p_out, i);
}
if(do_expand)
expand_2d_to_3d_convertVideoToOutput((uint8_t*)p_out->rgb_video_output_data.screen_data, sizeof(VideoPixelRGB), interleaved_3d, requested_3d);
}
else {
USB3DSOptimizeHeaderSoundData* first_column_header = getAudioHeaderPtrOptimize3DS3D(p_in, is_rgb888, 0);
@ -692,6 +766,7 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt
bool converted = false;
CaptureDevice* chosen_device = &status->device;
bool is_data_3d = data_buffer->is_3d;
bool should_be_3d = data_buffer->should_be_3d;
InputVideoDataType video_data_type = data_buffer->buffer_video_data_type;
bool is_3d_requested = get_3d_enabled(status);
#ifdef USE_FTD3
@ -727,7 +802,7 @@ bool convertVideoToOutput(VideoOutputData *p_out, const bool is_big_endian, Capt
#ifdef USE_CYPRESS_OPTIMIZE
if(status->device.cc_type == CAPTURE_CONN_CYPRESS_OPTIMIZE) {
bool is_rgb888 = video_data_type == VIDEO_DATA_RGB;
usb_3ds_optimize_convertVideoToOutput(p_in, p_out, is_data_3d, is_big_endian, interleaved_3d, is_3d_requested, is_rgb888);
usb_3ds_optimize_convertVideoToOutput(p_in, p_out, is_data_3d, should_be_3d, is_big_endian, interleaved_3d, is_3d_requested, is_rgb888);
converted = true;
}
#endif
@ -756,6 +831,10 @@ static USB3DSOptimizeHeaderSoundData* getAudioHeaderPtrOptimize3DS3D(CaptureRece
return &buffer->cypress_optimize_received_888_3d.columns_data[column / 2][column % 2].header_sound;
}
static USB3DSOptimizeHeaderSoundData* getAudioHeaderPtrOptimize3DS3DForced2D(CaptureReceived* buffer, uint16_t column) {
return &buffer->cypress_optimize_received_888_3d_2d.columns_data[column].header_sound;
}
static USB3DSOptimizeHeaderSoundData* getAudioHeaderPtrOptimize3DS3DExtraHeader(CaptureReceived* buffer, bool is_rgb888) {
if(!is_rgb888)
return &buffer->cypress_optimize_received_565_3d.bottom_only_column.header_sound;
@ -823,6 +902,18 @@ static void copyAudioOptimize3DS3DLE(std::int16_t *p_out, uint64_t &n_samples, u
n_samples = num_inserted * 2;
}
static void copyAudioOptimize3DS3DForced2DLE(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, CaptureReceived* buffer) {
uint64_t num_inserted = 0;
int last_inserted_index = last_buffer_index;
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++) {
USB3DSOptimizeHeaderSoundData* curr_column_data = getAudioHeaderPtrOptimize3DS3DForced2D(buffer, i);
copyAudioFromSoundDataOptimize3DSLE(p_out, &curr_column_data->samples[0], num_inserted, last_inserted_index);
copyAudioFromSoundDataOptimize3DSLE(p_out, &curr_column_data->samples[1], num_inserted, last_inserted_index);
}
last_buffer_index = last_inserted_index;
n_samples = num_inserted * 2;
}
static void copyAudioOptimize3DSBE(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, CaptureReceived* buffer, bool is_rgb888) {
uint64_t num_inserted = 0;
int last_inserted_index = last_buffer_index;
@ -856,10 +947,23 @@ static void copyAudioOptimize3DS3DBE(std::int16_t *p_out, uint64_t &n_samples, u
n_samples = num_inserted * 2;
}
static void copyAudioOptimize3DS3DForced2DBE(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, CaptureReceived* buffer) {
uint64_t num_inserted = 0;
int last_inserted_index = last_buffer_index;
for(int i = 0; i < (TOP_WIDTH_3DS + 1); i++) {
USB3DSOptimizeHeaderSoundData* curr_column_data = getAudioHeaderPtrOptimize3DS3DForced2D(buffer, i);
copyAudioFromSoundDataOptimize3DSBE(p_out, &curr_column_data->samples[0], num_inserted, last_inserted_index);
copyAudioFromSoundDataOptimize3DSBE(p_out, &curr_column_data->samples[1], num_inserted, last_inserted_index);
}
last_buffer_index = last_inserted_index;
n_samples = num_inserted * 2;
}
bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &last_buffer_index, const bool is_big_endian, CaptureDataSingleBuffer* data_buffer, CaptureStatus* status) {
if(!status->device.has_audio)
return true;
bool is_data_3d = data_buffer->is_3d;
bool should_be_3d = data_buffer->should_be_3d;
InputVideoDataType video_data_type = data_buffer->buffer_video_data_type;
CaptureReceived* p_in = (CaptureReceived*)(((uint8_t*)&data_buffer->capture_buf) + data_buffer->unused_offset);
uint8_t* base_ptr = NULL;
@ -907,14 +1011,22 @@ bool convertAudioToOutput(std::int16_t *p_out, uint64_t &n_samples, uint16_t &la
if(is_big_endian) {
if(is_data_3d)
copyAudioOptimize3DS3DBE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
else
copyAudioOptimize3DSBE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
else {
if(should_be_3d && is_rgb888)
copyAudioOptimize3DS3DForced2DBE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf);
else
copyAudioOptimize3DSBE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
}
}
else {
if(is_data_3d)
copyAudioOptimize3DS3DLE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
else
copyAudioOptimize3DSLE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
else {
if(should_be_3d && is_rgb888)
copyAudioOptimize3DS3DForced2DLE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf);
else
copyAudioOptimize3DSLE(p_out, n_samples, last_buffer_index, &data_buffer->capture_buf, is_rgb888);
}
}
return true;
}

View File

@ -260,7 +260,7 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer*
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_OPTIMIZE)
return -1;
#endif
uint64_t n_samples = (data_buffer->read - get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->buffer_video_data_type)) / 2;
uint64_t n_samples = (data_buffer->read - get_video_in_size(capture_data, data_buffer->is_3d, data_buffer->should_be_3d, data_buffer->buffer_video_data_type)) / 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
@ -269,14 +269,14 @@ uint64_t get_audio_n_samples(CaptureData* capture_data, CaptureDataSingleBuffer*
return n_samples;
}
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, InputVideoDataType video_data_type) {
uint64_t get_video_in_size(CaptureData* capture_data, bool is_3d, bool should_be_3d, InputVideoDataType video_data_type) {
#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_CYPRESS_OPTIMIZE
if(capture_data->status.device.cc_type == CAPTURE_CONN_CYPRESS_OPTIMIZE)
return cyop_device_get_video_in_size(capture_data, is_3d, video_data_type);
return cyop_device_get_video_in_size(capture_data, is_3d, should_be_3d, video_data_type);
#endif
#ifdef USE_FTD3
if(capture_data->status.device.cc_type == CAPTURE_CONN_FTD3)