1 /* Copyright 2018 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <syslog.h>
7
8 #include "cras_rstream.h"
9 #include "cras_server.h"
10 #include "cras_system_state.h"
11 #include "cras_types.h"
12 #include "server_stream.h"
13 #include "stream_list.h"
14
15 /* Parameters used for server stream. */
16 static unsigned int server_stream_block_size = 480;
17
18 /*
19 * Information of a stream created by server. Currently only
20 * one server stream is allowed, for echo reference use.
21 */
22 static struct cras_rstream_config *stream_config;
23
24 /* Actually create the server stream and add to stream list. */
server_stream_add_cb(void * data)25 static void server_stream_add_cb(void *data)
26 {
27 struct stream_list *stream_list = (struct stream_list *)data;
28 struct cras_rstream *stream;
29
30 if (!stream_config)
31 return;
32
33 stream_list_add(stream_list, stream_config, &stream);
34 }
35
server_stream_create(struct stream_list * stream_list,unsigned int dev_idx,struct cras_audio_format * format)36 void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx,
37 struct cras_audio_format *format)
38 {
39 int audio_fd = -1;
40 int client_shm_fd = -1;
41 uint64_t buffer_offsets[2] = { 0, 0 };
42
43 if (stream_config) {
44 syslog(LOG_ERR, "server stream already exists, dev %u",
45 stream_config->dev_idx);
46 return;
47 }
48
49 stream_config =
50 (struct cras_rstream_config *)calloc(1, sizeof(*stream_config));
51 cras_rstream_config_init(
52 /*client=*/NULL, cras_get_stream_id(SERVER_STREAM_CLIENT_ID, 0),
53 CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_SERVER_STREAM,
54 CRAS_STREAM_INPUT, dev_idx,
55 /*flags=*/SERVER_ONLY,
56 /*effects=*/0, format, server_stream_block_size,
57 server_stream_block_size, &audio_fd, &client_shm_fd,
58 /*client_shm_size=*/0, buffer_offsets, stream_config);
59
60 /* Schedule add stream in next main thread loop. */
61 cras_system_add_task(server_stream_add_cb, stream_list);
62 }
63
server_stream_rm_cb(void * data)64 static void server_stream_rm_cb(void *data)
65 {
66 struct stream_list *stream_list = (struct stream_list *)data;
67
68 if (stream_config == NULL)
69 return;
70
71 if (stream_list_rm(stream_list, stream_config->stream_id))
72 syslog(LOG_ERR, "Server stream %x no longer exist",
73 stream_config->stream_id);
74
75 free(stream_config);
76 stream_config = NULL;
77 }
78
server_stream_destroy(struct stream_list * stream_list,unsigned int dev_idx)79 void server_stream_destroy(struct stream_list *stream_list,
80 unsigned int dev_idx)
81 {
82 if (!stream_config || stream_config->dev_idx != dev_idx) {
83 syslog(LOG_ERR, "No server stream to destroy");
84 return;
85 }
86 server_stream_rm_cb(stream_list);
87 }
88