Skip to content

Instantly share code, notes, and snippets.

@x-labz
Last active January 12, 2022 15:45
Show Gist options
  • Save x-labz/8c6f5d4fafecfc8cad023cd74cf2833e to your computer and use it in GitHub Desktop.
Save x-labz/8c6f5d4fafecfc8cad023cd74cf2833e to your computer and use it in GitHub Desktop.
frame transformer for wasm
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define WASM_EXPORT __attribute__((visibility("default")))
uint16_t w; // frame width
uint16_t h ; // frame height
uint8_t * input_buffer;
uint8_t * out_buffer;
uint8_t * bg_buffer ; // buffer for background image
WASM_EXPORT
uint8_t * init_in(uint16_t w_in, uint16_t h_in) {
w = w_in;
h = h_in;
input_buffer = malloc(w*h*1.5) ; // input buffer for YUV format
return input_buffer ;
}
WASM_EXPORT
uint8_t * init_out(void) {
out_buffer = malloc(w*h*4) ; // output buffer for RGBA format
return out_buffer ;
}
WASM_EXPORT
uint8_t * init_bg_img(void) {
bg_buffer = malloc(w*h*4) ; // background image, RGBA format
return bg_buffer ;
}
// saturation function
inline uint8_t sat (float val) {
if (val > 255) return 255;
if (val < 0) return 0;
return (uint8_t)val ;
};
// frame processor function
WASM_EXPORT
void process(uint32_t stride, uint32_t offset1, uint32_t offset2) {
uint32_t xUV = 0;
uint32_t yUV = 0;
for (uint32_t y=0; y != h; y++) {
yUV = (y >> 1) * stride;
for (uint32_t x= 0; x != w; x++) {
xUV = x >> 1;
float Y = (float)input_buffer[x + y * w];
float V = (float)input_buffer[offset1 + xUV + yUV] - 128;
float U = (float)input_buffer[offset2 + xUV + yUV] - 128;
uint8_t R = sat(Y + 1.370705 * V);
uint8_t G = sat(Y - 0.698001 * V - 0.337633 * U);
uint8_t B = sat(Y + 1.732446 * U);
uint32_t p = x * 4 + y * w * 4 ;
if ( G > 0.6 * (R + B) ) {
R = bg_buffer[0 + p];
G = bg_buffer[1 + p];
B = bg_buffer[2 + p];
}
out_buffer[0 + p] = R;
out_buffer[1 + p] = G;
out_buffer[2 + p] = B;
out_buffer[3 + p] = 255;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment