static void enc_preprocess(MSFilter *f){ EncData *d=(EncData*)f->data; x264_param_t *params=&d->params; d->packer=rfc3984_new(); rfc3984_set_mode(d->packer,d->mode); rfc3984_enable_stap_a(d->packer,FALSE); #if defined(__arm__) || defined(ANDROID) if (x264_param_default_preset(params,"superfast"/*"ultrafast"*/,"zerolatency")) { #else x264_param_default(params); { #endif ms_error("Cannot apply default x264 configuration"); }; params->i_threads=ms_get_cpu_count(); params->i_sync_lookahead=0; params->i_width=d->vconf.vsize.width; params->i_height=d->vconf.vsize.height; params->i_fps_num=(int)d->vconf.fps; params->i_fps_den=1; params->i_slice_max_size=ms_get_payload_max_size()-100; /*-100 security margin*/ params->i_level_idc=13; apply_bitrate(f); params->rc.i_lookahead=0; /*enable this by config ?*/ /* params.i_keyint_max = (int)d->fps*d->keyframe_int; params.i_keyint_min = (int)d->fps; */ params->b_repeat_headers=1; params->b_annexb=0; //these parameters must be set so that our stream is baseline params->analyse.b_transform_8x8 = 0; params->b_cabac = 0; params->i_cqm_preset = X264_CQM_FLAT; params->i_bframe = 0; params->analyse.i_weighted_pred = X264_WEIGHTP_NONE; d->enc=x264_encoder_open(params); if (d->enc==NULL) ms_error("Fail to create x264 encoder."); d->framenum=0; video_starter_init(&d->starter); } static void x264_nals_to_msgb(x264_nal_t *xnals, int num_nals, MSQueue * nalus){ int i; mblk_t *m; /*int bytes;*/ for (i=0;i<num_nals;++i){ m=allocb(xnals[i].i_payload+10,0); memcpy(m->b_wptr,xnals[i].p_payload+4,xnals[i].i_payload-4); m->b_wptr+=xnals[i].i_payload-4; if (xnals[i].i_type==7) { ms_message("A SPS is being sent."); }else if (xnals[i].i_type==8) { ms_message("A PPS is being sent."); } ms_queue_put(nalus,m); } }
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt){ call->audio_bw=(int)(get_audio_payload_bandwidth(call->core,pt)/1000.0); ms_message("Audio bandwidth for this call is %i",call->audio_bw); }
void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) { if (handling != SalOpSDPNormal) ms_message("Enabling special SDP handling for SalOp[%p]!", h); h->sdp_handling = handling; }
void ms_factory_init(MSFactory *obj){ int i; long num_cpu=1; char *debug_log_enabled = NULL; char *tags; #ifdef _WIN32 SYSTEM_INFO sysinfo; #endif #if defined(ENABLE_NLS) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); #endif #ifndef MS2_WINDOWS_UNIVERSAL debug_log_enabled=getenv("MEDIASTREAMER_DEBUG"); #endif if (debug_log_enabled!=NULL && (strcmp("1",debug_log_enabled)==0) ){ ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); } ms_message("Mediastreamer2 factory " MEDIASTREAMER_VERSION " (git: " GIT_VERSION ") initialized."); /* register builtin MSFilter's */ for (i=0;ms_base_filter_descs[i]!=NULL;i++){ ms_factory_register_filter(obj,ms_base_filter_descs[i]); } #ifdef _WIN32 /*fixme to be tested*/ GetNativeSystemInfo( &sysinfo ); num_cpu = sysinfo.dwNumberOfProcessors; #elif __APPLE__ || __linux num_cpu = sysconf( _SC_NPROCESSORS_CONF); /*check the number of processors configured, not just the one that are currently active.*/ #elif __QNX__ num_cpu = _syspage_ptr->num_cpu; #else #warning "There is no code that detects the number of CPU for this platform." #endif ms_factory_set_cpu_count(obj,num_cpu); ms_factory_set_mtu(obj,MS_MTU_DEFAULT); #ifdef _WIN32 ms_factory_add_platform_tag(obj, "win32"); #ifdef MS2_WINDOWS_PHONE ms_factory_add_platform_tag(obj, "windowsphone"); #endif #ifdef MS2_WINDOWS_UNIVERSAL ms_factory_add_platform_tag(obj, "windowsuniversal"); #endif #endif #ifdef __APPLE__ ms_factory_add_platform_tag(obj, "apple"); #endif #ifdef __linux ms_factory_add_platform_tag(obj, "linux"); #endif #ifdef __QNX__ ms_factory_add_platform_tag(obj, "qnx"); #endif #ifdef ANDROID ms_factory_add_platform_tag(obj, "android"); #endif #ifdef TARGET_OS_IPHONE ms_factory_add_platform_tag(obj, "ios"); #endif #if defined(__arm__) || defined(_M_ARM) ms_factory_add_platform_tag(obj, "arm"); #else ms_factory_add_platform_tag(obj, "x86"); #endif #if defined(ANDROID) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM) ms_factory_add_platform_tag(obj, "embedded"); #else ms_factory_add_platform_tag(obj, "desktop"); #endif tags = ms_factory_get_platform_tags_as_string(obj); ms_message("ms_factory_init() done: platform_tags=%s", tags); ms_free(tags); }
/* inputs[0]= reference signal from far end (sent to soundcard) * inputs[1]= near speech & echo signal (read from soundcard) * outputs[0]= is a copy of inputs[0] to be sent to soundcard * outputs[1]= near end speech, echo removed - towards far end */ static void speex_ec_process(MSFilter *f){ SpeexECState *s=(SpeexECState*)f->data; int nbytes=s->framesize*2; mblk_t *refm; uint8_t *ref,*echo; if (s->bypass_mode) { while((refm=ms_queue_get(f->inputs[0]))!=NULL){ ms_queue_put(f->outputs[0],refm); } while((refm=ms_queue_get(f->inputs[1]))!=NULL){ ms_queue_put(f->outputs[1],refm); } return; } if (f->inputs[0]!=NULL){ if (s->echostarted){ while((refm=ms_queue_get(f->inputs[0]))!=NULL){ refm=audio_flow_controller_process(&s->afc,refm); if (refm){ mblk_t *cp=dupmsg(refm); ms_bufferizer_put(&s->delayed_ref,cp); ms_bufferizer_put(&s->ref,refm); } } }else{ ms_warning("Getting reference signal but no echo to synchronize on."); ms_queue_flush(f->inputs[0]); } } ms_bufferizer_put_from_queue(&s->echo,f->inputs[1]); ref=(uint8_t*)alloca(nbytes); echo=(uint8_t*)alloca(nbytes); while (ms_bufferizer_read(&s->echo,echo,nbytes)==nbytes){ mblk_t *oecho=allocb(nbytes,0); int avail; int avail_samples; if (!s->echostarted) s->echostarted=TRUE; if ((avail=ms_bufferizer_get_avail(&s->delayed_ref))<((s->nominal_ref_samples*2)+nbytes)){ /*we don't have enough to read in a reference signal buffer, inject silence instead*/ avail=nbytes; refm=allocb(nbytes,0); memset(refm->b_wptr,0,nbytes); refm->b_wptr+=nbytes; ms_bufferizer_put(&s->delayed_ref,refm); ms_queue_put(f->outputs[0],dupmsg(refm)); if (!s->using_zeroes){ ms_warning("Not enough ref samples, using zeroes"); s->using_zeroes=TRUE; } }else{ if (s->using_zeroes){ ms_message("Samples are back."); s->using_zeroes=FALSE; } /* read from our no-delay buffer and output */ refm=allocb(nbytes,0); if (ms_bufferizer_read(&s->ref,refm->b_wptr,nbytes)==0){ ms_fatal("Should never happen"); } refm->b_wptr+=nbytes; ms_queue_put(f->outputs[0],refm); } /*now read a valid buffer of delayed ref samples*/ if (ms_bufferizer_read(&s->delayed_ref,ref,nbytes)==0){ ms_fatal("Should never happen"); } avail-=nbytes; avail_samples=avail/2; /*ms_message("avail=%i",avail_samples);*/ if (avail_samples<s->min_ref_samples || s->min_ref_samples==-1){ s->min_ref_samples=avail_samples; } #ifdef EC_DUMP if (s->reffile) fwrite(ref,nbytes,1,s->reffile); if (s->echofile) fwrite(echo,nbytes,1,s->echofile); #endif speex_echo_cancellation(s->ecstate,(short*)echo,(short*)ref,(short*)oecho->b_wptr); speex_preprocess_run(s->den, (short*)oecho->b_wptr); #ifdef EC_DUMP if (s->cleanfile) fwrite(oecho->b_wptr,nbytes,1,s->cleanfile); #endif oecho->b_wptr+=nbytes; ms_queue_put(f->outputs[1],oecho); } /*verify our ref buffer does not become too big, meaning that we are receiving more samples than we are sending*/ if ((((uint32_t)(f->ticker->time - s->flow_control_time)) >= flow_control_interval_ms) && (s->min_ref_samples != -1)) { int diff=s->min_ref_samples-s->nominal_ref_samples; if (diff>(nbytes/2)){ int purge=diff-(nbytes/2); ms_warning("echo canceller: we are accumulating too much reference signal, need to throw out %i samples",purge); audio_flow_controller_set_target(&s->afc,purge,(flow_control_interval_ms*s->samplerate)/1000); } s->min_ref_samples=-1; s->flow_control_time = f->ticker->time; } }
MSZrtpContext* ms_zrtp_multistream_new(MSMediaStreamSessions *sessions, MSZrtpContext* activeContext, MSZrtpParams *params) { ms_message("ZRTP is disabled - not adding stream"); return NULL; }
static int set_high_prio(MSTicker *obj){ int precision=2; int prio=obj->prio; if (prio>MS_TICKER_PRIO_NORMAL){ #ifdef WIN32 MMRESULT mm; TIMECAPS ptc; mm=timeGetDevCaps(&ptc,sizeof(ptc)); if (mm==0){ if (ptc.wPeriodMin<(UINT)precision) ptc.wPeriodMin=precision; else precision = ptc.wPeriodMin; mm=timeBeginPeriod(ptc.wPeriodMin); if (mm!=TIMERR_NOERROR){ ms_warning("timeBeginPeriod failed."); } ms_message("win32 timer resolution set to %i ms",ptc.wPeriodMin); }else{ ms_warning("timeGetDevCaps failed."); } if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)){ ms_warning("SetThreadPriority() failed (%d)\n", (int)GetLastError()); } #else struct sched_param param; int policy=SCHED_RR; memset(¶m,0,sizeof(param)); int result=0; char* env_prio_c=NULL; int min_prio, max_prio, env_prio; if (prio==MS_TICKER_PRIO_REALTIME) policy=SCHED_FIFO; min_prio = sched_get_priority_min(policy); max_prio = sched_get_priority_max(policy); env_prio_c = getenv("MS_TICKER_SCHEDPRIO"); env_prio = (env_prio_c == NULL)?max_prio:atoi(env_prio_c); env_prio = MAX(MIN(env_prio, max_prio), min_prio); ms_message("Priority used: %d", env_prio); param.sched_priority=env_prio; if((result=pthread_setschedparam(pthread_self(),policy, ¶m))) { if (result==EPERM){ /* The linux kernel has sched_get_priority_max(SCHED_OTHER)=sched_get_priority_max(SCHED_OTHER)=0. As long as we can't use SCHED_RR or SCHED_FIFO, the only way to increase priority of a calling thread is to use setpriority(). */ if (setpriority(PRIO_PROCESS,0,-20)==-1){ ms_message("%s setpriority() failed: %s, nevermind.",obj->name,strerror(errno)); }else{ ms_message("%s priority increased to maximum.",obj->name); } }else ms_warning("%s: Set pthread_setschedparam failed: %s",obj->name,strerror(result)); } else { ms_message("%s priority set to %s and value (%i)",obj->name, policy==SCHED_FIFO ? "SCHED_FIFO" : "SCHED_RR", param.sched_priority); } #endif }else ms_message("%s priority left to normal.",obj->name); return precision; }
static int ice_process_stun_message(RtpSession *session, struct IceCheckList *checklist, OrtpEvent *evt) { struct CandidatePair *remote_candidates = NULL; StunMessage msg; bool_t res; int highest_priority_success=-1; OrtpEventData *evt_data = ortp_event_get_data(evt); mblk_t *mp = evt_data->packet; struct sockaddr_in *udp_remote; char src6host[NI_MAXHOST]; int recvport = 0; int i; udp_remote = (struct sockaddr_in*)&evt_data->ep->addr; memset( &msg, 0 , sizeof(msg) ); res = stunParseMessage((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr, &msg); if (!res) { ms_error("ice.c: Malformed STUN packet."); return -1; } if (checklist==NULL) { ms_error("ice.c: dropping STUN packet: ice is not configured"); return -1; } remote_candidates = checklist->cand_pairs; if (remote_candidates==NULL) { ms_error("ice.c: dropping STUN packet: ice is not configured"); return -1; } /* prepare ONCE tie-break value */ if (checklist->tiebreak_value==0) { checklist->tiebreak_value = random() * (0x7fffffffffffffffLL/0x7fff); } memset (src6host, 0, sizeof (src6host)); { struct sockaddr_storage *aaddr = (struct sockaddr_storage *)&evt_data->ep->addr; if (aaddr->ss_family==AF_INET) recvport = ntohs (((struct sockaddr_in *) udp_remote)->sin_port); else recvport = ntohs (((struct sockaddr_in6 *) &evt_data->ep->addr)->sin6_port); } i = getnameinfo ((struct sockaddr*)&evt_data->ep->addr, evt_data->ep->addrlen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (i != 0) { ms_error("ice.c: Error with getnameinfo"); return -1; } if (STUN_IS_REQUEST(msg.msgHdr.msgType)) ms_message("ice.c: STUN_CONNECTIVITYCHECK: Request received from: %s:%i", src6host, recvport); else if (STUN_IS_INDICATION(msg.msgHdr.msgType)) ms_message("ice.c: SUN_INDICATION: Request Indication received from: %s:%i", src6host, recvport); else ms_message("ice.c: STUN_ANSWER: Answer received from: %s:%i", src6host, recvport); { int pos; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { struct CandidatePair *cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_SUCCEEDED) { highest_priority_success=pos; break; } } } if (STUN_IS_INDICATION(msg.msgHdr.msgType)) { ms_message("ice.c: STUN INDICATION <- (?:?:? <- %s:%i:?)", src6host, recvport); return 0; } else if (STUN_IS_REQUEST(msg.msgHdr.msgType)) { StunMessage resp; StunAtrString hmacPassword; StunAddress4 remote_addr; int rtp_socket; memset( &resp, 0 , sizeof(resp)); remote_addr.addr = ntohl(udp_remote->sin_addr.s_addr); remote_addr.port = ntohs(udp_remote->sin_port); rtp_socket = rtp_session_get_rtp_socket(session); resp.msgHdr.magic_cookie = ntohl(msg.msgHdr.magic_cookie); for (i=0; i<12; i++ ) { resp.msgHdr.tr_id.octet[i] = msg.msgHdr.tr_id.octet[i]; } /* check mandatory params */ if (!msg.hasUsername) { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- Missing USERNAME attribute in connectivity check"); _ice_createErrorResponse(&resp, 4, 32, "Missing USERNAME attribute"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } if (!msg.hasMessageIntegrity) { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- Missing MESSAGEINTEGRITY attribute in connectivity check"); _ice_createErrorResponse(&resp, 4, 1, "Missing MESSAGEINTEGRITY attribute"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } /* The password associated with that transport address ID is used to verify the MESSAGE-INTEGRITY attribute, if one was present in the request. */ { char hmac[20]; /* remove length of fingerprint if present */ if (msg.hasFingerprint==TRUE) { char *lenpos = (char *)mp->b_rptr + sizeof(UInt16); UInt16 newlen = htons(msg.msgHdr.msgLength-8); /* remove fingerprint size */ memcpy(lenpos, &newlen, sizeof(UInt16)); stunCalculateIntegrity_shortterm(hmac, (char*)mp->b_rptr, mp->b_wptr-mp->b_rptr-24-8, checklist->loc_ice_pwd); } else stunCalculateIntegrity_shortterm(hmac, (char*)mp->b_rptr, mp->b_wptr-mp->b_rptr-24, checklist->loc_ice_pwd); if (memcmp(msg.messageIntegrity.hash, hmac, 20)!=0) { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- Wrong MESSAGEINTEGRITY attribute in connectivity check"); _ice_createErrorResponse(&resp, 4, 1, "Wrong MESSAGEINTEGRITY attribute"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } if (msg.hasFingerprint==TRUE) { char *lenpos = (char *)mp->b_rptr + sizeof(UInt16); UInt16 newlen = htons(msg.msgHdr.msgLength); /* add back fingerprint size */ memcpy(lenpos, &newlen, sizeof(UInt16)); } } /* 7.2.1.1. Detecting and Repairing Role Conflicts */ /* TODO */ if (!msg.hasIceControlling && !msg.hasIceControlled) { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- Missing either ICE-CONTROLLING or ICE-CONTROLLED attribute"); _ice_createErrorResponse(&resp, 4, 87, "Missing either ICE-CONTROLLING or ICE-CONTROLLED attribute"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } if (checklist->rem_controlling==0 && msg.hasIceControlling) { /* If the agent's tie-breaker is larger than or equal to the contents of the ICE-CONTROLLING attribute -> send 487, and do not change ROLE */ if (checklist->tiebreak_value >= msg.iceControlling.value) { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- 487 Role Conflict"); _ice_createErrorResponse(&resp, 4, 87, "Role Conflict"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } else { int pos; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { /* controller agent */ uint64_t G = remote_candidates[pos].remote_candidate.priority; /* controlled agent */ uint64_t D = remote_candidates[pos].local_candidate.priority; remote_candidates[pos].pair_priority = (MIN(G, D))<<32 | (MAX(G, D))<<1 | (G>D?1:0); } checklist->rem_controlling = 1; /* reset all to initial WAITING state? */ ms_message("ice.c: STUN REQ <- tiebreaker -> reset all to ICE_WAITING state"); for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (remote_candidates[pos].connectivity_check == ICE_PRUNED) continue; remote_candidates[pos].connectivity_check = ICE_WAITING; memset(&remote_candidates[pos].tid , 0, sizeof(remote_candidates[pos].tid)); remote_candidates[pos].retransmission_time = 0; remote_candidates[pos].retransmission_number = 0; } } } if (checklist->rem_controlling==1 && msg.hasIceControlled) { /* If the agent's tie-breaker is larger than or equal to the contents of the ICE-CONTROLLED attribute -> change ROLE */ if (checklist->tiebreak_value >= msg.iceControlled.value) { int pos; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { /* controller agent */ uint64_t G = remote_candidates[pos].local_candidate.priority; /* controlled agent */ uint64_t D = remote_candidates[pos].remote_candidate.priority; remote_candidates[pos].pair_priority = (MIN(G, D))<<32 | (MAX(G, D))<<1 | (G>D?1:0); } checklist->rem_controlling = 0; /* reset all to initial WAITING state? */ ms_message("ice.c: STUN REQ <- tiebreaker -> reset all to ICE_WAITING state"); for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (remote_candidates[pos].connectivity_check == ICE_PRUNED) continue; remote_candidates[pos].connectivity_check = ICE_WAITING; memset(&remote_candidates[pos].tid , 0, sizeof(remote_candidates[pos].tid)); remote_candidates[pos].retransmission_time = 0; remote_candidates[pos].retransmission_number = 0; } } else { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); ms_error("ice.c: STUN REQ <- 487 Role Conflict"); _ice_createErrorResponse(&resp, 4, 87, "Role Conflict"); len = stunEncodeMessage(&resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); return -1; } } { struct CandidatePair *cand_pair; int pos; cand_pair=NULL; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; /* connectivity check is coming from a known remote candidate? we should also check the port... */ if (strcmp(cand_pair->remote_candidate.conn_addr, src6host)==0 && cand_pair->remote_candidate.conn_port==recvport) { ms_message("ice.c: STUN REQ (%s) <- %i (%s:%i:%s <- %s:%i:%s) from known peer", msg.hasUseCandidate==0?"":"USE-CANDIDATE", pos, cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->local_candidate.cand_type, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port, cand_pair->remote_candidate.cand_type); if (cand_pair->connectivity_check==ICE_FROZEN || cand_pair->connectivity_check==ICE_IN_PROGRESS || cand_pair->connectivity_check==ICE_FAILED) { cand_pair->connectivity_check = ICE_WAITING; if (msg.hasUseCandidate==TRUE && checklist->rem_controlling==0) cand_pair->nominated_pair = 1; } else if (cand_pair->connectivity_check==ICE_SUCCEEDED) { if (msg.hasUseCandidate==TRUE && checklist->rem_controlling==0) { cand_pair->nominated_pair = 1; /* USE-CANDIDATE is in STUN request and we already succeeded on that link */ ms_message("ice.c: ICE CONCLUDED == %i (%s:%i:%s <- %s:%i:%s nominated=%s)", pos, cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->local_candidate.cand_type, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port, cand_pair->remote_candidate.cand_type, cand_pair->nominated_pair==0?"FALSE":"TRUE"); memcpy(&session->rtp.rem_addr, &evt_data->ep->addr, evt_data->ep->addrlen); session->rtp.rem_addrlen=evt_data->ep->addrlen; } } break; } cand_pair=NULL; } if (cand_pair==NULL) { struct CandidatePair new_pair; memset(&new_pair, 0, sizeof(struct CandidatePair)); ms_message("ice.c: STUN REQ <- connectivity check received from an unknow candidate (%s:%i)", src6host, recvport); /* TODO: add the peer-reflexive candidate */ memcpy(&new_pair.local_candidate, &remote_candidates[0].local_candidate, sizeof(new_pair.local_candidate)); new_pair.remote_candidate.foundation = 6; new_pair.remote_candidate.component_id = remote_candidates[0].remote_candidate.component_id; /* -> no known base address for peer */ new_pair.remote_candidate.conn_port = recvport; snprintf(new_pair.remote_candidate.conn_addr, sizeof(new_pair.remote_candidate.conn_addr), "%s", src6host); /* take it from PRIORITY STUN attr */ new_pair.remote_candidate.priority = msg.priority.priority; if (new_pair.remote_candidate.priority==0) { uint32_t type_preference = 110; uint32_t interface_preference = 255; uint32_t stun_priority=255; new_pair.remote_candidate.priority = (type_preference << 24) | (interface_preference << 16) | (stun_priority << 8) | (256 - new_pair.remote_candidate.component_id); } snprintf(new_pair.remote_candidate.cand_type, sizeof(cand_pair->remote_candidate.cand_type), "prflx"); snprintf (new_pair.remote_candidate.transport, sizeof (new_pair.remote_candidate.transport), "UDP"); if (checklist->rem_controlling==0) { uint64_t G = new_pair.local_candidate.priority; /* controlled agent */ uint64_t D = new_pair.remote_candidate.priority; new_pair.pair_priority = (MIN(G, D))<<32 | (MAX(G, D))<<1 | (G>D?1:0); } else { uint64_t G = new_pair.remote_candidate.priority; /* controlled agent */ uint64_t D = new_pair.local_candidate.priority; new_pair.pair_priority = (MIN(G, D))<<32 | (MAX(G, D))<<1 | (G>D?1:0); } new_pair.connectivity_check = ICE_WAITING; /* insert new pair candidate */ if (msg.hasUseCandidate==TRUE && checklist->rem_controlling==0) { new_pair.nominated_pair = 1; } for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (pos==9) { ms_message("ice.c: STUN REQ (%s) <- X (%s:%i:%s <- %s:%i:%s) no room for new remote reflexive candidate", msg.hasUseCandidate==0?"":"USE-CANDIDATE", new_pair.local_candidate.conn_addr, new_pair.local_candidate.conn_port, new_pair.local_candidate.cand_type, new_pair.remote_candidate.conn_addr, new_pair.remote_candidate.conn_port, new_pair.remote_candidate.cand_type); break; } if (new_pair.pair_priority > remote_candidates[pos].pair_priority) { /* move upper data */ memmove(&remote_candidates[pos+1], &remote_candidates[pos], sizeof(struct CandidatePair)*(10-pos-1)); memcpy(&remote_candidates[pos], &new_pair, sizeof(struct CandidatePair)); if (checklist->nominated_pair_index>=pos) checklist->nominated_pair_index++; ms_message("ice.c: STUN REQ (%s) <- %i (%s:%i:%s <- %s:%i:%s) new learned remote reflexive candidate", msg.hasUseCandidate==0?"":"USE-CANDIDATE", pos, new_pair.local_candidate.conn_addr, new_pair.local_candidate.conn_port, new_pair.local_candidate.cand_type, new_pair.remote_candidate.conn_addr, new_pair.remote_candidate.conn_port, new_pair.remote_candidate.cand_type); break; } } } } { UInt32 cookie = 0x2112A442; resp.hasXorMappedAddress = TRUE; resp.xorMappedAddress.ipv4.port = remote_addr.port^(cookie>>16); resp.xorMappedAddress.ipv4.addr = remote_addr.addr^cookie; } resp.msgHdr.msgType = (STUN_METHOD_BINDING | STUN_SUCCESS_RESP); resp.hasUsername = TRUE; memcpy(resp.username.value, msg.username.value, msg.username.sizeValue ); resp.username.sizeValue = msg.username.sizeValue; /* ? any messageintegrity in response? */ resp.hasMessageIntegrity = TRUE; { const char serverName[] = "mediastreamer2 " STUN_VERSION; resp.hasSoftware = TRUE; memcpy( resp.softwareName.value, serverName, sizeof(serverName)); resp.softwareName.sizeValue = sizeof(serverName); } resp.hasFingerprint = TRUE; { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); len = stunEncodeMessage( &resp, buf, len, &hmacPassword ); if (len) sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port); } }
static int ice_restart(struct IceCheckList *checklist) { struct CandidatePair *remote_candidates = NULL; int pos; int count_waiting=0; int count=0; if (checklist==NULL) return 0; remote_candidates = checklist->cand_pairs; if (remote_candidates==NULL) return 0; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (strcasecmp(remote_candidates[pos].local_candidate.cand_type, "srflx")==0) { /* search for a highest priority "equivalent" pair */ int pos2; for (pos2=0;pos2<pos && remote_candidates[pos2].remote_candidate.conn_addr[0]!='\0';pos2++) { /* same "base" address (origin of STUN connectivity check to the remote candidate */ if (strcasecmp(remote_candidates[pos].local_candidate.rel_addr, /* base address for "reflexive" address */ remote_candidates[pos2].local_candidate.conn_addr)==0) /* base address for "host" address */ { /* if same target remote candidate: -> remove the one with lowest priority */ if (strcasecmp(remote_candidates[pos].remote_candidate.conn_addr, remote_candidates[pos2].remote_candidate.conn_addr)==0) { /* useless cpair */ ms_message("ice.c: Removing useless pair (idx=%i)", pos); remote_candidates[pos].connectivity_check = ICE_PRUNED; } } } } } /* no currently nominated pair */ checklist->nominated_pair_index = -1; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (remote_candidates[pos].connectivity_check == ICE_PRUNED) continue; if (remote_candidates[pos].connectivity_check == ICE_FROZEN) remote_candidates[pos].connectivity_check = ICE_WAITING; } checklist->Ta = 40; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { if (remote_candidates[pos].connectivity_check == ICE_PRUNED) continue; if (remote_candidates[pos].connectivity_check == ICE_WAITING) count_waiting++; count++; } checklist->RTO = MAX(200, count*checklist->Ta*count_waiting); return 0; }
static void presence_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { ms_message("presence_process_transaction_terminated not implemented yet"); }
static int ice_sound_send_stun_request(RtpSession *session, struct IceCheckList *checklist, uint64_t ctime) { struct CandidatePair *remote_candidates = NULL; if (checklist==NULL) return 0; remote_candidates = checklist->cand_pairs; if (remote_candidates==NULL) return 0; { struct CandidatePair *cand_pair; int media_socket = rtp_session_get_rtp_socket(session); StunAddress4 stunServerAddr; StunAtrString username; StunAtrString password; bool_t res; int pos; /* prepare ONCE tie-break value */ if (checklist->tiebreak_value==0) { checklist->tiebreak_value = random() * (0x7fffffffffffffffLL /0x7fff); } cand_pair=NULL; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_PRUNED) { cand_pair=NULL; continue; } if (cand_pair->connectivity_check == ICE_WAITING) break; if (cand_pair->connectivity_check == ICE_IN_PROGRESS) break; if (cand_pair->connectivity_check == ICE_SUCCEEDED) break; cand_pair=NULL; } if (cand_pair==NULL) return 0; /* nothing to do: every pair is FAILED, FROZEN or PRUNED */ /* start first WAITING pair */ cand_pair=NULL; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_PRUNED) { cand_pair=NULL; continue; } if (cand_pair->connectivity_check == ICE_WAITING) break; cand_pair=NULL; } if (cand_pair!=NULL) { cand_pair->connectivity_check = ICE_IN_PROGRESS; cand_pair->retransmission_number=0; cand_pair->retransmission_time=ctime+checklist->RTO; /* keep same rem_controlling for retransmission */ cand_pair->rem_controlling = checklist->rem_controlling; } /* try no nominate a pair if we are ready */ if (cand_pair==NULL && checklist->nominated_pair_index<0) { for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_PRUNED) { cand_pair=NULL; continue; } if (cand_pair->connectivity_check == ICE_SUCCEEDED) { break; } cand_pair=NULL; } /* ALWAYS accept "host" candidate that have succeeded */ if (cand_pair!=NULL && (strcasecmp(cand_pair->remote_candidate.cand_type, "host")==0)) { checklist->nominated_pair_index = pos; cand_pair->nominated_pair = 1; cand_pair->connectivity_check = ICE_IN_PROGRESS; cand_pair->retransmission_number=0; cand_pair->retransmission_time=ctime+checklist->RTO; /* keep same rem_controlling for retransmission */ cand_pair->rem_controlling = checklist->rem_controlling; /* send a new STUN with USE-CANDIDATE */ ms_message("ice.c: nominating pair -> %i (%s:%i:%s -> %s:%i:%s) nominated=%s", pos, cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->local_candidate.cand_type, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port, cand_pair->remote_candidate.cand_type, cand_pair->nominated_pair==0?"FALSE":"TRUE"); checklist->keepalive_time=ctime+15*1000; } else if (cand_pair!=NULL) { struct CandidatePair *cand_pair2=NULL; int pos2; for (pos2=0;pos2<pos && remote_candidates[pos2].remote_candidate.conn_addr[0]!='\0';pos2++) { cand_pair2 = &remote_candidates[pos2]; if (cand_pair2->connectivity_check == ICE_PRUNED) { cand_pair2=NULL; continue; } if (cand_pair2->connectivity_check == ICE_IN_PROGRESS ||cand_pair2->connectivity_check == ICE_WAITING) { break; } cand_pair2=NULL; } if (cand_pair2!=NULL) { /* a better candidate is still tested */ cand_pair=NULL; } else { checklist->nominated_pair_index = pos; cand_pair->nominated_pair = 1; cand_pair->connectivity_check = ICE_IN_PROGRESS; cand_pair->retransmission_number=0; cand_pair->retransmission_time=ctime+checklist->RTO; /* keep same rem_controlling for retransmission */ cand_pair->rem_controlling = checklist->rem_controlling; /* send a new STUN with USE-CANDIDATE */ ms_message("ice.c: nominating pair -> %i (%s:%i:%s -> %s:%i:%s) nominated=%s", pos, cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->local_candidate.cand_type, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port, cand_pair->remote_candidate.cand_type, cand_pair->nominated_pair==0?"FALSE":"TRUE"); checklist->keepalive_time=ctime+15*1000; } } } if (cand_pair==NULL) { /* no WAITING pair: retransmit after RTO */ for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_PRUNED) { cand_pair=NULL; continue; } if (cand_pair->connectivity_check == ICE_IN_PROGRESS && ctime > cand_pair->retransmission_time) { if (cand_pair->retransmission_number>7) { ms_message("ice.c: ICE_FAILED for candidate pair! %s:%i -> %s:%i", cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port); cand_pair->connectivity_check = ICE_FAILED; cand_pair=NULL; continue; } cand_pair->retransmission_number++; cand_pair->retransmission_time=ctime+checklist->RTO; break; } cand_pair=NULL; } } if (cand_pair==NULL) { if (checklist->nominated_pair_index<0) return 0; /* send STUN indication each 15 seconds: keepalive */ if (ctime>checklist->keepalive_time) { checklist->keepalive_time=ctime+15*1000; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++) { cand_pair = &remote_candidates[pos]; if (cand_pair->connectivity_check == ICE_SUCCEEDED) { res = stunParseServerName(cand_pair->remote_candidate.conn_addr, &stunServerAddr); if ( res == TRUE ) { StunMessage req; char buf[STUN_MAX_MESSAGE_SIZE]; int len = STUN_MAX_MESSAGE_SIZE; stunServerAddr.port = cand_pair->remote_candidate.conn_port; memset(&req, 0, sizeof(StunMessage)); stunBuildReqSimple( &req, NULL, FALSE, FALSE, 1); req.msgHdr.msgType = (STUN_METHOD_BINDING|STUN_INDICATION); req.hasFingerprint = TRUE; len = stunEncodeMessage( &req, buf, len, NULL); sendMessage( media_socket, buf, len, stunServerAddr.addr, stunServerAddr.port ); } } } } return 0; } username.sizeValue = 0; password.sizeValue = 0; /* username comes from "ice-ufrag" (rfrag:lfrag) */ /* ufrag and pwd are in first row only */ snprintf(username.value, sizeof(username.value), "%s:%s", checklist->rem_ice_ufrag, checklist->loc_ice_ufrag); username.sizeValue = (UInt16)strlen(username.value); snprintf(password.value, sizeof(password.value), "%s", checklist->rem_ice_pwd); password.sizeValue = (UInt16)strlen(password.value); res = stunParseServerName(cand_pair->remote_candidate.conn_addr, &stunServerAddr); if ( res == TRUE ) { ms_message("ice.c: STUN REQ (%s) -> %i (%s:%i:%s -> %s:%i:%s) nominated=%s", cand_pair->nominated_pair==0?"":"USE-CANDIDATE", pos, cand_pair->local_candidate.conn_addr, cand_pair->local_candidate.conn_port, cand_pair->local_candidate.cand_type, cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port, cand_pair->remote_candidate.cand_type, cand_pair->nominated_pair==0?"FALSE":"TRUE"); stunServerAddr.port = cand_pair->remote_candidate.conn_port; ice_sendtest(checklist, cand_pair, media_socket, &stunServerAddr, &username, &password, &(cand_pair->tid)); } } return 0; }
static void conference_free(LinphoneConference *conf) { if(conf->name!=NULL) ms_free(conf->name); if(ms_list_size(conf->members)!=0) ms_message("free members"); ms_free(conf); }
static void dec_process(MSFilter *f){ DecData *d=(DecData*)f->data; MSPicture pic = {0}; mblk_t *im,*om = NULL; ssize_t oBufidx = -1; size_t bufsize; bool_t need_reinit=FALSE; bool_t request_pli=FALSE; MSQueue nalus; AMediaCodecBufferInfo info; ms_queue_init(&nalus); while((im=ms_queue_get(f->inputs[0]))!=NULL){ if (d->packet_num==0 && d->sps && d->pps){ mblk_set_timestamp_info(d->sps,mblk_get_timestamp_info(im)); mblk_set_timestamp_info(d->pps,mblk_get_timestamp_info(im)); rfc3984_unpack(&d->unpacker, d->sps, &nalus); rfc3984_unpack(&d->unpacker, d->pps, &nalus); d->sps=NULL; d->pps=NULL; } if(rfc3984_unpack(&d->unpacker,im,&nalus) <0){ request_pli=TRUE; } if (!ms_queue_empty(&nalus)){ int size; uint8_t *buf=NULL; ssize_t iBufidx; size=nalusToFrame(d,&nalus,&need_reinit); if (need_reinit) { //In case of rotation, the decoder needs to flushed in order to restart with the new video size AMediaCodec_flush(d->codec); d->first_buffer_queued = FALSE; } /*First put our H264 bitstream into the decoder*/ iBufidx = AMediaCodec_dequeueInputBuffer(d->codec, TIMEOUT_US); if (iBufidx >= 0) { buf = AMediaCodec_getInputBuffer(d->codec, iBufidx, &bufsize); if(buf == NULL) { ms_error("MSMediaCodecH264Dec: AMediaCodec_getInputBuffer() returned NULL"); break; } if((size_t)size > bufsize) { ms_error("Cannot copy the bitstream into the input buffer size : %i and bufsize %i",size,(int) bufsize); break; } else { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); memcpy(buf,d->bitstream,(size_t)size); AMediaCodec_queueInputBuffer(d->codec, iBufidx, 0, (size_t)size, (ts.tv_nsec/1000) + 10000LL, 0); d->first_buffer_queued = TRUE; } }else if (iBufidx == AMEDIA_ERROR_UNKNOWN){ ms_error("MSMediaCodecH264Dec: AMediaCodec_dequeueInputBuffer() had an exception"); } } d->packet_num++; if (d->sps && d->pps) request_pli = FALSE; else request_pli = TRUE; } /*secondly try to get decoded frames from the decoder, this is performed every tick*/ while (d->first_buffer_queued && (oBufidx = AMediaCodec_dequeueOutputBuffer(d->codec, &info, TIMEOUT_US)) >= 0){ AMediaFormat *format; int width = 0, height = 0, color = 0; uint8_t *buf = AMediaCodec_getOutputBuffer(d->codec, oBufidx, &bufsize); if(buf == NULL){ ms_filter_notify_no_arg(f,MS_VIDEO_DECODER_DECODING_ERRORS); ms_error("MSMediaCodecH264Dec: AMediaCodec_getOutputBuffer() returned NULL"); } format = AMediaCodec_getOutputFormat(d->codec); if(format != NULL){ AMediaFormat_getInt32(format, "width", &width); AMediaFormat_getInt32(format, "height", &height); AMediaFormat_getInt32(format, "color-format", &color); d->vsize.width=width; d->vsize.height=height; AMediaFormat_delete(format); } if(buf != NULL && d->sps && d->pps){ /*some decoders output garbage while no sps or pps have been received yet !*/ if(width != 0 && height != 0 ){ if(color == 19) { //YUV int ysize = width*height; int usize = ysize/4; om = ms_yuv_buf_allocator_get(d->buf_allocator,&pic,width,height); memcpy(pic.planes[0],buf,ysize); memcpy(pic.planes[1],buf+ysize,usize); memcpy(pic.planes[2],buf+ysize+usize,usize); } else { uint8_t* cbcr_src = (uint8_t*) (buf + width * height); om = copy_ycbcrbiplanar_to_true_yuv_with_rotation_and_down_scale_by_2(d->buf_allocator, buf, cbcr_src, 0, width, height, width, width, TRUE, FALSE); } if (!d->first_image_decoded) { ms_message("First frame decoded %ix%i",width,height); d->first_image_decoded = true; ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_FIRST_IMAGE_DECODED); } ms_queue_put(f->outputs[0], om); }else{ ms_error("MSMediaCodecH264Dec: width and height are not known !"); } } AMediaCodec_releaseOutputBuffer(d->codec, oBufidx, FALSE); } if (oBufidx == AMEDIA_ERROR_UNKNOWN){ ms_error("MSMediaCodecH264Dec: AMediaCodec_dequeueOutputBuffer() had an exception"); } if (d->avpf_enabled && request_pli) { ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_SEND_PLI); } ms_queue_flush(f->inputs[0]); }
MS2_PUBLIC void libmsx264_init(void){ ms_filter_register(&x264_enc_desc); ms_message("ms264-" VERSION " plugin registered."); }
/** * @briefThis function is called by ZRTP engine as soon as SRTP secrets are ready to be used * Depending on which role we assume in the ZRTP protocol (Initiator or Responder, randomly selected) * both secrets may not be available at the same time, the part argument is either * ZRTP_SRTP_SECRETS_FOR_SENDER or ZRTP_SRTP_SECRETS_FOR_RECEIVER. * Secrets are used to set up SRTP sessions * * @param[in] clientData Pointer to our ZrtpContext structure used to retrieve stream sessions structure needed to setup SRTP sessions * @param[in] secrets The SRTP keys and algorithm setup * @param[in] part for receiver or for sender in order to determine which SRTP stream the secret apply to * @return 0 on success */ static int32_t ms_zrtp_srtpSecretsAvailable(void* clientData, bzrtpSrtpSecrets_t* secrets, uint8_t part) { MSZrtpContext *userData = (MSZrtpContext *)clientData; // Get authentication and cipher algorithms in srtp format if ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS32) && ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS80))) { ms_fatal("unsupported authentication algorithm by srtp"); } if ((secrets->cipherAlgo != ZRTP_CIPHER_AES1) && (secrets->cipherAlgo != ZRTP_CIPHER_AES3)) { ms_fatal("unsupported cipher algorithm by srtp"); } ms_message("ZRTP secrets are ready for %s; auth tag algo is %s and cipher algo is %s", (part==ZRTP_SRTP_SECRETS_FOR_SENDER)?"sender":"receiver", (secrets->authTagAlgo==ZRTP_AUTHTAG_HS32)?"HS32":"HS80", (secrets->cipherAlgo==ZRTP_CIPHER_AES3)?"AES256":"AES128"); if (part==ZRTP_SRTP_SECRETS_FOR_RECEIVER) { uint8_t *key = (uint8_t *)ms_malloc0((secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength+16)*sizeof(uint8_t)); memcpy(key, secrets->peerSrtpKey, secrets->peerSrtpKeyLength); memcpy(key + secrets->peerSrtpKeyLength, secrets->peerSrtpSalt, secrets->peerSrtpSaltLength); if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_256_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_128_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_256_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_recv_key(userData->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else{ ms_fatal("unsupported auth tag"); } ms_free(key); } if (part==ZRTP_SRTP_SECRETS_FOR_SENDER) { uint8_t *key = (uint8_t *)ms_malloc0((secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength+16)*sizeof(uint8_t)); memcpy(key, secrets->selfSrtpKey, secrets->selfSrtpKeyLength); memcpy(key + secrets->selfSrtpKeyLength, secrets->selfSrtpSalt, secrets->selfSrtpSaltLength); if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_256_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_128_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){ if (secrets->cipherAlgo == ZRTP_CIPHER_AES3){ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_256_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); }else{ ms_media_stream_sessions_set_srtp_send_key(userData->stream_sessions, MS_AES_128_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS); } }else{ ms_fatal("unsupported auth tag"); } ms_free(key); } return 0; }
void ms_snd_card_manager_add_card(MSSndCardManager *m, MSSndCard *c){ ms_message("Card %s added",ms_snd_card_get_string_id(c)); m->cards=ms_list_append(m->cards,c); }
MSZrtpContext* ms_zrtp_context_new(MSMediaStreamSessions *sessions, MSZrtpParams *params){ ms_message("ZRTP is disabled"); return NULL; }
static void tone_detected_cb(void *data, MSFilter *f, unsigned int event_id, MSToneDetectorEvent *ev) { ms_message("Tone detected at time %u",(unsigned int)ev->tone_start_time); }
static int _v4w_start(V4wState *s, void *arg) { MSVideoSize try_vsize; int tryformat; int i; s->frame_count=-1; if (s->pix_fmt==MS_YUV420P) tryformat = MS_RGB24; else if (s->pix_fmt==MS_RGB24) tryformat = MS_YUV420P; try_vsize.height = s->vsize.height; try_vsize.width = s->vsize.width; i = try_format(s, s->pix_fmt, &try_vsize); if (i==-14) { /* try second format with same size */ i = try_format(s, tryformat, &try_vsize); } /* try both format with CIF size */ if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_CIF_H) { try_vsize.height = MS_VIDEO_SIZE_CIF_H; try_vsize.width = MS_VIDEO_SIZE_CIF_W; i = try_format(s, s->pix_fmt, &try_vsize); if (i==-14) { i = try_format(s, tryformat, &try_vsize); } } if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_QCIF_H) { try_vsize.height = MS_VIDEO_SIZE_QCIF_H; try_vsize.width = MS_VIDEO_SIZE_QCIF_W; i = try_format(s, s->pix_fmt, &try_vsize); if (i==-14) { i = try_format(s, tryformat, &try_vsize); } } if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_VGA_H) { try_vsize.height = MS_VIDEO_SIZE_VGA_H; try_vsize.width = MS_VIDEO_SIZE_VGA_W; i = try_format(s, s->pix_fmt, &try_vsize); if (i==-14) { i = try_format(s, tryformat, &try_vsize); } } if (i==-14 && s->vsize.height!=MS_VIDEO_SIZE_QVGA_H) { try_vsize.height = MS_VIDEO_SIZE_QVGA_H; try_vsize.width = MS_VIDEO_SIZE_QVGA_W; i = try_format(s, s->pix_fmt, &try_vsize); if (i==-14) { i = try_format(s, tryformat, &try_vsize); } } if (i==0) { if (s->pix_fmt==MS_YUV420P) ms_message("Using YUV420P"); else if (s->pix_fmt==MS_RGB24) ms_message("Using RGB24"); } if (s->rotregvalue==0){ //RemoveGraphFromRot(s->rotregvalue); if (s->m_pNullRenderer!=NULL) s->m_pGraph->RemoveFilter(s->m_pNullRenderer); if (s->m_pIDXFilter!=NULL) s->m_pGraph->RemoveFilter(s->m_pIDXFilter); if (s->m_pDeviceFilter!=NULL) s->m_pGraph->RemoveFilter(s->m_pDeviceFilter); s->m_pBuilder=NULL; s->m_pControl=NULL; s->m_pIDXFilter=NULL; if (s->m_pDXFilter!=NULL) s->m_pDXFilter->Release(); s->m_pDXFilter=NULL; s->m_pGraph=NULL; s->m_pNullRenderer=NULL; s->m_pDeviceFilter=NULL; CoUninitialize(); s_callback = NULL; flushq(&s->rq,0); ms_message("v4w: graph not started (err=%i)", i); s->rotregvalue=0; } return i; }
static void tone_sent_cb(void *data, MSFilter *f, unsigned int event_id, MSDtmfGenEvent *ev) { ms_message("Tone sent at time %u",(unsigned int)ev->tone_start_time); }
void ms_factory_set_cpu_count(MSFactory *obj, unsigned int c) { ms_message("CPU count set to %d", c); obj->cpu_count = c; }
int ms_load_plugins(const char *dir){ int num=0; #if defined(WIN32) && !defined(_WIN32_WCE) WIN32_FIND_DATA FileData; HANDLE hSearch; char szDirPath[1024]; char szPluginFile[1024]; BOOL fFinished = FALSE; const char *tmp=getenv("DEBUG"); BOOL debug=(tmp!=NULL && atoi(tmp)==1); snprintf(szDirPath, sizeof(szDirPath), "%s", dir); // Start searching for .dll files in the current directory. snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir); hSearch = FindFirstFile(szDirPath, &FileData); if (hSearch == INVALID_HANDLE_VALUE) { ms_message("no plugin (*.dll) found in %s.", szDirPath); return 0; } snprintf(szDirPath, sizeof(szDirPath), "%s", dir); while (!fFinished) { /* load library */ HINSTANCE os_handle; UINT em; if (!debug) em = SetErrorMode (SEM_FAILCRITICALERRORS); snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName); os_handle = LoadLibraryEx (szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (os_handle==NULL) { ms_message("Fail to load plugin %s with altered search path: error %i",szPluginFile,GetLastError()); os_handle = LoadLibraryEx (szPluginFile, NULL, 0); } if (!debug) SetErrorMode (em); if (os_handle==NULL) ms_error("Fail to load plugin %s", szPluginFile); else{ init_func_t initroutine; char szPluginName[256]; char szMethodName[256]; char *minus; snprintf(szPluginName, 256, "%s", FileData.cFileName); /*on mingw, dll names might be libsomething-3.dll. We must skip the -X.dll stuff*/ minus=strchr(szPluginName,'-'); if (minus) *minus='\0'; else szPluginName[strlen(szPluginName)-4]='\0'; /*remove .dll*/ snprintf(szMethodName, 256, "%s_init", szPluginName); initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName); if (initroutine!=NULL){ initroutine(); ms_message("Plugin loaded (%s)", szPluginFile); num++; }else{ ms_warning("Could not locate init routine of plugin %s. Should be %s", szPluginFile, szMethodName); } } if (!FindNextFile(hSearch, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES){ fFinished = TRUE; } else { ms_error("couldn't find next plugin dll."); fFinished = TRUE; } } } /* Close the search handle. */ FindClose(hSearch); #elif HAVE_DLOPEN DIR *ds; struct dirent *de; char *fullpath; ds=opendir(dir); if (ds==NULL){ ms_message("Cannot open directory %s: %s",dir,strerror(errno)); return -1; } while( (de=readdir(ds))!=NULL){ if ((de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL) || (de->d_type==DT_UNKNOWN && strstr(de->d_name,PLUGINS_EXT)==de->d_name+strlen(de->d_name)-strlen(PLUGINS_EXT))) { void *handle; fullpath=ms_strdup_printf("%s/%s",dir,de->d_name); ms_message("Loading plugin %s...",fullpath); if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ ms_warning("Fail to load plugin %s : %s",fullpath,dlerror()); }else { char *initroutine_name=ms_malloc0(strlen(de->d_name)+10); char *p; void *initroutine=NULL; strcpy(initroutine_name,de->d_name); p=strstr(initroutine_name,PLUGINS_EXT); if (p!=NULL){ strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } #ifdef __APPLE__ if (initroutine==NULL){ /* on macosx: library name are libxxxx.1.2.3.dylib */ /* -> MUST remove the .1.2.3 */ p=strstr(initroutine_name,"."); if (p!=NULL) { strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } } #endif if (initroutine!=NULL){ init_func_t func=(init_func_t)initroutine; func(); ms_message("Plugin loaded (%s)", fullpath); num++; }else{ ms_warning("Could not locate init routine of plugin %s",de->d_name); } ms_free(initroutine_name); } ms_free(fullpath); } } closedir(ds); #else ms_warning("no loadable plugin support: plugins cannot be loaded."); num=-1; #endif return num; }
int ms_factory_load_plugins(MSFactory *factory, const char *dir){ int num=0; #if defined(_WIN32) && !defined(_WIN32_WCE) WIN32_FIND_DATA FileData; HANDLE hSearch; char szDirPath[1024]; #ifdef UNICODE wchar_t wszDirPath[1024]; #endif char szPluginFile[1024]; BOOL fFinished = FALSE; const char *tmp = NULL; BOOL debug = FALSE; #ifndef MS2_WINDOWS_UNIVERSAL tmp = getenv("DEBUG"); #endif debug = (tmp != NULL && atoi(tmp) == 1); snprintf(szDirPath, sizeof(szDirPath), "%s", dir); // Start searching for .dll files in the current directory. #ifdef MS2_WINDOWS_DESKTOP snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir); #else snprintf(szDirPath, sizeof(szDirPath), "%s\\libms*.dll", dir); #endif #ifdef UNICODE mbstowcs(wszDirPath, szDirPath, sizeof(wszDirPath)); hSearch = FindFirstFileExW(wszDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); #else hSearch = FindFirstFileExA(szDirPath, FindExInfoStandard, &FileData, FindExSearchNameMatch, NULL, 0); #endif if (hSearch == INVALID_HANDLE_VALUE) { ms_message("no plugin (*.dll) found in [%s] [%d].", szDirPath, (int)GetLastError()); return 0; } snprintf(szDirPath, sizeof(szDirPath), "%s", dir); while (!fFinished) { /* load library */ #ifdef MS2_WINDOWS_DESKTOP UINT em=0; #endif HINSTANCE os_handle; #ifdef UNICODE wchar_t wszPluginFile[2048]; char filename[512]; wcstombs(filename, FileData.cFileName, sizeof(filename)); snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, filename); mbstowcs(wszPluginFile, szPluginFile, sizeof(wszPluginFile)); #else snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName); #endif #ifdef MS2_WINDOWS_DESKTOP if (!debug) em = SetErrorMode (SEM_FAILCRITICALERRORS); #ifdef UNICODE os_handle = LoadLibraryExW(wszPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); #else os_handle = LoadLibraryExA(szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); #endif if (os_handle==NULL) { ms_message("Fail to load plugin %s with altered search path: error %i",szPluginFile,(int)GetLastError()); #ifdef UNICODE os_handle = LoadLibraryExW(wszPluginFile, NULL, 0); #else os_handle = LoadLibraryExA(szPluginFile, NULL, 0); #endif } if (!debug) SetErrorMode (em); #else os_handle = LoadPackagedLibrary(wszPluginFile, 0); #endif if (os_handle==NULL) ms_error("Fail to load plugin %s: error %i", szPluginFile, (int)GetLastError()); else{ init_func_t initroutine; char szPluginName[256]; char szMethodName[256]; char *minus; #ifdef UNICODE snprintf(szPluginName, sizeof(szPluginName), "%s", filename); #else snprintf(szPluginName, sizeof(szPluginName), "%s", FileData.cFileName); #endif /*on mingw, dll names might be libsomething-3.dll. We must skip the -X.dll stuff*/ minus=strchr(szPluginName,'-'); if (minus) *minus='\0'; else szPluginName[strlen(szPluginName)-4]='\0'; /*remove .dll*/ snprintf(szMethodName, sizeof(szMethodName), "%s_init", szPluginName); initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName); if (initroutine!=NULL){ initroutine(factory); ms_message("Plugin loaded (%s)", szPluginFile); // Add this new loaded plugin to the list (useful for FreeLibrary at the end) factory->ms_plugins_loaded_list=ms_list_append(factory->ms_plugins_loaded_list,os_handle); num++; }else{ ms_warning("Could not locate init routine of plugin %s. Should be %s", szPluginFile, szMethodName); } } if (!FindNextFile(hSearch, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES){ fFinished = TRUE; } else { ms_error("couldn't find next plugin dll."); fFinished = TRUE; } } } /* Close the search handle. */ FindClose(hSearch); #elif defined(HAVE_DLOPEN) char plugin_name[64]; DIR *ds; MSList *loaded_plugins = NULL; struct dirent *de; char *ext; char *fullpath; ds=opendir(dir); if (ds==NULL){ ms_message("Cannot open directory %s: %s",dir,strerror(errno)); return -1; } while( (de=readdir(ds))!=NULL){ if ( #ifndef __QNX__ (de->d_type==DT_REG || de->d_type==DT_UNKNOWN || de->d_type==DT_LNK) && #endif (ext=strstr(de->d_name,PLUGINS_EXT))!=NULL) { void *handle; snprintf(plugin_name, MIN(sizeof(plugin_name), ext - de->d_name + 1), "%s", de->d_name); if (ms_list_find_custom(loaded_plugins, (MSCompareFunc)strcmp, plugin_name) != NULL) continue; loaded_plugins = ms_list_append(loaded_plugins, ms_strdup(plugin_name)); fullpath=ms_strdup_printf("%s/%s",dir,de->d_name); ms_message("Loading plugin %s...",fullpath); if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){ ms_warning("Fail to load plugin %s : %s",fullpath,dlerror()); }else { char *initroutine_name=ms_malloc0(strlen(de->d_name)+10); char *p; void *initroutine=NULL; strcpy(initroutine_name,de->d_name); p=strstr(initroutine_name,PLUGINS_EXT); if (p!=NULL){ strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } #ifdef __APPLE__ if (initroutine==NULL){ /* on macosx: library name are libxxxx.1.2.3.dylib */ /* -> MUST remove the .1.2.3 */ p=strstr(initroutine_name,"."); if (p!=NULL) { strcpy(p,"_init"); initroutine=dlsym(handle,initroutine_name); } } #endif if (initroutine!=NULL){ init_func_t func=(init_func_t)initroutine; func(factory); ms_message("Plugin loaded (%s)", fullpath); num++; }else{ ms_warning("Could not locate init routine of plugin %s",de->d_name); } ms_free(initroutine_name); } ms_free(fullpath); } } ms_list_for_each(loaded_plugins, ms_free); ms_list_free(loaded_plugins); closedir(ds); #else ms_warning("no loadable plugin support: plugins cannot be loaded."); num=-1; #endif return num; }
void ms_web_cam_manager_prepend_cam(MSWebCamManager *m, MSWebCam *c){ ms_message("Webcam %s prepended",ms_web_cam_get_string_id(c)); m->cams=ms_list_prepend(m->cams,c); }
static int speex_ec_set_bypass_mode(MSFilter *f, void *arg) { SpeexECState *s=(SpeexECState*)f->data; s->bypass_mode=*(bool_t*)arg; ms_message("set EC bypass mode to [%i]",s->bypass_mode); return 0; }
static int audio_unit_open(AUCommon *d, bool_t is_read) { OSStatus result; UInt32 param; ComponentDescription desc; Component comp; AudioStreamBasicDescription asbd; const int input_bus=1; const int output_bus=0; // Get Default Input audio unit desc.componentType = kAudioUnitType_Output; desc.componentSubType = d->dev!=-1?kAudioUnitSubType_HALOutput:kAudioUnitSubType_DefaultOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; comp = FindNextComponent(NULL, &desc); if (comp == NULL) { ms_message("Cannot find audio component"); return -1; } result = OpenAComponent(comp, &d->au); if(result != noErr) { ms_message("Cannot open audio component %x", result); return -1; } param = is_read; if (d->dev!=-1) { CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, input_bus, ¶m, sizeof(UInt32))); param = !is_read; CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, output_bus, ¶m, sizeof(UInt32))); // Set the current device CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, output_bus, &d->dev, sizeof(AudioDeviceID))); } param=0; CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioUnitProperty_ShouldAllocateBuffer, is_read ? kAudioUnitScope_Input : kAudioUnitScope_Output , is_read ? input_bus : output_bus , ¶m, sizeof(param))); UInt32 asbdsize = sizeof(AudioStreamBasicDescription); memset((char *)&asbd, 0, asbdsize); CHECK_AURESULT(AudioUnitGetProperty(d->au, kAudioUnitProperty_StreamFormat, is_read ? kAudioUnitScope_Input : kAudioUnitScope_Output, is_read ? input_bus : output_bus, &asbd, &asbdsize)); show_format(is_read ? "Input audio unit" : "Output audio unit",&asbd); asbd.mSampleRate=d->rate; asbd.mBytesPerPacket=asbd.mBytesPerFrame = 2*d->nchannels; asbd.mChannelsPerFrame = d->nchannels; asbd.mBitsPerChannel=16; asbd.mFormatID=kAudioFormatLinearPCM; asbd.mFormatFlags=kAudioFormatFlagIsPacked|kAudioFormatFlagIsSignedInteger; CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioUnitProperty_StreamFormat, is_read ? kAudioUnitScope_Output : kAudioUnitScope_Input, is_read ? input_bus : output_bus , &asbd, sizeof(AudioStreamBasicDescription))); CHECK_AURESULT(AudioUnitGetProperty(d->au, kAudioUnitProperty_StreamFormat, is_read ? kAudioUnitScope_Output : kAudioUnitScope_Input, is_read ? input_bus : output_bus , &asbd, &asbdsize)); show_format(is_read ? "Input audio unit after configuration" : "Output audio unit after configuration",&asbd); // Get the number of frames in the IO buffer(s) param = sizeof(UInt32); UInt32 numFrames; CHECK_AURESULT(AudioUnitGetProperty(d->au, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Input, input_bus, &numFrames, ¶m)); ms_message("Number of frames per buffer = %i", numFrames); AURenderCallbackStruct cbs; cbs.inputProcRefCon = d; if (is_read) { cbs.inputProc = readRenderProc; CHECK_AURESULT(AudioUnitSetProperty(d->au, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, input_bus, &cbs, sizeof(AURenderCallbackStruct))); } else { cbs.inputProc = writeRenderProc; CHECK_AURESULT(AudioUnitSetProperty (d->au, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, output_bus, &cbs, sizeof(AURenderCallbackStruct))); } result = AudioUnitInitialize(d->au); if(result != noErr) { ms_error("failed to AudioUnitInitialize %i , is_read=%i", result,(int)is_read); return -1; } CHECK_AURESULT(AudioOutputUnitStart(d->au)); return 0; }
void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ const char *server=linphone_core_get_stun_server(lc); if (lc->sip_conf.ipv6_enabled){ ms_warning("stun support is not implemented for ipv6"); return; } if (server!=NULL){ struct sockaddr_storage ss; socklen_t ss_len; ortp_socket_t sock1=-1, sock2=-1; int loops=0; bool_t video_enabled=linphone_core_video_enabled(lc); bool_t got_audio,got_video; bool_t cone_audio=FALSE,cone_video=FALSE; struct timeval init,cur; SalEndpointCandidate *ac,*vc; ac=&call->localdesc->streams[0].candidates[0]; vc=&call->localdesc->streams[1].candidates[0]; if (parse_hostname_to_addr(server,&ss,&ss_len)<0){ ms_error("Fail to parser stun server address: %s",server); return; } if (lc->vtable.display_status!=NULL) lc->vtable.display_status(lc,_("Stun lookup in progress...")); /*create the two audio and video RTP sockets, and send STUN message to our stun server */ sock1=create_socket(call->audio_port); if (sock1==-1) return; if (video_enabled){ sock2=create_socket(call->video_port); if (sock2==-1) return ; } got_audio=FALSE; got_video=FALSE; gettimeofday(&init,NULL); do{ double elapsed; int id; if (loops%20==0){ ms_message("Sending stun requests..."); sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,11,TRUE); sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,1,FALSE); if (sock2!=-1){ sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,22,TRUE); sendStunRequest(sock2,(struct sockaddr*)&ss,ss_len,2,FALSE); } } #ifdef WIN32 Sleep(10); #else usleep(10000); #endif if (recvStunResponse(sock1,ac->addr, &ac->port,&id)>0){ ms_message("STUN test result: local audio port maps to %s:%i", ac->addr, ac->port); if (id==11) cone_audio=TRUE; got_audio=TRUE; } if (recvStunResponse(sock2,vc->addr, &vc->port,&id)>0){ ms_message("STUN test result: local video port maps to %s:%i", vc->addr, vc->port); if (id==22) cone_video=TRUE; got_video=TRUE; } gettimeofday(&cur,NULL); elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0); if (elapsed>2000) { ms_message("Stun responses timeout, going ahead."); break; } loops++; }while(!(got_audio && (got_video||sock2==-1) ) ); if (!got_audio){ ms_error("No stun server response for audio port."); }else{ if (!cone_audio) { ms_message("NAT is symmetric for audio port"); } } if (sock2!=-1){ if (!got_video){ ms_error("No stun server response for video port."); }else{ if (!cone_video) { ms_message("NAT is symmetric for video port."); } } } if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || sock2==-1){ strcpy(call->localdesc->addr,ac->addr); } close_socket(sock1); if (sock2!=-1) close_socket(sock2); } }
static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { LinphoneContent *content = linphone_content_new(); LinphoneAddress *addr; int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; int ret = 0; /*if we are on a low bandwidth network, do not send reports to not overload it*/ if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){ ms_warning("QualityReporting[%p]: Avoid sending reports on low bandwidth network", call); ret = 1; goto end; } /*if the call was hung up too early, we might have invalid IPs information in that case, we abort the report since it's not useful data*/ if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { ms_warning("QualityReporting[%p]: Trying to submit a %s too early (call duration: %d sec) but %s IP could " "not be retrieved so dropping this report" , call , report_event , linphone_call_get_duration(call) , (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0) ? "local" : "remote"); ret = 2; goto end; } addr = linphone_address_new(linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); if (addr == NULL) { ms_warning("QualityReporting[%p]: Asked to submit reporting statistics but no collector address found" , call); ret = 3; goto end; } buffer = (char *) belle_sip_malloc(size); linphone_content_set_type(content, "application"); linphone_content_set_subtype(content, "vq-rtcpxr"); append_to_buffer(&buffer, &size, &offset, "%s\r\n", report_event); append_to_buffer(&buffer, &size, &offset, "CallID: %s\r\n", report->info.call_id); append_to_buffer(&buffer, &size, &offset, "LocalID: %s\r\n", report->info.local_addr.id); append_to_buffer(&buffer, &size, &offset, "RemoteID: %s\r\n", report->info.remote_addr.id); append_to_buffer(&buffer, &size, &offset, "OrigID: %s\r\n", report->info.orig_id); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalGroup: %s\r\n", report->info.local_addr.group); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteGroup: %s\r\n", report->info.remote_addr.group); append_to_buffer(&buffer, &size, &offset, "LocalAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.local_addr.ip, report->info.local_addr.port, report->info.local_addr.ssrc); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalMAC: %s\r\n", report->info.local_addr.mac); append_to_buffer(&buffer, &size, &offset, "RemoteAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.remote_addr.ip, report->info.remote_addr.port, report->info.remote_addr.ssrc); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteMAC: %s\r\n", report->info.remote_addr.mac); append_to_buffer(&buffer, &size, &offset, "LocalMetrics:\r\n"); append_metrics_to_buffer(&buffer, &size, &offset, report->local_metrics); if (are_metrics_filled(report->remote_metrics)!=0) { append_to_buffer(&buffer, &size, &offset, "RemoteMetrics:\r\n"); append_metrics_to_buffer(&buffer, &size, &offset, report->remote_metrics); } APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "DialogID: %s\r\n", report->dialog_id); if (report->qos_analyzer.timestamp!=NULL){ append_to_buffer(&buffer, &size, &offset, "AdaptiveAlg:"); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " NAME=\"%s\"", report->qos_analyzer.name); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " TS=\"%s\"", report->qos_analyzer.timestamp); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN_LEG=\"%s\"", report->qos_analyzer.input_leg); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN=\"%s\"", report->qos_analyzer.input); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT_LEG=\"%s\"", report->qos_analyzer.output_leg); APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT=\"%s\"", report->qos_analyzer.output); append_to_buffer(&buffer, &size, &offset, "\r\n"); } linphone_content_set_buffer(content, buffer, strlen(buffer)); ms_free(buffer); if (call->log->reporting.on_report_sent != NULL){ call->log->reporting.on_report_sent( call, (report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO, content); } if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, content)){ ret=4; } else { reset_avg_metrics(report); STR_REASSIGN(report->qos_analyzer.timestamp, NULL); STR_REASSIGN(report->qos_analyzer.input_leg, NULL); STR_REASSIGN(report->qos_analyzer.input, NULL); STR_REASSIGN(report->qos_analyzer.output_leg, NULL); STR_REASSIGN(report->qos_analyzer.output, NULL); } linphone_address_destroy(addr); linphone_content_unref(content); end: ms_message("QualityReporting[%p]: Send '%s' with status %d", call, report_event, ret ); return ret; }
static void sound_read_setup(MSFilter *f){ ms_debug("andsnd_read_preprocess"); msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data; jmethodID constructor_id=0; jmethodID min_buff_size_id; //jmethodID set_notification_period; int rc; JNIEnv *jni_env = ms_get_jni_env(); d->audio_record_class = (jclass)jni_env->NewGlobalRef(jni_env->FindClass("android/media/AudioRecord")); if (d->audio_record_class == 0) { ms_error("cannot find android/media/AudioRecord"); return; } constructor_id = jni_env->GetMethodID(d->audio_record_class,"<init>", "(IIIII)V"); if (constructor_id == 0) { ms_error("cannot find AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)"); return; } min_buff_size_id = jni_env->GetStaticMethodID(d->audio_record_class,"getMinBufferSize", "(III)I"); if (min_buff_size_id == 0) { ms_error("cannot find AudioRecord.getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)"); return; } d->buff_size = jni_env->CallStaticIntMethod(d->audio_record_class,min_buff_size_id,d->rate,2/*CHANNEL_CONFIGURATION_MONO*/,2/* ENCODING_PCM_16BIT */); d->read_chunk_size = d->buff_size/4; d->buff_size*=2;/*double the size for configuring the recorder: this does not affect latency but prevents "AudioRecordThread: buffer overflow"*/ if (d->buff_size > 0) { ms_message("Configuring recorder with [%i] bits rate [%i] nchanels [%i] buff size [%i], chunk size [%i]" ,d->bits ,d->rate ,d->nchannels ,d->buff_size ,d->read_chunk_size); } else { ms_message("Cannot configure recorder with [%i] bits rate [%i] nchanels [%i] buff size [%i] chunk size [%i]" ,d->bits ,d->rate ,d->nchannels ,d->buff_size ,d->read_chunk_size); return; } d->read_buff = jni_env->NewByteArray(d->buff_size); d->read_buff = (jbyteArray)jni_env->NewGlobalRef(d->read_buff); if (d->read_buff == 0) { ms_error("cannot instanciate read buff"); return; } d->audio_record = jni_env->NewObject(d->audio_record_class ,constructor_id ,sdk_version<11?1/*MIC*/:7/*VOICE_COMMUNICATION*/ ,d->rate ,2/*CHANNEL_CONFIGURATION_MONO*/ ,2/* ENCODING_PCM_16BIT */ ,d->buff_size); d->audio_record = jni_env->NewGlobalRef(d->audio_record); if (d->audio_record == 0) { ms_error("cannot instantiate AudioRecord"); return; } d->min_avail=-1; d->read_samples=0; d->ticker_synchronizer = ms_ticker_synchronizer_new(); d->outgran_ms=20; d->start_time=-1; d->framesize=(d->outgran_ms*d->rate)/1000; d->started=true; // start reader thread rc = ms_thread_create(&d->thread_id, 0, (void*(*)(void*))msandroid_read_cb, d); if (rc){ ms_error("cannot create read thread return code is [%i]", rc); d->started=false; } }
static void dec_process(MSFilter *f) { mblk_t *im; DecState *s=(DecState*)f->data; while( (im=ms_queue_get(f->inputs[0]))!=0) { mblk_t *m; dec_unpacketize(f, s, im, &s->q); while((m=ms_queue_get(&s->q))!=NULL){ vpx_codec_err_t err; vpx_codec_iter_t iter = NULL; vpx_image_t *img; err = vpx_codec_decode(&s->codec, m->b_rptr, m->b_wptr - m->b_rptr, NULL, 0); if (err) { ms_warning("vpx_codec_decode failed : %d %s (%s)\n", err, vpx_codec_err_to_string(err), vpx_codec_error_detail(&s->codec)); if ((f->ticker->time - s->last_error_reported_time)>5000 || s->last_error_reported_time==0) { s->last_error_reported_time=f->ticker->time; ms_filter_notify_no_arg(f,MS_VIDEO_DECODER_DECODING_ERRORS); } if (s->first_image_decoded == FALSE) { /* if no frames have been decoded yet, do not try to browse decoded frames */ freemsg(m); continue; } } /* browse decoded frames */ while((img = vpx_codec_get_frame(&s->codec, &iter))) { int i,j; if (s->yuv_width != img->d_w || s->yuv_height != img->d_h) { if (s->yuv_msg) freemsg(s->yuv_msg); s->yuv_msg = ms_yuv_buf_alloc(&s->outbuf, img->d_w, img->d_h); s->yuv_width = img->d_w; s->yuv_height = img->d_h; } /* scale/copy frame to destination mblk_t */ for(i=0; i<3; i++) { uint8_t* dest = s->outbuf.planes[i]; uint8_t* src = img->planes[i]; int h = img->d_h >> ((i>0)?1:0); for(j=0; j<h; j++) { memcpy(dest, src, s->outbuf.strides[i]); dest += s->outbuf.strides[i]; src += img->stride[i]; } } ms_queue_put(f->outputs[0], dupmsg(s->yuv_msg)); if (ms_video_update_average_fps(&s->fps, f->ticker->time)) { ms_message("VP8 decoder: Frame size: %dx%d", s->yuv_width, s->yuv_height); } if (!s->first_image_decoded) { s->first_image_decoded = TRUE; ms_filter_notify_no_arg(f,MS_VIDEO_DECODER_FIRST_IMAGE_DECODED); } } freemsg(m); } } }