diff --git a/app/src/demuxer.c b/app/src/demuxer.c index e5f07628..c5898060 100644 --- a/app/src/demuxer.c +++ b/app/src/demuxer.c @@ -23,6 +23,7 @@ sc_demuxer_to_avcodec_id(uint32_t codec_id) { #define SC_CODEC_ID_H264 UINT32_C(0x68323634) // "h264" in ASCII #define SC_CODEC_ID_H265 UINT32_C(0x68323635) // "h265" in ASCII #define SC_CODEC_ID_AV1 UINT32_C(0x00617631) // "av1" in ASCII +#define SC_CODEC_ID_OPUS UINT32_C(0x6f707573) // "opus" in ASCII switch (codec_id) { case SC_CODEC_ID_H264: return AV_CODEC_ID_H264; @@ -30,6 +31,8 @@ sc_demuxer_to_avcodec_id(uint32_t codec_id) { return AV_CODEC_ID_HEVC; case SC_CODEC_ID_AV1: return AV_CODEC_ID_AV1; + case SC_CODEC_ID_OPUS: + return AV_CODEC_ID_OPUS; default: LOGE("Unknown codec id 0x%08" PRIx32, codec_id); return AV_CODEC_ID_NONE; @@ -233,6 +236,8 @@ end: void sc_demuxer_init(struct sc_demuxer *demuxer, const char *name, sc_socket socket, const struct sc_demuxer_callbacks *cbs, void *cbs_userdata) { + assert(socket != SC_SOCKET_NONE); + demuxer->name = name; // statically allocated demuxer->socket = socket; demuxer->sink_count = 0; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 820f3328..0c846123 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -41,6 +41,7 @@ struct scrcpy { struct sc_server server; struct sc_screen screen; struct sc_demuxer video_demuxer; + struct sc_demuxer audio_demuxer; struct sc_decoder decoder; struct sc_recorder recorder; #ifdef HAVE_V4L2 @@ -225,6 +226,16 @@ sc_video_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos, } } +static void +sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos, + void *userdata) { + (void) demuxer; + (void) eos; + (void) userdata; + + // Contrary to the video demuxer, keep mirroring if only the audio fails +} + static void sc_server_on_connection_failed(struct sc_server *server, void *userdata) { (void) server; @@ -283,6 +294,7 @@ scrcpy(struct scrcpy_options *options) { bool v4l2_sink_initialized = false; #endif bool video_demuxer_started = false; + bool audio_demuxer_started = false; #ifdef HAVE_USB bool aoa_hid_initialized = false; bool hid_keyboard_initialized = false; @@ -390,6 +402,14 @@ scrcpy(struct scrcpy_options *options) { sc_demuxer_init(&s->video_demuxer, "video", s->server.video_socket, &video_demuxer_cbs, NULL); + if (options->audio) { + static const struct sc_demuxer_callbacks audio_demuxer_cbs = { + .on_ended = sc_audio_demuxer_on_ended, + }; + sc_demuxer_init(&s->audio_demuxer, "audio", s->server.audio_socket, + &audio_demuxer_cbs, NULL); + } + bool needs_decoder = options->display; #ifdef HAVE_V4L2 needs_decoder |= !!options->v4l2_device; @@ -629,6 +649,13 @@ aoa_hid_end: } video_demuxer_started = true; + if (options->audio) { + if (!sc_demuxer_start(&s->audio_demuxer)) { + goto end; + } + audio_demuxer_started = true; + } + ret = event_loop(s); LOGD("quit..."); @@ -678,6 +705,10 @@ end: sc_demuxer_join(&s->video_demuxer); } + if (audio_demuxer_started) { + sc_demuxer_join(&s->audio_demuxer); + } + #ifdef HAVE_V4L2 if (v4l2_sink_initialized) { sc_v4l2_sink_destroy(&s->v4l2_sink);