mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-12 19:19:04 +00:00
Improve color space conversion
Use both the color space and color range from FFmpeg to determine the appropriate SDL YUV conversion mode.
This commit is contained in:
parent
0b840dcef1
commit
d7e0d36fe6
3 changed files with 29 additions and 10 deletions
|
@ -125,14 +125,26 @@ sc_display_destroy(struct sc_display *display) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_YUV_CONVERSION_MODE
|
static SDL_YUV_CONVERSION_MODE
|
||||||
sc_display_to_sdl_color_range(enum AVColorRange color_range) {
|
sc_display_to_sdl_color_mode(enum AVColorSpace color_space,
|
||||||
return color_range == AVCOL_RANGE_JPEG ? SDL_YUV_CONVERSION_JPEG
|
enum AVColorRange color_range) {
|
||||||
: SDL_YUV_CONVERSION_AUTOMATIC;
|
switch (color_space) {
|
||||||
|
case AVCOL_SPC_BT709:
|
||||||
|
return SDL_YUV_CONVERSION_BT709;
|
||||||
|
case AVCOL_SPC_BT470BG:
|
||||||
|
case AVCOL_SPC_SMPTE170M:
|
||||||
|
return SDL_YUV_CONVERSION_BT601;
|
||||||
|
default:
|
||||||
|
if (color_range == AVCOL_RANGE_JPEG) {
|
||||||
|
return SDL_YUV_CONVERSION_JPEG;
|
||||||
|
}
|
||||||
|
return SDL_YUV_CONVERSION_AUTOMATIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_Texture *
|
static SDL_Texture *
|
||||||
sc_display_create_texture(struct sc_display *display,
|
sc_display_create_texture(struct sc_display *display,
|
||||||
struct sc_size size, enum AVColorRange color_range) {
|
struct sc_size size, enum AVColorSpace color_space,
|
||||||
|
enum AVColorRange color_range) {
|
||||||
SDL_Renderer *renderer = display->renderer;
|
SDL_Renderer *renderer = display->renderer;
|
||||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
|
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
@ -156,9 +168,9 @@ sc_display_create_texture(struct sc_display *display,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure YUV color range conversion
|
// Configure YUV color range conversion
|
||||||
SDL_YUV_CONVERSION_MODE sdl_color_range =
|
SDL_YUV_CONVERSION_MODE sdl_color_mode =
|
||||||
sc_display_to_sdl_color_range(color_range);
|
sc_display_to_sdl_color_mode(color_space, color_range);
|
||||||
SDL_SetYUVConversionMode(sdl_color_range);
|
SDL_SetYUVConversionMode(sdl_color_mode);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
@ -201,6 +213,7 @@ sc_display_apply_pending(struct sc_display *display) {
|
||||||
display->texture =
|
display->texture =
|
||||||
sc_display_create_texture(display,
|
sc_display_create_texture(display,
|
||||||
display->pending.texture.size,
|
display->pending.texture.size,
|
||||||
|
display->pending.texture.color_space,
|
||||||
display->pending.texture.color_range);
|
display->pending.texture.color_range);
|
||||||
if (!display->texture) {
|
if (!display->texture) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -226,6 +239,7 @@ sc_display_apply_pending(struct sc_display *display) {
|
||||||
static bool
|
static bool
|
||||||
sc_display_prepare_texture_internal(struct sc_display *display,
|
sc_display_prepare_texture_internal(struct sc_display *display,
|
||||||
struct sc_size size,
|
struct sc_size size,
|
||||||
|
enum AVColorSpace color_space,
|
||||||
enum AVColorRange color_range) {
|
enum AVColorRange color_range) {
|
||||||
assert(size.width && size.height);
|
assert(size.width && size.height);
|
||||||
|
|
||||||
|
@ -233,7 +247,8 @@ sc_display_prepare_texture_internal(struct sc_display *display,
|
||||||
SDL_DestroyTexture(display->texture);
|
SDL_DestroyTexture(display->texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
display->texture = sc_display_create_texture(display, size, color_range);
|
display->texture =
|
||||||
|
sc_display_create_texture(display, size, color_space, color_range);
|
||||||
if (!display->texture) {
|
if (!display->texture) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -244,8 +259,10 @@ sc_display_prepare_texture_internal(struct sc_display *display,
|
||||||
|
|
||||||
enum sc_display_result
|
enum sc_display_result
|
||||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||||
|
enum AVColorSpace color_space,
|
||||||
enum AVColorRange color_range) {
|
enum AVColorRange color_range) {
|
||||||
bool ok = sc_display_prepare_texture_internal(display, size, color_range);
|
bool ok = sc_display_prepare_texture_internal(display, size, color_space,
|
||||||
|
color_range);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
sc_display_set_pending_texture(display, size, color_range);
|
sc_display_set_pending_texture(display, size, color_range);
|
||||||
return SC_DISPLAY_RESULT_PENDING;
|
return SC_DISPLAY_RESULT_PENDING;
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct sc_display {
|
||||||
int8_t flags;
|
int8_t flags;
|
||||||
struct {
|
struct {
|
||||||
struct sc_size size;
|
struct sc_size size;
|
||||||
|
enum AVColorSpace color_space;
|
||||||
enum AVColorRange color_range;
|
enum AVColorRange color_range;
|
||||||
} texture;
|
} texture;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
@ -54,6 +55,7 @@ sc_display_destroy(struct sc_display *display);
|
||||||
|
|
||||||
enum sc_display_result
|
enum sc_display_result
|
||||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||||
|
enum AVColorSpace color_space,
|
||||||
enum AVColorRange color_range);
|
enum AVColorRange color_range);
|
||||||
|
|
||||||
enum sc_display_result
|
enum sc_display_result
|
||||||
|
|
|
@ -620,7 +620,7 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
||||||
|
|
||||||
enum sc_display_result res =
|
enum sc_display_result res =
|
||||||
sc_display_prepare_texture(&screen->display, screen->frame_size,
|
sc_display_prepare_texture(&screen->display, screen->frame_size,
|
||||||
frame->color_range);
|
frame->colorspace, frame->color_range);
|
||||||
if (res == SC_DISPLAY_RESULT_ERROR) {
|
if (res == SC_DISPLAY_RESULT_ERROR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue