mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Merge branch 'master' of git.linphone.org:linphone-private
This commit is contained in:
commit
f47dff36b0
22 changed files with 637 additions and 160 deletions
|
|
@ -1,6 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([linphone],[3.3.99.9],[linphone-developers@nongnu.org])
|
||||
AC_INIT([linphone],[3.3.99.10],[linphone-developers@nongnu.org])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,10 @@ static LPC_COMMAND commands[] = {
|
|||
},
|
||||
{ "call", lpc_cmd_call, "Call a SIP uri or number",
|
||||
#ifdef VIDEO_ENABLED
|
||||
"'call <sip-url or number> [--audio-only]' \t: initiate a call to the specified destination.\n"
|
||||
"'call <sip-url or number> [options]' \t: initiate a call to the specified destination.\n"
|
||||
"Options can be:\n"
|
||||
"--audio-only : initiate the call without video.\n"
|
||||
"--early-media : sends audio and video stream immediately when remote proposes early media.\n"
|
||||
#else
|
||||
"'call <sip-url or number>' \t: initiate a call to the specified destination.\n"
|
||||
#endif
|
||||
|
|
@ -542,17 +545,22 @@ lpc_cmd_call(LinphoneCore *lc, char *args)
|
|||
{
|
||||
LinphoneCall *call;
|
||||
LinphoneCallParams *cp=linphone_core_create_default_call_parameters (lc);
|
||||
char *opt;
|
||||
char *opt1,*opt2;
|
||||
if ( linphone_core_in_call(lc) )
|
||||
{
|
||||
linphonec_out("Terminate or hold on the current call first.\n");
|
||||
return 1;
|
||||
}
|
||||
opt=strstr(args,"--audio-only");
|
||||
if (opt){
|
||||
opt[0]='\0';
|
||||
opt1=strstr(args,"--audio-only");
|
||||
opt2=strstr(args,"--early-media");
|
||||
if (opt1){
|
||||
opt1[0]='\0';
|
||||
linphone_call_params_enable_video (cp,FALSE);
|
||||
}
|
||||
if (opt2){
|
||||
opt2[0]='\0';
|
||||
linphone_call_params_enable_early_media_sending(cp,TRUE);
|
||||
}
|
||||
if ( NULL == (call=linphone_core_invite_with_params(lc, args,cp)) )
|
||||
{
|
||||
linphonec_out("Error from linphone_core_invite.\n");
|
||||
|
|
|
|||
|
|
@ -356,10 +356,28 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L
|
|||
break;
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphonec_call_identify(call);
|
||||
id=(long)linphone_call_get_user_pointer (call);
|
||||
from=linphone_call_get_remote_address_as_string(call);
|
||||
linphonec_out("Establishing call id to %s, assigned id %i\n", from,id);
|
||||
break;
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
linphonec_call_updated(call);
|
||||
break;
|
||||
case LinphoneCallOutgoingProgress:
|
||||
linphonec_out("Call %i to %s in progress.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallOutgoingRinging:
|
||||
linphonec_out("Call %i to %s ringing.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallConnected:
|
||||
linphonec_out("Call %i with %s connected.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
linphonec_out("Call %i with %s early media.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallError:
|
||||
linphonec_out("Call %i with %s error.\n", id, from);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,69 @@ 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 void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){
|
||||
static bool_t media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd){
|
||||
return !sal_media_description_equals(oldmd,newmd) || call->up_bw!=linphone_core_get_upload_bandwidth(call->core);
|
||||
}
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
|
||||
SalMediaDescription *oldmd=call->resultdesc;
|
||||
|
||||
if (lc->ringstream!=NULL){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
linphone_call_start_media_streams(call);
|
||||
if (new_md!=NULL){
|
||||
sal_media_description_ref(new_md);
|
||||
call->media_pending=FALSE;
|
||||
}else{
|
||||
call->media_pending=TRUE;
|
||||
}
|
||||
call->resultdesc=new_md;
|
||||
if (call->audiostream && call->audiostream->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){
|
||||
sal_media_description_unref(oldmd);
|
||||
if (call->all_muted){
|
||||
ms_message("Early media finished, unmuting inputs...");
|
||||
/*we were in early media, now we want to enable real media */
|
||||
linphone_call_enable_camera (call,linphone_call_camera_enabled (call));
|
||||
if (call->audiostream)
|
||||
linphone_core_mute_mic (lc, linphone_core_is_mic_muted(lc));
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream && call->camera_active)
|
||||
video_stream_change_camera(call->videostream,lc->video_conf.device );
|
||||
#endif
|
||||
}
|
||||
ms_message("No need to restart streams, SDP is unchanged.");
|
||||
return;
|
||||
}else{
|
||||
ms_message("Media descriptions are different, need to restart the streams.");
|
||||
}
|
||||
}
|
||||
linphone_call_stop_media_streams (call);
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
if (oldmd)
|
||||
sal_media_description_unref(oldmd);
|
||||
|
||||
if (new_md) {
|
||||
bool_t all_muted=FALSE;
|
||||
bool_t send_ringbacktone=FALSE;
|
||||
|
||||
if (call->audiostream==NULL){
|
||||
/*this happens after pausing the call locally. The streams is destroyed and then we wait the 200Ok to recreate it*/
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
|
||||
send_ringbacktone=TRUE;
|
||||
}
|
||||
if (call->state==LinphoneCallIncomingEarlyMedia ||
|
||||
(call->state==LinphoneCallOutgoingEarlyMedia && !call->params.real_early_media)){
|
||||
all_muted=TRUE;
|
||||
}
|
||||
linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){
|
||||
|
|
@ -55,7 +112,9 @@ static void call_received(SalOp *h){
|
|||
char *tmp;
|
||||
LinphoneAddress *from_parsed;
|
||||
LinphoneAddress *from_addr, *to_addr;
|
||||
const char * early_media=linphone_core_get_remote_ringback_tone (lc);
|
||||
SalMediaDescription *md;
|
||||
bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
|
||||
const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
|
||||
|
||||
/* first check if we can answer successfully to this invite */
|
||||
if (lc->presence_mode==LinphoneStatusBusy ||
|
||||
|
|
@ -93,16 +152,14 @@ static void call_received(SalOp *h){
|
|||
|
||||
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
|
||||
sal_call_set_local_media_description(h,call->localdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(h);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
if (call->resultdesc && sal_media_description_empty(call->resultdesc)){
|
||||
md=sal_call_get_final_media_description(h);
|
||||
|
||||
if (md && sal_media_description_empty(md)){
|
||||
sal_call_decline(h,SalReasonMedia,NULL);
|
||||
linphone_call_unref(call);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* the call is acceptable so we can now add it to our list */
|
||||
linphone_core_add_call(lc,call);
|
||||
|
||||
|
|
@ -124,7 +181,7 @@ static void call_received(SalOp *h){
|
|||
lc->ringstream=NULL;
|
||||
lc->dmfs_playing_start_time=0;
|
||||
}
|
||||
if(lc->ringstream==NULL){
|
||||
if(lc->ringstream==NULL && lc->sound_conf.local_ring){
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard;
|
||||
ms_message("Starting local ring...");
|
||||
lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,ringcard);
|
||||
|
|
@ -136,17 +193,18 @@ static void call_received(SalOp *h){
|
|||
}else{
|
||||
/*TODO : play a tone within the context of the current call */
|
||||
}
|
||||
sal_call_notify_ringing(h,early_media!=NULL);
|
||||
#if !(__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)
|
||||
linphone_call_init_media_streams(call);
|
||||
if (early_media!=NULL){
|
||||
linphone_call_start_early_media (call);
|
||||
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
|
||||
|
||||
sal_call_notify_ringing(h,propose_early_media || ringback_tone!=NULL);
|
||||
|
||||
if (propose_early_media || ringback_tone!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");
|
||||
linphone_core_update_streams(lc,call,md);
|
||||
}
|
||||
#endif
|
||||
ms_free(barmesg);
|
||||
ms_free(tmp);
|
||||
|
||||
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
|
||||
|
||||
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}
|
||||
|
|
@ -183,8 +241,6 @@ static void call_ringing(SalOp *h){
|
|||
ms_message("Early media already started.");
|
||||
return;
|
||||
}
|
||||
sal_media_description_ref(md);
|
||||
call->resultdesc=md;
|
||||
if (lc->vtable.show) lc->vtable.show(lc);
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Early media."));
|
||||
|
|
@ -194,8 +250,7 @@ static void call_ringing(SalOp *h){
|
|||
lc->ringstream=NULL;
|
||||
}
|
||||
ms_message("Doing early media...");
|
||||
linphone_call_start_media_streams(call);
|
||||
call->media_pending=TRUE;
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,33 +262,23 @@ static void call_ringing(SalOp *h){
|
|||
static void call_accepted(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
|
||||
SalMediaDescription *md;
|
||||
|
||||
if (call==NULL){
|
||||
ms_warning("No call to accept.");
|
||||
return ;
|
||||
}
|
||||
if ((call->audiostream!=NULL) && (call->audiostream->ticker!=NULL)){
|
||||
/*case where we accepted early media or already in call*/
|
||||
linphone_call_stop_media_streams(call);
|
||||
}
|
||||
if (call->audiostream==NULL){
|
||||
linphone_call_init_media_streams(call);
|
||||
}
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc){
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
call->media_pending=FALSE;
|
||||
}
|
||||
|
||||
md=sal_call_get_final_media_description(op);
|
||||
|
||||
if (call->state==LinphoneCallOutgoingProgress ||
|
||||
call->state==LinphoneCallOutgoingRinging ||
|
||||
call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
|
||||
}
|
||||
if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
|
||||
if (sal_media_description_has_dir(call->resultdesc,SalStreamSendOnly) ||
|
||||
sal_media_description_has_dir(call->resultdesc,SalStreamInactive)){
|
||||
if (md && !sal_media_description_empty(md)){
|
||||
if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
|
||||
sal_media_description_has_dir(md,SalStreamInactive)){
|
||||
if (lc->vtable.display_status){
|
||||
char *tmp=linphone_call_get_remote_address_as_string (call);
|
||||
char *msg=ms_strdup_printf(_("Call with %s is paused."),tmp);
|
||||
|
|
@ -242,7 +287,7 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(msg);
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
}else if (sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly)){
|
||||
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
|
||||
/*we are put on hold when the call is initially accepted */
|
||||
if (lc->vtable.display_status){
|
||||
char *tmp=linphone_call_get_remote_address_as_string (call);
|
||||
|
|
@ -256,9 +301,14 @@ static void call_accepted(SalOp *op){
|
|||
if (lc->vtable.display_status){
|
||||
lc->vtable.display_status(lc,_("Call answered - connected."));
|
||||
}
|
||||
if (call->state==LinphoneCallStreamsRunning){
|
||||
/*media was running before, the remote as acceted a call modification (that is
|
||||
a reinvite made by us. We must notify the application this reinvite was accepted*/
|
||||
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
linphone_connect_incoming (lc,call);
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
}else{
|
||||
/*send a bye*/
|
||||
ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
|
||||
|
|
@ -274,18 +324,14 @@ static void call_ack(SalOp *op){
|
|||
return ;
|
||||
}
|
||||
if (call->media_pending){
|
||||
if (call->audiostream->ticker!=NULL){
|
||||
/*case where we accepted early media */
|
||||
linphone_call_stop_media_streams(call);
|
||||
linphone_call_init_media_streams(call);
|
||||
}
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
|
||||
linphone_connect_incoming(lc,call);
|
||||
SalMediaDescription *md=sal_call_get_final_media_description(op);
|
||||
if (md && !sal_media_description_empty(md)){
|
||||
if (call->state==LinphoneCallStreamsRunning){
|
||||
/*media was running before, the remote as acceted a call modification (that is
|
||||
a reinvite made by us. We must notify the application this reinvite was accepted*/
|
||||
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}else{
|
||||
/*send a bye*/
|
||||
|
|
@ -293,7 +339,6 @@ static void call_ack(SalOp *op){
|
|||
linphone_core_abort_call(lc,call,"No codec intersection");
|
||||
return;
|
||||
}
|
||||
call->media_pending=FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,17 +347,14 @@ static void call_updating(SalOp *op){
|
|||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
LinphoneCallState prevstate=LinphoneCallIdle;
|
||||
SalMediaDescription *md;
|
||||
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
|
||||
if (call->resultdesc && !sal_media_description_empty(call->resultdesc))
|
||||
md=sal_call_get_final_media_description(op);
|
||||
|
||||
if (md && !sal_media_description_empty(md))
|
||||
{
|
||||
if ((call->state==LinphoneCallPausedByRemote || call->state==LinphoneCallPaused) &&
|
||||
sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && strcmp(call->resultdesc->addr,"0.0.0.0")!=0){
|
||||
sal_media_description_has_dir(md,SalStreamSendRecv) && strcmp(md->addr,"0.0.0.0")!=0){
|
||||
/*make sure we can be resumed */
|
||||
if (lc->current_call!=NULL && lc->current_call!=call){
|
||||
ms_warning("Attempt to be resumed but already in call with somebody else!");
|
||||
|
|
@ -325,9 +367,9 @@ static void call_updating(SalOp *op){
|
|||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
else if(call->state==LinphoneCallStreamsRunning &&
|
||||
( sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly)
|
||||
|| sal_media_description_has_dir(call->resultdesc,SalStreamInactive)
|
||||
|| strcmp(call->resultdesc->addr,"0.0.0.0")==0)){
|
||||
( sal_media_description_has_dir(md,SalStreamRecvOnly)
|
||||
|| sal_media_description_has_dir(md,SalStreamInactive)
|
||||
|| strcmp(md->addr,"0.0.0.0")==0)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
|
|
@ -340,9 +382,7 @@ static void call_updating(SalOp *op){
|
|||
}
|
||||
/*accept the modification (sends a 200Ok)*/
|
||||
sal_call_accept(op);
|
||||
linphone_call_stop_media_streams (call);
|
||||
linphone_call_init_media_streams (call);
|
||||
linphone_call_start_media_streams (call);
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
if (prevstate!=LinphoneCallIdle){
|
||||
linphone_call_set_state (call,prevstate,"Connected (streams running)");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,21 +40,25 @@ static MSWebCam *get_nowebcam_device(){
|
|||
#endif
|
||||
|
||||
|
||||
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, bool_t only_one_codec){
|
||||
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){
|
||||
MSList *l=NULL;
|
||||
const MSList *it;
|
||||
for(it=codecs;it!=NULL;it=it->next){
|
||||
PayloadType *pt=(PayloadType*)it->data;
|
||||
if ((pt->flags & PAYLOAD_TYPE_ENABLED) && linphone_core_check_payload_type_usability(lc,pt)){
|
||||
l=ms_list_append(l,payload_type_clone(pt));
|
||||
if (only_one_codec) break;
|
||||
if (pt->flags & PAYLOAD_TYPE_ENABLED){
|
||||
if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){
|
||||
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint.",pt->mime_type,pt->clock_rate);
|
||||
continue;
|
||||
}
|
||||
if (linphone_core_check_payload_type_usability(lc,pt)){
|
||||
l=ms_list_append(l,payload_type_clone(pt));
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc,
|
||||
LinphoneCall *call, bool_t with_video, bool_t only_one_codec){
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
const char *me=linphone_core_get_identity(lc);
|
||||
|
|
@ -72,7 +76,7 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc,
|
|||
md->streams[0].proto=SalProtoRtpAvp;
|
||||
md->streams[0].type=SalAudio;
|
||||
md->streams[0].ptime=lc->net_conf.down_ptime;
|
||||
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,only_one_codec);
|
||||
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw);
|
||||
pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
|
||||
l=ms_list_append(l,pt);
|
||||
md->streams[0].payloads=l;
|
||||
|
|
@ -80,12 +84,12 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc,
|
|||
if (lc->dw_audio_bw>0)
|
||||
md->streams[0].bandwidth=lc->dw_audio_bw;
|
||||
|
||||
if (with_video){
|
||||
if (call->params.has_video){
|
||||
md->nstreams++;
|
||||
md->streams[1].port=call->video_port;
|
||||
md->streams[1].proto=SalProtoRtpAvp;
|
||||
md->streams[1].type=SalVideo;
|
||||
l=make_codec_list(lc,lc->codecs_conf.video_codecs,only_one_codec);
|
||||
l=make_codec_list(lc,lc->codecs_conf.video_codecs,0);
|
||||
md->streams[1].payloads=l;
|
||||
if (lc->dw_video_bw)
|
||||
md->streams[1].bandwidth=lc->dw_video_bw;
|
||||
|
|
@ -156,7 +160,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
|
|||
linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
|
||||
linphone_call_init_common(call,from,to);
|
||||
call->params=*params;
|
||||
call->localdesc=create_local_media_description (lc,call,params->has_video,FALSE);
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=params->has_video;
|
||||
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
|
||||
linphone_core_run_stun_tests(call->core,call);
|
||||
|
|
@ -194,8 +198,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
|
||||
linphone_call_init_common(call, from, to);
|
||||
call->params.has_video=linphone_core_video_enabled(lc);
|
||||
call->localdesc=create_local_media_description (lc,call,
|
||||
call->params.has_video,lc->sip_conf.only_one_codec);
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=call->params.has_video;
|
||||
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
|
||||
linphone_core_run_stun_tests(call->core,call);
|
||||
|
|
@ -279,6 +282,10 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){
|
|||
return "LinphoneCallPausedByRemote";
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
return "LinphoneCallUpdatedByRemote";
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
return "LinphoneCallIncomingEarlyMedia";
|
||||
case LinphoneCallUpdated:
|
||||
return "LinphoneCallUpdated";
|
||||
}
|
||||
return "undefined state";
|
||||
}
|
||||
|
|
@ -521,6 +528,25 @@ bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
|
|||
return cp->has_video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable sending of real early media (during outgoing calls).
|
||||
**/
|
||||
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled){
|
||||
cp->real_early_media=enabled;
|
||||
}
|
||||
|
||||
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp){
|
||||
return cp->real_early_media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refine bandwidth settings for this call by setting a bandwidth limit for audio streams.
|
||||
* As a consequence, codecs whose bitrates are not compatible with this limit won't be used.
|
||||
**/
|
||||
void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bandwidth){
|
||||
cp->audio_bw=bandwidth;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
|
|
@ -638,9 +664,10 @@ static void post_configure_audio_streams(LinphoneCall*call){
|
|||
float ng_floorgain=lp_config_get_float(lc->config,"sound","ng_floorgain",0);
|
||||
int dc_removal=lp_config_get_int(lc->config,"sound","dc_removal",0);
|
||||
|
||||
if (mic_gain!=-1)
|
||||
if (!call->audio_muted)
|
||||
audio_stream_set_mic_gain(st,mic_gain);
|
||||
call->audio_muted=FALSE;
|
||||
else
|
||||
audio_stream_set_mic_gain(st,0);
|
||||
|
||||
recv_gain = lc->sound_conf.soft_play_lev;
|
||||
if (recv_gain != 0) {
|
||||
|
|
@ -738,18 +765,21 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md,
|
|||
return prof;
|
||||
}
|
||||
|
||||
|
||||
static void setup_ring_player(LinphoneCore *lc, LinphoneCall *call){
|
||||
int pause_time=3000;
|
||||
audio_stream_play(call->audiostream,lc->sound_conf.ringback_tone);
|
||||
ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
|
||||
}
|
||||
|
||||
static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_early_media){
|
||||
|
||||
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){
|
||||
LinphoneCore *lc=call->core;
|
||||
LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
|
||||
const char *tool="linphone-" LINPHONE_VERSION;
|
||||
char *cname;
|
||||
int used_pt=-1;
|
||||
|
||||
if(call->audiostream == NULL)
|
||||
{
|
||||
ms_fatal("start_media_stream() called without prior init !");
|
||||
|
|
@ -783,12 +813,15 @@ static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_e
|
|||
if (stream->port==0 || stream->dir==SalStreamRecvOnly){
|
||||
captcard=NULL;
|
||||
playfile=NULL;
|
||||
}else if (stream->dir==SalStreamSendOnly || send_early_media){
|
||||
}else if (stream->dir==SalStreamSendOnly){
|
||||
playcard=NULL;
|
||||
captcard=NULL;
|
||||
recfile=NULL;
|
||||
if (send_early_media)
|
||||
playfile=NULL;
|
||||
playfile=NULL;
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
captcard=NULL;
|
||||
playfile=NULL;/* it is setup later*/
|
||||
}
|
||||
/*if playfile are supplied don't use soundcards*/
|
||||
if (lc->use_files) {
|
||||
|
|
@ -809,13 +842,18 @@ static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_e
|
|||
captcard,
|
||||
captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc));
|
||||
post_configure_audio_streams(call);
|
||||
if (send_early_media) setup_ring_player(lc,call);
|
||||
if (all_inputs_muted && !send_ringbacktone){
|
||||
audio_stream_set_mic_gain(call->audiostream,0);
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
setup_ring_player(lc,call);
|
||||
}
|
||||
audio_stream_set_rtcp_information(call->audiostream, cname, tool);
|
||||
}else ms_warning("No audio stream accepted ?");
|
||||
}
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (!send_early_media){
|
||||
{
|
||||
const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
used_pt=-1;
|
||||
|
|
@ -859,7 +897,7 @@ static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_e
|
|||
/*either inactive or incompatible with local capabilities*/
|
||||
is_inactive=TRUE;
|
||||
}
|
||||
if (call->camera_active==FALSE){
|
||||
if (call->camera_active==FALSE || all_inputs_muted){
|
||||
cam=get_nowebcam_device();
|
||||
}
|
||||
if (!is_inactive){
|
||||
|
|
@ -876,21 +914,16 @@ static void _linphone_call_start_media_streams(LinphoneCall *call, bool_t send_e
|
|||
}
|
||||
}
|
||||
#endif
|
||||
call->all_muted=all_inputs_muted;
|
||||
call->playing_ringbacktone=send_ringbacktone;
|
||||
call->up_bw=linphone_core_get_upload_bandwidth(lc);
|
||||
|
||||
goto end;
|
||||
end:
|
||||
ms_free(cname);
|
||||
linphone_address_destroy(me);
|
||||
}
|
||||
|
||||
|
||||
void linphone_call_start_media_streams(LinphoneCall *call){
|
||||
_linphone_call_start_media_streams(call,FALSE);
|
||||
}
|
||||
|
||||
void linphone_call_start_early_media(LinphoneCall *call){
|
||||
_linphone_call_start_media_streams(call,TRUE);
|
||||
}
|
||||
|
||||
static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
|
||||
audio_stream_get_local_rtp_stats (st,&log->local_stats);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -486,7 +486,6 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
sal_use_session_timers(lc->sal,200);
|
||||
}
|
||||
|
||||
|
||||
tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
|
||||
linphone_core_set_use_rfc2833_for_dtmf(lc,tmp);
|
||||
|
||||
|
|
@ -562,21 +561,16 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
|
||||
|
||||
/*for tuning or test*/
|
||||
lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
|
||||
lc->sip_conf.only_one_codec=lp_config_get_int(lc->config,"sip","only_one_codec",0);
|
||||
lc->sip_conf.register_only_when_network_is_up=
|
||||
lp_config_get_int(lc->config,"sip","register_only_when_network_is_up",1);
|
||||
lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1);
|
||||
lc->sip_conf.auto_net_state_mon=lp_config_get_int(lc->config,"sip","auto_net_state_mon",1);
|
||||
lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
|
||||
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
|
||||
sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
|
||||
}
|
||||
|
||||
static void rtp_config_read(LinphoneCore *lc)
|
||||
|
|
@ -2193,8 +2187,9 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, LinphoneCall
|
|||
|
||||
if (call->localdesc)
|
||||
sal_media_description_unref(call->localdesc);
|
||||
call->localdesc=create_local_media_description (lc,call,
|
||||
params->has_video,FALSE);
|
||||
call->params=*params;
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=params->has_video;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Modifying call parameters..."));
|
||||
sal_call_set_local_media_description (call->op,call->localdesc);
|
||||
|
|
@ -2221,6 +2216,7 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
|
|||
LinphoneProxyConfig *cfg=NULL;
|
||||
const char *contact=NULL;
|
||||
SalOp *replaced;
|
||||
SalMediaDescription *new_md;
|
||||
|
||||
if (call==NULL){
|
||||
//if just one call is present answer the only one ...
|
||||
|
|
@ -2276,26 +2272,21 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
|
|||
contact=get_fixed_contact(lc,call,cfg);
|
||||
if (contact)
|
||||
sal_op_set_contact(call->op,contact);
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000
|
||||
linphone_call_init_media_streams(call);
|
||||
#else
|
||||
if (call->audiostream!=NULL && call->audiostream->ticker!=NULL){
|
||||
/*case where we sent early media*/
|
||||
linphone_call_stop_media_streams (call);
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (call->audiostream==NULL)
|
||||
linphone_call_init_media_streams(call);
|
||||
|
||||
sal_call_accept(call->op);
|
||||
if (lc->vtable.display_status!=NULL)
|
||||
lc->vtable.display_status(lc,_("Connected."));
|
||||
lc->current_call=call;
|
||||
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
|
||||
call->resultdesc=sal_call_get_final_media_description(call->op);
|
||||
if (call->resultdesc){
|
||||
linphone_call_start_media_streams(call);
|
||||
new_md=sal_call_get_final_media_description(call->op);
|
||||
linphone_core_update_streams(lc, call, new_md);
|
||||
if (new_md){
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
}else call->media_pending=TRUE;
|
||||
|
||||
ms_message("call answered.");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2830,7 +2821,7 @@ void linphone_core_set_sound_source(LinphoneCore *lc, char source)
|
|||
/**
|
||||
* Sets the path to a wav file used for ringing.
|
||||
*
|
||||
* The file must be a wav 16bit linear.
|
||||
* @param path The file must be a wav 16bit linear. Local ring is disabled if null
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
|
|
@ -2946,17 +2937,12 @@ void linphone_core_mute_mic(LinphoneCore *lc, bool_t val){
|
|||
}
|
||||
|
||||
bool_t linphone_core_is_mic_muted(LinphoneCore *lc) {
|
||||
float gain=1.0;
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call==NULL){
|
||||
ms_warning("linphone_core_is_mic_muted(): No current call !");
|
||||
return FALSE;
|
||||
}
|
||||
if (call->audiostream && call->audiostream->volsend){
|
||||
ms_filter_call_method(call->audiostream->volsend,MS_VOLUME_GET_GAIN,&gain);
|
||||
}else ms_warning("Could not get gain: gain control wasn't activated. ");
|
||||
|
||||
return gain==0 || call->audio_muted;
|
||||
return call->audio_muted;
|
||||
}
|
||||
|
||||
// returns rtp transmission status for an active stream
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ char * linphone_call_log_to_str(LinphoneCallLog *cl);
|
|||
|
||||
|
||||
/**
|
||||
* The LinphoneCallParams is an object contaning various call related parameters.
|
||||
* It can be used to retrieve parameters from a currently running call or modify the call's characterisitcs
|
||||
* The LinphoneCallParams is an object containing various call related parameters.
|
||||
* It can be used to retrieve parameters from a currently running call or modify the call's characteristics
|
||||
* dynamically.
|
||||
**/
|
||||
struct _LinphoneCallParams;
|
||||
|
|
@ -178,6 +178,9 @@ typedef struct _LinphoneCallParams LinphoneCallParams;
|
|||
LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled);
|
||||
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
|
||||
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
|
||||
void linphone_call_params_destroy(LinphoneCallParams *cp);
|
||||
|
||||
/**
|
||||
|
|
@ -216,7 +219,9 @@ typedef enum _LinphoneCallState{
|
|||
LinphoneCallError, /**<The call encountered an error*/
|
||||
LinphoneCallEnd, /**<The call ended normally*/
|
||||
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
|
||||
LinphoneCallUpdatedByRemote /**<The call's parameters are updated, used for example when video is asked by remote */
|
||||
LinphoneCallUpdatedByRemote, /**<The call's parameters are updated, used for example when video is asked by remote */
|
||||
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
|
||||
LinphoneCallUpdated /**<The remote accepted the call update initiated by us */
|
||||
} LinphoneCallState;
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs);
|
||||
|
|
@ -779,8 +784,10 @@ void linphone_core_set_ring(LinphoneCore *lc, const char *path);
|
|||
const char *linphone_core_get_ring(const LinphoneCore *lc);
|
||||
void linphone_core_set_ringback(LinphoneCore *lc, const char *path);
|
||||
const char * linphone_core_get_ringback(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_remote_ringback_tone(LinphoneCore *lc,const char *);
|
||||
const char *linphone_core_get_remote_ringback_tone(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata);
|
||||
void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_echo_cancellation_enabled(LinphoneCore *lc);
|
||||
|
|
|
|||
|
|
@ -580,6 +580,26 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isVideoEnabled(JNIEn
|
|||
,jlong lc) {
|
||||
return linphone_core_video_enabled((LinphoneCore*)lc);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setRing(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jstring jpath) {
|
||||
const char* path = jpath?env->GetStringUTFChars(jpath, NULL):NULL;
|
||||
linphone_core_set_ring((LinphoneCore*)lc,path);
|
||||
if (path) env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
) {
|
||||
const char* path = linphone_core_get_ring((LinphoneCore*)lc);
|
||||
if (path) {
|
||||
return env->NewStringUTF(path);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ProxyConfig
|
||||
|
||||
|
|
@ -973,5 +993,57 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getStunServer(JNIEnv
|
|||
return jvalue;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideo(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
|
||||
linphone_call_params_enable_video((LinphoneCallParams*)lcp, b);
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_getVideoEnabled(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return linphone_call_params_video_enabled((LinphoneCallParams*)lcp);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallParamsImpl_copy(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return (jlong) linphone_call_params_copy((LinphoneCallParams*)lcp);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createDefaultCallParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_core_create_default_call_parameters((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_call_get_current_params((LinphoneCall*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_inviteAddressWithParams(JNIEnv *env, jobject thiz, jlong lc, jlong addr, jlong params){
|
||||
return (jlong) linphone_core_invite_address_with_params((LinphoneCore *)lc, (const LinphoneAddress *)addr, (const LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateAddressWithParams(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateCall(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc, jint width, jint height){
|
||||
MSVideoSize vsize;
|
||||
vsize.width = (int)width;
|
||||
vsize.height = (int)height;
|
||||
linphone_core_set_preferred_video_size((LinphoneCore *)lc, vsize);
|
||||
}
|
||||
|
||||
extern "C" jintArray Java_org_linphone_core_LinphoneCoreImpl_getPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc){
|
||||
MSVideoSize vsize = linphone_core_get_preferred_video_size((LinphoneCore *)lc);
|
||||
jintArray arr = env->NewIntArray(2);
|
||||
int tVsize [2]= {vsize.width,vsize.height};
|
||||
env->SetIntArrayRegion(arr, 0, 2, tVsize);
|
||||
return arr;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
|
||||
linphone_core_set_download_bandwidth((LinphoneCore *)lc, (int) bw);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
|
||||
linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,39 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
|
||||
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit)
|
||||
{
|
||||
double codec_band;
|
||||
bool_t ret=FALSE;
|
||||
|
||||
switch (pt->type){
|
||||
case PAYLOAD_AUDIO_CONTINUOUS:
|
||||
case PAYLOAD_AUDIO_PACKETIZED:
|
||||
codec_band=get_audio_payload_bandwidth(lc,pt);
|
||||
ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band);
|
||||
/*hack to avoid using uwb codecs when having low bitrate and video*/
|
||||
if (bandwidth_is_greater(199,bandwidth_limit)){
|
||||
if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){
|
||||
ret=FALSE;
|
||||
}
|
||||
}
|
||||
//ms_message("Payload %s: %g",pt->mime_type,codec_band);
|
||||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (bandwidth_limit!=0) {/* infinite (-1) or strictly positive*/
|
||||
/*let the video use all the bandwidth minus the maximum bandwidth used by audio */
|
||||
if (bandwidth_limit>0)
|
||||
pt->normal_bitrate=bandwidth_limit*1000;
|
||||
else
|
||||
pt->normal_bitrate=1500000; /*around 1.5 Mbit/s*/
|
||||
ret=TRUE;
|
||||
}
|
||||
else ret=FALSE;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return TRUE if codec can be used with bandwidth, FALSE else*/
|
||||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "sal.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static bool_t only_telephone_event(const MSList *l){
|
||||
PayloadType *p=(PayloadType*)l->data;
|
||||
if (strcasecmp(p->mime_type,"telephone-event")!=0){
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
|
|
@ -53,10 +60,12 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
|
|||
return candidate;
|
||||
}
|
||||
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response){
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
|
||||
const MSList *e2;
|
||||
MSList *res=NULL;
|
||||
PayloadType *matched;
|
||||
bool_t found_codec=FALSE;
|
||||
|
||||
for(e2=remote;e2!=NULL;e2=e2->next){
|
||||
PayloadType *p2=(PayloadType*)e2->data;
|
||||
matched=find_payload_type_best_match(local,p2);
|
||||
|
|
@ -64,6 +73,14 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
PayloadType *newp;
|
||||
int local_number=payload_type_get_number(matched);
|
||||
int remote_number=payload_type_get_number(p2);
|
||||
|
||||
if (one_matching_codec){
|
||||
if (strcasecmp(matched->mime_type,"telephone-event")!=0){
|
||||
if (found_codec){/* we have found a real codec already*/
|
||||
continue; /*this codec won't be added*/
|
||||
}else found_codec=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
newp=payload_type_clone(matched);
|
||||
if (p2->send_fmtp)
|
||||
|
|
@ -90,13 +107,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
return res;
|
||||
}
|
||||
|
||||
static bool_t only_telephone_event(const MSList *l){
|
||||
PayloadType *p=(PayloadType*)l->data;
|
||||
if (strcasecmp(p->mime_type,"telephone-event")!=0){
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
||||
SalStreamDir res=local;
|
||||
|
|
@ -117,7 +128,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
const SalStreamDescription *remote_answer,
|
||||
SalStreamDescription *result){
|
||||
if (remote_answer->port!=0)
|
||||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE);
|
||||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
|
||||
result->proto=local_offer->proto;
|
||||
result->type=local_offer->type;
|
||||
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
|
||||
|
|
@ -135,8 +146,8 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
|
||||
static void initiate_incoming(const SalStreamDescription *local_cap,
|
||||
const SalStreamDescription *remote_offer,
|
||||
SalStreamDescription *result){
|
||||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE);
|
||||
SalStreamDescription *result, bool_t one_matching_codec){
|
||||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
|
||||
result->proto=local_cap->proto;
|
||||
result->type=local_cap->type;
|
||||
if (remote_offer->dir==SalStreamSendOnly)
|
||||
|
|
@ -187,7 +198,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
**/
|
||||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result){
|
||||
SalMediaDescription *result, bool_t one_matching_codec){
|
||||
int i,j;
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
|
|
@ -196,7 +207,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
ms_message("Processing for stream %i",i);
|
||||
ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
|
||||
if (ls){
|
||||
initiate_incoming(ls,rs,&result->streams[j]);
|
||||
initiate_incoming(ls,rs,&result->streams[j],one_matching_codec);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
**/
|
||||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result);
|
||||
SalMediaDescription *result, bool_t one_matching_codec);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,10 @@
|
|||
|
||||
struct _LinphoneCallParams{
|
||||
LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
|
||||
int audio_bw; /* bandwidth limit for audio stream */
|
||||
bool_t has_video;
|
||||
bool_t pad[3];
|
||||
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
|
||||
bool_t pad[2];
|
||||
};
|
||||
|
||||
struct _LinphoneCall
|
||||
|
|
@ -86,10 +88,13 @@ struct _LinphoneCall
|
|||
struct _VideoStream *videostream;
|
||||
char *refer_to;
|
||||
LinphoneCallParams params;
|
||||
int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
|
||||
bool_t refer_pending;
|
||||
bool_t media_pending;
|
||||
bool_t audio_muted;
|
||||
bool_t camera_active;
|
||||
bool_t all_muted; /*this flag is set during early medias*/
|
||||
bool_t playing_ringbacktone;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -187,8 +192,7 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char
|
|||
void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg);
|
||||
|
||||
void linphone_call_init_media_streams(LinphoneCall *call);
|
||||
void linphone_call_start_media_streams(LinphoneCall *call);
|
||||
void linphone_call_start_early_media(LinphoneCall *call);
|
||||
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
|
||||
void linphone_call_stop_media_streams(LinphoneCall *call);
|
||||
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
|
|
@ -278,7 +282,6 @@ typedef struct sip_config
|
|||
bool_t loopback_only;
|
||||
bool_t ipv6_enabled;
|
||||
bool_t sdp_200_ack;
|
||||
bool_t only_one_codec; /*in SDP answers*/
|
||||
bool_t register_only_when_network_is_up;
|
||||
bool_t ping_with_options;
|
||||
bool_t auto_net_state_mon;
|
||||
|
|
@ -436,8 +439,11 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc);
|
|||
|
||||
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc,
|
||||
LinphoneCall *call, bool_t with_video, bool_t only_one_codec);
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
|
||||
|
||||
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit);
|
||||
|
||||
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
|
||||
void _linphone_core_configure_resolver();
|
||||
|
|
|
|||
|
|
@ -94,6 +94,72 @@ bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir
|
|||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
static bool_t fmtp_equals(const char *p1, const char *p2){
|
||||
if (p1 && p2 && strcmp(p1,p2)==0) return TRUE;
|
||||
if (p1==NULL && p2==NULL) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
static bool_t payload_type_equals(const PayloadType *p1, const PayloadType *p2){
|
||||
if (p1->type!=p2->type) return FALSE;
|
||||
if (strcmp(p1->mime_type,p2->mime_type)!=0) return FALSE;
|
||||
if (p1->clock_rate!=p2->clock_rate) return FALSE;
|
||||
if (p1->channels!=p2->channels) return FALSE;
|
||||
/*
|
||||
Do not compare fmtp right now: they are modified internally when the call is started
|
||||
*/
|
||||
/*
|
||||
if (!fmtp_equals(p1->recv_fmtp,p2->recv_fmtp) ||
|
||||
!fmtp_equals(p1->send_fmtp,p2->send_fmtp))
|
||||
return FALSE;
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
|
||||
const MSList *e1,*e2;
|
||||
for(e1=l1,e2=l2;e1!=NULL && e2!=NULL; e1=e1->next,e2=e2->next){
|
||||
PayloadType *p1=(PayloadType*)e1->data;
|
||||
PayloadType *p2=(PayloadType*)e2->data;
|
||||
if (!payload_type_equals(p1,p2))
|
||||
return FALSE;
|
||||
}
|
||||
if (e1!=NULL || e2!=NULL){
|
||||
/*means one list is longer than the other*/
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
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->addr,sd2->addr)!=0) return FALSE;
|
||||
if (sd1->port!=sd2->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;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2){
|
||||
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;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void assign_string(char **str, const char *arg){
|
||||
if (*str){
|
||||
ms_free(*str);
|
||||
|
|
|
|||
|
|
@ -127,6 +127,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);
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
||||
SalMediaProto proto, SalStreamType type);
|
||||
|
|
@ -245,6 +246,7 @@ void sal_set_user_agent(Sal *ctx, const char *user_agent);
|
|||
/*keepalive period in ms*/
|
||||
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
|
||||
void sal_use_session_timers(Sal *ctx, int expires);
|
||||
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
|
||||
int sal_iterate(Sal *sal);
|
||||
MSList * sal_get_pending_auths(Sal *sal);
|
||||
|
||||
|
|
|
|||
|
|
@ -379,6 +379,10 @@ void sal_use_session_timers(Sal *ctx, int expires){
|
|||
ctx->session_expires=expires;
|
||||
}
|
||||
|
||||
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
|
||||
ctx->one_matching_codec=one_matching_codec;
|
||||
}
|
||||
|
||||
MSList *sal_get_pending_auths(Sal *sal){
|
||||
return ms_list_copy(sal->pending_auths);
|
||||
}
|
||||
|
|
@ -449,7 +453,7 @@ static void sdp_process(SalOp *h){
|
|||
offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
|
||||
}else{
|
||||
int i;
|
||||
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
|
||||
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
|
||||
h->sdp_answer=media_description_to_sdp(h->result);
|
||||
strcpy(h->result->addr,h->base.remote_media->addr);
|
||||
h->result->bandwidth=h->base.remote_media->bandwidth;
|
||||
|
|
@ -1955,7 +1959,7 @@ int sal_call_hold(SalOp *h, bool_t holdon)
|
|||
osip_message_t *reinvite=NULL;
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
|
||||
return -1;
|
||||
osip_message_set_subject(reinvite,osip_strdup("Phone Call Hold"));
|
||||
osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct Sal{
|
|||
int session_expires;
|
||||
int keepalive_period;
|
||||
void *up;
|
||||
bool_t one_matching_codec;
|
||||
};
|
||||
|
||||
struct SalOp{
|
||||
|
|
|
|||
20
gtk/main.c
20
gtk/main.c
|
|
@ -512,6 +512,7 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
|
|||
static gboolean first_time=TRUE;
|
||||
unsigned long id;
|
||||
static unsigned long previd=0;
|
||||
static unsigned long preview_previd=0;
|
||||
static gboolean in_iterate=FALSE;
|
||||
|
||||
/*avoid reentrancy*/
|
||||
|
|
@ -534,6 +535,25 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
|
|||
w=gdk_window_foreign_new(id);
|
||||
#else
|
||||
w=gdk_window_foreign_new((HANDLE)id);
|
||||
#endif
|
||||
if (w) {
|
||||
set_video_window_decorations(w);
|
||||
g_object_unref(G_OBJECT(w));
|
||||
}
|
||||
else ms_error("gdk_window_foreign_new() failed");
|
||||
if (video_needs_update) video_needs_update=FALSE;
|
||||
}
|
||||
}
|
||||
id=linphone_core_get_native_preview_window_id (lc);
|
||||
if (id!=preview_previd ){
|
||||
GdkWindow *w;
|
||||
preview_previd=id;
|
||||
if (id!=0){
|
||||
ms_message("Updating window decorations for preview");
|
||||
#ifndef WIN32
|
||||
w=gdk_window_foreign_new(id);
|
||||
#else
|
||||
w=gdk_window_foreign_new((HANDLE)id);
|
||||
#endif
|
||||
if (w) {
|
||||
set_video_window_decorations(w);
|
||||
|
|
|
|||
|
|
@ -89,10 +89,28 @@ public interface LinphoneCall {
|
|||
* Call end
|
||||
*/
|
||||
public final static State CallEnd = new State(13,"CallEnd");
|
||||
|
||||
/**
|
||||
* Paused by remote
|
||||
*/
|
||||
public final static State PausedByRemote = new State(14,"PausedByRemote");
|
||||
|
||||
/**
|
||||
* The call's parameters are updated, used for example when video is asked by remote
|
||||
*/
|
||||
public static final State CallUpdatedByRemote = new State(15, "CallUpdatedByRemote");
|
||||
|
||||
/**
|
||||
* We are proposing early media to an incoming call
|
||||
*/
|
||||
public static final State CallIncomingEarlyMedia = new State(16,"CallIncomingEarlyMedia");
|
||||
|
||||
/**
|
||||
* The remote accepted the call update initiated by us
|
||||
*/
|
||||
public static final State CallUpdated = new State(17, "CallUpdated");
|
||||
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
|
|
@ -132,4 +150,9 @@ public interface LinphoneCall {
|
|||
**/
|
||||
public LinphoneCallLog getCallLog();
|
||||
|
||||
/**
|
||||
* @return parameters for this call; read only, call copy() to get a read/write version.
|
||||
*/
|
||||
public LinphoneCallParams getCurrentParamsReadOnly();
|
||||
|
||||
}
|
||||
|
|
|
|||
32
java/common/org/linphone/core/LinphoneCallParams.java
Normal file
32
java/common/org/linphone/core/LinphoneCallParams.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
LinphoneCallParameters.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
/**
|
||||
* The LinphoneCallParams is an object containing various call related parameters.
|
||||
* It can be used to retrieve parameters from a currently running call or modify the call's characteristics
|
||||
* dynamically.
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public interface LinphoneCallParams {
|
||||
void setVideoEnabled(boolean b);
|
||||
boolean getVideoEnabled();
|
||||
LinphoneCallParams copy();
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ public interface LinphoneCore {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* Describes proxy registration states.
|
||||
* Describes firewall policy.
|
||||
*
|
||||
*/
|
||||
static public class FirewallPolicy {
|
||||
|
|
@ -298,7 +298,12 @@ public interface LinphoneCore {
|
|||
* @param network state
|
||||
*
|
||||
*/
|
||||
public void setNetworkStateReachable(boolean isReachable);
|
||||
public void setNetworkReachable(boolean isReachable);
|
||||
/**
|
||||
*
|
||||
* @return if false, there is no network connection.
|
||||
*/
|
||||
public boolean isNetworkReachable();
|
||||
/**
|
||||
* destroy linphone core and free all underlying resources
|
||||
*/
|
||||
|
|
@ -454,4 +459,30 @@ public interface LinphoneCore {
|
|||
* @return previously set firewall policy.
|
||||
*/
|
||||
public FirewallPolicy getFirewallPolicy();
|
||||
|
||||
public LinphoneCall inviteAddressWithParams(LinphoneAddress destination, LinphoneCallParams params) throws LinphoneCoreException ;
|
||||
|
||||
public int updateCall(LinphoneCall call, LinphoneCallParams params);
|
||||
|
||||
public LinphoneCallParams createDefaultCallParameters();
|
||||
|
||||
/**
|
||||
* Sets the path to a wav file used for ringing.
|
||||
*
|
||||
* @param path The file must be a wav 16bit linear. Local ring is disabled if null
|
||||
*/
|
||||
public void setRing(String path);
|
||||
/**
|
||||
* gets the path to a wav file used for ringing.
|
||||
*
|
||||
* @param null if not set
|
||||
*/
|
||||
public String getRing();
|
||||
public void setUploadBandwidth(int bw);
|
||||
|
||||
public void setDownloadBandwidth(int bw);
|
||||
|
||||
public void setPreferredVideoSize(VideoSize vSize);
|
||||
|
||||
public VideoSize getPreferredVideoSize();
|
||||
}
|
||||
|
|
|
|||
84
java/common/org/linphone/core/VideoSize.java
Normal file
84
java/common/org/linphone/core/VideoSize.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
VideoSize.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
/**
|
||||
* @author Guillaume Beraudo
|
||||
*/
|
||||
public final class VideoSize {
|
||||
public static final int QCIF = 0;
|
||||
public static final int CIF = 1;
|
||||
public static final int HVGA = 2;
|
||||
|
||||
private int width;
|
||||
public int getWidth() {return width;}
|
||||
public void setWidth(int width) {this.width = width;}
|
||||
|
||||
private int height;
|
||||
public int getHeight() {return height;}
|
||||
public void setHeight(int height) {this.height = height;}
|
||||
|
||||
public VideoSize() {}
|
||||
private VideoSize(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public static final VideoSize createStandard(int code) {
|
||||
switch (code) {
|
||||
case QCIF:
|
||||
return new VideoSize(176, 144);
|
||||
case CIF:
|
||||
return new VideoSize(352, 288);
|
||||
case HVGA:
|
||||
return new VideoSize(320, 480);
|
||||
default:
|
||||
return new VideoSize(); // Invalid one
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
// Generated
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + height;
|
||||
result = prime * result + width;
|
||||
return result;
|
||||
}
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
VideoSize other = (VideoSize) obj;
|
||||
if (height != other.height)
|
||||
return false;
|
||||
if (width != other.width)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit c4d5e14dca123596d1effb68bd7310124bfa1b11
|
||||
Subproject commit 28a6e7f22fbdd93a01676fc9cc47a2605c846d75
|
||||
Loading…
Add table
Reference in a new issue