mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2025-06-19 00:55:38 -04:00
Add support for Optimize DS mode
This commit is contained in:
parent
8e87c7afd1
commit
aec8741cb4
@ -82,13 +82,21 @@ struct PACKED USB3DSOptimizeSingleSoundData {
|
|||||||
uint16_t sample_r;
|
uint16_t sample_r;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PACKED USB3DSOptimizeHeaderSoundData {
|
struct PACKED USB3DSOptimizeColumnInfo {
|
||||||
// Order is Little Endian
|
// Order is Little Endian
|
||||||
uint16_t magic;
|
|
||||||
uint16_t unk_fixed_1 : 1;
|
|
||||||
uint16_t buffer_num : 1;
|
|
||||||
uint16_t unk : 4;
|
|
||||||
uint16_t column_index : 10;
|
uint16_t column_index : 10;
|
||||||
|
uint16_t unk : 4;
|
||||||
|
uint16_t buffer_num : 1;
|
||||||
|
uint16_t has_extra_header_data : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PACKED USB3DSOptimizeHeaderData {
|
||||||
|
uint16_t magic;
|
||||||
|
USB3DSOptimizeColumnInfo column_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PACKED USB3DSOptimizeHeaderSoundData {
|
||||||
|
USB3DSOptimizeHeaderData header_info;
|
||||||
USB3DSOptimizeSingleSoundData samples[2];
|
USB3DSOptimizeSingleSoundData samples[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -223,6 +231,22 @@ struct ALIGNED(16) PACKED USB8883DSOptimizeCaptureReceived_3D {
|
|||||||
USB8883DSOptimizePixelData bottom_only_column[HEIGHT_3DS][3];
|
USB8883DSOptimizePixelData bottom_only_column[HEIGHT_3DS][3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ALIGNED(16) PACKED USB5653DSOptimizeCaptureReceivedExtraHeader {
|
||||||
|
USB5653DSOptimizeInputColumnData columns_data[TOP_WIDTH_3DS + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ALIGNED(16) PACKED USB5653DSOptimizeCaptureReceived_3DExtraHeader {
|
||||||
|
USB5653DSOptimizeInputColumnData3D columns_data[TOP_WIDTH_3DS + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ALIGNED(16) PACKED USB8883DSOptimizeCaptureReceivedExtraHeader {
|
||||||
|
USB8883DSOptimizeInputColumnData columns_data[TOP_WIDTH_3DS + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ALIGNED(16) PACKED USB8883DSOptimizeCaptureReceived_3DExtraHeader {
|
||||||
|
USB8883DSOptimizeInputColumnData3D columns_data[TOP_WIDTH_3DS + 1];
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct ALIGNED(16) FTD2OldDSCaptureReceivedNormalPlusRaw {
|
struct ALIGNED(16) FTD2OldDSCaptureReceivedNormalPlusRaw {
|
||||||
@ -245,6 +269,10 @@ union CaptureReceived {
|
|||||||
USB5653DSOptimizeCaptureReceived_3D cypress_optimize_received_565_3d;
|
USB5653DSOptimizeCaptureReceived_3D cypress_optimize_received_565_3d;
|
||||||
USB8883DSOptimizeCaptureReceived cypress_optimize_received_888;
|
USB8883DSOptimizeCaptureReceived cypress_optimize_received_888;
|
||||||
USB8883DSOptimizeCaptureReceived_3D cypress_optimize_received_888_3d;
|
USB8883DSOptimizeCaptureReceived_3D cypress_optimize_received_888_3d;
|
||||||
|
USB5653DSOptimizeCaptureReceivedExtraHeader cypress_optimize_received_565_extra_header;
|
||||||
|
USB5653DSOptimizeCaptureReceived_3DExtraHeader cypress_optimize_received_565_3d_extra_header;
|
||||||
|
USB8883DSOptimizeCaptureReceivedExtraHeader cypress_optimize_received_888_extra_header;
|
||||||
|
USB8883DSOptimizeCaptureReceived_3DExtraHeader cypress_optimize_received_888_3d_extra_header;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CaptureDevice {
|
struct CaptureDevice {
|
||||||
|
@ -42,7 +42,8 @@ struct CypressOptimize3DSDeviceCaptureReceivedData {
|
|||||||
bool* is_ring_buffer_slice_data_ready_arr;
|
bool* is_ring_buffer_slice_data_ready_arr;
|
||||||
int ring_buffer_slice_index;
|
int ring_buffer_slice_index;
|
||||||
int* last_ring_buffer_slice_allocated;
|
int* last_ring_buffer_slice_allocated;
|
||||||
int* last_used_ring_buffer_slice_index;
|
int* first_usable_ring_buffer_slice_index;
|
||||||
|
bool* is_synchronized;
|
||||||
size_t* last_used_ring_buffer_slice_pos;
|
size_t* last_used_ring_buffer_slice_pos;
|
||||||
int* buffer_ring_slice_to_array_ptr;
|
int* buffer_ring_slice_to_array_ptr;
|
||||||
InputVideoDataType* stored_video_data_type;
|
InputVideoDataType* stored_video_data_type;
|
||||||
@ -201,6 +202,18 @@ uint64_t cyop_device_get_video_in_size(bool is_3d, InputVideoDataType video_data
|
|||||||
return sizeof(USB5653DSOptimizeCaptureReceived);
|
return sizeof(USB5653DSOptimizeCaptureReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t cyop_device_get_video_in_size_extra_header(bool is_3d, InputVideoDataType video_data_type) {
|
||||||
|
bool is_rgb888 = video_data_type == VIDEO_DATA_RGB;
|
||||||
|
if(is_rgb888) {
|
||||||
|
if(is_3d)
|
||||||
|
return sizeof(USB8883DSOptimizeCaptureReceived_3DExtraHeader);
|
||||||
|
return sizeof(USB8883DSOptimizeCaptureReceivedExtraHeader);
|
||||||
|
}
|
||||||
|
if(is_3d)
|
||||||
|
return sizeof(USB5653DSOptimizeCaptureReceived_3DExtraHeader);
|
||||||
|
return sizeof(USB5653DSOptimizeCaptureReceivedExtraHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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(CaptureStatus* status, bool is_3d, InputVideoDataType video_data_type) {
|
||||||
return cyop_device_get_video_in_size(is_3d, video_data_type);
|
return cyop_device_get_video_in_size(is_3d, video_data_type);
|
||||||
@ -234,34 +247,62 @@ static int cypress_device_read_frame_request(CaptureData* capture_data, CypressO
|
|||||||
return ReadFrameAsync((cy_device_device_handlers*)capture_data->handle, buffer, (int)read_size, usb_device_info, &cypress_device_capture_recv_data->cb_data);
|
return ReadFrameAsync((cy_device_device_handlers*)capture_data->handle, buffer, (int)read_size, usb_device_info, &cypress_device_capture_recv_data->cb_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlock_buffer_directly(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data_real) {
|
static void unlock_buffer_directly(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data_real, bool reset_slice_data_arr_info) {
|
||||||
int slice_index = cypress_device_capture_recv_data_real->ring_buffer_slice_index;
|
int slice_index = cypress_device_capture_recv_data_real->ring_buffer_slice_index;
|
||||||
cypress_device_capture_recv_data_real->is_ring_buffer_slice_data_ready_arr[slice_index] = false;
|
if(reset_slice_data_arr_info) {
|
||||||
cypress_device_capture_recv_data_real->is_ring_buffer_slice_data_in_use_arr[slice_index] = false;
|
cypress_device_capture_recv_data_real->is_ring_buffer_slice_data_ready_arr[slice_index] = false;
|
||||||
|
cypress_device_capture_recv_data_real->is_ring_buffer_slice_data_in_use_arr[slice_index] = false;
|
||||||
|
}
|
||||||
cypress_device_capture_recv_data_real->buffer_ring_slice_to_array_ptr[slice_index] = -1;
|
cypress_device_capture_recv_data_real->buffer_ring_slice_to_array_ptr[slice_index] = -1;
|
||||||
cypress_device_capture_recv_data_real->in_use = false;
|
cypress_device_capture_recv_data_real->in_use = false;
|
||||||
cypress_device_capture_recv_data_real->is_buffer_free_shared_mutex->specific_unlock(cypress_device_capture_recv_data_real->cb_data.internal_index);
|
if(!cypress_device_capture_recv_data_real->to_process)
|
||||||
|
cypress_device_capture_recv_data_real->is_buffer_free_shared_mutex->specific_unlock(cypress_device_capture_recv_data_real->cb_data.internal_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlock_buffer_slice_index(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, size_t slice_index) {
|
static void unlock_buffer_slice_index(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, size_t slice_index, bool reset_slice_data_arr_info) {
|
||||||
int index = cypress_device_capture_recv_data->buffer_ring_slice_to_array_ptr[slice_index];
|
int index = cypress_device_capture_recv_data->buffer_ring_slice_to_array_ptr[slice_index];
|
||||||
if(index == -1)
|
if(index == -1) {
|
||||||
|
if(reset_slice_data_arr_info) {
|
||||||
|
cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[slice_index] = false;
|
||||||
|
cypress_device_capture_recv_data->is_ring_buffer_slice_data_in_use_arr[slice_index] = false;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
unlock_buffer_directly(&cypress_device_capture_recv_data->array_ptr[index]);
|
}
|
||||||
|
unlock_buffer_directly(&cypress_device_capture_recv_data->array_ptr[index], reset_slice_data_arr_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_cypress_device_read_frame_cb(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool to_unlock) {
|
static void end_cypress_device_read_frame_cb(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, bool to_unlock) {
|
||||||
cypress_device_capture_recv_data->to_process = false;
|
|
||||||
if(to_unlock)
|
if(to_unlock)
|
||||||
unlock_buffer_directly(cypress_device_capture_recv_data);
|
unlock_buffer_directly(cypress_device_capture_recv_data, true);
|
||||||
|
cypress_device_capture_recv_data->to_process = false;
|
||||||
|
if(!cypress_device_capture_recv_data->in_use)
|
||||||
|
cypress_device_capture_recv_data->is_buffer_free_shared_mutex->specific_unlock(cypress_device_capture_recv_data->cb_data.internal_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.buffer_num = (value >> 14) & 1;
|
||||||
|
column_info.unk = (value >> 10) & 0xF;
|
||||||
|
column_info.column_index = value & 0x3FF;
|
||||||
|
return column_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_expect_extra_header_in_buffer(uint16_t value) {
|
||||||
|
return convert_to_column_info(value).has_extra_header_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 false;
|
||||||
|
return convert_to_column_info(read_le16(buffer + pos_to_check + 2)).column_index == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer) {
|
static size_t get_pos_first_synch_in_buffer(uint8_t* buffer) {
|
||||||
for(int i = 0; i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
|
for(int i = 0; i < (SINGLE_RING_BUFFER_SLICE_SIZE / 2); i++) {
|
||||||
if(read_le16(buffer, i) == SYNCH_VALUE_OPTIMIZE) {
|
if(get_is_pos_first_synch_in_buffer(buffer, i * 2))
|
||||||
if((read_le16(buffer, i + 1) & 0x3FF) == 0)
|
return i * 2;
|
||||||
return i * 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return SINGLE_RING_BUFFER_SLICE_SIZE + 1;
|
return SINGLE_RING_BUFFER_SLICE_SIZE + 1;
|
||||||
}
|
}
|
||||||
@ -276,18 +317,27 @@ static int get_num_consecutive_ready_ring_buffer_slices(CypressOptimize3DSDevice
|
|||||||
return NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
return NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unlock_buffers_from_x(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, int pos_to_unlock, int num_buffers_to_unlock, bool reset_slice_data_arr_info) {
|
||||||
|
for(int i = 0; i < num_buffers_to_unlock; i++)
|
||||||
|
unlock_buffer_slice_index(cypress_device_capture_recv_data, (pos_to_unlock + i) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS, reset_slice_data_arr_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_slice_data_to_buffer(uint8_t* dst, uint8_t *src, size_t start_slice_index, size_t start_slice_pos, size_t copy_size) {
|
||||||
|
size_t start_byte = (start_slice_index * SINGLE_RING_BUFFER_SLICE_SIZE) + start_slice_pos;
|
||||||
|
if((start_byte + copy_size) <= (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE))
|
||||||
|
memcpy(dst, src + start_byte, copy_size);
|
||||||
|
else {
|
||||||
|
size_t upper_read_size = (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE) - start_byte;
|
||||||
|
size_t start_read_size = copy_size - upper_read_size;
|
||||||
|
memcpy(dst, src + start_byte, upper_read_size);
|
||||||
|
memcpy(dst + upper_read_size, src, start_read_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
// Output to the other threads...
|
// Output to the other threads...
|
||||||
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(internal_index);
|
CaptureDataSingleBuffer* data_buf = capture_data->data_buffers.GetWriterBuffer(internal_index);
|
||||||
size_t start_byte = (start_slice_index * SINGLE_RING_BUFFER_SLICE_SIZE) + start_slice_pos;
|
copy_slice_data_to_buffer((uint8_t*)&data_buf->capture_buf, buffer_arr, start_slice_index, start_slice_pos, read_size);
|
||||||
if((start_byte + read_size) <= (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE))
|
|
||||||
memcpy(&data_buf->capture_buf, buffer_arr + start_byte, read_size);
|
|
||||||
else {
|
|
||||||
size_t upper_read_size = (NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS * SINGLE_RING_BUFFER_SLICE_SIZE) - start_byte;
|
|
||||||
size_t start_read_size = read_size - upper_read_size;
|
|
||||||
memcpy(&data_buf->capture_buf, buffer_arr + start_byte, upper_read_size);
|
|
||||||
memcpy(((uint8_t*)&data_buf->capture_buf) + upper_read_size, buffer_arr, start_read_size);
|
|
||||||
}
|
|
||||||
const auto curr_time = std::chrono::high_resolution_clock::now();
|
const auto curr_time = std::chrono::high_resolution_clock::now();
|
||||||
const std::chrono::duration<double> diff = curr_time - (*clock_start);
|
const std::chrono::duration<double> diff = curr_time - (*clock_start);
|
||||||
*clock_start = curr_time;
|
*clock_start = curr_time;
|
||||||
@ -298,6 +348,88 @@ static void cypress_output_to_thread(CaptureData* capture_data, uint8_t *buffer_
|
|||||||
capture_data->status.audio_wait.unlock();
|
capture_data->status.audio_wait.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cypress_device_read_frame_not_synchronized(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, int &error) {
|
||||||
|
volatile int first_slice_to_check = *cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index;
|
||||||
|
bool found = false;
|
||||||
|
// Determine which buffer is the first which needs to still be checked
|
||||||
|
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
|
||||||
|
int index_to_check = (first_slice_to_check + i) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
||||||
|
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_in_use_arr[index_to_check]) {
|
||||||
|
first_slice_to_check = index_to_check;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Too many have been checked... Just fail.
|
||||||
|
if(!found) {
|
||||||
|
error = LIBUSB_ERROR_OTHER;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS; i++) {
|
||||||
|
int check_index = (first_slice_to_check + i) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
||||||
|
// Search for the synch values. If they're not there, free the buffer.
|
||||||
|
// If they are there, enque the buffer and switch mode.
|
||||||
|
// Checks all available buffers which have data (but in order).
|
||||||
|
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[check_index]) {
|
||||||
|
size_t result = get_pos_first_synch_in_buffer(&cypress_device_capture_recv_data->ring_slice_buffer_arr[check_index * SINGLE_RING_BUFFER_SLICE_SIZE]);
|
||||||
|
if(result >= SINGLE_RING_BUFFER_SLICE_SIZE) {
|
||||||
|
unlock_buffer_slice_index(cypress_device_capture_recv_data, check_index, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index = check_index;
|
||||||
|
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos = result;
|
||||||
|
*cypress_device_capture_recv_data->is_synchronized = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cypress_device_read_frame_synchronized(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
||||||
|
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);
|
||||||
|
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)];
|
||||||
|
copy_slice_data_to_buffer(tmp_buffer, cypress_device_capture_recv_data->ring_slice_buffer_arr, read_slice_index, read_slice_pos, sizeof(USB3DSOptimizeHeaderData));
|
||||||
|
if(!get_is_pos_first_synch_in_buffer(tmp_buffer, 0)) {
|
||||||
|
*cypress_device_capture_recv_data->is_synchronized = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
// 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));
|
||||||
|
size_t new_slice_pos = raw_new_pos % SINGLE_RING_BUFFER_SLICE_SIZE;
|
||||||
|
new_slice_index %= NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
||||||
|
// Fully unlock used buffers
|
||||||
|
unlock_buffers_from_x(cypress_device_capture_recv_data, read_slice_index, (new_slice_index + NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS - read_slice_index) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS, true);
|
||||||
|
// Update the position of the data
|
||||||
|
*cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index = new_slice_index;
|
||||||
|
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos = new_slice_pos;
|
||||||
|
}
|
||||||
|
// Partially unlock buffers already with data.
|
||||||
|
// Unlocks the transfers to be used for more.
|
||||||
|
// This is possible under the assumption that there are significantly
|
||||||
|
// more buffers than transfers!!!
|
||||||
|
// Without said assumption, you'd risk the two stepping on each other.
|
||||||
|
read_slice_index = *cypress_device_capture_recv_data->first_usable_ring_buffer_slice_index;
|
||||||
|
num_consecutive_ready_buffers = get_num_consecutive_ready_ring_buffer_slices(cypress_device_capture_recv_data, read_slice_index);
|
||||||
|
unlock_buffers_from_x(cypress_device_capture_recv_data, read_slice_index, num_consecutive_ready_buffers, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status) {
|
static void cypress_device_read_frame_cb(void* user_data, int transfer_length, int transfer_status) {
|
||||||
CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data = (CypressOptimize3DSDeviceCaptureReceivedData*)user_data;
|
CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data = (CypressOptimize3DSDeviceCaptureReceivedData*)user_data;
|
||||||
if((*cypress_device_capture_recv_data->status) < 0)
|
if((*cypress_device_capture_recv_data->status) < 0)
|
||||||
@ -310,66 +442,27 @@ static void cypress_device_read_frame_cb(void* user_data, int transfer_length, i
|
|||||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
||||||
}
|
}
|
||||||
cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[cypress_device_capture_recv_data->ring_buffer_slice_index] = true;
|
cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[cypress_device_capture_recv_data->ring_buffer_slice_index] = true;
|
||||||
// First case
|
// Not synchronized case
|
||||||
bool to_free = false;
|
bool to_free = false;
|
||||||
volatile int read_slice_index = *cypress_device_capture_recv_data->last_used_ring_buffer_slice_index;
|
bool continue_looping = true;
|
||||||
if(read_slice_index == -1) {
|
int remaining_iters_before_force_exit = 4;
|
||||||
size_t first_to_check = 0;
|
volatile bool read_is_synchronized = *cypress_device_capture_recv_data->is_synchronized;
|
||||||
for(int i = 0; i < NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS; i++) {
|
while(continue_looping) {
|
||||||
if(!cypress_device_capture_recv_data->is_ring_buffer_slice_data_in_use_arr[i])
|
if(read_is_synchronized)
|
||||||
first_to_check++;
|
cypress_device_read_frame_synchronized(cypress_device_capture_recv_data);
|
||||||
else
|
else {
|
||||||
break;
|
int error = 0;
|
||||||
}
|
bool retval = cypress_device_read_frame_not_synchronized(cypress_device_capture_recv_data, error);
|
||||||
if(first_to_check > NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS) {
|
if(!retval) {
|
||||||
int error = LIBUSB_ERROR_OTHER;
|
*cypress_device_capture_recv_data->status = error;
|
||||||
*cypress_device_capture_recv_data->status = error;
|
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
||||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, true);
|
|
||||||
}
|
|
||||||
for(int i = 0; i < NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS; i++) {
|
|
||||||
size_t check_index = (first_to_check + i) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
|
||||||
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[check_index]) {
|
|
||||||
size_t result = get_pos_first_synch_in_buffer(&cypress_device_capture_recv_data->ring_slice_buffer_arr[check_index * SINGLE_RING_BUFFER_SLICE_SIZE]);
|
|
||||||
if(result >= SINGLE_RING_BUFFER_SLICE_SIZE) {
|
|
||||||
unlock_buffer_slice_index(cypress_device_capture_recv_data, check_index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_index = (int)check_index;
|
|
||||||
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos = result;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Generic case
|
|
||||||
read_slice_index = *cypress_device_capture_recv_data->last_used_ring_buffer_slice_index;
|
|
||||||
volatile size_t read_slice_pos = *cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos;
|
|
||||||
if(read_slice_index != -1) {
|
|
||||||
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);
|
|
||||||
size_t raw_new_pos = read_slice_pos + video_in_size;
|
|
||||||
int num_needed_buffers = (int)((raw_new_pos + SINGLE_RING_BUFFER_SLICE_SIZE - 1) / SINGLE_RING_BUFFER_SLICE_SIZE);
|
|
||||||
if(num_consecutive_ready_buffers >= num_needed_buffers) {
|
|
||||||
// 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);
|
|
||||||
// Keep the ring buffer going.
|
|
||||||
int new_slice_index = read_slice_index + num_needed_buffers - 1;
|
|
||||||
size_t new_slice_pos = raw_new_pos % SINGLE_RING_BUFFER_SLICE_SIZE;
|
|
||||||
if(new_slice_pos == 0)
|
|
||||||
new_slice_index += 1;
|
|
||||||
new_slice_index %= NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
|
||||||
// Unlock the buffers already processed
|
|
||||||
int pos_to_unlock = read_slice_index;
|
|
||||||
while(pos_to_unlock != new_slice_index) {
|
|
||||||
unlock_buffer_slice_index(cypress_device_capture_recv_data, pos_to_unlock);
|
|
||||||
pos_to_unlock = (pos_to_unlock + 1) % NUM_TOTAL_OPTIMIZE_3DS_CYPRESS_BUFFERS;
|
|
||||||
}
|
|
||||||
// Update the position of the data
|
|
||||||
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_index = new_slice_index;
|
|
||||||
*cypress_device_capture_recv_data->last_used_ring_buffer_slice_pos = new_slice_pos;
|
|
||||||
}
|
}
|
||||||
|
volatile bool new_read_is_synchronized = *cypress_device_capture_recv_data->is_synchronized;
|
||||||
|
remaining_iters_before_force_exit--;
|
||||||
|
if((new_read_is_synchronized == read_is_synchronized) || (remaining_iters_before_force_exit == 0))
|
||||||
|
continue_looping = false;
|
||||||
|
read_is_synchronized = new_read_is_synchronized;
|
||||||
}
|
}
|
||||||
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, to_free);
|
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data, to_free);
|
||||||
}
|
}
|
||||||
@ -403,10 +496,9 @@ static void error_too_much_time_passed(CaptureData* capture_data, CypressOptimiz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_unlock_waiting_with_error(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data) {
|
static void unlock_buffer_in_error_case(CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_capture_recv_data, int status) {
|
||||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0) {
|
if((status < 0) && (!cypress_device_capture_recv_data->to_process)) {
|
||||||
if(cypress_device_capture_recv_data->is_ring_buffer_slice_data_ready_arr[cypress_device_capture_recv_data->ring_buffer_slice_index])
|
unlock_buffer_directly(cypress_device_capture_recv_data, true);
|
||||||
unlock_buffer_directly(cypress_device_capture_recv_data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +511,7 @@ static void wait_all_cypress_device_buffers_free(CaptureData* capture_data, Cypr
|
|||||||
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++)
|
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++)
|
||||||
while(cypress_device_capture_recv_data[i].in_use) {
|
while(cypress_device_capture_recv_data[i].in_use) {
|
||||||
error_too_much_time_passed(capture_data, cypress_device_capture_recv_data, async_read_closed, start_time);
|
error_too_much_time_passed(capture_data, cypress_device_capture_recv_data, async_read_closed, start_time);
|
||||||
check_unlock_waiting_with_error(&cypress_device_capture_recv_data[i]);
|
unlock_buffer_in_error_case(&cypress_device_capture_recv_data[i], get_cypress_device_status(cypress_device_capture_recv_data));
|
||||||
cypress_device_capture_recv_data[i].is_buffer_free_shared_mutex->specific_timed_lock(i);
|
cypress_device_capture_recv_data[i].is_buffer_free_shared_mutex->specific_timed_lock(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,7 +521,7 @@ static void wait_one_cypress_device_buffer_free(CaptureData* capture_data, Cypre
|
|||||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||||
while(!done) {
|
while(!done) {
|
||||||
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
|
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
|
||||||
if(!cypress_device_capture_recv_data[i].in_use)
|
if((!cypress_device_capture_recv_data[i].in_use) && (!cypress_device_capture_recv_data[i].to_process))
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
if(!done) {
|
if(!done) {
|
||||||
@ -448,7 +540,7 @@ static CypressOptimize3DSDeviceCaptureReceivedData* cypress_device_get_free_buff
|
|||||||
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++)
|
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++)
|
||||||
if(!cypress_device_capture_recv_data[i].in_use) {
|
if((!cypress_device_capture_recv_data[i].in_use) && (!cypress_device_capture_recv_data[i].to_process)) {
|
||||||
return &cypress_device_capture_recv_data[i];
|
return &cypress_device_capture_recv_data[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -478,7 +570,7 @@ static bool cyop_device_acquisition_loop(CaptureData* capture_data, CypressOptim
|
|||||||
capture_error_print(true, capture_data, "Capture Start: Failed");
|
capture_error_print(true, capture_data, "Capture Start: Failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CypressSetMaxTransferSize(handlers, get_cy_usb_info(usb_device_desc), (size_t)cyop_device_get_video_in_size(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_video_data_type));
|
||||||
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
|
for(int i = 0; i < NUM_OPTIMIZE_3DS_CYPRESS_CONCURRENTLY_RUNNING_BUFFERS; i++) {
|
||||||
CypressOptimize3DSDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
CypressOptimize3DSDeviceCaptureReceivedData* chosen_buffer = cypress_device_get_free_buffer(capture_data, cypress_device_capture_recv_data);
|
||||||
ret = cypress_device_read_frame_request(capture_data, chosen_buffer, index++, stored_is_3d, stored_video_data_type);
|
ret = cypress_device_read_frame_request(capture_data, chosen_buffer, index++, stored_is_3d, stored_video_data_type);
|
||||||
@ -536,7 +628,8 @@ void cyop_device_acquisition_main_loop(CaptureData* capture_data) {
|
|||||||
is_ring_buffer_slice_data_in_use[i] = false;
|
is_ring_buffer_slice_data_in_use[i] = false;
|
||||||
buffer_ring_slice_to_array[i] = -1;
|
buffer_ring_slice_to_array[i] = -1;
|
||||||
}
|
}
|
||||||
int last_used_ring_buffer_slice_index = -1;
|
int first_usable_ring_buffer_slice_index = 0;
|
||||||
|
bool is_synchronized = false;
|
||||||
size_t last_used_ring_buffer_slice_pos = 0;
|
size_t last_used_ring_buffer_slice_pos = 0;
|
||||||
int last_ring_buffer_slice_allocated = -1;
|
int last_ring_buffer_slice_allocated = -1;
|
||||||
|
|
||||||
@ -557,7 +650,8 @@ void cyop_device_acquisition_main_loop(CaptureData* capture_data) {
|
|||||||
cypress_device_capture_recv_data[i].is_ring_buffer_slice_data_in_use_arr = is_ring_buffer_slice_data_in_use;
|
cypress_device_capture_recv_data[i].is_ring_buffer_slice_data_in_use_arr = is_ring_buffer_slice_data_in_use;
|
||||||
cypress_device_capture_recv_data[i].is_ring_buffer_slice_data_ready_arr = is_ring_buffer_slice_data_ready;
|
cypress_device_capture_recv_data[i].is_ring_buffer_slice_data_ready_arr = is_ring_buffer_slice_data_ready;
|
||||||
cypress_device_capture_recv_data[i].last_ring_buffer_slice_allocated = &last_ring_buffer_slice_allocated;
|
cypress_device_capture_recv_data[i].last_ring_buffer_slice_allocated = &last_ring_buffer_slice_allocated;
|
||||||
cypress_device_capture_recv_data[i].last_used_ring_buffer_slice_index = &last_used_ring_buffer_slice_index;
|
cypress_device_capture_recv_data[i].first_usable_ring_buffer_slice_index = &first_usable_ring_buffer_slice_index;
|
||||||
|
cypress_device_capture_recv_data[i].is_synchronized = &is_synchronized;
|
||||||
cypress_device_capture_recv_data[i].last_used_ring_buffer_slice_pos = &last_used_ring_buffer_slice_pos;
|
cypress_device_capture_recv_data[i].last_used_ring_buffer_slice_pos = &last_used_ring_buffer_slice_pos;
|
||||||
cypress_device_capture_recv_data[i].buffer_ring_slice_to_array_ptr = buffer_ring_slice_to_array;
|
cypress_device_capture_recv_data[i].buffer_ring_slice_to_array_ptr = buffer_ring_slice_to_array;
|
||||||
cypress_device_capture_recv_data[i].capture_data = capture_data;
|
cypress_device_capture_recv_data[i].capture_data = capture_data;
|
||||||
|
@ -432,6 +432,14 @@ static inline void usb_oldDSconvertVideoToOutputHalfLineDirectOptBE(USBOldDSCapt
|
|||||||
usb_rgb565convertInterleaveVideoToOutputDirectOptBE(out_ptr_top, out_ptr_bottom, in_ptr, halfline_iters, input_halfline, output_halfline);
|
usb_rgb565convertInterleaveVideoToOutputDirectOptBE(out_ptr_top, out_ptr_bottom, in_ptr, halfline_iters, input_halfline, output_halfline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool usb_OptimizeHasExtraHeaderSoundData(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.has_extra_header_data = (base_data >> 15) & 1;
|
||||||
|
return column_info.has_extra_header_data;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptLE(USB5653DSOptimizeCaptureReceived *p_in, VideoOutputData *p_out, uint16_t column) {
|
static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptLE(USB5653DSOptimizeCaptureReceived *p_in, VideoOutputData *p_out, uint16_t column) {
|
||||||
//de-interleave pixels
|
//de-interleave pixels
|
||||||
const int pixels_size = 2;
|
const int pixels_size = 2;
|
||||||
@ -444,6 +452,8 @@ static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptLE(USB5653
|
|||||||
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
|
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
|
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);
|
||||||
const uint32_t num_iters = HEIGHT_3DS;
|
const uint32_t num_iters = HEIGHT_3DS;
|
||||||
if(column == column_last_bot_pos)
|
if(column == column_last_bot_pos)
|
||||||
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
usb_rgb565convertInterleaveVideoToOutputDirectOptLEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
||||||
@ -471,6 +481,8 @@ static inline void usb_3DS565OptimizeconvertVideoToOutputLineDirectOptBE(USB5653
|
|||||||
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
|
interleaved_rgb565_pixels* in_ptr = (interleaved_rgb565_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_rgb565_pixels*)p_in->columns_data[column].pixel;
|
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);
|
||||||
const uint32_t num_iters = HEIGHT_3DS;
|
const uint32_t num_iters = HEIGHT_3DS;
|
||||||
if(column == column_last_bot_pos)
|
if(column == column_last_bot_pos)
|
||||||
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
usb_rgb565convertInterleaveVideoToOutputDirectOptBEMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
||||||
@ -499,6 +511,8 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptLE(USB56
|
|||||||
interleaved_3d_rgb565_pixels* in_ptr = (interleaved_3d_rgb565_pixels*)p_in->bottom_only_column;
|
interleaved_3d_rgb565_pixels* in_ptr = (interleaved_3d_rgb565_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_3d_rgb565_pixels*)p_in->columns_data[column].pixel;
|
in_ptr = (interleaved_3d_rgb565_pixels*)p_in->columns_data[column].pixel;
|
||||||
|
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
|
||||||
|
in_ptr = (interleaved_3d_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceived_3DExtraHeader*)p_in)->columns_data[column].pixel);
|
||||||
int multiplier_top = 1;
|
int multiplier_top = 1;
|
||||||
if(interleaved_3d) {
|
if(interleaved_3d) {
|
||||||
multiplier_top = 2;
|
multiplier_top = 2;
|
||||||
@ -533,6 +547,8 @@ static inline void usb_3DS565Optimizeconvert3DVideoToOutputLineDirectOptBE(USB56
|
|||||||
interleaved_3d_rgb565_pixels* in_ptr = (interleaved_3d_rgb565_pixels*)p_in->bottom_only_column;
|
interleaved_3d_rgb565_pixels* in_ptr = (interleaved_3d_rgb565_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_3d_rgb565_pixels*)p_in->columns_data[column].pixel;
|
in_ptr = (interleaved_3d_rgb565_pixels*)p_in->columns_data[column].pixel;
|
||||||
|
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
|
||||||
|
in_ptr = (interleaved_3d_rgb565_pixels*)(((USB5653DSOptimizeCaptureReceived_3DExtraHeader*)p_in)->columns_data[column].pixel);
|
||||||
int multiplier_top = 1;
|
int multiplier_top = 1;
|
||||||
if(interleaved_3d) {
|
if(interleaved_3d) {
|
||||||
multiplier_top = 2;
|
multiplier_top = 2;
|
||||||
@ -566,6 +582,8 @@ static inline void usb_3DS888OptimizeconvertVideoToOutputLineDirectOpt(USB8883DS
|
|||||||
interleaved_rgb888_u16_pixels* in_ptr = (interleaved_rgb888_u16_pixels*)p_in->bottom_only_column;
|
interleaved_rgb888_u16_pixels* in_ptr = (interleaved_rgb888_u16_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_rgb888_u16_pixels*)p_in->columns_data[column].pixel;
|
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);
|
||||||
const uint32_t num_iters = HEIGHT_3DS;
|
const uint32_t num_iters = HEIGHT_3DS;
|
||||||
if(column == column_last_bot_pos)
|
if(column == column_last_bot_pos)
|
||||||
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
usb_rgb888convertInterleaveU16VideoToOutputDirectOptMonoBottom(out_ptr_bottom, in_ptr, num_iters, 0, BOT_WIDTH_3DS - 1);
|
||||||
@ -594,6 +612,8 @@ static inline void usb_3DS888Optimizeconvert3DVideoToOutputLineDirectOpt(USB8883
|
|||||||
interleaved_3d_rgb888_u16_pixels* in_ptr = (interleaved_3d_rgb888_u16_pixels*)p_in->bottom_only_column;
|
interleaved_3d_rgb888_u16_pixels* in_ptr = (interleaved_3d_rgb888_u16_pixels*)p_in->bottom_only_column;
|
||||||
if(column < column_last_bot_pos)
|
if(column < column_last_bot_pos)
|
||||||
in_ptr = (interleaved_3d_rgb888_u16_pixels*)p_in->columns_data[column].pixel;
|
in_ptr = (interleaved_3d_rgb888_u16_pixels*)p_in->columns_data[column].pixel;
|
||||||
|
else if(usb_OptimizeHasExtraHeaderSoundData(&p_in->columns_data[0].header_sound))
|
||||||
|
in_ptr = (interleaved_3d_rgb888_u16_pixels*)(((USB8883DSOptimizeCaptureReceived_3DExtraHeader*)p_in)->columns_data[column].pixel);
|
||||||
int multiplier_top = 1;
|
int multiplier_top = 1;
|
||||||
if(interleaved_3d) {
|
if(interleaved_3d) {
|
||||||
multiplier_top = 2;
|
multiplier_top = 2;
|
||||||
@ -851,6 +871,17 @@ static USB3DSOptimizeHeaderSoundData* getAudioHeaderPtrOptimize3DS(CaptureReceiv
|
|||||||
return &buffer->cypress_optimize_received_888_3d.columns_data[column].header_sound;
|
return &buffer->cypress_optimize_received_888_3d.columns_data[column].header_sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static USB3DSOptimizeHeaderSoundData* getAudioHeaderPtrOptimize3DSExtraHeader(CaptureReceived* buffer, bool is_rgb888, bool is_data_3d, uint16_t column) {
|
||||||
|
if(!is_rgb888) {
|
||||||
|
if(!is_data_3d)
|
||||||
|
return &buffer->cypress_optimize_received_565_extra_header.columns_data[column].header_sound;
|
||||||
|
return &buffer->cypress_optimize_received_565_3d_extra_header.columns_data[column].header_sound;
|
||||||
|
}
|
||||||
|
if(!is_data_3d)
|
||||||
|
return &buffer->cypress_optimize_received_888_extra_header.columns_data[column].header_sound;
|
||||||
|
return &buffer->cypress_optimize_received_888_3d_extra_header.columns_data[column].header_sound;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint16_t read_sample_indexLE(USB3DSOptimizeSingleSoundData* sample) {
|
static inline uint16_t read_sample_indexLE(USB3DSOptimizeSingleSoundData* sample) {
|
||||||
return sample->sample_index % OPTIMIZE_3DS_AUDIO_BUFFER_MAX_SIZE;
|
return sample->sample_index % OPTIMIZE_3DS_AUDIO_BUFFER_MAX_SIZE;
|
||||||
}
|
}
|
||||||
@ -887,6 +918,12 @@ static void copyAudioOptimize3DSLE(std::int16_t *p_out, uint64_t &n_samples, uin
|
|||||||
copyAudioFromSoundDataOptimize3DSLE(p_out, &curr_column_data->samples[0], num_inserted, last_inserted_index);
|
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);
|
copyAudioFromSoundDataOptimize3DSLE(p_out, &curr_column_data->samples[1], num_inserted, last_inserted_index);
|
||||||
}
|
}
|
||||||
|
USB3DSOptimizeHeaderSoundData* initial_column_data = getAudioHeaderPtrOptimize3DS(buffer, is_rgb888, is_data_3d, 0);
|
||||||
|
if(usb_OptimizeHasExtraHeaderSoundData(initial_column_data)) {
|
||||||
|
USB3DSOptimizeHeaderSoundData* curr_column_data = getAudioHeaderPtrOptimize3DSExtraHeader(buffer, is_rgb888, is_data_3d, TOP_WIDTH_3DS);
|
||||||
|
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;
|
last_buffer_index = last_inserted_index;
|
||||||
n_samples = num_inserted * 2;
|
n_samples = num_inserted * 2;
|
||||||
}
|
}
|
||||||
@ -899,6 +936,12 @@ static void copyAudioOptimize3DSBE(std::int16_t *p_out, uint64_t &n_samples, uin
|
|||||||
copyAudioFromSoundDataOptimize3DSBE(p_out, &curr_column_data->samples[0], num_inserted, last_inserted_index);
|
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);
|
copyAudioFromSoundDataOptimize3DSBE(p_out, &curr_column_data->samples[1], num_inserted, last_inserted_index);
|
||||||
}
|
}
|
||||||
|
USB3DSOptimizeHeaderSoundData* initial_column_data = getAudioHeaderPtrOptimize3DS(buffer, is_rgb888, is_data_3d, 0);
|
||||||
|
if(usb_OptimizeHasExtraHeaderSoundData(initial_column_data)) {
|
||||||
|
USB3DSOptimizeHeaderSoundData* curr_column_data = getAudioHeaderPtrOptimize3DSExtraHeader(buffer, is_rgb888, is_data_3d, TOP_WIDTH_3DS);
|
||||||
|
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;
|
last_buffer_index = last_inserted_index;
|
||||||
n_samples = num_inserted * 2;
|
n_samples = num_inserted * 2;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user