mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-02-14 10:24:29 +01:00
Set display texture from a frame
Add a function to set a texture from an AVFrame on a sc_display. PR #6651 <https://github.com/Genymobile/scrcpy/pull/6651>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -704,13 +704,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;
|
||||
|
||||
@@ -726,7 +719,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user