mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-10 01:59: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
|
||||
sc_display_to_sdl_color_range(enum AVColorRange color_range) {
|
||||
return color_range == AVCOL_RANGE_JPEG ? SDL_YUV_CONVERSION_JPEG
|
||||
: SDL_YUV_CONVERSION_AUTOMATIC;
|
||||
sc_display_to_sdl_color_mode(enum AVColorSpace color_space,
|
||||
enum AVColorRange color_range) {
|
||||
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 *
|
||||
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_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
|
@ -156,9 +168,9 @@ sc_display_create_texture(struct sc_display *display,
|
|||
}
|
||||
|
||||
// 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);
|
||||
SDL_YUV_CONVERSION_MODE sdl_color_mode =
|
||||
sc_display_to_sdl_color_mode(color_space, color_range);
|
||||
SDL_SetYUVConversionMode(sdl_color_mode);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
@ -201,6 +213,7 @@ sc_display_apply_pending(struct sc_display *display) {
|
|||
display->texture =
|
||||
sc_display_create_texture(display,
|
||||
display->pending.texture.size,
|
||||
display->pending.texture.color_space,
|
||||
display->pending.texture.color_range);
|
||||
if (!display->texture) {
|
||||
return false;
|
||||
|
@ -226,6 +239,7 @@ sc_display_apply_pending(struct sc_display *display) {
|
|||
static bool
|
||||
sc_display_prepare_texture_internal(struct sc_display *display,
|
||||
struct sc_size size,
|
||||
enum AVColorSpace color_space,
|
||||
enum AVColorRange color_range) {
|
||||
assert(size.width && size.height);
|
||||
|
||||
|
@ -233,7 +247,8 @@ sc_display_prepare_texture_internal(struct sc_display *display,
|
|||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -244,8 +259,10 @@ sc_display_prepare_texture_internal(struct sc_display *display,
|
|||
|
||||
enum sc_display_result
|
||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||
enum AVColorSpace color_space,
|
||||
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) {
|
||||
sc_display_set_pending_texture(display, size, color_range);
|
||||
return SC_DISPLAY_RESULT_PENDING;
|
||||
|
|
|
@ -33,6 +33,7 @@ struct sc_display {
|
|||
int8_t flags;
|
||||
struct {
|
||||
struct sc_size size;
|
||||
enum AVColorSpace color_space;
|
||||
enum AVColorRange color_range;
|
||||
} texture;
|
||||
AVFrame *frame;
|
||||
|
@ -54,6 +55,7 @@ sc_display_destroy(struct sc_display *display);
|
|||
|
||||
enum sc_display_result
|
||||
sc_display_prepare_texture(struct sc_display *display, struct sc_size size,
|
||||
enum AVColorSpace color_space,
|
||||
enum AVColorRange color_range);
|
||||
|
||||
enum sc_display_result
|
||||
|
|
|
@ -620,7 +620,7 @@ sc_screen_apply_frame(struct sc_screen *screen) {
|
|||
|
||||
enum sc_display_result res =
|
||||
sc_display_prepare_texture(&screen->display, screen->frame_size,
|
||||
frame->color_range);
|
||||
frame->colorspace, frame->color_range);
|
||||
if (res == SC_DISPLAY_RESULT_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue