3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "offeranswer.h"
24 static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
28 PayloadType *candidate=NULL;
30 for (elem=l;elem!=NULL;elem=elem->next){
31 pt=(PayloadType*)elem->data;
32 if (strcasecmp(pt->mime_type,refpt->mime_type)==0 && pt->clock_rate==refpt->clock_rate){
34 /*good candidate, check fmtp for H264 */
35 if (strcasecmp(pt->mime_type,"H264")==0){
36 if (pt->recv_fmtp!=NULL && refpt->recv_fmtp!=NULL){
38 if (fmtp_get_value(pt->recv_fmtp,"packetization-mode",value,sizeof(value))){
41 if (fmtp_get_value(refpt->recv_fmtp,"packetization-mode",value,sizeof(value))){
45 break; /*exact match */
53 static MSList *match_payloads(const MSList *local, const MSList *remote){
57 for(e2=remote;e2!=NULL;e2=e2->next){
58 PayloadType *p2=(PayloadType*)e2->data;
59 matched=find_payload_type_best_match(local,p2);
61 matched=payload_type_clone(matched);
63 payload_type_set_send_fmtp(matched,p2->recv_fmtp);
64 res=ms_list_append(res,matched);
65 payload_type_set_number(matched,payload_type_get_number(p2));
67 ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate);
73 static bool_t only_telephone_event(const MSList *l){
74 PayloadType *p=(PayloadType*)l->data;
75 if (strcasecmp(p->mime_type,"telephone-event")!=0){
81 static void initiate_outgoing(const SalStreamDescription *local_offer,
82 const SalStreamDescription *remote_answer,
83 SalStreamDescription *result){
84 if (remote_answer->port!=0)
85 result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads);
86 if (result->payloads && !only_telephone_event(result->payloads)){
87 strcpy(result->addr,remote_answer->addr);
88 result->port=remote_answer->port;
89 result->bandwidth=remote_answer->bandwidth;
90 result->ptime=remote_answer->ptime;
91 result->proto=local_offer->proto;
92 result->type=local_offer->type;
99 static void initiate_incoming(const SalStreamDescription *local_cap,
100 const SalStreamDescription *remote_offer,
101 SalStreamDescription *result){
102 result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads);
103 if (result->payloads && !only_telephone_event(result->payloads)){
104 strcpy(result->addr,local_cap->addr);
105 result->port=local_cap->port;
106 result->bandwidth=local_cap->bandwidth;
107 result->ptime=local_cap->ptime;
108 result->proto=local_cap->proto;
109 result->type=local_cap->type;
116 * Returns a media description to run the streams with, based on a local offer
117 * and the returned response (remote).
119 int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
120 const SalMediaDescription *remote_answer,
121 SalMediaDescription *result){
123 const SalStreamDescription *ls,*rs;
124 for(i=0,j=0;i<local_offer->nstreams;++i){
125 ms_message("Processing for stream %i",i);
126 ls=&local_offer->streams[i];
127 rs=sal_media_description_find_stream(remote_answer,ls->proto,ls->type);
129 initiate_outgoing(ls,rs,&result->streams[j]);
132 else ms_warning("No matching stream for %i",i);
135 strcpy(result->addr,remote_answer->addr);
140 * Returns a media description to run the streams with, based on the local capabilities and
141 * and the received offer.
142 * The returned media description is an answer and should be sent to the offerer.
144 int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
145 const SalMediaDescription *remote_offer,
146 SalMediaDescription *result){
148 const SalStreamDescription *ls,*rs;
150 for(i=0,j=0;i<remote_offer->nstreams;++i){
151 rs=&remote_offer->streams[i];
152 ms_message("Processing for stream %i",i);
153 ls=sal_media_description_find_stream(local_capabilities,rs->proto,rs->type);
155 initiate_incoming(ls,rs,&result->streams[j]);
160 strcpy(result->addr,local_capabilities->addr);