Home | History | Annotate | Download | only in server
      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 
     16 /* Parameters used for server stream. */
     17 static unsigned int server_stream_block_size = 480;
     18 
     19 /*
     20  * Server stream doesn't care what format is used, because no
     21  * client is reading data from stream. The main point is to
     22  * make pinned device open and let data flow through its dsp
     23  * pipeline.
     24  */
     25 static struct cras_audio_format format =
     26 {
     27 	SND_PCM_FORMAT_S16_LE,
     28 	48000,
     29 	2,
     30 };
     31 
     32 /*
     33  * Information of a stream created by server. Currently only
     34  * one server stream is allowed, for echo reference use.
     35  */
     36 static struct cras_rstream_config *stream_config;
     37 
     38 /* Actually create the server stream and add to stream list. */
     39 static void server_stream_add_cb(void *data)
     40 {
     41 	struct stream_list *stream_list = (struct stream_list *)data;
     42 	struct cras_rstream *stream;
     43 
     44 	if (!stream_config)
     45 		return;
     46 
     47 	stream_list_add(stream_list, stream_config, &stream);
     48 }
     49 
     50 void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx)
     51 {
     52 	if (stream_config) {
     53 		syslog(LOG_ERR, "server stream already exists, dev %u",
     54 		       stream_config->dev_idx);
     55 		return;
     56 	}
     57 
     58 	stream_config = (struct cras_rstream_config *)
     59 			calloc(1, sizeof(*stream_config));
     60 	stream_config->format = &format;
     61 	stream_config->stream_id =
     62 			cras_get_stream_id(SERVER_STREAM_CLIENT_ID, 0);
     63 	stream_config->stream_type = CRAS_STREAM_TYPE_DEFAULT;
     64 	stream_config->direction = CRAS_STREAM_INPUT;
     65 	stream_config->flags = SERVER_ONLY;
     66 	stream_config->buffer_frames = server_stream_block_size;
     67 	stream_config->cb_threshold = server_stream_block_size;
     68 	stream_config->dev_idx = dev_idx;
     69 	stream_config->audio_fd = -1;
     70 
     71 	/* Schedule add stream in next main thread loop. */
     72 	cras_system_add_task(server_stream_add_cb, stream_list);
     73 }
     74 
     75 static void server_stream_rm_cb(void *data)
     76 {
     77 	struct stream_list *stream_list = (struct stream_list *)data;
     78 
     79 	if (stream_config == NULL)
     80 		return;
     81 
     82 	if (stream_list_rm(stream_list, stream_config->stream_id))
     83 		syslog(LOG_ERR, "Server stream %x no longer exist",
     84 		       stream_config->stream_id);
     85 
     86 	free(stream_config);
     87 	stream_config = NULL;
     88 }
     89 
     90 void server_stream_destroy(struct stream_list *stream_list,
     91 			   unsigned int dev_idx)
     92 {
     93 	if (!stream_config || stream_config->dev_idx != dev_idx) {
     94 		syslog(LOG_ERR, "No server stream to destroy");
     95 		return;
     96 	}
     97 	/* Schedule remove stream in next main thread loop. */
     98 	cras_system_add_task(server_stream_rm_cb, stream_list);
     99 }
    100