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 (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 red; }
/* return TRUE if codec can be used with bandwidth, FALSE else*/ bool_t linphone_core_check_payload_type_usability(const LinphoneCore *lc, PayloadType *pt) { double codec_band; double npacket; double packet_size; int bitrate; int min_audio_bw=get_min_bandwidth(lc->dw_audio_bw,lc->up_audio_bw); int min_video_bw=get_min_bandwidth(lc->dw_video_bw,lc->up_video_bw); bool_t ret=FALSE; switch (pt->type){ case PAYLOAD_AUDIO_CONTINUOUS: case PAYLOAD_AUDIO_PACKETIZED: if (strcmp(pt->mime_type,"speex")==0 && (pt->clock_rate==8000)){ /*speex can go down to 8kbit/s */ bitrate=8000; }else bitrate=pt->normal_bitrate; /* very approximative estimation... revisit*/ npacket=50; packet_size=(double)(bitrate/(50*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; codec_band=packet_size*8.0*npacket; ret=bandwidth_is_greater(min_audio_bw*1000,codec_band); //ms_message("Payload %s: %g",pt->mime_type,codec_band); break; case PAYLOAD_VIDEO: if (min_video_bw!=0) {/* infinite (-1) or strictly positive*/ if (strcmp(pt->mime_type,"H263-1998")==0){ payload_type_set_recv_fmtp(pt,"CIF=1;QCIF=1"); } /*let the video use all the bandwidth minus the maximum bandwidth used by audio */ if (min_video_bw>0) pt->normal_bitrate=min_video_bw*1000; else pt->normal_bitrate=512000; ret=TRUE; } else ret=FALSE; break; } /*if (!ret) ms_warning("Payload %s is not usable with your internet connection.",pt->mime_type);*/ return ret; }
PayloadType * sipomatic_payload_is_supported(sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile) { int localpt; if (payload->a_rtpmap!=NULL){ localpt=rtp_profile_get_payload_number_from_rtpmap(local_profile,payload->a_rtpmap); }else{ localpt=payload->pt; ms_warning("payload has no rtpmap."); } if (localpt>=0){ /* this payload is supported in our local rtp profile, so add it to the dialog rtp profile */ PayloadType *rtppayload; rtppayload=rtp_profile_get_payload(local_profile,localpt); if (rtppayload==NULL) return NULL; /*check if we have the appropriate coder/decoder for this payload */ if (strcmp(rtppayload->mime_type,"telephone-event")!=0) { if (!ms_filter_codec_supported(rtppayload->mime_type)) { ms_message("Codec %s is not supported.", rtppayload->mime_type); return NULL; } } rtppayload=payload_type_clone(rtppayload); rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload); /* add to the rtp payload type some other parameters (bandwidth) */ if (payload->b_as_bandwidth!=0) rtppayload->normal_bitrate=payload->b_as_bandwidth*1000; if (payload->a_fmtp!=NULL) payload_type_set_send_fmtp(rtppayload,payload->a_fmtp); if (strcasecmp(rtppayload->mime_type,"iLBC")==0){ /*default to 30 ms mode */ payload->a_fmtp="ptime=30"; payload_type_set_recv_fmtp(rtppayload,payload->a_fmtp); } return rtppayload; } return NULL; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneVideoPolicy policy; int i; LinphoneAddress *addr=NULL; LCSipTransports tp; char * tmp = NULL; LpConfig * lp_config = lp_config_new(NULL); int max_call_duration=3600; static const char *media_file = NULL; policy.automatically_accept=TRUE; signal(SIGINT,stop); #ifndef _WIN32 signal(SIGUSR1,stats); signal(SIGUSR2,dump_call_logs); #endif for(i = 1; i < argc; ++i) { if (strcmp(argv[i], "--verbose") == 0) { linphone_core_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); } else if (strcmp(argv[i], "--max-call-duration") == 0){ max_call_duration = atoi(argv[++i]); } else if (strcmp(argv[i], "--listening-uri") == 0){ addr = linphone_address_new(argv[++i]); if (!addr) { printf("Error, bad sip uri"); helper(argv[0]); } /* switch(linphone_address_get_transport(addr)) { case LinphoneTransportUdp: case LinphoneTransportTcp: break; default: ms_error("Error, bad sip uri [%s] transport, should be udp | tcp",argv[i]); helper(); break; }*/ } else if (strcmp(argv[i], "--media-file") == 0){ i++; if (i<argc){ media_file = argv[i]; }else helper(argv[0]); } else { helper(argv[0]); } } if (!addr) { addr = linphone_address_new("sip:[email protected]:5060"); } lp_config_set_string(lp_config,"sip","bind_address",linphone_address_get_domain(addr)); lp_config_set_string(lp_config,"rtp","bind_address",linphone_address_get_domain(addr)); lp_config_set_int(lp_config,"misc","history_max_size",100000); vtable.call_state_changed=call_state_changed; lc=linphone_core_new_with_config(&vtable,lp_config,NULL); linphone_core_enable_video_capture(lc,TRUE); linphone_core_enable_video_display(lc,FALSE); linphone_core_set_video_policy(lc,&policy); linphone_core_enable_keep_alive(lc,FALSE); /*instead of using sound capture card, a file is played to the calling party*/ linphone_core_set_use_files(lc,TRUE); linphone_core_enable_echo_cancellation(lc, FALSE); /*no need for local echo cancellation when playing files*/ if (!media_file){ linphone_core_set_play_file(lc,PACKAGE_DATA_DIR "/sounds/linphone/hello16000.wav"); linphone_core_set_preferred_framerate(lc,5); }else{ PayloadType *pt = linphone_core_find_payload_type(lc, "opus", 48000, -1); /*if opus is present, give it a bitrate for good quality with music, and stereo enabled*/ if (pt){ linphone_core_set_payload_type_bitrate(lc, pt, 150); payload_type_set_send_fmtp(pt, "stereo=1"); payload_type_set_recv_fmtp(pt, "stereo=1"); } linphone_core_set_play_file(lc, media_file); linphone_core_set_preferred_video_size_by_name(lc, "720p"); } { MSWebCamDesc *desc = ms_mire_webcam_desc_get(); if (desc){ ms_web_cam_manager_add_cam(ms_factory_get_web_cam_manager(linphone_core_get_ms_factory(lc)),ms_web_cam_new(desc)); linphone_core_set_video_device(lc,"Mire: Mire (synthetic moving picture)"); } } memset(&tp,0,sizeof(LCSipTransports)); tp.udp_port = linphone_address_get_port(addr); tp.tcp_port = linphone_address_get_port(addr); linphone_core_set_sip_transports(lc,&tp); linphone_core_set_audio_port_range(lc,1024,65000); linphone_core_set_video_port_range(lc,1024,65000); linphone_core_set_primary_contact(lc,tmp=linphone_address_as_string(addr)); ms_free(tmp); /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ const bctbx_list_t * iterator; linphone_core_iterate(lc); ms_usleep(50000); if (print_stats) { ms_message("*********************************"); ms_message("*Current number of calls [%10u] *", (unsigned int)bctbx_list_size(linphone_core_get_calls(lc))); ms_message("*Number of calls until now [%10u] *", (unsigned int)bctbx_list_size(linphone_core_get_call_logs(lc))); ms_message("*********************************"); print_stats=FALSE; } if (dump_stats) { ms_message("*********************************"); for (iterator=linphone_core_get_call_logs(lc);iterator!=NULL;iterator=iterator->next) { LinphoneCallLog *call_log=(LinphoneCallLog *)iterator->data; char * tmp_str = linphone_call_log_to_str(call_log); ms_message("\n%s",tmp_str); ms_free(tmp_str); } dump_stats=FALSE; ms_message("*********************************"); } for (iterator=linphone_core_get_calls(lc);iterator!=NULL;iterator=iterator->next) { LinphoneCall *call=(LinphoneCall *)iterator->data; if (linphone_call_get_duration(call) > max_call_duration) { ms_message("Terminating call [%p] after [%i] s",call,linphone_call_get_duration(call)); linphone_core_terminate_call(lc,call); break; } } } ms_message("Shutting down...\n"); linphone_core_destroy(lc); ms_message("Exited\n"); return 0; }