From 1c2d4b3e7c233f1ef531cd253e7b732b32a06048 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Mon, 26 Jan 2015 20:33:45 +0100 Subject: [PATCH] Control socket: better support for audio TODO: figure out where to start control_start(). --- src/audio/audio.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/control_socket.cpp | 19 ++++++++++++++----- src/main.cpp | 5 ++--- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/audio/audio.cpp b/src/audio/audio.cpp index 06176180e..b70237d72 100644 --- a/src/audio/audio.cpp +++ b/src/audio/audio.cpp @@ -115,6 +115,7 @@ struct state_audio { struct state_audio_capture *audio_capture_device; struct state_audio_playback *audio_playback_device; + struct module audio_receiver_module; struct module audio_sender_module; struct audio_codec_state *audio_coder; @@ -147,6 +148,8 @@ struct state_audio { char *requested_encryption; volatile bool paused; + + int audio_tx_mode; }; /** @@ -253,6 +256,11 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in s->mod.cls = MODULE_CLASS_AUDIO; module_register(&s->mod, parent); + module_init_default(&s->audio_receiver_module); + s->audio_receiver_module.cls = MODULE_CLASS_RECEIVER; + s->audio_receiver_module.priv_data = s; + module_register(&s->audio_receiver_module, &s->mod); + module_init_default(&s->audio_sender_module); s->audio_sender_module.cls = MODULE_CLASS_SENDER; s->audio_sender_module.priv_data = s; @@ -337,6 +345,8 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in } free(tmp); + s->audio_tx_mode = 0; + if (strcmp(send_cfg, "none") != 0) { char *cfg = NULL; char *device = strdup(send_cfg); @@ -356,6 +366,7 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in if(ret > 0) { goto error; } + s->audio_tx_mode |= MODE_SENDER; } else { s->audio_capture_device = audio_capture_init_null_device(); } @@ -378,6 +389,7 @@ struct state_audio * audio_cfg_init(struct module *parent, const char *addrs, in if(ret > 0) { goto error; } + s->audio_tx_mode |= MODE_RECEIVER; } else { s->audio_playback_device = audio_playback_init_null_device(); } @@ -434,6 +446,9 @@ error: pdb_destroy(&s->audio_participants); } + if (s->audio_receiver_module.cls != 0) { + module_done(&s->audio_receiver_module); + } if (s->audio_sender_module.cls != 0) { module_done(&s->audio_sender_module); } @@ -469,6 +484,7 @@ void audio_done(struct state_audio *s) audio_playback_done(s->audio_playback_device); audio_capture_done(s->audio_capture_device); module_done(CAST_MODULE(s->tx_session)); + module_done(&s->audio_receiver_module); module_done(&s->audio_sender_module); if(s->audio_network_device) rtp_done(s->audio_network_device); @@ -517,6 +533,24 @@ static struct rtp *initialize_audio_network(struct audio_network_parameters *par return r; } +static void audio_receiver_process_message(struct state_audio *s, struct msg_receiver *msg) +{ + switch (msg->type) { + case RECEIVER_MSG_CHANGE_RX_PORT: + assert(s->audio_tx_mode == MODE_RECEIVER); // receiver only + rtp_done(s->audio_network_device); + s->audio_network_parameters.recv_port = msg->new_rx_port; + s->audio_network_device = initialize_audio_network( + &s->audio_network_parameters); + if (!s->audio_network_device) { + fprintf(stderr, "Changing RX port failed!"); + } + break; + default: + abort(); + } +} + static void *audio_receiver_thread(void *arg) { struct state_audio *s = (struct state_audio *) arg; @@ -535,6 +569,12 @@ static void *audio_receiver_thread(void *arg) printf("Audio receiving started.\n"); while (!should_exit_audio) { + struct message *msg; + while((msg= check_message(&s->audio_receiver_module))) { + audio_receiver_process_message(s, (struct msg_receiver *) msg); + free_message(msg); + } + bool decoded = false; pbuf_data.buffer.data_len = 0; @@ -744,6 +784,8 @@ static void resample(struct state_resample *s, struct audio_frame *buffer) static void audio_sender_process_message(struct state_audio *s, struct msg_sender *msg) { + assert(s->audio_tx_mode == MODE_SENDER); + int ret; switch (msg->type) { case SENDER_MSG_CHANGE_RECEIVER: diff --git a/src/control_socket.cpp b/src/control_socket.cpp index 4d39345bc..c307ea230 100644 --- a/src/control_socket.cpp +++ b/src/control_socket.cpp @@ -276,11 +276,11 @@ static int process_msg(struct control_state *s, fd_t client_fd, char *message) { int ret = 0; struct response *resp = NULL; - char path[1024]; + char path[1024] = ""; // path for msg receiver (usually video) + char path_audio[1024] = ""; // auxiliary buffer used when we need to signalize both audio + // and video char buf[1024]; - memset(path, 0, sizeof(path)); - if(prefix_matches(message, "port ")) { message = suffix(message, "port "); snprintf(path, 1024, "%s[%d]", module_class_name(MODULE_CLASS_PORT), atoi(message)); @@ -314,12 +314,11 @@ static int process_msg(struct control_state *s, fd_t client_fd, char *message) struct msg_sender *msg_audio = (struct msg_sender *) malloc(sizeof(struct msg_sender)); memcpy(msg_audio, msg, sizeof(struct msg_sender)); if (msg_audio->type == SENDER_MSG_CHANGE_PORT) { - msg->port = atoi(suffix(message, "sender-port ")); + msg_audio->port = atoi(suffix(message, "sender-port ")) + 2; } enum module_class path_sender[] = { MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; enum module_class path_sender_audio[] = { MODULE_CLASS_AUDIO, MODULE_CLASS_SENDER, MODULE_CLASS_NONE }; - char path_audio[1024]; memcpy(path_audio, path, sizeof(path_audio)); append_message_path(path, sizeof(path), path_sender); append_message_path(path_audio, sizeof(path_audio), path_sender_audio); @@ -333,13 +332,23 @@ static int process_msg(struct control_state *s, fd_t client_fd, char *message) struct msg_receiver *msg = (struct msg_receiver *) new_message(sizeof(struct msg_receiver)); + struct msg_receiver *msg_audio = + (struct msg_receiver *) + new_message(sizeof(struct msg_receiver)); msg->type = RECEIVER_MSG_CHANGE_RX_PORT; msg->new_rx_port = atoi(suffix(message, "receiver-port ")); + memcpy(msg_audio, msg, sizeof(struct msg_receiver)); + msg_audio->new_rx_port = atoi(suffix(message, "receiver-port ")) + 2; enum module_class path_receiver[] = { MODULE_CLASS_RECEIVER, MODULE_CLASS_NONE }; + enum module_class path_audio_receiver[] = { MODULE_CLASS_AUDIO, MODULE_CLASS_RECEIVER, MODULE_CLASS_NONE }; append_message_path(path, sizeof(path), path_receiver); + append_message_path(path_audio, sizeof(path_audio), path_audio_receiver); resp = send_message(s->root_module, path, (struct message *) msg); + struct response *resp_audio = + send_message(s->root_module, path_audio, (struct message *) msg_audio); + resp_audio->deleter(resp_audio); } else if(prefix_matches(message, "fec ")) { struct msg_change_fec_data *msg = (struct msg_change_fec_data *) new_message(sizeof(struct msg_change_fec_data)); diff --git a/src/main.cpp b/src/main.cpp index 1b400ef09..e838e419e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -961,6 +961,8 @@ int main(int argc, char *argv[]) rxtx_mode |= MODE_SENDER; } + control_start(control); + if (rxtx_mode == 0) { goto after_video_init; } @@ -1066,9 +1068,6 @@ int main(int argc, char *argv[]) int)) display_reconfigure_audio, uv->display_device); } - // should be started after requested modules are able to respond after start - control_start(control); - if (strcmp("none", requested_display) != 0) display_run(uv->display_device); } catch (string const &str) {