Compare commits

..

13 Commits

Author SHA1 Message Date
Romain Vimont
55187864ba Add some logs to debug issue 386 2019-01-06 12:23:19 +01:00
Romain Vimont
0e019f8ab8 Add a note to allow simulating input in README 2018-11-25 11:29:27 +01:00
Romain Vimont
f7d02cad4b Add ninja-build to the packages list to install
The package ninja-build should be installed automatically as a meson
dependency, but some users need to install a newer meson from pip3, so
ninja must be installed explicitly.
2018-11-19 09:43:05 +01:00
Romain Vimont
a7fe9ad779 Ignore mouse events outside device screen
Never create a "struct point" with a position possibly outside the
device screen (i.e. in the black borders area), and do not transmit such
events.

This fixes an assertion failure on mouse wheel events outside the device
screen area.
2018-11-18 21:31:57 +01:00
Romain Vimont
b2c3df7550 Point out that ninja must not be run as root
See https://github.com/Genymobile/scrcpy/issues/335.
2018-11-15 21:11:58 +01:00
Romain Vimont
46fec41b7b Move drag&drop features in README
Present how to install an APK and how to push a file in the "features"
section (instead of "shortcuts").
2018-11-13 20:39:18 +01:00
Romain Vimont
2876463d39 Fix read_packet() return value on error or EOF
Fix warning on error or EOF:

> Invalid return value 0 for stream protocol

See <http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=a606f27f4c610708fa96e35eed7b7537d3d8f712>.

Fixes <https://github.com/Genymobile/scrcpy/issues/333>.
2018-11-12 14:45:43 +01:00
Romain Vimont
6dc6ec05d5 Configure version at meson project level
Make meson aware of the project version, so that it does not print:

    Project version: undefined
2018-11-12 14:10:21 +01:00
Romain Vimont
b5e630eea3 Update links to v1.5-fixversion
I forgot to bump version _before_ the release, so I had to make a new
one which fixes the version string (for scrcpy --help).
2018-11-12 08:52:45 +01:00
Pierre Gordon
a17f1116ce Bump version to 1.5
Signed-off-by: Romain Vimont <rom@rom1v.com>
2018-11-12 08:24:18 +01:00
Romain Vimont
e4cf152b26 Update links to v1.5 in README and BUILD 2018-11-11 23:35:47 +01:00
Romain Vimont
bd32016632 Improve features presentation in README 2018-11-11 21:40:05 +01:00
Romain Vimont
77b620e1d0 Merge branch 'record' into dev (#292)
Record screen to file
2018-11-11 21:39:38 +01:00
10 changed files with 113 additions and 50 deletions

View File

@@ -43,7 +43,7 @@ Install the required packages from your package manager.
sudo apt install ffmpeg libsdl2-2.0.0
# client build dependencies
sudo apt install make gcc pkg-config meson \
sudo apt install make gcc pkg-config meson ninja-build \
libavcodec-dev libavformat-dev libavutil-dev \
libsdl2-dev
@@ -199,6 +199,12 @@ cd x
ninja
```
_Note: `ninja` [must][ninja-user] be run as a non-root user (only `ninja
install` must be run as root)._
[ninja-user]: https://github.com/Genymobile/scrcpy/commit/4c49b27e9f6be02b8e63b508b60535426bd0291a
### Run
To run without installing:
@@ -228,10 +234,10 @@ You can then [run](README.md#run) _scrcpy_.
## Prebuilt server
- [`scrcpy-server-v1.4.jar`][direct-scrcpy-server]
_(SHA-256: 1ff7a72fcfe81dadccfab9d6f86c971cd7c7f38f17196748fe05480e301b443d)_
- [`scrcpy-server-v1.5.jar`][direct-scrcpy-server]
_(SHA-256: d97aab6f60294e33e7ff79c2856ad3e01f912892395131f4f337e9ece03c24de)_
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.4/scrcpy-server-v1.4.jar
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.5-fixversion/scrcpy-server-v1.5.jar
Download the prebuilt server somewhere, and specify its path during the Meson
configuration:

View File

@@ -1,4 +1,4 @@
# scrcpy (v1.4)
# scrcpy (v1.5)
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.
@@ -15,6 +15,11 @@ Make sure you [enabled adb debugging][enable-adb] on your device(s).
[enable-adb]: https://developer.android.com/studio/command-line/adb.html#Enabling
On some devices, you also need to enable [an additional option][control] to
control it using keyboard and mouse.
[control]: https://github.com/Genymobile/scrcpy/issues/70#issuecomment-373286323
## Get the app
@@ -42,13 +47,13 @@ For Gentoo, an [Ebuild] is available: [`scrcpy/`][ebuild-link].
For Windows, for simplicity, prebuilt archives with all the dependencies
(including `adb`) are available:
- [`scrcpy-win32-v1.4.zip`][direct-win32]
_(SHA-256: 1f72fa520980727e8943b7214b64c66b00b9b5267f7cffefb64fa37c3ca803cf)_
- [`scrcpy-win64-v1.4.zip`][direct-win64]
_(SHA-256: 382f02bd8ed3db2cc7ab15aabdb83674744993b936d602b01e6959a150584a79)_
- [`scrcpy-win32-v1.5.zip`][direct-win32]
_(SHA-256: 46ae0d4c1c6bd049ec4a30080d2ad91a32b31d3f758afdca2c3a915ecabf02c1)_
- [`scrcpy-win64-v1.5.zip`][direct-win64]
_(SHA-256: 89daa07325129617cf943a84bc4e304ee5e57118416fe265b9b5d4a1bf87c501)_
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v1.4/scrcpy-win32-v1.4.zip
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.4/scrcpy-win64-v1.4.zip
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v1.5-fixversion/scrcpy-win32-v1.5.zip
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.5-fixversion/scrcpy-win64-v1.5.zip
You can also [build the app manually][BUILD].
@@ -208,6 +213,22 @@ scrcpy -t
Note that it only shows _physical_ touches (with the finger on the device).
### Install APK
To install an APK, drag & drop an APK file (ending with `.apk`) to the _scrcpy_
window.
There is no visual feedback, a log is printed to the console.
### Push file to device
To push a file to `/sdcard/` on the device, drag & drop a (non-APK) file to the
_scrcpy_ window.
There is no visual feedback, a log is printed to the console.
### Forward audio
Audio is not forwarded by _scrcpy_.
@@ -238,8 +259,6 @@ you are interested, see [issue 14].
| turn screen on | _Right-click²_ |
| paste computer clipboard to device | `Ctrl`+`v` |
| enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
| install APK from computer | drag & drop APK file |
| push file to `/sdcard/` | drag & drop non-APK file |
_¹Double-click on black borders to remove them._
_²Right-click turns the screen on if it was off, presses BACK otherwise._

View File

@@ -86,7 +86,7 @@ conf = configuration_data()
conf.set('BUILD_DEBUG', get_option('buildtype') == 'debug')
# the version, updated on release
conf.set_quoted('SCRCPY_VERSION', '1.4')
conf.set_quoted('SCRCPY_VERSION', meson.project_version())
# the prefix used during configuration (meson --prefix=PREFIX)
conf.set_quoted('PREFIX', get_option('prefix'))

View File

@@ -80,12 +80,15 @@ static int read_packet_with_meta(void *opaque, uint8_t *buf, int buf_size) {
if (!state->remaining) {
#define HEADER_SIZE 12
uint8_t header[HEADER_SIZE];
ssize_t ret = net_recv_all(decoder->video_socket, header, HEADER_SIZE);
if (ret <= 0) {
return ret;
ssize_t r = net_recv_all(decoder->video_socket, header, HEADER_SIZE);
if (r == -1) {
return AVERROR(errno);
}
if (r == 0) {
return AVERROR_EOF;
}
// no partial read (net_recv_all())
SDL_assert_release(ret == HEADER_SIZE);
SDL_assert_release(r == HEADER_SIZE);
uint64_t pts = buffer_read64be(header);
state->remaining = buffer_read32be(&header[8]);
@@ -93,7 +96,7 @@ static int read_packet_with_meta(void *opaque, uint8_t *buf, int buf_size) {
if (pts != NO_PTS && !receiver_state_push_meta(state, pts)) {
LOGE("Could not store PTS for recording");
// we cannot save the PTS, the recording would be broken
return -1;
return AVERROR(ENOMEM);
}
}
@@ -102,20 +105,30 @@ static int read_packet_with_meta(void *opaque, uint8_t *buf, int buf_size) {
if (buf_size > state->remaining)
buf_size = state->remaining;
ssize_t ret = net_recv(decoder->video_socket, buf, buf_size);
if (ret <= 0) {
return ret;
ssize_t r = net_recv(decoder->video_socket, buf, buf_size);
if (r == -1) {
return AVERROR(errno);
}
if (r == 0) {
return AVERROR_EOF;
}
SDL_assert(state->remaining >= ret);
state->remaining -= ret;
SDL_assert(state->remaining >= r);
state->remaining -= r;
return ret;
return r;
}
static int read_raw_packet(void *opaque, uint8_t *buf, int buf_size) {
struct decoder *decoder = opaque;
return net_recv(decoder->video_socket, buf, buf_size);
ssize_t r = net_recv(decoder->video_socket, buf, buf_size);
if (r == -1) {
return AVERROR(errno);
}
if (r == 0) {
return AVERROR_EOF;
}
return r;
}
// set the decoded frame as ready for rendering, and notify

View File

@@ -18,16 +18,9 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int
*y = (int) (*y / scale_y) - viewport.y;
}
static struct point get_mouse_point(struct screen *screen) {
int x;
int y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(screen->renderer, &x, &y);
SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000);
return (struct point) {
.x = (Uint16) x,
.y = (Uint16) y,
};
static void get_mouse_point(struct screen *screen, int *x, int *y) {
SDL_GetMouseState(x, y);
convert_to_renderer_coordinates(screen->renderer, x, y);
}
static const int ACTION_DOWN = 1;
@@ -271,8 +264,18 @@ void input_manager_process_mouse_motion(struct input_manager *input_manager,
}
}
static SDL_bool is_outside_device_screen(struct input_manager *input_manager,
int x, int y)
{
return x < 0 || x >= input_manager->screen->frame_size.width ||
y < 0 || y >= input_manager->screen->frame_size.height;
}
void input_manager_process_mouse_button(struct input_manager *input_manager,
const SDL_MouseButtonEvent *event) {
SDL_bool outside_device_screen = is_outside_device_screen(input_manager,
event->x,
event->y);
if (event->type == SDL_MOUSEBUTTONDOWN) {
if (event->button == SDL_BUTTON_RIGHT) {
press_back_or_turn_screen_on(input_manager->controller);
@@ -283,17 +286,19 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,
return;
}
// double-click on black borders resize to fit the device screen
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
SDL_bool outside_device_screen =
event->x < 0 || event->x >= input_manager->screen->frame_size.width ||
event->y < 0 || event->y >= input_manager->screen->frame_size.height;
if (outside_device_screen) {
screen_resize_to_fit(input_manager->screen);
return;
}
// otherwise, send the click event to the device
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2
&& outside_device_screen) {
screen_resize_to_fit(input_manager->screen);
return;
}
// otherwise, send the click event to the device
}
if (outside_device_screen) {
// ignore
return;
}
struct control_event control_event;
if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) {
if (!controller_push_event(input_manager->controller, &control_event)) {
@@ -304,9 +309,22 @@ void input_manager_process_mouse_button(struct input_manager *input_manager,
void input_manager_process_mouse_wheel(struct input_manager *input_manager,
const SDL_MouseWheelEvent *event) {
int x;
int y;
get_mouse_point(input_manager->screen, &x, &y);
if (is_outside_device_screen(input_manager, x, y)) {
// ignore
return;
}
SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000);
struct position position = {
.screen_size = input_manager->screen->frame_size,
.point = get_mouse_point(input_manager->screen),
.point = {
.x = (Uint16) x,
.y = (Uint16) y,
},
};
struct control_event control_event;
if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {

View File

@@ -124,7 +124,7 @@ static void usage(const char *arg0) {
}
static void print_version(void) {
fprintf(stderr, "scrcpy v%s\n\n", SCRCPY_VERSION);
fprintf(stderr, "scrcpy %s\n\n", SCRCPY_VERSION);
fprintf(stderr, "dependencies:\n");
fprintf(stderr, " - SDL %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL);

View File

@@ -80,6 +80,7 @@ static process_t execute_server(const char *serial,
Uint16 max_size, Uint32 bit_rate,
SDL_bool tunnel_forward, const char *crop,
SDL_bool send_frame_meta) {
LOGD("tunnel_forward=%d\n", (int) tunnel_forward);
char max_size_string[6];
char bit_rate_string[11];
sprintf(max_size_string, "%"PRIu16, max_size);

View File

@@ -1,4 +1,7 @@
project('scrcpy', 'c', meson_version: '>= 0.37', default_options : 'c_std=c11')
project('scrcpy', 'c',
version: '1.5',
meson_version: '>= 0.37',
default_options: 'c_std=c11')
if get_option('build_app')
subdir('app')

View File

@@ -6,8 +6,8 @@ android {
applicationId "com.genymobile.scrcpy"
minSdkVersion 21
targetSdkVersion 27
versionCode 5
versionName "1.4"
versionCode 6
versionName "1.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {

View File

@@ -64,6 +64,7 @@ public final class Server {
}
// use "adb forward" instead of "adb tunnel"? (so the server must listen)
boolean tunnelForward = Boolean.parseBoolean(args[2]);
Ln.d("tunnelForward = " + tunnelForward);
options.setTunnelForward(tunnelForward);
if (args.length < 4) {
@@ -105,6 +106,8 @@ public final class Server {
}
});
Ln.d("args: " + Arrays.toString(args));
Options options = createOptions(args);
scrcpy(options);
}