From fea9ad9bf9869b88ea275985baac7b4f033a67e6 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 2 Mar 2023 23:14:01 +0100 Subject: [PATCH] Add --audio-buffer Expose an option to add a buffering delay (in milliseconds) before playing audio. This is similar to the options --display-buffer and --v4l2-buffer for video frames. --- app/scrcpy.1 | 6 ++++++ app/src/cli.c | 14 ++++++++++++++ app/src/options.c | 1 + app/src/options.h | 1 + app/src/scrcpy.c | 12 ++++++++++-- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 49215807..2e1775ca 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -25,6 +25,12 @@ Encode the audio at the given bit\-rate, expressed in bits/s. Unit suffixes are Default is 196K (196000). +.TP +.BI "\-\-audio\-buffer ms +Add a buffering delay (in milliseconds) before playing audio. This increases latency to compensate for jitter. + +Default is 0 (no buffering). + .TP .BI "\-\-audio\-codec " name Select an audio codec (opus or aac). diff --git a/app/src/cli.c b/app/src/cli.c index 123aacfe..66223266 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -70,6 +70,7 @@ enum { OPT_LIST_ENCODERS, OPT_LIST_DISPLAYS, OPT_REQUIRE_AUDIO, + OPT_AUDIO_BUFFER, }; struct sc_option { @@ -119,6 +120,14 @@ static const struct sc_option options[] = { "Unit suffixes are supported: 'K' (x1000) and 'M' (x1000000).\n" "Default is 196K (196000).", }, + { + .longopt_id = OPT_AUDIO_BUFFER, + .longopt = "audio-buffer", + .argdesc = "ms", + .text = "Add a buffering delay (in milliseconds) before playing audio. " + "This increases latency to compensate for jitter.\n" + "Default is 0 (no buffering).", + }, { .longopt_id = OPT_AUDIO_CODEC, .longopt = "audio-codec", @@ -1812,6 +1821,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], case OPT_REQUIRE_AUDIO: opts->require_audio = true; break; + case OPT_AUDIO_BUFFER: + if (!parse_buffering_time(optarg, &opts->audio_buffer)) { + return false; + } + break; default: // getopt prints the error message on stderr return false; diff --git a/app/src/options.c b/app/src/options.c index 5dd655ce..adc665c4 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -43,6 +43,7 @@ const struct scrcpy_options scrcpy_options_default = { .display_id = 0, .display_buffer = 0, .v4l2_buffer = 0, + .audio_buffer = 0, #ifdef HAVE_USB .otg = false, #endif diff --git a/app/src/options.h b/app/src/options.h index 5fcaf016..d9c2d228 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -125,6 +125,7 @@ struct scrcpy_options { uint32_t display_id; sc_tick display_buffer; sc_tick v4l2_buffer; + sc_tick audio_buffer; #ifdef HAVE_USB bool otg; #endif diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 93dfbcc4..7c0e9399 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -43,6 +43,7 @@ struct scrcpy { struct sc_server server; struct sc_screen screen; struct sc_audio_player audio_player; + struct sc_delay_buffer audio_buffer; struct sc_demuxer video_demuxer; struct sc_demuxer audio_demuxer; struct sc_decoder video_decoder; @@ -694,9 +695,16 @@ aoa_hid_end: sc_frame_source_add_sink(src, &s->screen.frame_sink); if (options->audio) { + struct sc_frame_source *src = &s->audio_decoder.frame_source; + if (options->audio_buffer) { + sc_delay_buffer_init(&s->audio_buffer, options->audio_buffer, + false); + sc_frame_source_add_sink(src, &s->audio_buffer.frame_sink); + src = &s->audio_buffer.frame_source; + } + sc_audio_player_init(&s->audio_player); - sc_frame_source_add_sink(&s->audio_decoder.frame_source, - &s->audio_player.frame_sink); + sc_frame_source_add_sink(src, &s->audio_player.frame_sink); } }