Compare commits

..

3 Commits

Author SHA1 Message Date
Romain Vimont
4f7869d130 Fix audio PTS when not monotonically increasing
Some decoders fail to guarantee that PTS must be monotonically
increasing. Fix the PTS when they're not.

Fixes #4054 <https://github.com/Genymobile/scrcpy/issues/4054>
2023-06-02 21:39:29 +02:00
Romain Vimont
0f28d39127 Do not add 1µS to the PTS in corner cases
The PTS must be monotonically increasing, but not strictly.
2023-06-02 21:38:30 +02:00
Romain Vimont
2aec7b4c9d Mention how to interrupt scrcpy without video
There is no window to close if video playback is disabled.
2023-06-02 09:00:33 +02:00
8 changed files with 17 additions and 33 deletions

View File

@@ -77,7 +77,6 @@ enum {
OPT_NO_AUDIO_PLAYBACK,
OPT_NO_VIDEO_PLAYBACK,
OPT_AUDIO_SOURCE,
OPT_NO_KILL_ADB_BEFORE_OTG,
};
struct sc_option {
@@ -412,16 +411,6 @@ static const struct sc_option options[] = {
.longopt = "no-key-repeat",
.text = "Do not forward repeated key events when a key is held down.",
},
{
.longopt_id = OPT_NO_KILL_ADB_BEFORE_OTG,
.longopt = "no-kill-adb-before-otg",
// with .text, the option is not documented on other platforms
#ifdef _WIN32
.text = "By default, scrcpy kills the adb daemon on Windows if --otg "
"is specified.\n"
"This option avoids to kill the adb daemon.",
#endif
},
{
.longopt_id = OPT_NO_MIPMAPS,
.longopt = "no-mipmaps",
@@ -1955,14 +1944,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}
break;
case OPT_NO_KILL_ADB_BEFORE_OTG:
#ifdef _WIN32
opts->kill_adb_before_otg = false;
break;
#else
LOGE("--no-kill-adb-before-otg only exists on Windows.");
return false;
#endif
default:
// getopt prints the error message on stderr
return false;

View File

@@ -48,9 +48,6 @@ const struct scrcpy_options scrcpy_options_default = {
#endif
#ifdef HAVE_USB
.otg = false,
#endif
#ifdef _WIN32
.kill_adb_before_otg = true,
#endif
.show_touches = false,
.fullscreen = false,

View File

@@ -148,9 +148,6 @@ struct scrcpy_options {
#endif
#ifdef HAVE_USB
bool otg;
#endif
#ifdef _WIN32
bool kill_adb_before_otg;
#endif
bool show_touches;
bool fullscreen;

View File

@@ -83,12 +83,10 @@ scrcpy_otg(struct scrcpy_options *options) {
#ifdef _WIN32
// On Windows, only one process could open a USB device
// <https://github.com/Genymobile/scrcpy/issues/2773>
if (options->kill_adb_before_otg) {
LOGI("Killing adb daemon (if any)...");
unsigned flags = SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR;
// uninterruptible (intr == NULL), but in practice it's very quick
sc_adb_kill_server(NULL, flags);
}
LOGI("Killing adb daemon (if any)...");
unsigned flags = SC_ADB_NO_STDOUT | SC_ADB_NO_STDERR | SC_ADB_NO_LOGERR;
// uninterruptible (intr == NULL), but in practice it's very quick
sc_adb_kill_server(NULL, flags);
#endif
static const struct sc_usb_callbacks cbs = {

View File

@@ -30,8 +30,9 @@ To disable only the audio playback, see [no playback](video.md#no-playback).
To play audio only, disable the video:
```
```bash
scrcpy --no-video
# interrupt with Ctrl+C
```
Without video, the audio latency is typically not criticial, so it might be

View File

@@ -168,6 +168,7 @@ the computer. This option is useful when [recording](recording.md) or when
```bash
scrcpy --v4l2-sink=/dev/video2 --no-playback
scrcpy --record=file.mkv --no-playback
# interrupt with Ctrl+C
```
It is also possible to disable video and audio playback separately:

View File

@@ -163,7 +163,7 @@ public final class AudioCapture {
// - an estimation from the previous PTS and the packet size as a fallback.
//
// Therefore, the property that PTS are monotonically increasing is no guaranteed in corner cases, so enforce it.
pts = previousPts + 1;
pts = previousPts;
}
previousPts = pts;

View File

@@ -105,8 +105,17 @@ public final class AudioEncoder implements AsyncProcessor {
private void outputThread(MediaCodec mediaCodec) throws IOException, InterruptedException {
streamer.writeAudioHeader();
long lastPts = 0;
while (!Thread.currentThread().isInterrupted()) {
OutputTask task = outputTasks.take();
if (task.bufferInfo.presentationTimeUs < lastPts) {
// Fix PTS if not monotonically increasing
task.bufferInfo.presentationTimeUs = lastPts;
} else {
lastPts = task.bufferInfo.presentationTimeUs;
}
ByteBuffer buffer = mediaCodec.getOutputBuffer(task.index);
try {
streamer.writePacket(buffer, task.bufferInfo);