From 82c0ffc69b0f0078d8d6ba14cb8776417b45cab5 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 24 Jan 2026 22:13:14 +0100 Subject: [PATCH] set_texture_from_frame --- app/src/display.c | 57 ++++++++++++++++++++++++++++++----------------- app/src/display.h | 16 ++++++++----- app/src/screen.c | 9 +------- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/app/src/display.c b/app/src/display.c index ba0e373d..69b4f481 100644 --- a/app/src/display.c +++ b/app/src/display.c @@ -102,9 +102,10 @@ sc_display_to_sdl_color_space(enum AVColorSpace color_space, } static SDL_Texture * -sc_display_create_texture(struct sc_display *display, - struct sc_size size, enum AVColorSpace color_space, - enum AVColorRange color_range) { +sc_display_create_frame_texture(struct sc_display *display, + struct sc_size size, + enum AVColorSpace color_space, + enum AVColorRange color_range) { SDL_PropertiesID props = SDL_CreateProperties(); if (!props) { return NULL; @@ -179,28 +180,40 @@ sc_display_create_texture(struct sc_display *display, } bool -sc_display_prepare_texture(struct sc_display *display, struct sc_size size, - enum AVColorSpace color_space, - enum AVColorRange color_range) { +sc_display_set_texture_from_frame(struct sc_display *display, + const AVFrame *frame) { + + struct sc_size size = {frame->width, frame->height}; assert(size.width && size.height); - if (display->texture) { - SDL_DestroyTexture(display->texture); + if (!display->texture + || display->texture_type != SC_TEXTURE_TYPE_FRAME + || display->texture_size.width != size.width + || display->texture_size.height != size.height) { + // Incompatible texture, recreate it + enum AVColorSpace color_space = frame->colorspace; + enum AVColorRange color_range = frame->color_range; + + if (display->texture) { + SDL_DestroyTexture(display->texture); + } + + display->texture = sc_display_create_frame_texture(display, size, + color_space, + color_range); + if (!display->texture) { + return false; + } + + display->texture_size = size; + display->texture_type = SC_TEXTURE_TYPE_FRAME; + + LOGI("Texture: %" PRIu16 "x%" PRIu16, size.width, size.height); } - display->texture = - sc_display_create_texture(display, size, color_space, color_range); - if (!display->texture) { - return false; - } - - LOGI("Texture: %" PRIu16 "x%" PRIu16, size.width, size.height); - return true; -} - -bool -sc_display_update_texture(struct sc_display *display, const AVFrame *frame) { assert(display->texture); + assert(display->texture_type == SC_TEXTURE_TYPE_FRAME); + bool ok = SDL_UpdateYUVTexture(display->texture, NULL, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], @@ -235,6 +248,10 @@ sc_display_set_texture_from_surface(struct sc_display *display, return false; } + display->texture_size.width = surface->w; + display->texture_size.height = surface->h; + display->texture_type = SC_TEXTURE_TYPE_ICON; + return true; } diff --git a/app/src/display.h b/app/src/display.h index 4fc4ab9d..75d3f313 100644 --- a/app/src/display.h +++ b/app/src/display.h @@ -15,9 +15,17 @@ # define SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE #endif +enum sc_texture_type { + SC_TEXTURE_TYPE_FRAME, + SC_TEXTURE_TYPE_ICON, +}; + struct sc_display { SDL_Renderer *renderer; // owned by the caller SDL_Texture *texture; + // Only valid if texture != NULL + struct sc_size texture_size; + enum sc_texture_type texture_type; struct sc_opengl gl; #ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE @@ -36,12 +44,8 @@ void sc_display_destroy(struct sc_display *display); bool -sc_display_prepare_texture(struct sc_display *display, struct sc_size size, - enum AVColorSpace color_space, - enum AVColorRange color_range); - -bool -sc_display_update_texture(struct sc_display *display, const AVFrame *frame); +sc_display_set_texture_from_frame(struct sc_display *display, + const AVFrame *frame); bool sc_display_set_texture_from_surface(struct sc_display *display, diff --git a/app/src/screen.c b/app/src/screen.c index 97bc1d42..f68e1c53 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -668,13 +668,6 @@ sc_screen_apply_frame(struct sc_screen *screen) { || screen->frame_size.width != new_frame_size.width || screen->frame_size.height != new_frame_size.height) { - bool ok = - sc_display_prepare_texture(&screen->display, new_frame_size, - frame->colorspace, frame->color_range); - if (!ok) { - return false; - } - // frame dimension changed screen->frame_size = new_frame_size; @@ -690,7 +683,7 @@ sc_screen_apply_frame(struct sc_screen *screen) { } } - bool ok = sc_display_update_texture(&screen->display, frame); + bool ok = sc_display_set_texture_from_frame(&screen->display, frame); if (!ok) { return false; }