diff --git a/scripts/core/_sdl_video.js b/scripts/core/_sdl_video.js index e2681350..e433ddbd 100644 --- a/scripts/core/_sdl_video.js +++ b/scripts/core/_sdl_video.js @@ -431,6 +431,7 @@ function handle_renderer(msg) { var tex; // Direct surface data var surf = new surface(msg.data) + if (!surf) return {error: "Must provide surface_id or surface data"}; diff --git a/source/qjs_sdl_surface.c b/source/qjs_sdl_surface.c index b487c093..c54b21ed 100644 --- a/source/qjs_sdl_surface.c +++ b/source/qjs_sdl_surface.c @@ -154,25 +154,32 @@ JSC_CCALL(surface_dup, return SDL_Surface2js(js,conv); ) -JSC_CCALL(surface_pixels, - SDL_Surface *surf = js2SDL_Surface(js, self); - +void *surface_pixel_dup(SDL_Surface *surf, size_t *size) +{ int locked = 0; if (SDL_MUSTLOCK(surf)) if (SDL_LockSurface(surf) < 0) - return JS_ThrowReferenceError(js, "Lock surface failed: %s", SDL_GetError()); + return NULL; - size_t byte_size; - if (SDL_ISPIXELFORMAT_FOURCC(surf->format)) { - /* Planar/YUV formats: use BitsPerPixel to compute true size */ - printf("FOURCC!!! Bits is %d\n", SDL_BYTESPERPIXEL(surf->format)); - byte_size = (size_t)surf->pitch * surf->h * SDL_BYTESPERPIXEL(surf->format); + if (surf->format == SDL_PIXELFORMAT_NV12) { + *size = surf->pitch * (surf->h*3.0/2.0); } else - byte_size = (size_t)surf->pitch * surf->h; - - ret = JS_NewArrayBufferCopy(js, surf->pixels, byte_size); - + *size = (size_t)surf->pitch * surf->h; + + void *data = malloc(*size); + memcpy(data, surf->pixels, *size); + if (locked) SDL_UnlockSurface(surf); + + return data; +} + +JSC_CCALL(surface_pixels, + SDL_Surface *surf = js2SDL_Surface(js, self); + + size_t size; + void *data = surface_pixel_dup(surf, &size); + return JS_NewArrayBufferCopy(js, data, size); ) JSC_CCALL(surface_get_width, @@ -211,25 +218,10 @@ JSC_CCALL(surface_toJSON, // Add pitch JS_SetPropertyStr(js, obj, "pitch", JS_NewInt32(js, surf->pitch)); - // Lock surface if needed - int locked = 0; - if (SDL_MUSTLOCK(surf)) { - if (SDL_LockSurface(surf) < 0) { - JS_FreeValue(js, obj); - return JS_ThrowInternalError(js, "Lock surface failed: %s", SDL_GetError()); - } - locked = 1; - } - - // Add pixels as ArrayBuffer - size_t byte_size = surf->pitch * surf->h; - JSValue pixels = JS_NewArrayBufferCopy(js, surf->pixels, byte_size); - JS_SetPropertyStr(js, obj, "pixels", pixels); - - // Unlock if we locked - if (locked) - SDL_UnlockSurface(surf); + size_t size; + void *pixels = surface_pixel_dup(surf, &size); + JS_SetPropertyStr(js, obj, "pixels", JS_NewArrayBufferCopy(js, pixels, size)); return obj; ) diff --git a/tests/webcam.js b/tests/webcam.js index fcbf08d9..49903ed4 100644 --- a/tests/webcam.js +++ b/tests/webcam.js @@ -163,9 +163,7 @@ function start_capturing() { draw2d.clear(); // Capture frame from camera - var surface = cam_obj.capture(); - - surface = surface.convert("abgr8888") + var surface = cam_obj.capture().convert("rgba8888"); if (surface) { // Create texture from surface directly @@ -247,4 +245,4 @@ function start_capturing() { } // Stop after 12 seconds if not already stopped -$_.delay($_.stop, 12); \ No newline at end of file +$_.delay($_.stop, 12);1 \ No newline at end of file