Exemple #1
0
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);
	}
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
/*	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;
	}
}
Exemple #6
0
MSZrtpContext* ms_zrtp_multistream_new(MSMediaStreamSessions *sessions, MSZrtpContext* activeContext, MSZrtpParams *params) {
	ms_message("ZRTP is disabled - not adding stream");
	return NULL;
}
Exemple #7
0
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(&param,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, &param))) {
			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;
}
Exemple #8
0
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);
		}
	}
Exemple #9
0
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;
}
Exemple #10
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");
}
Exemple #11
0
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]);
}
Exemple #14
0
MS2_PUBLIC void libmsx264_init(void){
	ms_filter_register(&x264_enc_desc);
	ms_message("ms264-" VERSION " plugin registered.");
}
Exemple #15
0
/**
 * @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;
}
Exemple #16
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);
}
Exemple #17
0
MSZrtpContext* ms_zrtp_context_new(MSMediaStreamSessions *sessions, MSZrtpParams *params){
	ms_message("ZRTP is disabled");
	return NULL;
}
Exemple #18
0
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);
}
Exemple #19
0
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;
}
Exemple #20
0
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);
}
Exemple #21
0
void ms_factory_set_cpu_count(MSFactory *obj, unsigned int c) {
	ms_message("CPU count set to %d", c);
	obj->cpu_count = c;
}
Exemple #22
0
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;
}
Exemple #23
0
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);
}
Exemple #25
0
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;
}
Exemple #26
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,
                                            &param,
                                            sizeof(UInt32)));

        param = !is_read;
        CHECK_AURESULT(AudioUnitSetProperty(d->au,
                                            kAudioOutputUnitProperty_EnableIO,
                                            kAudioUnitScope_Output,
                                            output_bus,
                                            &param,
                                            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 ,
                                        &param,
                                        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,
                                        &param));
    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;
}
Exemple #27
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);
	}
}
Exemple #28
0
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;
	}
}
Exemple #30
0
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);
		}
	}
}