mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-01-14 11:14:29 +01:00
Set color range during texture creation
This prepares for the migration to SDL3, where the color range can only be specified at the time of texture creation. PR #6216 <https://github.com/Genymobile/scrcpy/pull/6216>
This commit is contained in:
@@ -94,7 +94,6 @@ sc_display_init(struct sc_display *display, SDL_Window *window,
|
||||
display->texture = NULL;
|
||||
display->pending.flags = 0;
|
||||
display->pending.frame = NULL;
|
||||
display->has_frame = false;
|
||||
|
||||
if (icon_novideo) {
|
||||
// Without video, set a static scrcpy icon as window content
|
||||
@@ -125,9 +124,15 @@ sc_display_destroy(struct sc_display *display) {
|
||||
SDL_DestroyRenderer(display->renderer);
|
||||
}
|
||||
|
||||
static SDL_YUV_CONVERSION_MODE
|
||||
sc_display_to_sdl_color_range(enum AVColorRange color_range) {
|
||||
return color_range == AVCOL_RANGE_JPEG ? SDL_YUV_CONVERSION_JPEG
|
||||
: SDL_YUV_CONVERSION_AUTOMATIC;
|
||||
}
|
||||
|
||||
static SDL_Texture *
|
||||
sc_display_create_texture(struct sc_display *display,
|
||||
struct sc_size size) {
|
||||
struct sc_size size, enum AVColorRange color_range) {
|
||||
SDL_Renderer *renderer = display->renderer;
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
@@ -150,14 +155,22 @@ sc_display_create_texture(struct sc_display *display,
|
||||
SDL_GL_UnbindTexture(texture);
|
||||
}
|
||||
|
||||
// Configure YUV color range conversion
|
||||
SDL_YUV_CONVERSION_MODE sdl_color_range =
|
||||
sc_display_to_sdl_color_range(color_range);
|
||||
SDL_SetYUVConversionMode(sdl_color_range);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static inline void
|
||||
sc_display_set_pending_size(struct sc_display *display, struct sc_size size) {
|
||||
sc_display_set_pending_texture(struct sc_display *display,
|
||||
struct sc_size size,
|
||||
enum AVColorRange color_range) {
|
||||
assert(!display->texture);
|
||||
display->pending.size = size;
|
||||
display->pending.flags |= SC_DISPLAY_PENDING_FLAG_SIZE;
|
||||
display->pending.texture.size = size;
|
||||
display->pending.texture.color_range = color_range;
|
||||
display->pending.flags |= SC_DISPLAY_PENDING_FLAG_TEXTURE;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -189,15 +202,17 @@ sc_display_update_texture_internal(struct sc_display *display,
|
||||
|
||||
static bool
|
||||
sc_display_apply_pending(struct sc_display *display) {
|
||||
if (display->pending.flags & SC_DISPLAY_PENDING_FLAG_SIZE) {
|
||||
if (display->pending.flags & SC_DISPLAY_PENDING_FLAG_TEXTURE) {
|
||||
assert(!display->texture);
|
||||
display->texture =
|
||||
sc_display_create_texture(display, display->pending.size);
|
||||
sc_display_create_texture(display,
|
||||
display->pending.texture.size,
|
||||
display->pending.texture.color_range);
|
||||
if (!display->texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
display->pending.flags &= ~SC_DISPLAY_PENDING_FLAG_SIZE;
|
||||
display->pending.flags &= ~SC_DISPLAY_PENDING_FLAG_TEXTURE;
|
||||
}
|
||||
|
||||
if (display->pending.flags & SC_DISPLAY_PENDING_FLAG_FRAME) {
|
||||
@@ -216,15 +231,16 @@ sc_display_apply_pending(struct sc_display *display) {
|
||||
}
|
||||
|
||||
static bool
|
||||
sc_display_set_texture_size_internal(struct sc_display *display,
|
||||
struct sc_size size) {
|
||||
sc_display_prepare_texture_internal(struct sc_display *display,
|
||||
struct sc_size size,
|
||||
enum AVColorRange color_range) {
|
||||
assert(size.width && size.height);
|
||||
|
||||
if (display->texture) {
|
||||
SDL_DestroyTexture(display->texture);
|
||||
}
|
||||
|
||||
display->texture = sc_display_create_texture(display, size);
|
||||
display->texture = sc_display_create_texture(display, size, color_range);
|
||||
if (!display->texture) {
|
||||
return false;
|
||||
}
|
||||
@@ -234,10 +250,11 @@ sc_display_set_texture_size_internal(struct sc_display *display,
|
||||
}
|
||||
|
||||
enum sc_display_result
|
||||
sc_display_set_texture_size(struct sc_display *display, struct sc_size size) {
|
||||
bool ok = sc_display_set_texture_size_internal(display, size);
|
||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||
enum AVColorRange color_range) {
|
||||
bool ok = sc_display_prepare_texture_internal(display, size, color_range);
|
||||
if (!ok) {
|
||||
sc_display_set_pending_size(display, size);
|
||||
sc_display_set_pending_texture(display, size, color_range);
|
||||
return SC_DISPLAY_RESULT_PENDING;
|
||||
|
||||
}
|
||||
@@ -245,25 +262,9 @@ sc_display_set_texture_size(struct sc_display *display, struct sc_size size) {
|
||||
return SC_DISPLAY_RESULT_OK;
|
||||
}
|
||||
|
||||
static SDL_YUV_CONVERSION_MODE
|
||||
sc_display_to_sdl_color_range(enum AVColorRange color_range) {
|
||||
return color_range == AVCOL_RANGE_JPEG ? SDL_YUV_CONVERSION_JPEG
|
||||
: SDL_YUV_CONVERSION_AUTOMATIC;
|
||||
}
|
||||
|
||||
static bool
|
||||
sc_display_update_texture_internal(struct sc_display *display,
|
||||
const AVFrame *frame) {
|
||||
if (!display->has_frame) {
|
||||
// First frame
|
||||
display->has_frame = true;
|
||||
|
||||
// Configure YUV color range conversion
|
||||
SDL_YUV_CONVERSION_MODE sdl_color_range =
|
||||
sc_display_to_sdl_color_range(frame->color_range);
|
||||
SDL_SetYUVConversionMode(sdl_color_range);
|
||||
}
|
||||
|
||||
int ret = SDL_UpdateYUVTexture(display->texture, NULL,
|
||||
frame->data[0], frame->linesize[0],
|
||||
frame->data[1], frame->linesize[1],
|
||||
|
||||
@@ -28,14 +28,15 @@ struct sc_display {
|
||||
bool mipmaps;
|
||||
|
||||
struct {
|
||||
#define SC_DISPLAY_PENDING_FLAG_SIZE 1
|
||||
#define SC_DISPLAY_PENDING_FLAG_TEXTURE 1
|
||||
#define SC_DISPLAY_PENDING_FLAG_FRAME 2
|
||||
int8_t flags;
|
||||
struct sc_size size;
|
||||
struct {
|
||||
struct sc_size size;
|
||||
enum AVColorRange color_range;
|
||||
} texture;
|
||||
AVFrame *frame;
|
||||
} pending;
|
||||
|
||||
bool has_frame;
|
||||
};
|
||||
|
||||
enum sc_display_result {
|
||||
@@ -52,7 +53,8 @@ void
|
||||
sc_display_destroy(struct sc_display *display);
|
||||
|
||||
enum sc_display_result
|
||||
sc_display_set_texture_size(struct sc_display *display, struct sc_size size);
|
||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||
enum AVColorRange color_range);
|
||||
|
||||
enum sc_display_result
|
||||
sc_display_update_texture(struct sc_display *display, const AVFrame *frame);
|
||||
|
||||
@@ -619,7 +619,8 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
||||
}
|
||||
|
||||
enum sc_display_result res =
|
||||
sc_display_set_texture_size(&screen->display, screen->frame_size);
|
||||
sc_display_prepare_texture(&screen->display, screen->frame_size,
|
||||
frame->color_range);
|
||||
if (res == SC_DISPLAY_RESULT_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user