mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-06 21:33:08 +00:00
Merge branch 'master' of git.linphone.org:linphone
This commit is contained in:
commit
d277ef7517
6 changed files with 450 additions and 351 deletions
|
|
@ -3323,7 +3323,7 @@ static void linphone_call_start_text_stream(LinphoneCall *call) {
|
|||
if (is_multicast) rtp_session_set_multicast_ttl(call->textstream->ms.sessions.rtp_session,tstream->ttl);
|
||||
|
||||
text_stream_start(call->textstream, call->text_profile, rtp_addr, tstream->rtp_port, rtcp_addr, (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (tstream->rtcp_port ? tstream->rtcp_port : tstream->rtp_port + 1) : 0, used_pt);
|
||||
ms_filter_add_notify_callback(call->textstream->rttsink, real_time_text_character_received, call, TRUE);
|
||||
ms_filter_add_notify_callback(call->textstream->rttsink, real_time_text_character_received, call, FALSE);
|
||||
|
||||
ms_media_stream_sessions_set_encryption_mandatory(&call->textstream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core));
|
||||
} else ms_warning("No text stream accepted.");
|
||||
|
|
|
|||
|
|
@ -1684,6 +1684,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
ms_init();
|
||||
|
||||
linphone_core_register_default_codecs(lc);
|
||||
linphone_core_register_offer_answer_providers(lc);
|
||||
/* Get the mediastreamer2 event queue */
|
||||
/* This allows to run event's callback in linphone_core_iterate() */
|
||||
lc->msevq=ms_factory_create_event_queue(ms_factory_get_fallback());
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -31,12 +31,8 @@ static bool_t only_telephone_event(const MSList *l){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _PayloadTypeMatcher{
|
||||
const char *mime_type;
|
||||
PayloadType *(*match_func)(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads);
|
||||
}PayloadTypeMatcher;
|
||||
|
||||
static PayloadType * opus_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){
|
||||
static PayloadType * opus_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
|
@ -50,15 +46,25 @@ static PayloadType * opus_match(const MSList *local_payloads, const PayloadType
|
|||
pt->channels=1; /*so that we respond with same number of channels */
|
||||
candidate=pt;
|
||||
}else if (refpt->channels==2){
|
||||
return pt;
|
||||
return payload_type_clone(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
return candidate ? payload_type_clone(candidate) : NULL;
|
||||
}
|
||||
|
||||
static MSOfferAnswerContext *opus_offer_answer_create_context(void){
|
||||
static MSOfferAnswerContext opus_oa = {opus_match, NULL};
|
||||
return &opus_oa;
|
||||
}
|
||||
|
||||
MSOfferAnswerProvider opus_offer_answer_provider={
|
||||
"opus",
|
||||
opus_offer_answer_create_context
|
||||
};
|
||||
|
||||
/* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/
|
||||
static PayloadType * g729A_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){
|
||||
static PayloadType * g729A_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
|
@ -70,38 +76,57 @@ static PayloadType * g729A_match(const MSList *local_payloads, const PayloadType
|
|||
candidate=pt;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
return candidate ? payload_type_clone(candidate) : NULL;
|
||||
}
|
||||
|
||||
static PayloadType * amr_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){
|
||||
PayloadType *pt;
|
||||
char value[10];
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
static MSOfferAnswerContext *g729a_offer_answer_create_context(void){
|
||||
static MSOfferAnswerContext g729_oa = {g729A_match, NULL};
|
||||
return &g729_oa;
|
||||
}
|
||||
|
||||
for (elem=local_payloads;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
MSOfferAnswerProvider g729a_offer_answer_provider={
|
||||
"G729A",
|
||||
g729a_offer_answer_create_context
|
||||
};
|
||||
|
||||
static PayloadType * red_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response) {
|
||||
const MSList *elem_local, *elem_remote;
|
||||
PayloadType *red = NULL;
|
||||
|
||||
for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) {
|
||||
PayloadType *pt = (PayloadType*)elem_local->data;
|
||||
|
||||
if ( pt->mime_type && refpt->mime_type
|
||||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels) {
|
||||
int octedalign1=0,octedalign2=0;
|
||||
if (pt->recv_fmtp!=NULL && fmtp_get_value(pt->recv_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign1=atoi(value);
|
||||
}
|
||||
if (refpt->send_fmtp!=NULL && fmtp_get_value(refpt->send_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign2=atoi(value);
|
||||
}
|
||||
if (octedalign1==octedalign2) {
|
||||
candidate=pt;
|
||||
break; /*exact match */
|
||||
if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) {
|
||||
red = payload_type_clone(pt);
|
||||
|
||||
for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) {
|
||||
PayloadType *pt2 = (PayloadType*)elem_remote->data;
|
||||
if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) {
|
||||
int t140_payload_number = payload_type_get_number(pt2);
|
||||
char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number);
|
||||
/*modify the local payload and the return value*/
|
||||
payload_type_set_recv_fmtp(pt, red_fmtp);
|
||||
payload_type_set_recv_fmtp(red, red_fmtp);
|
||||
ms_free(red_fmtp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
return red;
|
||||
}
|
||||
|
||||
static MSOfferAnswerContext *red_offer_answer_create_context(void){
|
||||
static MSOfferAnswerContext red_oa = {red_match, NULL};
|
||||
return &red_oa;
|
||||
}
|
||||
|
||||
MSOfferAnswerProvider red_offer_answer_provider={
|
||||
"red",
|
||||
red_offer_answer_create_context
|
||||
};
|
||||
|
||||
static PayloadType * generic_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
|
|
@ -113,55 +138,31 @@ static PayloadType * generic_match(const MSList *local_payloads, const PayloadTy
|
|||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels)
|
||||
return pt;
|
||||
return payload_type_clone(pt);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PayloadType * red_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads) {
|
||||
const MSList *elem_local, *elem_remote;
|
||||
PayloadType *red = NULL;
|
||||
|
||||
for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) {
|
||||
PayloadType *pt = (PayloadType*)elem_local->data;
|
||||
|
||||
if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) {
|
||||
red = pt;
|
||||
|
||||
for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) {
|
||||
PayloadType *pt2 = (PayloadType*)elem_remote->data;
|
||||
if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) {
|
||||
int t140_payload_number = payload_type_get_number(pt2);
|
||||
const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number);
|
||||
payload_type_set_recv_fmtp(red, red_fmtp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return red;
|
||||
void linphone_core_register_offer_answer_providers(LinphoneCore *lc){
|
||||
MSFactory *factory = ms_factory_get_fallback();
|
||||
ms_factory_register_offer_answer_provider(factory, &red_offer_answer_provider);
|
||||
ms_factory_register_offer_answer_provider(factory, &g729a_offer_answer_provider);
|
||||
ms_factory_register_offer_answer_provider(factory, &opus_offer_answer_provider);
|
||||
}
|
||||
|
||||
static PayloadTypeMatcher matchers[]={
|
||||
{"opus", opus_match},
|
||||
{"G729A", g729A_match},
|
||||
{"AMR", amr_match},
|
||||
{"AMR-WB", amr_match},
|
||||
{"red", red_match},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list
|
||||
*/
|
||||
static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){
|
||||
PayloadTypeMatcher *m;
|
||||
for(m=matchers;m->mime_type!=NULL;++m){
|
||||
if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){
|
||||
return m->match_func(local_payloads, refpt, remote_payloads);
|
||||
}
|
||||
static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt,
|
||||
const MSList *remote_payloads, bool_t reading_response){
|
||||
PayloadType *ret = NULL;
|
||||
MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(ms_factory_get_fallback(), refpt->mime_type);
|
||||
if (ctx){
|
||||
ms_message("Doing offer/answer processing with specific provider for codec [%s]", refpt->mime_type);
|
||||
ret = ms_offer_answer_context_match_payload(ctx, local_payloads, refpt, remote_payloads, reading_response);
|
||||
ms_offer_answer_context_destroy(ctx);
|
||||
return ret;
|
||||
}
|
||||
return generic_match(local_payloads, refpt, remote_payloads);
|
||||
}
|
||||
|
|
@ -175,9 +176,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
|
||||
for(e2=remote;e2!=NULL;e2=e2->next){
|
||||
PayloadType *p2=(PayloadType*)e2->data;
|
||||
matched=find_payload_type_best_match(local,p2,remote);
|
||||
matched=find_payload_type_best_match(local, p2, remote, reading_response);
|
||||
if (matched){
|
||||
PayloadType *newp;
|
||||
int local_number=payload_type_get_number(matched);
|
||||
int remote_number=payload_type_get_number(p2);
|
||||
|
||||
|
|
@ -189,37 +189,36 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
}
|
||||
}
|
||||
|
||||
newp=payload_type_clone(matched);
|
||||
if (p2->send_fmtp){
|
||||
payload_type_append_send_fmtp(newp,p2->send_fmtp);
|
||||
payload_type_append_send_fmtp(matched,p2->send_fmtp);
|
||||
}
|
||||
newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND;
|
||||
matched->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND;
|
||||
if (p2->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
|
||||
newp->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED;
|
||||
matched->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED;
|
||||
/* Negotiation of AVPF features (keep common features) */
|
||||
newp->avpf.features &= p2->avpf.features;
|
||||
newp->avpf.rpsi_compatibility = p2->avpf.rpsi_compatibility;
|
||||
matched->avpf.features &= p2->avpf.features;
|
||||
matched->avpf.rpsi_compatibility = p2->avpf.rpsi_compatibility;
|
||||
/* Take bigger AVPF trr interval */
|
||||
if (p2->avpf.trr_interval < matched->avpf.trr_interval) {
|
||||
newp->avpf.trr_interval = matched->avpf.trr_interval;
|
||||
matched->avpf.trr_interval = matched->avpf.trr_interval;
|
||||
}
|
||||
}
|
||||
res=ms_list_append(res,newp);
|
||||
res=ms_list_append(res,matched);
|
||||
/* we should use the remote numbering even when parsing a response */
|
||||
payload_type_set_number(newp,remote_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
payload_type_set_number(matched,remote_number);
|
||||
payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
if (reading_response && remote_number!=local_number){
|
||||
ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i",
|
||||
newp->mime_type, local_number, remote_number);
|
||||
matched->mime_type, local_number, remote_number);
|
||||
/*
|
||||
We must add this payload type with our local numbering in order to be able to receive it.
|
||||
Indeed despite we must sent with the remote numbering, we must be able to receive with
|
||||
our local one.
|
||||
*/
|
||||
newp=payload_type_clone(newp);
|
||||
payload_type_set_number(newp,local_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,newp);
|
||||
matched=payload_type_clone(matched);
|
||||
payload_type_set_number(matched,local_number);
|
||||
payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,matched);
|
||||
}
|
||||
}else{
|
||||
if (p2->channels>0)
|
||||
|
|
|
|||
|
|
@ -1083,6 +1083,7 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s
|
|||
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
|
||||
LinphoneContent *linphone_content_from_sal_body(const SalBody *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
void linphone_core_register_offer_answer_providers(LinphoneCore *lc);
|
||||
|
||||
|
||||
struct _LinphoneContent {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3caf56649034b6f5ec633372ae0c24416b9013a5
|
||||
Subproject commit ca35de0fbd6b7e1a93f0f2bd1ea9983074e6c6f7
|
||||
Loading…
Add table
Reference in a new issue