diff --git a/LICENSE b/LICENSE index cea43741..3d6840b1 100644 --- a/LICENSE +++ b/LICENSE @@ -188,6 +188,7 @@ identification within third-party archives. Copyright (C) 2018 Genymobile + Copyright (C) 2018-2019 Romain Vimont Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile.CrossWindows b/Makefile.CrossWindows index 7955c544..49adcfb7 100644 --- a/Makefile.CrossWindows +++ b/Makefile.CrossWindows @@ -44,7 +44,7 @@ clean: build-server: [ -d "$(SERVER_BUILD_DIR)" ] || ( mkdir "$(SERVER_BUILD_DIR)" && \ meson "$(SERVER_BUILD_DIR)" \ - --buildtype release -Dbuild_app=false ) + --buildtype release -Dcompile_app=false ) ninja -C "$(SERVER_BUILD_DIR)" prepare-deps-win32: @@ -56,7 +56,7 @@ build-win32: prepare-deps-win32 --cross-file cross_win32.txt \ --buildtype release --strip -Db_lto=true \ -Dcrossbuild_windows=true \ - -Dbuild_server=false \ + -Dcompile_server=false \ -Dportable=true ) ninja -C "$(WIN32_BUILD_DIR)" @@ -66,7 +66,7 @@ build-win32-noconsole: prepare-deps-win32 --cross-file cross_win32.txt \ --buildtype release --strip -Db_lto=true \ -Dcrossbuild_windows=true \ - -Dbuild_server=false \ + -Dcompile_server=false \ -Dwindows_noconsole=true \ -Dportable=true ) ninja -C "$(WIN32_NOCONSOLE_BUILD_DIR)" @@ -80,7 +80,7 @@ build-win64: prepare-deps-win64 --cross-file cross_win64.txt \ --buildtype release --strip -Db_lto=true \ -Dcrossbuild_windows=true \ - -Dbuild_server=false \ + -Dcompile_server=false \ -Dportable=true ) ninja -C "$(WIN64_BUILD_DIR)" @@ -90,7 +90,7 @@ build-win64-noconsole: prepare-deps-win64 --cross-file cross_win64.txt \ --buildtype release --strip -Db_lto=true \ -Dcrossbuild_windows=true \ - -Dbuild_server=false \ + -Dcompile_server=false \ -Dwindows_noconsole=true \ -Dportable=true ) ninja -C "$(WIN64_NOCONSOLE_BUILD_DIR)" diff --git a/README.md b/README.md index c0a4c510..dbc92e8a 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ This application provides display and control of Android devices connected on USB (or [over TCP/IP][article-tcpip]). It does not require any _root_ access. -It works on _GNU/Linux_, _Windows_ and _MacOS_. +It works on _GNU/Linux_, _Windows_ and _macOS_. ![screenshot](assets/screenshot-debian-600.jpg) ## Requirements -The Android part requires at least API 21 (Android 5.0). +The Android device requires at least API 21 (Android 5.0). Make sure you [enabled adb debugging][enable-adb] on your device(s). @@ -62,7 +62,7 @@ For Windows, for simplicity, prebuilt archives with all the dependencies You can also [build the app manually][BUILD]. -### Mac OS +### macOS The application is available in [Homebrew]. Just install it: @@ -101,22 +101,22 @@ scrcpy --help ### Reduce size Sometimes, it is useful to mirror an Android device at a lower definition to -increase performances. +increase performance. -To limit both width and height to some value (e.g. 1024): +To limit both the width and height to some value (e.g. 1024): ```bash scrcpy --max-size 1024 scrcpy -m 1024 # short version ``` -The other dimension is computed to that the device aspect-ratio is preserved. +The other dimension is computed to that the device aspect ratio is preserved. That way, a device in 1920×1080 will be mirrored at 1024×576. ### Change bit-rate -The default bit-rate is 8Mbps. To change the video bitrate (e.g. to 2Mbps): +The default bit-rate is 8 Mbps. To change the video bitrate (e.g. to 2 Mbps): ```bash scrcpy --bit-rate 2M @@ -128,7 +128,7 @@ scrcpy -b 2M # short version The device screen may be cropped to mirror only part of the screen. -This is useful for example to mirror only 1 eye of the Oculus Go: +This is useful for example to mirror only one eye of the Oculus Go: ```bash scrcpy --crop 1224:1440:0:0 # 1224x1440 at offset (0,0) @@ -312,24 +312,24 @@ Also see [issue #14]. | Action | Shortcut | | -------------------------------------- |:---------------------------- | - | switch fullscreen mode | `Ctrl`+`f` | - | resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` | - | resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ | - | click on `HOME` | `Ctrl`+`h` \| _Middle-click_ | - | click on `BACK` | `Ctrl`+`b` \| _Right-click²_ | - | click on `APP_SWITCH` | `Ctrl`+`s` | - | click on `MENU` | `Ctrl`+`m` | - | click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ (`Cmd`+`↑` on MacOS) | - | click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ (`Cmd`+`↓` on MacOS) | - | click on `POWER` | `Ctrl`+`p` | - | power on | _Right-click²_ | - | turn device screen off (keep mirroring)| `Ctrl`+`o` | - | expand notification panel | `Ctrl`+`n` | - | collapse notification panel | `Ctrl`+`Shift`+`n` | - | copy device clipboard to computer | `Ctrl`+`c` | - | paste computer clipboard to device | `Ctrl`+`v` | - | copy computer clipboard to device | `Ctrl`+`Shift`+`v` | - | enable/disable FPS counter (on stdout) | `Ctrl`+`i` | + | Switch fullscreen mode | `Ctrl`+`f` | + | Resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` | + | Resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ | + | Click on `HOME` | `Ctrl`+`h` \| _Middle-click_ | + | Click on `BACK` | `Ctrl`+`b` \| _Right-click²_ | + | Click on `APP_SWITCH` | `Ctrl`+`s` | + | Click on `MENU` | `Ctrl`+`m` | + | Click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ (`Cmd`+`↑` on macOS) | + | Click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ (`Cmd`+`↓` on macOS) | + | Click on `POWER` | `Ctrl`+`p` | + | Power on | _Right-click²_ | + | Turn device screen off (keep mirroring)| `Ctrl`+`o` | + | Expand notification panel | `Ctrl`+`n` | + | Collapse notification panel | `Ctrl`+`Shift`+`n` | + | Copy device clipboard to computer | `Ctrl`+`c` | + | Paste computer clipboard to device | `Ctrl`+`v` | + | Copy computer clipboard to device | `Ctrl`+`Shift`+`v` | + | Enable/disable FPS counter (on stdout) | `Ctrl`+`i` | _¹Double-click on black borders to remove them._ _²Right-click turns the screen on if it was off, presses BACK otherwise._ @@ -380,6 +380,7 @@ Read the [developers page]. ## Licence Copyright (C) 2018 Genymobile + Copyright (C) 2018-2019 Romain Vimont Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/app/src/recorder.c b/app/src/recorder.c index f0f64a5f..3de8257a 100644 --- a/app/src/recorder.c +++ b/app/src/recorder.c @@ -151,9 +151,6 @@ recorder_write_header(struct recorder *recorder, const AVPacket *packet) { int ret = avformat_write_header(recorder->ctx, NULL); if (ret < 0) { LOGE("Failed to write header to %s", recorder->filename); - SDL_free(extradata); - avio_closep(&recorder->ctx->pb); - avformat_free_context(recorder->ctx); return false; } diff --git a/app/src/stream.c b/app/src/stream.c index 30151859..e85834c1 100644 --- a/app/src/stream.c +++ b/app/src/stream.c @@ -198,7 +198,7 @@ run_stream(void *data) { if (stream->recorder && !recorder_open(stream->recorder, codec)) { LOGE("Could not open recorder"); - goto finally_close_input; + goto finally_close_decoder; } AVPacket packet; @@ -248,6 +248,10 @@ quit: if (stream->recorder) { recorder_close(stream->recorder); } +finally_close_decoder: + if (stream->decoder) { + decoder_close(stream->decoder); + } finally_close_input: avformat_close_input(&format_ctx); finally_free_avio_ctx: diff --git a/meson.build b/meson.build index 053d8c94..bdd4a879 100644 --- a/meson.build +++ b/meson.build @@ -3,11 +3,11 @@ project('scrcpy', 'c', meson_version: '>= 0.37', default_options: 'c_std=c11') -if get_option('build_app') +if get_option('compile_app') subdir('app') endif -if get_option('build_server') +if get_option('compile_server') subdir('server') endif diff --git a/meson_options.txt b/meson_options.txt index e832fafd..d93161e3 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,5 +1,5 @@ -option('build_app', type: 'boolean', value: true, description: 'Build the client') -option('build_server', type: 'boolean', value: true, description: 'Build the server') +option('compile_app', type: 'boolean', value: true, description: 'Build the client') +option('compile_server', type: 'boolean', value: true, description: 'Build the server') option('crossbuild_windows', type: 'boolean', value: false, description: 'Build for Windows from Linux') option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)') option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server') diff --git a/server/src/test/java/com/genymobile/scrcpy/DeviceMessageWriterTest.java b/server/src/test/java/com/genymobile/scrcpy/DeviceMessageWriterTest.java new file mode 100644 index 00000000..df12f647 --- /dev/null +++ b/server/src/test/java/com/genymobile/scrcpy/DeviceMessageWriterTest.java @@ -0,0 +1,35 @@ +package com.genymobile.scrcpy; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class DeviceMessageWriterTest { + + @Test + public void testSerializeClipboard() throws IOException { + DeviceMessageWriter writer = new DeviceMessageWriter(); + + String text = "aéûoç"; + byte[] data = text.getBytes(StandardCharsets.UTF_8); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeByte(DeviceMessage.TYPE_CLIPBOARD); + dos.writeShort(data.length); + dos.write(data); + + byte[] expected = bos.toByteArray(); + + DeviceMessage msg = DeviceMessage.createClipboard(text); + bos = new ByteArrayOutputStream(); + writer.writeTo(msg, bos); + + byte[] actual = bos.toByteArray(); + + Assert.assertArrayEquals(expected, actual); + } +}