ref: ea94204aa4ed1f7c46c6829b7d01d29dfe0f18ee
parent: 752d81359f71404b3cb410995ecbe43b0a11efa8
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Oct 8 17:20:15 EDT 2023
Fix audio segfault Work on multi-block MDEC decoding (WIP)
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -60,7 +60,8 @@
dev = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0);
- if (dev) SDL_PauseAudioDevice(dev, 0);
+ if (dev)
+ SDL_PauseAudioDevice(dev, 0);
psx_gpu_t* gpu = psx_get_gpu(psx);
psx_gpu_set_event_callback(gpu, GPU_EVENT_DMODE, psxe_gpu_dmode_event_cb);
@@ -93,6 +94,8 @@
while (psxe_screen_is_open(screen)) {psx_update(psx);
}
+
+ SDL_PauseAudioDevice(dev, 1);
psx_cpu_t* cpu = psx_get_cpu(psx);
--- a/psx/dev/mdec.c
+++ b/psx/dev/mdec.c
@@ -54,7 +54,7 @@
int sum = 0;
for (int z = 0; z < 8; z++)
- sum += src[y+z*8] * (scale[x+z*8] / 8);
+ sum += (int32_t)src[y+z*8] * ((int32_t)scale[x+z*8] / 8);
dst[x+y*8] = (sum + 0xfff) / 0x2000;
}
@@ -116,7 +116,7 @@
return src;
}
-void yuv_to_rgb(psx_mdec_t* mdec, int xx, int yy) {+void yuv_to_rgb(psx_mdec_t* mdec, uint8_t* buf, int xx, int yy) { for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) {int16_t r = mdec->crblk[((x + xx) >> 1) + ((y + yy) >> 1) * 8];
@@ -143,17 +143,17 @@
uint16_t g5 = ((uint8_t)g) >> 3;
uint16_t b5 = ((uint8_t)b) >> 3;
- uint16_t rgb = (b << 10) | (g << 5) | r;
+ uint16_t rgb = (b5 << 10) | (g5 << 5) | r5;
if (mdec->output_bit15)
rgb |= 0x8000;
- mdec->output[0 + ((x + xx) + (y + yy) * 16) * 2] = rgb & 0xff;
- mdec->output[1 + ((x + xx) + (y + yy) * 16) * 2] = rgb >> 8;
+ buf[0 + ((x + xx) + (y + yy) * 16) * 2] = rgb & 0xff;
+ buf[1 + ((x + xx) + (y + yy) * 16) * 2] = rgb >> 8;
} else {- mdec->output[0 + ((x + xx) + (y + yy) * 16) * 3] = r & 0xff;
- mdec->output[1 + ((x + xx) + (y + yy) * 16) * 3] = g & 0xff;
- mdec->output[2 + ((x + xx) + (y + yy) * 16) * 3] = b & 0xff;
+ buf[0 + ((x + xx) + (y + yy) * 16) * 3] = r & 0xff;
+ buf[1 + ((x + xx) + (y + yy) * 16) * 3] = g & 0xff;
+ buf[2 + ((x + xx) + (y + yy) * 16) * 3] = b & 0xff;
}
}
}
@@ -180,25 +180,58 @@
mdec->output_empty = 0;
mdec->output_index = 0;
} else {- uint16_t* ptr = mdec->input;
+ uint16_t* in = mdec->input;
+ uint8_t* out;
- ptr = rl_decode_block(mdec->crblk, ptr, mdec->uv_quant_table, mdec->scale_table);
- ptr = rl_decode_block(mdec->cbblk, ptr, mdec->uv_quant_table, mdec->scale_table);
- ptr = rl_decode_block(mdec->yblk, ptr, mdec->y_quant_table, mdec->scale_table);
- yuv_to_rgb(mdec, 0, 0);
- ptr = rl_decode_block(mdec->yblk, ptr, mdec->y_quant_table, mdec->scale_table);
- yuv_to_rgb(mdec, 0, 8);
- ptr = rl_decode_block(mdec->yblk, ptr, mdec->y_quant_table, mdec->scale_table);
- yuv_to_rgb(mdec, 8, 0);
- ptr = rl_decode_block(mdec->yblk, ptr, mdec->y_quant_table, mdec->scale_table);
- yuv_to_rgb(mdec, 8, 8);
+ size_t block_size = (mdec->output_depth == 3) ? 512 : 768;
+ size_t size = block_size;
- mdec->output_words_remaining = ((mdec->output_depth == 3) ? 512 : 768) >> 2;
+ unsigned int bytes_processed = 0;
+
+ while (bytes_processed < mdec->input_size) {+ if (!mdec->output) {+ mdec->output = malloc(size);
+
+ out = mdec->output;
+ } else {+ mdec->output = realloc(mdec->output, size);
+ }
+
+ in = rl_decode_block(mdec->crblk, in, mdec->uv_quant_table, mdec->scale_table);
+ in = rl_decode_block(mdec->cbblk, in, mdec->uv_quant_table, mdec->scale_table);
+ in = rl_decode_block(mdec->yblk, in, mdec->y_quant_table, mdec->scale_table);
+ yuv_to_rgb(mdec, out, 0, 0);
+ in = rl_decode_block(mdec->yblk, in, mdec->y_quant_table, mdec->scale_table);
+ yuv_to_rgb(mdec, out, 0, 8);
+ in = rl_decode_block(mdec->yblk, in, mdec->y_quant_table, mdec->scale_table);
+ yuv_to_rgb(mdec, out, 8, 0);
+ in = rl_decode_block(mdec->yblk, in, mdec->y_quant_table, mdec->scale_table);
+ yuv_to_rgb(mdec, out, 8, 8);
+
+ size += block_size;
+ out += block_size;
+
+ bytes_processed = (uintptr_t)in - (uintptr_t)mdec->input;
+
+ log_set_quiet(0);
+ log_fatal("Decompressed 1 macroblock (%u total bytes processed) output=%p, output+size=%p, output ptr=%p",+ bytes_processed, mdec->output, mdec->output + size, out
+ );
+ log_set_quiet(1);
+ }
+
+ mdec->output_words_remaining = size >> 2;
mdec->output_empty = 0;
mdec->output_index = 0;
log_set_quiet(0);
- log_fatal("Finished decoding %u-bit MDEC data", (mdec->output_depth == 3) ? 15 : 24);+ log_fatal("Finished decoding %u-bit MDEC data input=(%p-%p=%04x, %04x)",+ (mdec->output_depth == 3) ? 15 : 24,
+ in,
+ mdec->input,
+ (uintptr_t)in - (uintptr_t)mdec->input,
+ mdec->input_size
+ );
log_set_quiet(1);
}
}
@@ -252,6 +285,8 @@
} else {mdec->output_empty = 1;
mdec->output_index = 0;
+
+ return 0xaabbccdd;
}
} break;
case 4: {@@ -356,9 +391,10 @@
log_set_quiet(1);
if (mdec->words_remaining) {+ mdec->input_size = mdec->words_remaining * sizeof(uint32_t);
mdec->input_full = 0;
mdec->input_index = 0;
- mdec->input = malloc(mdec->words_remaining * sizeof(uint32_t));
+ mdec->input = malloc(mdec->input_size);
}
} break;
--- a/psx/dev/mdec.h
+++ b/psx/dev/mdec.h
@@ -52,8 +52,9 @@
uint32_t* input;
int input_index;
+ size_t input_size;
- uint8_t output[(16 * 16) * 3];
+ uint8_t* output;
int output_index;
uint16_t output_words_remaining;
--
⑨