Compare commits

...

2 Commits

Author SHA1 Message Date
Simon Chan
bf625790fa Request limited color range by default
Most devices currently use limited color range, but some recent devices
encode in full color range, which is currently not supported by the SDL
opengl render driver.

Fixes #4756 <https://github.com/Genymobile/scrcpy/issues/4756>
Refs <https://github.com/Genymobile/scrcpy/issues/4756#issuecomment-2003710860>
Refs libusb/#9311 <https://github.com/libsdl-org/SDL/issues/9311>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-03-30 15:28:57 +01:00
Romain Vimont
db55edb196 Fix YUV conversion for full color range
Take the color range (full vs limited) into account to render the
picture.

Note that with the current version of SDL, it has no impact with the SDL
opengl render driver.

Fixes #4756 <https://github.com/Genymobile/scrcpy/issues/4756>
Refs <https://github.com/Genymobile/scrcpy/issues/4756#issuecomment-2003228916>
Refs libusb/#9311 <https://github.com/libsdl-org/SDL/issues/9311>

Suggested-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2024-03-30 15:28:09 +01:00
3 changed files with 24 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
#include "display.h"
#include <assert.h>
#include <libavutil/pixfmt.h>
#include "util/log.h"
@@ -65,6 +66,7 @@ sc_display_init(struct sc_display *display, SDL_Window *window, bool mipmaps) {
display->texture = NULL;
display->pending.flags = 0;
display->pending.frame = NULL;
display->has_frame = false;
return true;
}
@@ -196,9 +198,25 @@ 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],

View File

@@ -33,6 +33,8 @@ struct sc_display {
struct sc_size size;
AVFrame *frame;
} pending;
bool has_frame;
};
enum sc_display_result {

View File

@@ -3,6 +3,7 @@ package com.genymobile.scrcpy;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Looper;
import android.os.SystemClock;
import android.view.Surface;
@@ -220,6 +221,9 @@ public class SurfaceEncoder implements AsyncProcessor {
// must be present to configure the encoder, but does not impact the actual frame rate, which is variable
format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED);
}
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, DEFAULT_I_FRAME_INTERVAL);
// display the very first frame, and recover from bad quality when no new frames
format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_FRAME_DELAY_US); // µs