summaryrefslogtreecommitdiff
path: root/cras/src/server/server_stream.c
blob: 6644c469fc1351156a74e1f2b9aabee1537cd409 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* Copyright 2018 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <syslog.h>

#include "cras_rstream.h"
#include "cras_server.h"
#include "cras_system_state.h"
#include "cras_types.h"
#include "server_stream.h"
#include "stream_list.h"

/* Parameters used for server stream. */
static unsigned int server_stream_block_size = 480;

/*
 * Information of a stream created by server. Currently only
 * one server stream is allowed, for echo reference use.
 */
static struct cras_rstream_config *stream_config;

/* Actually create the server stream and add to stream list. */
static void server_stream_add_cb(void *data)
{
	struct stream_list *stream_list = (struct stream_list *)data;
	struct cras_rstream *stream;

	if (!stream_config)
		return;

	stream_list_add(stream_list, stream_config, &stream);
}

void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx,
			  struct cras_audio_format *format)
{
	int audio_fd = -1;
	int client_shm_fd = -1;
	uint64_t buffer_offsets[2] = { 0, 0 };

	if (stream_config) {
		syslog(LOG_ERR, "server stream already exists, dev %u",
		       stream_config->dev_idx);
		return;
	}

	stream_config =
		(struct cras_rstream_config *)calloc(1, sizeof(*stream_config));
	cras_rstream_config_init(
		/*client=*/NULL, cras_get_stream_id(SERVER_STREAM_CLIENT_ID, 0),
		CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_SERVER_STREAM,
		CRAS_STREAM_INPUT, dev_idx,
		/*flags=*/SERVER_ONLY,
		/*effects=*/0, format, server_stream_block_size,
		server_stream_block_size, &audio_fd, &client_shm_fd,
		/*client_shm_size=*/0, buffer_offsets, stream_config);

	/* Schedule add stream in next main thread loop. */
	cras_system_add_task(server_stream_add_cb, stream_list);
}

static void server_stream_rm_cb(void *data)
{
	struct stream_list *stream_list = (struct stream_list *)data;

	if (stream_config == NULL)
		return;

	if (stream_list_rm(stream_list, stream_config->stream_id))
		syslog(LOG_ERR, "Server stream %x no longer exist",
		       stream_config->stream_id);

	free(stream_config);
	stream_config = NULL;
}

void server_stream_destroy(struct stream_list *stream_list,
			   unsigned int dev_idx)
{
	if (!stream_config || stream_config->dev_idx != dev_idx) {
		syslog(LOG_ERR, "No server stream to destroy");
		return;
	}
	/* Schedule remove stream in next main thread loop. */
	cras_system_add_task(server_stream_rm_cb, stream_list);
}