diff --git a/linphone/configure.in b/linphone/configure.in index 323cd46350283fb19417fa8d3b2c0e822b8f2c1f..e996f99515477a995fac57c486cc75411a3cfcf5 100644 --- a/linphone/configure.in +++ b/linphone/configure.in @@ -196,7 +196,15 @@ fi AC_SUBST(TRUESPEECH_CFLAGS) AM_CONDITIONAL([BUILD_TRUESPEECH], [test x$truespeech = xtrue]) - +AC_ARG_ENABLE(nonstandard-gsm, + [ --enable-nonstandard-gsm Enable GSM codec at nonstandard rates (11025hz, 16000hz)], + [case "${enableval}" in + yes) exotic_gsm=yes + AC_DEFINE(ENABLE_NONSTANDARD_GSM,1,[Defined when using gsm at nonstandard rates]) + ;; + no) exotic_gsm=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-nonstandard-gsm) ;; + esac],[exotic_gsm=no]) dnl support for RSVP (by Vincent Maury) diff --git a/linphone/coreapi/Makefile.am b/linphone/coreapi/Makefile.am index 4cde949920376f95489fbf6e1353dc702e9a1173..d2506730e99f842f18df0571bff8256270ba5659 100644 --- a/linphone/coreapi/Makefile.am +++ b/linphone/coreapi/Makefile.am @@ -49,5 +49,4 @@ AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \ -DLOG_DOMAIN=\"LinphoneCore\" \ $(IPV6_CFLAGS) \ -DORTP_INET6 \ - $(VIDEO_CFLAGS) - + $(VIDEO_CFLAGS) diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c index 7dbe50bc9a58d85ac01f7f55375c5f340f59677f..4030e259ec113753668b987c26e7c521b185f9d7 100644 --- a/linphone/coreapi/linphonecore.c +++ b/linphone/coreapi/linphonecore.c @@ -655,17 +655,21 @@ const char * linphone_core_get_version(void){ return liblinphone_version; } -#ifdef VIDEO_ENABLED -static PayloadType * payload_type_h264_packetization_mode_1=NULL; -static PayloadType * linphone_h263_1998=NULL; -static PayloadType * linphone_mp4v_es=NULL; -static PayloadType * linphone_h263_old=NULL; -#endif +static MSList *linphone_payload_types=NULL; -#ifdef UNSTANDART_GSM_11K -static PayloadType *gsm_11k=NULL; -#endif +static void linphone_core_assign_payload_type(PayloadType *const_pt, int number, const char *recv_fmtp){ + PayloadType *pt; + pt=payload_type_clone(const_pt); + if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp); + rtp_profile_set_payload(&av_profile,number,pt); +} + +static void linphone_core_free_payload_types(void){ + ms_list_for_each(linphone_payload_types,(void (*)(void*))payload_type_destroy); + ms_list_free(linphone_payload_types); + linphone_payload_types=NULL; +} void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path, void * userdata) { @@ -678,38 +682,30 @@ void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, co gstate_new_state(lc, GSTATE_POWER_STARTUP, NULL); ortp_init(); - rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015); - rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb); - rtp_profile_set_payload(&av_profile,111,&payload_type_speex_wb); - rtp_profile_set_payload(&av_profile,112,&payload_type_ilbc); - rtp_profile_set_payload(&av_profile,116,&payload_type_truespeech); - rtp_profile_set_payload(&av_profile,101,&payload_type_telephone_event); - -#ifdef VIDEO_ENABLED - rtp_profile_set_payload(&av_profile,97,&payload_type_theora); - - linphone_h263_1998=payload_type_clone(&payload_type_h263_1998); - payload_type_set_recv_fmtp(linphone_h263_1998,"CIF=1;QCIF=1"); - rtp_profile_set_payload(&av_profile,98,linphone_h263_1998); - - linphone_h263_old=payload_type_clone(&payload_type_h263); - payload_type_set_recv_fmtp(linphone_h263_old,"QCIF=2"); - rtp_profile_set_payload(&av_profile,34,linphone_h263_old); - - linphone_mp4v_es=payload_type_clone(&payload_type_mp4v); - payload_type_set_recv_fmtp(linphone_mp4v_es,"profile-level-id=3"); - rtp_profile_set_payload(&av_profile,99,linphone_mp4v_es); - rtp_profile_set_payload(&av_profile,100,&payload_type_x_snow); - payload_type_h264_packetization_mode_1=payload_type_clone(&payload_type_h264); - payload_type_set_recv_fmtp(payload_type_h264_packetization_mode_1,"packetization-mode=1"); - rtp_profile_set_payload(&av_profile,103,payload_type_h264_packetization_mode_1); - rtp_profile_set_payload(&av_profile,102,&payload_type_h264); + linphone_core_assign_payload_type(&payload_type_lpc1015,115,NULL); + linphone_core_assign_payload_type(&payload_type_speex_nb,110,"vbr=on"); + linphone_core_assign_payload_type(&payload_type_speex_wb,111,"vbr=on"); + linphone_core_assign_payload_type(&payload_type_speex_uwb,112,"vbr=on"); + linphone_core_assign_payload_type(&payload_type_telephone_event,101,NULL); + linphone_core_assign_payload_type(&payload_type_ilbc,113,NULL); + +#ifdef ENABLE_NONSTANDARD_GSM + { + PayloadType *pt; + pt=payload_type_clone(&payload_type_gsm); + pt->clock_rate=11025; + rtp_profile_set_payload(&av_profile,114,pt); + } #endif -#ifdef UNSTANDART_GSM_11K - gsm_11k=payload_type_clone(&payload_type_gsm); - gsm_11k->clock_rate=11025; - rtp_profile_set_payload(&av_profile,96,gsm_11k); +#ifdef VIDEO_ENABLED + linphone_core_assign_payload_type(&payload_type_h263,34,NULL); + linphone_core_assign_payload_type(&payload_type_theora,97,NULL); + linphone_core_assign_payload_type(&payload_type_h263_1998,98,"CIF=1;QCIF=1"); + linphone_core_assign_payload_type(&payload_type_mp4v,99,"profile-level-id=3"); + linphone_core_assign_payload_type(&payload_type_x_snow,100,NULL); + linphone_core_assign_payload_type(&payload_type_h264,102,NULL); + linphone_core_assign_payload_type(&payload_type_h264,103,"packetization-mode=1"); #endif ms_init(); @@ -2666,10 +2662,8 @@ void linphone_core_uninit(LinphoneCore *lc) if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config); lp_config_destroy(lc->config); sip_setup_unregister_all(); -#ifdef VIDEO_ENABLED - if (payload_type_h264_packetization_mode_1!=NULL) - payload_type_destroy(payload_type_h264_packetization_mode_1); -#endif + + linphone_core_free_payload_types(); ortp_exit(); eXosip_quit(); diff --git a/linphone/coreapi/lpconfig.c b/linphone/coreapi/lpconfig.c index 13021a3775949bb2c44f1253e5be649b8514c4d1..08abcd5e811089edc85b714aa08616eace94cbfd 100644 --- a/linphone/coreapi/lpconfig.c +++ b/linphone/coreapi/lpconfig.c @@ -97,6 +97,7 @@ struct _LpConfig{ char *filename; MSList *sections; int modified; + int readonly; }; LpItem * lp_item_new(const char *key, const char *value){ @@ -339,13 +340,15 @@ void lp_section_write(LpSection *sec, FILE *file){ int lp_config_sync(LpConfig *lpconfig){ FILE *file; if (lpconfig->filename==NULL) return -1; + if (lpconfig->readonly) return 0; #ifndef WIN32 /* don't create group/world-accessible files */ (void) umask(S_IRWXG | S_IRWXO); #endif file=fopen(lpconfig->filename,"w"); if (file==NULL){ - ms_warning("Could not write %s !",lpconfig->filename); + ms_warning("Could not write %s ! Maybe it is read-only. Configuration will not be saved.",lpconfig->filename); + lpconfig->readonly=1; return -1; } ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file); diff --git a/linphone/coreapi/misc.c b/linphone/coreapi/misc.c index 2add44d7bd4d9305d6c5f60a48655992f39984bc..59a64b89495362896da59dbc58397f37818f2324 100644 --- a/linphone/coreapi/misc.c +++ b/linphone/coreapi/misc.c @@ -27,6 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> +#include <strings.h> + #undef snprintf #include <ortp/stun.h> @@ -187,17 +189,31 @@ int payload_type_get_rate(PayloadType *pt){ return pt->clock_rate; } -static double get_audio_payload_bandwidth(const PayloadType *pt){ +/*this function makes a special case for speex/8000. +This codec is variable bitrate. The 8kbit/s mode is interesting when having a low upload bandwidth, but its quality +is not very good. We 'd better use its 15kbt/s mode when we have enough bandwidth*/ +static int get_codec_bitrate(LinphoneCore *lc, const PayloadType *pt){ + int upload_bw=linphone_core_get_upload_bandwidth(lc); + if (upload_bw>128 || (upload_bw>32 && !linphone_core_video_enabled(lc)) ) { + if (strcmp(pt->mime_type,"speex")==0 && pt->clock_rate==8000){ + ms_message("Let's use speex at 15kbit/s"); + return 15000; + } + } + return pt->normal_bitrate; +} + +static double get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt){ double npacket=50; double packet_size; int bitrate; - bitrate=pt->normal_bitrate; - packet_size=(double)(bitrate/(50*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; + bitrate=get_codec_bitrate(lc,pt); + packet_size= (((double)bitrate)/(50*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ; return packet_size*8.0*npacket; } void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt){ - lc->audio_bw=(int)(get_audio_payload_bandwidth(pt)/1000.0); + lc->audio_bw=(int)(get_audio_payload_bandwidth(lc,pt)/1000.0); /*update*/ linphone_core_set_download_bandwidth(lc,lc->net_conf.download_bw); linphone_core_set_upload_bandwidth(lc,lc->net_conf.upload_bw); @@ -209,8 +225,9 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){ for(elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; if (payload_type_enabled(pt)){ + int pt_bitrate=get_codec_bitrate(lc,pt); if (max==NULL) max=pt; - else if (max->normal_bitrate<pt->normal_bitrate){ + else if (max->normal_bitrate<pt_bitrate){ max=pt; } } @@ -241,7 +258,7 @@ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType switch (pt->type){ case PAYLOAD_AUDIO_CONTINUOUS: case PAYLOAD_AUDIO_PACKETIZED: - codec_band=get_audio_payload_bandwidth(pt); + codec_band=get_audio_payload_bandwidth(lc,pt); ret=bandwidth_is_greater(min_audio_bw*1000,codec_band); //ms_message("Payload %s: %g",pt->mime_type,codec_band); break; diff --git a/linphone/mediastreamer2/src/msspeex.c b/linphone/mediastreamer2/src/msspeex.c index 92d032a7f29895c0651269b84713be2dfa9ddf35..871db54096d5d1cb5c8a108af090b0705352abe2 100644 --- a/linphone/mediastreamer2/src/msspeex.c +++ b/linphone/mediastreamer2/src/msspeex.c @@ -113,18 +113,18 @@ static void enc_preprocess(MSFilter *f){ } if (s->rate==8000){ - //+------+---------------+-------------+ - //| mode | Speex quality | bit-rate | - //+------+---------------+-------------+ - //| 1 | 0 | 2.15 kbit/s | - //| 2 | 2 | 5.95 kbit/s | - //| 3 | 3 or 4 | 8.00 kbit/s | - //| 4 | 5 or 6 | 11.0 kbit/s | - //| 5 | 7 or 8 | 15.0 kbit/s | - //| 6 | 9 | 18.2 kbit/s | - //| 7 | 10 | 24.6 kbit/s | - //| 8 | 1 | 3.95 kbit/s | - //+------+---------------+-------------+ + //+------+---------------+-------------+ + //| mode | Speex quality | bit-rate | + //+------+---------------+-------------+ + //| 1 | 0 | 2.15 kbit/s | + //| 2 | 2 | 5.95 kbit/s | + //| 3 | 3 or 4 | 8.00 kbit/s | + //| 4 | 5 or 6 | 11.0 kbit/s | + //| 5 | 7 or 8 | 15.0 kbit/s | + //| 6 | 9 | 18.2 kbit/s | + //| 7 | 10 | 24.6 kbit/s | + //| 8 | 1 | 3.95 kbit/s | + //+------+---------------+-------------+ if (s->mode<=0 || s->mode>8) s->mode = 3; /* default mode */ @@ -152,22 +152,22 @@ static void enc_preprocess(MSFilter *f){ } } else if (s->rate==16000 || s->rate==32000){ - //+------+---------------+-------------------+------------------------+ - //| mode | Speex quality | wideband bit-rate | ultra wideband | - //| | | | bit-rate | - //+------+---------------+-------------------+------------------------+ - //| 0 | 0 | 3.95 kbit/s | 5.75 kbit/s | - //| 1 | 1 | 5.75 kbit/s | 7.55 kbit/s | - //| 2 | 2 | 7.75 kbit/s | 9.55 kbit/s | - //| 3 | 3 | 9.80 kbit/s | 11.6 kbit/s | - //| 4 | 4 | 12.8 kbit/s | 14.6 kbit/s | - //| 5 | 5 | 16.8 kbit/s | 18.6 kbit/s | - //| 6 | 6 | 20.6 kbit/s | 22.4 kbit/s | - //| 7 | 7 | 23.8 kbit/s | 25.6 kbit/s | - //| 8 | 8 | 27.8 kbit/s | 29.6 kbit/s | - //| 9 | 9 | 34.2 kbit/s | 36.0 kbit/s | - //| 10 | 10 | 42.2 kbit/s | 44.0 kbit/s | - //+------+---------------+-------------------+------------------------+ + //+------+---------------+-------------------+------------------------+ + //| mode | Speex quality | wideband bit-rate | ultra wideband | + //| | | | bit-rate | + //+------+---------------+-------------------+------------------------+ + //| 0 | 0 | 3.95 kbit/s | 5.75 kbit/s | + //| 1 | 1 | 5.75 kbit/s | 7.55 kbit/s | + //| 2 | 2 | 7.75 kbit/s | 9.55 kbit/s | + //| 3 | 3 | 9.80 kbit/s | 11.6 kbit/s | + //| 4 | 4 | 12.8 kbit/s | 14.6 kbit/s | + //| 5 | 5 | 16.8 kbit/s | 18.6 kbit/s | + //| 6 | 6 | 20.6 kbit/s | 22.4 kbit/s | + //| 7 | 7 | 23.8 kbit/s | 25.6 kbit/s | + //| 8 | 8 | 27.8 kbit/s | 29.6 kbit/s | + //| 9 | 9 | 34.2 kbit/s | 36.0 kbit/s | + //| 10 | 10 | 42.2 kbit/s | 44.0 kbit/s | + //+------+---------------+-------------------+------------------------+ int q=0; if (s->mode<0 || s->mode>10) s->mode = 8; /* default mode */ @@ -180,7 +180,8 @@ static void enc_preprocess(MSFilter *f){ if (s->maxbitrate>0){ /* convert from network bitrate to codec bitrate:*/ /* ((nbr/(50*8)) -20-12-8)*50*8*/ - int cbr=(int)( (((float)s->maxbitrate/(50.0*8))-20-12-8)*50*8); + int cbr=(int)( ((((float)s->maxbitrate)/(50.0*8))-20-12-8)*50*8); + ms_message("Setting maxbitrate=%i to speex encoder.",cbr); if (speex_encoder_ctl(s->state,SPEEX_SET_BITRATE,&cbr)!=0){ ms_error("Could not set maxbitrate %i to speex encoder.",s->bitrate); }