Skip to content

Conversation

rom1v
Copy link
Collaborator

@rom1v rom1v commented Jul 11, 2025

First, this PR contains some fixes that could be merged directly into dev.

Then, there are some refactors to make the transition easier, especially the handling of integer scrolling (#6156 (comment)) and the configuration of the color space at texture creation.

Finally, there's a "big" migration commit, followed by the changes for the build script and the GitHub Actions script.

Links:


Tests and reviews welcome.

TODO:


I don't plan to merge this immediately, SDL3 is not available yet on many distros (not even in current Debian stable).

I'd like to implement hardware decoding first (#3800libsdl-org/SDL#5405 (comment) | libsdl-org/SDL#8366), and if everything works as expected, release a new major version (scrcpy 4.0).

@rom1v rom1v mentioned this pull request Jul 12, 2025
@yume-chan
Copy link
Contributor

Quickly tried it on Windows (using the prebuilt binary) and it keeps printing Unexpected SDL audio behavior: too much data requested

┖[~\Downloads\scrcpy-win64-sdl3]> .\scrcpy.exe
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
C:\Users\simon\Downloads\scrcpy-win64-sdl3\scrcpy-server: ...file pushed, 0 skipped. 112.9 MB/s (90788 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d11
INFO: Texture: 1440x3200
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested

Enabling -Vverbose shows more [Audio] Buffering threshold exceeded messages

ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: Unexpected SDL audio behavior: too much data requested
ERROR: Unexpected SDL audio behavior: too much data requested
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
DEBUG: [Audio] Buffering threshold exceeded, skipping 960 samples

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 15, 2025

Thank you for your tests!

I assumed (on purpose, to detect early if that was false) that the additional_amount requested by SDL3 never exceeds the "audio output buffer" hint. It is true on my machine, but apparently not everywhere (I only tested on Linux).

How much data does it require:

diff --git app/src/audio_player.c app/src/audio_player.c
index e1a4134e7..6ca13a1e0 100644
--- app/src/audio_player.c
+++ app/src/audio_player.c
@@ -21,7 +21,8 @@ sc_audio_player_stream_callback(void *userdata, SDL_AudioStream *stream,
         assert(len <= ap->aout_buffer_size);
         if (len > ap->aout_buffer_size) {
             // Just in case for release builds
-            LOGE("Unexpected SDL audio behavior: too much data requested");
+            LOGE("Unexpected SDL audio behavior: too much data requested: %d",
+                 additional_amount);
             len = ap->aout_buffer_size;
         }
 

?

Is it different with --audio-output-buffer=10 or --audio-output-buffer=20? (default is 5)

On SDL2, do you need to use --audio-output-buffer=xx to get audio working correctly?

@yume-chan
Copy link
Contributor

yume-chan commented Jul 15, 2025

How much data does it require:

additional_amount is always 3840, and audio sounds like a robot

Is it different with --audio-output-buffer=10 or --audio-output-buffer=20?

There is no error with either --audio-output-buffer=10 or --audio-output-buffer=20, additional_amount is still 3840, and audio is working

On SDL2, do you need to use --audio-output-buffer=xx to get audio working correctly?

No

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 15, 2025

There is no error with either --audio-output-buffer=10 or --audio-output-buffer=20, and audio is working

What is the value of additional_amount in these cases?

@icculus Sorry to ping you here, but do you know why setting SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES to 240 (5 milliseconds of samples, 1920 bytes for 2 channels of 4 bytes each) can result in the callback being called with additional_amount = 3840 (instead of 1920) on Windows?

Apparently, on SDL2, the callback was correctly called with 1920 bytes. @yume-chan, this can be confirmed on scrcpy 3.3.1 with:

diff --git app/src/audio_player.c app/src/audio_player.c
index 9413c2ea8..07979b31b 100644
--- app/src/audio_player.c
+++ app/src/audio_player.c
@@ -11,6 +11,8 @@ static void SDLCALL
 sc_audio_player_sdl_callback(void *userdata, uint8_t *stream, int len_int) {
     struct sc_audio_player *ap = userdata;
 
+    LOGI("=== SDL2 audio callback: %d bytes (%d samples)", len_int, len_int / 8);
+
     assert(len_int > 0);
     size_t len = len_int;
 

@icculus
Copy link

icculus commented Jul 15, 2025

Not awake yet, but I'll try the Windows build today and see what happens.

@metayan
Copy link

metayan commented Jul 15, 2025

scrcpy with SDL3 can even be built on macOS Catalina with MacOSX_SDK11 using

SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.1.sdk ./release/build_macos.sh x86_64

and it works splendidly, both with OpenGL and Metal.
I have an older Android phone, so can't test audio.

@metayan
Copy link

metayan commented Jul 15, 2025

diff --git a/app/deps/sdl.sh b/app/deps/sdl.sh
index ae79ae9c..a308ae9e 100755
--- a/app/deps/sdl.sh
+++ b/app/deps/sdl.sh
@@ -28,7 +28,7 @@ export CXXFLAGS="$CFLAGS"
 
 if [[ -d "$DIRNAME" ]]
 then
-    echo "'$PWD/$HDIRNAME' already exists, not reconfigured"
+    echo "'$PWD/$DIRNAME' already exists, not reconfigured"
     cd "$DIRNAME"
 else
     mkdir "$DIRNAME"
@@ -41,7 +41,7 @@ else
     if [[ "$HOST" == linux ]]
     then
         conf+=(
-            -DSDL_WAYLOAD=ON
+            -DSDL_WAYLAND=ON
             -DSDL_X11=ON
         )
     fi

@metayan
Copy link

metayan commented Jul 15, 2025

Also tested with SDL 3.2.18 and it works fine on macOS. Audio not tested.

diff --git a/app/deps/sdl.sh b/app/deps/sdl.sh
index ae79ae9c..970fcbfa 100755
--- a/app/deps/sdl.sh
+++ b/app/deps/sdl.sh
@@ -5,10 +5,10 @@ cd "$DEPS_DIR"
 . common
 process_args "$@"
 
-VERSION=3.2.16
+VERSION=3.2.18
 FILENAME=SDL-$VERSION.tar.gz
 PROJECT_DIR=SDL-release-$VERSION
-SHA256SUM=a1af401fb49b824ba721683862439e014498f79753602827e174f3613357aff0
+SHA256SUM=51539fa13e546bc50c632beed3f34257de2baa38a4c642048de56377903b4265
 
 cd "$SOURCES_DIR"

@yume-chan
Copy link
Contributor

What is the value of additional_amount in these cases?

It's still 3840

diff --git a/app/src/audio_player.c b/app/src/audio_player.c
index e1a4134e..71fbef2a 100644
--- a/app/src/audio_player.c
+++ b/app/src/audio_player.c
@@ -16,6 +16,8 @@ sc_audio_player_stream_callback(void *userdata, SDL_AudioStream *stream,
     struct sc_audio_player *ap = userdata;
 
     if (additional_amount > 0) {
+        LOGE("additional_amount: %d", additional_amount);
+
         size_t len = additional_amount;
 
         assert(len <= ap->aout_buffer_size);
@@ -82,6 +84,9 @@ sc_audio_player_frame_sink_open(struct sc_frame_sink *sink,
     int r = snprintf(str, sizeof(str), "%" PRIu16, (uint16_t) aout_samples);
     assert(r >= 0 && (size_t) r < sizeof(str));
     (void) r;
+
+    LOGE("setting SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES to %s", str);
+
     if (!SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, str)) {
         LOGE("Could not set audio output buffer");
         sc_audio_regulator_destroy(&ap->audioreg);
> ./scrcpy --audio-output-buffer=10
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o...file pushed, 0 skipped. 102.8 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d11
ERROR: setting SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES to 480
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
> ./scrcpy --audio-output-buffer=20
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o...file pushed, 0 skipped. 107.7 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d11
ERROR: setting SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES to 960
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840
INFO: Texture: 1440x3200
ERROR: additional_amount: 3840
ERROR: additional_amount: 3840

this can be confirmed on scrcpy 3.3.1

> ./scrcpy
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o... file pushed, 0 skipped. 99.5 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d
INFO: Texture: 1440x3200
ERROR: === SDL2 audio callback: 1920 bytes (240 samples)
ERROR: === SDL2 audio callback: 1920 bytes (240 samples)
ERROR: === SDL2 audio callback: 1920 bytes (240 samples)
ERROR: === SDL2 audio callback: 1920 bytes (240 samples)
ERROR: === SDL2 audio callback: 1920 bytes (240 samples)
> ./scrcpy --audio-output-buffer=10
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o...file pushed, 0 skipped. 104.3 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d
INFO: Texture: 1440x3200
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
ERROR: === SDL2 audio callback: 3840 bytes (480 samples)
> ./scrcpy --audio-output-buffer=20
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o...file pushed, 0 skipped. 103.7 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
INFO: Renderer: direct3d
INFO: Texture: 1440x3200
ERROR: === SDL2 audio callback: 7680 bytes (960 samples)
ERROR: === SDL2 audio callback: 7680 bytes (960 samples)
ERROR: === SDL2 audio callback: 7680 bytes (960 samples)
ERROR: === SDL2 audio callback: 7680 bytes (960 samples)
ERROR: === SDL2 audio callback: 7680 bytes (960 samples)

rom1v added a commit that referenced this pull request Jul 16, 2025
Commit 3609362 mistakenly left an
additional 'H' when replacing $HOST with $DIRNAME.

Refs <#6216 (comment)>
@metayan
Copy link

metayan commented Jul 17, 2025

Numbers and punctuation now only work with --raw-key-events.

@yume-chan
Copy link
Contributor

yume-chan commented Jul 17, 2025

https://github.com/libsdl-org/SDL/blob/bc5c9a686ca01c7cffa45e223efcd0cb7ef1efb7/src/audio/wasapi/SDL_wasapi.c#L759-L760

SDL3 calls IAudioClient3::GetSharedModeEnginePeriod and clamps device->sample_frames. min_period_in_frames and max_period_in_frames are both 480, so additional_amount is always 3840. Not sure what it means, nor how does SDL2 works.


directsound audio driver doesn't work with the default --audio-output-buffer=5 neither, additional_amount is 1920 as expected, but audio played is broken:

log
> ./scrcpy --audio-output-buffer=5
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  73294bba                        device  M2011K2C
DEBUG: Device serial: 73294bba
DEBUG: Using SCRCPY_SERVER_PATH: D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\outputs\apk\release\server-release-unsigned.apk
D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\server\build\o...file pushed, 0 skipped. 104.2 MB/s (91004 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi M2011K2C (Android 13)
[server] DEBUG: Using audio encoder: 'c2.android.opus.encoder'
[server] DEBUG: Using video encoder: 'c2.qti.avc.encoder'
[server] DEBUG: Display: using SurfaceControl API
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
DEBUG: Using icon (portable): D:\dev\yume-chan\scrcpy-devcontainer\scrcpy\release\work\build-win64\dist\icon.png
INFO: Renderer: direct3d11
DEBUG: Trilinear filtering disabled (not an OpenGL renderer)
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
INFO: Texture: 1440x3200
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
ERROR: additional_amount: 1920
ERROR: additional_amount: 1920
DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 17, 2025

Numbers and punctuation now only work with --raw-key-events.

Oh, SDL_EVENT_TEXT_INPUT is never received:

case SDL_EVENT_TEXT_INPUT:

Reported here: libsdl-org/SDL#13380

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 17, 2025

directsound audio driver doesn't work with the default --audio-output-buffer=5 neither, additional_amount is 1920 as expected, but audio played is broken

Is it also the case on SDL2?

--audio-output-buffer was added because some audio outputs on Windows did not support 5ms, so if the behavior was the same on SDL2 (and respects the sample_frames value), it's ok I guess: #3793

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 17, 2025

Oh, SDL_EVENT_TEXT_INPUT is never received

Should be fixed on the new branch.

I added:

diff --git app/src/screen.c app/src/screen.c
index 27259e830..6ecb64167 100644
--- app/src/screen.c
+++ app/src/screen.c
@@ -394,6 +394,12 @@ sc_screen_init(struct sc_screen *screen,
         goto error_destroy_fps_counter;
     }
 
+    ok = SDL_StartTextInput(screen->window);
+    if (!ok) {
+        LOGE("Could not enable text input: %s", SDL_GetError());
+        goto error_destroy_window;
+    }
+
     SDL_Surface *icon = scrcpy_icon_load();
     if (icon) {
         SDL_SetWindowIcon(screen->window, icon);

(cf libsdl-org/SDL#13380)

As a consequence, it might open an IME on scrcpy start (libsdl-org/SDL#13380 (comment)). If that's the case (to be tested), we need a workaround.

@yume-chan
Copy link
Contributor

directsound audio driver doesn't work with the default --audio-output-buffer=5 neither, additional_amount is 1920 as expected, but audio played is broken

Is it also the case on SDL2?

Yes, with SDL2, directsound driver, and --audio-output-buffer=5, audio playback is also broken. wasapi driver works.

@yume-chan
Copy link
Contributor

check if the "continuous resizing" workaround is still necessary, or if it can be removed (0b1e591)

It still doesn't work, video stream pauses when moving or resizing window.

I think libsdl-org/SDL#1059 (comment) only applies automatically when using main callbacks, otherwise the SC_EVENT_NEW_FRAME custom events are still not delivered (#3458 (comment))

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 20, 2025

Thank you 👍

Maybe it can make sense to use SDL main callbacks (to be tested). This will require to rework the way the scrcpy-server is started, but in the end in might simplify (or not).

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 20, 2025

@yume-chan

=== SDL2 audio callback: 1920 bytes (240 samples)

Could you please also add the timestamp of the call, to see if the callback is called twice in a row: libsdl-org/SDL#13397

@szmarczak
Copy link

I don't plan to merge this immediately, SDL3 is not available yet on many distros (not even in current Debian stable).

Why not use a statically linked lib? Unless it's lots of megabytes in size but I'd still accept the tradeoff for better color accuracy.

@rom1v
Copy link
Collaborator Author

rom1v commented Jul 22, 2025

Why not use a statically linked lib

This is one of the possibilities: https://github.com/Genymobile/scrcpy/blob/master/doc/linux.md#from-the-official-release

But I would like to avoid a dependency "too recent", which is not even packaged (Debian stable is my reference, if it's in stable, it's not "too recent").

Anyway, it will take some time to resolve the remaining issues with SDL3.

@adamponi
Copy link

adamponi commented Aug 12, 2025

Hi,

I compiled the SDL3 branch in Termux, and it works well with the default settings. However, when using the --render=vulkan option, the colors appear inverted, although scrcpy remains usable.

In contrast, the precompiled build linked in the first post, which I ran on Windows, performs much worse. When launched with the --render=vulkan parameter, the screen displays only glitches, and the image is completely unreadable.

Downloads\scrcpy-release-sdl3\scrcpy-win64-sdl3> ./scrcpy --render=vulkan --no-audio
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  ec8faaa3                        device  xxxxxxxxxxx
C:\Users\xxxxxxx\Downloads\scrcpy-release-sdl3\scrcpy-... file pushed, 0 skipped. 27.7 MB/s (90788 bytes in 0.003s)
[server] INFO: Device: [Xiaomi] Redmi xxxxxxxxxxxxxxxxxx (Android 13)
INFO: Renderer: vulkan
INFO: Texture: 1224x2712
image

If there’s anything I can do to help diagnose or resolve this issue, please let me know. I’m happy to provide logs or any other information needed.

For reference, on Windows 11 I have the latest graphics drivers installed for the Intel® Core™ Ultra 5 Processor 135U.

Thanks!

@rom1v
Copy link
Collaborator Author

rom1v commented Aug 12, 2025

Looks like there is an alignment issue. Maybe because in 1224x2712, 1224 and 2712 are not multiple of 16. (see #55)
Try -m1024 or something else until you get both dimensions multiple of 16.

Can you reproduce with scrcpy + SDL2?

@adamponi
Copy link

I can't reproduce this using SDL2 because the version built on github doesn't offer a Vulkan renderer.

@adamponi
Copy link

adamponi commented Aug 12, 2025

PS C:\Users\xxxxxxxxxxxx\Downloads\scrcpy-release-sdl3\scrcpy-win64-sdl3> ./scrcpy --render=vulkan --no-audio -m1024
scrcpy 3.3.1 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  ec8faaa3                        device  xxxxxxxxxxxx
C:\Users\xxxxxxxxxxxx\Downloads\scrcpy-release-sdl3\scrcpy-... file pushed, 0 skipped. 28.7 MB/s (90788 bytes in 0.003s)
[server] INFO: Device: [Xiaomi] Redmi xxxxxxxxxxxx (Android 13)
INFO: Renderer: vulkan
INFO: Texture: 464x1024
image

This parameter didn't help. The problem is the same. I tested several other renderers, and the ones I tested were:
-direct3d12
-direct3d11
-opengl

The problem doesn't occur. The problem only occurs with the Vulkan renderer.

@adamponi
Copy link

I also just tested the "direct3d" renderer and everything works fine there. The problem is only with the "vulkan" renderer.

@rom1v
Copy link
Collaborator Author

rom1v commented Aug 12, 2025

Indeed, I can reproduce on Linux. Even with dimensions which are a multiple of 16 (or even 32).

Thank you for you report.

I created an issue here: libsdl-org/SDL#13734

@DienoX
Copy link

DienoX commented Aug 12, 2025

Thank you very much for your commitment and project.
I have a question about SDL3.
Does it bring any other benefits besides hardware acceleration of video decoding and DirectX 11, 12, Vulkan rendering?

@DienoX
Copy link

DienoX commented Aug 12, 2025

I'm asking in the context of scrcpy

@metayan
Copy link

metayan commented Aug 13, 2025

Paste doesn't work on macOS.
Tried SDL 3.2.16 3.2.18 3.2.20.

SDL issue filed:
libsdl-org/SDL#13737

Copy works and sometimes Control-Shift-V works.

@rom1v
Copy link
Collaborator Author

rom1v commented Sep 13, 2025

I updated the PR to not assume that the SDL SAMPLES_FRAMES hint is honored (refs libsdl-org/SDL#13397). @yume-chan this should fix #6216 (comment).

@adamponi The vulkan driver issue is fixed: libsdl-org/SDL#13734

Does it bring any other benefits besides hardware acceleration of video decoding and DirectX 11, 12, Vulkan rendering?

Besides hardware acceleration (which requires some work), the main benefit is to use a version of SDL that will continue to evolve (not become abandoned/deprecated).

@rom1v rom1v force-pushed the sdl3 branch 2 times, most recently from aa581b8 to 76352d3 Compare September 15, 2025 22:28
rom1v and others added 12 commits October 12, 2025 12:48
Do not rely on SDL to expose integer scroll values, as they are not
available in all versions.

It was reimplemented in SDL 3.2.12 by this commit:
<libsdl-org/SDL@0447c2f>

Refs #6156 <#6156>
Inline the function body in its only caller.

This will simplify further refactors.
The texture was created as soon as the initial video size was known,
even before the first frame arrived.

However, texture creation will require other data, such as the color
range, which is only available once the first frame is received.

Therefore, delay texture creation until the first frame.
This prepares for the migration to SDL3, where the color range can only
be specified at the time of texture creation.
Use both the color space and color range from FFmpeg to determine the
appropriate SDL YUV conversion mode.
TODO refs 3031
TODO refs SDL 5340 5976
This provides a more convenient API (e.g., using types sc_size
and sc_point), and will hide API changes made in SDL3.
The latest Ubuntu does not provide the SDL3 package yet.
Use BT.709 color space for AVCOL_SPC_RGB.

Refs #1868 comment <#1868 (comment)>

Signed-off-by: Romain Vimont <rom@rom1v.com>
@rom1v
Copy link
Collaborator Author

rom1v commented Oct 13, 2025

I added some changes on this branch.

Firstly, I removed a workaround for macOS (e59d40e), because the underlying issue should be fixed in SDL3 (libsdl-org/SDL#5340, libsdl-org/SDL#5976). Please verify on macOS.

Then, I noticed a very annoying change from SDL2 to SDL3: many previously infallible functions have been made fallible without good reason (in my opinion). See the discussion in libsdl-org/SDL#14223 for details.

For example, SDL_GetWindowSize(), which returned void in SDL2, now returns bool in SDL3. In general, it's a good thing that a function reports an error when an error can occur. However, in these changes, the functions only report programming errors, basically when SDL is not initialized or an invalid argument is passed (at least for cases they can detect):

https://github.com/libsdl-org/SDL/blob/5dab2c73f0537bd121d2311b6949a654c5692af9/src/video/SDL_video.c#L3203-L3213
https://github.com/libsdl-org/SDL/blob/5dab2c73f0537bd121d2311b6949a654c5692af9/src/video/SDL_video.c#L159-L178

Handling such errors would have cascading consequence in scrcpy. For instance, if a function calls SDL_GetWindowSize(), it should report the error to its caller, which would also have be made fallible, and so on… adding a lot of complexity for no reason, since in practice, SDL_GetWindowSize() cannot fail except due to programming errors.

The SDL maintainers disagree with the statement that "these functions only fails if the object is invalid", and suggest that these functions may fail for other reasons in the future.

In practice, I still assume that they may not fail, and that they never will (at least for SDL_GetWindowXXX()):

  • The current implementation cannot fail when the functions are called correctly.
  • If they add genuine failure cases in the future, every call to SDL_GetWindowSize() that doesn't check the error in a project would effectively be a bug (leading to undefined behavior if the output variables are not initialized beforehand).
  • The migration script from SDL2 to SDL3 does not add these error checks, so this would basically introduce undefined behavior in every migrated project.

Therefore, I added a wrapper in scrcpy that check the reported values, log them when failing is not fatal, and abort() (think "assertion enabled in release mode") to avoid undefined behavior for window size and position getters: a9a8fb1.

Error handling could be added later if my assumptions prove to be incorrect.

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants