-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Xiaomi Android 14] Light grays appearing as white only for scrcpy #4756
Comments
What do you mean by adb here? screenrecord ( If you record then play the file (with VLC or Firefox for example), does the problem occur?
|
In the console output, which renderer is used? For example:
I guess this is If so, could you try other values:
|
All of them look the same (partially horrible) way, even software, which was unexpected to me 😆
|
I've experienced the same issue before (not with scrcpy) and it was the encoder which was at fault (switching from the hardware encoder to x264 fixed it). I don't know if its possible the device is somehow defaulting to a different h264 encoder on A14? Though not sure why recording to a .mp4 would fix it. |
|
You can list and change the encoder.
Maybe your hardware encoder encodes with different parameters and set some metadata to handle color, and scrcpy does not handle them (either during the YUV-to-RGB conversion, either during rendering) while VLC does. If you could try the same device on another computer with another OS (on Linux for example), that might help (or not). |
Same as #4282 Maybe the device captures in HDR but SDL can't render them correctly? |
@pain414410797 what Xiaomi phone are you using? |
Some newer XiaoMi devices encode in full color range. I found this fix, but updating it in every frame might not be the most efficient method: (apparently libsdl-org/SDL#7083 is not true, FFMpeg and SDL both use JPEG to refer full color range) diff --git a/app/src/display.c b/app/src/display.c
index c8df615d..ccc65902 100644
--- a/app/src/display.c
+++ b/app/src/display.c
@@ -199,6 +199,13 @@ sc_display_set_texture_size(struct sc_display *display, struct sc_size size) {
static bool
sc_display_update_texture_internal(struct sc_display *display,
const AVFrame *frame) {
+ if (frame->color_range == AVCOL_RANGE_JPEG){
+ LOGE("JPEG color range detected");
+ SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG);
+ } else {
+ SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC);
+ }
+
int ret = SDL_UpdateYUVTexture(display->texture, NULL,
frame->data[0], frame->linesize[0],
frame->data[1], frame->linesize[1],
Recoding from Mi 11 (color is correct in Scrcpy 2.4): limited.zip MediaInfo:
Recording from Redmi K60 (color not correct in Scrcpy 2.4): full.zip MediaInfo:
|
👍
Although Lines 281 to 283 in 79968a0
|
@rom1v I have tried exactly there, but diff --git a/app/src/decoder.c b/app/src/decoder.c
index 5d42b8b0..123f9d44 100644
--- a/app/src/decoder.c
+++ b/app/src/decoder.c
@@ -43,6 +43,10 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
return true;
}
+ if (decoder->ctx->width != 0) {
+ LOGE("color range before avcodec_send_packet: %d", decoder->ctx->color_range);
+ }
+
int ret = avcodec_send_packet(decoder->ctx, packet);
if (ret < 0 && ret != AVERROR(EAGAIN)) {
LOGE("Decoder '%s': could not send video packet: %d",
@@ -50,6 +54,10 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
return false;
}
+ if (decoder->ctx->width != 0) {
+ LOGE("color range after avcodec_send_packet: %d", decoder->ctx->color_range);
+ }
+
for (;;) {
ret = avcodec_receive_frame(decoder->ctx, decoder->frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
Output:
It was changed in the first |
Or always request the encoder to encode in limited range? diff --git a/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java b/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java
index 28435c09..467406fd 100644
--- a/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java
+++ b/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java
@@ -219,6 +219,9 @@ public class SurfaceEncoder implements AsyncProcessor {
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
// 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);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED);
+ }
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
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
|
Why not 😄 @carstenhag Can you confirm that this command fixes your issue:
? (btw, I'm able to reproduce the issue with my device using |
Yep works fine with |
@yume-chan Does the patch from your comment work for you? I tested with |
It works on Redmi K60 (Android 14), but not on Mi 11 (Android 13) with If I record Mi 11 with Here is Redmi K60, recorded with |
OK, so if your patch fixes the problem, calling EDIT: it works for me with your patch and:
But not the default:
|
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 <#4756> Refs <#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Suggested-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
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 <#4756> Refs <#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Signed-off-by: Romain Vimont <rom@rom1v.com>
@yume-chan I suggest to apply both changes (branch |
Sounds good to me. |
Merged into |
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 Genymobile#4756 <Genymobile#4756> Refs <Genymobile#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Suggested-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
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 Genymobile#4756 <Genymobile#4756> Refs <Genymobile#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Signed-off-by: Romain Vimont <rom@rom1v.com>
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 Genymobile#4756 <Genymobile#4756> Refs <Genymobile#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Suggested-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
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 Genymobile#4756 <Genymobile#4756> Refs <Genymobile#4756 (comment)> Refs libusb/#9311 <libsdl-org/SDL#9311> Signed-off-by: Romain Vimont <rom@rom1v.com>
Environment
Describe the bug
Light grays are not shown. They are displayed as white. ADB and Android Studio render the colors correctly.
I am pretty sure this is happening since I upgraded the phone from Android 13 to Android 14 some weeks ago.
With a
[Google] google Pixel 6 (Android 14)
the issue is not occurring, which means the device is somehow influencing this.AS:
ADB:
scrpcy:
The text was updated successfully, but these errors were encountered: