Compare commits

..

13 Commits

Author SHA1 Message Date
Romain Vimont
b419eef55e Do not report error on device disconnected
A device disconnection (when the adb connection is closed) makes the
read() on the "receiver" socket fail.

Since commit 063a8339ed, this is reported
as an error. As a consequence, scrcpy fails with:

    ERROR: Controller error

instead of:

    WARN: Device disconnected

To fix the issue, report a device disconnection in that case.

PR #5044 <https://github.com/Genymobile/scrcpy/pull/5044>
2024-07-06 00:04:07 +02:00
Romain Vimont
a4f8c02502 Reorder initialization to simplify
This also avoids a warning with some compilers which do not understand
that the condition to initialize the variable is the same as the
condition to use it:

    ../app/src/scrcpy.c: In function ‘scrcpy’:
    ../app/src/scrcpy.c:750:13: warning: ‘src’ may be used uninitialized in this function [-Wmaybe-uninitialized]
      750 |             sc_frame_source_add_sink(src, &s->screen.frame_sink);
          |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Refs 45fe6b602b
Refs <https://github.com/Genymobile/scrcpy/issues/5045#issuecomment-2201589757>
2024-07-02 08:14:58 +02:00
Romain Vimont
a8871bfad7 Update links to 2.5 2024-06-29 17:51:36 +02:00
Romain Vimont
89df38f641 Bump version to 2.5 2024-06-29 16:52:45 +02:00
Romain Vimont
c95e6964c5 Merge branch 'master' into release 2024-06-29 16:52:32 +02:00
Romain Vimont
343f715323 Upgrade platform-tools (35.0.0) for Windows 2024-06-29 13:10:45 +02:00
Romain Vimont
f13f00021f Upgrade SDL (2.30.4) for Windows 2024-06-29 13:10:45 +02:00
Romain Vimont
48c2c03093 Upgrade FFmpeg (7.0.1) for Windows 2024-06-29 13:10:45 +02:00
Romain Vimont
1e3deabd6c Do not call avcodec_close()
The documentation of avcodec_close() says:

> Do not use this function. Use avcodec_free_context() to destroy a
> codec context (either open or closed).

It was deprecated in FFmpeg 7 by commit
1cc24d749569a42510399a29b034f7a77bdec34e:

<1cc24d7495>

> Its use has been discouraged since 2016, but now is no longer used in
> avformat, so there is no reason to keep it public.
2024-06-29 13:10:45 +02:00
Romain Vimont
576e7552a2 Mention that the Debian package is obsolete
It cannot be updated until the android-framework-XX Debian package is
fixed.

Refs <https://tracker.debian.org/pkg/scrcpy>
2024-06-13 09:14:40 +02:00
Romain Vimont
c27ab46efb Remove suggestion to install from winget
It does not work.

Refs #4027 <https://github.com/Genymobile/scrcpy/issues/4027>
Refs #4389 <https://github.com/Genymobile/scrcpy/issues/4389>
Refs #4956 <https://github.com/Genymobile/scrcpy/issues/4956>
2024-05-30 08:23:42 +02:00
Romain Vimont
b5849db32f Document missing package to build for Windows
To build ffmpeg, libz is necessary.

Refs #4955 <https://github.com/Genymobile/scrcpy/issues/4955>
2024-05-29 10:32:58 +02:00
Romain Vimont
206809a99a Fix typo in documentation 2024-04-02 18:01:21 +02:00
22 changed files with 84 additions and 105 deletions

View File

@@ -2,7 +2,7 @@
source for the project. Do not download releases from random websites, even if
their name contains `scrcpy`.**
# scrcpy (v2.4)
# scrcpy (v2.5)
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />

View File

@@ -4,10 +4,10 @@ DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
cd "$DEPS_DIR"
. common
VERSION=34.0.5
VERSION=35.0.0
FILENAME=platform-tools_r$VERSION-windows.zip
PROJECT_DIR=platform-tools-$VERSION
SHA256SUM=3f8320152704377de150418a3c4c9d07d16d80a6c0d0d8f7289c22c499e33571
SHA256SUM=7ab78a8f8b305ae4d0de647d99c43599744de61a0838d3a47bda0cdffefee87e
cd "$SOURCES_DIR"

View File

@@ -4,10 +4,10 @@ DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
cd "$DEPS_DIR"
. common
VERSION=6.1.1
VERSION=7.0.1
FILENAME=ffmpeg-$VERSION.tar.xz
PROJECT_DIR=ffmpeg-$VERSION
SHA256SUM=8684f4b00f94b85461884c3719382f1261f0d9eb3d59640a1f4ac0873616f968
SHA256SUM=bce9eeb0f17ef8982390b1f37711a61b4290dc8c2a0c1a37b5857e85bfb0e4ff
cd "$SOURCES_DIR"
@@ -17,7 +17,6 @@ then
else
get_file "https://ffmpeg.org/releases/$FILENAME" "$FILENAME" "$SHA256SUM"
tar xf "$FILENAME" # First level directory is "$PROJECT_DIR"
patch -d "$PROJECT_DIR" -p1 < "$PATCHES_DIR"/ffmpeg-6.1-fix-build.patch
fi
mkdir -p "$BUILD_DIR/$PROJECT_DIR"

View File

@@ -1,27 +0,0 @@
From 03c80197afb324da38c9b70254231e3fdcfa68fc Mon Sep 17 00:00:00 2001
From: Romain Vimont <rom@rom1v.com>
Date: Sun, 12 Nov 2023 17:58:50 +0100
Subject: [PATCH] Fix FFmpeg 6.1 build
Build failed on tag n6.1 With --enable-decoder=av1 but without
--enable-muxer=av1.
---
libavcodec/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 580a8d6b54..aff19b670c 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -249,7 +249,7 @@ OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \
OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
-OBJS-$(CONFIG_AV1_DECODER) += av1dec.o
+OBJS-$(CONFIG_AV1_DECODER) += av1dec.o av1_parse.o
OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_AV1_MEDIACODEC_ENCODER) += mediacodecenc.o
--
2.42.0

View File

@@ -4,10 +4,10 @@ DEPS_DIR=$(dirname ${BASH_SOURCE[0]})
cd "$DEPS_DIR"
. common
VERSION=2.28.5
VERSION=2.30.4
FILENAME=SDL-$VERSION.tar.gz
PROJECT_DIR=SDL-release-$VERSION
SHA256SUM=9f0556e4a24ef5b267010038ad9e9948b62f236d5bcc4b22179f95ef62d84023
SHA256SUM=dcc2c8c9c3e9e1a7c8d61d9522f1cba4e9b740feb560dcb15234030984610ee2
cd "$SOURCES_DIR"

View File

@@ -13,7 +13,7 @@ BEGIN
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
VALUE "OriginalFilename", "scrcpy.exe"
VALUE "ProductName", "scrcpy"
VALUE "ProductVersion", "2.4"
VALUE "ProductVersion", "2.5"
END
END
BLOCK "VarFileInfo"

View File

@@ -7,12 +7,13 @@
#define SC_CONTROL_MSG_QUEUE_MAX 64
static void
sc_controller_receiver_on_error(struct sc_receiver *receiver, void *userdata) {
sc_controller_receiver_on_ended(struct sc_receiver *receiver, bool error,
void *userdata) {
(void) receiver;
struct sc_controller *controller = userdata;
// Forward the event to the controller listener
controller->cbs->on_error(controller, controller->cbs_userdata);
controller->cbs->on_ended(controller, error, controller->cbs_userdata);
}
bool
@@ -27,7 +28,7 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket,
}
static const struct sc_receiver_callbacks receiver_cbs = {
.on_error = sc_controller_receiver_on_error,
.on_ended = sc_controller_receiver_on_ended,
};
ok = sc_receiver_init(&controller->receiver, control_socket, &receiver_cbs,
@@ -55,7 +56,7 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket,
controller->control_socket = control_socket;
controller->stopped = false;
assert(cbs && cbs->on_error);
assert(cbs && cbs->on_ended);
controller->cbs = cbs;
controller->cbs_userdata = cbs_userdata;
@@ -110,21 +111,30 @@ sc_controller_push_msg(struct sc_controller *controller,
static bool
process_msg(struct sc_controller *controller,
const struct sc_control_msg *msg) {
const struct sc_control_msg *msg, bool *eos) {
static uint8_t serialized_msg[SC_CONTROL_MSG_MAX_SIZE];
size_t length = sc_control_msg_serialize(msg, serialized_msg);
if (!length) {
*eos = false;
return false;
}
ssize_t w =
net_send_all(controller->control_socket, serialized_msg, length);
return (size_t) w == length;
if ((size_t) w != length) {
*eos = true;
return false;
}
return true;
}
static int
run_controller(void *data) {
struct sc_controller *controller = data;
bool error = false;
for (;;) {
sc_mutex_lock(&controller->mutex);
while (!controller->stopped
@@ -134,6 +144,7 @@ run_controller(void *data) {
if (controller->stopped) {
// stop immediately, do not process further msgs
sc_mutex_unlock(&controller->mutex);
LOGD("Controller stopped");
break;
}
@@ -141,20 +152,21 @@ run_controller(void *data) {
struct sc_control_msg msg = sc_vecdeque_pop(&controller->queue);
sc_mutex_unlock(&controller->mutex);
bool ok = process_msg(controller, &msg);
bool eos;
bool ok = process_msg(controller, &msg, &eos);
sc_control_msg_destroy(&msg);
if (!ok) {
LOGD("Could not write msg to socket");
goto error;
if (eos) {
LOGD("Controller stopped (socket closed)");
} // else error already logged
error = !eos;
break;
}
}
controller->cbs->on_ended(controller, error, controller->cbs_userdata);
return 0;
error:
controller->cbs->on_error(controller, controller->cbs_userdata);
return 1; // ignored
}
bool

View File

@@ -28,7 +28,8 @@ struct sc_controller {
};
struct sc_controller_callbacks {
void (*on_error)(struct sc_controller *controller, void *userdata);
void (*on_ended)(struct sc_controller *controller, bool error,
void *userdata);
};
bool

View File

@@ -278,7 +278,6 @@ run_demuxer(void *data) {
finally_close_sinks:
sc_packet_source_sinks_close(&demuxer->packet_source);
finally_free_context:
// This also calls avcodec_close() internally
avcodec_free_context(&codec_ctx);
end:
demuxer->cbs->on_ended(demuxer, status, demuxer->cbs_userdata);

View File

@@ -117,21 +117,21 @@ decode_image(const char *path) {
AVFrame *frame = av_frame_alloc();
if (!frame) {
LOG_OOM();
goto close_codec;
goto free_codec_ctx;
}
AVPacket *packet = av_packet_alloc();
if (!packet) {
LOG_OOM();
av_frame_free(&frame);
goto close_codec;
goto free_codec_ctx;
}
if (av_read_frame(ctx, packet) < 0) {
LOGE("Could not read frame");
av_packet_free(&packet);
av_frame_free(&frame);
goto close_codec;
goto free_codec_ctx;
}
int ret;
@@ -139,22 +139,20 @@ decode_image(const char *path) {
LOGE("Could not send icon packet: %d", ret);
av_packet_free(&packet);
av_frame_free(&frame);
goto close_codec;
goto free_codec_ctx;
}
if ((ret = avcodec_receive_frame(codec_ctx, frame)) != 0) {
LOGE("Could not receive icon frame: %d", ret);
av_packet_free(&packet);
av_frame_free(&frame);
goto close_codec;
goto free_codec_ctx;
}
av_packet_free(&packet);
result = frame;
close_codec:
avcodec_close(codec_ctx);
free_codec_ctx:
avcodec_free_context(&codec_ctx);
close_input:

View File

@@ -21,7 +21,7 @@ sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket,
receiver->acksync = NULL;
receiver->uhid_devices = NULL;
assert(cbs && cbs->on_error);
assert(cbs && cbs->on_ended);
receiver->cbs = cbs;
receiver->cbs_userdata = cbs_userdata;
@@ -134,12 +134,15 @@ run_receiver(void *data) {
static uint8_t buf[DEVICE_MSG_MAX_SIZE];
size_t head = 0;
bool error = false;
for (;;) {
assert(head < DEVICE_MSG_MAX_SIZE);
ssize_t r = net_recv(receiver->control_socket, buf + head,
DEVICE_MSG_MAX_SIZE - head);
if (r <= 0) {
LOGD("Receiver stopped");
// device disconnected: keep error=false
break;
}
@@ -147,6 +150,7 @@ run_receiver(void *data) {
ssize_t consumed = process_msgs(receiver, buf, head);
if (consumed == -1) {
// an error occurred
error = true;
break;
}
@@ -157,7 +161,7 @@ run_receiver(void *data) {
}
}
receiver->cbs->on_error(receiver, receiver->cbs_userdata);
receiver->cbs->on_ended(receiver, error, receiver->cbs_userdata);
return 0;
}

View File

@@ -25,7 +25,7 @@ struct sc_receiver {
};
struct sc_receiver_callbacks {
void (*on_error)(struct sc_receiver *receiver, void *userdata);
void (*on_ended)(struct sc_receiver *receiver, bool error, void *userdata);
};
bool

View File

@@ -269,13 +269,18 @@ sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer,
}
static void
sc_controller_on_error(struct sc_controller *controller, void *userdata) {
sc_controller_on_ended(struct sc_controller *controller, bool error,
void *userdata) {
// Note: this function may be called twice, once from the controller thread
// and once from the receiver thread
(void) controller;
(void) userdata;
PUSH_EVENT(SC_EVENT_CONTROLLER_ERROR);
if (error) {
PUSH_EVENT(SC_EVENT_CONTROLLER_ERROR);
} else {
PUSH_EVENT(SC_EVENT_DEVICE_DISCONNECTED);
}
}
static void
@@ -567,7 +572,7 @@ scrcpy(struct scrcpy_options *options) {
if (options->control) {
static const struct sc_controller_callbacks controller_cbs = {
.on_error = sc_controller_on_error,
.on_ended = sc_controller_on_ended,
};
if (!sc_controller_init(&s->controller, s->server.control_socket,
@@ -730,23 +735,20 @@ scrcpy(struct scrcpy_options *options) {
.start_fps_counter = options->start_fps_counter,
};
struct sc_frame_source *src;
if (options->video_playback) {
src = &s->video_decoder.frame_source;
if (options->display_buffer) {
sc_delay_buffer_init(&s->display_buffer,
options->display_buffer, true);
sc_frame_source_add_sink(src, &s->display_buffer.frame_sink);
src = &s->display_buffer.frame_source;
}
}
if (!sc_screen_init(&s->screen, &screen_params)) {
goto end;
}
screen_initialized = true;
if (options->video_playback) {
struct sc_frame_source *src = &s->video_decoder.frame_source;
if (options->display_buffer) {
sc_delay_buffer_init(&s->display_buffer,
options->display_buffer, true);
sc_frame_source_add_sink(src, &s->display_buffer.frame_sink);
src = &s->display_buffer.frame_source;
}
sc_frame_source_add_sink(src, &s->screen.frame_sink);
}
}

View File

@@ -240,7 +240,7 @@ sc_v4l2_sink_open(struct sc_v4l2_sink *vs, const AVCodecContext *ctx) {
vs->frame = av_frame_alloc();
if (!vs->frame) {
LOG_OOM();
goto error_avcodec_close;
goto error_avcodec_free_context;
}
vs->packet = av_packet_alloc();
@@ -268,8 +268,6 @@ error_av_packet_free:
av_packet_free(&vs->packet);
error_av_frame_free:
av_frame_free(&vs->frame);
error_avcodec_close:
avcodec_close(vs->encoder_ctx);
error_avcodec_free_context:
avcodec_free_context(&vs->encoder_ctx);
error_avio_close:
@@ -297,7 +295,6 @@ sc_v4l2_sink_close(struct sc_v4l2_sink *vs) {
av_packet_free(&vs->packet);
av_frame_free(&vs->frame);
avcodec_close(vs->encoder_ctx);
avcodec_free_context(&vs->encoder_ctx);
avio_close(vs->format_ctx->pb);
avformat_free_context(vs->format_ctx);

View File

@@ -42,7 +42,7 @@ scrcpy --no-window
# interrupt with Ctrl+C
```
Without video, the audio latency is typically not criticial, so it might be
Without video, the audio latency is typically not critical, so it might be
interesting to add [buffering](#buffering) to minimize glitches:
```

View File

@@ -94,7 +94,7 @@ This is the preferred method (and the way the release is built).
From _Debian_, install _mingw_:
```bash
sudo apt install mingw-w64 mingw-w64-tools
sudo apt install mingw-w64 mingw-w64-tools libz-mingw-w64-dev
```
You also need the JDK to build the server:
@@ -233,10 +233,10 @@ install` must be run as root)._
#### Option 2: Use prebuilt server
- [`scrcpy-server-v2.4`][direct-scrcpy-server]
<sub>SHA-256: `93c272b7438605c055e127f7444064ed78fa9ca49f81156777fd201e79ce7ba3`</sub>
- [`scrcpy-server-v2.5`][direct-scrcpy-server]
<sub>SHA-256: `1488b1105d6aff534873a26bf610cd2aea06ee867dd7a4d9c6bb2c091396eb15`</sub>
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-server-v2.4
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.5/scrcpy-server-v2.5
Download the prebuilt server somewhere, and specify its path during the Meson
configuration:

View File

@@ -6,7 +6,7 @@
Scrcpy is packaged in several distributions and package managers:
- Debian/Ubuntu: `apt install scrcpy`
- Debian/Ubuntu: ~~`apt install scrcpy`~~ _(obsolete version)_
- Arch Linux: `pacman -S scrcpy`
- Fedora: `dnf copr enable zeno/scrcpy && dnf install scrcpy`
- Gentoo: `emerge scrcpy`

View File

@@ -4,24 +4,18 @@
Download the [latest release]:
- [`scrcpy-win64-v2.4.zip`][direct-win64] (64-bit)
<sub>SHA-256: `9dc56f21bfa455352ec0c58b40feaf2fb02d67372910a4235e298ece286ff3a9`</sub>
- [`scrcpy-win32-v2.4.zip`][direct-win32] (32-bit)
<sub>SHA-256: `cf92acc45eef37c6ee2db819f92e420ced3bc50f1348dd57f7d6ca1fc80f6116`</sub>
- [`scrcpy-win64-v2.5.zip`][direct-win64] (64-bit)
<sub>SHA-256: `345cf04a66a9144281dce72ca4e82adfd2c3092463196e586051df4c69e1507b`</sub>
- [`scrcpy-win32-v2.5.zip`][direct-win32] (32-bit)
<sub>SHA-256: `d56312a92471565fa4f3a6b94e8eb07717c4c90f2c0f05b03ba444e1001806ec`</sub>
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-win64-v2.4.zip
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-win32-v2.4.zip
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.5/scrcpy-win64-v2.5.zip
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.5/scrcpy-win32-v2.5.zip
and extract it.
Alternatively, you could install it from packages manager, like [Winget]:
```bash
winget install scrcpy
```
or [Chocolatey]:
Alternatively, you could install it from packages manager, like [Chocolatey]:
```bash
choco install scrcpy

View File

@@ -2,8 +2,8 @@
set -e
BUILDDIR=build-auto
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.4/scrcpy-server-v2.4
PREBUILT_SERVER_SHA256=93c272b7438605c055e127f7444064ed78fa9ca49f81156777fd201e79ce7ba3
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.5/scrcpy-server-v2.5
PREBUILT_SERVER_SHA256=1488b1105d6aff534873a26bf610cd2aea06ee867dd7a4d9c6bb2c091396eb15
echo "[scrcpy] Downloading prebuilt server..."
wget "$PREBUILT_SERVER_URL" -O scrcpy-server

View File

@@ -1,5 +1,5 @@
project('scrcpy', 'c',
version: '2.4',
version: '2.5',
meson_version: '>= 0.48',
default_options: [
'c_std=c11',

View File

@@ -7,8 +7,8 @@ android {
applicationId "com.genymobile.scrcpy"
minSdkVersion 21
targetSdkVersion 34
versionCode 20400
versionName "2.4"
versionCode 20500
versionName "2.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {

View File

@@ -12,7 +12,7 @@
set -e
SCRCPY_DEBUG=false
SCRCPY_VERSION_NAME=2.4
SCRCPY_VERSION_NAME=2.5
PLATFORM=${ANDROID_PLATFORM:-34}
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-34.0.0}