diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-11-07 22:28:39 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-11-07 22:28:39 (GMT) |
commit | 63907d01004264445645453cb8ae6eeba7ab540a (patch) | |
tree | 3d20a8e9db6e020536abfa09e21c2a8196608c58 | |
parent | bc769f1abae57cd277c31c7f0ecc0576758e83ac (diff) | |
parent | c57b32ea2fa6b80ec35e43d190f251958665a256 (diff) | |
download | uscxml-63907d01004264445645453cb8ae6eeba7ab540a.zip uscxml-63907d01004264445645453cb8ae6eeba7ab540a.tar.gz uscxml-63907d01004264445645453cb8ae6eeba7ab540a.tar.bz2 |
Merge branch 'master' of https://github.com/tklab-tud/uscxml
-rw-r--r-- | apps/samples/miles/miles.html | 6 | ||||
-rw-r--r-- | apps/samples/miles/miles.js | 32 | ||||
-rw-r--r-- | apps/samples/miles/miles.scxml | 25 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/miles/.MilesSessionInvoker.cpp.swp | bin | 0 -> 16384 bytes | |||
-rw-r--r-- | src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp | 293 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h | 12 |
6 files changed, 299 insertions, 69 deletions
diff --git a/apps/samples/miles/miles.html b/apps/samples/miles/miles.html index 08cfeca..5028621 100644 --- a/apps/samples/miles/miles.html +++ b/apps/samples/miles/miles.html @@ -16,9 +16,9 @@ <script type="text/javascript"> require(["dojo/domReady!"], function(dom) { var milesSession1 = new Miles("miles1"); - var milesSession2 = new Miles("miles2"); - var milesSession3 = new Miles("miles3"); - var milesSession4 = new Miles("miles4"); + var milesSession2 = new Miles("miles2", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "yetanother@smartvortex.eu"}); + var milesSession3 = new Miles("miles3", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "stillanother@smartvortex.eu"}); + var milesSession4 = new Miles("miles4", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "last@smartvortex.eu"}); }); </script> </head> diff --git a/apps/samples/miles/miles.js b/apps/samples/miles/miles.js index f979266..d1efb0d 100644 --- a/apps/samples/miles/miles.js +++ b/apps/samples/miles/miles.js @@ -12,8 +12,8 @@ function Miles(element, params) { this.connected = false; this.imageIteration = 0; - this.width = 300; - this.height = 200; + this.width = 320; + this.height = 240; // private attributes var scxmlURL = "localhost:8080" @@ -60,6 +60,7 @@ function Miles(element, params) { if (params && params.reflectorIp) reflectorIp = params.reflectorIp; if (params && params.email) email = params.email; if (params && params.problemName) problemName = params.problemName; + if (params && params.remoteEmail) remoteEmail = params.remoteEmail; // called when dojo loaded all requirements below this.connect = function() { @@ -93,10 +94,25 @@ function Miles(element, params) { } this.disconnect = function() { - self.connected = false; - hideChat(); - self.controlDropDown.dropDown.onCancel(true); - self.controlElem.replaceChild(self.connectDropDown.domNode, self.controlDropDown.domNode); + var query = ""; + query += "?reflector=" + encodeURIComponent(reflectorIp); + query += "&userid=" + encodeURIComponent(email); + query += "&session=" + encodeURIComponent(problemName); + + self.xhr.get({ + // The URL to request + url: "http://" + scxmlURL + "/miles/stop" + query, + // handleAs:"text", + error: function(err) { + console.log(err); + }, + load: function(result) { + self.connected = false; + hideChat(); + self.controlDropDown.dropDown.onCancel(true); + self.controlElem.replaceChild(self.connectDropDown.domNode, self.controlDropDown.domNode); + } + }); } var hideChat = function() { @@ -176,7 +192,7 @@ function Miles(element, params) { }, load: function(result) { if (result.message) { - self.chatOutputElem.innerHTML += stopChatScrolling + " " + Math.random() + ": " + result.message + '<br />'; + self.chatOutputElem.innerHTML += result.message + '<br />'; if (!stopChatScrolling) self.chatOutputElem.scrollTop = self.chatOutputElem.scrollHeight; } @@ -283,7 +299,7 @@ function Miles(element, params) { self.chatSendButton = new Button({ label: "Send", onClick: function(){ - alert(self.chatInput.value); + //alert(self.chatInput.value); self.xhr.post({ // The URL to request url: "http://" + scxmlURL + "/miles/text", diff --git a/apps/samples/miles/miles.scxml b/apps/samples/miles/miles.scxml index 650add8..c1c6c69 100644 --- a/apps/samples/miles/miles.scxml +++ b/apps/samples/miles/miles.scxml @@ -3,7 +3,7 @@ <state id="main"> <invoke type="miles" id="miles"> <finalize> - <log label="out" expr="_event.name" /> + <!-- <log label="out" expr="_event.name" /> --> <script>//dump(_event);</script> <if cond="_event.data.origin"> <!-- <log label="Reply-length" expr="_event.data.base64.length" /> --> @@ -12,6 +12,7 @@ <header name="Cache-Control" value="no-cache" /> <!-- force IE to actually reload --> <header name="Access-Control-Allow-Origin" value="*" /> <header name="Content-Type" value="text/plain" /> + <header name="Access-Control-Allow-Origin" value="*" /> <content expr="_event.data.image.base64()" /> </respond> <else /> @@ -19,6 +20,7 @@ <header name="Cache-Control" value="no-cache" /> <!-- force IE to actually reload --> <header name="Access-Control-Allow-Origin" value="*" /> <!-- respond element will add content-type header --> + <header name="Access-Control-Allow-Origin" value="*" /> <content expr="_event.data" /> </respond> </if> @@ -40,7 +42,7 @@ </transition> <transition event="http.get" target="idle"> - <log label="in" expr="_event.data.path" /> + <!-- <log label="in" expr="_event.data.path" /> --> <script>//dump(_event);</script> <if cond="false"> @@ -49,7 +51,16 @@ <send target="#_miles" event="start"> <param name="origin" expr="_event.origin" /> <param name="reflector" expr="_event.data.query.reflector" /> - <param name="userId" expr="_event.data.query.userid" /> + <param name="userid" expr="_event.data.query.userid" /> + <param name="session" expr="_event.data.query.session" /> + </send> + + <!-- STOP ############### --> + <elseif cond="_event.data.pathComponent[1] === 'stop'" /> + <send target="#_miles" event="stop"> + <param name="origin" expr="_event.origin" /> + <param name="reflector" expr="_event.data.query.reflector" /> + <param name="userid" expr="_event.data.query.userid" /> <param name="session" expr="_event.data.query.session" /> </send> @@ -63,7 +74,7 @@ <elseif cond="_event.data.pathComponent[1] === 'thumbnail'" /> <send target="#_miles" event="thumbnail"> <param name="origin" expr="_event.origin" /> - <param name="userId" expr="_event.data.query.userid" /> + <param name="userid" expr="_event.data.query.userid" /> </send> <!-- VIDEO ON ############### --> @@ -135,8 +146,8 @@ </transition> <transition event="http.post" target="idle"> - <log label="in" expr="_event.data.path" /> - <script>dump(_event);</script> + <!-- <log label="in" expr="_event.data.path" /> --> + <script>//dump(_event);</script> <if cond="false"> <!-- POST TEXT ############### --> @@ -155,4 +166,4 @@ </state> </state> -</scxml>
\ No newline at end of file +</scxml> diff --git a/src/uscxml/plugins/invoker/miles/.MilesSessionInvoker.cpp.swp b/src/uscxml/plugins/invoker/miles/.MilesSessionInvoker.cpp.swp Binary files differnew file mode 100644 index 0000000..368f327 --- /dev/null +++ b/src/uscxml/plugins/invoker/miles/.MilesSessionInvoker.cpp.swp diff --git a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp index d4a709b..b36935c 100644 --- a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp +++ b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.cpp @@ -41,13 +41,11 @@ bool pluginConnect(pluma::Host& host) { #endif MilesSessionInvoker::MilesSessionInvoker() { - /* Initalize Miles */ + /* Initialize Miles */ miles_init(); - /* media buffers */ - init_media_buffers(); - _isRunning = false; + num_connected = 0; } MilesSessionInvoker::~MilesSessionInvoker() { @@ -75,6 +73,8 @@ void MilesSessionInvoker::init_media_buffers() { encoded_out_audio = NULL; audio_read_buf = NULL; video_data = (char *)malloc(1000000); + text_msg_buf = (char *)malloc(1000); + text_msg_available = 0; } void MilesSessionInvoker::free_media_buffers() { @@ -103,6 +103,74 @@ void MilesSessionInvoker::free_media_buffers() { if(audio_read_buf) free(audio_read_buf); audio_read_buf = NULL; + if(text_msg_buf) + free(text_msg_buf); + text_msg_buf = NULL; + text_msg_available = 0; +} + +void MilesSessionInvoker::free_video_buffers() { + if(video_out_buf) + free(video_out_buf); + video_out_buf = NULL; + if(encoded_out_img) + free(encoded_out_img); + encoded_out_img = NULL; + if(render_img) + free(render_img); + render_img = NULL; + render_img_size = 0; + if(video_data) + free(video_data); + video_data = NULL; +} + +void MilesSessionInvoker::free_audio_buffers() { + if(audio_in_buf) + free(audio_in_buf); + audio_in_buf = NULL; + if(audio_data) + free(audio_data); + audio_data = NULL; + video_data = NULL; + if(encoded_out_audio) + free(encoded_out_audio); + encoded_out_audio = NULL; + if(audio_read_buf) + free(audio_read_buf); + audio_read_buf = NULL; +} + +void MilesSessionInvoker::free_text_buffers() { + if(text_msg_buf) + free(text_msg_buf); + text_msg_buf = NULL; + text_msg_available = 0; +} + +// Yes, sort of ugly... +char confero_text_msg_buf[1000]; +int confero_text_msg_available = 0; + +int receive_text_message_callback(u_int32_t ssrc, char *pkt, int length) { + char cname[100]; + int i=0, j; + + while(pkt[i]) { + cname[i] = pkt[i]; + i++; + } + cname[i++] = 0; + j = i; + while(pkt[j] && j<length) { + if(pkt[j]=='<' || pkt[j]=='>' || pkt[j]=='\r' || pkt[j]=='\n') + pkt[j] = ' '; + j++; + } + memcpy(confero_text_msg_buf, pkt+i, length-i); + //printf("RTCP app depacketizer called, cname = %s, msg = %s\n", cname, confero_text_msg_buf); + confero_text_msg_available = 1; + return length; } void MilesSessionInvoker::send(const SendRequest& req) { @@ -201,9 +269,13 @@ void MilesSessionInvoker::send(const SendRequest& req) { void MilesSessionInvoker::processEventStart(const std::string& origin, const std::string& userid, const std::string& reflector, const std::string& session) { + Event ev; + ev.data.compound["origin"] = origin; //std::cout << req; - if(_isRunning) { - LOG(ERROR) << "already connected"; + if(num_connected>0) { + num_connected++; + ev.name = "start.reply"; + returnEvent(ev); return; } @@ -213,17 +285,21 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std rv = miles_connect_reflector_session((char*)reflector.c_str(), (char*)session.c_str()); if (!rv) { LOG(ERROR) << "Could not setup reflector session"; + ev.name = "start.error"; + returnEvent(ev); return; } LOG(ERROR) << "session set up"; + /* set up media buffers */ + init_media_buffers(); + /* Set up audio and video RTP sockets */ video_rtp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), video_port, video_port, 10, 16000); audio_rtp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), audio_port, audio_port, 10, 16000); video_rtp_out_socket = video_rtp_in_socket; audio_rtp_out_socket = audio_rtp_in_socket; - LOG(ERROR) << "rtp sockets set up"; /* Set up audio and video RTCP sockets */ video_rtcp_in_socket = miles_net_setup_udp_socket((char*)reflector.c_str(), video_port+1, video_port+1, 10, 16000); @@ -241,9 +317,13 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std /* Set up video capture */ video_grabber_available = setup_video_grabber(); + if(video_grabber_available) + sendvideo_enabled = 1; /* Set up audio capture/playback */ audio_available = setup_audio(); + if(audio_available) + sendaudio_enabled = 1; /* Set up outgoing RTP stream for video */ if(video_grabber_available) { @@ -263,7 +343,15 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std out_rtcp_audio_stream = miles_rtp_setup_outgoing_rtcp_stream(audio_session->rtcp_session, audio_rtcp_out_socket, out_rtp_audio_stream->ssrc); } + /* Register RTCP APP handler for text messages */ + rv = miles_rtp_register_rtcp_app_handler("text", NULL, receive_text_message_callback, 0); + if(rv==0) { + LOG(ERROR) << "Error registering text message callback"; + } + memset(confero_text_msg_buf, 0, 1000); + _isRunning = true; + num_connected=1; _reflector = reflector; _userId = userid; _session = session; @@ -271,29 +359,55 @@ void MilesSessionInvoker::processEventStart(const std::string& origin, const std if(audio_available) _audioThread = new tthread::thread(MilesSessionInvoker::runAudio, this); _videoThread = new tthread::thread(MilesSessionInvoker::runVideo, this); - Event ev; ev.name = "start.reply"; - ev.data.compound["origin"] = origin; returnEvent(ev); } void MilesSessionInvoker::processEventStop(const std::string& origin) { + Event ev; + ev.data.compound["origin"] = origin; + + if(num_connected==0) { + LOG(ERROR) << "not connected"; + ev.name = "stop.error"; + returnEvent(ev); + return; + } + num_connected--; + if(num_connected>0) { + ev.name = "stop.reply"; + returnEvent(ev); + return; + } int rv = miles_disconnect_reflector_session((char*)_reflector.c_str(), (char*)_session.c_str()); if (!rv) { LOG(ERROR) << "Could not disconnect from reflector session"; + ev.name = "stop.error"; + returnEvent(ev); return; } - free_media_buffers(); + /* Unregister RTCP APP handler for text messages */ + rv = miles_rtp_unregister_rtcp_app_handler("text"); + if(rv==0) { + LOG(ERROR) << "Error registering text message callback"; + } _isRunning = false; - Event ev; + free_text_buffers(); ev.name = "stop.reply"; - ev.data.compound["origin"] = origin; returnEvent(ev); + LOG(ERROR) << "disconnected from reflector session"; } void MilesSessionInvoker::processEventParticipants(const std::string& origin) { Event ev; + ev.data.compound["origin"] = origin; + if(num_connected==0) { + LOG(ERROR) << "not connected"; + ev.name = "participants.error"; + returnEvent(ev); + return; + } // create an array with objects inside for (int i = 0; i < 5; i++) { Data userInfo; @@ -303,47 +417,51 @@ void MilesSessionInvoker::processEventParticipants(const std::string& origin) { } ev.name = "participants.reply"; - ev.data.compound["origin"] = origin; returnEvent(ev); - } + void MilesSessionInvoker::processEventThumbnail(const std::string& origin, const std::string& userid) { - LOG(ERROR) << "processEventThumbnail"; + Event ev; + ev.data.compound["origin"] = origin; + if(num_connected==0) { + LOG(ERROR) << "not connected"; + ev.name = "thumbnail.error"; + returnEvent(ev); + return; + } URL imageURL("emptyface.jpg"); imageURL.toAbsolute(_interpreter->getBaseURI()); std::stringstream ssImage; ssImage << imageURL; std::string imageContent = ssImage.str(); - Event ev; ev.name = "thumbnail.reply"; - ev.data.compound["origin"] = origin; - int has_thumb = 0; + struct thumb_entry *use_thumb = NULL; struct miles_rtp_in_stream *rtps; struct miles_list *p; struct thumb_entry *te; _mutex.lock(); - if(video_session->instreams) { - rtps = video_session->instreams->stream; - if(rtps) { - p = thumb_list; - while(p) { - te = (struct thumb_entry *)p->item; - if(te->ssrc == rtps->ssrc) { - break; - } - p = p->next; - } - if(p) { - has_thumb = 1; - ev.data.compound["image"] = Data(te->img_buf, te->img_size, "image/jpeg"); - } + // Find thumbnail of user + p = thumb_list; + while(p) { + te = (struct thumb_entry *)p->item; + if(te->userid && strcmp(te->userid, userid.c_str()) == 0) { + use_thumb = te; + break; } - } - if(!has_thumb) { - // Return empty face image - ev.data.compound["image"] = Data(imageContent.data(), imageContent.size(), "image/jpeg"); + if(te->userid==NULL && use_thumb == NULL) { + use_thumb = te; + } + p = p->next; + } + if(!p && use_thumb) + use_thumb->userid = strdup(userid.c_str()); + if(use_thumb) { + ev.data.compound["image"] = Data(use_thumb->img_buf, use_thumb->img_size, "image/jpeg"); + } else { + // Return empty face image + ev.data.compound["image"] = Data(imageContent.data(), imageContent.size(), "image/jpeg"); } _mutex.unlock(); @@ -378,6 +496,7 @@ void MilesSessionInvoker::processEventSendVideo(const std::string& origin, size_ Event ev; ev.name = "sendvideo.reply"; ev.data.compound["origin"] = origin; + sendvideo_enabled = 1; returnEvent(ev); } void MilesSessionInvoker::processEventSendVideoOff(const std::string& origin) { @@ -385,33 +504,67 @@ void MilesSessionInvoker::processEventSendVideoOff(const std::string& origin) { ev.name = "sendvideooff.reply"; ev.data.compound["origin"] = origin; returnEvent(ev); + sendvideo_enabled = 0; } void MilesSessionInvoker::processEventSendAudio(const std::string& origin, const std::string& encoding) { Event ev; ev.name = "sendaudio.reply"; ev.data.compound["origin"] = origin; returnEvent(ev); + sendaudio_enabled = 1; } void MilesSessionInvoker::processEventSendAudioOff(const std::string& origin) { Event ev; ev.name = "sendaudiooff.reply"; ev.data.compound["origin"] = origin; returnEvent(ev); + sendaudio_enabled = 0; } void MilesSessionInvoker::processEventPostText(const std::string& origin, const std::string& userid, const std::string& message) { + char msgbuf[1000]; + char pkt[1000]; + char *cname = "user@all"; // for now + int n, length; Event ev; - ev.name = "posttext.reply"; + ev.data.compound["origin"] = origin; + if(num_connected==0) { + LOG(ERROR) << "not connected"; + ev.name = "posttext.error"; + returnEvent(ev); + return; + } + ev.name = "posttext.reply"; returnEvent(ev); + if(out_rtcp_video_stream==NULL) + return; + //printf("sending message %s\n", message.c_str()); + memcpy(msgbuf, cname, strlen(cname)+1); + sprintf(msgbuf+strlen(cname)+1, "<%s>: %s", userid.c_str(), message.c_str()); + n = strlen(cname)+1 + userid.length() + 4 + message.length(); + length = miles_rtp_make_rtcp_app(pkt, out_rtcp_video_stream->ssrc, "text", n, msgbuf); + if(length>0 && out_rtcp_video_stream) + out_rtcp_video_stream->send_packet(out_rtcp_video_stream->socket, pkt, length, 0); } + void MilesSessionInvoker::processEventGetText(const std::string& origin) { Event ev; - ev.name = "gettext.reply"; ev.data.compound["origin"] = origin; + if(num_connected==0) { + LOG(ERROR) << "not connected"; + ev.name = "gettext.error"; + returnEvent(ev); + return; + } - if (rand() % 5 == 0) { // return some mocked up chat message - ev.data.compound["message"] = Data(".. and then she was all like: aren't we supposed to discuss work related stuff?", Data::VERBATIM); + ev.name = "gettext.reply"; + if(confero_text_msg_available) { + strcpy(text_msg_buf, confero_text_msg_buf); + ev.data.compound["message"] = Data(text_msg_buf, Data::VERBATIM); + //ev.data.compound["message"] = Data(base64_encode(text_msg_buf, strlen(text_msg_buf)), Data::VERBATIM); ev.data.compound["user"] = Data("username1", Data::VERBATIM); + memset(confero_text_msg_buf, 0, 1000); + confero_text_msg_available = 0; } returnEvent(ev); @@ -428,19 +581,57 @@ void MilesSessionInvoker::runVideo(void* instance) { void MilesSessionInvoker::processVideo() { while(_isRunning) { rtp_video_receiver(video_session); - if(video_grabber_available) + if(video_grabber_available && sendvideo_enabled) video_transmitter(video_grabber, video_encoder, out_rtp_video_stream, out_rtcp_video_stream); } + /* done, clean up */ + if(video_grabber_available) { + miles_rtp_destroy_out_stream(out_rtp_video_stream); + miles_video_grabber_destroy(video_grabber); + miles_video_codec_destroy_encoder(video_encoder); + video_grabber_available = 0; + sendvideo_enabled = 0; + } + miles_rtp_destroy_session(video_session); + miles_list_destroy(thumb_list); + thumb_list = NULL; + miles_net_socket_close(video_rtp_in_socket); + miles_net_socket_close(video_rtcp_in_socket); + + free_video_buffers(); } void MilesSessionInvoker::processAudio() { while(_isRunning) { rtp_audio_receiver(audio_session); - audio_transmitter(audio_dev, audio_encoder, out_rtp_audio_stream, out_rtcp_audio_stream); + if(audio_available && sendaudio_enabled) + audio_transmitter(audio_dev, audio_encoder, out_rtp_audio_stream, out_rtcp_audio_stream); } + /* done, clean up */ + if(audio_available) { + miles_rtp_destroy_out_stream(out_rtp_audio_stream); + if(audio_dev_playback) + miles_audio_device_close(MILES_AUDIO_IO_OPENAL, audio_dev_playback, 0); + if(audio_dev) + miles_audio_device_close(MILES_AUDIO_IO_OPENAL, audio_dev_playback, 1); + miles_audio_codec_destroy_encoder(audio_encoder); + audio_available = 0; + sendaudio_enabled = 0; + } + miles_rtp_destroy_session(audio_session); + miles_net_socket_close(audio_rtp_in_socket); + miles_net_socket_close(audio_rtcp_in_socket); + + free_video_buffers(); } int MilesSessionInvoker::setup_audio() { + /* Check that we have OpeanAL audio */ + if(!miles_audio_io_is_supported(MILES_AUDIO_IO_OPENAL)) { + fprintf(stderr, "OpenAL audio i/o not supported on this platform.\n"); + return 0; + } + /* Initialize and configure audio encoder */ audio_encoder = miles_audio_codec_init_encoder(); audio_encoder->codec_id = miles_audio_codec_get_encoder_for_rtp_payload_type(MILES_RTP_PAYLOAD_TYPE_L16); @@ -454,10 +645,9 @@ int MilesSessionInvoker::setup_audio() { LOG(ERROR) << "Couldn't set up audio codec"; return 0; } - LOG(ERROR) << "audio enc set up"; /* Set up audio grabber */ - int n = miles_audio_device_get_supported_devices(MILES_AUDIO_DEVICE_OPENAL, &supported_audio_devices); + int n = miles_audio_device_get_supported_devices(MILES_AUDIO_IO_OPENAL, &supported_audio_devices); if(n<=0) { /* No audio device available */ LOG(ERROR) << "No audio device available"; @@ -465,7 +655,7 @@ int MilesSessionInvoker::setup_audio() { } /* Use first device that supports capture */ for(int i=0; i<n; i++) { - audio_dev = miles_audio_device_open(MILES_AUDIO_DEVICE_OPENAL, supported_audio_devices[i].id, MILES_AUDIO_FORMAT_PCM, 16000, 2, 1, 640, 1); + audio_dev = miles_audio_device_open(MILES_AUDIO_IO_OPENAL, supported_audio_devices[i].id, MILES_AUDIO_FORMAT_PCM, 16000, 2, 1, 640, 1); if(audio_dev) break; } @@ -476,7 +666,7 @@ int MilesSessionInvoker::setup_audio() { /* Find first audio device that supports playback */ for(int i=0; i<n; i++) { - audio_dev_playback = miles_audio_device_open(MILES_AUDIO_DEVICE_OPENAL, supported_audio_devices[i].id, MILES_AUDIO_FORMAT_PCM, 16000, 2, 1, 640, 0); + audio_dev_playback = miles_audio_device_open(MILES_AUDIO_IO_OPENAL, supported_audio_devices[i].id, MILES_AUDIO_FORMAT_PCM, 16000, 2, 1, 640, 0); if(audio_dev_playback) { audio_dev_playback_id = supported_audio_devices[i].id; break; @@ -594,14 +784,14 @@ void MilesSessionInvoker::playback_audio(u_int32_t ssrc, char *buf, int sample_r if(audio_dev_playback == NULL || audio_dev_playback->chunk_size != size || audio_dev_playback->sample_rate != sample_rate || audio_dev_playback->format != audio_format || audio_dev_playback->bytes_per_sample != bps) { if(audio_dev_playback) - miles_audio_device_close(MILES_AUDIO_DEVICE_OPENAL, audio_dev_playback, 0); - audio_dev_playback = miles_audio_device_open(MILES_AUDIO_DEVICE_OPENAL, audio_dev_playback_id, audio_format, sample_rate, bps, 1, size, 0); + miles_audio_device_close(MILES_AUDIO_IO_OPENAL, audio_dev_playback, 0); + audio_dev_playback = miles_audio_device_open(MILES_AUDIO_IO_OPENAL, audio_dev_playback_id, audio_format, sample_rate, bps, 1, size, 0); if(audio_dev_playback == NULL) return; } /* play audio */ - miles_audio_device_write(MILES_AUDIO_DEVICE_OPENAL, audio_dev_playback, buf, size); + miles_audio_device_write(MILES_AUDIO_IO_OPENAL, audio_dev_playback, buf, size); } /** @@ -655,6 +845,7 @@ int MilesSessionInvoker::video_receiver(struct miles_rtp_in_stream *rtp_stream, p = miles_list_append(thumb_list, te); te->ssrc = rtp_stream->ssrc; te->window_ctx = NULL; + te->userid = NULL; te->img_buf = (char *)malloc(bytes_read); te->buf_size = bytes_read; te->img_size = 0; @@ -842,7 +1033,7 @@ int MilesSessionInvoker::audio_transmitter(struct miles_audio_device *dev, struc /* Send RTCP packets, if due */ miles_rtp_send_rtcp(out_rtcp_audio_stream); - n = miles_audio_device_read(MILES_AUDIO_DEVICE_OPENAL, dev, audio_read_buf, codec_ctx->chunk_size); + n = miles_audio_device_read(MILES_AUDIO_IO_OPENAL, dev, audio_read_buf, codec_ctx->chunk_size); if(n <= 0) return 0; if(dev->format != codec_ctx->input_format) { diff --git a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h index 32d4610..fec2243 100644 --- a/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h +++ b/src/uscxml/plugins/invoker/miles/MilesSessionInvoker.h @@ -27,6 +27,7 @@ extern "C" { #include "miles/network.h" #include "miles/rtp.h" #include "miles/audio_codec.h" +#include "miles/audio_io.h" #include "miles/audio_device.h" #include "miles/video_codec.h" #include "miles/video_grabber.h" @@ -50,6 +51,7 @@ struct thumb_entry { int img_format; // JPEG or PNG image char *decode_buf; u_int32_t ssrc; + char *userid; // The user id assigned to the video stream void *window_ctx; // The context of the window popped up when the thumbnail is clicked. }; @@ -120,10 +122,15 @@ protected: struct miles_list *thumb_list; int save_image; + char *text_msg_buf; + int text_msg_available; + struct miles_audio_device *audio_dev_playback; int audio_dev_playback_id; int audio_available; int video_grabber_available; + int sendvideo_enabled; + int sendaudio_enabled; static void runAudio(void* instance); static void runVideo(void* instance); @@ -134,6 +141,10 @@ protected: void init_media_buffers(); void free_media_buffers(); + void free_video_buffers(); + void free_audio_buffers(); + void free_text_buffers(); + void render_video_image(char *img, int width, int height, int img_format); void playback_audio(u_int32_t ssrc, char *buf, int sample_rate, int bps, int audio_format, int size); int video_receiver(struct miles_rtp_in_stream *rtp_stream, char *data, int bytes_read); @@ -145,6 +156,7 @@ protected: bool _isRunning; + int num_connected; std::string _userId, _reflector, _session; tthread::thread* _videoThread; tthread::thread* _audioThread; |