]> sjero.net Git - linphone/commitdiff
Do not restart the media streams if only network addresses have been changed in re...
authorGhislain MARY <ghislain.mary@belledonne-communications.com>
Mon, 22 Oct 2012 13:44:23 +0000 (15:44 +0200)
committerGhislain MARY <ghislain.mary@belledonne-communications.com>
Tue, 23 Oct 2012 08:45:53 +0000 (10:45 +0200)
coreapi/callbacks.c
coreapi/sal.c
coreapi/sal.h

index e7f6a7b219846c85b47eb1a76d90b2a39ca3cbf4..a4a4232c436ebf397c945fba403a02a856f19381 100644 (file)
@@ -27,9 +27,63 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details);
 
-static bool_t media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd){
-       if (call->params.in_conference!=call->current_params.in_conference) return TRUE;
-       return !sal_media_description_equals(oldmd,newmd)  || call->up_bw!=linphone_core_get_upload_bandwidth(call->core);
+static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) {
+       if (call->params.in_conference != call->current_params.in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED;
+       if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_CHANGED;
+       return sal_media_description_equals(oldmd, newmd);
+}
+
+void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) {
+       SalStreamDescription *old_audiodesc = NULL;
+       SalStreamDescription *old_videodesc = NULL;
+       SalStreamDescription *new_audiodesc = NULL;
+       SalStreamDescription *new_videodesc = NULL;
+       char *rtp_addr, *rtcp_addr;
+       int i;
+
+       for (i = 0; i < old_md->nstreams; i++) {
+               if (old_md->streams[i].type == SalAudio) {
+                       old_audiodesc = &old_md->streams[i];
+               } else if (old_md->streams[i].type == SalVideo) {
+                       old_videodesc = &old_md->streams[i];
+               }
+       }
+       for (i = 0; i < new_md->nstreams; i++) {
+               if (new_md->streams[i].type == SalAudio) {
+                       new_audiodesc = &new_md->streams[i];
+               } else if (new_md->streams[i].type == SalVideo) {
+                       new_videodesc = &new_md->streams[i];
+               }
+       }
+       if (call->audiostream && new_audiodesc) {
+               rtp_addr = (new_audiodesc->rtp_addr[0] != '\0') ? new_audiodesc->rtp_addr : new_md->addr;
+               rtcp_addr = (new_audiodesc->rtcp_addr[0] != '\0') ? new_audiodesc->rtcp_addr : new_md->addr;
+               ms_message("Change audio stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_audiodesc->rtp_port, rtcp_addr, new_audiodesc->rtcp_port);
+               rtp_session_set_remote_addr_full(call->audiostream->session, rtp_addr, new_audiodesc->rtp_port, rtcp_addr, new_audiodesc->rtcp_port);
+       }
+#ifdef VIDEO_ENABLED
+       if (call->videostream && new_videodesc) {
+               rtp_addr = (new_videodesc->rtp_addr[0] != '\0') ? new_videodesc->rtp_addr : new_md->addr;
+               rtcp_addr = (new_videodesc->rtcp_addr[0] != '\0') ? new_videodesc->rtcp_addr : new_md->addr;
+               ms_message("Change video stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
+               rtp_session_set_remote_addr_full(call->videostream->session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
+       }
+#endif
+
+       /* Copy address and port values from new_md to old_md since we will keep old_md as resultdesc */
+       strcpy(old_md->addr, new_md->addr);
+       if (old_audiodesc && new_audiodesc) {
+               strcpy(old_audiodesc->rtp_addr, new_audiodesc->rtp_addr);
+               strcpy(old_audiodesc->rtcp_addr, new_audiodesc->rtcp_addr);
+               old_audiodesc->rtp_port = new_audiodesc->rtp_port;
+               old_audiodesc->rtcp_port = new_audiodesc->rtcp_port;
+       }
+       if (old_videodesc && new_videodesc) {
+               strcpy(old_videodesc->rtp_addr, new_videodesc->rtp_addr);
+               strcpy(old_videodesc->rtcp_addr, new_videodesc->rtcp_addr);
+               old_videodesc->rtp_port = new_videodesc->rtp_port;
+               old_videodesc->rtcp_port = new_videodesc->rtcp_port;
+       }
 }
 
 void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
@@ -49,7 +103,8 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
        if ((call->audiostream && call->audiostream->ticker) || (call->videostream && call->videostream->ticker)){
                /* we already started media: check if we really need to restart it*/
                if (oldmd){
-                       if (!media_parameters_changed(call,oldmd,new_md) && !call->playing_ringbacktone){
+                       int md_changed = media_parameters_changed(call, oldmd, new_md);
+                       if ((md_changed == SAL_MEDIA_DESCRIPTION_UNCHANGED) && !call->playing_ringbacktone) {
                                /*as nothing has changed, keep the oldmd */
                                call->resultdesc=oldmd;
                                sal_media_description_unref(new_md);
@@ -66,6 +121,12 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
                                }
                                ms_message("No need to restart streams, SDP is unchanged.");
                                return;
+                       } else if ((md_changed == SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED) && !call->playing_ringbacktone) {
+                               call->resultdesc = oldmd;
+                               ms_message("Network parameters have changed, update them.");
+                               linphone_core_update_streams_destinations(lc, call, oldmd, new_md);
+                               sal_media_description_unref(new_md);
+                               return;
                        }else{
                                ms_message("Media descriptions are different, need to restart the streams.");
                        }
index b349ad0a4e4efd002dbd701d607415a88c843fff..229ee577f3a531e3b8c9d3bf85c1312c6d5e03aa 100644 (file)
@@ -177,32 +177,40 @@ static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
        return TRUE;
 }
 
-bool_t sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2){
-       if (sd1->proto!=sd2->proto) return FALSE;
-       if (sd1->type!=sd2->type) return FALSE;
-       if (strcmp(sd1->rtp_addr,sd2->rtp_addr)!=0) return FALSE;
-       if (sd1->rtp_port!=sd2->rtp_port) return FALSE;
-       if (strcmp(sd1->rtcp_addr,sd2->rtcp_addr)!=0) return FALSE;
-       if (sd1->rtcp_port!=sd2->rtcp_port) return FALSE;
-       if (!payload_list_equals(sd1->payloads,sd2->payloads)) return FALSE;
-       if (sd1->bandwidth!=sd2->bandwidth) return FALSE;
-       if (sd1->ptime!=sd2->ptime) return FALSE;
-       /* compare candidates: TODO */
-       if (sd1->dir!=sd2->dir) return FALSE;
-       return TRUE;
+int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2) {
+       int result = SAL_MEDIA_DESCRIPTION_UNCHANGED;
+
+       /* A different proto should result in SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED but the encryption change
+          needs a stream restart for now, so use SAL_MEDIA_DESCRIPTION_CODEC_CHANGED */
+       if (sd1->proto != sd2->proto) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+
+       if (sd1->type != sd2->type) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (strcmp(sd1->rtp_addr, sd2->rtp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
+       if (sd1->rtp_port != sd2->rtp_port) {
+               if ((sd1->rtp_port == 0) || (sd2->rtp_port == 0)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+               else result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
+       }
+       if (strcmp(sd1->rtcp_addr, sd2->rtcp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
+       if (sd1->rtcp_port != sd2->rtcp_port) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
+       if (!payload_list_equals(sd1->payloads, sd2->payloads)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (sd1->bandwidth != sd2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (sd1->ptime != sd2->ptime) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (sd1->dir != sd2->dir) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+
+       return result;
 }
 
-bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2){
+int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2) {
+       int result = SAL_MEDIA_DESCRIPTION_UNCHANGED;
        int i;
-       
-       if (strcmp(md1->addr,md2->addr)!=0) return FALSE;
-       if (md1->nstreams!=md2->nstreams) return FALSE;
-       if (md1->bandwidth!=md2->bandwidth) return FALSE;
-       for(i=0;i<md1->nstreams;++i){
-               if (!sal_stream_description_equals(&md1->streams[i],&md2->streams[i]))
-                       return FALSE;
+
+       if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
+       if (md1->nstreams != md2->nstreams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       for(i = 0; i < md1->nstreams; ++i){
+               result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
        }
-       return TRUE;
+       return result;
 }
 
 static void assign_string(char **str, const char *arg){
index 2913096caf5270b64e97eacf544dc25974f5fb7d..54a075ed6169e817cf4ce0aefc665432c49396ca 100644 (file)
@@ -53,6 +53,11 @@ typedef enum {
        SalTransportDTLS /*DTLS*/
 }SalTransport;
 
+#define SAL_MEDIA_DESCRIPTION_UNCHANGED                0x00
+#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED  0x01
+#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED    0x02
+#define SAL_MEDIA_DESCRIPTION_CHANGED          (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED)
+
 const char* sal_transport_to_string(SalTransport transport);
 SalTransport sal_transport_parse(const char*);
 /* Address manipulation API*/
@@ -189,7 +194,7 @@ SalMediaDescription *sal_media_description_new();
 void sal_media_description_ref(SalMediaDescription *md);
 void sal_media_description_unref(SalMediaDescription *md);
 bool_t sal_media_description_empty(const SalMediaDescription *md);
-bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
+int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
 bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
 SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
     SalMediaProto proto, SalStreamType type);