mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-08-31 08:49:46 +08:00
Move QR decoding back to UI thread.
This commit is contained in:
parent
2c982d85ec
commit
33a97577c9
@ -6,7 +6,6 @@
|
||||
#include "capturecam.h"
|
||||
#include "task.h"
|
||||
#include "../util.h"
|
||||
#include "../../libs/quirc/quirc.h"
|
||||
|
||||
#define EVENT_CANCEL 0
|
||||
#define EVENT_RECV 1
|
||||
@ -14,17 +13,8 @@
|
||||
|
||||
#define EVENT_COUNT 3
|
||||
|
||||
typedef struct {
|
||||
capture_cam_data* data;
|
||||
|
||||
struct quirc* qrContext;
|
||||
} capture_cam_internal_data;
|
||||
|
||||
static void task_capture_cam_thread(void* arg) {
|
||||
capture_cam_internal_data* internalData = (capture_cam_internal_data*) arg;
|
||||
capture_cam_data* data = internalData->data;
|
||||
|
||||
data->qrReady = false;
|
||||
capture_cam_data* data = (capture_cam_data*) arg;
|
||||
|
||||
Handle events[EVENT_COUNT] = {0};
|
||||
events[EVENT_CANCEL] = data->cancelEvent;
|
||||
@ -73,37 +63,6 @@ static void task_capture_cam_thread(void* arg) {
|
||||
GSPGPU_FlushDataCache(data->buffer, bufferSize);
|
||||
svcReleaseMutex(data->mutex);
|
||||
|
||||
if(data->scanQR) {
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
uint8_t* qrBuf = quirc_begin(internalData->qrContext, &w, &h);
|
||||
|
||||
for(int x = 0; x < w; x++) {
|
||||
for(int y = 0; y < h; y++) {
|
||||
u16 px = buffer[y * data->width + x];
|
||||
qrBuf[y * w + x] = (u8) (((((px >> 11) & 0x1F) << 3) + (((px >> 5) & 0x3F) << 2) + ((px & 0x1F) << 3)) / 3);
|
||||
}
|
||||
}
|
||||
|
||||
quirc_end(internalData->qrContext);
|
||||
|
||||
int qrCount = quirc_count(internalData->qrContext);
|
||||
for(int i = 0; i < qrCount; i++) {
|
||||
struct quirc_code qrCode;
|
||||
quirc_extract(internalData->qrContext, i, &qrCode);
|
||||
|
||||
struct quirc_data qrData;
|
||||
if(quirc_decode(&qrCode, &qrData) == 0) {
|
||||
svcWaitSynchronization(data->mutex, U64_MAX);
|
||||
|
||||
data->qrReady = true;
|
||||
memcpy(data->qrData, qrData.payload, sizeof(data->qrData));
|
||||
|
||||
svcReleaseMutex(data->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = CAMU_SetReceiving(&events[EVENT_RECV], buffer, PORT_CAM1, bufferSize, (s16) transferUnit);
|
||||
break;
|
||||
case EVENT_BUFFER_ERROR:
|
||||
@ -150,9 +109,6 @@ static void task_capture_cam_thread(void* arg) {
|
||||
}
|
||||
}
|
||||
|
||||
quirc_destroy(internalData->qrContext);
|
||||
free(internalData);
|
||||
|
||||
svcCloseHandle(data->mutex);
|
||||
|
||||
data->result = res;
|
||||
@ -164,43 +120,23 @@ Result task_capture_cam(capture_cam_data* data) {
|
||||
return R_FBI_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
capture_cam_internal_data* internalData = (capture_cam_internal_data*) calloc(1, sizeof(capture_cam_internal_data));
|
||||
if(internalData == NULL) {
|
||||
return R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data->mutex = 0;
|
||||
|
||||
data->finished = false;
|
||||
data->result = 0;
|
||||
data->cancelEvent = 0;
|
||||
|
||||
internalData->data = data;
|
||||
|
||||
Result res = 0;
|
||||
|
||||
internalData->qrContext = quirc_new();
|
||||
if(internalData->qrContext != NULL && quirc_resize(internalData->qrContext, data->width, data->height) == 0) {
|
||||
if(R_SUCCEEDED(res = svcCreateEvent(&data->cancelEvent, RESET_STICKY)) && R_SUCCEEDED(res = svcCreateMutex(&data->mutex, false))) {
|
||||
if(threadCreate(task_capture_cam_thread, internalData, 0x10000, 0x1A, 1, true) == NULL) {
|
||||
res = R_FBI_THREAD_CREATE_FAILED;
|
||||
}
|
||||
if(R_SUCCEEDED(res = svcCreateEvent(&data->cancelEvent, RESET_STICKY)) && R_SUCCEEDED(res = svcCreateMutex(&data->mutex, false))) {
|
||||
if(threadCreate(task_capture_cam_thread, data, 0x10000, 0x1A, 0, true) == NULL) {
|
||||
res = R_FBI_THREAD_CREATE_FAILED;
|
||||
}
|
||||
} else {
|
||||
res = R_FBI_QR_INIT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if(R_FAILED(res)) {
|
||||
data->finished = true;
|
||||
|
||||
if(internalData->qrContext != NULL) {
|
||||
quirc_destroy(internalData->qrContext);
|
||||
internalData->qrContext = NULL;
|
||||
}
|
||||
|
||||
free(internalData);
|
||||
|
||||
if(data->cancelEvent != 0) {
|
||||
svcCloseHandle(data->cancelEvent);
|
||||
data->cancelEvent = 0;
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define CAMERA_QR_DATA_MAX 8896
|
||||
|
||||
typedef enum capture_cam_camera_e {
|
||||
CAMERA_OUTER,
|
||||
CAMERA_INNER
|
||||
@ -12,10 +10,6 @@ typedef struct capture_cam_data_s {
|
||||
s16 width;
|
||||
s16 height;
|
||||
capture_cam_camera camera;
|
||||
bool scanQR;
|
||||
|
||||
bool qrReady;
|
||||
u8 qrData[CAMERA_QR_DATA_MAX];
|
||||
|
||||
Handle mutex;
|
||||
|
||||
|
@ -10,13 +10,12 @@ typedef struct json_t json_t;
|
||||
#define R_FBI_PARSE_FAILED MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 5)
|
||||
#define R_FBI_BAD_DATA MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 6)
|
||||
#define R_FBI_TOO_MANY_REDIRECTS MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 7)
|
||||
#define R_FBI_QR_INIT_FAILED MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 8)
|
||||
#define R_FBI_CURL_INIT_FAILED MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 9)
|
||||
|
||||
#define R_FBI_HTTP_ERROR_BASE MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 10)
|
||||
#define R_FBI_HTTP_ERROR_BASE MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, 8)
|
||||
#define R_FBI_HTTP_ERROR_END (R_FBI_HTTP_ERROR_BASE + 600)
|
||||
|
||||
#define R_FBI_CURL_ERROR_BASE (R_FBI_HTTP_ERROR_END + 1)
|
||||
#define R_FBI_CURL_INIT_FAILED (R_FBI_HTTP_ERROR_END + 1)
|
||||
#define R_FBI_CURL_ERROR_BASE (R_FBI_CURL_INIT_FAILED + 1)
|
||||
|
||||
#define R_FBI_NOT_IMPLEMENTED MAKERESULT(RL_PERMANENT, RS_INTERNAL, RM_APPLICATION, RD_NOT_IMPLEMENTED)
|
||||
#define R_FBI_OUT_OF_MEMORY MAKERESULT(RL_FATAL, RS_OUTOFRESOURCE, RM_APPLICATION, RD_OUT_OF_MEMORY)
|
||||
|
@ -503,8 +503,6 @@ static const char* description_to_string(Result res) {
|
||||
return "Bad data";
|
||||
case R_FBI_TOO_MANY_REDIRECTS:
|
||||
return "Too many redirects";
|
||||
case R_FBI_QR_INIT_FAILED:
|
||||
return "Failed to initialize QR code parser.";
|
||||
case R_FBI_CURL_INIT_FAILED:
|
||||
return "Failed to initialize CURL.";
|
||||
default:
|
||||
|
@ -251,6 +251,7 @@ static void remoteinstall_receive_urls_network() {
|
||||
#define QR_IMAGE_HEIGHT 240
|
||||
|
||||
typedef struct {
|
||||
struct quirc* qrContext;
|
||||
u32 tex;
|
||||
|
||||
bool capturing;
|
||||
@ -285,6 +286,11 @@ static void remoteinstall_qr_free_data(remoteinstall_qr_data* data) {
|
||||
data->tex = 0;
|
||||
}
|
||||
|
||||
if(data->qrContext != NULL) {
|
||||
quirc_destroy(data->qrContext);
|
||||
data->qrContext = NULL;
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
@ -348,17 +354,39 @@ static void remoteinstall_qr_update(ui_view* view, void* data, float* progress,
|
||||
return;
|
||||
}
|
||||
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
uint8_t* qrBuf = quirc_begin(installData->qrContext, &w, &h);
|
||||
|
||||
svcWaitSynchronization(installData->captureInfo.mutex, U64_MAX);
|
||||
|
||||
if(installData->captureInfo.qrReady) {
|
||||
remoteinstall_set_last_urls((const char*) installData->captureInfo.qrData);
|
||||
action_install_url("Install from the scanned QR code?", (const char*) installData->captureInfo.qrData, NULL, NULL, NULL, NULL);
|
||||
installData->captureInfo.qrReady = false;
|
||||
svcReleaseMutex(installData->captureInfo.mutex);
|
||||
for(int x = 0; x < w; x++) {
|
||||
for(int y = 0; y < h; y++) {
|
||||
u16 px = installData->captureInfo.buffer[y * QR_IMAGE_WIDTH + x];
|
||||
qrBuf[y * w + x] = (u8) (((((px >> 11) & 0x1F) << 3) + (((px >> 5) & 0x3F) << 2) + ((px & 0x1F) << 3)) / 3);
|
||||
}
|
||||
}
|
||||
|
||||
remoteinstall_qr_stop_capture(installData);
|
||||
} else {
|
||||
svcReleaseMutex(installData->captureInfo.mutex);
|
||||
svcReleaseMutex(installData->captureInfo.mutex);
|
||||
|
||||
quirc_end(installData->qrContext);
|
||||
|
||||
int qrCount = quirc_count(installData->qrContext);
|
||||
for(int i = 0; i < qrCount; i++) {
|
||||
struct quirc_code qrCode;
|
||||
quirc_extract(installData->qrContext, i, &qrCode);
|
||||
|
||||
struct quirc_data qrData;
|
||||
quirc_decode_error_t err = quirc_decode(&qrCode, &qrData);
|
||||
|
||||
if(err == 0) {
|
||||
remoteinstall_qr_stop_capture(installData);
|
||||
|
||||
remoteinstall_set_last_urls((const char*) qrData.payload);
|
||||
|
||||
action_install_url("Install from the scanned QR code?", (const char*) qrData.payload, NULL, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(text, PROGRESS_TEXT_MAX, "Waiting for QR code...");
|
||||
@ -381,10 +409,23 @@ static void remoteinstall_scan_qr_code() {
|
||||
|
||||
data->captureInfo.camera = CAMERA_OUTER;
|
||||
|
||||
data->captureInfo.scanQR = true;
|
||||
|
||||
data->captureInfo.finished = true;
|
||||
|
||||
data->qrContext = quirc_new();
|
||||
if(data->qrContext == NULL) {
|
||||
error_display(NULL, NULL, "Failed to create QR context.");
|
||||
|
||||
remoteinstall_qr_free_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if(quirc_resize(data->qrContext, QR_IMAGE_WIDTH, QR_IMAGE_HEIGHT) != 0) {
|
||||
error_display(NULL, NULL, "Failed to resize QR context.");
|
||||
|
||||
remoteinstall_qr_free_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
data->captureInfo.buffer = (u16*) calloc(1, QR_IMAGE_WIDTH * QR_IMAGE_HEIGHT * sizeof(u16));
|
||||
if(data->captureInfo.buffer == NULL) {
|
||||
error_display(NULL, NULL, "Failed to create image buffer.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user