Skip to content

Commit a28560d

Browse files
Yu-HsuanChromeos LUCI
Yu-Hsuan
authored and
Chromeos LUCI
committed
CRAS: Attach streams at the same time
Attach streams at the same time instead of adding them seperately. It can avoid the first stream from committing data to a device before the second stream is added. BUG=b:361243861 TEST=Switch devices when using Recorder App and Youtube at the same time. Change-Id: I8e25045768e853680998efd0e92c1836a87316c6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/5828304 Reviewed-by: Li-Yu Yu <[email protected]> Reviewed-by: Terry Cheong <[email protected]> Tested-by: [email protected] <[email protected]> Commit-Queue: Yu-Hsuan Hsu <[email protected]> Tested-by: Yu-Hsuan Hsu <[email protected]>
1 parent 0fe3ecc commit a28560d

File tree

5 files changed

+259
-168
lines changed

5 files changed

+259
-168
lines changed

cras/src/server/audio_thread.c

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ enum AUDIO_THREAD_COMMAND {
6060
AUDIO_THREAD_ADD_OPEN_DEV,
6161
AUDIO_THREAD_RM_OPEN_DEV,
6262
AUDIO_THREAD_IS_DEV_OPEN,
63-
AUDIO_THREAD_ADD_STREAM,
63+
AUDIO_THREAD_ADD_STREAMS,
6464
AUDIO_THREAD_DISCONNECT_STREAM,
6565
AUDIO_THREAD_STOP,
6666
AUDIO_THREAD_DUMP_THREAD_INFO,
@@ -104,6 +104,14 @@ struct audio_thread_add_rm_stream_msg {
104104
unsigned int num_devs;
105105
};
106106

107+
struct audio_thread_add_streams_msg {
108+
struct audio_thread_msg header;
109+
struct cras_rstream** streams;
110+
unsigned int num_streams;
111+
struct cras_iodev** devs;
112+
unsigned int num_devs;
113+
};
114+
107115
struct audio_thread_dump_debug_info_msg {
108116
struct audio_thread_msg header;
109117
struct audio_debug_info* info;
@@ -451,18 +459,22 @@ static int thread_drain_stream(struct audio_thread* thread,
451459
return ms_left;
452460
}
453461

454-
// Handles the add_stream message from the main thread.
455-
static int thread_add_stream(struct audio_thread* thread,
456-
struct cras_rstream* stream,
457-
struct cras_iodev** iodevs,
458-
unsigned int num_iodevs) {
462+
// Handles the add_streams message from the main thread.
463+
static int thread_add_streams(struct audio_thread* thread,
464+
struct cras_rstream** streams,
465+
unsigned int num_streams,
466+
struct cras_iodev** iodevs,
467+
unsigned int num_iodevs) {
459468
int rc;
460-
461-
rc = dev_io_append_stream(&thread->open_devs[CRAS_STREAM_OUTPUT],
462-
&thread->open_devs[CRAS_STREAM_INPUT], stream,
463-
iodevs, num_iodevs);
464-
if (rc < 0) {
465-
return rc;
469+
unsigned int i;
470+
for (i = 0; i < num_streams; i++) {
471+
rc = dev_io_append_stream(&thread->open_devs[CRAS_STREAM_OUTPUT],
472+
&thread->open_devs[CRAS_STREAM_INPUT], streams[i],
473+
iodevs, num_iodevs);
474+
if (rc < 0) {
475+
syslog(LOG_ERR, "Failed to add streams: %d", rc);
476+
return rc;
477+
}
466478
}
467479

468480
return 0;
@@ -616,10 +628,11 @@ static int handle_audio_thread_message(struct audio_thread* thread) {
616628
ATLOG(atlog, AUDIO_THREAD_PB_MSG, msg->id, 0, 0);
617629

618630
switch (msg->id) {
619-
case AUDIO_THREAD_ADD_STREAM: {
620-
struct audio_thread_add_rm_stream_msg* amsg;
621-
amsg = (struct audio_thread_add_rm_stream_msg*)msg;
622-
ret = thread_add_stream(thread, amsg->stream, amsg->devs, amsg->num_devs);
631+
case AUDIO_THREAD_ADD_STREAMS: {
632+
struct audio_thread_add_streams_msg* amsg;
633+
amsg = (struct audio_thread_add_streams_msg*)msg;
634+
ret = thread_add_streams(thread, amsg->streams, amsg->num_streams,
635+
amsg->devs, amsg->num_devs);
623636
break;
624637
}
625638
case AUDIO_THREAD_DISCONNECT_STREAM: {
@@ -1064,6 +1077,21 @@ static void init_add_rm_stream_msg(struct audio_thread_add_rm_stream_msg* msg,
10641077
msg->num_devs = num_devs;
10651078
}
10661079

1080+
static void init_add_streams_msg(struct audio_thread_add_streams_msg* msg,
1081+
enum AUDIO_THREAD_COMMAND id,
1082+
struct cras_rstream** streams,
1083+
unsigned int num_streams,
1084+
struct cras_iodev** devs,
1085+
unsigned int num_devs) {
1086+
memset(msg, 0, sizeof(*msg));
1087+
msg->header.id = id;
1088+
msg->header.length = sizeof(*msg);
1089+
msg->streams = streams;
1090+
msg->num_streams = num_streams;
1091+
msg->devs = devs;
1092+
msg->num_devs = num_devs;
1093+
}
1094+
10671095
static void init_dump_debug_info_msg(
10681096
struct audio_thread_dump_debug_info_msg* msg,
10691097
struct audio_debug_info* info) {
@@ -1098,22 +1126,24 @@ int audio_thread_event_log_shm_fd() {
10981126
return atlog_ro_shm_fd;
10991127
}
11001128

1101-
int audio_thread_add_stream(struct audio_thread* thread,
1102-
struct cras_rstream* stream,
1103-
struct cras_iodev** devs,
1104-
unsigned int num_devs) {
1105-
struct audio_thread_add_rm_stream_msg msg;
1129+
int audio_thread_add_streams(struct audio_thread* thread,
1130+
struct cras_rstream** streams,
1131+
unsigned int num_streams,
1132+
struct cras_iodev** devs,
1133+
unsigned int num_devs) {
1134+
struct audio_thread_add_streams_msg msg;
11061135

11071136
// Separate into multiple CRAS_CHECK calls to determine which variable is NULL
11081137
CRAS_CHECK(thread);
1109-
CRAS_CHECK(stream);
1138+
CRAS_CHECK(streams);
11101139
CRAS_CHECK(devs);
11111140

11121141
if (!thread->started) {
11131142
return -EINVAL;
11141143
}
11151144

1116-
init_add_rm_stream_msg(&msg, AUDIO_THREAD_ADD_STREAM, stream, devs, num_devs);
1145+
init_add_streams_msg(&msg, AUDIO_THREAD_ADD_STREAMS, streams, num_streams,
1146+
devs, num_devs);
11171147
return audio_thread_post_message(thread, &msg.header);
11181148
}
11191149

cras/src/server/audio_thread.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,22 +150,24 @@ void audio_thread_destroy(struct audio_thread* thread);
150150
// Returns the shm fd for the ATlog.
151151
int audio_thread_event_log_shm_fd();
152152

153-
/* Add a stream to the thread. After this call, the ownership of the stream will
153+
/* Add streams to the thread. After this call, the ownership of the streams will
154154
* be passed to the audio thread. Audio thread is responsible to release the
155-
* stream's resources.
155+
* streams' resources.
156156
* Args:
157157
* thread - a pointer to the audio thread.
158-
* stream - the new stream to add.
158+
* streams - an array of streams to add.
159+
* num_streams - nunber of streams in the array `streams`.
159160
* devs - an array of devices to attach stream.
160-
* num_devs - number of devices in the array pointed by devs
161+
* num_devs - number of devices in the array pointed by devs.
161162
* Returns:
162163
* zero on success, negative error from the AUDIO_THREAD enum above when an
163164
* the thread can't be added.
164165
*/
165-
int audio_thread_add_stream(struct audio_thread* thread,
166-
struct cras_rstream* stream,
167-
struct cras_iodev** devs,
168-
unsigned int num_devs);
166+
int audio_thread_add_streams(struct audio_thread* thread,
167+
struct cras_rstream** streams,
168+
unsigned int num_streams,
169+
struct cras_iodev** devs,
170+
unsigned int num_devs);
169171

170172
/* Begin draining a stream and check the draining status.
171173
* Args:

cras/src/server/cras_iodev_list.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "third_party/utlist/utlist.h"
4646

4747
#define NUM_OPEN_DEVS_MAX 10
48+
#define NUM_STREAMS_ATTACHED_MAX 256
4849
#define NUM_FLOOP_PAIRS_MAX 20
4950

5051
#define FOR_ALL_DEVS(list, dir, tmp, func) \
@@ -885,20 +886,24 @@ static void possibly_enable_fallback(enum CRAS_STREAM_DIRECTION dir,
885886
}
886887

887888
/*
888-
* Adds stream to one or more open iodevs. If the stream has processing effect
889+
* Adds streams to one or more open iodevs. If a stream has processing effect
889890
* turned on, create new APM instance and add to the list. This makes sure the
890891
* time consuming APM creation happens in main thread.
891892
*/
892-
static int add_stream_to_open_devs(struct cras_rstream* stream,
893-
struct cras_iodev** iodevs,
894-
unsigned int num_iodevs) {
895-
int i;
896-
if (stream->stream_apm) {
897-
for (i = 0; i < num_iodevs; i++) {
898-
cras_stream_apm_add(stream->stream_apm, iodevs[i], iodevs[i]->format);
893+
static int add_streams_to_open_devs(struct cras_rstream** streams,
894+
unsigned int num_streams,
895+
struct cras_iodev** iodevs,
896+
unsigned int num_iodevs) {
897+
for (int j = 0; j < num_streams; j++) {
898+
if (streams[j]->stream_apm) {
899+
for (int i = 0; i < num_iodevs; i++) {
900+
cras_stream_apm_add(streams[j]->stream_apm, iodevs[i],
901+
iodevs[i]->format);
902+
}
899903
}
900904
}
901-
return audio_thread_add_stream(audio_thread, stream, iodevs, num_iodevs);
905+
return audio_thread_add_streams(audio_thread, streams, num_streams, iodevs,
906+
num_iodevs);
902907
}
903908

904909
// Returns true if dev is one of the fallback devices.
@@ -910,8 +915,10 @@ static inline bool is_fallback_dev(struct cras_iodev* dev) {
910915
static int init_and_attach_streams(struct cras_iodev* dev) {
911916
int rc;
912917
enum CRAS_STREAM_DIRECTION dir = dev->direction;
918+
struct cras_rstream* streams[NUM_STREAMS_ATTACHED_MAX];
913919
struct cras_rstream* stream;
914920
int dev_enabled = cras_iodev_list_dev_is_enabled(dev);
921+
unsigned int num_streams = 0;
915922

916923
/* If called after suspend, for example bluetooth
917924
* profile switching, don't add back the stream list. */
@@ -965,8 +972,16 @@ static int init_and_attach_streams(struct cras_iodev* dev) {
965972
syslog(LOG_WARNING, "Enable %s failed, rc = %d", dev->info.name, rc);
966973
return rc;
967974
}
968-
add_stream_to_open_devs(stream, &dev, 1);
975+
if (num_streams == NUM_STREAMS_ATTACHED_MAX) {
976+
syslog(LOG_ERR, "The number of streams exceeds the limitation.");
977+
break;
978+
}
979+
streams[num_streams++] = stream;
969980
}
981+
if (num_streams) {
982+
add_streams_to_open_devs(streams, num_streams, &dev, 1);
983+
}
984+
970985
return 0;
971986
}
972987

@@ -1139,7 +1154,7 @@ static int pinned_stream_added(struct cras_rstream* rstream) {
11391154

11401155
// Attach the stream to devices that are opened successfully on the first try.
11411156
if (num_open_devs) {
1142-
int rc = add_stream_to_open_devs(rstream, open_devs, num_open_devs);
1157+
int rc = add_streams_to_open_devs(&rstream, 1, open_devs, num_open_devs);
11431158
if (rc) {
11441159
syslog(LOG_ERR, "Adding pinned stream to thread failed, rc %d", rc);
11451160
if (!first_err) {
@@ -1238,7 +1253,8 @@ static int stream_added_cb(struct cras_rstream* rstream) {
12381253
// Catch the stream with fallback if it is already enabled
12391254
if (cras_iodev_list_dev_is_enabled(fallback_devs[rstream->direction])) {
12401255
init_device(fallback_devs[rstream->direction], rstream);
1241-
add_stream_to_open_devs(rstream, &fallback_devs[rstream->direction], 1);
1256+
add_streams_to_open_devs(&rstream, 1, &fallback_devs[rstream->direction],
1257+
1);
12421258
}
12431259

12441260
/* Add the new stream to all enabled iodevs at once to avoid offset
@@ -1329,7 +1345,7 @@ static int stream_added_cb(struct cras_rstream* rstream) {
13291345
/* Add stream failure is considered critical because it'll
13301346
* trigger client side error. Collect the error type and send
13311347
* for UMA metrics. */
1332-
rc = add_stream_to_open_devs(rstream, iodevs, num_iodevs);
1348+
rc = add_streams_to_open_devs(&rstream, 1, iodevs, num_iodevs);
13331349
if (rc == -EIO) {
13341350
cras_server_metrics_stream_add_failure(CRAS_STREAM_ADD_IO_ERROR);
13351351
} else if (rc == -EINVAL) {
@@ -2044,7 +2060,7 @@ int cras_iodev_list_suspend_hotword_streams() {
20442060
}
20452061

20462062
audio_thread_disconnect_stream(audio_thread, stream, hotword_dev);
2047-
audio_thread_add_stream(audio_thread, stream, &empty_hotword_dev, 1);
2063+
audio_thread_add_streams(audio_thread, &stream, 1, &empty_hotword_dev, 1);
20482064
}
20492065
close_pinned_device(hotword_dev);
20502066
hotword_suspended = 1;
@@ -2078,7 +2094,7 @@ int cras_iodev_list_resume_hotword_stream() {
20782094
}
20792095

20802096
audio_thread_disconnect_stream(audio_thread, stream, empty_hotword_dev);
2081-
audio_thread_add_stream(audio_thread, stream, &hotword_dev, 1);
2097+
audio_thread_add_streams(audio_thread, &stream, 1, &hotword_dev, 1);
20822098
}
20832099
close_pinned_device(empty_hotword_dev);
20842100
hotword_suspended = 0;
@@ -2638,7 +2654,7 @@ static int remove_then_reconnect_stream(struct cras_rstream* rstream) {
26382654
cras_stream_apm_remove(rstream->stream_apm, iodevs[i]);
26392655
}
26402656

2641-
return add_stream_to_open_devs(rstream, iodevs, num_iodevs);
2657+
return add_streams_to_open_devs(&rstream, 1, iodevs, num_iodevs);
26422658
}
26432659

26442660
int cras_iodev_list_set_aec_ref(unsigned int stream_id, unsigned int dev_idx) {
@@ -2781,7 +2797,7 @@ void cras_iodev_list_enable_floop_pair(struct cras_floop_pair* pair) {
27812797
continue;
27822798
}
27832799
struct cras_iodev* devs[] = {&pair->output};
2784-
add_stream_to_open_devs(stream, devs, 1);
2800+
add_streams_to_open_devs(&stream, 1, devs, 1);
27852801
}
27862802
}
27872803
}

0 commit comments

Comments
 (0)