set_texture_from_frame

This commit is contained in:
Romain Vimont
2026-01-28 19:39:53 +01:00
parent 72658ef5aa
commit 5540e93bcb
3 changed files with 48 additions and 34 deletions

View File

@@ -77,9 +77,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;
@@ -154,28 +155,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],
@@ -210,5 +223,9 @@ 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;
}

View File

@@ -11,9 +11,17 @@
#include "coords.h"
#include "opengl.h"
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;
@@ -29,12 +37,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,

View File

@@ -703,13 +703,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;
@@ -725,7 +718,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;
}