diff --git a/scripts/core/_sdl_video.js b/scripts/core/_sdl_video.js index 3184b52c..e2681350 100644 --- a/scripts/core/_sdl_video.js +++ b/scripts/core/_sdl_video.js @@ -429,23 +429,12 @@ function handle_renderer(msg) { if (!msg.data) return {error: "Missing data"}; var tex; - // Load from surface ID - if (msg.data.surface_id) { - var surf = resources.surface[msg.data.surface_id]; - if (!surf) return {error: "Invalid surface id"}; - tex = ren.load_texture(surf); - } - // Load from raw surface object (for graphics module) - else if (msg.data.surface) { - tex = ren.load_texture(new surface(msg.data)); - } // Direct surface data - else if (msg.data.width && msg.data.height) { - tex = ren.load_texture(new surface(msg.data)); - } - else { + var surf = new surface(msg.data) + if (!surf) return {error: "Must provide surface_id or surface data"}; - } + + tex = ren.load_texture(surf); if (!tex) return {error: "Failed to load texture"}; var tex_id = allocate_id(); diff --git a/source/qjs_sdl.c b/source/qjs_sdl.c index 0829851a..c47d41aa 100644 --- a/source/qjs_sdl.c +++ b/source/qjs_sdl.c @@ -162,7 +162,7 @@ JSValue js_input_use(JSContext *js) { // CAMERA FUNCTIONS // Helper functions for camera format conversion -static const char *pixelformat2str(SDL_PixelFormat format) { +const char *pixelformat2str(SDL_PixelFormat format) { switch(format) { case SDL_PIXELFORMAT_UNKNOWN: return "unknown"; case SDL_PIXELFORMAT_INDEX1LSB: return "index1lsb"; @@ -231,7 +231,7 @@ static const char *pixelformat2str(SDL_PixelFormat format) { } } -static SDL_PixelFormat str2pixelformat(const char *str) { +SDL_PixelFormat str2pixelformat(const char *str) { if (!strcmp(str, "unknown")) return SDL_PIXELFORMAT_UNKNOWN; if (!strcmp(str, "index1lsb")) return SDL_PIXELFORMAT_INDEX1LSB; if (!strcmp(str, "index1msb")) return SDL_PIXELFORMAT_INDEX1MSB; @@ -439,6 +439,7 @@ JSC_CCALL(camera_capture, // Create a copy of the surface SDL_Surface *newsurf = SDL_CreateSurface(surf->w, surf->h, surf->format); + if (!newsurf) { SDL_ReleaseCameraFrame(cam, surf); return JS_ThrowReferenceError(js, "Could not create surface: %s", SDL_GetError()); diff --git a/source/qjs_sdl_surface.c b/source/qjs_sdl_surface.c index f511f648..b487c093 100644 --- a/source/qjs_sdl_surface.c +++ b/source/qjs_sdl_surface.c @@ -13,36 +13,13 @@ extern rect js2rect(JSContext *js, JSValue v); extern irect js2irect(JSContext *js, JSValue v); extern colorf js2color(JSContext *js, JSValue v); extern HMM_Vec2 js2vec2(JSContext *js, JSValue v); - -// Type conversion functions -typedef struct { const char *name; SDL_PixelFormat fmt; } fmt_entry; - -static const fmt_entry k_fmt_table[] = { - { "rgba32", SDL_PIXELFORMAT_RGBA32 }, - { "argb32", SDL_PIXELFORMAT_ARGB32 }, - { "bgra32", SDL_PIXELFORMAT_BGRA32 }, - { "abgr32", SDL_PIXELFORMAT_ABGR32 }, - { "rgb565", SDL_PIXELFORMAT_RGB565 }, - { "bgr565", SDL_PIXELFORMAT_BGR565 }, - { "rgb24", SDL_PIXELFORMAT_RGB24 }, - { "bgr24", SDL_PIXELFORMAT_BGR24 }, - { "rgb332", SDL_PIXELFORMAT_RGB332 }, - { "rgba64", SDL_PIXELFORMAT_RGBA64 }, - { "rgb48", SDL_PIXELFORMAT_RGB48 }, - { NULL, SDL_PIXELFORMAT_UNKNOWN } -}; +extern SDL_PixelFormat str2pixelformat(const char *str); +extern const char *pixelformat2str(SDL_PixelFormat fmt); static JSValue pixelformat2js(JSContext *js, SDL_PixelFormat fmt) { - fmt_entry *it; - for (it = (fmt_entry*)k_fmt_table; it->name; it++) - if (it->fmt == fmt) - break; - - if (it->name) - return JS_NewString(js, it->name); - - return JS_UNDEFINED; + const char *str = pixelformat2str(fmt); + return JS_NewString(js, str); } static SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v) @@ -51,13 +28,9 @@ static SDL_PixelFormat js2pixelformat(JSContext *js, JSValue v) const char *s = JS_ToCString(js, v); if (!s) return SDL_PIXELFORMAT_UNKNOWN; - fmt_entry *it; - for (it = (fmt_entry*)k_fmt_table; it->name; it++) - if (!strcmp(it->name, s)) - break; - + SDL_PixelFormat fmt = str2pixelformat(s); JS_FreeCString(js,s); - return it->fmt; + return fmt; } typedef struct { const char *name; SDL_ScaleMode mode; } scale_entry; @@ -182,26 +155,24 @@ JSC_CCALL(surface_dup, ) JSC_CCALL(surface_pixels, - SDL_Surface *surf = js2SDL_Surface(js,self); - -/* if (SDL_ISPIXELFORMAT_FOURCC(surf->format->format)) - return JS_ThrowTypeError(js, "planar or FOURCC formats are not supported - convert first"); -*/ - + SDL_Surface *surf = js2SDL_Surface(js, self); + int locked = 0; - if (SDL_MUSTLOCK(surf)) { + if (SDL_MUSTLOCK(surf)) if (SDL_LockSurface(surf) < 0) - return JS_ThrowInternalError(js, "Lock surface failed: %s", SDL_GetError()); - - locked = 1; - } - - size_t byte_size = surf->pitch*surf->h; + return JS_ThrowReferenceError(js, "Lock surface failed: %s", SDL_GetError()); + 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); + } else + byte_size = (size_t)surf->pitch * surf->h; + ret = JS_NewArrayBufferCopy(js, surf->pixels, byte_size); - - if (locked) - SDL_UnlockSurface(surf); + + if (locked) SDL_UnlockSurface(surf); ) JSC_CCALL(surface_get_width, diff --git a/tests/webcam.js b/tests/webcam.js index 23eeb2ea..fcbf08d9 100644 --- a/tests/webcam.js +++ b/tests/webcam.js @@ -164,7 +164,9 @@ function start_capturing() { // Capture frame from camera var surface = cam_obj.capture(); - console.log(`rendering cam! ${json.encode(surface)}`) + + surface = surface.convert("abgr8888") + if (surface) { // Create texture from surface directly send(video_actor, { @@ -204,10 +206,11 @@ function start_capturing() { } // Draw info + /* draw2d.text("Camera: " + camera.name(cam_id), {x: 20, y: 20, size: 16}); draw2d.text("Position: " + camera.position(cam_id), {x: 20, y: 40, size: 16}); draw2d.text("Frame: " + frame, {x: 20, y: 60, size: 16}); - + */ // Flush all commands to renderer draw2d.flush();